From 717092d93ec2ae8ad9dc85c4f77d27e2c678bd8c Mon Sep 17 00:00:00 2001 From: PascalWithopf Date: Wed, 2 Aug 2017 08:23:08 +0200 Subject: [PATCH] gnutls: add possibility to use priority string --- plugins/imtcp/imtcp.c | 11 +++++-- runtime/netstrm.c | 11 +++++++ runtime/netstrm.h | 4 ++- runtime/nsd.h | 4 ++- runtime/nsd_gtls.c | 30 +++++++++++++++++-- runtime/nsd_gtls.h | 1 + runtime/tcpsrv.c | 13 ++++++++ runtime/tcpsrv.h | 5 +++- tests/Makefile.am | 4 +++ tests/sndrcv_tls_priorityString.sh | 6 ++++ .../sndrcv_tls_priorityString_rcvr.conf | 21 +++++++++++++ .../sndrcv_tls_priorityString_sender.conf | 19 ++++++++++++ tools/omfwd.c | 9 ++++++ 13 files changed, 131 insertions(+), 7 deletions(-) create mode 100755 tests/sndrcv_tls_priorityString.sh create mode 100644 tests/testsuites/sndrcv_tls_priorityString_rcvr.conf create mode 100644 tests/testsuites/sndrcv_tls_priorityString_sender.conf diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 11afaff72..0f33c238b 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -101,6 +101,7 @@ static struct configSettings_s { int bDisableLFDelim; int discardTruncatedMsg; int bUseFlowControl; + uchar *gnutlsPriorityString; uchar *pszStrmDrvrAuthMode; uchar *pszInputName; uchar *pszBindRuleset; @@ -139,6 +140,7 @@ struct modConfData_s { int iKeepAliveProbes; int iKeepAliveTime; sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */ + uchar *gnutlsPriorityString; uchar *pszStrmDrvrName; /* stream driver to use */ uchar *pszStrmDrvrAuthMode; /* authentication mode to use */ struct cnfarray *permittedPeers; @@ -167,7 +169,8 @@ static struct cnfparamdescr modpdescr[] = { { "keepalive", eCmdHdlrBinary, 0 }, { "keepalive.probes", eCmdHdlrPositiveInt, 0 }, { "keepalive.time", eCmdHdlrPositiveInt, 0 }, - { "keepalive.interval", eCmdHdlrPositiveInt, 0 } + { "keepalive.interval", eCmdHdlrPositiveInt, 0 }, + { "gnutlsprioritystring", eCmdHdlrString, 0 } }; static struct cnfparamblk modpblk = { CNFPARAMBLK_VERSION, @@ -357,6 +360,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst) CHKiRet(tcpsrv.SetKeepAliveIntvl(pOurTcpsrv, modConf->iKeepAliveIntvl)); CHKiRet(tcpsrv.SetKeepAliveProbes(pOurTcpsrv, modConf->iKeepAliveProbes)); CHKiRet(tcpsrv.SetKeepAliveTime(pOurTcpsrv, modConf->iKeepAliveTime)); + CHKiRet(tcpsrv.SetGnutlsPriorityString(pOurTcpsrv, modConf->gnutlsPriorityString)); CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax)); CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode)); @@ -469,6 +473,7 @@ CODESTARTbeginCnfLoad loadModConf->maxFrameSize = 200000; loadModConf->bDisableLFDelim = 0; loadModConf->discardTruncatedMsg = 0; + loadModConf->gnutlsPriorityString = NULL; loadModConf->pszStrmDrvrName = NULL; loadModConf->pszStrmDrvrAuthMode = NULL; loadModConf->permittedPeers = NULL; @@ -533,6 +538,8 @@ CODESTARTsetModCnf loadModConf->iKeepAliveTime = (int) pvals[i].val.d.n; } else if(!strcmp(modpblk.descr[i].name, "keepalive.interval")) { loadModConf->iKeepAliveIntvl = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "gnutlsprioritystring")) { + loadModConf->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(modpblk.descr[i].name, "streamdriver.mode")) { loadModConf->iStrmDrvrMode = (int) pvals[i].val.d.n; } else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) { @@ -627,7 +634,7 @@ CODESTARTactivateCnfPrePrivDrop } } for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { - addListner(pModConf, inst); + addListner(runModConf, inst); } if(pOurTcpsrv == NULL) ABORT_FINALIZE(RS_RET_NO_RUN); diff --git a/runtime/netstrm.c b/runtime/netstrm.c index 551cb89d0..5ee82fea8 100644 --- a/runtime/netstrm.c +++ b/runtime/netstrm.c @@ -280,6 +280,16 @@ SetKeepAliveIntvl(netstrm_t *pThis, int keepAliveIntvl) RETiRet; } +/* gnutls priority string */ +static rsRetVal +SetGnutlsPriorityString(netstrm_t *pThis, uchar *gnutlsPriorityString) +{ + DEFiRet; + ISOBJ_TYPE_assert(pThis, netstrm); + iRet = pThis->Drvr.SetGnutlsPriorityString(pThis->pDrvrData, gnutlsPriorityString); + RETiRet; +} + /* check connection - slim wrapper for NSD driver function */ static rsRetVal CheckConnection(netstrm_t *pThis) @@ -387,6 +397,7 @@ CODESTARTobjQueryInterface(netstrm) pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; + pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; finalize_it: ENDobjQueryInterface(netstrm) diff --git a/runtime/netstrm.h b/runtime/netstrm.h index b07ece8fd..92de636e8 100644 --- a/runtime/netstrm.h +++ b/runtime/netstrm.h @@ -75,14 +75,16 @@ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*SetKeepAliveProbes)(netstrm_t *pThis, int keepAliveProbes); rsRetVal (*SetKeepAliveTime)(netstrm_t *pThis, int keepAliveTime); rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl); + rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString); ENDinterface(netstrm) -#define netstrmCURR_IF_VERSION 8 /* increment whenever you change the interface structure! */ +#define netstrmCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */ /* interface version 3 added GetRemAddr() * interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02 * interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06 * interface version 6 changed signature of GetRemoteIP() -- rgerhards, 2013-01-21 * interface version 7 added KeepAlive parameter set functions * interface version 8 changed signature of Connect() -- dsa, 2016-11-14 + * interface version 9 added SetGnutlsPriorityString -- PascalWithopf, 2017-08-08 * */ /* prototypes */ diff --git a/runtime/nsd.h b/runtime/nsd.h index 826070d00..1a84de4b5 100644 --- a/runtime/nsd.h +++ b/runtime/nsd.h @@ -83,14 +83,16 @@ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */ rsRetVal (*SetKeepAliveIntvl)(nsd_t *pThis, int keepAliveIntvl); rsRetVal (*SetKeepAliveProbes)(nsd_t *pThis, int keepAliveProbes); rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime); + rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString); ENDinterface(nsd) -#define nsdCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */ +#define nsdCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */ /* interface version 4 added GetRemAddr() * interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02 * interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06 * interface version 7 changed signature ofGetRempoteIP() -- rgerhards, 2013-01-21 * interface version 8 added keep alive parameter set functions * interface version 9 changed signature of Connect() -- dsa, 2016-11-14 + * interface version 10 added SetGnutlsPriorityString() -- PascalWithopf, 2017-08-08 */ /* interface for the select call */ diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c index a10c3736f..0f70b9441 100644 --- a/runtime/nsd_gtls.c +++ b/runtime/nsd_gtls.c @@ -1302,6 +1302,19 @@ finalize_it: RETiRet; } +/* gnutls priority string + */ +static rsRetVal +SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString) +{ + DEFiRet; + nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd; + + ISOBJ_TYPE_assert((pThis), nsd_gtls); + pThis->gnutlsPriorityString = gnutlsPriorityString; + RETiRet; +} + /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_gtls) who utilize ourselfs @@ -1690,6 +1703,7 @@ Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd; int sock; int gnuRet; + const char *error_position; # ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; # endif @@ -1726,8 +1740,19 @@ Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) FINALIZE; /* we have an error case! */ } - /* Use default priorities */ - CHKgnutls(gnutls_set_default_priority(pThis->sess)); + /*priority string setzen*/ + if(pThis->gnutlsPriorityString != NULL) { + if(gnutls_priority_set_direct(pThis->sess, + (const char*) pThis->gnutlsPriorityString, + &error_position)==GNUTLS_E_INVALID_REQUEST) { + errmsg.LogError(0, RS_RET_GNUTLS_ERR, "Syntax Error in" + " Priority String: \"%s\"\n", error_position); + } + } else { + /* Use default priorities */ + CHKgnutls(gnutls_set_default_priority(pThis->sess)); + } + # ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY /* The gnutls_certificate_type_set_priority function is deprecated * and not available in recent GnuTLS versions. However, there is no @@ -1811,6 +1836,7 @@ CODESTARTobjQueryInterface(nsd_gtls) pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; + pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; finalize_it: ENDobjQueryInterface(nsd_gtls) diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h index 740a78a88..c3ab84d4f 100644 --- a/runtime/nsd_gtls.h +++ b/runtime/nsd_gtls.h @@ -56,6 +56,7 @@ struct nsd_gtls_s { * set to 1 and changed to 0 after the first report. It is changed back to 1 after * one successful authentication. */ permittedPeers_t *pPermPeers; /* permitted peers */ + uchar *gnutlsPriorityString; /* gnutls priority string */ gnutls_x509_crt_t ourCert; /**< our certificate, if in client mode (unused in server mode) */ gnutls_x509_privkey_t ourKey; /**< our private key, if in client mode (unused in server mode) */ short bOurCertIsInit; /**< 1 if our certificate is initialized and must be deinit on destruction */ diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c index f0266cff4..b49a489b9 100644 --- a/runtime/tcpsrv.c +++ b/runtime/tcpsrv.c @@ -472,6 +472,9 @@ SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess, } /* we found a free spot and can construct our session object */ + if(pThis->gnutlsPriorityString != NULL) { + CHKiRet(netstrm.SetGnutlsPriorityString(pNewStrm, pThis->gnutlsPriorityString)); + } CHKiRet(tcps_sess.Construct(&pSess)); CHKiRet(tcps_sess.SetTcpsrv(pSess, pThis)); CHKiRet(tcps_sess.SetLstnInfo(pSess, pLstnInfo)); @@ -1167,6 +1170,15 @@ SetKeepAliveTime(tcpsrv_t *pThis, int iVal) RETiRet; } +static rsRetVal +SetGnutlsPriorityString(tcpsrv_t *pThis, uchar *iVal) +{ + DEFiRet; + DBGPRINTF("tcpsrv: gnutlsPriorityString set to %s\n", iVal); + pThis->gnutlsPriorityString = iVal; + RETiRet; +} + static rsRetVal SetOnMsgReceive(tcpsrv_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t*, uchar*, int)) { @@ -1423,6 +1435,7 @@ CODESTARTobjQueryInterface(tcpsrv) pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; + pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetUsrP = SetUsrP; pIf->SetInputName = SetInputName; pIf->SetOrigin = SetOrigin; diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h index 3d9557b22..5032e7477 100644 --- a/runtime/tcpsrv.h +++ b/runtime/tcpsrv.h @@ -61,6 +61,7 @@ struct tcpsrv_s { int iKeepAliveTime; /**< socket layer KEEPALIVE timeout */ netstrms_t *pNS; /**< pointer to network stream subsystem */ int iDrvrMode; /**< mode of the stream driver to use */ + uchar *gnutlsPriorityString; /**< priority string for gnutls */ uchar *pszDrvrAuthMode; /**< auth mode of the stream driver to use */ uchar *pszDrvrName; /**< name of stream driver to use */ uchar *pszInputName; /**< value to be used as input name */ @@ -172,8 +173,10 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */ rsRetVal (*SetKeepAliveTime)(tcpsrv_t*, int); /* added v18 */ rsRetVal (*SetbSPFramingFix)(tcpsrv_t*, sbool); + /* added v19 -- PascalWithopf, 2017-08-08 */ + rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*); ENDinterface(tcpsrv) -#define tcpsrvCURR_IF_VERSION 18 /* increment whenever you change the interface structure! */ +#define tcpsrvCURR_IF_VERSION 19 /* increment whenever you change the interface structure! */ /* change for v4: * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10 * - SetInputName() added -- rgerhards, 2008-12-10 diff --git a/tests/Makefile.am b/tests/Makefile.am index baf59daab..5a39de05a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -533,6 +533,7 @@ if ENABLE_GNUTLS TESTS += \ imtcp_conndrop_tls.sh \ sndrcv_tls_anon.sh \ + sndrcv_tls_priorityString.sh \ imtcp-tls-basic.sh \ sndrcv_tls_anon_rebind.sh if HAVE_VALGRIND @@ -1534,6 +1535,9 @@ EXTRA_DIST= \ sndrcv_tls_anon.sh \ testsuites/sndrcv_tls_anon_sender.conf \ testsuites/sndrcv_tls_anon_rcvr.conf \ + sndrcv_tls_priorityString.sh \ + testsuites/sndrcv_tls_priorityString_sender.conf \ + testsuites/sndrcv_tls_priorityString_rcvr.conf \ omtcl.sh \ omtcl.tcl \ pmsnare.sh \ diff --git a/tests/sndrcv_tls_priorityString.sh b/tests/sndrcv_tls_priorityString.sh new file mode 100755 index 000000000..63626a9a8 --- /dev/null +++ b/tests/sndrcv_tls_priorityString.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# Pascal Withopf, 2017-07-25 +# This file is part of the rsyslog project, released under ASL 2.0 +echo =============================================================================== +echo \[sndrcv_tls_priorityString.sh\]: testing sending and receiving via TLS with anon auth +. $srcdir/sndrcv_drvr.sh sndrcv_tls_priorityString 2500 diff --git a/tests/testsuites/sndrcv_tls_priorityString_rcvr.conf b/tests/testsuites/sndrcv_tls_priorityString_rcvr.conf new file mode 100644 index 000000000..0d8ff52d7 --- /dev/null +++ b/tests/testsuites/sndrcv_tls_priorityString_rcvr.conf @@ -0,0 +1,21 @@ +# see equally-named shell file for details +# this is the config fil for the TLS server +# Pascal Withopf, 2017-07-25 +$IncludeConfig diag-common.conf + +# certificates +global( + defaultNetstreamDriver="gtls" + defaultNetstreamDriverKeyFile="testsuites/x.509/client-key.pem" + defaultNetstreamDriverCertFile="testsuites/x.509/client-cert.pem" + defaultNetstreamDriverCaFile="testsuites/x.509/ca.pem" +) +module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" gnutlspriorityString="NORMAL:-MD5") +input(type="imtcp" port="13515") + +template(name="outfmt" type="string" string="%msg:F,58:2%\n") + +if $msg contains "msgnum" then { + action(type="omfile" template="outfmt" file="rsyslog.out.log") +} + diff --git a/tests/testsuites/sndrcv_tls_priorityString_sender.conf b/tests/testsuites/sndrcv_tls_priorityString_sender.conf new file mode 100644 index 000000000..d6b95e8a5 --- /dev/null +++ b/tests/testsuites/sndrcv_tls_priorityString_sender.conf @@ -0,0 +1,19 @@ +# see tcpsndrcv.sh for details +# this is the TLS client +# Pascal Withopf 25.07.2017 +$IncludeConfig diag-common2.conf + +#certificates +global( + defaultNetstreamDriver="gtls" + defaultNetstreamDriverKeyFile="testsuites/x.509/client-key.pem" + defaultNetstreamDriverCertFile="testsuites/x.509/client-cert.pem" + defaultNetstreamDriverCaFile="testsuites/x.509/ca.pem" +) + +module(load="../plugins/imtcp/.libs/imtcp") +input(type="imtcp" port="13514") + +action(type="omfwd" Target="127.0.0.1" port="13515" Protocol="tcp" streamdriver="gtls" + StreamDriverAuthMode="anon" StreamDriverMode="1" + gnutlsprioritystring="NORMAL:-MD5:+VERS-TLS-ALL") diff --git a/tools/omfwd.c b/tools/omfwd.c index 54c77a335..de1035eff 100644 --- a/tools/omfwd.c +++ b/tools/omfwd.c @@ -95,6 +95,7 @@ typedef struct _instanceData { int iKeepAliveIntvl; int iKeepAliveProbes; int iKeepAliveTime; + uchar *gnutlsPriorityString; # define FORW_UDP 0 # define FORW_TCP 1 @@ -144,6 +145,7 @@ typedef struct configSettings_s { int iKeepAliveIntvl; int iKeepAliveProbes; int iKeepAliveTime; + uchar *gnutlsPriorityString; permittedPeers_t *pPermPeers; } configSettings_t; static configSettings_t cs; @@ -177,6 +179,7 @@ static struct cnfparamdescr actpdescr[] = { { "keepalive.probes", eCmdHdlrPositiveInt, 0 }, { "keepalive.time", eCmdHdlrPositiveInt, 0 }, { "keepalive.interval", eCmdHdlrPositiveInt, 0 }, + { "gnutlsprioritystring", eCmdHdlrString, 0 }, { "streamdriver", eCmdHdlrGetWord, 0 }, { "streamdrivermode", eCmdHdlrInt, 0 }, { "streamdriverauthmode", eCmdHdlrGetWord, 0 }, @@ -717,6 +720,9 @@ static rsRetVal TCPSendInit(void *pvData) CHKiRet(netstrm.SetDrvrPermPeers(pWrkrData->pNetstrm, pData->pPermPeers)); } /* params set, now connect */ + if(pData->gnutlsPriorityString != NULL) { + CHKiRet(netstrm.SetGnutlsPriorityString(pWrkrData->pNetstrm, pData->gnutlsPriorityString)); + } CHKiRet(netstrm.Connect(pWrkrData->pNetstrm, glbl.GetDefPFFamily(), (uchar*)pData->port, (uchar*)pData->target, pData->device)); @@ -1049,6 +1055,7 @@ setInstParamDefaults(instanceData *pData) pData->iKeepAliveProbes = 0; pData->iKeepAliveIntvl = 0; pData->iKeepAliveTime = 0; + pData->gnutlsPriorityString = NULL; pData->bResendLastOnRecon = 0; pData->bSendToAll = -1; /* unspecified */ pData->iUDPSendDelay = 0; @@ -1137,6 +1144,8 @@ CODESTARTnewActInst pData->iKeepAliveIntvl = (int) pvals[i].val.d.n; } else if(!strcmp(actpblk.descr[i].name, "keepalive.time")) { pData->iKeepAliveTime = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "gnutlsprioritystring")) { + pData->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(actpblk.descr[i].name, "streamdriver")) { pData->pszStrmDrvr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(actpblk.descr[i].name, "streamdrivermode")) {