INN commit: branches/2.5 (7 files)
INN Commit
rra at isc.org
Sun Nov 15 09:26:49 UTC 2009
Date: Sunday, November 15, 2009 @ 01:26:49
Author: iulius
Revision: 8786
Fix a bug introduced by commit 8437. If the Message-ID:
or the Supersedes: headers contains trailing white spaces,
the article is stored corrupted (we have a '\r' inside
the header).
Introduce more intelligence in the parsing (see a wish
explained in commit 6921) and retain the removed character
to properly put it again after the parsing.
Modified:
branches/2.5/include/inn/libinn.h
branches/2.5/innd/art.c
branches/2.5/innd/innd.h
branches/2.5/innd/nc.c
branches/2.5/lib/messageid.c
branches/2.5/nnrpd/article.c
branches/2.5/nnrpd/commands.c
----------------------+
include/inn/libinn.h | 2 +-
innd/art.c | 35 +++++++++++++++++++++++------------
innd/innd.h | 21 ++++++++++++---------
innd/nc.c | 11 ++++++-----
lib/messageid.c | 17 ++++++++++++++---
nnrpd/article.c | 6 +++---
nnrpd/commands.c | 2 +-
7 files changed, 60 insertions(+), 34 deletions(-)
Modified: include/inn/libinn.h
===================================================================
--- include/inn/libinn.h 2009-11-15 09:26:37 UTC (rev 8785)
+++ include/inn/libinn.h 2009-11-15 09:26:49 UTC (rev 8786)
@@ -152,7 +152,7 @@
/* Headers. */
extern char * GenerateMessageID(char *domain);
extern void InitializeMessageIDcclass(void);
-extern bool IsValidMessageID(const char *string);
+extern bool IsValidMessageID(const char *string, bool stripspaces);
extern bool IsValidHeaderName(const char *string);
extern void HeaderCleanFrom(char *from);
extern struct _DDHANDLE * DDstart(FILE *FromServer, FILE *ToServer);
Modified: innd/art.c
===================================================================
--- innd/art.c 2009-11-15 09:26:37 UTC (rev 8785)
+++ innd/art.c 2009-11-15 09:26:49 UTC (rev 8786)
@@ -386,8 +386,10 @@
char **hops;
/* We may still haven't received the message-ID of the rejected article. */
- if (HDR_FOUND(HDR__MESSAGE_ID))
+ if (HDR_FOUND(HDR__MESSAGE_ID)) {
+ HDR_LASTCHAR_SAVE(HDR__MESSAGE_ID);
HDR_PARSE_START(HDR__MESSAGE_ID);
+ }
/* Set up the headers that we want to use. We only need to parse the path
on rejections if logipaddr is false or we can't find a good host. */
@@ -399,6 +401,7 @@
}
} else {
if (HDR_FOUND(HDR__PATH)) {
+ HDR_LASTCHAR_SAVE(HDR__PATH);
HDR_PARSE_START(HDR__PATH);
hopcount =
ARTparsepath(HDR(HDR__PATH), HDR_LEN(HDR__PATH), &data->Path);
@@ -689,7 +692,8 @@
hc->Length = -1;
} else {
/* We need to remove leading and trailing spaces for
- * message-IDs; otherwise, ARTidok() will fail. */
+ * message-IDs; otherwise, history hashes may not be
+ * correctly computed. */
if (i == HDR__MESSAGE_ID || i == HDR__SUPERSEDES) {
for (p = colon + 1 ; (p < header + size - 2) &&
(ISWHITE(*p)) ; p++);
@@ -721,6 +725,7 @@
for (i = 0 ; i < MAX_ARTHEADER ; i++, hc++) {
hc->Value = NULL;
hc->Length = 0;
+ hc->LastChar = '\r';
}
data->Lines = data->HeaderLines = data->CRwithoutLF = data->LFwithoutCR = 0;
data->DotStuffedLines = 0;
@@ -778,12 +783,14 @@
/* Write a local cancel entry so nobody else gives it to us. */
if (HDR_FOUND(HDR__MESSAGE_ID)) {
+ HDR_LASTCHAR_SAVE(HDR__MESSAGE_ID);
HDR_PARSE_START(HDR__MESSAGE_ID);
msgid = HDR(HDR__MESSAGE_ID);
/* The article posting time has not been parsed. We cannot
* give it to InndHisRemember. */
if (!HIScheck(History, msgid) && !InndHisRemember(msgid, 0))
warn("SERVER cant write %s", msgid);
+ HDR_PARSE_END(HDR__MESSAGE_ID);
}
}
}
@@ -976,8 +983,10 @@
/* replace trailing '\r\n' with '\0\n' of all system header to be handled
easily by str*() functions */
for (i = 0 ; i < MAX_ARTHEADER ; i++) {
- if (HDR_FOUND(i))
+ if (HDR_FOUND(i)) {
+ HDR_LASTCHAR_SAVE(i);
HDR_PARSE_START(i);
+ }
}
/* Make sure all the headers we need are there */
@@ -985,7 +994,7 @@
if (hp[i].Type == HTreq) {
if (HDR_FOUND(i))
continue;
- if (hc[i].Length < 0) {
+ if (HDR_LEN(i) < 0) {
sprintf(buff, "%d Duplicate \"%s\" header",
ihave ? NNTP_FAIL_IHAVE_REJECT : NNTP_FAIL_TAKETHIS_REJECT,
hp[i].Name);
@@ -1000,7 +1009,7 @@
}
/* Assumes the Message-ID: header is a required header. */
- if (!IsValidMessageID(HDR(HDR__MESSAGE_ID))) {
+ if (!IsValidMessageID(HDR(HDR__MESSAGE_ID), true)) {
HDR_LEN(HDR__MESSAGE_ID) = 0;
sprintf(buff, "%d Bad \"Message-ID\" header",
ihave ? NNTP_FAIL_IHAVE_REJECT : NNTP_FAIL_TAKETHIS_REJECT);
@@ -1208,9 +1217,9 @@
return;
}
- if (!IsValidMessageID(MessageID)) {
+ if (!IsValidMessageID(MessageID, true)) {
syslog(L_NOTICE, "%s bad cancel Message-ID %s", data->Feedsite,
- MaxLength(MessageID, MessageID));
+ MaxLength(MessageID, MessageID));
TMRstop(TMR_ARTCNCL);
return;
}
@@ -1243,7 +1252,7 @@
OVcancel(token);
if (!SMcancel(token) && SMerrno != SMERR_NOENT && SMerrno != SMERR_UNINIT)
syslog(L_ERROR, "%s cant cancel %s (SMerrno %d)", LogName,
- TokenToText(token), SMerrno);
+ TokenToText(token), SMerrno);
if (innconf->immediatecancel && !SMflushcacheddata(SM_CANCELLEDART))
syslog(L_ERROR, "%s cant cancel cached %s", LogName, TokenToText(token));
snprintf(buff, sizeof(buff), "Cancelling %s",
@@ -1267,7 +1276,7 @@
if (c == 'c' && strncmp(Control, "cancel", 6) == 0) {
for (p = &Control[6]; ISWHITE(*p); p++)
continue;
- if (*p && IsValidMessageID(p))
+ if (*p && IsValidMessageID(p, true))
ARTcancel(data, p, false);
return;
}
@@ -2426,10 +2435,12 @@
ngp->PostCount = 0;
token = ARTstore(cp);
- /* change trailing '\r\n' to '\0\n' of all system header */
+ /* Change trailing '\r\n' to '\0\n' of all system header. */
for (i = 0 ; i < MAX_ARTHEADER ; i++) {
- if (HDR_FOUND(i))
+ if (HDR_FOUND(i)) {
+ HDR_LASTCHAR_SAVE(i);
HDR_PARSE_START(i);
+ }
}
if (token.type == TOKEN_EMPTY) {
syslog(L_ERROR, "%s cant store article: %s", LogName, SMerrorstr);
@@ -2538,7 +2549,7 @@
ARTcontrol(data, HDR(HDR__CONTROL), cp);
}
if (DoCancels && HDR_FOUND(HDR__SUPERSEDES)) {
- if (IsValidMessageID(HDR(HDR__SUPERSEDES)))
+ if (IsValidMessageID(HDR(HDR__SUPERSEDES), true))
ARTcancel(data, HDR(HDR__SUPERSEDES), false);
}
}
Modified: innd/innd.h
===================================================================
--- innd/innd.h 2009-11-15 09:26:37 UTC (rev 8785)
+++ innd/innd.h 2009-11-15 09:26:49 UTC (rev 8786)
@@ -116,24 +116,27 @@
/*
-** Header content
+** Header content.
*/
typedef struct _HDRCONTENT {
- char * Value; /* don't copy, shows where it begins */
- int Length; /* Length of Value(tailing CRLF is not
- included. -1 if duplicated */
+ char * Value; /* Don't copy, shows where it begins. */
+ int Length; /* Length of Value(tailing CRLF is not
+ included. -1 if duplicated. */
+ char LastChar; /* Saved char when the last one is cut during parsing.
+ Usually '\r' but it may be another char. */
} HDRCONTENT;
/*
** A way to index into the header table.
*/
-#define HDR_FOUND(_x) (hc[(_x)].Length > 0)
-#define HDR_PARSE_START(_x) hc[(_x)].Value[hc[_x].Length] = '\0'
-#define HDR(_x) (hc[(_x)].Value)
+#define HDR_FOUND(_x) (hc[(_x)].Length > 0)
+#define HDR_LASTCHAR_SAVE(_x) hc[(_x)].LastChar = hc[(_x)].Value[hc[_x].Length]
+#define HDR_PARSE_START(_x) hc[(_x)].Value[hc[_x].Length] = '\0'
+#define HDR(_x) (hc[(_x)].Value)
/* HDR_LEN does not includes trailing "\r\n" */
-#define HDR_LEN(_x) (hc[(_x)].Length)
-#define HDR_PARSE_END(_x) hc[(_x)].Value[hc[_x].Length] = '\r'
+#define HDR_LEN(_x) (hc[(_x)].Length)
+#define HDR_PARSE_END(_x) hc[(_x)].Value[hc[_x].Length] = hc[(_x)].LastChar
#define HDR__APPROVED 0
Modified: innd/nc.c
===================================================================
--- innd/nc.c 2009-11-15 09:26:37 UTC (rev 8785)
+++ innd/nc.c 2009-11-15 09:26:49 UTC (rev 8786)
@@ -322,7 +322,7 @@
return;
}
- if (!IsValidMessageID(cp->av[1])) {
+ if (!IsValidMessageID(cp->av[1], true)) {
xasprintf(&buff, "%d Syntax error in message-ID", NNTP_ERR_SYNTAX);
NCwritereply(cp, buff);
free(buff);
@@ -388,7 +388,7 @@
return;
}
- if (!IsValidMessageID(cp->av[1])) {
+ if (!IsValidMessageID(cp->av[1], true)) {
xasprintf(&buff, "%d Syntax error in message-ID", NNTP_ERR_SYNTAX);
NCwritereply(cp, buff);
free(buff);
@@ -605,7 +605,7 @@
cp->Ihave++;
cp->Start = cp->Next;
- if (!IsValidMessageID(cp->av[1])) {
+ if (!IsValidMessageID(cp->av[1], false)) {
/* Return 435 here instead of 501 for compatibility reasons. */
xasprintf(&buff, "%d Syntax error in message-ID", NNTP_FAIL_IHAVE_REFUSE);
NCwritereply(cp, buff);
@@ -1312,6 +1312,7 @@
if (*cp->Error != '\0') {
if (innconf->remembertrash && (Mode == OMrunning)
&& HDR_FOUND(HDR__MESSAGE_ID)) {
+ HDR_LASTCHAR_SAVE(HDR__MESSAGE_ID);
HDR_PARSE_START(HDR__MESSAGE_ID);
/* The article posting time has not been parsed. We cannot
* give it to InndHisRemember. */
@@ -1705,7 +1706,7 @@
cp->Sendid.size = MAXHEADERSIZE;
cp->Sendid.data = xmalloc(cp->Sendid.size);
}
- if (!IsValidMessageID(cp->av[1])) {
+ if (!IsValidMessageID(cp->av[1], false)) {
snprintf(cp->Sendid.data, cp->Sendid.size, "%d %s",
NNTP_FAIL_CHECK_REFUSE, cp->av[1]);
NCwritereply(cp, cp->Sendid.data);
@@ -1797,7 +1798,7 @@
cp->Takethis++;
cp->Start = cp->Next;
- if (!IsValidMessageID(cp->av[1])) {
+ if (!IsValidMessageID(cp->av[1], false)) {
syslog(L_NOTICE, "%s bad_messageid %s", CHANname(cp),
MaxLength(cp->av[1], cp->av[1]));
}
Modified: lib/messageid.c
===================================================================
--- lib/messageid.c 2009-11-15 09:26:37 UTC (rev 8785)
+++ lib/messageid.c 2009-11-15 09:26:49 UTC (rev 8786)
@@ -100,7 +100,7 @@
** Updated to RFC 5536 by Julien Elie.
*/
bool
-IsValidMessageID(const char *MessageID)
+IsValidMessageID(const char *MessageID, bool stripspaces)
{
int c;
const unsigned char *p;
@@ -111,6 +111,10 @@
p = (const unsigned char *) MessageID;
+ if (stripspaces) {
+ for (; ISWHITE(*p); p++);
+ }
+
/* Scan local-part: "< dot-atom-text". */
if (*p++ != '<')
return false;
@@ -154,6 +158,13 @@
if (*p != '.')
break;
}
-
- return *p == '>' && *++p == '\0';
+
+ if (*p++ != '>')
+ return false;
+
+ if (stripspaces) {
+ for (; ISWHITE(*p); p++);
+ }
+
+ return (*p == '\0');
}
Modified: nnrpd/article.c
===================================================================
--- nnrpd/article.c 2009-11-15 09:26:37 UTC (rev 8785)
+++ nnrpd/article.c 2009-11-15 09:26:49 UTC (rev 8786)
@@ -596,7 +596,7 @@
ARTNUM tart;
bool final = false;
- mid = (ac > 1 && IsValidMessageID(av[1]));
+ mid = (ac > 1 && IsValidMessageID(av[1], true));
/* Check the syntax of the arguments first. */
if (ac > 1 && !IsValidArticleNumber(av[1])) {
@@ -887,7 +887,7 @@
bool xover, mid;
xover = (strcasecmp(av[0], "XOVER") == 0);
- mid = (ac > 1 && IsValidMessageID(av[1]));
+ mid = (ac > 1 && IsValidMessageID(av[1], true));
if (mid && !xover) {
/* FIXME: We still do not support OVER MSGID, sorry! */
@@ -1106,7 +1106,7 @@
bool hdr, mid;
hdr = (strcasecmp(av[0], "HDR") == 0);
- mid = (ac > 2 && IsValidMessageID(av[2]));
+ mid = (ac > 2 && IsValidMessageID(av[2], true));
/* Check the syntax of the arguments first. */
if (ac > 2 && !IsValidRange(av[2])) {
Modified: nnrpd/commands.c
===================================================================
--- nnrpd/commands.c 2009-11-15 09:26:37 UTC (rev 8785)
+++ nnrpd/commands.c 2009-11-15 09:26:49 UTC (rev 8786)
@@ -602,7 +602,7 @@
ihave = (strcasecmp(av[0], "IHAVE") == 0);
/* Check whether the message-ID is valid for IHAVE. */
- if (ihave && ac == 2 && !IsValidMessageID(av[1])) {
+ if (ihave && ac == 2 && !IsValidMessageID(av[1], true)) {
Reply("%d Syntax error in message-ID\r\n", NNTP_ERR_SYNTAX);
return;
}
More information about the inn-committers
mailing list