dovecot-2.2: lib-http: Fixed handling of non-standard CRLF at en...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 15 03:38:25 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/819dd674f100
changeset: 16734:819dd674f100
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Sep 15 03:31:51 2013 +0300
description:
lib-http: Fixed handling of non-standard CRLF at end of request.

diffstat:

 src/lib-http/http-request-parser.c |  32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diffs (69 lines):

diff -r bdc5d6dcfc53 -r 819dd674f100 src/lib-http/http-request-parser.c
--- a/src/lib-http/http-request-parser.c	Sun Sep 15 03:31:28 2013 +0300
+++ b/src/lib-http/http-request-parser.c	Sun Sep 15 03:31:51 2013 +0300
@@ -8,6 +8,7 @@
 
 enum http_request_parser_state {
 	HTTP_REQUEST_PARSE_STATE_INIT = 0,
+	HTTP_REQUEST_PARSE_STATE_SKIP_LINE,
 	HTTP_REQUEST_PARSE_STATE_METHOD,
 	HTTP_REQUEST_PARSE_STATE_SP1,
 	HTTP_REQUEST_PARSE_STATE_TARGET,
@@ -23,6 +24,8 @@
 	enum http_request_parser_state state;
 
 	struct http_request request;
+
+	unsigned int skipping_line:1;
 };
 
 struct http_request_parser *http_request_parser_init(struct istream *input)
@@ -105,15 +108,24 @@
 		switch (parser->state) {
 		case HTTP_REQUEST_PARSE_STATE_INIT:
 			http_request_parser_restart(parser);
-			parser->state = HTTP_REQUEST_PARSE_STATE_VERSION;
+			parser->state = HTTP_REQUEST_PARSE_STATE_SKIP_LINE;
 			if (_parser->cur == _parser->end)
 				return 0;
+		case HTTP_REQUEST_PARSE_STATE_SKIP_LINE:
 			if (*_parser->cur == '\r' || *_parser->cur == '\n') {
-				/* HTTP/1.0 client sent a CRLF after body.
+				if (parser->skipping_line) {
+					/* second extra CRLF; not allowed */
+					*error_r = "Empty request line";
+					return -1;
+				}
+				/* HTTP/1.0 client sent one extra CRLF after body.
 				   ignore it. */
+				parser->skipping_line = TRUE;
 				parser->state = HTTP_REQUEST_PARSE_STATE_CR;
-				return http_request_parse(parser, error_r);
+				break;
 			}
+			parser->state = HTTP_REQUEST_PARSE_STATE_METHOD;
+			parser->skipping_line = FALSE;
 			/* fall through */
 		case HTTP_REQUEST_PARSE_STATE_METHOD:
 			if ((ret=http_request_parse_method(parser)) <= 0) {
@@ -184,11 +196,15 @@
 				return -1;
 			}
 			_parser->cur++;
-			parser->state = HTTP_REQUEST_PARSE_STATE_HEADER;
-			return 1;
-		case HTTP_REQUEST_PARSE_STATE_HEADER:
-		default:
-			i_unreached();
+			if (!parser->skipping_line) {
+				parser->state = HTTP_REQUEST_PARSE_STATE_HEADER;
+				return 1;
+			}
+			parser->state = HTTP_REQUEST_PARSE_STATE_INIT;
+			break;
+ 		case HTTP_REQUEST_PARSE_STATE_HEADER:
+ 		default:
+ 			i_unreached();
 		}
 	}
 


More information about the dovecot-cvs mailing list