# HG changeset patch # User Edouard Tisserant # Date 1724321731 -7200 # Node ID 482452574fb4c8d1099b242fffe304ca478b34ed # Parent 19f8192b7d6865ec92c6b01b238410f6f23f73e2 MQTT: add SSL support diff -r 19f8192b7d68 -r 482452574fb4 mqtt/client.py --- a/mqtt/client.py Thu Aug 08 14:56:13 2024 +0200 +++ b/mqtt/client.py Thu Aug 22 12:15:31 2024 +0200 @@ -3,6 +3,7 @@ from __future__ import absolute_import import os +import re from editors.ConfTreeNodeEditor import ConfTreeNodeEditor from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT @@ -41,8 +42,15 @@ - - + + + + + + + + + @@ -96,12 +104,23 @@ paramList = authParams.get(AuthType, None) if paramList: for name,default in paramList: - value = cfg("AuthType."+name) + + # Translate internal config naming into user config naming + displayed_name = {"KeyStore" : "Client_certificate", + "TrustStore" : "Broker_certificate", + "Verify" : "Verify_hostname"}.get(name, name) + + value = cfg("AuthType." + displayed_name) if value == "" or value is None: value = default - # cryptomaterial is expected to be in project's user provide file directory - if name in ["Certificate","PrivateKey"]: - value = os.path.join(self.GetCTRoot()._getProjectFilesPath(), value) + + if value is not None: + # cryptomaterial is expected to be in project's user provided file directory + + # User input may contain char incompatible with C string literal escaping + if name in ["User","Password","TrustStore","KeyStore","Broker_URI","Client_ID"]: + value = re.sub(r'([\"\\])', r'\\\1', value) + res[name] = value return res @@ -123,7 +142,7 @@ #include "beremiz.h" """ config = self.GetConfig() - c_code += self.modeldata.GenerateC(c_path, locstr, self.GetConfig()) + c_code += self.modeldata.GenerateC(c_path, locstr, config) with open(c_path, 'w') as c_file: c_file.write(c_code) diff -r 19f8192b7d68 -r 482452574fb4 mqtt/mqtt_client_gen.py --- a/mqtt/mqtt_client_gen.py Thu Aug 08 14:56:13 2024 +0200 +++ b/mqtt/mqtt_client_gen.py Thu Aug 22 12:15:31 2024 +0200 @@ -66,10 +66,12 @@ directions = ["input", "output"] +# expected configuration entries with internal default value authParams = { "x509":[ - ("Certificate", "certificate.der"), - ("PrivateKey", "private_key.pem")], + ("Verify", True), + ("KeyStore", None), + ("TrustStore", None)], "UserPassword":[ ("User", None), ("Password", None)]} @@ -350,9 +352,15 @@ #define USE_MQTT_5""".format(**config) AuthType = config["AuthType"] + print(config) if AuthType == "x509": + for k in ["KeyStore","TrustStore"]: + config[k] = '"'+config[k]+'"' if config[k] else "NULL" formatdict["init"] += """ - INIT_x509("{PrivateKey}", "{Certificate}")""".format(**config) + INIT_x509({Verify:d}, {KeyStore}, {TrustStore})""".format(**config) + if AuthType == "PSK": + formatdict["init"] += """ + INIT_PSK("{Secret}", "{ID}")""".format(**config) elif AuthType == "UserPassword": formatdict["init"] += """ INIT_UserPassword("{User}", "{Password}")""".format(**config) diff -r 19f8192b7d68 -r 482452574fb4 mqtt/mqtt_template.c --- a/mqtt/mqtt_template.c Thu Aug 08 14:56:13 2024 +0200 +++ b/mqtt/mqtt_template.c Thu Aug 22 12:15:31 2024 +0200 @@ -56,6 +56,8 @@ static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; #endif +MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer; + /* condition to quit publish thread */ static int MQTT_stop_thread = 0; @@ -176,9 +178,19 @@ #define INIT_NoAuth() \ LogInfo("MQTT Init no auth\n"); -#define INIT_x509(PrivateKey, Certificate) \ - LogInfo("MQTT Init x509 %s,%s\n", PrivateKey, Certificate); - /* TODO */ +#define INIT_x509(Verify, KeyStore, TrustStore) \ + LogInfo("MQTT Init x509 with %s,%s\n", KeyStore, TrustStore) \ + ssl_opts.verify = Verify; \ + ssl_opts.keyStore = KeyStore; \ + ssl_opts.trustStore = TrustStore; \ + conn_opts.ssl = &ssl_opts; + +#define INIT_PSK(Secret, ID) \ + LogError("MQTT PSK NOT IMPLEMENTED\n") \ + /* LogInfo("MQTT Init PSK for ID %s\n", ID) */ \ + /* ssl_opts.ssl_psk_cb = TODO; */ \ + /* ssl_opts.ssl_psk_context = TODO; */ \ + conn_opts.ssl = &ssl_opts; #define INIT_UserPassword(User, Password) \ LogInfo("MQTT Init UserPassword %s,%s\n", User, Password); \