mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
The domain was suppressed for any proxy request, but a reverse-proxied request authenticates to this server with an origin-style WWW-Authenticate, so AuthDigestDomain applies to it as it does to a non-proxied request; only a forward-proxy (PROXYREQ_PROXY) request, whose challenge is Proxy-Authenticate, should omit it. * modules/aaa/mod_auth_digest.c (note_digest_auth_failure): Suppress domain= only for PROXYREQ_PROXY, matching the rest of the file. * test/modules/aaa/env.py: Load mod_proxy and mod_proxy_http. * test/modules/aaa/conftest.py: Add a reverse-proxied location which authenticates with Digest and sets AuthDigestDomain. * test/modules/aaa/test_013_proxy_domain.py: New test suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> GitHub: PR #787 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1939035 13f79535-47bb-0310-9956-ffa450edef68
80 lines
3.0 KiB
Python
80 lines
3.0 KiB
Python
import hashlib
|
|
import inspect
|
|
import logging
|
|
import os
|
|
from typing import List, Optional
|
|
|
|
from pyhttpd.env import HttpdTestEnv, HttpdTestSetup
|
|
from pyhttpd.result import ExecResult
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class AAATestSetup(HttpdTestSetup):
|
|
|
|
def __init__(self, env: 'HttpdTestEnv'):
|
|
super().__init__(env=env)
|
|
self.add_source_dir(os.path.dirname(inspect.getfile(AAATestSetup)))
|
|
self.add_modules(["auth_digest", "authn_file", "authn_core",
|
|
"authz_core", "authz_user", "proxy", "proxy_http"])
|
|
|
|
|
|
class AAATestEnv(HttpdTestEnv):
|
|
|
|
REALM = "AAA Digest Realm"
|
|
DIGEST_USER = "digestuser"
|
|
DIGEST_PASSWORD = "digestpass2617"
|
|
DIGEST_USER2 = "otheruser"
|
|
DIGEST_PASSWORD2 = "otherpass2617"
|
|
|
|
def __init__(self, pytestconfig=None):
|
|
super().__init__(pytestconfig=pytestconfig)
|
|
self.add_httpd_log_modules(["auth_digest", "authn_file", "authz_core"])
|
|
self._digest_pwfile = os.path.join(self.server_dir, "digest.passwd")
|
|
|
|
def setup_httpd(self, setup: HttpdTestSetup = None):
|
|
super().setup_httpd(setup=AAATestSetup(env=self))
|
|
self._write_digest_pwfile()
|
|
|
|
def _write_digest_pwfile(self):
|
|
def ha1(user, password):
|
|
return hashlib.md5(
|
|
f"{user}:{self.REALM}:{password}".encode()).hexdigest()
|
|
|
|
with open(self._digest_pwfile, 'w') as fd:
|
|
fd.write(f"{self.DIGEST_USER}:{self.REALM}:"
|
|
f"{ha1(self.DIGEST_USER, self.DIGEST_PASSWORD)}\n")
|
|
fd.write(f"{self.DIGEST_USER2}:{self.REALM}:"
|
|
f"{ha1(self.DIGEST_USER2, self.DIGEST_PASSWORD2)}\n")
|
|
|
|
@property
|
|
def digest_pwfile(self) -> str:
|
|
return self._digest_pwfile
|
|
|
|
def configtest(self, directory_lines: List[str], extra_top_lines: Optional[List[str]] = None
|
|
) -> ExecResult:
|
|
"""Run `httpd -t` against a minimal, standalone config built from the
|
|
already-generated modules.conf plus `directory_lines` wrapped in a
|
|
<Directory> block over the shared docroot. Used to test directives
|
|
that are rejected at config-check time (e.g. AuthDigestQop values
|
|
other than 'auth') without touching the package's running server.
|
|
"""
|
|
conf_path = os.path.join(self.gen_dir, "digest-configtest.conf")
|
|
modules_conf = os.path.join(self.server_conf_dir, "modules.conf")
|
|
lines = [
|
|
f'ServerRoot "{self.server_dir}"',
|
|
f'Include "{modules_conf}"',
|
|
f'DocumentRoot "{self.server_docs_dir}"',
|
|
f'Listen {self.http_port2}',
|
|
]
|
|
if extra_top_lines:
|
|
lines.extend(extra_top_lines)
|
|
lines.append(f'<Directory "{self.server_docs_dir}">')
|
|
lines.extend(f" {l}" for l in directory_lines)
|
|
lines.append('</Directory>')
|
|
with open(conf_path, 'w') as fd:
|
|
fd.write('\n'.join(lines))
|
|
fd.write('\n')
|
|
httpd_bin = os.path.join(self.bin_dir, 'httpd')
|
|
return self.run([httpd_bin, '-t', '-f', conf_path])
|