| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "../httpdunit.h" |
| |
| /* XXX This'll almost certainly cause headaches... Need a better way to test |
| * module helper functions. |
| * |
| * - What if the user doesn't want to, or can't, build mod_auth_digest? |
| * - How do we make sure the Makefile rebuilds us when the module changes? |
| */ |
| #include "../../modules/aaa/mod_auth_digest.c" |
| |
| /* |
| * Test Fixture -- runs once per test |
| */ |
| |
| static apr_pool_t *g_pool; |
| static request_rec *g_request; |
| |
| /* XXX: duplicated from the authn.c tests; find a way to pull this into a helper |
| * library */ |
| static void mod_auth_digest_setup(void) |
| { |
| if (apr_pool_create(&g_pool, NULL) != APR_SUCCESS) { |
| exit(1); |
| } |
| |
| /* Stub out just enough of a request_req to get the tests working. |
| * Unfortunately this couples us to implementation details in the code being |
| * tested, but the logic to get a "real" request_rec requires spinning up |
| * half of the world. */ |
| g_request = apr_pcalloc(g_pool, sizeof(*g_request)); |
| if (!g_request) { |
| exit(1); |
| } |
| |
| g_request->pool = g_pool; |
| g_request->headers_in = apr_table_make(g_pool, 1); |
| |
| if (!g_request->headers_in) { |
| exit(1); |
| } |
| } |
| |
| static void mod_auth_digest_teardown(void) |
| { |
| apr_pool_destroy(g_pool); |
| } |
| |
| /* |
| * get_digest_rec() |
| * |
| * Note that this function is an implementation detail, so the tests might not |
| * have the longest lifetime. |
| */ |
| |
| /* TODO: more functional tests! */ |
| |
| START_TEST(get_digest_rec_uses_empty_string_for_key_without_value) |
| { |
| digest_header_rec resp = { 0 }; |
| apr_table_set(g_request->headers_in, "Authorization", |
| "Digest username=user, nc"); |
| |
| get_digest_rec(g_request, &resp); |
| |
| ck_assert_str_eq(resp.username, "user"); |
| ck_assert_str_eq(resp.nonce_count, ""); |
| } |
| END_TEST |
| |
| /* |
| * Regression test for CVE-2017-9788. Note that it only reliably fails if APR |
| * fills memory with something other than NULL; otherwise you can get false |
| * positives. But it's better than nothing. |
| */ |
| START_TEST(get_digest_rec_does_not_use_uninitialized_memory_for_key_without_value) |
| { |
| digest_header_rec resp = { 0 }; |
| apr_table_set(g_request->headers_in, "Authorization", "Digest nc"); |
| |
| get_digest_rec(g_request, &resp); |
| |
| ck_assert_str_eq(resp.nonce_count, ""); |
| } |
| END_TEST |
| |
| /* |
| * Test Case Boilerplate |
| */ |
| HTTPD_BEGIN_TEST_CASE_WITH_FIXTURE(mod_auth_digest, mod_auth_digest_setup, mod_auth_digest_teardown) |
| #include "test/unit/mod_auth_digest.tests" |
| HTTPD_END_TEST_CASE |