Skip to content

Commit a628b22

Browse files
committed
Remove Secure Connection macro and add the config to wifimanager.
This adds the ability to specify if the MQTT broker connection is secure via a checkbox on the config page of WiFiManager. Also added to the WiFiManager config page is a text box to enter the brokers TLS certificate. In the case of using manual configuration a new macro is created MQTT_SECURE_DEFAULT. When defined as true a secure connection will be requested and the certificate defined in user_config.h will be used.
1 parent 00327f2 commit a628b22

File tree

3 files changed

+126
-102
lines changed

3 files changed

+126
-102
lines changed

main/User_config.h

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ const byte ip[] = {192, 168, 1, 99};
8080
const byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0x54, 0x95}; //W5100 ethernet shield mac adress
8181
#endif
8282

83+
#ifndef NTP_SERVER
84+
# define NTP_SERVER "pool.ntp.org"
85+
#endif
86+
8387
#ifdef MQTT_HTTPS_FW_UPDATE
8488
# if defined(ESP8266) || defined(ESP32)
8589
//If used, this should be set to the root CA certificate of the server hosting the firmware.
@@ -89,7 +93,6 @@ const char* https_fw_server_cert PROGMEM = R"EOF("
8993
...
9094
-----END CERTIFICATE-----
9195
")EOF";
92-
# define NTP_SERVER "pool.ntp.org"
9396
# ifndef MQTT_HTTPS_FW_UPDATE_USE_PASSWORD
9497
# define MQTT_HTTPS_FW_UPDATE_USE_PASSWORD 1 // Set this to 0 if not using TLS connection to MQTT broker to prevent clear text passwords being sent.
9598
# endif
@@ -142,16 +145,6 @@ const char* https_fw_server_cert PROGMEM = R"EOF("
142145
# define mqtt_max_packet_size 128
143146
#endif
144147

145-
// activate the use of TLS for secure connection to the MQTT broker
146-
// MQTT_SERVER must be set to the Common Name (CN) of the broker's certificate
147-
//#define SECURE_CONNECTION
148-
149-
#ifdef SECURE_CONNECTION
150-
# define MQTT_DEFAULT_PORT "8883"
151-
#else
152-
# define MQTT_DEFAULT_PORT "1883"
153-
#endif
154-
155148
#ifndef MQTT_USER
156149
# define MQTT_USER "your_username"
157150
#endif
@@ -162,11 +155,13 @@ const char* https_fw_server_cert PROGMEM = R"EOF("
162155
# define MQTT_SERVER "192.168.1.17"
163156
#endif
164157
#ifndef MQTT_PORT
165-
# define MQTT_PORT MQTT_DEFAULT_PORT
158+
# define MQTT_PORT "1883"
159+
#endif
160+
#ifndef MQTT_SECURE_DEFAULT
161+
# define MQTT_SECURE_DEFAULT false
166162
#endif
167163

168-
#ifdef SECURE_CONNECTION
169-
# if defined(ESP8266) || defined(ESP32)
164+
#if defined(ESP8266) || defined(ESP32)
170165
// The root ca certificate used for validating the MQTT broker
171166
// The certificate must be in PEM ascii format
172167
const char* certificate PROGMEM = R"EOF("
@@ -175,16 +170,6 @@ const char* certificate PROGMEM = R"EOF("
175170
-----END CERTIFICATE-----
176171
")EOF";
177172

178-
// specify a NTP server here or else the NTP server from DHCP is used
179-
# ifndef NTP_SERVER
180-
//# define NTP_SERVER "pool.ntp.org"
181-
# endif
182-
# else
183-
# error "only ESP8266 and ESP32 support SECURE_CONNECTION with TLS"
184-
# endif
185-
#endif
186-
187-
#if defined(ESP8266) || defined(ESP32)
188173
# define ATTEMPTS_BEFORE_BG 10 // Number of wifi connection attempts before going to BG protocol
189174
# define ATTEMPTS_BEFORE_B 20 // Number of wifi connection attempts before going to B protocol
190175
#endif

main/main.ino

Lines changed: 110 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ int failure_number_mqtt = 0; // number of failure connecting to MQTT
173173
bool disc = true; // Auto discovery with Home Assistant convention
174174
#endif
175175
unsigned long timer_led_measures = 0;
176+
static void* eClient = nullptr;
177+
static bool mqtt_secure = MQTT_SECURE_DEFAULT;
178+
static String mqtt_cert = "";
176179

177180
#ifdef ESP32
178181
# include <ArduinoOTA.h>
@@ -186,13 +189,8 @@ unsigned long timer_led_measures = 0;
186189
void WiFiEvent(WiFiEvent_t event);
187190
static bool esp32EthConnected = false;
188191
# endif
189-
# ifdef SECURE_CONNECTION
190-
# include <WiFiClientSecure.h>
191-
WiFiClientSecure eClient;
192-
# else
193-
# include <WiFi.h>
194-
WiFiClient eClient;
195-
# endif
192+
193+
# include <WiFiClientSecure.h>
196194
# include <WiFiMulti.h>
197195
WiFiMulti wifiMulti;
198196
# include <Preferences.h>
@@ -201,6 +199,7 @@ Preferences preferences;
201199
# ifdef MDNS_SD
202200
# include <ESPmDNS.h>
203201
# endif
202+
204203
#elif defined(ESP8266)
205204
# include <ArduinoOTA.h>
206205
# include <DNSServer.h>
@@ -209,26 +208,21 @@ Preferences preferences;
209208
# include <ESP8266WiFiMulti.h>
210209
# include <FS.h>
211210
# include <WiFiManager.h>
212-
# ifdef SECURE_CONNECTION
213-
WiFiClientSecure eClient;
214-
X509List caCert(certificate);
215-
# else
216-
WiFiClient eClient;
217-
# endif
211+
X509List caCert;
218212
ESP8266WiFiMulti wifiMulti;
219213
# ifdef MDNS_SD
220214
# include <ESP8266mDNS.h>
221215
# endif
216+
222217
#else
223218
# include <Ethernet.h>
224-
EthernetClient eClient;
225219
#endif
226220

227221
#define convertTemp_CtoF(c) ((c * 1.8) + 32)
228222
#define convertTemp_FtoC(f) ((f - 32) * 5 / 9)
229223

230224
// client link to pubsub mqtt
231-
PubSubClient client(eClient);
225+
PubSubClient client;
232226

233227
void revert_hex_data(const char* in, char* out, int l) {
234228
//reverting array 2 by 2 to get the data in good order
@@ -517,10 +511,10 @@ void connectMQTT() {
517511
failure_number_mqtt++; // we count the failure
518512
Log.warning(F("failure_number_mqtt: %d" CR), failure_number_mqtt);
519513
Log.warning(F("failed, rc=%d" CR), client.state());
520-
#if defined(SECURE_CONNECTION) && defined(ESP32)
521-
Log.warning(F("failed, ssl error code=%d" CR), eClient.lastError(nullptr, 0));
522-
#elif defined(SECURE_CONNECTION) && defined(ESP8266)
523-
Log.warning(F("failed, ssl error code=%d" CR), eClient.getLastSSLError());
514+
#if defined(ESP32)
515+
Log.warning(F("failed, ssl error code=%d" CR), ((WiFiClientSecure*)eClient)->lastError(nullptr, 0));
516+
#elif defined(ESP8266)
517+
Log.warning(F("failed, ssl error code=%d" CR), ((WiFiClientSecure*)eClient)->getLastSSLError());
524518
#endif
525519
digitalWrite(LED_INFO, LED_INFO_ON);
526520
delay(1000);
@@ -590,9 +584,6 @@ void setup() {
590584
# endif
591585

592586
setOTA();
593-
# ifdef SECURE_CONNECTION
594-
setupTLS();
595-
# endif
596587
#else // In case of arduino platform
597588

598589
//Launch serial for debugging purposes
@@ -617,6 +608,18 @@ void setup() {
617608
port = strtol(mqtt_port, NULL, 10);
618609
Log.trace(F("Port: %l" CR), port);
619610
Log.trace(F("Mqtt server: %s" CR), mqtt_server);
611+
# if defined(ESP8266) || defined(ESP32)
612+
if (mqtt_secure) {
613+
eClient = new WiFiClientSecure;
614+
setupTLS();
615+
} else {
616+
eClient = new WiFiClient;
617+
}
618+
# else
619+
eClient = new EthernetClient;
620+
# endif
621+
622+
client.setClient(*(Client*)eClient);
620623
client.setServer(mqtt_server, port);
621624
#endif
622625

@@ -848,19 +851,24 @@ void setOTA() {
848851
ArduinoOTA.begin();
849852
}
850853

851-
# ifdef SECURE_CONNECTION
852854
void setupTLS() {
853-
# if defined(NTP_SERVER)
854855
configTime(0, 0, NTP_SERVER);
855-
# endif
856-
# if defined(ESP32)
857-
eClient.setCACert(certificate);
858-
# elif defined(ESP8266)
859-
eClient.setTrustAnchors(&caCert);
860-
eClient.setBufferSizes(512, 512);
861-
# endif
862-
}
856+
WiFiClientSecure* sClient = (WiFiClientSecure*)eClient;
857+
if (mqtt_cert.length() > 0) {
858+
# if defined(ESP32)
859+
sClient->setCACert(mqtt_cert.c_str());
860+
} else {
861+
sClient->setCACert(certificate);
862+
}
863+
# elif defined(ESP8266)
864+
caCert.append(mqtt_cert.c_str());
865+
} else {
866+
caCert.append(certificate);
867+
}
868+
sClient->setTrustAnchors(&caCert);
869+
sClient->setBufferSizes(512, 512);
863870
# endif
871+
}
864872
#endif
865873

866874
#if defined(ESPWifiManualSetup)
@@ -904,7 +912,7 @@ void setup_wifi() {
904912
WiFiManager wifiManager;
905913

906914
//flag for saving data
907-
bool shouldSaveConfig = true;
915+
bool shouldSaveConfig = false;
908916
//do we have been connected once to mqtt
909917

910918
//callback notifying us of the need to save config
@@ -999,6 +1007,10 @@ void setup_wifimanager(bool reset_settings) {
9991007
strcpy(mqtt_pass, json["mqtt_pass"]);
10001008
if (json.containsKey("mqtt_topic"))
10011009
strcpy(mqtt_topic, json["mqtt_topic"]);
1010+
if (json.containsKey("mqtt_secure"))
1011+
mqtt_secure = json.get<bool>("mqtt_secure");
1012+
if (json.containsKey("mqtt_cert"))
1013+
mqtt_cert = json.get<const char*>("mqtt_cert");
10021014
if (json.containsKey("gateway_name"))
10031015
strcpy(gateway_name, json["gateway_name"]);
10041016
} else {
@@ -1015,6 +1027,8 @@ void setup_wifimanager(bool reset_settings) {
10151027
WiFiManagerParameter custom_mqtt_user("user", "mqtt user", mqtt_user, parameters_size);
10161028
WiFiManagerParameter custom_mqtt_pass("pass", "mqtt pass", mqtt_pass, parameters_size * 2);
10171029
WiFiManagerParameter custom_mqtt_topic("topic", "mqtt base topic", mqtt_topic, mqtt_topic_max_size);
1030+
WiFiManagerParameter custom_mqtt_secure("secure", "mqtt secure", "1", 1, mqtt_secure ? "type=\"checkbox\" checked" : "type=\"checkbox\"");
1031+
WiFiManagerParameter custom_mqtt_cert("cert", "mqtt broker cert", mqtt_cert.c_str(), 2048);
10181032
WiFiManagerParameter custom_gateway_name("name", "gateway name", gateway_name, parameters_size * 2);
10191033

10201034
//WiFiManager
@@ -1041,6 +1055,8 @@ void setup_wifimanager(bool reset_settings) {
10411055
wifiManager.addParameter(&custom_mqtt_port);
10421056
wifiManager.addParameter(&custom_mqtt_user);
10431057
wifiManager.addParameter(&custom_mqtt_pass);
1058+
wifiManager.addParameter(&custom_mqtt_secure);
1059+
wifiManager.addParameter(&custom_mqtt_cert);
10441060
wifiManager.addParameter(&custom_gateway_name);
10451061
wifiManager.addParameter(&custom_mqtt_topic);
10461062

@@ -1083,16 +1099,35 @@ void setup_wifimanager(bool reset_settings) {
10831099
M5Display("Wifi connected", "", "");
10841100
# endif
10851101

1086-
//read updated parameters
1087-
strcpy(mqtt_server, custom_mqtt_server.getValue());
1088-
strcpy(mqtt_port, custom_mqtt_port.getValue());
1089-
strcpy(mqtt_user, custom_mqtt_user.getValue());
1090-
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
1091-
strcpy(mqtt_topic, custom_mqtt_topic.getValue());
1092-
strcpy(gateway_name, custom_gateway_name.getValue());
1093-
1094-
//save the custom parameters to FS
10951102
if (shouldSaveConfig) {
1103+
//read updated parameters
1104+
strcpy(mqtt_server, custom_mqtt_server.getValue());
1105+
strcpy(mqtt_port, custom_mqtt_port.getValue());
1106+
strcpy(mqtt_user, custom_mqtt_user.getValue());
1107+
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
1108+
strcpy(mqtt_topic, custom_mqtt_topic.getValue());
1109+
strcpy(gateway_name, custom_gateway_name.getValue());
1110+
mqtt_secure = *custom_mqtt_secure.getValue();
1111+
1112+
int cert_len = strlen(custom_mqtt_cert.getValue());
1113+
if (cert_len) {
1114+
char* cert_in = (char*)custom_mqtt_cert.getValue();
1115+
while (*cert_in == ' ' || *cert_in == '\t') {
1116+
cert_in++;
1117+
}
1118+
1119+
char* cert_begin = cert_in;
1120+
while (*cert_in != NULL) {
1121+
if (*cert_in == ' ' && (strncmp((cert_in + 1), "CERTIFICATE", 11) != 0)) {
1122+
*cert_in = '\n';
1123+
}
1124+
cert_in++;
1125+
}
1126+
1127+
mqtt_cert = cert_begin;
1128+
}
1129+
1130+
//save the custom parameters to FS
10961131
Log.trace(F("saving config" CR));
10971132
DynamicJsonBuffer jsonBuffer;
10981133
JsonObject& json = jsonBuffer.createObject();
@@ -1102,6 +1137,8 @@ void setup_wifimanager(bool reset_settings) {
11021137
json["mqtt_pass"] = mqtt_pass;
11031138
json["mqtt_topic"] = mqtt_topic;
11041139
json["gateway_name"] = gateway_name;
1140+
json["mqtt_secure"] = mqtt_secure;
1141+
json["mqtt_cert"] = mqtt_cert;
11051142

11061143
File configFile = SPIFFS.open("/config.json", "w");
11071144
if (!configFile) {
@@ -1623,12 +1660,11 @@ void receivingMQTT(char* topicOri, char* datacallback) {
16231660
}
16241661

16251662
#ifdef MQTT_HTTPS_FW_UPDATE
1626-
# ifndef NTP_SERVER
1627-
# error no NTP_SERVER defined
1628-
# endif
16291663
# include <WiFiClientSecure.h>
1664+
1665+
# include "Ota_github.h"
1666+
16301667
# ifdef ESP32
1631-
# include "Ota_github.h"
16321668
# include "zzHTTPUpdate.h"
16331669
# elif ESP8266
16341670
# include <ESP8266httpUpdate.h>
@@ -1649,9 +1685,6 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
16491685
}
16501686

16511687
# if MQTT_HTTPS_FW_UPDATE_USE_PASSWORD > 0
1652-
# ifndef SECURE_CONNECTION
1653-
# warning using a password with an unsecure MQTT connection will send it as clear text!!!
1654-
# endif
16551688
const char* pwd = HttpsFwUpdateData["password"];
16561689
if (pwd) {
16571690
if (strcmp(pwd, ota_password) != 0) {
@@ -1683,38 +1716,46 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
16831716

16841717
} else {
16851718
WiFiClientSecure update_client;
1686-
# ifdef SECURE_CONNECTION
1687-
client.disconnect();
1688-
update_client = eClient;
1689-
# else
1690-
configTime(0, 0, NTP_SERVER);
1691-
time_t now = time(nullptr);
1692-
uint8_t count = 0;
1693-
Log.trace(F("Waiting for NTP time sync" CR));
1694-
while ((now < 8 * 3600 * 2) && count++ < 60) {
1695-
vTaskDelay(500);
1696-
now = time(nullptr);
1719+
if (mqtt_secure) {
1720+
client.disconnect();
1721+
update_client = *(WiFiClientSecure*)eClient;
1722+
} else {
1723+
configTime(0, 0, NTP_SERVER);
1724+
time_t now = time(nullptr);
1725+
uint8_t count = 0;
1726+
Log.trace(F("Waiting for NTP time sync" CR));
1727+
while ((now < 8 * 3600 * 2) && count++ < 60) {
1728+
delay(500);
1729+
now = time(nullptr);
1730+
}
1731+
1732+
if (count >= 60) {
1733+
Log.error(F("Unable to update - invalid time" CR));
1734+
# if defined(ZgatewayBT) && defined(ESP32)
1735+
startProcessing();
1736+
# endif
1737+
return;
1738+
}
16971739
}
16981740

1699-
if (count >= 60) {
1700-
Log.error(F("Unable to update - invalid time" CR));
1701-
# if defined(ZgatewayBT) && defined(ESP32)
1702-
startProcessing();
1703-
# endif
1704-
return;
1705-
}
1706-
# endif
17071741
# ifdef ESP32
17081742
if (strstr(url, "github") != 0) {
17091743
update_client.setCACert(_github_cert);
17101744
} else {
17111745
update_client.setCACert(https_fw_server_cert);
17121746
}
1747+
17131748
update_client.setTimeout(12);
17141749
httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
17151750
result = httpUpdate.update(update_client, url);
17161751
# elif ESP8266
1717-
update_client.setInsecure(); // TODO: replace with cert checking
1752+
if (strstr(url, "github") != 0) {
1753+
caCert.append(_github_cert);
1754+
} else {
1755+
caCert.append(https_fw_server_cert);
1756+
}
1757+
1758+
update_client.setTrustAnchors(&caCert);
17181759
update_client.setTimeout(12000);
17191760
ESPhttpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
17201761
result = ESPhttpUpdate.update(update_client, url);

0 commit comments

Comments
 (0)