* finding or making robertc@squid-cache.org--squid/squid--HEAD--3.0--patch-513 * finding or making robertc@squid-cache.org--squid/squid--authentication--3.0--patch-75 * auto-adding robertc@squid-cache.org--squid/squid--authentication--3.0--patch-75 to greedy revision library /home/robertc/arch/revisionlibrary * found immediate ancestor revision in library (robertc@squid-cache.org--squid/squid--authentication--3.0--patch-74) * patching for this revision (robertc@squid-cache.org--squid/squid--authentication--3.0--patch-75) * computing changeset A/ src/tests A/ src/tests/.arch-ids A/ {arch}/squid/squid--authentication A/ {arch}/squid/squid--authentication/squid--authentication--3.0 A/ {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid A/ {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log D src/.arch-ids/auth_modules.sh.id D src/auth_modules.sh A src/.arch-ids/AuthConfig.cc.id A src/.arch-ids/AuthConfig.h.id A src/.arch-ids/AuthScheme.cc.id A src/.arch-ids/AuthScheme.h.id A src/.arch-ids/AuthUser.cc.id A src/.arch-ids/AuthUser.cci.id A src/.arch-ids/AuthUser.h.id A src/AuthConfig.cc A src/AuthConfig.h A src/AuthScheme.cc A src/AuthScheme.h A src/AuthUser.cc A src/AuthUser.cci A src/AuthUser.h A src/auth/basic/.arch-ids/basicScheme.cc.id A src/auth/basic/.arch-ids/basicScheme.h.id A src/auth/basic/basicScheme.cc A src/auth/basic/basicScheme.h A src/auth/digest/.arch-ids/digestScheme.cc.id A src/auth/digest/.arch-ids/digestScheme.h.id A src/auth/digest/digestScheme.cc A src/auth/digest/digestScheme.h A src/auth/ntlm/.arch-ids/ntlmScheme.cc.id A src/auth/ntlm/.arch-ids/ntlmScheme.h.id A src/auth/ntlm/ntlmScheme.cc A src/auth/ntlm/ntlmScheme.h A src/tests/.arch-ids/=id A src/tests/.arch-ids/testAuth.cc.id A src/tests/.arch-ids/testAuth.h.id A src/tests/.arch-ids/testMain.cc.id A src/tests/stub_HttpRequest.cc A src/tests/stub_acl.cc A src/tests/stub_cache_cf.cc A src/tests/stub_cache_manager.cc A src/tests/stub_errorpage.cc A src/tests/stub_helper.cc A src/tests/stub_stat.cc A src/tests/stub_store.cc A src/tests/testAuth.cc A src/tests/testAuth.h A src/tests/testMain.cc A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/base-0 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-1 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-10 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-11 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-12 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-13 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-14 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-15 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-16 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-17 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-18 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-19 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-2 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-20 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-21 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-22 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-23 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-24 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-25 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-26 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-27 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-28 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-29 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-3 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-30 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-31 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-32 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-33 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-34 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-35 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-36 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-37 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-38 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-39 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-4 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-40 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-41 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-42 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-43 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-44 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-45 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-46 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-47 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-48 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-49 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-5 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-50 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-51 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-52 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-53 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-54 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-55 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-56 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-57 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-58 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-59 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-6 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-60 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-61 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-62 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-63 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-64 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-65 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-66 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-67 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-68 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-69 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-7 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-70 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-71 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-72 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-73 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-74 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-75 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-8 A {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-9 M {arch}/=tagging-method M {arch}/squid/squid--HEAD/squid--HEAD--3.0/robertc@squid-cache.org--squid/patch-log/patch-76 M {arch}/squid/squid--comms/squid--comms--3.0/robertc@squid-cache.org--squid/patch-log/patch-1 M src/DelayUser.cc M src/ACLProxyAuth.cc M test-suite/Makefile.am M src/String.cc M src/authenticate.cc M src/cache_cf.cc M src/cbdata.cc M src/client_side.cc M src/external_acl.cc M src/http.cc M src/redirect.cc M src/tools.cc M src/authenticate.h M src/enums.h M src/structs.h M src/typedefs.h M src/Makefile.am M src/auth/basic/auth_basic.cc M src/auth/basic/auth_basic.h M src/auth/digest/auth_digest.cc M src/auth/digest/auth_digest.h M src/auth/ntlm/auth_ntlm.cc M src/auth/ntlm/auth_ntlm.h M configure.in M include/autoconf.h.in M test-suite/mem_node_test.cc M test-suite/test_tools.cc M test-suite/MemPoolTest.cc * changeset report * added directories src/tests src/tests/.arch-ids {arch}/squid/squid--authentication {arch}/squid/squid--authentication/squid--authentication--3.0 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log * removed files src/.arch-ids/auth_modules.sh.id src/auth_modules.sh * added files src/.arch-ids/AuthConfig.cc.id src/.arch-ids/AuthConfig.h.id src/.arch-ids/AuthScheme.cc.id src/.arch-ids/AuthScheme.h.id src/.arch-ids/AuthUser.cc.id src/.arch-ids/AuthUser.cci.id src/.arch-ids/AuthUser.h.id src/AuthConfig.cc src/AuthConfig.h src/AuthScheme.cc src/AuthScheme.h src/AuthUser.cc src/AuthUser.cci src/AuthUser.h src/auth/basic/.arch-ids/basicScheme.cc.id src/auth/basic/.arch-ids/basicScheme.h.id src/auth/basic/basicScheme.cc src/auth/basic/basicScheme.h src/auth/digest/.arch-ids/digestScheme.cc.id src/auth/digest/.arch-ids/digestScheme.h.id src/auth/digest/digestScheme.cc src/auth/digest/digestScheme.h src/auth/ntlm/.arch-ids/ntlmScheme.cc.id src/auth/ntlm/.arch-ids/ntlmScheme.h.id src/auth/ntlm/ntlmScheme.cc src/auth/ntlm/ntlmScheme.h src/tests/.arch-ids/=id src/tests/.arch-ids/testAuth.cc.id src/tests/.arch-ids/testAuth.h.id src/tests/.arch-ids/testMain.cc.id src/tests/stub_HttpRequest.cc src/tests/stub_acl.cc src/tests/stub_cache_cf.cc src/tests/stub_cache_manager.cc src/tests/stub_errorpage.cc src/tests/stub_helper.cc src/tests/stub_stat.cc src/tests/stub_store.cc src/tests/testAuth.cc src/tests/testAuth.h src/tests/testMain.cc {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/base-0 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-1 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-10 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-11 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-12 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-13 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-14 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-15 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-16 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-17 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-18 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-19 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-2 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-20 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-21 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-22 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-23 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-24 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-25 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-26 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-27 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-28 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-29 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-3 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-30 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-31 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-32 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-33 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-34 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-35 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-36 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-37 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-38 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-39 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-4 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-40 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-41 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-42 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-43 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-44 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-45 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-46 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-47 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-48 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-49 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-5 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-50 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-51 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-52 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-53 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-54 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-55 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-56 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-57 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-58 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-59 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-6 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-60 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-61 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-62 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-63 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-64 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-65 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-66 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-67 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-68 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-69 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-7 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-70 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-71 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-72 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-73 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-74 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-75 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-8 {arch}/squid/squid--authentication/squid--authentication--3.0/robertc@squid-cache.org--squid/patch-log/patch-9 * modified files --- orig/configure.in +++ mod/configure.in @@ -1105,9 +1105,14 @@ AUTH_OBJS="auth/lib`echo $AUTH_MODULES|sed -e 's% %.a auth/lib%g'`.a" AUTH_LIBS="`echo $AUTH_OBJS|sed -e 's%auth/%%g'`" fi +AUTH_LINKOBJS= +for module in $AUTH_MODULES; do + AUTH_LINKOBJS="$AUTH_LINKOBJS auth/${module}/${module}Scheme.o" +done AC_SUBST(AUTH_MODULES) -AC_SUBST(AUTH_OBJS) AC_SUBST(AUTH_LIBS) +AC_SUBST(AUTH_LINKOBJS) +AC_SUBST(AUTH_OBJS) dnl Select basic auth scheme helpers to build BASIC_AUTH_HELPERS="" --- orig/include/autoconf.h.in +++ mod/include/autoconf.h.in @@ -110,12 +110,21 @@ */ #undef HAVE_DIRENT_H +/* Define if you have the GNU dld library. */ +#undef HAVE_DLD + +/* Define to 1 if you have the `dlerror' function. */ +#undef HAVE_DLERROR + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `drand48' function. */ #undef HAVE_DRAND48 +/* Define if you have the _dyld_func_lookup function. */ +#undef HAVE_DYLD + /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H @@ -435,6 +444,9 @@ /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID +/* Define if you have the shl_load function. */ +#undef HAVE_SHL_LOAD + /* short is defined in system headers */ #undef HAVE_SHORT --- orig/src/ACLProxyAuth.cc +++ mod/src/ACLProxyAuth.cc @@ -42,6 +42,7 @@ #include "ACLRegexData.h" #include "client_side.h" #include "HttpRequest.h" +#include "AuthUser.h" MemPool (*ACLProxyAuth::Pool)(NULL); void * @@ -216,7 +217,8 @@ int ACLProxyAuth::matchForCache(ACLChecklist *checklist) { - return data->match(authenticateUserRequestUsername(checklist->auth_user_request)); + assert (checklist->auth_user_request); + return data->match(checklist->auth_user_request->username()); } /* aclMatchProxyAuth can return two exit codes: --- orig/src/DelayUser.cc +++ mod/src/DelayUser.cc @@ -41,6 +41,7 @@ #include "squid.h" #include "DelayUser.h" #include "authenticate.h" +#include "AuthUser.h" #include "NullDelayId.h" #include "Store.h" @@ -184,7 +185,7 @@ DelayUserBucket::DelayUserBucket(AuthUser *aUser) : authUser (aUser) { debug (77,3) ("DelayUserBucket::DelayUserBucket\n"); - authenticateAuthUserLock (authUser); + authUser->lock(); } DelayUserBucket::~DelayUserBucket() --- orig/src/Makefile.am +++ mod/src/Makefile.am @@ -22,6 +22,9 @@ SNMPSOURCE = endif +TESTS=$(check_PROGRAMS) +check_PROGRAMS= + DELAY_POOL_ALL_SOURCE = \ CommonPool.h \ CompositePoolNode.h \ @@ -200,8 +203,14 @@ fs/null/StoreFSnull.cc \ fs/ufs/StoreFSufs.cc +all_AUTHMODULES = \ + auth/basic/basicScheme.cc \ + auth/digest/digestScheme.cc \ + auth/ntlm/ntlmScheme.cc + EXTRA_squid_SOURCES = \ $(all_FSMODULES) \ + $(all_AUTHMODULES) \ $(ARP_ACL_ALL_SOURCE) \ $(DELAY_POOL_ALL_SOURCE) \ dns.cc \ @@ -302,6 +311,11 @@ asn.cc \ authenticate.cc \ authenticate.h \ + AuthConfig.cc \ + AuthConfig.h \ + AuthScheme.cc \ + AuthScheme.h \ + AuthUser.cc \ cache_cf.cc \ CacheDigest.cc \ cache_manager.cc \ @@ -471,6 +485,8 @@ $(WIN32SOURCE) noinst_HEADERS = ACLChecklist.cci \ + AuthUser.cci \ + AuthUser.h \ client_side_request.cci \ MemBuf.cci \ MemBuf.h \ @@ -482,7 +498,6 @@ nodist_squid_SOURCES = \ repl_modules.cc \ - auth_modules.cc \ cf_parser.h \ globals.cc \ string_arrays.c @@ -493,6 +508,7 @@ @REPL_OBJS@ \ @STORE_LINKOBJS@ \ @STORE_OBJS@ \ + @AUTH_LINKOBJS@ \ @AUTH_OBJS@ \ @CRYPTLIB@ \ @REGEXLIB@ \ @@ -502,7 +518,10 @@ -lmiscutil \ @XTRA_LIBS@ \ @EPOLL_LIBS@ -squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @STORE_OBJS@ @STORE_LINKOBJS@ +squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @STORE_OBJS@ @STORE_LINKOBJS@ \ + @REPL_OBJS@ \ + @AUTH_LINKOBJS@ \ + @AUTH_OBJS@ unlinkd_SOURCES = unlinkd.cc SquidNew.cc unlinkd_CXXFLAGS = -DUNLINK_DAEMON @@ -540,6 +559,7 @@ $(squid_ACLSOURCES) \ asn.cc \ authenticate.cc \ + AuthUser.cc \ cache_cf.cc \ CacheDigest.cc \ cache_manager.cc \ @@ -677,7 +697,6 @@ ufsdump_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a nodist_ufsdump_SOURCES = \ repl_modules.cc \ - auth_modules.cc \ cf_parser.h \ globals.cc \ string_arrays.c @@ -690,8 +709,7 @@ cf_parser.h \ globals.cc \ string_arrays.c \ - repl_modules.cc \ - auth_modules.cc + repl_modules.cc sysconf_DATA = \ squid.conf.default \ @@ -707,7 +725,6 @@ cf.data.pre \ mk-globals-c.pl \ mk-string-arrays.pl \ - auth_modules.sh \ repl_modules.sh \ mib.txt \ mime.conf.default @@ -786,9 +803,6 @@ repl_modules.cc: repl_modules.sh Makefile $(SHELL) $(srcdir)/repl_modules.sh $(REPL_POLICIES) > repl_modules.cc -auth_modules.cc: auth_modules.sh Makefile - @$(SHELL) $(srcdir)/auth_modules.sh $(AUTH_MODULES) >auth_modules.cc - install-data-local: install-sysconfDATA install-dataDATA @if test -f $(DESTDIR)$(DEFAULT_MIME_TABLE) ; then \ echo "$@ will not overwrite existing $(DESTDIR)$(DEFAULT_MIME_TABLE)" ; \ @@ -817,7 +831,7 @@ # fi DISTCLEANFILES = cf_gen_defines.h cf.data cf_parser.h squid.conf.default \ - globals.cc string_arrays.c repl_modules.cc auth_modules.cc + globals.cc string_arrays.c repl_modules.cc ##install-pinger: ## @f=$(PINGER_EXE); \ @@ -832,3 +846,24 @@ ## $(RM) -f $(libexecdir)/-$$f; \ ## fi +TESTSOURCES=../test-suite/test_tools.cc + +check_PROGRAMS+=tests/testAuth +tests_testAuth_SOURCES= tests/testAuth.cc tests/testMain.cc tests/testAuth.h $(TESTSOURCES) \ + AuthScheme.cc globals.cc authenticate.cc AuthUser.cc AuthConfig.cc \ + tests/stub_acl.cc tests/stub_cache_cf.cc \ + tests/stub_helper.cc cbdata.cc String.cc tests/stub_cache_manager.cc \ + tests/stub_store.cc HttpHeaderTools.cc HttpHeader.cc acl.cc event.cc mem.cc \ + MemBuf.cc HttpHdrContRange.cc Packer.cc ACLChecklist.cc HttpHdrCc.cc HttpHdrSc.cc \ + HttpHdrScTarget.cc url.cc ACLProxyAuth.cc ACLRegexData.cc ACLUserData.cc \ + StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \ + tests/stub_HttpRequest.cc +## acl.cc cache_cf.cc tools.cc \ +## helper.cc String.cc cbdata.cc HttpHeaderTools.cc store.cc cache_manager.cc \ +## HttpHeader.cc url.cc event.cc mem.cc HttpRequest.cc Packer.cc access_log.cc \ +## MemBuf.cc StatHist.cc logfile.cc + +tests_testAuth_LDADD= -L$(top_builddir)/lib -lmiscutil @AUTH_LINKOBJS@ @AUTH_OBJS@ \ + -lmiscutil \ + @SQUID_CPPUNIT_LA@ +tests_testAuth_LDFLAGS = $(LIBADD_DL) --- orig/src/String.cc +++ mod/src/String.cc @@ -267,6 +267,115 @@ #endif +/* TODO: move onto String */ +int +stringHasWhitespace(const char *s) +{ + return strpbrk(s, w_space) != NULL; +} + +/* TODO: move onto String */ +int +stringHasCntl(const char *s) +{ + unsigned char c; + + while ((c = (unsigned char) *s++) != '\0') { + if (c <= 0x1f) + return 1; + + if (c >= 0x7f && c <= 0x9f) + return 1; + } + + return 0; +} + +/* + * Similar to strtok, but has some rudimentary knowledge + * of quoting + */ +char * +strwordtok(char *buf, char **t) +{ + unsigned char *word = NULL; + unsigned char *p = (unsigned char *) buf; + unsigned char *d; + unsigned char ch; + int quoted = 0; + + if (!p) + p = (unsigned char *) *t; + + if (!p) + goto error; + + while (*p && isspace(*p)) + p++; + + if (!*p) + goto error; + + word = d = p; + + while ((ch = *p)) { + switch (ch) { + + case '\\': + p++; + + switch (*p) { + + case 'n': + ch = '\n'; + + break; + + case 'r': + ch = '\r'; + + break; + + default: + ch = *p; + + break; + + } + + *d++ = ch; + + if (ch) + p++; + + break; + + case '"': + quoted = !quoted; + + p++; + + break; + + default: + if (!quoted && isspace(*p)) { + p++; + goto done; + } + + *d++ = *p++; + break; + } + } + +done: + *d++ = '\0'; + +error: + *t = (char *) p; + return (char *) word; +} + #ifndef _USE_INLINE_ #include "String.cci" #endif --- orig/src/auth/basic/auth_basic.cc +++ mod/src/auth/basic/auth_basic.cc @@ -42,6 +42,7 @@ #include "authenticate.h" #include "Store.h" #include "HttpReply.h" +#include "basicScheme.h" static void authenticateStateFree(AuthenticateStateData * r) @@ -52,29 +53,14 @@ /* Basic Scheme */ static HLPCB authenticateBasicHandleReply; -static AUTHSACTIVE authenticateBasicActive; -static AUTHSAUTHED authenticateBasicAuthenticated; -static AUTHSAUTHUSER authenticateBasicAuthenticateUser; -static AUTHSCONFIGURED authBasicConfigured; -static AUTHSDIRECTION authenticateBasicDirection; -static AUTHSDECODE authenticateBasicDecodeAuth; -static AUTHSDUMP authBasicCfgDump; -static AUTHSFIXERR authenticateBasicFixErrorHeader; -static AUTHSFREE authenticateBasicFreeUser; -static AUTHSFREECONFIG authBasicFreeConfig; -static AUTHSPARSE authBasicParse; -static AUTHSINIT authBasicInit; static AUTHSSTART authenticateBasicStart; static AUTHSSTATS authenticateBasicStats; -static AUTHSUSERNAME authenticateBasicUsername; -static AUTHSSHUTDOWN authBasicDone; static helper *basicauthenticators = NULL; -static auth_basic_config *basicConfig = NULL; +static AuthBasicConfig basicConfig; static int authbasic_initialised = 0; -MemPool *basic_data_pool = NULL; /* @@ -83,37 +69,23 @@ * */ -AUTHSSETUP authSchemeSetup_basic; - +/* TODO: move to basicScheme.cc - after all per request and user functions are moved out */ void -authSchemeSetup_basic(authscheme_entry_t * authscheme) +basicScheme::setup(authscheme_entry_t * authscheme) { assert(!authbasic_initialised); - authscheme->Active = authenticateBasicActive; - authscheme->parse = authBasicParse; - authscheme->dump = authBasicCfgDump; - authscheme->init = authBasicInit; - authscheme->authAuthenticate = authenticateBasicAuthenticateUser; - authscheme->authenticated = authenticateBasicAuthenticated; - authscheme->configured = authBasicConfigured; - authscheme->authFixHeader = authenticateBasicFixErrorHeader; - authscheme->FreeUser = authenticateBasicFreeUser; - authscheme->freeconfig = authBasicFreeConfig; authscheme->authStart = authenticateBasicStart; - authscheme->authStats = authenticateBasicStats; - authscheme->authUserUsername = authenticateBasicUsername; - authscheme->getdirection = authenticateBasicDirection; authscheme->oncloseconnection = NULL; - authscheme->decodeauth = authenticateBasicDecodeAuth; - authscheme->donefunc = authBasicDone; authscheme->authConnLastHeader = NULL; } /* internal functions */ -static void -authBasicDone(void) +/* TODO: move to basicScheme.cc - after all per request and user functions are moved out */ +void +basicScheme::done() { + /* TODO: this should be a Config call. */ if (basicauthenticators) helperShutdown(basicauthenticators); @@ -127,72 +99,86 @@ basicauthenticators = NULL; -#if DEBUGSHUTDOWN - - if (basic_data_pool) { - memPoolDestroy(&basic_data_pool); - basic_data_pool = NULL; - } - -#endif + /* XXX Reinstate auth shutdown for dynamic schemes? */ debug(29, 2) ("authBasicDone: Basic authentication Shutdown.\n"); } -static int -authenticateBasicActive() +bool +AuthBasicConfig::active() const { - return (authbasic_initialised == 1) ? 1 : 0; + return authbasic_initialised == 1; } -static int -authBasicConfigured() +bool +AuthBasicConfig::configured() const { - if ((basicConfig != NULL) && (basicConfig->authenticate != NULL) && - (basicConfig->authenticateChildren != 0) && - (basicConfig->basicAuthRealm != NULL)) { + if ((authenticate != NULL) && (authenticateChildren != 0) && + (basicAuthRealm != NULL)) { debug(29, 9) ("authBasicConfigured: returning configured\n"); - return 1; + return true; } debug(29, 9) ("authBasicConfigured: returning unconfigured\n"); - return 0; + return false; } -static int -authenticateBasicAuthenticated(auth_user_request_t * auth_user_request) +const char * +AuthBasicConfig::type() const { - basic_data *basic_auth = static_cast(auth_user_request->auth_user->scheme_data); + return basicScheme::GetInstance().type(); +} - if ((basic_auth->flags.credentials_ok == 1) && (basic_auth->credentials_checkedtime + basicConfig->credentialsTTL > squid_curtime)) - return 1; +MemPool (*BasicRequestState::Pool)(NULL); +void * +BasicRequestState::operator new (size_t byteCount) +{ + /* derived classes with different sizes must implement their own new */ + assert (byteCount == sizeof (BasicRequestState)); - debug(29, 4) ("User not authenticated or credentials need rechecking.\n"); + if (!Pool) + Pool = memPoolCreate("BasicRequestState", sizeof (BasicRequestState)); - return 0; + return memPoolAlloc(Pool); } -#if UNUSED_CODE -static int -authenticateBasiccmpUsername(basic_data * u1, basic_data * u2) +void +BasicRequestState::operator delete (void *address) { - return strcmp(u1->username, u2->username); + memPoolFree (Pool, address); } -#endif + +bool +BasicUser::authenticated() const +{ + if ((flags.credentials_ok == 1) && (credentials_checkedtime + basicConfig.credentialsTTL > squid_curtime)) + return true; + + debug(29, 4) ("User not authenticated or credentials need rechecking.\n"); + + return false; +} + +int +BasicRequestState::authenticated() const +{ + basic_data *basic_auth = theUser; + assert (theUser); + + if (basic_auth->authenticated()) + return 1; + + return 0; +} /* log a basic user in */ -static void -authenticateBasicAuthenticateUser(auth_user_request_t * auth_user_request, HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) +void +BasicRequestState::authenticate(auth_user_request_t * auth_user_request,HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) { - auth_user_t *auth_user; - basic_data *basic_auth; + assert(theUser != NULL); - assert(auth_user_request->auth_user != NULL); - auth_user = auth_user_request->auth_user; - - assert(auth_user->scheme_data != NULL); - basic_auth = static_cast(auth_user->scheme_data); + basic_data *basic_auth = theUser; /* if the password is not ok, do an identity */ @@ -200,28 +186,28 @@ return; /* are we about to recheck the credentials externally? */ - if ((basic_auth->credentials_checkedtime + basicConfig->credentialsTTL) <= squid_curtime) { + if ((basic_auth->credentials_checkedtime + basicConfig.credentialsTTL) <= squid_curtime) { debug(29, 4) ("authBasicAuthenticate: credentials expired - rechecking\n"); return; } /* we have been through the external helper, and the credentials haven't expired */ debug(29, 9) ("authenticateBasicAuthenticateuser: user '%s' authenticated\n", - basic_auth->username); + basic_auth->username()); - /* Decode now takes care of finding the auth_user struct in the cache */ + /* Decode now takes care of finding the AuthUser struct in the cache */ /* after external auth occurs anyway */ - auth_user->expiretime = current_time.tv_sec; + basic_auth->expiretime = current_time.tv_sec; return; } int -authenticateBasicDirection(auth_user_request_t * auth_user_request) +BasicRequestState::direction() { /* null auth_user is checked for by authenticateDirection */ - auth_user_t *auth_user = auth_user_request->auth_user; - basic_data *basic_auth = static_cast(auth_user->scheme_data); + basic_data *basic_auth = theUser; + assert (basic_auth); switch (basic_auth->flags.credentials_ok) { @@ -230,7 +216,7 @@ case 1: /* checked & ok */ - if (basic_auth->credentials_checkedtime + basicConfig->credentialsTTL <= squid_curtime) + if (basic_auth->credentials_checkedtime + basicConfig.credentialsTTL <= squid_curtime) return -1; return 0; @@ -246,49 +232,31 @@ } void -authenticateBasicFixErrorHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, HttpRequest * request) +AuthBasicConfig::fixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, HttpRequest * request) { - if (basicConfig->authenticate) { - debug(29, 9) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n", type, basicConfig->basicAuthRealm); - httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", basicConfig->basicAuthRealm); + if (authenticate) { + debug(29, 9) ("authenticateFixErrorHeader: Sending type:%d header: 'Basic realm=\"%s\"'\n", type, basicAuthRealm); + httpHeaderPutStrf(&rep->header, type, "Basic realm=\"%s\"", basicAuthRealm); } } /* free any allocated configuration details */ void -authBasicFreeConfig(authScheme * scheme) +AuthBasicConfig::done() { - if (basicConfig == NULL) - return; - - assert(basicConfig == scheme->scheme_data); - - if (basicConfig->authenticate) - wordlistDestroy(&basicConfig->authenticate); - - if (basicConfig->basicAuthRealm) - safe_free(basicConfig->basicAuthRealm); - - xfree(basicConfig); + if (authenticate) + wordlistDestroy(&authenticate); - basicConfig = NULL; + if (basicAuthRealm) + safe_free(basicAuthRealm); } -void -authenticateBasicFreeUser(auth_user_t * auth_user) +BasicUser::~BasicUser() { - basic_data *basic_auth = static_cast(auth_user->scheme_data); - debug(29, 5) ("authenticateBasicFreeUser: Clearing Basic scheme data\n"); - - if (basic_auth->username) - xfree(basic_auth->username); - - if (basic_auth->passwd) - xfree(basic_auth->passwd); + if (passwd) + xfree(passwd); - memPoolFree(basic_data_pool, auth_user->scheme_data); - - auth_user->scheme_data = NULL; + safe_free (cleartext); } static void @@ -341,11 +309,10 @@ authenticateStateFree(r); } -static void -authBasicCfgDump(StoreEntry * entry, const char *name, authScheme * scheme) +void +AuthBasicConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme) { - auth_basic_config *config = static_cast(scheme->scheme_data); - wordlist *list = config->authenticate; + wordlist *list = authenticate; storeAppendPrintf(entry, "%s %s", name, "basic"); while (list != NULL) { @@ -355,43 +322,38 @@ storeAppendPrintf(entry, "\n"); - storeAppendPrintf(entry, "%s basic realm %s\n", name, config->basicAuthRealm); - storeAppendPrintf(entry, "%s basic children %d\n", name, config->authenticateChildren); - storeAppendPrintf(entry, "%s basic concurrency %d\n", name, config->authenticateConcurrency); - storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) config->credentialsTTL); + storeAppendPrintf(entry, "%s basic realm %s\n", name, basicAuthRealm); + storeAppendPrintf(entry, "%s basic children %d\n", name, authenticateChildren); + storeAppendPrintf(entry, "%s basic concurrency %d\n", name, authenticateConcurrency); + storeAppendPrintf(entry, "%s basic credentialsttl %d seconds\n", name, (int) credentialsTTL); } -static void -authBasicParse(authScheme * scheme, int n_configured, char *param_str) +AuthBasicConfig::AuthBasicConfig() { - if (scheme->scheme_data == NULL) { - assert(basicConfig == NULL); - /* this is the first param to be found */ - scheme->scheme_data = xmalloc(sizeof(auth_basic_config)); - memset(scheme->scheme_data, 0, sizeof(auth_basic_config)); - basicConfig = static_cast(scheme->scheme_data); - basicConfig->authenticateChildren = 5; - basicConfig->credentialsTTL = 2 * 60 * 60; /* two hours */ - } - - basicConfig = static_cast(scheme->scheme_data); + /* TODO: move into initialisation list */ + authenticateChildren = 5; + credentialsTTL = 2 * 60 * 60; /* two hours */ +} +void +AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) +{ if (strcasecmp(param_str, "program") == 0) { - if (basicConfig->authenticate) - wordlistDestroy(&basicConfig->authenticate); + if (authenticate) + wordlistDestroy(&authenticate); - parse_wordlist(&basicConfig->authenticate); + parse_wordlist(&authenticate); - requirePathnameExists("authparam basic program", basicConfig->authenticate->key); + requirePathnameExists("authparam basic program", authenticate->key); } else if (strcasecmp(param_str, "children") == 0) { - parse_int(&basicConfig->authenticateChildren); + parse_int(&authenticateChildren); } else if (strcasecmp(param_str, "concurrency") == 0) { - parse_int(&basicConfig->authenticateConcurrency); + parse_int(&authenticateConcurrency); } else if (strcasecmp(param_str, "realm") == 0) { - parse_eol(&basicConfig->basicAuthRealm); + parse_eol(&basicAuthRealm); } else if (strcasecmp(param_str, "credentialsttl") == 0) { - parse_time_t(&basicConfig->credentialsTTL); + parse_time_t(&credentialsTTL); } else { debug(28, 0) ("unrecognised basic auth scheme parameter '%s'\n", param_str); } @@ -406,37 +368,6 @@ CBDATA_TYPE(AuthenticateStateData); -/* authenticateBasicUsername: return a pointer to the username in the */ -char const * -authenticateBasicUsername(auth_user_t const * auth_user) -{ - basic_data *basic_auth = static_cast(auth_user->scheme_data); - - if (basic_auth) - return basic_auth->username; - - return NULL; -} - -static basic_data * -authBasicDataNew(void) -{ - basic_data *temp; - temp = static_cast(memPoolAlloc(basic_data_pool)); - assert(temp != NULL); - temp->username = NULL; - temp->passwd = NULL; - temp->auth_queue = NULL; - return temp; -} - -#if UNUSED_CODE -static void -authBasicDataFree(basic_data * basic_auth) -{} - -#endif - static auth_user_t * authBasicAuthUserFindUsername(const char *username) { @@ -456,46 +387,53 @@ return NULL; } +MemPool *BasicUser::Pool (NULL); +void +BasicUser::deleteSelf() const +{ + delete this; +} - -/* - * Decode a Basic [Proxy-]Auth string, linking the passed auth_user_request structure - * to any existing user structure or creating one if needed. Note that just returning - * will be treated as "cannot decode credentials". Use the message field to return a - * descriptive message to the user. - */ - -static void -authenticateBasicDecodeAuth(auth_user_request_t * auth_user_request, const char *proxy_auth) +void * +BasicUser::operator new(size_t byteCount) { - char *sent_auth; - char *cleartext; - basic_data *basic_auth, local_basic; - auth_user_t *auth_user; - dlink_node *node; + /* derived classes with different sizes must implement their own new */ + assert (byteCount == sizeof (BasicUser)); - /* decode the username */ - /* trim BASIC from string */ + if (!Pool) + Pool = memPoolCreate("Authenticate Basic User Data", sizeof (BasicUser)); - while (!xisspace(*proxy_auth)) - proxy_auth++; + return memPoolAlloc(Pool); +} - local_basic.passwd = NULL; +void +BasicUser::operator delete (void *address) +{ + memPoolFree(Pool, address); +} - /* Trim leading whitespace before decoding */ - while (xisspace(*proxy_auth)) - proxy_auth++; +BasicUser::BasicUser(AuthConfig *config) : AuthUser (config) , passwd (NULL), credentials_checkedtime(0), auth_queue(NULL), cleartext (NULL), currentRequest (NULL), httpAuthHeader (NULL) +{ + flags.credentials_ok = 0; +} +void +BasicUser::decodeCleartext() +{ + char *sent_auth; /* username and password */ - sent_auth = xstrdup(proxy_auth); - + sent_auth = xstrdup(httpAuthHeader); /* Trim trailing \n before decoding */ strtok(sent_auth, "\n"); cleartext = uudecode(sent_auth); xfree(sent_auth); +} +void +BasicUser::extractUsername() +{ /* * Don't allow NL or CR in the credentials. * Oezguer Kesim @@ -504,133 +442,208 @@ debug(29, 9) ("authenticateBasicDecodeAuth: cleartext = '%s'\n", cleartext); - local_basic.username = xstrndup(cleartext, USER_IDENT_SZ); - + username(xstrndup(cleartext, USER_IDENT_SZ)); xfree(cleartext); + /* terminate the username string */ - if ((cleartext = strchr(local_basic.username, ':')) != NULL) + if ((cleartext = strchr(username(), ':')) != NULL) *(cleartext)++ = '\0'; +} - local_basic.passwd = cleartext; +void +BasicUser::extractPassword() +{ + passwd = cleartext; if (cleartext == NULL) { debug(29, 4) ("authenticateBasicDecodeAuth: no password in proxy authorization header '%s'\n", - proxy_auth); - local_basic.passwd = NULL; - authenticateSetDenyMessage (auth_user_request, "no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug"); + httpAuthHeader); + passwd = NULL; + authenticateSetDenyMessage (currentRequest, "no password was present in the HTTP [proxy-]authorization header. This is most likely a browser bug"); } else if (*cleartext == '\0') { debug(29, 4) ("authenticateBasicDecodeAuth: Disallowing empty password," - "user is '%s'\n", local_basic.username); - local_basic.passwd = NULL; - authenticateSetDenyMessage (auth_user_request, "Request denied because you provided an empty password. Users MUST have a password."); + "user is '%s'\n", username()); + passwd = NULL; + authenticateSetDenyMessage (currentRequest, "Request denied because you provided an empty password. Users MUST have a password."); } - /* special case: we have to free the strings for user and password - * if we are not returning a filled out structure - */ - if (local_basic.passwd == NULL) { - if (local_basic.username) { - /* log the username */ - debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", local_basic.username); - /* new auth_user */ - auth_user = authenticateAuthUserNew("basic"); - /* new scheme data */ - basic_auth = authBasicDataNew(); - /* save the credentials */ - basic_auth->username = local_basic.username; - /* link the scheme data in */ - auth_user->scheme_data = basic_auth; - /* set the auth_user type */ - auth_user->auth_type = AUTH_BROKEN; - /* link the request to the user */ - auth_user_request->auth_user = auth_user; - /* lock for the auth_user_request link */ - authenticateAuthUserLock(auth_user); - node = dlinkNodeNew(); - dlinkAdd(auth_user_request, node, &auth_user->requests); - } + if (passwd) + passwd = xstrndup(cleartext, USER_IDENT_SZ); - return; - } else { - local_basic.passwd = xstrndup(cleartext, USER_IDENT_SZ); - } + cleartext = NULL; +} - /* now lookup and see if we have a matching auth_user structure in memory. */ +void +BasicUser::decode(char const *proxy_auth, AuthUserRequest *auth_user_request) +{ + currentRequest = auth_user_request; + httpAuthHeader = proxy_auth; + decodeCleartext (); + extractUsername(); + extractPassword(); + currentRequest = NULL; + httpAuthHeader = NULL; +} - if ((auth_user = authBasicAuthUserFindUsername(local_basic.username)) == NULL) { - /* the user doesn't exist in the username cache yet */ - debug(29, 9) ("authBasicDecodeAuth: Creating new user '%s'\n", local_basic.username); - /* new auth_user */ - auth_user = authenticateAuthUserNew("basic"); +bool +BasicUser::valid() const +{ + return passwd != NULL; +} + +void +BasicUser::makeLoggingInstance(AuthUserRequest *auth_user_request) +{ + if (username()) { + /* log the username */ + debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", username()); /* new scheme data */ - basic_auth = authBasicDataNew(); + BasicUser *basic_auth = new BasicUser(& basicConfig); + /* auth_user is a parent */ + AuthUser *auth_user = dynamic_cast(basic_auth); + assert (auth_user); /* save the credentials */ - basic_auth->username = local_basic.username; - basic_auth->passwd = local_basic.passwd; + basic_auth->username(username()); + username(NULL); /* link the scheme data in */ auth_user->scheme_data = basic_auth; /* set the auth_user type */ - auth_user->auth_type = AUTH_BASIC; - /* current time for timeouts */ - auth_user->expiretime = current_time.tv_sec; - - /* this auth_user struct is the 'lucky one' to get added to the username cache */ - /* the requests after this link to the auth_user */ - /* store user in hash */ - authenticateUserNameCacheAdd(auth_user); + auth_user->auth_type = AUTH_BROKEN; + /* link the request to the user */ + auth_user_request->auth_user = auth_user; + auth_user->addRequest(auth_user_request); + } +} + +AuthUser * +BasicUser::makeCachedFrom() +{ + /* the user doesn't exist in the username cache yet */ + debug(29, 9) ("authBasicDecodeAuth: Creating new user '%s'\n", username()); + /* new scheme data */ + BasicUser *basic_auth = new BasicUser(&basicConfig); + /* auth_user is a parent */ + AuthUser *auth_user = dynamic_cast(basic_auth); + assert (auth_user); + /* save the credentials */ + basic_auth->username(username()); + username(NULL); + basic_auth->passwd = passwd; + passwd = NULL; + /* link the scheme data in */ + auth_user->scheme_data = basic_auth; + /* set the auth_user type */ + auth_user->auth_type = AUTH_BASIC; + /* current time for timeouts */ + auth_user->expiretime = current_time.tv_sec; + + /* this auth_user struct is the 'lucky one' to get added to the username cache */ + /* the requests after this link to the auth_user */ + /* store user in hash */ + authenticateUserNameCacheAdd(auth_user); + return auth_user; +} + +void +BasicUser::updateCached(BasicUser *from) +{ + debug(29, 9) ("authBasicDecodeAuth: Found user '%s' in the user cache as '%p'\n", from->username(), this); + + if (strcmp(from->passwd, passwd)) { + debug(29, 4) ("authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked\n"); + flags.credentials_ok = 0; + xfree(passwd); + passwd = from->passwd; + from->passwd = NULL; + } + + if (flags.credentials_ok == 3) { + debug(29, 4) ("authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked\n"); + flags.credentials_ok = 0; + } +} + +/* + * Decode a Basic [Proxy-]Auth string, linking the passed + * auth_user_request structure to any existing user structure or creating one + * if needed. Note that just returning will be treated as + * "cannot decode credentials". Use the message field to return a + * descriptive message to the user. + */ +AuthUserRequest * +AuthBasicConfig::decode(char const *proxy_auth) +{ + AuthUserRequest *auth_user_request = new AuthUserRequest; + /* decode the username */ + /* trim BASIC from string */ + + while (!xisspace(*proxy_auth)) + proxy_auth++; + + BasicUser *basic_auth, local_basic(&basicConfig); + + auth_user_t *auth_user; + + /* Trim leading whitespace before decoding */ + while (xisspace(*proxy_auth)) + proxy_auth++; + + local_basic.decode(proxy_auth, auth_user_request); + + if (!local_basic.valid()) { + local_basic.makeLoggingInstance(auth_user_request); + return auth_user_request; + } + + /* now lookup and see if we have a matching auth_user structure in + * memory. */ + + if ((auth_user = authBasicAuthUserFindUsername(local_basic.username())) == NULL) { + auth_user = local_basic.makeCachedFrom(); + basic_auth = dynamic_cast(auth_user); + assert (basic_auth); } else { - debug(29, 9) ("authBasicDecodeAuth: Found user '%s' in the user cache as '%p'\n", local_basic.username, auth_user); - xfree(local_basic.username); - basic_auth = static_cast(auth_user->scheme_data); - - if (strcmp(local_basic.passwd, basic_auth->passwd)) { - debug(29, 4) ("authBasicDecodeAuth: new password found. Updating in user master record and resetting auth state to unchecked\n"); - basic_auth->flags.credentials_ok = 0; - xfree(basic_auth->passwd); - basic_auth->passwd = local_basic.passwd; - } else - xfree(local_basic.passwd); - - if (basic_auth->flags.credentials_ok == 3) { - debug(29, 4) ("authBasicDecodeAuth: last attempt to authenticate this user failed, resetting auth state to unchecked\n"); - basic_auth->flags.credentials_ok = 0; - } + basic_auth = dynamic_cast(auth_user); + assert (basic_auth); + basic_auth->updateCached (&local_basic); } - /* link the request to the user */ + /* link the request to the in-cache user */ auth_user_request->auth_user = auth_user; - /* lock for the auth_user_request link */ - authenticateAuthUserLock(auth_user); + BasicRequestState * basic_request = new BasicRequestState(basic_auth); - node = dlinkNodeNew(); + auth_user_request->state(basic_request); - dlinkAdd(auth_user_request, node, &auth_user->requests); + auth_user->addRequest(auth_user_request); - return; + return auth_user_request; } +BasicRequestState::~BasicRequestState() +{} + +BasicRequestState::BasicRequestState(BasicUser *aUser) : theUser (aUser) +{} + /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */ -static void -authBasicInit(authScheme * scheme) +void +AuthBasicConfig::init(AuthConfig * scheme) { static int init = 0; - if (basicConfig->authenticate) { - if (!basic_data_pool) - basic_data_pool = memPoolCreate("Basic Scheme User Data", sizeof(basic_data)); - + if (authenticate) { authbasic_initialised = 1; if (basicauthenticators == NULL) basicauthenticators = helperCreate("basicauthenticator"); - basicauthenticators->cmdline = basicConfig->authenticate; + basicauthenticators->cmdline = authenticate; - basicauthenticators->n_to_start = basicConfig->authenticateChildren; + basicauthenticators->n_to_start = authenticateChildren; - basicauthenticators->concurrency = basicConfig->authenticateConcurrency; + basicauthenticators->concurrency = authenticateConcurrency; basicauthenticators->ipc_type = IPC_STREAM; @@ -647,23 +660,34 @@ } } +void +BasicUser::queueRequest(auth_user_request_t * auth_user_request, RH * handler, void *data) +{ + BasicAuthQueueNode *node; + node = static_cast(xmalloc(sizeof(BasicAuthQueueNode))); + assert(node); + /* save the details */ + node->next = auth_queue; + auth_queue = node; + node->auth_user_request = auth_user_request; + node->handler = handler; + node->data = cbdataReference(data); +} + /* send the initial data to a basic authenticator module */ static void authenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, void *data) { - AuthenticateStateData *r = NULL; - char buf[8192]; - char user[1024], pass[1024]; basic_data *basic_auth; assert(auth_user_request); assert(handler); assert(auth_user_request->auth_user->auth_type == AUTH_BASIC); assert(auth_user_request->auth_user->scheme_data != NULL); basic_auth = static_cast(auth_user_request->auth_user->scheme_data); - debug(29, 9) ("authenticateStart: '%s:%s'\n", basic_auth->username, + debug(29, 9) ("authenticateStart: '%s:%s'\n", basic_auth->username(), basic_auth->passwd); - if (basicConfig->authenticate == NULL) { + if (basicConfig.authenticate == NULL) { handler(data, NULL); return; } @@ -671,26 +695,34 @@ /* check to see if the auth_user already has a request outstanding */ if (basic_auth->flags.credentials_ok == 2) { /* there is a request with the same credentials already being verified */ - BasicAuthQueueNode *node; - node = static_cast(xmalloc(sizeof(BasicAuthQueueNode))); - assert(node); - /* save the details */ - node->next = basic_auth->auth_queue; - basic_auth->auth_queue = node; - node->auth_user_request = auth_user_request; - node->handler = handler; - node->data = cbdataReference(data); + basic_auth->queueRequest(auth_user_request, handler, data); return; - } else { - r = cbdataAlloc(AuthenticateStateData); - r->handler = handler; - r->data = cbdataReference(data); - r->auth_user_request = auth_user_request; - /* mark the user as haveing verification in progress */ - basic_auth->flags.credentials_ok = 2; - xstrncpy(user, rfc1738_escape(basic_auth->username), sizeof(user)); - xstrncpy(pass, rfc1738_escape(basic_auth->passwd), sizeof(pass)); - snprintf(buf, sizeof(buf), "%s %s\n", user, pass); - helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); } + + basic_auth->submitRequest (auth_user_request, handler, data); } + +void +BasicUser::submitRequest (auth_user_request_t * auth_user_request, RH * handler, void *data) +{ + /* mark the user as haveing verification in progress */ + flags.credentials_ok = 2; + AuthenticateStateData *r = NULL; + char buf[8192]; + char user[1024], pass[1024]; + r = cbdataAlloc(AuthenticateStateData); + r->handler = handler; + r->data = cbdataReference(data); + r->auth_user_request = auth_user_request; + xstrncpy(user, rfc1738_escape(username()), sizeof(user)); + xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass)); + snprintf(buf, sizeof(buf), "%s %s\n", user, pass); + helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); +} + +AuthConfig * +basicScheme::createConfig() +{ + return &basicConfig; +} + --- orig/src/auth/basic/auth_basic.h +++ mod/src/auth/basic/auth_basic.h @@ -6,6 +6,8 @@ #ifndef __AUTH_BASIC_H__ #define __AUTH_BASIC_H__ #include "authenticate.h" +#include "AuthUser.h" +#include "AuthConfig.h" #define DefaultAuthenticateChildrenMax 32 /* 32 processes */ @@ -32,11 +34,44 @@ void *data; }; -class basic_data +class BasicUser; + +/* follows the http request around */ +class BasicRequestState : public AuthUserRequestState { +public: + void *operator new (size_t); + void operator delete (void *); + virtual ~BasicRequestState(); + BasicRequestState(BasicUser *); + + virtual int authenticated() const; + virtual void authenticate(auth_user_request_t * auth_user_request,HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type); + virtual int direction(); + + BasicUser *theUser; +private: + static MemPool *Pool; +}; + +class BasicUser : public AuthUser +{ public: - char *username; + virtual void deleteSelf() const; + void *operator new(size_t); + void operator delete (void *); + BasicUser(AuthConfig *); + ~BasicUser(); + bool authenticated() const; + void queueRequest(auth_user_request_t * auth_user_request, RH * handler, void *data); + void submitRequest (auth_user_request_t * auth_user_request, RH * handler, void *data); + void decode(char const *credentials, AuthUserRequest *); + char *getCleartext() {return cleartext;} + bool valid() const; + void makeLoggingInstance(AuthUserRequest *auth_user_request); + AuthUser * makeCachedFrom(); + void updateCached(BasicUser *from); char *passwd; time_t credentials_checkedtime; @@ -49,14 +84,33 @@ flags; BasicAuthQueueNode *auth_queue; +private: + static MemPool *Pool; + void decodeCleartext(); + void extractUsername(); + void extractPassword(); + char *cleartext; + AuthUserRequest *currentRequest; + char const *httpAuthHeader; }; +typedef class BasicUser basic_data; /* configuration runtime data */ -class auth_basic_config +class AuthBasicConfig : public AuthConfig { public: + AuthBasicConfig::AuthBasicConfig(); + virtual bool active() const; + virtual bool configured() const; + virtual AuthUserRequest *decode(char const *proxy_auth); + virtual void done(); + virtual void dump(StoreEntry *, const char *, AuthConfig *); + virtual void fixHeader(auth_user_request_t *, HttpReply *, http_hdr_type, HttpRequest *); + virtual void init(AuthConfig *); + virtual void parse(AuthConfig *, int, char *); + virtual const char * type() const; int authenticateChildren; int authenticateConcurrency; char *basicAuthRealm; --- orig/src/auth/digest/auth_digest.cc +++ mod/src/auth/digest/auth_digest.cc @@ -45,34 +45,23 @@ #include "Store.h" #include "HttpRequest.h" #include "HttpReply.h" - -extern AUTHSSETUP authSchemeSetup_digest; +/* TODO don't include this */ +#include "digestScheme.h" /* Digest Scheme */ static HLPCB authenticateDigestHandleReply; -static AUTHSACTIVE authenticateDigestActive; #if WAITING_FOR_TE static AUTHSADDTRAILER authDigestAddTrailer; #endif -static AUTHSCONFIGURED authDigestConfigured; -static AUTHSDECODE authenticateDigestDecodeAuth; -static AUTHSDUMP authDigestCfgDump; -static AUTHSFIXERR authenticateDigestFixHeader; -static AUTHSFREE authenticateDigestUserFree; -static AUTHSFREECONFIG authDigestFreeConfig; -static AUTHSINIT authDigestInit; -static AUTHSPARSE authDigestParse; static AUTHSSTART authenticateDigestStart; static AUTHSSTATS authenticateDigestStats; -static AUTHSUSERNAME authenticateDigestUsername; -static AUTHSSHUTDOWN authDigestDone; static helper *digestauthenticators = NULL; static hash_table *digest_nonce_cache; -static auth_digest_config *digestConfig = NULL; +static AuthDigestConfig digestConfig; static int authdigest_initialised = 0; static MemPool *digest_nonce_pool = NULL; @@ -218,7 +207,7 @@ if (!digest_nonce_cache) { digest_nonce_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); assert(digest_nonce_cache); - eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval, 1); + eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig.nonceGCInterval, 1); } } @@ -285,8 +274,8 @@ debug(29, 3) ("authenticateDigestNonceCacheCleanup: Finished cleaning the nonce cache.\n"); - if (authenticateDigestActive()) - eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig->nonceGCInterval, 1); + if (digestConfig.active()) + eventAdd("Digest none cache maintenance", authenticateDigestNonceCacheCleanup, NULL, digestConfig.nonceGCInterval, 1); } static void @@ -373,12 +362,12 @@ } /* is the nonce-count ok ? */ - if (!digestConfig->CheckNonceCount) { + if (!digestConfig.CheckNonceCount) { nonce->nc++; return -1; /* forced OK by configuration */ } - if ((digestConfig->NonceStrictness && intnc != nonce->nc + 1) || + if ((digestConfig.NonceStrictness && intnc != nonce->nc + 1) || intnc < nonce->nc + 1) { debug(29, 4) ("authDigestNonceIsValid: Nonce count doesn't match\n"); nonce->flags.valid = 0; @@ -403,8 +392,8 @@ return -1; /* has it's max duration expired? */ - if (nonce->noncedata.creationtime + digestConfig->noncemaxduration < current_time.tv_sec) { - debug(29, 4) ("authDigestNonceIsStale: Nonce is too old. %ld %d %ld\n", (long int) nonce->noncedata.creationtime, (int) digestConfig->noncemaxduration, (long int) current_time.tv_sec); + if (nonce->noncedata.creationtime + digestConfig.noncemaxduration < current_time.tv_sec) { + debug(29, 4) ("authDigestNonceIsStale: Nonce is too old. %ld %d %ld\n", (long int) nonce->noncedata.creationtime, (int) digestConfig.noncemaxduration, (long int) current_time.tv_sec); nonce->flags.valid = 0; return -1; } @@ -415,7 +404,7 @@ return -1; } - if (nonce->nc > digestConfig->noncemaxuses) { + if (nonce->nc > digestConfig.noncemaxuses) { debug(29, 4) ("authDigestNoncelastRequest: Nonce count over user limit\n"); nonce->flags.valid = 0; return -1; @@ -437,7 +426,7 @@ return -1; } - if (nonce->nc >= digestConfig->noncemaxuses - 1) { + if (nonce->nc >= digestConfig.noncemaxuses - 1) { debug(29, 4) ("authDigestNoncelastRequest: Nonce count about to hit user limit\n"); return -1; } @@ -464,17 +453,6 @@ } /* USER related functions */ - - -#if NOT_USED -static int -authDigestUsercmpname(digest_user_h * u1, digest_user_h * u2) -{ - return strcmp(u1->username, u2->username); -} - -#endif - static auth_user_t * authDigestUserFindUsername(const char *username) { @@ -511,10 +489,8 @@ while ((usernamehash = ((auth_user_hash_pointer *) hash_next(proxy_auth_username_cache)))) { auth_user = authUserHashPointerUser(usernamehash); - - if (authscheme_list[auth_user->auth_module - 1].typestr && - strcmp(authscheme_list[auth_user->auth_module - 1].typestr, "digest") == 0) - /* it's digest */ + + if (strcmp(auth_user->config->type(), "digest") == 0) authenticateAuthUserUnlock(auth_user); } } @@ -542,9 +518,11 @@ authenticateAuthUserUnlock(theUser); } -static void -authDigestDone(void) +/* delete the digest request structure. Does NOT delete related structures */ +void +digestScheme::done() { + /* TODO: this should be a Config call. */ if (digestauthenticators) helperShutdown(digestauthenticators); @@ -565,11 +543,10 @@ debug(29, 2) ("authenticateDigestDone: Digest authentication shut down.\n"); } -static void -authDigestCfgDump(StoreEntry * entry, const char *name, authScheme * scheme) +void +AuthDigestConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme) { - auth_digest_config *config = static_cast < auth_digest_config * >(scheme->scheme_data); - wordlist *list = config->authenticate; + wordlist *list = authenticate; debug(29, 9) ("authDigestCfgDump: Dumping configuration\n"); storeAppendPrintf(entry, "%s %s", name, "digest"); @@ -579,58 +556,44 @@ } storeAppendPrintf(entry, "\n%s %s realm %s\n%s %s children %d\n%s %s nonce_max_count %d\n%s %s nonce_max_duration %d seconds\n%s %s nonce_garbage_interval %d seconds\n", - name, "digest", config->digestAuthRealm, - name, "digest", config->authenticateChildren, - name, "digest", config->noncemaxuses, - name, "digest", (int) config->noncemaxduration, - name, "digest", (int) config->nonceGCInterval); + name, "digest", digestAuthRealm, + name, "digest", authenticateChildren, + name, "digest", noncemaxuses, + name, "digest", (int) noncemaxduration, + name, "digest", (int) nonceGCInterval); } +/* TODO: move to digestScheme.cc - after all per request and user functions are moved out */ void -authSchemeSetup_digest(authscheme_entry_t * authscheme) +digestScheme::setup(authscheme_entry_t * authscheme) { assert(!authdigest_initialised); - authscheme->Active = authenticateDigestActive; - authscheme->configured = authDigestConfigured; - authscheme->parse = authDigestParse; - authscheme->freeconfig = authDigestFreeConfig; - authscheme->dump = authDigestCfgDump; - authscheme->init = authDigestInit; - authscheme->authAuthenticate = NULL; - authscheme->authenticated = NULL; - authscheme->authFixHeader = authenticateDigestFixHeader; - authscheme->FreeUser = authenticateDigestUserFree; #if WAITING_FOR_TE authscheme->AddTrailer = authDigestAddTrailer; #endif authscheme->authStart = authenticateDigestStart; - authscheme->authStats = authenticateDigestStats; - authscheme->authUserUsername = authenticateDigestUsername; - authscheme->getdirection = NULL; authscheme->oncloseconnection = NULL; - authscheme->decodeauth = authenticateDigestDecodeAuth; - authscheme->donefunc = authDigestDone; authscheme->requestFree = NULL; authscheme->authConnLastHeader = NULL; } -static int -authenticateDigestActive(void) +bool +AuthDigestConfig::active() const { - return (authdigest_initialised == 1) ? 1 : 0; + return authdigest_initialised == 1; } -static int -authDigestConfigured(void) +bool +AuthDigestConfig::configured() const { - if ((digestConfig != NULL) && (digestConfig->authenticate != NULL) && - (digestConfig->authenticateChildren != 0) && - (digestConfig->digestAuthRealm != NULL) && (digestConfig->noncemaxduration > -1)) - return 1; + if ((authenticate != NULL) && + (authenticateChildren != 0) && + (digestAuthRealm != NULL) && (noncemaxduration > -1)) + return true; - return 0; + return false; } int @@ -645,7 +608,7 @@ /* log a digest user in */ void -digest_request_h::authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) +digest_request_h::authenticate(auth_user_request_t * auth_user_request,HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) { auth_user_t *auth_user; digest_request_h *digest_request; @@ -701,7 +664,7 @@ return; } - if (digestConfig->PostWorkaround && request->method != METHOD_GET) { + if (digestConfig.PostWorkaround && request->method != METHOD_GET) { /* Ugly workaround for certain very broken browsers using the * wrong method to calculate the request-digest on POST request. * This should be deleted once Digest authentication becomes more @@ -739,7 +702,7 @@ /* check for stale nonce */ if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc)) { debug(29, 3) ("authenticateDigestAuthenticateuser: user '%s' validated OK but nonce stale\n", - digest_user->username); + digest_user->username()); digest_request->flags.nonce_stale = 1; credentials(Failed); return; @@ -750,7 +713,7 @@ /* password was checked and did match */ debug(29, 4) ("authenticateDigestAuthenticateuser: user '%s' validated OK\n", - digest_user->username); + digest_user->username()); /* auth_user is now linked, we reset these values * after external auth occurs anyway */ @@ -806,7 +769,7 @@ #endif - if ((digestConfig->authenticate) && authDigestNonceLastRequest(nonce)) { + if ((digestConfig.authenticate) && authDigestNonceLastRequest(nonce)) { flags.authinfo_sent = 1; debug(29, 9) ("authDigestAddHead: Sending type:%d header: 'nextnonce=\"%s\"", type, authenticateDigestNonceNonceb64(nonce)); httpHeaderPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(nonce)); @@ -837,7 +800,7 @@ type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; - if ((digestConfig->authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { + if ((digestConfig.authenticate) && authDigestNonceLastRequest(digest_request->nonce)) { debug(29, 9) ("authDigestAddTrailer: Sending type:%d header: 'nextnonce=\"%s\"", type, authenticateDigestNonceNonceb64(digest_request->nonce)); httpTrailerPutStrf(&rep->header, type, "nextnonce=\"%s\"", authenticateDigestNonceNonceb64(digest_request->nonce)); } @@ -847,9 +810,9 @@ /* add the [www-|Proxy-]authenticate header on a 407 or 401 reply */ void -authenticateDigestFixHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, HttpRequest * request) +AuthDigestConfig::fixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, HttpRequest * request) { - if (!digestConfig->authenticate) + if (!authenticate) return; int stale = 0; @@ -865,29 +828,14 @@ /* on a 407 or 401 we always use a new nonce */ digest_nonce_h *nonce = authenticateDigestNonceNew(); - debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); + debug(29, 9) ("authenticateFixHeader: Sending type:%d header: 'Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s\n", type, digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); /* in the future, for WWW auth we may want to support the domain entry */ - httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s", digestConfig->digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); -} - -static void -authenticateDigestUserFree(auth_user_t * auth_user) -{ - digest_user_h *digest_user = static_cast < digest_user_h * >(auth_user->scheme_data); - debug(29, 9) ("authenticateDigestFreeUser: Clearing Digest scheme data\n"); - - if (!digest_user) - return; - - delete digest_user; - - auth_user->scheme_data = NULL; + httpHeaderPutStrf(&rep->header, type, "Digest realm=\"%s\", nonce=\"%s\", qop=\"%s\", stale=%s", digestAuthRealm, authenticateDigestNonceNonceb64(nonce), QOP_AUTH, stale ? "true" : "false"); } -digest_user_h::~digest_user_h() +DigestUser::~DigestUser() { - safe_free(username); dlink_node *link, *tmplink; link = nonces.head; @@ -942,21 +890,21 @@ /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */ -static void -authDigestInit(authScheme * scheme) +void +AuthDigestConfig::init(AuthConfig * scheme) { static int init = 0; - if (digestConfig->authenticate) { + if (authenticate) { authenticateDigestNonceSetup(); authdigest_initialised = 1; if (digestauthenticators == NULL) digestauthenticators = helperCreate("digestauthenticator"); - digestauthenticators->cmdline = digestConfig->authenticate; + digestauthenticators->cmdline = authenticate; - digestauthenticators->n_to_start = digestConfig->authenticateChildren; + digestauthenticators->n_to_start = authenticateChildren; digestauthenticators->ipc_type = IPC_STREAM; @@ -975,75 +923,68 @@ /* free any allocated configuration details */ void -authDigestFreeConfig(authScheme * scheme) +AuthDigestConfig::done() { - if (digestConfig == NULL) - return; - - assert(digestConfig == scheme->scheme_data); - - if (digestConfig->authenticate) - wordlistDestroy(&digestConfig->authenticate); + if (authenticate) + wordlistDestroy(&authenticate); - safe_free(digestConfig->digestAuthRealm); + safe_free(digestAuthRealm); +} - xfree(digestConfig); - digestConfig = NULL; +AuthDigestConfig::AuthDigestConfig() +{ + /* TODO: move into initialisation list */ + authenticateChildren = 5; + /* 5 minutes */ + nonceGCInterval = 5 * 60; + /* 30 minutes */ + noncemaxduration = 30 * 60; + /* 50 requests */ + noncemaxuses = 50; + /* Not strict nonce count behaviour */ + NonceStrictness = 0; + /* Verify nonce count */ + CheckNonceCount = 1; } -static void -authDigestParse(authScheme * scheme, int n_configured, char *param_str) +void +AuthDigestConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) { - if (scheme->scheme_data == NULL) { - assert(digestConfig == NULL); - /* this is the first param to be found */ - scheme->scheme_data = xmalloc(sizeof(auth_digest_config)); - memset(scheme->scheme_data, 0, sizeof(auth_digest_config)); - digestConfig = static_cast < auth_digest_config * >(scheme->scheme_data); - digestConfig->authenticateChildren = 5; - /* 5 minutes */ - digestConfig->nonceGCInterval = 5 * 60; - /* 30 minutes */ - digestConfig->noncemaxduration = 30 * 60; - /* 50 requests */ - digestConfig->noncemaxuses = 50; - /* Not strict nonce count behaviour */ - digestConfig->NonceStrictness = 0; - /* Verify nonce count */ - digestConfig->CheckNonceCount = 1; - } - - digestConfig = static_cast < auth_digest_config * >(scheme->scheme_data); - if (strcasecmp(param_str, "program") == 0) { - if (digestConfig->authenticate) - wordlistDestroy(&digestConfig->authenticate); + if (authenticate) + wordlistDestroy(&authenticate); - parse_wordlist(&digestConfig->authenticate); + parse_wordlist(&authenticate); - requirePathnameExists("authparam digest program", digestConfig->authenticate->key); + requirePathnameExists("authparam digest program", authenticate->key); } else if (strcasecmp(param_str, "children") == 0) { - parse_int(&digestConfig->authenticateChildren); + parse_int(&authenticateChildren); } else if (strcasecmp(param_str, "realm") == 0) { - parse_eol(&digestConfig->digestAuthRealm); + parse_eol(&digestAuthRealm); } else if (strcasecmp(param_str, "nonce_garbage_interval") == 0) { - parse_time_t(&digestConfig->nonceGCInterval); + parse_time_t(&nonceGCInterval); } else if (strcasecmp(param_str, "nonce_max_duration") == 0) { - parse_time_t(&digestConfig->noncemaxduration); + parse_time_t(&noncemaxduration); } else if (strcasecmp(param_str, "nonce_max_count") == 0) { - parse_int((int *) &digestConfig->noncemaxuses); + parse_int((int *) &noncemaxuses); } else if (strcasecmp(param_str, "nonce_strictness") == 0) { - parse_onoff(&digestConfig->NonceStrictness); + parse_onoff(&NonceStrictness); } else if (strcasecmp(param_str, "check_nonce_count") == 0) { - parse_onoff(&digestConfig->CheckNonceCount); + parse_onoff(&CheckNonceCount); } else if (strcasecmp(param_str, "post_workaround") == 0) { - parse_onoff(&digestConfig->PostWorkaround); + parse_onoff(&PostWorkaround); } else { debug(28, 0) ("unrecognised digest auth scheme parameter '%s'\n", param_str); } } +const char * +AuthDigestConfig::type() const +{ + return digestScheme::GetInstance().type(); +} + static void authenticateDigestStats(StoreEntry * sentry) @@ -1130,54 +1071,39 @@ nonce->auth_user = auth_user; } -/* authenticateDigestUsername: return a pointer to the username in the */ -static char const * -authenticateDigestUsername(auth_user_t const *auth_user) -{ - digest_user_h *digest_user = static_cast < digest_user_h * >(auth_user->scheme_data); - - if (digest_user) - return digest_user->username; - - return NULL; -} - /* setup the necessary info to log the username */ static void authDigestLogUsername(auth_user_request_t * auth_user_request, char *username) { auth_user_t *auth_user; digest_user_h *digest_user; - dlink_node *node; /* log the username */ debug(29, 9) ("authBasicDecodeAuth: Creating new user for logging '%s'\n", username); - /* new auth_user */ - auth_user = authenticateAuthUserNew("digest"); /* new scheme data */ - digest_user = new digest_user_h; + digest_user = new DigestUser(&digestConfig); + /* auth_user is a parent */ + auth_user = dynamic_cast(digest_user); + assert (auth_user); /* save the credentials */ - digest_user->username = username; + digest_user->username(username); /* link the scheme data in */ auth_user->scheme_data = digest_user; /* set the auth_user type */ auth_user->auth_type = AUTH_BROKEN; /* link the request to the user */ auth_user_request->auth_user = auth_user; - /* lock for the auth_user_request link */ - authenticateAuthUserLock(auth_user); - node = dlinkNodeNew(); - dlinkAdd(auth_user_request, node, &auth_user->requests); + auth_user->addRequest (auth_user_request); } /* * Decode a Digest [Proxy-]Auth string, placing the results in the passed * Auth_user structure. */ - -static void -authenticateDigestDecodeAuth(auth_user_request_t * auth_user_request, const char *proxy_auth) +AuthUserRequest * +AuthDigestConfig::decode(char const *proxy_auth) { + AuthUserRequest *auth_user_request = new AuthUserRequest; const char *item; const char *p; const char *pos = NULL; @@ -1187,7 +1113,6 @@ digest_request_h *digest_request; digest_user_h *digest_user; auth_user_t *auth_user; - dlink_node *node; debug(29, 9) ("authenticateDigestDecodeAuth: beginning\n"); assert(auth_user_request != NULL); @@ -1342,7 +1267,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* now the nonce */ @@ -1355,7 +1280,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } digest_request->nonce = nonce; @@ -1371,7 +1296,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* we can't check the URI just yet. We'll check it in the @@ -1385,7 +1310,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* do we have a username ? */ @@ -1395,7 +1320,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* check that we're not being hacked / the username hasn't changed */ @@ -1405,7 +1330,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* if we got a qop, did we get a cnonce or did we get a cnonce wihtout a qop? */ @@ -1416,7 +1341,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* check the algorithm is present and supported */ @@ -1429,7 +1354,7 @@ /* we don't need the scheme specific data anymore */ delete digest_request; - return; + return auth_user_request; } /* the method we'll check at the authenticate step as well */ @@ -1442,12 +1367,13 @@ if ((auth_user = authDigestUserFindUsername(username)) == NULL) { /* the user doesn't exist in the username cache yet */ debug(29, 9) ("authDigestDecodeAuth: Creating new digest user '%s'\n", username); - /* new auth_user */ - auth_user = authenticateAuthUserNew("digest"); /* new scheme user data */ - digest_user = new digest_user_h; + digest_user = new DigestUser (&digestConfig); + /* auth_user is a parent */ + auth_user = dynamic_cast(digest_user); + assert (auth_user); /* save the username */ - digest_user->username = username; + digest_user->username(username); /* link the primary struct in */ auth_user->scheme_data = digest_user; /* set the user type */ @@ -1476,20 +1402,15 @@ digest_request->authUser (auth_user); - /* lock for the request link */ - authenticateAuthUserLock(auth_user); - - node = dlinkNodeNew(); - - dlinkAdd(auth_user_request, node, &auth_user->requests); + auth_user->addRequest (auth_user_request); debug(29, 9) ("username = '%s'\nrealm = '%s'\nqop = '%s'\nalgorithm = '%s'\nuri = '%s'\nnonce = '%s'\nnc = '%s'\ncnonce = '%s'\nresponse = '%s'\ndigestnonce = '%p'\n", - digest_user->username, digest_request->realm, + digest_user->username(), digest_request->realm, digest_request->qop, digest_request->algorithm, digest_request->uri, digest_request->nonceb64, digest_request->nc, digest_request->cnonce, digest_request->response, nonce); - return; + return auth_user_request; } /* send the initial data to a digest authenticator module */ @@ -1507,10 +1428,10 @@ digest_request = dynamic_cast < digest_request_h * >(auth_user_request->state()); assert(digest_request); digest_user = static_cast < digest_user_h * >(auth_user_request->auth_user->scheme_data); - debug(29, 9) ("authenticateStart: '\"%s\":\"%s\"'\n", digest_user->username, + debug(29, 9) ("authenticateStart: '\"%s\":\"%s\"'\n", digest_user->username(), digest_request->realm); - if (digestConfig->authenticate == NULL) { + if (digestConfig.authenticate == NULL) { handler(data, NULL); return; } @@ -1519,31 +1440,31 @@ r->handler = handler; r->data = cbdataReference(data); r->auth_user_request = auth_user_request; - snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username, digest_request->realm); + snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username(), digest_request->realm); helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r); } -MemPool (*digest_user_h::Pool)(NULL); +MemPool (*DigestUser::Pool)(NULL); void * -digest_user_h::operator new (size_t byteCount) +DigestUser::operator new (size_t byteCount) { /* derived classes with different sizes must implement their own new */ - assert (byteCount == sizeof (digest_user_h)); + assert (byteCount == sizeof (DigestUser)); if (!Pool) - Pool = memPoolCreate("digest_user_h", sizeof (digest_user_h)); + Pool = memPoolCreate("Authentication Digest User data", sizeof (DigestUser)); return memPoolAlloc(Pool); } void -digest_user_h::operator delete (void *address) +DigestUser::operator delete (void *address) { memPoolFree (Pool, address); } -digest_user_h::digest_user_h () : username (NULL), HA1created (0) +DigestUser::DigestUser (AuthConfig *config) : AuthUser (config), HA1created (0) {} MemPool (*digest_request_h::Pool)(NULL); @@ -1572,7 +1493,10 @@ digest_request_h::digest_request_h (auth_user_t *aUser) : theUser (aUser) , credentials_ok (Unchecked) { - authenticateAuthUserLock(theUser); + + theUser->lock() + + ; } auth_user_t * @@ -1585,8 +1509,11 @@ digest_request_h::authUser(auth_user_t *aUser) { assert (!authUser()); - authenticateAuthUserLock(aUser); theUser = aUser; + + theUser->lock() + + ; } digest_request_h::CredentialsState @@ -1601,3 +1528,9 @@ { credentials_ok = newCreds; } + +AuthConfig * +digestScheme::createConfig() +{ + return &digestConfig; +} --- orig/src/auth/digest/auth_digest.h +++ mod/src/auth/digest/auth_digest.h @@ -7,6 +7,8 @@ #define __AUTH_DIGEST_H__ #include "rfc2617.h" #include "authenticate.h" +#include "AuthUser.h" +#include "AuthConfig.h" /* Generic */ class DigestAuthenticateStateData @@ -22,17 +24,16 @@ typedef struct _digest_nonce_h digest_nonce_h; -class digest_user_h +class DigestUser : public AuthUser { public: void *operator new(size_t); void operator delete (void *); - digest_user_h(); - ~digest_user_h(); + DigestUser(AuthConfig *); + ~DigestUser(); int authenticated() const; - char *username; HASH HA1; int HA1created; @@ -42,6 +43,7 @@ private: static MemPool *Pool; }; +typedef class DigestUser digest_user_h; /* the digest_request structure is what follows the http_request around */ @@ -58,7 +60,7 @@ ~digest_request_h(); int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type); + virtual void authenticate(auth_user_request_t * auth_user_request,HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type); virtual int direction(); virtual void addHeader(HttpReply * rep, int accel); @@ -139,8 +141,19 @@ /* configuration runtime data */ -struct _auth_digest_config +class AuthDigestConfig : public AuthConfig { + public: + AuthDigestConfig::AuthDigestConfig(); + virtual bool active() const; + virtual bool configured() const; + virtual AuthUserRequest *decode(char const *proxy_auth); + virtual void done(); + virtual void dump(StoreEntry *, const char *, AuthConfig *); + virtual void fixHeader(auth_user_request_t *, HttpReply *, http_hdr_type, HttpRequest *); + virtual void init(AuthConfig *); + virtual void parse(AuthConfig *, int, char *); + virtual const char * type() const; int authenticateChildren; char *digestAuthRealm; wordlist *authenticate; @@ -152,7 +165,7 @@ int PostWorkaround; }; -typedef struct _auth_digest_config auth_digest_config; +typedef class AuthDigestConfig auth_digest_config; /* strings */ #define QOP_AUTH "auth" --- orig/src/auth/ntlm/auth_ntlm.cc +++ mod/src/auth/ntlm/auth_ntlm.cc @@ -45,8 +45,8 @@ #include "client_side.h" #include "HttpReply.h" #include "HttpRequest.h" - -extern AUTHSSETUP authSchemeSetup_ntlm; +/* TODO remove this include */ +#include "ntlmScheme.h" static void authenticateStateFree(authenticateStateData * r) @@ -57,22 +57,10 @@ /* NTLM Scheme */ static HLPSCB authenticateNTLMHandleReply; static HLPSCB authenticateNTLMHandleplaceholder; -static AUTHSACTIVE authenticateNTLMActive; -static AUTHSAUTHUSER authenticateNTLMAuthenticateUser; -static AUTHSCONFIGURED authNTLMConfigured; -static AUTHSFIXERR authenticateNTLMFixErrorHeader; -static AUTHSFREE authenticateNTLMFreeUser; -static AUTHSDECODE authenticateDecodeNTLMAuth; -static AUTHSDUMP authNTLMCfgDump; -static AUTHSFREECONFIG authNTLMFreeConfig; -static AUTHSINIT authNTLMInit; static AUTHSONCLOSEC authenticateNTLMOnCloseConnection; static AUTHSCONNLASTHEADER NTLMLastHeader; -static AUTHSUSERNAME authenticateNTLMUsername; -static AUTHSPARSE authNTLMParse; static AUTHSSTART authenticateNTLMStart; static AUTHSSTATS authenticateNTLMStats; -static AUTHSSHUTDOWN authNTLMDone; /* helper callbacks to handle per server state data */ static HLPSAVAIL authenticateNTLMHelperServerAvailable; @@ -85,10 +73,9 @@ static int authntlm_initialised = 0; static MemPool *ntlm_helper_state_pool = NULL; -static MemPool *ntlm_user_pool = NULL; static MemPool *ntlm_user_hash_pool = NULL; -static auth_ntlm_config *ntlmConfig = NULL; +static auth_ntlm_config ntlmConfig; static hash_table *proxy_auth_cache = NULL; @@ -98,9 +85,11 @@ * */ -static void -authNTLMDone(void) +/* move to ntlmScheme.cc */ +void +ntlmScheme::done() { + /* TODO: this should be a Config call. */ debug(29, 2) ("authNTLMDone: shutting down NTLM authentication.\n"); if (ntlmauthenticators) @@ -122,36 +111,22 @@ memPoolDestroy(&ntlm_helper_state_pool); } - if (ntlm_user_pool) { - memPoolDestroy(&ntlm_user_pool); - } - #endif debug(29, 2) ("authNTLMDone: NTLM authentication Shutdown.\n"); } /* free any allocated configuration details */ -static void -authNTLMFreeConfig(authScheme * scheme) +void +AuthNTLMConfig::done() { - if (ntlmConfig == NULL) - return; - - assert(ntlmConfig == scheme->scheme_data); - - if (ntlmConfig->authenticate) - wordlistDestroy(&ntlmConfig->authenticate); - - xfree(ntlmConfig); - - ntlmConfig = NULL; + if (authenticate) + wordlistDestroy(&authenticate); } -static void -authNTLMCfgDump(StoreEntry * entry, const char *name, authScheme * scheme) +void +AuthNTLMConfig::dump(StoreEntry * entry, const char *name, AuthConfig * scheme) { - auth_ntlm_config *config = static_cast(scheme->scheme_data); - wordlist *list = config->authenticate; + wordlist *list = authenticate; storeAppendPrintf(entry, "%s %s", name, "ntlm"); while (list != NULL) { @@ -160,41 +135,36 @@ } storeAppendPrintf(entry, "\n%s %s children %d\n%s %s max_challenge_reuses %d\n%s %s max_challenge_lifetime %d seconds\n", - name, "ntlm", config->authenticateChildren, - name, "ntlm", config->challengeuses, - name, "ntlm", (int) config->challengelifetime); + name, "ntlm", authenticateChildren, + name, "ntlm", challengeuses, + name, "ntlm", (int) challengelifetime); } -static void -authNTLMParse(authScheme * scheme, int n_configured, char *param_str) +AuthNTLMConfig::AuthNTLMConfig() { - if (scheme->scheme_data == NULL) { - assert(ntlmConfig == NULL); - /* this is the first param to be found */ - scheme->scheme_data = xmalloc(sizeof(auth_ntlm_config)); - memset(scheme->scheme_data, 0, sizeof(auth_ntlm_config)); - ntlmConfig = static_cast(scheme->scheme_data); - ntlmConfig->authenticateChildren = 5; - ntlmConfig->challengeuses = 0; - ntlmConfig->challengelifetime = 60; - } - - ntlmConfig = static_cast(scheme->scheme_data); + /* TODO Move into initialisation list */ + authenticateChildren = 5; + challengeuses = 0; + challengelifetime = 60; +} +void +AuthNTLMConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) +{ if (strcasecmp(param_str, "program") == 0) { - if (ntlmConfig->authenticate) - wordlistDestroy(&ntlmConfig->authenticate); + if (authenticate) + wordlistDestroy(&authenticate); - parse_wordlist(&ntlmConfig->authenticate); + parse_wordlist(&authenticate); - requirePathnameExists("authparam ntlm program", ntlmConfig->authenticate->key); + requirePathnameExists("authparam ntlm program", authenticate->key); } else if (strcasecmp(param_str, "children") == 0) { - parse_int(&ntlmConfig->authenticateChildren); + parse_int(&authenticateChildren); } else if (strcasecmp(param_str, "max_challenge_reuses") == 0) { - parse_int(&ntlmConfig->challengeuses); + parse_int(&challengeuses); } else if (strcasecmp(param_str, "max_challenge_lifetime") == 0) { - parse_time_t(&ntlmConfig->challengelifetime); + parse_time_t(&challengelifetime); } else { debug(28, 0) ("unrecognised ntlm auth scheme parameter '%s'\n", param_str); } @@ -207,50 +177,39 @@ * state will be preserved. Caveats: this should be a post-parse * test, but that can wait for the modular parser to be integrated. */ - if (ntlmConfig->authenticate) + if (authenticate) Config.onoff.pipeline_prefetch = 0; } +const char * +AuthNTLMConfig::type() const +{ + return ntlmScheme::GetInstance().type(); +} + +/* TODO: move to ntlmScheme.cc - after all per request and user functions are moved out */ void -authSchemeSetup_ntlm(authscheme_entry_t * authscheme) +ntlmScheme::setup(authscheme_entry_t * authscheme) { assert(!authntlm_initialised); - authscheme->Active = authenticateNTLMActive; - authscheme->configured = authNTLMConfigured; - authscheme->parse = authNTLMParse; - authscheme->dump = authNTLMCfgDump; authscheme->requestFree = NULL; - authscheme->freeconfig = authNTLMFreeConfig; - authscheme->init = authNTLMInit; - authscheme->authAuthenticate = authenticateNTLMAuthenticateUser; - authscheme->authenticated = NULL; - authscheme->authFixHeader = authenticateNTLMFixErrorHeader; - authscheme->FreeUser = authenticateNTLMFreeUser; authscheme->authStart = authenticateNTLMStart; - authscheme->authStats = authenticateNTLMStats; - authscheme->authUserUsername = authenticateNTLMUsername; - authscheme->getdirection = NULL; - authscheme->decodeauth = authenticateDecodeNTLMAuth; - authscheme->donefunc = authNTLMDone; authscheme->oncloseconnection = authenticateNTLMOnCloseConnection; authscheme->authConnLastHeader = NTLMLastHeader; } /* Initialize helpers and the like for this auth scheme. Called AFTER parsing the * config file */ -static void -authNTLMInit(authScheme * scheme) +void +AuthNTLMConfig::init(AuthConfig * scheme) { static int ntlminit = 0; - if (ntlmConfig->authenticate) { + if (authenticate) { if (!ntlm_helper_state_pool) ntlm_helper_state_pool = memPoolCreate("NTLM Helper State data", sizeof(ntlm_helper_state_t)); - if (!ntlm_user_pool) - ntlm_user_pool = memPoolCreate("NTLM Scheme User Data", sizeof(ntlm_user_t)); - if (!ntlm_user_hash_pool) ntlm_user_hash_pool = memPoolCreate("NTLM Header Hash Data", sizeof(struct ProxyAuthCachePointer)); @@ -265,9 +224,9 @@ assert(proxy_auth_cache); - ntlmauthenticators->cmdline = ntlmConfig->authenticate; + ntlmauthenticators->cmdline = authenticate; - ntlmauthenticators->n_to_start = ntlmConfig->authenticateChildren; + ntlmauthenticators->n_to_start = authenticateChildren; ntlmauthenticators->ipc_type = IPC_STREAM; @@ -298,23 +257,22 @@ } } -static int -authenticateNTLMActive() +bool +AuthNTLMConfig::active() const { - return (authntlm_initialised == 1) ? 1 : 0; + return authntlm_initialised == 1; } - -static int -authNTLMConfigured() +bool +AuthNTLMConfig::configured() const { - if ((ntlmConfig != NULL) && (ntlmConfig->authenticate != NULL) && (ntlmConfig->authenticateChildren != 0) && (ntlmConfig->challengeuses > -1) && (ntlmConfig->challengelifetime > -1)) { + if ((authenticate != NULL) && (authenticateChildren != 0) && (challengeuses > -1) && (challengelifetime > -1)) { debug(29, 9) ("authNTLMConfigured: returning configured\n"); - return 1; + return true; } debug(29, 9) ("authNTLMConfigured: returning unconfigured\n"); - return 0; + return false; } /* NTLM Scheme */ @@ -362,12 +320,12 @@ * must be first. To ensure that, the configure use --enable-auth=ntlm, anything * else. */ -static void -authenticateNTLMFixErrorHeader(auth_user_request_t * auth_user_request, HttpReply * rep, http_hdr_type type, HttpRequest * request) +void +AuthNTLMConfig::fixHeader(auth_user_request_t *auth_user_request, HttpReply *rep, http_hdr_type type, HttpRequest * request) { ntlm_request_t *ntlm_request; - if (ntlmConfig->authenticate) { + if (authenticate) { /* New request, no user details */ if (auth_user_request == NULL) { @@ -429,35 +387,27 @@ } } -static void -authenticateNTLMFreeUser(auth_user_t * auth_user) +NTLMUser::~NTLMUser() { dlink_node *link, *tmplink; - ntlm_user_t *ntlm_user = static_cast(auth_user->scheme_data); ProxyAuthCachePointer *proxy_auth_hash; - - debug(29, 5) ("authenticateNTLMFreeUser: Clearing NTLM scheme data\n"); - - if (ntlm_user->username) - xfree(ntlm_user->username); + debug(29, 5) ("NTLMUser::~NTLMUser: Clearing NTLM scheme data\n"); /* were they linked in by one or more proxy-authenticate headers */ - link = ntlm_user->proxy_auth_list.head; + link = proxy_auth_list.head; while (link) { debug(29, 9) ("authenticateFreeProxyAuthUser: removing proxy_auth hash entry '%p'\n", link->data); proxy_auth_hash = static_cast(link->data); tmplink = link; link = link->next; - dlinkDelete(tmplink, &ntlm_user->proxy_auth_list); + dlinkDelete(tmplink, &proxy_auth_list); hash_remove_link(proxy_auth_cache, (hash_link *) proxy_auth_hash); /* free the key (usually the proxy_auth header) */ xfree(proxy_auth_hash->key); memPoolFree(ntlm_user_hash_pool, proxy_auth_hash); } - memPoolFree(ntlm_user_pool, ntlm_user); - auth_user->scheme_data = NULL; } static stateful_helper_callback_t @@ -571,7 +521,7 @@ result = S_HELPER_RELEASE; /* we only expect OK when finishing the handshake */ assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); - ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); + ntlm_user->username(xstrndup(reply, MAX_LOGIN_SZ)); ntlm_request->authserver = NULL; #ifdef NTLM_FAIL_OPEN @@ -597,7 +547,7 @@ result = S_HELPER_RELEASE; /* we only expect LD when finishing the handshake */ assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); - ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); + ntlm_user->username_ = xstrndup(reply, MAX_LOGIN_SZ); helperstate = static_cast(helperStatefulServerGetData(ntlm_request->authserver)); ntlm_request->authserver = NULL; /* BH code: mark helper as broken */ @@ -734,13 +684,13 @@ return 0; } - if (helperstate->challengeuses > ntlmConfig->challengeuses) { - debug(29, 4) ("authenticateNTLMChangeChallenge_p: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig->challengeuses); + if (helperstate->challengeuses > ntlmConfig.challengeuses) { + debug(29, 4) ("authenticateNTLMChangeChallenge_p: Challenge uses (%d) exceeded max uses (%d)\n", helperstate->challengeuses, ntlmConfig.challengeuses); return 1; } - if (helperstate->renewed + ntlmConfig->challengelifetime < squid_curtime) { - debug(29, 4) ("authenticateNTLMChangeChallenge_p: Challenge exceeded max lifetime by %d seconds\n", (int) (squid_curtime - (helperstate->renewed + ntlmConfig->challengelifetime))); + if (helperstate->renewed + ntlmConfig.challengelifetime < squid_curtime) { + debug(29, 4) ("authenticateNTLMChangeChallenge_p: Challenge exceeded max lifetime by %d seconds\n", (int) (squid_curtime - (helperstate->renewed + ntlmConfig.challengelifetime))); return 1; } @@ -798,7 +748,7 @@ debug(29, 9) ("authenticateNTLMStart: '%s'\n", sent_string); - if (ntlmConfig->authenticate == NULL) { + if (ntlmConfig.authenticate == NULL) { debug(29, 0) ("authenticateNTLMStart: no NTLM program specified:'%s'\n", sent_string); handler(data, NULL); return; @@ -964,18 +914,6 @@ } } -/* authenticateUserUsername: return a pointer to the username in the */ -static const char * -authenticateNTLMUsername(auth_user_t const * auth_user) -{ - ntlm_user_t *ntlm_user = static_cast(auth_user->scheme_data); - - if (ntlm_user) - return ntlm_user->username; - - return NULL; -} - /* NTLMLastHeader: return a pointer to the last header used in authenticating * the request/conneciton */ @@ -993,30 +931,27 @@ * Decode an NTLM [Proxy-]Auth string, placing the results in the passed * Auth_user structure. */ - -static void -authenticateDecodeNTLMAuth(auth_user_request_t * auth_user_request, const char *proxy_auth) +AuthUserRequest * +AuthNTLMConfig::decode(char const *proxy_auth) { - dlink_node *node; + AuthUserRequest *auth_user_request = new AuthUserRequest; assert(auth_user_request->auth_user == NULL); - auth_user_request->auth_user = authenticateAuthUserNew("ntlm"); + NTLMUser *newUser = new NTLMUser(&ntlmConfig); + auth_user_request->auth_user = dynamic_cast (newUser); auth_user_request->auth_user->auth_type = AUTH_NTLM; - auth_user_request->auth_user->scheme_data = memPoolAlloc(ntlm_user_pool); - auth_user_request->state (new ntlm_request_t); - /* lock for the auth_user_request link */ - authenticateAuthUserLock(auth_user_request->auth_user); - node = dlinkNodeNew(); - dlinkAdd(auth_user_request, node, &auth_user_request->auth_user->requests); + auth_user_request->auth_user->scheme_data = newUser; + auth_user_request->state (new ntlm_request_t(newUser)); + auth_user_request->auth_user->addRequest(auth_user_request); /* all we have to do is identify that it's NTLM - the helper does the rest */ debug(29, 9) ("authenticateDecodeNTLMAuth: NTLM authentication\n"); - return; + return auth_user_request; } static int authenticateNTLMcmpUsername(ntlm_user_t * u1, ntlm_user_t * u2) { - return strcmp(u1->username, u2->username); + return strcmp(u1->username(), u2->username()); } @@ -1062,14 +997,9 @@ } void -ntlm_request_t::authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) -{ - fatal ("unusable"); -} - -static void -authenticateNTLMAuthenticateUser(auth_user_request_t * auth_user_request, HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) +ntlm_request_t::authenticate(auth_user_request_t * auth_user_request, HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) { + assert (this == auth_user_request->state()); const char *proxy_auth; struct ProxyAuthCachePointer *proxy_auth_hash = NULL; @@ -1081,12 +1011,12 @@ /* get header */ proxy_auth = httpHeaderGetStr(&request->header, type); - auth_user = auth_user_request->auth_user; + auth_user = theUser; assert(auth_user); assert(auth_user->auth_type == AUTH_NTLM); assert(auth_user->scheme_data != NULL); ntlm_user = static_cast(auth_user->scheme_data); - ntlm_request = dynamic_cast< ntlm_request_t *>(auth_user_request->state()); + ntlm_request = this; assert (ntlm_request); /* Check that we are in the client side, where we can generate * auth challenges */ @@ -1165,7 +1095,7 @@ assert(auth_user->auth_type == AUTH_NTLM); /* get the existing entries details */ ntlm_user = static_cast(auth_user->scheme_data); - debug(29, 9) ("Username to be used is %s\n", ntlm_user->username); + debug(29, 9) ("Username to be used is %s\n", ntlm_user->username()); /* on ntlm auth we do not unlock the auth_user until the * connection is dropped. Thank MS for this quirk */ auth_user->expiretime = current_time.tv_sec; @@ -1182,7 +1112,7 @@ debug(29, 4) ("authenticated\nch %s\nauth %s\nauthuser %s\n", ntlm_request->authchallenge, ntlm_request->ntlmauthenticate, - ntlm_user->username); + ntlm_user->username()); /* cache entries have authenticateauthheaderchallengestring */ snprintf(ntlmhash, sizeof(ntlmhash) - 1, "%s%s", ntlm_request->ntlmauthenticate, @@ -1190,7 +1120,7 @@ /* see if this is an existing user with a different proxy_auth * string */ - if ((usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, ntlm_user->username))) + if ((usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, ntlm_user->username()))) ) { while ((authUserHashPointerUser(usernamehash)->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername(static_cast(authUserHashPointerUser(usernamehash)->scheme_data), ntlm_user) ) @@ -1251,3 +1181,43 @@ { memPoolFree (Pool, address); } + +ntlm_request_t::ntlm_request_t(NTLMUser *aUser) : theUser(aUser) +{} + +MemPool *NTLMUser::Pool (NULL); +void +NTLMUser::deleteSelf() const +{ + delete this; +} + +void * +NTLMUser::operator new(size_t byteCount) +{ + /* derived classes with different sizes must implement their own new */ + assert (byteCount == sizeof (NTLMUser)); + + if (!Pool) + Pool = memPoolCreate("Authenticate NTLM User Data", sizeof (NTLMUser)); + + return memPoolAlloc(Pool); +} + +void +NTLMUser::operator delete (void *address) +{ + memPoolFree(Pool, address); +} + +NTLMUser::NTLMUser (AuthConfig *config) : AuthUser (config) +{ + proxy_auth_list.head = proxy_auth_list.tail = NULL; +} + +AuthConfig * +ntlmScheme::createConfig() +{ + return &ntlmConfig; +} + --- orig/src/auth/ntlm/auth_ntlm.h +++ mod/src/auth/ntlm/auth_ntlm.h @@ -6,6 +6,8 @@ #ifndef __AUTH_NTLM_H__ #define __AUTH_NTLM_H__ #include "authenticate.h" +#include "AuthUser.h" +#include "AuthConfig.h" #define DefaultAuthenticateChildrenMax 32 /* 32 processes */ @@ -29,12 +31,19 @@ authenticateStateData; -struct _ntlm_user +class NTLMUser : public AuthUser { - /* what username did this connection get? */ - char *username; + public: + virtual void deleteSelf() const; + void *operator new(size_t); + void operator delete (void *); + NTLMUser(AuthConfig *); + ~NTLMUser(); dlink_list proxy_auth_list; + private: + static MemPool *Pool; }; +typedef class NTLMUser ntlm_user_t; class ntlm_request_t : public AuthUserRequestState { @@ -43,9 +52,10 @@ void *operator new(size_t); void operator delete (void *); + ntlm_request_t(NTLMUser *aUser); ~ntlm_request_t(); virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type); + virtual void authenticate(auth_user_request_t * auth_user_request,HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type); virtual int direction(); /* what negotiate string did the client use? */ char *ntlmnegotiate; @@ -62,6 +72,9 @@ /* what connection is this associated with */ ConnStateData::Pointer conn; + /* the user */ + NTLMUser * theUser; + private: static MemPool *Pool; }; @@ -76,8 +89,19 @@ /* configuration runtime data */ -struct _auth_ntlm_config +class AuthNTLMConfig : public AuthConfig { + public: + AuthNTLMConfig::AuthNTLMConfig(); + virtual bool active() const; + virtual bool configured() const; + virtual AuthUserRequest *decode(char const *proxy_auth); + virtual void done(); + virtual void dump(StoreEntry *, const char *, AuthConfig *); + virtual void fixHeader(auth_user_request_t *, HttpReply *, http_hdr_type, HttpRequest *); + virtual void init(AuthConfig *); + virtual void parse(AuthConfig *, int, char *); + virtual const char * type() const; int authenticateChildren; wordlist *authenticate; int challengeuses; @@ -91,11 +115,8 @@ auth_user_t *auth_user; }; -typedef struct _ntlm_user ntlm_user_t; - - typedef struct _ntlm_helper_state_t ntlm_helper_state_t; -typedef struct _auth_ntlm_config auth_ntlm_config; +typedef class AuthNTLMConfig auth_ntlm_config; #endif --- orig/src/authenticate.cc +++ mod/src/authenticate.cc @@ -41,6 +41,9 @@ #include "authenticate.h" #include "ACL.h" #include "client_side.h" +#include "AuthConfig.h" +#include "AuthScheme.h" +#include "AuthUser.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -54,7 +57,6 @@ MemPool *AuthUserRequest::pool = NULL; MemPool *AuthUserHashPointer::pool = NULL; -MemPool *AuthUser::pool = NULL; /* * memDataInit(MEM_AUTH_USER_T, "auth_user_t", * sizeof(auth_user_t), 0); @@ -62,24 +64,14 @@ /* Generic Functions */ - -static int -authenticateAuthSchemeConfigured(const char *proxy_auth) +authscheme_entry_t * +authenticateAuthScheme(const char *typestr) { - authScheme *scheme; - int i; - - for (i = 0; i < Config.authConfiguration.n_configured; i++) { - scheme = Config.authConfiguration.schemes + i; - - if ((strncasecmp(proxy_auth, scheme->typestr, strlen(scheme->typestr)) == 0) && - (authscheme_list[scheme->Id].Active())) - return 1; - } - - return 0; + int i = authenticateAuthSchemeId(typestr); + if (i > -1) + return &authscheme_list[i]; + return NULL; } - int authenticateAuthSchemeId(const char *typestr) { @@ -94,24 +86,6 @@ return -1; } -void -AuthUserRequest::decodeAuth(const char *proxy_auth) -{ - int i = 0; - assert(proxy_auth != NULL); - debug(29, 9) ("authenticateDecodeAuth: header = '%s'\n", proxy_auth); - - if (!authenticateAuthSchemeConfigured(proxy_auth) || - (i = authenticateAuthSchemeId(proxy_auth)) == -1) { - debug(29, 1) ("AuthUserRequest::decodeAuth: Unsupported or unconfigured proxy-auth scheme, '%s'\n", proxy_auth); - return; - } - - assert (i >= 0); - authscheme_list[i].decodeauth(this, proxy_auth); - auth_user->auth_module = i + 1; -} - size_t AuthUserRequest::refCount () const { @@ -222,43 +196,6 @@ } void * -AuthUser::operator new (size_t byteCount) -{ - /* derived classes with different sizes must implement their own new */ - assert (byteCount == sizeof (AuthUser)); - - if (!pool) - pool = memPoolCreate("Authenticate User Data", sizeof (auth_user_t)); - - return memPoolAlloc(pool); -} - -AuthUser::AuthUser (const char *scheme) : - auth_type (AUTH_UNKNOWN), auth_module (authenticateAuthSchemeId(scheme) + 1), - usernamehash (NULL), ipcount (0), expiretime (0), references (0), scheme_data (NULL) -{ - proxy_auth_list.head = proxy_auth_list.tail = NULL; - proxy_match_cache.head = proxy_match_cache.tail = NULL; - ip_list.head = ip_list.tail = NULL; - requests.head = requests.tail = NULL; -} - -char const * -AuthUser::username () const -{ - if (auth_module <= 0) - return NULL; - - return authscheme_list[auth_module - 1].authUserUsername(this); -} - -auth_user_t * -authenticateAuthUserNew(const char *scheme) -{ - return new AuthUser (scheme); -} - -void * AuthUserRequest::operator new (size_t byteCount) { /* derived classes with different sizes must implement their own new */ @@ -447,37 +384,11 @@ } -static void -authenticateAuthUserClearIp(auth_user_t * auth_user) -{ - auth_user_ip_t *ipdata, *tempnode; - - if (!auth_user) - return; - - ipdata = (auth_user_ip_t *) auth_user->ip_list.head; - - while (ipdata) { - tempnode = (auth_user_ip_t *) ipdata->node.next; - /* walk the ip list */ - dlinkDelete(&ipdata->node, &auth_user->ip_list); - cbdataFree(ipdata); - /* catch incipient underflow */ - assert(auth_user->ipcount); - auth_user->ipcount--; - ipdata = tempnode; - } - - /* integrity check */ - assert(auth_user->ipcount == 0); -} - - void authenticateAuthUserRequestClearIp(auth_user_request_t * auth_user_request) { if (auth_user_request) - authenticateAuthUserClearIp(auth_user_request->auth_user); + auth_user_request->auth_user->clearIp(); } size_t @@ -489,25 +400,6 @@ } -/* Get Auth User: Return a filled out auth_user structure for the given - * Proxy Auth (or Auth) header. It may be a cached Auth User or a new - * Unauthenticated structure. The structure is given an inital lock here. - */ -auth_user_request_t * -AuthUserRequest::createAuthUser(const char *proxy_auth) -{ - auth_user_request_t *result = new auth_user_request_t; - /* and lock for the callers instance */ - - result->lock() - - ; - /* The scheme is allowed to provide a cached auth_user or a new one */ - result->decodeAuth(proxy_auth); - - return result; -} - /* * authenticateUserAuthenticated: is this auth_user structure logged in ? */ @@ -518,15 +410,9 @@ return 0; if (auth_user_request->auth_user->auth_module > 0) { - /* legacy interface */ - - if (authscheme_list[auth_user_request->auth_user->auth_module - 1].authenticated) - return authscheme_list[auth_user_request->auth_user->auth_module - 1].authenticated(auth_user_request); - else { - /* state interface */ - assert (auth_user_request->state()); - return auth_user_request->state()->authenticated(); - } + /* state interface */ + assert (auth_user_request->state()); + return auth_user_request->state()->authenticated(); } else return 0; } @@ -543,12 +429,8 @@ assert(auth_user_request != NULL); if (auth_user_request->auth_user->auth_module > 0) { - if (authscheme_list[auth_user_request->auth_user->auth_module - 1].authAuthenticate) - authscheme_list[auth_user_request->auth_user->auth_module - 1].authAuthenticate(auth_user_request, request, conn, type); - else { - assert (auth_user_request->state()); - auth_user_request->state()->authenticate(request, conn, type); - } + assert (auth_user_request->state()); + auth_user_request->state()->authenticate(auth_user_request, request, conn, type); } } @@ -666,7 +548,9 @@ debug(28, 4) ("authenticateAuthenticate: no connection authentication type\n"); if (!authenticateValidateUser(*auth_user_request = - createAuthUser(proxy_auth))) { + AuthConfig::CreateAuthUser(proxy_auth))) { + if (*auth_user_request == NULL) + return AUTH_ACL_CHALLENGE; /* the decode might have left a username for logging, or a message to * the user */ @@ -829,14 +713,6 @@ return AuthUserRequest::tryToAuthenticateAndSetAuthUser (auth_user_request, headertype,request, conn, src_addr); } -/* authenticateUserRequestUsername: return a pointer to the username in the */ -char const * -authenticateUserRequestUsername(auth_user_request_t * auth_user_request) -{ - assert(auth_user_request != NULL); - return auth_user_request->username(); -} - /* returns * 0: no output needed * 1: send to client @@ -853,12 +729,8 @@ return 0; if (auth_user_request->auth_user->auth_module > 0) { - if (authscheme_list[auth_user_request->auth_user->auth_module - 1].getdirection) - return authscheme_list[auth_user_request->auth_user->auth_module - 1].getdirection(auth_user_request); - else { - assert (auth_user_request->state()); - return auth_user_request->state()->direction(); - } + assert (auth_user_request->state()); + return auth_user_request->state()->direction(); } return -2; @@ -867,11 +739,11 @@ int authenticateActiveSchemeCount(void) { - int i = 0, rv = 0; + int rv = 0; - for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) - if (authscheme_list[i].configured()) - rv++; + for (authConfig::iterator i = Config.authConfiguration.begin(); i != Config.authConfiguration.end(); ++i) + if ((*i)->configured()) + ++rv; debug(29, 9) ("authenticateActiveSchemeCount: %d active.\n", rv); @@ -894,21 +766,17 @@ void authenticateSchemeInit(void) { - authSchemeSetup(); + AuthScheme::SetupAll(); } void authenticateInit(authConfig * config) { - int i; - authScheme *scheme; + for (authConfig::iterator i = config->begin(); i != config->end(); ++i) { + AuthConfig *scheme = *i; - for (i = 0; i < config->n_configured; i++) { - scheme = config->schemes + i; - - if (authscheme_list[scheme->Id].init && authscheme_list[scheme->Id].configured()) { - authscheme_list[scheme->Id].init(scheme); - } + if (scheme->configured()) + scheme->init(scheme); } if (!proxy_auth_username_cache) @@ -920,22 +788,15 @@ void authenticateShutdown(void) { - int i; debug(29, 2) ("authenticateShutdown: shutting down auth schemes\n"); /* free the cache if we are shutting down */ - if (shutting_down) + if (shutting_down) { hashFreeItems(proxy_auth_username_cache, AuthUserHashPointer::removeFromCache); - - /* find the currently known authscheme types */ - for (i = 0; authscheme_list && authscheme_list[i].typestr; i++) { - if (authscheme_list[i].donefunc != NULL) - authscheme_list[i].donefunc(); - else - debug(29, 2) ("authenticateShutdown: scheme %s has not registered a shutdown function.\n", authscheme_list[i].typestr); - - if (shutting_down) - authscheme_list[i].typestr = NULL; + AuthScheme::FreeAll(); + } else { + for (AuthScheme::const_iterator i = AuthScheme::Schemes().begin(); i != AuthScheme::Schemes().end(); ++i) + (*i)->done(); } } @@ -973,21 +834,18 @@ { if ((auth_user_request != NULL) && (auth_user_request->auth_user->auth_module > 0) & !authenticateUserAuthenticated(auth_user_request)) - authscheme_list[auth_user_request->auth_user->auth_module - 1].authFixHeader(auth_user_request, rep, type, request); + /* scheme specific */ + auth_user_request->auth_user->config->fixHeader(auth_user_request, rep, type, request); else { - int i; - authScheme *scheme; /* call each configured & running authscheme */ + for (authConfig::iterator i = Config.authConfiguration.begin(); i != Config.authConfiguration.end(); ++i) { + AuthConfig *scheme = *i; - for (i = 0; i < Config.authConfiguration.n_configured; i++) { - scheme = Config.authConfiguration.schemes + i; - - if (authscheme_list[scheme->Id].Active()) - authscheme_list[scheme->Id].authFixHeader(NULL, rep, type, - request); + if (scheme->active()) + scheme->fixHeader(NULL, rep, type, request); else - debug(29, 4) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->typestr); + debug(29, 4) ("authenticateFixHeader: Configured scheme %s not Active\n", scheme->type()); } } @@ -1021,15 +879,6 @@ } void -authenticateAuthUserLock(auth_user_t * auth_user) -{ - debug(29, 9) ("authenticateAuthUserLock auth_user '%p'.\n", auth_user); - assert(auth_user != NULL); - auth_user->references++; - debug(29, 9) ("authenticateAuthUserLock auth_user '%p' now at '%ld'.\n", auth_user, (long int) auth_user->references); -} - -void authenticateAuthUserUnlock(auth_user_t * auth_user) { debug(29, 9) ("authenticateAuthUserUnlock auth_user '%p'.\n", auth_user); @@ -1076,6 +925,18 @@ delete this; } +AuthScheme * +AuthUserRequest::scheme() const +{ + return AuthScheme::Find(auth_user->config->type()); +} + +_authscheme_entry * +AuthUserRequest::oldscheme() const +{ + return &authscheme_list[auth_user->auth_module - 1]; +} + void authenticateAuthUserRequestLock(auth_user_request_t * auth_user_request) { @@ -1100,170 +961,12 @@ return auth_user->references; } -/* Combine two user structs. ONLY to be called from within a scheme - * module. The scheme module is responsible for ensuring that the - * two users _can_ be merged without invalidating all the request - * scheme data. The scheme is also responsible for merging any user - * related scheme data itself. - */ -void -AuthUser::absorb (AuthUser *from) -{ - auth_user_request_t *auth_user_request; - /* - * XXX combine two authuser structs. Incomplete: it should merge - * in hash references too and ask the module to merge in scheme - * data - */ - debug(29, 5) ("authenticateAuthUserMerge auth_user '%p' into auth_user '%p'.\n", from, this); - dlink_node *link = from->requests.head; - - while (link) { - auth_user_request = static_cast(link->data); - dlink_node *tmplink = link; - link = link->next; - dlinkDelete(tmplink, &from->requests); - dlinkAddTail(auth_user_request, tmplink, &requests); - auth_user_request->auth_user = this; - } - - references += from->references; - from->references = 0; - delete from; -} - void authenticateAuthUserMerge(auth_user_t * from, auth_user_t * to) { to->absorb (from); } -void -AuthUser::operator delete (void *address) -{ - memPoolFree(pool, address); -} - -AuthUser::~AuthUser() -{ - auth_user_request_t *auth_user_request; - dlink_node *link, *tmplink; - debug(29, 5) ("AuthUser::~AuthUser: Freeing auth_user '%p' with refcount '%ld'.\n", this, (long int) references); - assert(references == 0); - /* were they linked in by username ? */ - - if (usernamehash) { - assert(usernamehash->user() == this); - debug(29, 5) ("AuthUser::~AuthUser: removing usernamehash entry '%p'\n", usernamehash); - hash_remove_link(proxy_auth_username_cache, - (hash_link *) usernamehash); - /* don't free the key as we use the same user string as the auth_user - * structure */ - delete usernamehash; - } - - /* remove any outstanding requests */ - link = requests.head; - - while (link) { - debug(29, 5) ("AuthUser::~AuthUser: removing request entry '%p'\n", link->data); - auth_user_request = static_cast(link->data); - tmplink = link; - link = link->next; - dlinkDelete(tmplink, &requests); - dlinkNodeDelete(tmplink); - delete auth_user_request; - } - - /* free cached acl results */ - aclCacheMatchFlush(&proxy_match_cache); - - /* free seen ip address's */ - authenticateAuthUserClearIp(this); - - if (scheme_data && auth_module > 0) - authscheme_list[auth_module - 1].FreeUser(this); - - /* prevent accidental reuse */ - auth_type = AUTH_UNKNOWN; -} - -void -AuthUser::cacheInit(void) -{ - if (!proxy_auth_username_cache) { - /* First time around, 7921 should be big enough */ - proxy_auth_username_cache = - hash_create((HASHCMP *) strcmp, 7921, hash_string); - assert(proxy_auth_username_cache); - eventAdd("User Cache Maintenance", cacheCleanup, NULL, Config.authenticateGCInterval, 1); - } -} - -void -AuthUser::CachedACLsReset() -{ - /* - * We walk the hash by username as that is the unique key we use. - * This must complete all at once, because we are ensuring correctness. - */ - AuthUserHashPointer *usernamehash; - auth_user_t *auth_user; - char const *username = NULL; - debug(29, 3) ("AuthUser::CachedACLsReset: Flushing the ACL caches for all users.\n"); - hash_first(proxy_auth_username_cache); - - while ((usernamehash = ((AuthUserHashPointer *) hash_next(proxy_auth_username_cache)))) { - auth_user = usernamehash->user(); - username = auth_user->username(); - /* free cached acl results */ - aclCacheMatchFlush(&auth_user->proxy_match_cache); - - } - - debug(29, 3) ("AuthUser::CachedACLsReset: Finished.\n"); -} - -void -AuthUser::cacheCleanup(void *datanotused) -{ - /* - * We walk the hash by username as that is the unique key we use. - * For big hashs we could consider stepping through the cache, 100/200 - * entries at a time. Lets see how it flys first. - */ - AuthUserHashPointer *usernamehash; - auth_user_t *auth_user; - char const *username = NULL; - debug(29, 3) ("AuthUser::cacheCleanup: Cleaning the user cache now\n"); - debug(29, 3) ("AuthUser::cacheCleanup: Current time: %ld\n", (long int) current_time.tv_sec); - hash_first(proxy_auth_username_cache); - - while ((usernamehash = ((AuthUserHashPointer *) hash_next(proxy_auth_username_cache)))) { - auth_user = usernamehash->user(); - username = auth_user->username(); - - /* if we need to have inpedendent expiry clauses, insert a module call - * here */ - debug(29, 4) ("AuthUser::cacheCleanup: Cache entry:\n\tType: %d\n\tUsername: %s\n\texpires: %ld\n\treferences: %ld\n", auth_user->auth_type, username, (long int) (auth_user->expiretime + Config.authenticateTTL), (long int) auth_user->references); - - if (auth_user->expiretime + Config.authenticateTTL <= current_time.tv_sec) { - debug(29, 5) ("AuthUser::cacheCleanup: Removing user %s from cache due to timeout.\n", username); - /* the minus 1 accounts for the cache lock */ - - if (!(authenticateAuthUserInuse(auth_user) - 1)) - /* we don't warn if we leave the user in the cache, - * because other modules (ie delay pools) may keep - * locks on users, and thats legitimate - */ - authenticateAuthUserUnlock(auth_user); - } - } - - debug(29, 3) ("AuthUser::cacheCleanup: Finished cleaning the user cache.\n"); - eventAdd("User Cache Maintenance", cacheCleanup, NULL, Config.authenticateGCInterval, 1); -} - /* * authenticateUserCacheRestart() cleans all config-dependent data from the * auth_user cache. It DOES NOT Flush the user cache. @@ -1288,7 +991,7 @@ * called to add another auth scheme module */ void -authSchemeAdd(const char *type, AUTHSSETUP * setup) +authSchemeAdd(const char *type) { int i; debug(29, 4) ("authSchemeAdd: adding %s\n", type); @@ -1306,9 +1009,6 @@ memset(&authscheme_list[i + 1], 0, sizeof(authscheme_entry_t)); authscheme_list[i].typestr = type; - - /* Call the scheme module to set up capabilities and initialize any global data */ - setup(&authscheme_list[i]); } /* _auth_user_hash_pointe */ @@ -1353,7 +1053,7 @@ next = NULL; hash_join(proxy_auth_username_cache, (hash_link *) this); /* lock for presence in the cache */ - authenticateAuthUserLock(auth_user); + auth_user->lock(); } AuthUser * @@ -1388,3 +1088,4 @@ { fatal ("unusable\n"); } + --- orig/src/authenticate.h +++ mod/src/authenticate.h @@ -66,52 +66,13 @@ time_t ip_expiretime; }; -class AuthUser -{ - -public: - /* extra fields for proxy_auth */ - /* this determines what scheme owns the user data. */ - auth_type_t auth_type; - /* the index +1 in the authscheme_list to the authscheme entry */ - int auth_module; - /* we only have one username associated with a given auth_user struct */ - auth_user_hash_pointer *usernamehash; - /* we may have many proxy-authenticate strings that decode to the same user */ - dlink_list proxy_auth_list; - dlink_list proxy_match_cache; - /* what ip addresses has this user been seen at?, plus a list length cache */ - dlink_list ip_list; - size_t ipcount; - long expiretime; - /* how many references are outstanding to this instance */ - size_t references; - /* the auth scheme has it's own private data area */ - void *scheme_data; - /* the auth_user_request structures that link to this. Yes it could be a splaytree - * but how many requests will a single username have in parallel? */ - dlink_list requests; - -public: - static void cacheInit (); - static void CachedACLsReset(); - - void absorb(auth_user_t *from); - AuthUser (const char *); - ~AuthUser (); - void *operator new (size_t byteCount); - void operator delete (void *address); - char const *username() const; - -private: - static void cacheCleanup (void *unused); - static MemPool *pool; -}; - /* Per scheme request data ABC */ class ConnStateData; +/* This should be converted into derived classes of AuthUserRequest. + * TODO. XXX. + */ class AuthUserRequestState { @@ -121,12 +82,14 @@ virtual ~AuthUserRequestState(){} virtual int authenticated() const = 0; - virtual void authenticate(HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) = 0; + virtual void authenticate(auth_user_request_t * auth_user_request, HttpRequest * request, ConnStateData::Pointer conn, http_hdr_type type) = 0; virtual int direction() = 0; virtual void addHeader(HttpReply * rep, int accel) {}} ; +class AuthScheme; + class AuthUserRequest { @@ -144,33 +107,31 @@ static auth_acl_t tryToAuthenticateAndSetAuthUser(auth_user_request_t **, http_hdr_type, HttpRequest *, ConnStateData::Pointer, struct in_addr); static void addReplyAuthHeader(HttpReply * rep, auth_user_request_t * auth_user_request, HttpRequest * request, int accelerated, int internal); + AuthUserRequest(); + ~AuthUserRequest(); void *operator new (size_t byteCount); void operator delete (void *address); + void start ( RH * handler, void *data); void setDenyMessage (char const *); char const * getDenyMessage (); size_t refCount() const; - void lock () - - ; + void lock (); void unlock (); char const *username() const; + AuthScheme *scheme() const; + authscheme_entry_t *oldscheme() const; + private: static auth_acl_t authenticate(auth_user_request_t ** auth_user_request, http_hdr_type headertype, HttpRequest * request, ConnStateData::Pointer conn, struct in_addr src_addr); - static auth_user_request_t *createAuthUser (const char *proxy_auth); - static MemPool *pool; - AuthUserRequest(); - - void decodeAuth (const char *proxy_auth); - /* return a message on the 407 error pages */ char *message; @@ -187,31 +148,16 @@ }; /* authenticate.c authenticate scheme routines typedefs */ -typedef int AUTHSACTIVE(void); -typedef int AUTHSAUTHED(auth_user_request_t *); -typedef void AUTHSAUTHUSER(auth_user_request_t *, HttpRequest *, ConnStateData::Pointer, http_hdr_type); -typedef int AUTHSCONFIGURED(void); -typedef void AUTHSDECODE(auth_user_request_t *, const char *); -typedef int AUTHSDIRECTION(auth_user_request_t *); -typedef void AUTHSDUMP(StoreEntry *, const char *, authScheme *); -typedef void AUTHSFIXERR(auth_user_request_t *, HttpReply *, http_hdr_type, HttpRequest *); typedef void AUTHSADDTRAILER(auth_user_request_t *, HttpReply *, int); -typedef void AUTHSFREE(auth_user_t *); -typedef void AUTHSFREECONFIG(authScheme *); -typedef char const *AUTHSUSERNAME(auth_user_t const *); typedef void AUTHSONCLOSEC(ConnStateData *); -typedef void AUTHSPARSE(authScheme *, int, char *); -typedef void AUTHSINIT(authScheme *); typedef void AUTHSREQFREE(auth_user_request_t *); -typedef void AUTHSSETUP(authscheme_entry_t *); -typedef void AUTHSSHUTDOWN(void); typedef void AUTHSSTART(auth_user_request_t *, RH *, void *); +/* TODO: this should be a generic cachemgr API type ? */ typedef void AUTHSSTATS(StoreEntry *); typedef const char *AUTHSCONNLASTHEADER(auth_user_request_t *); /* subsumed by the C++ interface */ extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *); -extern auth_user_t *authenticateAuthUserNew(const char *); /* AuthUserRequest */ extern void authenticateStart(auth_user_request_t *, RH *, void *); @@ -221,6 +167,7 @@ extern size_t authenticateRequestRefCount (auth_user_request_t *); extern char const *authenticateAuthUserRequestMessage(auth_user_request_t *); +extern authscheme_entry_t *authenticateAuthScheme(const char *typestr); extern int authenticateAuthSchemeId(const char *typestr); extern void authenticateSchemeInit(void); extern void authenticateInit(authConfig *); @@ -228,7 +175,6 @@ extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, HttpRequest *, int, int); extern void authenticateAddTrailer(HttpReply *, auth_user_request_t *, HttpRequest *, int); extern void authenticateAuthUserUnlock(auth_user_t * auth_user); -extern void authenticateAuthUserLock(auth_user_t * auth_user); extern void authenticateAuthUserRequestUnlock(auth_user_request_t *); extern void authenticateAuthUserRequestLock(auth_user_request_t *); extern int authenticateAuthUserInuse(auth_user_t * auth_user); @@ -245,17 +191,13 @@ extern int authenticateCheckAuthUserIP(struct in_addr request_src_addr, auth_user_request_t * auth_user); extern int authenticateUserAuthenticated(auth_user_request_t *); extern void authenticateUserCacheRestart(void); -extern char const *authenticateUserRequestUsername(auth_user_request_t *); extern int authenticateValidateUser(auth_user_request_t *); extern void authenticateOnCloseConnection(ConnStateData * conn); -extern void authSchemeAdd(const char *type, AUTHSSETUP * setup); +extern void authSchemeAdd(const char *type); /* AuthUserHashPointer */ extern auth_user_t* authUserHashPointerUser(auth_user_hash_pointer *); -/* auth_modules.c */ -SQUIDCEXTERN void authSchemeSetup(void); - /* * This defines an auth scheme module */ @@ -263,42 +205,11 @@ struct _authscheme_entry { const char *typestr; - AUTHSACTIVE *Active; AUTHSADDTRAILER *AddTrailer; - AUTHSAUTHED *authenticated; - AUTHSAUTHUSER *authAuthenticate; - AUTHSCONFIGURED *configured; - AUTHSDUMP *dump; - AUTHSFIXERR *authFixHeader; - AUTHSFREE *FreeUser; - AUTHSFREECONFIG *freeconfig; - AUTHSUSERNAME *authUserUsername; AUTHSONCLOSEC *oncloseconnection; /*optional */ AUTHSCONNLASTHEADER *authConnLastHeader; - AUTHSDECODE *decodeauth; - AUTHSDIRECTION *getdirection; - AUTHSPARSE *parse; - AUTHSINIT *init; AUTHSREQFREE *requestFree; - AUTHSSHUTDOWN *donefunc; AUTHSSTART *authStart; - AUTHSSTATS *authStats; -}; - -/* - * This is a configured auth scheme - */ - -/* private data types */ - -struct _authScheme -{ - /* pointer to the authscheme_list's string entry */ - const char *typestr; - /* the scheme id in the authscheme_list */ - int Id; - /* the scheme's configuration details. */ - void *scheme_data; }; #endif /* SQUID_AUTHENTICATE_H */ --- orig/src/cache_cf.cc +++ mod/src/cache_cf.cc @@ -35,6 +35,8 @@ #include "squid.h" #include "authenticate.h" +#include "AuthConfig.h" +#include "AuthScheme.h" #include "Store.h" #include "SwapDir.h" #include "ConfigParser.h" @@ -48,6 +50,8 @@ #include "ESIParser.h" #endif +CBDATA_TYPE(peer); + static const char *const T_SECOND_STR = "second"; static const char *const T_MINUTE_STR = "minute"; static const char *const T_HOUR_STR = "hour"; @@ -536,6 +540,7 @@ if (Config.Wais._peer) cbdataFree(Config.Wais._peer); + CBDATA_INIT_TYPE_FREECB(peer, peerDestroy); Config.Wais._peer = cbdataAlloc(peer); Config.Wais._peer->host = xstrdup(Config.Wais.relayHost); @@ -1227,30 +1232,10 @@ } static void -allocate_new_authScheme(authConfig * cfg) -{ - if (cfg->schemes == NULL) { - cfg->n_allocated = 4; - cfg->schemes = static_cast(xcalloc(cfg->n_allocated, sizeof(authScheme))); - } - - if (cfg->n_allocated == cfg->n_configured) { - authScheme *tmp; - cfg->n_allocated <<= 1; - tmp = static_cast(xcalloc(cfg->n_allocated, sizeof(authScheme))); - xmemcpy(tmp, cfg->schemes, cfg->n_configured * sizeof(authScheme)); - xfree(cfg->schemes); - cfg->schemes = tmp; - } -} - -static void parse_authparam(authConfig * config) { char *type_str; char *param_str; - authScheme *scheme = NULL; - int type, i; if ((type_str = strtok(NULL, w_space)) == NULL) self_destruct(); @@ -1258,59 +1243,44 @@ if ((param_str = strtok(NULL, w_space)) == NULL) self_destruct(); - if ((type = authenticateAuthSchemeId(type_str)) == -1) { - debug(3, 0) ("Parsing Config File: Unknown authentication scheme '%s'.\n", type_str); - return; - } - - for (i = 0; i < config->n_configured; i++) { - if (config->schemes[i].Id == type) { - scheme = config->schemes + i; - } - } + /* find a configuration for the scheme */ + AuthConfig *scheme = AuthConfig::Find (type_str); if (scheme == NULL) { - allocate_new_authScheme(config); - scheme = config->schemes + config->n_configured; - config->n_configured++; - scheme->Id = type; - scheme->typestr = authscheme_list[type].typestr; + /* Create a configuration */ + AuthScheme *theScheme; + if ((theScheme = AuthScheme::Find(type_str)) == NULL) { + debug(3, 0) ("Parsing Config File: Unknown authentication scheme '%s'.\n", type_str); + return; + } + config->push_back(theScheme->createConfig()); + scheme = config->back(); + assert (scheme); } - authscheme_list[type].parse(scheme, config->n_configured, param_str); + scheme->parse(scheme, config->size(), param_str); } static void free_authparam(authConfig * cfg) { - authScheme *scheme; - int i; + AuthConfig *scheme; /* DON'T FREE THESE FOR RECONFIGURE */ if (reconfiguring) return; - for (i = 0; i < cfg->n_configured; i++) { - scheme = cfg->schemes + i; - authscheme_list[scheme->Id].freeconfig(scheme); + while (cfg->size()) { + scheme = cfg->pop_back(); + scheme->done(); } - - safe_free(cfg->schemes); - cfg->schemes = NULL; - cfg->n_allocated = 0; - cfg->n_configured = 0; } static void dump_authparam(StoreEntry * entry, const char *name, authConfig cfg) { - authScheme *scheme; - int i; - - for (i = 0; i < cfg.n_configured; i++) { - scheme = cfg.schemes + i; - authscheme_list[scheme->Id].dump(entry, name, scheme); - } + for (authConfig::iterator i = cfg.begin(); i != cfg.end(); ++i) + (*i)->dump(entry, name, (*i)); } void @@ -1501,6 +1471,7 @@ char *token = NULL; peer *p; int i; + CBDATA_INIT_TYPE_FREECB(peer, peerDestroy); p = cbdataAlloc(peer); p->http_port = CACHE_HTTP_PORT; p->icp.port = CACHE_ICP_PORT; --- orig/src/cbdata.cc +++ mod/src/cbdata.cc @@ -245,7 +245,6 @@ CREATE_CBDATA(helper_server); CREATE_CBDATA(statefulhelper); CREATE_CBDATA(helper_stateful_server); - CREATE_CBDATA_FREE(peer, peerDestroy); CREATE_CBDATA(ps_state); CREATE_CBDATA(RemovalPolicy); CREATE_CBDATA(RemovalPolicyWalker); --- orig/src/client_side.cc +++ mod/src/client_side.cc @@ -466,15 +466,15 @@ aLogEntry->cache.extuser = request->extacl_user.buf(); if (request->auth_user_request) { - if (authenticateUserRequestUsername(request->auth_user_request)) + + if (request->auth_user_request->username()) aLogEntry->cache.authuser = - xstrdup(authenticateUserRequestUsername(request->auth_user_request)); + xstrdup(request->auth_user_request->username()); authenticateAuthUserRequestUnlock(request->auth_user_request); request->auth_user_request = NULL; } - } void --- orig/src/enums.h +++ mod/src/enums.h @@ -661,7 +661,6 @@ CBDATA_helper_server, CBDATA_statefulhelper, CBDATA_helper_stateful_server, - CBDATA_peer, CBDATA_ps_state, CBDATA_RemovalPolicy, CBDATA_RemovalPolicyWalker, --- orig/src/external_acl.cc +++ mod/src/external_acl.cc @@ -710,7 +710,8 @@ switch (format->type) { case _external_acl_format::EXT_ACL_LOGIN: - str = authenticateUserRequestUsername(ch->auth_user_request); + assert (ch->auth_user_request); + str = ch->auth_user_request->username(); break; #if USE_IDENT --- orig/src/http.cc +++ mod/src/http.cc @@ -1273,7 +1273,7 @@ const char *username = "-"; if (orig_request->auth_user_request) - username = authenticateUserRequestUsername(orig_request->auth_user_request); + username = orig_request->auth_user_request->username(); else if (orig_request->extacl_user.size()) username = orig_request->extacl_user.buf(); --- orig/src/redirect.cc +++ mod/src/redirect.cc @@ -153,7 +153,7 @@ r->client_addr = conn.getRaw() != NULL ? conn->log_addr : no_addr; if (http->request->auth_user_request) - r->client_ident = authenticateUserRequestUsername(http->request->auth_user_request); + r->client_ident = http->request->auth_user_request->username(); else if (conn.getRaw() != NULL && conn->rfc931[0]) { r->client_ident = conn->rfc931; } else { --- orig/src/structs.h +++ mod/src/structs.h @@ -206,13 +206,6 @@ #include "DelayConfig.h" #endif -struct _authConfig -{ - authScheme *schemes; - int n_allocated; - int n_configured; -}; - struct _RemovalPolicySettings { char *type; --- orig/src/tools.cc +++ mod/src/tools.cc @@ -1070,12 +1070,6 @@ memBufClean(&mb); } -int -stringHasWhitespace(const char *s) -{ - return strpbrk(s, w_space) != NULL; -} - void linklistPush(link_list ** L, void *p) { @@ -1134,22 +1128,6 @@ return -1; } -int -stringHasCntl(const char *s) -{ - unsigned char c; - - while ((c = (unsigned char) *s++) != '\0') { - if (c <= 0x1f) - return 1; - - if (c >= 0x7f && c <= 0x9f) - return 1; - } - - return 0; -} - void parseEtcHosts(void) { @@ -1260,90 +1238,6 @@ return 0; /* NOT REACHED */ } -/* - * Similar to strtok, but has some rudimentary knowledge - * of quoting - */ -char * -strwordtok(char *buf, char **t) -{ - unsigned char *word = NULL; - unsigned char *p = (unsigned char *) buf; - unsigned char *d; - unsigned char ch; - int quoted = 0; - - if (!p) - p = (unsigned char *) *t; - - if (!p) - goto error; - - while (*p && isspace(*p)) - p++; - - if (!*p) - goto error; - - word = d = p; - - while ((ch = *p)) { - switch (ch) { - - case '\\': - p++; - - switch (*p) { - - case 'n': - ch = '\n'; - - break; - - case 'r': - ch = '\r'; - - break; - - default: - ch = *p; - - break; - - } - - *d++ = ch; - - if (ch) - p++; - - break; - - case '"': - quoted = !quoted; - - p++; - - break; - - default: - if (!quoted && isspace(*p)) { - p++; - goto done; - } - - *d++ = *p++; - break; - } - } - -done: - *d++ = '\0'; - -error: - *t = (char *) p; - return (char *) word; -} /* * Inverse of strwordtok. Quotes a word if needed --- orig/src/typedefs.h +++ mod/src/typedefs.h @@ -69,7 +69,10 @@ typedef struct _authscheme_entry authscheme_entry_t; -typedef struct _authScheme authScheme; +/* temporary: once Config is fully hidden, this shouldn't be needed */ +#include "Array.h" +class AuthConfig; +typedef Vector authConfig; typedef struct _acl_snmp_comm acl_snmp_comm; @@ -209,8 +212,6 @@ typedef struct _storeSwapLogData storeSwapLogData; -typedef struct _authConfig authConfig; - typedef struct _cacheSwap cacheSwap; typedef struct _StatHist StatHist; --- orig/test-suite/Makefile.am +++ mod/test-suite/Makefile.am @@ -50,19 +50,16 @@ syntheticoperators \ VirtualDeleteOperator -LDADD = -L$(top_builddir)/lib -lmiscutil +LDADD =$(top_builddir)/src/globals.o -L$(top_builddir)/lib -lmiscutil DEBUG_SOURCE = test_tools.cc -DEBUG_OBJECTS = $(top_builddir)/src/globals.o debug_SOURCES = debug.cc $(DEBUG_SOURCE) -debug_LDADD = $(DEBUG_OBJECTS) $(LDADD) ESIExpressions_SOURCES = ESIExpressions.cc $(DEBUG_SOURCE) ESIExpressions_LDADD = $(top_builddir)/src/ESIExpression.o \ - $(DEBUG_OBJECTS) $(LDADD) + $(LDADD) mem_node_test_SOURCES = mem_node_test.cc mem_node_test_LDADD = $(top_builddir)/src/mem_node.o $(LDADD) mem_hdr_test_SOURCES = mem_hdr_test.cc $(DEBUG_SOURCE) mem_hdr_test_LDADD = $(top_builddir)/src/stmem.o \ - $(DEBUG_OBJECTS) \ $(top_builddir)/src/mem_node.o $(LDADD) MemPoolTest_SOURCES = MemPoolTest.cc refcount_SOURCES = refcount.cc @@ -74,12 +71,11 @@ $(top_builddir)/src/Packer.o \ $(top_builddir)/src/String.o \ $(top_builddir)/src/mem.o \ - $(DEBUG_OBJECTS) $(LDADD) + $(LDADD) splay_SOURCES = splay.cc StackTest_SOURCES = StackTest.cc $(DEBUG_SOURCE) - syntheticoperators_SOURCES = syntheticoperators.cc $(DEBUG_SOURCE) VirtualDeleteOperator_SOURCES = VirtualDeleteOperator.cc $(DEBUG_SOURCE) --- orig/test-suite/MemPoolTest.cc +++ mod/test-suite/MemPoolTest.cc @@ -43,7 +43,6 @@ std::cout << "Assertion failed: (" << msg << ") at " << file << ":" << line << std::endl; exit (1); } -time_t squid_curtime = 0; class MemPoolTest { public: --- orig/test-suite/mem_node_test.cc +++ mod/test-suite/mem_node_test.cc @@ -45,8 +45,6 @@ exit (1); } -time_t squid_curtime = 0; - int main (int argc, char *argv) { --- orig/test-suite/test_tools.cc +++ mod/test-suite/test_tools.cc @@ -120,6 +120,41 @@ exit (1); } +/* used by fatalf */ +static void +fatalvf(const char *fmt, va_list args) { + static char fatal_str[BUFSIZ]; + vsnprintf(fatal_str, sizeof(fatal_str), fmt, args); + fatal(fatal_str); +} + +/* printf-style interface for fatal */ +#if STDC_HEADERS +void +fatalf(const char *fmt,...) +{ + va_list args; + va_start(args, fmt); +#else +void +fatalf(va_alist) +va_dcl +{ + va_list args; + const char *fmt = NULL; + va_start(args); + fmt = va_arg(args, char *); +#endif + + fatalvf(fmt, args); + va_end(args); +} + +void +debug_trap(const char *message) { + fatal(message); +} + std::ostream & Debug::getDebugOut() { @@ -137,3 +172,93 @@ } std::ostringstream *Debug::CurrentDebug (NULL); + +MemPool *dlink_node_pool = NULL; + +dlink_node * +dlinkNodeNew() +{ + if (dlink_node_pool == NULL) + dlink_node_pool = memPoolCreate("Dlink list nodes", sizeof(dlink_node)); + + /* where should we call memPoolDestroy(dlink_node_pool); */ + return (dlink_node *)memPoolAlloc(dlink_node_pool); +} + +/* the node needs to be unlinked FIRST */ +void +dlinkNodeDelete(dlink_node * m) +{ + if (m == NULL) + return; + + memPoolFree(dlink_node_pool, m); +} + +void +dlinkAdd(void *data, dlink_node * m, dlink_list * list) +{ + m->data = data; + m->prev = NULL; + m->next = list->head; + + if (list->head) + list->head->prev = m; + + list->head = m; + + if (list->tail == NULL) + list->tail = m; +} + +void +dlinkAddAfter(void *data, dlink_node * m, dlink_node * n, dlink_list * list) +{ + m->data = data; + m->prev = n; + m->next = n->next; + + if (n->next) + n->next->prev = m; + else { + assert(list->tail == n); + list->tail = m; + } + + n->next = m; +} + +void +dlinkAddTail(void *data, dlink_node * m, dlink_list * list) +{ + m->data = data; + m->next = NULL; + m->prev = list->tail; + + if (list->tail) + list->tail->next = m; + + list->tail = m; + + if (list->head == NULL) + list->head = m; +} + +void +dlinkDelete(dlink_node * m, dlink_list * list) +{ + if (m->next) + m->next->prev = m->prev; + + if (m->prev) + m->prev->next = m->next; + + if (m == list->head) + list->head = m->next; + + if (m == list->tail) + list->tail = m->prev; + + m->next = m->prev = NULL; +} + --- orig/{arch}/=tagging-method +++ mod/{arch}/=tagging-method @@ -1,6 +1,7 @@ -explicit +tagline untagged-source precious backup ^.*(~|\.~[0-9]+~|\.bak|\.orig|\.rej|\.original|\.modified|\.reject|\.#.*)$ precious ^(\+.*|\.gdbinit|=build\.*|=install\.*|CVS\.adm|RCS|RCSLOG|SCCS|TAGS|\.cvsignore|CVS|autom4te\.cache|Makefile.in|aclocal.m4|configure|compile|config.guess|config.sub|install-sh|missing|depcomp|mkinstalldirs)$ +precious ^\..*\.swp$ source ^([_=a-zA-Z0-9].*|\.arch-ids|\{arch\}|\.arch-project-tree)$ exclude ^(.arch-ids|\{arch\})$ --- orig/{arch}/squid/squid--HEAD/squid--HEAD--3.0/robertc@squid-cache.org--squid/patch-log/patch-76 +++ mod/{arch}/squid/squid--HEAD/squid--HEAD--3.0/robertc@squid-cache.org--squid/patch-log/patch-76 @@ -47,7 +47,7 @@ src/Makefile.am src/Makefile.in src/auth/Makefile.in src/client_side.cc src/comm.cc src/comm.h src/fs/Makefile.in src/ftp.cc src/protos.h src/repl/Makefile.in src/typedefs.h - test-suite/Makefile.in {arch}/=default-version~ + test-suite/Makefile.in New-patches: robertc@squid-cache.org--squid/squid--HEAD--3.0--patch-76 robertc@squid-cache.org--squid/squid--comms--3.0--base-0 robertc@squid-cache.org--squid/squid--comms--3.0--patch-1 --- orig/{arch}/squid/squid--comms/squid--comms--3.0/robertc@squid-cache.org--squid/patch-log/patch-1 +++ mod/{arch}/squid/squid--comms/squid--comms--3.0/robertc@squid-cache.org--squid/patch-log/patch-1 @@ -36,7 +36,6 @@ lib/Makefile.in scripts/Makefile.in snmplib/Makefile.in src/Makefile.in src/auth/Makefile.in src/fs/Makefile.in src/repl/Makefile.in test-suite/Makefile.in - {arch}/=default-version New-patches: robertc@squid-cache.org--squid/squid--comms--3.0--patch-1 Bootstrapped.