mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
mqtt tls only for esp32-S3, certificate input strips header/footer/CR/LF
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
|
||||||
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
||||||
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment, TextField } from '@mui/material';
|
import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment, TextField } from '@mui/material';
|
||||||
|
import { useRequest } from 'alova';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { ValidateFieldsError } from 'async-validator';
|
|
||||||
import type { FC } from 'react';
|
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import RestartMonitor from '../system/RestartMonitor';
|
import RestartMonitor from '../system/RestartMonitor';
|
||||||
import { useRequest } from 'alova';
|
import type { ValidateFieldsError } from 'async-validator';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import type { MqttSettings } from 'types';
|
import type { MqttSettings } from 'types';
|
||||||
import * as MqttApi from 'api/mqtt';
|
import * as MqttApi from 'api/mqtt';
|
||||||
@@ -187,17 +187,19 @@ const MqttSettingsForm: FC = () => {
|
|||||||
<MenuItem value={2}>2</MenuItem>
|
<MenuItem value={2}>2</MenuItem>
|
||||||
</TextField>
|
</TextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={6}>
|
{data.rootCA !== undefined && (
|
||||||
<ValidatedPasswordField
|
<Grid item xs={12} sm={6}>
|
||||||
name="rootCA"
|
<ValidatedPasswordField
|
||||||
label={LL.CERT()}
|
name="rootCA"
|
||||||
fullWidth
|
label={LL.CERT()}
|
||||||
variant="outlined"
|
fullWidth
|
||||||
value={data.rootCA}
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
value={data.rootCA}
|
||||||
margin="normal"
|
onChange={updateFormValue}
|
||||||
/>
|
margin="normal"
|
||||||
</Grid>
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
|
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export interface MqttSettings {
|
|||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
base: string;
|
base: string;
|
||||||
rootCA: string;
|
rootCA?: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
client_id: string;
|
client_id: string;
|
||||||
|
|||||||
@@ -47,18 +47,23 @@ void MqttSettingsService::begin() {
|
|||||||
if (_mqttClient != nullptr) {
|
if (_mqttClient != nullptr) {
|
||||||
delete _mqttClient;
|
delete _mqttClient;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
if (_state.rootCA.length() > 0) {
|
if (_state.rootCA.length() > 0) {
|
||||||
_mqttClient = static_cast<MqttClient *>(new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO));
|
_mqttClient = static_cast<MqttClient *>(new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO));
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setInsecure();
|
if (_state.rootCA == "insecure") {
|
||||||
String cert = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n";
|
static_cast<espMqttClientSecure *>(_mqttClient)->setInsecure();
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setCACert(retainCstr(cert.c_str(), &_retainedRootCA));
|
} else {
|
||||||
|
String certificate = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n";
|
||||||
|
static_cast<espMqttClientSecure *>(_mqttClient)->setCACert(retainCstr(certificate.c_str(), &_retainedRootCA));
|
||||||
|
}
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1));
|
static_cast<espMqttClientSecure *>(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1));
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1));
|
static_cast<espMqttClientSecure *>(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1));
|
||||||
} else {
|
return;
|
||||||
_mqttClient = static_cast<MqttClient *>(new espMqttClient(espMqttClientTypes::UseInternalTask::NO));
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1));
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1));
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
_mqttClient = static_cast<MqttClient *>(new espMqttClient(espMqttClientTypes::UseInternalTask::NO));
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1));
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::loop() {
|
void MqttSettingsService::loop() {
|
||||||
@@ -83,19 +88,23 @@ const char * MqttSettingsService::getClientId() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::setWill(const char * topic) {
|
void MqttSettingsService::setWill(const char * topic) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
if (_state.rootCA.length() > 0) {
|
if (_state.rootCA.length() > 0) {
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
static_cast<espMqttClientSecure *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
||||||
} else {
|
return;
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setWill(topic, 1, true, "offline");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::onMessage(espMqttClientTypes::OnMessageCallback callback) {
|
void MqttSettingsService::onMessage(espMqttClientTypes::OnMessageCallback callback) {
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
if (_state.rootCA.length() > 0) {
|
if (_state.rootCA.length() > 0) {
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->onMessage(callback);
|
static_cast<espMqttClientSecure *>(_mqttClient)->onMessage(callback);
|
||||||
} else {
|
return;
|
||||||
static_cast<espMqttClient *>(_mqttClient)->onMessage(callback);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->onMessage(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
espMqttClientTypes::DisconnectReason MqttSettingsService::getDisconnectReason() {
|
espMqttClientTypes::DisconnectReason MqttSettingsService::getDisconnectReason() {
|
||||||
@@ -113,7 +122,6 @@ void MqttSettingsService::onMqttConnect(bool sessionPresent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettingsService::onMqttDisconnect(espMqttClientTypes::DisconnectReason reason) {
|
void MqttSettingsService::onMqttDisconnect(espMqttClientTypes::DisconnectReason reason) {
|
||||||
// emsesp::EMSESP::logger().info("Disconnected from MQTT reason: %d", (uint8_t)reason);
|
|
||||||
_disconnectReason = reason;
|
_disconnectReason = reason;
|
||||||
if (!_disconnectedAt) {
|
if (!_disconnectedAt) {
|
||||||
_disconnectedAt = uuid::get_uptime();
|
_disconnectedAt = uuid::get_uptime();
|
||||||
@@ -136,14 +144,12 @@ void MqttSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||||||
case ARDUINO_EVENT_ETH_GOT_IP6:
|
case ARDUINO_EVENT_ETH_GOT_IP6:
|
||||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
||||||
if (_state.enabled) {
|
if (_state.enabled) {
|
||||||
// emsesp::EMSESP::logger().info("IPv4 Network connection found, starting MQTT client");
|
|
||||||
onConfigUpdated();
|
onConfigUpdated();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||||
if (_state.enabled) {
|
if (_state.enabled) {
|
||||||
// emsesp::EMSESP::logger().info("Network connection dropped, stopping MQTT client");
|
|
||||||
_mqttClient->disconnect(true);
|
_mqttClient->disconnect(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -156,12 +162,16 @@ void MqttSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||||||
bool MqttSettingsService::configureMqtt() {
|
bool MqttSettingsService::configureMqtt() {
|
||||||
// disconnect if connected
|
// disconnect if connected
|
||||||
if (_mqttClient->connected()) {
|
if (_mqttClient->connected()) {
|
||||||
|
emsesp::EMSESP::logger().info("Disconneting to configure");
|
||||||
_mqttClient->disconnect(true);
|
_mqttClient->disconnect(true);
|
||||||
}
|
}
|
||||||
// only connect if WiFi is connected and MQTT is enabled
|
// only connect if WiFi is connected and MQTT is enabled
|
||||||
if (_state.enabled && emsesp::EMSESP::system_.network_connected() && !_state.host.isEmpty()) {
|
if (_state.enabled && emsesp::EMSESP::system_.network_connected() && !_state.host.isEmpty()) {
|
||||||
|
// if (_state.enabled && !_state.host.isEmpty()) {
|
||||||
_reconfigureMqtt = false;
|
_reconfigureMqtt = false;
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
if (_state.rootCA.length() > 0) {
|
if (_state.rootCA.length() > 0) {
|
||||||
|
// emsesp::EMSESP::logger().info("Start secure MQTT with rootCA");
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
static_cast<espMqttClientSecure *>(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
||||||
if (_state.username.length() > 0) {
|
if (_state.username.length() > 0) {
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)
|
static_cast<espMqttClientSecure *>(_mqttClient)
|
||||||
@@ -173,27 +183,30 @@ bool MqttSettingsService::configureMqtt() {
|
|||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId));
|
static_cast<espMqttClientSecure *>(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId));
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
static_cast<espMqttClientSecure *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
static_cast<espMqttClientSecure *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
||||||
} else {
|
return _mqttClient->connect();
|
||||||
// emsesp::EMSESP::logger().info("Configuring MQTT client");
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
|
||||||
if (_state.username.length() > 0) {
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)
|
|
||||||
->setCredentials(retainCstr(_state.username.c_str(), &_retainedUsername),
|
|
||||||
retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword));
|
|
||||||
} else {
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword));
|
|
||||||
}
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId));
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
|
||||||
static_cast<espMqttClient *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
// emsesp::EMSESP::logger().info("Configuring MQTT client");
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port);
|
||||||
|
if (_state.username.length() > 0) {
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)
|
||||||
|
->setCredentials(retainCstr(_state.username.c_str(), &_retainedUsername),
|
||||||
|
retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword));
|
||||||
|
} else {
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword));
|
||||||
|
}
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId));
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setKeepAlive(_state.keepAlive);
|
||||||
|
static_cast<espMqttClient *>(_mqttClient)->setCleanSession(_state.cleanSession);
|
||||||
return _mqttClient->connect();
|
return _mqttClient->connect();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
|
void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
|
||||||
root["rootCA"] = settings.rootCA;
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
root["rootCA"] = settings.rootCA;
|
||||||
|
#endif
|
||||||
root["enabled"] = settings.enabled;
|
root["enabled"] = settings.enabled;
|
||||||
root["host"] = settings.host;
|
root["host"] = settings.host;
|
||||||
root["port"] = settings.port;
|
root["port"] = settings.port;
|
||||||
@@ -229,7 +242,9 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
|
|||||||
bool changed = false;
|
bool changed = false;
|
||||||
bool restartNeeded = false;
|
bool restartNeeded = false;
|
||||||
|
|
||||||
newSettings.rootCA = root["rootCA"] | "";
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
newSettings.rootCA = root["rootCA"] | "";
|
||||||
|
#endif
|
||||||
newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED;
|
newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED;
|
||||||
newSettings.host = root["host"] | FACTORY_MQTT_HOST;
|
newSettings.host = root["host"] | FACTORY_MQTT_HOST;
|
||||||
newSettings.port = root["port"] | FACTORY_MQTT_PORT;
|
newSettings.port = root["port"] | FACTORY_MQTT_PORT;
|
||||||
@@ -345,11 +360,18 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
|
|||||||
emsesp::EMSESP::mqtt_.set_publish_time_heartbeat(newSettings.publish_time_heartbeat);
|
emsesp::EMSESP::mqtt_.set_publish_time_heartbeat(newSettings.publish_time_heartbeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
// strip down to certificate only
|
||||||
|
newSettings.rootCA.replace("\r", "");
|
||||||
|
newSettings.rootCA.replace("\n", "");
|
||||||
|
newSettings.rootCA.replace("-----BEGIN CERTIFICATE-----", "");
|
||||||
|
newSettings.rootCA.replace("-----END CERTIFICATE-----", "");
|
||||||
|
newSettings.rootCA.replace(" ", "");
|
||||||
if (newSettings.rootCA != settings.rootCA) {
|
if (newSettings.rootCA != settings.rootCA) {
|
||||||
changed = true;
|
changed = true;
|
||||||
restartNeeded = true;
|
restartNeeded = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// save the new settings
|
// save the new settings
|
||||||
settings = newSettings;
|
settings = newSettings;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user