From 50394fa65f774a842d6356a587f285c5493e1447 Mon Sep 17 00:00:00 2001 From: hxy7yx <1595670487@qq.com> Date: Mon, 22 Jun 2026 02:00:49 -0700 Subject: [PATCH] fix(mqtt): require CA for TLS and verify broker certificates --- plugins/monitor/monitor.json | 2 +- plugins/monitor/monitor_config.c | 8 ++--- plugins/mqtt/aws-iot.json | 2 +- plugins/mqtt/azure-iot.json | 4 --- plugins/mqtt/azure_iot_plugin.c | 57 +++++++++++--------------------- plugins/mqtt/mqtt.json | 2 +- plugins/mqtt/mqtt_config.c | 8 ++--- src/connection/mqtt_client.c | 27 ++++++++------- 8 files changed, 44 insertions(+), 66 deletions(-) diff --git a/plugins/monitor/monitor.json b/plugins/monitor/monitor.json index 3aded419..da5c74fc 100644 --- a/plugins/monitor/monitor.json +++ b/plugins/monitor/monitor.json @@ -111,7 +111,7 @@ "name_zh": "CA 证书", "description": "CA certificate which signs the server certificate", "description_zh": "签发服务器证书的 CA 证书", - "attribute": "optional", + "attribute": "required", "type": "file", "condition": { "field": "ssl", diff --git a/plugins/monitor/monitor_config.c b/plugins/monitor/monitor_config.c index 8a54ee62..9d0ff6da 100644 --- a/plugins/monitor/monitor_config.c +++ b/plugins/monitor/monitor_config.c @@ -84,11 +84,11 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting, return 0; } - // ca, optional + // ca, required when ssl enabled ret = neu_parse_param(setting, NULL, 1, ca); if (0 != ret) { - plog_notice(plugin, "setting no ca"); - return 0; + plog_error(plugin, "setting no ca, required when ssl enabled"); + return -1; } if (0 != decode_b64_param(plugin, ca)) { @@ -106,7 +106,7 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting, return -1; } - // key, required if cert enable + // key, required if cert is set ret = parse_b64_param(plugin, setting, key); if (0 != ret) { return -1; diff --git a/plugins/mqtt/aws-iot.json b/plugins/mqtt/aws-iot.json index 237e8065..04a81d67 100644 --- a/plugins/mqtt/aws-iot.json +++ b/plugins/mqtt/aws-iot.json @@ -206,7 +206,7 @@ "name_zh": "根 CA 证书", "description": "AWS IoT data endpoint root CA certificate", "description_zh": "AWS IoT 设备数据终端节点根 CA 证书", - "attribute": "optional", + "attribute": "required", "type": "file", "condition": { "field": "ssl", diff --git a/plugins/mqtt/azure-iot.json b/plugins/mqtt/azure-iot.json index cdc373e7..67c2654a 100644 --- a/plugins/mqtt/azure-iot.json +++ b/plugins/mqtt/azure-iot.json @@ -165,10 +165,6 @@ "description_zh": "签发服务器证书的 CA 证书", "attribute": "required", "type": "file", - "condition": { - "field": "auth", - "value": 1 - }, "valid": { "length": 81960 } diff --git a/plugins/mqtt/azure_iot_plugin.c b/plugins/mqtt/azure_iot_plugin.c index 014f43a8..5d4e40d4 100644 --- a/plugins/mqtt/azure_iot_plugin.c +++ b/plugins/mqtt/azure_iot_plugin.c @@ -103,41 +103,6 @@ static int parse_cache_params(neu_plugin_t *plugin, const char *setting, return 0; } -static int parse_ssl_params(neu_plugin_t *plugin, const char *setting, - neu_json_elem_t *ca, neu_json_elem_t *cert, - neu_json_elem_t *key) -{ - // ca, required - int ret = neu_parse_param(setting, NULL, 1, ca); - if (0 != ret) { - plog_notice(plugin, "setting no ca"); - return -1; - } - - if (0 != decode_b64_param(plugin, ca)) { - return -1; - } - - // cert, required - ret = neu_parse_param(setting, NULL, 1, cert); - if (0 != ret) { - plog_notice(plugin, "setting no cert"); - return -1; - } - - if (0 != decode_b64_param(plugin, cert)) { - return -1; - } - - // key, required - ret = parse_b64_param(plugin, setting, key); - if (0 != ret) { - return -1; - } - - return 0; -} - static int azure_parse_config(neu_plugin_t *plugin, const char *setting, mqtt_config_t *config) { @@ -212,10 +177,28 @@ static int azure_parse_config(neu_plugin_t *plugin, const char *setting, password.v.val_str = strdup(""); } + // ca, required for TLS (SSL is always enabled) + ret = neu_parse_param(setting, NULL, 1, &ca); + if (0 != ret) { + plog_error(plugin, "setting no ca"); + goto error; + } + if (0 != decode_b64_param(plugin, &ca)) { + goto error; + } + if (AUTH_CERT == auth.v.val_int) { - ret = parse_ssl_params(plugin, setting, &ca, &cert, &key); + ret = neu_parse_param(setting, NULL, 1, &cert); if (0 != ret) { - plog_error(plugin, "setting certificates fail"); + plog_error(plugin, "setting no cert"); + goto error; + } + if (0 != decode_b64_param(plugin, &cert)) { + goto error; + } + ret = parse_b64_param(plugin, setting, &key); + if (0 != ret) { + plog_error(plugin, "setting no key"); goto error; } } diff --git a/plugins/mqtt/mqtt.json b/plugins/mqtt/mqtt.json index 9d1829d2..814fda74 100644 --- a/plugins/mqtt/mqtt.json +++ b/plugins/mqtt/mqtt.json @@ -306,7 +306,7 @@ "name_zh": "CA 证书", "description": "CA certificate which signs the server certificate", "description_zh": "签发服务器证书的 CA 证书", - "attribute": "optional", + "attribute": "required", "type": "file", "condition": { "field": "ssl", diff --git a/plugins/mqtt/mqtt_config.c b/plugins/mqtt/mqtt_config.c index 422cfcde..5f84a6d0 100644 --- a/plugins/mqtt/mqtt_config.c +++ b/plugins/mqtt/mqtt_config.c @@ -81,11 +81,11 @@ static int parse_ssl_params(neu_plugin_t *plugin, const char *setting, return 0; } - // ca, optional + // ca, required when ssl enabled ret = neu_parse_param(setting, NULL, 1, ca); if (0 != ret) { - plog_notice(plugin, "setting no ca"); - return 0; + plog_error(plugin, "setting no ca, required when ssl enabled"); + return -1; } if (0 != decode_b64_param(plugin, ca)) { @@ -103,7 +103,7 @@ static int parse_ssl_params(neu_plugin_t *plugin, const char *setting, return -1; } - // key, required if cert enable + // key, required if cert is set ret = parse_b64_param(plugin, setting, key); if (0 != ret) { return -1; diff --git a/src/connection/mqtt_client.c b/src/connection/mqtt_client.c index 66a5cce1..af1c41fd 100644 --- a/src/connection/mqtt_client.c +++ b/src/connection/mqtt_client.c @@ -1587,20 +1587,19 @@ int neu_mqtt_client_set_tls(neu_mqtt_client_t *client, bool enabled, goto end; } - if (ca && (rv = nng_tls_config_ca_chain(cfg, ca, NULL)) != 0) { + if (NULL == ca || '\0' == ca[0]) { + log(error, "tls enabled but no ca"); + rv = -1; + goto end; + } + + if ((rv = nng_tls_config_ca_chain(cfg, ca, NULL)) != 0) { log(error, "nng_tls_config_ca_chain fail: %s", nng_strerror(rv)); rv = -1; goto end; } if (cert != NULL && key != NULL) { - if ((rv = nng_tls_config_auth_mode(cfg, NNG_TLS_AUTH_MODE_REQUIRED)) != - 0) { - log(error, "nng_tls_config_auth_mode fail: %s", nng_strerror(rv)); - rv = -1; - goto end; - } - if (keypass) { pass[0] = write_string_to_random_file(((char **) keypass)[0]); pass[1] = write_string_to_random_file(((char **) keypass)[1]); @@ -1612,12 +1611,12 @@ int neu_mqtt_client_set_tls(neu_mqtt_client_t *client, bool enabled, rv = -1; goto end; } - } else { - if ((rv = nng_tls_config_auth_mode(cfg, NNG_TLS_AUTH_MODE_NONE)) != 0) { - log(error, "nng_tls_config_auth_mode fail: %s", nng_strerror(rv)); - rv = -1; - goto end; - } + } + + if ((rv = nng_tls_config_auth_mode(cfg, NNG_TLS_AUTH_MODE_REQUIRED)) != 0) { + log(error, "nng_tls_config_auth_mode fail: %s", nng_strerror(rv)); + rv = -1; + goto end; } end: