INN commit: trunk (doc/pod/news.pod innd/nc.c nnrpd/post.c)
INN Commit
rra at isc.org
Fri Nov 27 20:37:38 UTC 2009
Date: Friday, November 27, 2009 @ 12:37:38
Author: iulius
Revision: 8823
* nnrpd now checks the syntax of the Message-ID: header.
* Fixed a bug when nnrpd sends "IHAVE <mid>\r\n" to innd.
Arbitrary commands could be passed to innd because nnrpd
did not ensure the validity of the syntax of the message-ID.
* The permanent variable was not properly set on IHAVE rejects
and defers.
* innd now accepts commands ending with only "\n".
Modified:
trunk/doc/pod/news.pod
trunk/innd/nc.c
trunk/nnrpd/post.c
------------------+
doc/pod/news.pod | 4 +++-
innd/nc.c | 39 ++++++++++++---------------------------
nnrpd/post.c | 12 +++++++++---
3 files changed, 24 insertions(+), 31 deletions(-)
Modified: doc/pod/news.pod
===================================================================
--- doc/pod/news.pod 2009-11-20 17:34:15 UTC (rev 8822)
+++ doc/pod/news.pod 2009-11-27 20:37:38 UTC (rev 8823)
@@ -153,9 +153,11 @@
=item *
-Fixed a bug on the parsing of Message-ID: and Supersedes: headers
+Fixed a bug on how B<innd> was parsing Message-ID: and Supersedes: headers
which contained trailing whitespaces. The article ended up
corrupted because of an unexpected "\r" in the middle of the header.
+Besides, B<nnrpd> now checks the syntax of the Message-ID: header,
+if present.
=item *
Modified: innd/nc.c
===================================================================
--- innd/nc.c 2009-11-20 17:34:15 UTC (rev 8822)
+++ innd/nc.c 2009-11-27 20:37:38 UTC (rev 8823)
@@ -1093,50 +1093,35 @@
}
/* i points where "\n" is; go forward. */
cp->Next = ++i;
+
/* Never move data so long as "\r\n" is found, since subsequent
* data may also include a command line. */
movedata = false;
readmore = false;
+
/* Ignore too small lines. */
if (i - cp->Start < 3) {
cp->Start = cp->Next;
break;
}
- p = &bp->data[i];
- if (p[-2] != '\r') { /* Probably in an article. */
- char *tmpstr;
- tmpstr = xmalloc(i - cp->Start + 1);
- memcpy(tmpstr, bp->data + cp->Start, i - cp->Start);
- tmpstr[i - cp->Start] = '\0';
-
- syslog(L_NOTICE, "%s bad_command %s", CHANname(cp),
- MaxLength(tmpstr, tmpstr));
- free(tmpstr);
-
- if (++(cp->BadCommands) >= BAD_COMMAND_COUNT) {
- cp->State = CSwritegoodbye;
- snprintf(buff, sizeof(buff), "%d Too many unrecognized commands",
- NNTP_FAIL_TERMINATING);
- NCwritereply(cp, buff);
- break;
- }
- snprintf(buff, sizeof(buff), "%d What?", NNTP_ERR_COMMAND);
- NCwritereply(cp, buff);
- /* Still some data left, go for it. */
- cp->Start = cp->Next;
- break;
- }
-
+ p = &bp->data[i];
q = &bp->data[cp->Start];
+
/* Ignore blank lines. */
if (*q == '\0' || i - cp->Start == 2) {
cp->Start = cp->Next;
break;
}
- /* Guarantee null-termination. */
- p[-2] = '\0';
+ /* Guarantee null-termination. Usually, "\r\n" is found at the end
+ * of the command line. In case we only have "\n", we also accept
+ * the command. */
+ if (p[-2] == '\r')
+ p[-2] = '\0';
+ else
+ p[-1] = '\0';
+
p = q;
cp->ac = nArgify(p, &cp->av, 1);
Modified: nnrpd/post.c
===================================================================
--- nnrpd/post.c 2009-11-20 17:34:15 UTC (rev 8822)
+++ nnrpd/post.c 2009-11-27 20:37:38 UTC (rev 8823)
@@ -132,7 +132,7 @@
/*
-** Trim trailing spaces, return pointer to first non-space char.
+** Trim leading and trailing spaces, return the length of the result.
*/
int
TrimSpaces(char *p)
@@ -401,6 +401,9 @@
return "Missing Message-ID: header";
HDR_SET(HDR__MESSAGEID, idbuff);
}
+ if (!IsValidMessageID(HDR(HDR__MESSAGEID), true)) {
+ return "Can't parse Message-ID: header";
+ }
/* Set the Path: header. */
if (HDR(HDR__PATH) == NULL && ihave)
@@ -792,6 +795,7 @@
{
static char CANTSEND[] = "Can't send %s to server, %s";
+ /* We have a valid message-ID here (checked beforehand). */
fprintf(ToServer, "IHAVE %s\r\n", HDR(HDR__MESSAGEID));
if (FLUSH_ERROR(ToServer)
|| fgets(buff, buffsize, FromServer) == NULL) {
@@ -1149,11 +1153,13 @@
if (i != NNTP_CONT_IHAVE) {
strlcpy(Error, buff, sizeof(Error));
SendQuit(FromServer, ToServer);
- if (i != NNTP_FAIL_IHAVE_REFUSE)
- return Spoolit(article, Error);
if (i == NNTP_FAIL_IHAVE_REJECT || i == NNTP_FAIL_IHAVE_DEFER) {
*permanent = false;
}
+ /* As the syntax of the IHAVE command sent by nnrpd is valid,
+ * the only valid case of response is a refusal. */
+ if (i != NNTP_FAIL_IHAVE_REFUSE)
+ return Spoolit(article, Error);
return Error;
}
if (Tracing)
More information about the inn-committers
mailing list