added ability to set the handle to the openssl library (so that programs that load openssl via dlopen() can still use amqp-cpp)

This commit is contained in:
Emiel Bruijntjes 2018-03-09 15:08:52 +01:00
parent d8bc58604d
commit 4c2b8ff68e
4 changed files with 84 additions and 24 deletions

View File

@ -79,4 +79,4 @@
#include "amqpcpp/connectionhandler.h" #include "amqpcpp/connectionhandler.h"
#include "amqpcpp/connectionimpl.h" #include "amqpcpp/connectionimpl.h"
#include "amqpcpp/connection.h" #include "amqpcpp/connection.h"
#include "amqpcpp/openssl.h"

37
include/amqpcpp/openssl.h Normal file
View File

@ -0,0 +1,37 @@
/**
* OpenSSL.h
*
* Function to set openssl features
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2018 Copernica BV
*/
/**
* Include guard
*/
#pragma once
/**
* Begin of namespace
*/
namespace AMQP {
/**
* To make secure "amqps://" connections, AMQP-CPP relies on functions from the
* openssl library. It your application is dynamically linked to openssl (because
* it was compiled with the "-lssl" flag), this works flawlessly because AMQPCPP
* can then locate the openssl symbols in its own project space. However, if the
* openssl library was not linked, you either cannot use amqps:// connections,
* or you have to supply a handle to the openssl library yourself, using the
* following method.
*
* @param handle Handle returned by dlopen() that has access to openssl
*/
void openssl(void *handle);
/**
* End of namespace
*/
}

View File

@ -115,10 +115,11 @@ private:
public: public:
/** /**
* Constructor * Constructor
* @param handle Handle to access openssl
* @param name Name of the function * @param name Name of the function
*/ */
Function(const char *name) : Function(void *handle, const char *name) :
_method(dlsym(RTLD_DEFAULT, name)) {} _method(dlsym(handle, name)) {}
/** /**
* Destructor * Destructor

View File

@ -11,11 +11,33 @@
*/ */
#include "openssl.h" #include "openssl.h"
#include "function.h" #include "function.h"
#include "amqpcpp/openssl.h"
/** /**
* Begin of namespace * The handle to access openssl (the result of dlopen("openssl.so"))
* By default we set this to RTLD_DEFAULT, so that AMQP-CPP checks the internal process space
*/ */
namespace AMQP { namespace OpenSSL { static void *handle = RTLD_DEFAULT;
/**
* Just the AMQP namespace
*/
namespace AMQP {
/**
* Function to set the openssl handle
* @param ptr
*/
void openssl(void *ptr)
{
// store handle
handle = ptr;
}
/**
* Begin of AMQP::OpenSSL namespace
*/
namespace OpenSSL {
/** /**
* Is the openssl library loaded? * Is the openssl library loaded?
@ -24,7 +46,7 @@ namespace AMQP { namespace OpenSSL {
bool valid() bool valid()
{ {
// create a function // create a function
static Function<decltype(::SSL_CTX_new)> func("SSL_CTX_new"); static Function<decltype(::SSL_CTX_new)> func(handle, "SSL_CTX_new");
// we need a library // we need a library
return func; return func;
@ -37,13 +59,13 @@ bool valid()
const SSL_METHOD *TLS_client_method() const SSL_METHOD *TLS_client_method()
{ {
// create a function that loads the method // create a function that loads the method
static Function<decltype(TLS_client_method)> func("TLS_client_method"); static Function<decltype(TLS_client_method)> func(handle, "TLS_client_method");
// call the openssl function // call the openssl function
if (func) return func(); if (func) return func();
// older openssl libraries do not have this function, so we try to load an other function // older openssl libraries do not have this function, so we try to load an other function
static Function<decltype(TLS_client_method)> old("SSLv23_client_method"); static Function<decltype(TLS_client_method)> old(handle, "SSLv23_client_method");
// call the old one // call the old one
return old(); return old();
@ -57,7 +79,7 @@ const SSL_METHOD *TLS_client_method()
SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) SSL_CTX *SSL_CTX_new(const SSL_METHOD *method)
{ {
// create a function // create a function
static Function<decltype(::SSL_CTX_new)> func("SSL_CTX_new"); static Function<decltype(::SSL_CTX_new)> func(handle, "SSL_CTX_new");
// call the openssl function // call the openssl function
return func(method); return func(method);
@ -73,7 +95,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method)
int SSL_read(SSL *ssl, void *buf, int num) int SSL_read(SSL *ssl, void *buf, int num)
{ {
// create a function // create a function
static Function<decltype(::SSL_read)> func("SSL_read"); static Function<decltype(::SSL_read)> func(handle, "SSL_read");
// call the openssl function // call the openssl function
return func(ssl, buf, num); return func(ssl, buf, num);
@ -89,7 +111,7 @@ int SSL_read(SSL *ssl, void *buf, int num)
int SSL_write(SSL *ssl, const void *buf, int num) int SSL_write(SSL *ssl, const void *buf, int num)
{ {
// create a function // create a function
static Function<decltype(::SSL_write)> func("SSL_write"); static Function<decltype(::SSL_write)> func(handle, "SSL_write");
// call the openssl function // call the openssl function
return func(ssl, buf, num); return func(ssl, buf, num);
@ -104,7 +126,7 @@ int SSL_write(SSL *ssl, const void *buf, int num)
int SSL_set_fd(SSL *ssl, int fd) int SSL_set_fd(SSL *ssl, int fd)
{ {
// create a function // create a function
static Function<decltype(::SSL_set_fd)> func("SSL_set_fd"); static Function<decltype(::SSL_set_fd)> func(handle, "SSL_set_fd");
// call the openssl function // call the openssl function
return func(ssl, fd); return func(ssl, fd);
@ -119,7 +141,7 @@ int SSL_set_fd(SSL *ssl, int fd)
int SSL_pending(const SSL *ssl) int SSL_pending(const SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_pending)> func("SSL_pending"); static Function<decltype(::SSL_pending)> func(handle, "SSL_pending");
// call the openssl function // call the openssl function
return func(ssl); return func(ssl);
@ -132,7 +154,7 @@ int SSL_pending(const SSL *ssl)
void SSL_CTX_free(SSL_CTX *ctx) void SSL_CTX_free(SSL_CTX *ctx)
{ {
// create a function // create a function
static Function<decltype(::SSL_CTX_free)> func("SSL_CTX_free"); static Function<decltype(::SSL_CTX_free)> func(handle, "SSL_CTX_free");
// call the openssl function // call the openssl function
return func(ctx); return func(ctx);
@ -146,7 +168,7 @@ void SSL_CTX_free(SSL_CTX *ctx)
void SSL_free(SSL *ssl) void SSL_free(SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_free)> func("SSL_free"); static Function<decltype(::SSL_free)> func(handle, "SSL_free");
// call the openssl function // call the openssl function
return func(ssl); return func(ssl);
@ -160,7 +182,7 @@ void SSL_free(SSL *ssl)
SSL *SSL_new(SSL_CTX *ctx) SSL *SSL_new(SSL_CTX *ctx)
{ {
// create a function // create a function
static Function<decltype(::SSL_new)> func("SSL_new"); static Function<decltype(::SSL_new)> func(handle, "SSL_new");
// call the openssl function // call the openssl function
return func(ctx); return func(ctx);
@ -174,7 +196,7 @@ SSL *SSL_new(SSL_CTX *ctx)
int SSL_up_ref(SSL *ssl) int SSL_up_ref(SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(SSL_up_ref)> func("SSL_up_ref"); static Function<decltype(SSL_up_ref)> func(handle, "SSL_up_ref");
// call the openssl function if it exists // call the openssl function if it exists
if (func) return func(ssl); if (func) return func(ssl);
@ -192,7 +214,7 @@ int SSL_up_ref(SSL *ssl)
int SSL_shutdown(SSL *ssl) int SSL_shutdown(SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_shutdown)> func("SSL_shutdown"); static Function<decltype(::SSL_shutdown)> func(handle, "SSL_shutdown");
// call the openssl function // call the openssl function
return func(ssl); return func(ssl);
@ -205,7 +227,7 @@ int SSL_shutdown(SSL *ssl)
void SSL_set_connect_state(SSL *ssl) void SSL_set_connect_state(SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_set_connect_state)> func("SSL_set_connect_state"); static Function<decltype(::SSL_set_connect_state)> func(handle, "SSL_set_connect_state");
// call the openssl function // call the openssl function
func(ssl); func(ssl);
@ -220,7 +242,7 @@ void SSL_set_connect_state(SSL *ssl)
int SSL_do_handshake(SSL *ssl) int SSL_do_handshake(SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_do_handshake)> func("SSL_do_handshake"); static Function<decltype(::SSL_do_handshake)> func(handle, "SSL_do_handshake");
// call the openssl function // call the openssl function
return func(ssl); return func(ssl);
@ -234,7 +256,7 @@ int SSL_do_handshake(SSL *ssl)
int SSL_get_shutdown(const SSL *ssl) int SSL_get_shutdown(const SSL *ssl)
{ {
// create a function // create a function
static Function<decltype(::SSL_get_shutdown)> func("SSL_get_shutdown"); static Function<decltype(::SSL_get_shutdown)> func(handle, "SSL_get_shutdown");
// call the openssl function // call the openssl function
return func(ssl); return func(ssl);
@ -249,7 +271,7 @@ int SSL_get_shutdown(const SSL *ssl)
int SSL_get_error(const SSL *ssl, int ret) int SSL_get_error(const SSL *ssl, int ret)
{ {
// create a function // create a function
static Function<decltype(::SSL_get_error)> func("SSL_get_error"); static Function<decltype(::SSL_get_error)> func(handle, "SSL_get_error");
// call the openssl function // call the openssl function
return func(ssl, ret); return func(ssl, ret);
@ -266,7 +288,7 @@ int SSL_get_error(const SSL *ssl, int ret)
long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg) long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg)
{ {
// create a function // create a function
static Function<decltype(::SSL_ctrl)> func("SSL_ctrl"); static Function<decltype(::SSL_ctrl)> func(handle, "SSL_ctrl");
// call the openssl function // call the openssl function
return func(ssl, cmd, larg, parg); return func(ssl, cmd, larg, parg);
@ -282,7 +304,7 @@ long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg)
int SSL_use_certificate_file(SSL *ssl, const char *file, int type) int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
{ {
// create a function // create a function
static Function<decltype(::SSL_use_certificate_file)> func("SSL_use_certificate_file"); static Function<decltype(::SSL_use_certificate_file)> func(handle, "SSL_use_certificate_file");
// call the openssl function // call the openssl function
return func(ssl, file, type); return func(ssl, file, type);