summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-02-02 00:45:39 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2011-02-02 00:45:39 +0100
commit910f635cececf329dd50aedb9f6e1a8fae4efb0c (patch)
tree11b215e3513b7c9d16a42f9af8ab5774504c8e29
parentbea499dcb2747d1f5b42eae4978cfe86a37dc957 (diff)
downloadrsyslog-910f635cececf329dd50aedb9f6e1a8fae4efb0c.tar.gz
rsyslog-910f635cececf329dd50aedb9f6e1a8fae4efb0c.tar.xz
rsyslog-910f635cececf329dd50aedb9f6e1a8fae4efb0c.zip
added support for TLS (in anon mode) to tcpflood
-rw-r--r--ChangeLog1
-rw-r--r--configure.ac1
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/tcpflood.c128
4 files changed, 130 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e6667c52..66743ad0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+- added support for TLS (in anon mode) to tcpflood
- improved TLS error reporting
- improved TLS startup (Diffie-Hellman bits do not need to be generated,
as we do not support full anon key exchange -- we always need certs)
diff --git a/configure.ac b/configure.ac
index b1af0662..1cde5935 100644
--- a/configure.ac
+++ b/configure.ac
@@ -651,6 +651,7 @@ AC_ARG_ENABLE(gnutls,
)
if test "x$enable_gnutls" = "xyes"; then
PKG_CHECK_MODULES(GNUTLS, gnutls >= 1.4.0)
+ AC_DEFINE([ENABLE_GNUTLS], [1], [Indicator that GnuTLS is present])
fi
AM_CONDITIONAL(ENABLE_GNUTLS, test x$enable_gnutls = xyes)
AC_SUBST(GNUTLS_CFLAGS)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 44c1daa7..68e84d53 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -326,7 +326,11 @@ uxsockrcvr_SOURCES = uxsockrcvr.c
uxsockrcvr_LDADD = $(SOL_LIBS)
tcpflood_SOURCES = tcpflood.c
-tcpflood_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS)
+tcpflood_CPPFLAGS = $(PTHREADS_CFLAGS) $(GNUTLS_CFLAGS)
+tcpflood_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS) $(GNUTLS_LIBS)
+if ENABLE_GNUTLS
+tcpflood_LDADD += -lgcrypt
+endif
syslog_caller_SOURCES = syslog_caller.c
syslog_caller_LDADD = $(SOL_LIBS)
diff --git a/tests/tcpflood.c b/tests/tcpflood.c
index 7b376bdd..eb2259ec 100644
--- a/tests/tcpflood.c
+++ b/tests/tcpflood.c
@@ -48,6 +48,8 @@
* -b number of messages within a batch (default: 100,000,000 millions)
* -Y use multiple threads, one per connection (which means 1 if one only connection
* is configured!)
+ * -z private key file for TLS mode
+ * -Z cert (public key) file for TLS mode
*
* Part of the testbench for rsyslog.
*
@@ -85,6 +87,12 @@
#include <pthread.h>
#include <sys/resource.h>
#include <sys/time.h>
+#include <errno.h>
+#ifdef ENABLE_GNUTLS
+# include <gnutls/gnutls.h>
+# include <gcrypt.h>
+ GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
#define EXIT_FAILURE 1
#define INVALID_SOCKET -1
@@ -122,6 +130,13 @@ static long long batchsize = 100000000ll;
static int waittime = 0;
static int runMultithreaded = 0; /* run tests in multithreaded mode */
static int numThrds = 1; /* number of threads to use */
+static char *tlsCertFile = NULL;
+static char *tlsKeyFile = NULL;
+
+#ifdef ENABLE_GNUTLS
+static gnutls_session_t *sessArray; /* array of TLS sessions to use */
+static gnutls_certificate_credentials tlscred;
+#endif
/* variables for managing multi-threaded operations */
int runningThreads; /* number of threads currently running */
@@ -151,7 +166,12 @@ struct runstats {
static int udpsock; /* socket for sending in UDP mode */
static struct sockaddr_in udpRcvr; /* remote receiver in UDP mode */
-static enum { TP_UDP, TP_TCP } transport = TP_TCP;
+static enum { TP_UDP, TP_TCP, TP_TLS } transport = TP_TCP;
+
+/* forward definitions */
+static void initTLSSess(int);
+static int sendTLS(int i, char *buf, int lenBuf);
+static void closeTLSSess(int __attribute__((unused)) i);
/* prepare send subsystem for UDP send */
static inline int
@@ -234,6 +254,9 @@ int openConnections(void)
if(bShowProgress)
write(1, " open connections", sizeof(" open connections")-1);
+# ifdef ENABLE_GNUTLS
+ sessArray = calloc(numConnections, sizeof(gnutls_session_t));
+# endif
sockArray = calloc(numConnections, sizeof(int));
for(i = 0 ; i < numConnections ; ++i) {
if(i % 10 == 0) {
@@ -244,6 +267,9 @@ int openConnections(void)
printf("error in trying to open connection i=%d\n", i);
return 1;
}
+ if(transport == TP_TLS) {
+ initTLSSess(i);
+ }
}
if(bShowProgress) {
lenMsg = sprintf(msgBuf, "\r%5.5d open connections\n", i);
@@ -268,7 +294,7 @@ void closeConnections(void)
struct linger ling;
char msgBuf[128];
- if(transport != TP_TCP)
+ if(transport == TP_UDP)
return;
if(bShowProgress)
@@ -287,6 +313,8 @@ void closeConnections(void)
ling.l_onoff = 1;
ling.l_linger = 1;
setsockopt(sockArray[i], SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+ if(transport == TP_TLS)
+ closeTLSSess(i);
close(sockArray[i]);
}
}
@@ -409,6 +437,8 @@ int sendMessages(struct instdata *inst)
lenSend = send(sockArray[socknum], buf, lenBuf, 0);
} else if(transport == TP_UDP) {
lenSend = sendto(udpsock, buf, lenBuf, 0, &udpRcvr, sizeof(udpRcvr));
+ } else if(transport == TP_TLS) {
+ lenSend = sendTLS(socknum, buf, lenBuf);
}
if(lenSend != lenBuf) {
printf("\r%5.5d\n", i);
@@ -643,6 +673,79 @@ runTests(void)
return 0;
}
+# if defined(ENABLE_GNUTLS)
+#if 0
+static void logFunction(int __attribute__((unused)) level, const char *msg) {
+ printf("%s\n", msg);
+}
+#endif
+/* global init GnuTLS
+ */
+static void
+initTLS(void)
+{
+ int r;
+
+ /* order of gcry_control and gnutls_global_init matters! */
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ gnutls_global_init ();
+ /* DEV debugging: gnutls_global_set_log_function(logFunction); */
+ /* DEV debugging: gnutls_global_set_log_level(9); */
+
+ r = gnutls_certificate_allocate_credentials(&tlscred);
+ if(r != GNUTLS_E_SUCCESS) {
+ /* I don't know why this works even in case of error... */
+ gnutls_perror(r);
+ }
+ r = gnutls_certificate_set_x509_key_file(tlscred, tlsCertFile, tlsKeyFile, GNUTLS_X509_FMT_PEM);
+ if(r != GNUTLS_E_SUCCESS) {
+ /* I don't know why this works even in case of error... */
+ gnutls_perror(r);
+ }
+}
+
+static void
+initTLSSess(int i)
+{
+ int r;
+ gnutls_init (sessArray + i, GNUTLS_CLIENT);
+
+ /* Use default priorities */
+ gnutls_set_default_priority(sessArray[i]);
+
+ /* put our credentials to the current session */
+ r = gnutls_credentials_set(sessArray[i], GNUTLS_CRD_CERTIFICATE, tlscred);
+
+ gnutls_transport_set_ptr(sessArray[i], (gnutls_transport_ptr_t) sockArray[i]);
+
+ /* Perform the TLS handshake */
+ r = gnutls_handshake(sessArray[i]);
+
+ if(r < 0) {
+ fprintf (stderr, "TLS Handshake failed\n");
+ gnutls_perror(r);
+ exit(1);
+ }
+}
+
+static int
+sendTLS(int i, char *buf, int lenBuf)
+{
+ return gnutls_record_send(sessArray[i], buf, lenBuf);
+}
+
+static void
+closeTLSSess(int i)
+{
+ gnutls_bye(sessArray[i], GNUTLS_SHUT_RDWR);
+ gnutls_deinit(sessArray[i]);
+}
+# else /* NO TLS available */
+static void initTLS(void) {}
+static void initTLSSess(int __attribute__((unused)) i) {}
+static int sendTLS(int i, char *buf, int lenBuf) { return 0; }
+static void closeTLSSess(int __attribute__((unused)) i) {}
+# endif
/* Run the test.
* rgerhards, 2009-04-03
@@ -666,7 +769,7 @@ int main(int argc, char *argv[])
setvbuf(stdout, buf, _IONBF, 48);
- while((opt = getopt(argc, argv, "b:ef:F:t:p:c:C:m:i:I:P:d:Dn:M:rsBR:S:T:XW:Y")) != -1) {
+ while((opt = getopt(argc, argv, "b:ef:F:t:p:c:C:m:i:I:P:d:Dn:M:rsBR:S:T:XW:YzZ")) != -1) {
switch (opt) {
case 'b': batchsize = atoll(optarg);
break;
@@ -725,8 +828,15 @@ int main(int argc, char *argv[])
transport = TP_UDP;
} else if(!strcmp(optarg, "tcp")) {
transport = TP_TCP;
+ } else if(!strcmp(optarg, "tls")) {
+# if defined(ENABLE_GNUTLS)
+ transport = TP_TLS;
+# else
+ fprintf(stderr, "compiled without TLS support!\n", optarg);
+ exit(1);
+# endif
} else {
- fprintf(stderr, "unkonwn transport '%s'\n", optarg);
+ fprintf(stderr, "unknown transport '%s'\n", optarg);
exit(1);
}
break;
@@ -734,6 +844,10 @@ int main(int argc, char *argv[])
break;
case 'Y': runMultithreaded = 1;
break;
+ case 'z': tlsKeyFile = optarg;
+ break;
+ case 'Z': tlsCertFile = optarg;
+ break;
default: printf("invalid option '%c' or value missing - terminating...\n", opt);
exit (1);
break;
@@ -769,6 +883,10 @@ int main(int argc, char *argv[])
}
}
+ if(transport == TP_TLS) {
+ initTLS();
+ }
+
if(openConnections() != 0) {
printf("error opening connections\n");
exit(1);
@@ -781,7 +899,7 @@ int main(int argc, char *argv[])
closeConnections(); /* this is important so that we do not finish too early! */
- if(nConnDrops > 0)
+ if(nConnDrops > 0 && !bSilent)
printf("-D option initiated %ld connection closures\n", nConnDrops);
if(!bSilent)