diff --git a/SOURCES/Fix-gss_localname-with-SPNEGO-wrapping.patch b/SOURCES/Fix-gss_localname-with-SPNEGO-wrapping.patch new file mode 100644 index 0000000..7b1c5de --- /dev/null +++ b/SOURCES/Fix-gss_localname-with-SPNEGO-wrapping.patch @@ -0,0 +1,39 @@ +From 676ec5fe0b6c7c5126dbf84ef59ec4a5d5f87ede Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 26 Apr 2022 10:23:53 +0200 +Subject: [PATCH] Fix gss_localname with SPNEGO wrapping + +Fix implemented upstream by Simo +--- + src/mod_auth_gssapi.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c +index b0999737daedf88fa84a9d8b1543bbedc79194ab..c91aa60707ba9b237a84f95670d483f1a7eab86b 100644 +--- a/src/mod_auth_gssapi.c ++++ b/src/mod_auth_gssapi.c +@@ -1264,7 +1264,21 @@ static int mag_complete(struct mag_req_cfg *req_cfg, struct mag_conn *mc, + #endif + + if (cfg->map_to_local) { ++ /* We have to play heuristics here as gss_localname does not work ++ * as expected with SPNEGO-wrapped names. ++ * http://krbdev.mit.edu/rt/Ticket/Display.html?id=8782 ++ */ + maj = gss_localname(&min, client, mech_type, &lname); ++ if (maj != GSS_S_COMPLETE) { ++ uint32_t sub_maj, sub_min; ++ /* try fallback with no oid */ ++ sub_maj = gss_localname(&sub_min, client, GSS_C_NO_OID, &lname); ++ if (sub_maj != GSS_S_UNAVAILABLE) { ++ /* use second call errors only if they are meaningful */ ++ maj = sub_maj; ++ min = sub_min; ++ } ++ } + if (maj != GSS_S_COMPLETE) { + mag_post_error(req, cfg, MAG_GSS_ERR, maj, min, + "gss_localname() failed"); +-- +2.35.1 + diff --git a/SOURCES/tests-add-test-for-gss_localname.patch b/SOURCES/tests-add-test-for-gss_localname.patch new file mode 100644 index 0000000..ab97f87 --- /dev/null +++ b/SOURCES/tests-add-test-for-gss_localname.patch @@ -0,0 +1,194 @@ +From 0dbf450a49784e2a750c667824e0e0249be575e4 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Wed, 27 Apr 2022 18:18:22 +0200 +Subject: [PATCH] Add test for gss_localname + +Backport test for gss_localname implemented upstream by Simo +--- + tests/httpd.conf | 13 ++++++++++ + tests/localname.html | 1 + + tests/magtests.py | 47 ++++++++++++++++++++++++++++++++- + tests/t_localname.py | 62 ++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 122 insertions(+), 1 deletion(-) + create mode 100644 tests/localname.html + create mode 100755 tests/t_localname.py + +diff --git a/tests/httpd.conf b/tests/httpd.conf +index f76f2b671e02515e6d4effe09ab123dace90c023..b3777574d9f0547560f24eff992fc1018569b5cc 100644 +--- a/tests/httpd.conf ++++ b/tests/httpd.conf +@@ -274,6 +274,19 @@ CoreDumpDirectory "{HTTPROOT}" + Require valid-user + + ++ ++ AuthType GSSAPI ++ AuthName "Login" ++ GssapiSSLonly Off ++ GssapiCredStore ccache:{HTTPROOT}/tmp/httpd_krb5_ccache ++ GssapiCredStore client_keytab:{HTTPROOT}/http.keytab ++ GssapiCredStore keytab:{HTTPROOT}/http.keytab ++ GssapiBasicAuth Off ++ GssapiAllowedMech krb5 ++ GssapiLocalName On ++ Require valid-user ++ ++ + + ProxyRequests On + ProxyVia On +diff --git a/tests/localname.html b/tests/localname.html +new file mode 100644 +index 0000000000000000000000000000000000000000..abf7c507de1eb32b31b882502eed5f2bbcc5fbf3 +--- /dev/null ++++ b/tests/localname.html +@@ -0,0 +1 @@ ++ +diff --git a/tests/magtests.py b/tests/magtests.py +index d0f0a67f075c6b631926e9abd91a665973d90f4a..d100413b371e7ecf4e09d944b7ff6e9bec7e316f 100755 +--- a/tests/magtests.py ++++ b/tests/magtests.py +@@ -58,12 +58,20 @@ def setup_wrappers(base): + f.write('%s %s\n' % (WRAP_IPADDR, WRAP_ALIASNAME)) + f.write('%s %s\n' % (WRAP_IPADDR, WRAP_FAILNAME)) + ++ passwd_file = os.path.join(testdir, 'passwd') ++ with open(passwd_file, 'w+') as f: ++ f.write('root:x:0:0:root:/root:/bin/sh') ++ f.write('maguser:x:1:1:maguser:/maguser:/bin/sh') ++ f.write('maguser2:x:2:2:maguser2:/maguser2:/bin/sh') ++ f.write('maguser3:x:3:3:maguser3:/maguser3:/bin/sh') ++ + wenv = {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so', + 'SOCKET_WRAPPER_DIR': wrapdir, + 'SOCKET_WRAPPER_DEFAULT_IFACE': '9', + 'WRAP_PROXY_PORT': WRAP_PROXY_PORT, + 'NSS_WRAPPER_HOSTNAME': WRAP_HOSTNAME, +- 'NSS_WRAPPER_HOSTS': hosts_file} ++ 'NSS_WRAPPER_HOSTS': hosts_file, ++ 'NSS_WRAPPER_PASSWD': passwd_file} + return wenv + + +@@ -744,6 +752,40 @@ def http_restart(testdir, so_dir, testenv): + return httpproc + + ++def test_gss_localname(testdir, testenv, logfile): ++ hdir = os.path.join(testdir, 'httpd', 'html', 'gss_localname') ++ os.mkdir(hdir) ++ shutil.copy('tests/localname.html', os.path.join(hdir, 'index.html')) ++ error_count = 0 ++ ++ # Make sure spnego is explicitly tested ++ spnego = subprocess.Popen(["tests/t_localname.py", "SPNEGO"], ++ stdout=logfile, stderr=logfile, ++ env=testenv, preexec_fn=os.setsid) ++ spnego.wait() ++ if spnego.returncode != 0: ++ sys.stderr.write('LOCALNAME(SPNEGO): FAILED\n') ++ error_count += 1 ++ else: ++ sys.stderr.write('LOCALNAME(SPNEGO): SUCCESS\n') ++ ++ # and bare krb5 (GS2-KRB5 is the name used by SASL for it) ++ krb5 = subprocess.Popen(["tests/t_localname.py", "GS2-KRB5"], ++ stdout=logfile, stderr=logfile, ++ env=testenv, preexec_fn=os.setsid) ++ krb5.wait() ++ if krb5.returncode != 0: ++ if krb5.returncode == 42: ++ sys.stderr.write('LOCALNAME(KRB5): SKIPPED\n') ++ else: ++ sys.stderr.write('LOCALNAME(KRB5): FAILED\n') ++ error_count += 1 ++ else: ++ sys.stderr.write('LOCALNAME(KRB5): SUCCESS\n') ++ ++ return error_count ++ ++ + if __name__ == '__main__': + args = parse_args() + +@@ -781,6 +823,9 @@ if __name__ == '__main__': + + errs += test_bad_acceptor_name(testdir, testenv, logfile) + ++ testenv['MAG_REMOTE_USER'] = USR_NAME ++ errs += test_gss_localname(testdir, testenv, logfile) ++ + rpm_path = "/usr/lib64/krb5/plugins/preauth/pkinit.so" + deb_path = "/usr/lib/x86_64-linux-gnu/krb5/plugins/preauth/pkinit.so" + if os.path.exists(rpm_path) or os.path.exists(deb_path): +diff --git a/tests/t_localname.py b/tests/t_localname.py +new file mode 100755 +index 0000000000000000000000000000000000000000..e990762c42aa9b370ac71292b5019fc63622c240 +--- /dev/null ++++ b/tests/t_localname.py +@@ -0,0 +1,62 @@ ++#!/usr/bin/env python3 ++# Copyright (C) 2020 - mod_auth_gssapi contributors, see COPYING for license. ++ ++import os ++import subprocess ++import sys ++ ++import gssapi ++ ++import requests ++ ++from requests_gssapi import HTTPSPNEGOAuth ++ ++ ++def use_requests(auth): ++ sess = requests.Session() ++ url = 'http://%s/gss_localname/' % os.environ['NSS_WRAPPER_HOSTNAME'] ++ ++ r = sess.get(url, auth=auth) ++ if r.status_code != 200: ++ raise ValueError('Localname failed') ++ ++ if r.text.rstrip() != os.environ['MAG_REMOTE_USER']: ++ raise ValueError('Localname, REMOTE_USER check failed') ++ ++ ++def use_curl(): ++ url = 'http://%s/gss_localname/' % os.environ['NSS_WRAPPER_HOSTNAME'] ++ curl = subprocess.Popen(["curl", "--negotiate", "-u:", url], ++ stdout=subprocess.PIPE) ++ curl.wait() ++ if curl.returncode != 0: ++ raise ValueError('Localname failed') ++ ++ line = curl.stdout.read().strip(b' \t\n\r').decode('utf-8') ++ if line != os.environ['MAG_REMOTE_USER']: ++ raise ValueError('Localname, REMOTE_USER check failed (%s != %s)' % ( ++ line, os.environ['MAG_REMOTE_USER'])) ++ ++ ++if __name__ == '__main__': ++ mech_name = None ++ if len(sys.argv) > 1: ++ mech_name = sys.argv[1] ++ ++ mech = None ++ if mech_name is not None: ++ mech = gssapi.mechs.Mechanism.from_sasl_name(mech_name) ++ ++ try: ++ auth = HTTPSPNEGOAuth(mech=mech) ++ use_requests(auth) ++ except TypeError: ++ # odler version of requests that does not support mechs ++ if mech_name == 'SPNEGO': ++ use_curl() ++ elif mech_name == 'GS2-KRB5': ++ # older request versions use krb5 as the mech by default ++ auth = HTTPSPNEGOAuth() ++ use_requests(auth) ++ else: ++ sys.exit(42) # SKIP +-- +2.35.1 + diff --git a/SPECS/mod_auth_gssapi.spec b/SPECS/mod_auth_gssapi.spec index 7a32d0f..dc5b86e 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: 7.1%{?dist} +Release: 8%{?dist} Summary: A GSSAPI Authentication module for Apache Group: System Environment/Daemons @@ -20,6 +20,8 @@ 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 +Patch13: Fix-gss_localname-with-SPNEGO-wrapping.patch +Patch14: tests-add-test-for-gss_localname.patch BuildRequires: httpd-devel, krb5-devel, openssl-devel, autoconf, automake, libtool BuildRequires: gssntlmssp-devel @@ -57,6 +59,11 @@ install -m 644 10-auth_gssapi.conf %{buildroot}%{_httpd_modconfdir} %{_httpd_moddir}/mod_auth_gssapi.so %changelog +* Wed Apr 27 2022 Francisco Trivino 1.6.1-8 +- Add test for gss_localname +- Fix gss_localname with SPNEGO wrapping +- Resolves: #1787630 + * Mon Oct 12 2020 Robbie Harwood 1.6.1-7.1 - Bang on gating until the environment gives up - Resolves: #1866149