diff options
Diffstat (limited to 'plugins/omudpspoof/omudpspoof.c')
-rw-r--r-- | plugins/omudpspoof/omudpspoof.c | 227 |
1 files changed, 184 insertions, 43 deletions
diff --git a/plugins/omudpspoof/omudpspoof.c b/plugins/omudpspoof/omudpspoof.c index 43cfe287..a45d49fa 100644 --- a/plugins/omudpspoof/omudpspoof.c +++ b/plugins/omudpspoof/omudpspoof.c @@ -83,6 +83,7 @@ MODULE_TYPE_OUTPUT MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omudpspoof") /* internal structures */ @@ -105,14 +106,45 @@ typedef struct _instanceData { #define DFLT_SOURCE_PORT_START 32000 #define DFLT_SOURCE_PORT_END 42000 -/* config data */ -static uchar *pszTplName = NULL; /* name of the default template to use */ -static uchar *pszSourceNameTemplate = NULL; /* name of the template containing the spoofing address */ -static uchar *pszTargetHost = NULL; -static uchar *pszTargetPort = NULL; -static int iCompressionLevel = 0; /* zlib compressionlevel, the usual values */ -static int iSourcePortStart = DFLT_SOURCE_PORT_START; -static int iSourcePortEnd = DFLT_SOURCE_PORT_END; +typedef struct configSettings_s { + uchar *tplName; /* name of the default template to use */ + uchar *pszSourceNameTemplate; /* name of the template containing the spoofing address */ + uchar *pszTargetHost; + uchar *pszTargetPort; + int iSourcePortStart; + int iSourcePortEnd; +} configSettings_t; +static configSettings_t cs; + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "template", eCmdHdlrGetWord, 0 }, +}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + uchar *tplName; /* default template */ +}; + +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 exec process */ + + + +BEGINinitConfVars /* (re)set config variables to default values */ +CODESTARTinitConfVars + cs.tplName = NULL; + cs.pszSourceNameTemplate = NULL; + cs.pszTargetHost = NULL; + cs.pszTargetPort = NULL; + cs.iSourcePortStart = DFLT_SOURCE_PORT_START; + cs.iSourcePortEnd = DFLT_SOURCE_PORT_END; +ENDinitConfVars /* add some variables needed for libnet */ @@ -124,6 +156,44 @@ pthread_mutex_t mutLibnet; static rsRetVal doTryResume(instanceData *pData); +/* this function gets the default template. It coordinates action between + * old-style and new-style configuration parts. + */ +static inline uchar* +getDfltTpl(void) +{ + if(loadModConf != NULL && loadModConf->tplName != NULL) + return loadModConf->tplName; + else if(cs.tplName == NULL) + return (uchar*)"RSYSLOG_FileFormat"; + else + return cs.tplName; +} + + +/* set the default template to be used + * This is a module-global parameter, and as such needs special handling. It needs to + * be coordinated with values set via the v2 config system (rsyslog v6+). What we do + * is we do not permit this directive after the v2 config system has been used to set + * the parameter. + */ +rsRetVal +setLegacyDfltTpl(void __attribute__((unused)) *pVal, uchar* newVal) +{ + DEFiRet; + + if(loadModConf != NULL && loadModConf->tplName != NULL) { + free(newVal); + errmsg.LogError(0, RS_RET_ERR, "omudpspoof default template already set via module " + "global parameter - can no longer be changed"); + ABORT_FINALIZE(RS_RET_ERR); + } + free(cs.tplName); + cs.tplName = newVal; +finalize_it: + RETiRet; +} + /* Close the UDP sockets. * rgerhards, 2009-05-29 */ @@ -153,6 +223,72 @@ static inline uchar *getFwdPt(instanceData *pData) } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + pModConf->tplName = NULL; +ENDbeginCnfLoad + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for omudpspoof:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "template")) { + loadModConf->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + if(cs.tplName != NULL) { + errmsg.LogError(0, RS_RET_DUP_PARAM, "omudpspoof: warning: default template " + "was already set via legacy directive - may lead to inconsistent " + "results."); + } + } else { + dbgprintf("omudpspoof: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +BEGINendCnfLoad +CODESTARTendCnfLoad + loadModConf = NULL; /* done loading */ + /* free legacy config vars */ + free(cs.tplName); + cs.tplName = NULL; +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf + free(pModConf->tplName); +ENDfreeCnf + + BEGINcreateInstance CODESTARTcreateInstance ENDcreateInstance @@ -217,7 +353,7 @@ UDPSend(instanceData *pData, uchar *pszSourcename, char *msg, size_t len) bSendSuccess = RSFALSE; d_pthread_mutex_lock(&mutLibnet); bNeedUnlock = 1; - for (r = pData->f_addr; r; r = r->ai_next) { + for (r = pData->f_addr; r && bSendSuccess == RSFALSE ; r = r->ai_next) { tempaddr = (struct sockaddr_in *)r->ai_addr; libnet_clear_packet(libnet_handle); /* note: libnet does need ports in host order NOT in network byte order! -- rgerhards, 2009-11-12 */ @@ -231,7 +367,7 @@ UDPSend(instanceData *pData, uchar *pszSourcename, char *msg, size_t len) libnet_handle, /* libnet handle */ udp); /* libnet id */ if (udp == -1) { - DBGPRINTF("Can't build UDP header: %s\n", libnet_geterror(libnet_handle)); + DBGPRINTF("omudpspoof: can't build UDP header: %s\n", libnet_geterror(libnet_handle)); } ip = libnet_build_ipv4( @@ -249,21 +385,24 @@ UDPSend(instanceData *pData, uchar *pszSourcename, char *msg, size_t len) libnet_handle, /* libnet handle */ ip); /* libnet id */ if (ip == -1) { - DBGPRINTF("Can't build IP header: %s\n", libnet_geterror(libnet_handle)); + DBGPRINTF("omudpspoof: can't build IP header: %s\n", libnet_geterror(libnet_handle)); } /* Write it to the wire. */ lsent = libnet_write(libnet_handle); - if (lsent == -1) { - DBGPRINTF("omudpspoof: write error: %s\n", libnet_geterror(libnet_handle)); + if(lsent != LIBNET_IPV4_H+LIBNET_UDP_H+len) { + DBGPRINTF("omudpspoof: write error len %d, sent %d: %s\n", + LIBNET_IPV4_H+LIBNET_UDP_H+len, lsent, libnet_geterror(libnet_handle)); + if(lsent != -1) { + bSendSuccess = RSTRUE; + } } else { bSendSuccess = RSTRUE; - break; } } /* finished looping */ - if (bSendSuccess == RSFALSE) { - DBGPRINTF("error forwarding via udp, suspending\n"); + if(bSendSuccess == RSFALSE) { + DBGPRINTF("omudpspoof: error sending message, suspending\n"); iRet = RS_RET_SUSPENDED; } @@ -331,7 +470,9 @@ CODESTARTdoAction iMaxLine = glbl.GetMaxLine(); - DBGPRINTF(" %s:%s/udpspoofs\n", pData->host, getFwdPt(pData)); + //TODO: enable THIS one! DBGPRINTF(" %s:%s/omudpspoof, src '%s', msg strt '%.256s'\n", pData->host, + DBGPRINTF(" %s:%s/omudpspoof, src '%s', msg strt '%s'\n", pData->host, + getFwdPt(pData), ppString[1], ppString[0]); psz = (char*) ppString[0]; l = strlen((char*) psz); @@ -398,28 +539,27 @@ CODE_STD_STRING_REQUESTparseSelectorAct(2) p += sizeof(":omudpspoof:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ CHKiRet(createInstance(&pData)); - sourceTpl = (pszSourceNameTemplate == NULL) ? UCHAR_CONSTANT("RSYSLOG_omudpspoofDfltSourceTpl") - : pszSourceNameTemplate; + sourceTpl = (cs.pszSourceNameTemplate == NULL) ? UCHAR_CONSTANT("RSYSLOG_omudpspoofDfltSourceTpl") + : cs.pszSourceNameTemplate; - if(pszTargetHost == NULL) { + if(cs.pszTargetHost == NULL) { errmsg.LogError(0, NO_ERRCODE, "No $ActionOMUDPSpoofTargetHost given, can not continue with this action."); ABORT_FINALIZE(RS_RET_HOST_NOT_SPECIFIED); } /* fill instance properties */ - CHKmalloc(pData->host = ustrdup(pszTargetHost)); - if(pszTargetPort == NULL) + CHKmalloc(pData->host = ustrdup(cs.pszTargetHost)); + if(cs.pszTargetPort == NULL) pData->port = NULL; else - CHKmalloc(pData->port = ustrdup(pszTargetPort)); + CHKmalloc(pData->port = ustrdup(cs.pszTargetPort)); CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(sourceTpl), OMSR_NO_RQD_TPL_OPTS)); - pData->compressionLevel = iCompressionLevel; - pData->sourcePort = pData->sourcePortStart = iSourcePortStart; - pData->sourcePortEnd = iSourcePortEnd; + pData->sourcePort = pData->sourcePortStart = cs.iSourcePortStart; + pData->sourcePortEnd = cs.iSourcePortEnd; /* process template */ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, - (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName)); + (cs.tplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : cs.tplName)); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct @@ -431,12 +571,12 @@ ENDparseSelectorAct static void freeConfigVars(void) { - free(pszTplName); - pszTplName = NULL; - free(pszTargetHost); - pszTargetHost = NULL; - free(pszTargetPort); - pszTargetPort = NULL; + free(cs.tplName); + cs.tplName = NULL; + free(cs.pszTargetHost); + cs.pszTargetHost = NULL; + free(cs.pszTargetPort); + cs.pszTargetPort = NULL; } @@ -456,6 +596,8 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES ENDqueryEtryPt @@ -466,15 +608,15 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a { freeConfigVars(); /* we now must reset all non-string values */ - iCompressionLevel = 0; - iSourcePortStart = DFLT_SOURCE_PORT_START; - iSourcePortEnd = DFLT_SOURCE_PORT_END; + cs.iSourcePortStart = DFLT_SOURCE_PORT_START; + cs.iSourcePortEnd = DFLT_SOURCE_PORT_END; return RS_RET_OK; } BEGINmodInit() CODESTARTmodInit +INITLegCnfVars *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); @@ -495,13 +637,12 @@ CODEmodInit_QueryRegCFSLineHdlr } pthread_mutex_init(&mutLibnet, NULL); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofdefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourcenametemplate", 0, eCmdHdlrGetWord, NULL, &pszSourceNameTemplate, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargethost", 0, eCmdHdlrGetWord, NULL, &pszTargetHost, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargetport", 0, eCmdHdlrGetWord, NULL, &pszTargetPort, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportstart", 0, eCmdHdlrInt, NULL, &iSourcePortStart, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportend", 0, eCmdHdlrInt, NULL, &iSourcePortEnd, NULL)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpcompressionlevel", 0, eCmdHdlrInt, NULL, &iCompressionLevel, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofdefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourcenametemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszSourceNameTemplate, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargethost", 0, eCmdHdlrGetWord, NULL, &cs.pszTargetHost, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspooftargetport", 0, eCmdHdlrGetWord, NULL, &cs.pszTargetPort, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportstart", 0, eCmdHdlrInt, NULL, &cs.iSourcePortStart, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionomudpspoofsourceportend", 0, eCmdHdlrInt, NULL, &cs.iSourcePortEnd, NULL)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit |