diff --git a/SOURCES/Add-option-to-control-timeout-for-Basic-Auth.patch b/SOURCES/Add-option-to-control-timeout-for-Basic-Auth.patch new file mode 100644 index 0000000..1f70a64 --- /dev/null +++ b/SOURCES/Add-option-to-control-timeout-for-Basic-Auth.patch @@ -0,0 +1,372 @@ +From b4ddd657ccc7793df9378209433f0142195a94d1 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 14 May 2020 09:19:37 -0400 +Subject: [PATCH] Add option to control timeout for Basic Auth + +Adds new option and tests. +Adds optional dependency on libfaketime to test this feature. + +Fixes: #210 +Signed-off-by: Simo Sorce +Merges: #217 +Reviewed-by: Robbie Harwood +(cherry picked from commit 09df7584b4abadbfea411adafdcc825da5b720d3) +[rharwood@redhat.com: git got confused by not having localname test] +--- + README | 24 +++++++++++++ + src/mod_auth_gssapi.c | 27 +++++++++++--- + src/mod_auth_gssapi.h | 1 + + tests/Makefile.am | 1 + + tests/httpd.conf | 32 ++++++++++++++++- + tests/magtests.py | 76 ++++++++++++++++++++++++++++++++++++++++ + tests/t_basic_timeout.py | 34 ++++++++++++++++++ + 7 files changed, 190 insertions(+), 5 deletions(-) + create mode 100755 tests/t_basic_timeout.py + +diff --git a/README b/README +index 700b57e..5eac94f 100644 +--- a/README ++++ b/README +@@ -97,6 +97,7 @@ Configuration Directives + [GssapiAllowedMech](#gssapiallowedmech)
+ [GssapiBasicAuth](#gssapibasicauth)
+ [GssapiBasicAuthMech](#gssapibasicauthmech)
++[GssapiBasicTicketTimeout](#gssapibasicticketvalidity)
+ [GssapiConnectionBound](#gssapiconnectionbound)
+ [GssapiCredStore](#gssapicredstore)
+ [GssapiDelegCcacheDir](#gssapidelegccachedir)
+@@ -503,3 +504,26 @@ Note: The GSS_C_NT_HOSTBASED_SERVICE format is used for names (see example). + GssapiAcceptorName HTTP@www.example.com + + ++### GssapiBasicTicketTimeout ++ ++This option controls the ticket validity time requested for the user TGT by the ++Basic Auth method. ++ ++Normally basic auth is repeated by the browser on each request so a short ++validity period is used to reduce the scope of the ticket as it will be ++replaced quickly. ++However in cases where the authentication page is separate and the session ++is used by other pages the validity can be changed to arbitrary duration. ++ ++Note: the validity of a ticket is still capped by KDC configuration. ++ ++Note: the value is specified in seconds. ++ ++- **Default:** GssapiBasicTicketTimeout 300 ++ ++#### Example ++ GssapiBasicTicketTimeout 36000 ++ ++Sets ticket/session validity to 10 hours. ++ ++ +diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c +index 9e42ef4..b099973 100644 +--- a/src/mod_auth_gssapi.c ++++ b/src/mod_auth_gssapi.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) 2014, 2016 mod_auth_gssapi contributors - See COPYING for (C) terms */ ++/* Copyright (C) 2014, 2016, 2020 mod_auth_gssapi contributors ++ * See COPYING for (C) terms */ + + #include "mod_auth_gssapi.h" + #include "mag_parse.h" +@@ -600,7 +601,7 @@ static int mag_auth_basic(struct mag_req_cfg *req_cfg, struct mag_conn *mc, + } + + maj = gss_acquire_cred_with_password(&min, user, &ba_pwd, +- GSS_C_INDEFINITE, ++ cfg->basic_timeout, + allowed_mechs, + GSS_C_INITIATE, + &user_cred, &actual_mechs, NULL); +@@ -619,8 +620,8 @@ static int mag_auth_basic(struct mag_req_cfg *req_cfg, struct mag_conn *mc, + + for (int i = 0; i < actual_mechs->count; i++) { + maj = mag_context_loop(&min, req, cfg, user_cred, server_cred, +- &actual_mechs->elements[i], 300, &client, +- &vtime, &delegated_cred); ++ &actual_mechs->elements[i], cfg->basic_timeout, ++ &client, &vtime, &delegated_cred); + if (maj == GSS_S_COMPLETE) { + ret = mag_complete(req_cfg, mc, client, &actual_mechs->elements[i], + vtime, delegated_cred); +@@ -1299,6 +1300,7 @@ static void *mag_create_dir_config(apr_pool_t *p, char *dir) + #ifdef HAVE_CRED_STORE + cfg->ccname_envvar = "KRB5CCNAME"; + #endif ++ cfg->basic_timeout = 300; + + return cfg; + } +@@ -1789,6 +1791,21 @@ static const char *mag_acceptor_name(cmd_parms *parms, void *mconfig, + return NULL; + } + ++static const char *mag_basic_timeout(cmd_parms *parms, void *mconfig, ++ const char *w) ++{ ++ struct mag_config *cfg = (struct mag_config *)mconfig; ++ unsigned long int value; ++ ++ value = strtoul(w, NULL, 10); ++ if (value >= UINT32_MAX) { ++ cfg->basic_timeout = GSS_C_INDEFINITE; ++ return NULL; ++ } ++ cfg->basic_timeout = value; ++ return NULL; ++} ++ + static void *mag_create_server_config(apr_pool_t *p, server_rec *s) + { + struct mag_server_config *scfg; +@@ -1865,6 +1882,8 @@ static const command_rec mag_commands[] = { + "Publish GSSAPI Errors in Envionment Variables"), + AP_INIT_RAW_ARGS("GssapiAcceptorName", mag_acceptor_name, NULL, OR_AUTHCFG, + "Name of the acceptor credentials."), ++ AP_INIT_TAKE1("GssapiBasicTicketTimeout", mag_basic_timeout, NULL, ++ OR_AUTHCFG, "Ticket Validity Timeout with Basic Auth."), + { NULL } + }; + +diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h +index 8c0b972..2312ab5 100644 +--- a/src/mod_auth_gssapi.h ++++ b/src/mod_auth_gssapi.h +@@ -93,6 +93,7 @@ struct mag_config { + int enverrs; + gss_name_t acceptor_name; + bool acceptor_name_from_req; ++ uint32_t basic_timeout; + }; + + struct mag_server_config { +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 16d87e9..c830e95 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -11,6 +11,7 @@ EXTRA_DIST = \ + t_basic_k5.py \ + t_basic_k5_two_users.py \ + t_basic_proxy.py \ ++ t_basic_timeout.py \ + t_localname.py \ + t_hostname_acceptor.py \ + t_nonego.py \ +diff --git a/tests/httpd.conf b/tests/httpd.conf +index 8c91e1c..f76f2b6 100644 +--- a/tests/httpd.conf ++++ b/tests/httpd.conf +@@ -111,7 +111,7 @@ DocumentRoot "{HTTPROOT}/html" + PidFile "{HTTPROOT}/logs/httpd.pid" + + +-LogFormat "%h %l %u %t \"%r\" %>s %b \"%{{Referer}}i\" \"%{{User-Agent}}i\"" combined ++LogFormat "%h %l %u %t \"%r\" %>s %b \"%{{Referer}}i\" \"%{{User-Agent}}i\" \"%{{Cookie}}i\"" combined + CustomLog "logs/access_log" combined + + +@@ -288,3 +288,33 @@ CoreDumpDirectory "{HTTPROOT}" + Require valid-user + + ++ ++ ++ Options +Includes ++ AddOutputFilter INCLUDES .html ++ AuthType GSSAPI ++ AuthName "Password Login" ++ GssapiSSLonly Off ++ GssapiUseSessions On ++ Session On ++ SessionCookieName gssapi_session path=/basic_auth_timeout;httponly ++ GssapiSessionKey file:{HTTPROOT}/session.key ++ GssapiCredStore keytab:{HTTPROOT}/http.keytab ++ GssapiBasicAuth On ++ GssapiBasicAuthMech krb5 ++ GssapiBasicTicketTimeout 400 ++ GssapiDelegCcacheDir {HTTPROOT} ++ Require valid-user ++ ++ ++ Options +Includes ++ AddOutputFilter INCLUDES .html ++ AuthType GSSAPI ++ AuthName "Session Login" ++ GssapiSSLonly Off ++ GssapiUseSessions On ++ Session On ++ SessionCookieName gssapi_session path=/basic_auth_timeout;httponly ++ GssapiSessionKey file:{HTTPROOT}/session.key ++ Require valid-user ++ +diff --git a/tests/magtests.py b/tests/magtests.py +index a4842a0..da1cca7 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -3,11 +3,13 @@ + + import argparse + import os ++import os.path + import random + import shutil + import signal + import subprocess + import sys ++import time + import traceback + + # check that we can import requests (for use in test scripts) +@@ -341,6 +343,7 @@ USR_PWD_2 = "magpwd2" + USR_NAME_3 = "maguser3" + SVC_KTNAME = "httpd/http.keytab" + KEY_TYPE = "aes256-cts-hmac-sha1-96:normal" ++USR_NAME_4 = "timeoutusr" + + + def setup_keys(tesdir, env): +@@ -361,6 +364,9 @@ def setup_keys(tesdir, env): + cmd = "addprinc -pw %s -e %s %s" % (USR_PWD_2, KEY_TYPE, USR_NAME_2) + kadmin_local(cmd, env, logfile) + ++ cmd = "addprinc -pw %s -e %s %s" % (USR_PWD, KEY_TYPE, USR_NAME_4) ++ kadmin_local(cmd, env, logfile) ++ + # alias for multinamed hosts testing + alias_name = "HTTP/%s" % WRAP_ALIASNAME + cmd = "addprinc -randkey -e %s %s" % (KEY_TYPE, alias_name) +@@ -600,6 +606,30 @@ def test_basic_auth_krb5(testdir, testenv, logfile): + return error_count + + ++def test_basic_auth_timeout(testdir, testenv, logfile): ++ httpdir = os.path.join(testdir, 'httpd') ++ timeoutdir = os.path.join(httpdir, 'html', 'basic_auth_timeout') ++ os.mkdir(timeoutdir) ++ authdir = os.path.join(timeoutdir, 'auth') ++ os.mkdir(authdir) ++ sessdir = os.path.join(timeoutdir, 'session') ++ os.mkdir(sessdir) ++ shutil.copy('tests/index.html', os.path.join(authdir)) ++ shutil.copy('tests/index.html', os.path.join(sessdir)) ++ ++ basictout = subprocess.Popen(["tests/t_basic_timeout.py"], ++ stdout=logfile, stderr=logfile, ++ env=testenv, preexec_fn=os.setsid) ++ basictout.wait() ++ if basictout.returncode != 0: ++ sys.stderr.write('BASIC Timeout Behavior: FAILED\n') ++ return 1 ++ else: ++ sys.stderr.write('BASIC Timeout Behavior: SUCCESS\n') ++ ++ return 0 ++ ++ + def test_bad_acceptor_name(testdir, testenv, logfile): + bandir = os.path.join(testdir, 'httpd', 'html', 'bad_acceptor_name') + os.mkdir(bandir) +@@ -661,6 +691,33 @@ def test_hostname_acceptor(testdir, testenv, logfile): + return 0 + + ++def faketime_setup(testenv): ++ libfaketime = '/usr/lib64/faketime/libfaketime.so.1' ++ # optional faketime ++ if not os.path.isfile(libfaketime): ++ raise NotImplementedError ++ ++ # spedup x100 ++ fakeenv = {'FAKETIME': '+0 x100'} ++ fakeenv.update(testenv) ++ fakeenv['LD_PRELOAD'] = ' '.join((testenv['LD_PRELOAD'], libfaketime)) ++ return fakeenv ++ ++ ++def http_restart(testdir, so_dir, testenv): ++ ++ httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin', ++ 'MALLOC_CHECK_': '3', ++ 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} ++ httpenv.update(testenv) ++ ++ httpd = "httpd" if os.path.exists("/etc/httpd/modules") else "apache2" ++ config = os.path.join(testdir, 'httpd', 'httpd.conf') ++ httpproc = subprocess.Popen([httpd, '-DFOREGROUND', '-f', config], ++ env=httpenv, preexec_fn=os.setsid) ++ return httpproc ++ ++ + if __name__ == '__main__': + args = parse_args() + +@@ -722,6 +779,25 @@ if __name__ == '__main__': + errs += test_basic_auth_krb5(testdir, testenv, logfile) + + errs += test_no_negotiate(testdir, testenv, logfile) ++ ++ # After this point we need to speed up httpd to test creds timeout ++ try: ++ fakeenv = faketime_setup(kdcenv) ++ timeenv = {'TIMEOUT_USER': USR_NAME_4, ++ 'MAG_USER_PASSWORD': USR_PWD} ++ timeenv.update(fakeenv) ++ curporc = httpproc ++ pid = processes['HTTPD(%d)' % httpproc.pid].pid ++ os.killpg(pid, signal.SIGTERM) ++ time.sleep(1) ++ del processes['HTTPD(%d)' % httpproc.pid] ++ httpproc = http_restart(testdir, so_dir, timeenv) ++ processes['HTTPD(%d)' % httpproc.pid] = httpproc ++ ++ errs += test_basic_auth_timeout(testdir, timeenv, logfile) ++ except NotImplementedError: ++ sys.stderr.write('BASIC Timeout Behavior: SKIPPED\n') ++ + except Exception: + traceback.print_exc() + finally: +diff --git a/tests/t_basic_timeout.py b/tests/t_basic_timeout.py +new file mode 100755 +index 0000000..983dfd2 +--- /dev/null ++++ b/tests/t_basic_timeout.py +@@ -0,0 +1,34 @@ ++#!/usr/bin/env python ++# Copyright (C) 2020 - mod_auth_gssapi contributors, see COPYING for license. ++ ++import os ++import time ++ ++import requests ++from requests.auth import HTTPBasicAuth ++ ++ ++if __name__ == '__main__': ++ s = requests.Session() ++ url = 'http://{}/basic_auth_timeout/auth/'.format( ++ os.environ['NSS_WRAPPER_HOSTNAME'] ++ ) ++ url2 = 'http://{}/basic_auth_timeout/session/'.format( ++ os.environ['NSS_WRAPPER_HOSTNAME'] ++ ) ++ ++ r = s.get(url, auth=HTTPBasicAuth(os.environ['TIMEOUT_USER'], ++ os.environ['MAG_USER_PASSWORD'])) ++ if r.status_code != 200: ++ raise ValueError('Basic Auth Failed') ++ ++ time.sleep(301) ++ r = s.get(url2) ++ if r.status_code != 200: ++ raise ValueError('Session Auth Failed') ++ ++ time.sleep(401) ++ ++ r = s.get(url2) ++ if r.status_code == 200: ++ raise ValueError('Timeout check Failed') diff --git a/SOURCES/Fix-PATH-handling-bug-in-test-suite.patch b/SOURCES/Fix-PATH-handling-bug-in-test-suite.patch new file mode 100644 index 0000000..97957e0 --- /dev/null +++ b/SOURCES/Fix-PATH-handling-bug-in-test-suite.patch @@ -0,0 +1,28 @@ +From c26b1aafbb9679b19b630a46eeb35a9dee61a95f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 13 Oct 2020 11:04:00 -0400 +Subject: [PATCH] Fix PATH handling bug in test suite + +virtualenv relies on its executable being ahead of the system ones. For +setting up the KDC, we don't have a preferencee - we just need the sbins +to be available. + +Signed-off-by: Robbie Harwood +(cherry picked from commit ae07252e356d8142ddd3987c9c3686ba7ee593de) +--- + tests/magtests.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/magtests.py b/tests/magtests.py +index e04fa65..082c6e4 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -312,7 +312,7 @@ def setup_kdc(testdir, wrapenv): + + kdcenv = wrapenv.copy() + kdcenv.update({ +- 'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', ++ 'PATH': f'{wrapenv["PATH"]}:/sbin:/bin:/usr/sbin:/usr/bin', + 'KRB5_CONFIG': krb5conf, + 'KRB5_KDC_PROFILE': kdcconf, + 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log'), diff --git a/SOURCES/Fix-distcheck.patch b/SOURCES/Fix-distcheck.patch new file mode 100644 index 0000000..a18e7c3 --- /dev/null +++ b/SOURCES/Fix-distcheck.patch @@ -0,0 +1,31 @@ +From 706494bde5c5124621006b857fc55529f9e8e0db Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 14 May 2020 18:04:47 -0400 +Subject: [PATCH] Fix distcheck + +Signed-off-by: Simo Sorce +Reviewed-by: Robbie Harwood +(cherry picked from commit eb6de7e946d7ecc9292bb454d43ac05f0801adf7) +--- + tests/Makefile.am | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 70754fb..16d87e9 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -4,12 +4,14 @@ EXTRA_DIST = \ + 401.html \ + httpd.conf \ + index.html \ ++ localname.html \ + magtests.py \ + t_bad_acceptor_name.py \ + t_basic_k5_fail_second.py \ + t_basic_k5.py \ + t_basic_k5_two_users.py \ + t_basic_proxy.py \ ++ t_localname.py \ + t_hostname_acceptor.py \ + t_nonego.py \ + t_required_name_attr.py \ diff --git a/SOURCES/Fix-mag_auth_basic-function-call.patch b/SOURCES/Fix-mag_auth_basic-function-call.patch new file mode 100644 index 0000000..1f81a73 --- /dev/null +++ b/SOURCES/Fix-mag_auth_basic-function-call.patch @@ -0,0 +1,121 @@ +From 1941fd1545b4786fee9464881239d74a91c55723 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 7 Feb 2019 14:48:56 -0500 +Subject: [PATCH] Fix mag_auth_basic function call. + +In order to respect the API we'd have to return nech_type as a copy of +the mech found to correctly complete authentication. +It would need to be a copy because the actual_mechs variable is an array +of statically copied OIDs not an array of pointers. + +Instead change mag_auth_basic to directly call mag_complete() and +mag_cache_basic on success. This is easier than attempting to handle +copying out OIDs and then freeing them in the caller as GSSAPI does not +offer standard APIs for copying OIDs. + +As a side-effect we reduce the number of arguments to mag_auth_gssapi, +which is good, to the slight detriment of legibility in the main +function as now you need to know mag_auth_basic() is already calling +mag_complete(). The trade off is worth it though. + +Signed-off-by: Simo Sorce +(cherry picked from commit 318db0b0e3777d4cfdc09eeef98e28c478607271) +--- + src/mod_auth_gssapi.c | 47 ++++++++++++++++++++----------------------- + 1 file changed, 22 insertions(+), 25 deletions(-) + +diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c +index 4048ee7..9e42ef4 100644 +--- a/src/mod_auth_gssapi.c ++++ b/src/mod_auth_gssapi.c +@@ -493,15 +493,15 @@ done: + return maj; + } + +-static bool mag_auth_basic(request_rec *req, +- struct mag_config *cfg, +- gss_buffer_desc ba_user, +- gss_buffer_desc ba_pwd, +- gss_name_t *client, +- gss_OID *mech_type, +- gss_cred_id_t *delegated_cred, +- uint32_t *vtime) ++static int mag_complete(struct mag_req_cfg *req_cfg, struct mag_conn *mc, ++ gss_name_t client, gss_OID mech_type, ++ uint32_t vtime, gss_cred_id_t delegated_cred); ++ ++static int mag_auth_basic(struct mag_req_cfg *req_cfg, struct mag_conn *mc, ++ gss_buffer_desc ba_user, gss_buffer_desc ba_pwd) + { ++ struct mag_config *cfg = req_cfg->cfg; ++ request_rec *req = req_cfg->req; + const char *user_ccache = NULL; + const char *orig_ccache = NULL; + long long unsigned int rndname; +@@ -512,9 +512,12 @@ static bool mag_auth_basic(request_rec *req, + gss_OID_set allowed_mechs; + gss_OID_set filtered_mechs; + gss_OID_set actual_mechs = GSS_C_NO_OID_SET; ++ gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL; ++ gss_name_t client = GSS_C_NO_NAME; ++ uint32_t vtime; + uint32_t maj, min; + int present = 0; +- bool ret = false; ++ int ret = HTTP_UNAUTHORIZED; + + maj = gss_import_name(&min, &ba_user, GSS_C_NT_USER_NAME, &user); + if (GSS_ERROR(maj)) { +@@ -616,15 +619,21 @@ static bool mag_auth_basic(request_rec *req, + + for (int i = 0; i < actual_mechs->count; i++) { + maj = mag_context_loop(&min, req, cfg, user_cred, server_cred, +- &actual_mechs->elements[i], 300, client, vtime, +- delegated_cred); ++ &actual_mechs->elements[i], 300, &client, ++ &vtime, &delegated_cred); + if (maj == GSS_S_COMPLETE) { +- ret = true; ++ ret = mag_complete(req_cfg, mc, client, &actual_mechs->elements[i], ++ vtime, delegated_cred); ++ if (ret == OK) { ++ mag_basic_cache(req_cfg, mc, ba_user, ba_pwd); ++ } + break; + } + } + + done: ++ gss_release_cred(&min, &delegated_cred); ++ gss_release_name(&min, &client); + gss_release_cred(&min, &server_cred); + gss_release_name(&min, &user); + gss_release_cred(&min, &user_cred); +@@ -683,10 +692,6 @@ struct mag_req_cfg *mag_init_cfg(request_rec *req) + return req_cfg; + } + +-static int mag_complete(struct mag_req_cfg *req_cfg, struct mag_conn *mc, +- gss_name_t client, gss_OID mech_type, +- uint32_t vtime, gss_cred_id_t delegated_cred); +- + #ifdef HAVE_CRED_STORE + static bool use_s4u2proxy(struct mag_req_cfg *req_cfg) { + if (req_cfg->cfg->use_s4u2proxy) { +@@ -1105,15 +1110,7 @@ static int mag_auth(request_rec *req) + #endif + + if (auth_type == AUTH_TYPE_BASIC) { +- if (mag_auth_basic(req, cfg, ba_user, ba_pwd, +- &client, &mech_type, +- &delegated_cred, &vtime)) { +- +- ret = mag_complete(req_cfg, mc, client, mech_type, vtime, +- delegated_cred); +- if (ret == OK) +- mag_basic_cache(req_cfg, mc, ba_user, ba_pwd); +- } ++ ret = mag_auth_basic(req_cfg, mc, ba_user, ba_pwd); + goto done; + } + diff --git a/SOURCES/Move-to-python3-by-default.patch b/SOURCES/Move-to-python3-by-default.patch new file mode 100644 index 0000000..675f76f --- /dev/null +++ b/SOURCES/Move-to-python3-by-default.patch @@ -0,0 +1,198 @@ +From eeca34dc64804a4b771800f54f0e0647ce88bdd4 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 13 Oct 2020 10:33:39 -0400 +Subject: [PATCH] Move to python3 by default + +When moving 2 -> 3, python elected to keep "python" as the name of the +python2 interpreter. As a result, python3-only machines have no +/usr/bin/python. Since python2 is EOL, it should be safe to make our +scripting default to python3. + +Signed-off-by: Robbie Harwood +(cherry picked from commit 840863f89ed4809602f1ca7b8ad650c0b979d20e) +[rharwood@redhat.com: tests that don't exist yet, README prg/prk, +contrib isn't packaged in dist tarballs] +--- + README | 4 ++-- + tests/magtests.py | 2 +- + tests/t_bad_acceptor_name.py | 2 +- + tests/t_basic_k5.py | 2 +- + tests/t_basic_k5_fail_second.py | 2 +- + tests/t_basic_k5_two_users.py | 2 +- + tests/t_basic_proxy.py | 2 +- + tests/t_basic_timeout.py | 2 +- + tests/t_hostname_acceptor.py | 2 +- + tests/t_nonego.py | 2 +- + tests/t_required_name_attr.py | 2 +- + tests/t_spnego.py | 2 +- + tests/t_spnego_negotiate_once.py | 2 +- + tests/t_spnego_no_auth.py | 2 +- + tests/t_spnego_proxy.py | 2 +- + tests/t_spnego_rewrite.py | 2 +- + 16 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/README b/README +index 5eac94f..654a891 100644 +--- a/README ++++ b/README +@@ -26,8 +26,8 @@ To run tests, you also need: + + * The Kerberos 5 Key-Distribution-Center (`krb5-kdc` package on Debian, + `krb5-server` on Fedora) +-* Packages `mod_session`, `krb5-workstation`, `python-requests-kerberos`, +- and `python-gssapi` on Fedora ++* Packages `mod_session`, `krb5-workstation`, `python3-requests-gssapi`, ++ and `python3-gssapi` on Fedora + * Some tests require `krb5-pkinit` package on fedora and krb5 >= 1.15. + * [nss_wrapper](https://cwrap.org/nss_wrapper.html), packaged in Fedora + * [socket_wrapper](https://cwrap.org/socket_wrapper.html), packaged in Fedora +diff --git a/tests/magtests.py b/tests/magtests.py +index 082c6e4..d0f0a67 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import argparse +diff --git a/tests/t_bad_acceptor_name.py b/tests/t_bad_acceptor_name.py +index 41ee48b..6cee588 100755 +--- a/tests/t_bad_acceptor_name.py ++++ b/tests/t_bad_acceptor_name.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_basic_k5.py b/tests/t_basic_k5.py +index e499eac..4b24801 100755 +--- a/tests/t_basic_k5.py ++++ b/tests/t_basic_k5.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_basic_k5_fail_second.py b/tests/t_basic_k5_fail_second.py +index 273e9a5..7e53218 100755 +--- a/tests/t_basic_k5_fail_second.py ++++ b/tests/t_basic_k5_fail_second.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_basic_k5_two_users.py b/tests/t_basic_k5_two_users.py +index 41ffe98..3d27e9e 100755 +--- a/tests/t_basic_k5_two_users.py ++++ b/tests/t_basic_k5_two_users.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_basic_proxy.py b/tests/t_basic_proxy.py +index 5370314..347b802 100755 +--- a/tests/t_basic_proxy.py ++++ b/tests/t_basic_proxy.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_basic_timeout.py b/tests/t_basic_timeout.py +index 983dfd2..007ff97 100755 +--- a/tests/t_basic_timeout.py ++++ b/tests/t_basic_timeout.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2020 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_hostname_acceptor.py b/tests/t_hostname_acceptor.py +index 6d59e85..bb85700 100755 +--- a/tests/t_hostname_acceptor.py ++++ b/tests/t_hostname_acceptor.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2017 - mod_auth_gssapi contributors, see COPYING for license. + + import sys +diff --git a/tests/t_nonego.py b/tests/t_nonego.py +index 430001a..4e77f80 100755 +--- a/tests/t_nonego.py ++++ b/tests/t_nonego.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_required_name_attr.py b/tests/t_required_name_attr.py +index bbfdc19..a67446b 100755 +--- a/tests/t_required_name_attr.py ++++ b/tests/t_required_name_attr.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_spnego.py b/tests/t_spnego.py +index e7003a6..04190a9 100755 +--- a/tests/t_spnego.py ++++ b/tests/t_spnego.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_spnego_negotiate_once.py b/tests/t_spnego_negotiate_once.py +index e8eb601..3d8e048 100755 +--- a/tests/t_spnego_negotiate_once.py ++++ b/tests/t_spnego_negotiate_once.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_spnego_no_auth.py b/tests/t_spnego_no_auth.py +index abcccdf..c564388 100755 +--- a/tests/t_spnego_no_auth.py ++++ b/tests/t_spnego_no_auth.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_spnego_proxy.py b/tests/t_spnego_proxy.py +index c47558b..b917191 100755 +--- a/tests/t_spnego_proxy.py ++++ b/tests/t_spnego_proxy.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os +diff --git a/tests/t_spnego_rewrite.py b/tests/t_spnego_rewrite.py +index 2ed1d3e..202d76a 100755 +--- a/tests/t_spnego_rewrite.py ++++ b/tests/t_spnego_rewrite.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license. + + import os diff --git a/SOURCES/tests-Don-t-override-the-specific-environment-by-the.patch b/SOURCES/tests-Don-t-override-the-specific-environment-by-the.patch new file mode 100644 index 0000000..b613083 --- /dev/null +++ b/SOURCES/tests-Don-t-override-the-specific-environment-by-the.patch @@ -0,0 +1,166 @@ +From bd2f8d20c589feae7249ccca28199d826d007667 Mon Sep 17 00:00:00 2001 +From: Stanislav Levin +Date: Thu, 6 Aug 2020 13:55:45 +0300 +Subject: [PATCH] tests: Don't override the specific environment by the global + one + +This changes the way in which a test environment is prepared. + +Before: +specific -> global + +After: +global -> specific + +In particular, this allows setting PATH env variable differed from +the global configuration. + +Fixes: https://github.com/gssapi/mod_auth_gssapi/issues/226 +Signed-off-by: Stanislav Levin +(cherry picked from commit 731761e63d72bf5656f40340daafce4e2d34bd92) +--- + tests/magtests.py | 78 +++++++++++++++++++++++++++++------------------ + 1 file changed, 48 insertions(+), 30 deletions(-) + +diff --git a/tests/magtests.py b/tests/magtests.py +index 1c0b26a..e04fa65 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -310,11 +310,13 @@ def setup_kdc(testdir, wrapenv): + with open(kdcconf, 'w+') as f: + f.write(text) + +- kdcenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', +- 'KRB5_CONFIG': krb5conf, +- 'KRB5_KDC_PROFILE': kdcconf, +- 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log')} +- kdcenv.update(wrapenv) ++ kdcenv = wrapenv.copy() ++ kdcenv.update({ ++ 'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', ++ 'KRB5_CONFIG': krb5conf, ++ 'KRB5_KDC_PROFILE': kdcconf, ++ 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log'), ++ }) + + logfile = open(testlog, 'a') + ksetup = subprocess.Popen(["kdb5_util", "create", "-W", "-s", +@@ -383,8 +385,10 @@ def setup_keys(tesdir, env): + cmd = "addprinc -nokey -e %s %s" % (KEY_TYPE, USR_NAME_3) + kadmin_local(cmd, env, logfile) + +- keys_env = {"KRB5_KTNAME": svc_keytab, } +- keys_env.update(env) ++ keys_env = env.copy() ++ keys_env.update({ ++ "KRB5_KTNAME": svc_keytab, ++ }) + return keys_env + + +@@ -421,10 +425,12 @@ def setup_http(testdir, so_dir, wrapenv): + + shutil.copy('tests/401.html', os.path.join(httpdir, 'html')) + +- httpenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', +- 'MALLOC_CHECK_': '3', +- 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} +- httpenv.update(wrapenv) ++ httpenv = wrapenv.copy() ++ httpenv.update({ ++ 'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', ++ 'MALLOC_CHECK_': '3', ++ 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1), ++ }) + + httpd = "httpd" if distro == "Fedora" else "apache2" + httpproc = subprocess.Popen([httpd, '-DFOREGROUND', '-f', config], +@@ -435,8 +441,10 @@ def setup_http(testdir, so_dir, wrapenv): + def kinit_user(testdir, kdcenv): + testlog = os.path.join(testdir, 'kinit.log') + ccache = os.path.join(testdir, 'k5ccache') +- testenv = {'KRB5CCNAME': ccache} +- testenv.update(kdcenv) ++ testenv = kdcenv.copy() ++ testenv.update({ ++ 'KRB5CCNAME': ccache, ++ }) + + with (open(testlog, 'a')) as logfile: + kinit = subprocess.Popen(["kinit", USR_NAME], +@@ -457,8 +465,10 @@ def kinit_certuser(testdir, kdcenv): + pkinit_user_cert = os.path.join(testdir, PKINIT_USER_CERT) + pkinit_key = os.path.join(testdir, PKINIT_KEY) + ident = "X509_user_identity=FILE:" + pkinit_user_cert + "," + pkinit_key +- testenv = {'KRB5CCNAME': ccache} +- testenv.update(kdcenv) ++ testenv = kdcenv.copy() ++ testenv.update({ ++ 'KRB5CCNAME': ccache, ++ }) + with (open(testlog, 'a')) as logfile: + logfile.write('PKINIT for maguser3\n') + kinit = subprocess.Popen(["kinit", USR_NAME_3, "-X", ident], +@@ -711,17 +721,21 @@ def faketime_setup(testenv): + raise NotImplementedError + + # spedup x100 +- fakeenv = {'FAKETIME': '+0 x100'} +- fakeenv.update(testenv) +- fakeenv['LD_PRELOAD'] = ' '.join((testenv['LD_PRELOAD'], libfaketime)) ++ fakeenv = testenv.copy() ++ fakeenv.update({ ++ 'FAKETIME': '+0 x100', ++ 'LD_PRELOAD': ' '.join((testenv['LD_PRELOAD'], libfaketime)), ++ }) + return fakeenv + + + def http_restart(testdir, so_dir, testenv): +- httpenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{testenv["PATH"]}', +- 'MALLOC_CHECK_': '3', +- 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} +- httpenv.update(testenv) ++ httpenv = testenv.copy() ++ httpenv.update({ ++ 'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{testenv["PATH"]}', ++ 'MALLOC_CHECK_': '3', ++ 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1), ++ }) + + httpd = "httpd" if os.path.exists("/etc/httpd/modules") else "apache2" + config = os.path.join(testdir, 'httpd', 'httpd.conf') +@@ -776,11 +790,13 @@ if __name__ == '__main__': + sys.stderr.write("krb5 PKINIT module not found, skipping name " + "attribute tests\n") + +- testenv = {'MAG_USER_NAME': USR_NAME, +- 'MAG_USER_PASSWORD': USR_PWD, +- 'MAG_USER_NAME_2': USR_NAME_2, +- 'MAG_USER_PASSWORD_2': USR_PWD_2} +- testenv.update(kdcenv) ++ testenv = kdcenv.copy() ++ testenv.update({ ++ 'MAG_USER_NAME': USR_NAME, ++ 'MAG_USER_PASSWORD': USR_PWD, ++ 'MAG_USER_NAME_2': USR_NAME_2, ++ 'MAG_USER_PASSWORD_2': USR_PWD_2, ++ }) + + errs += test_basic_auth_krb5(testdir, testenv, logfile) + +@@ -789,9 +805,11 @@ if __name__ == '__main__': + # After this point we need to speed up httpd to test creds timeout + try: + fakeenv = faketime_setup(kdcenv) +- timeenv = {'TIMEOUT_USER': USR_NAME_4, +- 'MAG_USER_PASSWORD': USR_PWD} +- timeenv.update(fakeenv) ++ timeenv = fakeenv.copy() ++ timeenv.update({ ++ 'TIMEOUT_USER': USR_NAME_4, ++ 'MAG_USER_PASSWORD': USR_PWD, ++ }) + curporc = httpproc + pid = processes['HTTPD(%d)' % httpproc.pid].pid + os.killpg(pid, signal.SIGTERM) diff --git a/SOURCES/tests-Fixup-virtualenv-handling.patch b/SOURCES/tests-Fixup-virtualenv-handling.patch new file mode 100644 index 0000000..1fb638d --- /dev/null +++ b/SOURCES/tests-Fixup-virtualenv-handling.patch @@ -0,0 +1,87 @@ +From f106e3afa21cdbc098d3c82698585744e3325621 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 15 May 2020 15:56:50 -0400 +Subject: [PATCH] [tests] Fixup virtualenv handling + +Fixes an issue where virtualenv's PATH would get lost + +Signed-off-by: Robbie Harwood +(cherry picked from commit e60384c0d4d4b4c213ec728ec3d444f998625941) +--- + tests/magtests.py | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/tests/magtests.py b/tests/magtests.py +index 6c38a8f..1c0b26a 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -67,6 +67,12 @@ def setup_wrappers(base): + return wenv + + ++def apply_venv(env): ++ env['PATH'] = os.environ.get('PATH', '') ++ env['VIRTUAL_ENV'] = os.environ.get('VIRTUAL_ENV', '') ++ return env ++ ++ + TESTREALM = "MAG.DEV" + KDC_DBNAME = 'db.file' + KDC_STASH = 'stash.file' +@@ -304,7 +310,7 @@ def setup_kdc(testdir, wrapenv): + with open(kdcconf, 'w+') as f: + f.write(text) + +- kdcenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin', ++ kdcenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', + 'KRB5_CONFIG': krb5conf, + 'KRB5_KDC_PROFILE': kdcconf, + 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log')} +@@ -415,7 +421,7 @@ def setup_http(testdir, so_dir, wrapenv): + + shutil.copy('tests/401.html', os.path.join(httpdir, 'html')) + +- httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin', ++ httpenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{wrapenv["PATH"]}', + 'MALLOC_CHECK_': '3', + 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} + httpenv.update(wrapenv) +@@ -712,8 +718,7 @@ def faketime_setup(testenv): + + + def http_restart(testdir, so_dir, testenv): +- +- httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin', ++ httpenv = {'PATH': f'/sbin:/bin:/usr/sbin:/usr/bin:{testenv["PATH"]}', + 'MALLOC_CHECK_': '3', + 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)} + httpenv.update(testenv) +@@ -738,7 +743,7 @@ if __name__ == '__main__': + logfile = open(os.path.join(testdir, 'tests.log'), 'w') + errs = 0 + try: +- wrapenv = setup_wrappers(testdir) ++ wrapenv = apply_venv(setup_wrappers(testdir)) + + kdcproc, kdcenv = setup_kdc(testdir, wrapenv) + processes['KDC(%d)' % kdcproc.pid] = kdcproc +@@ -749,10 +754,6 @@ if __name__ == '__main__': + keysenv = setup_keys(testdir, kdcenv) + testenv = kinit_user(testdir, kdcenv) + +- # support virtualenv +- testenv['PATH'] = os.environ.get('PATH', '') +- testenv['VIRTUAL_ENV'] = os.environ.get('VIRTUAL_ENV', '') +- + testenv['DELEGCCACHE'] = os.path.join(testdir, 'httpd', + USR_NAME + '@' + TESTREALM) + errs += test_spnego_auth(testdir, testenv, logfile) +@@ -780,8 +781,6 @@ if __name__ == '__main__': + 'MAG_USER_NAME_2': USR_NAME_2, + 'MAG_USER_PASSWORD_2': USR_PWD_2} + testenv.update(kdcenv) +- testenv['PATH'] = os.environ.get('PATH', '') +- testenv['VIRTUAL_ENV'] = os.environ.get('VIRTUAL_ENV', '') + + errs += test_basic_auth_krb5(testdir, testenv, logfile) + diff --git a/SOURCES/tests-Support-Debian-s-libfaketime.patch b/SOURCES/tests-Support-Debian-s-libfaketime.patch new file mode 100644 index 0000000..94f2314 --- /dev/null +++ b/SOURCES/tests-Support-Debian-s-libfaketime.patch @@ -0,0 +1,35 @@ +From 27f7ca84a5a05f65e6d113a8a6698c7f40fd66c6 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 15 May 2020 15:51:19 -0400 +Subject: [PATCH] [tests] Support Debian's libfaketime + +Signed-off-by: Robbie Harwood +(cherry picked from commit 367120a1c02641680a8f51bd59cc96d56cc9804b) +--- + tests/magtests.py | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/tests/magtests.py b/tests/magtests.py +index da1cca7..6c38a8f 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -692,9 +692,16 @@ def test_hostname_acceptor(testdir, testenv, logfile): + + + def faketime_setup(testenv): +- libfaketime = '/usr/lib64/faketime/libfaketime.so.1' +- # optional faketime +- if not os.path.isfile(libfaketime): ++ # Wanted: an architecture- and distro-agnostic way to do this. ++ # libfaketime is installed in a place where ld.so won't pick it up by ++ # default, so... ++ paths = ['/usr/lib64/faketime/libfaketime.so.1', ++ '/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1'] ++ libfaketime = None ++ for p in paths: ++ if os.path.isfile(p): ++ libfaketime = p ++ if not libfaketime: + raise NotImplementedError + + # spedup x100 diff --git a/SPECS/mod_auth_gssapi.spec b/SPECS/mod_auth_gssapi.spec index ee219f1..7a32d0f 100644 --- a/SPECS/mod_auth_gssapi.spec +++ b/SPECS/mod_auth_gssapi.spec @@ -1,6 +1,6 @@ Name: mod_auth_gssapi Version: 1.6.1 -Release: 6%{?dist} +Release: 7.1%{?dist} Summary: A GSSAPI Authentication module for Apache Group: System Environment/Daemons @@ -12,6 +12,14 @@ Patch0: In-tests-show-the-exception-on-failure.patch Patch1: Fix-tests-to-work-with-python3.patch Patch2: tests-Test-suite-fixes-for-virtualenv-and-clang.patch Patch3: Fix-integer-sizes-used-with-ap_set_flag_slot.patch +Patch4: Fix-mag_auth_basic-function-call.patch +Patch6: Fix-distcheck.patch +Patch7: Add-option-to-control-timeout-for-Basic-Auth.patch +Patch8: tests-Support-Debian-s-libfaketime.patch +Patch9: tests-Fixup-virtualenv-handling.patch +Patch10: tests-Don-t-override-the-specific-environment-by-the.patch +Patch11: Fix-PATH-handling-bug-in-test-suite.patch +Patch12: Move-to-python3-by-default.patch BuildRequires: httpd-devel, krb5-devel, openssl-devel, autoconf, automake, libtool BuildRequires: gssntlmssp-devel @@ -49,6 +57,14 @@ install -m 644 10-auth_gssapi.conf %{buildroot}%{_httpd_modconfdir} %{_httpd_moddir}/mod_auth_gssapi.so %changelog +* Mon Oct 12 2020 Robbie Harwood 1.6.1-7.1 +- Bang on gating until the environment gives up +- Resolves: #1866149 + +* Mon Oct 12 2020 Robbie Harwood - 1.6.1-7 +- Backport basic auth timeout control +- Resolves: #1866149 + * Fri Mar 22 2019 Robbie Harwood - 1.6.1-6 - Gating update - Resolves: #1682259