From 4a3dc401470e18cca90cadd2dc3796fce5c21212 Mon Sep 17 00:00:00 2001 From: Yu Ming Zhu Date: Oct 10 2019 13:01:24 +0000 Subject: [PATCH 1/7] use GSS_NAME instead of REMOTE_USER for GSSAPI auth jira: https://projects.engineering.redhat.com/browse/BST-475 --- diff --git a/hub/hub.conf b/hub/hub.conf index 452d023..cc096e9 100644 --- a/hub/hub.conf +++ b/hub/hub.conf @@ -25,6 +25,8 @@ KojiDir = /mnt/koji ## Allowed Kerberos Realms separated by ','. ## Default value "*" indicates any Realm is allowed # AllowedKrbRealms = * +## default realm to support multiple realms +# DefaultRealm = EXAMPLE.COM ## end Kerberos auth configuration diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 9f2dd3c..026dc99 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -422,6 +422,7 @@ def load_config(environ): ['ProxyPrincipals', 'string', ''], ['HostPrincipalFormat', 'string', None], ['AllowedKrbRealms', 'string', '*'], + ['DefaultRealm', 'string', None], ['DNUsernameComponent', 'string', 'CN'], ['ProxyDNs', 'string', ''], diff --git a/koji/auth.py b/koji/auth.py index d281319..4d844af 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -398,8 +398,21 @@ class Session(object): if self.logged_in: raise koji.AuthError("Already logged in") - if context.environ.get('REMOTE_USER'): - username = context.environ.get('REMOTE_USER') + # we use GSS_NAME(krb_principal) to identify user + if context.environ.get('GSS_NAME'): + # it is kerberos principal rather than user's name. + username = context.environ.get('GSS_NAME') + # to support multipal realms, replace realm part with the default one. + atidx = username.find('@') + if atidx == -1: + raise koji.AuthError( + 'invalid Kerberos principal: %s' % username) + default_realm = context.opts.get('DefaultRealm') + if not default_realm: + raise koji.ConfigurationError( + 'DefaultRealm is not specified. Please contact the' + ' administrator.') + username = username[:atidx] + '@' + default_realm client_dn = username authtype = koji.AUTHTYPE_GSSAPI else: @@ -414,17 +427,29 @@ class Session(object): authtype = koji.AUTHTYPE_SSL if proxyuser: - proxy_dns = [dn.strip() for dn in context.opts.get('ProxyDNs', '').split('|')] + if authtype == koji.AUTHTYPE_GSSAPI: + delimiter = ',' + proxy_opt = 'ProxyPrincipals' + else: + delimiter = '|' + proxy_opt = 'ProxyDNs' + proxy_dns = [dn.strip() for dn in context.opts.get(proxy_opt, '').split(delimiter)] if client_dn in proxy_dns: - # the SSL-authenticated user authorized to login other users + # the user authorized to login other users username = proxyuser else: raise koji.AuthError('%s is not authorized to login other users' % client_dn) - user_id = self.getUserId(username) + if authtype == koji.AUTHTYPE_GSSAPI: + user_id = self.getUserIdFromKerberos(username) + else: + user_id = self.getUserId(username) if not user_id: if context.opts.get('LoginCreatesUser'): - user_id = self.createUser(username) + if authtype == koji.AUTHTYPE_GSSAPI: + user_id = self.createUserFromKerberos(username) + else: + user_id = self.createUser(username) else: raise koji.AuthError('Unknown user: %s' % username) From d662fb837d8f4391336f96b8c0d27695c570306e Mon Sep 17 00:00:00 2001 From: Yuming Zhu Date: Oct 10 2019 13:02:55 +0000 Subject: [PATCH 2/7] keep on using REMOTE_USER and handover realm translation to auth_to_local rules in /etc/krb5.conf --- diff --git a/hub/hub.conf b/hub/hub.conf index cc096e9..452d023 100644 --- a/hub/hub.conf +++ b/hub/hub.conf @@ -25,8 +25,6 @@ KojiDir = /mnt/koji ## Allowed Kerberos Realms separated by ','. ## Default value "*" indicates any Realm is allowed # AllowedKrbRealms = * -## default realm to support multiple realms -# DefaultRealm = EXAMPLE.COM ## end Kerberos auth configuration diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 026dc99..9f2dd3c 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -422,7 +422,6 @@ def load_config(environ): ['ProxyPrincipals', 'string', ''], ['HostPrincipalFormat', 'string', None], ['AllowedKrbRealms', 'string', '*'], - ['DefaultRealm', 'string', None], ['DNUsernameComponent', 'string', 'CN'], ['ProxyDNs', 'string', ''], diff --git a/koji/auth.py b/koji/auth.py index 4d844af..c1cfa22 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -399,20 +399,9 @@ class Session(object): raise koji.AuthError("Already logged in") # we use GSS_NAME(krb_principal) to identify user - if context.environ.get('GSS_NAME'): + if context.environ.get('REMOTE_USER'): # it is kerberos principal rather than user's name. - username = context.environ.get('GSS_NAME') - # to support multipal realms, replace realm part with the default one. - atidx = username.find('@') - if atidx == -1: - raise koji.AuthError( - 'invalid Kerberos principal: %s' % username) - default_realm = context.opts.get('DefaultRealm') - if not default_realm: - raise koji.ConfigurationError( - 'DefaultRealm is not specified. Please contact the' - ' administrator.') - username = username[:atidx] + '@' + default_realm + username = context.environ.get('REMOTE_USER') client_dn = username authtype = koji.AUTHTYPE_GSSAPI else: From 2408e86ff69bcf51f66f49b237b136c9604e808a Mon Sep 17 00:00:00 2001 From: Yuming Zhu Date: Oct 10 2019 13:02:55 +0000 Subject: [PATCH 3/7] in proxyuser case, do use username rather than principal --- diff --git a/koji/auth.py b/koji/auth.py index c1cfa22..4596a89 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -429,13 +429,13 @@ class Session(object): else: raise koji.AuthError('%s is not authorized to login other users' % client_dn) - if authtype == koji.AUTHTYPE_GSSAPI: + if authtype == koji.AUTHTYPE_GSSAPI and '@' in username: user_id = self.getUserIdFromKerberos(username) else: user_id = self.getUserId(username) if not user_id: if context.opts.get('LoginCreatesUser'): - if authtype == koji.AUTHTYPE_GSSAPI: + if authtype == koji.AUTHTYPE_GSSAPI and '@' in username: user_id = self.createUserFromKerberos(username) else: user_id = self.createUser(username) From 3b4673879bb4ea09de0dd25aa3754a4a6df493be Mon Sep 17 00:00:00 2001 From: Yu Ming Zhu Date: Oct 10 2019 13:02:55 +0000 Subject: [PATCH 4/7] fix typo --- diff --git a/koji/auth.py b/koji/auth.py index 4596a89..8ffa329 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -398,7 +398,7 @@ class Session(object): if self.logged_in: raise koji.AuthError("Already logged in") - # we use GSS_NAME(krb_principal) to identify user + # we use REMOTE_USER to identify user if context.environ.get('REMOTE_USER'): # it is kerberos principal rather than user's name. username = context.environ.get('REMOTE_USER') From 0c4d57d958f974262851326acc198509d9821152 Mon Sep 17 00:00:00 2001 From: Yuming Zhu Date: Oct 10 2019 13:02:55 +0000 Subject: [PATCH 5/7] adding some notes in documents --- diff --git a/docs/source/server_howto.rst b/docs/source/server_howto.rst index b070b94..a897959 100644 --- a/docs/source/server_howto.rst +++ b/docs/source/server_howto.rst @@ -588,6 +588,7 @@ Configuration Files * ``/etc/httpd/conf/httpd.conf`` * ``/etc/httpd/conf.d/kojihub.conf`` * ``/etc/httpd/conf.d/ssl.conf`` (when using ssl auth) +* ``/etc/krb5.conf`` (when using GSSAPI auth) Install koji-hub ---------------- @@ -652,6 +653,24 @@ options should point to where the certificates are located on the hub. # https://bugs.python.org/issue34670 SSLProtocol TLSv1.2 +/etc/krb5.conf +^^^^^^^^^^^^^^ + +If Apache's mod_auth_gssapi is enabled on hub, ``auth_to_local`` rules should +be configured as below. + +:: + + [realms] + EXAMPLE.COM = { + ... + auth_to_local = RULE:[1:$1@$0](.*@OTHER\.COM)s/@.*/@EXAMPLE.COM/ + auth_to_local = RULE:[1:$1@$0](.*@EXAMPLE\.COM) + auth_to_local = RULE:[2:$1/$2@$0](.*@OTHER\.COM)s/@.*/@EXAMPLE.COM/ + auth_to_local = RULE:[2:$1/$2@$0](.*@EXAMPLE\.COM) + ... + } + /etc/koji-hub/hub.conf ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/hub/httpd.conf b/hub/httpd.conf index 8a741d7..9df9dd4 100644 --- a/hub/httpd.conf +++ b/hub/httpd.conf @@ -55,3 +55,13 @@ Alias /kojifiles "/mnt/koji/" # In this case, you will need to enable these options globally (in ssl.conf): # SSLVerifyClient require # SSLVerifyDepth 10 + +# uncomment this to enable authentication via GSSAPI +# +# AuthType GSSAPI +# GssapiSSLonly Off +# GssapiLocalName On +# AuthName "GSSAPI Single Sign On Login" +# GssapiCredStore keytab:/etc/koji.keytab +# Require valid-user +# From 7b60e0e7eb7e378759398afe1b5e1e7a2c86e227 Mon Sep 17 00:00:00 2001 From: Yuming Zhu Date: Oct 10 2019 13:04:06 +0000 Subject: [PATCH 6/7] backwards compatibility for ProxyDNs change --- diff --git a/hub/hub.conf b/hub/hub.conf index 452d023..ba365ed 100644 --- a/hub/hub.conf +++ b/hub/hub.conf @@ -25,6 +25,8 @@ KojiDir = /mnt/koji ## Allowed Kerberos Realms separated by ','. ## Default value "*" indicates any Realm is allowed # AllowedKrbRealms = * +## TODO: this option should be removed in future release +# DisableGSSAPIProxyDNFallback = False ## end Kerberos auth configuration diff --git a/hub/kojixmlrpc.py b/hub/kojixmlrpc.py index 9f2dd3c..7b91e15 100644 --- a/hub/kojixmlrpc.py +++ b/hub/kojixmlrpc.py @@ -422,6 +422,8 @@ def load_config(environ): ['ProxyPrincipals', 'string', ''], ['HostPrincipalFormat', 'string', None], ['AllowedKrbRealms', 'string', '*'], + # TODO: this option should be removed in future release + ['DisableGSSAPIProxyDNFallback', 'boolean', False], ['DNUsernameComponent', 'string', 'CN'], ['ProxyDNs', 'string', ''], diff --git a/koji/auth.py b/koji/auth.py index 8ffa329..2399698 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -423,6 +423,15 @@ class Session(object): delimiter = '|' proxy_opt = 'ProxyDNs' proxy_dns = [dn.strip() for dn in context.opts.get(proxy_opt, '').split(delimiter)] + + # backwards compatible for GSSAPI. + # in old way, proxy user whitelist is ProxyDNs. + # TODO: this should be removed in future release + if authtype == koji.AUTHTYPE_GSSAPI and not context.opts.get( + 'DisableGSSAPIProxyDNFallback', False): + proxy_dns += [dn.strip() for dn in + context.opts.get('ProxyDNs', '').split('|')] + if client_dn in proxy_dns: # the user authorized to login other users username = proxyuser From 5629ff59a02054c87df640eccbf2539eb04faed8 Mon Sep 17 00:00:00 2001 From: Yu Ming Zhu Date: Oct 10 2019 13:04:06 +0000 Subject: [PATCH 7/7] doc: GssapiLocalName should be off --- diff --git a/docs/source/server_howto.rst b/docs/source/server_howto.rst index a897959..b070b94 100644 --- a/docs/source/server_howto.rst +++ b/docs/source/server_howto.rst @@ -588,7 +588,6 @@ Configuration Files * ``/etc/httpd/conf/httpd.conf`` * ``/etc/httpd/conf.d/kojihub.conf`` * ``/etc/httpd/conf.d/ssl.conf`` (when using ssl auth) -* ``/etc/krb5.conf`` (when using GSSAPI auth) Install koji-hub ---------------- @@ -653,24 +652,6 @@ options should point to where the certificates are located on the hub. # https://bugs.python.org/issue34670 SSLProtocol TLSv1.2 -/etc/krb5.conf -^^^^^^^^^^^^^^ - -If Apache's mod_auth_gssapi is enabled on hub, ``auth_to_local`` rules should -be configured as below. - -:: - - [realms] - EXAMPLE.COM = { - ... - auth_to_local = RULE:[1:$1@$0](.*@OTHER\.COM)s/@.*/@EXAMPLE.COM/ - auth_to_local = RULE:[1:$1@$0](.*@EXAMPLE\.COM) - auth_to_local = RULE:[2:$1/$2@$0](.*@OTHER\.COM)s/@.*/@EXAMPLE.COM/ - auth_to_local = RULE:[2:$1/$2@$0](.*@EXAMPLE\.COM) - ... - } - /etc/koji-hub/hub.conf ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/hub/httpd.conf b/hub/httpd.conf index 9df9dd4..208a29c 100644 --- a/hub/httpd.conf +++ b/hub/httpd.conf @@ -60,7 +60,7 @@ Alias /kojifiles "/mnt/koji/" # # AuthType GSSAPI # GssapiSSLonly Off -# GssapiLocalName On +# GssapiLocalName Off # AuthName "GSSAPI Single Sign On Login" # GssapiCredStore keytab:/etc/koji.keytab # Require valid-user