Browse Source

Added official (kinda) SSL support in async-mqtt-client

fastled
Xose Pérez 7 years ago
parent
commit
3783b35e05
6 changed files with 152 additions and 68 deletions
  1. +5
    -1
      code/espurna/config/general.h
  2. +46
    -3
      code/espurna/mqtt.ino
  3. +62
    -61
      code/espurna/static/index.html.gz.h
  4. +21
    -1
      code/espurna/web.ino
  5. +17
    -1
      code/html/index.html
  6. +1
    -1
      code/platformio.ini

+ 5
- 1
code/espurna/config/general.h View File

@ -189,9 +189,13 @@ PROGMEM const char* const custom_reset_string[] = {
#define MQTT_USE_ASYNC 1 #define MQTT_USE_ASYNC 1
#endif #endif
// You will need the fingerprint for your MQTT server, example for CloudMQTT:
// $ echo -n | openssl s_client -connect m11.cloudmqtt.com:24055 > cloudmqtt.pem
// $ openssl x509 -noout -in cloudmqtt.pem -fingerprint -sha1
#define MQTT_USE_SSL 0
#define MQTT_SERVER "" #define MQTT_SERVER ""
#define MQTT_PORT 1883 #define MQTT_PORT 1883
#define MQTT_SSL 0
#define MQTT_TOPIC "/test/switch/{identifier}" #define MQTT_TOPIC "/test/switch/{identifier}"
#define MQTT_RETAIN true #define MQTT_RETAIN true
#define MQTT_QOS 0 #define MQTT_QOS 0


+ 46
- 3
code/espurna/mqtt.ino View File

@ -178,6 +178,22 @@ void _mqttOnMessage(char* topic, char* payload, unsigned int len) {
} }
bool fp2array(const char * fingerprint, unsigned char * bytearray) {
// check length (20 2-character digits ':'-separated => 20*2+19 = 59)
if (strlen(fingerprint) != 59) return false;
DEBUG_MSG_P(PSTR("[MQTT] Fingerprint %s\n"), fingerprint);
// walk the fingerprint
for (unsigned int i=0; i<20; i++) {
bytearray[i] = strtol(fingerprint + 3*i, NULL, 16);
}
return true;
}
void mqttConnect() { void mqttConnect() {
if (!mqtt.connected()) { if (!mqtt.connected()) {
@ -224,12 +240,21 @@ void mqttConnect() {
mqtt.setCredentials(_mqttUser, _mqttPass); mqtt.setCredentials(_mqttUser, _mqttPass);
} }
DEBUG_MSG_P(PSTR("\n")); DEBUG_MSG_P(PSTR("\n"));
#if ASYNC_TCP_SSL_ENABLED #if ASYNC_TCP_SSL_ENABLED
mqtt.connect(getSetting("mqttSSL", MQTT_SSL).toInt() == 1);
#else
mqtt.connect();
bool secure = getSetting("mqttUseSSL", MQTT_USE_SSL).toInt() == 1;
mqtt.setSecure(secure);
if (secure) {
DEBUG_MSG_P(PSTR("[MQTT] Using SSL\n"));
unsigned char fp[20];
if (fp2array(getSetting("mqttFP").c_str(), fp)) {
mqtt.addServerFingerprint(fp);
}
}
#endif #endif
mqtt.connect();
#else #else
bool response; bool response;
@ -268,6 +293,24 @@ void mqttSetup() {
_mqttOnConnect(); _mqttOnConnect();
}); });
mqtt.onDisconnect([](AsyncMqttClientDisconnectReason reason) { mqtt.onDisconnect([](AsyncMqttClientDisconnectReason reason) {
if (reason == AsyncMqttClientDisconnectReason::TCP_DISCONNECTED) {
DEBUG_MSG_P(PSTR("[MQTT] TCP Disconnected\n"));
}
if (reason == AsyncMqttClientDisconnectReason::MQTT_IDENTIFIER_REJECTED) {
DEBUG_MSG_P(PSTR("[MQTT] Identifier Rejected\n"));
}
if (reason == AsyncMqttClientDisconnectReason::MQTT_SERVER_UNAVAILABLE) {
DEBUG_MSG_P(PSTR("[MQTT] Server unavailable\n"));
}
if (reason == AsyncMqttClientDisconnectReason::MQTT_MALFORMED_CREDENTIALS) {
DEBUG_MSG_P(PSTR("[MQTT] Malformed credentials\n"));
}
if (reason == AsyncMqttClientDisconnectReason::MQTT_NOT_AUTHORIZED) {
DEBUG_MSG_P(PSTR("[MQTT] Not authorized\n"));
}
if (reason == AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT) {
DEBUG_MSG_P(PSTR("[MQTT] Bad fingerprint\n"));
}
_mqttOnDisconnect(); _mqttOnDisconnect();
}); });
mqtt.onMessage([](char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { mqtt.onMessage([](char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {


+ 62
- 61
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 21
- 1
code/espurna/web.ino View File

@ -163,6 +163,9 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
bool changedNTP = false; bool changedNTP = false;
bool apiEnabled = false; bool apiEnabled = false;
bool dstEnabled = false; bool dstEnabled = false;
#if ASYNC_TCP_SSL_ENABLED
bool mqttUseSSL = false;
#endif
#if ENABLE_FAUXMO #if ENABLE_FAUXMO
bool fauxmoEnabled = false; bool fauxmoEnabled = false;
#endif #endif
@ -256,6 +259,12 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
dstEnabled = true; dstEnabled = true;
continue; continue;
} }
#if ASYNC_TCP_SSL_ENABLED
if (key == "mqttUseSSL") {
mqttUseSSL = true;
continue;
}
#endif
#if ENABLE_FAUXMO #if ENABLE_FAUXMO
if (key == "fauxmoEnabled") { if (key == "fauxmoEnabled") {
fauxmoEnabled = true; fauxmoEnabled = true;
@ -304,6 +313,12 @@ void _wsParse(uint32_t client_id, uint8_t * payload, size_t length) {
setSetting("ntpDST", dstEnabled); setSetting("ntpDST", dstEnabled);
save = changed = changedNTP = true; save = changed = changedNTP = true;
} }
#if ASYNC_TCP_SSL_ENABLED
if (mqttUseSSL != (getSetting("mqttUseSSL", 0). toInt() == 1)) {
setSetting("mqttUseSSL", mqttUseSSL);
save = changed = changedMQTT = true;
}
#endif
#if ENABLE_FAUXMO #if ENABLE_FAUXMO
if (fauxmoEnabled != (getSetting("fauxmoEnabled").toInt() == 1)) { if (fauxmoEnabled != (getSetting("fauxmoEnabled").toInt() == 1)) {
setSetting("fauxmoEnabled", fauxmoEnabled); setSetting("fauxmoEnabled", fauxmoEnabled);
@ -431,6 +446,11 @@ void _wsStart(uint32_t client_id) {
root["mqttPort"] = getSetting("mqttPort", MQTT_PORT); root["mqttPort"] = getSetting("mqttPort", MQTT_PORT);
root["mqttUser"] = getSetting("mqttUser"); root["mqttUser"] = getSetting("mqttUser");
root["mqttPassword"] = getSetting("mqttPassword"); root["mqttPassword"] = getSetting("mqttPassword");
#if ASYNC_TCP_SSL_ENABLED
root["mqttsslVisible"] = 1;
root["mqttUseSSL"] = getSetting("mqttUseSSL", 0).toInt() == 1;
root["mqttFP"] = getSetting("mqttFP");
#endif
root["mqttTopic"] = getSetting("mqttTopic", MQTT_TOPIC); root["mqttTopic"] = getSetting("mqttTopic", MQTT_TOPIC);
JsonArray& relay = root.createNestedArray("relayStatus"); JsonArray& relay = root.createNestedArray("relayStatus");
@ -780,7 +800,7 @@ void _onRPC(AsyncWebServerRequest *request) {
if (action.equals("reset")) { if (action.equals("reset")) {
response = 200; response = 200;
deferred.once_ms(100, []() {
deferred.once_ms(100, []() {
customReset(CUSTOM_RESET_RPC); customReset(CUSTOM_RESET_RPC);
ESP.restart(); ESP.restart();
}); });


+ 17
- 1
code/html/index.html View File

@ -458,9 +458,25 @@
<input class="pure-u-1 pure-u-md-3-4" name="mqttPassword" type="password" size="20" tabindex="24" placeholder="Leave blank if no user/pass" /> <input class="pure-u-1 pure-u-md-3-4" name="mqttPassword" type="password" size="20" tabindex="24" placeholder="Leave blank if no user/pass" />
</div> </div>
<div class="pure-g module module-mqttssl">
<div class="pure-u-1 pure-u-sm-1-4"><label for="mqttUseSSL">Use secure connection (SSL)</label></div>
<div class="pure-u-1 pure-u-sm-1-4"><input type="checkbox" name="mqttUseSSL" tabindex="25" /></div>
</div>
<div class="pure-g module module-mqttssl">
<label class="pure-u-1 pure-u-md-1-4" for="mqttFP">SSL Fingerprint</label>
<input class="pure-u-1 pure-u-md-3-4" name="mqttFP" type="text" size="59" tabindex="26" />
<div class="pure-u-0 pure-u-md-1-4">&nbsp;</div>
<div class="pure-u-1 pure-u-md-3-4 hint">
This is the fingerprint for the SSL certificate of the server. If using CloudMQTT you can get it using (use your server and port):<br />
$ echo -n | openssl s_client -connect m11.cloudmqtt.com:24055 > cloudmqtt.pem<br />
$ openssl x509 -noout -in cloudmqtt.pem -fingerprint -sha1
</div>
</div>
<div class="pure-g"> <div class="pure-g">
<label class="pure-u-1 pure-u-md-1-4" for="mqttTopic">MQTT Root Topic</label> <label class="pure-u-1 pure-u-md-1-4" for="mqttTopic">MQTT Root Topic</label>
<input class="pure-u-1 pure-u-md-3-4" name="mqttTopic" type="text" size="20" tabindex="25" />
<input class="pure-u-1 pure-u-md-3-4" name="mqttTopic" type="text" size="20" tabindex="27" />
<div class="pure-u-0 pure-u-md-1-4">&nbsp;</div> <div class="pure-u-0 pure-u-md-1-4">&nbsp;</div>
<div class="pure-u-1 pure-u-md-3-4 hint"> <div class="pure-u-1 pure-u-md-3-4 hint">
This is the root topic for this device. A trailing slash will be added if not preset. The {identifier} placeholder will be replaces by the device hostname.<br /> This is the root topic for this device. A trailing slash will be added if not preset. The {identifier} placeholder will be replaces by the device hostname.<br />


+ 1
- 1
code/platformio.ini View File

@ -13,7 +13,7 @@ lib_deps =
ArduinoJson ArduinoJson
https://github.com/me-no-dev/ESPAsyncTCP#36b6b5a https://github.com/me-no-dev/ESPAsyncTCP#36b6b5a
https://github.com/me-no-dev/ESPAsyncWebServer#bab5457 https://github.com/me-no-dev/ESPAsyncWebServer#bab5457
https://github.com/marvinroger/async-mqtt-client#f1b4576
https://github.com/marvinroger/async-mqtt-client#ddbf4d1
PubSubClient PubSubClient
Embedis Embedis
NtpClientLib NtpClientLib


Loading…
Cancel
Save