From 783d2c0368b7992822bfea3a981e56bf063b188a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 21 Dec 2007 14:07:14 +0000 Subject: begun work on imtcp --- plugins/imtcp/imtcp.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 plugins/imtcp/imtcp.c (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c new file mode 100644 index 00000000..96686811 --- /dev/null +++ b/plugins/imtcp/imtcp.c @@ -0,0 +1,148 @@ +/* imtcp.c + * This is the implementation of the TCP input module. + * + * NOTE: read comments in module-template.h to understand how this file + * works! + * + * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c) + * + * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include "rsyslog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "syslogd.h" +#include "cfsysline.h" +#include "module-template.h" + +MODULE_TYPE_INPUT +TERM_SYNC_TYPE(eTermSync_NONE) + +/* defines */ + +/* Module static data */ +DEF_IMOD_STATIC_DATA + +typedef struct _instanceData { +} instanceData; + +/* config settings */ + + +/* This function is called to gather input. + */ +BEGINrunInput + int maxfds; + int nfds; + int i; + int fd; + fd_set readfds; +CODESTARTrunInput + /* this is an endless loop - it is terminated when the thread is + * signalled to do so. This, however, is handled by the framework, + * right into the sleep below. + */ + while(1) { + /* Add the Unix Domain Sockets to the list of read + * descriptors. + * rgerhards 2005-08-01: we must now check if there are + * any local sockets to listen to at all. If the -o option + * is given without -a, we do not need to listen at all.. + */ + maxfds = 0; + FD_ZERO (&readfds); + + if(Debug) { + dbgprintf("--------imTCP calling select, active file descriptors (max %d): ", maxfds); + for (nfds= 0; nfds <= maxfds; ++nfds) + if ( FD_ISSET(nfds, &readfds) ) + dbgprintf("%d ", nfds); + dbgprintf("\n"); + } + + /* wait for io to become ready */ + /* select here */ + + } + + return iRet; +ENDrunInput + + +/* initialize and return if will run or not */ +BEGINwillRun +CODESTARTwillRun + /* first apply some config settings */ +ENDwillRun + + +BEGINafterRun +CODESTARTafterRun + /* do cleanup here */ +ENDafterRun + + +BEGINfreeInstance +CODESTARTfreeInstance +ENDfreeInstance + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +ENDqueryEtryPt + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + //bOmitLocalLogging = 0; + return RS_RET_OK; +} + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = 1; /* so far, we only support the initial definition */ +CODEmodInit_QueryRegCFSLineHdlr + /* register config file handlers */ + //CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, + // NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit +/* + * vi:set ai: + */ -- cgit v1.2.3 From 4e6bba7df8170514183040897e363528c574be0e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 21 Dec 2007 14:37:50 +0000 Subject: created first version of imtcp (still very much depending on syslogd.c for configuration and a lot of other things) --- plugins/imtcp/imtcp.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 133 insertions(+), 7 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 96686811..ef0912e9 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -26,18 +26,16 @@ * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" -#include "rsyslog.h" #include -#include #include #include #include #include -#include -#include +#include "rsyslog.h" #include "syslogd.h" #include "cfsysline.h" #include "module-template.h" +#include "tcpsyslog.h" MODULE_TYPE_INPUT TERM_SYNC_TYPE(eTermSync_NONE) @@ -59,7 +57,7 @@ BEGINrunInput int maxfds; int nfds; int i; - int fd; + int iTCPSess; fd_set readfds; CODESTARTrunInput /* this is an endless loop - it is terminated when the thread is @@ -76,17 +74,119 @@ CODESTARTrunInput maxfds = 0; FD_ZERO (&readfds); + /* Add the TCP listen sockets to the list of read descriptors. + */ + if(sockTCPLstn != NULL && *sockTCPLstn) { + for (i = 0; i < *sockTCPLstn; i++) { + /* The if() below is theoretically not needed, but I leave it in + * so that a socket may become unsuable during execution. That + * feature is not yet supported by the current code base. + */ + if (sockTCPLstn[i+1] != -1) { + if(Debug) + debugListenInfo(sockTCPLstn[i+1], "TCP"); + FD_SET(sockTCPLstn[i+1], &readfds); + if(sockTCPLstn[i+1]>maxfds) maxfds=sockTCPLstn[i+1]; + } + } + /* do the sessions */ + iTCPSess = TCPSessGetNxtSess(-1); + while(iTCPSess != -1) { + int fdSess; + fdSess = pTCPSessions[iTCPSess].sock; + dbgprintf("Adding TCP Session %d\n", fdSess); + FD_SET(fdSess, &readfds); + if (fdSess>maxfds) maxfds=fdSess; + /* now get next... */ + iTCPSess = TCPSessGetNxtSess(iTCPSess); + } + } + if(Debug) { dbgprintf("--------imTCP calling select, active file descriptors (max %d): ", maxfds); - for (nfds= 0; nfds <= maxfds; ++nfds) + for (nfds = 0; nfds <= maxfds; ++nfds) if ( FD_ISSET(nfds, &readfds) ) dbgprintf("%d ", nfds); dbgprintf("\n"); } /* wait for io to become ready */ - /* select here */ + nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL); + + for (i = 0; i < *sockTCPLstn; i++) { + if (FD_ISSET(sockTCPLstn[i+1], &readfds)) { + dbgprintf("New connect on TCP inetd socket: #%d\n", sockTCPLstn[i+1]); +# ifdef USE_GSSAPI + if(bEnableTCP & ALLOWEDMETHOD_GSS) + TCPSessGSSAccept(sockTCPLstn[i+1]); + else +# endif + TCPSessAccept(sockTCPLstn[i+1]); + --nfds; /* indicate we have processed one */ + } + } + + /* now check the sessions */ + iTCPSess = TCPSessGetNxtSess(-1); + while(nfds && iTCPSess != -1) { + int fdSess; + int state; + fdSess = pTCPSessions[iTCPSess].sock; + if(FD_ISSET(fdSess, &readfds)) { + char buf[MAXLINE]; + dbgprintf("tcp session socket with new data: #%d\n", fdSess); + /* Receive message */ +# ifdef USE_GSSAPI + int allowedMethods = pTCPSessions[iTCPSess].allowedMethods; + if(allowedMethods & ALLOWEDMETHOD_GSS) + state = TCPSessGSSRecv(iTCPSess, buf, sizeof(buf)); + else +# endif + state = recv(fdSess, buf, sizeof(buf), 0); + if(state == 0) { +# ifdef USE_GSSAPI + if(allowedMethods & ALLOWEDMETHOD_GSS) + TCPSessGSSClose(iTCPSess); + else { +# endif + /* process any incomplete frames left over */ + TCPSessPrepareClose(iTCPSess); + /* Session closed */ + TCPSessClose(iTCPSess); +# ifdef USE_GSSAPI + } +# endif + } else if(state == -1) { + logerrorInt("TCP session %d will be closed, error ignored\n", + fdSess); +# ifdef USE_GSSAPI + if(allowedMethods & ALLOWEDMETHOD_GSS) + TCPSessGSSClose(iTCPSess); + else +# endif + TCPSessClose(iTCPSess); + } else { + /* valid data received, process it! */ + if(TCPSessDataRcvd(iTCPSess, buf, state) == 0) { + /* in this case, something went awfully wrong. + * We are instructed to terminate the session. + */ + logerrorInt("Tearing down TCP Session %d - see " + "previous messages for reason(s)\n", + iTCPSess); +# ifdef USE_GSSAPI + if(allowedMethods & ALLOWEDMETHOD_GSS) + TCPSessGSSClose(iTCPSess); + else +# endif + TCPSessClose(iTCPSess); + } + } + --nfds; /* indicate we have processed one */ + } + iTCPSess = TCPSessGetNxtSess(iTCPSess); + } } return iRet; @@ -97,6 +197,29 @@ ENDrunInput BEGINwillRun CODESTARTwillRun /* first apply some config settings */ +dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP); + if (bEnableTCP) { + if(sockTCPLstn == NULL) { + /* even when doing a re-init, we do not shut down and + * re-open the TCP socket. That would break existing TCP + * session, which we do not desire. Should at some time arise + * need to do that, I recommend controlling that via a + * user-selectable option. rgerhards, 2007-06-21 + */ +# ifdef USE_GSSAPI + if(bEnableTCP & ALLOWEDMETHOD_GSS) { + if(TCPSessGSSInit()) { + logerror("GSS-API initialization failed\n"); + bEnableTCP &= ~(ALLOWEDMETHOD_GSS); + } + } + if(bEnableTCP) +# endif + if((sockTCPLstn = create_tcp_socket()) != NULL) { + dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn); + } + } + } ENDwillRun @@ -140,6 +263,9 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ //CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, // NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID)); +#if defined(USE_GSSAPI) + CHKiRet(regCfSysLineHdlr((uchar *)"gsslistenservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, NULL)); +#endif CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 9a72402b80c9b67abae090645ba30adf697f3025 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 21 Dec 2007 14:56:49 +0000 Subject: cleaned up code (resulting in some shuffeling from syslogd.c to the "right" module) --- plugins/imtcp/imtcp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index ef0912e9..8639baf3 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -241,6 +241,14 @@ ENDdbgPrintInstInfo BEGINmodExit CODESTARTmodExit + /* Close the TCP inet socket. */ + if(sockTCPLstn != NULL && *sockTCPLstn) { + deinit_tcp_listener(); + } +#ifdef USE_GSSAPI + if(bEnableTCP & ALLOWEDMETHOD_GSS) + TCPSessGSSDeinit(); +#endif ENDmodExit @@ -251,7 +259,12 @@ ENDqueryEtryPt static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - //bOmitLocalLogging = 0; +#if defined(USE_GSSAPI) + if (gss_listen_service_name != NULL) { + free(gss_listen_service_name); + gss_listen_service_name = NULL; + } +#endif return RS_RET_OK; } -- cgit v1.2.3 From 483be404716d8e3e55f200955e1904219eb97a9b Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 10 Dec 2008 14:26:19 +0100 Subject: enhanced imtcp, among others to handel invalid NetScreen framing - added $InputTCPServerAddtlFrameDelimiter config directive, which enabeles to specify an additional, non-standard message delimiter for processing plain tcp syslog. This is primarily a fix for the invalid framing used in Juniper's NetScreen products. Credit to forum user Arv for suggesting this solution. - added $InputTCPServerInputName property, which enables a name to be specified that will be available during message processing in the inputname property. This is considered useful for logic that treats messages differently depending on which input received them. --- plugins/imtcp/imtcp.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 89f1dbcf..19138d94 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -80,7 +80,9 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ +static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ +static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ /* callbacks */ @@ -166,6 +168,8 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); + CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? (uchar*)"imtcp" : pszInputName)); + CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); /* now set optional params, but only if they were actually configured */ if(pszStrmDrvrAuthMode != NULL) { CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode)); @@ -239,6 +243,15 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus { iTCPSessMax = 200; iStrmDrvrMode = 0; + iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; + if(pszInputName != NULL) { + free(pszInputName); + pszInputName = NULL; + } + if(pszStrmDrvrAuthMode != NULL) { + free(pszStrmDrvrAuthMode); + pszStrmDrvrAuthMode = NULL; + } return RS_RET_OK; } @@ -273,6 +286,10 @@ CODEmodInit_QueryRegCFSLineHdlr eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverpermittedpeer", 0, eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserveraddtlframedelimiter", 0, eCmdHdlrInt, + NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverinputname", 0, + eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 94af628fbd7eaed384e0b9150638019fb6efd5e3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 26 Dec 2007 17:21:02 +0000 Subject: removed active INET code from syslogd.c - still some auxiliary things remain --- plugins/imtcp/imtcp.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 8639baf3..1efd5316 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -198,6 +198,10 @@ BEGINwillRun CODESTARTwillRun /* first apply some config settings */ dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP); + PrintAllowedSenders(2); /* TCP */ +#ifdef USE_GSSAPI + PrintAllowedSenders(3); /* GSS */ +#endif if (bEnableTCP) { if(sockTCPLstn == NULL) { /* even when doing a re-init, we do not shut down and @@ -226,6 +230,18 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ +dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_TCP); + if (pAllowedSenders_TCP != NULL) { + clearAllowedSenders (pAllowedSenders_TCP); + pAllowedSenders_TCP = NULL; + } +#ifdef USE_GSSAPI +dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_GSS); + if (pAllowedSenders_GSS != NULL) { + clearAllowedSenders (pAllowedSenders_GSS); + pAllowedSenders_GSS = NULL; + } +#endif ENDafterRun -- cgit v1.2.3 From bcdb6dcfd7b28e3dbf9fa0c4e9f718b6b91a7b3f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 27 Dec 2007 17:32:10 +0000 Subject: internal restructuring in omfwd.c - stage work for further modularization I think I also fixed a bug as a side-effect - but not looked to much at it --- plugins/imtcp/imtcp.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 1efd5316..579885ca 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -204,12 +204,6 @@ dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP); #endif if (bEnableTCP) { if(sockTCPLstn == NULL) { - /* even when doing a re-init, we do not shut down and - * re-open the TCP socket. That would break existing TCP - * session, which we do not desire. Should at some time arise - * need to do that, I recommend controlling that via a - * user-selectable option. rgerhards, 2007-06-21 - */ # ifdef USE_GSSAPI if(bEnableTCP & ALLOWEDMETHOD_GSS) { if(TCPSessGSSInit()) { @@ -230,13 +224,11 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ -dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_TCP); if (pAllowedSenders_TCP != NULL) { clearAllowedSenders (pAllowedSenders_TCP); pAllowedSenders_TCP = NULL; } #ifdef USE_GSSAPI -dbgprintf("call clearAllowedSenders(0x%lx)\n", (unsigned long) pAllowedSenders_GSS); if (pAllowedSenders_GSS != NULL) { clearAllowedSenders (pAllowedSenders_GSS); pAllowedSenders_GSS = NULL; @@ -290,8 +282,6 @@ CODESTARTmodInit *ipIFVersProvided = 1; /* so far, we only support the initial definition */ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ - //CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, - // NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID)); #if defined(USE_GSSAPI) CHKiRet(regCfSysLineHdlr((uchar *)"gsslistenservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, NULL)); #endif -- cgit v1.2.3 From 28c44e9a7bf4f99279af94a96bac42d0379b27d0 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 10 Jan 2008 14:27:26 +0000 Subject: - fixed a bug that caused a segfault on startup when no $WorkDir directive was specified in rsyslog.conf - fixed a bug that caused a segfault on queues with types other than "disk" - removed the now longer needed thread TermSyncTool --- plugins/imtcp/imtcp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 579885ca..01852044 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -38,7 +38,6 @@ #include "tcpsyslog.h" MODULE_TYPE_INPUT -TERM_SYNC_TYPE(eTermSync_NONE) /* defines */ -- cgit v1.2.3 From 2c5712f6ac066d197d1255685368af93c9143c7d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 22 Feb 2008 07:04:03 +0000 Subject: integrated patch from Peter Vrabec to change the build process to produce imtcp.so and imgssapi.so from imtcp.c (in support of new gassapi input module) - many thanks, Peter! --- plugins/imtcp/imtcp.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 01852044..43f3bdd6 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -25,7 +25,14 @@ * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ + #include "config.h" +#ifdef FORCE_NO_GSS + #ifdef USE_GSSAPI + #undef USE_GSSAPI + #endif +#endif + #include #include #include -- cgit v1.2.3 From 51bb02e3cdb7ddf8d19120804d2c13c7acebe9ce Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 22 Feb 2008 07:24:15 +0000 Subject: applied patch by varmojfekoj to allow gssapi functionality to be build as a separate plugin (so that gssapi and plain tcp functionality can be individually distributed). Also inclulded some other enhancements, most importantly initial compatibility mode system --- plugins/imtcp/imtcp.c | 1003 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1001 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 43f3bdd6..dc005af8 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -38,15 +38,37 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#if HAVE_FCNTL_H +#include +#endif +#ifdef USE_GSSAPI +#include +#endif #include "rsyslog.h" #include "syslogd.h" #include "cfsysline.h" #include "module-template.h" -#include "tcpsyslog.h" +#include "net.h" +#ifdef USE_GSSAPI +#include "gss-misc.h" +#endif +#include "srUtils.h" MODULE_TYPE_INPUT /* defines */ +#ifdef USE_GSSAPI +#define ALLOWEDMETHOD_GSS 2 +#endif +#define ALLOWEDMETHOD_TCP 1 + +#define TCPSESS_MAX_DEFAULT 200 /* default for nbr of tcp sessions if no number is given */ /* Module static data */ DEF_IMOD_STATIC_DATA @@ -54,9 +76,979 @@ DEF_IMOD_STATIC_DATA typedef struct _instanceData { } instanceData; +typedef enum _TCPFRAMINGMODE { + TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */ + TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */ + } TCPFRAMINGMODE; + +struct TCPSession { + int sock; + int iMsg; /* index of next char to store in msg */ + int bAtStrtOfFram; /* are we at the very beginning of a new frame? */ + int iOctetsRemain; /* Number of Octets remaining in message */ + TCPFRAMINGMODE eFraming; + char msg[MAXLINE+1]; + char *fromHost; +#ifdef USE_GSSAPI + OM_uint32 gss_flags; + gss_ctx_id_t gss_context; + char allowedMethods; +#endif +}; + +static int iTCPSessMax = TCPSESS_MAX_DEFAULT; /* actual number of sessions */ +char *TCPLstnPort = "0"; /* read-only after startup */ +int bEnableTCP = 0; /* read-only after startup */ +int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */ +struct TCPSession *pTCPSessions; +/* The thread-safeness of the sesion table is doubtful */ +#ifdef USE_GSSAPI +static gss_cred_id_t gss_server_creds = GSS_C_NO_CREDENTIAL; +char *gss_listen_service_name = NULL; +#endif + /* config settings */ +/* code to free all sockets within a socket table. + * A socket table is a descriptor table where the zero + * element has the count of elements. This is used for + * listening sockets. The socket table itself is also + * freed. + * A POINTER to this structure must be provided, thus + * double indirection! + * rgerhards, 2007-06-28 + */ +static void freeAllSockets(int **socks) +{ + assert(socks != NULL); + assert(*socks != NULL); + while(**socks) { + dbgprintf("Closing socket %d.\n", (*socks)[**socks]); + close((*socks)[**socks]); + (**socks)--; + } + free(*socks); + socks = NULL; +} + + +/* configure TCP listener settings. This is called during command + * line parsing. The argument following -t is supplied as an argument. + * The format of this argument is + * ", " + * Typically, there is no whitespace between port and session number. + * (but it may be...). + * NOTE: you can not use dbgprintf() in here - the dbgprintf() system is + * not yet initilized when this function is called. + * rgerhards, 2007-06-21 + * We can also not use logerror(), as that system is also not yet + * initialized... rgerhards, 2007-06-28 + */ +void configureTCPListen(char *cOptarg) +{ + register int i; + register char *pArg = cOptarg; + + assert(cOptarg != NULL); + + /* extract port */ + i = 0; + while(isdigit((int) *pArg)) { + i = i * 10 + *pArg++ - '0'; + } + + if( i >= 0 && i <= 65535) { + TCPLstnPort = cOptarg; + } else { + logerrorSz("Invalid TCP listen port %s - changed to 514.\n", cOptarg); + TCPLstnPort = "514"; + } +} + + +void configureTCPListenSessMax(char *cOptarg) +{ + register int i; + register char *pArg = cOptarg; + + assert(cOptarg != NULL); + + /* number of sessions */ + i = 0; + while(isdigit((int) *pArg)) { + i = i * 10 + *pArg++ - '0'; + } + + if(i > 0) + iTCPSessMax = i; + else { + /* too small, need to adjust */ + logerrorSz("TCP session max configured to %s - changing to 1.\n", cOptarg); + iTCPSessMax = 1; + } +} + + +/* Initialize the session table + * returns 0 if OK, somewhat else otherwise + */ +static int TCPSessInit(void) +{ + register int i; + + assert(pTCPSessions == NULL); + dbgprintf("Allocating buffer for %d TCP sessions.\n", iTCPSessMax); + if((pTCPSessions = (struct TCPSession *) malloc(sizeof(struct TCPSession) * iTCPSessMax)) + == NULL) { + dbgprintf("Error: TCPSessInit() could not alloc memory for TCP session table.\n"); + return(1); + } + + for(i = 0 ; i < iTCPSessMax ; ++i) { + pTCPSessions[i].sock = -1; /* no sock */ + pTCPSessions[i].iMsg = 0; /* just make sure... */ + pTCPSessions[i].bAtStrtOfFram = 1; /* indicate frame header expected */ + pTCPSessions[i].eFraming = TCP_FRAMING_OCTET_STUFFING; /* just make sure... */ +#ifdef USE_GSSAPI + pTCPSessions[i].gss_flags = 0; + pTCPSessions[i].gss_context = GSS_C_NO_CONTEXT; + pTCPSessions[i].allowedMethods = 0; +#endif + } + return(0); +} + + +/* find a free spot in the session table. If the table + * is full, -1 is returned, else the index of the free + * entry (0 or higher). + */ +static int TCPSessFindFreeSpot(void) +{ + register int i; + + for(i = 0 ; i < iTCPSessMax ; ++i) { + if(pTCPSessions[i].sock == -1) + break; + } + + return((i < iTCPSessMax) ? i : -1); +} + + +/* Get the next session index. Free session tables entries are + * skipped. This function is provided the index of the last + * session entry, or -1 if no previous entry was obtained. It + * returns the index of the next session or -1, if there is no + * further entry in the table. Please note that the initial call + * might as well return -1, if there is no session at all in the + * session table. + */ +int TCPSessGetNxtSess(int iCurr) +{ + register int i; + + for(i = iCurr + 1 ; i < iTCPSessMax ; ++i) + if(pTCPSessions[i].sock != -1) + break; + + return((i < iTCPSessMax) ? i : -1); +} + + +/* De-Initialize TCP listner sockets. + * This function deinitializes everything, including freeing the + * session table. No TCP listen receive operations are permitted + * unless the subsystem is reinitialized. + * rgerhards, 2007-06-21 + */ +void deinit_tcp_listener(void) +{ + int iTCPSess; + + assert(pTCPSessions != NULL); + /* close all TCP connections! */ + iTCPSess = TCPSessGetNxtSess(-1); + while(iTCPSess != -1) { + int fd; + fd = pTCPSessions[iTCPSess].sock; + dbgprintf("Closing TCP Session %d\n", fd); + close(fd); + free(pTCPSessions[iTCPSess].fromHost); +#ifdef USE_GSSAPI + if(bEnableTCP & ALLOWEDMETHOD_GSS) { + OM_uint32 maj_stat, min_stat; + maj_stat = gss_delete_sec_context(&min_stat, &pTCPSessions[iTCPSess].gss_context, GSS_C_NO_BUFFER); + if (maj_stat != GSS_S_COMPLETE) + display_status("deleting context", maj_stat, min_stat); + } +#endif + /* now get next... */ + iTCPSess = TCPSessGetNxtSess(iTCPSess); + } + + /* we are done with the session table - so get rid of it... + */ + free(pTCPSessions); + pTCPSessions = NULL; /* just to make sure... */ + + /* finally close the listen sockets themselfs */ + freeAllSockets(&sockTCPLstn); +} + + +/* Initialize TCP sockets (for listener) + * This function returns either NULL (which means it failed) or + * a pointer to an array of file descriptiors. If the pointer is + * returned, the zeroest element [0] contains the count of valid + * descriptors. The descriptors themself follow in range + * [1] ... [num-descriptors]. It is guaranteed that each of these + * descriptors is valid, at least when this function returns. + * Please note that technically the array may be larger than the number + * of valid pointers stored in it. The memory overhead is minimal, so + * we do not bother to re-allocate an array of the exact size. Logically, + * the array still contains the exactly correct number of descriptors. + */ +int *create_tcp_socket(void) +{ + struct addrinfo hints, *res, *r; + int error, maxs, *s, *socks, on = 1; + + if(!strcmp(TCPLstnPort, "0")) + TCPLstnPort = "514"; + /* use default - we can not do service db update, because there is + * no IANA-assignment for syslog/tcp. In the long term, we might + * re-use RFC 3195 port of 601, but that would probably break to + * many existing configurations. + * rgerhards, 2007-06-28 + */ + dbgprintf("creating tcp socket on port %s\n", TCPLstnPort); + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; + + error = getaddrinfo(NULL, TCPLstnPort, &hints, &res); + if(error) { + logerror((char*) gai_strerror(error)); + return NULL; + } + + /* Count max number of sockets we may open */ + for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++) + /* EMPTY */; + socks = malloc((maxs+1) * sizeof(int)); + if (socks == NULL) { + logerror("couldn't allocate memory for TCP listen sockets, suspending TCP message reception."); + freeaddrinfo(res); + return NULL; + } + + *socks = 0; /* num of sockets counter at start of array */ + s = socks + 1; + for (r = res; r != NULL ; r = r->ai_next) { + *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); + if (*s < 0) { + if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT)) + logerror("create_udp_socket(), socket"); + /* it is debatable if PF_INET with EAFNOSUPPORT should + * also be ignored... + */ + continue; + } + +#ifdef IPV6_V6ONLY + if (r->ai_family == AF_INET6) { + int iOn = 1; + if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, + (char *)&iOn, sizeof (iOn)) < 0) { + logerror("TCP setsockopt"); + close(*s); + *s = -1; + continue; + } + } +#endif + if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, + (char *) &on, sizeof(on)) < 0 ) { + logerror("TCP setsockopt(REUSEADDR)"); + close(*s); + *s = -1; + continue; + } + + /* We need to enable BSD compatibility. Otherwise an attacker + * could flood our log files by sending us tons of ICMP errors. + */ +#ifndef BSD + if (should_use_so_bsdcompat()) { + if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT, + (char *) &on, sizeof(on)) < 0) { + logerror("TCP setsockopt(BSDCOMPAT)"); + close(*s); + *s = -1; + continue; + } + } +#endif + + if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0) +#ifndef IPV6_V6ONLY + && (errno != EADDRINUSE) +#endif + ) { + logerror("TCP bind"); + close(*s); + *s = -1; + continue; + } + + if( listen(*s,iTCPSessMax / 10 + 5) < 0) { + /* If the listen fails, it most probably fails because we ask + * for a too-large backlog. So in this case we first set back + * to a fixed, reasonable, limit that should work. Only if + * that fails, too, we give up. + */ + logerrorInt("listen with a backlog of %d failed - retrying with default of 32.", + iTCPSessMax / 10 + 5); + if(listen(*s, 32) < 0) { + logerror("TCP listen, suspending tcp inet"); + close(*s); + *s = -1; + continue; + } + } + + (*socks)++; + s++; + } + + if(res != NULL) + freeaddrinfo(res); + + if(Debug && *socks != maxs) + dbgprintf("We could initialize %d TCP listen sockets out of %d we received " + "- this may or may not be an error indication.\n", *socks, maxs); + + if(*socks == 0) { + logerror("No TCP listen socket could successfully be initialized, " + "message reception via TCP disabled.\n"); + free(socks); + return(NULL); + } + + /* OK, we had success. Now it is also time to + * initialize our connections + */ + if(TCPSessInit() != 0) { + /* OK, we are in some trouble - we could not initialize the + * session table, so we can not continue. We need to free all + * we have assigned so far, because we can not really use it... + */ + logerror("Could not initialize TCP session table, suspending TCP message reception."); + freeAllSockets(&socks); /* prevent a socket leak */ + return(NULL); + } + + return(socks); +} + + +/* Accept new TCP connection; make entry in session table. If there + * is no more space left in the connection table, the new TCP + * connection is immediately dropped. + */ +int TCPSessAccept(int fd) +{ + int newConn; + int iSess; + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(struct sockaddr_storage); + size_t lenHostName; + uchar fromHost[NI_MAXHOST]; + uchar fromHostFQDN[NI_MAXHOST]; + char *pBuf; +#ifdef USE_GSSAPI + char allowedMethods = 0; +#endif + + newConn = accept(fd, (struct sockaddr*) &addr, &addrlen); + if (newConn < 0) { + logerror("tcp accept, ignoring error and connection request"); + return -1; + } + + /* Add to session list */ + iSess = TCPSessFindFreeSpot(); + if(iSess == -1) { + errno = 0; + logerror("too many tcp sessions - dropping incoming request"); + close(newConn); + return -1; + } + + /* OK, we have a "good" index... */ + /* get the host name */ + if(cvthname(&addr, fromHost, fromHostFQDN) != RS_RET_OK) { + /* we seem to have something malicous - at least we + * are now told to discard the connection request. + * Error message has been generated by cvthname. + */ + close (newConn); + return -1; + } + + /* Here we check if a host is permitted to send us + * syslog messages. If it isn't, we do not further + * process the message but log a warning (if we are + * configured to do this). + * rgerhards, 2005-09-26 + */ +#ifdef USE_GSSAPI + if((bEnableTCP & ALLOWEDMETHOD_TCP) && + isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN)) + allowedMethods |= ALLOWEDMETHOD_TCP; + if((bEnableTCP & ALLOWEDMETHOD_GSS) && + isAllowedSender(pAllowedSenders_GSS, (struct sockaddr *)&addr, (char*)fromHostFQDN)) + allowedMethods |= ALLOWEDMETHOD_GSS; + if(allowedMethods) + pTCPSessions[iSess].allowedMethods = allowedMethods; + else +#else + if(!isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN)) +#endif + { + dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN); + if(option_DisallowWarning) { + errno = 0; + logerrorSz("TCP message from disallowed sender %s discarded", + (char*)fromHost); + } + close(newConn); + return -1; + } + + /* OK, we have an allowed sender, so let's continue */ + lenHostName = strlen((char*)fromHost) + 1; /* for \0 byte */ + if((pBuf = (char*) malloc(sizeof(char) * lenHostName)) == NULL) { + glblHadMemShortage = 1; + pTCPSessions[iSess].fromHost = "NO-MEMORY-FOR-HOSTNAME"; + } else { + memcpy(pBuf, fromHost, lenHostName); + pTCPSessions[iSess].fromHost = pBuf; + } + + pTCPSessions[iSess].sock = newConn; + pTCPSessions[iSess].iMsg = 0; /* init msg buffer! */ + return iSess; +} + + +/* This should be called before a normal (non forced) close + * of a TCP session. This function checks if there is any unprocessed + * message left in the TCP stream. Such a message is probably a + * fragement. If evrything goes well, we must be right at the + * beginnig of a new frame without any data received from it. If + * not, there is some kind of a framing error. I think I remember that + * some legacy syslog/TCP implementations have non-LF terminated + * messages at the end of the stream. For now, we allow this behaviour. + * Later, it should probably become a configuration option. + * rgerhards, 2006-12-07 + */ +void TCPSessPrepareClose(int iTCPSess) +{ + if(iTCPSess < 0 || iTCPSess > iTCPSessMax) { + errno = 0; + logerror("internal error, trying to close an invalid TCP session!"); + return; + } + + if(pTCPSessions[iTCPSess].bAtStrtOfFram == 1) { + /* this is how it should be. There is no unprocessed + * data left and such we have nothing to do. For simplicity + * reasons, we immediately return in that case. + */ + return; + } + + /* we have some data left! */ + if(pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_COUNTING) { + /* In this case, we have an invalid frame count and thus + * generate an error message and discard the frame. + */ + logerrorInt("Incomplete frame at end of stream in session %d - " + "ignoring extra data (a message may be lost).\n", + pTCPSessions[iTCPSess].sock); + /* nothing more to do */ + } else { /* here, we have traditional framing. Missing LF at the end + * of message may occur. As such, we process the message in + * this case. + */ + dbgprintf("Extra data at end of stream in legacy syslog/tcp message - processing\n"); + parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pTCPSessions[iTCPSess].msg, + pTCPSessions[iTCPSess].iMsg, MSG_PARSE_HOSTNAME); + pTCPSessions[iTCPSess].bAtStrtOfFram = 1; + } +} + + +/* Closes a TCP session and marks its slot in the session + * table as unused. No attention is paid to the return code + * of close, so potential-double closes are not detected. + */ +void TCPSessClose(int iSess) +{ + if(iSess < 0 || iSess > iTCPSessMax) { + errno = 0; + logerror("internal error, trying to close an invalid TCP session!"); + return; + } + + close(pTCPSessions[iSess].sock); + pTCPSessions[iSess].sock = -1; + free(pTCPSessions[iSess].fromHost); + pTCPSessions[iSess].fromHost = NULL; /* not really needed, but... */ +} + + +/* Processes the data received via a TCP session. If there + * is no other way to handle it, data is discarded. + * Input parameter data is the data received, iLen is its + * len as returned from recv(). iLen must be 1 or more (that + * is errors must be handled by caller!). iTCPSess must be + * the index of the TCP session that received the data. + * rgerhards 2005-07-04 + * Changed this functions interface. We now return a status of + * what shall happen with the session. This is information for + * the caller. If 1 is returned, the session should remain open + * and additional data be accepted. If we return 0, the TCP + * session is to be closed by the caller. This functionality is + * needed in order to support framing errors, from which there + * is no recovery possible other than session termination and + * re-establishment. The need for this functionality thus is + * primarily rooted in support for -transport-tls I-D framing. + * rgerhards, 2006-12-07 + */ +int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) +{ + register int iMsg; + char *pMsg; + char *pEnd; + assert(pData != NULL); + assert(iLen > 0); + assert(iTCPSess >= 0); + assert(iTCPSess < iTCPSessMax); + assert(pTCPSessions[iTCPSess].sock != -1); + + /* We now copy the message to the session buffer. As + * it looks, we need to do this in any case because + * we might run into multiple messages inside a single + * buffer. Of course, we could think about optimizations, + * but as this code is to be replaced by liblogging, it + * probably doesn't make so much sense... + * rgerhards 2005-07-04 + * + * Algo: + * - copy message to buffer until the first LF is found + * - printline() the buffer + * - continue with copying + */ + iMsg = pTCPSessions[iTCPSess].iMsg; /* copy for speed */ + pMsg = pTCPSessions[iTCPSess].msg; /* just a shortcut */ + pEnd = pData + iLen; /* this is one off, which is intensional */ + + while(pData < pEnd) { + /* Check if we are at a new frame */ + if(pTCPSessions[iTCPSess].bAtStrtOfFram) { + /* we need to look at the message and detect + * the framing mode used + *//* + * Contrary to -transport-tls, we accept leading zeros in the message + * length. We do this in the spirit of "Be liberal in what you accept, + * and conservative in what you send". We expect that including leading + * zeros could be a common coding error. + * rgerhards, 2006-12-07 + * The chairs of the IETF syslog-sec WG have announced that it is + * consensus to do the octet count on the SYSLOG-MSG part only. I am + * now changing the code to reflect this. Hopefully, it will not change + * once again (there can no compatibility layer programmed for this). + * To be on the save side, I just comment the code out. I mark these + * comments with "IETF20061218". + * rgerhards, 2006-12-19 + */ + if(isdigit((int) *pData)) { + int iCnt; /* the frame count specified */ + pTCPSessions[iTCPSess].eFraming = TCP_FRAMING_OCTET_COUNTING; + /* in this mode, we have OCTET-COUNT SP MSG - so we now need + * to extract the OCTET-COUNT and the SP and then extract + * the msg. + */ + iCnt = 0; + /* IETF20061218 int iNbrOctets = 0; / * number of octets already consumed */ + while(isdigit((int) *pData)) { + iCnt = iCnt * 10 + *pData - '0'; + /* IETF20061218 ++iNbrOctets; */ + ++pData; + } + dbgprintf("TCP Message with octet-counter, size %d.\n", iCnt); + if(*pData == ' ') { + ++pData; /* skip over SP */ + /* IETF20061218 ++iNbrOctets; */ + } else { + /* TODO: handle "invalid frame" case */ + logerrorInt("Framing Error in received TCP message: " + "delimiter is not SP but has ASCII value %d.\n", + *pData); + return(0); /* unconditional error exit */ + } + /* IETF20061218 pTCPSessions[iTCPSess].iOctetsRemain = iCnt - iNbrOctets; */ + pTCPSessions[iTCPSess].iOctetsRemain = iCnt; + if(pTCPSessions[iTCPSess].iOctetsRemain < 1) { + /* TODO: handle the case where the octet count is 0 or negative! */ + dbgprintf("Framing Error: invalid octet count\n"); + logerrorInt("Framing Error in received TCP message: " + "invalid octet count %d.\n", + pTCPSessions[iTCPSess].iOctetsRemain); + return(0); /* unconditional error exit */ + } + } else { + pTCPSessions[iTCPSess].eFraming = TCP_FRAMING_OCTET_STUFFING; + /* No need to do anything else here in this case */ + } + pTCPSessions[iTCPSess].bAtStrtOfFram = 0; /* done frame header */ + } + + /* now copy message until end of record */ + + if(iMsg >= MAXLINE) { + /* emergency, we now need to flush, no matter if + * we are at end of message or not... + */ + parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); + iMsg = 0; + /* we might think if it is better to ignore the rest of the + * message than to treat it as a new one. Maybe this is a good + * candidate for a configuration parameter... + * rgerhards, 2006-12-04 + */ + } + + if(*pData == '\n' && + pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_STUFFING) { /* record delemiter? */ + parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); + iMsg = 0; + pTCPSessions[iTCPSess].bAtStrtOfFram = 1; + ++pData; + } else { + /* IMPORTANT: here we copy the actual frame content to the message! */ + *(pMsg + iMsg++) = *pData++; + } + + if(pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_COUNTING) { + /* do we need to find end-of-frame via octet counting? */ + pTCPSessions[iTCPSess].iOctetsRemain--; + if(pTCPSessions[iTCPSess].iOctetsRemain < 1) { + /* we have end of frame! */ + parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); + iMsg = 0; + pTCPSessions[iTCPSess].bAtStrtOfFram = 1; + } + } + } + + pTCPSessions[iTCPSess].iMsg = iMsg; /* persist value */ + + return(1); /* successful return */ +} + + +static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) +{ + if (!bEnableTCP) + configureTCPListen((char *) pNewVal); + bEnableTCP |= ALLOWEDMETHOD_TCP; + + return RS_RET_OK; +} + + +#ifdef USE_GSSAPI +static rsRetVal addGSSListener(void __attribute__((unused)) *pVal, uchar *pNewVal) +{ + if (!bEnableTCP) + configureTCPListen((char *) pNewVal); + bEnableTCP |= ALLOWEDMETHOD_GSS; + + return RS_RET_OK; +} + + +/* returns 0 if all went OK, -1 if it failed */ +int TCPSessGSSInit(void) +{ + gss_buffer_desc name_buf; + gss_name_t server_name; + OM_uint32 maj_stat, min_stat; + + if (gss_server_creds != GSS_C_NO_CREDENTIAL) + return 0; + + name_buf.value = (gss_listen_service_name == NULL) ? "host" : gss_listen_service_name; + name_buf.length = strlen(name_buf.value) + 1; + maj_stat = gss_import_name(&min_stat, &name_buf, GSS_C_NT_HOSTBASED_SERVICE, &server_name); + if (maj_stat != GSS_S_COMPLETE) { + display_status("importing name", maj_stat, min_stat); + return -1; + } + + maj_stat = gss_acquire_cred(&min_stat, server_name, 0, + GSS_C_NULL_OID_SET, GSS_C_ACCEPT, + &gss_server_creds, NULL, NULL); + if (maj_stat != GSS_S_COMPLETE) { + display_status("acquiring credentials", maj_stat, min_stat); + return -1; + } + + gss_release_name(&min_stat, &server_name); + dbgprintf("GSS-API initialized\n"); + return 0; +} + + +/* returns 0 if all went OK, -1 if it failed */ +int TCPSessGSSAccept(int fd) +{ + gss_buffer_desc send_tok, recv_tok; + gss_name_t client; + OM_uint32 maj_stat, min_stat, acc_sec_min_stat; + int iSess; + gss_ctx_id_t *context; + OM_uint32 *sess_flags; + int fdSess; + char allowedMethods; + + if ((iSess = TCPSessAccept(fd)) == -1) + return -1; + + allowedMethods = pTCPSessions[iSess].allowedMethods; + if (allowedMethods & ALLOWEDMETHOD_GSS) { + /* Buffer to store raw message in case that + * gss authentication fails halfway through. + */ + char buf[MAXLINE]; + int ret = 0; + + dbgprintf("GSS-API Trying to accept TCP session %d\n", iSess); + + fdSess = pTCPSessions[iSess].sock; + if (allowedMethods & ALLOWEDMETHOD_TCP) { + int len; + fd_set fds; + struct timeval tv; + + do { + FD_ZERO(&fds); + FD_SET(fdSess, &fds); + tv.tv_sec = 1; + tv.tv_usec = 0; + ret = select(fdSess + 1, &fds, NULL, NULL, &tv); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + logerrorInt("TCP session %d will be closed, error ignored\n", iSess); + TCPSessClose(iSess); + return -1; + } else if (ret == 0) { + dbgprintf("GSS-API Reverting to plain TCP\n"); + pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; + return 0; + } + + do { + ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK); + } while (ret < 0 && errno == EINTR); + if (ret <= 0) { + if (ret == 0) + dbgprintf("GSS-API Connection closed by peer\n"); + else + logerrorInt("TCP session %d will be closed, error ignored\n", iSess); + TCPSessClose(iSess); + return -1; + } + + if (ret < 4) { + dbgprintf("GSS-API Reverting to plain TCP\n"); + pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; + return 0; + } else if (ret == 4) { + /* The client might has been interupted after sending + * the data length (4B), give him another chance. + */ + sleep(1); + do { + ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK); + } while (ret < 0 && errno == EINTR); + if (ret <= 0) { + if (ret == 0) + dbgprintf("GSS-API Connection closed by peer\n"); + else + logerrorInt("TCP session %d will be closed, error ignored\n", iSess); + TCPSessClose(iSess); + return -1; + } + } + + len = ntohl((buf[0] << 24) + | (buf[1] << 16) + | (buf[2] << 8) + | buf[3]); + if ((ret - 4) < len || len == 0) { + dbgprintf("GSS-API Reverting to plain TCP\n"); + pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; + return 0; + } + } + + context = &pTCPSessions[iSess].gss_context; + *context = GSS_C_NO_CONTEXT; + sess_flags = &pTCPSessions[iSess].gss_flags; + do { + if (recv_token(fdSess, &recv_tok) <= 0) { + logerrorInt("TCP session %d will be closed, error ignored\n", iSess); + TCPSessClose(iSess); + return -1; + } + maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, gss_server_creds, + &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, + NULL, &send_tok, sess_flags, NULL, NULL); + if (recv_tok.value) { + free(recv_tok.value); + recv_tok.value = NULL; + } + if (maj_stat != GSS_S_COMPLETE + && maj_stat != GSS_S_CONTINUE_NEEDED) { + gss_release_buffer(&min_stat, &send_tok); + if (*context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); + if ((allowedMethods & ALLOWEDMETHOD_TCP) && + (GSS_ROUTINE_ERROR(maj_stat) == GSS_S_DEFECTIVE_TOKEN)) { + dbgprintf("GSS-API Reverting to plain TCP\n"); + dbgprintf("tcp session socket with new data: #%d\n", fdSess); + if(TCPSessDataRcvd(iSess, buf, ret) == 0) { + logerrorInt("Tearing down TCP Session %d - see " + "previous messages for reason(s)\n", + iSess); + TCPSessClose(iSess); + return -1; + } + pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; + return 0; + } + display_status("accepting context", maj_stat, + acc_sec_min_stat); + TCPSessClose(iSess); + return -1; + } + if (send_tok.length != 0) { + if (send_token(fdSess, &send_tok) < 0) { + gss_release_buffer(&min_stat, &send_tok); + logerrorInt("TCP session %d will be closed, error ignored\n", iSess); + if (*context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); + TCPSessClose(iSess); + return -1; + } + gss_release_buffer(&min_stat, &send_tok); + } + } while (maj_stat == GSS_S_CONTINUE_NEEDED); + + maj_stat = gss_display_name(&min_stat, client, &recv_tok, NULL); + if (maj_stat != GSS_S_COMPLETE) + display_status("displaying name", maj_stat, min_stat); + else + dbgprintf("GSS-API Accepted connection from: %s\n", (char*) recv_tok.value); + gss_release_name(&min_stat, &client); + gss_release_buffer(&min_stat, &recv_tok); + + dbgprintf("GSS-API Provided context flags:\n"); + display_ctx_flags(*sess_flags); + pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_GSS; + } + + return 0; +} + + +/* returns: ? */ +int TCPSessGSSRecv(int iSess, void *buf, size_t buf_len) +{ + gss_buffer_desc xmit_buf, msg_buf; + gss_ctx_id_t *context; + OM_uint32 maj_stat, min_stat; + int fdSess; + int conf_state; + int state, len; + + fdSess = pTCPSessions[iSess].sock; + if ((state = recv_token(fdSess, &xmit_buf)) <= 0) + return state; + + context = &pTCPSessions[iSess].gss_context; + maj_stat = gss_unwrap(&min_stat, *context, &xmit_buf, &msg_buf, + &conf_state, (gss_qop_t *) NULL); + if (maj_stat != GSS_S_COMPLETE) { + display_status("unsealing message", maj_stat, min_stat); + if (xmit_buf.value) { + free(xmit_buf.value); + xmit_buf.value = 0; + } + return (-1); + } + if (xmit_buf.value) { + free(xmit_buf.value); + xmit_buf.value = 0; + } + + len = msg_buf.length < buf_len ? msg_buf.length : buf_len; + memcpy(buf, msg_buf.value, len); + gss_release_buffer(&min_stat, &msg_buf); + + return len; +} + + +void TCPSessGSSClose(int iSess) { + OM_uint32 maj_stat, min_stat; + gss_ctx_id_t *context; + + if(iSess < 0 || iSess > iTCPSessMax) { + errno = 0; + logerror("internal error, trying to close an invalid TCP session!"); + return; + } + + context = &pTCPSessions[iSess].gss_context; + maj_stat = gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); + if (maj_stat != GSS_S_COMPLETE) + display_status("deleting context", maj_stat, min_stat); + *context = GSS_C_NO_CONTEXT; + pTCPSessions[iSess].gss_flags = 0; + pTCPSessions[iSess].allowedMethods = 0; + + TCPSessClose(iSess); +} + + +void TCPSessGSSDeinit(void) { + OM_uint32 maj_stat, min_stat; + + maj_stat = gss_release_cred(&min_stat, &gss_server_creds); + if (maj_stat != GSS_S_COMPLETE) + display_status("releasing credentials", maj_stat, min_stat); +} +#endif /* #ifdef USE_GSSAPI */ + + /* This function is called to gather input. */ BEGINrunInput @@ -288,8 +1280,15 @@ CODESTARTmodInit *ipIFVersProvided = 1; /* so far, we only support the initial definition */ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, + addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, + NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); #if defined(USE_GSSAPI) - CHKiRet(regCfSysLineHdlr((uchar *)"gsslistenservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, NULL)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverrun", 0, eCmdHdlrGetWord, + addGSSListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgsslistenservicename", 0, eCmdHdlrGetWord, + NULL, &gss_listen_service_name, STD_LOADABLE_MODULE_ID)); #endif CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); -- cgit v1.2.3 From 8fdd3b45c0c2b2a5751efd79e2be4cc0241af53e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 22 Feb 2008 09:13:14 +0000 Subject: added some doc for imgssapi and imtcp input modules --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index dc005af8..c3f5e138 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -1287,7 +1287,7 @@ CODEmodInit_QueryRegCFSLineHdlr #if defined(USE_GSSAPI) CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverrun", 0, eCmdHdlrGetWord, addGSSListener, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgsslistenservicename", 0, eCmdHdlrGetWord, + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, STD_LOADABLE_MODULE_ID)); #endif CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, -- cgit v1.2.3 From 01ceb6d79979ea8aedd174c47ed8c65fbf168c43 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Feb 2008 09:43:18 +0000 Subject: declared some things in imtcp.c static so that they don't conflict if loaded as imtcp and imgssapi --- plugins/imtcp/imtcp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index c3f5e138..84bb61a2 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -97,14 +97,14 @@ struct TCPSession { }; static int iTCPSessMax = TCPSESS_MAX_DEFAULT; /* actual number of sessions */ -char *TCPLstnPort = "0"; /* read-only after startup */ -int bEnableTCP = 0; /* read-only after startup */ -int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */ -struct TCPSession *pTCPSessions; +static char *TCPLstnPort = "0"; /* read-only after startup */ +static int bEnableTCP = 0; /* read-only after startup */ +static int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */ +static struct TCPSession *pTCPSessions; /* The thread-safeness of the sesion table is doubtful */ #ifdef USE_GSSAPI static gss_cred_id_t gss_server_creds = GSS_C_NO_CREDENTIAL; -char *gss_listen_service_name = NULL; +static char *gss_listen_service_name = NULL; #endif /* config settings */ -- cgit v1.2.3 From b98ca5114ed1d1975e06614472d4019d8c1767ab Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Feb 2008 11:02:27 +0000 Subject: split off imgssapi from imtcp, but still with a lot of dependency --- plugins/imtcp/imtcp.c | 309 +++----------------------------------------------- 1 file changed, 18 insertions(+), 291 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 84bb61a2..a1fabea7 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -47,17 +47,11 @@ #if HAVE_FCNTL_H #include #endif -#ifdef USE_GSSAPI -#include -#endif #include "rsyslog.h" #include "syslogd.h" #include "cfsysline.h" #include "module-template.h" #include "net.h" -#ifdef USE_GSSAPI -#include "gss-misc.h" -#endif #include "srUtils.h" MODULE_TYPE_INPUT @@ -102,10 +96,6 @@ static int bEnableTCP = 0; /* read-only after startup */ static int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */ static struct TCPSession *pTCPSessions; /* The thread-safeness of the sesion table is doubtful */ -#ifdef USE_GSSAPI -static gss_cred_id_t gss_server_creds = GSS_C_NO_CREDENTIAL; -static char *gss_listen_service_name = NULL; -#endif /* config settings */ @@ -763,6 +753,7 @@ int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) } +#ifndef USE_GSSAPI static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) { if (!bEnableTCP) @@ -771,283 +762,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa return RS_RET_OK; } - - -#ifdef USE_GSSAPI -static rsRetVal addGSSListener(void __attribute__((unused)) *pVal, uchar *pNewVal) -{ - if (!bEnableTCP) - configureTCPListen((char *) pNewVal); - bEnableTCP |= ALLOWEDMETHOD_GSS; - - return RS_RET_OK; -} - - -/* returns 0 if all went OK, -1 if it failed */ -int TCPSessGSSInit(void) -{ - gss_buffer_desc name_buf; - gss_name_t server_name; - OM_uint32 maj_stat, min_stat; - - if (gss_server_creds != GSS_C_NO_CREDENTIAL) - return 0; - - name_buf.value = (gss_listen_service_name == NULL) ? "host" : gss_listen_service_name; - name_buf.length = strlen(name_buf.value) + 1; - maj_stat = gss_import_name(&min_stat, &name_buf, GSS_C_NT_HOSTBASED_SERVICE, &server_name); - if (maj_stat != GSS_S_COMPLETE) { - display_status("importing name", maj_stat, min_stat); - return -1; - } - - maj_stat = gss_acquire_cred(&min_stat, server_name, 0, - GSS_C_NULL_OID_SET, GSS_C_ACCEPT, - &gss_server_creds, NULL, NULL); - if (maj_stat != GSS_S_COMPLETE) { - display_status("acquiring credentials", maj_stat, min_stat); - return -1; - } - - gss_release_name(&min_stat, &server_name); - dbgprintf("GSS-API initialized\n"); - return 0; -} - - -/* returns 0 if all went OK, -1 if it failed */ -int TCPSessGSSAccept(int fd) -{ - gss_buffer_desc send_tok, recv_tok; - gss_name_t client; - OM_uint32 maj_stat, min_stat, acc_sec_min_stat; - int iSess; - gss_ctx_id_t *context; - OM_uint32 *sess_flags; - int fdSess; - char allowedMethods; - - if ((iSess = TCPSessAccept(fd)) == -1) - return -1; - - allowedMethods = pTCPSessions[iSess].allowedMethods; - if (allowedMethods & ALLOWEDMETHOD_GSS) { - /* Buffer to store raw message in case that - * gss authentication fails halfway through. - */ - char buf[MAXLINE]; - int ret = 0; - - dbgprintf("GSS-API Trying to accept TCP session %d\n", iSess); - - fdSess = pTCPSessions[iSess].sock; - if (allowedMethods & ALLOWEDMETHOD_TCP) { - int len; - fd_set fds; - struct timeval tv; - - do { - FD_ZERO(&fds); - FD_SET(fdSess, &fds); - tv.tv_sec = 1; - tv.tv_usec = 0; - ret = select(fdSess + 1, &fds, NULL, NULL, &tv); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { - logerrorInt("TCP session %d will be closed, error ignored\n", iSess); - TCPSessClose(iSess); - return -1; - } else if (ret == 0) { - dbgprintf("GSS-API Reverting to plain TCP\n"); - pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; - return 0; - } - - do { - ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK); - } while (ret < 0 && errno == EINTR); - if (ret <= 0) { - if (ret == 0) - dbgprintf("GSS-API Connection closed by peer\n"); - else - logerrorInt("TCP session %d will be closed, error ignored\n", iSess); - TCPSessClose(iSess); - return -1; - } - - if (ret < 4) { - dbgprintf("GSS-API Reverting to plain TCP\n"); - pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; - return 0; - } else if (ret == 4) { - /* The client might has been interupted after sending - * the data length (4B), give him another chance. - */ - sleep(1); - do { - ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK); - } while (ret < 0 && errno == EINTR); - if (ret <= 0) { - if (ret == 0) - dbgprintf("GSS-API Connection closed by peer\n"); - else - logerrorInt("TCP session %d will be closed, error ignored\n", iSess); - TCPSessClose(iSess); - return -1; - } - } - - len = ntohl((buf[0] << 24) - | (buf[1] << 16) - | (buf[2] << 8) - | buf[3]); - if ((ret - 4) < len || len == 0) { - dbgprintf("GSS-API Reverting to plain TCP\n"); - pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; - return 0; - } - } - - context = &pTCPSessions[iSess].gss_context; - *context = GSS_C_NO_CONTEXT; - sess_flags = &pTCPSessions[iSess].gss_flags; - do { - if (recv_token(fdSess, &recv_tok) <= 0) { - logerrorInt("TCP session %d will be closed, error ignored\n", iSess); - TCPSessClose(iSess); - return -1; - } - maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, gss_server_creds, - &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, - NULL, &send_tok, sess_flags, NULL, NULL); - if (recv_tok.value) { - free(recv_tok.value); - recv_tok.value = NULL; - } - if (maj_stat != GSS_S_COMPLETE - && maj_stat != GSS_S_CONTINUE_NEEDED) { - gss_release_buffer(&min_stat, &send_tok); - if (*context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); - if ((allowedMethods & ALLOWEDMETHOD_TCP) && - (GSS_ROUTINE_ERROR(maj_stat) == GSS_S_DEFECTIVE_TOKEN)) { - dbgprintf("GSS-API Reverting to plain TCP\n"); - dbgprintf("tcp session socket with new data: #%d\n", fdSess); - if(TCPSessDataRcvd(iSess, buf, ret) == 0) { - logerrorInt("Tearing down TCP Session %d - see " - "previous messages for reason(s)\n", - iSess); - TCPSessClose(iSess); - return -1; - } - pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP; - return 0; - } - display_status("accepting context", maj_stat, - acc_sec_min_stat); - TCPSessClose(iSess); - return -1; - } - if (send_tok.length != 0) { - if (send_token(fdSess, &send_tok) < 0) { - gss_release_buffer(&min_stat, &send_tok); - logerrorInt("TCP session %d will be closed, error ignored\n", iSess); - if (*context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); - TCPSessClose(iSess); - return -1; - } - gss_release_buffer(&min_stat, &send_tok); - } - } while (maj_stat == GSS_S_CONTINUE_NEEDED); - - maj_stat = gss_display_name(&min_stat, client, &recv_tok, NULL); - if (maj_stat != GSS_S_COMPLETE) - display_status("displaying name", maj_stat, min_stat); - else - dbgprintf("GSS-API Accepted connection from: %s\n", (char*) recv_tok.value); - gss_release_name(&min_stat, &client); - gss_release_buffer(&min_stat, &recv_tok); - - dbgprintf("GSS-API Provided context flags:\n"); - display_ctx_flags(*sess_flags); - pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_GSS; - } - - return 0; -} - - -/* returns: ? */ -int TCPSessGSSRecv(int iSess, void *buf, size_t buf_len) -{ - gss_buffer_desc xmit_buf, msg_buf; - gss_ctx_id_t *context; - OM_uint32 maj_stat, min_stat; - int fdSess; - int conf_state; - int state, len; - - fdSess = pTCPSessions[iSess].sock; - if ((state = recv_token(fdSess, &xmit_buf)) <= 0) - return state; - - context = &pTCPSessions[iSess].gss_context; - maj_stat = gss_unwrap(&min_stat, *context, &xmit_buf, &msg_buf, - &conf_state, (gss_qop_t *) NULL); - if (maj_stat != GSS_S_COMPLETE) { - display_status("unsealing message", maj_stat, min_stat); - if (xmit_buf.value) { - free(xmit_buf.value); - xmit_buf.value = 0; - } - return (-1); - } - if (xmit_buf.value) { - free(xmit_buf.value); - xmit_buf.value = 0; - } - - len = msg_buf.length < buf_len ? msg_buf.length : buf_len; - memcpy(buf, msg_buf.value, len); - gss_release_buffer(&min_stat, &msg_buf); - - return len; -} - - -void TCPSessGSSClose(int iSess) { - OM_uint32 maj_stat, min_stat; - gss_ctx_id_t *context; - - if(iSess < 0 || iSess > iTCPSessMax) { - errno = 0; - logerror("internal error, trying to close an invalid TCP session!"); - return; - } - - context = &pTCPSessions[iSess].gss_context; - maj_stat = gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); - if (maj_stat != GSS_S_COMPLETE) - display_status("deleting context", maj_stat, min_stat); - *context = GSS_C_NO_CONTEXT; - pTCPSessions[iSess].gss_flags = 0; - pTCPSessions[iSess].allowedMethods = 0; - - TCPSessClose(iSess); -} - - -void TCPSessGSSDeinit(void) { - OM_uint32 maj_stat, min_stat; - - maj_stat = gss_release_cred(&min_stat, &gss_server_creds); - if (maj_stat != GSS_S_COMPLETE) - display_status("releasing credentials", maj_stat, min_stat); -} -#endif /* #ifdef USE_GSSAPI */ - +#endif /* This function is called to gather input. */ @@ -1194,7 +909,15 @@ ENDrunInput /* initialize and return if will run or not */ BEGINwillRun CODESTARTwillRun +#ifdef USE_GSSAPI + /* first check if we must support plain TCP, too. If so, set mode + * accordingly. -- rgerhards, 2008-02-26 + */ + if(bPermitPlainTcp) + bEnableTCP |= ALLOWEDMETHOD_TCP; + /* first apply some config settings */ +#endif dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP); PrintAllowedSenders(2); /* TCP */ #ifdef USE_GSSAPI @@ -1270,6 +993,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a free(gss_listen_service_name); gss_listen_service_name = NULL; } + bPermitPlainTcp = 0; #endif return RS_RET_OK; } @@ -1280,15 +1004,18 @@ CODESTARTmodInit *ipIFVersProvided = 1; /* so far, we only support the initial definition */ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, - addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, - NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); #if defined(USE_GSSAPI) + CHKiRet(omsdRegCFSLineHdlr((uchar *)"permitplaintcp", 0, eCmdHdlrBinary, + NULL, bPermitPlainTcp, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverrun", 0, eCmdHdlrGetWord, addGSSListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverservicename", 0, eCmdHdlrGetWord, NULL, &gss_listen_service_name, STD_LOADABLE_MODULE_ID)); +#else + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, + addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, + NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); #endif CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); -- cgit v1.2.3 From 3467a10c06414a5dea2ef933fc9709085d362446 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Feb 2008 11:16:05 +0000 Subject: shuffled some more code, added comments varmojfekoj sent me a while ago to imgssapi --- plugins/imtcp/imtcp.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index a1fabea7..d3752d42 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -918,7 +918,6 @@ CODESTARTwillRun /* first apply some config settings */ #endif -dbgprintf("imtcp: bEnableTCP %d\n", bEnableTCP); PrintAllowedSenders(2); /* TCP */ #ifdef USE_GSSAPI PrintAllowedSenders(3); /* GSS */ @@ -986,15 +985,10 @@ CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES ENDqueryEtryPt + +#ifndef USE_GSSAPI static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { -#if defined(USE_GSSAPI) - if (gss_listen_service_name != NULL) { - free(gss_listen_service_name); - gss_listen_service_name = NULL; - } - bPermitPlainTcp = 0; -#endif return RS_RET_OK; } @@ -1004,22 +998,14 @@ CODESTARTmodInit *ipIFVersProvided = 1; /* so far, we only support the initial definition */ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ -#if defined(USE_GSSAPI) - CHKiRet(omsdRegCFSLineHdlr((uchar *)"permitplaintcp", 0, eCmdHdlrBinary, - NULL, bPermitPlainTcp, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverrun", 0, eCmdHdlrGetWord, - addGSSListener, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputgssserverservicename", 0, eCmdHdlrGetWord, - NULL, &gss_listen_service_name, STD_LOADABLE_MODULE_ID)); -#else CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); -#endif CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -/* - * vi:set ai: +#endif + +/* vim:set ai: */ -- cgit v1.2.3 From 9d8eb28ebd941694d8dcbc66c6e5c80cf90a206d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sun, 2 Mar 2008 10:19:25 +0000 Subject: - added class tcps - added class tcps_sess - changed imtcp to use new classes; seems to work; imgssapi currently broken --- plugins/imtcp/imtcp.c | 958 +++++--------------------------------------------- 1 file changed, 90 insertions(+), 868 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d3752d42..9ad85044 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -1,9 +1,6 @@ /* imtcp.c * This is the implementation of the TCP input module. * - * NOTE: read comments in module-template.h to understand how this file - * works! - * * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c) * * Copyright 2007 Rainer Gerhards and Adiscon GmbH. @@ -27,12 +24,6 @@ */ #include "config.h" -#ifdef FORCE_NO_GSS - #ifdef USE_GSSAPI - #undef USE_GSSAPI - #endif -#endif - #include #include #include @@ -52,856 +43,112 @@ #include "cfsysline.h" #include "module-template.h" #include "net.h" -#include "srUtils.h" +#include "tcpsrv.h" MODULE_TYPE_INPUT -/* defines */ -#ifdef USE_GSSAPI -#define ALLOWEDMETHOD_GSS 2 -#endif -#define ALLOWEDMETHOD_TCP 1 - -#define TCPSESS_MAX_DEFAULT 200 /* default for nbr of tcp sessions if no number is given */ +/* static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(obj) +DEFobjCurrIf(tcpsrv) +DEFobjCurrIf(tcps_sess) /* Module static data */ -DEF_IMOD_STATIC_DATA typedef struct _instanceData { } instanceData; -typedef enum _TCPFRAMINGMODE { - TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */ - TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */ - } TCPFRAMINGMODE; - -struct TCPSession { - int sock; - int iMsg; /* index of next char to store in msg */ - int bAtStrtOfFram; /* are we at the very beginning of a new frame? */ - int iOctetsRemain; /* Number of Octets remaining in message */ - TCPFRAMINGMODE eFraming; - char msg[MAXLINE+1]; - char *fromHost; -#ifdef USE_GSSAPI - OM_uint32 gss_flags; - gss_ctx_id_t gss_context; - char allowedMethods; -#endif -}; - -static int iTCPSessMax = TCPSESS_MAX_DEFAULT; /* actual number of sessions */ -static char *TCPLstnPort = "0"; /* read-only after startup */ -static int bEnableTCP = 0; /* read-only after startup */ -static int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */ -static struct TCPSession *pTCPSessions; -/* The thread-safeness of the sesion table is doubtful */ +static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ /* config settings */ +static int iTCPSessMax = 200; /* max number of sessions */ +static char *TCPLstnPort = "0"; /* read-only after startup */ -/* code to free all sockets within a socket table. - * A socket table is a descriptor table where the zero - * element has the count of elements. This is used for - * listening sockets. The socket table itself is also - * freed. - * A POINTER to this structure must be provided, thus - * double indirection! - * rgerhards, 2007-06-28 - */ -static void freeAllSockets(int **socks) -{ - assert(socks != NULL); - assert(*socks != NULL); - while(**socks) { - dbgprintf("Closing socket %d.\n", (*socks)[**socks]); - close((*socks)[**socks]); - (**socks)--; - } - free(*socks); - socks = NULL; -} - - -/* configure TCP listener settings. This is called during command - * line parsing. The argument following -t is supplied as an argument. - * The format of this argument is - * ", " - * Typically, there is no whitespace between port and session number. - * (but it may be...). - * NOTE: you can not use dbgprintf() in here - the dbgprintf() system is - * not yet initilized when this function is called. - * rgerhards, 2007-06-21 - * We can also not use logerror(), as that system is also not yet - * initialized... rgerhards, 2007-06-28 - */ -void configureTCPListen(char *cOptarg) -{ - register int i; - register char *pArg = cOptarg; - - assert(cOptarg != NULL); - - /* extract port */ - i = 0; - while(isdigit((int) *pArg)) { - i = i * 10 + *pArg++ - '0'; - } - - if( i >= 0 && i <= 65535) { - TCPLstnPort = cOptarg; - } else { - logerrorSz("Invalid TCP listen port %s - changed to 514.\n", cOptarg); - TCPLstnPort = "514"; - } -} - - -void configureTCPListenSessMax(char *cOptarg) -{ - register int i; - register char *pArg = cOptarg; - - assert(cOptarg != NULL); - - /* number of sessions */ - i = 0; - while(isdigit((int) *pArg)) { - i = i * 10 + *pArg++ - '0'; - } - - if(i > 0) - iTCPSessMax = i; - else { - /* too small, need to adjust */ - logerrorSz("TCP session max configured to %s - changing to 1.\n", cOptarg); - iTCPSessMax = 1; - } -} - - -/* Initialize the session table - * returns 0 if OK, somewhat else otherwise - */ -static int TCPSessInit(void) -{ - register int i; - - assert(pTCPSessions == NULL); - dbgprintf("Allocating buffer for %d TCP sessions.\n", iTCPSessMax); - if((pTCPSessions = (struct TCPSession *) malloc(sizeof(struct TCPSession) * iTCPSessMax)) - == NULL) { - dbgprintf("Error: TCPSessInit() could not alloc memory for TCP session table.\n"); - return(1); - } - - for(i = 0 ; i < iTCPSessMax ; ++i) { - pTCPSessions[i].sock = -1; /* no sock */ - pTCPSessions[i].iMsg = 0; /* just make sure... */ - pTCPSessions[i].bAtStrtOfFram = 1; /* indicate frame header expected */ - pTCPSessions[i].eFraming = TCP_FRAMING_OCTET_STUFFING; /* just make sure... */ -#ifdef USE_GSSAPI - pTCPSessions[i].gss_flags = 0; - pTCPSessions[i].gss_context = GSS_C_NO_CONTEXT; - pTCPSessions[i].allowedMethods = 0; -#endif - } - return(0); -} - - -/* find a free spot in the session table. If the table - * is full, -1 is returned, else the index of the free - * entry (0 or higher). - */ -static int TCPSessFindFreeSpot(void) -{ - register int i; - - for(i = 0 ; i < iTCPSessMax ; ++i) { - if(pTCPSessions[i].sock == -1) - break; - } - - return((i < iTCPSessMax) ? i : -1); -} - - -/* Get the next session index. Free session tables entries are - * skipped. This function is provided the index of the last - * session entry, or -1 if no previous entry was obtained. It - * returns the index of the next session or -1, if there is no - * further entry in the table. Please note that the initial call - * might as well return -1, if there is no session at all in the - * session table. - */ -int TCPSessGetNxtSess(int iCurr) -{ - register int i; - - for(i = iCurr + 1 ; i < iTCPSessMax ; ++i) - if(pTCPSessions[i].sock != -1) - break; - - return((i < iTCPSessMax) ? i : -1); -} - - -/* De-Initialize TCP listner sockets. - * This function deinitializes everything, including freeing the - * session table. No TCP listen receive operations are permitted - * unless the subsystem is reinitialized. - * rgerhards, 2007-06-21 - */ -void deinit_tcp_listener(void) +/* callbacks */ +/* this shall go into a specific ACL module! */ +static int +isPermittedHost(struct sockaddr *addr, char *fromHostFQDN) { - int iTCPSess; - - assert(pTCPSessions != NULL); - /* close all TCP connections! */ - iTCPSess = TCPSessGetNxtSess(-1); - while(iTCPSess != -1) { - int fd; - fd = pTCPSessions[iTCPSess].sock; - dbgprintf("Closing TCP Session %d\n", fd); - close(fd); - free(pTCPSessions[iTCPSess].fromHost); -#ifdef USE_GSSAPI - if(bEnableTCP & ALLOWEDMETHOD_GSS) { - OM_uint32 maj_stat, min_stat; - maj_stat = gss_delete_sec_context(&min_stat, &pTCPSessions[iTCPSess].gss_context, GSS_C_NO_BUFFER); - if (maj_stat != GSS_S_COMPLETE) - display_status("deleting context", maj_stat, min_stat); - } -#endif - /* now get next... */ - iTCPSess = TCPSessGetNxtSess(iTCPSess); - } - - /* we are done with the session table - so get rid of it... - */ - free(pTCPSessions); - pTCPSessions = NULL; /* just to make sure... */ - - /* finally close the listen sockets themselfs */ - freeAllSockets(&sockTCPLstn); + return isAllowedSender(pAllowedSenders_TCP, addr, fromHostFQDN); } -/* Initialize TCP sockets (for listener) - * This function returns either NULL (which means it failed) or - * a pointer to an array of file descriptiors. If the pointer is - * returned, the zeroest element [0] contains the count of valid - * descriptors. The descriptors themself follow in range - * [1] ... [num-descriptors]. It is guaranteed that each of these - * descriptors is valid, at least when this function returns. - * Please note that technically the array may be larger than the number - * of valid pointers stored in it. The memory overhead is minimal, so - * we do not bother to re-allocate an array of the exact size. Logically, - * the array still contains the exactly correct number of descriptors. - */ -int *create_tcp_socket(void) +static rsRetVal +onSessAccept(tcpsrv_t *pThis, int fd) { - struct addrinfo hints, *res, *r; - int error, maxs, *s, *socks, on = 1; - - if(!strcmp(TCPLstnPort, "0")) - TCPLstnPort = "514"; - /* use default - we can not do service db update, because there is - * no IANA-assignment for syslog/tcp. In the long term, we might - * re-use RFC 3195 port of 601, but that would probably break to - * many existing configurations. - * rgerhards, 2007-06-28 - */ - dbgprintf("creating tcp socket on port %s\n", TCPLstnPort); - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - - error = getaddrinfo(NULL, TCPLstnPort, &hints, &res); - if(error) { - logerror((char*) gai_strerror(error)); - return NULL; - } - - /* Count max number of sockets we may open */ - for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++) - /* EMPTY */; - socks = malloc((maxs+1) * sizeof(int)); - if (socks == NULL) { - logerror("couldn't allocate memory for TCP listen sockets, suspending TCP message reception."); - freeaddrinfo(res); - return NULL; - } - - *socks = 0; /* num of sockets counter at start of array */ - s = socks + 1; - for (r = res; r != NULL ; r = r->ai_next) { - *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); - if (*s < 0) { - if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT)) - logerror("create_udp_socket(), socket"); - /* it is debatable if PF_INET with EAFNOSUPPORT should - * also be ignored... - */ - continue; - } - -#ifdef IPV6_V6ONLY - if (r->ai_family == AF_INET6) { - int iOn = 1; - if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, - (char *)&iOn, sizeof (iOn)) < 0) { - logerror("TCP setsockopt"); - close(*s); - *s = -1; - continue; - } - } -#endif - if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, - (char *) &on, sizeof(on)) < 0 ) { - logerror("TCP setsockopt(REUSEADDR)"); - close(*s); - *s = -1; - continue; - } - - /* We need to enable BSD compatibility. Otherwise an attacker - * could flood our log files by sending us tons of ICMP errors. - */ -#ifndef BSD - if (should_use_so_bsdcompat()) { - if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT, - (char *) &on, sizeof(on)) < 0) { - logerror("TCP setsockopt(BSDCOMPAT)"); - close(*s); - *s = -1; - continue; - } - } -#endif - - if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0) -#ifndef IPV6_V6ONLY - && (errno != EADDRINUSE) -#endif - ) { - logerror("TCP bind"); - close(*s); - *s = -1; - continue; - } - - if( listen(*s,iTCPSessMax / 10 + 5) < 0) { - /* If the listen fails, it most probably fails because we ask - * for a too-large backlog. So in this case we first set back - * to a fixed, reasonable, limit that should work. Only if - * that fails, too, we give up. - */ - logerrorInt("listen with a backlog of %d failed - retrying with default of 32.", - iTCPSessMax / 10 + 5); - if(listen(*s, 32) < 0) { - logerror("TCP listen, suspending tcp inet"); - close(*s); - *s = -1; - continue; - } - } - - (*socks)++; - s++; - } - - if(res != NULL) - freeaddrinfo(res); - - if(Debug && *socks != maxs) - dbgprintf("We could initialize %d TCP listen sockets out of %d we received " - "- this may or may not be an error indication.\n", *socks, maxs); - - if(*socks == 0) { - logerror("No TCP listen socket could successfully be initialized, " - "message reception via TCP disabled.\n"); - free(socks); - return(NULL); - } + DEFiRet; - /* OK, we had success. Now it is also time to - * initialize our connections - */ - if(TCPSessInit() != 0) { - /* OK, we are in some trouble - we could not initialize the - * session table, so we can not continue. We need to free all - * we have assigned so far, because we can not really use it... - */ - logerror("Could not initialize TCP session table, suspending TCP message reception."); - freeAllSockets(&socks); /* prevent a socket leak */ - return(NULL); - } - - return(socks); + tcpsrv.SessAccept(pThis, fd); + RETiRet; } -/* Accept new TCP connection; make entry in session table. If there - * is no more space left in the connection table, the new TCP - * connection is immediately dropped. - */ -int TCPSessAccept(int fd) +static int +doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf) { - int newConn; - int iSess; - struct sockaddr_storage addr; - socklen_t addrlen = sizeof(struct sockaddr_storage); - size_t lenHostName; - uchar fromHost[NI_MAXHOST]; - uchar fromHostFQDN[NI_MAXHOST]; - char *pBuf; -#ifdef USE_GSSAPI - char allowedMethods = 0; -#endif + int state; + assert(pSess != NULL); - newConn = accept(fd, (struct sockaddr*) &addr, &addrlen); - if (newConn < 0) { - logerror("tcp accept, ignoring error and connection request"); - return -1; - } - - /* Add to session list */ - iSess = TCPSessFindFreeSpot(); - if(iSess == -1) { - errno = 0; - logerror("too many tcp sessions - dropping incoming request"); - close(newConn); - return -1; - } - - /* OK, we have a "good" index... */ - /* get the host name */ - if(cvthname(&addr, fromHost, fromHostFQDN) != RS_RET_OK) { - /* we seem to have something malicous - at least we - * are now told to discard the connection request. - * Error message has been generated by cvthname. - */ - close (newConn); - return -1; - } - - /* Here we check if a host is permitted to send us - * syslog messages. If it isn't, we do not further - * process the message but log a warning (if we are - * configured to do this). - * rgerhards, 2005-09-26 - */ -#ifdef USE_GSSAPI - if((bEnableTCP & ALLOWEDMETHOD_TCP) && - isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN)) - allowedMethods |= ALLOWEDMETHOD_TCP; - if((bEnableTCP & ALLOWEDMETHOD_GSS) && - isAllowedSender(pAllowedSenders_GSS, (struct sockaddr *)&addr, (char*)fromHostFQDN)) - allowedMethods |= ALLOWEDMETHOD_GSS; - if(allowedMethods) - pTCPSessions[iSess].allowedMethods = allowedMethods; - else -#else - if(!isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN)) -#endif - { - dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN); - if(option_DisallowWarning) { - errno = 0; - logerrorSz("TCP message from disallowed sender %s discarded", - (char*)fromHost); - } - close(newConn); - return -1; - } - - /* OK, we have an allowed sender, so let's continue */ - lenHostName = strlen((char*)fromHost) + 1; /* for \0 byte */ - if((pBuf = (char*) malloc(sizeof(char) * lenHostName)) == NULL) { - glblHadMemShortage = 1; - pTCPSessions[iSess].fromHost = "NO-MEMORY-FOR-HOSTNAME"; - } else { - memcpy(pBuf, fromHost, lenHostName); - pTCPSessions[iSess].fromHost = pBuf; - } - - pTCPSessions[iSess].sock = newConn; - pTCPSessions[iSess].iMsg = 0; /* init msg buffer! */ - return iSess; + state = recv(pSess->sock, buf, lenBuf, 0); + return state; } - -/* This should be called before a normal (non forced) close - * of a TCP session. This function checks if there is any unprocessed - * message left in the TCP stream. Such a message is probably a - * fragement. If evrything goes well, we must be right at the - * beginnig of a new frame without any data received from it. If - * not, there is some kind of a framing error. I think I remember that - * some legacy syslog/TCP implementations have non-LF terminated - * messages at the end of the stream. For now, we allow this behaviour. - * Later, it should probably become a configuration option. - * rgerhards, 2006-12-07 - */ -void TCPSessPrepareClose(int iTCPSess) +static rsRetVal +onRegularClose(tcps_sess_t *pSess) { - if(iTCPSess < 0 || iTCPSess > iTCPSessMax) { - errno = 0; - logerror("internal error, trying to close an invalid TCP session!"); - return; - } - - if(pTCPSessions[iTCPSess].bAtStrtOfFram == 1) { - /* this is how it should be. There is no unprocessed - * data left and such we have nothing to do. For simplicity - * reasons, we immediately return in that case. - */ - return; - } - - /* we have some data left! */ - if(pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_COUNTING) { - /* In this case, we have an invalid frame count and thus - * generate an error message and discard the frame. - */ - logerrorInt("Incomplete frame at end of stream in session %d - " - "ignoring extra data (a message may be lost).\n", - pTCPSessions[iTCPSess].sock); - /* nothing more to do */ - } else { /* here, we have traditional framing. Missing LF at the end - * of message may occur. As such, we process the message in - * this case. - */ - dbgprintf("Extra data at end of stream in legacy syslog/tcp message - processing\n"); - parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pTCPSessions[iTCPSess].msg, - pTCPSessions[iTCPSess].iMsg, MSG_PARSE_HOSTNAME); - pTCPSessions[iTCPSess].bAtStrtOfFram = 1; - } + DEFiRet; + assert(pSess != NULL); + + /* process any incomplete frames left over */ + tcps_sess.PrepareClose(pSess); + /* Session closed */ + tcps_sess.Close(pSess); + RETiRet; } -/* Closes a TCP session and marks its slot in the session - * table as unused. No attention is paid to the return code - * of close, so potential-double closes are not detected. - */ -void TCPSessClose(int iSess) +static rsRetVal +onErrClose(tcps_sess_t *pSess) { - if(iSess < 0 || iSess > iTCPSessMax) { - errno = 0; - logerror("internal error, trying to close an invalid TCP session!"); - return; - } + DEFiRet; + assert(pSess != NULL); - close(pTCPSessions[iSess].sock); - pTCPSessions[iSess].sock = -1; - free(pTCPSessions[iSess].fromHost); - pTCPSessions[iSess].fromHost = NULL; /* not really needed, but... */ + tcps_sess.Close(pSess); + RETiRet; } +/* ------------------------------ end callbacks ------------------------------ */ -/* Processes the data received via a TCP session. If there - * is no other way to handle it, data is discarded. - * Input parameter data is the data received, iLen is its - * len as returned from recv(). iLen must be 1 or more (that - * is errors must be handled by caller!). iTCPSess must be - * the index of the TCP session that received the data. - * rgerhards 2005-07-04 - * Changed this functions interface. We now return a status of - * what shall happen with the session. This is information for - * the caller. If 1 is returned, the session should remain open - * and additional data be accepted. If we return 0, the TCP - * session is to be closed by the caller. This functionality is - * needed in order to support framing errors, from which there - * is no recovery possible other than session termination and - * re-establishment. The need for this functionality thus is - * primarily rooted in support for -transport-tls I-D framing. - * rgerhards, 2006-12-07 - */ -int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen) -{ - register int iMsg; - char *pMsg; - char *pEnd; - assert(pData != NULL); - assert(iLen > 0); - assert(iTCPSess >= 0); - assert(iTCPSess < iTCPSessMax); - assert(pTCPSessions[iTCPSess].sock != -1); - - /* We now copy the message to the session buffer. As - * it looks, we need to do this in any case because - * we might run into multiple messages inside a single - * buffer. Of course, we could think about optimizations, - * but as this code is to be replaced by liblogging, it - * probably doesn't make so much sense... - * rgerhards 2005-07-04 - * - * Algo: - * - copy message to buffer until the first LF is found - * - printline() the buffer - * - continue with copying - */ - iMsg = pTCPSessions[iTCPSess].iMsg; /* copy for speed */ - pMsg = pTCPSessions[iTCPSess].msg; /* just a shortcut */ - pEnd = pData + iLen; /* this is one off, which is intensional */ - - while(pData < pEnd) { - /* Check if we are at a new frame */ - if(pTCPSessions[iTCPSess].bAtStrtOfFram) { - /* we need to look at the message and detect - * the framing mode used - *//* - * Contrary to -transport-tls, we accept leading zeros in the message - * length. We do this in the spirit of "Be liberal in what you accept, - * and conservative in what you send". We expect that including leading - * zeros could be a common coding error. - * rgerhards, 2006-12-07 - * The chairs of the IETF syslog-sec WG have announced that it is - * consensus to do the octet count on the SYSLOG-MSG part only. I am - * now changing the code to reflect this. Hopefully, it will not change - * once again (there can no compatibility layer programmed for this). - * To be on the save side, I just comment the code out. I mark these - * comments with "IETF20061218". - * rgerhards, 2006-12-19 - */ - if(isdigit((int) *pData)) { - int iCnt; /* the frame count specified */ - pTCPSessions[iTCPSess].eFraming = TCP_FRAMING_OCTET_COUNTING; - /* in this mode, we have OCTET-COUNT SP MSG - so we now need - * to extract the OCTET-COUNT and the SP and then extract - * the msg. - */ - iCnt = 0; - /* IETF20061218 int iNbrOctets = 0; / * number of octets already consumed */ - while(isdigit((int) *pData)) { - iCnt = iCnt * 10 + *pData - '0'; - /* IETF20061218 ++iNbrOctets; */ - ++pData; - } - dbgprintf("TCP Message with octet-counter, size %d.\n", iCnt); - if(*pData == ' ') { - ++pData; /* skip over SP */ - /* IETF20061218 ++iNbrOctets; */ - } else { - /* TODO: handle "invalid frame" case */ - logerrorInt("Framing Error in received TCP message: " - "delimiter is not SP but has ASCII value %d.\n", - *pData); - return(0); /* unconditional error exit */ - } - /* IETF20061218 pTCPSessions[iTCPSess].iOctetsRemain = iCnt - iNbrOctets; */ - pTCPSessions[iTCPSess].iOctetsRemain = iCnt; - if(pTCPSessions[iTCPSess].iOctetsRemain < 1) { - /* TODO: handle the case where the octet count is 0 or negative! */ - dbgprintf("Framing Error: invalid octet count\n"); - logerrorInt("Framing Error in received TCP message: " - "invalid octet count %d.\n", - pTCPSessions[iTCPSess].iOctetsRemain); - return(0); /* unconditional error exit */ - } - } else { - pTCPSessions[iTCPSess].eFraming = TCP_FRAMING_OCTET_STUFFING; - /* No need to do anything else here in this case */ - } - pTCPSessions[iTCPSess].bAtStrtOfFram = 0; /* done frame header */ - } - - /* now copy message until end of record */ - - if(iMsg >= MAXLINE) { - /* emergency, we now need to flush, no matter if - * we are at end of message or not... - */ - parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); - iMsg = 0; - /* we might think if it is better to ignore the rest of the - * message than to treat it as a new one. Maybe this is a good - * candidate for a configuration parameter... - * rgerhards, 2006-12-04 - */ - } - - if(*pData == '\n' && - pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_STUFFING) { /* record delemiter? */ - parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); - iMsg = 0; - pTCPSessions[iTCPSess].bAtStrtOfFram = 1; - ++pData; - } else { - /* IMPORTANT: here we copy the actual frame content to the message! */ - *(pMsg + iMsg++) = *pData++; - } - - if(pTCPSessions[iTCPSess].eFraming == TCP_FRAMING_OCTET_COUNTING) { - /* do we need to find end-of-frame via octet counting? */ - pTCPSessions[iTCPSess].iOctetsRemain--; - if(pTCPSessions[iTCPSess].iOctetsRemain < 1) { - /* we have end of frame! */ - parseAndSubmitMessage(pTCPSessions[iTCPSess].fromHost, pMsg, iMsg, MSG_PARSE_HOSTNAME); - iMsg = 0; - pTCPSessions[iTCPSess].bAtStrtOfFram = 1; - } - } - } - - pTCPSessions[iTCPSess].iMsg = iMsg; /* persist value */ - return(1); /* successful return */ -} - - -#ifndef USE_GSSAPI static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) { - if (!bEnableTCP) - configureTCPListen((char *) pNewVal); - bEnableTCP |= ALLOWEDMETHOD_TCP; - - return RS_RET_OK; + DEFiRet; + if(pOurTcpsrv == NULL) { + CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); + /* TODO: fill params! */ + CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); + CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); + //CHKiRet(tcpsrv.SetCBOnListenDeinit(pOurTcpsrv, )); + CHKiRet(tcpsrv.SetCBOnSessAccept(pOurTcpsrv, onSessAccept)); + CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); + CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); + tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal); + CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); + } + +finalize_it: + RETiRet; } -#endif /* This function is called to gather input. */ BEGINrunInput - int maxfds; - int nfds; - int i; - int iTCPSess; - fd_set readfds; CODESTARTrunInput - /* this is an endless loop - it is terminated when the thread is - * signalled to do so. This, however, is handled by the framework, - * right into the sleep below. + /* TODO: we must be careful to start the listener here. Currently, tcpsrv.c seems to + * do that in ConstructFinalize */ - while(1) { - /* Add the Unix Domain Sockets to the list of read - * descriptors. - * rgerhards 2005-08-01: we must now check if there are - * any local sockets to listen to at all. If the -o option - * is given without -a, we do not need to listen at all.. - */ - maxfds = 0; - FD_ZERO (&readfds); - - /* Add the TCP listen sockets to the list of read descriptors. - */ - if(sockTCPLstn != NULL && *sockTCPLstn) { - for (i = 0; i < *sockTCPLstn; i++) { - /* The if() below is theoretically not needed, but I leave it in - * so that a socket may become unsuable during execution. That - * feature is not yet supported by the current code base. - */ - if (sockTCPLstn[i+1] != -1) { - if(Debug) - debugListenInfo(sockTCPLstn[i+1], "TCP"); - FD_SET(sockTCPLstn[i+1], &readfds); - if(sockTCPLstn[i+1]>maxfds) maxfds=sockTCPLstn[i+1]; - } - } - /* do the sessions */ - iTCPSess = TCPSessGetNxtSess(-1); - while(iTCPSess != -1) { - int fdSess; - fdSess = pTCPSessions[iTCPSess].sock; - dbgprintf("Adding TCP Session %d\n", fdSess); - FD_SET(fdSess, &readfds); - if (fdSess>maxfds) maxfds=fdSess; - /* now get next... */ - iTCPSess = TCPSessGetNxtSess(iTCPSess); - } - } - - if(Debug) { - dbgprintf("--------imTCP calling select, active file descriptors (max %d): ", maxfds); - for (nfds = 0; nfds <= maxfds; ++nfds) - if ( FD_ISSET(nfds, &readfds) ) - dbgprintf("%d ", nfds); - dbgprintf("\n"); - } - - /* wait for io to become ready */ - nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL); - - for (i = 0; i < *sockTCPLstn; i++) { - if (FD_ISSET(sockTCPLstn[i+1], &readfds)) { - dbgprintf("New connect on TCP inetd socket: #%d\n", sockTCPLstn[i+1]); -# ifdef USE_GSSAPI - if(bEnableTCP & ALLOWEDMETHOD_GSS) - TCPSessGSSAccept(sockTCPLstn[i+1]); - else -# endif - TCPSessAccept(sockTCPLstn[i+1]); - --nfds; /* indicate we have processed one */ - } - } - - /* now check the sessions */ - iTCPSess = TCPSessGetNxtSess(-1); - while(nfds && iTCPSess != -1) { - int fdSess; - int state; - fdSess = pTCPSessions[iTCPSess].sock; - if(FD_ISSET(fdSess, &readfds)) { - char buf[MAXLINE]; - dbgprintf("tcp session socket with new data: #%d\n", fdSess); - - /* Receive message */ -# ifdef USE_GSSAPI - int allowedMethods = pTCPSessions[iTCPSess].allowedMethods; - if(allowedMethods & ALLOWEDMETHOD_GSS) - state = TCPSessGSSRecv(iTCPSess, buf, sizeof(buf)); - else -# endif - state = recv(fdSess, buf, sizeof(buf), 0); - if(state == 0) { -# ifdef USE_GSSAPI - if(allowedMethods & ALLOWEDMETHOD_GSS) - TCPSessGSSClose(iTCPSess); - else { -# endif - /* process any incomplete frames left over */ - TCPSessPrepareClose(iTCPSess); - /* Session closed */ - TCPSessClose(iTCPSess); -# ifdef USE_GSSAPI - } -# endif - } else if(state == -1) { - logerrorInt("TCP session %d will be closed, error ignored\n", - fdSess); -# ifdef USE_GSSAPI - if(allowedMethods & ALLOWEDMETHOD_GSS) - TCPSessGSSClose(iTCPSess); - else -# endif - TCPSessClose(iTCPSess); - } else { - /* valid data received, process it! */ - if(TCPSessDataRcvd(iTCPSess, buf, state) == 0) { - /* in this case, something went awfully wrong. - * We are instructed to terminate the session. - */ - logerrorInt("Tearing down TCP Session %d - see " - "previous messages for reason(s)\n", - iTCPSess); -# ifdef USE_GSSAPI - if(allowedMethods & ALLOWEDMETHOD_GSS) - TCPSessGSSClose(iTCPSess); - else -# endif - TCPSessClose(iTCPSess); - } - } - --nfds; /* indicate we have processed one */ - } - iTCPSess = TCPSessGetNxtSess(iTCPSess); - } - } - + iRet = tcpsrv.Run(pOurTcpsrv); return iRet; ENDrunInput @@ -909,35 +156,11 @@ ENDrunInput /* initialize and return if will run or not */ BEGINwillRun CODESTARTwillRun -#ifdef USE_GSSAPI - /* first check if we must support plain TCP, too. If so, set mode - * accordingly. -- rgerhards, 2008-02-26 - */ - if(bPermitPlainTcp) - bEnableTCP |= ALLOWEDMETHOD_TCP; - /* first apply some config settings */ -#endif PrintAllowedSenders(2); /* TCP */ -#ifdef USE_GSSAPI - PrintAllowedSenders(3); /* GSS */ -#endif - if (bEnableTCP) { - if(sockTCPLstn == NULL) { -# ifdef USE_GSSAPI - if(bEnableTCP & ALLOWEDMETHOD_GSS) { - if(TCPSessGSSInit()) { - logerror("GSS-API initialization failed\n"); - bEnableTCP &= ~(ALLOWEDMETHOD_GSS); - } - } - if(bEnableTCP) -# endif - if((sockTCPLstn = create_tcp_socket()) != NULL) { - dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn); - } - } - } + if(pOurTcpsrv == NULL) + ABORT_FINALIZE(RS_RET_NO_RUN); +finalize_it: ENDwillRun @@ -948,14 +171,27 @@ CODESTARTafterRun clearAllowedSenders (pAllowedSenders_TCP); pAllowedSenders_TCP = NULL; } -#ifdef USE_GSSAPI - if (pAllowedSenders_GSS != NULL) { - clearAllowedSenders (pAllowedSenders_GSS); - pAllowedSenders_GSS = NULL; - } -#endif ENDafterRun +BEGINmodExit +CODESTARTmodExit + iRet = tcpsrv.Destruct(&pOurTcpsrv); +#if 0 // TODO: remove + /* Close the TCP inet socket. */ + if(sockTCPLstn != NULL && *sockTCPLstn) { + deinit_tcp_listener(); + } +#endif +ENDmodExit + + +static rsRetVal +resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + iTCPSessMax = 200; + return RS_RET_OK; +} + BEGINfreeInstance CODESTARTfreeInstance @@ -967,36 +203,22 @@ CODESTARTdbgPrintInstInfo ENDdbgPrintInstInfo -BEGINmodExit -CODESTARTmodExit - /* Close the TCP inet socket. */ - if(sockTCPLstn != NULL && *sockTCPLstn) { - deinit_tcp_listener(); - } -#ifdef USE_GSSAPI - if(bEnableTCP & ALLOWEDMETHOD_GSS) - TCPSessGSSDeinit(); -#endif -ENDmodExit - - BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES ENDqueryEtryPt -#ifndef USE_GSSAPI -static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) -{ - return RS_RET_OK; -} - - BEGINmodInit() CODESTARTmodInit *ipIFVersProvided = 1; /* so far, we only support the initial definition */ CODEmodInit_QueryRegCFSLineHdlr + pOurTcpsrv = NULL; + /* request objects we use */ +CHKiRet(objGetObjInterface(&obj)); /* get ourselves ;) */ // TODO: framework must do this + CHKiRet(objUse(tcps_sess, "tcps_sess")); + CHKiRet(objUse(tcpsrv, "tcpsrv")); + /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); @@ -1005,7 +227,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -#endif + /* vim:set ai: */ -- cgit v1.2.3 From 42730360196f1aaafaebb955c1a0a66a185e61ec Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 3 Mar 2008 09:04:59 +0000 Subject: made imgssapi compile --- plugins/imtcp/imtcp.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 9ad85044..efdc3e9c 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -62,28 +62,35 @@ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change fo /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ -static char *TCPLstnPort = "0"; /* read-only after startup */ /* callbacks */ /* this shall go into a specific ACL module! */ static int -isPermittedHost(struct sockaddr *addr, char *fromHostFQDN) +isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, + void __attribute__((unused)) *pUsrSess) { return isAllowedSender(pAllowedSenders_TCP, addr, fromHostFQDN); } static rsRetVal -onSessAccept(tcpsrv_t *pThis, int fd) +onSessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd) { DEFiRet; - - tcpsrv.SessAccept(pThis, fd); + tcpsrv.SessAccept(pThis, ppSess, fd); RETiRet; } +static int* +doOpenLstnSocks(tcpsrv_t *pSrv) +{ + ISOBJ_TYPE_assert(pSrv, tcpsrv); + return tcpsrv.create_tcp_socket(pSrv); +} + + static int doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf) { @@ -129,6 +136,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa /* TODO: fill params! */ CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); + CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); //CHKiRet(tcpsrv.SetCBOnListenDeinit(pOurTcpsrv, )); CHKiRet(tcpsrv.SetCBOnSessAccept(pOurTcpsrv, onSessAccept)); CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); @@ -149,7 +157,6 @@ CODESTARTrunInput * do that in ConstructFinalize */ iRet = tcpsrv.Run(pOurTcpsrv); - return iRet; ENDrunInput @@ -173,6 +180,7 @@ CODESTARTafterRun } ENDafterRun + BEGINmodExit CODESTARTmodExit iRet = tcpsrv.Destruct(&pOurTcpsrv); -- cgit v1.2.3 From cb71628f67e12081db2449eff83667e2a832f495 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 3 Mar 2008 12:40:04 +0000 Subject: fixed newly introduced bugs in imgssapi and imtcp and their helpers now plain tcp works again --- plugins/imtcp/imtcp.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index efdc3e9c..9ef186b4 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -78,7 +78,7 @@ static rsRetVal onSessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd) { DEFiRet; - tcpsrv.SessAccept(pThis, ppSess, fd); + iRet = tcpsrv.SessAccept(pThis, ppSess, fd); RETiRet; } @@ -183,13 +183,8 @@ ENDafterRun BEGINmodExit CODESTARTmodExit - iRet = tcpsrv.Destruct(&pOurTcpsrv); -#if 0 // TODO: remove - /* Close the TCP inet socket. */ - if(sockTCPLstn != NULL && *sockTCPLstn) { - deinit_tcp_listener(); - } -#endif + if(pOurTcpsrv != NULL) + iRet = tcpsrv.Destruct(&pOurTcpsrv); ENDmodExit -- cgit v1.2.3 From bc7d8ccebb0a9e7726a9c85cb10746d7407c28d8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 4 Mar 2008 10:27:45 +0000 Subject: - changed module interface to support querying obj interface (stage work) - changed module interface version, as the interface change is quite large --- plugins/imtcp/imtcp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 9ef186b4..9ea0863c 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -49,7 +49,6 @@ MODULE_TYPE_INPUT /* static data */ DEF_IMOD_STATIC_DATA -DEFobjCurrIf(obj) DEFobjCurrIf(tcpsrv) DEFobjCurrIf(tcps_sess) @@ -214,11 +213,10 @@ ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit - *ipIFVersProvided = 1; /* so far, we only support the initial definition */ + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ -CHKiRet(objGetObjInterface(&obj)); /* get ourselves ;) */ // TODO: framework must do this CHKiRet(objUse(tcps_sess, "tcps_sess")); CHKiRet(objUse(tcpsrv, "tcpsrv")); -- cgit v1.2.3 From 545346e697fe930b8b7b9bd0ede47890b26a4832 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 5 Mar 2008 10:30:06 +0000 Subject: - changed modules.c calling conventions to be interface-based - moved module loader from conf.c to module.c, where it belongs - made the necessary plumbing to auto-load library modules - upgraded debug system to include iRet in function exit message - changed module interface so that instances need only to be supported by output plugins (if we actually need them for input plugins, we can always add it again...) - milestone: first implementation of library modules (but do not get unloaded on exit/hup so far) --- plugins/imtcp/imtcp.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 9ea0863c..fea79d49 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -53,10 +53,6 @@ DEFobjCurrIf(tcpsrv) DEFobjCurrIf(tcps_sess) /* Module static data */ - -typedef struct _instanceData { -} instanceData; - static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ /* config settings */ @@ -195,15 +191,6 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus } -BEGINfreeInstance -CODESTARTfreeInstance -ENDfreeInstance - - -BEGINdbgPrintInstInfo -CODESTARTdbgPrintInstInfo -ENDdbgPrintInstInfo - BEGINqueryEtryPt CODESTARTqueryEtryPt @@ -217,7 +204,7 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ - CHKiRet(objUse(tcps_sess, "tcps_sess")); + CHKiRet(objUse(tcps_sess, "tcpsrv.so")); CHKiRet(objUse(tcpsrv, "tcpsrv")); /* register config file handlers */ -- cgit v1.2.3 From f9105d514134152094dfd02cab5113650dc53f76 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 5 Mar 2008 16:55:13 +0000 Subject: changed module loader to automatically add ".so" suffix if not specified (over time, this shall also ease portability of config files) --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index fea79d49..ca52d3c5 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -204,7 +204,7 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ - CHKiRet(objUse(tcps_sess, "tcpsrv.so")); + CHKiRet(objUse(tcps_sess, "tcpsrv")); CHKiRet(objUse(tcpsrv, "tcpsrv")); /* register config file handlers */ -- cgit v1.2.3 From fa67273c1644551b50919fa7879acfdc92e269bc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 7 Mar 2008 08:06:16 +0000 Subject: - added RSYSLOGD_MODDIR environment variable - added -M rsyslogd option (allows to specify module directory location) - converted net.c into a loadable library plugin --- plugins/imtcp/imtcp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index ca52d3c5..2da094a4 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -51,6 +51,7 @@ MODULE_TYPE_INPUT DEF_IMOD_STATIC_DATA DEFobjCurrIf(tcpsrv) DEFobjCurrIf(tcps_sess) +DEFobjCurrIf(net) /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ @@ -65,7 +66,7 @@ static int isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess) { - return isAllowedSender(pAllowedSenders_TCP, addr, fromHostFQDN); + return isAllowedSender(net.pAllowedSenders_TCP, addr, fromHostFQDN); } @@ -159,7 +160,7 @@ ENDrunInput BEGINwillRun CODESTARTwillRun /* first apply some config settings */ - PrintAllowedSenders(2); /* TCP */ + net.PrintAllowedSenders(2); /* TCP */ if(pOurTcpsrv == NULL) ABORT_FINALIZE(RS_RET_NO_RUN); finalize_it: @@ -169,9 +170,9 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ - if (pAllowedSenders_TCP != NULL) { - clearAllowedSenders (pAllowedSenders_TCP); - pAllowedSenders_TCP = NULL; + if(net.pAllowedSenders_TCP != NULL) { + net.clearAllowedSenders(net.pAllowedSenders_TCP); + net.pAllowedSenders_TCP = NULL; } ENDafterRun @@ -204,6 +205,7 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ + CHKiRet(objUse(net, "net")); CHKiRet(objUse(tcps_sess, "tcpsrv")); CHKiRet(objUse(tcpsrv, "tcpsrv")); -- cgit v1.2.3 From 4db62823e7a8e41e829c08a461f5e6b2193a6d62 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 7 Mar 2008 17:26:58 +0000 Subject: renamed library module file names to lm*, so that they match the overall scheme (like im* and om*) --- plugins/imtcp/imtcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 2da094a4..d58c6f56 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -205,9 +205,9 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ - CHKiRet(objUse(net, "net")); - CHKiRet(objUse(tcps_sess, "tcpsrv")); - CHKiRet(objUse(tcpsrv, "tcpsrv")); + CHKiRet(objUse(net, LM_NET_FILENAME)); + CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME)); + CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME)); /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, -- cgit v1.2.3 From e946e122d02987552874595f2613c07ce0c0aa23 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 11 Mar 2008 16:43:13 +0000 Subject: implemented module unload handling (required a number of interface changes) --- plugins/imtcp/imtcp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d58c6f56..d4ac9cb6 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -66,7 +66,7 @@ static int isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess) { - return isAllowedSender(net.pAllowedSenders_TCP, addr, fromHostFQDN); + return net.isAllowedSender(net.pAllowedSenders_TCP, addr, fromHostFQDN); } @@ -181,6 +181,11 @@ BEGINmodExit CODESTARTmodExit if(pOurTcpsrv != NULL) iRet = tcpsrv.Destruct(&pOurTcpsrv); + + /* release objects we used */ + objRelease(net, LM_NET_FILENAME); + objRelease(tcps_sess, LM_TCPSRV_FILENAME); + objRelease(tcpsrv, LM_TCPSRV_FILENAME); ENDmodExit -- cgit v1.2.3 From 618a7f6a220563a50909d0e15eb90ce222aced31 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 12 Mar 2008 14:08:21 +0000 Subject: changed omgssapi and omfwd to utilize new object calling interface; made a tcpclt class; (stage work, among others, for more intelligent recovery from TCP session recovery) --- plugins/imtcp/imtcp.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d4ac9cb6..ed0131b8 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -129,11 +129,9 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa DEFiRet; if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); - /* TODO: fill params! */ CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); - //CHKiRet(tcpsrv.SetCBOnListenDeinit(pOurTcpsrv, )); CHKiRet(tcpsrv.SetCBOnSessAccept(pOurTcpsrv, onSessAccept)); CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); -- cgit v1.2.3 From 17f36a76cbf15e088d2973ed5608f93e09827f8a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 13 Mar 2008 11:04:33 +0000 Subject: bugfix: imgssapi segfaulted under some conditions; this fix is actually not just a fix but a change in the object model. Thanks to varmojfekoj for providing the bug report, an initial fix and lots of good discussion that lead to where we finally ended up. --- plugins/imtcp/imtcp.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index ed0131b8..7baa95f2 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -70,15 +70,6 @@ isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((u } -static rsRetVal -onSessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd) -{ - DEFiRet; - iRet = tcpsrv.SessAccept(pThis, ppSess, fd); - RETiRet; -} - - static int* doOpenLstnSocks(tcpsrv_t *pSrv) { @@ -132,7 +123,6 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); - CHKiRet(tcpsrv.SetCBOnSessAccept(pOurTcpsrv, onSessAccept)); CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal); -- cgit v1.2.3 From d9b0c77d3e719d4c08361e62f3b067228c30f6a9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Apr 2008 15:27:53 +0200 Subject: some more cleanup reduced dependencies, moved non-runtime files to its own directory except for some whom's status is unclear --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 7baa95f2..b7f8f0b5 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -39,7 +39,7 @@ #include #endif #include "rsyslog.h" -#include "syslogd.h" +#include "dirty.h" #include "cfsysline.h" #include "module-template.h" #include "net.h" -- cgit v1.2.3 From 1892fc75f9fad0b0741b4a3eb1fc382f900b2301 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Apr 2008 15:07:19 +0200 Subject: added new netstrms class netstrms is at the top layer of the socket abstraction --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index b7f8f0b5..17a48d17 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -70,7 +70,7 @@ isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((u } -static int* +static rsRetVal doOpenLstnSocks(tcpsrv_t *pSrv) { ISOBJ_TYPE_assert(pSrv, tcpsrv); -- cgit v1.2.3 From 721b9ee252143d182c3c145380e5dbec8c3b0102 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 23 Apr 2008 17:48:13 +0200 Subject: client functionality works again (with the new socket abstraction) --- plugins/imtcp/imtcp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 17a48d17..1e599d14 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -43,6 +43,7 @@ #include "cfsysline.h" #include "module-template.h" #include "net.h" +#include "netstrm.h" #include "tcpsrv.h" MODULE_TYPE_INPUT @@ -52,6 +53,7 @@ DEF_IMOD_STATIC_DATA DEFobjCurrIf(tcpsrv) DEFobjCurrIf(tcps_sess) DEFobjCurrIf(net) +DEFobjCurrIf(netstrm) /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ @@ -81,10 +83,12 @@ doOpenLstnSocks(tcpsrv_t *pSrv) static int doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf) { - int state; + ssize_t state; assert(pSess != NULL); - state = recv(pSess->sock, buf, lenBuf, 0); + state = lenBuf; + if(netstrm.Rcv(pSess->pStrm, (uchar*) buf, &state) != RS_RET_OK) + state = -1; // TODO: move this function to an iRet interface! 2008-04-23 return state; } @@ -172,6 +176,7 @@ CODESTARTmodExit /* release objects we used */ objRelease(net, LM_NET_FILENAME); + objRelease(netstrm, LM_NETSTRM_FILENAME); objRelease(tcps_sess, LM_TCPSRV_FILENAME); objRelease(tcpsrv, LM_TCPSRV_FILENAME); ENDmodExit @@ -199,6 +204,7 @@ CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ CHKiRet(objUse(net, LM_NET_FILENAME)); + CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME)); CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME)); CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME)); -- cgit v1.2.3 From 055d4ffc2afc77e03a3d31720d4a0998f8c3d92c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 29 Apr 2008 15:36:22 +0200 Subject: fixed problem with module unload sequence --- plugins/imtcp/imtcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 1e599d14..bb5f4fe5 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -176,7 +176,7 @@ CODESTARTmodExit /* release objects we used */ objRelease(net, LM_NET_FILENAME); - objRelease(netstrm, LM_NETSTRM_FILENAME); + objRelease(netstrm, LM_NETSTRMS_FILENAME); objRelease(tcps_sess, LM_TCPSRV_FILENAME); objRelease(tcpsrv, LM_TCPSRV_FILENAME); ENDmodExit @@ -204,7 +204,7 @@ CODEmodInit_QueryRegCFSLineHdlr pOurTcpsrv = NULL; /* request objects we use */ CHKiRet(objUse(net, LM_NET_FILENAME)); - CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME)); + CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME)); CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME)); -- cgit v1.2.3 From b0d63ea8f26f525bbfd177aaa6a1294b0d94f1f9 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 30 Apr 2008 14:51:45 +0200 Subject: made plain tcp syslog via TLS work on the server ... but so far only in blocking mode --- plugins/imtcp/imtcp.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index bb5f4fe5..a9924365 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -44,6 +44,7 @@ #include "module-template.h" #include "net.h" #include "netstrm.h" +#include "errmsg.h" #include "tcpsrv.h" MODULE_TYPE_INPUT @@ -54,6 +55,7 @@ DEFobjCurrIf(tcpsrv) DEFobjCurrIf(tcps_sess) DEFobjCurrIf(net) DEFobjCurrIf(netstrm) +DEFobjCurrIf(errmsg) /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ @@ -134,6 +136,11 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa } finalize_it: + if(iRet != RS_RET_OK) { + errmsg.LogError(NO_ERRCODE, "error %d trying to add listener", iRet); + if(pOurTcpsrv != NULL) + tcpsrv.Destruct(&pOurTcpsrv); + } RETiRet; } @@ -179,6 +186,7 @@ CODESTARTmodExit objRelease(netstrm, LM_NETSTRMS_FILENAME); objRelease(tcps_sess, LM_TCPSRV_FILENAME); objRelease(tcpsrv, LM_TCPSRV_FILENAME); + objRelease(errmsg, CORE_COMPONENT); ENDmodExit @@ -207,6 +215,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME)); CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME)); + CHKiRet(objUse(errmsg, CORE_COMPONENT)); /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, -- cgit v1.2.3 From da889001432c7a9242d8a6ef947fe6887dc366f3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 30 Apr 2008 18:53:21 +0200 Subject: added $InputTCPServerStreamDriverMode config directive --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index a9924365..1bf30493 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -62,6 +62,7 @@ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change fo /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ +static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ /* callbacks */ @@ -131,6 +132,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); + CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal); CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); } @@ -194,6 +196,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + iStrmDrvrMode = 0; return RS_RET_OK; } @@ -222,6 +225,8 @@ CODEmodInit_QueryRegCFSLineHdlr addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); + CHKiRet(regCfSysLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0, + eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From d2b63414ef92cde8a3107b8d17b74b1518775df6 Mon Sep 17 00:00:00 2001 From: varmojfekoj Date: Wed, 14 May 2008 08:32:40 +0200 Subject: fixed potential segfault due to invalid call to cfsysline thanks to varmojfekoj for the patch Signed-off-by: Rainer Gerhards --- plugins/imtcp/imtcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 1bf30493..971d3aec 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -225,8 +225,8 @@ CODEmodInit_QueryRegCFSLineHdlr addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); - CHKiRet(regCfSysLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0, - eCmdHdlrInt, NULL, &iStrmDrvrMode, NULL)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0, + eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 85b587f93d7f1294fae78317c0841a30aaa03583 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 19 May 2008 18:52:44 +0200 Subject: first implementation of TLS server client authentication check The TLS server now checks the client fingerprint. This works, but is highly experimental. Needs to be refined for practice. Also: - implemented permittedPeers helper construct to store names - changed omfwd implementation to use new permittedPeers --- plugins/imtcp/imtcp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 971d3aec..d8363151 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -23,6 +23,20 @@ * A copy of the GPL can be found in the file "COPYING" in this distribution. */ +/* This note shall explain the calling sequence while we do not have + * have full RainerScript support for (TLS) sender authentication: + * + * imtcp --> tcpsrv --> netstrms (this sequence stored pPermPeers in netstrms class) + * then a callback (doOpenLstnSocks) into imtcp happens, which in turn calls + * into tcpsrv.create_tcp_socket(), + * which calls into netstrm.LstnInit(), which receives a pointer to netstrms obj + * which calls into the driver function LstnInit (again, netstrms obj passed) + * which finally calls back into netstrms obj's get functions to obtain the auth + * parameters and then applies them to the driver object instance + * + * rgerhards, 2008-05-19 + */ + #include "config.h" #include #include @@ -46,6 +60,7 @@ #include "netstrm.h" #include "errmsg.h" #include "tcpsrv.h" +#include "net.h" /* for permittedPeers, may be removed when this is removed */ MODULE_TYPE_INPUT @@ -59,10 +74,13 @@ DEFobjCurrIf(errmsg) /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ +static permittedPeers_t *pPermPeersRoot = NULL; + /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ +static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ /* callbacks */ @@ -122,9 +140,22 @@ onErrClose(tcps_sess_t *pSess) /* ------------------------------ end callbacks ------------------------------ */ +/* set permitted peer -- rgerhards, 2008-05-19 + */ +static rsRetVal +setPermittedPeer(void __attribute__((unused)) *pVal, uchar *pszID) +{ + DEFiRet; + CHKiRet(net.AddPermittedPeer(&pPermPeersRoot, pszID)); +finalize_it: + RETiRet; +} + + static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) { DEFiRet; + if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); @@ -133,6 +164,15 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); + /* now set optional params, but only if they were actually configured */ + if(pszStrmDrvrAuthMode != NULL) { +RUNLOG_VAR("%s", pszStrmDrvrAuthMode); + CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode)); + } + if(pPermPeersRoot != NULL) { + CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot)); + } + /* most params set, now start listener */ tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal); CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); } @@ -183,6 +223,10 @@ CODESTARTmodExit if(pOurTcpsrv != NULL) iRet = tcpsrv.Destruct(&pOurTcpsrv); + if(pPermPeersRoot != NULL) { + net.DestructPermittedPeers(&pPermPeersRoot); + } + /* release objects we used */ objRelease(net, LM_NET_FILENAME); objRelease(netstrm, LM_NETSTRMS_FILENAME); @@ -227,6 +271,10 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverauthmode", 0, + eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverpermittedpeer", 0, + eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 99e97dadf1d03c9db33d49e91b26ceb28a39ed1a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 4 Jun 2008 09:37:10 +0200 Subject: bugfix: removed some memory leaks in TLS code --- plugins/imtcp/imtcp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d8363151..d50d80e9 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -147,6 +147,7 @@ setPermittedPeer(void __attribute__((unused)) *pVal, uchar *pszID) { DEFiRet; CHKiRet(net.AddPermittedPeer(&pPermPeersRoot, pszID)); + free(pszID); /* no longer needed, but we need to free as of interface def */ finalize_it: RETiRet; } -- cgit v1.2.3 From 7b1a570d54ac4c82325aeeee70d7a8871ecd688a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 23 Jun 2008 10:29:15 +0200 Subject: changed Rcv-Interface in tcpsrv subsystem It is now iRet based. This enables us to communicate more in-depth information to the upper peers. This is needed to handle the EGAIN case on rcv (not yet implemented) --- plugins/imtcp/imtcp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d50d80e9..4d31744d 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -101,16 +101,17 @@ doOpenLstnSocks(tcpsrv_t *pSrv) } -static int -doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf) +static rsRetVal +doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd) { - ssize_t state; + DEFiRet; assert(pSess != NULL); + assert(piLenRcvd != NULL); - state = lenBuf; - if(netstrm.Rcv(pSess->pStrm, (uchar*) buf, &state) != RS_RET_OK) - state = -1; // TODO: move this function to an iRet interface! 2008-04-23 - return state; + *piLenRcvd = lenBuf; + CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd) != RS_RET_OK); +finalize_it: + RETiRet; } static rsRetVal @@ -167,7 +168,6 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); /* now set optional params, but only if they were actually configured */ if(pszStrmDrvrAuthMode != NULL) { -RUNLOG_VAR("%s", pszStrmDrvrAuthMode); CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode)); } if(pPermPeersRoot != NULL) { -- cgit v1.2.3 From 75063e54b2a95416c0fd32b2ae1df9b8db776b5c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 24 Jun 2008 18:27:52 +0200 Subject: bugfix: gtls und ptcp netstream driver communicated invalid iRet This was introduced due to recent interface change. --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 4d31744d..49d48633 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -109,7 +109,7 @@ doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd) assert(piLenRcvd != NULL); *piLenRcvd = lenBuf; - CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd) != RS_RET_OK); + CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd)); finalize_it: RETiRet; } -- cgit v1.2.3 From 3f6c73a8b7ff2c6d9c931876d823f2b4ef6bbea2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 27 Jun 2008 12:52:45 +0200 Subject: added (internal) error codes to error messages Also added redirector to web description of error codes closes bug http://bugzilla.adiscon.com/show_bug.cgi?id=20 --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 49d48633..f01a9f0f 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -180,7 +180,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa finalize_it: if(iRet != RS_RET_OK) { - errmsg.LogError(NO_ERRCODE, "error %d trying to add listener", iRet); + errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet); if(pOurTcpsrv != NULL) tcpsrv.Destruct(&pOurTcpsrv); } -- cgit v1.2.3 From f0ddbed44c332391ae6d9bbf6b07e2f06c4dd676 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 29 Nov 2008 07:22:48 +0100 Subject: security bugfix: $AllowedSender was not honored, ...all senders were permitted instead --- plugins/imtcp/imtcp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index f01a9f0f..8e7d2905 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -89,7 +89,7 @@ static int isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess) { - return net.isAllowedSender(net.pAllowedSenders_TCP, addr, fromHostFQDN); + return net.isAllowedSender((uchar*) "TCP", addr, fromHostFQDN); } @@ -212,10 +212,7 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ - if(net.pAllowedSenders_TCP != NULL) { - net.clearAllowedSenders(net.pAllowedSenders_TCP); - net.pAllowedSenders_TCP = NULL; - } + net.clearAllowedSenders((char*)"TCP"); ENDafterRun -- cgit v1.2.3 From 48799529955eff8eb3120b02a356a92a8bd9b2ae Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 29 Nov 2008 07:48:24 +0100 Subject: minor cleanup --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 8e7d2905..89f1dbcf 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -212,7 +212,7 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ - net.clearAllowedSenders((char*)"TCP"); + net.clearAllowedSenders((uchar*)"TCP"); ENDafterRun -- cgit v1.2.3 From bc471f1d9046bf75a2e27d593ce9b13e4094ffdc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 9 Apr 2009 13:36:44 +0200 Subject: bugfix: $InputTCPMaxSessions config directive was accepted, but not honored This resulted in a fixed upper limit of 200 connections. --- plugins/imtcp/imtcp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 89f1dbcf..7b3eeda5 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -160,6 +160,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); + CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax)); CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); -- cgit v1.2.3 From aba90e82484118f3568ec51c01de5ba845da589a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 22 May 2009 17:06:52 +0200 Subject: added capability to run multiple tcp listeners (on different ports) Well, actually this and a lot of related things. I improved the testbench so that the new capabilities are automatically tested and also did some general cleanup. The current multiple tcp listener solution will probably receive some further cleanup, too, but looks quite OK so far. I also reviewed the way tcpsrv et all work, in preparation of using this code for imdiag. I need to document the findings, especially as the code is rather complicated "thanks" to the combination of plain tcp and gssapi transport modes. --- plugins/imtcp/imtcp.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 5a8a62f6..f0efe1ee 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -3,7 +3,7 @@ * * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c) * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -56,6 +56,7 @@ #include "dirty.h" #include "cfsysline.h" #include "module-template.h" +#include "unicode-helper.h" #include "net.h" #include "netstrm.h" #include "errmsg.h" @@ -91,7 +92,7 @@ static int isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess) { - return net.isAllowedSender((uchar*) "TCP", addr, fromHostFQDN); + return net.isAllowedSender(UCHAR_CONSTANT("TCP"), addr, fromHostFQDN); } @@ -169,7 +170,6 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); - CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? (uchar*)"imtcp" : pszInputName)); CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); /* now set optional params, but only if they were actually configured */ if(pszStrmDrvrAuthMode != NULL) { @@ -178,11 +178,14 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa if(pPermPeersRoot != NULL) { CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot)); } - /* most params set, now start listener */ - tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal); - CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); } +dbgprintf("XXX: try add listen port %s\n", pNewVal); + /* initialized, now add socket */ + CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? + UCHAR_CONSTANT("imtcp") : pszInputName)); + tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + finalize_it: if(iRet != RS_RET_OK) { errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet); @@ -199,7 +202,9 @@ CODESTARTrunInput /* TODO: we must be careful to start the listener here. Currently, tcpsrv.c seems to * do that in ConstructFinalize */ + CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); iRet = tcpsrv.Run(pOurTcpsrv); +finalize_it: ENDrunInput @@ -217,7 +222,7 @@ ENDwillRun BEGINafterRun CODESTARTafterRun /* do cleanup here */ - net.clearAllowedSenders((uchar*)"TCP"); + net.clearAllowedSenders(UCHAR_CONSTANT("TCP")); ENDafterRun @@ -277,21 +282,21 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(errmsg, CORE_COMPONENT)); /* register config file handlers */ - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverauthmode", 0, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverpermittedpeer", 0, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserveraddtlframedelimiter", 0, eCmdHdlrInt, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverinputname", 0, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From a900a7c34b674573f4b86350af0d68838da6550a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 27 May 2009 11:29:47 +0200 Subject: greatly enhanced testbench The imdiag module now can very effectively inject messages, which also frees us from uncertainties of tcp reception and processing. All shell script based tests have been modularized, what makes it far easier to create new tests. Also, the test bench now executes more reliable and much faster, because we can now rely on actual engine information where we previously did just a dumb sleep. --- plugins/imtcp/imtcp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index f0efe1ee..84e660bc 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -180,7 +180,6 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa } } -dbgprintf("XXX: try add listen port %s\n", pNewVal); /* initialized, now add socket */ CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : pszInputName)); -- cgit v1.2.3 From ca0ddc30a3edce02a440904a01f0b866c0f82b5a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 12 Jun 2009 15:31:08 +0200 Subject: completed multi-ruleset core support ... as well as added multi-ruleset support for imtcp --- plugins/imtcp/imtcp.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 84e660bc..e1f513c8 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -61,6 +61,7 @@ #include "netstrm.h" #include "errmsg.h" #include "tcpsrv.h" +#include "ruleset.h" #include "net.h" /* for permittedPeers, may be removed when this is removed */ MODULE_TYPE_INPUT @@ -72,6 +73,7 @@ DEFobjCurrIf(tcps_sess) DEFobjCurrIf(net) DEFobjCurrIf(netstrm) DEFobjCurrIf(errmsg) +DEFobjCurrIf(ruleset) /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ @@ -84,6 +86,7 @@ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mos static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ +static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */ /* callbacks */ @@ -157,6 +160,27 @@ finalize_it: } +/* accept a new ruleset to bind. Checks if it exists and complains, if not */ +static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName) +{ + ruleset_t *pRuleset; + rsRetVal localRet; + DEFiRet; + + localRet = ruleset.GetRuleset(&pRuleset, pszName); + if(localRet == RS_RET_NOT_FOUND) { + errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName); + } + CHKiRet(localRet); + pBindRuleset = pRuleset; + DBGPRINTF("imtcp current bind ruleset %p: '%s'\n", pRuleset, pszName); + +finalize_it: + free(pszName); /* no longer needed */ + RETiRet; +} + + static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) { DEFiRet; @@ -180,7 +204,8 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa } } - /* initialized, now add socket */ + /* initialized, now add socket and listener params */ + CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, pBindRuleset)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : pszInputName)); tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); @@ -240,6 +265,7 @@ CODESTARTmodExit objRelease(tcps_sess, LM_TCPSRV_FILENAME); objRelease(tcpsrv, LM_TCPSRV_FILENAME); objRelease(errmsg, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); ENDmodExit @@ -249,14 +275,10 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus iTCPSessMax = 200; iStrmDrvrMode = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; - if(pszInputName != NULL) { - free(pszInputName); - pszInputName = NULL; - } - if(pszStrmDrvrAuthMode != NULL) { - free(pszStrmDrvrAuthMode); - pszStrmDrvrAuthMode = NULL; - } + free(pszInputName); + pszInputName = NULL; + free(pszStrmDrvrAuthMode); + pszStrmDrvrAuthMode = NULL; return RS_RET_OK; } @@ -279,6 +301,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME)); CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, @@ -295,6 +318,8 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, + eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 7d92de155c832e0a4af2cb3b65f7cef909b19f8d Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 20 Jul 2009 18:36:30 +0200 Subject: internal: added ability to terminate input modules not via pthread_cancel... ... but an alternate approach via pthread_kill. This is somewhat safer as we do not need to think about the cancel-safeness of all libraries we use. However, not all inputs can easily supported, so this now is a feature that can be requested by the input module (the most important ones request it). --- plugins/imtcp/imtcp.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index e1f513c8..1f111ef3 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -250,6 +250,13 @@ CODESTARTafterRun ENDafterRun +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + BEGINmodExit CODESTARTmodExit if(pOurTcpsrv != NULL) @@ -287,6 +294,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES ENDqueryEtryPt -- cgit v1.2.3 From 56b781e5bb1ea08b76d5dcc1d5e5eab10a40a4c6 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 17 Aug 2009 17:18:19 +0200 Subject: added $InputTCPMaxListeners directive permits to specify how many TCP servers shall be possible (default is 20). --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index e1f513c8..01c4bc33 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -82,6 +82,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ +static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ @@ -188,6 +189,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax)); + CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, iTCPLstnMax)); CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); @@ -273,6 +275,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + iTCPLstnMax = 20; iStrmDrvrMode = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; free(pszInputName); @@ -308,6 +311,8 @@ CODEmodInit_QueryRegCFSLineHdlr addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, + NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, -- cgit v1.2.3 From 6a69e478224d1513dbe8501e8978643ba89c8c82 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 1 Oct 2009 18:39:21 +0200 Subject: added $InputTCPServerNotifyOnConnectionClose config directive --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 01c4bc33..d122e976 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -84,6 +84,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; static int iTCPSessMax = 200; /* max number of sessions */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ +static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ @@ -197,6 +198,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); + CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose)); /* now set optional params, but only if they were actually configured */ if(pszStrmDrvrAuthMode != NULL) { CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode)); @@ -277,6 +279,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus iTCPSessMax = 200; iTCPLstnMax = 20; iStrmDrvrMode = 0; + bEmitMsgOnClose = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; free(pszInputName); pszInputName = NULL; @@ -313,6 +316,8 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, + eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, -- cgit v1.2.3 From 05d693123b175855174023874ce6f497f3642e61 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 2 Nov 2009 11:39:38 +0100 Subject: added omruleset output module, which provides great flexibility in action processing. THIS IS A VERY IMPORTANT ADDITION, see its doc for why. --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index c56593f2..176b5b18 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -171,7 +171,7 @@ static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName) localRet = ruleset.GetRuleset(&pRuleset, pszName); if(localRet == RS_RET_NOT_FOUND) { - errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName); + errmsg.LogError(0, RS_RET_RULESET_NOT_FOUND, "error: ruleset '%s' not found - ignored", pszName); } CHKiRet(localRet); pBindRuleset = pRuleset; -- cgit v1.2.3 From 604d782f09f38734ca84d63cf1f09234c4dd94e3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 17 Nov 2009 10:43:36 +0100 Subject: minor: moved all code to new isAllowedSender2() interface --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 176b5b18..2348c974 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -97,7 +97,7 @@ static int isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess) { - return net.isAllowedSender(UCHAR_CONSTANT("TCP"), addr, fromHostFQDN); + return net.isAllowedSender2(UCHAR_CONSTANT("TCP"), addr, fromHostFQDN, 1); } -- cgit v1.2.3 From ebf058226120b89bc2735ff72c4c12c14cfa2599 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 1 Mar 2010 11:33:48 +0100 Subject: added capability to turn off standard LF delimiter in TCP server via new directive "$InputTCPServerDisableLFDelimiter on" --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 2348c974..0cfae057 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -86,6 +86,7 @@ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ +static int bDisableLFDelim = 0; /* disbale standard LF delimiter */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */ @@ -198,6 +199,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); + CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, bDisableLFDelim)); CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose)); /* now set optional params, but only if they were actually configured */ if(pszStrmDrvrAuthMode != NULL) { @@ -288,6 +290,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus iStrmDrvrMode = 0; bEmitMsgOnClose = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; + bDisableLFDelim = 0; free(pszInputName); pszInputName = NULL; free(pszStrmDrvrAuthMode); @@ -334,6 +337,8 @@ CODEmodInit_QueryRegCFSLineHdlr eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, + NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, -- cgit v1.2.3 From e64cd212432c2cf76245888499461e9c8bf73243 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 21 Jul 2010 18:08:19 +0200 Subject: moving towards scoping inside rsyslog.conf first step: adding object-type specifier to config statement table --- plugins/imtcp/imtcp.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 0cfae057..ce787357 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -322,29 +322,29 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, - addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + addTCPListener, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, - NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); + NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, - NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID)); + NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, - eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID)); + eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, - eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); + eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, - eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); + eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, - eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); + eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, - NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); + NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, - NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID)); + NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, - eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); + eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, - eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID)); + eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, - resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); ENDmodInit -- cgit v1.2.3 From d1eb6e0edc51a78f3209448e800b25eda50340f2 Mon Sep 17 00:00:00 2001 From: Bojan Smojver Date: Wed, 23 Feb 2011 11:25:43 +0100 Subject: added work-around for bug in gtls, which causes fd leak when using TLS The capability has been added for module to specify that they do not like being unloaded. related bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=222 Signed-off-by: Rainer Gerhards --- plugins/imtcp/imtcp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 0cfae057..d3e9cabe 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -65,6 +65,7 @@ #include "net.h" /* for permittedPeers, may be removed when this is removed */ MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP /* static data */ DEF_IMOD_STATIC_DATA -- cgit v1.2.3 From 0edf73f88096f3656da466027417d04ce7a2511c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 1 Apr 2011 16:26:21 +0200 Subject: added new config directive $InputTCPFlowControl... ... to select if tcp received messages shall be flagged as light delayable or not. --- plugins/imtcp/imtcp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d3e9cabe..1a62d82e 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -3,7 +3,7 @@ * * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c) * - * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -88,6 +88,7 @@ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mos static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ static int bDisableLFDelim = 0; /* disbale standard LF delimiter */ +static int bUseFlowControl = 1; /* use flow control, what means indicate ourselfs a "light delayable" */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */ @@ -199,6 +200,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); + CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, bUseFlowControl)); CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, bDisableLFDelim)); CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose)); @@ -289,6 +291,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus iTCPSessMax = 200; iTCPLstnMax = 20; iStrmDrvrMode = 0; + bUseFlowControl = 0; bEmitMsgOnClose = 0; iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; bDisableLFDelim = 0; @@ -344,6 +347,8 @@ CODEmodInit_QueryRegCFSLineHdlr eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, + eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From b722cd3fe608a0bbf4a6df962f9d5c5e547fdc09 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 19 Apr 2011 12:18:26 +0200 Subject: milestone: ruleset now supports rsconf_t --- plugins/imtcp/imtcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 24c0cd7e..be95d287 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -172,7 +172,7 @@ static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName) rsRetVal localRet; DEFiRet; - localRet = ruleset.GetRuleset(&pRuleset, pszName); + localRet = ruleset.GetRuleset(ourConf, &pRuleset, pszName); if(localRet == RS_RET_NOT_FOUND) { errmsg.LogError(0, RS_RET_RULESET_NOT_FOUND, "error: ruleset '%s' not found - ignored", pszName); } -- cgit v1.2.3 From d0d9f823b79c5649dad18cb1d8d7744796ae0907 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 3 May 2011 18:02:18 +0200 Subject: step: put plumbing in place for new input module config system --- plugins/imtcp/imtcp.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index be95d287..b034ebe9 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -82,6 +82,11 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ + +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int iTCPSessMax = 200; /* max number of sessions */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ @@ -228,6 +233,31 @@ finalize_it: RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput -- cgit v1.2.3 From c0d1334f6e23b1cfb21d302e3a4b32c449c26547 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 5 May 2011 11:36:05 +0200 Subject: step: imtcp moved to new config interface as far as we know that new interface right now ;) --- plugins/imtcp/imtcp.c | 242 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 163 insertions(+), 79 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index b034ebe9..67fa1557 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -76,28 +76,53 @@ DEFobjCurrIf(netstrm) DEFobjCurrIf(errmsg) DEFobjCurrIf(ruleset) +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); + /* Module static data */ static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ - -typedef struct { - EMPTY_STRUCT; -} modConfData_t; - -static int iTCPSessMax = 200; /* max number of sessions */ -static int iTCPLstnMax = 20; /* max number of sessions */ -static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ -static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ -static int iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; /* addtl frame delimiter, e.g. for netscreen, default none */ -static int bDisableLFDelim = 0; /* disbale standard LF delimiter */ -static int bUseFlowControl = 1; /* use flow control, what means indicate ourselfs a "light delayable" */ -static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ -static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */ -static ruleset_t *pBindRuleset = NULL; /* ruleset to bind listener to (use system default if unspecified) */ - +static struct configSettings_s { + int iTCPSessMax; + int iTCPLstnMax; + int iStrmDrvrMode; + int bEmitMsgOnClose; + int iAddtlFrameDelim; + int bDisableLFDelim; + int bUseFlowControl; + uchar *pszStrmDrvrAuthMode; + uchar *pszInputName; + uchar *pszBindRuleset; +} cs; + +struct instanceConf_s { + uchar *pszBindPort; /* port to bind to */ + uchar *pszBindRuleset; /* name of ruleset to bind to */ + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */ + struct instanceConf_s *next; +}; + + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + instanceConf_t *root, *tail; + int iTCPSessMax; /* max number of sessions */ + int iTCPLstnMax; /* max number of sessions */ + int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ + int bEmitMsgOnClose; /* emit an informational message on close by remote peer */ + int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */ + int bDisableLFDelim; /* disable standard LF delimiter */ + int bUseFlowControl; /* use flow control, what means indicate ourselfs a "light delayable" */ + uchar *pszStrmDrvrAuthMode; /* authentication mode to use */ +}; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ + +#include "im-helper.h" /* must be included AFTER the type definitions! */ /* callbacks */ /* this shall go into a specific ACL module! */ @@ -170,48 +195,70 @@ finalize_it: } -/* accept a new ruleset to bind. Checks if it exists and complains, if not */ -static rsRetVal setRuleset(void __attribute__((unused)) *pVal, uchar *pszName) +/* This function is called when a new listener instace shall be added to + * the current config object via the legacy config system. It just shuffles + * all parameters to the listener in-memory instance. + * rgerhards, 2011-05-04 + */ +static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal) { - ruleset_t *pRuleset; - rsRetVal localRet; + instanceConf_t *inst; DEFiRet; - localRet = ruleset.GetRuleset(ourConf, &pRuleset, pszName); - if(localRet == RS_RET_NOT_FOUND) { - errmsg.LogError(0, RS_RET_RULESET_NOT_FOUND, "error: ruleset '%s' not found - ignored", pszName); + CHKmalloc(inst = MALLOC(sizeof(instanceConf_t))); + + CHKmalloc(inst->pszBindPort = ustrdup((pNewVal == NULL || *pNewVal == '\0') + ? (uchar*) "10514" : pNewVal)); + if((cs.pszBindRuleset == NULL) || (cs.pszBindRuleset[0] == '\0')) { + inst->pszBindRuleset = NULL; + } else { + CHKmalloc(inst->pszBindRuleset = ustrdup(cs.pszBindRuleset)); + } + if((cs.pszInputName == NULL) || (cs.pszInputName[0] == '\0')) { + inst->pszInputName = NULL; + } else { + CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName)); + } + inst->next = NULL; + + /* node created, let's add to config */ + if(loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = inst; + } else { + loadModConf->tail->next = inst; + loadModConf->tail = inst; } - CHKiRet(localRet); - pBindRuleset = pRuleset; - DBGPRINTF("imtcp current bind ruleset %p: '%s'\n", pRuleset, pszName); finalize_it: - free(pszName); /* no longer needed */ + free(pNewVal); RETiRet; } -static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal) +static rsRetVal +addListner(modConfData_t *modConf, instanceConf_t *inst) { DEFiRet; if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); - CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax)); - CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, iTCPLstnMax)); + /* callbacks */ CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData)); CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks)); CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose)); CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose)); - CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode)); - CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, bUseFlowControl)); - CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim)); - CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, bDisableLFDelim)); - CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, bEmitMsgOnClose)); + /* params */ + CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax)); + CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax)); + CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode)); + CHKiRet(tcpsrv.SetUseFlowControl(pOurTcpsrv, modConf->bUseFlowControl)); + CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, modConf->iAddtlFrameDelim)); + CHKiRet(tcpsrv.SetbDisableLFDelim(pOurTcpsrv, modConf->bDisableLFDelim)); + CHKiRet(tcpsrv.SetNotificationOnRemoteClose(pOurTcpsrv, modConf->bEmitMsgOnClose)); /* now set optional params, but only if they were actually configured */ - if(pszStrmDrvrAuthMode != NULL) { - CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode)); + if(modConf->pszStrmDrvrAuthMode != NULL) { + CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, modConf->pszStrmDrvrAuthMode)); } if(pPermPeersRoot != NULL) { CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot)); @@ -219,16 +266,14 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa } /* initialized, now add socket and listener params */ - CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, pBindRuleset)); - CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? - UCHAR_CONSTANT("imtcp") : pszInputName)); - tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset)); + CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ? + UCHAR_CONSTANT("imtcp") : inst->pszInputName)); + tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort); finalize_it: if(iRet != RS_RET_OK) { - errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet); - if(pOurTcpsrv != NULL) - tcpsrv.Destruct(&pOurTcpsrv); + errmsg.LogError(0, NO_ERRCODE, "imtcp: error %d trying to add listener", iRet); } RETiRet; } @@ -236,21 +281,64 @@ finalize_it: BEGINbeginCnfLoad CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + /* init legacy config variables */ + cs.pszStrmDrvrAuthMode = NULL; + resetConfigVariables(NULL, NULL); /* dummy parameters just to fulfill interface def */ ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad + /* persist module-specific settings from legacy config system */ + pModConf->iTCPSessMax = cs.iTCPSessMax; + pModConf->iTCPLstnMax = cs.iTCPLstnMax; + pModConf->iStrmDrvrMode = cs.iStrmDrvrMode; + pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose; + pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim; + pModConf->bDisableLFDelim = cs.bDisableLFDelim; + pModConf->bUseFlowControl = cs.bUseFlowControl; + if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) { + loadModConf->pszStrmDrvrAuthMode = NULL; + free(cs.pszStrmDrvrAuthMode); + } else { + loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode; + } + cs.pszStrmDrvrAuthMode = NULL; + + loadModConf = NULL; /* done loading */ ENDendCnfLoad +/* function to generate error message if framework does not find requested ruleset */ +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) +{ + errmsg.LogError(0, NO_ERRCODE, "imtcp: ruleset '%s' for port %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->pszBindPort); +} + BEGINcheckCnf + instanceConf_t *inst; CODESTARTcheckCnf + for(inst = pModConf->root ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf, inst); + } ENDcheckCnf BEGINactivateCnf + instanceConf_t *inst; CODESTARTactivateCnf + runModConf = pModConf; + for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { + addListner(pModConf, inst); + } + if(pOurTcpsrv == NULL) + ABORT_FINALIZE(RS_RET_NO_RUN); +finalize_it: ENDactivateCnf @@ -274,11 +362,7 @@ ENDrunInput /* initialize and return if will run or not */ BEGINwillRun CODESTARTwillRun - /* first apply some config settings */ net.PrintAllowedSenders(2); /* TCP */ - if(pOurTcpsrv == NULL) - ABORT_FINALIZE(RS_RET_NO_RUN); -finalize_it: ENDwillRun @@ -318,17 +402,17 @@ ENDmodExit static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - iTCPSessMax = 200; - iTCPLstnMax = 20; - iStrmDrvrMode = 0; - bUseFlowControl = 0; - bEmitMsgOnClose = 0; - iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; - bDisableLFDelim = 0; - free(pszInputName); - pszInputName = NULL; - free(pszStrmDrvrAuthMode); - pszStrmDrvrAuthMode = NULL; + cs.iTCPSessMax = 200; + cs.iTCPLstnMax = 20; + cs.iStrmDrvrMode = 0; + cs.bUseFlowControl = 0; + cs.bEmitMsgOnClose = 0; + cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; + cs.bDisableLFDelim = 0; + free(cs.pszInputName); + cs.pszInputName = NULL; + free(cs.pszStrmDrvrAuthMode); + cs.pszStrmDrvrAuthMode = NULL; return RS_RET_OK; } @@ -356,31 +440,31 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, - addTCPListener, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + addInstance, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, - NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, - NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, - eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, - eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, - eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, - eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &cs.iTCPLstnMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary, + NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, + NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord, + NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord, + setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, - NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, - NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, - eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, - eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, - eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &cs.bDisableLFDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, + NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord, + NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, eCmdHdlrBinary, + NULL, &cs.bUseFlowControl, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, - resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); ENDmodInit -- cgit v1.2.3 From b056c258d7bab528034ec8c8749cdcf0d0102268 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 6 May 2011 08:43:15 +0200 Subject: step: generalized new config interface for all module types --- plugins/imtcp/imtcp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 67fa1557..75987aed 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -421,6 +421,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES ENDqueryEtryPt -- cgit v1.2.3 From ff2bb192f2c566f189a9d104d83d7a70c7888774 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 6 May 2011 10:06:32 +0200 Subject: step: conf interface now natively supports priv drop --- plugins/imtcp/imtcp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 75987aed..3978ff5d 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -266,6 +266,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst) } /* initialized, now add socket and listener params */ + DBGPRINTF("imtcp: trying to add port *:%s\n", inst->pszBindPort); CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : inst->pszInputName)); @@ -329,9 +330,9 @@ CODESTARTcheckCnf ENDcheckCnf -BEGINactivateCnf +BEGINactivateCnfPrePrivDrop instanceConf_t *inst; -CODESTARTactivateCnf +CODESTARTactivateCnfPrePrivDrop runModConf = pModConf; for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { addListner(pModConf, inst); @@ -339,6 +340,12 @@ CODESTARTactivateCnf if(pOurTcpsrv == NULL) ABORT_FINALIZE(RS_RET_NO_RUN); finalize_it: +ENDactivateCnfPrePrivDrop + + +BEGINactivateCnf +CODESTARTactivateCnf + /* sorry, nothing to do here... */ ENDactivateCnf @@ -422,6 +429,7 @@ BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES ENDqueryEtryPt -- cgit v1.2.3 From 759904862dab6e580c6b890fd9ed75e1f29271f1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 6 May 2011 10:30:10 +0200 Subject: step: imtcp did not properly handle privilege drop --- plugins/imtcp/imtcp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 3978ff5d..976fbf1f 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -339,6 +339,7 @@ CODESTARTactivateCnfPrePrivDrop } if(pOurTcpsrv == NULL) ABORT_FINALIZE(RS_RET_NO_RUN); + CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); finalize_it: ENDactivateCnfPrePrivDrop @@ -357,12 +358,7 @@ ENDfreeCnf */ BEGINrunInput CODESTARTrunInput - /* TODO: we must be careful to start the listener here. Currently, tcpsrv.c seems to - * do that in ConstructFinalize - */ - CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv)); iRet = tcpsrv.Run(pOurTcpsrv); -finalize_it: ENDrunInput -- cgit v1.2.3 From 6625a8790d3e89b3ecc0612cf08fc917b9631398 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 9 May 2011 10:07:23 +0200 Subject: added capability for imtcp to activate keep-alive packets at the socket layer. reference: http://kb.monitorware.com/post20791.html --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 1a62d82e..c939e1d6 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -82,6 +82,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ +static int bKeepAlive = 0; /* support keep-alive packets */ static int iTCPSessMax = 200; /* max number of sessions */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ @@ -192,6 +193,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa if(pOurTcpsrv == NULL) { CHKiRet(tcpsrv.Construct(&pOurTcpsrv)); + CHKiRet(tcpsrv.SetKeepAlive(pOurTcpsrv, bKeepAlive)); CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax)); CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, iTCPLstnMax)); CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost)); @@ -289,6 +291,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + bKeepAlive = 0; iTCPLstnMax = 20; iStrmDrvrMode = 0; bUseFlowControl = 0; @@ -327,6 +330,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary, + NULL, &bKeepAlive, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, -- cgit v1.2.3 From a7e3afb20b461f608f478e8fca15b02e67d6d9c3 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 20 Jul 2011 10:47:24 +0200 Subject: milestone: added module config names --- plugins/imtcp/imtcp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 142f0791..4fd717d7 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -66,6 +66,7 @@ MODULE_TYPE_INPUT MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imtcp") /* static data */ DEF_IMOD_STATIC_DATA -- cgit v1.2.3 From f8342ced6f7c17ecd2f043254151c786257b3fbb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 5 Aug 2011 14:56:20 +0200 Subject: - imudp&imtcp now report error if no listener at all was defined Thanks to Marcin for suggesting this error message --- plugins/imtcp/imtcp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 4fd717d7..98f49051 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -332,6 +332,11 @@ CODESTARTcheckCnf for(inst = pModConf->root ; inst != NULL ; inst = inst->next) { std_checkRuleset(pModConf, inst); } + if(pModConf->root == NULL) { + errmsg.LogError(0, RS_RET_NO_LISTNERS , "imtcp: module loaded, but " + "no listeners defined - no input will be gathered"); + iRet = RS_RET_NO_LISTNERS; + } ENDcheckCnf -- cgit v1.2.3 From ca39d8e60e569d837f39a9c33e28cf8f0e89f321 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 12 Jan 2012 03:29:19 +0100 Subject: more files moved to ASL 2.0 --- plugins/imtcp/imtcp.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index d122e976..d8f712d2 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -1,26 +1,26 @@ /* imtcp.c * This is the implementation of the TCP input module. * - * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c) + * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c, + * which at the time of the rsyslog fork was BSD-licensed) * - * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * - * Rsyslog is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Rsyslog is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Rsyslog. If not, see . - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /* This note shall explain the calling sequence while we do not have -- cgit v1.2.3 From 9b24152b6ac6af942a62675c6136316fd487b661 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 18 Jan 2012 18:21:08 +0100 Subject: undoing v6.1 config scoping interface, part I The most common files are now changed, more needs to be done. --- plugins/imtcp/imtcp.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 90534104..b537cbb8 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -326,31 +326,31 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, - addTCPListener, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, - NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, - NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &iTCPLstnMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, - eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrBinary, NULL, &bEmitMsgOnClose, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, - eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, - eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, - eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, - NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, - NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + NULL, &bDisableLFDelim, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, - eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, - eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrGetWord, setRuleset, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, - eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + eCmdHdlrBinary, NULL, &bUseFlowControl, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, - resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit v1.2.3 From 4fb7ba113c4d4afd485feb2729c5ff67bc8ddd4a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 19 Mar 2012 15:28:25 +0100 Subject: added configuration directive to disable octet-counted framing ... for imtcp, directive is $InputTCPServerSupportOctetCountedFraming --- plugins/imtcp/imtcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 6ab39477..2239d0f4 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -83,6 +83,7 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ static int iTCPSessMax = 200; /* max number of sessions */ +static int bSuppOctetFram = 1; /* octet counted TCP framing supported? */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static int bEmitMsgOnClose = 0; /* emit an informational message on close by remote peer */ @@ -215,7 +216,7 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, pBindRuleset)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : pszInputName)); - tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal); + tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, bSuppOctetFram); finalize_it: if(iRet != RS_RET_OK) { @@ -287,6 +288,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iTCPSessMax = 200; + bSuppOctetFram = 1; iTCPLstnMax = 20; iStrmDrvrMode = 0; bEmitMsgOnClose = 0; @@ -324,6 +326,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addTCPListener, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary, + NULL, &bSuppOctetFram, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, -- cgit v1.2.3 From bf85d81790a26945e404c6fdfdddad5eadbaa371 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 25 Jun 2012 12:35:46 +0200 Subject: implemented freeCnf() module interface & fixed some mem leaks The interface was actually not present in older versions, even though some modules already used it. The implementation was now done, and not in 6.3/6.4 because the resulting memory leak was ultra-slim and the new interface handling has some potential to seriously break things. Not the kind of thing you want to add in late beta state, if avoidable. --- plugins/imtcp/imtcp.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 33404fee..a3365d44 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -366,7 +366,16 @@ ENDactivateCnf BEGINfreeCnf + instanceConf_t *inst, *del; CODESTARTfreeCnf + for(inst = pModConf->root ; inst != NULL ; ) { + free(inst->pszBindPort); + free(inst->pBindRuleset); + free(inst->pszInputName); + del = inst; + inst = inst->next; + free(del); + } ENDfreeCnf /* This function is called to gather input. -- cgit v1.2.3 From 7348da7e02fae85ad24dd496f1cd8f6385cfcfa8 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 28 Aug 2012 19:07:58 +0200 Subject: bugfix: imtcp could abort on exit due to invalid free() --- plugins/imtcp/imtcp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index a3365d44..f021307b 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -370,7 +370,6 @@ BEGINfreeCnf CODESTARTfreeCnf for(inst = pModConf->root ; inst != NULL ; ) { free(inst->pszBindPort); - free(inst->pBindRuleset); free(inst->pszInputName); del = inst; inst = inst->next; -- cgit v1.2.3 From da01473c60459773170a9405385f5bfde31eca9f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 26 Sep 2012 15:21:59 +0200 Subject: imtcp: implement support for input() --- plugins/imtcp/imtcp.c | 99 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 10 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index f021307b..5d865945 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -128,6 +128,20 @@ struct modConfData_s { static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ +/* input instance parameters */ +static struct cnfparamdescr inppdescr[] = { + { "port", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */ + { "name", eCmdHdlrString, 0 }, + { "ruleset", eCmdHdlrString, 0 }, + { "supportOctetCountedFraming", eCmdHdlrBinary, 0 } +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + + #include "im-helper.h" /* must be included AFTER the type definitions! */ /* callbacks */ @@ -201,6 +215,36 @@ finalize_it: } +/* create input instance, set default paramters, and + * add it to the list of instances. + */ +static rsRetVal +createInstance(instanceConf_t **pinst) +{ + instanceConf_t *inst; + DEFiRet; + CHKmalloc(inst = MALLOC(sizeof(instanceConf_t))); + inst->next = NULL; + inst->pszBindRuleset = NULL; + inst->pszInputName = NULL; + inst->bSuppOctetFram = 1; + + /* node created, let's add to config */ + if(loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = inst; + } else { + loadModConf->tail->next = inst; + loadModConf->tail = inst; + } + + *pinst = inst; +finalize_it: + RETiRet; +} + + + + /* This function is called when a new listener instace shall be added to * the current config object via the legacy config system. It just shuffles * all parameters to the listener in-memory instance. @@ -211,7 +255,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal) instanceConf_t *inst; DEFiRet; - CHKmalloc(inst = MALLOC(sizeof(instanceConf_t))); + CHKiRet(createInstance(&inst)); CHKmalloc(inst->pszBindPort = ustrdup((pNewVal == NULL || *pNewVal == '\0') ? (uchar*) "10514" : pNewVal)); @@ -226,15 +270,6 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal) CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName)); } inst->bSuppOctetFram = cs.bSuppOctetFram; - inst->next = NULL; - - /* node created, let's add to config */ - if(loadModConf->tail == NULL) { - loadModConf->tail = loadModConf->root = inst; - } else { - loadModConf->tail->next = inst; - loadModConf->tail = inst; - } finalize_it: free(pNewVal); @@ -288,6 +323,49 @@ finalize_it: } +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *inst; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imtcp)\n"); + + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(pvals == NULL) { + errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, + "imtcp: required parameter are missing\n"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("input param blk in imtcp:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&inst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(inppblk.descr[i].name, "port")) { + inst->pszBindPort = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "name")) { + inst->pszInputName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "supportOctetCountedFraming")) { + inst->bSuppOctetFram = (int) pvals[i].val.d.n; + } else { + dbgprintf("imtcp: program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } +finalize_it: +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + + BEGINbeginCnfLoad CODESTARTbeginCnfLoad loadModConf = pModConf; @@ -451,6 +529,7 @@ CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES CODEqueryEtryPt_STD_CONF2_QUERIES CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES ENDqueryEtryPt -- cgit v1.2.3 From 7366f115aeaca7b7ae4e777f4da86dca42c3dba4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 26 Sep 2012 16:08:19 +0200 Subject: imptcp: implement support for input() --- plugins/imtcp/imtcp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 5d865945..a00d4ebe 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -141,7 +141,6 @@ static struct cnfparamblk inppblk = inppdescr }; - #include "im-helper.h" /* must be included AFTER the type definitions! */ /* callbacks */ -- cgit v1.2.3 From 43da91636a5d8f60c21f1795d25fb0755e356d9f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 28 Sep 2012 08:09:47 +0200 Subject: imtcp: implement support for module() parameters --- plugins/imtcp/imtcp.c | 173 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 135 insertions(+), 38 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index a00d4ebe..3ad03615 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -123,11 +123,31 @@ struct modConfData_s { sbool bKeepAlive; sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */ uchar *pszStrmDrvrAuthMode; /* authentication mode to use */ + sbool configSetViaV2Method; }; static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "flowcontrol", eCmdHdlrBinary, 0 }, + { "disablelfdelimiter", eCmdHdlrBinary, 0 }, + { "octetcountedframing", eCmdHdlrBinary, 0 }, + { "notifyonconnectionclose", eCmdHdlrBinary, 0 }, + { "addtlframedelimiter", eCmdHdlrPositiveInt, 0 }, + { "maxsessions", eCmdHdlrPositiveInt, 0 }, + { "maxlistners", eCmdHdlrPositiveInt, 0 }, + { "streamdriver.mode", eCmdHdlrPositiveInt, 0 }, + { "streamdriver.authmode", eCmdHdlrString, 0 }, + { "keepalive", eCmdHdlrBinary, 0 } +}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + /* input instance parameters */ static struct cnfparamdescr inppdescr[] = { { "port", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */ @@ -143,6 +163,8 @@ static struct cnfparamblk inppblk = #include "im-helper.h" /* must be included AFTER the type definitions! */ +static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */ + /* callbacks */ /* this shall go into a specific ACL module! */ static int @@ -242,8 +264,6 @@ finalize_it: } - - /* This function is called when a new listener instace shall be added to * the current config object via the legacy config system. It just shuffles * all parameters to the listener in-memory instance. @@ -369,30 +389,103 @@ BEGINbeginCnfLoad CODESTARTbeginCnfLoad loadModConf = pModConf; pModConf->pConf = pConf; + /* init our settings */ + loadModConf->iTCPSessMax = 200; + loadModConf->iTCPLstnMax = 20; + loadModConf->bSuppOctetFram = 1; + loadModConf->iStrmDrvrMode = 0; + loadModConf->bUseFlowControl = 0; + loadModConf->bKeepAlive = 0; + loadModConf->bEmitMsgOnClose = 0; + loadModConf->iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; + loadModConf->bDisableLFDelim = 0; + loadModConf->pszStrmDrvrAuthMode = NULL; + loadModConf->configSetViaV2Method = 0; + bLegacyCnfModGlobalsPermitted = 1; /* init legacy config variables */ cs.pszStrmDrvrAuthMode = NULL; resetConfigVariables(NULL, NULL); /* dummy parameters just to fulfill interface def */ ENDbeginCnfLoad +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, "imtcp: error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for imtcp:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "flowcontrol")) { + loadModConf->bUseFlowControl = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "disablelfdelimiter")) { + loadModConf->bDisableLFDelim = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "octetcountedframing")) { + loadModConf->bSuppOctetFram = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "notifyonconnectionclose")) { + loadModConf->bEmitMsgOnClose = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "addtlframedelimiter")) { + loadModConf->iAddtlFrameDelim = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "maxsessions")) { + loadModConf->iTCPSessMax = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "maxlistners")) { + loadModConf->iTCPLstnMax = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "keepalive")) { + loadModConf->bKeepAlive = (int) pvals[i].val.d.n; + } 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.mode")) { + loadModConf->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else { + dbgprintf("imtcp: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } + + /* remove all of our legacy handlers, as they can not used in addition + * the the new-style config method. + */ + bLegacyCnfModGlobalsPermitted = 0; + loadModConf->configSetViaV2Method = 1; + +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + + BEGINendCnfLoad CODESTARTendCnfLoad - /* persist module-specific settings from legacy config system */ - pModConf->iTCPSessMax = cs.iTCPSessMax; - pModConf->iTCPLstnMax = cs.iTCPLstnMax; - pModConf->iStrmDrvrMode = cs.iStrmDrvrMode; - pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose; - pModConf->bSuppOctetFram = cs.bSuppOctetFram; - pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim; - pModConf->bDisableLFDelim = cs.bDisableLFDelim; - pModConf->bUseFlowControl = cs.bUseFlowControl; - pModConf->bKeepAlive = cs.bKeepAlive; - if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) { - loadModConf->pszStrmDrvrAuthMode = NULL; - free(cs.pszStrmDrvrAuthMode); - } else { - loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode; + if(!loadModConf->configSetViaV2Method) { + /* persist module-specific settings from legacy config system */ + pModConf->iTCPSessMax = cs.iTCPSessMax; + pModConf->iTCPLstnMax = cs.iTCPLstnMax; + pModConf->iStrmDrvrMode = cs.iStrmDrvrMode; + pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose; + pModConf->bSuppOctetFram = cs.bSuppOctetFram; + pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim; + pModConf->bDisableLFDelim = cs.bDisableLFDelim; + pModConf->bUseFlowControl = cs.bUseFlowControl; + pModConf->bKeepAlive = cs.bKeepAlive; + if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) { + loadModConf->pszStrmDrvrAuthMode = NULL; + } else { + loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode; + } } + if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) + free(cs.pszStrmDrvrAuthMode); cs.pszStrmDrvrAuthMode = NULL; loadModConf = NULL; /* done loading */ @@ -527,6 +620,7 @@ BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_IMOD_QUERIES CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES @@ -549,36 +643,39 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addInstance, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary, - NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary, - NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, - NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, - NULL, &cs.iTCPLstnMax, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary, - NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, - NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord, - NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, - NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, - NULL, &cs.bDisableLFDelim, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord, NULL, &cs.pszBindRuleset, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, eCmdHdlrBinary, - NULL, &cs.bUseFlowControl, STD_LOADABLE_MODULE_ID)); + /* module-global config params - will be disabled in configs that are loaded + * via module(...). + */ + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord, + NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary, + NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpflowcontrol"), 0, eCmdHdlrBinary, + NULL, &cs.bUseFlowControl, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverdisablelfdelimiter"), 0, eCmdHdlrBinary, + NULL, &cs.bDisableLFDelim, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt, + NULL, &cs.iAddtlFrameDelim, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary, + NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt, + NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt, + NULL, &cs.iTCPLstnMax, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpservernotifyonconnectionclose"), 0, eCmdHdlrBinary, + NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt, + NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit - /* vim:set ai: */ -- cgit v1.2.3 From 11c203c6732ebe939571919ee85f414f0457a017 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 1 Oct 2012 12:00:52 +0200 Subject: implement imtcp "permittedPeers" module-global parameter --- plugins/imtcp/imtcp.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 3ad03615..eaf9a213 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -36,7 +36,6 @@ * * rgerhards, 2008-05-19 */ - #include "config.h" #include #include @@ -62,6 +61,7 @@ #include "errmsg.h" #include "tcpsrv.h" #include "ruleset.h" +#include "rainerscript.h" #include "net.h" /* for permittedPeers, may be removed when this is removed */ MODULE_TYPE_INPUT @@ -123,6 +123,7 @@ struct modConfData_s { sbool bKeepAlive; sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */ uchar *pszStrmDrvrAuthMode; /* authentication mode to use */ + struct cnfarray *permittedPeers; sbool configSetViaV2Method; }; @@ -140,6 +141,7 @@ static struct cnfparamdescr modpdescr[] = { { "maxlistners", eCmdHdlrPositiveInt, 0 }, { "streamdriver.mode", eCmdHdlrPositiveInt, 0 }, { "streamdriver.authmode", eCmdHdlrString, 0 }, + { "permittedpeer", eCmdHdlrArray, 0 }, { "keepalive", eCmdHdlrBinary, 0 } }; static struct cnfparamblk modpblk = @@ -400,6 +402,7 @@ CODESTARTbeginCnfLoad loadModConf->iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; loadModConf->bDisableLFDelim = 0; loadModConf->pszStrmDrvrAuthMode = NULL; + loadModConf->permittedPeers = NULL; loadModConf->configSetViaV2Method = 0; bLegacyCnfModGlobalsPermitted = 1; /* init legacy config variables */ @@ -445,8 +448,10 @@ CODESTARTsetModCnf loadModConf->bKeepAlive = (int) pvals[i].val.d.n; } 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.mode")) { + } else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) { loadModConf->pszStrmDrvrAuthMode = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "permittedpeer")) { + loadModConf->permittedPeers = cnfarrayDup(pvals[i].val.d.ar); } else { dbgprintf("imtcp: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); @@ -517,8 +522,15 @@ ENDcheckCnf BEGINactivateCnfPrePrivDrop instanceConf_t *inst; + int i; CODESTARTactivateCnfPrePrivDrop runModConf = pModConf; + if(runModConf->permittedPeers != NULL) { + for(i = 0 ; i < runModConf->permittedPeers->nmemb ; ++i) { + setPermittedPeer(NULL, (uchar*) + es_str2cstr(runModConf->permittedPeers->arr[i], NULL)); + } + } for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { addListner(pModConf, inst); } @@ -538,6 +550,10 @@ ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf + if(runModConf->permittedPeers != NULL) { + cnfarrayContentDestruct(runModConf->permittedPeers); + free(runModConf->permittedPeers); + } for(inst = pModConf->root ; inst != NULL ; ) { free(inst->pszBindPort); free(inst->pszInputName); @@ -643,8 +659,6 @@ CODEmodInit_QueryRegCFSLineHdlr /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord, addInstance, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord, - setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0, eCmdHdlrGetWord, NULL, &cs.pszInputName, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverbindruleset"), 0, eCmdHdlrGetWord, @@ -652,6 +666,8 @@ CODEmodInit_QueryRegCFSLineHdlr /* module-global config params - will be disabled in configs that are loaded * via module(...). */ + CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0, eCmdHdlrGetWord, + setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0, eCmdHdlrGetWord, NULL, &cs.pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary, -- cgit v1.2.3 From 0d60901e6e404419b06ad0d20429edf7ea3053ce Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 12:09:37 +0200 Subject: ratelimit: imtcp (and gssapi) converted to new interface --- plugins/imtcp/imtcp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index eaf9a213..beb7d705 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -580,7 +580,9 @@ ENDwillRun BEGINafterRun CODESTARTafterRun - /* do cleanup here */ + if(pOurTcpsrv != NULL) + iRet = tcpsrv.Destruct(&pOurTcpsrv); + net.clearAllowedSenders(UCHAR_CONSTANT("TCP")); ENDafterRun @@ -594,9 +596,6 @@ ENDisCompatibleWithFeature BEGINmodExit CODESTARTmodExit - if(pOurTcpsrv != NULL) - iRet = tcpsrv.Destruct(&pOurTcpsrv); - if(pPermPeersRoot != NULL) { net.DestructPermittedPeers(&pPermPeersRoot); } -- cgit v1.2.3 From 0dc56f1426315854c09e78b37104ed1e818a75bb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 15 Oct 2012 19:01:05 +0200 Subject: imtcp: support for Linux-Type ratelimiting added --- plugins/imtcp/imtcp.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index beb7d705..8d71d5f2 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -105,6 +105,8 @@ struct instanceConf_s { uchar *pszBindRuleset; /* name of ruleset to bind to */ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */ + int ratelimitInterval; + int ratelimitBurst; int bSuppOctetFram; struct instanceConf_s *next; }; @@ -155,7 +157,9 @@ static struct cnfparamdescr inppdescr[] = { { "port", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */ { "name", eCmdHdlrString, 0 }, { "ruleset", eCmdHdlrString, 0 }, - { "supportOctetCountedFraming", eCmdHdlrBinary, 0 } + { "supportOctetCountedFraming", eCmdHdlrBinary, 0 }, + { "ratelimit.interval", eCmdHdlrInt, 0 }, + { "ratelimit.burst", eCmdHdlrInt, 0 } }; static struct cnfparamblk inppblk = { CNFPARAMBLK_VERSION, @@ -251,6 +255,8 @@ createInstance(instanceConf_t **pinst) inst->pszBindRuleset = NULL; inst->pszInputName = NULL; inst->bSuppOctetFram = 1; + inst->ratelimitInterval = 0; + inst->ratelimitBurst = 10000; /* node created, let's add to config */ if(loadModConf->tail == NULL) { @@ -334,6 +340,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst) CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset)); CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : inst->pszInputName)); + CHKiRet(tcpsrv.SetLinuxLikeRatelimiters(pOurTcpsrv, inst->ratelimitInterval, inst->ratelimitBurst)); tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort, inst->bSuppOctetFram); finalize_it: @@ -376,6 +383,10 @@ CODESTARTnewInpInst inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(inppblk.descr[i].name, "supportOctetCountedFraming")) { inst->bSuppOctetFram = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "ratelimit.burst")) { + inst->ratelimitBurst = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "ratelimit.interval")) { + inst->ratelimitInterval = (int) pvals[i].val.d.n; } else { dbgprintf("imtcp: program error, non-handled " "param '%s'\n", inppblk.descr[i].name); -- cgit v1.2.3 From a3742bdffd0622e8cc151accaadf1a433c0720fd Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 2 Nov 2012 19:05:05 +0100 Subject: bugfix: potential abort of imtcp on rsyslogd shutdown --- plugins/imtcp/imtcp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index eaf9a213..0cecb704 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -550,9 +550,9 @@ ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf - if(runModConf->permittedPeers != NULL) { - cnfarrayContentDestruct(runModConf->permittedPeers); - free(runModConf->permittedPeers); + if(pModConf->permittedPeers != NULL) { + cnfarrayContentDestruct(pModConf->permittedPeers); + free(pModConf->permittedPeers); } for(inst = pModConf->root ; inst != NULL ; ) { free(inst->pszBindPort); -- cgit v1.2.3 From 1b1fb636f72f6fa6ee3dcd4eefc4203eb0a3e483 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 14 Dec 2012 12:44:49 +0100 Subject: bugfix: small, mostly static memory leak in imtcp This had no practical effect, a handful of bytes was lost at most, no matter how many messages were processed (leak in config processor). --- plugins/imtcp/imtcp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'plugins/imtcp/imtcp.c') diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index 8750eb59..fc22d452 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -498,10 +498,10 @@ CODESTARTendCnfLoad loadModConf->pszStrmDrvrAuthMode = NULL; } else { loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode; + cs.pszStrmDrvrAuthMode = NULL; } } - if((cs.pszStrmDrvrAuthMode == NULL) || (cs.pszStrmDrvrAuthMode[0] == '\0')) - free(cs.pszStrmDrvrAuthMode); + free(cs.pszStrmDrvrAuthMode); cs.pszStrmDrvrAuthMode = NULL; loadModConf = NULL; /* done loading */ @@ -561,6 +561,7 @@ ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf + free(pModConf->pszStrmDrvrAuthMode); if(pModConf->permittedPeers != NULL) { cnfarrayContentDestruct(pModConf->permittedPeers); free(pModConf->permittedPeers); -- cgit v1.2.3