Skip to content

Commit

Permalink
amqp: add tls support
Browse files Browse the repository at this point in the history
  • Loading branch information
Märt Bakhoff committed Mar 1, 2020
1 parent c3402e2 commit e4808ad
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 10 deletions.
108 changes: 98 additions & 10 deletions src/amqp.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <amqp_framing.h>

#ifdef HAVE_AMQP_TCP_SOCKET_H
#include <amqp_ssl_socket.h>
#include <amqp_tcp_socket.h>
#endif
#ifdef HAVE_AMQP_SOCKET_H
Expand Down Expand Up @@ -75,6 +76,13 @@ struct camqp_config_s {
char *user;
char *password;

bool tls_enabled;
bool tls_verify_peer;
bool tls_verify_hostname;
char *tls_cacert;
char *tls_client_cert;
char *tls_client_key;

char *exchange;
char *routing_key;

Expand Down Expand Up @@ -149,6 +157,9 @@ static void camqp_config_free(void *ptr) /* {{{ */
sfree(conf->vhost);
sfree(conf->user);
sfree(conf->password);
sfree(conf->tls_cacert);
sfree(conf->tls_client_cert);
sfree(conf->tls_client_key);
sfree(conf->exchange);
sfree(conf->exchange_type);
sfree(conf->queue);
Expand Down Expand Up @@ -430,20 +441,56 @@ static int camqp_connect(camqp_config_t *conf) /* {{{ */
#ifdef HAVE_AMQP_TCP_SOCKET
#define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us \
*/
/* TODO: add support for SSL using amqp_ssl_socket_new
* and related functions */
socket = amqp_tcp_socket_new(conf->connection);
if (!socket) {
ERROR("amqp plugin: amqp_tcp_socket_new failed.");
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return ENOMEM;

if (conf->tls_enabled) {
socket = amqp_ssl_socket_new(conf->connection);
if (!socket) {
ERROR("amqp plugin: amqp_ssl_socket_new failed.");
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return ENOMEM;
}

#if AMQP_VERSION >= 0x00080000
amqp_ssl_socket_set_verify_peer(socket, conf->tls_verify_peer);
amqp_ssl_socket_set_verify_hostname(socket, conf->tls_verify_hostname);
#endif

if (conf->tls_cacert) {
status = amqp_ssl_socket_set_cacert(socket, conf->tls_cacert);
if (status < 0) {
ERROR("amqp plugin: amqp_ssl_socket_set_cacert failed: %s",
amqp_error_string2(status));
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return status;
}
}
if (conf->tls_client_cert && conf->tls_client_key) {
status = amqp_ssl_socket_set_key(socket, conf->tls_client_cert,
conf->tls_client_key);
if (status < 0) {
ERROR("amqp plugin: amqp_ssl_socket_set_key failed: %s",
amqp_error_string2(status));
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return status;
}
}
} else {
socket = amqp_tcp_socket_new(conf->connection);
if (!socket) {
ERROR("amqp plugin: amqp_tcp_socket_new failed.");
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return ENOMEM;
}
}

status = amqp_socket_open(socket, CONF(conf, host), conf->port);
if (status < 0) {
status *= -1;
ERROR("amqp plugin: amqp_socket_open failed: %s", STRERROR(status));
ERROR("amqp plugin: amqp_socket_open failed: %s",
amqp_error_string2(status));
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
return status;
Expand Down Expand Up @@ -845,6 +892,12 @@ static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */
conf->vhost = NULL;
conf->user = NULL;
conf->password = NULL;
conf->tls_enabled = false;
conf->tls_verify_peer = true;
conf->tls_verify_hostname = true;
conf->tls_cacert = NULL;
conf->tls_client_cert = NULL;
conf->tls_client_key = NULL;
conf->exchange = NULL;
conf->routing_key = NULL;
conf->connection_retry_delay = 0;
Expand Down Expand Up @@ -890,6 +943,18 @@ static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */
status = cf_util_get_string(child, &conf->user);
else if (strcasecmp("Password", child->key) == 0)
status = cf_util_get_string(child, &conf->password);
else if (strcasecmp("TLSEnabled", child->key) == 0)
status = cf_util_get_boolean(child, &conf->tls_enabled);
else if (strcasecmp("TLSVerifyPeer", child->key) == 0)
status = cf_util_get_boolean(child, &conf->tls_verify_peer);
else if (strcasecmp("TLSVerifyHostName", child->key) == 0)
status = cf_util_get_boolean(child, &conf->tls_verify_hostname);
else if (strcasecmp("TLSCACert", child->key) == 0)
status = cf_util_get_string(child, &conf->tls_cacert);
else if (strcasecmp("TLSClientCert", child->key) == 0)
status = cf_util_get_string(child, &conf->tls_client_cert);
else if (strcasecmp("TLSClientKey", child->key) == 0)
status = cf_util_get_string(child, &conf->tls_client_key);
else if (strcasecmp("Exchange", child->key) == 0)
status = cf_util_get_string(child, &conf->exchange);
else if (strcasecmp("ExchangeType", child->key) == 0)
Expand Down Expand Up @@ -959,6 +1024,29 @@ static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */
"without the \"Exchange\" option. It will be ignored.");
}

#if !defined(AMQP_VERSION) || AMQP_VERSION < 0x00040000
if (status == 0 && conf->tls_enabled) {
ERROR("amqp plugin: TLSEnabled is set but not supported. "
"rebuild collectd with rabbitmq-c >= 0.4");
status = 1;
}
#endif
#if !defined(AMQP_VERSION) || AMQP_VERSION < 0x00080000
if (status == 0 && (!conf->tls_verify_peer || !conf->tls_verify_hostname)) {
ERROR("amqp plugin: disabling TLSVerify* is not supported. "
"rebuild collectd with rabbitmq-c >= 0.8");
status = 1;
}
#endif
if (status == 0 &&
(conf->tls_client_cert != NULL || conf->tls_client_key != NULL)) {
if (conf->tls_client_cert == NULL || conf->tls_client_key == NULL) {
ERROR("amqp plugin: only one of TLSClientCert/TLSClientKey is "
"configured. need both or neither.");
status = 1;
}
}

if (status != 0) {
camqp_config_free(conf);
return status;
Expand Down
6 changes: 6 additions & 0 deletions src/collectd.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@
# Persistent false
# StoreRates false
# ConnectionRetryDelay 0
# TLSEnabled false
# TLSVerifyPeer true
# TLSVerifyHostName true
# TLSCACert "/path/to/ca.pem"
# TLSClientCert "/path/to/client-cert.pem"
# TLSClientKey "/path/to/client-key.pem"
# </Publish>
#</Plugin>

Expand Down
47 changes: 47 additions & 0 deletions src/collectd.conf.pod
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,12 @@ B<Synopsis:>
# ConnectionRetryDelay 0
# Format "command"
# StoreRates false
# TLSEnabled false
# TLSVerifyPeer true
# TLSVerifyHostName true
# TLSCACert "/path/to/ca.pem"
# TLSClientCert "/path/to/client-cert.pem"
# TLSClientKey "/path/to/client-key.pem"
# GraphitePrefix "collectd."
# GraphiteEscapeChar "_"
# GraphiteSeparateInstances false
Expand All @@ -572,6 +578,12 @@ B<Synopsis:>
# QueueAutoDelete true
# RoutingKey "collectd.#"
# ConnectionRetryDelay 0
# TLSEnabled false
# TLSVerifyPeer true
# TLSVerifyHostName true
# TLSCACert "/path/to/ca.pem"
# TLSClientCert "/path/to/client-cert.pem"
# TLSClientKey "/path/to/client-key.pem"
</Subscribe>
</Plugin>

Expand Down Expand Up @@ -736,6 +748,41 @@ If set to B<false> (the default) the C<.> (dot) character is replaced with
I<GraphiteEscapeChar>. Otherwise, if set to B<true>, the C<.> (dot) character
is preserved, i.e. passed through.

=item B<TLSEnabled> B<true>|B<false>

If set to B<true> then connect to the broker using a TLS connection.
If set to B<false> (the default), then a plain text connection is used.

Requires rabbitmq-c >= 0.4.

=item B<TLSVerifyPeer> B<true>|B<false>

If set to B<true> (the default) then the server certificate chain is verified.
Setting this to B<false> will skip verification (insecure).

Requires rabbitmq-c >= 0.8.

=item B<TLSVerifyHostName> B<true>|B<false>

If set to B<true> (the default) then the server host name is verified.
Setting this to B<false> will skip verification (insecure).

Requires rabbitmq-c >= 0.8.

=item B<TLSCACert> I<Path>

Path to the CA cert file in PEM format.

=item B<TLSClientCert> I<Path>

Path to the client certificate in PEM format.
If this is set, then B<TLSClientKey> must be set as well.

=item B<TLSClientKey> I<Path>

Path to the client key in PEM format.
If this is set, then B<TLSClientCert> must be set as well.

=back

=head2 Plugin C<amqp1>
Expand Down

0 comments on commit e4808ad

Please sign in to comment.