From 32db6291bc310062cffd3266fc297c7b13c571a7 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Mar 2011 16:59:49 +0100 Subject: backporting patch for clean make distcheck --- plugins/imdiag/imdiag.c | 3 +++ plugins/imfile/imfile.c | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'plugins') diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c index 0a69ee43..404cebc7 100644 --- a/plugins/imdiag/imdiag.c +++ b/plugins/imdiag/imdiag.c @@ -433,6 +433,9 @@ CODESTARTmodExit net.DestructPermittedPeers(&pPermPeersRoot); } + /* free some globals to keep valgrind happy */ + free(pszInputName); + /* release objects we used */ objRelease(net, LM_NET_FILENAME); objRelease(netstrm, LM_NETSTRMS_FILENAME); diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c index acb58dad..cac3a55d 100644 --- a/plugins/imfile/imfile.c +++ b/plugins/imfile/imfile.c @@ -331,6 +331,11 @@ ENDrunInput */ BEGINwillRun CODESTARTwillRun + /* free config variables we do no longer needed */ + free(pszFileName); + free(pszFileTag); + free(pszStateFile); + if(iFilPtr == 0) { errmsg.LogError(0, RS_RET_NO_RUN, "No files configured to be monitored"); ABORT_FINALIZE(RS_RET_NO_RUN); @@ -398,6 +403,9 @@ CODESTARTafterRun persistStrmState(&files[i]); strm.Destruct(&(files[i].pStrm)); } + free(files[i].pszFileName); + free(files[i].pszTag); + free(files[i].pszStateFile); } if(pInputName != NULL) -- cgit From 68bde6252d22cc4e88edc2b51523726bb858c818 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Mar 2011 13:19:38 +0100 Subject: prepared skeleton for new strgen module --- plugins/sm_cust_bindcdr/Makefile.am | 6 ++ plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 138 ++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 plugins/sm_cust_bindcdr/Makefile.am create mode 100644 plugins/sm_cust_bindcdr/sm_cust_bindcdr.c (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/Makefile.am b/plugins/sm_cust_bindcdr/Makefile.am new file mode 100644 index 00000000..1f71d499 --- /dev/null +++ b/plugins/sm_cust_bindcdr/Makefile.am @@ -0,0 +1,6 @@ +pkglib_LTLIBRARIES = sm_cust_bindcdr.la + +sm_cust_bindcdr_la_SOURCES = sm_cust_bindcdr.c +sm_cust_bindcdr_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +sm_cust_bindcdr_la_LDFLAGS = -module -avoid-version +sm_cust_bindcdr_la_LIBADD = diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c new file mode 100644 index 00000000..cf3cdeef --- /dev/null +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -0,0 +1,138 @@ +/* sm_cust_bindcdr.c + * This is a custom developed plugin to process bind information into + * a specific SQL statement. While the actual processing may be too specific + * to be of general use, this module serves as a template on how this type + * of processing can be done. + * + * Format generated: + * "%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" + * Note that this is the same as smtradfile.c, except that we do have a RFC3339 timestamp. However, + * we have copied over the code from there, it is too simple to go through all the hassle + * of having a single code base. + * + * NOTE: read comments in module-template.h to understand how this file + * works! + * + * File begun on 2011-03-17 by RGerhards + * + * Copyright 2011 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 "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "unicode-helper.h" + +MODULE_TYPE_STRGEN +MODULE_TYPE_NOKEEP +STRGEN_NAME("Custom_BindCDR") + +/* internal structures + */ +DEF_SMOD_STATIC_DATA + + +/* config data */ + + +/* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings + * needed (including their length) and then calculating the actual space required. So when we + * finally copy, we know exactly what we need. So we do at most one alloc. + */ +BEGINstrgen + register int iBuf; + uchar *pTimeStamp; + size_t lenTimeStamp; + uchar *pHOSTNAME; + size_t lenHOSTNAME; + uchar *pTAG; + int lenTAG; + uchar *pMSG; + size_t lenMSG; + size_t lenTotal; +CODESTARTstrgen + /* first obtain all strings and their length (if not fixed) */ + pTimeStamp = (uchar*) getTimeReported(pMsg, tplFmtRFC3339Date); + lenTimeStamp = ustrlen(pTimeStamp); + pHOSTNAME = (uchar*) getHOSTNAME(pMsg); + lenHOSTNAME = getHOSTNAMELen(pMsg); + getTAG(pMsg, &pTAG, &lenTAG); + pMSG = getMSG(pMsg); + lenMSG = getMSGLen(pMsg); + + /* calculate len, constants for spaces and similar fixed strings */ + lenTotal = lenTimeStamp + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 2; + if(pMSG[0] != ' ') + ++lenTotal; /* then we need to introduce one additional space */ + + /* now make sure buffer is large enough */ + if(lenTotal >= *pLenBuf) + CHKiRet(ExtendBuf(ppBuf, pLenBuf, lenTotal)); + + /* and concatenate the resulting string */ + memcpy(*ppBuf, pTimeStamp, lenTimeStamp); + iBuf = lenTimeStamp; + *(*ppBuf + iBuf++) = ' '; + + memcpy(*ppBuf + iBuf, pHOSTNAME, lenHOSTNAME); + iBuf += lenHOSTNAME; + *(*ppBuf + iBuf++) = ' '; + + memcpy(*ppBuf + iBuf, pTAG, lenTAG); + iBuf += lenTAG; + + if(pMSG[0] != ' ') + *(*ppBuf + iBuf++) = ' '; + memcpy(*ppBuf + iBuf, pMSG, lenMSG); + iBuf += lenMSG; + + /* trailer */ + *(*ppBuf + iBuf++) = '\n'; + *(*ppBuf + iBuf) = '\0'; + +finalize_it: +ENDstrgen + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_SMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit(sm_cust_bindcdr) +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + + dbgprintf("rsyslog sm_cust_bindcdr called, compiled with version %s\n", VERSION); +ENDmodInit -- cgit From 459f0d094fcb48fd58204ad3527f931715839bcb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 17 Mar 2011 14:59:18 +0100 Subject: setup test environment and test code in order to look at... bug http://bugzilla.adiscon.com/show_bug.cgi?id=195 That bug currently prevents strgen's to be used with databases --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 45 ++++++++++--------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index cf3cdeef..5ea7e653 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -63,56 +63,39 @@ DEF_SMOD_STATIC_DATA * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. */ +//#define SQL_STMT "INSERT INTO CDR(date,time,client,view,query,ip) VALUES ('" +#define SQL_STMT "INSERT INTO bind_test(date,time,client,view,query,ip) VALUES ('" BEGINstrgen register int iBuf; uchar *pTimeStamp; size_t lenTimeStamp; - uchar *pHOSTNAME; - size_t lenHOSTNAME; - uchar *pTAG; - int lenTAG; - uchar *pMSG; - size_t lenMSG; size_t lenTotal; CODESTARTstrgen /* first obtain all strings and their length (if not fixed) */ pTimeStamp = (uchar*) getTimeReported(pMsg, tplFmtRFC3339Date); lenTimeStamp = ustrlen(pTimeStamp); - pHOSTNAME = (uchar*) getHOSTNAME(pMsg); - lenHOSTNAME = getHOSTNAMELen(pMsg); - getTAG(pMsg, &pTAG, &lenTAG); - pMSG = getMSG(pMsg); - lenMSG = getMSGLen(pMsg); /* calculate len, constants for spaces and similar fixed strings */ - lenTotal = lenTimeStamp + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 2; - if(pMSG[0] != ' ') - ++lenTotal; /* then we need to introduce one additional space */ + lenTotal = lenTimeStamp + 1 + 200 /* test! */ + 2; /* now make sure buffer is large enough */ if(lenTotal >= *pLenBuf) CHKiRet(ExtendBuf(ppBuf, pLenBuf, lenTotal)); /* and concatenate the resulting string */ - memcpy(*ppBuf, pTimeStamp, lenTimeStamp); - iBuf = lenTimeStamp; - *(*ppBuf + iBuf++) = ' '; + memcpy(*ppBuf, SQL_STMT, sizeof(SQL_STMT) - 1); + iBuf = sizeof(SQL_STMT) - 1; - memcpy(*ppBuf + iBuf, pHOSTNAME, lenHOSTNAME); - iBuf += lenHOSTNAME; - *(*ppBuf + iBuf++) = ' '; + // SQL content:DATE,TIME,CLIENT,VIEW,QUERY,IP); - memcpy(*ppBuf + iBuf, pTAG, lenTAG); - iBuf += lenTAG; + memcpy(*ppBuf + iBuf, pTimeStamp, lenTimeStamp); + iBuf += lenTimeStamp; + memcpy(*ppBuf + iBuf, "' , '", sizeof("', '") - 1); + iBuf += sizeof("', '") - 1; - if(pMSG[0] != ' ') - *(*ppBuf + iBuf++) = ' '; - memcpy(*ppBuf + iBuf, pMSG, lenMSG); - iBuf += lenMSG; - - /* trailer */ - *(*ppBuf + iBuf++) = '\n'; - *(*ppBuf + iBuf) = '\0'; + /* end of SQL statement/trailer (NUL is contained in string!) */ + memcpy(*ppBuf + iBuf, "');", sizeof("');")); + iBuf += sizeof("');"); finalize_it: ENDstrgen @@ -129,7 +112,7 @@ CODEqueryEtryPt_STD_SMOD_QUERIES ENDqueryEtryPt -BEGINmodInit(sm_cust_bindcdr) +BEGINmodInit() CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr -- cgit From 41d79b8fead00f85614547606b0c1117f3efa04e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 21 Mar 2011 10:34:43 +0100 Subject: bugfix: strgen could not be used together with database outputs because the sql/stdsql option could not be specified. This has been solved by permitting the strgen to include the opton inside its name. closes: http://bugzilla.adiscon.com/show_bug.cgi?id=195 --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index 5ea7e653..d1634252 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -49,7 +49,7 @@ MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP -STRGEN_NAME("Custom_BindCDR") +STRGEN_NAME("Custom_BindCDR,sql") /* internal structures */ -- cgit From 5808af91e7e5e552a5cde4603687685978934626 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 22 Mar 2011 12:17:20 +0100 Subject: added internal processing of BIND records still some questions outstanding, so actual SQL statement is not usable at the moment --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 121 ++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index d1634252..be01db77 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -37,6 +37,7 @@ #include "config.h" #include "rsyslog.h" #include +#include #include #include #include @@ -64,19 +65,112 @@ DEF_SMOD_STATIC_DATA * finally copy, we know exactly what we need. So we do at most one alloc. */ //#define SQL_STMT "INSERT INTO CDR(date,time,client,view,query,ip) VALUES ('" -#define SQL_STMT "INSERT INTO bind_test(date,time,client,view,query,ip) VALUES ('" +//#define SQL_STMT "INSERT INTO bind_test(`Date`,`time`,client,view,query,ip) VALUES ('" +#define SQL_STMT "INSERT INTO bind_test(`Date`,ip) VALUES ('" +#define ADD_SQL_DELIM \ + memcpy(*ppBuf + iBuf, "', '", sizeof("', '") - 1); \ + iBuf += sizeof("', '") - 1; +#define SQL_STMT_END "');\n" BEGINstrgen register int iBuf; + uchar *psz; uchar *pTimeStamp; + uchar szClient[64]; + unsigned lenClient; + uchar szView[64]; + unsigned lenView; + uchar szQuery[64]; + unsigned lenQuery; + uchar szIP[64]; + unsigned lenIP; size_t lenTimeStamp; size_t lenTotal; CODESTARTstrgen + /* first create an empty statement. This is to be replaced if + * we have better data to fill in. + */ + /* now make sure buffer is large enough */ + if(*pLenBuf < 2) + CHKiRet(ExtendBuf(ppBuf, pLenBuf, 2)); + memcpy(*ppBuf, ";", sizeof(";")); + /* first obtain all strings and their length (if not fixed) */ pTimeStamp = (uchar*) getTimeReported(pMsg, tplFmtRFC3339Date); lenTimeStamp = ustrlen(pTimeStamp); + + /* "client" */ + psz = (uchar*) strstr((char*) getMSG(pMsg), "client "); + if(psz == NULL) { + dbgprintf("Custom_BindCDR: client part in msg missing\n"); + FINALIZE; + } else { + psz += sizeof("client ") - 1; /* skip "label" */ + for( lenClient = 0 + ; *psz && *psz != '#' && lenClient < sizeof(szClient) - 1 + ; ++lenClient) { + szClient[lenClient] = *psz++; + } + szClient[lenClient] = '\0'; + } + + /* "view" */ + psz = (uchar*) strstr((char*) getMSG(pMsg), "view "); + if(psz == NULL) { + dbgprintf("Custom_BindCDR: view part in msg missing\n"); + FINALIZE; + } else { + psz += sizeof("view ") - 1; /* skip "label" */ + for( lenView = 0 + ; *psz && *psz != ':' && lenView < sizeof(szView) - 1 + ; ++lenView) { + szView[lenView] = *psz++; + } + szView[lenView] = '\0'; + } + + /* "query" - we must extract just the number, and in reverse! */ + psz = (uchar*) strstr((char*) getMSG(pMsg), "query: "); + if(psz == NULL) { + dbgprintf("Custom_BindCDR: query part in msg missing\n"); + FINALIZE; + } else { + psz += sizeof("query: ") - 1; /* skip "label" */ + /* first find end-of-string to process */ + while(*psz && (isdigit(*psz) || *psz == '.')) { +dbgprintf("XXXX: step 1: %c\n", *psz); + psz++; + } + /* now shuffle data */ + for( lenQuery = 0 + ; *psz && *psz != ' ' && lenQuery < sizeof(szQuery) - 1 + ; --psz) { + if(isdigit(*psz)) + szQuery[lenQuery++] = *psz; + } + szQuery[lenQuery] = '\0'; + } + + /* "ip" */ + psz = (uchar*) strstr((char*) getMSG(pMsg), "IN TXT + ("); + if(psz == NULL) { + dbgprintf("Custom_BindCDR: ip part in msg missing\n"); + FINALIZE; + } else { + psz += sizeof("IN TXT + (") - 1; /* skip "label" */ + for( lenIP = 0 + ; *psz && *psz != ')' && lenIP < sizeof(szIP) - 1 + ; ++lenIP) { + szIP[lenIP] = *psz++; + } + szIP[lenIP] = '\0'; + } + + + /* --- strings extracted ---- */ /* calculate len, constants for spaces and similar fixed strings */ - lenTotal = lenTimeStamp + 1 + 200 /* test! */ + 2; + lenTotal = lenTimeStamp + lenClient + lenView + lenQuery + lenIP + 5 * 5 + + sizeof(SQL_STMT) + sizeof(SQL_STMT_END) + 2; /* now make sure buffer is large enough */ if(lenTotal >= *pLenBuf) @@ -90,12 +184,27 @@ CODESTARTstrgen memcpy(*ppBuf + iBuf, pTimeStamp, lenTimeStamp); iBuf += lenTimeStamp; - memcpy(*ppBuf + iBuf, "' , '", sizeof("', '") - 1); - iBuf += sizeof("', '") - 1; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szClient, lenClient); + iBuf += lenClient; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szView, lenView); + iBuf += lenView; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szQuery, lenQuery); + iBuf += lenQuery; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szIP, lenIP); + iBuf += lenIP; + ADD_SQL_DELIM /* end of SQL statement/trailer (NUL is contained in string!) */ - memcpy(*ppBuf + iBuf, "');", sizeof("');")); - iBuf += sizeof("');"); + memcpy(*ppBuf + iBuf, SQL_STMT_END, sizeof(SQL_STMT_END)); + iBuf += sizeof(SQL_STMT_END); finalize_it: ENDstrgen -- cgit From 0d80f4e4612fb209cc9dda5faf7b71cd261c0c20 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 22 Mar 2011 14:22:38 +0100 Subject: sm_bind_cdr: added capability to configure "allowed IPs" --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 83 +++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index be01db77..005a4ba9 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -43,10 +43,12 @@ #include #include "conf.h" #include "syslogd-types.h" +#include "cfsysline.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "unicode-helper.h" +#include "errmsg.h" MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP @@ -55,10 +57,65 @@ STRGEN_NAME("Custom_BindCDR,sql") /* internal structures */ DEF_SMOD_STATIC_DATA +DEFobjCurrIf(errmsg) + +/* list of "allowed" IPs */ +typedef struct allowedip_s { + uchar *pszIP; + struct allowedip_s *next; +} allowedip_t; + +static allowedip_t *root; /* config data */ +/* check if the provided IP is (already) in the allowed list + */ +static int +isAllowed(uchar *pszIP) +{ + allowedip_t *pallow; + int ret = 0; + + for(pallow = root ; pallow != NULL ; pallow = pallow->next) { + DBGPRINTF("XXXX: checking allowed IP '%s'\n", pallow->pszIP); + if(!ustrcmp(pallow->pszIP, pszIP)) { + ret = 1; + goto finalize_it; + } + } +finalize_it: return ret; +} + +/* This function is called to add an additional allowed IP. It adds + * the IP to the linked list of them. An error is emitted if the IP + * already exists. + */ +static rsRetVal addAllowedIP(void __attribute__((unused)) *pVal, uchar *pNewVal) +{ + allowedip_t *pNew; + DEFiRet; + + if(isAllowed(pNewVal)) { + errmsg.LogError(0, NO_ERRCODE, "error: allowed IP '%s' already configured " + "duplicate ignored", pNewVal); + ABORT_FINALIZE(RS_RET_ERR); + } + + CHKmalloc(pNew = malloc(sizeof(allowedip_t))); + pNew->pszIP = pNewVal; + pNew->next = root; + root = pNew; + DBGPRINTF("sm_cust_bindcdr: allowed IP '%s' added.\n", pNewVal); + +finalize_it: + if(iRet != RS_RET_OK) { + free(pNewVal); + } + + RETiRet; +} /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we @@ -72,9 +129,10 @@ DEF_SMOD_STATIC_DATA iBuf += sizeof("', '") - 1; #define SQL_STMT_END "');\n" BEGINstrgen - register int iBuf; + int iBuf; uchar *psz; uchar *pTimeStamp; + size_t lenTimeStamp; uchar szClient[64]; unsigned lenClient; uchar szView[64]; @@ -83,7 +141,6 @@ BEGINstrgen unsigned lenQuery; uchar szIP[64]; unsigned lenIP; - size_t lenTimeStamp; size_t lenTotal; CODESTARTstrgen /* first create an empty statement. This is to be replaced if @@ -137,7 +194,6 @@ CODESTARTstrgen psz += sizeof("query: ") - 1; /* skip "label" */ /* first find end-of-string to process */ while(*psz && (isdigit(*psz) || *psz == '.')) { -dbgprintf("XXXX: step 1: %c\n", *psz); psz++; } /* now shuffle data */ @@ -168,6 +224,14 @@ dbgprintf("XXXX: step 1: %c\n", *psz); /* --- strings extracted ---- */ + /* now check if the IP is "allowed", in which case we should not + * insert into the database. + */ + if(isAllowed(szIP)) { + DBGPRINTF("sm_cust_bindcdr: message from allowed IP, ignoring\n"); + FINALIZE; + } + /* calculate len, constants for spaces and similar fixed strings */ lenTotal = lenTimeStamp + lenClient + lenView + lenQuery + lenIP + 5 * 5 + sizeof(SQL_STMT) + sizeof(SQL_STMT_END) + 2; @@ -211,7 +275,16 @@ ENDstrgen BEGINmodExit + allowedip_t *pallow, *pdel; CODESTARTmodExit + for(pallow = root ; pallow != NULL ; ) { + pdel = pallow; + pallow = pallow->next; + free(pdel->pszIP); + free(pdel); + } + + objRelease(errmsg, CORE_COMPONENT); ENDmodExit @@ -225,6 +298,10 @@ BEGINmodInit() CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + root = NULL; + CHKiRet(omsdRegCFSLineHdlr((uchar *)"sgcustombindcdrallowedip", 0, eCmdHdlrGetWord, + addAllowedIP, NULL, STD_LOADABLE_MODULE_ID)); dbgprintf("rsyslog sm_cust_bindcdr called, compiled with version %s\n", VERSION); ENDmodInit -- cgit From 0fcbbfbe3b40e2739531cfa3a308c6fc8681ee7f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 28 Mar 2011 16:09:07 +0200 Subject: sm_cust_bindcdr: custom date parsing added --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 100 +++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index 005a4ba9..fa16acb5 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -120,6 +120,8 @@ finalize_it: /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. + * An actual message sample for what we intend to parse is (one line): + <30>Mar 24 13:01:51 named[6085]: 24-Mar-2011 13:01:51.865 queries: info: client 10.0.0.96#39762: view trusted: query: 8.6.0.9.9.4.1.4.6.1.8.3.mobilecrawler.com IN TXT + (10.0.0.96) */ //#define SQL_STMT "INSERT INTO CDR(date,time,client,view,query,ip) VALUES ('" //#define SQL_STMT "INSERT INTO bind_test(`Date`,`time`,client,view,query,ip) VALUES ('" @@ -131,8 +133,12 @@ finalize_it: BEGINstrgen int iBuf; uchar *psz; - uchar *pTimeStamp; - size_t lenTimeStamp; + uchar szDate[64]; + unsigned lenDate; + uchar szTime[64]; + unsigned lenTime; + uchar szMSec[64]; + unsigned lenMSec; uchar szClient[64]; unsigned lenClient; uchar szView[64]; @@ -152,9 +158,76 @@ CODESTARTstrgen memcpy(*ppBuf, ";", sizeof(";")); /* first obtain all strings and their length (if not fixed) */ - pTimeStamp = (uchar*) getTimeReported(pMsg, tplFmtRFC3339Date); - lenTimeStamp = ustrlen(pTimeStamp); - + /* Note that there are two date fields present, one in the header + * and one more in the actual message. We use the one from the message + * and parse that our. We check validity based on some fixe fields. In- + * depth verification is probably not worth the effort (CPU time), because + * we do various other checks on the message format below). + */ + psz = getMSG(pMsg); + if(psz[0] == ' ' && psz[3] == '-' && psz[7] == '-') { + memcpy(szDate, psz+8, 4); + szDate[4] = '-'; + if(!strncmp((char*)psz+4, "Jan", 3)) { + szDate[5] = '0'; + szDate[6] = '1'; + } else if(!strncmp((char*)psz+4, "Feb", 3)) { + szDate[5] = '0'; + szDate[6] = '2'; + } else if(!strncmp((char*)psz+4, "Mar", 3)) { + szDate[5] = '0'; + szDate[6] = '3'; + } else if(!strncmp((char*)psz+4, "Apr", 3)) { + szDate[5] = '0'; + szDate[6] = '4'; + } else if(!strncmp((char*)psz+4, "May", 3)) { + szDate[5] = '0'; + szDate[6] = '5'; + } else if(!strncmp((char*)psz+4, "Jun", 3)) { + szDate[5] = '0'; + szDate[6] = '6'; + } else if(!strncmp((char*)psz+4, "Jul", 3)) { + szDate[5] = '0'; + szDate[6] = '7'; + } else if(!strncmp((char*)psz+4, "Aug", 3)) { + szDate[5] = '0'; + szDate[6] = '8'; + } else if(!strncmp((char*)psz+4, "Sep", 3)) { + szDate[5] = '0'; + szDate[6] = '9'; + } else if(!strncmp((char*)psz+4, "Oct", 3)) { + szDate[5] = '1'; + szDate[6] = '0'; + } else if(!strncmp((char*)psz+4, "Nov", 3)) { + szDate[5] = '1'; + szDate[6] = '1'; + } else if(!strncmp((char*)psz+4, "Dec", 3)) { + szDate[5] = '1'; + szDate[6] = '2'; + } + szDate[7] = '-'; + szDate[8] = psz[1]; + szDate[9] = psz[2]; + szDate[10] = '\0'; + lenDate = 10; + } else { + dbgprintf("Custom_BindCDR: date part in msg missing\n"); + FINALIZE; + } + + /* now time (pull both regular time and ms) */ + if(psz[12] == ' ' && psz[15] == ':' && psz[18] == ':' && psz[21] == '.' && psz[25] == ' ') { + memcpy(szTime, (char*)psz+13, 8); + szTime[9] = '\0'; + lenTime = 8; + memcpy(szMSec, (char*)psz+22, 3); + szMSec[4] = '\0'; + lenMSec = 3; + } else { + dbgprintf("Custom_BindCDR: date part in msg missing\n"); + FINALIZE; + } + /* "client" */ psz = (uchar*) strstr((char*) getMSG(pMsg), "client "); if(psz == NULL) { @@ -233,8 +306,8 @@ CODESTARTstrgen } /* calculate len, constants for spaces and similar fixed strings */ - lenTotal = lenTimeStamp + lenClient + lenView + lenQuery + lenIP + 5 * 5 - + sizeof(SQL_STMT) + sizeof(SQL_STMT_END) + 2; + lenTotal = lenDate + lenTime + lenMSec + lenClient + lenView + lenQuery + + lenIP + 7 * 5 + sizeof(SQL_STMT) + sizeof(SQL_STMT_END) + 2; /* now make sure buffer is large enough */ if(lenTotal >= *pLenBuf) @@ -246,8 +319,16 @@ CODESTARTstrgen // SQL content:DATE,TIME,CLIENT,VIEW,QUERY,IP); - memcpy(*ppBuf + iBuf, pTimeStamp, lenTimeStamp); - iBuf += lenTimeStamp; + memcpy(*ppBuf + iBuf, szDate, lenDate); + iBuf += lenDate; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szTime, lenTime); + iBuf += lenTime; + ADD_SQL_DELIM + + memcpy(*ppBuf + iBuf, szMSec, lenMSec); + iBuf += lenMSec; ADD_SQL_DELIM memcpy(*ppBuf + iBuf, szClient, lenClient); @@ -264,7 +345,6 @@ CODESTARTstrgen memcpy(*ppBuf + iBuf, szIP, lenIP); iBuf += lenIP; - ADD_SQL_DELIM /* end of SQL statement/trailer (NUL is contained in string!) */ memcpy(*ppBuf + iBuf, SQL_STMT_END, sizeof(SQL_STMT_END)); -- cgit From 030fd145a3d8759367b73cc66e03023ff131c951 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 29 Mar 2011 11:50:32 +0200 Subject: did mapping of data items to database table columns to facilitate testing --- plugins/sm_cust_bindcdr/sm_cust_bindcdr.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'plugins') diff --git a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c index fa16acb5..3fe96ac4 100644 --- a/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c +++ b/plugins/sm_cust_bindcdr/sm_cust_bindcdr.c @@ -79,7 +79,6 @@ isAllowed(uchar *pszIP) int ret = 0; for(pallow = root ; pallow != NULL ; pallow = pallow->next) { - DBGPRINTF("XXXX: checking allowed IP '%s'\n", pallow->pszIP); if(!ustrcmp(pallow->pszIP, pszIP)) { ret = 1; goto finalize_it; @@ -123,9 +122,7 @@ finalize_it: * An actual message sample for what we intend to parse is (one line): <30>Mar 24 13:01:51 named[6085]: 24-Mar-2011 13:01:51.865 queries: info: client 10.0.0.96#39762: view trusted: query: 8.6.0.9.9.4.1.4.6.1.8.3.mobilecrawler.com IN TXT + (10.0.0.96) */ -//#define SQL_STMT "INSERT INTO CDR(date,time,client,view,query,ip) VALUES ('" -//#define SQL_STMT "INSERT INTO bind_test(`Date`,`time`,client,view,query,ip) VALUES ('" -#define SQL_STMT "INSERT INTO bind_test(`Date`,ip) VALUES ('" +#define SQL_STMT "INSERT INTO CDR(`Date`,`Time`, timeMS, client, view, query, ip) VALUES ('" #define ADD_SQL_DELIM \ memcpy(*ppBuf + iBuf, "', '", sizeof("', '") - 1); \ iBuf += sizeof("', '") - 1; @@ -212,7 +209,7 @@ CODESTARTstrgen lenDate = 10; } else { dbgprintf("Custom_BindCDR: date part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } /* now time (pull both regular time and ms) */ @@ -225,14 +222,14 @@ CODESTARTstrgen lenMSec = 3; } else { dbgprintf("Custom_BindCDR: date part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } /* "client" */ psz = (uchar*) strstr((char*) getMSG(pMsg), "client "); if(psz == NULL) { dbgprintf("Custom_BindCDR: client part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } else { psz += sizeof("client ") - 1; /* skip "label" */ for( lenClient = 0 @@ -247,7 +244,7 @@ CODESTARTstrgen psz = (uchar*) strstr((char*) getMSG(pMsg), "view "); if(psz == NULL) { dbgprintf("Custom_BindCDR: view part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } else { psz += sizeof("view ") - 1; /* skip "label" */ for( lenView = 0 @@ -262,10 +259,10 @@ CODESTARTstrgen psz = (uchar*) strstr((char*) getMSG(pMsg), "query: "); if(psz == NULL) { dbgprintf("Custom_BindCDR: query part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } else { psz += sizeof("query: ") - 1; /* skip "label" */ - /* first find end-of-string to process */ + /* first find end-of-strihttp://www.rsyslog.com/doc/omruleset.htmlng to process */ while(*psz && (isdigit(*psz) || *psz == '.')) { psz++; } @@ -283,7 +280,7 @@ CODESTARTstrgen psz = (uchar*) strstr((char*) getMSG(pMsg), "IN TXT + ("); if(psz == NULL) { dbgprintf("Custom_BindCDR: ip part in msg missing\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } else { psz += sizeof("IN TXT + (") - 1; /* skip "label" */ for( lenIP = 0 @@ -302,7 +299,7 @@ CODESTARTstrgen */ if(isAllowed(szIP)) { DBGPRINTF("sm_cust_bindcdr: message from allowed IP, ignoring\n"); - FINALIZE; + ABORT_FINALIZE(RS_RET_ERR); } /* calculate len, constants for spaces and similar fixed strings */ @@ -317,8 +314,6 @@ CODESTARTstrgen memcpy(*ppBuf, SQL_STMT, sizeof(SQL_STMT) - 1); iBuf = sizeof(SQL_STMT) - 1; - // SQL content:DATE,TIME,CLIENT,VIEW,QUERY,IP); - memcpy(*ppBuf + iBuf, szDate, lenDate); iBuf += lenDate; ADD_SQL_DELIM -- cgit From 9003632c7df5e6020b06b7d19e1c226ea46640de Mon Sep 17 00:00:00 2001 From: Christian Kastner Date: Tue, 29 Mar 2011 12:00:56 +0200 Subject: Force ANSI SQL treatment of strings for Postgres Signed-off-by: Rainer Gerhards --- plugins/ompgsql/ompgsql.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/ompgsql/ompgsql.c b/plugins/ompgsql/ompgsql.c index ab8e4d2c..ea4b4b75 100644 --- a/plugins/ompgsql/ompgsql.c +++ b/plugins/ompgsql/ompgsql.c @@ -149,8 +149,13 @@ static rsRetVal initPgSQL(instanceData *pData, int bSilent) dbgprintf("host=%s dbname=%s uid=%s\n",pData->f_dbsrv,pData->f_dbname,pData->f_dbuid); + /* Force PostgreSQL to use ANSI-SQL conforming strings, otherwise we may + * get all sorts of side effects (e.g.: backslash escapes) and warnings + */ + const char *PgConnectionOptions = "-c standard_conforming_strings=on"; + /* Connect to database */ - if((pData->f_hpgsql=PQsetdbLogin(pData->f_dbsrv, NULL, NULL, NULL, + if((pData->f_hpgsql=PQsetdbLogin(pData->f_dbsrv, NULL, PgConnectionOptions, NULL, pData->f_dbname, pData->f_dbuid, pData->f_dbpwd)) == NULL) { reportDBError(pData, bSilent); closePgSQL(pData); /* ignore any error we may get */ -- cgit From b59f8fd65d4f464ce3673439725db1606ec31329 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 30 Mar 2011 11:19:22 +0200 Subject: fixed problem in testbench & added new test (not yet integrated) The test is a setup scenario for this bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=241 --- plugins/imdiag/imdiag.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c index 404cebc7..ed6ef509 100644 --- a/plugins/imdiag/imdiag.c +++ b/plugins/imdiag/imdiag.c @@ -205,7 +205,7 @@ doInjectMsg(int iNum) DEFiRet; snprintf((char*)szMsg, sizeof(szMsg)/sizeof(uchar), - "<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:\n", iNum); + "<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:", iNum); datetime.getCurrTime(&stTime, &ttGenTime); /* we now create our own message object and submit it to the queue */ @@ -247,6 +247,7 @@ injectMsg(uchar *pszCmd, tcps_sess_t *pSess) } CHKiRet(sendResponse(pSess, "%d messages injected\n", nMsgs)); + DBGPRINTF("imdiag: %d messages injected\n", nMsgs); finalize_it: RETiRet; @@ -279,6 +280,7 @@ waitMainQEmpty(tcps_sess_t *pSess) } CHKiRet(sendResponse(pSess, "mainqueue empty\n")); + DBGPRINTF("imdiag: mainqueue empty\n"); finalize_it: RETiRet; @@ -314,6 +316,7 @@ OnMsgReceived(tcps_sess_t *pSess, uchar *pRcv, int iLenMsg) if(!ustrcmp(cmdBuf, UCHAR_CONSTANT("getmainmsgqueuesize"))) { CHKiRet(diagGetMainMsgQSize(&iMsgQueueSize)); CHKiRet(sendResponse(pSess, "%d\n", iMsgQueueSize)); + DBGPRINTF("imdiag: %d messages in main queue\n", iMsgQueueSize); } else if(!ustrcmp(cmdBuf, UCHAR_CONSTANT("waitmainqueueempty"))) { CHKiRet(waitMainQEmpty(pSess)); } else if(!ustrcmp(cmdBuf, UCHAR_CONSTANT("injectmsg"))) { -- cgit