From 272612f1cb4e7ca99b49b170a29988a2b82ff75d Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 1/10] proxy login method --- diff --git a/koji/auth.py b/koji/auth.py index 3f169a5..a43a310 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -315,7 +315,7 @@ class Session(object): return (local_ip, local_port, remote_ip, remote_port) - def sslLogin(self, proxyuser=None): + def sslLogin(self, proxyuser=None, proxyauthtype=None): if self.logged_in: raise koji.AuthError("Already logged in") @@ -362,6 +362,10 @@ class Session(object): else: raise koji.AuthError('%s is not authorized to login other users' % client_dn) + # in this point we can continue with proxied user in same way as if it is not proxied + if proxyauthtype is not None: + authtype = proxyauthtype + if authtype == koji.AUTHTYPE_GSSAPI and '@' in username: user_id = self.getUserIdFromKerberos(username) else: From 4601472e00fbeb4547a555f830a27b4438ffa178 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 2/10] Allow kojiweb to proxy users obtained via different mechanisms This allows for users authenticated to the Koji Web interface via Kerberos to be proxied to the HUB using an SSL certificate and (in theory) vice versa though it's not clear why you'd want that. This is useful in environments where the owners of the Kerberos realm are not willing to create service accounts and export keytabs for them. Set WebAuth = kerberos to indicate that users are authenticated to the web via Kerberos. The existing config controls how kojiweb authenticates to the HUB. If using this, it is recommended to set LoginCreatesUser = Off in hub.conf, to avoid accidental creation of Koji accounts for users of the wider Kerberos realm. --- diff --git a/www/conf/web.conf b/www/conf/web.conf index 4da640d..a0cde34 100644 --- a/www/conf/web.conf +++ b/www/conf/web.conf @@ -21,6 +21,14 @@ KojiFilesURL = http://server.example.com/kojifiles # it already. Note, that it will override that bundle. # KojiHubCA = /etc/kojiweb/kojihubca.crt +# How the users authenticate to kojiweb, if different from the +# way Kojiweb authenticates to the hub. This can be used +# to have users authenticate to kojiweb via kerberos while +# still using an SSL certificate to authenticate to the hub. +# If doing that, consider also setting "LoginCreatesUser = Off" +# in the hub config. +# WebAuth = kerberos + LoginTimeout = 72 # This must be CHANGED to random value and uncommented before deployment diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 573c71c..e57feaa 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -272,8 +272,24 @@ def login(environ, page=None): session = _getServer(environ) options = environ['koji.options'] - # try SSL first, fall back to Kerberos - if options['WebCert']: + # If 'WebAuth' is not set, then default it to + # match the method of authenticating to the hub. + # This matches the original behaviour + webauth = options['WebAuth'] + if not webauth: + if options['WebCert']: + webauth = 'ssl' + if options['WebPrincipal']: + webauth = 'kerberos' + + if not webauth: + raise koji.AuthError( + 'KojiWeb is incorrectly configured for authentication, contact the system ' + 'administrator') + + if webauth == 'ssl': + ## Clients authenticate to KojiWeb by SSL, so extract + ## the username via the (verified) client certificate if environ['wsgi.url_scheme'] != 'https': dest = 'login' if page: @@ -289,22 +305,37 @@ def login(environ, page=None): if not username: raise koji.AuthError('unable to get user information from client certificate') - if not _sslLogin(environ, session, username): - raise koji.AuthError('could not login %s using SSL certificates' % username) - - authlogger.info('Successful SSL authentication by %s', username) - - elif options['WebPrincipal']: + elif webauth == 'kerberos': + ## Clients authenticate to KojiWeb by Kerberos, so extract + ## the username via the REMOTE_USER which will be the + ## Kerberos principal principal = environ.get('REMOTE_USER') if not principal: raise koji.AuthError( 'configuration error: mod_auth_gssapi should have performed authentication before ' 'presenting this page') - if not _gssapiLogin(environ, session, principal): - raise koji.AuthError('could not login using principal: %s' % principal) - username = principal + else: + ## It is still possible to get here if someone explicitly + ## set WebAuth to an incorrect value in the configuration file + raise koji.AuthError( + 'KojiWeb is incorrectly configured for authentication, contact the system ' + 'administrator') + + ## This now is how we proxy the user to the hub + if options['WebCert']: + ## The username might be a principal user@REALM. Remove + ## any @REALM part here. + username = username.split('@', 1)[0] + if not _sslLogin(environ, session, username): + raise koji.AuthError('could not login %s using SSL certificates' % username) + + authlogger.info('Successful SSL authentication by %s', username) + elif options['WebPrincipal']: + if not _gssapiLogin(environ, session, username): + raise koji.AuthError('could not login using principal: %s' % username) + authlogger.info('Successful Kerberos authentication by %s', username) else: raise koji.AuthError( diff --git a/www/kojiweb/wsgi_publisher.py b/www/kojiweb/wsgi_publisher.py index 8dab930..e96ee48 100644 --- a/www/kojiweb/wsgi_publisher.py +++ b/www/kojiweb/wsgi_publisher.py @@ -78,6 +78,8 @@ class Dispatcher(object): ['KrbCanonHost', 'boolean', False], ['KrbServerRealm', 'string', None], + ['WebAuth', 'string', None], + ['WebCert', 'string', None], ['KojiHubCA', 'string', '/etc/kojiweb/kojihubca.crt'], From e5b43b397116f43e73abc2ee16d52d7cadec69c9 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 3/10] Reverse check order between WebCert and WebPrincipal in case both are set In the case that both WebPrincipal and WebCert are set, reverse the order of checking them so that WebCert is used by default. --- diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index e57feaa..102ff9e 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -277,10 +277,10 @@ def login(environ, page=None): # This matches the original behaviour webauth = options['WebAuth'] if not webauth: - if options['WebCert']: - webauth = 'ssl' if options['WebPrincipal']: webauth = 'kerberos' + if options['WebCert']: + webauth = 'ssl' if not webauth: raise koji.AuthError( From 6141fa36b7e561ff48d063612625fbbbf3f89540 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 4/10] proxyauthtype for web users --- diff --git a/koji/auth.py b/koji/auth.py index a43a310..f6345b0 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -316,6 +316,15 @@ class Session(object): return (local_ip, local_port, remote_ip, remote_port) def sslLogin(self, proxyuser=None, proxyauthtype=None): + + """Login into brew via SSL. proxyuser name can be specified and if it is + allowed in the configuration file then connection is allowed to login as + that user. By default we assume that proxyuser is coming via same + authentication mechanism but proxyauthtype can be set to koji.AUTHTYPE_* + value for different handling. Typical case is proxying kerberos user via + web ui which itself is authenticated via SSL certificate. (See kojiweb + for usage). + """ if self.logged_in: raise koji.AuthError("Already logged in") @@ -364,6 +373,9 @@ class Session(object): # in this point we can continue with proxied user in same way as if it is not proxied if proxyauthtype is not None: + if proxyauthtype not in (koji.AUTHTYPE_GSSAPI, koji.AUTHTYPE_SSL): + raise koji.AuthError( + "Proxied authtype %s is not valid for sslLogin" % proxyauthtype) authtype = proxyauthtype if authtype == koji.AUTHTYPE_GSSAPI and '@' in username: diff --git a/www/conf/web.conf b/www/conf/web.conf index a0cde34..9f2922e 100644 --- a/www/conf/web.conf +++ b/www/conf/web.conf @@ -25,9 +25,7 @@ KojiFilesURL = http://server.example.com/kojifiles # way Kojiweb authenticates to the hub. This can be used # to have users authenticate to kojiweb via kerberos while # still using an SSL certificate to authenticate to the hub. -# If doing that, consider also setting "LoginCreatesUser = Off" -# in the hub config. -# WebAuth = kerberos +# WebAuthType = kerberos LoginTimeout = 72 diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 102ff9e..4805a1b 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -151,17 +151,18 @@ def _gssapiLogin(environ, session, principal): wprinc = options['WebPrincipal'] keytab = options['WebKeytab'] ccache = options['WebCCache'] + authtype = options['WebAuthType'] return session.gssapi_login(principal=wprinc, keytab=keytab, - ccache=ccache, proxyuser=principal) + ccache=ccache, proxyuser=principal, proxyauthtype=authtype) def _sslLogin(environ, session, username): options = environ['koji.options'] client_cert = options['WebCert'] server_ca = options['KojiHubCA'] - + authtype = options['WebAuthType'] return session.ssl_login(client_cert, None, server_ca, - proxyuser=username) + proxyuser=username, proxyauthtype=authtype) def _assertLogin(environ): @@ -272,22 +273,7 @@ def login(environ, page=None): session = _getServer(environ) options = environ['koji.options'] - # If 'WebAuth' is not set, then default it to - # match the method of authenticating to the hub. - # This matches the original behaviour - webauth = options['WebAuth'] - if not webauth: - if options['WebPrincipal']: - webauth = 'kerberos' - if options['WebCert']: - webauth = 'ssl' - - if not webauth: - raise koji.AuthError( - 'KojiWeb is incorrectly configured for authentication, contact the system ' - 'administrator') - - if webauth == 'ssl': + if options['WebAuthType'] == koji.AUTHTYPE_SSL: ## Clients authenticate to KojiWeb by SSL, so extract ## the username via the (verified) client certificate if environ['wsgi.url_scheme'] != 'https': @@ -304,8 +290,7 @@ def login(environ, page=None): username = environ.get('SSL_CLIENT_S_DN_CN') if not username: raise koji.AuthError('unable to get user information from client certificate') - - elif webauth == 'kerberos': + elif options['WebAuthType'] == koji.AUTHTYPE_GSSAPI: ## Clients authenticate to KojiWeb by Kerberos, so extract ## the username via the REMOTE_USER which will be the ## Kerberos principal @@ -316,18 +301,9 @@ def login(environ, page=None): 'presenting this page') username = principal - else: - ## It is still possible to get here if someone explicitly - ## set WebAuth to an incorrect value in the configuration file - raise koji.AuthError( - 'KojiWeb is incorrectly configured for authentication, contact the system ' - 'administrator') ## This now is how we proxy the user to the hub if options['WebCert']: - ## The username might be a principal user@REALM. Remove - ## any @REALM part here. - username = username.split('@', 1)[0] if not _sslLogin(environ, session, username): raise koji.AuthError('could not login %s using SSL certificates' % username) diff --git a/www/kojiweb/wsgi_publisher.py b/www/kojiweb/wsgi_publisher.py index e96ee48..f703f1e 100644 --- a/www/kojiweb/wsgi_publisher.py +++ b/www/kojiweb/wsgi_publisher.py @@ -78,7 +78,7 @@ class Dispatcher(object): ['KrbCanonHost', 'boolean', False], ['KrbServerRealm', 'string', None], - ['WebAuth', 'string', None], + ['WebAuthType', 'string', None], ['WebCert', 'string', None], ['KojiHubCA', 'string', '/etc/kojiweb/kojihubca.crt'], @@ -150,6 +150,20 @@ class Dispatcher(object): else: opts[name] = default opts['Secret'] = koji.util.HiddenValue(opts['Secret']) + + if opts['WebAuthType'] not in (None, 'gssapi', 'ssl'): + raise koji.ConfigurationError(f"Invalid value {opts['WebAuthType']} for " + "WebAuthType (ssl/gssapi)") + if opts['WebAuthType'] == 'gssapi': + opts['WebAuthType'] = koji.AUTHTYPE_GSSAPI + elif opts['WebAuthType'] == 'ssl': + opts['WebAuthType'] = koji.AUTHTYPE_SSL + # if there is no explicit request, use same authtype as web has + elif opts['WebPrincipal']: + opts['WebAuthType'] = koji.AUTHTYPE_GSSAPI + elif opts['WebCert']: + opts['WebAuthType'] = koji.AUTHTYPE_SSL + self.options = opts return opts From 3f6c8b8805a2c88b5b59fbc15ea2ea5e3af3c937 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 5/10] further fixes (will be squashed before merge) --- diff --git a/hub/hub.conf b/hub/hub.conf index 7aabe7c..220cab9 100644 --- a/hub/hub.conf +++ b/hub/hub.conf @@ -54,6 +54,9 @@ KojiDir = /mnt/koji ## Other options ## LoginCreatesUser = On +# Clients with ProxyPrincipals can use different method for proxying user than GSSAPI. In such case +# it need to be explicitely allowed via ProxyAuthType. +# ProxyAuthType = Off KojiWebURL = http://kojiweb.example.com/koji # The domain name that will be appended to Koji usernames # when creating email notifications diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 1263c7d..324de87 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -427,6 +427,7 @@ def load_config(environ): ['CheckClientIP', 'boolean', True], ['LoginCreatesUser', 'boolean', True], + ['ProxyAuthType', 'boolean', False], ['KojiWebURL', 'string', 'http://localhost.localdomain/koji'], ['EmailDomain', 'string', None], ['NotifyOnSuccess', 'boolean', True], diff --git a/koji/auth.py b/koji/auth.py index f6345b0..fd9fd4a 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -324,6 +324,9 @@ class Session(object): value for different handling. Typical case is proxying kerberos user via web ui which itself is authenticated via SSL certificate. (See kojiweb for usage). + + proxyauthtype is working only if ProxyAuthType option is set to 'On' in + the hub.conf """ if self.logged_in: raise koji.AuthError("Already logged in") @@ -373,6 +376,9 @@ class Session(object): # in this point we can continue with proxied user in same way as if it is not proxied if proxyauthtype is not None: + if not context.opts['ProxyAuthType']: + raise koji.AuthError("Proxy must use same auth mechanism as hub " + "(behaviour can be overriden via ProxyAuthType hub option)") if proxyauthtype not in (koji.AUTHTYPE_GSSAPI, koji.AUTHTYPE_SSL): raise koji.AuthError( "Proxied authtype %s is not valid for sslLogin" % proxyauthtype) diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index 4805a1b..b5e0122 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -301,6 +301,9 @@ def login(environ, page=None): 'presenting this page') username = principal + else: + raise koji.AuthError( + 'configuration error: set WebAuthType or on of WebPrincipal/WebCert options') ## This now is how we proxy the user to the hub if options['WebCert']: From 04aa48e93b055bc4daeeff29f337f5bfbbf85f52 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 6/10] conditional evaluation of proxyauthtype --- diff --git a/koji/auth.py b/koji/auth.py index fd9fd4a..7b539ab 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -374,15 +374,15 @@ class Session(object): else: raise koji.AuthError('%s is not authorized to login other users' % client_dn) - # in this point we can continue with proxied user in same way as if it is not proxied - if proxyauthtype is not None: - if not context.opts['ProxyAuthType']: - raise koji.AuthError("Proxy must use same auth mechanism as hub " - "(behaviour can be overriden via ProxyAuthType hub option)") - if proxyauthtype not in (koji.AUTHTYPE_GSSAPI, koji.AUTHTYPE_SSL): - raise koji.AuthError( - "Proxied authtype %s is not valid for sslLogin" % proxyauthtype) - authtype = proxyauthtype + # in this point we can continue with proxied user in same way as if it is not proxied + if proxyauthtype is not None: + if not context.opts['ProxyAuthType']: + raise koji.AuthError("Proxy must use same auth mechanism as hub (behaviour " + "can be overriden via ProxyAuthType hub option)") + if proxyauthtype not in (koji.AUTHTYPE_GSSAPI, koji.AUTHTYPE_SSL): + raise koji.AuthError( + "Proxied authtype %s is not valid for sslLogin" % proxyauthtype) + authtype = proxyauthtype if authtype == koji.AUTHTYPE_GSSAPI and '@' in username: user_id = self.getUserIdFromKerberos(username) From 4ded3d3fefa8895527120ea0362adb73e91e677c Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 7/10] propagate proxyauthtype in login calls --- diff --git a/koji/__init__.py b/koji/__init__.py index 4fe2209..25c8e76 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2472,7 +2472,8 @@ class ClientSession(object): return self.gssapi_login(principal=principal, keytab=keytab, ccache=ccache, proxyuser=proxyuser) - def gssapi_login(self, principal=None, keytab=None, ccache=None, proxyuser=None): + def gssapi_login(self, principal=None, keytab=None, ccache=None, + proxyuser=None, proxyauthtype=None): if not reqgssapi: raise PythonImportError( "Please install python-requests-gssapi to use GSSAPI." @@ -2515,7 +2516,9 @@ class ClientSession(object): # Depending on the server configuration, we might not be able to # connect without client certificate, which means that the conn # will fail with a handshake failure, which is retried by default. - sinfo = self._callMethod('sslLogin', [proxyuser], retry=False) + sinfo = self._callMethod('sslLogin', [], + {'proxyuser': proxyuser, 'proxyauthtype': proxyauthtype}, + retry=False) except Exception as e: e_str = ''.join(traceback.format_exception_only(type(e), e)).strip('\n') e_str = '(gssapi auth failed: %s)\n' % e_str @@ -2542,7 +2545,7 @@ class ClientSession(object): self.authtype = AUTHTYPE_GSSAPI return True - def ssl_login(self, cert=None, ca=None, serverca=None, proxyuser=None): + def ssl_login(self, cert=None, ca=None, serverca=None, proxyuser=None, proxyauthtype=None): cert = cert or self.opts.get('cert') serverca = serverca or self.opts.get('serverca') if cert is None: @@ -2571,7 +2574,9 @@ class ClientSession(object): self.opts['serverca'] = serverca e_str = None try: - sinfo = self.callMethod('sslLogin', proxyuser) + sinfo = self.callMethod('sslLogin', [], + {'proxyuser': proxyuser, 'proxyauthtype': proxyauthtype}) + except Exception as ex: e_str = ''.join(traceback.format_exception_only(type(ex), ex)) e_str = 'ssl auth failed: %s' % e_str diff --git a/tests/test_lib/test_gssapi.py b/tests/test_lib/test_gssapi.py index afbc897..da57c68 100644 --- a/tests/test_lib/test_gssapi.py +++ b/tests/test_lib/test_gssapi.py @@ -26,8 +26,8 @@ class TestGSSAPI(unittest.TestCase): def test_gssapi_login(self): old_environ = dict(**os.environ) self.session.gssapi_login() - self.session._callMethod.assert_called_once_with('sslLogin', [None], - retry=False) + self.session._callMethod.assert_called_once_with( + 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) @mock.patch('koji.reqgssapi.HTTPKerberosAuth') @@ -46,9 +46,8 @@ class TestGSSAPI(unittest.TestCase): for accepted_version in accepted_versions: koji.reqgssapi.__version__ = accepted_version rv = self.session.gssapi_login(principal, keytab, ccache) - self.session._callMethod.assert_called_once_with('sslLogin', - [None], - retry=False) + self.session._callMethod.assert_called_once_with( + 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) self.assertTrue(rv) self.session._callMethod.reset_mock() @@ -84,8 +83,8 @@ class TestGSSAPI(unittest.TestCase): self.session._callMethod.side_effect = Exception('login failed') with self.assertRaises(koji.GSSAPIAuthError): self.session.gssapi_login() - self.session._callMethod.assert_called_once_with('sslLogin', [None], - retry=False) + self.session._callMethod.assert_called_once_with( + 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) def test_gssapi_login_http(self): From 446b9ae8f2abb17ea4d288ed0e23b4dde8c46d72 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:30:42 +0000 Subject: [PATCH 8/10] rename ProxyAuthType -> AllowProxyAuthType --- diff --git a/hub/hub.conf b/hub/hub.conf index 220cab9..d8740b2 100644 --- a/hub/hub.conf +++ b/hub/hub.conf @@ -55,8 +55,8 @@ KojiDir = /mnt/koji ## Other options ## LoginCreatesUser = On # Clients with ProxyPrincipals can use different method for proxying user than GSSAPI. In such case -# it need to be explicitely allowed via ProxyAuthType. -# ProxyAuthType = Off +# it need to be explicitely allowed via AllowProxyAuthType. +# AllowProxyAuthType = Off KojiWebURL = http://kojiweb.example.com/koji # The domain name that will be appended to Koji usernames # when creating email notifications diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 324de87..ebdfdc2 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -427,7 +427,7 @@ def load_config(environ): ['CheckClientIP', 'boolean', True], ['LoginCreatesUser', 'boolean', True], - ['ProxyAuthType', 'boolean', False], + ['AllowProxyAuthType', 'boolean', False], ['KojiWebURL', 'string', 'http://localhost.localdomain/koji'], ['EmailDomain', 'string', None], ['NotifyOnSuccess', 'boolean', True], diff --git a/koji/auth.py b/koji/auth.py index 7b539ab..15f7071 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -325,8 +325,8 @@ class Session(object): web ui which itself is authenticated via SSL certificate. (See kojiweb for usage). - proxyauthtype is working only if ProxyAuthType option is set to 'On' in - the hub.conf + proxyauthtype is working only if AllowProxyAuthType option is set to + 'On' in the hub.conf """ if self.logged_in: raise koji.AuthError("Already logged in") @@ -376,9 +376,9 @@ class Session(object): # in this point we can continue with proxied user in same way as if it is not proxied if proxyauthtype is not None: - if not context.opts['ProxyAuthType']: + if not context.opts['AllowProxyAuthType']: raise koji.AuthError("Proxy must use same auth mechanism as hub (behaviour " - "can be overriden via ProxyAuthType hub option)") + "can be overriden via AllowProxyAuthType hub option)") if proxyauthtype not in (koji.AUTHTYPE_GSSAPI, koji.AUTHTYPE_SSL): raise koji.AuthError( "Proxied authtype %s is not valid for sslLogin" % proxyauthtype) From bab6517b4a0c3d86a36eca6bdb5126f354d40730 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 07 2021 12:53:12 +0000 Subject: [PATCH 9/10] backward compatibility for older hub use proxyauthtype only if it is explicetly requested. Older hubs don't know this option and will refuse login attempt. --- diff --git a/koji/__init__.py b/koji/__init__.py index 25c8e76..5c2a100 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2516,9 +2516,10 @@ class ClientSession(object): # Depending on the server configuration, we might not be able to # connect without client certificate, which means that the conn # will fail with a handshake failure, which is retried by default. - sinfo = self._callMethod('sslLogin', [], - {'proxyuser': proxyuser, 'proxyauthtype': proxyauthtype}, - retry=False) + kwargs = {'proxyuser': proxyuser} + if proxyauthtype is not None: + kwargs['proxyauthtype'] = proxyauthtype + sinfo = self._callMethod('sslLogin', [], kwargs, retry=False) except Exception as e: e_str = ''.join(traceback.format_exception_only(type(e), e)).strip('\n') e_str = '(gssapi auth failed: %s)\n' % e_str @@ -2574,8 +2575,10 @@ class ClientSession(object): self.opts['serverca'] = serverca e_str = None try: - sinfo = self.callMethod('sslLogin', [], - {'proxyuser': proxyuser, 'proxyauthtype': proxyauthtype}) + kwargs = {'proxyuser': proxyuser} + if proxyauthtype is not None: + kwargs['proxyauthtype'] = proxyauthtype + sinfo = self.callMethod('sslLogin', [], kwargs) except Exception as ex: e_str = ''.join(traceback.format_exception_only(type(ex), ex)) diff --git a/tests/test_lib/test_gssapi.py b/tests/test_lib/test_gssapi.py index da57c68..c5f71be 100644 --- a/tests/test_lib/test_gssapi.py +++ b/tests/test_lib/test_gssapi.py @@ -27,7 +27,7 @@ class TestGSSAPI(unittest.TestCase): old_environ = dict(**os.environ) self.session.gssapi_login() self.session._callMethod.assert_called_once_with( - 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) + 'sslLogin', [], {'proxyuser': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) @mock.patch('koji.reqgssapi.HTTPKerberosAuth') @@ -47,7 +47,7 @@ class TestGSSAPI(unittest.TestCase): koji.reqgssapi.__version__ = accepted_version rv = self.session.gssapi_login(principal, keytab, ccache) self.session._callMethod.assert_called_once_with( - 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) + 'sslLogin', [], {'proxyuser': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) self.assertTrue(rv) self.session._callMethod.reset_mock() @@ -84,7 +84,7 @@ class TestGSSAPI(unittest.TestCase): with self.assertRaises(koji.GSSAPIAuthError): self.session.gssapi_login() self.session._callMethod.assert_called_once_with( - 'sslLogin', [], {'proxyuser': None, 'proxyauthtype': None}, retry=False) + 'sslLogin', [], {'proxyuser': None}, retry=False) self.assertEqual(old_environ, dict(**os.environ)) def test_gssapi_login_http(self): From dada27f2fab276a68d75592d922eba50fdfa60a6 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Oct 13 2021 11:27:13 +0000 Subject: [PATCH 10/10] fix callMethod --- diff --git a/koji/__init__.py b/koji/__init__.py index 5c2a100..82d2e64 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2578,7 +2578,7 @@ class ClientSession(object): kwargs = {'proxyuser': proxyuser} if proxyauthtype is not None: kwargs['proxyauthtype'] = proxyauthtype - sinfo = self.callMethod('sslLogin', [], kwargs) + sinfo = self._callMethod('sslLogin', [], kwargs) except Exception as ex: e_str = ''.join(traceback.format_exception_only(type(ex), ex))