From 3ba4cde3e4aed43862d244fa4b43c981c0a3da90 Mon Sep 17 00:00:00 2001 From: gc87 Date: Wed, 30 Mar 2022 19:03:55 +0800 Subject: [PATCH] Update the CA of mqtt by uploading --- ft/common.resource | 2 +- ft/persistence_test.robot | 5 +- include/connection/mqtt_client_intf.h | 2 +- plugins/mqtt/mqtt.json | 24 ++----- plugins/mqtt/util.c | 96 ++++++++++++++++++++++----- tests/mqtt_test.cc | 2 +- 6 files changed, 90 insertions(+), 41 deletions(-) diff --git a/ft/common.resource b/ft/common.resource index 5da49f5a..752e99e1 100644 --- a/ft/common.resource +++ b/ft/common.resource @@ -99,7 +99,7 @@ ${MQTT_CONFIG_HOST} 127.0.0.1 ${MQTT_CONFIG_PORT} ${1883} ${MQTT_CONFIG} {"client-id": "${MQTT_CLIENTID}", ... "ssl": false, "host": "${MQTT_CONFIG_HOST}", "port": ${MQTT_CONFIG_PORT}, -... "username": "", "password": "", "ca-path":"", "ca-file": ""} +... "username": "", "password": "", "ca":""} ${MODBUS_TCP_CONFIG} {"host": "127.0.0.1", "port": 60502, "connection_mode": 0} diff --git a/ft/persistence_test.robot b/ft/persistence_test.robot index 2a800a3d..52fb825d 100644 --- a/ft/persistence_test.robot +++ b/ft/persistence_test.robot @@ -93,7 +93,7 @@ Get the setted adapters information after stopping and restarting Neuron, it sho Node Setting ${modbus_tcp2_id} {"host": "127.0.0.1", "port": 502, "connection_mode": 0} ${mqtt_id} = Get Node ID ${NODE_MQTT} mqtt-1 - Node Setting ${mqtt_id} {"client-id":"upload123","ssl":false,"host":"127.0.0.1","port":1883,"username":"admin","password":"0000","ca-path":"","ca-file":""} + Node Setting ${mqtt_id} {"client-id":"upload123","ssl":false,"host":"127.0.0.1","port":1883,"username":"admin","password":"0000","ca":""} Neuron Stop Running ${process} ${process} = Neuron Start Running @@ -124,8 +124,7 @@ Get the setted adapters information after stopping and restarting Neuron, it sho Should Be Equal As Strings ${params}[host] 127.0.0.1 Should Be Equal As Strings ${params}[username] admin Should Be Equal As Strings ${params}[password] 0000 - Should Be Empty ${params}[ca-path] - Should Be Empty ${params}[ca-file] + Should Be Empty ${params}[ca] [Teardown] Neuron Stop Running ${process} diff --git a/include/connection/mqtt_client_intf.h b/include/connection/mqtt_client_intf.h index b2f60e75..a2cac421 100644 --- a/include/connection/mqtt_client_intf.h +++ b/include/connection/mqtt_client_intf.h @@ -53,8 +53,8 @@ typedef struct { int will_retain; /* TLS options */ char *ca_path; - char *cert; char *ca_file; + char *cert; char *key; char *keypass; } neu_mqtt_option_t; diff --git a/plugins/mqtt/mqtt.json b/plugins/mqtt/mqtt.json index 62903e48..e8a225a5 100644 --- a/plugins/mqtt/mqtt.json +++ b/plugins/mqtt/mqtt.json @@ -58,32 +58,18 @@ "length": 30 } }, - "ca-path": { - "name": "ca-path", - "description": "", + "ca": { + "name": "CA", + "description": "CA certificate file", "attribute": "required", - "type": "string", - "default": "", - "condition": { - "field": "ssl", - "value": true - }, - "valid": { - "length": 100 - } - }, - "ca-file": { - "name": "ca-file", - "description": "", - "attribute": "required", - "type": "string", + "type": "file", "condition": { "field": "ssl", "value": true }, "default": "", "valid": { - "length": 100 + "length": 81960 } } } \ No newline at end of file diff --git a/plugins/mqtt/util.c b/plugins/mqtt/util.c index 1ca30302..04be30f8 100644 --- a/plugins/mqtt/util.c +++ b/plugins/mqtt/util.c @@ -18,6 +18,7 @@ **/ #include +#include #include #include #include @@ -28,49 +29,89 @@ #include #include +#define MQTT_CERT_PATH "config" +#define MQTT_CA_FILE "mqtt_ca.crt" + void mqtt_option_uninit(neu_mqtt_option_t *option) { if (NULL != option->clientid) { free(option->clientid); + option->clientid = NULL; } if (NULL != option->topic) { free(option->topic); + option->topic = NULL; } if (NULL != option->respons_topic) { free(option->respons_topic); + option->respons_topic = NULL; } if (NULL != option->connection) { free(option->connection); + option->connection = NULL; } if (NULL != option->host) { free(option->host); + option->host = NULL; } if (NULL != option->port) { free(option->port); + option->port = NULL; } if (NULL != option->username) { free(option->username); + option->username = NULL; } if (NULL != option->password) { free(option->password); + option->password = NULL; } if (NULL != option->ca_path) { free(option->ca_path); + option->ca_path = NULL; } if (NULL != option->ca_file) { free(option->ca_file); + option->ca_file = NULL; } } +static int b64_file_store(const char *in, const char *file_name) +{ + unsigned char *result = NULL; + int out_len = 0; + result = neu_decode64(&out_len, in); + if (NULL == result) { + return -1; + } + + FILE *fp = fopen(file_name, "w+"); + if (NULL == fp) { + free(result); + return -1; + } + + size_t write_len = fwrite(result, sizeof(unsigned char), out_len, fp); + if (0 == write_len) { + free(result); + fclose(fp); + return -1; + } + + free(result); + fclose(fp); + return 0; +} + int mqtt_option_init(neu_config_t *config, neu_mqtt_option_t *option) { if (NULL == config || NULL == option) { @@ -85,15 +126,17 @@ int mqtt_option_init(neu_config_t *config, neu_mqtt_option_t *option) neu_json_elem_t port = { .name = "port", .t = NEU_JSON_INT }; neu_json_elem_t username = { .name = "username", .t = NEU_JSON_STR }; neu_json_elem_t password = { .name = "password", .t = NEU_JSON_STR }; - neu_json_elem_t ca_path = { .name = "ca-path", .t = NEU_JSON_STR }; - neu_json_elem_t ca_file = { .name = "ca-file", .t = NEU_JSON_STR }; + neu_json_elem_t ca = { .name = "ca", .t = NEU_JSON_STR, .v.val_str = NULL }; - ret = neu_parse_param(config->buf, &error, 8, &id, &ssl, &host, &port, - &username, &password, &ca_path, &ca_file); + ret = neu_parse_param(config->buf, &error, 7, &id, &ssl, &host, &port, + &username, &password, &ca); if (0 != ret) { return ret; } + char ca_path[PATH_MAX + 1] = { 0 }; + char ca_file[PATH_MAX + 1] = { 0 }; + // MQTT option option->clientid = NULL; // Use random id option->MQTT_version = 4; // Version 3.1.1 @@ -104,23 +147,44 @@ int mqtt_option_init(neu_config_t *config, neu_mqtt_option_t *option) option->connection = strdup("ssl://"); } + if (0 == strcmp(option->connection, "ssl://")) { + if (NULL == ca.v.val_str) { + return -1; + } + + if (0 == strlen(ca.v.val_str)) { + free(ca.v.val_str); + return -1; + } + + char workdir[PATH_MAX + 1] = { 0 }; + getcwd(workdir, sizeof(workdir)); + sprintf(ca_file, "%s/%s/%s", workdir, MQTT_CERT_PATH, MQTT_CA_FILE); + sprintf(ca_path, "%s/%s", workdir, MQTT_CERT_PATH); + + ret = b64_file_store(ca.v.val_str, ca_file); + free(ca.v.val_str); + + if (0 != ret) { + return -1; + } + } + option->host = host.v.val_str; int32_t p = (int) port.v.val_int; option->port = calloc(10, sizeof(char)); snprintf(option->port, 10, "%d", p); - option->clientid = id.v.val_str; - option->username = username.v.val_str; - option->password = password.v.val_str; - option->ca_path = ca_path.v.val_str; - option->ca_file = ca_file.v.val_str; - - if (0 == strcmp(option->connection, "ssl://") && NULL == option->ca_file) { - return -1; - } - - if (0 == strcmp(option->connection, "ssl://")) { } - + option->clientid = id.v.val_str; + option->username = username.v.val_str; + option->password = password.v.val_str; + option->ca_path = strdup(ca_path); + option->ca_file = strdup(ca_file); option->keepalive_interval = 20; option->clean_session = 1; + + if (NULL != ca.v.val_str) { + free(ca.v.val_str); + } + return 0; } diff --git a/tests/mqtt_test.cc b/tests/mqtt_test.cc index 85dd7884..3524c3c9 100644 --- a/tests/mqtt_test.cc +++ b/tests/mqtt_test.cc @@ -13,7 +13,7 @@ TEST(MQTTTest, mqtt_option_init_by_config) config.buf = (char *) "{\"node_id\":5,\"params\":{\"client-id\":" "\"upload123\",\"ssl\":false,\"host\":\"192.168.10." "116\",\"port\":1883,\"username\":\"\",\"password\":" - "\"\",\"ca-path\":\"\",\"ca-file\":\"\"}}"; + "\"\",\"ca\":\"\"}}"; int rc = mqtt_option_init(&config, &option); EXPECT_EQ(0, rc);