Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ add_executable(amqpcpp_libuv_example libuv.cpp)
add_dependencies(amqpcpp_libuv_example amqpcpp)

target_link_libraries(amqpcpp_libuv_example amqpcpp uv pthread dl ssl)


###################################
# Libuv + external authentication
###################################

add_executable(amqpcpp_libuv_external_example libuv_external.cpp)

add_dependencies(amqpcpp_libuv_external_example amqpcpp)

target_link_libraries(amqpcpp_libuv_external_example amqpcpp uv pthread dl ssl crypto)
127 changes: 127 additions & 0 deletions examples/libuv_external.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* libuv_external.cpp
*
* Test program to check AMQP functionality based on LibUV
*
* @author Emiel Bruijntjes <[email protected]>
* @copyright 2015 - 2021 Copernica BV
*/

/**
* Dependencies
*/
#include <openssl/ssl.h>
#include <uv.h>
#include <amqpcpp.h>
#include <amqpcpp/libuv.h>

/**
* Custom handler
*/
class MyHandler : public AMQP::LibUvHandler
{
private:
/**
* Method that is called when a connection error occurs
* @param connection
* @param message
*/
virtual void onError(AMQP::TcpConnection *connection, const char *message) override
{
std::cout << "error: " << message << std::endl;
}

/**
* Method that is called when the TCP connection ends up in a connected state
* @param connection The TCP connection
*/
virtual void onConnected(AMQP::TcpConnection *connection) override
{
std::cout << "connected" << std::endl;
}

virtual bool onSecuring(AMQP::TcpConnection *connection, SSL* ssl) override
{
SSL_CTX* ctx = SSL_get_SSL_CTX(ssl);
if (!ctx)
{
std::cerr << "Cannot load SSL context." << std::endl;
return false;
}
if (SSL_CTX_load_verify_locations(ctx, "ca_certificate.pem", nullptr) != 1)
{
std::cerr << "Cannot load CA certificate." << std::endl;
return false;
}
if (SSL_use_certificate_file(ssl, "client_certificate.pem", SSL_FILETYPE_PEM) != 1)
{
std::cerr << "Cannot load client certificate." << std::endl;
return false;
}
if (SSL_use_PrivateKey_file(ssl, "private_key.pem", SSL_FILETYPE_PEM) != 1)
{
std::cerr << "Cannot load private key." << std::endl;
return false;
}
return true;
}

virtual bool onSecured(AMQP::TcpConnection *connection, const SSL* ssl) override
{
if (SSL_get_verify_result(ssl) != X509_V_OK)
return false;

X509* peer = SSL_get_peer_certificate(ssl);
if (!peer)
return false;

X509_free(peer);

return true;
}

public:
/**
* Constructor
* @param uv_loop
*/
MyHandler(uv_loop_t *loop) : AMQP::LibUvHandler(loop) {}

/**
* Destructor
*/
virtual ~MyHandler() = default;
};

/**
* Main program
* @return int
*/
int main()
{
// access to the event loop
auto *loop = uv_default_loop();

// handler for libev
MyHandler handler(loop);

// make a connection
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"), AMQP::ExternalAuth());

// we need a channel too
AMQP::TcpChannel channel(&connection);

// create a temporary queue
channel.declareQueue(AMQP::exclusive).onSuccess([&connection](const std::string &name, uint32_t messagecount, uint32_t consumercount) {

// report the name of the temporary queue
std::cout << "declared queue " << name << std::endl;
});

// run the loop
uv_run(loop, UV_RUN_DEFAULT);

// done
return 0;
}

1 change: 1 addition & 0 deletions include/amqpcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
#include "amqpcpp/throttle.h"
#include "amqpcpp/reliable.h"
#include "amqpcpp/login.h"
#include "amqpcpp/externalauth.h"
#include "amqpcpp/address.h"
#include "amqpcpp/connectionhandler.h"
#include "amqpcpp/connectionimpl.h"
Expand Down
55 changes: 55 additions & 0 deletions include/amqpcpp/authentication.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* The authentication information to access a server
*
* This class may provide a SASL PLAIN or EXTERNAL authentication
*
* @copyright 2014 - 2021 Copernica BV
*/

/**
* Include guard
*/
#pragma once

/**
* Dependencies
*/
#include <string>

/**
* Set up namespace
*/
namespace AMQP {

/**
* Class definition
*/
class Authentication
{
public:
/**
* Destructor
*/
virtual ~Authentication() = default;

/**
*
* @return string
*/
virtual std::string mechanism() const = 0;

/**
*
* @return string
*/
virtual std::string response() const
{
return "";
}
};

/**
* End of namespace
*/
}

29 changes: 19 additions & 10 deletions include/amqpcpp/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ class Connection

public:
/**
* Construct an AMQP object based on full login data
* Construct an AMQP object based on authentication data
*
* The first parameter is a handler object. This handler class is
* an interface that should be implemented by the caller.
*
*
* @param handler Connection handler
* @param login Login data
* @param auth Authentication data
* @param vhost Vhost to use
*/
Connection(ConnectionHandler *handler, const Login &login, const std::string &vhost) : _implementation(this, handler, login, vhost) {}
Connection(ConnectionHandler *handler, const Authentication &auth, const std::string &vhost) : _implementation(this, handler, auth, vhost) {}

/**
* Construct with default vhost
* @param handler Connection handler
* @param login Login data
* @param auth Authentication data
*/
Connection(ConnectionHandler *handler, const Login &login) : _implementation(this, handler, login, "/") {}
Connection(ConnectionHandler *handler, const Authentication &auth) : _implementation(this, handler, auth, "/") {}

/**
* Construct an AMQP object with default login data and default vhost
Expand Down Expand Up @@ -77,12 +77,21 @@ class Connection
Connection &operator=(const Connection &connection) = delete;

/**
* Retrieve the login data
* @return Login
* Retrieve the authentication mechanism
* @return string
*/
const std::string &authenticationMechanism() const
{
return _implementation.authenticationMechanism();
}

/**
* Retrieve the authentication response data
* @return string
*/
const Login &login() const
const std::string &authenticationResponse() const
{
return _implementation.login();
return _implementation.authenticationResponse();
}

/**
Expand Down
35 changes: 25 additions & 10 deletions include/amqpcpp/connectionimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "channelimpl.h"
#include "copiedbuffer.h"
#include "monitor.h"
#include "login.h"
#include "authentication.h"
#include <unordered_map>
#include <memory>
#include <queue>
Expand Down Expand Up @@ -108,10 +108,16 @@ class ConnectionImpl : public Watchable
uint32_t _expected = 7;

/**
* The login for the server (login, password)
* @var Login
* The authentication mechanism for the server
* @var Authentication mechanism
*/
Login _login;
std::string _auth_mechanism;

/**
* The authentication response for the server
* @var Authentication response
*/
std::string _auth_response;

/**
* Vhost to connect to
Expand Down Expand Up @@ -164,9 +170,9 @@ class ConnectionImpl : public Watchable
*
* @param parent Parent connection object
* @param handler Connection handler
* @param login Login data
* @param auth authentication data
*/
ConnectionImpl(Connection *parent, ConnectionHandler *handler, const Login &login, const std::string &vhost);
ConnectionImpl(Connection *parent, ConnectionHandler *handler, const Authentication& auth, const std::string &vhost);

public:
/**
Expand Down Expand Up @@ -274,12 +280,21 @@ class ConnectionImpl : public Watchable
void setReady();

/**
* Retrieve the login data
* @return Login
* Retrieve the authentication mechanism
* @return string
*/
const std::string &authenticationMechanism() const
{
return _auth_mechanism;
}

/**
* Retrieve the authentication response data
* @return string
*/
const Login &login() const
const std::string &authenticationResponse() const
{
return _login;
return _auth_response;
}

/**
Expand Down
43 changes: 43 additions & 0 deletions include/amqpcpp/externalauth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Authentication for EXTERNAL
*
* @copyright 2014 - 2021 Copernica BV
*/

/**
* Include guard
*/
#pragma once

/**
* Dependencies
*/
#include "authentication.h"

/**
* Set up namespace
*/
namespace AMQP {

/**
* Class definition
*/
class ExternalAuth : public Authentication
{
public:
/**
*
* @return string
*/
std::string mechanism() const override
{
return "EXTERNAL";
}

};

/**
* End of namespace
*/
}

11 changes: 10 additions & 1 deletion include/amqpcpp/linux_tcp/tcpconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,17 @@ class TcpConnection :
* Constructor
* @param handler User implemented handler object
* @param hostname The address to connect to
* @param auth The authentication to use
*/
TcpConnection(TcpHandler *handler, const Address &address);
TcpConnection(TcpHandler *handler, const Address &address, const Authentication& auth);

/**
* Constructor
* @param handler User implemented handler object
* @param hostname The address to connect to
*/
TcpConnection(TcpHandler *handler, const Address &address) :
TcpConnection(handler, address, address.login()) {}

/**
* No copying
Expand Down
Loading