summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/syslogd.c100
1 files changed, 68 insertions, 32 deletions
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 912cca69..608fb5df 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -959,10 +959,12 @@ msgConsumer(void __attribute__((unused)) *notNeeded, batch_t *pBatch)
* to after the terminating SP. The caller must ensure that the
* provided buffer is large enough to hold the to be extracted value.
* Returns 0 if everything is fine or 1 if either the field is not
- * SP-terminated or any other error occurs.
- * rger, 2005-11-24
+ * SP-terminated or any other error occurs. -- rger, 2005-11-24
+ * The function now receives the size of the string and makes sure
+ * that it does not process more than that. The *pLenStr counter is
+ * updated on exit. -- rgerhards, 2009-09-23
*/
-static int parseRFCField(uchar **pp2parse, uchar *pResult)
+static int parseRFCField(uchar **pp2parse, uchar *pResult, int *pLenStr)
{
uchar *p2parse;
int iRet = 0;
@@ -974,14 +976,17 @@ static int parseRFCField(uchar **pp2parse, uchar *pResult)
p2parse = *pp2parse;
/* this is the actual parsing loop */
- while(*p2parse && *p2parse != ' ') {
+ while(*pLenStr > 0 && *p2parse != ' ') {
*pResult++ = *p2parse++;
+ --(*pLenStr);
}
- if(*p2parse == ' ')
+ if(*pLenStr > 0 && *p2parse == ' ') {
++p2parse; /* eat SP, but only if not at end of string */
- else
+ --(*pLenStr);
+ } else {
iRet = 1; /* there MUST be an SP! */
+ }
*pResult = '\0';
/* set the new parse pointer */
@@ -997,20 +1002,24 @@ static int parseRFCField(uchar **pp2parse, uchar *pResult)
* to after the terminating SP. The caller must ensure that the
* provided buffer is large enough to hold the to be extracted value.
* Returns 0 if everything is fine or 1 if either the field is not
- * SP-terminated or any other error occurs.
- * rger, 2005-11-24
+ * SP-terminated or any other error occurs. -- rger, 2005-11-24
+ * The function now receives the size of the string and makes sure
+ * that it does not process more than that. The *pLenStr counter is
+ * updated on exit. -- rgerhards, 2009-09-23
*/
-static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult)
+static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr)
{
uchar *p2parse;
int bCont = 1;
int iRet = 0;
+ int lenStr;
assert(pp2parse != NULL);
assert(*pp2parse != NULL);
assert(pResult != NULL);
p2parse = *pp2parse;
+ lenStr = *pLenStr;
/* this is the actual parsing loop
* Remeber: structured data starts with [ and includes any characters
@@ -1018,40 +1027,55 @@ static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult)
* structured data. There may also be \] inside the structured data, which
* do NOT terminate an element.
*/
- if(*p2parse != '[')
+ if(lenStr == 0 || *p2parse != '[')
return 1; /* this is NOT structured data! */
if(*p2parse == '-') { /* empty structured data? */
*pResult++ = '-';
++p2parse;
+ --lenStr;
} else {
while(bCont) {
- if(*p2parse == '\0') {
- iRet = 1; /* this is not valid! */
- bCont = 0;
+ if(lenStr < 2) {
+ /* we now need to check if we have only structured data */
+ if(lenStr > 0 && *p2parse == ']') {
+ *pResult++ = *p2parse;
+ p2parse++;
+ lenStr--;
+ bCont = 0;
+ } else {
+ iRet = 1; /* this is not valid! */
+ bCont = 0;
+ }
} else if(*p2parse == '\\' && *(p2parse+1) == ']') {
/* this is escaped, need to copy both */
*pResult++ = *p2parse++;
*pResult++ = *p2parse++;
+ lenStr -= 2;
} else if(*p2parse == ']' && *(p2parse+1) == ' ') {
/* found end, just need to copy the ] and eat the SP */
*pResult++ = *p2parse;
p2parse += 2;
+ lenStr -= 2;
bCont = 0;
} else {
*pResult++ = *p2parse++;
+ --lenStr;
}
}
}
- if(*p2parse == ' ')
+ if(lenStr > 0 && *p2parse == ' ') {
++p2parse; /* eat SP, but only if not at end of string */
- else
+ --lenStr;
+ } else {
iRet = 1; /* there MUST be an SP! */
+ }
*pResult = '\0';
/* set the new parse pointer */
*pp2parse = p2parse;
+ *pLenStr = lenStr;
return 0;
}
@@ -1076,23 +1100,26 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags)
{
uchar *p2parse;
uchar *pBuf;
+ int lenMsg;
int bContParse = 1;
BEGINfunc
assert(pMsg != NULL);
assert(pMsg->pszRawMsg != NULL);
p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */
+ lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI;
- /* do a sanity check on the version and eat it */
+ /* do a sanity check on the version and eat it (the caller checked this already) */
assert(p2parse[0] == '1' && p2parse[1] == ' ');
p2parse += 2;
+ lenMsg -= 2;
/* Now get us some memory we can use as a work buffer while parsing.
* We simply allocated a buffer sufficiently large to hold all of the
* message, so we can not run into any troubles. I think this is
* more wise then to use individual buffers.
*/
- if((pBuf = malloc(sizeof(uchar) * ustrlen(p2parse) + 1)) == NULL)
+ if((pBuf = malloc(sizeof(uchar) * (lenMsg + 1))) == NULL)
return 1;
/* IMPORTANT NOTE:
@@ -1103,7 +1130,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags)
*/
/* TIMESTAMP */
- if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) {
+ if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) {
if(flags & IGNDATE) {
/* we need to ignore the msg data, so simply copy over reception date */
memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime));
@@ -1115,31 +1142,31 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags)
/* HOSTNAME */
if(bContParse) {
- parseRFCField(&p2parse, pBuf);
+ parseRFCField(&p2parse, pBuf, &lenMsg);
MsgSetHOSTNAME(pMsg, pBuf, ustrlen(pBuf));
}
/* APP-NAME */
if(bContParse) {
- parseRFCField(&p2parse, pBuf);
+ parseRFCField(&p2parse, pBuf, &lenMsg);
MsgSetAPPNAME(pMsg, (char*)pBuf);
}
/* PROCID */
if(bContParse) {
- parseRFCField(&p2parse, pBuf);
+ parseRFCField(&p2parse, pBuf, &lenMsg);
MsgSetPROCID(pMsg, (char*)pBuf);
}
/* MSGID */
if(bContParse) {
- parseRFCField(&p2parse, pBuf);
+ parseRFCField(&p2parse, pBuf, &lenMsg);
MsgSetMSGID(pMsg, (char*)pBuf);
}
/* STRUCTURED-DATA */
if(bContParse) {
- parseRFCStructuredData(&p2parse, pBuf);
+ parseRFCStructuredData(&p2parse, pBuf, &lenMsg);
MsgSetStructuredData(pMsg, (char*)pBuf);
}
@@ -1168,6 +1195,7 @@ int parseRFCSyslogMsg(msg_t *pMsg, int flags)
int parseLegacySyslogMsg(msg_t *pMsg, int flags)
{
uchar *p2parse;
+ int lenMsg;
int bTAGCharDetected;
int i; /* general index for parsing */
uchar bufParseTAG[CONF_TAG_MAXSIZE];
@@ -1176,27 +1204,32 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
assert(pMsg != NULL);
assert(pMsg->pszRawMsg != NULL);
+ lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1);
+RUNLOG_VAR("%d", pMsg->offAfterPRI);
+RUNLOG_VAR("%d", lenMsg);
p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */
/* Check to see if msg contains a timestamp. We start by assuming
- * that the message timestamp is the time of reciption (which we
+ * that the message timestamp is the time of reception (which we
* generated ourselfs and then try to actually find one inside the
* message. There we go from high-to low precison and are done
* when we find a matching one. -- rgerhards, 2008-09-16
*/
- if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) {
+ if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) {
/* we are done - parse pointer is moved by ParseTIMESTAMP3339 */;
- } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) {
+ } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) {
/* we are done - parse pointer is moved by ParseTIMESTAMP3164 */;
- } else if(*p2parse == ' ') { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */
+ } else if(*p2parse == ' ' && lenMsg > 1) { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */
++p2parse; /* move over space */
- if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse) == RS_RET_OK) {
+ --lenMsg;
+ if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) {
/* indeed, we got it! */
/* we are done - parse pointer is moved by ParseTIMESTAMP3164 */;
} else {/* parse pointer needs to be restored, as we moved it off-by-one
* for this try.
*/
--p2parse;
+ ++lenMsg;
}
}
@@ -1227,12 +1260,13 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
* that is not a valid hostname.
*/
bTAGCharDetected = 0;
- if(flags & PARSE_HOSTNAME) {
+ if(lenMsg > 0 && flags & PARSE_HOSTNAME) {
i = 0;
- while((isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.'
+ while(lenMsg > 0 && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.'
|| p2parse[i] == '_' || p2parse[i] == '-') && i < CONF_TAG_MAXSIZE) {
bufParseHOSTNAME[i] = p2parse[i];
++i;
+ --lenMsg;
}
if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) {
@@ -1257,11 +1291,13 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
* outputs so that only 32 characters max are used by default.
*/
i = 0;
- while(*p2parse && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) {
+ while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) {
bufParseTAG[i++] = *p2parse++;
+ --lenMsg;
}
- if(*p2parse == ':') {
+ if(lenMsg > 0 && *p2parse == ':') {
++p2parse;
+ --lenMsg;
bufParseTAG[i++] = ':';
}