Skip to content
Snippets Groups Projects
Commit 93adfa9a authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Add new "Synchronet Broker" MQTT TLS type

With this, you don't need a username, password, PSK, or PSK ID,
certs, CAs, etc, and things just work by magic (when using the
Synchronet broker)
parent 7907e9a5
No related branches found
No related tags found
No related merge requests found
Pipeline #8119 passed
......@@ -102,6 +102,7 @@ static JSBool js_connect(JSContext* cx, uintN argc, jsval *arglist)
if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_mqtt_class)) == NULL)
return JS_FALSE;
scfg_t* scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
rc = JS_SUSPENDREQUEST(cx);
......@@ -126,6 +127,13 @@ static JSBool js_connect(JSContext* cx, uintN argc, jsval *arglist)
JSVALUE_TO_STRBUF(cx, argv[argn], password, sizeof password, NULL);
++argn;
}
if (p->cfg.tls.mode == MQTT_TLS_SBBS) {
username[0] = 0;
strlcpy(password, scfg->sys_pass, sizeof(password));
mosquitto_int_option(p->handle, MOSQ_OPT_PROTOCOL_VERSION, 5);
}
else
mosquitto_int_option(p->handle, MOSQ_OPT_PROTOCOL_VERSION, p->cfg.protocol_version);
mosquitto_username_pw_set(p->handle, *username ? username : NULL, *password ? password : NULL);
p->retval = MOSQ_ERR_SUCCESS;
......@@ -151,6 +159,30 @@ static JSBool js_connect(JSContext* cx, uintN argc, jsval *arglist)
NULL // ciphers (default)
);
}
else if (p->cfg.tls.mode == MQTT_TLS_SBBS) {
user_t user = {
.number = 1
};
if ((getuserdat(scfg, &user) == USER_SUCCESS)
&& user.number == 1
&& user_is_sysop(&user)) {
char hexpass[LEN_PASS * 2 + 1];
for (size_t i = 0; user.pass[i]; i++) {
const char hd[] = "0123456789ABCDEF";
hexpass[i*2] = hd[(((uint8_t *)user.pass)[i] & 0xf0) >> 4];
hexpass[i*2+1] = hd[user.pass[i] & 0x0f];
}
strlwr(user.alias);
p->retval = mosquitto_tls_psk_set(p->handle,
hexpass,
user.alias,
NULL // ciphers (default)
);
}
else
p->retval = MQTT_FAILURE;
}
if (p->retval == MOSQ_ERR_SUCCESS)
p->retval = mosquitto_connect_bind(p->handle,
broker_addr,
......
......@@ -380,10 +380,17 @@ int mqtt_connect(struct mqtt* mqtt, const char* bind_address)
char topic[128];
char* username = mqtt->cfg->mqtt.username;
char* password = mqtt->cfg->mqtt.password;
if (*username == '\0')
username = NULL;
if (*password == '\0')
password = NULL;
if (mqtt->cfg->mqtt.tls.mode == MQTT_TLS_SBBS) {
username = NULL;
password = mqtt->cfg->sys_pass;
mosquitto_int_option(mqtt->handle, MOSQ_OPT_PROTOCOL_VERSION, 5);
}
else
mosquitto_int_option(mqtt->handle, MOSQ_OPT_PROTOCOL_VERSION, mqtt->cfg->mqtt.protocol_version);
mosquitto_username_pw_set(mqtt->handle, username, password);
char value[128];
......@@ -416,6 +423,32 @@ int mqtt_connect(struct mqtt* mqtt, const char* bind_address)
if (result != MOSQ_ERR_SUCCESS)
return result;
}
else if (mqtt->cfg->mqtt.tls.mode == MQTT_TLS_SBBS) {
user_t user = {
.number = 1
};
int result = MQTT_FAILURE;
if ((getuserdat(mqtt->cfg, &user) == USER_SUCCESS)
&& user.number == 1
&& user_is_sysop(&user)) {
strlwr(user.pass);
char hexpass[LEN_PASS * 2 + 1];
for (size_t i = 0; user.pass[i]; i++) {
const char hd[] = "0123456789ABCDEF";
hexpass[i*2] = hd[(((uint8_t *)user.pass)[i] & 0xf0) >> 4];
hexpass[i*2+1] = hd[user.pass[i] & 0x0f];
}
strlwr(user.alias);
result = mosquitto_tls_psk_set(mqtt->handle,
hexpass,
user.alias,
NULL // ciphers (default)
);
}
if (result != MOSQ_ERR_SUCCESS)
return result;
}
return mosquitto_connect_bind(mqtt->handle,
mqtt->cfg->mqtt.broker_addr,
mqtt->cfg->mqtt.broker_port,
......
......@@ -159,22 +159,24 @@ void mqtt_cfg()
static char* mqttVersion[]
= { "3.1.0", "3.1.1", "5.0", NULL };
static char* mqttTlsMode[]
= { "Off", "Certificate", "Pre-Shared-Key", NULL };
= { "Off", "Certificate", "Pre-Shared-Key", "Synchronet Broker", NULL };
while (1) {
int i = 0;
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Enabled", cfg.mqtt.enabled ? "Yes" : "No");
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Broker Address", cfg.mqtt.broker_addr);
snprintf(opt[i++], MAX_OPLN, "%-20s%u", "Broker Port", cfg.mqtt.broker_port);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Username", cfg.mqtt.username);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Password", cfg.mqtt.password);
snprintf(opt[i++], MAX_OPLN, "%-20s%u seconds", "Keep-alive", cfg.mqtt.keepalive);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Protocol Version", mqttVersion[cfg.mqtt.protocol_version - 3]);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Publish Verbosity", cfg.mqtt.verbose ? "High" : "Low");
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Publish QOS", mqttQOS[cfg.mqtt.publish_qos]);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Subscribe QOS", mqttQOS[cfg.mqtt.subscribe_qos]);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Log Level", logLevelStringList[cfg.mqtt.log_level]);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "TLS (encryption)", mqttTlsMode[cfg.mqtt.tls.mode]);
if (cfg.mqtt.tls.mode != MQTT_TLS_SBBS) {
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Username", cfg.mqtt.username);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Password", cfg.mqtt.password);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Protocol Version", mqttVersion[cfg.mqtt.protocol_version - 3]);
}
if (cfg.mqtt.tls.mode == MQTT_TLS_CERT) {
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "CA Cert", cfg.mqtt.tls.cafile);
snprintf(opt[i++], MAX_OPLN, "%-20s%s", "Client Cert", cfg.mqtt.tls.certfile);
......@@ -238,48 +240,25 @@ void mqtt_cfg()
cfg.mqtt.broker_port = atoi(str);
break;
case 3:
uifc.helpbuf =
"~ User name ~\n"
"\n"
"Enter the user name to use for authenticating with the MQTT Broker.\n"
;
uifc.input(WIN_MID | WIN_SAV, 0, 0, "User name for authentication"
, cfg.mqtt.username, sizeof(cfg.mqtt.username) - 1, K_EDIT);
break;
case 4:
uifc.helpbuf =
"~ Password ~\n"
"\n"
"Enter the user password to use for authenticating with the MQTT Broker.\n"
;
uifc.input(WIN_MID | WIN_SAV, 0, 0, "Password for authentication"
, cfg.mqtt.password, sizeof(cfg.mqtt.password) - 1, K_EDIT);
break;
case 5:
SAFEPRINTF(str, "%u", cfg.mqtt.keepalive);
if (uifc.input(WIN_MID | WIN_SAV, 0, 0, "Seconds to keep inactive connection alive"
, str, 5, K_EDIT | K_NUMBER) > 0 && atoi(str) >= 5)
cfg.mqtt.keepalive = atoi(str);
break;
case 6:
i = cfg.mqtt.protocol_version - 3;
if ((i = uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &i, 0, "Protocol Version", mqttVersion)) >= 0)
cfg.mqtt.protocol_version = 3 + i;
break;
case 7:
case 4:
cfg.mqtt.verbose = !cfg.mqtt.verbose;
break;
case 8:
case 5:
i = cfg.mqtt.publish_qos;
if ((i = uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &i, 0, "Quality of Service for Publishing", mqttQOS)) >= 0)
cfg.mqtt.publish_qos = i;
break;
case 9:
case 6:
i = cfg.mqtt.subscribe_qos;
if ((i = uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &i, 0, "Quality of Service for Subscriptions", mqttQOS)) >= 0)
cfg.mqtt.subscribe_qos = i;
break;
case 10:
case 7:
uifc.helpbuf =
"~ MQTT Log Level ~\n"
"\n"
......@@ -292,14 +271,15 @@ void mqtt_cfg()
if (i >= 0 && i <= LOG_DEBUG)
cfg.mqtt.log_level = i;
break;
case 11:
case 8:
uifc.helpbuf =
"~ Encryption via TLS ~\n"
"\n"
"MQTT traffic may be encrypted via TLS using either:\n"
"MQTT traffic may be encrypted via TLS using one of:\n"
"\n"
" - `Certificate-based` authentication (mutual-auth optionally supported)\n"
" - `Pre-Shared-Key` authentication\n"
" - `Synchronet Broker` use internal Synchronet authentication\n"
"\n"
"When TLS is used, the default MQTT port is `8883`.\n"
;
......@@ -308,6 +288,29 @@ void mqtt_cfg()
if (i >= 0)
cfg.mqtt.tls.mode = i;
break;
case 9:
uifc.helpbuf =
"~ User name ~\n"
"\n"
"Enter the user name to use for authenticating with the MQTT Broker.\n"
;
uifc.input(WIN_MID | WIN_SAV, 0, 0, "User name for authentication"
, cfg.mqtt.username, sizeof(cfg.mqtt.username) - 1, K_EDIT);
break;
case 10:
uifc.helpbuf =
"~ Password ~\n"
"\n"
"Enter the user password to use for authenticating with the MQTT Broker.\n"
;
uifc.input(WIN_MID | WIN_SAV, 0, 0, "Password for authentication"
, cfg.mqtt.password, sizeof(cfg.mqtt.password) - 1, K_EDIT);
break;
case 11:
i = cfg.mqtt.protocol_version - 3;
if ((i = uifc.list(WIN_MID | WIN_SAV, 0, 0, 0, &i, 0, "Protocol Version", mqttVersion)) >= 0)
cfg.mqtt.protocol_version = 3 + i;
break;
case 12:
if (cfg.mqtt.tls.mode == MQTT_TLS_CERT) {
uifc.helpbuf =
......
......@@ -387,7 +387,8 @@ struct mqtt_cfg {
enum {
MQTT_TLS_DISABLED,
MQTT_TLS_CERT,
MQTT_TLS_PSK
MQTT_TLS_PSK,
MQTT_TLS_SBBS
} mode;
char cafile[256];
char certfile[256];
......
......@@ -228,7 +228,7 @@ bool read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen)
cfg->mqtt.subscribe_qos = iniGetIntInRange(section, NULL, "subscribe_qos", 0, 2, 2);
cfg->mqtt.protocol_version = iniGetIntInRange(section, NULL, "protocol_version", 3, 4, 5);
cfg->mqtt.log_level = iniGetLogLevel(section, NULL, "LogLevel", LOG_INFO);
cfg->mqtt.tls.mode = iniGetIntInRange(section, NULL, "tls_mode", MQTT_TLS_DISABLED, MQTT_TLS_DISABLED, MQTT_TLS_PSK);
cfg->mqtt.tls.mode = iniGetIntInRange(section, NULL, "tls_mode", MQTT_TLS_DISABLED, MQTT_TLS_DISABLED, MQTT_TLS_SBBS);
SAFECOPY(cfg->mqtt.tls.cafile, iniGetString(section, NULL, "tls_cafile", "", value));
SAFECOPY(cfg->mqtt.tls.certfile, iniGetString(section, NULL, "tls_certfile", "", value));
SAFECOPY(cfg->mqtt.tls.keyfile, iniGetString(section, NULL, "tls_keyfile", "", value));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment