Merge pull request #194 from CopernicaMarketingSoftware/openssl_auth
Openssl auth
This commit is contained in:
commit
963d06c1e8
|
|
@ -65,7 +65,7 @@ int main()
|
|||
MyHandler handler(loop);
|
||||
|
||||
// init the SSL library
|
||||
// SSL_library_init();
|
||||
SSL_library_init();
|
||||
|
||||
// make a connection
|
||||
AMQP::Address address("amqps://guest:guest@localhost/");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
* Function.h
|
||||
*
|
||||
* When you want to retrieve a function from a dynamicallly loaded
|
||||
* library, you normally use the dlsym() function for that. The
|
||||
* Function object is a little more convenient:
|
||||
*
|
||||
* // open the library
|
||||
* void *lib = dlopen("library.so");
|
||||
*
|
||||
* // get the function object
|
||||
* Function func<int(int)> magic_open(library, "my_function");
|
||||
*
|
||||
* // call the function
|
||||
* int result = func(123);
|
||||
*
|
||||
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
|
||||
* @copyright 2018 Copernica BV
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Include guard
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
/**
|
||||
* Namespace
|
||||
*/
|
||||
namespace AMQP {
|
||||
|
||||
/**
|
||||
* Make the Function class a templated class
|
||||
*/
|
||||
template <class T> class Function {};
|
||||
|
||||
/**
|
||||
* So that we can write a partial specialisation
|
||||
* using a function prototype, indicating the
|
||||
* prototype usable for the given callback
|
||||
*/
|
||||
template <class T, class ...Arguments>
|
||||
class Function<T(Arguments...)>
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Store pointer to the actual dynamically loaded
|
||||
* function. This is done in a union because the
|
||||
* result from a dlsym call is a void pointer which
|
||||
* cannot be legally cast into a function pointer.
|
||||
*
|
||||
* We therefore always set the first type (which is
|
||||
* void* making it legal) and, because all members
|
||||
* in a union share the same address, we can then
|
||||
* read the second type and actually call it.
|
||||
*
|
||||
* @var Callable
|
||||
*/
|
||||
union Callable {
|
||||
|
||||
/**
|
||||
* Property for getting and setting the return
|
||||
* value from dlsym. This is always a void*
|
||||
* @var void
|
||||
*/
|
||||
void *ptr;
|
||||
|
||||
/**
|
||||
* Property for executing the mapped function
|
||||
*
|
||||
* @param mixed,... function parameters
|
||||
* @return mixed
|
||||
*
|
||||
* @var function
|
||||
*/
|
||||
T (*func)(Arguments...);
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Callable() : ptr(nullptr) {}
|
||||
|
||||
/**
|
||||
* We may be moved
|
||||
*
|
||||
* @param callable the callable we are moving
|
||||
*/
|
||||
Callable(Callable&& callable) :
|
||||
ptr(callable.ptr)
|
||||
{
|
||||
// the other callable no longer has a handle
|
||||
callable.ptr = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy construtor
|
||||
* @param callable the callable we are moving
|
||||
*/
|
||||
Callable(const Callable &callable) :
|
||||
ptr(callable.ptr) {}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param function the mapped function
|
||||
*/
|
||||
Callable(void *function) : ptr(function) {}
|
||||
|
||||
} _method;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param library The library to load the function from
|
||||
* @param name Name of the function
|
||||
*/
|
||||
Function(void *library, const char *name) :
|
||||
_method(dlsym(library, name)) {}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~Function() {}
|
||||
|
||||
/**
|
||||
* Is this a valid function or not?
|
||||
* @return bool
|
||||
*/
|
||||
bool valid() const
|
||||
{
|
||||
return _method.ptr != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* The library object can also be used as in a boolean context,
|
||||
* for that there is an implementation of a casting operator, and
|
||||
* the negate operator
|
||||
* @return bool
|
||||
*/
|
||||
operator bool () const { return valid(); }
|
||||
bool operator ! () const { return !valid(); }
|
||||
|
||||
/**
|
||||
* Test whether we are a valid object
|
||||
* @param nullptr test if we are null
|
||||
*/
|
||||
bool operator==(std::nullptr_t /* nullptr */) const { return !valid(); }
|
||||
bool operator!=(std::nullptr_t /* nullptr */) const { return valid(); }
|
||||
|
||||
/**
|
||||
* Invoke the function
|
||||
*
|
||||
* @param mixed,...
|
||||
*/
|
||||
T operator()(Arguments... parameters) const
|
||||
{
|
||||
// check whether we have a valid function
|
||||
if (!valid()) throw std::bad_function_call();
|
||||
|
||||
// execute the method given all the parameters
|
||||
return _method.func(std::forward<Arguments>(parameters)...);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* End of namespace
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* OpenSSL.cpp
|
||||
*
|
||||
* Implementation file for the openssl.h header file
|
||||
*
|
||||
* @copyright 2018 Copernica BV
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
// #include "includes.h"
|
||||
#include "amqpcpp/linux_tcp/openssl.h"
|
||||
|
||||
#include "function.h"
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* Begin of namespace
|
||||
*/
|
||||
namespace AMQP { namespace OpenSSL {
|
||||
|
||||
/**
|
||||
* Get the library handle
|
||||
* @return void *
|
||||
*/
|
||||
static void *library()
|
||||
{
|
||||
// stored pointer
|
||||
static void *ptr = nullptr;
|
||||
|
||||
// is it already opened?
|
||||
if (ptr != nullptr) return ptr;
|
||||
|
||||
// open ourselves
|
||||
ptr = dlopen("libssl.so", RTLD_NOW);
|
||||
if (!ptr)
|
||||
{
|
||||
std::cout << "Cannot load library: " << dlerror() << std::endl;
|
||||
|
||||
// reset errors
|
||||
dlerror();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SSL library by registering algorithnms
|
||||
*/
|
||||
//~int SSL_library_init()
|
||||
//~{
|
||||
//~// create function
|
||||
//~static Function<decltype(::SSL_library_init)> func(library(), "SSL_libarary_init");
|
||||
|
||||
//~// call the openssl function
|
||||
//~func();
|
||||
//~}
|
||||
|
||||
/**
|
||||
* Create new SSL context
|
||||
* @param SSL_METHOD can be of the following types: TLS_method(), TLS_server_method(), TLS_client_method()
|
||||
* @return nullptr if failed pointer to object otherwise
|
||||
*/
|
||||
SSL_CTX *SSL_CTX_new(const SSL_METHOD *method)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_CTX_new)> func(library(), "SSL_CTX_new");
|
||||
|
||||
// call the openssl function
|
||||
return func(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from an ssl socket
|
||||
* @param ssl
|
||||
* @param buf
|
||||
* @param num
|
||||
* @return int number of bytes read
|
||||
*/
|
||||
int SSL_read(SSL *ssl, void *buf, int num)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_read)> func(library(), "SSL_read");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl, buf, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from an ssl socket
|
||||
* @param ssl
|
||||
* @param buf
|
||||
* @param num
|
||||
* @return int number of bytes written
|
||||
*/
|
||||
int SSL_write(SSL *ssl, const void *buf, int num)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_write)> func(library(), "SSL_write");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl, buf, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the SSL object with a file descriptor
|
||||
* @param ssl SSL object
|
||||
* @param fd file descriptor
|
||||
* @return int wether the operation succeeded or not
|
||||
*/
|
||||
int SSL_set_fd(SSL *ssl, int fd)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_set_fd)> func(library(), "SSL_set_fd");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl, fd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free an allocated SSL structure
|
||||
* @param ssl SSL object to be freed
|
||||
* @return int wether the operation succeeded or not
|
||||
*/
|
||||
void SSL_free(SSL *ssl)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_free)> func(library(), "SSL_free");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SSL structure for a connection
|
||||
* @param ctx SSL context object
|
||||
* @return SSL the created SSL oject based on th context
|
||||
*/
|
||||
SSL *SSL_new(SSL_CTX *ctx)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_new)> func(library(), "SSL_new");
|
||||
|
||||
// call the openssl function
|
||||
return func(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SSL structure for a connection
|
||||
* @param ctx SSL context object
|
||||
* @return SSL the created SSL oject based on th context
|
||||
*/
|
||||
int SSL_up_ref(SSL *ssl)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_up_ref)> func(library(), "SSL_up_ref");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down a TLS/SSL shut down
|
||||
* @param ssl SSL object to terminate
|
||||
* @return int returns diagnostic values
|
||||
*/
|
||||
int SSL_shutdown(SSL *ssl)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_shutdown)> func(library(), "SSL_shutdown");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare SSL object to work in client or server mode
|
||||
* @param ssl SSL object to set connect state on
|
||||
*/
|
||||
void SSL_set_connect_state(SSL *ssl)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_set_connect_state)> func(library(), "SSL_set_connect_state");
|
||||
|
||||
// call the openssl function
|
||||
func(ssl);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a TLS/SSL handshake
|
||||
* @param ssl SSL object
|
||||
* @return int returns diagnostic values
|
||||
*/
|
||||
int SSL_do_handshake(SSL *ssl)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_do_handshake)> func(library(), "SSL_do_handshake");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain result code for TLS/SSL I/O operation
|
||||
* @param ssl SSL object
|
||||
* @param ret the returned diagnostic value of SSL calls
|
||||
* @return int returns error values
|
||||
*/
|
||||
int SSL_get_error(const SSL *ssl, int ret)
|
||||
{
|
||||
// create a function
|
||||
static Function<decltype(::SSL_get_error)> func(library(), "SSL_get_error");
|
||||
|
||||
// call the openssl function
|
||||
return func(ssl, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* End of namespace
|
||||
*/
|
||||
}}
|
||||
|
||||
|
|
@ -12,6 +12,11 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
/**
|
||||
* Beginnig of namespace
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
/**
|
||||
* FIONREAD on Solaris is defined elsewhere
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue