Blob Blame History Raw
From 9ac54f0d7d70b8a9879889b4522a1d552fca1100 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@momo7.localdomain>
Date: Thu, 12 Jul 2018 11:52:04 -0700
Subject: [PATCH] Introducing an option preservecase to imudp and imtcp module
 for managing the case of FROMHOST value.

Usage:
module(load="imudp" [preservecase="on"|"off"])
module(load="imtdp" [preservecase="on"|"off"])

If preservecase="on", FROMHOST value is handled in the case sensitive manner.
If preservecase="off", FROMHOST value is handled in the case insensitive manner.

To maintain the current behaviour, the default value of preservecase is
"on" for imtcp and "off" for imudp.

Incremented tcpsrvCURR_IF_VERSION by 1.

References:
https://github.com/rsyslog/rsyslog/pull/2774
https://bugzilla.redhat.com/show_bug.cgi?id=1309698
---
 plugins/imtcp/imtcp.c | 14 ++++++++++++--
 plugins/imudp/imudp.c | 15 ++++++++++++---
 runtime/msg.c         |  6 +++++-
 runtime/msg.h         |  2 ++
 runtime/net.c         |  2 +-
 runtime/tcpsrv.c      | 21 +++++++++++++++++++++
 runtime/tcpsrv.h      |  5 ++++-
 7 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 8e3dcc0a2..45fa240b5 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -100,6 +100,7 @@ static struct configSettings_s {
 	int bDisableLFDelim;
 	int discardTruncatedMsg;
 	int bUseFlowControl;
+	int bPreserveCase;
 	uchar *gnutlsPriorityString;
 	uchar *pszStrmDrvrAuthMode;
 	uchar *pszInputName;
@@ -144,6 +145,7 @@ struct modConfData_s {
 	uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
 	struct cnfarray *permittedPeers;
 	sbool configSetViaV2Method;
+	sbool bPreserveCase; /* preserve case of fromhost; true by default */
 };
 
 static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
@@ -169,7 +171,8 @@ static struct cnfparamdescr modpdescr[] = {
 	{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
 	{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
 	{ "keepalive.interval", eCmdHdlrPositiveInt, 0 },
-	{ "gnutlsprioritystring", eCmdHdlrString, 0 }
+	{ "gnutlsprioritystring", eCmdHdlrString, 0 },
+	{ "preservecase", eCmdHdlrBinary, 0 }
 };
 static struct cnfparamblk modpblk =
 	{ CNFPARAMBLK_VERSION,
@@ -375,6 +378,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
 		if(pPermPeersRoot != NULL) {
 			CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
 		}
+		CHKiRet(tcpsrv.SetPreserveCase(pOurTcpsrv, modConf->bPreserveCase));
 	}
 
 	/* initialized, now add socket and listener params */
@@ -473,6 +477,7 @@ CODESTARTbeginCnfLoad
 	loadModConf->pszStrmDrvrAuthMode = NULL;
 	loadModConf->permittedPeers = NULL;
 	loadModConf->configSetViaV2Method = 0;
+	loadModConf->bPreserveCase = 1; /* default to true */
 	bLegacyCnfModGlobalsPermitted = 1;
 	/* init legacy config variables */
 	cs.pszStrmDrvrAuthMode = NULL;
@@ -543,6 +548,8 @@ CODESTARTsetModCnf
 			loadModConf->pszStrmDrvrName = (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 if(!strcmp(modpblk.descr[i].name, "preservecase")) {
+			loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
 		} else {
 			dbgprintf("imtcp: program error, non-handled "
 			  "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
@@ -584,6 +591,7 @@ CODESTARTendCnfLoad
 			loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode;
 			cs.pszStrmDrvrAuthMode = NULL;
 		}
+		pModConf->bPreserveCase = cs.bPreserveCase;
 	}
 	free(cs.pszStrmDrvrAuthMode);
 	cs.pszStrmDrvrAuthMode = NULL;
@@ -731,6 +739,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
 	cs.pszInputName = NULL;
 	free(cs.pszStrmDrvrAuthMode);
 	cs.pszStrmDrvrAuthMode = NULL;
+	cs.bPreserveCase = 1;
 	return RS_RET_OK;
 }
 
@@ -797,7 +806,8 @@ CODEmodInit_QueryRegCFSLineHdlr
 			   NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
 	CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt,
 			   NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
-
+	CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverpreservecase"), 1, eCmdHdlrBinary,
+			   NULL, &cs.bPreserveCase, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
 	CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
 				   resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
 ENDmodInit
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 51a9d712a..74437781c 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -152,6 +152,7 @@ struct modConfData_s {
 	int batchSize;			/* max nbr of input batch --> also recvmmsg() max count */
 	int8_t wrkrMax;			/* max nbr of worker threads */
 	sbool configSetViaV2Method;
+	sbool bPreserveCase;	/* preserves the case of fromhost; "off" by default */
 };
 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 */
@@ -162,7 +163,8 @@ static struct cnfparamdescr modpdescr[] = {
 	{ "schedulingpriority", eCmdHdlrInt, 0 },
 	{ "batchsize", eCmdHdlrInt, 0 },
 	{ "threads", eCmdHdlrPositiveInt, 0 },
-	{ "timerequery", eCmdHdlrInt, 0 }
+	{ "timerequery", eCmdHdlrInt, 0 },
+	{ "preservecase", eCmdHdlrBinary, 0 }
 };
 static struct cnfparamblk modpblk =
 	{ CNFPARAMBLK_VERSION,
@@ -447,8 +449,12 @@ processPacket(struct lstn_s *lstn, struct sockaddr_storage *frominetPrev, int *p
 		if(lstn->dfltTZ != NULL)
 			MsgSetDfltTZ(pMsg, (char*) lstn->dfltTZ);
 		pMsg->msgFlags  = NEEDS_PARSING | PARSE_HOSTNAME | NEEDS_DNSRESOL;
-		if(*pbIsPermitted == 2)
-			pMsg->msgFlags  |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
+		if(*pbIsPermitted == 2) {
+			pMsg->msgFlags |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
+		}
+		if(runModConf->bPreserveCase) {
+			pMsg->msgFlags |= PRESERVE_CASE; /* preserve case of fromhost */
+		}
 		CHKiRet(msgSetFromSockinfo(pMsg, frominet));
 		CHKiRet(ratelimitAddMsg(lstn->ratelimiter, multiSub, pMsg));
 		STATSCOUNTER_INC(lstn->ctrSubmit, lstn->mutCtrSubmit);
@@ -1030,6 +1036,7 @@ CODESTARTbeginCnfLoad
 	loadModConf->iTimeRequery = TIME_REQUERY_DFLT;
 	loadModConf->iSchedPrio = SCHED_PRIO_UNSET;
 	loadModConf->pszSchedPolicy = NULL;
+	loadModConf->bPreserveCase = 0; /* off */
 	bLegacyCnfModGlobalsPermitted = 1;
 	/* init legacy config vars */
 	cs.pszBindRuleset = NULL;
@@ -1079,6 +1086,8 @@ CODESTARTsetModCnf
 			} else {
 				loadModConf->wrkrMax = wrkrMax;
 			}
+		} else if(!strcmp(modpblk.descr[i].name, "preservecase")) {
+			loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
 		} else {
 			dbgprintf("imudp: program error, non-handled "
 			  "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
diff --git a/runtime/msg.c b/runtime/msg.c
index c43f81314..9ed4eaf84 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -506,7 +506,11 @@ resolveDNS(smsg_t * const pMsg) {
 	MsgLock(pMsg);
 	CHKiRet(objUse(net, CORE_COMPONENT));
 	if(pMsg->msgFlags & NEEDS_DNSRESOL) {
-		localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
+		if (pMsg->msgFlags & PRESERVE_CASE) {
+			localRet = net.cvthname(pMsg->rcvFrom.pfrominet, NULL, &localName, &ip);
+		} else {
+			localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
+		}
 		if(localRet == RS_RET_OK) {
 			/* we pass down the props, so no need for AddRef */
 			MsgSetRcvFromWithoutAddRef(pMsg, localName);
diff --git a/runtime/msg.h b/runtime/msg.h
index cd530aca3..1287cb7a4 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -156,6 +156,8 @@ struct msg {
 /* check UDP ACLs after DNS resolution has been done in main queue consumer */
 #define NO_PRI_IN_RAW	0x100
 /* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
+#define PRESERVE_CASE	0x200
+/* preserve case in fromhost */
 
 /* (syslog) protocol types */
 #define MSG_LEGACY_PROTOCOL 0
diff --git a/runtime/net.c b/runtime/net.c
index d6ff8a3d4..aef906601 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -1152,7 +1152,7 @@ cvthname(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t *
 {
 	DEFiRet;
 	assert(f != NULL);
-	iRet = dnscacheLookup(f, NULL, fqdn, localName, ip);
+	iRet = dnscacheLookup(f, fqdn, NULL, localName, ip);
 	RETiRet;
 }
 
diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c
index 61e9ff4d2..d5993b4f0 100644
--- a/runtime/tcpsrv.c
+++ b/runtime/tcpsrv.c
@@ -495,6 +495,15 @@ SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess,
 
 	/* get the host name */
 	CHKiRet(netstrm.GetRemoteHName(pNewStrm, &fromHostFQDN));
+	if (!pThis->bPreserveCase) {
+		/* preserve_case = off */
+		uchar *p;
+		for(p = fromHostFQDN; *p; p++) {
+			if (isupper((int) *p)) {
+				*p = tolower((int) *p);
+			}
+		}
+	}
 	CHKiRet(netstrm.GetRemoteIP(pNewStrm, &fromHostIP));
 	CHKiRet(netstrm.GetRemAddr(pNewStrm, &addr));
 	/* TODO: check if we need to strip the domain name here -- rgerhards, 2008-04-24 */
@@ -1001,6 +1010,7 @@ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macr
 	pThis->ratelimitBurst = 10000;
 	pThis->bUseFlowControl = 1;
 	pThis->pszDrvrName = NULL;
+	pThis->bPreserveCase = 1; /* preserve case in fromhost; default to true. */
 ENDobjConstruct(tcpsrv)
 
 
@@ -1433,6 +1443,16 @@ SetSessMax(tcpsrv_t *pThis, int iMax)
 }
 
 
+static rsRetVal
+SetPreserveCase(tcpsrv_t *pThis, int bPreserveCase)
+{
+	DEFiRet;
+	ISOBJ_TYPE_assert(pThis, tcpsrv);
+	pThis-> bPreserveCase = bPreserveCase;
+	RETiRet;
+}
+
+
 /* queryInterface function
  * rgerhards, 2008-02-29
  */
@@ -1491,6 +1511,7 @@ CODESTARTobjQueryInterface(tcpsrv)
 	pIf->SetRuleset = SetRuleset;
 	pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters;
 	pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose;
+	pIf->SetPreserveCase = SetPreserveCase;
 
 finalize_it:
 ENDobjQueryInterface(tcpsrv)
diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h
index 22a65c20a..f17b1b438 100644
--- a/runtime/tcpsrv.h
+++ b/runtime/tcpsrv.h
@@ -85,6 +85,7 @@ struct tcpsrv_s {
 	int maxFrameSize;	/**< max frame size for octet counted*/
 	int bDisableLFDelim;	/**< if 1, standard LF frame delimiter is disabled (*very dangerous*) */
 	int discardTruncatedMsg;/**< discard msg part that has been truncated*/
+	sbool bPreserveCase;	/**< preserve case in fromhost */
 	int ratelimitInterval;
 	int ratelimitBurst;
 	tcps_sess_t **pSessions;/**< array of all of our sessions */
@@ -177,8 +178,10 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
 	rsRetVal (*SetbSPFramingFix)(tcpsrv_t*, sbool);
 	/* added v19 -- PascalWithopf, 2017-08-08 */
 	rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
+	/* added v21 -- Preserve case in fromhost, 2018-08-16 */
+	rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
 ENDinterface(tcpsrv)
-#define tcpsrvCURR_IF_VERSION 20 /* increment whenever you change the interface structure! */
+#define tcpsrvCURR_IF_VERSION 21 /* increment whenever you change the interface structure! */
 /* change for v4:
  * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
  * - SetInputName() added -- rgerhards, 2008-12-10