dovecot-2.2: pop3: satisfy some strict parsing rules in RFC 1939

dovecot at dovecot.org dovecot at dovecot.org
Fri Aug 15 12:05:23 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/a45147ddd655
changeset: 17719:a45147ddd655
user:      Phil Carmody <phil at dovecot.fi>
date:      Fri Aug 15 15:02:59 2014 +0300
description:
pop3: satisfy some strict parsing rules in RFC 1939
"Commands in the POP3 consist of a case-insensitive keyword, possibly
 followed by one or more arguments.  All commands are terminated by a
 CRLF pair.  Keywords and arguments consist of printable ASCII
 characters.  Keywords and arguments are each separated by a single
 SPACE character."

"A server MUST respond to an unrecognized, unimplemented, or
 syntactically invalid command by responding with a negative status
 indicator."

Therefore the following commands must be rejected:
LIST 2600Hz
LIST 99 red balloons
TOP 1 2 buckle-my-shoe

Signed-off-by: Phil Carmody <phil at dovecot.fi>

diffstat:

 src/pop3/pop3-commands.c |  25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diffs (93 lines):

diff -r 88d95b8f8a19 -r a45147ddd655 src/pop3/pop3-commands.c
--- a/src/pop3/pop3-commands.c	Fri Aug 15 15:02:59 2014 +0300
+++ b/src/pop3/pop3-commands.c	Fri Aug 15 15:02:59 2014 +0300
@@ -26,7 +26,7 @@
 }
 
 static const char *get_msgnum(struct client *client, const char *args,
-			      unsigned int *msgnum)
+			      unsigned int *msgnum, bool thenspace)
 {
 	unsigned int num;
 
@@ -40,6 +40,11 @@
 				 "-ERR Message number too large: %s", args);
 		return NULL;
 	}
+	if (*args != (thenspace ? ' ' : '\0')) {
+		client_send_line(client,
+				 "-ERR Noise after message number: %s", args);
+		return NULL;
+	}
 	if (num == 0 || num > client->messages_count) {
 		client_send_line(client,
 				 "-ERR There's no message %u.", num);
@@ -62,7 +67,7 @@
 }
 
 static const char *get_size(struct client *client, const char *args,
-			    uoff_t *size)
+			    uoff_t *size, bool thenspace)
 {
 	uoff_t num;
 
@@ -76,6 +81,10 @@
 				 args);
 		return NULL;
 	}
+	if (*args != (thenspace ? ' ' : '\0')) {
+		client_send_line(client, "-ERR Noise after size: %s", args);
+		return NULL;
+	}
 
 	while (*args == ' ') args++;
 
@@ -93,7 +102,7 @@
 {
 	unsigned int msgnum;
 
-	if (get_msgnum(client, args, &msgnum) == NULL)
+	if (get_msgnum(client, args, &msgnum, FALSE) == NULL)
 		return -1;
 
 	if (!client->deleted) {
@@ -155,7 +164,7 @@
 	} else {
 		unsigned int msgnum;
 
-		if (get_msgnum(client, args, &msgnum) == NULL)
+		if (get_msgnum(client, args, &msgnum, FALSE) == NULL)
 			return -1;
 
 		client_send_line(client, "+OK %u %"PRIuUOFF_T, msgnum+1,
@@ -470,7 +479,7 @@
 {
 	unsigned int msgnum;
 
-	if (get_msgnum(client, args, &msgnum) == NULL)
+	if (get_msgnum(client, args, &msgnum, FALSE) == NULL)
 		return -1;
 
 	if (client->lowest_retr_pop3_msn > msgnum+1 ||
@@ -534,10 +543,10 @@
 	unsigned int msgnum;
 	uoff_t max_lines;
 
-	args = get_msgnum(client, args, &msgnum);
+	args = get_msgnum(client, args, &msgnum, TRUE);
 	if (args == NULL)
 		return -1;
-	if (get_size(client, args, &max_lines) == NULL)
+	if (get_size(client, args, &max_lines, FALSE) == NULL)
 		return -1;
 
 	client->top_count++;
@@ -860,7 +869,7 @@
 	} else {
 		unsigned int msgnum;
 
-		if (get_msgnum(client, args, &msgnum) == NULL)
+		if (get_msgnum(client, args, &msgnum, FALSE) == NULL)
 			return -1;
 
 		seq = msgnum_to_seq(client, msgnum);


More information about the dovecot-cvs mailing list