summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-06-23 16:14:19 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-06-23 16:14:19 +0200
commit86e37f70fe0e9de0e00362990c73536843c8fef3 (patch)
treed39609114407368847b1c7142187cb4e08820fda
parentb1f2e53921b7ab19c363a63de47a0e7a35866052 (diff)
downloadrsyslog-86e37f70fe0e9de0e00362990c73536843c8fef3.tar.gz
rsyslog-86e37f70fe0e9de0e00362990c73536843c8fef3.tar.xz
rsyslog-86e37f70fe0e9de0e00362990c73536843c8fef3.zip
more strict parsing of the hostname in rfc3164 mode
... hopefully removes false positives (but may cause some trouble with hostname parsing). For details, see this bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=126 This patch is not optimal for v4 - another one will follow. The spirit of this commit is to enable easier backporting if someone is interested in doing so.
-rw-r--r--ChangeLog8
-rw-r--r--runtime/msg.h2
-rw-r--r--runtime/rsyslog.h12
-rw-r--r--tools/syslogd.c114
4 files changed, 57 insertions, 79 deletions
diff --git a/ChangeLog b/ChangeLog
index 36a819a3..46235ff7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,5 @@
---------------------------------------------------------------------------
-Version 4.3.2 [DEVEL] (rgerhards), 2009-??-??
+Version 4.5.0 [DEVEL] (rgerhards), 2009-??-??
- greatly reduced memory requirements of msg object
to around half of the previous demand. This means that more messages can
be stored in core! Due to fewer cache misses, this also means some
@@ -22,6 +22,10 @@ Version 4.3.2 [DEVEL] (rgerhards), 2009-??-??
- added capability to fsync() queue disk files for enhanced reliability
(also add's speed, because you do no longer need to run the whole file
system in sync mode)
+- more strict parsing of the hostname in rfc3164 mode, hopefully
+ removes false positives (but may cause some trouble with hostname
+ parsing). For details, see this bug tracker:
+ http://bugzilla.adiscon.com/show_bug.cgi?id=126
- added configuration commands (see doc for explanations)
* $OMFileZipLevel
* $OMFileIOBufferSize
@@ -29,6 +33,8 @@ Version 4.3.2 [DEVEL] (rgerhards), 2009-??-??
* $MainMsgQueueSyncQueueFiles
* $ActionQueueSyncQueueFiles
---------------------------------------------------------------------------
+Version 4.3.2 [beta] (rgerhards), 2009-??-??
+---------------------------------------------------------------------------
Version 4.3.1 [DEVEL] (rgerhards), 2009-05-25
- added capability to run multiple tcp listeners (on different ports)
- performance enhancement: imtcp calls parser no longer on input thread
diff --git a/runtime/msg.h b/runtime/msg.h
index c38cb788..d70b939a 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -152,7 +152,7 @@ rsRetVal MsgSetFlowControlType(msg_t *pMsg, flowControl_t eFlowCtl);
rsRetVal MsgSetStructuredData(msg_t *pMsg, char* pszStrucData);
void MsgSetRcvFrom(msg_t *pMsg, uchar* pszRcvFrom);
rsRetVal MsgSetRcvFromIP(msg_t *pMsg, uchar* pszRcvFromIP);
-void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf);
+//void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf);
void MsgSetHOSTNAME(msg_t *pMsg, uchar* pszHOSTNAME);
rsRetVal MsgSetAfterPRIOffs(msg_t *pMsg, short offs);
void MsgSetMSGoffs(msg_t *pMsg, short offs);
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 793df782..4fa5100e 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -29,10 +29,14 @@
/* ############################################################# *
* # Config Settings # *
* ############################################################# */
-#define RS_STRINGBUF_ALLOC_INCREMENT 128
-#define CONF_TAG_MAXSIZE 512 /* a value that is deemed far too large for any valid TAG */
-#define CONF_RAWMSG_BUFSIZE 101
-#define CONF_TAG_BUFSIZE 33 /* RFC says 32 chars (+ \0), but in practice we see longer ones... */
+#define RS_STRINGBUF_ALLOC_INCREMENT 128
+/* MAXSIZE are absolute maxima, while BUFSIZE are just values after which
+ * processing is more time-intense.
+ */
+#define CONF_TAG_MAXSIZE 512 /* a value that is deemed far too large for any valid TAG */
+#define CONF_TAG_HOSTNAME 512 /* a value that is deemed far too large for any valid HOSTNAME */
+#define CONF_RAWMSG_BUFSIZE 101
+#define CONF_TAG_BUFSIZE 33 /* RFC says 32 chars (+ \0), but in practice we see longer ones... */
/* ############################################################# *
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 385fef1c..2f28cde0 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1176,6 +1176,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
int bTAGCharDetected;
int i; /* general index for parsing */
uchar bufParseTAG[CONF_TAG_MAXSIZE];
+ uchar bufParseHOSTNAME[CONF_TAG_HOSTNAME];
BEGINfunc
assert(pMsg != NULL);
@@ -1228,50 +1229,27 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
* If I find them, I set a simple flag but continue. After parsing, I check the flag.
* If it was set, then we most probably do not have a hostname but a TAG. Thus, I change
* the fields. I think this logic shall work with any type of syslog message.
+ * rgerhards, 2009-06-23: and I now have extended this logic to every character
+ * that is not a valid hostname.
*/
bTAGCharDetected = 0;
if(flags & PARSE_HOSTNAME) {
- /* TODO: quick and dirty memory allocation */
- /* the memory allocated is far too much in most cases. But on the plus side,
- * it is quite fast... - rgerhards, 2007-09-20
- */
- if((pBuf = malloc(sizeof(char)* (ustrlen(p2parse) +1))) == NULL)
- return 1;
- pWork = pBuf;
- /* this is the actual parsing loop */
- while(*p2parse && *p2parse != ' ' && *p2parse != ':') {
- if(*p2parse == '[' || *p2parse == ']' || *p2parse == '/')
- bTAGCharDetected = 1;
- *pWork++ = *p2parse++;
+ i = 0;
+ while((isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.'
+ || p2parse[i] == '_') && i < CONF_TAG_MAXSIZE) {
+ bufParseHOSTNAME[i] = p2parse[i];
+ ++i;
+ }
+
+ if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) {
+ /* we got a hostname! */
+ p2parse += i + 1; /* "eat" it (including SP delimiter) */
+ bufParseHOSTNAME[i] = '\0';
+ MsgSetHOSTNAME(pMsg, bufParseHOSTNAME);
+ //MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i);
+ } else {
+ MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
}
- /* we need to handle ':' seperately, because it terminates the
- * TAG - so we also need to terminate the parser here!
- * rgerhards, 2007-09-10 *p2parse points to a valid address here in
- * any case. We can reach this point only if we are at end of string,
- * or we have a ':' or ' '. What the if below does is check if we are
- * not at end of string and, if so, advance the parse pointer. If we
- * are already at end of string, *p2parse is equal to '\0', neither if
- * will be true and the parse pointer remain as is. This is perfectly
- * well.
- */
- if(*p2parse == ':') {
- bTAGCharDetected = 1;
- /* We will move hostname to tag, so preserve ':' (otherwise we
- * will needlessly change the message format) */
- *pWork++ = *p2parse++;
- } else if(*p2parse == ' ')
- ++p2parse;
- *pWork = '\0';
- MsgAssignHOSTNAME(pMsg, pBuf);
- }
- /* check if we seem to have a TAG */
- if(bTAGCharDetected) {
- /* indeed, this smells like a TAG, so lets use it for this. We take
- * the HOSTNAME from the sender system instead.
- */
- DBGPRINTF("HOSTNAME contains invalid characters, assuming it to be a TAG.\n");
- moveHOSTNAMEtoTAG(pMsg);
- MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
}
/* now parse TAG - that should be present in message from all sources.
@@ -1287,40 +1265,30 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
* in RFC3164...). We now receive the full size, but will modify the
* outputs so that only 32 characters max are used by default.
*/
- /* The following code in general is quick & dirty - I need to get
- * it going for a test, rgerhards 2004-11-16 */
- /* lol.. we tried to solve it, just to remind ourselfs that 32 octets
- * is the max size ;) we need to shuffle the code again... Just for
- * the records: the code is currently clean, but we could optimize it! */
- if(!bTAGCharDetected) {
- i = 0;
- while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) {
- bufParseTAG[i++] = *p2parse++;
- }
- if(*p2parse == ':') {
- ++p2parse;
- bufParseTAG[i++] = ':';
- }
+ i = 0;
+ while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) {
+ bufParseTAG[i++] = *p2parse++;
+ }
+ if(*p2parse == ':') {
+ ++p2parse;
+ bufParseTAG[i++] = ':';
+ }
- if(i == 0)
- { /* rger, 2005-11-10: no TAG found - this implies that what
- * we have considered to be the HOSTNAME is most probably the
- * TAG. We consider it so probable, that we now adjust it
- * that way. So we pick up the previously set hostname, assign
- * it to tag and use the sender system (from IP stack) as
- * the hostname. This situation is the standard case with
- * stock BSD syslogd.
- */
- DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n");
- moveHOSTNAMEtoTAG(pMsg);
- MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
- } else { /* we have a TAG, so we can happily set it ;) */
- bufParseTAG[i] = '\0'; /* terminate string */
- MsgSetTAG(pMsg, bufParseTAG, i);
- }
- } else {
- /* we have no TAG, so we ... */
- /*DO NOTHING*/;
+ if(i == 0)
+ { /* rger, 2005-11-10: no TAG found - this implies that what
+ * we have considered to be the HOSTNAME is most probably the
+ * TAG. We consider it so probable, that we now adjust it
+ * that way. So we pick up the previously set hostname, assign
+ * it to tag and use the sender system (from IP stack) as
+ * the hostname. This situation is the standard case with
+ * stock BSD syslogd.
+ */
+ DBGPRINTF("No TAG in message, assuming that HOSTNAME is missing.\n");
+ moveHOSTNAMEtoTAG(pMsg);
+ MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
+ } else { /* we have a TAG, so we can happily set it ;) */
+ bufParseTAG[i] = '\0'; /* terminate string */
+ MsgSetTAG(pMsg, bufParseTAG, i);
}
} else {
/* we enter this code area when the user has instructed rsyslog NOT