From 253f35cc0a316f5c361a21a91e4c696175a7994f Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Thu, 7 Nov 2019 15:14:02 +0800 Subject: [PATCH] TLS support for MQTT and put the config file in the UserDir --- qt-ozwdaemon/main.cpp | 55 ++++++++++++++++++++++++++-------- qt-ozwdaemon/mqttpublisher.cpp | 41 ++++++++++++++++--------- qt-ozwdaemon/mqttpublisher.h | 4 +-- 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/qt-ozwdaemon/main.cpp b/qt-ozwdaemon/main.cpp index 7383d74..560a838 100644 --- a/qt-ozwdaemon/main.cpp +++ b/qt-ozwdaemon/main.cpp @@ -75,8 +75,24 @@ int main(int argc, char *argv[]) ); parser.addOption(MQTTPort); + + QCommandLineOption MQTTInstance(QStringList() << "mqtt-instance", + "OpenZWave Instance Number - Defaults to 1", + "Number" + ); + + parser.addOption(MQTTInstance); + + QCommandLineOption MQTTTLS(QStringList() << "mqtt-tls", + "Enable TLS Encryption to MQTT Server" + ); + + parser.addOption(MQTTTLS); + #endif + + parser.process(a); if (!parser.isSet(serialPort)) { fputs(qPrintable("Serial Port is Required\n"), stderr); @@ -84,15 +100,6 @@ int main(int argc, char *argv[]) fputs(qPrintable(parser.helpText()), stderr); exit(-1); } - QSettings settings; -#ifdef HAVE_MQTT - if (parser.isSet(MQTTServer)) { - settings.setValue("MQTTServer", parser.value(MQTTServer)); - } - if (parser.isSet(MQTTPort)) { - settings.setValue("MQTTPort", parser.value(MQTTPort).toInt()); - } -#endif #if 0 QLoggingCategory::setFilterRules("qt.remoteobjects.debug=true\n" @@ -109,7 +116,8 @@ int main(int argc, char *argv[]) if (parser.isSet(configDir)) PossibleDBPaths << parser.value(configDir); PossibleDBPaths << "./config/"; - PossibleDBPaths << settings.value("openzwave/ConfigPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); + PossibleDBPaths << QDir::toNativeSeparators("../../../config/"); + //PossibleDBPaths << settings.value("openzwave/ConfigPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); PossibleDBPaths << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); QString path, dbPath, userPath; @@ -129,7 +137,8 @@ int main(int argc, char *argv[]) if (parser.isSet(userDir)) PossibleDBPaths << parser.value(userDir); PossibleDBPaths << "./config/"; - PossibleDBPaths << settings.value("openzwave/UserPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); + PossibleDBPaths << QDir::toNativeSeparators("../../../config/"); +// PossibleDBPaths << settings.value("openzwave/UserPath", QDir::toNativeSeparators("../../../config/")).toString().append("/"); PossibleDBPaths << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); foreach(path, PossibleDBPaths) { @@ -157,6 +166,28 @@ int main(int argc, char *argv[]) qDebug() << "DBPath: " << dbPath; qDebug() << "userPath: " << userPath; + QSettings settings(userPath.append("/ozwdaemon.ini"), QSettings::IniFormat); + + +#ifdef HAVE_MQTT + if (parser.isSet(MQTTServer)) { + settings.setValue("MQTTServer", parser.value(MQTTServer)); + } + if (parser.isSet(MQTTPort)) { + settings.setValue("MQTTPort", parser.value(MQTTPort).toInt()); + } + if (parser.isSet(MQTTInstance)) { + settings.setValue("Instance", parser.value(MQTTInstance).toInt()); + } + if (parser.isSet(MQTTTLS)) { + qDebug() << "mqtt tls set"; + settings.setValue("MQTTTLS", true); + } else { + settings.setValue("MQTTTLS", false); + } +#endif + + QTOZWOptions options(QTOZWOptions::Local); options.setUserPath(userPath); @@ -166,7 +197,7 @@ int main(int argc, char *argv[]) qtozwdaemon daemon; #ifdef HAVE_MQTT - mqttpublisher mqttpublisher; + mqttpublisher mqttpublisher(&settings); mqttpublisher.setOZWDaemon(&daemon); #endif daemon.setSerialPort(parser.value(serialPort)); diff --git a/qt-ozwdaemon/mqttpublisher.cpp b/qt-ozwdaemon/mqttpublisher.cpp index 203b6ef..5587f6b 100644 --- a/qt-ozwdaemon/mqttpublisher.cpp +++ b/qt-ozwdaemon/mqttpublisher.cpp @@ -240,12 +240,13 @@ bool mqttValueIDModel::setData(quint64 vidKey, QVariant data) { -mqttpublisher::mqttpublisher(QObject *parent) : QObject(parent) +mqttpublisher::mqttpublisher(QSettings *settings, QObject *parent) : QObject(parent) { - + this->settings = settings; this->m_client = new QMqttClient(this); - this->m_client->setHostname(settings.value("MQTTServer", "127.0.0.1").toString()); - this->m_client->setPort(static_cast(settings.value("MQTTPort", 1883).toInt())); + this->m_client->setHostname(settings->value("MQTTServer", "127.0.0.1").toString()); + this->m_client->setPort(static_cast(settings->value("MQTTPort", 1883).toInt())); + /* setup the Commands */ this->m_commands = new MqttCommands(this); @@ -277,6 +278,7 @@ void mqttpublisher::cleanTopics(QMqttMessage msg) { qCDebug(ozwmp) << "Topics: " << msg.topic().name(); QJsonDocument jsmsg = QJsonDocument::fromJson(msg.payload()); if (msg.topic().name() == getTopic("status")) { + qCDebug(ozwmp) << jsmsg.toJson(); /* when our status message is anything other than Offline, drop the Subscription */ if (jsmsg["Status"].toString() != "Offline") { qCDebug(ozwmp) << "Unsubscribing from Topic Cleanup"; @@ -298,6 +300,10 @@ void mqttpublisher::cleanTopics(QMqttMessage msg) { void mqttpublisher::brokerError(QMqttClient::ClientError error) { qCWarning(ozwmp) << "Broker Error" << error; + if (settings->value("MQTTTLS").toBool() == true) { + qCWarning(ozwmp) << qobject_cast(this->m_client->transport())->errorString(); + } + } @@ -398,32 +404,32 @@ bool mqttpublisher::setValue(quint64 vidKey, QVariant data) { QString mqttpublisher::getTopic(QString topic) { if (!topic.endsWith('#') && !topic.endsWith('/')) topic = topic.append("/"); - return QString(MQTT_OZW_TOP_TOPIC).arg(settings.value("Instance", 1).toInt()).append(topic); + return QString(MQTT_OZW_TOP_TOPIC).arg(settings->value("Instance", 1).toInt()).append(topic); } QString mqttpublisher::getNodeTopic(QString topic, quint8 node) { QString t(MQTT_OZW_TOP_TOPIC); - t = t.arg(settings.value("Instance", 1).toInt()); + t = t.arg(settings->value("Instance", 1).toInt()); t.append(topic.arg(static_cast(node))); return t; } QString mqttpublisher::getValueTopic(QString topic, quint8 node, quint64 vid) { QString t(MQTT_OZW_TOP_TOPIC); - t = t.arg(settings.value("Instance", 1).toInt()); + t = t.arg(settings->value("Instance", 1).toInt()); t.append(topic.arg(static_cast(node)).arg(static_cast(vid))); return t; } QString mqttpublisher::getCommandTopic() { QString t(MQTT_OZW_TOP_TOPIC); - t = t.arg(settings.value("Instance", 1).toInt()); + t = t.arg(settings->value("Instance", 1).toInt()); t.append(QString(MQTT_OZW_COMMAND_TOPIC)); return t; } QString mqttpublisher::getCommandResponseTopic(QString cmd) { QString t(MQTT_OZW_TOP_TOPIC); - t = t.arg(settings.value("Instance", 1).toInt()); + t = t.arg(settings->value("Instance", 1).toInt()); t.append(QString(MQTT_OZW_RESPONSE_TOPIC).arg(cmd)); return t; } @@ -466,15 +472,22 @@ void mqttpublisher::setOZWDaemon(qtozwdaemon *ozwdaemon) { connect(manager, &QTOZWManager::stopped, this, &mqttpublisher::stopped); this->m_currentStartTime = QDateTime::currentDateTime(); - this->m_client->connectToHost(); + if (settings->value("MQTTTLS").toBool() == true) { + this->m_client->connectToHostEncrypted(); + } else { + this->m_client->connectToHost(); + } } +#include + void mqttpublisher::updateLogStateChange() { - const QString content = QDateTime::currentDateTime().toString() - + QLatin1String(": State Change: " ) - + QString::number(m_client->state()); - qCDebug(ozwmp) << content; + qCDebug(ozwmp) << "State Change" << m_client->state(); + if (settings->value("MQTTTLS").toBool() == true && this->m_client->state() == QMqttClient::ClientState::Connecting) { + QSslSocket *socket = qobject_cast(this->m_client->transport()); + socket->setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone); + } if (this->m_client->state() == QMqttClient::ClientState::Connected) { this->m_cleanTopicSubscription = this->m_client->subscribe(QMqttTopicFilter(getTopic("#"))); connect(this->m_cleanTopicSubscription, &QMqttSubscription::messageReceived, this, &mqttpublisher::cleanTopics); diff --git a/qt-ozwdaemon/mqttpublisher.h b/qt-ozwdaemon/mqttpublisher.h index f16b601..06e2206 100644 --- a/qt-ozwdaemon/mqttpublisher.h +++ b/qt-ozwdaemon/mqttpublisher.h @@ -46,7 +46,7 @@ class mqttpublisher : public QObject { Q_OBJECT public: - explicit mqttpublisher(QObject *parent = nullptr); + explicit mqttpublisher(QSettings *setting, QObject *parent = nullptr); void setOZWDaemon(qtozwdaemon *ozwdaemon); QTOZWManager *getQTOZWManager(); void sendCommandUpdate(QString, QJsonObject); @@ -117,7 +117,7 @@ private: QMqttClient *m_client; qtozwdaemon *m_qtozwdeamon; - QSettings settings; + QSettings *settings; QTimer m_statsTimer; MqttCommands *m_commands; QMqttSubscription *m_cleanTopicSubscription;