/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */ #include "test-lib.h" #include "test-common.h" #include "array.h" #include "str-sanitize.h" #include "http-auth.h" struct http_auth_challenge_test { const char *scheme; const char *data; struct http_auth_param *params; }; struct http_auth_challenges_test { const char *challenges_in; struct http_auth_challenge_test *challenges; }; /* Valid auth challenges tests */ static const struct http_auth_challenges_test valid_auth_challenges_tests[] = { { .challenges_in = "Basic realm=\"WallyWorld\"", .challenges = (struct http_auth_challenge_test []) { { .scheme = "Basic", .data = NULL, .params = (struct http_auth_param []) { { "realm", "WallyWorld" }, { NULL, NULL } } },{ .scheme = NULL } } },{ .challenges_in = "Digest " "realm=\"testrealm@host.com\", " "qop=\"auth,auth-int\", " "nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", " "opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"", .challenges = (struct http_auth_challenge_test []) { { .scheme = "Digest", .data = NULL, .params = (struct http_auth_param []) { { "realm", "testrealm@host.com" }, { "qop", "auth,auth-int" }, { "nonce", "dcd98b7102dd2f0e8b11d0f600bfb0c093" }, { "opaque", "5ccc069c403ebaf9f0171e9517f40e41" }, { NULL, NULL } } },{ .scheme = NULL } } },{ .challenges_in = "Newauth realm=\"apps\", type=1, " "title=\"Login to \\\"apps\\\"\", Basic realm=\"simple\"", .challenges = (struct http_auth_challenge_test []) { { .scheme = "Newauth", .data = NULL, .params = (struct http_auth_param []) { { "realm", "apps" }, { "type", "1" }, { "title", "Login to \"apps\"" }, { NULL, NULL } } },{ .scheme = "Basic", .data = NULL, .params = (struct http_auth_param []) { { "realm", "simple" }, { NULL, NULL } } },{ .scheme = NULL } } } }; static const unsigned int valid_auth_challenges_test_count = N_ELEMENTS(valid_auth_challenges_tests); static void test_http_auth_challenges_valid(void) { unsigned int i; for (i = 0; i < valid_auth_challenges_test_count; i++) T_BEGIN { const char *challenges_in; ARRAY_TYPE(http_auth_challenge) out; const struct http_auth_challenges_test *test; bool result; test = &valid_auth_challenges_tests[i]; challenges_in = test->challenges_in; test_begin(t_strdup_printf("http auth challenges valid [%d]", i)); i_zero(&out); result = (http_auth_parse_challenges ((const unsigned char *)challenges_in, strlen(challenges_in), &out) > 0); test_out(t_strdup_printf("parse `%s'", challenges_in), result); if (result) { const struct http_auth_challenge *chalo; const struct http_auth_challenge_test *chalt; unsigned int index; index = 0; chalt = test->challenges; array_foreach(&out, chalo) { const struct http_auth_param *paramo, *paramt; unsigned int pindex; if (chalt != NULL && chalt->scheme != NULL) { i_assert(chalo->scheme != NULL); test_out(t_strdup_printf("[%d]->scheme = %s", index, str_sanitize(chalo->scheme, 80)), strcmp(chalo->scheme, chalt->scheme) == 0); if (chalo->data == NULL || chalt->data == NULL) { test_out(t_strdup_printf("[%d]->data = %s", index, str_sanitize(chalo->data, 80)), chalo->data == chalt->data); } else { test_out(t_strdup_printf("[%d]->data = %s", index, str_sanitize(chalo->data, 80)), strcmp(chalo->data, chalt->data) == 0); } paramt = chalt->params; pindex = 0; array_foreach(&chalo->params, paramo) { if (paramt->name == NULL) { test_out(t_strdup_printf("[%d]->params[%d]: %s = %s", index, pindex, str_sanitize(paramo->name, 80), str_sanitize(paramo->value, 80)), FALSE); break; } else { test_out(t_strdup_printf("[%d]->params[%d]: %s = %s", index, pindex, str_sanitize(paramo->name, 80), str_sanitize(paramo->value, 80)), strcmp(paramo->name, paramt->name) == 0 && strcmp(paramo->value, paramt->value) == 0); paramt++; } pindex++; } chalt++; } index++; } } test_end(); } T_END; } struct http_auth_credentials_test { const char *credentials_in; const char *scheme; const char *data; struct http_auth_param *params; }; /* Valid auth credentials tests */ static const struct http_auth_credentials_test valid_auth_credentials_tests[] = { { .credentials_in = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", .scheme = "Basic", .data = "QWxhZGRpbjpvcGVuIHNlc2FtZQ==", .params = NULL },{ .credentials_in = "Digest username=\"Mufasa\", " "realm=\"testrealm@host.com\", " "nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", " "uri=\"/dir/index.html\", " "qop=auth, " "nc=00000001, " "cnonce=\"0a4f113b\", " "response=\"6629fae49393a05397450978507c4ef1\", " "opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"", .scheme = "Digest", .data = NULL, .params = (struct http_auth_param []) { { "username", "Mufasa" }, { "realm", "testrealm@host.com" }, { "nonce", "dcd98b7102dd2f0e8b11d0f600bfb0c093" }, { "uri", "/dir/index.html" }, { "qop", "auth" }, { "nc", "00000001" }, { "cnonce", "0a4f113b" }, { "response", "6629fae49393a05397450978507c4ef1" }, { "opaque", "5ccc069c403ebaf9f0171e9517f40e41" }, { NULL, NULL } } } }; static const unsigned int valid_auth_credentials_test_count = N_ELEMENTS(valid_auth_credentials_tests); static void test_http_auth_credentials_valid(void) { unsigned int i; for (i = 0; i < valid_auth_credentials_test_count; i++) T_BEGIN { const char *credentials_in; struct http_auth_credentials out; const struct http_auth_credentials_test *test; bool result; test = &valid_auth_credentials_tests[i]; credentials_in = test->credentials_in; test_begin(t_strdup_printf("http auth credentials valid [%d]", i)); result = (http_auth_parse_credentials ((const unsigned char *)credentials_in, strlen(credentials_in), &out) > 0); test_out(t_strdup_printf("parse `%s'", credentials_in), result); if (result) { const struct http_auth_param *paramo, *paramt; unsigned int index; i_assert(out.scheme != NULL); test_out(t_strdup_printf("->scheme = %s", str_sanitize(out.scheme, 80)), strcmp(out.scheme, test->scheme) == 0); if (out.data == NULL || test->data == NULL) { test_out(t_strdup_printf("->data = %s", str_sanitize(out.data, 80)), out.data == test->data); } else { test_out(t_strdup_printf("->data = %s", str_sanitize(out.data, 80)), strcmp(out.data, test->data) == 0); } paramt = test->params; index = 0; if (array_is_created(&out.params)) { array_foreach(&out.params, paramo) { if (paramt == NULL || paramt->name == NULL) { test_out(t_strdup_printf("->params[%d]: %s = %s", index++, str_sanitize(paramo->name, 80), str_sanitize(paramo->value, 80)), FALSE); break; } else { test_out(t_strdup_printf("->params[%d]: %s = %s", index++, str_sanitize(paramo->name, 80), str_sanitize(paramo->value, 80)), strcmp(paramo->name, paramt->name) == 0 && strcmp(paramo->value, paramt->value) == 0); paramt++; } } } } test_end(); } T_END; } int main(void) { static void (*const test_functions[])(void) = { test_http_auth_challenges_valid, test_http_auth_credentials_valid, NULL }; return test_run(test_functions); }