diff --git a/test/httpauth.c b/test/httpauth.c index 3606ada2f..950b7c64e 100644 --- a/test/httpauth.c +++ b/test/httpauth.c @@ -171,8 +171,8 @@ int test_httpauth_resp(void) PL("sip:creytiv.com;transport=udp"), PL("00000002"), PL("66a7a21e46ad8edd"), - PL("auth"), - NULL}, + PL("auth"), PL_INIT, PL_INIT, + PL_INIT, NULL, 0, NULL}, PL("REGISTER"), "\x1c\x0a\x98\x61\x5b\x7b\x37\xc6" "\x94\x51\xae\xb6\x4b\x2f\x11\x02", @@ -180,8 +180,9 @@ int test_httpauth_resp(void) }, { "Digest bogus tull", - {PL_INIT, PL_INIT, PL_INIT, PL_INIT, - PL_INIT, PL_INIT, PL_INIT, PL_INIT, NULL}, + {PL_INIT, PL_INIT, PL_INIT, PL_INIT, PL_INIT, + PL_INIT, PL_INIT, PL_INIT, PL_INIT, PL_INIT, + PL_INIT, NULL, 0 , NULL}, PL_INIT, "", EBADMSG @@ -420,7 +421,7 @@ int test_httpauth_digest_request(void) mb_printed = mbuf_alloc(512); if (!mb_refval || !mb_printed) { err = ENOMEM; - goto for_out; + goto out; } err = httpauth_digest_chall_request_full(&req, testv[i].realm, @@ -428,7 +429,7 @@ int test_httpauth_digest_request(void) testv[i].stale, testv[i].algorithm, testv[i].qop, testv[i].charset, testv[i].userhash); if (err == ENOMEM) { - goto for_out; + goto out; } else if (err != testv[i].err) { DEBUG_WARNING("[%d]" @@ -443,7 +444,7 @@ int test_httpauth_digest_request(void) if (err) { DEBUG_WARNING("[%d]" " No reference created %m\n", i, err); - goto for_out; + goto out; } err = mbuf_printf(mb_printed, "%H", @@ -451,14 +452,14 @@ int test_httpauth_digest_request(void) if (err) { DEBUG_WARNING("[%d]" " Digest request print error %m\n", i, err); - goto for_out; + goto out; } if (mb_refval->end != mb_printed->end) { DEBUG_WARNING("[%d] Expected header len %d, got %d\n", i, mb_refval->end, mb_printed->end); err = EINVAL; - goto for_out; + goto out; } if (memcmp(mb_refval->buf, mb_printed->buf, mb_refval->end)) { @@ -466,7 +467,7 @@ int test_httpauth_digest_request(void) mb_refval->buf, mb_refval->end, mb_printed->buf, mb_printed->end); err = EINVAL; - goto for_out; + goto out; } for_continue: @@ -475,7 +476,7 @@ int test_httpauth_digest_request(void) mem_deref(mb_printed); continue; -for_out: +out: mem_deref(req); mem_deref(mb_refval); mem_deref(mb_printed); @@ -599,7 +600,7 @@ int test_httpauth_digest_response(void) mb_printed = mbuf_alloc(512); if (!mb_printed) { err = ENOMEM; - goto for_out; + goto out; } err = httpauth_digest_response_full(&resp, &testv[i].chall, @@ -607,12 +608,12 @@ int test_httpauth_digest_response(void) testv[i].passwd, testv[i].qop, testv[i].entitybody, NULL, false); if (err == ENOMEM) { - goto for_out; + goto out; } else if (err) { DEBUG_WARNING("[%d]" " Could not generate response %m\n", i, err); - goto for_out; + goto out; } err = httpauth_digest_response_set_cnonce(resp, @@ -622,13 +623,13 @@ int test_httpauth_digest_response(void) if (err) { DEBUG_WARNING("[%d]" " Response recalculation failed %m\n", i, err); - goto for_out; + goto out; } err = mbuf_printf(mb_printed, "%H", httpauth_digest_response_print, resp); if (err) - goto for_out; + goto out; if (str_casecmp(resp->response, testv[i].precalc_digest) != 0) { @@ -637,7 +638,7 @@ int test_httpauth_digest_response(void) " Expected response %s, got %w\n", i, testv[i].precalc_digest, resp->response, resp->hash_length); - goto for_out; + goto out; } if (memcmp(testv[i].resp_hval, @@ -647,14 +648,14 @@ int test_httpauth_digest_response(void) " Expected header %s, got %b\n", i, testv[i].resp_hval, mb_printed->buf, mb_printed->end); - goto for_out; + goto out; } mb_printed = mem_deref (mb_printed); resp = mem_deref(resp); continue; -for_out: +out: mb_printed = mem_deref (mb_printed); resp = mem_deref(resp); break; @@ -662,3 +663,184 @@ int test_httpauth_digest_response(void) return err; } + + +int test_httpauth_digest_verification(void) +{ + static const struct { + const char *realm; + const char *domain; + const char *opaque; + const bool stale; + const char *algorithm; + const char *qop; + const char *charset; + const bool userhash; + + const char *etag; + const char *entitybody; + + const char *user; + const char *passwd; + const char *uri; + const struct pl method; + const char *huser; + } testv [] = { + /* qop=auth & normal algorithm */ + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "MD5", "auth", NULL, false, + "localhost:5060", NULL, "retest", "sec_passwd", + "example.com/my/home/something", PL("GET"), NULL, + }, + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "SHA-256", "auth", NULL, false, + "localhost:5060", NULL, "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + /* qop=auth & session algorithm */ + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "MD5-sess", "auth", NULL, false, + "localhost:5060", NULL, "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "SHA-256-sess", "auth", NULL, false, + "localhost:5060", NULL, "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + /* qop=auth-int & normal algorithm */ + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "MD5", "auth-int", NULL, false, + "localhost:5060", NULL, "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "SHA-256", "auth-int", NULL, false, + "localhost:5060", "Strange body with content", + "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + /* qop=auth-int & session algorithm */ + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "MD5-sess", "auth-int", NULL, false, + "localhost:5060", "NOT NULL", "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + { + "/my/home", "example.com", + "185803523d335c8fe52cf633391d47f7", + false, "SHA-256-sess", "auth-int", NULL, false, + "localhost:5060", "NULL as String :D", + "retest", "sec_passed", + "example.com/my/home/something", PL("GET"), NULL + }, + }; + + int err = 0; + for (size_t i = 0; i < RE_ARRAY_SIZE(testv); i++) { + struct httpauth_digest_chall_req *req = NULL; + struct httpauth_digest_enc_resp *resp = NULL; + struct httpauth_digest_chall chall; + struct mbuf *mb_req = NULL; + struct mbuf *mb_resp = NULL; + struct pl plreq; + struct pl plresp; + + mb_req = mbuf_alloc(512); + mb_resp = mbuf_alloc(512); + if (!mb_req || !mb_resp) { + err = ENOMEM; + DEBUG_WARNING("[%d]" + " Could not allocate memory buffers \n", i); + goto out; + } + + err = httpauth_digest_chall_request_full(&req, testv[i].realm, + testv[i].domain, testv[i].etag, testv[i].opaque, + testv[i].stale, testv[i].algorithm, testv[i].qop, + testv[i].charset, testv[i].userhash); + if (err) { + DEBUG_WARNING("[%d]" + " Could not generate request (%m)\n", i, err); + goto out; + } + + err = mbuf_printf(mb_req, "%H", + httpauth_digest_chall_req_print, req); + if (err) { + DEBUG_WARNING("[%d]" + " Could not write digest request (%m)", + i, err); + goto out; + } + + mbuf_set_pos(mb_req, 0); + pl_set_mbuf(&plreq, mb_req); + err = httpauth_digest_challenge_decode(&chall, &plreq); + if (err) { + DEBUG_WARNING("[%d] Could not" + " decode \"received\" challenge (%m)", + i, err); + goto out; + } + + err = httpauth_digest_response_full(&resp, &chall, + &testv[i].method, testv[i].uri, testv[i].user, + testv[i].passwd, testv[i].qop, testv[i].entitybody, + testv[i].charset, testv[i].userhash); + if (err) { + DEBUG_WARNING("[%d]" + " Could not generate response (%m)\n", i, err); + goto out; + } + + err = mbuf_printf(mb_resp, "%H", + httpauth_digest_response_print, resp); + if (err) { + DEBUG_WARNING("[%d] Could not" + " decode \"received\" response (%m)\n", + i, err); + goto out; + } + + mbuf_set_pos(mb_resp, 0); + pl_set_mbuf(&plresp, mb_resp); + err = httpauth_digest_verify(req, &plresp, + &testv[i].method, testv[i].etag, + testv[i].user, testv[i].passwd, testv[i].entitybody); + if (err) { + DEBUG_WARNING("[%d]" + " Verification failed (%m)\n", i, err); + goto out; + } + + mem_deref(req); + mem_deref(resp); + mem_deref(mb_req); + mem_deref(mb_resp); + continue; + +out: + mem_deref(req); + mem_deref(resp); + mem_deref(mb_req); + mem_deref(mb_resp); + break; + } + + return err; +} diff --git a/test/test.c b/test/test.c index 3597b9742..261c1d96f 100644 --- a/test/test.c +++ b/test/test.c @@ -125,6 +125,7 @@ static const struct test tests[] = { TEST(test_httpauth_basic_request), TEST(test_httpauth_digest_request), TEST(test_httpauth_digest_response), + TEST(test_httpauth_digest_verification), TEST(test_ice_cand), TEST(test_ice_loop), TEST(test_json), diff --git a/test/test.h b/test/test.h index 57817908a..68a681e2c 100644 --- a/test/test.h +++ b/test/test.h @@ -229,6 +229,7 @@ int test_httpauth_resp(void); int test_httpauth_basic_request(void); int test_httpauth_digest_request(void); int test_httpauth_digest_response(void); +int test_httpauth_digest_verification(void); int test_ice_loop(void); int test_ice_cand(void); int test_json(void);