commit f2bce4c656228718793871f2b2141ba93e0599b0
parent 94c16f349dac04636da8fe94277d53c344e958c5
Author: Christian Grothoff <christian@grothoff.org>
Date: Fri, 25 Sep 2015 07:51:21 +0000
fix digest auth when used with more complex arguments being passed to GET, i.e. keys without missing values at the beginning and certain other constellations
Diffstat:
4 files changed, 88 insertions(+), 34 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Sep 25 09:49:10 CEST 2015
+ Fix digest authentication with URL arguments where
+ value-less keys are given before the last argument.
+ Thanks to MA for reporting. -CG
+
Tue Sep 22 19:17:54 CEST 2015
Do not use shutdown() on listen socket if MHD_USE_PIPE_FOR_SHUTDOWN
is set. -CG
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00094301
+#define MHD_VERSION 0x00094302
/**
* MHD-internal return code for "YES".
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
@@ -1,5 +1,5 @@
/*
- This file is part of libmicrohttpd
+ This file is part of libmicrohttpd
Copyright (C) 2007-2015 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
@@ -17,7 +17,6 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-
/**
* @file connection.c
* @brief Methods for managing connections
@@ -301,7 +300,7 @@ connection_close_error (struct MHD_Connection *connection,
if (NULL != emsg)
MHD_DLOG (connection->daemon, emsg);
#endif
- MHD_connection_close (connection,
+ MHD_connection_close (connection,
MHD_REQUEST_TERMINATED_WITH_ERROR);
}
@@ -369,7 +368,7 @@ try_ready_normal_body (struct MHD_Connection *connection)
if (NULL != response->crc)
(void) MHD_mutex_unlock_ (&response->mutex);
if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret)
- MHD_connection_close (connection,
+ MHD_connection_close (connection,
MHD_REQUEST_TERMINATED_COMPLETED_OK);
else
CONNECTION_CLOSE_ERROR (connection,
@@ -1264,7 +1263,6 @@ parse_arguments (enum MHD_ValueKind kind,
/* continue with 'bar' */
args = amper;
continue;
-
}
/* equals and amper are non-NULL here, and equals < amper,
so we got regular 'foo=value&bar...'-kind of argument */
@@ -2597,12 +2595,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
connection->client_aware = MHD_NO;
}
end =
- MHD_lookup_connection_value (connection,
+ MHD_lookup_connection_value (connection,
MHD_HEADER_KIND,
MHD_HTTP_HEADER_CONNECTION);
if ( (MHD_YES == connection->read_closed) ||
(client_close) ||
- ( (NULL != end) &&
+ ( (NULL != end) &&
(MHD_str_equal_caseless_ (end, "close")) ) )
{
connection->read_closed = MHD_YES;
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
@@ -493,12 +493,12 @@ check_argument_match (struct MHD_Connection *connection,
char *amper;
unsigned int num_headers;
- argb = strdup(args);
+ argb = strdup (args);
if (NULL == argb)
{
#if HAVE_MESSAGES
- MHD_DLOG(connection->daemon,
- "Failed to allocate memory for copy of URI arguments\n");
+ MHD_DLOG (connection->daemon,
+ "Failed to allocate memory for copy of URI arguments\n");
#endif /* HAVE_MESSAGES */
return MHD_NO;
}
@@ -508,45 +508,93 @@ check_argument_match (struct MHD_Connection *connection,
('\0' != argp[0]) )
{
equals = strchr (argp, '=');
- if (NULL == equals)
+ amper = strchr (argp, '&');
+ if (NULL == amper)
{
+ /* last argument */
+ if (NULL == equals)
+ {
+ /* last argument, without '=' */
+ MHD_unescape_plus (argp);
+ if (MHD_YES != test_header (connection,
+ argp,
+ NULL))
+ {
+ free (argb);
+ return MHD_NO;
+ }
+ num_headers++;
+ break;
+ }
+ /* got 'foo=bar' */
+ equals[0] = '\0';
+ equals++;
+ MHD_unescape_plus (argp);
/* add with 'value' NULL */
connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
connection,
argp);
- if (MHD_YES != test_header (connection, argp, NULL))
- {
- free(argb);
- return MHD_NO;
- }
+ MHD_unescape_plus (equals);
+ /* add with 'value' NULL */
+ connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
+ connection,
+ equals);
+ if (MHD_YES != test_header (connection,
+ argp,
+ equals))
+ {
+ free (argb);
+ return MHD_NO;
+ }
num_headers++;
break;
}
- equals[0] = '\0';
- equals++;
- amper = strchr (equals, '&');
- if (NULL != amper)
+ /* amper is non-NULL here */
+ amper[0] = '\0';
+ amper++;
+ if ( (NULL == equals) ||
+ (equals >= amper) )
{
- amper[0] = '\0';
- amper++;
+ /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */
+ MHD_unescape_plus (argp);
+ connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
+ connection,
+ argp);
+ if (MHD_YES !=
+ test_header (connection,
+ argp,
+ NULL))
+ {
+ free (argb);
+ return MHD_NO;
+ }
+ /* continue with 'bar' */
+ num_headers++;
+ args = amper;
+ continue;
}
+ equals[0] = '\0';
+ equals++;
+ MHD_unescape_plus (argp);
connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
connection,
argp);
+ MHD_unescape_plus (equals);
connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
connection,
equals);
- if (! test_header (connection, argp, equals))
- {
- free(argb);
+ if (MHD_YES !=
+ test_header (connection,
+ argp,
+ equals))
+ {
+ free (argb);
return MHD_NO;
- }
-
+ }
num_headers++;
argp = amper;
}
-
- free(argb);
+ free (argb);
/* also check that the number of headers matches */
for (pos = connection->headers_received; NULL != pos; pos = pos->next)
@@ -556,7 +604,10 @@ check_argument_match (struct MHD_Connection *connection,
num_headers--;
}
if (0 != num_headers)
- return MHD_NO;
+ {
+ /* argument count mismatch */
+ return MHD_NO;
+ }
return MHD_YES;
}
@@ -623,9 +674,9 @@ MHD_digest_auth_check (struct MHD_Connection *connection,
{
char r[MAX_REALM_LENGTH];
- len = lookup_sub_value(r,
- sizeof (r),
- header, "realm");
+ len = lookup_sub_value (r,
+ sizeof (r),
+ header, "realm");
if ( (0 == len) ||
(0 != strcmp(realm, r)) )
return MHD_NO;