Skip to content

Commit

Permalink
added config entries for MQTT TLS (#2651)
Browse files Browse the repository at this point in the history
3 new entries in the config section, for setting file paths for
        - Root CA
        - Client Certificate
        - Client Private Key
 (all set as expert parameters)

- logging cert filenames

added config entries for MQTT TLS

 3 new entries in the config section, for setting file paths for
        - Root CA
        - Client Certificate
        - Client Private Key

- logging cert filenames

MQTT-TLS: Updates for the PR comments

- config.ini now has default values closer to "real" life filenames
- MQTT cert entries are hidden as Expert parameters
- Fixed debug logging at MQTT interface for unhandled messages
  • Loading branch information
LordGuilly authored Nov 7, 2023
1 parent 36c12b4 commit 75b15b8
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 1 deletion.
18 changes: 17 additions & 1 deletion code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ void ClassFlowMQTT::SetInitialParameter(void)
topicUptime = "";
topicFreeMem = "";

caCertFilename = "";
clientCertFilename = "";
clientKeyFilename = "";
clientname = wlan_config.hostname;

OldValue = "";
Expand Down Expand Up @@ -102,6 +105,18 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
if ((toUpper(splitted[0]) == "CACERT") && (splitted.size() > 1))
{
this->caCertFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "CLIENTCERT") && (splitted.size() > 1))
{
this->clientCertFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "CLIENTKEY") && (splitted.size() > 1))
{
this->clientKeyFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
{
this->user = splitted[1];
Expand Down Expand Up @@ -196,7 +211,8 @@ bool ClassFlowMQTT::Start(float AutoInterval)
mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);

bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED,
LWT_DISCONNECTED, keepAlive, SetRetainFlag, (void *)&GotConnected);
LWT_DISCONNECTED, caCertFilename, clientCertFilename, clientKeyFilename,
keepAlive, SetRetainFlag, (void *)&GotConnected);

if (!MQTTConfigCheck) {
return false;
Expand Down
1 change: 1 addition & 0 deletions code/components/jomjol_flowcontroll/ClassFlowMQTT.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ClassFlowMQTT :
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
std::string caCertFilename, clientCertFilename, clientKeyFilename;
bool SetRetainFlag;
int keepAlive; // Seconds
float roundInterval; // Minutes
Expand Down
42 changes: 42 additions & 0 deletions code/components/jomjol_mqtt/interface_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include "interface_mqtt.h"

#include "esp_log.h"
#if DEBUG_DETAIL_ON
#include "esp_timer.h"
#endif
#include "connect_wlan.h"
#include "mqtt_client.h"
#include "ClassLogFile.h"
Expand Down Expand Up @@ -32,6 +35,7 @@ bool mqtt_connected = false;

esp_mqtt_client_handle_t client = NULL;
std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic;
std::string caCert, clientCert, clientKey;
int keepalive;
bool SetRetainFlag;
void (*callbackOnConnected)(std::string, bool) = NULL;
Expand Down Expand Up @@ -169,6 +173,10 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) {
else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_NOT_AUTHORIZED) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, not authorized. Check username/password (0x05)");
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Other event id:" + event->error_handle->connect_return_code);
ESP_LOGE(TAG, "Other event id:%d", event->error_handle->connect_return_code);
}

#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "MQTT_EVENT_ERROR - esp_mqtt_error_codes:");
Expand Down Expand Up @@ -198,6 +206,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_

bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename,
int _keepalive, bool _SetRetainFlag, void *_callbackOnConnected) {
if ((_mqttURI.length() == 0) || (_maintopic.length() == 0) || (_clientid.length() == 0))
{
Expand All @@ -215,6 +224,25 @@ bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us
maintopic = _maintopic;
callbackOnConnected = ( void (*)(std::string, bool) )(_callbackOnConnected);

if (_clientcertfilename.length() && _clientkeyfilename.length()){
std::ifstream cert_ifs(_clientcertfilename);
std::string cert_content((std::istreambuf_iterator<char>(cert_ifs)), (std::istreambuf_iterator<char>()));
clientCert = cert_content;
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "using clientCert: " + _clientcertfilename);

std::ifstream key_ifs(_clientkeyfilename);
std::string key_content((std::istreambuf_iterator<char>(key_ifs)), (std::istreambuf_iterator<char>()));
clientKey = key_content;
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "using clientKey: " + _clientkeyfilename);
}

if (_cacertfilename.length() ){
std::ifstream ifs(_cacertfilename);
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
caCert = content;
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "using caCert: " + _cacertfilename);
}

if (_user.length() && _password.length()){
user = _user;
password = _password;
Expand Down Expand Up @@ -268,6 +296,20 @@ int MQTT_Init() {
mqtt_cfg.session.keepalive = keepalive;
mqtt_cfg.buffer.size = 1536; // size of MQTT send/receive buffer (Default: 1024)

if (caCert.length()){
mqtt_cfg.broker.verification.certificate = caCert.c_str();
mqtt_cfg.broker.verification.certificate_len = caCert.length() + 1;
mqtt_cfg.broker.verification.skip_cert_common_name_check = true;
}

if (clientCert.length() && clientKey.length()){
mqtt_cfg.credentials.authentication.certificate = clientCert.c_str();
mqtt_cfg.credentials.authentication.certificate_len = clientCert.length() + 1;

mqtt_cfg.credentials.authentication.key = clientKey.c_str();
mqtt_cfg.credentials.authentication.key_len = clientKey.length() + 1;
}

if (user.length() && password.length()){
mqtt_cfg.credentials.username = user.c_str();
mqtt_cfg.credentials.authentication.password = password.c_str();
Expand Down
1 change: 1 addition & 0 deletions code/components/jomjol_mqtt/interface_mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

bool MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password,
std::string _maintopic, std::string _lwt, std::string _lwt_connected, std::string _lwt_disconnected,
std::string _cacertfilename, std::string _clientcertfilename, std::string _clientkeyfilename,
int _keepalive, bool SetRetainFlag, void *callbackOnConnected);
int MQTT_Init();
void MQTTdestroy_client(bool _disable);
Expand Down
3 changes: 3 additions & 0 deletions sd-card/config/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ CheckDigitIncreaseConsistency = false
RetainMessages = false
HomeassistantDiscovery = false
;MeterType = other
;CACert = /config/certs/RootCA.pem
;ClientCert = /config/certs/client.pem.crt
;ClientKey = /config/certs/client.pem.key

;[InfluxDB]
;Uri = undefined
Expand Down
39 changes: 39 additions & 0 deletions sd-card/html/edit_config_param.html
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,39 @@ <h4>
<td>$TOOLTIP_MQTT_password</td>
</tr>

<tr class="MQTTItem expert" id="exMqtt">
<td class="indent1">
<input type="checkbox" id="MQTT_CACert_enabled" value="1" onclick = 'InvertEnableItem("MQTT", "CACert")' unchecked >
<label for=MQTT_CACert_enabled><class id="MQTT_CACert_text" style="color:black;">Root CA Certificate file</class></label>
</td>
<td>
<input type="text" id="MQTT_CACert_value1">
</td>
<td>$TOOLTIP_MQTT_CACert</td>
</tr>

<tr class="MQTTItem expert" id="exMqtt">
<td class="indent1">
<input type="checkbox" id="MQTT_ClientCert_enabled" value="1" onclick = 'InvertEnableItem("MQTT", "ClientCert")' unchecked >
<label for=MQTT_ClientCert_enabled><class id="MQTT_ClientCert_text" style="color:black;">Client Certificate file</class></label>
</td>
<td>
<input type="text" id="MQTT_ClientCert_value1">
</td>
<td>$TOOLTIP_MQTT_ClientCert</td>
</tr>

<tr class="MQTTItem expert" id="exMqtt">
<td class="indent1">
<input type="checkbox" id="MQTT_ClientKey_enabled" value="1" onclick = 'InvertEnableItem("MQTT", "ClientKey")' unchecked >
<label for=MQTT_ClientKey_enabled><class id="MQTT_ClientKey_text" style="color:black;">Client Key file</class></label>
</td>
<td>
<input type="text" id="MQTT_ClientKey_value1">
</td>
<td>$TOOLTIP_MQTT_ClientKey</td>
</tr>

<tr class="MQTTItem">
<td class="indent1">
<label><class id="MQTT_RetainMessages_text" style="color:black;">Retain Messages</class></label>
Expand Down Expand Up @@ -2089,6 +2122,9 @@ <h4><input type="checkbox" id="Category_GPIO_enabled" value="1" onclick='Update
WriteParameter(param, category, "MQTT", "RetainMessages", false);
WriteParameter(param, category, "MQTT", "HomeassistantDiscovery", false);
WriteParameter(param, category, "MQTT", "MeterType", true);
WriteParameter(param, category, "MQTT", "CACert", true);
WriteParameter(param, category, "MQTT", "ClientCert", true);
WriteParameter(param, category, "MQTT", "ClientKey", true);

WriteParameter(param, category, "InfluxDB", "Uri", true);
WriteParameter(param, category, "InfluxDB", "Database", true);
Expand Down Expand Up @@ -2225,6 +2261,9 @@ <h4><input type="checkbox" id="Category_GPIO_enabled" value="1" onclick='Update
ReadParameter(param, "MQTT", "RetainMessages", false);
ReadParameter(param, "MQTT", "HomeassistantDiscovery", false);
ReadParameter(param, "MQTT", "MeterType", true);
ReadParameter(param, "MQTT", "CACert", true);
ReadParameter(param, "MQTT", "ClientCert", true);
ReadParameter(param, "MQTT", "ClientKey", true);

ReadParameter(param, "InfluxDB", "Uri", true);
ReadParameter(param, "InfluxDB", "Database", true);
Expand Down
3 changes: 3 additions & 0 deletions sd-card/html/readconfigparam.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ function ParseConfig() {
ParamAddValue(param, catname, "RetainMessages");
ParamAddValue(param, catname, "HomeassistantDiscovery");
ParamAddValue(param, catname, "MeterType");
ParamAddValue(param, catname, "CACert");
ParamAddValue(param, catname, "ClientCert");
ParamAddValue(param, catname, "ClientKey");

var catname = "InfluxDB";
category[catname] = new Object();
Expand Down

0 comments on commit 75b15b8

Please sign in to comment.