From a7aedc55998dedba5b1fa00eba229aea268dbc0b Mon Sep 17 00:00:00 2001 From: Luc Date: Mon, 26 Sep 2016 21:31:01 +0800 Subject: [PATCH] Rewrite ESP commands add password protection if authentication is set --- README.md | 79 +++++++++-- docs/Commands.txt | 66 +++++++++ esp3d/command.cpp | 352 ++++++++++++++++++++++++++++++++++------------ esp3d/command.h | 2 + esp3d/config.h | 8 +- 5 files changed, 400 insertions(+), 107 deletions(-) create mode 100644 docs/Commands.txt diff --git a/README.md b/README.md index 7f2dd582..9cc338d9 100644 --- a/README.md +++ b/README.md @@ -103,19 +103,72 @@ Additionally 404.tpl (the page not found) and restart.tpl(restart page when appl ##Direct commands: ``` - -Restart module from host/printer: [ESP888]RESTART - -Send file line by line from SPIFFS: [ESP700] - -Get IP (only printer see answer): [ESP111]M117 - -Reset EEPROM and restart: [ESP444]RESET - -Reset user password: [ESP555] - -Display EEPROM content: [ESP444]CONFIG - -Go to safe mode without restart: [ESP444]SAFEMODE - -SSID: [ESP100] - -Password: [ESP101] - -Station mode: [ESP103]STA - -AP mode: [ESP103]AP - -IP Static: [ESP104]STATIC - -IP DHCP: [ESP104]DHCP +* Change STA SSID +[ESP100] +if authentication is on, need admin password +[ESP100]pwd= + +* Change STA Password +[ESP101] +if authentication is on, need admin password +[ESP101]pwd= + +* Change Hostname +[ESP102] +if authentication is on, need admin password +[ESP102]pwd= + +* Change Wifi mode (STA/AP) +[ESP103] +if authentication is on, need admin password +[ESP103]pwd= + +* Change STA IP mode (DHCP/STATIC) +[ESP104] +if authentication is on, need admin password +[ESP104]pwd= + +* Change AP SSID +[ESP105] +if authentication is on, need admin password +[ESP105]pwd= + +* Change AP Password +[ESP106] +if authentication is on, need admin password +[ESP106]pwd= + +* Change AP IP mode (DHCP/STATIC) +[ESP107] +if authentication is on, need admin password +[ESP107]pwd= + +* Get current IP +[ESP111]
+ +* Get hostname +[ESP112]
+ +* Get/Set ESP mode +cmd can be RESET, SAFEMODE, CONFIG, RESTART +[ESP444] +if authentication is on, need admin password for RESET, RESTART and SAFEMODE +[ESP444]pwd= + +* Change / Reset user password +[ESP555]pwd= +if no password set it use default one + +* Read SPIFFS file and send each line to serial +[ESP700] + +* Get fw version +[ESP800]
+ +* Clear status/error/info list +cmd can be ALL, ERROR, INFO, STATUS +[ESP999] + ``` ##Installation * For stable: diff --git a/docs/Commands.txt b/docs/Commands.txt new file mode 100644 index 00000000..ae414448 --- /dev/null +++ b/docs/Commands.txt @@ -0,0 +1,66 @@ +* Change STA SSID +[ESP100] +if authentication is on, need admin password +[ESP100]pwd= + +* Change STA Password +[ESP101] +if authentication is on, need admin password +[ESP101]pwd= + +* Change Hostname +[ESP102] +if authentication is on, need admin password +[ESP102]pwd= + +* Change Wifi mode (STA/AP) +[ESP103] +if authentication is on, need admin password +[ESP103]pwd= + +* Change STA IP mode (DHCP/STATIC) +[ESP104] +if authentication is on, need admin password +[ESP104]pwd= + +* Change AP SSID +[ESP105] +if authentication is on, need admin password +[ESP105]pwd= + +* Change AP Password +[ESP106] +if authentication is on, need admin password +[ESP106]pwd= + +* Change AP IP mode (DHCP/STATIC) +[ESP107] +if authentication is on, need admin password +[ESP107]pwd= + +* Get current IP +[ESP111]
+ +* Get hostname +[ESP112]
+ +* Get/Set ESP mode +cmd can be RESET, SAFEMODE, CONFIG, RESTART +[ESP444] +if authentication is on, need admin password for RESET, RESTART and SAFEMODE +[ESP444]pwd= + +* Change / Reset user password +[ESP555]pwd= +if no password set it use default one + +* Read SPIFFS file and send each line to serial +[ESP700] + +* Get fw version +[ESP800]
+ +* Clear status/error/info list +cmd can be ALL, ERROR, INFO, STATUS +[ESP999] + diff --git a/esp3d/command.cpp b/esp3d/command.cpp index 7bb47a12..9aad662b 100644 --- a/esp3d/command.cpp +++ b/esp3d/command.cpp @@ -32,93 +32,221 @@ String COMMAND::buffer_serial; String COMMAND::buffer_tcp; +#define ERROR_CMD_MSG F("\nM117 Cmd Error") +#define INCORRECT_CMD_MSG F("\nM117 Incorrect Cmd") +#define OK_CMD_MSG F("\nM117 Cmd Ok") +String COMMAND::get_param(String & cmd_params, const char * id, bool withspace) +{ + static String parameter; + String sid=id; + int start; + int end = -1; + parameter = ""; + //if no id it means it is first part of cmd + if (strlen(id) == 0) start = 0; + //else find id position + else start = cmd_params.indexOf(id); + //if no id found and not first part leave + if (start == -1 ) return parameter; + //password and SSID can have space so handle it + //if no space expected use space as delimiter + if (!withspace)end = cmd_params.indexOf(" ",start); + //if space expected only one parameter but additional password may be present + else if (sid!="pwd=")end = cmd_params.indexOf("pwd=",start); + //if no end found - take all + if (end == -1) end = cmd_params.length(); + //extract parameter + parameter = cmd_params.substring(start+strlen(id),end); + //be sure no extra space + parameter.trim(); + return parameter; +} +#ifdef AUTHENTICATION_FEATURE +bool COMMAND::isadmin(String & cmd_params) +{ + String adminpassword; + String sadminPassword; + if (!CONFIG::read_string(EP_ADMIN_PWD, sadminPassword , MAX_LOCAL_PASSWORD_LENGTH)) { + LOG("ERROR getting admin\n") + sadminPassword=FPSTR(DEFAULT_ADMIN_PWD); + } + adminpassword = get_param(cmd_params,"pwd=", true); + if (!sadminPassword.equals(adminpassword)) { + LOG("Not allowed \n") + return false; + } + else return true; +} +#endif void COMMAND::execute_command(int cmd,String cmd_params) { //manage parameters - + byte mode = 254; + String parameter; switch(cmd) { - byte mode; - case 800: - Serial.print(cmd_params); - Serial.print("\nFW version:"); - Serial.println(FW_VERSION); - break; + //STA SSID + //[ESP100][pwd=] case 100: - if (!CONFIG::isSSIDValid(cmd_params.c_str()))Serial.println("\nError"); - if(!CONFIG::write_string(EP_STA_SSID,cmd_params.c_str())) { - Serial.println("\nError"); + parameter = get_param(cmd_params,"", true); + if (!CONFIG::isSSIDValid(parameter.c_str()))Serial.println(INCORRECT_CMD_MSG); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_string(EP_STA_SSID,parameter.c_str())) { + Serial.println(ERROR_CMD_MSG); } else { - Serial.println("\nOk"); + Serial.println(OK_CMD_MSG); } break; + //STA Password + //[ESP101][pwd=] case 101: - if(!CONFIG::write_string(EP_STA_PASSWORD,cmd_params.c_str())) { - Serial.println("\nError"); + parameter = get_param(cmd_params,"", true); + if (!CONFIG::isPasswordValid(parameter.c_str()))Serial.println(INCORRECT_CMD_MSG); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_string(EP_STA_PASSWORD,parameter.c_str())) { + Serial.println(ERROR_CMD_MSG); } else { - Serial.println("\nOk"); + Serial.println(OK_CMD_MSG); } break; + //Hostname + //[ESP102][pwd=] case 102: - if (!CONFIG::isHostnameValid(cmd_params.c_str()))Serial.println("\nError"); - if(!CONFIG::write_string(EP_HOSTNAME,cmd_params.c_str())) { - Serial.println("\nError"); + parameter = get_param(cmd_params,"", true); + if (!CONFIG::isHostnameValid(parameter.c_str()))Serial.println(INCORRECT_CMD_MSG); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_string(EP_HOSTNAME,parameter.c_str())) { + Serial.println(ERROR_CMD_MSG); } else { - Serial.println("\nOk"); + Serial.println(OK_CMD_MSG); } break; + //Wifi mode (STA/AP) + //[ESP103][pwd=] case 103: - - if (cmd_params=="STA") { + parameter = get_param(cmd_params,"", true); + if (parameter == "STA") { mode = CLIENT_MODE; + } else if (parameter == "AP") { + mode = AP_MODE; } else { - mode=AP_MODE; + Serial.println(INCORRECT_CMD_MSG); } - if(!CONFIG::write_byte(EP_WIFI_MODE,mode)) { - Serial.println("\nError"); - } else { - Serial.println("\nOk"); + if ((mode == CLIENT_MODE) || (mode == AP_MODE)){ +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_byte(EP_WIFI_MODE,mode)) { + Serial.println(ERROR_CMD_MSG); + } else { + Serial.println(OK_CMD_MSG); + } } break; + //STA IP mode (DHCP/STATIC) + //[ESP104][pwd=] case 104: - if (cmd_params=="STATIC") { + parameter = get_param(cmd_params,"", true); + if (parameter == "STATIC") { mode = STATIC_IP_MODE; - } else { - mode=DHCP_MODE; + } else if (parameter == "DHCP") { + mode = DHCP_MODE; + } else{ + Serial.println(INCORRECT_CMD_MSG); } - if(!CONFIG::write_byte(EP_STA_IP_MODE,mode)) { - Serial.println("\nError"); - } else { - Serial.println("\nOk"); + if ((mode == STATIC_IP_MODE) || (mode == DHCP_MODE)){ +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_byte(EP_STA_IP_MODE,mode)) { + Serial.println(ERROR_CMD_MSG); + } else { + Serial.println(OK_CMD_MSG); + } } break; + //AP SSID + //[ESP105][pwd=] case 105: - if (!CONFIG::isSSIDValid(cmd_params.c_str()))Serial.println("\nError"); - if(!CONFIG::write_string(EP_AP_SSID,cmd_params.c_str())) { - Serial.println("\nError"); + parameter = get_param(cmd_params,"", true); + if (!CONFIG::isSSIDValid(parameter.c_str()))Serial.println(INCORRECT_CMD_MSG); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_string(EP_AP_SSID,parameter.c_str())) { + Serial.println(ERROR_CMD_MSG); } else { - Serial.println("\nOk"); + Serial.println(OK_CMD_MSG); } break; + //AP Password + //[ESP106][pwd=] case 106: - if(!CONFIG::write_string(EP_AP_PASSWORD,cmd_params.c_str())) { - Serial.println("\nError"); + parameter = get_param(cmd_params,"", true); + if (!CONFIG::isPasswordValid(parameter.c_str()))Serial.println(INCORRECT_CMD_MSG); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_string(EP_AP_PASSWORD,parameter.c_str())) { + Serial.println(ERROR_CMD_MSG); } else { - Serial.println("\nOk"); + Serial.println(OK_CMD_MSG); } break; + //AP IP mode (DHCP/STATIC) + //[ESP107][pwd=] case 107: - if (cmd_params=="STATIC") { + parameter = get_param(cmd_params,"", true); + if (parameter == "STATIC") { mode = STATIC_IP_MODE; - } else { - mode=DHCP_MODE; + } else if (parameter == "DHCP") { + mode = DHCP_MODE; + } else{ + Serial.println(INCORRECT_CMD_MSG); } - if(!CONFIG::write_byte(EP_AP_IP_MODE,mode)) { - Serial.println("\nError"); - } else { - Serial.println("\nOk"); + if ((mode == STATIC_IP_MODE) || (mode == DHCP_MODE)){ +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + if(!CONFIG::write_byte(EP_AP_IP_MODE,mode)) { + Serial.println(ERROR_CMD_MSG); + } else { + Serial.println(OK_CMD_MSG); + } } break; + //Get current IP + //[ESP111]
case 111: { String currentIP ; if (WiFi.getMode()==WIFI_STA) { @@ -132,6 +260,8 @@ void COMMAND::execute_command(int cmd,String cmd_params) Serial.print("\r\n"); } break; + //Get hostname + //[ESP112]
case 112: { String shost ; if (!CONFIG::read_string(EP_HOSTNAME, shost , MAX_HOSTNAME_LENGTH)) { @@ -143,36 +273,63 @@ void COMMAND::execute_command(int cmd,String cmd_params) Serial.print("\r\n"); } break; + //Get/Set ESP mode + //cmd is RESET, SAFEMODE, CONFIG, RESTART + //[ESP444]pwd= case 444: - if (cmd_params=="RESET") { - CONFIG::reset_config(); - } - if (cmd_params=="SAFEMODE") { - wifi_config.Safe_Setup(); - } - if (cmd_params=="CONFIG") { + parameter = get_param(cmd_params,"", true); +#ifdef AUTHENTICATION_FEATURE + if (!isadmin(cmd_params)) { + Serial.println(INCORRECT_CMD_MSG); + } + else +#endif + { + if (parameter=="RESET") { + CONFIG::reset_config(); + } + if (parameter=="SAFEMODE") { + wifi_config.Safe_Setup(); + } + if (parameter=="RESTART") { + CONFIG::esp_restart(); + } + } + if (parameter=="CONFIG") { CONFIG::print_config(); } break; #ifdef AUTHENTICATION_FEATURE + //Change / Reset user password + //[ESP555]pwd= case 555: { - String sadminPassword; - if (!CONFIG::read_string(EP_ADMIN_PWD, sadminPassword , MAX_LOCAL_PASSWORD_LENGTH)) { - sadminPassword=FPSTR(DEFAULT_ADMIN_PWD); - } - if (cmd_params == sadminPassword.c_str()) { - if(CONFIG::write_string(EP_USER_PWD,FPSTR(DEFAULT_USER_PWD))) { - Serial.println("\nOk"); - } - else { - Serial.println("\nFailed"); + if (isadmin(cmd_params)) { + parameter = get_param(cmd_params,"", true); + if (parameter.length() == 0){ + if(CONFIG::write_string(EP_USER_PWD,FPSTR(DEFAULT_USER_PWD))) { + Serial.println(OK_CMD_MSG); + } + else { + Serial.println(ERROR_CMD_MSG); + } + } else { + if (CONFIG::isLocalPasswordValid(parameter.c_str())){ + if(CONFIG::write_string(EP_USER_PWD,parameter.c_str())) { + Serial.println(OK_CMD_MSG); + } + else { + Serial.println(ERROR_CMD_MSG); + } + } + else Serial.println(INCORRECT_CMD_MSG); } } - else Serial.println("\nFailed"); + else Serial.println(INCORRECT_CMD_MSG); break; } #endif + //[ESP700] case 700: //read local file {//be sure serial is locked if ((web_interface->blockserial)) break; @@ -195,19 +352,21 @@ void COMMAND::execute_command(int cmd,String cmd_params) //read next line if any currentline = currentfile.readString(); } - currentfile.close() -; } + currentfile.close(); + } break; } - case 888: - if (cmd_params=="RESTART") { - Serial.print("\r"); - Serial.print(cmd_params); - web_interface->restartmodule=true; - Serial.print("\r\n"); - } + //get fw version + //[ESP800]
+ case 800: + Serial.print(cmd_params); + Serial.print("\nFW version:"); + Serial.println(FW_VERSION); break; + //clear status/error/info list + //[ESP999] case 999: + cmd_params.trim(); #ifdef ERROR_MSG_FEATURE if (cmd_params=="ERROR") { web_interface->error_msg.clear(); @@ -249,11 +408,11 @@ void COMMAND::check_command(String buffer) static uint32_t start_list=0; //if SD list is not on going if (!bfileslist) { - //check if command is a start of SD File list + //check if command is a start of SD File list int filesstart = buffer.indexOf("Begin file list"); //yes it is file list starting to be displayed if (filesstart>-1) { - //init time out + //init time out start_list = millis(); //set file list started bfileslist=true; @@ -290,7 +449,7 @@ void COMMAND::check_command(String buffer) #endif #else #ifdef SPEED_MONITORING_FEATURE - int Speedpos = buffer.indexOf("SpeedMultiply:"); + int Speedpos = buffer.indexOf("SpeedMultiply:"); #endif #ifdef FLOW_MONITORING_FEATURE int Flowpos = buffer.indexOf("FlowMultiply:"); @@ -350,26 +509,26 @@ void COMMAND::check_command(String buffer) #ifdef SPEED_MONITORING_FEATURE //Speed if (Speedpos>-1) { - //get just the value + //get just the value #if FIRMWARE_TARGET == SMOOTHIEWARE - buffer2 =buffer.substring(Speedpos+16); - int p2 = buffer2.indexOf("."); + buffer2 =buffer.substring(Speedpos+16); + int p2 = buffer2.indexOf("."); web_interface->answer4M220=buffer2.substring(0,p2); #else - web_interface->answer4M220=buffer.substring(Speedpos+14); + web_interface->answer4M220=buffer.substring(Speedpos+14); #endif } #endif #ifdef FLOW_MONITORING_FEATURE //Flow if (Flowpos>-1) { - //get just the value + //get just the value #if FIRMWARE_TARGET == SMOOTHIEWARE - buffer2 =buffer.substring(Flowpos+13); - int p2 = buffer2.indexOf("."); + buffer2 =buffer.substring(Flowpos+13); + int p2 = buffer2.indexOf("."); web_interface->answer4M221=buffer2.substring(0,p2); #else - web_interface->answer4M221=buffer.substring(Flowpos+13); + web_interface->answer4M221=buffer.substring(Flowpos+13); #endif } #endif @@ -391,19 +550,19 @@ void COMMAND::check_command(String buffer) #if FIRMWARE_TARGET == SMOOTHIEWARE (web_interface->status_msg).add(buffer.substring(Statuspos+8).c_str()); #else - (web_interface->status_msg).add(buffer.substring(Statuspos+7).c_str()); + (web_interface->status_msg).add(buffer.substring(Statuspos+7).c_str()); #endif } #endif #ifndef DIRECT_SDCARD_FEATURE } else { //listing file is on going - //check if we are too long + //check if we are too long if ((millis()-start_list)>30000) { //timeout in case of problem bfileslist=false; (web_interface->blockserial) = false; //release serial LOG("Time out\n"); } else { - //check if this is the end + //check if this is the end if (buffer.indexOf("End file list")>-1) { bfileslist=false; (web_interface->blockserial) = false; @@ -415,7 +574,7 @@ void COMMAND::check_command(String buffer) LOG(String(web_interface->fileslist.size())); LOG(":"); LOG(buffer); - LOG('\n'); + LOG('\n'); } } } @@ -435,19 +594,26 @@ void COMMAND::read_buffer_serial(uint8_t *b, size_t len) void COMMAND::read_buffer_tcp(uint8_t b) { static bool previous_was_char=false; + static bool iscomment=false; //to ensure it is continuous string, no char separated by binaries if (!previous_was_char) { buffer_tcp=""; + iscomment = false; } +//is comment ? +if (char(b) == ';') iscomment = true; //it is a char so add it to buffer if (isPrintable(b)) { previous_was_char=true; - buffer_tcp+=char(b); + //add char if not a comment + if (!iscomment)buffer_tcp+=char(b); } else { previous_was_char=false; //next call will reset the buffer } //this is not printable but end of command check if need to handle it if (b==13 ||b==10) { + //reset comment flag + iscomment = false; //Minimum is something like M10 so 3 char if (buffer_tcp.length()>3) { check_command(buffer_tcp); @@ -459,19 +625,25 @@ void COMMAND::read_buffer_tcp(uint8_t b) void COMMAND::read_buffer_serial(uint8_t b) { static bool previous_was_char=false; + static bool iscomment=false; //to ensure it is continuous string, no char separated by binaries if (!previous_was_char) { buffer_serial=""; + iscomment = false; } +//is comment ? +if (char(b) == ';') iscomment = true; //it is a char so add it to buffer if (isPrintable(b)) { previous_was_char=true; - buffer_serial+=char(b); + if (!iscomment)buffer_serial+=char(b); } else { previous_was_char=false; //next call will reset the buffer } //this is not printable but end of command check if need to handle it if (b==13) { + //reset comment flag + iscomment = false; //Minimum is something like M10 so 3 char if (buffer_serial.length()>3) { check_command(buffer_serial); diff --git a/esp3d/command.h b/esp3d/command.h index 1c393398..6d27ca20 100644 --- a/esp3d/command.h +++ b/esp3d/command.h @@ -32,6 +32,8 @@ public: static void read_buffer_tcp(uint8_t b); static void check_command(String buffer); static void execute_command(int cmd,String cmd_params); + static String get_param(String & cmd_params, const char * id, bool withspace = false); + static bool isadmin(String & cmd_params); }; diff --git a/esp3d/config.h b/esp3d/config.h index 0b4cd890..71e06e45 100644 --- a/esp3d/config.h +++ b/esp3d/config.h @@ -40,13 +40,13 @@ #define SSDP_FEATURE //NETBIOS_FEATURE: this feature is a discovery protocol, supported on Windows out of the box -#define NETBIOS_FEATURE +//#define NETBIOS_FEATURE //CAPTIVE_PORTAL_FEATURE: In SoftAP redirect all unknow call to main page #define CAPTIVE_PORTAL_FEATURE //AUTHENTICATION_FEATURE: protect pages by login password -//#define AUTHENTICATION_FEATURE +#define AUTHENTICATION_FEATURE //WEB_UPDATE_FEATURE: allow to flash fw using web UI #define WEB_UPDATE_FEATURE @@ -85,10 +85,10 @@ //DEBUG Flag do not do this when connected to printer !!! -//#define DEBUG_ESP3D +#define DEBUG_ESP3D //#define DEBUG_OUTPUT_SPIFFS //#define DEBUG_OUTPUT_SD -//#define DEBUG_OUTPUT_SERIAL +#define DEBUG_OUTPUT_SERIAL #include