From a8976a01fd14285b7926ffe5cdc403426e4ebae9 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 9 Nov 2015 00:42:30 +0200 Subject: [PATCH] Add MD5 to core, Fix OTA examples and Digest Authentication to OTA and espota.py --- cores/esp8266/MD5Builder.cpp | 43 ++++ cores/esp8266/MD5Builder.h | 47 ++++ cores/esp8266/Updater.cpp | 29 ++- cores/esp8266/Updater.h | 22 +- cores/esp8266/md5.h | 44 ++++ libraries/ArduinoOTA/ArduinoOTA.cpp | 242 +++++++++++++----- libraries/ArduinoOTA/ArduinoOTA.h | 59 +++-- .../ArduinoOTA/examples/BasicOTA/BasicOTA.ino | 42 +-- .../ArduinoOTA/examples/OTALeds/OTALeds.ino | 25 +- .../DNS_SD_Arduino_OTA/DNS_SD_Arduino_OTA.ino | 107 -------- .../OTA-mDNS-SPIFFS/OTA-mDNS-SPIFFS.ino | 9 +- platform.txt | 2 +- tools/espota.py | 60 ++++- 13 files changed, 501 insertions(+), 230 deletions(-) create mode 100644 cores/esp8266/MD5Builder.cpp create mode 100644 cores/esp8266/MD5Builder.h create mode 100644 cores/esp8266/md5.h delete mode 100644 libraries/ESP8266mDNS/examples/DNS_SD_Arduino_OTA/DNS_SD_Arduino_OTA.ino diff --git a/cores/esp8266/MD5Builder.cpp b/cores/esp8266/MD5Builder.cpp new file mode 100644 index 0000000000..0957785ce6 --- /dev/null +++ b/cores/esp8266/MD5Builder.cpp @@ -0,0 +1,43 @@ +#include "Arduino.h" +#include "md5.h" +#include "MD5Builder.h" + +#define hex_char_to_byte(c) (((c)>='a'&&(c)<='f')?((c)-87):((c)>='A'&&(c)<='F')?((c)-55):((c)>='0'&&(c)<='9')?((c)-48):0) + +void MD5Builder::begin(void){ + memset(_buf, 0x00, 16); + MD5Init(&_ctx); +} + +void MD5Builder::add(uint8_t * data, uint16_t len){ + MD5Update(&_ctx, data, len); +} + +void MD5Builder::addHexString(const char * data){ + uint16_t i, len = strlen(data); + uint8_t * tmp = (uint8_t*)malloc(len/2); + if(tmp == NULL) + return; + for(i=0; i #include #include "ArduinoOTA.h" +#include "MD5Builder.h" -ArduinoOTA::ArduinoOTA(const char *mdns_host_prefix, int port, bool serial_debug) +//#define OTA_DEBUG 1 + +ArduinoOTAClass::ArduinoOTAClass() { - _port = port; - _mdns_host = new String(mdns_host_prefix); - *_mdns_host += String(ESP.getChipId(), HEX); _udp_ota = new WiFiUDP(); - _serial_debug = serial_debug; - + _password = 0; + _hostname = 0; + _port = 0; + _nonce = 0; + _state = OTA_IDLE; + + _size = 0; + _cmd = 0; + _ota_port = 0; + _ota_ip = (uint32_t)0; + _md5 = new char[33]; + _start_callback = NULL; _end_callback = NULL; _progress_callback = NULL; _error_callback = NULL; } -void ArduinoOTA::onStart(OTA_CALLBACK(fn)){ +void ArduinoOTAClass::onStart(OTA_CALLBACK(fn)){ _start_callback = fn; } -void ArduinoOTA::onEnd(OTA_CALLBACK(fn)){ +void ArduinoOTAClass::onEnd(OTA_CALLBACK(fn)){ _end_callback = fn; } -void ArduinoOTA::onProgress(OTA_CALLBACK_PROGRESS(fn)){ +void ArduinoOTAClass::onProgress(OTA_CALLBACK_PROGRESS(fn)){ _progress_callback = fn; } -void ArduinoOTA::onError(OTA_CALLBACK(fn)){ +void ArduinoOTAClass::onError(OTA_CALLBACK_ERROR(fn)){ _error_callback = fn; } -ArduinoOTA::~ArduinoOTA(){ +ArduinoOTAClass::~ArduinoOTAClass(){ delete _udp_ota; - delete _mdns_host; } -void ArduinoOTA::setup() { - _udp_ota->begin(_port); - if (_mdns_host) { - if (_serial_debug) - Serial.printf("OTA server at: %s:%u\n", - _mdns_host->c_str(), - _port); - MDNS.begin(_mdns_host->c_str()); - MDNS.addService("arduino", "tcp", _port); +void ArduinoOTAClass::setPort(uint16_t port){ + if(!_initialized && !_port && port){ + _port = port; } } -void ArduinoOTA::handle() { - - if (!*_udp_ota) { - _udp_ota->begin(_port); - if (_serial_debug) { - Serial.println("OTA restarted"); - } +void ArduinoOTAClass::setHostname(const char * hostname){ + if(!_initialized && !_hostname && hostname){ + _hostname = new char[strlen(hostname)]; + sprintf(_hostname, "%s", hostname); } +} - if (!_udp_ota->parsePacket()) return; - - IPAddress remote = _udp_ota->remoteIP(); - int cmd = _udp_ota->parseInt(); - int port = _udp_ota->parseInt(); - int size = _udp_ota->parseInt(); - - if (_serial_debug){ - Serial.print("Update Start: ip:"); - Serial.print(remote); - Serial.printf(", port:%d, size:%d\n", port, size); +void ArduinoOTAClass::setPassword(const char * password){ + if(!_initialized && !_password && password){ + _password = new char[strlen(password)]; + sprintf(_password, "%s", password); } +} - WiFiUDP::stopAll(); +void ArduinoOTAClass::begin() { + if(_initialized) + return; + _initialized = true; + if(!_hostname){ + _hostname = new char[15]; + sprintf(_hostname, "esp8266-%02x", ESP.getChipId()); + } + if(!_port) + _port = 8266; + + _udp_ota->begin(_port); + MDNS.begin(_hostname); + if(_password){ + _nonce = new char[33]; + MDNS.enableArduino(_port, true); + } else + MDNS.enableArduino(_port); + _state = OTA_IDLE; +#if OTA_DEBUG + Serial.printf("OTA server at: %s.local:%u\n", _hostname, _port); +#endif +} - if(!Update.begin(size, cmd)){ - if (_serial_debug) - Serial.println("Update Begin Error"); - if (_error_callback) _error_callback(); +void ArduinoOTAClass::_runUpdate(){ + if(!Update.begin(_size, _cmd)){ +#if OTA_DEBUG + Serial.println("Update Begin Error"); +#endif + if (_error_callback) _error_callback(OTA_BEGIN_ERROR); _udp_ota->begin(_port); + _state = OTA_IDLE; return; } + Update.setMD5(_md5); + WiFiUDP::stopAll(); + WiFiClient::stopAll(); + + if (_start_callback) _start_callback(); - if (_progress_callback) _progress_callback(0, size); + if (_progress_callback) _progress_callback(0, _size); WiFiClient client; - if (!client.connect(remote, port)) { - if (_serial_debug) - Serial.printf("Connect Failed\n"); + if (!client.connect(_ota_ip, _ota_port)) { +#if OTA_DEBUG + Serial.printf("Connect Failed\n"); +#endif _udp_ota->begin(_port); - if (_error_callback) _error_callback(); + if (_error_callback) _error_callback(OTA_CONNECT_ERROR); + _state = OTA_IDLE; } - uint32_t written; + uint32_t written, total = 0; while(!Update.isFinished() && client.connected()){ - // TODO(mangelajo): enhance the Update.write(client) to - // accept a progress callback + int waited = 1000; + while(!client.available() && waited--) + delay(1); + if(!waited){ +#if OTA_DEBUG + Serial.printf("Recieve Failed\n"); +#endif + _udp_ota->begin(_port); + if (_error_callback) _error_callback(OTA_RECIEVE_ERROR); + _state = OTA_IDLE; + } written = Update.write(client); - if(written > 0) client.print(written, DEC); - if(_progress_callback) _progress_callback(written, size); + if(written > 0){ + client.print(written, DEC); + total += written; + if(_progress_callback) _progress_callback(total, _size); + } } - Serial.setDebugOutput(false); - if(Update.end()){ - client.println("OK"); - if (_serial_debug) - Serial.printf("Update Success\nRebooting...\n"); + client.print("OK"); +#if OTA_DEBUG + Serial.printf("Update Success\nRebooting...\n"); +#endif if(_end_callback) _end_callback(); ESP.restart(); } else { - // Update failed: listen UDP again, callback and print _udp_ota->begin(_port); - if (_error_callback) _error_callback(); + if (_error_callback) _error_callback(OTA_END_ERROR); Update.printError(client); - if (_serial_debug) - Update.printError(Serial); +#if OTA_DEBUG + Update.printError(Serial); +#endif + _state = OTA_IDLE; } } + +void ArduinoOTAClass::handle() { + if (!*_udp_ota) { + _udp_ota->begin(_port); +#if OTA_DEBUG + Serial.println("OTA restarted"); +#endif + } + + if (!_udp_ota->parsePacket()) return; + + if(_state == OTA_IDLE){ + _ota_ip = _udp_ota->remoteIP(); + _cmd = _udp_ota->parseInt(); + _ota_port = _udp_ota->parseInt(); + _size = _udp_ota->parseInt(); + _udp_ota->read(); + sprintf(_md5, "%s", _udp_ota->readStringUntil('\n').c_str()); + +#if OTA_DEBUG + Serial.print("Update Start: ip:"); + Serial.print(_ota_ip); + Serial.printf(", port:%d, size:%d, md5:%s\n", _ota_port, _size, _md5); +#endif + + _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); + if(_password){ + MD5Builder nonce_md5; + nonce_md5.begin(); + nonce_md5.add(String(micros())); + nonce_md5.calculate(); + nonce_md5.getChars(_nonce); + _udp_ota->printf("AUTH %s", _nonce); + _udp_ota->endPacket(); + _state = OTA_WAITAUTH; + return; + } else { + _udp_ota->print("OK"); + _udp_ota->endPacket(); + _state = OTA_RUNUPDATE; + } + } else if(_state == OTA_WAITAUTH){ + String cnonce = _udp_ota->readStringUntil(' '); + String response = _udp_ota->readStringUntil('\n'); + + MD5Builder _passmd5; + _passmd5.begin(); + _passmd5.add(_password); + _passmd5.calculate(); + String passmd5 = _passmd5.toString(); + + String challenge = passmd5 + ":" + String(_nonce) + ":" + cnonce; + MD5Builder _challengemd5; + _challengemd5.begin(); + _challengemd5.add(challenge); + _challengemd5.calculate(); + String result = _challengemd5.toString(); + + if(result.equals(response)){ + _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); + _udp_ota->print("OK"); + _udp_ota->endPacket(); + _state = OTA_RUNUPDATE; + } else { + _udp_ota->beginPacket(_ota_ip, _udp_ota->remotePort()); + _udp_ota->print("Authentication Failed"); + _udp_ota->endPacket(); + if (_error_callback) _error_callback(OTA_AUTH_ERROR); + _state = OTA_IDLE; + } + } + + if(_state == OTA_RUNUPDATE) + _runUpdate(); +} + +ArduinoOTAClass ArduinoOTA; diff --git a/libraries/ArduinoOTA/ArduinoOTA.h b/libraries/ArduinoOTA/ArduinoOTA.h index 1413306e8c..350c129e5e 100644 --- a/libraries/ArduinoOTA/ArduinoOTA.h +++ b/libraries/ArduinoOTA/ArduinoOTA.h @@ -5,31 +5,58 @@ class WiFiUDP; #define OTA_CALLBACK(callback) void (*callback)() #define OTA_CALLBACK_PROGRESS(callback) void (*callback)(unsigned int, unsigned int) +#define OTA_CALLBACK_ERROR(callback) void (*callback)(ota_error_t) -class ArduinoOTA +typedef enum { + OTA_IDLE, + OTA_WAITAUTH, + OTA_RUNUPDATE +} ota_state_t; + +typedef enum { + OTA_AUTH_ERROR, + OTA_BEGIN_ERROR, + OTA_CONNECT_ERROR, + OTA_RECIEVE_ERROR, + OTA_END_ERROR +} ota_error_t; + +class ArduinoOTAClass { + private: int _port; - String* _mdns_host; + char *_password; + char * _hostname; + char * _nonce; WiFiUDP* _udp_ota; - bool _serial_debug; + bool _initialized; + + ota_state_t _state; + int _size, _cmd, _ota_port; + IPAddress _ota_ip; + char * _md5; OTA_CALLBACK(_start_callback); OTA_CALLBACK(_end_callback); - OTA_CALLBACK(_error_callback); - + OTA_CALLBACK_ERROR(_error_callback); OTA_CALLBACK_PROGRESS(_progress_callback); + + void _runUpdate(void); - public: - ArduinoOTA(const char *mdns_host="ESP8266-OTA-", - int port=8266, - bool serial_debug=true); - ~ArduinoOTA(); - void setup(); - void handle(); - void onStart(OTA_CALLBACK(fn)); - void onEnd(OTA_CALLBACK(fn)); - void onProgress(OTA_CALLBACK_PROGRESS(fn)); - void onError(OTA_CALLBACK (fn)); + public: + ArduinoOTAClass(); + ~ArduinoOTAClass(); + void setPort(uint16_t port); + void setHostname(const char *hostname); + void setPassword(const char *password); + void onStart(OTA_CALLBACK(fn)); + void onEnd(OTA_CALLBACK(fn)); + void onProgress(OTA_CALLBACK_PROGRESS(fn)); + void onError(OTA_CALLBACK_ERROR (fn)); + void begin(); + void handle(); }; +extern ArduinoOTAClass ArduinoOTA; + #endif /* __ARDUINO_OTA_H */ diff --git a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino index 0f8967f898..1cbb24e7bb 100644 --- a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino +++ b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino @@ -6,26 +6,36 @@ const char* ssid = "..."; const char* password = "..."; -ArduinoOTA ota_server; - void setup() { - Serial.begin(115200); - - Serial.println("Booting"); - WiFi.mode(WIFI_STA); - - /* try the flash stored password first */ - WiFi.begin(); - - while (WiFi.waitForConnectResult() != WL_CONNECTED){ - WiFi.begin(ssid, password); - Serial.println("Retrying connection..."); + Serial.begin(115200); + Serial.println("Booting"); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + while (WiFi.waitForConnectResult() != WL_CONNECTED){ + Serial.println("Connection Failed! Rebooting..."); + delay(5000); + ESP.reset(); } - ota_server.setup(); + //ArduinoOTA.setPort(8266);//Defaults to 8266 + //ArduinoOTA.setHostname((const char *)"myesp8266");//Defaults to esp8266-[ChipID] + //ArduinoOTA.setPassword((const char *)"123");//defaults to no authentication + ArduinoOTA.onStart([]() { Serial.println("Start"); }); + ArduinoOTA.onEnd([]() { Serial.println("End"); }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\n", (progress/(total/100))); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if(error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if(error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if(error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if(error == OTA_RECIEVE_ERROR) Serial.println("Recieve Failed"); + else if(error == OTA_END_ERROR) Serial.println("End Failed"); + }); + ArduinoOTA.begin(); Serial.println("Ready"); } void loop() { - ota_server.handle(); - yield(); + ArduinoOTA.handle(); } diff --git a/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino b/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino index 208e0be084..3b15fe6066 100644 --- a/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino +++ b/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino @@ -5,9 +5,7 @@ const char* ssid = "..."; const char* password = "..."; -const char* host_prefix = "OTA-LEDS-"; - -ArduinoOTA ota_server(host_prefix, 8266, /* debug_serial= */ true); +const char* host = "OTA-LEDS"; int led_pin = 13; #define N_DIMMERS 3 @@ -23,8 +21,7 @@ void setup() { Serial.println("Booting"); WiFi.mode(WIFI_STA); - /* try the flash stored password first */ - WiFi.begin(); + WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED){ WiFi.begin(ssid, password); @@ -33,10 +30,6 @@ void setup() { /* switch off led */ digitalWrite(led_pin, HIGH); - /* setup the OTA server */ - ota_server.setup(); - Serial.println("Ready"); - /* configure dimmers, and OTA server events */ analogWriteRange(1000); analogWrite(led_pin,990); @@ -47,13 +40,14 @@ void setup() { analogWrite(dimmer_pin[i],50); } - ota_server.onStart([]() { // switch off all the PWMs during upgrade + ArduinoOTA.setHostname(host); + ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade for(int i=0; i -#include - -const char* host = "esp8266-ota"; -const char* ssid = "**********"; -const char* pass = "**********"; -const uint16_t ota_port = 8266; -const char* ota_pass = "1234"; - -WiFiUDP OTA; -WiFiServer MonitorServer(ota_port); -WiFiClient Monitor; - -void setup() { - Serial.begin(115200); - Serial.println(""); - Serial.println("Bare Minimum Arduino OTA"); - - Serial.printf("Sketch size: %u\n", ESP.getSketchSize()); - Serial.printf("Free size: %u\n", ESP.getFreeSketchSpace()); - - WiFi.begin(ssid, pass); - if(WiFi.waitForConnectResult() == WL_CONNECTED){ - MDNS.begin(host); - MDNS.enableArduino(ota_port, true); - OTA.begin(ota_port); - MonitorServer.begin(); - MonitorServer.setNoDelay(true); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); - } else { - Serial.println("WiFi Connect Failed"); - delay(10000); - ESP.reset(); - } -} - -void loop() { - if (OTA.parsePacket()) { - IPAddress remote = OTA.remoteIP(); - String pass = OTA.readStringUntil(' '); - int cmd = OTA.parseInt(); - int port = OTA.parseInt(); - int size = OTA.parseInt(); - - if(!pass.equals(String(ota_pass))){ - Serial.println("ERROR: Wrong Password"); - return; - } - - Serial.print("Update Start: ip:"); - Serial.print(remote); - Serial.printf(", port:%d, size:%d\n", port, size); - uint32_t startTime = millis(); - - if(!Update.begin(size)){ - Update.printError(Serial); - return; - } - - WiFiUDP::stopAll(); - WiFiClient::stopAll(); - - WiFiClient client; - if (client.connect(remote, port)) { - uint32_t written; - while(!Update.isFinished()){ - written = Update.write(client); - if(written > 0) client.print(written, DEC); - } - if(Update.end()){ - client.println("OK"); - Serial.printf("Update Success: %u\nRebooting...\n", millis() - startTime); - ESP.restart(); - } else { - Update.printError(client); - Update.printError(Serial); - } - } else { - Serial.printf("Connect Failed: %u\n", millis() - startTime); - } - } - //IDE Monitor (connected to Serial) - if (MonitorServer.hasClient()){ - if (!Monitor || !Monitor.connected()){ - if(Monitor) Monitor.stop(); - Monitor = MonitorServer.available(); - } else { - MonitorServer.available().stop(); - } - } - if (Monitor && Monitor.connected() && Monitor.available()){ - while(Monitor.available()) - Serial.write(Monitor.read()); - } - if(Serial.available()){ - size_t len = Serial.available(); - uint8_t * sbuf = (uint8_t *)malloc(len); - Serial.readBytes(sbuf, len); - if (Monitor && Monitor.connected()){ - Monitor.write((uint8_t *)sbuf, len); - delay(0); - } - free(sbuf); - } - delay(0); -} diff --git a/libraries/ESP8266mDNS/examples/OTA-mDNS-SPIFFS/OTA-mDNS-SPIFFS.ino b/libraries/ESP8266mDNS/examples/OTA-mDNS-SPIFFS/OTA-mDNS-SPIFFS.ino index 896c692050..618dff351f 100644 --- a/libraries/ESP8266mDNS/examples/OTA-mDNS-SPIFFS/OTA-mDNS-SPIFFS.ino +++ b/libraries/ESP8266mDNS/examples/OTA-mDNS-SPIFFS/OTA-mDNS-SPIFFS.ino @@ -38,10 +38,6 @@ const char* ap_default_psk = "esp8266esp8266"; ///< Default PSK. /// Uncomment the next line for verbose output over UART. //#define SERIAL_VERBOSE -/// OTA server handle. -ArduinoOTA ota_server; - - /** * @brief Read WiFi connection information from file system. * @param ssid String pointer for storing SSID. @@ -244,7 +240,8 @@ void setup() } // Start OTA server. - ota_server.setup(); + ArduinoOTA.setHostname((const char *)hostname.c_str()); + ArduinoOTA.begin(); } @@ -254,7 +251,7 @@ void setup() void loop() { // Handle OTA server. - ota_server.handle(); + ArduinoOTA.handle(); yield(); } diff --git a/platform.txt b/platform.txt index ca99e858c6..254bacd326 100644 --- a/platform.txt +++ b/platform.txt @@ -64,7 +64,7 @@ recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.cpreprocessor.flags} {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" ## Create archives -recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}" +recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" {compiler.c.elf.libs} -Wl,--end-group "-L{build.path}" diff --git a/tools/espota.py b/tools/espota.py index cacbc12d54..a07c8d61c1 100755 --- a/tools/espota.py +++ b/tools/espota.py @@ -4,11 +4,12 @@ # https://gist.github.com/igrr/d35ab8446922179dc58c # # Modified since 2015-09-18 from Pascal Gollor (https://github.com/pgollor) +# Modified since 2015-11-09 from Hristo Gochkov (https://github.com/me-no-dev) # # This script will push an OTA update to the ESP -# use it like: python espota.py -i -p -f +# use it like: python espota.py -i -p [-a password] -f # Or to upload SPIFFS image: -# python espota.py -i -p -s -f +# python espota.py -i -p [-a password] -s -f # # Changes # 2015-09-18: @@ -16,6 +17,11 @@ # - Add logging. # - Send command to controller to differ between flashing and transmitting SPIFFS image. # +# Changes +# 2015-11-09: +# - Added digest authentication +# - Enchanced error tracking and reporting +# from __future__ import print_function import socket @@ -23,6 +29,7 @@ import os import optparse import logging +import hashlib # Commands FLASH = 0 @@ -43,14 +50,55 @@ def serve(remoteAddr, remotePort, password, filename, command = FLASH): return 1 content_size = os.path.getsize(filename) + f = open(filename,'rb') + file_md5 = hashlib.md5(f.read()).hexdigest() + f.close() logging.info('Upload size: %d', content_size) - message = '%s %d %d %d\n' % (password, command, serverPort, content_size) + message = '%d %d %d %s\n' % (command, serverPort, content_size, file_md5) # Wait for a connection logging.info('Sending invitation to: %s', remoteAddr) sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) remote_address = (remoteAddr, int(remotePort)) sent = sock2.sendto(message, remote_address) + sock2.settimeout(10) + try: + data = sock2.recv(37) + except: + logging.error('No Answer') + sock2.close() + return 1 + if (data != "OK"): + if(data.startswith('AUTH')): + nonce = data.split()[1] + cnonce_text = '%s%u%s%s' % (filename, content_size, file_md5, remoteAddr) + cnonce = hashlib.md5(cnonce_text).hexdigest() + passmd5 = hashlib.md5(password).hexdigest() + result_text = '%s:%s:%s' % (passmd5 ,nonce, cnonce) + result = hashlib.md5(result_text).hexdigest() + sys.stderr.write('Authenticating...') + sys.stderr.flush() + message = '%s %s\n' % (cnonce, result) + sock2.sendto(message, remote_address) + sock2.settimeout(10) + try: + data = sock2.recv(32) + except: + sys.stderr.write('FAIL\n') + logging.error('No Answer to our Authentication') + sock2.close() + return 1 + if (data != "OK"): + sys.stderr.write('FAIL\n') + logging.error('%s', data) + sock2.close() + sys.exit(1); + return 1 + sys.stderr.write('OK\n') + else: + logging.error('Bad Answer: %s', data) + sock2.close() + return 1 sock2.close() logging.info('Waiting for device...') @@ -94,9 +142,13 @@ def serve(remoteAddr, remotePort, password, filename, command = FLASH): connection.close() f.close() sock.close() + if (data != "OK"): + sys.stderr.write('\n') + logging.error('%s', data) + return 1; return 0 except: - logging.error('Result: No Answer!') + logging.error('No Result!') connection.close() f.close() sock.close()