Skip to content
Merged
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
45 changes: 45 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2638,6 +2638,16 @@ AC_ARG_ENABLE(redis_tests,
)
AM_CONDITIONAL(ENABLE_REDIS_TESTS, test x$enable_redis_tests = xyes)

AC_ARG_ENABLE(redis_ssl,
[AS_HELP_STRING([--enable-redis-ssl],[Enable redis ssl support @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_redis_ssl="yes" ;;
no) enable_redis_ssl="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-redis-ssl) ;;
esac],
[enable_redis_ssl=no]
)

if test "x$enable_omhiredis" = "xyes" -o "x$enable_imhiredis" = "xyes" ; then
PKG_CHECK_MODULES(HIREDIS, hiredis >= 0.10.1, [],
[AC_SEARCH_LIBS(redisConnectWithTimeout, hiredis,
Expand All @@ -2662,6 +2672,39 @@ if test "x$enable_omhiredis" = "xyes" -o "x$enable_imhiredis" = "xyes" ; then
[AC_MSG_ERROR([hiredis not found])]
)]
)
if test "x$enable_redis_ssl" = "xyes"; then
PKG_CHECK_MODULES(HIREDIS_SSL, hiredis_ssl >= 1.0.0,
# hiredis_ssl found using pkg-config
[
AC_DEFINE(HIREDIS_SSL, 1, [TLS support enabled in hiredis])
],
# hiredis_ssl not found with pkg-static, searching for it manually
[AC_SEARCH_LIBS(redisCreateSSLContext, hiredis_ssl,
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[ #include <hiredis/hiredis.h>
#include <hiredis/hiredis_ssl.h>
]],
[[ #define major 1
#define minor 0
#define patch 0
#if (( HIREDIS_MAJOR > major ) || \
(( HIREDIS_MAJOR == major ) && ( HIREDIS_MINOR > minor )) || \
(( HIREDIS_MAJOR == major ) && ( HIREDIS_MINOR == minor ) && ( HIREDIS_PATCH >= patch ))) \
/* OK */
#else
# error Hiredis_ssl version must be >= major.minor.path
#endif
]]
)],
[],
[AC_MSG_ERROR([hiredis_ssl version must be >= 1.0.0])]
)],
[AC_MSG_WARN([hiredis_ssl not found, no TLS support in hiredis])]
)]
)
fi

fi

if test "x$enable_imhiredis" = "xyes" ; then
Expand All @@ -2672,6 +2715,7 @@ if test "x$enable_imhiredis" = "xyes" ; then
],
# libevent not found
[AC_MSG_ERROR([no libevent >= 2.0 found with pthreads support, imhiredis cannot use pub/sub])])

fi

if test "x$enable_imhiredis" = "xyes" || test "x$enable_omhiredis" = "xyes"; then
Expand Down Expand Up @@ -2982,6 +3026,7 @@ echo " kafka static linking enabled: $enable_kafka_static"
echo " qpid proton static linking enabled: $enable_qpidproton_static"
echo " atomic operations enabled: $enable_atomic_operations"
echo " libcap-ng support enabled: $enable_libcapng"
echo " redis ssl support enabled: $enable_redis_ssl"

echo
echo "---{ input plugins }---"
Expand Down
4 changes: 2 additions & 2 deletions contrib/omhiredis/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pkglib_LTLIBRARIES = omhiredis.la
omhiredis_la_SOURCES = omhiredis.c
omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS)
omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) $(HIREDIS_SSL_CFLAGS)
omhiredis_la_LDFLAGS = -module -avoid-version
omhiredis_la_LIBADD = $(HIREDIS_LIBS)
omhiredis_la_LIBADD = $(HIREDIS_LIBS) $(HIREDIS_SSL_LIBS)

EXTRA_DIST =
107 changes: 106 additions & 1 deletion contrib/omhiredis/omhiredis.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
*
* Author: Brian Knox
* <bknox@digitalocean.com>
*
* Author: Jérémie Jourdin (TLS support)
* <jeremie.jourdin@advens.fr>
*/


Expand All @@ -32,6 +35,9 @@
#include <time.h>
#include <math.h>
#include <hiredis/hiredis.h>
#ifdef HIREDIS_SSL
#include <hiredis/hiredis_ssl.h>
#endif

#include "rsyslog.h"
#include "conf.h"
Expand Down Expand Up @@ -93,13 +99,25 @@ typedef struct _instanceData {
- $.redis!index
Those 2 infos can either be provided through usage of imhiredis
or set manually with Rainerscript */
#ifdef HIREDIS_SSL
sbool use_tls; /* Should we use TLS to connect to redis ? */
char *ca_cert_bundle; /* CA bundle file */
char *ca_cert_dir; /* Path of trusted certificates */
char *client_cert; /* Client certificate */
char *client_key; /* Client private key */
char *sni; /* TLS Server Name Indication */
#endif

} instanceData;

typedef struct wrkrInstanceData {
instanceData *pData; /* instanc data */
redisContext *conn; /* redis connection */
int count; /* count of command sent for current batch */
#ifdef HIREDIS_SSL
redisSSLContext *ssl_conn; /* redis ssl connection */
redisSSLContextError ssl_error; /* ssl error handler */
#endif
} wrkrInstanceData_t;

static struct cnfparamdescr actpdescr[] = {
Expand All @@ -122,6 +140,14 @@ static struct cnfparamdescr actpdescr[] = {
{ "stream.dynaKeyAck", eCmdHdlrBinary, 0 },
{ "stream.dynaGroupAck", eCmdHdlrBinary, 0 },
{ "stream.dynaIndexAck", eCmdHdlrBinary, 0 },
#ifdef HIREDIS_SSL
{ "use_tls", eCmdHdlrBinary, 0 },
{ "ca_cert_bundle", eCmdHdlrGetWord, 0 },
{ "ca_cert_dir", eCmdHdlrGetWord, 0 },
{ "client_cert", eCmdHdlrGetWord, 0 },
{ "client_key", eCmdHdlrGetWord, 0 },
{ "sni", eCmdHdlrGetWord, 0 },
#endif
};

static struct cnfparamblk actpblk = {
Expand All @@ -137,6 +163,10 @@ ENDcreateInstance
BEGINcreateWrkrInstance
CODESTARTcreateWrkrInstance
pWrkrData->conn = NULL; /* Connect later */
#ifdef HIREDIS_SSL
pWrkrData->ssl_conn = NULL; /* Connect later */
pWrkrData->ssl_error = REDIS_SSL_CTX_NONE;
#endif
ENDcreateWrkrInstance

BEGINisCompatibleWithFeature
Expand All @@ -152,6 +182,12 @@ static void closeHiredis(wrkrInstanceData_t *pWrkrData)
redisFree(pWrkrData->conn);
pWrkrData->conn = NULL;
}
#ifdef HIREDIS_SSL
if(pWrkrData->ssl_conn != NULL) {
redisFreeSSLContext(pWrkrData->ssl_conn);
pWrkrData->ssl_conn = NULL;
}
#endif
}

/* Free our instance data. */
Expand All @@ -168,6 +204,13 @@ CODESTARTfreeInstance
free(pData->streamGroupAck);
free(pData->streamIndexAck);
free(pData->streamOutField);
#ifdef HIREDIS_SSL
free(pData->ca_cert_bundle);
free(pData->ca_cert_dir);
free(pData->client_cert);
free(pData->client_key);
free(pData->sni);
#endif
ENDfreeInstance

BEGINfreeWrkrInstance
Expand Down Expand Up @@ -195,13 +238,34 @@ static rsRetVal initHiredis(wrkrInstanceData_t *pWrkrData, int bSilent)
struct timeval timeout = { 1, 500000 }; /* 1.5 seconds */
pWrkrData->conn = redisConnectWithTimeout(server, pWrkrData->pData->port,
timeout);
if (pWrkrData->conn->err) {
if (pWrkrData->conn == NULL || pWrkrData->conn->err) {
if(!bSilent)
LogError(0, RS_RET_SUSPENDED,
"can not initialize redis handle");
ABORT_FINALIZE(RS_RET_SUSPENDED);
}

#ifdef HIREDIS_SSL
if (pWrkrData->pData->use_tls) {
pWrkrData->ssl_conn = redisCreateSSLContext(pWrkrData->pData->ca_cert_bundle, pWrkrData->pData->ca_cert_dir, pWrkrData->pData->client_cert, pWrkrData->pData->client_key, pWrkrData->pData->sni, &pWrkrData->ssl_error);
if (!pWrkrData->ssl_conn || pWrkrData->ssl_error != REDIS_SSL_CTX_NONE) {
LogError(0, NO_ERRCODE, "omhiredis: SSL Context error: %s", redisSSLContextGetError(pWrkrData->ssl_error));
if(!bSilent)
LogError(0, RS_RET_SUSPENDED,
"[TLS] can not initialize redis handle");
ABORT_FINALIZE(RS_RET_SUSPENDED);
}
if (redisInitiateSSLWithContext(pWrkrData->conn, pWrkrData->ssl_conn) != REDIS_OK) {
LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr);
LogError(0, NO_ERRCODE, "omhiredis: SSL Context error: %s", redisSSLContextGetError(pWrkrData->ssl_error));
if(!bSilent)
LogError(0, RS_RET_SUSPENDED,
"[TLS] can not initialize redis handle");
ABORT_FINALIZE(RS_RET_SUSPENDED);
}
}
#endif

if (pWrkrData->pData->serverpassword != NULL) {
reply = redisCommand(pWrkrData->conn, "AUTH %s", (char*) pWrkrData->pData->serverpassword);
if (reply == NULL) {
Expand All @@ -219,6 +283,12 @@ static rsRetVal initHiredis(wrkrInstanceData_t *pWrkrData, int bSilent)
redisFree(pWrkrData->conn);
pWrkrData->conn = NULL;
}
#ifdef HIREDIS_SSL
if (iRet != RS_RET_OK && pWrkrData-> ssl_conn != NULL) {
redisFreeSSLContext(pWrkrData->ssl_conn);
pWrkrData->ssl_conn = NULL;
}
#endif
if (reply != NULL) freeReplyObject(reply);
RETiRet;
}
Expand Down Expand Up @@ -470,6 +540,14 @@ setInstParamDefaults(instanceData *pData)
pData->streamCapacityLimit = 0;
pData->streamAck = 0;
pData->streamDel = 0;
#ifdef HIREDIS_SSL
pData->use_tls = 0;
pData->ca_cert_bundle = NULL;
pData->ca_cert_dir = NULL;
pData->client_cert = NULL;
pData->client_key = NULL;
pData->sni = NULL;
#endif
}

/* here is where the work to set up a new instance
Expand Down Expand Up @@ -545,13 +623,34 @@ CODESTARTnewActInst
} else if(!strcmp(actpblk.descr[i].name, "expiration")) {
pData->expiration = pvals[i].val.d.n;
dbgprintf("omhiredis: expiration set to %d\n", pData->expiration);
#ifdef HIREDIS_SSL
} else if(!strcmp(actpblk.descr[i].name, "use_tls")) {
pData->use_tls = pvals[i].val.d.n;
} else if(!strcmp(actpblk.descr[i].name, "ca_cert_bundle")) {
pData->ca_cert_bundle = (char*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "ca_cert_dir")) {
pData->ca_cert_dir = (char*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "client_cert")) {
pData->client_cert = (char*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "client_key")) {
pData->client_key = (char*)es_str2cstr(pvals[i].val.d.estr, NULL);
} else if(!strcmp(actpblk.descr[i].name, "sni")) {
pData->sni = (char*)es_str2cstr(pvals[i].val.d.estr, NULL);
#endif
} else {
dbgprintf("omhiredis: program error, non-handled "
"param '%s'\n", actpblk.descr[i].name);
}
}

dbgprintf("omhiredis: checking config sanity\n");

#ifdef HIREDIS_SSL
if((pData->client_cert == NULL) ^ (pData->client_key == NULL)){
LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "omhiredis: \"client_cert\" and \"client_key\" must be specified together!");
ABORT_FINALIZE(RS_RET_PARAM_ERROR);
}
#endif

if (!pData->modeDescription) {
dbgprintf("omhiredis: no mode specified, setting it to 'template'\n");
Expand Down Expand Up @@ -750,4 +849,10 @@ CODEmodInit_QueryRegCFSLineHdlr
ABORT_FINALIZE(RS_RET_ERR);
}
DBGPRINTF("omhiredis: module compiled with rsyslog version %s.\n", VERSION);

#ifdef HIREDIS_SSL
// initialize OpenSSL
redisInitOpenSSL();
#endif

ENDmodInit
Loading