------------------------------------------------------------------------
r1875 | jan | 2007-06-15 18:22:30 +0200 (Fri, 15 Jun 2007) | 8 lines
Changed paths:
   M /branches/lighttpd-1.4.x/NEWS
   M /branches/lighttpd-1.4.x/src/http_auth.c
   M /branches/lighttpd-1.4.x/tests/mod-auth.t

* fixed mem-leak in mod_auth (reported by Stefan Esser)
* fixed crash with md5-sess and cnonce not set in mod_auth (reported
  by Stefan Esser)
* fixed missing check for base64 encoded string in mod_auth and Basic
  auth (reported by Stefan Esser)
* fixed possible crash in Auth-Digest header parser on trailing WS in
  mod_auth (reported by Stefan Esser)

------------------------------------------------------------------------
Index: src/http_auth.c
===================================================================
--- src/http_auth.c	(revision 1874)
+++ src/http_auth.c	(revision 1875)
@@ -830,8 +830,14 @@
 
 	username = buffer_init();
 
-	base64_decode(username, realm_str);
+	if (!base64_decode(username, realm_str)) {
+		buffer_free(username);
 
+		log_error_write(srv, __FILE__, __LINE__, "sb", "decodeing base64-string failed", username);
+
+		return 0;
+	}
+
 	/* r2 == user:password */
 	if (NULL == (pw = strchr(username->ptr, ':'))) {
 		buffer_free(username);
@@ -967,7 +973,7 @@
 	for (c = b->ptr; *c; c++) {
 		/* skip whitespaces */
 		while (*c == ' ' || *c == '\t') c++;
-		if (!c) break;
+		if (!*c) break;
 
 		for (i = 0; dkv[i].key; i++) {
 			if ((0 == strncmp(c, dkv[i].key, dkv[i].key_len))) {
@@ -1016,9 +1022,24 @@
 
 		log_error_write(srv, __FILE__, __LINE__, "s",
 				"digest: missing field");
+
+		buffer_free(b);
 		return -1;
 	}
 
+	/**
+	 * protect the md5-sess against missing cnonce and nonce
+	 */
+	if (algorithm &&
+	    0 == strcasecmp(algorithm, "md5-sess") &&
+	    (!nonce || !cnonce)) {
+		log_error_write(srv, __FILE__, __LINE__, "s",
+				"digest: (md5-sess: missing field");
+
+		buffer_free(b);
+		return -1;
+	}
+
 	m = get_http_method_name(con->request.http_method);
 
 	/* password-string == HA1 */
Index: tests/mod-auth.t
===================================================================
--- tests/mod-auth.t	(revision 1874)
+++ tests/mod-auth.t	(revision 1875)
@@ -8,7 +8,7 @@
 
 use strict;
 use IO::Socket;
-use Test::More tests => 10;
+use Test::More tests => 13;
 use LightyTest;
 
 my $tf = LightyTest->new();
@@ -93,7 +93,44 @@
 $t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 400 } ];
 ok($tf->handle_http($t) == 0, 'Digest-Auth: missing nc (noncecount instead), no crash');
 
+$t->{REQUEST}  = ( <<EOF
+GET /server-status HTTP/1.0
+Authorization: Basic =
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
+ok($tf->handle_http($t) == 0, 'Basic-Auth: Invalid Base64');
 
 
+$t->{REQUEST}  = ( <<EOF
+GET /server-status HTTP/1.0
+User-Agent: Wget/1.9.1
+Authorization: Digest username="jan", realm="jan",
+	nonce="b1d12348b4620437c43dd61c50ae4639", algorithm="md5-sess",
+	uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001",
+	cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7",
+	nc="asd",
+	response="29B32C2953C763C6D033C8A49983B87E"
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
+ok($tf->handle_http($t) == 0, 'Digest-Auth: md5-sess + missing cnonce');
+
+$t->{REQUEST}  = ( <<EOF
+GET /server-status HTTP/1.0
+User-Agent: Wget/1.9.1
+Authorization: Digest username="jan", realm="jan",
+	nonce="b1d12348b4620437c43dd61c50ae4639", algorithm="md5-sess",
+	uri="/MJ-BONG.xm.mpc", qop=auth, noncecount=00000001",
+	cnonce="036FCA5B86F7E7C4965C7F9B8FE714B7",
+	nc="asd",
+	response="29B32C2953C763C6D033C8A49983B87E"     
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 401 } ];
+ok($tf->handle_http($t) == 0, 'Digest-Auth: trailing WS');
+
+
+
 ok($tf->stop_proc == 0, "Stopping lighttpd");
 
