Skip to content

Commit 996a306

Browse files
committed
Broker check certificate load error and perform periodic reloading
1 parent 56d51f9 commit 996a306

File tree

7 files changed

+88
-17
lines changed

7 files changed

+88
-17
lines changed

example/CMakeLists.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ FOREACH (source_file ${exec_PROGRAMS})
5050
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
5151
ADD_EXECUTABLE (${source_file_we} ${source_file})
5252
TARGET_LINK_LIBRARIES (${source_file_we} mqtt_cpp_iface)
53+
54+
IF (MSVC AND MQTT_USE_STATIC_OPENSSL)
55+
TARGET_LINK_LIBRARIES (${source_file_we} Crypt32)
56+
ENDIF ()
57+
5358
IF (MQTT_USE_LOG)
5459
TARGET_COMPILE_DEFINITIONS (${source_file_we} PUBLIC $<IF:$<BOOL:${MQTT_USE_STATIC_BOOST}>,,BOOST_LOG_DYN_LINK>)
5560
TARGET_LINK_LIBRARIES (${source_file_we} Boost::log)
@@ -58,19 +63,16 @@ FOREACH (source_file ${exec_PROGRAMS})
5863
TARGET_LINK_LIBRARIES (${source_file_we} Boost::program_options)
5964
ENDFOREACH ()
6065

61-
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../example/broker.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
66+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/broker.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
67+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/mosquitto.org.crt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6268
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.crt.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6369
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6470
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/cacert.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6571

6672
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
73+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/broker.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
6774
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/mosquitto.org.crt DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
6875
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.crt.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
6976
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
7077
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/cacert.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
71-
ELSE ()
72-
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/mosquitto.org.crt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
73-
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.crt.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
74-
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
75-
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/cacert.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
7678
ENDIF ()

example/broker.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Default configuration for MQTT-CPP Broker
22
verbose=1
3-
certificate=broker.crt.pem
4-
private_key=broker.key.pem
3+
certificate=server.crt.pem
4+
private_key=server.key.pem
55

66
# Configuration for TCP
77
[tcp]
@@ -17,4 +17,4 @@ port=1883
1717

1818
# Configuration for Websocket with TLS
1919
[wss]
20-
# port=10433
20+
# port=10443

example/broker.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,45 @@
1616
#include <fstream>
1717

1818
#if defined(MQTT_USE_TLS)
19-
boost::asio::ssl::context init_ctx(boost::program_options::variables_map const& vm)
19+
constexpr std::size_t certificate_reload_interval_seconds = 3600;
20+
21+
template<typename ServerPtr>
22+
void reload_ctx(boost::asio::io_context &ioc, ServerPtr server, boost::program_options::variables_map const& vm, std::string const &name)
2023
{
24+
MQTT_LOG("mqtt_broker", info) << "Reloading certificates for server " << name;
25+
2126
if (vm.count("certificate") == 0 && vm.count("private_key") == 0) {
2227
throw std::runtime_error("TLS requested but certificate and/or private_key not specified");
2328
}
2429

30+
boost::system::error_code ec;
31+
server->get_ssl_context().use_certificate_file(vm["certificate"].as<std::string>(), boost::asio::ssl::context::pem, ec);
32+
if (ec) {
33+
throw std::runtime_error("Failed to load certificate file: " + ec.message());
34+
}
35+
36+
server->get_ssl_context().use_private_key_file(vm["private_key"].as<std::string>(), boost::asio::ssl::context::pem, ec);
37+
if (ec) {
38+
throw std::runtime_error("Failed to load private key file: " + ec.message());
39+
}
40+
41+
auto reload_timer = std::make_shared<boost::asio::deadline_timer>(ioc, boost::posix_time::seconds(certificate_reload_interval_seconds));
42+
reload_timer->async_wait([&, server = server, reload_timer = reload_timer, name = name](boost::system::error_code const &e) {
43+
BOOST_ASSERT(!e || e == boost::asio::error::operation_aborted);
44+
45+
if(!e) {
46+
reload_ctx(ioc, server, vm, name);
47+
}
48+
});
49+
}
50+
51+
boost::asio::ssl::context init_ctx(boost::program_options::variables_map const& vm)
52+
{
2553
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
2654
ctx.set_options(
2755
boost::asio::ssl::context::default_workarounds |
2856
boost::asio::ssl::context::single_dh_use);
29-
ctx.use_certificate_file(vm["certificate"].as<std::string>(), boost::asio::ssl::context::pem);
30-
ctx.use_private_key_file(vm["private_key"].as<std::string>(), boost::asio::ssl::context::pem);
57+
3158
return ctx;
3259
}
3360
#endif // defined(MQTT_USE_TLS)
@@ -51,16 +78,18 @@ void run_broker(boost::program_options::variables_map const& vm)
5178
#endif // defined(MQTT_USE_WS)
5279

5380
#if defined(MQTT_USE_TLS)
54-
std::unique_ptr<test_server_tls> s_tls;
81+
std::shared_ptr<test_server_tls> s_tls;
5582
if (vm.count("tls.port")) {
56-
s_tls = std::make_unique<test_server_tls>(ioc, init_ctx(vm), b, vm["tls.port"].as<uint16_t>());
83+
s_tls = std::make_shared<test_server_tls>(ioc, init_ctx(vm), b, vm["tls.port"].as<uint16_t>());
84+
reload_ctx(ioc, s_tls, vm, "TLS");
5785
}
5886
#endif // defined(MQTT_USE_TLS)
5987

60-
#if defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
61-
std::unique_ptr<test_server_tls_ws> s_tls_ws;
88+
#if defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
89+
std::shared_ptr<test_server_tls_ws> s_tls_ws;
6290
if (vm.count("wss.port")) {
63-
s_tls_ws = std::make_unique<test_server_tls_ws>(ioc, init_ctx(vm), b, vm["wss.port"].as<uint16_t>());
91+
s_tls_ws = std::make_shared<test_server_tls_ws>(ioc, init_ctx(vm), b, vm["wss.port"].as<uint16_t>());
92+
reload_ctx(ioc, s_tls_ws, vm, "WSS");
6493
}
6594
#endif // defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
6695

test/system/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ FOREACH (source_file ${check_PROGRAMS})
8383
TARGET_LINK_LIBRARIES (
8484
${source_file_we} mqtt_cpp_iface Boost::unit_test_framework
8585
)
86+
IF (MSVC AND MQTT_USE_STATIC_OPENSSL)
87+
TARGET_LINK_LIBRARIES (${source_file_we} Crypt32)
88+
ENDIF ()
89+
8690
IF (MQTT_USE_LOG)
8791
TARGET_COMPILE_DEFINITIONS (${source_file_we} PUBLIC $<IF:$<BOOL:${MQTT_USE_STATIC_BOOST}>,,BOOST_LOG_DYN_LINK>)
8892
TARGET_LINK_LIBRARIES (

test/system/test_server_tls.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,22 @@ class test_server_tls {
5959
server_.close();
6060
}
6161

62+
/**
63+
* @brief Get boost asio ssl context.
64+
* @return ssl context
65+
*/
66+
MQTT_NS::tls::context& get_ssl_context() {
67+
return server_.get_ssl_context();
68+
}
69+
70+
/**
71+
* @brief Get boost asio ssl context.
72+
* @return ssl context
73+
*/
74+
MQTT_NS::tls::context const& get_ssl_context() const {
75+
return server_.get_ssl_context();
76+
}
77+
6278
private:
6379
MQTT_NS::server_tls<> server_;
6480
MQTT_NS::broker::broker_t& b_;

test/system/test_server_tls_ws.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ class test_server_tls_ws {
6060
server_.close();
6161
}
6262

63+
/**
64+
* @brief Get boost asio ssl context.
65+
* @return ssl context
66+
*/
67+
MQTT_NS::tls::context& get_ssl_context() {
68+
return server_.get_ssl_context();
69+
}
70+
71+
/**
72+
* @brief Get boost asio ssl context.
73+
* @return ssl context
74+
*/
75+
MQTT_NS::tls::context const& get_ssl_context() const {
76+
return server_.get_ssl_context();
77+
}
78+
6379
private:
6480
MQTT_NS::server_tls_ws<> server_;
6581
MQTT_NS::broker::broker_t& b_;

test/unit/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ FOREACH (source_file ${check_PROGRAMS})
3939
TARGET_LINK_LIBRARIES (
4040
${source_file_we} mqtt_cpp_iface Boost::unit_test_framework
4141
)
42+
IF (MSVC AND MQTT_USE_STATIC_OPENSSL)
43+
TARGET_LINK_LIBRARIES (${source_file_we} Crypt32)
44+
ENDIF ()
45+
4246
IF (MQTT_USE_LOG)
4347
TARGET_COMPILE_DEFINITIONS (${source_file_we} PUBLIC $<IF:$<BOOL:${MQTT_USE_STATIC_BOOST}>,,BOOST_LOG_DYN_LINK>)
4448
TARGET_LINK_LIBRARIES (

0 commit comments

Comments
 (0)