فهرست منبع

test_digestauth2: added testing with two requests

Second request should test additional code paths
Evgeny Grin (Karlson2k) 3 سال پیش
والد
کامیت
63c6f68b5d
1فایلهای تغییر یافته به همراه155 افزوده شده و 34 حذف شده
  1. 155 34
      src/testcurl/test_digestauth2.c

+ 155 - 34
src/testcurl/test_digestauth2.c

@@ -228,6 +228,7 @@ _checkCURLE_OK_func (CURLcode code, const char *curlFunc,
 #define TIMEOUTS_VAL 10
 #define TIMEOUTS_VAL 10
 
 
 #define MHD_URI_BASE_PATH "/bar%20foo?key=value"
 #define MHD_URI_BASE_PATH "/bar%20foo?key=value"
+#define MHD_URI_BASE_PATH2 "/another_path"
 
 
 #define REALM_VAL "TestRealm"
 #define REALM_VAL "TestRealm"
 #define USERNAME1 "test_user"
 #define USERNAME1 "test_user"
@@ -388,6 +389,20 @@ struct CBC
   size_t size;
   size_t size;
 };
 };
 
 
+struct req_track
+{
+  /**
+   * The number of used URI, zero-based
+   */
+  unsigned int uri_num;
+
+  /**
+   * The number of request for URI.
+   * This includes number of unauthorised requests.
+   */
+  unsigned int req_num;
+};
+
 
 
 static size_t
 static size_t
 copyBuffer (void *ptr,
 copyBuffer (void *ptr,
@@ -418,9 +433,10 @@ ahc_echo (void *cls,
   struct MHD_Response *response;
   struct MHD_Response *response;
   enum MHD_Result res;
   enum MHD_Result res;
   static int already_called_marker;
   static int already_called_marker;
-  (void) cls; (void) url;         /* Unused. Silent compiler warning. */
+  struct req_track *const tr_p = (struct req_track *) cls;
+  (void) url;              /* Unused. Silent compiler warning. */
   (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
   (void) method; (void) version; (void) upload_data; /* Unused. Silent compiler warning. */
-  (void) upload_data_size;        /* Unused. Silent compiler warning. */
+  (void) upload_data_size; /* Unused. Silent compiler warning. */
 
 
   if (&already_called_marker != *req_cls)
   if (&already_called_marker != *req_cls)
   { /* Called for the first time, request not fully read yet */
   { /* Called for the first time, request not fully read yet */
@@ -432,6 +448,10 @@ ahc_echo (void *cls,
   if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
   if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
     mhdErrorExitDesc ("Unexpected HTTP method");
     mhdErrorExitDesc ("Unexpected HTTP method");
 
 
+  tr_p->req_num++;
+  if (2 < tr_p->req_num)
+    mhdErrorExitDesc ("Received more than two requests for the same URI");
+
   response = NULL;
   response = NULL;
   if (! test_oldapi)
   if (! test_oldapi)
   {
   {
@@ -447,6 +467,7 @@ ahc_echo (void *cls,
       /* Got any kind of Digest response. Check it, it must be valid */
       /* Got any kind of Digest response. Check it, it must be valid */
       struct MHD_DigestAuthUsernameInfo *uname;
       struct MHD_DigestAuthUsernameInfo *uname;
       enum MHD_DigestAuthResult check_res;
       enum MHD_DigestAuthResult check_res;
+      enum MHD_DigestAuthResult expect_res;
 
 
       if (NULL == dinfo->username)
       if (NULL == dinfo->username)
         mhdErrorExitDesc ("'username' is NULL");
         mhdErrorExitDesc ("'username' is NULL");
@@ -678,18 +699,40 @@ ahc_echo (void *cls,
                                          (enum MHD_DigestAuthMultiQOP) qop,
                                          (enum MHD_DigestAuthMultiQOP) qop,
                                          (enum MHD_DigestAuthMultiAlgo3) algo3);
                                          (enum MHD_DigestAuthMultiAlgo3) algo3);
 
 
+      if (test_rfc2069)
+      {
+        if ((1 == tr_p->uri_num) && (1 == tr_p->req_num))
+          expect_res = MHD_DAUTH_NONCE_STALE;
+        else
+          expect_res = MHD_DAUTH_OK;
+      }
+      else
+        expect_res = MHD_DAUTH_OK;
+
       switch (check_res)
       switch (check_res)
       {
       {
-      /* Valid result */
+      /* Conditionally valid results */
       case MHD_DAUTH_OK:
       case MHD_DAUTH_OK:
-        if (verbose)
-          printf ("Got valid auth check result: MHD_DAUTH_OK.\n");
+        if (expect_res == MHD_DAUTH_OK)
+        {
+          if (verbose)
+            printf ("Got valid auth check result: MHD_DAUTH_OK.\n");
+        }
+        else
+          mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \
+                            "MHD_DAUTH_OK");
         break;
         break;
-      /* Invalid results */
       case MHD_DAUTH_NONCE_STALE:
       case MHD_DAUTH_NONCE_STALE:
-        mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \
-                          "MHD_DAUTH_NONCE_STALE");
+        if (expect_res == MHD_DAUTH_NONCE_STALE)
+        {
+          if (verbose)
+            printf ("Got expected auth check result: MHD_DAUTH_NONCE_STALE.\n");
+        }
+        else
+          mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \
+                            "MHD_DAUTH_NONCE_STALE");
         break;
         break;
+      /* Invalid results */
       case MHD_DAUTH_NONCE_WRONG:
       case MHD_DAUTH_NONCE_WRONG:
         mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \
         mhdErrorExitDesc ("MHD_digest_auth_check[_digest]3()' returned " \
                           "MHD_DAUTH_NONCE_WRONG");
                           "MHD_DAUTH_NONCE_WRONG");
@@ -731,19 +774,50 @@ ahc_echo (void *cls,
         mhdErrorExitDesc ("Impossible returned code");
         mhdErrorExitDesc ("Impossible returned code");
       }
       }
 
 
-      response =
-        MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE),
-                                                (const void *) PAGE);
-      if (NULL == response)
-        mhdErrorExitDesc ("Response creation failed");
-
-      if (MHD_YES !=
-          MHD_queue_response (connection, MHD_HTTP_OK, response))
-        mhdErrorExitDesc ("'MHD_queue_response()' failed");
+      if (MHD_DAUTH_OK == check_res)
+      {
+        response =
+          MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE),
+                                                  (const void *) PAGE);
+        if (NULL == response)
+          mhdErrorExitDesc ("Response creation failed");
+
+        if (MHD_YES !=
+            MHD_queue_response (connection, MHD_HTTP_OK, response))
+          mhdErrorExitDesc ("'MHD_queue_response()' failed");
+      }
+      else if (MHD_DAUTH_NONCE_STALE == check_res)
+      {
+        response =
+          MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
+                                                  (const void *) DENIED);
+        if (NULL == response)
+          mhdErrorExitDesc ("Response creation failed");
+        res =
+          MHD_queue_auth_required_response3 (connection, REALM_VAL,
+                                             OPAQUE_VALUE,
+                                             "/", response, 1,
+                                             (enum MHD_DigestAuthMultiQOP) qop,
+                                             (enum MHD_DigestAuthMultiAlgo3)
+                                             algo3,
+                                             test_userhash, 0);
+        if (MHD_YES != res)
+          mhdErrorExitDesc ("'MHD_queue_auth_required_response3()' failed");
+      }
+      else
+        mhdErrorExitDesc ("Wrong 'check_res' value");
     }
     }
     else
     else
     {
     {
       /* No Digest auth header */
       /* No Digest auth header */
+      if ((1 != tr_p->req_num) || (0 != tr_p->uri_num))
+      {
+        fprintf (stderr, "Received request number %u for URI number %u "
+                 "without Digest Authorisation header. ",
+                 tr_p->req_num, tr_p->uri_num + 1);
+        mhdErrorExitDesc ("Wrong requests sequence");
+      }
+
       response =
       response =
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
                                                 (const void *) DENIED);
                                                 (const void *) DENIED);
@@ -813,6 +887,13 @@ ahc_echo (void *cls,
     else
     else
     {
     {
       /* Has no valid username in header */
       /* Has no valid username in header */
+      if ((1 != tr_p->req_num) || (0 != tr_p->uri_num))
+      {
+        fprintf (stderr, "Received request number %u for URI number %u "
+                 "without Digest Authorisation header. ",
+                 tr_p->req_num, tr_p->uri_num + 1);
+        mhdErrorExitDesc ("Wrong requests sequence");
+      }
       response =
       response =
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
                                                 (const void *) DENIED);
                                                 (const void *) DENIED);
@@ -877,6 +958,13 @@ ahc_echo (void *cls,
     else
     else
     {
     {
       /* Has no valid username in header */
       /* Has no valid username in header */
+      if ((1 != tr_p->req_num) || (0 != tr_p->uri_num))
+      {
+        fprintf (stderr, "Received request number %u for URI number %u "
+                 "without Digest Authorisation header. ",
+                 tr_p->req_num, tr_p->uri_num + 1);
+        mhdErrorExitDesc ("Wrong requests sequence");
+      }
       response =
       response =
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
         MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (DENIED),
                                                 (const void *) DENIED);
                                                 (const void *) DENIED);
@@ -897,22 +985,35 @@ ahc_echo (void *cls,
 }
 }
 
 
 
 
+/**
+ *
+ * @param c the CURL handle to use
+ * @param port the port to set
+ * @param uri_num the number of URI, 0 or 1
+ */
+static void
+setCURL_rq_path (CURL *c, unsigned int port, unsigned int uri_num)
+{
+  char uri[512];
+  int res;
+  /* A workaround for some old libcurl versions, which ignore the specified
+   * port by CURLOPT_PORT when authorisation is used. */
+  res = snprintf (uri, (sizeof(uri) / sizeof(uri[0])),
+                  "http://127.0.0.1:%u%s", port,
+                  (0 == uri_num) ?
+                  MHD_URI_BASE_PATH : MHD_URI_BASE_PATH2);
+  if ((0 >= res) || ((sizeof(uri) / sizeof(uri[0])) <= (size_t) res))
+    externalErrorExitDesc ("Cannot form request URL");
+
+  if (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, uri))
+    libcurlErrorExitDesc ("Cannot set request URL");
+}
+
+
 static CURL *
 static CURL *
-setupCURL (void *cbc, int port)
+setupCURL (void *cbc, unsigned int port)
 {
 {
   CURL *c;
   CURL *c;
-  char url[512];
-
-  if (1)
-  {
-    int res;
-    /* A workaround for some old libcurl versions, which ignore the specified
-     * port by CURLOPT_PORT when authorisation is used. */
-    res = snprintf (url, (sizeof(url) / sizeof(url[0])),
-                    "http://127.0.0.1:%d%s", port, MHD_URI_BASE_PATH);
-    if ((0 >= res) || ((sizeof(url) / sizeof(url[0])) <= (size_t) res))
-      externalErrorExitDesc ("Cannot form request URL");
-  }
 
 
   c = curl_easy_init ();
   c = curl_easy_init ();
   if (NULL == c)
   if (NULL == c)
@@ -947,9 +1048,11 @@ setupCURL (void *cbc, int port)
 #if CURL_AT_LEAST_VERSION (7, 45, 0)
 #if CURL_AT_LEAST_VERSION (7, 45, 0)
       (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) ||
       (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) ||
 #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */
 #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */
-      (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port))) ||
-      (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, url)))
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port))))
     libcurlErrorExitDesc ("curl_easy_setopt() failed");
     libcurlErrorExitDesc ("curl_easy_setopt() failed");
+
+  setCURL_rq_path (c, port, 0);
+
   return c;
   return c;
 }
 }
 
 
@@ -1113,6 +1216,7 @@ testDigestAuth (void)
   struct MHD_Daemon *d;
   struct MHD_Daemon *d;
   uint16_t port;
   uint16_t port;
   struct CBC cbc;
   struct CBC cbc;
+  struct req_track rq_tr;
   char buf[2048];
   char buf[2048];
   CURL *c;
   CURL *c;
   int failed = 0;
   int failed = 0;
@@ -1135,7 +1239,7 @@ testDigestAuth (void)
 
 
     d = MHD_start_daemon (MHD_USE_ERROR_LOG,
     d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                           port, NULL, NULL,
                           port, NULL, NULL,
-                          &ahc_echo, NULL,
+                          &ahc_echo, &rq_tr,
                           MHD_OPTION_DIGEST_AUTH_RANDOM_COPY,
                           MHD_OPTION_DIGEST_AUTH_RANDOM_COPY,
                           sizeof (salt), salt,
                           sizeof (salt), salt,
                           MHD_OPTION_NONCE_NC_SIZE, 300,
                           MHD_OPTION_NONCE_NC_SIZE, 300,
@@ -1156,11 +1260,28 @@ testDigestAuth (void)
   }
   }
 
 
   /* First request */
   /* First request */
+  rq_tr.req_num = 0;
+  rq_tr.uri_num = 0;
   cbc.buf = buf;
   cbc.buf = buf;
   cbc.size = sizeof (buf);
   cbc.size = sizeof (buf);
   cbc.pos = 0;
   cbc.pos = 0;
   memset (cbc.buf, 0, cbc.size);
   memset (cbc.buf, 0, cbc.size);
-  c = setupCURL (&cbc, port);
+  c = setupCURL (&cbc, (unsigned int) port);
+  /* First request */
+  if (check_result (performQueryExternal (d, c), c, &cbc))
+  {
+    if (verbose)
+      printf ("Got expected response.\n");
+  }
+  else
+  {
+    fprintf (stderr, "Request FAILED.\n");
+    failed = 1;
+  }
+  cbc.pos = 0; /* Reset buffer position */
+  rq_tr.req_num = 0;
+  /* Second request */
+  setCURL_rq_path (c, port, ++rq_tr.uri_num);
   if (check_result (performQueryExternal (d, c), c, &cbc))
   if (check_result (performQueryExternal (d, c), c, &cbc))
   {
   {
     if (verbose)
     if (verbose)