1
0
mirror of https://github.com/eclipse/paho.mqtt.cpp.git synced 2025-05-09 19:31:22 +08:00

Added SSL option callbacks

This commit is contained in:
fpagliughi 2020-12-06 14:32:22 -05:00
parent 9321cc5e6a
commit f57c54f8d4
3 changed files with 162 additions and 15 deletions

View File

@ -54,18 +54,18 @@ namespace mqtt {
#if defined(PAHO_MQTTPP_VERSIONS)
/** The version number for the client library. */
const uint32_t PAHO_MQTTPP_VERSION = 0x01010000;
const uint32_t PAHO_MQTTPP_VERSION = 0x01020000;
/** The version string for the client library */
const string PAHO_MQTTPP_VERSION_STR("Paho MQTT C++ (mqttpp) v. 1.1");
const string PAHO_MQTTPP_VERSION_STR("Paho MQTT C++ (mqttpp) v. 1.2");
/** Copyright notice for the client library */
const string PAHO_MQTTPP_COPYRIGHT("Copyright (c) 2013-2019 Frank Pagliughi");
const string PAHO_MQTTPP_COPYRIGHT("Copyright (c) 2013-2020 Frank Pagliughi");
#else
/** The version number for the client library. */
const uint32_t VERSION = 0x01010000;
const uint32_t VERSION = 0x01020000;
/** The version string for the client library */
const string VERSION_STR("Paho MQTT C++ (mqttpp) v. 1.1");
const string VERSION_STR("Paho MQTT C++ (mqttpp) v. 1.2");
/** Copyright notice for the client library */
const string COPYRIGHT("Copyright (c) 2013-2019 Frank Pagliughi");
const string COPYRIGHT("Copyright (c) 2013-2020 Frank Pagliughi");
#endif
/////////////////////////////////////////////////////////////////////////////

View File

@ -7,7 +7,7 @@
/*******************************************************************************
* Copyright (c) 2016 Guilherme Ferreira <guilherme.maciel.ferreira@gmail.com>
* Copyright (c) 2016-2019 Frank Pagliughi <fpagliughi@mindspring.com>
* Copyright (c) 2016-2020 Frank Pagliughi <fpagliughi@mindspring.com>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -32,6 +32,7 @@
#include "mqtt/topic.h"
#include "mqtt/types.h"
#include <vector>
#include <functional>
namespace mqtt {
@ -42,6 +43,26 @@ namespace mqtt {
*/
class ssl_options
{
public:
/** Smart/shared pointer to an object of this class. */
using ptr_t = std::shared_ptr<ssl_options>;
/** Smart/shared pointer to a const object of this class. */
using const_ptr_t = std::shared_ptr<const ssl_options>;
/** Unique pointer to an object of this class. */
using unique_ptr_t = std::unique_ptr<ssl_options>;
/** Handler type for error message callbacks */
using error_handler = std::function<void(const ssl_options&, const string& errMsg)>;
/**
* Handler type for TLS-PSK option callback.
* On success, the callback should return the length of the PSK (in
* bytes). On failure, it should throw or return zero.
*/
using psk_handler = std::function<unsigned(const ssl_options&, const string& hint,
char *identity, size_t max_identity_len,
unsigned char *psk, size_t max_psk_len)>;
private:
/** The default C struct */
static const MQTTAsync_SSLOptions DFLT_C_STRUCT ;
@ -72,9 +93,18 @@ class ssl_options
*/
string enabledCipherSuites_;
/** Error message callback handler */
error_handler errHandler_;
/** PSK callback handler */
psk_handler pskHandler_;
/** Callbacks from the C library */
static int on_error(const char *str, size_t len, void *context);
static unsigned on_psk(const char *hint, char *identity, unsigned int max_identity_len,
unsigned char *psk, unsigned int max_psk_len, void *context);
/** The connect options has special access */
friend class connect_options;
//friend class connect_options_test;
/**
* Gets a pointer to the C-language NUL-terminated strings for the
@ -95,13 +125,6 @@ class ssl_options
void update_c_struct();
public:
/** Smart/shared pointer to an object of this class. */
using ptr_t = std::shared_ptr<ssl_options>;
/** Smart/shared pointer to a const object of this class. */
using const_ptr_t = std::shared_ptr<const ssl_options>;
/** Unique pointer to an object of this class. */
using unique_ptr_t = std::unique_ptr<ssl_options>;
/**
* Constructs a new MqttConnectOptions object using the default values.
*/
@ -279,6 +302,17 @@ public:
* format.
*/
void ca_path(const string& path);
/**
* Registers the error message callback handler.
* @param cb The callback to receive error messages.
*/
void set_error_handler(error_handler cb);
/**
* Registers a callback handler to set the TLS-PSK options.
* See: OpenSSL SSL_CTX_set_psk_client_callback()
* @param cb The callback.
*/
void set_psk_handler(psk_handler cb);
};
/**
@ -402,6 +436,23 @@ public:
opts_.ca_path(path);
return *this;
}
/**
* Registers an error callback handler.
* @param cb The callback to receive error messages.
*/
auto error_handler(ssl_options::error_handler cb) -> self& {
opts_.set_error_handler(cb);
return *this;
}
/**
* Registers a callback handler to set the TLS-PSK options.
* See: OpenSSL SSL_CTX_set_psk_client_callback()
* @param cb The callback.
*/
auto psk_handler(ssl_options::psk_handler cb) -> self& {
opts_.set_psk_handler(cb);
return *this;
}
/**
* Finish building the options and return them.
* @return The option struct as built.

View File

@ -64,8 +64,74 @@ void ssl_options::update_c_struct()
opts_.privateKey = c_str(privateKey_);
opts_.privateKeyPassword = c_str(privateKeyPassword_);
opts_.enabledCipherSuites = c_str(enabledCipherSuites_);
if (errHandler_) {
opts_.ssl_error_cb = &ssl_options::on_error;
opts_.ssl_error_context = this;
}
else {
opts_.ssl_error_cb = nullptr;
opts_.ssl_error_context = nullptr;
}
if (pskHandler_) {
opts_.ssl_psk_cb = &ssl_options::on_psk;
opts_.ssl_psk_context = this;
}
else {
opts_.ssl_psk_cb = nullptr;
opts_.ssl_psk_context = nullptr;
}
}
// --------------------------------------------------------------------------
int ssl_options::on_error(const char *str, size_t len, void *context)
{
try {
if (context && str && len > 0) {
string errMsg { str, str+len };
ssl_options* opts = static_cast<ssl_options*>(context);
auto& errHandler = opts->errHandler_;
if (errHandler)
errHandler(*opts, errMsg);
return MQTTASYNC_SUCCESS;
}
}
catch (...) {}
return MQTTASYNC_FAILURE;
}
unsigned ssl_options::on_psk(const char *hint, char *identity, unsigned max_identity_len,
unsigned char *psk, unsigned max_psk_len, void *context)
{
unsigned ret = 0;
try {
if (context) {
auto hintStr = (hint) ? string(hint) : string();
ssl_options* opts = static_cast<ssl_options*>(context);
auto& pskHandler = opts->pskHandler_;
if (pskHandler) {
ret = pskHandler(*opts, hintStr,
identity, size_t(max_identity_len),
psk, size_t(max_psk_len));
}
}
}
catch (...) {}
return ret;
}
// --------------------------------------------------------------------------
ssl_options& ssl_options::operator=(const ssl_options& rhs)
{
if (&rhs == this)
@ -100,6 +166,8 @@ ssl_options& ssl_options::operator=(ssl_options&& rhs)
return *this;
}
// --------------------------------------------------------------------------
void ssl_options::set_trust_store(const string& trustStore)
{
trustStore_ = trustStore;
@ -141,6 +209,34 @@ void ssl_options::ca_path(const string& path)
opts_.CApath = c_str(caPath_);
}
void ssl_options::set_error_handler(error_handler cb)
{
errHandler_ = cb;
if (errHandler_) {
opts_.ssl_error_cb = &ssl_options::on_error;
opts_.ssl_error_context = this;
}
else {
opts_.ssl_error_cb = nullptr;
opts_.ssl_error_context = nullptr;
}
}
void ssl_options::set_psk_handler(psk_handler cb)
{
pskHandler_ = cb;
if (pskHandler_) {
opts_.ssl_psk_cb = &ssl_options::on_psk;
opts_.ssl_psk_context = this;
}
else {
opts_.ssl_psk_cb = nullptr;
opts_.ssl_psk_context = nullptr;
}
}
/////////////////////////////////////////////////////////////////////////////
} // end namespace mqtt