From 6067d72c10db89f7e0af17d2e8dc3804ea7e6554 Mon Sep 17 00:00:00 2001 From: rajani Date: Mon, 5 Dec 2022 20:35:42 -0600 Subject: [PATCH 1/7] modifications with mqtt tls use case... --- src/mqtt/mqtt_client_impl.hpp | 23 +--------- src/mqtt/mqtt_server_impl.hpp | 84 ++++++++++++++++++++++++----------- test/mqtt_isolated_test.cpp | 80 ++++++++++++++++----------------- 3 files changed, 99 insertions(+), 88 deletions(-) diff --git a/src/mqtt/mqtt_client_impl.hpp b/src/mqtt/mqtt_client_impl.hpp index 77479d8c0..50dbf20b3 100644 --- a/src/mqtt/mqtt_client_impl.hpp +++ b/src/mqtt/mqtt_client_impl.hpp @@ -379,17 +379,7 @@ namespace mtconnect { if (cacert) { m_client->get_ssl_context().load_verify_file(*cacert); - } - - auto private_key = GetOption(m_options, configuration::MqttPrivateKey); - auto cert = GetOption(m_options, configuration::MqttCert); - if (private_key && cert) - { - m_client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); - m_client->get_ssl_context().use_certificate_chain_file(*cert); - m_client->get_ssl_context().use_private_key_file(*private_key, - boost::asio::ssl::context::pem); - } + } } return m_client; @@ -419,16 +409,7 @@ namespace mtconnect { if (cacert) { m_client->get_ssl_context().load_verify_file(*cacert); - } - auto private_key = GetOption(m_options, configuration::MqttPrivateKey); - auto cert = GetOption(m_options, configuration::MqttCert); - if (private_key && cert) - { - m_client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); - m_client->get_ssl_context().use_certificate_chain_file(*cert); - m_client->get_ssl_context().use_private_key_file(*private_key, - boost::asio::ssl::context::pem); - } + } } return m_client; diff --git a/src/mqtt/mqtt_server_impl.hpp b/src/mqtt/mqtt_server_impl.hpp index 6b2dab9ac..88e0a4599 100644 --- a/src/mqtt/mqtt_server_impl.hpp +++ b/src/mqtt/mqtt_server_impl.hpp @@ -300,18 +300,38 @@ namespace mtconnect { boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12); ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::single_dh_use); - auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); - auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); - ctx.use_certificate_chain_file(*serverCert); - //ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); - ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); - - if (HasOption(m_options, configuration::TlsCertificatePassword)) + + if (HasOption(m_options, configuration::TlsCertificateChain) && + HasOption(m_options, configuration::TlsPrivateKey) && + HasOption(m_options, configuration::TlsDHKey)) { - ctx.set_password_callback( - [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { - return *GetOption(m_options, configuration::TlsCertificatePassword); - }); + LOG(info) << "Server: Initializing TLS support"; + if (HasOption(m_options, configuration::TlsCertificatePassword)) + { + ctx.set_password_callback( + [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { + return *GetOption(m_options, configuration::TlsCertificatePassword); + }); + } + + auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); + auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); + ctx.use_certificate_chain_file(*serverCert); + ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); + ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); + + if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) + { + LOG(info) << "Server: Will only accept client connections with valid certificates"; + + ctx.set_verify_mode(boost::asio::ssl::verify_peer | + boost::asio::ssl::verify_fail_if_no_peer_cert); + if (HasOption(m_options, configuration::MqttCaCert)) + { + LOG(info) << "Server: Adding Client Certificates."; + ctx.load_verify_file(*GetOption(m_options, configuration::MqttCaCert)); + } + } } m_server.emplace(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port), std::move(ctx), m_ioContext); @@ -346,25 +366,39 @@ namespace mtconnect { boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12); ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::single_dh_use); - auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); - auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); - ctx.use_certificate_chain_file(*serverCert); - //ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); - ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); - /*if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) + if (HasOption(m_options, configuration::TlsCertificateChain) && + HasOption(m_options, configuration::TlsPrivateKey) && + HasOption(m_options, configuration::TlsDHKey)) { - LOG(info) << "Server: Will only accept client connections with valid certificates"; - - ctx.set_verify_mode(boost::asio::ssl::verify_peer | - boost::asio::ssl::verify_fail_if_no_peer_cert); - if (HasOption(m_options, configuration::MqttCaCert)) + LOG(info) << "Server: Initializing TLS WS support"; + if (HasOption(m_options, configuration::TlsCertificatePassword)) { - LOG(info) << "Server: Adding Client Certificates."; - ctx.load_verify_file(*GetOption(m_options, configuration::MqttCaCert)); + ctx.set_password_callback( + [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { + return *GetOption(m_options, configuration::TlsCertificatePassword); + }); } - }*/ + auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); + auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); + ctx.use_certificate_chain_file(*serverCert); + ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); + ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); + + if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) + { + LOG(info) << "Server: Will only accept client connections with valid certificates"; + + ctx.set_verify_mode(boost::asio::ssl::verify_peer | + boost::asio::ssl::verify_fail_if_no_peer_cert); + if (HasOption(m_options, configuration::MqttCaCert)) + { + LOG(info) << "Server: Adding Client Certificates."; + ctx.load_verify_file(*GetOption(m_options, configuration::MqttCaCert)); + } + } + } m_server.emplace(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port), std::move(ctx), m_ioContext); } diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index d7e4eaa4f..b166ee2d4 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -79,25 +79,15 @@ class MqttIsolatedUnitTest : public testing::Test { bool withTlsOption = IsOptionSet(options, configuration::MqttTls); - ConfigOptions opts(options); - MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, withTlsOption}, - {AutoAvailable, false}, - {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {TlsCertificatePassword, "mtconnect"s}, - {RealTime, false}}); - if (withTlsOption) { - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); + m_server = make_shared(m_agentTestHelper->m_ioContext, + options); } else { - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); + m_server = make_shared(m_agentTestHelper->m_ioContext, + options); } } @@ -141,14 +131,8 @@ class MqttIsolatedUnitTest : public testing::Test bool withTlsOption = IsOptionSet(options, configuration::MqttTls); ConfigOptions opts(options); - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, withTlsOption}, - {AutoAvailable, false}, - {MqttCaCert, MqttClientCACert}, - {MqttCert, MqttClientCert}, - {MqttPrivateKey, MqttClientKey}, - {RealTime, false}}); + + MergeOptions(opts, {{MqttPort, m_port}}); if (withTlsOption) { @@ -183,7 +167,13 @@ class MqttIsolatedUnitTest : public testing::Test TEST_F(MqttIsolatedUnitTest, mqtt_client_should_connect_to_broker) { - ConfigOptions options; + ConfigOptions options{{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, false}, + {AutoAvailable, false}, + {MqttCaCert, MqttClientCACert}, + {RealTime, false}}; + createServer(options); startServer(); @@ -201,7 +191,11 @@ TEST_F(MqttIsolatedUnitTest, mqtt_client_should_connect_to_broker) TEST_F(MqttIsolatedUnitTest, mqtt_tcp_client_should_receive_loopback_publication) { - ConfigOptions options; + ConfigOptions options {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, false}, + {AutoAvailable, false}, + {RealTime, false}}; createServer(options); startServer(); @@ -317,7 +311,15 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls) { GTEST_SKIP(); - ConfigOptions options {{configuration::MqttTls, true}}; + ConfigOptions options{{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, true}, + {AutoAvailable, false}, + {TlsCertificateChain, ServerCertFile}, + {TlsPrivateKey, ServerKeyFile}, + {TlsDHKey, ServerDhFile}, + {MqttCaCert, MqttClientCACert}, + {RealTime, false}}; createServer(options); @@ -338,14 +340,15 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) { GTEST_SKIP(); - ConfigOptions options; - MergeOptions(options, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, true}, - {AutoAvailable, false}, - {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {RealTime, false}}); + ConfigOptions options {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, true}, + {AutoAvailable, false}, + {TlsCertificateChain, ServerCertFile}, + {TlsPrivateKey, ServerKeyFile}, + {TlsDHKey, ServerDhFile}, + {MqttCaCert, MqttClientCACert}, + {RealTime, false}}; m_server = make_shared(m_agentTestHelper->m_ioContext, options); @@ -356,15 +359,8 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) auto handler = make_unique(); - ConfigOptions opts; - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, true}, - {AutoAvailable, false}, - {MqttCaCert, MqttClientCACert}, - {MqttCert, MqttClientCert}, - {MqttPrivateKey, MqttClientKey}, - {RealTime, false}}); + ConfigOptions opts(options); + MergeOptions(opts, {{MqttPort, m_port}}); m_client = make_shared(m_agentTestHelper->m_ioContext, opts, move(handler)); From a05c3acf4e1339b09a8000e0880ef57d4a4988d8 Mon Sep 17 00:00:00 2001 From: rajani Date: Thu, 15 Dec 2022 09:27:14 +0530 Subject: [PATCH 2/7] MQTT for Authentication.. --- src/mqtt/mqtt_client_impl.hpp | 26 +++++++++++++++++++++++--- src/mqtt/mqtt_server_impl.hpp | 8 ++++---- test/mqtt_isolated_test.cpp | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/mqtt/mqtt_client_impl.hpp b/src/mqtt/mqtt_client_impl.hpp index 5e2fa7759..c0b5b2c23 100644 --- a/src/mqtt/mqtt_client_impl.hpp +++ b/src/mqtt/mqtt_client_impl.hpp @@ -15,6 +15,8 @@ // limitations under the License. // +#include + #include #include #include @@ -374,18 +376,36 @@ namespace mtconnect { m_client->set_user_name(*m_username); if (m_password) m_client->set_password(*m_password); - + auto cacert = GetOption(m_options, configuration::MqttCaCert); if (cacert) { - m_client->get_ssl_context().load_verify_file(*cacert); - } + ifstream root; + root.open(*cacert); + std::string cert((istreambuf_iterator(root)), (istreambuf_iterator())); + m_client->get_ssl_context().add_certificate_authority( + boost::asio::buffer(cert.data(), cert.size())); + if (HasOption(m_options, configuration::TlsCertificateChain) && + HasOption(m_options, configuration::TlsPrivateKey)) + { + m_client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); + auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); + auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); + m_client->get_ssl_context().use_certificate_chain_file(*serverCert); + m_client->get_ssl_context().use_private_key_file(*serverPrivateKey, + boost::asio::ssl::context::pem); + } + if (HasOption(m_options, configuration::TlsClientCAs)) + m_client->get_ssl_context().load_verify_file( + *GetOption(m_options, configuration::TlsClientCAs)); + } } return m_client; } protected: + mqtt_tls_client m_client; }; diff --git a/src/mqtt/mqtt_server_impl.hpp b/src/mqtt/mqtt_server_impl.hpp index 88e0a4599..8517b075f 100644 --- a/src/mqtt/mqtt_server_impl.hpp +++ b/src/mqtt/mqtt_server_impl.hpp @@ -326,10 +326,10 @@ namespace mtconnect { ctx.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert); - if (HasOption(m_options, configuration::MqttCaCert)) + if (HasOption(m_options, configuration::TlsClientCAs)) { LOG(info) << "Server: Adding Client Certificates."; - ctx.load_verify_file(*GetOption(m_options, configuration::MqttCaCert)); + ctx.load_verify_file(*GetOption(m_options, configuration::TlsClientCAs)); } } } @@ -392,10 +392,10 @@ namespace mtconnect { ctx.set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert); - if (HasOption(m_options, configuration::MqttCaCert)) + if (HasOption(m_options, configuration::TlsClientCAs)) { LOG(info) << "Server: Adding Client Certificates."; - ctx.load_verify_file(*GetOption(m_options, configuration::MqttCaCert)); + ctx.load_verify_file(*GetOption(m_options, configuration::TlsClientCAs)); } } } diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index b166ee2d4..8c4017b53 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -47,6 +47,7 @@ const string MqttClientKey {PROJECT_ROOT_DIR "/test/resources/client.key"}; const string ServerCertFile(PROJECT_ROOT_DIR "/test/resources/user.crt"); const string ServerKeyFile {PROJECT_ROOT_DIR "/test/resources/user.key"}; const string ServerDhFile {PROJECT_ROOT_DIR "/test/resources/dh2048.pem"}; +const string ClientCA(PROJECT_ROOT_DIR "/test/resources/clientca.crt"); class MqttIsolatedUnitTest : public testing::Test { @@ -370,4 +371,34 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) ASSERT_TRUE(m_client->isConnected()); } -TEST_F(MqttIsolatedUnitTest, should_conenct_using_authentication) { GTEST_SKIP(); } +TEST_F(MqttIsolatedUnitTest, should_conenct_using_authentication) +{ + //GTEST_SKIP(); + + ConfigOptions options {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, true}, + {AutoAvailable, false}, + {TlsCertificateChain, ServerCertFile}, + {TlsPrivateKey, ServerKeyFile}, + {TlsDHKey, ServerDhFile}, + {TlsClientCAs, ClientCA}, + {MqttCaCert, MqttClientCACert}, + {TlsVerifyClientCertificate, true}, + {TlsCertificatePassword, "mtconnect"s}, + {RealTime, false}}; + + createServer(options); + + startServer(); + + ASSERT_NE(0, m_port); + + auto handler = make_unique(); + + createClient(options, move(handler)); + + ASSERT_TRUE(startClient()); + + ASSERT_TRUE(m_client->isConnected()); +} From 72bae4cc1f450d274e2db47c4a5bcb6d680a9abf Mon Sep 17 00:00:00 2001 From: rajani Date: Tue, 20 Dec 2022 10:20:58 +0530 Subject: [PATCH 3/7] skipped authentication Unit test --- test/mqtt_isolated_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index 8c4017b53..6758e8fa7 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -373,7 +373,7 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) TEST_F(MqttIsolatedUnitTest, should_conenct_using_authentication) { - //GTEST_SKIP(); + GTEST_SKIP(); ConfigOptions options {{ServerIp, "127.0.0.1"s}, {MqttPort, 0}, From 73230488e1c7e5c9c22cfaab8d0e0ac79c97ae90 Mon Sep 17 00:00:00 2001 From: rajani Date: Wed, 11 Jan 2023 15:12:18 -0600 Subject: [PATCH 4/7] Mqtt tls authentication --- agent_lib/CMakeLists.txt | 1 + src/configuration/config_options.hpp | 6 +- src/mqtt/mqtt_authorization.hpp | 108 +++++++++++++++++++++++ src/mqtt/mqtt_client_impl.hpp | 43 ++++----- src/mqtt/mqtt_server_impl.hpp | 11 +-- src/sink/mqtt_sink/mqtt_service.cpp | 6 +- src/source/adapter/mqtt/mqtt_adapter.cpp | 2 +- test/mqtt_isolated_test.cpp | 34 ++++--- 8 files changed, 158 insertions(+), 53 deletions(-) create mode 100644 src/mqtt/mqtt_authorization.hpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 87840a559..748dd4234 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -131,6 +131,7 @@ set(AGENT_SOURCES # src/mqtt HEADER_FILE_ONLY + "${CMAKE_CURRENT_SOURCE_DIR}/../src/mqtt/mqtt_authorization.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/../src/mqtt/mqtt_client.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/../src/mqtt/mqtt_server.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/../src/mqtt/mqtt_client_impl.hpp" diff --git a/src/configuration/config_options.hpp b/src/configuration/config_options.hpp index 752040102..5d7329e6f 100644 --- a/src/configuration/config_options.hpp +++ b/src/configuration/config_options.hpp @@ -60,9 +60,9 @@ namespace mtconnect { DECLARE_CONFIGURATION(DeviceTopic); DECLARE_CONFIGURATION(AssetTopic); DECLARE_CONFIGURATION(ObservationTopic); - DECLARE_CONFIGURATION(MqttCaCert); - DECLARE_CONFIGURATION(MqttCert); - DECLARE_CONFIGURATION(MqttPrivateKey); + DECLARE_CONFIGURATION(MqttClientCaCert); + DECLARE_CONFIGURATION(MqttClientCrt); + DECLARE_CONFIGURATION(MqttClientPrivateKey); DECLARE_CONFIGURATION(MqttClientId); DECLARE_CONFIGURATION(MqttTls); DECLARE_CONFIGURATION(MqttPort); diff --git a/src/mqtt/mqtt_authorization.hpp b/src/mqtt/mqtt_authorization.hpp new file mode 100644 index 000000000..35576c766 --- /dev/null +++ b/src/mqtt/mqtt_authorization.hpp @@ -0,0 +1,108 @@ +// +// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include "source/adapter/adapter.hpp" +#include "source/adapter/adapter_pipeline.hpp" + +using namespace std; +using namespace mtconnect; +using namespace mtconnect::configuration; + +namespace mtconnect { + namespace mqtt_client { + + class MqttTopicPermission + { + enum AuthorizationType + { + Allow, + Deny + }; + + enum TopicMode + { + Subscribe, + Publish, + Both + }; + + void MqttTopicPermission(const std::string &topic, const std::string& clientId) + { + m_topic = topic; + m_clientId = clientId; + m_type = AuthorizationType::Allow; + m_mode = TopicMode::Subscribe; + } + + void MqttTopicPermission(const std::string& topic, const std::string& clientId, + AuthorizationType type) + { + m_topic = topic; + m_clientId = clientId; + m_type = type; + m_mode = TopicMode::Subscribe; + } + + void MqttTopicPermission(const std::string& topic, const std::string& clientId, + AuthorizationType type, TopicMode mode) + { + m_topic = topic; + m_clientId = clientId; + m_type = type; + m_mode = mode; + } + + protected: + TopicMode m_mode; + AuthorizationType m_type; + std::string m_clientId; + std::string m_topic; + }; + + class MqttAuthorization : public std::enable_shared_from_this + { + public: + MqttAuthorization(const ConfigOptions &options) : m_options(options) + { + m_clientId = GetOption(options, configuration::MqttClientId); + m_username = GetOption(options, configuration::MqttUserName); + m_password = GetOption(options, configuration::MqttPassword); + } + + virtual ~MqttAuthorization() = default; + + bool checkCredentials() + { + if (!m_username && !m_password) + { + LOG(error) << "MQTT USERNAME_OR_PASSWORD are Not Available"; + return false; + } + + return true; + } + + protected: + std::optional m_username; + std::optional m_password; + std::string m_clientId; + ConfigOptions m_options; + }; + } // namespace MqttAuthorization +} // namespace mtconnect diff --git a/src/mqtt/mqtt_client_impl.hpp b/src/mqtt/mqtt_client_impl.hpp index 093c7eea6..3a172949f 100644 --- a/src/mqtt/mqtt_client_impl.hpp +++ b/src/mqtt/mqtt_client_impl.hpp @@ -377,31 +377,23 @@ namespace mtconnect { m_client->set_user_name(*m_username); if (m_password) m_client->set_password(*m_password); - - auto cacert = GetOption(m_options, configuration::MqttCaCert); + + auto cacert = GetOption(m_options, configuration::MqttClientCaCert); if (cacert) { - ifstream root; - root.open(*cacert); - std::string cert((istreambuf_iterator(root)), (istreambuf_iterator())); - m_client->get_ssl_context().add_certificate_authority( - boost::asio::buffer(cert.data(), cert.size())); - if (HasOption(m_options, configuration::TlsCertificateChain) && - HasOption(m_options, configuration::TlsPrivateKey)) + if (HasOption(m_options, configuration::MqttClientCrt) && + HasOption(m_options, configuration::MqttClientPrivateKey)) { - m_client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); - auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); - auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); - m_client->get_ssl_context().use_certificate_chain_file(*serverCert); - m_client->get_ssl_context().use_private_key_file(*serverPrivateKey, + auto clientPrivateKey = + GetOption(m_options, configuration::MqttClientPrivateKey); + auto clientCrt = GetOption(m_options, configuration::MqttClientCrt); + m_client->get_ssl_context().use_certificate_chain_file(*clientCrt); + m_client->get_ssl_context().use_private_key_file(*clientPrivateKey, boost::asio::ssl::context::pem); } - if (HasOption(m_options, configuration::TlsClientCAs)) - m_client->get_ssl_context().load_verify_file( - *GetOption(m_options, configuration::TlsClientCAs)); - } + m_client->get_ssl_context().load_verify_file(*cacert); + } } - return m_client; } @@ -426,7 +418,18 @@ namespace mtconnect { if (m_password) m_client->set_password(*m_password); - auto cacert = GetOption(m_options, configuration::MqttCaCert); + if (HasOption(m_options, configuration::MqttClientCrt) && + HasOption(m_options, configuration::MqttClientPrivateKey)) + { + auto clientPrivateKey = + GetOption(m_options, configuration::MqttClientPrivateKey); + auto clientCrt = GetOption(m_options, configuration::MqttClientCrt); + m_client->get_ssl_context().use_certificate_chain_file(*clientCrt); + m_client->get_ssl_context().use_private_key_file(*clientPrivateKey, + boost::asio::ssl::context::pem); + } + + auto cacert = GetOption(m_options, configuration::MqttClientCaCert); if (cacert) { m_client->get_ssl_context().load_verify_file(*cacert); diff --git a/src/mqtt/mqtt_server_impl.hpp b/src/mqtt/mqtt_server_impl.hpp index 8517b075f..a5136b1ac 100644 --- a/src/mqtt/mqtt_server_impl.hpp +++ b/src/mqtt/mqtt_server_impl.hpp @@ -302,30 +302,27 @@ namespace mtconnect { boost::asio::ssl::context::single_dh_use); if (HasOption(m_options, configuration::TlsCertificateChain) && - HasOption(m_options, configuration::TlsPrivateKey) && - HasOption(m_options, configuration::TlsDHKey)) + HasOption(m_options, configuration::TlsPrivateKey)) { LOG(info) << "Server: Initializing TLS support"; - if (HasOption(m_options, configuration::TlsCertificatePassword)) + /*if (HasOption(m_options, configuration::TlsCertificatePassword)) { ctx.set_password_callback( [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { return *GetOption(m_options, configuration::TlsCertificatePassword); }); - } + }*/ auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); ctx.use_certificate_chain_file(*serverCert); - ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) { LOG(info) << "Server: Will only accept client connections with valid certificates"; - ctx.set_verify_mode(boost::asio::ssl::verify_peer | - boost::asio::ssl::verify_fail_if_no_peer_cert); + ctx.set_verify_mode(boost::asio::ssl::verify_peer); if (HasOption(m_options, configuration::TlsClientCAs)) { LOG(info) << "Server: Adding Client Certificates."; diff --git a/src/sink/mqtt_sink/mqtt_service.cpp b/src/sink/mqtt_sink/mqtt_service.cpp index e008f4a16..6175a0fdf 100644 --- a/src/sink/mqtt_sink/mqtt_service.cpp +++ b/src/sink/mqtt_sink/mqtt_service.cpp @@ -49,9 +49,9 @@ namespace mtconnect { GetOptions(config, m_options, options); AddOptions(config, m_options, - {{configuration::MqttCaCert, string()}, - {configuration::MqttPrivateKey, string()}, - {configuration::MqttCert, string()}, + {{configuration::MqttClientCaCert, string()}, + {configuration::MqttClientPrivateKey, string()}, + {configuration::MqttClientCrt, string()}, {configuration::MqttClientId, string()}}); AddDefaultedOptions(config, m_options, {{configuration::MqttHost, "127.0.0.1"s}, diff --git a/src/source/adapter/mqtt/mqtt_adapter.cpp b/src/source/adapter/mqtt/mqtt_adapter.cpp index 577d90ea8..3e1200130 100644 --- a/src/source/adapter/mqtt/mqtt_adapter.cpp +++ b/src/source/adapter/mqtt/mqtt_adapter.cpp @@ -63,7 +63,7 @@ namespace mtconnect { {configuration::Manufacturer, string()}, {configuration::Station, string()}, {configuration::Url, string()}, - {configuration::MqttCaCert, string()}}); + {configuration::MqttClientCaCert, string()}}); AddDefaultedOptions(block, m_options, {{configuration::MqttHost, "localhost"s}, diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index 6758e8fa7..596ff60c6 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -172,7 +172,7 @@ TEST_F(MqttIsolatedUnitTest, mqtt_client_should_connect_to_broker) {MqttPort, 0}, {MqttTls, false}, {AutoAvailable, false}, - {MqttCaCert, MqttClientCACert}, + {MqttClientCaCert, MqttClientCACert}, {RealTime, false}}; createServer(options); @@ -317,9 +317,8 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls) {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {TlsDHKey, ServerDhFile}, - {MqttCaCert, MqttClientCACert}, + {TlsPrivateKey, ServerKeyFile}, + {MqttClientCaCert, MqttClientCACert}, {RealTime, false}}; createServer(options); @@ -346,9 +345,8 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {TlsDHKey, ServerDhFile}, - {MqttCaCert, MqttClientCACert}, + {TlsPrivateKey, ServerKeyFile}, + {MqttClientCaCert, MqttClientCACert}, {RealTime, false}}; m_server = @@ -371,22 +369,20 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) ASSERT_TRUE(m_client->isConnected()); } -TEST_F(MqttIsolatedUnitTest, should_conenct_using_authentication) +TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) { GTEST_SKIP(); ConfigOptions options {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, true}, - {AutoAvailable, false}, - {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {TlsDHKey, ServerDhFile}, - {TlsClientCAs, ClientCA}, - {MqttCaCert, MqttClientCACert}, - {TlsVerifyClientCertificate, true}, - {TlsCertificatePassword, "mtconnect"s}, - {RealTime, false}}; + {MqttPort, 0}, + {MqttTls, true}, + {AutoAvailable, false}, + {TlsCertificateChain, ServerCertFile}, + {TlsPrivateKey, ServerKeyFile}, + {MqttClientCaCert, MqttClientCACert}, + {MqttClientCrt, MqttClientCert}, + {MqttClientPrivateKey, MqttClientKey}, + {RealTime, false}}; createServer(options); From 24427af4c98f29efbe3c8da7f1f6d4af8e962a29 Mon Sep 17 00:00:00 2001 From: rajani Date: Tue, 17 Jan 2023 14:59:53 -0600 Subject: [PATCH 5/7] some modification swith tls authentification... --- src/configuration/config_options.hpp | 6 +- src/mqtt/mqtt_client_impl.hpp | 13 +- src/mqtt/mqtt_server_impl.hpp | 35 +----- src/sink/mqtt_sink/mqtt_service.cpp | 6 +- test/mqtt_isolated_test.cpp | 172 +++++++++++++++++++++++++-- 5 files changed, 176 insertions(+), 56 deletions(-) diff --git a/src/configuration/config_options.hpp b/src/configuration/config_options.hpp index 5d7329e6f..752040102 100644 --- a/src/configuration/config_options.hpp +++ b/src/configuration/config_options.hpp @@ -60,9 +60,9 @@ namespace mtconnect { DECLARE_CONFIGURATION(DeviceTopic); DECLARE_CONFIGURATION(AssetTopic); DECLARE_CONFIGURATION(ObservationTopic); - DECLARE_CONFIGURATION(MqttClientCaCert); - DECLARE_CONFIGURATION(MqttClientCrt); - DECLARE_CONFIGURATION(MqttClientPrivateKey); + DECLARE_CONFIGURATION(MqttCaCert); + DECLARE_CONFIGURATION(MqttCert); + DECLARE_CONFIGURATION(MqttPrivateKey); DECLARE_CONFIGURATION(MqttClientId); DECLARE_CONFIGURATION(MqttTls); DECLARE_CONFIGURATION(MqttPort); diff --git a/src/mqtt/mqtt_client_impl.hpp b/src/mqtt/mqtt_client_impl.hpp index 25a986f1f..412603cd2 100644 --- a/src/mqtt/mqtt_client_impl.hpp +++ b/src/mqtt/mqtt_client_impl.hpp @@ -134,7 +134,7 @@ namespace mtconnect { else { LOG(debug) << "No connect handler, setting connected"; - m_connected = true; + m_connected = true; } } else @@ -425,16 +425,7 @@ namespace mtconnect { if (cacert) { m_client->get_ssl_context().load_verify_file(*cacert); - } - auto private_key = GetOption(m_options, configuration::MqttPrivateKey); - auto cert = GetOption(m_options, configuration::MqttCert); - if (private_key && cert) - { - m_client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); - m_client->get_ssl_context().use_certificate_chain_file(*cert); - m_client->get_ssl_context().use_private_key_file(*private_key, - boost::asio::ssl::context::pem); - } + } } return m_client; diff --git a/src/mqtt/mqtt_server_impl.hpp b/src/mqtt/mqtt_server_impl.hpp index a5136b1ac..73c9d8ba2 100644 --- a/src/mqtt/mqtt_server_impl.hpp +++ b/src/mqtt/mqtt_server_impl.hpp @@ -115,10 +115,10 @@ namespace mtconnect { // including close_handler and error_handler. ep.start_session(std::make_tuple(std::move(spep), std::move(g))); ep.set_connect_handler([this, wp](MQTT_NS::buffer client_id, - MQTT_NS::optional username, - MQTT_NS::optional password, - MQTT_NS::optional, - bool clean_session, std::uint16_t keep_alive) { + MQTT_NS::optional username, + MQTT_NS::optional password, + MQTT_NS::optional, bool clean_session, + std::uint16_t keep_alive) { using namespace MQTT_NS::literals; LOG(info) << "Server: Client_id : " << client_id << std::endl; LOG(info) << "Server: User Name : " << (username ? username.value() : "none"_mb) @@ -365,37 +365,14 @@ namespace mtconnect { boost::asio::ssl::context::single_dh_use); if (HasOption(m_options, configuration::TlsCertificateChain) && - HasOption(m_options, configuration::TlsPrivateKey) && - HasOption(m_options, configuration::TlsDHKey)) + HasOption(m_options, configuration::TlsPrivateKey)) { - LOG(info) << "Server: Initializing TLS WS support"; - if (HasOption(m_options, configuration::TlsCertificatePassword)) - { - ctx.set_password_callback( - [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { - return *GetOption(m_options, configuration::TlsCertificatePassword); - }); - } - auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); ctx.use_certificate_chain_file(*serverCert); - ctx.use_tmp_dh_file(*GetOption(m_options, configuration::TlsDHKey)); ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); - - if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) - { - LOG(info) << "Server: Will only accept client connections with valid certificates"; - - ctx.set_verify_mode(boost::asio::ssl::verify_peer | - boost::asio::ssl::verify_fail_if_no_peer_cert); - if (HasOption(m_options, configuration::TlsClientCAs)) - { - LOG(info) << "Server: Adding Client Certificates."; - ctx.load_verify_file(*GetOption(m_options, configuration::TlsClientCAs)); - } - } } + m_server.emplace(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port), std::move(ctx), m_ioContext); } diff --git a/src/sink/mqtt_sink/mqtt_service.cpp b/src/sink/mqtt_sink/mqtt_service.cpp index 6175a0fdf..e008f4a16 100644 --- a/src/sink/mqtt_sink/mqtt_service.cpp +++ b/src/sink/mqtt_sink/mqtt_service.cpp @@ -49,9 +49,9 @@ namespace mtconnect { GetOptions(config, m_options, options); AddOptions(config, m_options, - {{configuration::MqttClientCaCert, string()}, - {configuration::MqttClientPrivateKey, string()}, - {configuration::MqttClientCrt, string()}, + {{configuration::MqttCaCert, string()}, + {configuration::MqttPrivateKey, string()}, + {configuration::MqttCert, string()}, {configuration::MqttClientId, string()}}); AddDefaultedOptions(config, m_options, {{configuration::MqttHost, "127.0.0.1"s}, diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index 596ff60c6..f97df1c4b 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -59,19 +59,23 @@ class MqttIsolatedUnitTest : public testing::Test } void TearDown() override - { + { if (m_client) { + m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); + while (m_agentTestHelper->m_ioContext.run_one_for(10ms)) + ; m_client.reset(); } + if (m_server) { m_server->stop(); m_agentTestHelper->m_ioContext.run_for(500ms); m_server.reset(); } + m_agentTestHelper.reset(); m_jsonPrinter.reset(); } @@ -172,7 +176,7 @@ TEST_F(MqttIsolatedUnitTest, mqtt_client_should_connect_to_broker) {MqttPort, 0}, {MqttTls, false}, {AutoAvailable, false}, - {MqttClientCaCert, MqttClientCACert}, + {MqttCaCert, MqttClientCACert}, {RealTime, false}}; createServer(options); @@ -308,6 +312,148 @@ TEST_F(MqttIsolatedUnitTest, mqtt_tcp_client_should_receive_loopback_publication ASSERT_TRUE(received); } +TEST_F(MqttIsolatedUnitTest, mqtt_tls_client_should_receive_loopback_publication) +{ + GTEST_SKIP(); + + ConfigOptions options {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, true}, + {AutoAvailable, false}, + {TlsCertificateChain, ServerCertFile}, + {TlsPrivateKey, ServerKeyFile}, + {TlsClientCAs, MqttClientCACert}, + {MqttCaCert, MqttClientCACert}, + {MqttCert, MqttClientCert}, + {MqttPrivateKey, MqttClientKey}, + {RealTime, false}}; + + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + std::uint16_t pid_sub1; + + auto client = mqtt::make_tls_async_client(m_agentTestHelper->m_ioContext, "localhost", m_port); + auto cacert = GetOption(options, configuration::MqttCaCert); + if (cacert) + { + client->get_ssl_context().load_verify_file(*cacert); + } + + auto private_key = GetOption(options, configuration::MqttPrivateKey); + auto cert = GetOption(options, configuration::MqttCert); + if (private_key && cert) + { + client->get_ssl_context().set_verify_mode(boost::asio::ssl::verify_peer); + client->get_ssl_context().use_certificate_chain_file(*cert); + client->get_ssl_context().use_private_key_file(*private_key, boost::asio::ssl::context::pem); + } + + client->set_client_id("cliendId1"); + client->set_clean_session(true); + client->set_keep_alive_sec(30); + + client->set_connack_handler([&client, &pid_sub1](bool sp, + mqtt::connect_return_code connack_return_code) { + std::cout << "Connack handler called" << std::endl; + std::cout << "Session Present: " << std::boolalpha << sp << std::endl; + std::cout << "Connack Return Code: " << connack_return_code << std::endl; + if (connack_return_code == mqtt::connect_return_code::accepted) + { + pid_sub1 = client->acquire_unique_packet_id(); + + client->async_subscribe(pid_sub1, "mqtt_tls_client_cpp/topic1", MQTT_NS::qos::at_most_once, + //[optional] checking async_subscribe completion code + [](MQTT_NS::error_code ec) { + EXPECT_FALSE(ec); + std::cout << "async_tls_subscribe callback: " << ec.message() + << std::endl; + }); + } + return true; + }); + client->set_close_handler([] { std::cout << "closed" << std::endl; }); + + client->set_suback_handler( + [&client, &pid_sub1](std::uint16_t packet_id, std::vector results) { + std::cout << "suback received. packet_id: " << packet_id << std::endl; + for (auto const &e : results) + { + std::cout << "subscribe result: " << e << std::endl; + } + + if (packet_id == pid_sub1) + { + client->async_publish("mqtt_tls_client_cpp/topic1", "test1", MQTT_NS::qos::at_most_once, + //[optional] checking async_publish completion code + [](MQTT_NS::error_code ec) { + EXPECT_FALSE(ec); + + std::cout << "async_tls_publish callback: " << ec.message() + << std::endl; + EXPECT_EQ(ec.message(), "Success"); + }); + return true; + } + + return true; + }); + + client->set_close_handler([] { std::cout << "closed" << std::endl; }); + + client->set_suback_handler( + [&client, &pid_sub1](std::uint16_t packet_id, std::vector results) { + std::cout << "suback received. packet_id: " << packet_id << std::endl; + for (auto const &e : results) + { + std::cout << "subscribe result: " << e << std::endl; + } + + if (packet_id == pid_sub1) + { + client->async_publish("mqtt_tls_client_cpp/topic1", "test1", MQTT_NS::qos::at_most_once, + //[optional] checking async_publish completion code + [packet_id](MQTT_NS::error_code ec) { + EXPECT_FALSE(ec); + + std::cout << "async_tls_publish callback: " << ec.message() + << std::endl; + ASSERT_TRUE(packet_id); + }); + } + + return true; + }); + + bool received = false; + client->set_publish_handler([&client, &received](mqtt::optional packet_id, + mqtt::publish_options pubopts, + mqtt::buffer topic_name, mqtt::buffer contents) { + std::cout << "publish received." + << " dup: " << pubopts.get_dup() << " qos: " << pubopts.get_qos() + << " retain: " << pubopts.get_retain() << std::endl; + if (packet_id) + std::cout << "packet_id: " << *packet_id << std::endl; + std::cout << "topic_name: " << topic_name << std::endl; + std::cout << "contents: " << contents << std::endl; + + EXPECT_EQ("mqtt_tls_client_cpp/topic1", topic_name); + EXPECT_EQ("test1", contents); + + client->async_disconnect(); + received = true; + return true; + }); + + client->async_connect(); + + m_agentTestHelper->m_ioContext.run(); + + ASSERT_TRUE(received); +} + TEST_F(MqttIsolatedUnitTest, should_connect_using_tls) { GTEST_SKIP(); @@ -317,8 +463,11 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls) {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, - {MqttClientCaCert, MqttClientCACert}, + {TlsPrivateKey, ServerKeyFile}, + {TlsClientCAs, MqttClientCACert}, + {MqttCaCert, MqttClientCACert}, + {MqttCert, MqttClientCert}, + {MqttPrivateKey, MqttClientKey}, {RealTime, false}}; createServer(options); @@ -346,7 +495,7 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, {TlsPrivateKey, ServerKeyFile}, - {MqttClientCaCert, MqttClientCACert}, + {MqttCaCert, MqttClientCACert}, {RealTime, false}}; m_server = @@ -379,9 +528,9 @@ TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, {TlsPrivateKey, ServerKeyFile}, - {MqttClientCaCert, MqttClientCACert}, - {MqttClientCrt, MqttClientCert}, - {MqttClientPrivateKey, MqttClientKey}, + {MqttCaCert, MqttClientCACert}, + {MqttCert, MqttClientCert}, + {MqttPrivateKey, MqttClientKey}, {RealTime, false}}; createServer(options); @@ -392,7 +541,10 @@ TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) auto handler = make_unique(); - createClient(options, move(handler)); + ConfigOptions opts(options); + MergeOptions(opts, {{MqttPort, m_port}}); + + createClient(opts, move(handler)); ASSERT_TRUE(startClient()); From 9c695545a83a0f36ca81f35acca1dea5ed1d2800 Mon Sep 17 00:00:00 2001 From: rajani Date: Fri, 20 Jan 2023 11:47:00 -0600 Subject: [PATCH 6/7] Mqtt_TLS Authentification/Certificates --- src/mqtt/mqtt_server_impl.hpp | 10 +++++--- test/mqtt_isolated_test.cpp | 47 ++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/mqtt/mqtt_server_impl.hpp b/src/mqtt/mqtt_server_impl.hpp index 73c9d8ba2..eba69851f 100644 --- a/src/mqtt/mqtt_server_impl.hpp +++ b/src/mqtt/mqtt_server_impl.hpp @@ -302,21 +302,25 @@ namespace mtconnect { boost::asio::ssl::context::single_dh_use); if (HasOption(m_options, configuration::TlsCertificateChain) && - HasOption(m_options, configuration::TlsPrivateKey)) + HasOption(m_options, configuration::TlsPrivateKey) && + HasOption(m_options, configuration::TlsDHKey)) { LOG(info) << "Server: Initializing TLS support"; - /*if (HasOption(m_options, configuration::TlsCertificatePassword)) + if (HasOption(m_options, configuration::TlsCertificatePassword)) { ctx.set_password_callback( [this](size_t, boost::asio::ssl::context_base::password_purpose) -> string { return *GetOption(m_options, configuration::TlsCertificatePassword); }); - }*/ + } auto serverPrivateKey = GetOption(m_options, configuration::TlsPrivateKey); auto serverCert = GetOption(m_options, configuration::TlsCertificateChain); + auto serverDHKey = GetOption(m_options, configuration::TlsDHKey); + ctx.use_certificate_chain_file(*serverCert); ctx.use_private_key_file(*serverPrivateKey, boost::asio::ssl::context::pem); + ctx.use_tmp_dh_file(*serverDHKey); if (IsOptionSet(m_options, configuration::TlsVerifyClientCertificate)) { diff --git a/test/mqtt_isolated_test.cpp b/test/mqtt_isolated_test.cpp index f97df1c4b..ad08765a2 100644 --- a/test/mqtt_isolated_test.cpp +++ b/test/mqtt_isolated_test.cpp @@ -314,7 +314,7 @@ TEST_F(MqttIsolatedUnitTest, mqtt_tcp_client_should_receive_loopback_publication TEST_F(MqttIsolatedUnitTest, mqtt_tls_client_should_receive_loopback_publication) { - GTEST_SKIP(); + GTEST_SKIP(); ConfigOptions options {{ServerIp, "127.0.0.1"s}, {MqttPort, 0}, @@ -322,6 +322,8 @@ TEST_F(MqttIsolatedUnitTest, mqtt_tls_client_should_receive_loopback_publication {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, {TlsPrivateKey, ServerKeyFile}, + {TlsDHKey, ServerDhFile}, + {TlsVerifyClientCertificate,true}, {TlsClientCAs, MqttClientCACert}, {MqttCaCert, MqttClientCACert}, {MqttCert, MqttClientCert}, @@ -458,16 +460,18 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls) { GTEST_SKIP(); - ConfigOptions options{{ServerIp, "127.0.0.1"s}, + ConfigOptions options {{ServerIp, "127.0.0.1"s}, {MqttPort, 0}, {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, {TlsPrivateKey, ServerKeyFile}, - {TlsClientCAs, MqttClientCACert}, + {TlsDHKey, ServerDhFile}, + /*{TlsVerifyClientCertificate, true}, + {TlsClientCAs, ClientCA},*/ {MqttCaCert, MqttClientCACert}, - {MqttCert, MqttClientCert}, - {MqttPrivateKey, MqttClientKey}, + /* {MqttCert, MqttClientCert}, + {MqttPrivateKey, MqttClientKey},*/ {RealTime, false}}; createServer(options); @@ -494,7 +498,7 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, - {TlsPrivateKey, ServerKeyFile}, + {TlsPrivateKey, ServerKeyFile}, {MqttCaCert, MqttClientCACert}, {RealTime, false}}; @@ -512,41 +516,44 @@ TEST_F(MqttIsolatedUnitTest, should_connect_using_tls_ws) m_client = make_shared(m_agentTestHelper->m_ioContext, opts, move(handler)); - + ASSERT_TRUE(startClient()); ASSERT_TRUE(m_client->isConnected()); } -TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) -{ - GTEST_SKIP(); - +TEST_F(MqttIsolatedUnitTest, should_conenct_using_tls_authentication) +{ + GTEST_SKIP(); + ConfigOptions options {{ServerIp, "127.0.0.1"s}, {MqttPort, 0}, {MqttTls, true}, {AutoAvailable, false}, {TlsCertificateChain, ServerCertFile}, {TlsPrivateKey, ServerKeyFile}, + {TlsDHKey, ServerDhFile}, + {TlsVerifyClientCertificate, true}, + {TlsClientCAs, ClientCA}, {MqttCaCert, MqttClientCACert}, {MqttCert, MqttClientCert}, {MqttPrivateKey, MqttClientKey}, {RealTime, false}}; - createServer(options); + createServer(options); - startServer(); + startServer(); - ASSERT_NE(0, m_port); + ASSERT_NE(0, m_port); - auto handler = make_unique(); + auto handler = make_unique(); - ConfigOptions opts(options); - MergeOptions(opts, {{MqttPort, m_port}}); + ConfigOptions opts(options); + MergeOptions(opts, {{MqttPort, m_port}}); - createClient(opts, move(handler)); + createClient(opts, move(handler)); - ASSERT_TRUE(startClient()); + ASSERT_TRUE(startClient()); - ASSERT_TRUE(m_client->isConnected()); + ASSERT_TRUE(m_client->isConnected()); } From a2b2b980656894a7fe105a2389645bbe8b315af5 Mon Sep 17 00:00:00 2001 From: rajani Date: Mon, 23 Jan 2023 12:40:52 -0600 Subject: [PATCH 7/7] renamed member variable in MqttClient class from m_clientid to m_packetId --- src/mqtt/mqtt_client_impl.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mqtt/mqtt_client_impl.hpp b/src/mqtt/mqtt_client_impl.hpp index 412603cd2..c895211cb 100644 --- a/src/mqtt/mqtt_client_impl.hpp +++ b/src/mqtt/mqtt_client_impl.hpp @@ -224,9 +224,9 @@ namespace mtconnect { } LOG(debug) << "Subscribing to topic: " << topic; - m_clientId = derived().getClient()->acquire_unique_packet_id(); + m_packetId = derived().getClient()->acquire_unique_packet_id(); derived().getClient()->async_subscribe( - m_clientId, topic.c_str(), mqtt::qos::at_least_once, [topic](mqtt::error_code ec) { + m_packetId, topic.c_str(), mqtt::qos::at_least_once, [topic](mqtt::error_code ec) { if (ec) { LOG(error) << "Subscribe failed: " << topic << ": " << ec.message(); @@ -251,9 +251,9 @@ namespace mtconnect { return false; } - m_clientId = derived().getClient()->acquire_unique_packet_id(); + m_packetId = derived().getClient()->acquire_unique_packet_id(); derived().getClient()->async_publish( - m_clientId, topic, payload, mqtt::qos::at_least_once | mqtt::retain::yes, + m_packetId, topic, payload, mqtt::qos::at_least_once | mqtt::retain::yes, [topic](mqtt::error_code ec) { if (ec) { @@ -332,7 +332,7 @@ namespace mtconnect { unsigned int m_port {1883}; - std::uint16_t m_clientId {0}; + std::uint16_t m_packetId {0}; std::optional m_username;