Pārlūkot izejas kodu

New unit test for HTTP authentication (part 4/4)

bel 9 gadi atpakaļ
vecāks
revīzija
c1ecae217b
1 mainītis faili ar 152 papildinājumiem un 2 dzēšanām
  1. 152 2
      test/public_server.c

+ 152 - 2
test/public_server.c

@@ -2057,7 +2057,7 @@ START_TEST(test_http_auth)
 	};
 	struct mg_context *ctx;
 	struct mg_connection *client_conn;
-	char client_err[256];
+	char client_err[256], nonce[256];
 	const struct mg_request_info *client_ri;
 	int client_res;
 	FILE *f;
@@ -2067,8 +2067,15 @@ START_TEST(test_http_auth)
 	const char *domain;
 	const char *doc_root;
 	const char *auth_request;
+	const char *str;
 	size_t len;
 	int i;
+	char HA1[256], HA2[256], HA[256];
+	char HA1_md5_buf[33], HA2_md5_buf[33], HA_md5_buf[33];
+	char *HA1_md5_ret, *HA2_md5_ret, *HA_md5_ret;
+	const char *nc = "00000001";
+	const char *cnonce = "6789ABCD";
+
 
 	/* Start with default options */
 	mark_point();
@@ -2153,8 +2160,152 @@ START_TEST(test_http_auth)
 		}
 	}
 	ck_assert_ptr_ne(auth_request, NULL);
+	str = "Digest qop=\"auth\", realm=\"";
+	len = strlen(str);
+	ck_assert(!mg_strncasecmp(auth_request, str, len));
+	ck_assert(!strncmp(auth_request + len, domain, strlen(domain)));
+	len += strlen(domain);
+	str = "\", nonce=\"";
+	ck_assert(!strncmp(auth_request + len, str, strlen(str)));
+	len += strlen(str);
+	str = strchr(auth_request + len, '\"');
+	ck_assert_ptr_ne(str, NULL);
+	ck_assert_ptr_ne(str, auth_request + len);
+	/* nonce is from including (auth_request + len) to excluding (str) */
+	ck_assert_int_gt((int)(str) - (int)(auth_request + len), 0);
+	ck_assert_int_lt((int)(str) - (int)(auth_request + len), sizeof(nonce));
+	memset(nonce, 0, sizeof(nonce));
+	memcpy(nonce, auth_request + len, (int)(str) - (int)(auth_request + len));
+	memset(HA1, 0, sizeof(HA1));
+	memset(HA2, 0, sizeof(HA2));
+	memset(HA, 0, sizeof(HA));
+	memset(HA1_md5_buf, 0, sizeof(HA1_md5_buf));
+	memset(HA2_md5_buf, 0, sizeof(HA2_md5_buf));
+	memset(HA_md5_buf, 0, sizeof(HA_md5_buf));
+
+	sprintf(HA1, "%s:%s:%s", "user", domain, "pass");
+	sprintf(HA2, "%s:/%s", "GET", test_file);
+	HA1_md5_ret = mg_md5(HA1_md5_buf, HA1, NULL);
+	HA2_md5_ret = mg_md5(HA2_md5_buf, HA2, NULL);
+
+	ck_assert_ptr_eq(HA1_md5_ret, HA1_md5_buf);
+	ck_assert_ptr_eq(HA2_md5_ret, HA2_md5_buf);
+
+	HA_md5_ret = mg_md5(HA_md5_buf, "user", ":", domain, ":", "pass", NULL);
+	ck_assert_ptr_eq(HA_md5_ret, HA_md5_buf);
+	ck_assert_str_eq(HA1_md5_ret, HA_md5_buf);
+
+	HA_md5_ret = mg_md5(HA_md5_buf, "GET", ":", "/", test_file, NULL);
+	ck_assert_ptr_eq(HA_md5_ret, HA_md5_buf);
+	ck_assert_str_eq(HA2_md5_ret, HA_md5_buf);
+
+	HA_md5_ret = mg_md5(HA_md5_buf,
+	                    HA1_md5_buf,
+	                    ":",
+	                    nonce,
+	                    ":",
+	                    nc,
+	                    ":",
+	                    cnonce,
+	                    ":",
+	                    "auth",
+	                    ":",
+	                    HA2_md5_buf,
+	                    NULL);
+	ck_assert_ptr_eq(HA_md5_ret, HA_md5_buf);
+
+	/* Retry with Authorization */
+	memset(client_err, 0, sizeof(client_err));
+	client_conn =
+	    mg_connect_client("127.0.0.1", 8080, 0, client_err, sizeof(client_err));
+	ck_assert(client_conn != NULL);
+	ck_assert_str_eq(client_err, "");
+	mg_printf(client_conn, "GET /%s HTTP/1.0\r\n", test_file);
+	mg_printf(client_conn,
+	          "Authorization: Digest "
+	          "username=\"%s\", "
+	          "realm=\"%s\", "
+	          "nonce=\"%s\", "
+	          "uri=\"/%s\", "
+	          "qop=auth, "
+	          "nc=%s, "
+	          "cnonce=\"%s\", "
+	          "response=\"%s\"\r\n\r\n",
+	          "user",
+	          domain,
+	          nonce,
+	          test_file,
+	          nc,
+	          cnonce,
+	          HA_md5_buf);
+	client_res =
+	    mg_get_response(client_conn, client_err, sizeof(client_err), 10000);
+	ck_assert_int_ge(client_res, 0);
+	ck_assert_str_eq(client_err, "");
+	client_ri = mg_get_request_info(client_conn);
+	ck_assert(client_ri != NULL);
 
+	ck_assert_str_eq(client_ri->uri, "200");
+	client_res = (int)mg_read(client_conn, client_err, sizeof(client_err));
+	ck_assert_int_gt(client_res, 0);
+	ck_assert_int_le(client_res, sizeof(client_err));
+	ck_assert_str_eq(client_err, test_content);
+	mg_close_connection(client_conn);
+
+	test_sleep(1);
+
+
+	/* Remove the user from the .htpasswd file again */
+	client_res = mg_modify_passwords_file(passwd_file, domain, "user", NULL);
+	ck_assert_int_eq(client_res, 1);
+
+	test_sleep(1);
 
+
+	/* Try to access the file again. Expected: 401 error */
+	memset(client_err, 0, sizeof(client_err));
+	client_conn =
+	    mg_connect_client("127.0.0.1", 8080, 0, client_err, sizeof(client_err));
+	ck_assert(client_conn != NULL);
+	ck_assert_str_eq(client_err, "");
+	mg_printf(client_conn, "GET /%s HTTP/1.0\r\n\r\n", test_file);
+	client_res =
+	    mg_get_response(client_conn, client_err, sizeof(client_err), 10000);
+	ck_assert_int_ge(client_res, 0);
+	ck_assert_str_eq(client_err, "");
+	client_ri = mg_get_request_info(client_conn);
+	ck_assert(client_ri != NULL);
+
+	ck_assert_str_eq(client_ri->uri, "401");
+	mg_close_connection(client_conn);
+
+	test_sleep(1);
+
+
+	/* Now remove the password file */
+	remove(passwd_file);
+	test_sleep(1);
+
+
+	/* Access to the file must work like before */
+	memset(client_err, 0, sizeof(client_err));
+	client_conn =
+	    mg_connect_client("127.0.0.1", 8080, 0, client_err, sizeof(client_err));
+	ck_assert(client_conn != NULL);
+	ck_assert_str_eq(client_err, "");
+	mg_printf(client_conn, "GET /%s HTTP/1.0\r\n\r\n", test_file);
+	client_res =
+	    mg_get_response(client_conn, client_err, sizeof(client_err), 10000);
+	ck_assert_int_ge(client_res, 0);
+	ck_assert_str_eq(client_err, "");
+	client_ri = mg_get_request_info(client_conn);
+	ck_assert(client_ri != NULL);
+
+	ck_assert_str_eq(client_ri->uri, "200");
+	client_res = (int)mg_read(client_conn, client_err, sizeof(client_err));
+	ck_assert_int_gt(client_res, 0);
+	ck_assert_int_le(client_res, sizeof(client_err));
+	ck_assert_str_eq(client_err, test_content);
 	mg_close_connection(client_conn);
 
 	test_sleep(1);
@@ -2162,7 +2313,6 @@ START_TEST(test_http_auth)
 
 	/* Stop the server and clean up */
 	mg_stop(ctx);
-	remove(passwd_file); /* Don't leave it here for the next test */
 	remove(test_file);
 
 #endif