libmicrohttpd

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

test_auth_parse.c (82199B)


      1 /*
      2   This file is part of libmicrohttpd
      3   Copyright (C) 2022-2023 Karlson2k (Evgeny Grin)
      4 
      5   This test tool is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 2, or
      8   (at your option) any later version.
      9 
     10   This test tool is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library; if not, write to the Free Software
     17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     18 */
     19 
     20 /**
     21  * @file microhttpd/test_auth_parse.c
     22  * @brief  Unit tests for request's 'Authorization" headers parsing
     23  * @author Karlson2k (Evgeny Grin)
     24  */
     25 
     26 #include "mhd_options.h"
     27 #include <string.h>
     28 #include <stdio.h>
     29 #include <errno.h>
     30 #include "gen_auth.h"
     31 #ifdef BAUTH_SUPPORT
     32 #include "basicauth.h"
     33 #endif /* BAUTH_SUPPORT */
     34 #ifdef DAUTH_SUPPORT
     35 #include "digestauth.h"
     36 #endif /* DAUTH_SUPPORT */
     37 #include "mhd_assert.h"
     38 #include "internal.h"
     39 #include "connection.h"
     40 
     41 /* Turn any MHD_PANIC() or failing mhd_assert() reached from this
     42    test into a marked, classifiable test error (TESTING.md, P5). */
     43 #include "mhd_panic_tripwire.h"
     44 
     45 
     46 #ifndef MHD_STATICSTR_LEN_
     47 /**
     48  * Determine length of static string / macro strings at compile time.
     49  */
     50 #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
     51 #endif /* ! MHD_STATICSTR_LEN_ */
     52 
     53 
     54 #if defined(HAVE___FUNC__)
     55 #define externalErrorExit(ignore) \
     56     _externalErrorExit_func(NULL, __func__, __LINE__)
     57 #define externalErrorExitDesc(errDesc) \
     58     _externalErrorExit_func(errDesc, __func__, __LINE__)
     59 #define mhdErrorExit(ignore) \
     60     _mhdErrorExit_func(NULL, __func__, __LINE__)
     61 #define mhdErrorExitDesc(errDesc) \
     62     _mhdErrorExit_func(errDesc, __func__, __LINE__)
     63 #elif defined(HAVE___FUNCTION__)
     64 #define externalErrorExit(ignore) \
     65     _externalErrorExit_func(NULL, __FUNCTION__, __LINE__)
     66 #define externalErrorExitDesc(errDesc) \
     67     _externalErrorExit_func(errDesc, __FUNCTION__, __LINE__)
     68 #define mhdErrorExit(ignore) \
     69     _mhdErrorExit_func(NULL, __FUNCTION__, __LINE__)
     70 #define mhdErrorExitDesc(errDesc) \
     71     _mhdErrorExit_func(errDesc, __FUNCTION__, __LINE__)
     72 #else
     73 #define externalErrorExit(ignore) _externalErrorExit_func(NULL, NULL, __LINE__)
     74 #define externalErrorExitDesc(errDesc) \
     75   _externalErrorExit_func(errDesc, NULL, __LINE__)
     76 #define mhdErrorExit(ignore) _mhdErrorExit_func(NULL, NULL, __LINE__)
     77 #define mhdErrorExitDesc(errDesc) _mhdErrorExit_func(errDesc, NULL, __LINE__)
     78 #endif
     79 
     80 
     81 _MHD_NORETURN static void
     82 _externalErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
     83 {
     84   if ((NULL != errDesc) && (0 != errDesc[0]))
     85     fprintf (stderr, "%s", errDesc);
     86   else
     87     fprintf (stderr, "System or external library call failed");
     88   if ((NULL != funcName) && (0 != funcName[0]))
     89     fprintf (stderr, " in %s", funcName);
     90   if (0 < lineNum)
     91     fprintf (stderr, " at line %d", lineNum);
     92 
     93   fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
     94            strerror (errno));
     95 #ifdef MHD_WINSOCK_SOCKETS
     96   fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
     97 #endif /* MHD_WINSOCK_SOCKETS */
     98   fflush (stderr);
     99   exit (99);
    100 }
    101 
    102 
    103 _MHD_NORETURN static void
    104 _mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
    105 {
    106   if ((NULL != errDesc) && (0 != errDesc[0]))
    107     fprintf (stderr, "%s", errDesc);
    108   else
    109     fprintf (stderr, "MHD unexpected error");
    110   if ((NULL != funcName) && (0 != funcName[0]))
    111     fprintf (stderr, " in %s", funcName);
    112   if (0 < lineNum)
    113     fprintf (stderr, " at line %d", lineNum);
    114 
    115   fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
    116            strerror (errno));
    117 
    118   fflush (stderr);
    119   exit (8);
    120 }
    121 
    122 
    123 /* Declarations for local replacements of MHD functions */
    124 /* None, headers are included */
    125 
    126 /* Local replacements implementations */
    127 
    128 void *
    129 MHD_connection_alloc_memory_ (struct MHD_Connection *connection,
    130                               size_t size)
    131 {
    132   void *ret;
    133   if (NULL == connection)
    134     mhdErrorExitDesc ("'connection' parameter is NULL");
    135   /* Use 'read_buffer' just as a flag */
    136   if (NULL != connection->read_buffer)
    137   {
    138     /* Use 'write_buffer' just as a flag */
    139     if (NULL != connection->write_buffer)
    140       mhdErrorExitDesc ("Unexpected third memory allocation, " \
    141                         "while previous allocations was not freed");
    142   }
    143   /* Just use simple "malloc()" here */
    144   ret = malloc (size);
    145   if (NULL == ret)
    146     externalErrorExit ();
    147 
    148   /* Track up to two allocations */
    149   if (NULL == connection->read_buffer)
    150     connection->read_buffer = (char *) ret;
    151   else
    152     connection->write_buffer = (char *) ret;
    153   return ret;
    154 }
    155 
    156 
    157 /**
    158  * Static variable to avoid additional malloc()/free() pairs
    159  */
    160 static struct MHD_Connection conn;
    161 
    162 void
    163 MHD_DLOG (const struct MHD_Daemon *daemon,
    164           const char *format,
    165           ...)
    166 {
    167   (void) daemon;
    168   if (! conn.rq.client_aware)
    169   {
    170     fprintf (stderr, "Unexpected call of 'MHD_LOG(), format is '%s'.\n",
    171              format);
    172     fprintf (stderr, "'Authorization' header value: '%s'.\n",
    173              (NULL == conn.rq.headers_received) ?
    174              "NULL" : (conn.rq.headers_received->value));
    175     mhdErrorExit ();
    176   }
    177   conn.rq.client_aware = false; /* Clear the flag */
    178   return;
    179 }
    180 
    181 
    182 /**
    183  * Static variable to avoid additional malloc()/free() pairs
    184  */
    185 static struct MHD_HTTP_Req_Header req_header;
    186 
    187 static void
    188 test_global_init (void)
    189 {
    190   memset (&conn, 0, sizeof(conn));
    191   memset (&req_header, 0, sizeof(req_header));
    192 }
    193 
    194 
    195 /**
    196  * Add "Authorization" client test header.
    197  *
    198  * @param hdr the pointer to the headr value, must be valid until end of
    199  *            checking of this header
    200  * @param hdr_len the length of the @a hdr
    201  * @note The function is NOT thread-safe
    202  */
    203 static void
    204 add_AuthHeader (const char *hdr, size_t hdr_len)
    205 {
    206   if ((NULL != conn.rq.headers_received) ||
    207       (NULL != conn.rq.headers_received_tail))
    208     externalErrorExitDesc ("Connection's test headers are not empty already");
    209   if (NULL != hdr)
    210   {
    211     /* Skip initial whitespaces, emulate MHD's headers processing */
    212     while (' ' == hdr[0] || '\t' == hdr[0])
    213     {
    214       hdr++;
    215       hdr_len--;
    216     }
    217     req_header.header = MHD_HTTP_HEADER_AUTHORIZATION; /* Static string */
    218     req_header.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION);
    219     req_header.value = hdr;
    220     req_header.value_size = hdr_len;
    221     req_header.kind = MHD_HEADER_KIND;
    222     req_header.prev = NULL;
    223     req_header.next = NULL;
    224     conn.rq.headers_received = &req_header;
    225     conn.rq.headers_received_tail = &req_header;
    226   }
    227   else
    228   {
    229     conn.rq.headers_received = NULL;
    230     conn.rq.headers_received_tail = NULL;
    231   }
    232   conn.state = MHD_CONNECTION_FULL_REQ_RECEIVED; /* Should be a typical value */
    233 }
    234 
    235 
    236 #ifdef BAUTH_SUPPORT
    237 /**
    238  * Parse previously added Basic Authorization client header and return
    239  * result of the parsing.
    240  *
    241  * Function performs basic checking of the parsing result
    242  * @return result of header parsing
    243  * @note The function is NOT thread-safe
    244  */
    245 static const struct MHD_RqBAuth *
    246 get_BAuthRqParams (void)
    247 {
    248   const struct MHD_RqBAuth *res1;
    249   const struct MHD_RqBAuth *res2;
    250   /* Store pointer in some member unused in this test */
    251   res1 = MHD_get_rq_bauth_params_ (&conn);
    252   if (! conn.rq.bauth_tried)
    253     mhdErrorExitDesc ("'rq.bauth_tried' is not set");
    254   res2 = MHD_get_rq_bauth_params_ (&conn);
    255   if (res1 != res2)
    256     mhdErrorExitDesc ("MHD_get_rq_bauth_params_() returned another pointer " \
    257                       "when called for the second time");
    258   return res2;
    259 }
    260 
    261 
    262 #endif /* BAUTH_SUPPORT */
    263 
    264 #ifdef DAUTH_SUPPORT
    265 /**
    266  * Parse previously added Digest Authorization client header and return
    267  * result of the parsing.
    268  *
    269  * Function performs basic checking of the parsing result
    270  * @return result of header parsing
    271  * @note The function is NOT thread-safe
    272  */
    273 static const struct MHD_RqDAuth *
    274 get_DAuthRqParams (void)
    275 {
    276   const struct MHD_RqDAuth *res1;
    277   const struct MHD_RqDAuth *res2;
    278   /* Store pointer in some member unused in this test */
    279   res1 = MHD_get_rq_dauth_params_ (&conn);
    280   if (! conn.rq.dauth_tried)
    281     mhdErrorExitDesc ("'rq.dauth_tried' is not set");
    282   res2 = MHD_get_rq_dauth_params_ (&conn);
    283   if (res1 != res2)
    284     mhdErrorExitDesc ("MHD_get_rq_bauth_params_() returned another pointer " \
    285                       "when called for the second time");
    286   return res2;
    287 }
    288 
    289 
    290 #endif /* DAUTH_SUPPORT */
    291 
    292 
    293 static void
    294 clean_AuthHeaders (void)
    295 {
    296   conn.state = MHD_CONNECTION_INIT;
    297   free (conn.read_buffer);
    298   free (conn.write_buffer);
    299 
    300 #ifdef BAUTH_SUPPORT
    301   conn.rq.bauth_tried = false;
    302 #endif /* BAUTH_SUPPORT */
    303 #ifdef DAUTH_SUPPORT
    304   conn.rq.dauth_tried = false;
    305 #endif /* BAUTH_SUPPORT */
    306 
    307 #ifdef BAUTH_SUPPORT
    308   if ((NULL != conn.rq.bauth) &&
    309       (conn.read_buffer != (const char *) conn.rq.bauth) &&
    310       (conn.write_buffer != (const char *) conn.rq.bauth))
    311     externalErrorExitDesc ("Memory allocation is not tracked as it should be");
    312   conn.rq.bauth = NULL;
    313 #endif /* BAUTH_SUPPORT */
    314 #ifdef DAUTH_SUPPORT
    315   if ((NULL != conn.rq.dauth) &&
    316       (conn.read_buffer != (const char *) conn.rq.dauth) &&
    317       (conn.write_buffer != (const char *) conn.rq.dauth))
    318     externalErrorExitDesc ("Memory allocation is not tracked as it should be");
    319   conn.rq.dauth = NULL;
    320 #endif /* BAUTH_SUPPORT */
    321 
    322   conn.rq.headers_received = NULL;
    323   conn.rq.headers_received_tail = NULL;
    324 
    325   conn.read_buffer = NULL;
    326   conn.write_buffer = NULL;
    327   conn.rq.client_aware = false;
    328 }
    329 
    330 
    331 enum MHD_TestAuthType
    332 {
    333   MHD_TEST_AUTHTYPE_NONE,
    334   MHD_TEST_AUTHTYPE_BASIC,
    335   MHD_TEST_AUTHTYPE_DIGEST,
    336 };
    337 
    338 
    339 /* return zero if succeed, non-zero otherwise */
    340 static unsigned int
    341 expect_result_type_n (const char *hdr, size_t hdr_len,
    342                       const enum MHD_TestAuthType expected_type,
    343                       int expect_log,
    344                       unsigned int line_num)
    345 {
    346   unsigned int ret;
    347 
    348   ret = 0;
    349   add_AuthHeader (hdr, hdr_len);
    350   if (expect_log)
    351     conn.rq.client_aware = true; /* Use like a flag */
    352   else
    353     conn.rq.client_aware = false;
    354 #ifdef BAUTH_SUPPORT
    355   if (MHD_TEST_AUTHTYPE_BASIC == expected_type)
    356   {
    357     if (NULL == get_BAuthRqParams ())
    358     {
    359       fprintf (stderr,
    360                "'Authorization' header parsing FAILED:\n"
    361                "Basic Authorization was not found, while it should be.\n");
    362       ret++;
    363     }
    364   }
    365   else
    366 #endif /* BAUTH_SUPPORT */
    367 #ifdef DAUTH_SUPPORT
    368   if (MHD_TEST_AUTHTYPE_DIGEST == expected_type)
    369   {
    370     if (NULL == get_DAuthRqParams ())
    371     {
    372       fprintf (stderr,
    373                "'Authorization' header parsing FAILED:\n"
    374                "Digest Authorization was not found, while it should be.\n");
    375       ret++;
    376     }
    377   }
    378   else
    379 #endif /* BAUTH_SUPPORT */
    380   {
    381 #ifdef BAUTH_SUPPORT
    382     if (NULL != get_BAuthRqParams ())
    383     {
    384       fprintf (stderr,
    385                "'Authorization' header parsing FAILED:\n"
    386                "Found Basic Authorization, while it should not be.\n");
    387       ret++;
    388     }
    389 #endif /* BAUTH_SUPPORT */
    390 #ifdef DAUTH_SUPPORT
    391     if (NULL != get_DAuthRqParams ())
    392     {
    393       fprintf (stderr,
    394                "'Authorization' header parsing FAILED:\n"
    395                "Found Digest Authorization, while it should not be.\n");
    396       ret++;
    397     }
    398 #endif /* DAUTH_SUPPORT */
    399   }
    400 #if defined(BAUTH_SUPPORT) && defined(DAUTH_SUPPORT)
    401   if (conn.rq.client_aware)
    402   {
    403     fprintf (stderr,
    404              "'Authorization' header parsing ERROR:\n"
    405              "Log function must be called, but it was not.\n");
    406     ret++;
    407   }
    408 #endif /* BAUTH_SUPPORT && DAUTH_SUPPORT */
    409 
    410   if (ret)
    411   {
    412     if (NULL == hdr)
    413       fprintf (stderr,
    414                "Input: Absence of 'Authorization' header.\n");
    415     else if (0 == hdr_len)
    416       fprintf (stderr,
    417                "Input: empty 'Authorization' header.\n");
    418     else
    419       fprintf (stderr,
    420                "Input Header: '%.*s'\n", (int) hdr_len, hdr);
    421     fprintf (stderr,
    422              "The check is at line: %u\n\n", line_num);
    423     ret = 1;
    424   }
    425   clean_AuthHeaders ();
    426 
    427   return ret;
    428 }
    429 
    430 
    431 #define expect_result_type(h,t,l) \
    432     expect_result_type_n(h,MHD_STATICSTR_LEN_(h),t,l,__LINE__)
    433 
    434 
    435 static unsigned int
    436 check_type (void)
    437 {
    438   unsigned int r = 0; /**< The number of errors */
    439 
    440   r += expect_result_type_n (NULL, 0, MHD_TEST_AUTHTYPE_NONE, 0, __LINE__);
    441 
    442   r += expect_result_type ("", MHD_TEST_AUTHTYPE_NONE, 0);
    443   r += expect_result_type (" ", MHD_TEST_AUTHTYPE_NONE, 0);
    444   r += expect_result_type ("    ", MHD_TEST_AUTHTYPE_NONE, 0);
    445   r += expect_result_type ("\t", MHD_TEST_AUTHTYPE_NONE, 0);
    446   r += expect_result_type (" \t", MHD_TEST_AUTHTYPE_NONE, 0);
    447   r += expect_result_type ("\t ", MHD_TEST_AUTHTYPE_NONE, 0);
    448   r += expect_result_type ("\t \t", MHD_TEST_AUTHTYPE_NONE, 0);
    449   r += expect_result_type (" \t ", MHD_TEST_AUTHTYPE_NONE, 0);
    450   r += expect_result_type (" \t \t", MHD_TEST_AUTHTYPE_NONE, 0);
    451   r += expect_result_type ("\t \t ", MHD_TEST_AUTHTYPE_NONE, 0);
    452 
    453   r += expect_result_type ("Basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    454   r += expect_result_type (" Basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    455   r += expect_result_type ("\tBasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    456   r += expect_result_type ("\t Basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    457   r += expect_result_type (" \tBasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    458   r += expect_result_type ("    Basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    459   r += expect_result_type ("\t\t\tBasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    460   r += expect_result_type ("\t\t  \tBasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    461   r += expect_result_type ("\t\t  \t Basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    462   r += expect_result_type ("Basic ", MHD_TEST_AUTHTYPE_BASIC, 0);
    463   r += expect_result_type ("Basic \t", MHD_TEST_AUTHTYPE_BASIC, 0);
    464   r += expect_result_type ("Basic \t ", MHD_TEST_AUTHTYPE_BASIC, 0);
    465   r += expect_result_type ("Basic 123", MHD_TEST_AUTHTYPE_BASIC, 0);
    466   r += expect_result_type ("Basic \t123", MHD_TEST_AUTHTYPE_BASIC, 0);
    467   r += expect_result_type ("Basic  abc ", MHD_TEST_AUTHTYPE_BASIC, 0);
    468   r += expect_result_type ("bAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    469   r += expect_result_type (" bAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    470   r += expect_result_type ("\tbAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    471   r += expect_result_type ("\t bAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    472   r += expect_result_type (" \tbAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    473   r += expect_result_type ("    bAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    474   r += expect_result_type ("\t\t\tbAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    475   r += expect_result_type ("\t\t  \tbAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    476   r += expect_result_type ("\t\t  \t bAsIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    477   r += expect_result_type ("bAsIC ", MHD_TEST_AUTHTYPE_BASIC, 0);
    478   r += expect_result_type ("bAsIC \t", MHD_TEST_AUTHTYPE_BASIC, 0);
    479   r += expect_result_type ("bAsIC \t ", MHD_TEST_AUTHTYPE_BASIC, 0);
    480   r += expect_result_type ("bAsIC 123", MHD_TEST_AUTHTYPE_BASIC, 0);
    481   r += expect_result_type ("bAsIC \t123", MHD_TEST_AUTHTYPE_BASIC, 0);
    482   r += expect_result_type ("bAsIC  abc ", MHD_TEST_AUTHTYPE_BASIC, 0);
    483   r += expect_result_type ("basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    484   r += expect_result_type (" basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    485   r += expect_result_type ("\tbasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    486   r += expect_result_type ("\t basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    487   r += expect_result_type (" \tbasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    488   r += expect_result_type ("    basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    489   r += expect_result_type ("\t\t\tbasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    490   r += expect_result_type ("\t\t  \tbasic", MHD_TEST_AUTHTYPE_BASIC, 0);
    491   r += expect_result_type ("\t\t  \t basic", MHD_TEST_AUTHTYPE_BASIC, 0);
    492   r += expect_result_type ("basic ", MHD_TEST_AUTHTYPE_BASIC, 0);
    493   r += expect_result_type ("basic \t", MHD_TEST_AUTHTYPE_BASIC, 0);
    494   r += expect_result_type ("basic \t ", MHD_TEST_AUTHTYPE_BASIC, 0);
    495   r += expect_result_type ("basic 123", MHD_TEST_AUTHTYPE_BASIC, 0);
    496   r += expect_result_type ("basic \t123", MHD_TEST_AUTHTYPE_BASIC, 0);
    497   r += expect_result_type ("basic  abc ", MHD_TEST_AUTHTYPE_BASIC, 0);
    498   r += expect_result_type ("BASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    499   r += expect_result_type (" BASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    500   r += expect_result_type ("\tBASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    501   r += expect_result_type ("\t BASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    502   r += expect_result_type (" \tBASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    503   r += expect_result_type ("    BASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    504   r += expect_result_type ("\t\t\tBASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    505   r += expect_result_type ("\t\t  \tBASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    506   r += expect_result_type ("\t\t  \t BASIC", MHD_TEST_AUTHTYPE_BASIC, 0);
    507   r += expect_result_type ("BASIC ", MHD_TEST_AUTHTYPE_BASIC, 0);
    508   r += expect_result_type ("BASIC \t", MHD_TEST_AUTHTYPE_BASIC, 0);
    509   r += expect_result_type ("BASIC \t ", MHD_TEST_AUTHTYPE_BASIC, 0);
    510   r += expect_result_type ("BASIC 123", MHD_TEST_AUTHTYPE_BASIC, 0);
    511   r += expect_result_type ("BASIC \t123", MHD_TEST_AUTHTYPE_BASIC, 0);
    512   r += expect_result_type ("BASIC  abc ", MHD_TEST_AUTHTYPE_BASIC, 0);
    513   /* Only single token is allowed for 'Basic' Authorization */
    514   r += expect_result_type ("Basic a b", MHD_TEST_AUTHTYPE_NONE, 1);
    515   r += expect_result_type ("Basic a\tb", MHD_TEST_AUTHTYPE_NONE, 1);
    516   r += expect_result_type ("Basic a\tb", MHD_TEST_AUTHTYPE_NONE, 1);
    517   r += expect_result_type ("Basic abc1 b", MHD_TEST_AUTHTYPE_NONE, 1);
    518   r += expect_result_type ("Basic c abc1", MHD_TEST_AUTHTYPE_NONE, 1);
    519   r += expect_result_type ("Basic c abc1 ", MHD_TEST_AUTHTYPE_NONE, 1);
    520   r += expect_result_type ("Basic c abc1\t", MHD_TEST_AUTHTYPE_NONE, 1);
    521   r += expect_result_type ("Basic c\tabc1\t", MHD_TEST_AUTHTYPE_NONE, 1);
    522   r += expect_result_type ("Basic c abc1 b", MHD_TEST_AUTHTYPE_NONE, 1);
    523   r += expect_result_type ("Basic zyx, b", MHD_TEST_AUTHTYPE_NONE, 1);
    524   r += expect_result_type ("Basic zyx,b", MHD_TEST_AUTHTYPE_NONE, 1);
    525   r += expect_result_type ("Basic zyx ,b", MHD_TEST_AUTHTYPE_NONE, 1);
    526   r += expect_result_type ("Basic zyx;b", MHD_TEST_AUTHTYPE_NONE, 1);
    527   r += expect_result_type ("Basic zyx; b", MHD_TEST_AUTHTYPE_NONE, 1);
    528 
    529   r += expect_result_type ("Basic2", MHD_TEST_AUTHTYPE_NONE, 0);
    530   r += expect_result_type (" Basic2", MHD_TEST_AUTHTYPE_NONE, 0);
    531   r += expect_result_type (" Basic2 ", MHD_TEST_AUTHTYPE_NONE, 0);
    532   r += expect_result_type ("\tBasic2", MHD_TEST_AUTHTYPE_NONE, 0);
    533   r += expect_result_type ("\t Basic2", MHD_TEST_AUTHTYPE_NONE, 0);
    534   r += expect_result_type (" \tBasic2", MHD_TEST_AUTHTYPE_NONE, 0);
    535   r += expect_result_type ("    Basic2", MHD_TEST_AUTHTYPE_NONE, 0);
    536   r += expect_result_type ("\t\t\tBasic2", MHD_TEST_AUTHTYPE_NONE, 0);
    537   r += expect_result_type ("\t\t  \tBasic2", MHD_TEST_AUTHTYPE_NONE, 0);
    538   r += expect_result_type ("\t\t  \t Basic2", MHD_TEST_AUTHTYPE_NONE, 0);
    539   r += expect_result_type ("Basic2 ", MHD_TEST_AUTHTYPE_NONE, 0);
    540   r += expect_result_type ("Basic2 \t", MHD_TEST_AUTHTYPE_NONE, 0);
    541   r += expect_result_type ("Basic2 \t ", MHD_TEST_AUTHTYPE_NONE, 0);
    542   r += expect_result_type ("Basic2 123", MHD_TEST_AUTHTYPE_NONE, 0);
    543   r += expect_result_type ("Basic2 \t123", MHD_TEST_AUTHTYPE_NONE, 0);
    544   r += expect_result_type ("Basic2  abc ", MHD_TEST_AUTHTYPE_NONE, 0);
    545   r += expect_result_type ("BasicBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    546   r += expect_result_type (" BasicBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    547   r += expect_result_type ("\tBasicBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    548   r += expect_result_type ("\t BasicBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    549   r += expect_result_type (" \tBasicBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    550   r += expect_result_type ("BasicBasic ", MHD_TEST_AUTHTYPE_NONE, 0);
    551   r += expect_result_type ("BasicBasic \t", MHD_TEST_AUTHTYPE_NONE, 0);
    552   r += expect_result_type ("BasicBasic \t\t", MHD_TEST_AUTHTYPE_NONE, 0);
    553   r += expect_result_type ("BasicDigest", MHD_TEST_AUTHTYPE_NONE, 0);
    554   r += expect_result_type (" BasicDigest", MHD_TEST_AUTHTYPE_NONE, 0);
    555   r += expect_result_type ("BasicDigest ", MHD_TEST_AUTHTYPE_NONE, 0);
    556   r += expect_result_type ("Basic\0", MHD_TEST_AUTHTYPE_NONE, 0);
    557   r += expect_result_type ("\0" "Basic", MHD_TEST_AUTHTYPE_NONE, 0);
    558 
    559   r += expect_result_type ("Digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    560   r += expect_result_type (" Digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    561   r += expect_result_type ("\tDigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    562   r += expect_result_type ("\t Digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    563   r += expect_result_type (" \tDigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    564   r += expect_result_type ("    Digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    565   r += expect_result_type ("\t\t\tDigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    566   r += expect_result_type ("\t\t  \tDigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    567   r += expect_result_type ("\t\t  \t Digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    568   r += expect_result_type ("Digest ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    569   r += expect_result_type ("Digest \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    570   r += expect_result_type ("Digest \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    571   r += expect_result_type ("\tDigest ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    572   r += expect_result_type ("  Digest \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    573   r += expect_result_type ("\t \tDigest \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    574 
    575   r += expect_result_type ("digEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    576   r += expect_result_type (" digEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    577   r += expect_result_type ("\tdigEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    578   r += expect_result_type ("\t digEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    579   r += expect_result_type (" \tdigEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    580   r += expect_result_type ("    digEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    581   r += expect_result_type ("\t\t\tdigEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    582   r += expect_result_type ("\t\t  \tdigEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    583   r += expect_result_type ("\t\t  \t digEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    584   r += expect_result_type ("digEST ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    585   r += expect_result_type ("digEST \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    586   r += expect_result_type ("digEST \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    587   r += expect_result_type ("\tdigEST ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    588   r += expect_result_type ("  digEST \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    589   r += expect_result_type ("\t \tdigEST \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    590   r += expect_result_type ("digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    591   r += expect_result_type (" digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    592   r += expect_result_type ("\tdigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    593   r += expect_result_type ("\t digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    594   r += expect_result_type (" \tdigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    595   r += expect_result_type ("    digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    596   r += expect_result_type ("\t\t\tdigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    597   r += expect_result_type ("\t\t  \tdigest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    598   r += expect_result_type ("\t\t  \t digest", MHD_TEST_AUTHTYPE_DIGEST, 0);
    599   r += expect_result_type ("digest ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    600   r += expect_result_type ("digest \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    601   r += expect_result_type ("digest \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    602   r += expect_result_type ("\tdigest ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    603   r += expect_result_type ("  digest \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    604   r += expect_result_type ("\t \tdigest \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    605   r += expect_result_type ("DIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    606   r += expect_result_type (" DIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    607   r += expect_result_type ("\tDIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    608   r += expect_result_type ("\t DIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    609   r += expect_result_type (" \tDIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    610   r += expect_result_type ("    DIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    611   r += expect_result_type ("\t\t\tDIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    612   r += expect_result_type ("\t\t  \tDIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    613   r += expect_result_type ("\t\t  \t DIGEST", MHD_TEST_AUTHTYPE_DIGEST, 0);
    614   r += expect_result_type ("DIGEST ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    615   r += expect_result_type ("DIGEST \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    616   r += expect_result_type ("DIGEST \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    617   r += expect_result_type ("\tDIGEST ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    618   r += expect_result_type ("  DIGEST \t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    619   r += expect_result_type ("\t \tDIGEST \t ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    620   r += expect_result_type ("Digest ,", MHD_TEST_AUTHTYPE_DIGEST, 0);
    621   r += expect_result_type ("Digest ,\t", MHD_TEST_AUTHTYPE_DIGEST, 0);
    622   r += expect_result_type ("Digest ,  ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    623   r += expect_result_type ("Digest   ,  ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    624   r += expect_result_type ("Digest ,\t, ,\t, ,\t, ,", \
    625                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    626   r += expect_result_type ("Digest ,\t,\t,\t,\t,\t,\t,", \
    627                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    628   r += expect_result_type ("Digest a=b", MHD_TEST_AUTHTYPE_DIGEST, 0);
    629   r += expect_result_type ("Digest a=\"b\"", MHD_TEST_AUTHTYPE_DIGEST, 0);
    630   r += expect_result_type ("Digest nc=1", MHD_TEST_AUTHTYPE_DIGEST, 0);
    631   r += expect_result_type ("Digest nc=\"1\"", MHD_TEST_AUTHTYPE_DIGEST, 0);
    632   r += expect_result_type ("Digest a=b ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    633   r += expect_result_type ("Digest a=\"b\" ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    634   r += expect_result_type ("Digest nc=1 ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    635   r += expect_result_type ("Digest nc=\"1\" ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    636   r += expect_result_type ("Digest a = b", MHD_TEST_AUTHTYPE_DIGEST, 0);
    637   r += expect_result_type ("Digest a\t=\t\"b\"", \
    638                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    639   r += expect_result_type ("Digest nc =1", MHD_TEST_AUTHTYPE_DIGEST, 0);
    640   r += expect_result_type ("Digest nc= \"1\"", MHD_TEST_AUTHTYPE_DIGEST, 0);
    641   r += expect_result_type ("Digest a=\tb ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    642   r += expect_result_type ("Digest a = \"b\" ", MHD_TEST_AUTHTYPE_DIGEST, 0);
    643   r += expect_result_type ("Digest nc\t\t\t= 1 ", \
    644                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    645   r += expect_result_type ("Digest nc   =\t\t\t\"1\" ", \
    646                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    647   r += expect_result_type ("Digest nc =1,,,,", MHD_TEST_AUTHTYPE_DIGEST, 0);
    648   r += expect_result_type ("Digest nc =1  ,,,,", \
    649                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    650   r += expect_result_type ("Digest ,,,,nc= \"1 \"", \
    651                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    652   r += expect_result_type ("Digest ,,,,  nc= \" 1\"", \
    653                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    654   r += expect_result_type ("Digest ,,,, nc= \"1\",,,,", \
    655                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    656   r += expect_result_type ("Digest ,,,, nc= \"1\"  ,,,,", \
    657                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    658   r += expect_result_type ("Digest ,,,, nc= \"1\"  ,,,,", \
    659                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    660   r += expect_result_type ("Digest ,,,, nc= \"1\"  ,,,,", \
    661                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    662   r += expect_result_type ("Digest ,,,, nc= \"1\"  ,,,,,", \
    663                            MHD_TEST_AUTHTYPE_DIGEST, 0);
    664 
    665   r += expect_result_type ("Digest nc", MHD_TEST_AUTHTYPE_NONE, 1);
    666   r += expect_result_type ("Digest   nc", MHD_TEST_AUTHTYPE_NONE, 1);
    667   r += expect_result_type ("Digest nc  ", MHD_TEST_AUTHTYPE_NONE, 1);
    668   r += expect_result_type ("Digest nc  ,", MHD_TEST_AUTHTYPE_NONE, 1);
    669   r += expect_result_type ("Digest nc  , ", MHD_TEST_AUTHTYPE_NONE, 1);
    670   r += expect_result_type ("Digest \tnc\t  ", MHD_TEST_AUTHTYPE_NONE, 1);
    671   r += expect_result_type ("Digest \tnc\t  ", MHD_TEST_AUTHTYPE_NONE, 1);
    672   r += expect_result_type ("Digest nc,", MHD_TEST_AUTHTYPE_NONE, 1);
    673   r += expect_result_type ("Digest nc,uri", MHD_TEST_AUTHTYPE_NONE, 1);
    674   r += expect_result_type ("Digest nc=1,uri", MHD_TEST_AUTHTYPE_NONE, 1);
    675   r += expect_result_type ("Digest nc=1,uri   ", \
    676                            MHD_TEST_AUTHTYPE_NONE, 1);
    677   r += expect_result_type ("Digest nc=1,uri,", MHD_TEST_AUTHTYPE_NONE, 1);
    678   r += expect_result_type ("Digest nc=1, uri,", \
    679                            MHD_TEST_AUTHTYPE_NONE, 1);
    680   r += expect_result_type ("Digest nc=1,uri   ,", \
    681                            MHD_TEST_AUTHTYPE_NONE, 1);
    682   r += expect_result_type ("Digest nc=1,uri   , ", \
    683                            MHD_TEST_AUTHTYPE_NONE, 1);
    684   /* Binary zero */
    685   r += expect_result_type ("Digest nc=1\0", MHD_TEST_AUTHTYPE_NONE, 1);
    686   r += expect_result_type ("Digest nc=1\0" " ", \
    687                            MHD_TEST_AUTHTYPE_NONE, 1);
    688   r += expect_result_type ("Digest nc=1\t\0", MHD_TEST_AUTHTYPE_NONE, 1);
    689   r += expect_result_type ("Digest nc=\0" "1", MHD_TEST_AUTHTYPE_NONE, 1);
    690   /* Semicolon */
    691   r += expect_result_type ("Digest nc=1;", MHD_TEST_AUTHTYPE_NONE, 1);
    692   r += expect_result_type ("Digest nc=1; ", MHD_TEST_AUTHTYPE_NONE, 1);
    693   r += expect_result_type ("Digest nc=;1", MHD_TEST_AUTHTYPE_NONE, 1);
    694   r += expect_result_type ("Digest nc;=1", MHD_TEST_AUTHTYPE_NONE, 1);
    695   /* The equal sign alone */
    696   r += expect_result_type ("Digest =", MHD_TEST_AUTHTYPE_NONE, 1);
    697   r += expect_result_type ("Digest   =", MHD_TEST_AUTHTYPE_NONE, 1);
    698   r += expect_result_type ("Digest   =  ", MHD_TEST_AUTHTYPE_NONE, 1);
    699   r += expect_result_type ("Digest ,=", MHD_TEST_AUTHTYPE_NONE, 1);
    700   r += expect_result_type ("Digest , =", MHD_TEST_AUTHTYPE_NONE, 1);
    701   r += expect_result_type ("Digest ,= ", MHD_TEST_AUTHTYPE_NONE, 1);
    702   r += expect_result_type ("Digest , = ", MHD_TEST_AUTHTYPE_NONE, 1);
    703   r += expect_result_type ("Digest nc=1,=", MHD_TEST_AUTHTYPE_NONE, 1);
    704   r += expect_result_type ("Digest nc=1, =", MHD_TEST_AUTHTYPE_NONE, 1);
    705   r += expect_result_type ("Digest foo=bar,=", MHD_TEST_AUTHTYPE_NONE, 1);
    706   r += expect_result_type ("Digest foo=bar, =", \
    707                            MHD_TEST_AUTHTYPE_NONE, 1);
    708   /* Unclosed quotation */
    709   r += expect_result_type ("Digest nc=\"", MHD_TEST_AUTHTYPE_NONE, 1);
    710   r += expect_result_type ("Digest nc=\"abc", MHD_TEST_AUTHTYPE_NONE, 1);
    711   r += expect_result_type ("Digest nc=\"   ", MHD_TEST_AUTHTYPE_NONE, 1);
    712   r += expect_result_type ("Digest nc=\"abc   ", \
    713                            MHD_TEST_AUTHTYPE_NONE, 1);
    714   r += expect_result_type ("Digest nc=\"   abc", \
    715                            MHD_TEST_AUTHTYPE_NONE, 1);
    716   r += expect_result_type ("Digest nc=\"   abc", \
    717                            MHD_TEST_AUTHTYPE_NONE, 1);
    718   r += expect_result_type ("Digest nc=\"\\", MHD_TEST_AUTHTYPE_NONE, 1);
    719   r += expect_result_type ("Digest nc=\"\\\"", MHD_TEST_AUTHTYPE_NONE, 1);
    720   r += expect_result_type ("Digest nc=\"  \\\"", \
    721                            MHD_TEST_AUTHTYPE_NONE, 1);
    722   r += expect_result_type ("Digest nc=\"\\\"  ", \
    723                            MHD_TEST_AUTHTYPE_NONE, 1);
    724   r += expect_result_type ("Digest nc=\"  \\\"  ", \
    725                            MHD_TEST_AUTHTYPE_NONE, 1);
    726   r += expect_result_type ("Digest nc=\"\\\"\\\"\\\"\\\"", \
    727                            MHD_TEST_AUTHTYPE_NONE, 1);
    728   r += expect_result_type ("Digest nc= \"", MHD_TEST_AUTHTYPE_NONE, 1);
    729   r += expect_result_type ("Digest nc= \"abc", MHD_TEST_AUTHTYPE_NONE, 1);
    730   r += expect_result_type ("Digest nc= \"   ", MHD_TEST_AUTHTYPE_NONE, 1);
    731   r += expect_result_type ("Digest nc= \"abc   ", \
    732                            MHD_TEST_AUTHTYPE_NONE, 1);
    733   r += expect_result_type ("Digest nc= \"   abc", \
    734                            MHD_TEST_AUTHTYPE_NONE, 1);
    735   r += expect_result_type ("Digest nc= \"   abc", \
    736                            MHD_TEST_AUTHTYPE_NONE, 1);
    737   r += expect_result_type ("Digest nc= \"\\", \
    738                            MHD_TEST_AUTHTYPE_NONE, 1);
    739   r += expect_result_type ("Digest nc= \"\\\"", \
    740                            MHD_TEST_AUTHTYPE_NONE, 1);
    741   r += expect_result_type ("Digest nc= \"  \\\"", \
    742                            MHD_TEST_AUTHTYPE_NONE, 1);
    743   r += expect_result_type ("Digest nc= \"\\\"  ", \
    744                            MHD_TEST_AUTHTYPE_NONE, 1);
    745   r += expect_result_type ("Digest nc= \"  \\\"  ", \
    746                            MHD_TEST_AUTHTYPE_NONE, 1);
    747   r += expect_result_type ("Digest nc= \"\\\"\\\"\\\"\\\"", \
    748                            MHD_TEST_AUTHTYPE_NONE, 1);
    749   r += expect_result_type ("Digest foo=\"", MHD_TEST_AUTHTYPE_NONE, 1);
    750   r += expect_result_type ("Digest foo=\"bar", MHD_TEST_AUTHTYPE_NONE, 1);
    751   r += expect_result_type ("Digest foo=\"   ", MHD_TEST_AUTHTYPE_NONE, 1);
    752   r += expect_result_type ("Digest foo=\"bar   ", \
    753                            MHD_TEST_AUTHTYPE_NONE, 1);
    754   r += expect_result_type ("Digest foo=\"   bar", \
    755                            MHD_TEST_AUTHTYPE_NONE, 1);
    756   r += expect_result_type ("Digest foo=\"   bar", \
    757                            MHD_TEST_AUTHTYPE_NONE, 1);
    758   r += expect_result_type ("Digest foo= \"   bar", \
    759                            MHD_TEST_AUTHTYPE_NONE, 1);
    760   r += expect_result_type ("Digest foo=\",   bar", \
    761                            MHD_TEST_AUTHTYPE_NONE, 1);
    762   r += expect_result_type ("Digest foo=\"   bar,", \
    763                            MHD_TEST_AUTHTYPE_NONE, 1);
    764   r += expect_result_type ("Digest foo=\"\\\"", \
    765                            MHD_TEST_AUTHTYPE_NONE, 1);
    766   r += expect_result_type ("Digest foo=\"  \\\"", \
    767                            MHD_TEST_AUTHTYPE_NONE, 1);
    768   r += expect_result_type ("Digest foo=\"\\\"  ", \
    769                            MHD_TEST_AUTHTYPE_NONE, 1);
    770   r += expect_result_type ("Digest foo=\"  \\\"  ", \
    771                            MHD_TEST_AUTHTYPE_NONE, 1);
    772   r += expect_result_type ("Digest foo=\"\\\"\\\"\\\"\\\"", \
    773                            MHD_TEST_AUTHTYPE_NONE, 1);
    774   /* Full set of parameters with semicolon inside */
    775   r += expect_result_type ("Digest username=\"test@example.com\", " \
    776                            "realm=\"users@example.com\", nonce=\"32141232413abcde\", " \
    777                            "uri=\"/example\", qop=auth, nc=00000001; cnonce=\"0a4f113b\", " \
    778                            "response=\"6629fae49393a05397450978507c4ef1\", " \
    779                            "opaque=\"sadfljk32sdaf\"", \
    780                            MHD_TEST_AUTHTYPE_NONE, 1);
    781   r += expect_result_type ("Digest username=\"test@example.com\", " \
    782                            "realm=\"users@example.com\", nonce=\"32141232413abcde\", " \
    783                            "uri=\"/example\", qop=auth, nc=00000001;cnonce=\"0a4f113b\", " \
    784                            "response=\"6629fae49393a05397450978507c4ef1\", " \
    785                            "opaque=\"sadfljk32sdaf\"", \
    786                            MHD_TEST_AUTHTYPE_NONE, 1);
    787   r += expect_result_type ("Digest username;=\"test@example.com\", " \
    788                            "realm=\"users@example.com\", nonce=\"32141232413abcde\", " \
    789                            "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \
    790                            "response=\"6629fae49393a05397450978507c4ef1\", " \
    791                            "opaque=\"sadfljk32sdaf\"", \
    792                            MHD_TEST_AUTHTYPE_NONE, 1);
    793 
    794   r += expect_result_type ("Digest2", MHD_TEST_AUTHTYPE_NONE, 0);
    795   r += expect_result_type ("2Digest", MHD_TEST_AUTHTYPE_NONE, 0);
    796   r += expect_result_type ("Digest" "a", MHD_TEST_AUTHTYPE_NONE, 0);
    797   r += expect_result_type ("a" "Digest", MHD_TEST_AUTHTYPE_NONE, 0);
    798   r += expect_result_type (" Digest2", MHD_TEST_AUTHTYPE_NONE, 0);
    799   r += expect_result_type (" 2Digest", MHD_TEST_AUTHTYPE_NONE, 0);
    800   r += expect_result_type (" Digest" "a", MHD_TEST_AUTHTYPE_NONE, 0);
    801   r += expect_result_type (" a" "Digest", MHD_TEST_AUTHTYPE_NONE, 0);
    802   r += expect_result_type ("Digest2 ", MHD_TEST_AUTHTYPE_NONE, 0);
    803   r += expect_result_type ("2Digest ", MHD_TEST_AUTHTYPE_NONE, 0);
    804   r += expect_result_type ("Digest" "a", MHD_TEST_AUTHTYPE_NONE, 0);
    805   r += expect_result_type ("a" "Digest ", MHD_TEST_AUTHTYPE_NONE, 0);
    806   r += expect_result_type ("DigestBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    807   r += expect_result_type ("DigestBasic ", MHD_TEST_AUTHTYPE_NONE, 0);
    808   r += expect_result_type (" DigestBasic", MHD_TEST_AUTHTYPE_NONE, 0);
    809   r += expect_result_type ("DigestBasic" "a", MHD_TEST_AUTHTYPE_NONE, 0);
    810   r += expect_result_type ("Digest" "\0", MHD_TEST_AUTHTYPE_NONE, 0);
    811   r += expect_result_type ("\0" "Digest", MHD_TEST_AUTHTYPE_NONE, 0);
    812   return r;
    813 }
    814 
    815 
    816 #ifdef BAUTH_SUPPORT
    817 
    818 /* return zero if succeed, 1 otherwise */
    819 static unsigned int
    820 expect_basic_n (const char *hdr, size_t hdr_len,
    821                 const char *tkn, size_t tkn_len,
    822                 unsigned int line_num)
    823 {
    824   const struct MHD_RqBAuth *h;
    825   unsigned int ret;
    826 
    827   mhd_assert (NULL != hdr);
    828   mhd_assert (0 != hdr_len);
    829 
    830   add_AuthHeader (hdr, hdr_len);
    831   h = get_BAuthRqParams ();
    832   if (NULL == h)
    833     mhdErrorExitDesc ("'MHD_get_rq_bauth_params_()' returned NULL");
    834   ret = 1;
    835   if (tkn_len != h->token68.len)
    836     fprintf (stderr,
    837              "'Authorization' header parsing FAILED:\n"
    838              "Wrong token length:\tRESULT[%u]: %.*s\tEXPECTED[%u]: %.*s\n",
    839              (unsigned) h->token68.len,
    840              (int) h->token68.len,
    841              h->token68.str ?
    842              h->token68.str : "(NULL)",
    843              (unsigned) tkn_len, (int) tkn_len, tkn ? tkn : "(NULL)");
    844   else if ( ((NULL == tkn) != (NULL == h->token68.str)) ||
    845             ((NULL != tkn) &&
    846              (0 != memcmp (tkn, h->token68.str, tkn_len))) )
    847     fprintf (stderr,
    848              "'Authorization' header parsing FAILED:\n"
    849              "Wrong token string:\tRESULT[%u]: %.*s\tEXPECTED[%u]: %.*s\n",
    850              (unsigned) h->token68.len,
    851              (int) h->token68.len,
    852              h->token68.str ?
    853              h->token68.str : "(NULL)",
    854              (unsigned) tkn_len, (int) tkn_len, tkn ? tkn : "(NULL)");
    855   else
    856     ret = 0;
    857   if (0 != ret)
    858   {
    859     fprintf (stderr,
    860              "Input Header: '%.*s'\n", (int) hdr_len, hdr);
    861     fprintf (stderr,
    862              "The check is at line: %u\n\n", line_num);
    863   }
    864   clean_AuthHeaders ();
    865 
    866   return ret;
    867 }
    868 
    869 
    870 #define expect_basic(h,t) \
    871     expect_basic_n(h,MHD_STATICSTR_LEN_(h),t,MHD_STATICSTR_LEN_(t),__LINE__)
    872 
    873 static unsigned int
    874 check_basic (void)
    875 {
    876   unsigned int r = 0; /**< The number of errors */
    877 
    878   r += expect_basic ("Basic a", "a");
    879   r += expect_basic ("Basic    a", "a");
    880   r += expect_basic ("Basic \ta", "a");
    881   r += expect_basic ("Basic \ta\t", "a");
    882   r += expect_basic ("Basic \ta ", "a");
    883   r += expect_basic ("Basic  a ", "a");
    884   r += expect_basic ("Basic \t a\t ", "a");
    885   r += expect_basic ("Basic \t abc\t ", "abc");
    886   r += expect_basic ("Basic 2143sdfa4325sdfgfdab354354314SDSDFc", \
    887                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    888   r += expect_basic ("Basic 2143sdfa4325sdfgfdab354354314SDSDFc  ", \
    889                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    890   r += expect_basic ("Basic   2143sdfa4325sdfgfdab354354314SDSDFc", \
    891                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    892   r += expect_basic ("Basic   2143sdfa4325sdfgfdab354354314SDSDFc  ", \
    893                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    894   r += expect_basic ("  Basic 2143sdfa4325sdfgfdab354354314SDSDFc", \
    895                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    896   r += expect_basic ("  Basic  2143sdfa4325sdfgfdab354354314SDSDFc", \
    897                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    898   r += expect_basic ("  Basic 2143sdfa4325sdfgfdab354354314SDSDFc ", \
    899                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    900   r += expect_basic ("  Basic  2143sdfa4325sdfgfdab354354314SDSDFc ", \
    901                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    902   r += expect_basic ("  Basic  2143sdfa4325sdfgfdab354354314SDSDFc  ", \
    903                      "2143sdfa4325sdfgfdab354354314SDSDFc");
    904   r += expect_basic ("Basic -A.1-z~9+/=====", "-A.1-z~9+/=====");
    905   r += expect_basic ("  Basic   -A.1-z~9+/===== ", "-A.1-z~9+/=====");
    906 
    907   r += expect_basic_n ("Basic", MHD_STATICSTR_LEN_ ("Basic"), NULL, 0,__LINE__);
    908   r += expect_basic_n ("   Basic", MHD_STATICSTR_LEN_ ("   Basic"), NULL, 0,
    909                        __LINE__);
    910   r += expect_basic_n ("Basic   ", MHD_STATICSTR_LEN_ ("Basic   "), NULL, 0,
    911                        __LINE__);
    912   r += expect_basic_n ("Basic \t\t", MHD_STATICSTR_LEN_ ("Basic \t\t"), NULL, 0,
    913                        __LINE__);
    914 
    915   return r;
    916 }
    917 
    918 
    919 #endif /* BAUTH_SUPPORT */
    920 
    921 
    922 #ifdef DAUTH_SUPPORT
    923 
    924 /* return zero if succeed, 1 otherwise */
    925 static unsigned int
    926 cmp_dauth_param (const char *pname, const struct MHD_RqDAuthParam *param,
    927                  const char *expected_value)
    928 {
    929   unsigned int ret;
    930   size_t expected_len;
    931   bool expected_quoted;
    932   mhd_assert (NULL != param);
    933   mhd_assert (NULL != pname);
    934   ret = 0;
    935 
    936   if (NULL == expected_value)
    937   {
    938     expected_len = 0;
    939     expected_quoted = false;
    940     if (NULL != param->value.str)
    941       ret = 1;
    942     else if (param->value.len != expected_len)
    943       ret = 1;
    944     else if (param->quoted != expected_quoted)
    945       ret = 1;
    946   }
    947   else
    948   {
    949     expected_len = strlen (expected_value);
    950     expected_quoted = (NULL != memchr (expected_value, '\\', expected_len));
    951     if (NULL == param->value.str)
    952       ret = 1;
    953     else if (param->value.len != expected_len)
    954       ret = 1;
    955     else if (param->quoted != expected_quoted)
    956       ret = 1;
    957     else if (0 != memcmp (param->value.str, expected_value, expected_len))
    958       ret = 1;
    959   }
    960   if (0 != ret)
    961   {
    962     fprintf (stderr, "Parameter '%s' parsed incorrectly:\n", pname);
    963     fprintf (stderr, "\tRESULT  :\tvalue.str: %.*s",
    964              (int) (param->value.str ? param->value.len : 6),
    965              param->value.str ? param->value.str : "(NULL)");
    966     fprintf (stderr, "\tvalue.len: %u",
    967              (unsigned) param->value.len);
    968     fprintf (stderr, "\tquoted: %s\n",
    969              (unsigned) param->quoted ? "true" : "false");
    970     fprintf (stderr, "\tEXPECTED:\tvalue.str: %.*s",
    971              (int) (expected_value ? expected_len : 6),
    972              expected_value ? expected_value : "(NULL)");
    973     fprintf (stderr, "\tvalue.len: %u",
    974              (unsigned) expected_len);
    975     fprintf (stderr, "\tquoted: %s\n",
    976              (unsigned) expected_quoted ? "true" : "false");
    977   }
    978   return ret;
    979 }
    980 
    981 
    982 /* return zero if succeed, 1 otherwise */
    983 static unsigned int
    984 expect_digest_n (const char *hdr, size_t hdr_len,
    985                  const char *nonce,
    986                  enum MHD_DigestAuthAlgo3 algo3,
    987                  const char *response,
    988                  const char *username,
    989                  const char *username_ext,
    990                  const char *realm,
    991                  const char *uri,
    992                  const char *qop_raw,
    993                  enum MHD_DigestAuthQOP qop,
    994                  const char *cnonce,
    995                  const char *nc,
    996                  int userhash,
    997                  unsigned int line_num)
    998 {
    999   const struct MHD_RqDAuth *h;
   1000   unsigned int ret;
   1001 
   1002   mhd_assert (NULL != hdr);
   1003   mhd_assert (0 != hdr_len);
   1004 
   1005   add_AuthHeader (hdr, hdr_len);
   1006 
   1007   h = get_DAuthRqParams ();
   1008   if (NULL == h)
   1009     mhdErrorExitDesc ("'MHD_get_rq_dauth_params_()' returned NULL");
   1010   ret = 0;
   1011 
   1012   ret += cmp_dauth_param ("nonce", &h->nonce, nonce);
   1013   if (h->algo3 != algo3)
   1014   {
   1015     ret += 1;
   1016     fprintf (stderr, "Parameter 'algorithm' detected incorrectly:\n");
   1017     fprintf (stderr, "\tRESULT  :\t%u\n",
   1018              (unsigned) h->algo3);
   1019     fprintf (stderr, "\tEXPECTED:\t%u\n",
   1020              (unsigned) algo3);
   1021   }
   1022   ret += cmp_dauth_param ("response", &h->response, response);
   1023   ret += cmp_dauth_param ("username", &h->username, username);
   1024   ret += cmp_dauth_param ("username_ext", &h->username_ext,
   1025                           username_ext);
   1026   ret += cmp_dauth_param ("realm", &h->realm, realm);
   1027   ret += cmp_dauth_param ("uri", &h->uri, uri);
   1028   ret += cmp_dauth_param ("qop", &h->qop_raw, qop_raw);
   1029   if (h->qop != qop)
   1030   {
   1031     ret += 1;
   1032     fprintf (stderr, "Parameter 'qop' detected incorrectly:\n");
   1033     fprintf (stderr, "\tRESULT  :\t%u\n",
   1034              (unsigned) h->qop);
   1035     fprintf (stderr, "\tEXPECTED:\t%u\n",
   1036              (unsigned) qop);
   1037   }
   1038   ret += cmp_dauth_param ("cnonce", &h->cnonce, cnonce);
   1039   ret += cmp_dauth_param ("nc", &h->nc, nc);
   1040   if (h->userhash != ! (! userhash))
   1041   {
   1042     ret += 1;
   1043     fprintf (stderr, "Parameter 'userhash' parsed incorrectly:\n");
   1044     fprintf (stderr, "\tRESULT  :\t%s\n",
   1045              h->userhash ? "true" : "false");
   1046     fprintf (stderr, "\tEXPECTED:\t%s\n",
   1047              userhash ? "true" : "false");
   1048   }
   1049   if (0 != ret)
   1050   {
   1051     fprintf (stderr,
   1052              "Input Header: '%.*s'\n", (int) hdr_len, hdr);
   1053     fprintf (stderr,
   1054              "The check is at line: %u\n\n", line_num);
   1055   }
   1056   clean_AuthHeaders ();
   1057 
   1058   return ret;
   1059 }
   1060 
   1061 
   1062 #define expect_digest(h,no,a,rs,un,ux,rm,ur,qr,qe,c,nc,uh) \
   1063     expect_digest_n(h,MHD_STATICSTR_LEN_(h),\
   1064                     no,a,rs,un,ux,rm,ur,qr,qe,c,nc,uh,__LINE__)
   1065 
   1066 /**
   1067  * Check the properties of the algorithm and QOP enumerations that the
   1068  * consumers of the parsed header rely on.
   1069  *
   1070  * The "invalid" members have the numeric value zero, which means that the
   1071  * usual "is the client value allowed by the application" test
   1072  *
   1073  *     if (client_value != (client_value & allowed_mask))
   1074  *       reject ();
   1075  *
   1076  * lets the "invalid" value pass for every possible @a allowed_mask.  Every
   1077  * consumer must therefore reject the "invalid" value explicitly before
   1078  * using it.  Failing to do so made an unknown 'algorithm=' token in the
   1079  * request abort the whole daemon.
   1080  *
   1081  * @return zero if succeed, number of failures otherwise
   1082  */
   1083 static unsigned int
   1084 check_digest_enum_sentinels (void)
   1085 {
   1086   unsigned int r = 0; /**< The number of errors */
   1087 
   1088   if (0 != (unsigned int) MHD_DIGEST_AUTH_ALGO3_INVALID)
   1089   {
   1090     r++;
   1091     fprintf (stderr, "MHD_DIGEST_AUTH_ALGO3_INVALID is not zero. Line: %u\n",
   1092              (unsigned int) __LINE__);
   1093   }
   1094   if (0 != (unsigned int) MHD_DIGEST_BASE_ALGO_INVALID)
   1095   {
   1096     r++;
   1097     fprintf (stderr, "MHD_DIGEST_BASE_ALGO_INVALID is not zero. Line: %u\n",
   1098              (unsigned int) __LINE__);
   1099   }
   1100   if (0 != (unsigned int) MHD_DIGEST_AUTH_QOP_INVALID)
   1101   {
   1102     r++;
   1103     fprintf (stderr, "MHD_DIGEST_AUTH_QOP_INVALID is not zero. Line: %u\n",
   1104              (unsigned int) __LINE__);
   1105   }
   1106   /* The bitmask test alone does not reject the "invalid" values. */
   1107   if (0 != (((unsigned int) MHD_DIGEST_AUTH_ALGO3_INVALID)
   1108             & ~((unsigned int) MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION)))
   1109   {
   1110     r++;
   1111     fprintf (stderr, "The bitmask check unexpectedly rejects "
   1112              "MHD_DIGEST_AUTH_ALGO3_INVALID. Line: %u\n",
   1113              (unsigned int) __LINE__);
   1114   }
   1115   return r;
   1116 }
   1117 
   1118 
   1119 static unsigned int
   1120 check_digest (void)
   1121 {
   1122   unsigned int r = 0; /**< The number of errors */
   1123 
   1124   r += check_digest_enum_sentinels ();
   1125 
   1126   r += expect_digest ("Digest", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1127                       NULL, NULL, NULL, NULL, NULL, \
   1128                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1129   r += expect_digest ("Digest nc=1", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1130                       NULL, NULL, NULL, NULL, NULL, NULL, \
   1131                       MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1132   r += expect_digest ("Digest nc=\"1\"", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1133                       NULL, NULL, NULL, NULL, NULL, \
   1134                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1135   r += expect_digest ("Digest nc=\"1\"   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1136                       NULL, NULL, NULL, NULL, NULL, \
   1137                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1138   r += expect_digest ("Digest ,nc=\"1\"   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1139                       NULL, NULL, NULL, NULL, NULL, \
   1140                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1141   r += expect_digest ("Digest nc=\"1\",   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1142                       NULL, NULL, NULL, NULL, NULL, \
   1143                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1144   r += expect_digest ("Digest nc=\"1\" ,   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1145                       NULL, NULL, NULL, NULL, NULL, \
   1146                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1147   r += expect_digest ("Digest nc=1,   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1148                       NULL, NULL, NULL, NULL, NULL, \
   1149                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1150   r += expect_digest ("Digest nc=1 ,   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1151                       NULL, NULL, NULL, NULL, NULL, \
   1152                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1153   r += expect_digest ("Digest ,,,nc=1,   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1154                       NULL, NULL, NULL, NULL, NULL, \
   1155                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1156   r += expect_digest ("Digest ,,,nc=1 ,   ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1157                       NULL, NULL, NULL, NULL, NULL, \
   1158                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1", 0);
   1159   r += expect_digest ("Digest ,,,nc=\"1 \",   ", NULL, \
   1160                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1161                       NULL, NULL, NULL, NULL, NULL, \
   1162                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0);
   1163   r += expect_digest ("Digest nc=\"1 \"", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1164                       NULL, NULL, NULL, NULL, NULL, \
   1165                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0);
   1166   r += expect_digest ("Digest nc=\"1 \" ,", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1167                       NULL, NULL, NULL, NULL, NULL, \
   1168                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0);
   1169   r += expect_digest ("Digest nc=\"1 \", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1170                       NULL, NULL, NULL, NULL, NULL, \
   1171                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1 ", 0);
   1172   r += expect_digest ("Digest nc=\"1;\", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1173                       NULL, NULL, NULL, NULL, NULL, \
   1174                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1;", 0);
   1175   r += expect_digest ("Digest nc=\"1\\;\", ", NULL, MHD_DIGEST_AUTH_ALGO3_MD5, \
   1176                       NULL, NULL, NULL, NULL, NULL, \
   1177                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, "1\\;", 0);
   1178 
   1179   r += expect_digest ("Digest userhash=false", NULL, \
   1180                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1181                       NULL, NULL, NULL, NULL, NULL, \
   1182                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1183   r += expect_digest ("Digest userhash=\"false\"", NULL, \
   1184                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1185                       NULL, NULL, NULL, NULL, NULL, \
   1186                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1187   r += expect_digest ("Digest userhash=foo", NULL, \
   1188                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1189                       NULL, NULL, NULL, NULL, NULL, \
   1190                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1191   r += expect_digest ("Digest userhash=true", NULL, \
   1192                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1193                       NULL, NULL, NULL, NULL, NULL, \
   1194                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1195   r += expect_digest ("Digest userhash=\"true\"", NULL, \
   1196                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1197                       NULL, NULL, NULL, NULL, NULL, \
   1198                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1199   r += expect_digest ("Digest userhash=\"\\t\\r\\u\\e\"", NULL, \
   1200                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1201                       NULL, NULL, NULL, NULL, NULL, \
   1202                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1203   r += expect_digest ("Digest userhash=TRUE", NULL, \
   1204                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1205                       NULL, NULL, NULL, NULL, NULL, \
   1206                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1207   r += expect_digest ("Digest userhash=True", NULL, \
   1208                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1209                       NULL, NULL, NULL, NULL, NULL, \
   1210                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1211   r += expect_digest ("Digest userhash = true", NULL, \
   1212                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1213                       NULL, NULL, NULL,  NULL, NULL, \
   1214                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 1);
   1215   r += expect_digest ("Digest userhash=True2", NULL, \
   1216                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1217                       NULL, NULL, NULL, NULL, NULL, \
   1218                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1219   r += expect_digest ("Digest userhash=\" true\"", NULL, \
   1220                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1221                       NULL, NULL, NULL,  NULL, NULL, \
   1222                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1223 
   1224   r += expect_digest ("Digest algorithm=MD5", NULL, \
   1225                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1226                       NULL, NULL, NULL, NULL, NULL, \
   1227                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1228   r += expect_digest ("Digest algorithm=md5", NULL, \
   1229                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1230                       NULL, NULL, NULL, NULL, NULL, \
   1231                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1232   r += expect_digest ("Digest algorithm=Md5", NULL, \
   1233                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1234                       NULL, NULL, NULL, NULL, NULL, \
   1235                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1236   r += expect_digest ("Digest algorithm=mD5", NULL, \
   1237                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1238                       NULL, NULL, NULL, NULL, NULL, \
   1239                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1240   r += expect_digest ("Digest algorithm=\"MD5\"", NULL, \
   1241                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1242                       NULL, NULL, NULL, NULL, NULL, \
   1243                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1244   r += expect_digest ("Digest algorithm=\"\\M\\D\\5\"", NULL, \
   1245                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1246                       NULL, NULL, NULL, NULL, NULL, \
   1247                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1248   r += expect_digest ("Digest algorithm=\"\\m\\d\\5\"", NULL, \
   1249                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1250                       NULL, NULL, NULL, NULL, NULL, \
   1251                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1252   r += expect_digest ("Digest algorithm=SHA-256", NULL, \
   1253                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1254                       NULL, NULL, NULL, NULL, NULL, \
   1255                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1256   r += expect_digest ("Digest algorithm=sha-256", NULL, \
   1257                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1258                       NULL, NULL, NULL, NULL, NULL, \
   1259                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1260   r += expect_digest ("Digest algorithm=Sha-256", NULL, \
   1261                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1262                       NULL, NULL, NULL, NULL, NULL, \
   1263                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1264   r += expect_digest ("Digest algorithm=\"SHA-256\"", NULL, \
   1265                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1266                       NULL, NULL, NULL, NULL, NULL, \
   1267                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1268   r += expect_digest ("Digest algorithm=\"SHA\\-25\\6\"", NULL, \
   1269                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1270                       NULL, NULL, NULL, NULL, NULL, \
   1271                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1272   r += expect_digest ("Digest algorithm=\"shA-256\"", NULL, \
   1273                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1274                       NULL, NULL, NULL, NULL, NULL, \
   1275                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1276   r += expect_digest ("Digest algorithm=MD5-sess", NULL, \
   1277                       MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \
   1278                       NULL, NULL, NULL, NULL, NULL, \
   1279                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1280   r += expect_digest ("Digest algorithm=MD5-SESS", NULL, \
   1281                       MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \
   1282                       NULL, NULL, NULL, NULL, NULL, \
   1283                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1284   r += expect_digest ("Digest algorithm=md5-Sess", NULL, \
   1285                       MHD_DIGEST_AUTH_ALGO3_MD5_SESSION, \
   1286                       NULL, NULL, NULL, NULL, NULL, \
   1287                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1288   r += expect_digest ("Digest algorithm=SHA-256-seSS", NULL, \
   1289                       MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, \
   1290                       NULL, NULL, NULL, NULL, NULL, \
   1291                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1292   r += expect_digest ("Digest algorithm=SHA-512-256", NULL, \
   1293                       MHD_DIGEST_AUTH_ALGO3_SHA512_256, \
   1294                       NULL, NULL, NULL, NULL, NULL, \
   1295                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1296   r += expect_digest ("Digest algorithm=SHA-512-256-sess", NULL, \
   1297                       MHD_DIGEST_AUTH_ALGO3_SHA512_256_SESSION, \
   1298                       NULL, NULL, NULL, NULL, NULL, \
   1299                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1300   r += expect_digest ("Digest algorithm=MD5-2", NULL, \
   1301                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1302                       NULL, NULL, NULL, NULL, NULL, \
   1303                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1304   r += expect_digest ("Digest algorithm=MD5-sess2", NULL, \
   1305                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1306                       NULL, NULL, NULL, NULL, NULL, \
   1307                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1308   r += expect_digest ("Digest algorithm=SHA-256-512", NULL, \
   1309                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1310                       NULL, NULL, NULL, NULL, NULL, \
   1311                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1312   r += expect_digest ("Digest algorithm=", NULL, \
   1313                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1314                       NULL, NULL, NULL, NULL, NULL, \
   1315                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1316   /* More spellings that the client may send and that must all be reported
   1317      as #MHD_DIGEST_AUTH_ALGO3_INVALID.  Note that the numeric value of
   1318      that enumeration member is zero, so a consumer that only validates the
   1319      value with a bitmask ("(algo & allowed) == algo") accepts every one of
   1320      these; the consumer must check for the INVALID value explicitly. */
   1321   r += expect_digest ("Digest algorithm=BOGUS", NULL, \
   1322                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1323                       NULL, NULL, NULL, NULL, NULL, \
   1324                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1325   r += expect_digest ("Digest algorithm=\"\"", NULL, \
   1326                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1327                       NULL, NULL, NULL, NULL, NULL, \
   1328                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1329   r += expect_digest ("Digest algorithm=\"BOGUS\"", NULL, \
   1330                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1331                       NULL, NULL, NULL, NULL, NULL, \
   1332                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1333   r += expect_digest ("Digest algorithm=SHA-512", NULL, \
   1334                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1335                       NULL, NULL, NULL, NULL, NULL, \
   1336                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1337   r += expect_digest ("Digest algorithm=SHA-1", NULL, \
   1338                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1339                       NULL, NULL, NULL, NULL, NULL, \
   1340                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1341   r += expect_digest ("Digest algorithm=MD5 ", NULL, \
   1342                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1343                       NULL, NULL, NULL, NULL, NULL, \
   1344                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1345   r += expect_digest ("Digest algorithm=\"MD5 \"", NULL, \
   1346                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1347                       NULL, NULL, NULL, NULL, NULL, \
   1348                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1349   r += expect_digest ("Digest algorithm=\" MD5\"", NULL, \
   1350                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1351                       NULL, NULL, NULL, NULL, NULL, \
   1352                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1353   r += expect_digest ("Digest algorithm=\"MD\\5\"", NULL, \
   1354                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1355                       NULL, NULL, NULL, NULL, NULL, \
   1356                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1357   /* A duplicated parameter is accepted and the last occurrence wins.
   1358      Both orders are checked so that any change of that behaviour is
   1359      noticed: a client that can make different HTTP implementations pick
   1360      different occurrences of the same parameter is a source of trouble. */
   1361   r += expect_digest ("Digest algorithm=MD5,algorithm=BOGUS", NULL, \
   1362                       MHD_DIGEST_AUTH_ALGO3_INVALID, \
   1363                       NULL, NULL, NULL, NULL, NULL, \
   1364                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1365   r += expect_digest ("Digest algorithm=BOGUS,algorithm=MD5", NULL, \
   1366                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1367                       NULL, NULL, NULL, NULL, NULL, \
   1368                       NULL, MHD_DIGEST_AUTH_QOP_NONE, NULL, NULL, 0);
   1369 
   1370   r += expect_digest ("Digest qop=auth", NULL, \
   1371                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1372                       NULL, NULL, NULL, NULL, NULL, \
   1373                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0);
   1374   r += expect_digest ("Digest qop=\"auth\"", NULL, \
   1375                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1376                       NULL, NULL, NULL, NULL, NULL, \
   1377                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0);
   1378   r += expect_digest ("Digest qop=Auth", NULL, \
   1379                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1380                       NULL, NULL, NULL, NULL, NULL, \
   1381                       "Auth", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0);
   1382   r += expect_digest ("Digest qop=AUTH", NULL, \
   1383                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1384                       NULL, NULL, NULL, NULL, NULL, \
   1385                       "AUTH", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0);
   1386   r += expect_digest ("Digest qop=\"\\A\\ut\\H\"", NULL, \
   1387                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1388                       NULL, NULL, NULL, NULL, NULL, \
   1389                       "\\A\\ut\\H", MHD_DIGEST_AUTH_QOP_AUTH, NULL, NULL, 0);
   1390   r += expect_digest ("Digest qop=\"auth \"", NULL, \
   1391                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1392                       NULL, NULL, NULL, NULL, NULL, \
   1393                       "auth ", MHD_DIGEST_AUTH_QOP_INVALID, NULL, NULL, 0);
   1394   r += expect_digest ("Digest qop=auth-int", NULL, \
   1395                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1396                       NULL, NULL, NULL, NULL, NULL, \
   1397                       "auth-int", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0);
   1398   r += expect_digest ("Digest qop=\"auth-int\"", NULL, \
   1399                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1400                       NULL, NULL, NULL, NULL, NULL, \
   1401                       "auth-int", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0);
   1402   r += expect_digest ("Digest qop=\"auTh-iNt\"", NULL, \
   1403                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1404                       NULL, NULL, NULL, NULL, NULL, \
   1405                       "auTh-iNt", MHD_DIGEST_AUTH_QOP_AUTH_INT, NULL, NULL, 0);
   1406   r += expect_digest ("Digest qop=\"auTh-iNt2\"", NULL, \
   1407                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1408                       NULL, NULL, NULL, NULL, NULL, \
   1409                       "auTh-iNt2", MHD_DIGEST_AUTH_QOP_INVALID, NULL, NULL, 0);
   1410 
   1411   r += expect_digest ("Digest username=\"test@example.com\", " \
   1412                       "realm=\"users@example.com\", " \
   1413                       "nonce=\"32141232413abcde\", " \
   1414                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1415                       "cnonce=\"0a4f113b\", " \
   1416                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1417                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \
   1418                       MHD_DIGEST_AUTH_ALGO3_MD5, \
   1419                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1420                       NULL, "users@example.com", "/example", \
   1421                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, \
   1422                       "0a4f113b", "00000001", 0);
   1423   r += expect_digest ("Digest username=\"test@example.com\", " \
   1424                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1425                       "nonce=\"32141232413abcde\", " \
   1426                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1427                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1428                       "cnonce=\"0a4f113b\", " \
   1429                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1430                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \
   1431                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1432                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1433                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1434                       "users@example.com", "/example", \
   1435                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1436                       "00000001", 0);
   1437   r += expect_digest ("Digest username=test@example.com, " \
   1438                       "realm=users@example.com, algorithm=\"SHA-256-sess\", " \
   1439                       "nonce=32141232413abcde, " \
   1440                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1441                       "uri=/example, qop=\"auth\", nc=\"00000001\", " \
   1442                       "cnonce=0a4f113b, " \
   1443                       "response=6629fae49393a05397450978507c4ef1, " \
   1444                       "opaque=sadfljk32sdaf", "32141232413abcde", \
   1445                       MHD_DIGEST_AUTH_ALGO3_SHA256_SESSION, \
   1446                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1447                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1448                       "users@example.com", "/example", \
   1449                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1450                       "00000001", 0);
   1451   r += expect_digest ("Digest username = \"test@example.com\", " \
   1452                       "realm\t=\t\"users@example.com\", algorithm\t= SHA-256, " \
   1453                       "nonce\t= \"32141232413abcde\", " \
   1454                       "username*\t=\tUTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1455                       "uri = \"/example\", qop = auth, nc\t=\t00000001, " \
   1456                       "cnonce\t\t\t=   \"0a4f113b\", " \
   1457                       "response  =\"6629fae49393a05397450978507c4ef1\", " \
   1458                       "opaque=\t\t\"sadfljk32sdaf\"", "32141232413abcde", \
   1459                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1460                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1461                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1462                       "users@example.com", "/example", \
   1463                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1464                       "00000001", 0);
   1465   r += expect_digest ("Digest username=\"test@example.com\"," \
   1466                       "realm=\"users@example.com\",algorithm=SHA-512-256," \
   1467                       "nonce=\"32141232413abcde\"," \
   1468                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates," \
   1469                       "uri=\"/example\",qop=auth,nc=00000001," \
   1470                       "cnonce=\"0a4f113b\"," \
   1471                       "response=\"6629fae49393a05397450978507c4ef1\"," \
   1472                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \
   1473                       MHD_DIGEST_AUTH_ALGO3_SHA512_256, \
   1474                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1475                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1476                       "users@example.com", "/example", \
   1477                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1478                       "00000001", 0);
   1479   r += expect_digest ("Digest username=\"test@example.com\"," \
   1480                       "realm=\"users@example.com\",algorithm=SHA-256," \
   1481                       "nonce=\"32141232413abcde\",asdf=asdffdsaf," \
   1482                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates," \
   1483                       "uri=\"/example\",qop=auth,nc=00000001,cnonce=\"0a4f113b\"," \
   1484                       "response=\"6629fae49393a05397450978507c4ef1\"," \
   1485                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \
   1486                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1487                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1488                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1489                       "users@example.com", "/example", \
   1490                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1491                       "00000001", 0);
   1492   r += expect_digest ("Digest abc=zyx, username=\"test@example.com\", " \
   1493                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1494                       "nonce=\"32141232413abcde\", " \
   1495                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1496                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1497                       "cnonce=\"0a4f113b\", " \
   1498                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1499                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde", \
   1500                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1501                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1502                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1503                       "users@example.com", "/example", \
   1504                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1505                       "00000001", 0);
   1506   r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \
   1507                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1508                       "nonce=\"32141232413abcde\", " \
   1509                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1510                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1511                       "cnonce=\"0a4f113b\", " \
   1512                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1513                       "opaque=\"sadfljk32sdaf\"", "32141232413abcde",
   1514                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1515                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1516                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1517                       "users@example.com", "/example", \
   1518                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1519                       "00000001", 0);
   1520   r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \
   1521                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1522                       "nonce=\"32141232413abcde\", " \
   1523                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1524                       "uri=\"/example\", qop=auth, nc=00000001, "
   1525                       "cnonce=\"0a4f113b\", " \
   1526                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1527                       "opaque=\"sadfljk32sdaf\",,,,,", "32141232413abcde", \
   1528                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1529                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1530                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1531                       "users@example.com", "/example", \
   1532                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1533                       "00000001", 0);
   1534   r += expect_digest ("Digest abc=zyx,,,,,,,username=\"test@example.com\", " \
   1535                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1536                       "nonce=\"32141232413abcde\", " \
   1537                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1538                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1539                       "cnonce=\"0a4f113b\", " \
   1540                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1541                       "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \
   1542                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1543                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1544                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1545                       "users@example.com", "/example", \
   1546                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1547                       "00000001", 0);
   1548   r += expect_digest ("Digest abc=\"zyx\", username=\"test@example.com\", " \
   1549                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1550                       "nonce=\"32141232413abcde\", " \
   1551                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1552                       "uri=\"/example\", qop=auth, nc=00000001, "
   1553                       "cnonce=\"0a4f113b\", " \
   1554                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1555                       "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \
   1556                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1557                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1558                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1559                       "users@example.com", "/example", \
   1560                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1561                       "00000001", 0);
   1562   r += expect_digest ("Digest abc=\"zyx, abc\", " \
   1563                       "username=\"test@example.com\", " \
   1564                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1565                       "nonce=\"32141232413abcde\", " \
   1566                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1567                       "uri=\"/example\", qop=auth, nc=00000001, "
   1568                       "cnonce=\"0a4f113b\", " \
   1569                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1570                       "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \
   1571                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1572                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1573                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1574                       "users@example.com", "/example", \
   1575                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1576                       "00000001", 0);
   1577   r += expect_digest ("Digest abc=\"zyx, abc=cde\", " \
   1578                       "username=\"test@example.com\", " \
   1579                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1580                       "nonce=\"32141232413abcde\", " \
   1581                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1582                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1583                       "cnonce=\"0a4f113b\", " \
   1584                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1585                       "opaque=\"sadfljk32sdaf\",foo=bar", "32141232413abcde", \
   1586                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1587                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1588                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1589                       "users@example.com", "/example", \
   1590                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1591                       "00000001", 0);
   1592   r += expect_digest ("Digest abc=\"zyx, abc=cde\", " \
   1593                       "username=\"test@example.com\", " \
   1594                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1595                       "nonce=\"32141232413abcde\", " \
   1596                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1597                       "uri=\"/example\", qop=auth, nc=00000001, " \
   1598                       "cnonce=\"0a4f113b\", " \
   1599                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1600                       "opaque=\"sadfljk32sdaf\", foo=\"bar1, bar2\"", \
   1601                       "32141232413abcde", \
   1602                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1603                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1604                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1605                       "users@example.com", "/example", \
   1606                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1607                       "00000001", 0);
   1608   r += expect_digest ("Digest abc=\"zyx, \\\\\"abc=cde\\\\\"\", " \
   1609                       "username=\"test@example.com\", " \
   1610                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1611                       "nonce=\"32141232413abcde\", " \
   1612                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1613                       "uri=\"/example\", qop=auth, nc=00000001, cnonce=\"0a4f113b\", " \
   1614                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1615                       "opaque=\"sadfljk32sdaf\", foo=\"bar1, bar2\"", \
   1616                       "32141232413abcde",
   1617                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1618                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1619                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1620                       "users@example.com", "/example", \
   1621                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1622                       "00000001", 0);
   1623   r += expect_digest ("Digest abc=\"zyx, \\\\\"abc=cde\\\\\"\", " \
   1624                       "username=\"test@example.com\", " \
   1625                       "realm=\"users@example.com\", algorithm=SHA-256, " \
   1626                       "nonce=\"32141232413abcde\", " \
   1627                       "username*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates, " \
   1628                       "uri=\"/example\", qop=auth, nc=00000001, "
   1629                       "cnonce=\"0a4f113b\", " \
   1630                       "response=\"6629fae49393a05397450978507c4ef1\", " \
   1631                       "opaque=\"sadfljk32sdaf\", foo=\",nc=02\"",
   1632                       "32141232413abcde", \
   1633                       MHD_DIGEST_AUTH_ALGO3_SHA256, \
   1634                       "6629fae49393a05397450978507c4ef1", "test@example.com", \
   1635                       "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates", \
   1636                       "users@example.com", "/example", \
   1637                       "auth", MHD_DIGEST_AUTH_QOP_AUTH, "0a4f113b", \
   1638                       "00000001", 0);
   1639 
   1640   return r;
   1641 }
   1642 
   1643 
   1644 #endif /* DAUTH_SUPPORT */
   1645 
   1646 #define TEST_AUTH_STR "dXNlcjpwYXNz"
   1647 
   1648 static unsigned int
   1649 check_two_auths (void)
   1650 {
   1651   unsigned int ret;
   1652   static struct MHD_HTTP_Req_Header h1;
   1653   static struct MHD_HTTP_Req_Header h2;
   1654   static struct MHD_HTTP_Req_Header h3;
   1655 #ifdef BAUTH_SUPPORT
   1656   const struct MHD_RqBAuth *bauth;
   1657 #endif /* BAUTH_SUPPORT */
   1658 #ifdef DAUTH_SUPPORT
   1659   const struct MHD_RqDAuth *dauth;
   1660 #endif /* DAUTH_SUPPORT */
   1661 
   1662   if ((NULL != conn.rq.headers_received) ||
   1663       (NULL != conn.rq.headers_received_tail))
   1664     externalErrorExitDesc ("Connection's test headers are not empty already");
   1665 
   1666   /* Init and use both Basic and Digest Auth headers */
   1667   memset (&h1, 0, sizeof(h1));
   1668   memset (&h2, 0, sizeof(h2));
   1669   memset (&h3, 0, sizeof(h3));
   1670 
   1671   h1.kind = MHD_HEADER_KIND;
   1672   h1.header = MHD_HTTP_HEADER_HOST; /* Just some random header */
   1673   h1.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_HOST);
   1674   h1.value = "localhost";
   1675   h1.value_size = strlen (h1.value);
   1676 
   1677   h2.kind = MHD_HEADER_KIND;
   1678   h2.header = MHD_HTTP_HEADER_AUTHORIZATION;
   1679   h2.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION);
   1680   h2.value = "Basic " TEST_AUTH_STR;
   1681   h2.value_size = strlen (h2.value);
   1682 
   1683   h3.kind = MHD_HEADER_KIND;
   1684   h3.header = MHD_HTTP_HEADER_AUTHORIZATION;
   1685   h3.header_size = MHD_STATICSTR_LEN_ (MHD_HTTP_HEADER_AUTHORIZATION);
   1686   h3.value = "Digest cnonce=" TEST_AUTH_STR;
   1687   h3.value_size = strlen (h3.value);
   1688 
   1689   conn.rq.headers_received = &h1;
   1690   h1.next = &h2;
   1691   h2.prev = &h1;
   1692   h2.next = &h3;
   1693   h3.prev = &h2;
   1694   conn.rq.headers_received_tail = &h3;
   1695 
   1696   conn.state = MHD_CONNECTION_FULL_REQ_RECEIVED; /* Should be a typical value */
   1697 
   1698   ret = 0;
   1699 #ifdef BAUTH_SUPPORT
   1700   bauth = get_BAuthRqParams ();
   1701 #endif /* BAUTH_SUPPORT */
   1702 #ifdef DAUTH_SUPPORT
   1703   dauth = get_DAuthRqParams ();
   1704 #endif /* DAUTH_SUPPORT */
   1705 #ifdef BAUTH_SUPPORT
   1706   if (NULL == bauth)
   1707   {
   1708     fprintf (stderr, "No Basic Authorization header detected. Line: %u\n",
   1709              (unsigned int) __LINE__);
   1710     ret++;
   1711   }
   1712   else if ((MHD_STATICSTR_LEN_ (TEST_AUTH_STR) != bauth->token68.len) ||
   1713            (0 != memcmp (bauth->token68.str, TEST_AUTH_STR,
   1714                          bauth->token68.len)))
   1715   {
   1716     fprintf (stderr, "Basic Authorization token does not match. Line: %u\n",
   1717              (unsigned int) __LINE__);
   1718     ret++;
   1719   }
   1720 #endif /* BAUTH_SUPPORT */
   1721 #ifdef DAUTH_SUPPORT
   1722   if (NULL == dauth)
   1723   {
   1724     fprintf (stderr, "No Digest Authorization header detected. Line: %u\n",
   1725              (unsigned int) __LINE__);
   1726     ret++;
   1727   }
   1728   else if ((MHD_STATICSTR_LEN_ (TEST_AUTH_STR) != dauth->cnonce.value.len) ||
   1729            (0 != memcmp (dauth->cnonce.value.str, TEST_AUTH_STR,
   1730                          dauth->cnonce.value.len)))
   1731   {
   1732     fprintf (stderr, "Digest Authorization 'cnonce' does not match. Line: %u\n",
   1733              (unsigned int) __LINE__);
   1734     ret++;
   1735   }
   1736 #endif /* DAUTH_SUPPORT */
   1737 
   1738   /* Cleanup */
   1739   conn.rq.headers_received = NULL;
   1740   conn.rq.headers_received_tail = NULL;
   1741   conn.state = MHD_CONNECTION_INIT;
   1742 
   1743   return ret;
   1744 }
   1745 
   1746 
   1747 int
   1748 main (int argc, char *argv[])
   1749 {
   1750   unsigned int errcount = 0;
   1751   (void) argc; (void) argv; /* Unused. Silent compiler warning. */
   1752   test_global_init ();
   1753 
   1754   errcount += check_type ();
   1755 #ifdef BAUTH_SUPPORT
   1756   errcount += check_basic ();
   1757 #endif /* BAUTH_SUPPORT */
   1758 #ifdef DAUTH_SUPPORT
   1759   errcount += check_digest ();
   1760 #endif /* DAUTH_SUPPORT */
   1761   errcount += check_two_auths ();
   1762   if (0 == errcount)
   1763     printf ("All tests were passed without errors.\n");
   1764   return errcount == 0 ? 0 : 1;
   1765 }