SPIFFS MQTT SSL and import/export

This commit is contained in:
iranl
2025-01-02 17:00:54 +01:00
parent 102773a764
commit e29976c8ca
8 changed files with 809 additions and 321 deletions

View File

@@ -4,10 +4,10 @@
#include "Logger.h"
#include "RestartReason.h"
#include <esp_task_wdt.h>
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#include "esp_psram.h"
#include "FS.h"
#include "SPIFFS.h"
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#include "esp_psram.h"
#endif
#ifndef CONFIG_IDF_TARGET_ESP32H2
#include <esp_wifi.h>
@@ -112,20 +112,10 @@ void WebCfgServer::initialize()
});
_psychicServer->on("/style.css", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
{
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
{
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
}
return sendCss(request, resp);
});
_psychicServer->on("/favicon.ico", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp)
{
if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword))
{
return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in.");
}
return sendFavicon(request, resp);
});
@@ -1269,206 +1259,335 @@ void WebCfgServer::printInputField(PsychicStreamResponse *response,
#ifndef NUKI_HUB_UPDATER
esp_err_t WebCfgServer::sendSettings(PsychicRequest *request, PsychicResponse* resp)
{
bool redacted = false;
bool pairing = false;
if(request->hasParam("redacted"))
{
const PsychicWebParameter* p = request->getParam("redacted");
if(p->value() == "1")
{
redacted = true;
}
}
if(request->hasParam("pairing"))
{
const PsychicWebParameter* p = request->getParam("pairing");
if(p->value() == "1")
{
pairing = true;
}
}
JsonDocument json;
String jsonPretty;
String name;
DebugPreferences debugPreferences;
const std::vector<char*> keysPrefs = debugPreferences.getPreferencesKeys();
const std::vector<char*> boolPrefs = debugPreferences.getPreferencesBoolKeys();
const std::vector<char*> redactedPrefs = debugPreferences.getPreferencesRedactedKeys();
const std::vector<char*> bytePrefs = debugPreferences.getPreferencesByteKeys();
for(const auto& key : keysPrefs)
if(request->hasParam("type"))
{
if(strcmp(key, preference_show_secrets) == 0)
name = "nuki_hub_http_ssl.json";
const PsychicWebParameter* p = request->getParam("type");
if(p->value() == "https")
{
continue;
}
if(strcmp(key, preference_latest_version) == 0)
{
continue;
}
if(!redacted) if(std::find(redactedPrefs.begin(), redactedPrefs.end(), key) != redactedPrefs.end())
{
continue;
name = "nuki_hub_http_ssl.json";
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/http_ssl.crt");
if (!file || file.isDirectory()) {
Log->println("http_ssl.crt not found");
}
else
{
Log->println("Reading http_ssl.crt");
size_t filesize = file.size();
char cert[filesize + 1];
file.read((uint8_t *)cert, sizeof(cert));
file.close();
cert[filesize] = '\0';
json["http_ssl.crt"] = cert;
}
}
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/http_ssl.key");
if (!file || file.isDirectory()) {
Log->println("http_ssl.key not found");
}
else
{
Log->println("Reading http_ssl.key");
size_t filesize = file.size();
char key[filesize + 1];
file.read((uint8_t *)key, sizeof(key));
file.close();
key[filesize] = '\0';
json["http_ssl.key"] = key;
}
}
if(!_preferences->isKey(key))
{
json[key] = "";
}
else if(std::find(boolPrefs.begin(), boolPrefs.end(), key) != boolPrefs.end())
{
json[key] = _preferences->getBool(key) ? "1" : "0";
}
else
{
switch(_preferences->getType(key))
name = "nuki_hub_mqtt_ssl.json";
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
case PT_I8:
json[key] = String(_preferences->getChar(key));
break;
case PT_I16:
json[key] = String(_preferences->getShort(key));
break;
case PT_I32:
json[key] = String(_preferences->getInt(key));
break;
case PT_I64:
json[key] = String(_preferences->getLong64(key));
break;
case PT_U8:
json[key] = String(_preferences->getUChar(key));
break;
case PT_U16:
json[key] = String(_preferences->getUShort(key));
break;
case PT_U32:
json[key] = String(_preferences->getUInt(key));
break;
case PT_U64:
json[key] = String(_preferences->getULong64(key));
break;
case PT_STR:
json[key] = _preferences->getString(key);
break;
default:
json[key] = _preferences->getString(key);
break;
File file = SPIFFS.open("/mqtt_ssl.ca");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.ca not found");
}
else
{
Log->println("Reading mqtt_ssl.ca");
size_t filesize = file.size();
char ca[filesize + 1];
file.read((uint8_t *)ca, sizeof(ca));
file.close();
ca[filesize] = '\0';
json["mqtt_ssl.ca"] = ca;
}
}
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.crt");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.crt not found");
}
else
{
Log->println("Reading mqtt_ssl.crt");
size_t filesize = file.size();
char cert[filesize + 1];
file.read((uint8_t *)cert, sizeof(cert));
file.close();
cert[filesize] = '\0';
json["mqtt_ssl.crt"] = cert;
}
}
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.key");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.key not found");
}
else
{
Log->println("Reading mqtt_ssl.key");
size_t filesize = file.size();
char key[filesize + 1];
file.read((uint8_t *)key, sizeof(key));
file.close();
key[filesize] = '\0';
json["mqtt_ssl.key"] = key;
}
}
}
}
if(pairing)
else
{
if(_nuki != nullptr)
name = "nuki_hub_settings.json";
bool redacted = false;
bool pairing = false;
if(request->hasParam("redacted"))
{
unsigned char currentBleAddress[6];
unsigned char authorizationId[4] = {0x00};
unsigned char secretKeyK[32] = {0x00};
uint16_t storedPincode = 0000;
Preferences nukiBlePref;
nukiBlePref.begin("NukiHub", false);
nukiBlePref.getBytes("bleAddress", currentBleAddress, 6);
nukiBlePref.getBytes("secretKeyK", secretKeyK, 32);
nukiBlePref.getBytes("authorizationId", authorizationId, 4);
nukiBlePref.getBytes("securityPinCode", &storedPincode, 2);
nukiBlePref.end();
const PsychicWebParameter* p = request->getParam("redacted");
if(p->value() == "1")
{
redacted = true;
}
}
if(request->hasParam("pairing"))
{
const PsychicWebParameter* p = request->getParam("pairing");
if(p->value() == "1")
{
pairing = true;
}
}
DebugPreferences debugPreferences;
const std::vector<char*> keysPrefs = debugPreferences.getPreferencesKeys();
const std::vector<char*> boolPrefs = debugPreferences.getPreferencesBoolKeys();
const std::vector<char*> redactedPrefs = debugPreferences.getPreferencesRedactedKeys();
const std::vector<char*> bytePrefs = debugPreferences.getPreferencesByteKeys();
for(const auto& key : keysPrefs)
{
if(strcmp(key, preference_show_secrets) == 0)
{
continue;
}
if(strcmp(key, preference_latest_version) == 0)
{
continue;
}
if(!redacted) if(std::find(redactedPrefs.begin(), redactedPrefs.end(), key) != redactedPrefs.end())
{
continue;
}
if(!_preferences->isKey(key))
{
json[key] = "";
}
else if(std::find(boolPrefs.begin(), boolPrefs.end(), key) != boolPrefs.end())
{
json[key] = _preferences->getBool(key) ? "1" : "0";
}
else
{
switch(_preferences->getType(key))
{
case PT_I8:
json[key] = String(_preferences->getChar(key));
break;
case PT_I16:
json[key] = String(_preferences->getShort(key));
break;
case PT_I32:
json[key] = String(_preferences->getInt(key));
break;
case PT_I64:
json[key] = String(_preferences->getLong64(key));
break;
case PT_U8:
json[key] = String(_preferences->getUChar(key));
break;
case PT_U16:
json[key] = String(_preferences->getUShort(key));
break;
case PT_U32:
json[key] = String(_preferences->getUInt(key));
break;
case PT_U64:
json[key] = String(_preferences->getULong64(key));
break;
case PT_STR:
json[key] = _preferences->getString(key);
break;
default:
json[key] = _preferences->getString(key);
break;
}
}
}
if(pairing)
{
if(_nuki != nullptr)
{
unsigned char currentBleAddress[6];
unsigned char authorizationId[4] = {0x00};
unsigned char secretKeyK[32] = {0x00};
uint16_t storedPincode = 0000;
Preferences nukiBlePref;
nukiBlePref.begin("NukiHub", false);
nukiBlePref.getBytes("bleAddress", currentBleAddress, 6);
nukiBlePref.getBytes("secretKeyK", secretKeyK, 32);
nukiBlePref.getBytes("authorizationId", authorizationId, 4);
nukiBlePref.getBytes("securityPinCode", &storedPincode, 2);
nukiBlePref.end();
char text[255];
text[0] = '\0';
for(int i = 0 ; i < 6 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", currentBleAddress[i]);
}
json["bleAddressLock"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 32 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", secretKeyK[i]);
}
json["secretKeyKLock"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 4 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", authorizationId[i]);
}
json["authorizationIdLock"] = text;
memset(text, 0, sizeof(text));
json["securityPinCodeLock"] = storedPincode;
}
if(_nukiOpener != nullptr)
{
unsigned char currentBleAddressOpn[6];
unsigned char authorizationIdOpn[4] = {0x00};
unsigned char secretKeyKOpn[32] = {0x00};
uint16_t storedPincodeOpn = 0000;
Preferences nukiBlePref;
nukiBlePref.begin("NukiHubopener", false);
nukiBlePref.getBytes("bleAddress", currentBleAddressOpn, 6);
nukiBlePref.getBytes("secretKeyK", secretKeyKOpn, 32);
nukiBlePref.getBytes("authorizationId", authorizationIdOpn, 4);
nukiBlePref.getBytes("securityPinCode", &storedPincodeOpn, 2);
nukiBlePref.end();
char text[255];
text[0] = '\0';
for(int i = 0 ; i < 6 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", currentBleAddressOpn[i]);
}
json["bleAddressOpener"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 32 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", secretKeyKOpn[i]);
}
json["secretKeyKOpener"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 4 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", authorizationIdOpn[i]);
}
json["authorizationIdOpener"] = text;
memset(text, 0, sizeof(text));
json["securityPinCodeOpener"] = storedPincodeOpn;
}
}
for(const auto& key : bytePrefs)
{
size_t storedLength = _preferences->getBytesLength(key);
if(storedLength == 0)
{
continue;
}
uint8_t serialized[storedLength];
memset(serialized, 0, sizeof(serialized));
size_t size = _preferences->getBytes(key, serialized, sizeof(serialized));
if(size == 0)
{
continue;
}
char text[255];
text[0] = '\0';
for(int i = 0 ; i < 6 ; i++)
for(int i = 0 ; i < size ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", currentBleAddress[i]);
sprintf(&(text[offset]), "%02x", serialized[i]);
}
json["bleAddressLock"] = text;
json[key] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 32 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", secretKeyK[i]);
}
json["secretKeyKLock"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 4 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", authorizationId[i]);
}
json["authorizationIdLock"] = text;
memset(text, 0, sizeof(text));
json["securityPinCodeLock"] = storedPincode;
}
if(_nukiOpener != nullptr)
{
unsigned char currentBleAddressOpn[6];
unsigned char authorizationIdOpn[4] = {0x00};
unsigned char secretKeyKOpn[32] = {0x00};
uint16_t storedPincodeOpn = 0000;
Preferences nukiBlePref;
nukiBlePref.begin("NukiHubopener", false);
nukiBlePref.getBytes("bleAddress", currentBleAddressOpn, 6);
nukiBlePref.getBytes("secretKeyK", secretKeyKOpn, 32);
nukiBlePref.getBytes("authorizationId", authorizationIdOpn, 4);
nukiBlePref.getBytes("securityPinCode", &storedPincodeOpn, 2);
nukiBlePref.end();
char text[255];
text[0] = '\0';
for(int i = 0 ; i < 6 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", currentBleAddressOpn[i]);
}
json["bleAddressOpener"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 32 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", secretKeyKOpn[i]);
}
json["secretKeyKOpener"] = text;
memset(text, 0, sizeof(text));
text[0] = '\0';
for(int i = 0 ; i < 4 ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", authorizationIdOpn[i]);
}
json["authorizationIdOpener"] = text;
memset(text, 0, sizeof(text));
json["securityPinCodeOpener"] = storedPincodeOpn;
}
}
for(const auto& key : bytePrefs)
{
size_t storedLength = _preferences->getBytesLength(key);
if(storedLength == 0)
{
continue;
}
uint8_t serialized[storedLength];
memset(serialized, 0, sizeof(serialized));
size_t size = _preferences->getBytes(key, serialized, sizeof(serialized));
if(size == 0)
{
continue;
}
char text[255];
text[0] = '\0';
for(int i = 0 ; i < size ; i++)
{
size_t offset = strlen(text);
sprintf(&(text[offset]), "%02x", serialized[i]);
}
json[key] = text;
memset(text, 0, sizeof(text));
}
serializeJsonPretty(json, jsonPretty);
char buf[26 + name.length()];
snprintf(buf, sizeof(buf), "attachment; filename=\"%s\"", name.c_str());
resp->addHeader("Content-Disposition", buf);
resp->setCode(200);
resp->setContentType("application/json");
resp->setContent(jsonPretty.c_str());
@@ -1580,9 +1699,32 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
else if(key == "MQTTCA")
{
if(_preferences->getString(preference_mqtt_ca, "") != value)
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
_preferences->putString(preference_mqtt_ca, value);
if(value != "")
{
File file = SPIFFS.open("/mqtt_ssl.ca", FILE_WRITE);
if (!file) {
Log->println("Failed to open /mqtt_ssl.ca for writing");
}
else
{
if (!file.print(value))
{
Log->println("Failed to write /mqtt_ssl.ca");
}
file.close();
}
}
else
{
if (!SPIFFS.remove("/mqtt_ssl.ca")) {
Serial.println("Failed to delete /mqtt_ssl.ca");
}
}
Log->print(F("Setting changed: "));
Log->println(key);
configChanged = true;
@@ -1590,9 +1732,32 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
else if(key == "MQTTCRT")
{
if(_preferences->getString(preference_mqtt_crt, "") != value)
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
_preferences->putString(preference_mqtt_crt, value);
if(value != "")
{
File file = SPIFFS.open("/mqtt_ssl.crt", FILE_WRITE);
if (!file) {
Log->println("Failed to open /mqtt_ssl.crt for writing");
}
else
{
if (!file.print(value))
{
Log->println("Failed to write /mqtt_ssl.crt");
}
file.close();
}
}
else
{
if (!SPIFFS.remove("/mqtt_ssl.crt")) {
Serial.println("Failed to delete /mqtt_ssl.crt");
}
}
Log->print(F("Setting changed: "));
Log->println(key);
configChanged = true;
@@ -1600,9 +1765,32 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
else if(key == "MQTTKEY")
{
if(_preferences->getString(preference_mqtt_key, "") != value)
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
_preferences->putString(preference_mqtt_key, value);
if(value != "")
{
File file = SPIFFS.open("/mqtt_ssl.key", FILE_WRITE);
if (!file) {
Log->println("Failed to open /mqtt_ssl.key for writing");
}
else
{
if (!file.print(value))
{
Log->println("Failed to write /mqtt_ssl.key");
}
file.close();
}
}
else
{
if (!SPIFFS.remove("/mqtt_ssl.key")) {
Serial.println("Failed to delete /mqtt_ssl.key");
}
}
Log->print(F("Setting changed: "));
Log->println(key);
configChanged = true;
@@ -1959,6 +2147,16 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
configChanged = true;
}
}
else if(key == "MQTTSENA")
{
if(_preferences->getBool(preference_mqtt_ssl_enabled, false) != (value == "1"))
{
_preferences->putBool(preference_mqtt_ssl_enabled, (value == "1"));
Log->print(F("Setting changed: "));
Log->println(key);
configChanged = true;
}
}
else if(key == "WEBLOG")
{
if(_preferences->getBool(preference_webserial_enabled, false) != (value == "1"))
@@ -3541,6 +3739,13 @@ esp_err_t WebCfgServer::buildImportExportHtml(PsychicRequest *request, PsychicRe
response.print("<button title=\"Basic export\" onclick=\" window.open('/get?page=export', '_self'); return false;\">Basic export</button>");
response.print("<br><br><button title=\"Export with redacted settings\" onclick=\" window.open('/get?page=export&redacted=1'); return false;\">Export with redacted settings</button>");
response.print("<br><br><button title=\"Export with redacted settings and pairing data\" onclick=\" window.open('/get?page=export&redacted=1&pairing=1'); return false;\">Export with redacted settings and pairing data</button>");
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
{
response.print("<br><br><button title=\"Export HTTP SSL certificate and key\" onclick=\" window.open('/get?page=export&type=https'); return false;\">Export HTTP SSL certificate and key</button>");
}
#endif
response.print("<br><br><button title=\"Export MQTT SSL CA, client certificate and client key\" onclick=\" window.open('/get?page=export&type=mqtts'); return false;\">Export MQTT SSL CA, client certificate and client key</button>");
response.print("</div></body></html>");
return response.endSend();
}
@@ -3783,7 +3988,7 @@ esp_err_t WebCfgServer::buildNetworkConfigHtml(PsychicRequest *request, PsychicR
if(esp_psram_get_size() > 0)
{
response.print("<tr><td>Set HTTP SSL Certificate</td><td><button title=\"Set HTTP SSL Certificate\" onclick=\" window.open('/get?page=httpcrtconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Set HTTP SSL Key</td><td><button title=\"Set MQTT SSL Key\" onclick=\" window.open('/get?page=httpkeyconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Set HTTP SSL Key</td><td><button title=\"Set HTTP SSL Key\" onclick=\" window.open('/get?page=httpkeyconfig', '_self'); return false;\">Change</button></td></tr>");
}
#endif
response.print("</table>");
@@ -3826,6 +4031,7 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request, PsychicResp
{
printCheckBox(&response, "OPENERCONT", "Set Nuki Opener Lock/Unlock action in Home Assistant to Continuous mode", _preferences->getBool(preference_opener_continuous_mode), "");
}
printCheckBox(&response, "MQTTSENA", "Enable MQTT SSL", _preferences->getBool(preference_mqtt_ssl_enabled, false), "");
response.print("<tr><td>Set MQTT SSL CA Certificate</td><td><button title=\"Set MQTT SSL CA Certificate\" onclick=\" window.open('/get?page=mqttcaconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Set MQTT SSL Client Certificate</td><td><button title=\"Set MQTT Client Certificate\" onclick=\" window.open('/get?page=mqttcrtconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Set MQTT SSL Client Key</td><td><button title=\"Set MQTT SSL Client Key\" onclick=\" window.open('/get?page=mqttkeyconfig', '_self'); return false;\">Change</button></td></tr>");
@@ -3860,15 +4066,102 @@ esp_err_t WebCfgServer::buildMqttSSLConfigHtml(PsychicRequest *request, PsychicR
if (type == 0)
{
printTextarea(&response, "MQTTCA", "MQTT SSL CA Certificate (*, optional)", _preferences->getString(preference_mqtt_ca).c_str(), TLS_CA_MAX_SIZE, true, true);
bool found = false;
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.ca");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.ca not found");
}
else
{
Log->println("Reading mqtt_ssl.ca");
size_t filesize = file.size();
char ca[filesize + 1];
file.read((uint8_t *)ca, sizeof(ca));
file.close();
ca[filesize] = '\0';
printTextarea(&response, "MQTTCA", "MQTT SSL CA Certificate (*, optional)", ca, 2200, true, true);
found = true;
}
}
if (!found)
{
printTextarea(&response, "MQTTCA", "MQTT SSL CA Certificate (*, optional)", "", 2200, true, true);
}
}
else if (type == 1)
{
printTextarea(&response, "MQTTCRT", "MQTT SSL Client Certificate (*, optional)", _preferences->getString(preference_mqtt_crt).c_str(), TLS_CERT_MAX_SIZE, true, true);
bool found = false;
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.crt");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.crt not found");
}
else
{
Log->println("Reading mqtt_ssl.crt");
size_t filesize = file.size();
char cert[filesize + 1];
file.read((uint8_t *)cert, sizeof(cert));
file.close();
cert[filesize] = '\0';
printTextarea(&response, "MQTTCRT", "MQTT SSL Client Certificate (*, optional)", cert, 2200, true, true);
found = true;
}
}
if (!found)
{
printTextarea(&response, "MQTTCRT", "MQTT SSL Client Certificate (*, optional)", "", 2200, true, true);
}
}
else
{
printTextarea(&response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, true, true);
bool found = false;
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.key");
if (!file || file.isDirectory()) {
Log->println("mqtt_ssl.key not found");
}
else
{
Log->println("Reading mqtt_ssl.key");
size_t filesize = file.size();
char key[filesize + 1];
file.read((uint8_t *)key, sizeof(key));
file.close();
key[filesize] = '\0';
printTextarea(&response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", key, 2200, true, true);
found = true;
}
}
if (!found)
{
printTextarea(&response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", "", 2200, true, true);
}
}
response.print("</table>");
response.print("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
@@ -3891,8 +4184,8 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
if (type == 1)
{
char cert[4400] = {0};
bool found = false;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
@@ -3906,21 +4199,27 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
else
{
Log->println("Reading http_ssl.crt");
uint32_t i = 0;
while(file.available()){
cert[i] = file.read();
i++;
}
size_t filesize = file.size();
char cert[filesize + 1];
file.read((uint8_t *)cert, sizeof(cert));
file.close();
cert[filesize] = '\0';
printTextarea(&response, "HTTPCRT", "HTTP SSL Certificate (*, optional)", cert, 4400, true, true);
found = true;
}
}
#endif
printTextarea(&response, "HTTPCRT", "HTTP SSL Certificate (*, optional)", cert, 4400, true, true);
if (!found)
{
printTextarea(&response, "HTTPCRT", "HTTP SSL Certificate (*, optional)", "", 4400, true, true);
}
}
else
{
char key[2200] = {0};
bool found = false;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
@@ -3934,16 +4233,22 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
else
{
Log->println("Reading http_ssl.key");
uint32_t i = 0;
while(file.available()){
key[i] = file.read();
i++;
}
size_t filesize = file.size();
char key[filesize + 1];
file.read((uint8_t *)key, sizeof(key));
file.close();
key[filesize] = '\0';
printTextarea(&response, "HTTPKEY", "HTTP SSL Key (*, optional)", key, 2200, true, true);
found = true;
}
}
#endif
printTextarea(&response, "HTTPKEY", "HTTP SSL Key (*, optional)", key, 2200, true, true);
if (!found)
{
printTextarea(&response, "HTTPKEY", "HTTP SSL Key (*, optional)", "", 2200, true, true);
}
}
response.print("</table>");
response.print("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
@@ -4528,10 +4833,29 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
response.print(_preferences->getString(preference_cred_password, "").length() > 0 ? "***" : "Not set");
response.print("\nWeb configurator enabled: ");
response.print(_preferences->getBool(preference_webserver_enabled, true) ? "Yes" : "No");
//response.print("\nHTTP SSL CRT: ");
//response.print(_preferences->getString(preference_http_crt, "").length() > 0 ? "***" : "Not set");
//response.print("\nHTTP SSL Key: ");
//response.print(_preferences->getString(preference_http_key, "").length() > 0 ? "***" : "Not set");
response.print("\nHTTP SSL: ");
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
{
if (!SPIFFS.begin(true)) {
response.print("Disabled");
}
else
{
File file = SPIFFS.open("/http_ssl.crt");
File file2 = SPIFFS.open("/http_ssl.key");
response.print((!file || file.isDirectory() || !file2 || file2.isDirectory()) ? "Disabled" : "Enabled");
file.close();
file2.close();
}
}
else
{
response.print("Disabled");
}
#else
response.print("Disabled");
#endif
response.print("\nPublish debug information enabled: ");
response.print(_preferences->getBool(preference_publish_debug_info, false) ? "Yes" : "No");
response.print("\nMQTT log enabled: ");
@@ -4628,12 +4952,38 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
response.print(_preferences->getString(preference_mqtt_password, "").length() > 0 ? "***" : "Not set");
response.print("\nMQTT base topic: ");
response.print(_preferences->getString(preference_mqtt_lock_path, ""));
response.print("\nMQTT SSL CA: ");
response.print(_preferences->getString(preference_mqtt_ca, "").length() > 0 ? "***" : "Not set");
response.print("\nMQTT SSL CRT: ");
response.print(_preferences->getString(preference_mqtt_crt, "").length() > 0 ? "***" : "Not set");
response.print("\nMQTT SSL Key: ");
response.print(_preferences->getString(preference_mqtt_key, "").length() > 0 ? "***" : "Not set");
response.print("\nMQTT SSL: ");
if(_preferences->getBool(preference_mqtt_ssl_enabled, false))
{
if (!SPIFFS.begin(true)) {
response.print("Disabled");
}
else
{
File file = SPIFFS.open("/mqtt_ssl.ca");
if (!file || file.isDirectory()) {
response.print("Disabled");
}
else
{
response.print("Enabled");
response.print("\nMQTT SSL CA: ***");
File file2 = SPIFFS.open("/mqtt_ssl.crt");
File file3 = SPIFFS.open("/mqtt_ssl.key");
response.print("\nMQTT SSL CRT: ");
response.print((!file2 || file2.isDirectory()) ? "Not set" : "***");
response.print("\nMQTT SSL Key: ");
response.print((!file3 || file3.isDirectory()) ? "Not set" : "***");
file2.close();
file3.close();
}
file.close();
}
}
else
{
response.print("Disabled");
}
response.print("\n\n------------ BLUETOOTH ------------");
response.print("\nBluetooth TX power (dB): ");
response.print(_preferences->getInt(preference_ble_tx_power, 9));