diff options
Diffstat (limited to 'src/testcurl/test_digestauth2.c')
-rw-r--r-- | src/testcurl/test_digestauth2.c | 189 |
1 files changed, 155 insertions, 34 deletions
diff --git a/src/testcurl/test_digestauth2.c b/src/testcurl/test_digestauth2.c index 4c3af9bf..d88435c3 100644 --- a/src/testcurl/test_digestauth2.c +++ b/src/testcurl/test_digestauth2.c | |||
@@ -228,6 +228,7 @@ _checkCURLE_OK_func (CURLcode code, const char *curlFunc, | |||
228 | #define TIMEOUTS_VAL 10 | 228 | #define TIMEOUTS_VAL 10 |
229 | 229 | ||
230 | #define MHD_URI_BASE_PATH "/bar%20foo?key=value" | 230 | #define MHD_URI_BASE_PATH "/bar%20foo?key=value" |
231 | #define MHD_URI_BASE_PATH2 "/another_path" | ||
231 | 232 | ||
232 | #define REALM_VAL "TestRealm" | 233 | #define REALM_VAL "TestRealm" |
233 | #define USERNAME1 "test_user" | 234 | #define USERNAME1 "test_user" |
@@ -388,6 +389,20 @@ struct CBC | |||
388 | size_t size; | 389 | size_t size; |
389 | }; | 390 | }; |
390 | 391 | ||
392 | struct req_track | ||
393 | { | ||
394 | /** | ||
395 | * The number of used URI, zero-based | ||
396 | */ | ||
397 | unsigned int uri_num; | ||
398 | |||
399 | /** | ||
400 | * The number of request for URI. | ||
401 | * This includes number of unauthorised requests. | ||
402 | */ | ||
403 | unsigned int req_num; | ||
404 | }; | ||
405 | |||
391 | 406 | ||
392 | static size_t | 407 | static size_t |
393 | copyBuffer (void *ptr, | 408 | copyBuffer (void *ptr, |
@@ -418,9 +433,10 @@ ahc_echo (void *cls, | |||
418 | struct MHD_Response *response; | 433 | struct MHD_Response *response; |
419 | enum MHD_Result res; | 434 | enum MHD_Result res; |
420 | static int already_called_marker; | 435 | static int already_called_marker; |
421 | (void) cls; (void) url; /* Unused. Silent compiler warning. */ | 436 | struct req_track *const tr_p = (struct req_track *) cls; |
437 | (void) url; /* Unused. Silent compiler warning. */ | ||
422 | (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */ | 438 | (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */ |
423 | (void) upload_data_size; /* Unused. Silent compiler warning. */ | 439 | (void) upload_data_size; /* Unused. Silent compiler warning. */ |
424 | 440 | ||
425 | if (&already_called_marker != *req_cls) | 441 | if (&already_called_marker != *req_cls) |
426 | { /* Called for the first time, request not fully read yet */ | 442 | { /* Called for the first time, request not fully read yet */ |
@@ -432,6 +448,10 @@ ahc_echo (void *cls, | |||
432 | if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) | 448 | if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) |
433 | mhdErrorExitDesc ("Unexpected HTTP method"); | 449 | mhdErrorExitDesc ("Unexpected HTTP method"); |
434 | 450 | ||
451 | tr_p->req_num++; | ||
452 | if (2 < tr_p->req_num) | ||
453 | mhdErrorExitDesc ("Received more than two requests for the same URI"); | ||
454 | |||
435 | response = NULL; | 455 | response = NULL; |
436 | if (! test_oldapi) | 456 | if (! test_oldapi) |
437 | { | 457 | { |
@@ -447,6 +467,7 @@ ahc_echo (void *cls, | |||
447 | /* Got any kind of Digest response. Check it, it must be valid */ | 467 | /* Got any kind of Digest response. Check it, it must be valid */ |
448 | struct MHD_DigestAuthUsernameInfo *uname; | 468 | struct MHD_DigestAuthUsernameInfo *uname; |
449 | enum MHD_DigestAuthResult check_res; | 469 | enum MHD_DigestAuthResult check_res; |
470 | enum MHD_DigestAuthResult expect_res; | ||
450 | 471 | ||
451 | if (NULL == dinfo->username) | 472 | if (NULL == dinfo->username) |
452 | mhdErrorExitDesc ("'username' is NULL"); | 473 | mhdErrorExitDesc ("'username' is NULL"); |
@@ -678,18 +699,40 @@ ahc_echo (void *cls, | |||
678 | (enum MHD_DigestAuthMultiQOP) qop, | 699 | (enum MHD_DigestAuthMultiQOP) qop, |
679 | (enum MHD_DigestAuthMultiAlgo3) algo3); | 700 | (enum MHD_DigestAuthMultiAlgo3) algo3); |
680 | 701 | ||
702 | if (test_rfc2069) | ||
703 | { | ||
704 | if ((1 == tr_p->uri_num) && (1 == tr_p->req_num)) | ||
705 | expect_res = MHD_DAUTH_NONCE_STALE; | ||
706 | else | ||
707 | expect_res = MHD_DAUTH_OK; | ||
708 | } | ||
709 | else | ||
710 | expect_res = MHD_DAUTH_OK; | ||
711 | |||
681 | switch (check_res) | 712 | switch (check_res) |
682 | { | 713 | { |
683 | /* Valid result */ | 714 | /* Conditionally valid results */ |
684 | case MHD_DAUTH_OK: | 715 | case MHD_DAUTH_OK: |
685 | if (verbose) | 716 | if (expect_res == MHD_DAUTH_OK) |
686 | printf ("Got valid auth check result: MHD_DAUTH_OK.\n"); | 717 | { |
718 | if (verbose) | ||
719 | printf ("Got valid auth check result: MHD_DAUTH_OK.\n"); | ||
720 | } | ||
721 | else | ||
722 | mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \ | ||
723 | "MHD_DAUTH_OK"); | ||
687 | break; | 724 | break; |
688 | /* Invalid results */ | ||
689 | case MHD_DAUTH_NONCE_STALE: | 725 | case MHD_DAUTH_NONCE_STALE: |
690 | mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \ | 726 | if (expect_res == MHD_DAUTH_NONCE_STALE) |
691 | "MHD_DAUTH_NONCE_STALE"); | 727 | { |
728 | if (verbose) | ||
729 | printf ("Got expected auth check result: MHD_DAUTH_NONCE_STALE.\n"); | ||
730 | } | ||
731 | else | ||
732 | mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \ | ||
733 | "MHD_DAUTH_NONCE_STALE"); | ||
692 | break; | 734 | break; |
735 | /* Invalid results */ | ||
693 | case MHD_DAUTH_NONCE_WRONG: | 736 | case MHD_DAUTH_NONCE_WRONG: |
694 | mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \ | 737 | mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \ |
695 | "MHD_DAUTH_NONCE_WRONG"); | 738 | "MHD_DAUTH_NONCE_WRONG"); |
@@ -731,19 +774,50 @@ ahc_echo (void *cls, | |||
731 | mhdErrorExitDesc ("Impossible returned code"); | 774 | mhdErrorExitDesc ("Impossible returned code"); |
732 | } | 775 | } |
733 | 776 | ||
734 | response = | 777 | if (MHD_DAUTH_OK == check_res) |
735 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE), | 778 | { |
736 | (const void *) PAGE); | 779 | response = |
737 | if (NULL == response) | 780 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE), |
738 | mhdErrorExitDesc ("Response creation failed"); | 781 | (const void *) PAGE); |
739 | 782 | if (NULL == response) | |
740 | if (MHD_YES != | 783 | mhdErrorExitDesc ("Response creation failed"); |
741 | MHD_queue_response (connection, MHD_HTTP_OK, response)) | 784 | |
742 | mhdErrorExitDesc ("'MHD_queue_response()' failed"); | 785 | if (MHD_YES != |
786 | MHD_queue_response (connection, MHD_HTTP_OK, response)) | ||
787 | mhdErrorExitDesc ("'MHD_queue_response()' failed"); | ||
788 | } | ||
789 | else if (MHD_DAUTH_NONCE_STALE == check_res) | ||
790 | { | ||
791 | response = | ||
792 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), | ||
793 | (const void *) DENIED); | ||
794 | if (NULL == response) | ||
795 | mhdErrorExitDesc ("Response creation failed"); | ||
796 | res = | ||
797 | MHD_queue_auth_required_response3 (connection, REALM_VAL, | ||
798 | OPAQUE_VALUE, | ||
799 | "/", response, 1, | ||
800 | (enum MHD_DigestAuthMultiQOP) qop, | ||
801 | (enum MHD_DigestAuthMultiAlgo3) | ||
802 | algo3, | ||
803 | test_userhash, 0); | ||
804 | if (MHD_YES != res) | ||
805 | mhdErrorExitDesc ("'MHD_queue_auth_required_response3()' failed"); | ||
806 | } | ||
807 | else | ||
808 | mhdErrorExitDesc ("Wrong 'check_res' value"); | ||
743 | } | 809 | } |
744 | else | 810 | else |
745 | { | 811 | { |
746 | /* No Digest auth header */ | 812 | /* No Digest auth header */ |
813 | if ((1 != tr_p->req_num) || (0 != tr_p->uri_num)) | ||
814 | { | ||
815 | fprintf (stderr, "Received request number %u for URI number %u " | ||
816 | "without Digest Authorisation header. ", | ||
817 | tr_p->req_num, tr_p->uri_num + 1); | ||
818 | mhdErrorExitDesc ("Wrong requests sequence"); | ||
819 | } | ||
820 | |||
747 | response = | 821 | response = |
748 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), | 822 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), |
749 | (const void *) DENIED); | 823 | (const void *) DENIED); |
@@ -813,6 +887,13 @@ ahc_echo (void *cls, | |||
813 | else | 887 | else |
814 | { | 888 | { |
815 | /* Has no valid username in header */ | 889 | /* Has no valid username in header */ |
890 | if ((1 != tr_p->req_num) || (0 != tr_p->uri_num)) | ||
891 | { | ||
892 | fprintf (stderr, "Received request number %u for URI number %u " | ||
893 | "without Digest Authorisation header. ", | ||
894 | tr_p->req_num, tr_p->uri_num + 1); | ||
895 | mhdErrorExitDesc ("Wrong requests sequence"); | ||
896 | } | ||
816 | response = | 897 | response = |
817 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), | 898 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), |
818 | (const void *) DENIED); | 899 | (const void *) DENIED); |
@@ -877,6 +958,13 @@ ahc_echo (void *cls, | |||
877 | else | 958 | else |
878 | { | 959 | { |
879 | /* Has no valid username in header */ | 960 | /* Has no valid username in header */ |
961 | if ((1 != tr_p->req_num) || (0 != tr_p->uri_num)) | ||
962 | { | ||
963 | fprintf (stderr, "Received request number %u for URI number %u " | ||
964 | "without Digest Authorisation header. ", | ||
965 | tr_p->req_num, tr_p->uri_num + 1); | ||
966 | mhdErrorExitDesc ("Wrong requests sequence"); | ||
967 | } | ||
880 | response = | 968 | response = |
881 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), | 969 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED), |
882 | (const void *) DENIED); | 970 | (const void *) DENIED); |
@@ -897,22 +985,35 @@ ahc_echo (void *cls, | |||
897 | } | 985 | } |
898 | 986 | ||
899 | 987 | ||
988 | /** | ||
989 | * | ||
990 | * @param c the CURL handle to use | ||
991 | * @param port the port to set | ||
992 | * @param uri_num the number of URI, 0 or 1 | ||
993 | */ | ||
994 | static void | ||
995 | setCURL_rq_path (CURL *c, unsigned int port, unsigned int uri_num) | ||
996 | { | ||
997 | char uri[512]; | ||
998 | int res; | ||
999 | /* A workaround for some old libcurl versions, which ignore the specified | ||
1000 | * port by CURLOPT_PORT when authorisation is used. */ | ||
1001 | res = snprintf (uri, (sizeof(uri) / sizeof(uri[0])), | ||
1002 | "http://127.0.0.1:%u%s", port, | ||
1003 | (0 == uri_num) ? | ||
1004 | MHD_URI_BASE_PATH : MHD_URI_BASE_PATH2); | ||
1005 | if ((0 >= res) || ((sizeof(uri) / sizeof(uri[0])) <= (size_t) res)) | ||
1006 | externalErrorExitDesc ("Cannot form request URL"); | ||
1007 | |||
1008 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, uri)) | ||
1009 | libcurlErrorExitDesc ("Cannot set request URL"); | ||
1010 | } | ||
1011 | |||
1012 | |||
900 | static CURL * | 1013 | static CURL * |
901 | setupCURL (void *cbc, int port) | 1014 | setupCURL (void *cbc, unsigned int port) |
902 | { | 1015 | { |
903 | CURL *c; | 1016 | CURL *c; |
904 | char url[512]; | ||
905 | |||
906 | if (1) | ||
907 | { | ||
908 | int res; | ||
909 | /* A workaround for some old libcurl versions, which ignore the specified | ||
910 | * port by CURLOPT_PORT when authorisation is used. */ | ||
911 | res = snprintf (url, (sizeof(url) / sizeof(url[0])), | ||
912 | "http://127.0.0.1:%d%s", port, MHD_URI_BASE_PATH); | ||
913 | if ((0 >= res) || ((sizeof(url) / sizeof(url[0])) <= (size_t) res)) | ||
914 | externalErrorExitDesc ("Cannot form request URL"); | ||
915 | } | ||
916 | 1017 | ||
917 | c = curl_easy_init (); | 1018 | c = curl_easy_init (); |
918 | if (NULL == c) | 1019 | if (NULL == c) |
@@ -947,9 +1048,11 @@ setupCURL (void *cbc, int port) | |||
947 | #if CURL_AT_LEAST_VERSION (7, 45, 0) | 1048 | #if CURL_AT_LEAST_VERSION (7, 45, 0) |
948 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) || | 1049 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) || |
949 | #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */ | 1050 | #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */ |
950 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port))) || | 1051 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port)))) |
951 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, url))) | ||
952 | libcurlErrorExitDesc ("curl_easy_setopt() failed"); | 1052 | libcurlErrorExitDesc ("curl_easy_setopt() failed"); |
1053 | |||
1054 | setCURL_rq_path (c, port, 0); | ||
1055 | |||
953 | return c; | 1056 | return c; |
954 | } | 1057 | } |
955 | 1058 | ||
@@ -1113,6 +1216,7 @@ testDigestAuth (void) | |||
1113 | struct MHD_Daemon *d; | 1216 | struct MHD_Daemon *d; |
1114 | uint16_t port; | 1217 | uint16_t port; |
1115 | struct CBC cbc; | 1218 | struct CBC cbc; |
1219 | struct req_track rq_tr; | ||
1116 | char buf[2048]; | 1220 | char buf[2048]; |
1117 | CURL *c; | 1221 | CURL *c; |
1118 | int failed = 0; | 1222 | int failed = 0; |
@@ -1135,7 +1239,7 @@ testDigestAuth (void) | |||
1135 | 1239 | ||
1136 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, | 1240 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, |
1137 | port, NULL, NULL, | 1241 | port, NULL, NULL, |
1138 | &ahc_echo, NULL, | 1242 | &ahc_echo, &rq_tr, |
1139 | MHD_OPTION_DIGEST_AUTH_RANDOM_COPY, | 1243 | MHD_OPTION_DIGEST_AUTH_RANDOM_COPY, |
1140 | sizeof (salt), salt, | 1244 | sizeof (salt), salt, |
1141 | MHD_OPTION_NONCE_NC_SIZE, 300, | 1245 | MHD_OPTION_NONCE_NC_SIZE, 300, |
@@ -1156,11 +1260,28 @@ testDigestAuth (void) | |||
1156 | } | 1260 | } |
1157 | 1261 | ||
1158 | /* First request */ | 1262 | /* First request */ |
1263 | rq_tr.req_num = 0; | ||
1264 | rq_tr.uri_num = 0; | ||
1159 | cbc.buf = buf; | 1265 | cbc.buf = buf; |
1160 | cbc.size = sizeof (buf); | 1266 | cbc.size = sizeof (buf); |
1161 | cbc.pos = 0; | 1267 | cbc.pos = 0; |
1162 | memset (cbc.buf, 0, cbc.size); | 1268 | memset (cbc.buf, 0, cbc.size); |
1163 | c = setupCURL (&cbc, port); | 1269 | c = setupCURL (&cbc, (unsigned int) port); |
1270 | /* First request */ | ||
1271 | if (check_result (performQueryExternal (d, c), c, &cbc)) | ||
1272 | { | ||
1273 | if (verbose) | ||
1274 | printf ("Got expected response.\n"); | ||
1275 | } | ||
1276 | else | ||
1277 | { | ||
1278 | fprintf (stderr, "Request FAILED.\n"); | ||
1279 | failed = 1; | ||
1280 | } | ||
1281 | cbc.pos = 0; /* Reset buffer position */ | ||
1282 | rq_tr.req_num = 0; | ||
1283 | /* Second request */ | ||
1284 | setCURL_rq_path (c, port, ++rq_tr.uri_num); | ||
1164 | if (check_result (performQueryExternal (d, c), c, &cbc)) | 1285 | if (check_result (performQueryExternal (d, c), c, &cbc)) |
1165 | { | 1286 | { |
1166 | if (verbose) | 1287 | if (verbose) |