blob: be9b8ba449f41d2827bb57c87d9771f6d86c7672 [file]
import logging
import os
import sys
import pytest
from .env import AAATestEnv
from pyhttpd.conf import HttpdConf
sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
def pytest_report_header(config, start_path):
env = AAATestEnv()
return f"mod_auth_digest [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"
def _digest_dir(docs, path, extra_lines):
lines = [
f'<Directory "{docs}/digest/{path}">',
' AuthType Digest',
f' AuthName "{AAATestEnv.REALM}"',
]
lines.extend(f" {l}" for l in extra_lines)
lines.append(' Require valid-user')
lines.append('</Directory>')
return lines
@pytest.fixture(scope="package")
def env(pytestconfig) -> AAATestEnv:
level = logging.INFO
console = logging.StreamHandler()
console.setLevel(level)
console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
logging.getLogger('').addHandler(console)
logging.getLogger('').setLevel(level=level)
env = AAATestEnv(pytestconfig=pytestconfig)
env.setup_httpd()
env.apache_access_log_clear()
env.httpd_error_log.clear_log()
docs = env.server_docs_dir
pwfile = env.digest_pwfile
conf = HttpdConf(env)
# Pin the client table to its historical size, ~12 entries, rather than
# the current default of ~140: the tests which need an entry to be
# garbage collected (085) drive that by filling the table with bare
# requests, and a table an order of magnitude larger makes them an order
# of magnitude slower for nothing.
conf.add('AuthDigestShmemSize 1000')
conf.add(_digest_dir(docs, "default", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
]))
conf.add(_digest_dir(docs, "nccheck", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNcCheck On',
]))
conf.add(_digest_dir(docs, "nccheck-shortlife", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNcCheck On',
'AuthDigestNonceLifetime 2',
]))
conf.add(_digest_dir(docs, "shortlife", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNonceLifetime 2',
]))
conf.add(_digest_dir(docs, "neverexpire", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNonceLifetime -1',
]))
conf.add(_digest_dir(docs, "onetime", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNonceLifetime 0',
]))
conf.add(_digest_dir(docs, "onetime-nccheck", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNonceLifetime 0',
'AuthDigestNcCheck On',
]))
conf.add(_digest_dir(docs, "domain", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestDomain "/digest/domain/" "https://mirror.example.org/other/"',
]))
# Tracks clients like "nccheck", but with a domain; a client crossing
# between the two is still the same user (test_015).
conf.add(_digest_dir(docs, "nccheck-domain", [
'AuthDigestProvider file',
f'AuthUserFile "{pwfile}"',
'AuthDigestNcCheck On',
'AuthDigestDomain "/digest/nccheck-domain/"',
]))
conf.add(_digest_dir(docs, "noprovider", [
# AuthDigestProvider intentionally omitted: falls back to "file".
f'AuthUserFile "{pwfile}"',
]))
# A request which fails header validation (e.g. no Host on HTTP/1.1)
# is answered before the Digest module's post_read_request runs, so it
# has no per-request Digest record; an ErrorDocument redirecting it into
# a Digest-protected location must not then dereference that record.
# Only configured where that is fixed (r1939032): earlier code does
# dereference the missing record.
if env.httpd_is_at_least("2.5.0"):
conf.add('ErrorDocument 400 /digest/default/secret.txt')
# A reverse-proxied location which authenticates with Digest at the
# proxy (so the backend is never reached and need not be reachable).
# The challenge is an origin-style WWW-Authenticate, so AuthDigestDomain
# applies to it just as for a non-proxied location.
conf.add([
'ProxyPass "/pxdomain/" "http://127.0.0.1:1/unused/"',
'<Location "/pxdomain/">',
' AuthType Digest',
f' AuthName "{AAATestEnv.REALM}"',
' AuthDigestProvider file',
f' AuthUserFile "{pwfile}"',
' AuthDigestDomain "/pxdomain/"',
' Require valid-user',
'</Location>',
])
# A second server with the same realm but its own accounts, on its own
# port so that the main server keeps the rest. The main server's
# <Directory> sections apply here too; this one overrides the password
# file for the nccheck location.
conf.add(f'Listen {env.http_port2}')
conf.start_vhost(domains=[f"aaa2.{env.http_tld}"], port=env.http_port2,
doc_root=docs)
conf.add(_digest_dir(docs, "nccheck", [
'AuthDigestProvider file',
f'AuthUserFile "{env.digest_pwfile2}"',
'AuthDigestNcCheck On',
]))
conf.end_vhost()
conf.install()
assert env.apache_restart() == 0
return env
@pytest.fixture(autouse=True, scope="package")
def _stop_package_scope(env):
yield
assert env.apache_stop() == 0