diff --git a/lib/HanConfigAp/src/HanConfigAp.cpp b/lib/HanConfigAp/src/HanConfigAp.cpp index 43933e0a..1c901e49 100644 --- a/lib/HanConfigAp/src/HanConfigAp.cpp +++ b/lib/HanConfigAp/src/HanConfigAp.cpp @@ -2,6 +2,8 @@ #include "config_html.h" #include "style_css.h" +#include "Base64.h" + #if defined(ESP8266) ESP8266WebServer HanConfigAp::server(80); #elif defined(ESP32) // ARDUINO_ARCH_ESP32 @@ -102,50 +104,81 @@ bool HanConfigAp::loop() { void HanConfigAp::handleRoot() { println("Serving / over http..."); - server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - String html = CONFIG_HTML; - configuration *config = new configuration(); config->load(); + String html = CONFIG_HTML; + if(config->hasConfig()) { - html.replace("${config.ssid}", config->ssid); - html.replace("${config.ssidPassword}", config->ssidPassword); - switch (config->meterType) { - case 1: - html.replace("${config.meterType0}", ""); - html.replace("${config.meterType1}", "selected"); - html.replace("${config.meterType2}", ""); - html.replace("${config.meterType3}", ""); - break; - case 2: - html.replace("${config.meterType0}", ""); - html.replace("${config.meterType1}", ""); - html.replace("${config.meterType2}", "selected"); - html.replace("${config.meterType3}", ""); - break; - case 3: - html.replace("${config.meterType0}", ""); - html.replace("${config.meterType1}", ""); - html.replace("${config.meterType2}", ""); - html.replace("${config.meterType3}", "selected"); - break; - default: - html.replace("${config.meterType0}", "selected"); - html.replace("${config.meterType1}", ""); - html.replace("${config.meterType2}", ""); - html.replace("${config.meterType3}", ""); + bool access = !config->isAuth(); + if(config->isAuth() && server.hasHeader("Authorization")) { + String expectedAuth = String(config->authUser) + ":" + String(config->authPass); + + String providedPwd = server.header("Authorization"); + providedPwd.replace("Basic ", ""); + char inputString[providedPwd.length()]; + providedPwd.toCharArray(inputString, providedPwd.length()+1); + + int inputStringLength = sizeof(inputString); + int decodedLength = Base64.decodedLength(inputString, inputStringLength); + char decodedString[decodedLength]; + Base64.decode(decodedString, inputString, inputStringLength); + print("Received auth: "); + println(decodedString); + access = String(decodedString).equals(expectedAuth); } - html.replace("${config.mqtt}", config->mqtt); - html.replace("${config.mqttPort}", String(config->mqttPort)); - html.replace("${config.mqttClientID}", config->mqttClientID); - html.replace("${config.mqttPublishTopic}", config->mqttPublishTopic); - html.replace("${config.mqttSubscribeTopic}", config->mqttSubscribeTopic); - html.replace("${config.mqttUser}", config->mqttUser); - html.replace("${config.mqttPass}", config->mqttPass); + + if(!access) { + server.sendHeader("WWW-Authenticate", "Basic realm=\"Secure Area\""); + server.send(401, "text/html", ""); + } else { + server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + server.sendHeader("Pragma", "no-cache"); + server.sendHeader("Expires", "-1"); + + html.replace("${config.ssid}", config->ssid); + html.replace("${config.ssidPassword}", config->ssidPassword); + switch (config->meterType) { + case 1: + html.replace("${config.meterType0}", ""); + html.replace("${config.meterType1}", "selected"); + html.replace("${config.meterType2}", ""); + html.replace("${config.meterType3}", ""); + break; + case 2: + html.replace("${config.meterType0}", ""); + html.replace("${config.meterType1}", ""); + html.replace("${config.meterType2}", "selected"); + html.replace("${config.meterType3}", ""); + break; + case 3: + html.replace("${config.meterType0}", ""); + html.replace("${config.meterType1}", ""); + html.replace("${config.meterType2}", ""); + html.replace("${config.meterType3}", "selected"); + break; + default: + html.replace("${config.meterType0}", "selected"); + html.replace("${config.meterType1}", ""); + html.replace("${config.meterType2}", ""); + html.replace("${config.meterType3}", ""); + } + html.replace("${config.mqtt}", config->mqtt); + html.replace("${config.mqttPort}", String(config->mqttPort)); + html.replace("${config.mqttClientID}", config->mqttClientID); + html.replace("${config.mqttPublishTopic}", config->mqttPublishTopic); + html.replace("${config.mqttSubscribeTopic}", config->mqttSubscribeTopic); + html.replace("${config.mqttUser}", config->mqttUser); + html.replace("${config.mqttPass}", config->mqttPass); + html.replace("${config.authUser}", config->authUser); + html.replace("${config.authPass}", config->authPass); + } + } else { + server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + server.sendHeader("Pragma", "no-cache"); + server.sendHeader("Expires", "-1"); + html.replace("${config.ssid}", ""); html.replace("${config.ssidPassword}", ""); html.replace("${config.meterType0}", "selected"); @@ -159,6 +192,8 @@ void HanConfigAp::handleRoot() { html.replace("${config.mqttSubscribeTopic}", ""); html.replace("${config.mqttUser}", ""); html.replace("${config.mqttPass}", ""); + html.replace("${config.authUser}", ""); + html.replace("${config.authPass}", ""); } server.send(200, "text/html", html); } @@ -213,6 +248,14 @@ void HanConfigAp::handleSave() { config->mqttPass = new char[temp.length() + 1]; temp.toCharArray(config->mqttPass, temp.length() + 1, 0); + temp = server.arg("authUser"); + config->authUser = new char[temp.length() + 1]; + temp.toCharArray(config->authUser, temp.length() + 1, 0); + + temp = server.arg("authPass"); + config->authPass = new char[temp.length() + 1]; + temp.toCharArray(config->authPass, temp.length() + 1, 0); + println("Saving configuration now..."); if (HanConfigAp::debugger) config->print(HanConfigAp::debugger); diff --git a/lib/HanConfigAp/src/config_html.h b/lib/HanConfigAp/src/config_html.h index ff2ea9a7..310b0bce 100644 --- a/lib/HanConfigAp/src/config_html.h +++ b/lib/HanConfigAp/src/config_html.h @@ -65,6 +65,19 @@ const char CONFIG_HTML[] PROGMEM = R"=="==( +
+
+

Webserver

+
+
+ + +
+
+ + +
+
diff --git a/lib/HanConfigAp/src/configuration.cpp b/lib/HanConfigAp/src/configuration.cpp index 94031f07..3fd2e8ce 100644 --- a/lib/HanConfigAp/src/configuration.cpp +++ b/lib/HanConfigAp/src/configuration.cpp @@ -38,6 +38,13 @@ bool configuration::save() else address += saveBool(address, false); + + address += saveBool(address, isAuth()); + if (isAuth()) { + address += saveString(address, authUser); + address += saveString(address, authPass); + } + bool success = EEPROM.commit(); EEPROM.end(); @@ -50,8 +57,22 @@ bool configuration::load() int address = EEPROM_CONFIG_ADDRESS; bool success = false; + ssid = (char*)String("").c_str(); + ssidPassword = (char*)String("").c_str(); + meterType = (byte)0; + mqtt = (char*)String("").c_str(); + mqttClientID = (char*)String("").c_str(); + mqttPublishTopic = (char*)String("").c_str(); + mqttSubscribeTopic = (char*)String("").c_str(); + mqttUser = 0; + mqttPass = 0; + mqttPort = 1883; + authUser = 0; + authPass = 0; + EEPROM.begin(EEPROM_SIZE); - if (EEPROM.read(address) == EEPROM_CHECK_SUM) + int cs = EEPROM.read(address); + if (cs >= 71) { address++; @@ -80,18 +101,18 @@ bool configuration::load() success = true; } - else - { - ssid = (char*)String("").c_str(); - ssidPassword = (char*)String("").c_str(); - meterType = (byte)0; - mqtt = (char*)String("").c_str(); - mqttClientID = (char*)String("").c_str(); - mqttPublishTopic = (char*)String("").c_str(); - mqttSubscribeTopic = (char*)String("").c_str(); - mqttUser = 0; - mqttPass = 0; - mqttPort = 1883; + if(cs >= 72) { + bool auth = false; + address += readBool(address, &auth); + if (auth) { + address += readString(address, &authUser); + address += readString(address, &authPass); + } else { + authUser = 0; + authPass = 0; + } + + success = true; } EEPROM.end(); return success; @@ -102,6 +123,10 @@ bool configuration::isSecure() return (mqttUser != 0) && (String(mqttUser).length() > 0); } +bool configuration::isAuth() { + return (authUser != 0) && (String(authUser).length() > 0); +} + int configuration::readInt(int address, int *value) { int lower = EEPROM.read(address); @@ -147,20 +172,6 @@ int configuration::saveByte(int address, byte value) } void configuration::print(Stream* debugger) { - /* - char* ssid; - char* ssidPassword; - byte meterType; - char* mqtt; - int mqttPort; - char* mqttClientID; - char* mqttPublishTopic; - char* mqttSubscribeTopic; - bool secure; - char* mqttUser; - char* mqttPass; - */ - debugger->println("Configuration:"); debugger->println("-----------------------------------------------"); debugger->printf("ssid: %s\r\n", this->ssid); @@ -178,6 +189,13 @@ void configuration::print(Stream* debugger) debugger->printf("mqttUser: %s\r\n", this->mqttUser); debugger->printf("mqttPass: %s\r\n", this->mqttPass); } + + if (this->isAuth()) { + debugger->printf("WEB AUTH:\r\n"); + debugger->printf("authUser: %s\r\n", this->authUser); + debugger->printf("authPass: %s\r\n", this->authPass); + } + debugger->println("-----------------------------------------------"); } diff --git a/lib/HanConfigAp/src/configuration.h b/lib/HanConfigAp/src/configuration.h index 0dfc86ad..d785a094 100644 --- a/lib/HanConfigAp/src/configuration.h +++ b/lib/HanConfigAp/src/configuration.h @@ -25,8 +25,12 @@ public: char* mqttPass; byte meterType; + char* authUser; + char* authPass; + bool hasConfig(); bool isSecure(); + bool isAuth(); bool save(); bool load(); @@ -35,7 +39,7 @@ protected: private: const int EEPROM_SIZE = 512; - const byte EEPROM_CHECK_SUM = 71; // Used to check if config is stored. Change if structure changes + const byte EEPROM_CHECK_SUM = 72; // Used to check if config is stored. Change if structure changes const int EEPROM_CONFIG_ADDRESS = 0; int saveString(int pAddress, char* pString); diff --git a/platformio.ini b/platformio.ini index 091c3d93..84250766 100755 --- a/platformio.ini +++ b/platformio.ini @@ -3,7 +3,7 @@ extra_configs = platformio-user.ini [common] framework = arduino -lib_deps = HanConfigAp@1.0.0, HanReader@1.0.0, HanToJson@1.0.0, ArduinoJson@^6.0.0, MQTT@^2.4.0, DallasTemperature@^3.8.0 +lib_deps = HanConfigAp@1.0.0, HanReader@1.0.0, HanToJson@1.0.0, ArduinoJson@^6.0.0, MQTT@^2.4.0, DallasTemperature@^3.8.0, Base64@0.0.1 [env:esp12e] platform = espressif8266