libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 305acdf03ade1ef83c97f03db7375107943ebd70
parent a22321bf1a3187ae9eaf0789ec477f2c9c7d81f7
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat,  1 Sep 2012 18:47:23 +0000

allowing independent enabling/disabling of digest and basic authentication (Mantis #2525)

Diffstat:
MChangeLog | 4++++
MINSTALL | 9++-------
Mconfigure.ac | 29+++++++++++++++++++++++------
Msrc/daemon/Makefile.am | 7++++++-
Asrc/daemon/basicauth.c | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/daemon/digestauth.c | 381++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/examples/Makefile.am | 6+++++-
7 files changed, 315 insertions(+), 253 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,7 @@ +Sat Sep 1 20:38:35 CEST 2012 + Adding configure option to allow selecting support for basic + and digest authentication separately (#2525). -CG + Thu Aug 30 21:12:56 CEST 2012 Fixing URI argument parsing when string contained keys without equals sign (i.e. '&bar&') in the middle of the argument (#2531). diff --git a/INSTALL b/INSTALL @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, -Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -226,11 +226,6 @@ order to use an ANSI C compiler: and if that doesn't work, install pre-built binaries of GCC for HP-UX. - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `<wchar.h>' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended diff --git a/configure.ac b/configure.ac @@ -360,24 +360,40 @@ AC_MSG_RESULT($enable_https) AM_CONDITIONAL(ENABLE_HTTPS, test "$enable_https" = "yes") +# optional: HTTP Basic Auth support. Enabled by default +AC_MSG_CHECKING(whether to support HTTP basic authentication) +AC_ARG_ENABLE([bauth], + AS_HELP_STRING([--disable-bauth], + [disable HTTP basic Auth support]), + [enable_bauth=${enableval}], + [enable_bauth=yes]) +if test "$enable_bauth" = "yes" +then + AC_DEFINE([BAUTH_SUPPORT],[1],[include basic Auth support]) +else + AC_DEFINE([BAUTH_SUPPORT],[0],[disable basic Auth support]) +fi +AC_MSG_RESULT($enable_bauth) +AM_CONDITIONAL(ENABLE_BAUTH, [test "x$enable_bauth" != "xno"]) + # optional: HTTP Digest Auth support. Enabled by default -AC_MSG_CHECKING(whether to support HTTP basic and digest authentication) +AC_MSG_CHECKING(whether to support HTTP digest authentication) AC_ARG_ENABLE([dauth], AS_HELP_STRING([--disable-dauth], [disable HTTP basic and digest Auth support]), [enable_dauth=${enableval}], [enable_dauth=yes]) - if test "$enable_dauth" = "yes" then - AC_DEFINE([DAUTH_SUPPORT],[1],[include basic and digest Auth support]) + AC_DEFINE([DAUTH_SUPPORT],[1],[include digest Auth support]) else - AC_DEFINE([DAUTH_SUPPORT],[0],[disable basic and digest Auth support]) + AC_DEFINE([DAUTH_SUPPORT],[0],[disable digest Auth support]) fi AC_MSG_RESULT($enable_dauth) - AM_CONDITIONAL(ENABLE_DAUTH, [test "x$enable_dauth" != "xno"]) + + MHD_LIB_LDFLAGS="-export-dynamic -no-undefined" # TODO insert a proper check here @@ -454,7 +470,8 @@ AC_MSG_NOTICE([Configuration Summary: libcurl (testing): ${MSG_CURL} Target directory: ${prefix} Messages: ${enable_messages} - HTTP Authentic.: ${enable_dauth} + Basic auth.: ${enable_bauth} + Digest auth.: ${enable_dauth} Postproc: ${enable_postprocessor} HTTPS support: ${enable_https} ]) diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am @@ -37,7 +37,12 @@ endif if ENABLE_DAUTH libmicrohttpd_la_SOURCES += \ digestauth.c \ - md5.c md5.h \ + md5.c md5.h +endif + +if ENABLE_BAUTH +libmicrohttpd_la_SOURCES += \ + basicauth.c \ base64.c base64.h endif diff --git a/src/daemon/basicauth.c b/src/daemon/basicauth.c @@ -0,0 +1,132 @@ +/* + This file is part of libmicrohttpd + (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/** + * @file basicauth.c + * @brief Implements HTTP basic authentication methods + * @author Amr Ali + * @author Matthieu Speder + */ +#include "platform.h" +#include <limits.h> +#include "internal.h" +#include "base64.h" + +/** + * Beginning string for any valid Basic authentication header. + */ +#define _BASIC_BASE "Basic " + + +/** + * Get the username and password from the basic authorization header sent by the client + * + * @param connection The MHD connection structure + * @param password a pointer for the password + * @return NULL if no username could be found, a pointer + * to the username if found + */ +char * +MHD_basic_auth_get_username_password(struct MHD_Connection *connection, + char** password) +{ + const char *header; + char *decode; + const char *separator; + char *user; + + if ( (NULL == (header = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION))) || + (0 != strncmp (header, _BASIC_BASE, strlen(_BASIC_BASE))) ) + return NULL; + header += strlen (_BASIC_BASE); + if (NULL == (decode = BASE64Decode (header))) + { +#if HAVE_MESSAGES + MHD_DLOG (connection->daemon, + "Error decoding basic authentication\n"); +#endif + return NULL; + } + /* Find user:password pattern */ + if (NULL == (separator = strchr (decode, ':'))) + { +#if HAVE_MESSAGES + MHD_DLOG(connection->daemon, + "Basic authentication doesn't contain ':' separator\n"); +#endif + free (decode); + return NULL; + } + if (NULL == (user = strdup (decode))) + { + free (decode); + return NULL; + } + user[separator - decode] = '\0'; /* cut off at ':' */ + if (NULL != password) + { + *password = strdup (separator + 1); + if (NULL == *password) + { +#if HAVE_MESSAGES + MHD_DLOG(connection->daemon, + "Failed to allocate memory for password\n"); +#endif + free (decode); + free (user); + return NULL; + } + } + free (decode); + return user; +} + + +/** + * Queues a response to request basic authentication from the client + * + * @param connection The MHD connection structure + * @param realm the realm presented to the client + * @return MHD_YES on success, MHD_NO otherwise + */ +int +MHD_queue_basic_auth_fail_response (struct MHD_Connection *connection, + const char *realm, + struct MHD_Response *response) +{ + int ret; + size_t hlen = strlen(realm) + strlen("Basic realm=\"\"") + 1; + char header[hlen]; + + snprintf (header, + sizeof (header), + "Basic realm=\"%s\"", + realm); + ret = MHD_add_response_header (response, + MHD_HTTP_HEADER_WWW_AUTHENTICATE, + header); + if (MHD_YES == ret) + ret = MHD_queue_response (connection, + MHD_HTTP_UNAUTHORIZED, + response); + return ret; +} + +/* end of basicauth.c */ diff --git a/src/daemon/digestauth.c b/src/daemon/digestauth.c @@ -16,19 +16,16 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - /** * @file digestauth.c - * @brief Implements various HTTP authentication methods + * @brief Implements HTTP digest authentication * @author Amr Ali * @author Matthieu Speder */ - #include "platform.h" #include <limits.h> #include "internal.h" #include "md5.h" -#include "base64.h" #define HASH_MD5_HEX_LEN (2 * MD5_DIGEST_SIZE) @@ -38,11 +35,6 @@ #define _BASE "Digest " /** - * Beginning string for any valid Basic authentication header. - */ -#define _BASIC_BASE "Basic " - -/** * Maximum length of a username for digest authentication. */ #define MAX_USERNAME_LENGTH 128 @@ -57,6 +49,7 @@ */ #define MAX_AUTH_RESPONSE_LENGTH 128 + /** * convert bin to hex * @@ -65,9 +58,9 @@ * @param hex pointer to len*2+1 bytes */ static void -cvthex(const unsigned char *bin, - size_t len, - char *hex) +cvthex (const unsigned char *bin, + size_t len, + char *hex) { size_t i; unsigned int j; @@ -82,6 +75,7 @@ cvthex(const unsigned char *bin, hex[len * 2] = '\0'; } + /** * calculate H(A1) as per RFC2617 spec and store the * result in 'sessionkey'. @@ -95,13 +89,13 @@ cvthex(const unsigned char *bin, * @param sessionkey pointer to buffer of HASH_MD5_HEX_LEN+1 bytes */ static void -digest_calc_ha1(const char *alg, - const char *username, - const char *realm, - const char *password, - const char *nonce, - const char *cnonce, - char *sessionkey) +digest_calc_ha1 (const char *alg, + const char *username, + const char *realm, + const char *password, + const char *nonce, + const char *cnonce, + char *sessionkey) { struct MD5Context md5; unsigned char ha1[MD5_DIGEST_SIZE]; @@ -113,7 +107,7 @@ digest_calc_ha1(const char *alg, MD5Update (&md5, ":", 1); MD5Update (&md5, password, strlen (password)); MD5Final (ha1, &md5); - if (0 == strcasecmp(alg, "md5-sess")) + if (0 == strcasecmp (alg, "md5-sess")) { MD5Init (&md5); MD5Update (&md5, ha1, sizeof (ha1)); @@ -123,7 +117,7 @@ digest_calc_ha1(const char *alg, MD5Update (&md5, cnonce, strlen (cnonce)); MD5Final (ha1, &md5); } - cvthex(ha1, sizeof (ha1), sessionkey); + cvthex (ha1, sizeof (ha1), sessionkey); } @@ -141,15 +135,15 @@ digest_calc_ha1(const char *alg, * @param response request-digest or response-digest */ static void -digest_calc_response(const char *ha1, - const char *nonce, - const char *noncecount, - const char *cnonce, - const char *qop, - const char *method, - const char *uri, - const char *hentity, - char *response) +digest_calc_response (const char *ha1, + const char *nonce, + const char *noncecount, + const char *cnonce, + const char *qop, + const char *method, + const char *uri, + const char *hentity, + char *response) { struct MD5Context md5; unsigned char ha2[MD5_DIGEST_SIZE]; @@ -161,17 +155,17 @@ digest_calc_response(const char *ha1, MD5Update (&md5, ":", 1); MD5Update (&md5, uri, strlen(uri)); #if 0 - if (strcasecmp(qop, "auth-int") == 0) + if (0 == strcasecmp(qop, "auth-int")) { /* This is dead code since the rest of this module does not support auth-int. */ MD5Update (&md5, ":", 1); - if (hentity != NULL) + if (NULL != hentity) MD5Update (&md5, hentity, strlen(hentity)); } #endif MD5Final (ha2, &md5); - cvthex(ha2, MD5_DIGEST_SIZE, ha2hex); + cvthex (ha2, MD5_DIGEST_SIZE, ha2hex); MD5Init (&md5); /* calculate response */ MD5Update (&md5, ha1, HASH_MD5_HEX_LEN); @@ -189,7 +183,7 @@ digest_calc_response(const char *ha1, } MD5Update (&md5, ha2hex, HASH_MD5_HEX_LEN); MD5Final (resphash, &md5); - cvthex(resphash, sizeof (resphash), response); + cvthex (resphash, sizeof (resphash), response); } @@ -208,14 +202,14 @@ digest_calc_response(const char *ha1, * @return size of the located value, 0 if otherwise */ static int -lookup_sub_value(char *dest, - size_t size, - const char *data, - const char *key) +lookup_sub_value (char *dest, + size_t size, + const char *data, + const char *key) { - size_t keylen = strlen(key); + size_t keylen; size_t len; - const char *ptr = data; + const char *ptr; const char *eq; const char *q1; const char *q2; @@ -223,6 +217,8 @@ lookup_sub_value(char *dest, if (0 == size) return 0; + keylen = strlen (key); + ptr = data; while ('\0' != *ptr) { if (NULL == (eq = strchr (ptr, '='))) @@ -248,7 +244,7 @@ lookup_sub_value(char *dest, keylen)) && (eq == &ptr[keylen]) ) { - if (q2 == NULL) + if (NULL == q2) { len = strlen (q1) + 1; if (size > len) @@ -309,7 +305,7 @@ check_nonce_nc (struct MHD_Connection *connection, /* super-fast xor-based "hash" function for HT lookup in nonce array */ off = 0; np = nonce; - while (*np != '\0') + while ('\0' != *np) { off = (off << 8) | (*np ^ (off >> 24)); np++; @@ -321,19 +317,19 @@ check_nonce_nc (struct MHD_Connection *connection, * then only increase the nonce counter by one. */ - pthread_mutex_lock(&connection->daemon->nnc_lock); - if (nc == 0) + pthread_mutex_lock (&connection->daemon->nnc_lock); + if (0 == nc) { strcpy(connection->daemon->nnc[off].nonce, nonce); connection->daemon->nnc[off].nc = 0; - pthread_mutex_unlock(&connection->daemon->nnc_lock); + pthread_mutex_unlock (&connection->daemon->nnc_lock); return MHD_YES; } if ( (nc <= connection->daemon->nnc[off].nc) || (0 != strcmp(connection->daemon->nnc[off].nonce, nonce)) ) { - pthread_mutex_unlock(&connection->daemon->nnc_lock); + pthread_mutex_unlock (&connection->daemon->nnc_lock); #if HAVE_MESSAGES MHD_DLOG (connection->daemon, "Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"); @@ -341,7 +337,7 @@ check_nonce_nc (struct MHD_Connection *connection, return MHD_NO; } connection->daemon->nnc[off].nc = nc; - pthread_mutex_unlock(&connection->daemon->nnc_lock); + pthread_mutex_unlock (&connection->daemon->nnc_lock); return MHD_YES; } @@ -360,21 +356,19 @@ MHD_digest_auth_get_username(struct MHD_Connection *connection) char user[MAX_USERNAME_LENGTH]; const char *header; - header = MHD_lookup_connection_value(connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_AUTHORIZATION); - if (header == NULL) + if (NULL == (header = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION))) return NULL; - if (strncmp(header, _BASE, strlen(_BASE)) != 0) + if (0 != strncmp (header, _BASE, strlen (_BASE))) return NULL; header += strlen (_BASE); - len = lookup_sub_value(user, - sizeof (user), - header, - "username"); - if (!len) + if (0 == (len = lookup_sub_value (user, + sizeof (user), + header, + "username"))) return NULL; - return strdup(user); + return strdup (user); } @@ -403,27 +397,27 @@ calculate_nonce (uint32_t nonce_time, struct MD5Context md5; unsigned char timestamp[4]; unsigned char tmpnonce[MD5_DIGEST_SIZE]; - char timestamphex[sizeof(timestamp)*2+1]; + char timestamphex[sizeof(timestamp) * 2 + 1]; MD5Init (&md5); timestamp[0] = (nonce_time & 0xff000000) >> 0x18; timestamp[1] = (nonce_time & 0x00ff0000) >> 0x10; timestamp[2] = (nonce_time & 0x0000ff00) >> 0x08; timestamp[3] = (nonce_time & 0x000000ff); - MD5Update(&md5, timestamp, 4); - MD5Update(&md5, ":", 1); - MD5Update(&md5, method, strlen(method)); - MD5Update(&md5, ":", 1); + MD5Update (&md5, timestamp, 4); + MD5Update (&md5, ":", 1); + MD5Update (&md5, method, strlen(method)); + MD5Update (&md5, ":", 1); if (rnd_size > 0) - MD5Update(&md5, rnd, rnd_size); - MD5Update(&md5, ":", 1); - MD5Update(&md5, uri, strlen(uri)); - MD5Update(&md5, ":", 1); - MD5Update(&md5, realm, strlen(realm)); + MD5Update (&md5, rnd, rnd_size); + MD5Update (&md5, ":", 1); + MD5Update (&md5, uri, strlen(uri)); + MD5Update (&md5, ":", 1); + MD5Update (&md5, realm, strlen(realm)); MD5Final (tmpnonce, &md5); - cvthex(tmpnonce, sizeof (tmpnonce), nonce); - cvthex(timestamp, 4, timestamphex); - strncat(nonce, timestamphex, 8); + cvthex (tmpnonce, sizeof (tmpnonce), nonce); + cvthex (timestamp, 4, timestamphex); + strncat (nonce, timestamphex, 8); } @@ -450,11 +444,12 @@ test_header (struct MHD_Connection *connection, continue; if (0 != strcmp (key, pos->header)) continue; - if ( (NULL == value) && (NULL == pos->value)) + if ( (NULL == value) && + (NULL == pos->value) ) return MHD_YES; - if ( (NULL == value) || (NULL == pos->value)) - continue; - if (0 != strcmp (value, pos->value)) + if ( (NULL == value) || + (NULL == pos->value) || + (0 != strcmp (value, pos->value)) ) continue; return MHD_YES; } @@ -487,11 +482,11 @@ check_argument_match (struct MHD_Connection *connection, num_headers = 0; memcpy (argb, args, slen); argp = argb; - while ( (argp != NULL) && - (argp[0] != '\0') ) + while ( (NULL != argp) && + ('\0' != argp[0]) ) { equals = strchr (argp, '='); - if (equals == NULL) + if (NULL == equals) { /* add with 'value' NULL */ connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, @@ -505,7 +500,7 @@ check_argument_match (struct MHD_Connection *connection, equals[0] = '\0'; equals++; amper = strchr (equals, '&'); - if (amper != NULL) + if (NULL != amper) { amper[0] = '\0'; amper++; @@ -548,11 +543,11 @@ check_argument_match (struct MHD_Connection *connection, * MHD_INVALID_NONCE if nonce is invalid */ int -MHD_digest_auth_check(struct MHD_Connection *connection, - const char *realm, - const char *username, - const char *password, - unsigned int nonce_timeout) +MHD_digest_auth_check (struct MHD_Connection *connection, + const char *realm, + const char *username, + const char *password, + unsigned int nonce_timeout) { size_t len; const char *header; @@ -571,41 +566,43 @@ MHD_digest_auth_check(struct MHD_Connection *connection, size_t left; /* number of characters left in 'header' for 'uri' */ unsigned long int nci; - header = MHD_lookup_connection_value(connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_AUTHORIZATION); - if (header == NULL) + header = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION); + if (NULL == header) return MHD_NO; - if (strncmp(header, _BASE, strlen(_BASE)) != 0) + if (0 != strncmp(header, _BASE, strlen(_BASE))) return MHD_NO; header += strlen (_BASE); left = strlen (header); { char un[MAX_USERNAME_LENGTH]; - len = lookup_sub_value(un, - sizeof (un), - header, "username"); - if ( (!len) || - (strcmp(username, un) != 0) ) + + len = lookup_sub_value (un, + sizeof (un), + header, "username"); + if ( (0 == len) || + (0 != strcmp(username, un)) ) return MHD_NO; left -= strlen ("username") + len; } { char r[MAX_REALM_LENGTH]; + len = lookup_sub_value(r, sizeof (r), header, "realm"); - if ( (!len) || - (strcmp(realm, r) != 0) ) + if ( (0 == len) || + (0 != strcmp(realm, r)) ) return MHD_NO; left -= strlen ("realm") + len; } - if (0 == (len = lookup_sub_value(nonce, - sizeof (nonce), - header, "nonce"))) + if (0 == (len = lookup_sub_value (nonce, + sizeof (nonce), + header, "nonce"))) return MHD_NO; left -= strlen ("nonce") + len; @@ -640,7 +637,8 @@ MHD_digest_auth_check(struct MHD_Connection *connection, } { const char *args = strchr (uri, '?'); - if (args == NULL) + + if (NULL == args) args = ""; else args++; @@ -672,16 +670,16 @@ MHD_digest_auth_check(struct MHD_Connection *connection, * very hard to achieve. */ - if (0 != strcmp(nonce, noncehashexp)) + if (0 != strcmp (nonce, noncehashexp)) return MHD_INVALID_NONCE; - if ( (0 == lookup_sub_value(cnonce, - sizeof (cnonce), - header, "cnonce")) || - (0 == lookup_sub_value(qop, sizeof (qop), header, "qop")) || + if ( (0 == lookup_sub_value (cnonce, + sizeof (cnonce), + header, "cnonce")) || + (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) || ( (0 != strcmp (qop, "auth")) && (0 != strcmp (qop, "")) ) || - (0 == lookup_sub_value(nc, sizeof (nc), header, "nc")) || - (0 == lookup_sub_value(response, sizeof (response), header, "response")) ) + (0 == lookup_sub_value (nc, sizeof (nc), header, "nc")) || + (0 == lookup_sub_value (response, sizeof (response), header, "response")) ) { #if HAVE_MESSAGES MHD_DLOG (connection->daemon, @@ -691,7 +689,8 @@ MHD_digest_auth_check(struct MHD_Connection *connection, } nci = strtoul (nc, &end, 16); if ( ('\0' != *end) || - ( (LONG_MAX == nci) && (errno == ERANGE) ) ) + ( (LONG_MAX == nci) && + (ERANGE == errno) ) ) { #if HAVE_MESSAGES MHD_DLOG (connection->daemon, @@ -715,16 +714,18 @@ MHD_digest_auth_check(struct MHD_Connection *connection, nonce, cnonce, ha1); - digest_calc_response(ha1, - nonce, - nc, - cnonce, - qop, - connection->method, - uri, - hentity, - respexp); - return strcmp(response, respexp) == 0 ? MHD_YES : MHD_NO; + digest_calc_response (ha1, + nonce, + nc, + cnonce, + qop, + connection->method, + uri, + hentity, + respexp); + return (0 == strcmp(response, respexp)) + ? MHD_YES + : MHD_NO; } } @@ -740,11 +741,11 @@ MHD_digest_auth_check(struct MHD_Connection *connection, * @return MHD_YES on success, MHD_NO otherwise */ int -MHD_queue_auth_fail_response(struct MHD_Connection *connection, - const char *realm, - const char *opaque, - struct MHD_Response *response, - int signal_stale) +MHD_queue_auth_fail_response (struct MHD_Connection *connection, + const char *realm, + const char *opaque, + struct MHD_Response *response, + int signal_stale) { int ret; size_t hlen; @@ -767,22 +768,27 @@ MHD_queue_auth_fail_response(struct MHD_Connection *connection, return MHD_NO; } /* Building the authentication header */ - hlen = snprintf(NULL, - 0, - "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", - realm, - nonce, - opaque, - signal_stale ? ",stale=\"true\"" : ""); + hlen = snprintf (NULL, + 0, + "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", + realm, + nonce, + opaque, + signal_stale + ? ",stale=\"true\"" + : ""); { char header[hlen + 1]; - snprintf(header, - sizeof(header), - "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", - realm, - nonce, - opaque, - signal_stale ? ",stale=\"true\"" : ""); + + snprintf (header, + sizeof(header), + "Digest realm=\"%s\",qop=\"auth\",nonce=\"%s\",opaque=\"%s\"%s", + realm, + nonce, + opaque, + signal_stale + ? ",stale=\"true\"" + : ""); ret = MHD_add_response_header(response, MHD_HTTP_HEADER_WWW_AUTHENTICATE, header); @@ -795,105 +801,4 @@ MHD_queue_auth_fail_response(struct MHD_Connection *connection, } -/** - * Get the username and password from the basic authorization header sent by the client - * - * @param connection The MHD connection structure - * @param password a pointer for the password - * @return NULL if no username could be found, a pointer - * to the username if found - */ -char * -MHD_basic_auth_get_username_password(struct MHD_Connection *connection, - char** password) -{ - const char *header; - char *decode; - const char *separator; - char *user; - - header = MHD_lookup_connection_value(connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_AUTHORIZATION); - if (header == NULL) - return NULL; - if (strncmp(header, _BASIC_BASE, strlen(_BASIC_BASE)) != 0) - return NULL; - header += strlen(_BASIC_BASE); - decode = BASE64Decode(header); - if (decode == NULL) - { -#if HAVE_MESSAGES - MHD_DLOG(connection->daemon, - "Error decoding basic authentication\n"); -#endif - return NULL; - } - /* Find user:password pattern */ - separator = strchr (decode, ':'); - if (separator == NULL) - { -#if HAVE_MESSAGES - MHD_DLOG(connection->daemon, - "Basic authentication doesn't contain ':' separator\n"); -#endif - free(decode); - return NULL; - } - user = strdup(decode); - if (NULL == user) - { - free (decode); - return NULL; - } - user[separator - decode] = '\0'; /* cut off at ':' */ - if (password != NULL) - { - *password = strdup(separator + 1); - if (NULL == *password) - { -#if HAVE_MESSAGES - MHD_DLOG(connection->daemon, - "Failed to allocate memory for password\n"); -#endif - free (decode); - free (user); - return NULL; - } - } - free(decode); - return user; -} - - -/** - * Queues a response to request basic authentication from the client - * - * @param connection The MHD connection structure - * @param realm the realm presented to the client - * @return MHD_YES on success, MHD_NO otherwise - */ -int -MHD_queue_basic_auth_fail_response(struct MHD_Connection *connection, - const char *realm, - struct MHD_Response *response) -{ - int ret; - size_t hlen = strlen(realm) + strlen("Basic realm=\"\"") + 1; - char header[hlen]; - - snprintf(header, - sizeof (header), - "Basic realm=\"%s\"", - realm); - ret = MHD_add_response_header(response, - MHD_HTTP_HEADER_WWW_AUTHENTICATE, - header); - if (MHD_YES == ret) - ret = MHD_queue_response(connection, - MHD_HTTP_UNAUTHORIZED, - response); - return ret; -} - /* end of digestauth.c */ diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am @@ -33,10 +33,14 @@ endif if ENABLE_DAUTH noinst_PROGRAMS += \ - authorization_example \ digest_auth_example endif +if ENABLE_BAUTH +noinst_PROGRAMS += \ + authorization_example +endif + if HAVE_W32 IBERTY=-liberty endif