diff --git a/builder/kojid b/builder/kojid index 24b97137..e962da35 100755 --- a/builder/kojid +++ b/builder/kojid @@ -69,12 +69,6 @@ from koji.tasks import ( ) from koji.util import dslice, dslice_ex, isSuccess, parseStatus, to_list -try: - import krbV - Krb5Error = krbV.Krb5Error -except ImportError: # pragma: no cover - krbV = None - try: import requests_kerberos Krb5Error = requests_kerberos.exceptions.RequestException @@ -6454,10 +6448,6 @@ def get_options(): 'host_principal_format': 'compile/%s@EXAMPLE.COM', 'keytab': '/etc/kojid/kojid.keytab', 'ccache': '/var/tmp/kojid.ccache', - 'krbservice': 'host', - 'krb_rdns': True, - 'krb_canon_host': False, - 'krb_server_realm': None, 'server': None, 'user': None, 'password': None, @@ -6501,8 +6491,7 @@ def get_options(): quit("value for %s option must be a valid integer" % name) elif name in ['offline_retry', 'use_createrepo_c', 'createrepo_skip_stat', 'createrepo_update', 'use_fast_upload', 'support_rpm_source_layout', - 'krb_rdns', 'krb_canon_host', 'build_arch_can_fail', 'no_ssl_verify', - 'log_timestamps']: + 'build_arch_can_fail', 'no_ssl_verify', 'log_timestamps']: defaults[name] = config.getboolean('kojid', name) elif name in ['plugin', 'plugins']: defaults['plugin'] = value.split() @@ -6608,14 +6597,14 @@ if __name__ == "__main__": quit("Error: Unable to log in. Bad credentials?") except requests.exceptions.ConnectionError: quit("Error: Unable to connect to server %s" % (options.server)) - elif krbV or requests_kerberos: + elif requests_kerberos: krb_principal = options.krb_principal if krb_principal is None: krb_principal = options.host_principal_format % socket.getfqdn() try: - session.krb_login(principal=krb_principal, - keytab=options.keytab, - ccache=options.ccache) + session.gssapi_login(principal=krb_principal, + keytab=options.keytab, + ccache=options.ccache) except Krb5Error as e: quit("Kerberos authentication failed: %s" % e.args) except socket.error as e: diff --git a/builder/kojid.conf b/builder/kojid.conf index 793aed3b..8a43cf0d 100644 --- a/builder/kojid.conf +++ b/builder/kojid.conf @@ -102,9 +102,6 @@ from_addr=Koji Build System ;location of the keytab ;keytab = /etc/kojid/kojid.keytab -;the service name of the principal being used by the hub -;krbservice = host - ;configuration for SSL authentication ;client certificate diff --git a/cli/koji b/cli/koji index 1f79f662..3e9c563f 100755 --- a/cli/koji +++ b/cli/koji @@ -119,7 +119,6 @@ def get_options(): help=_("specify a configuration profile")) parser.add_option("--keytab", help=_("specify a Kerberos keytab to use"), metavar="FILE") parser.add_option("--principal", help=_("specify a Kerberos principal to use")) - parser.add_option("--krbservice", help=_("specify the Kerberos service name for the hub")) parser.add_option("--cert", help=_("specify a SSL cert to use"), metavar="FILE") parser.add_option("--ca", help=SUPPRESS_HELP, metavar="FILE") # FIXME: remove in 1.24 parser.add_option("--runas", help=_("run as the specified user (requires special privileges)")) diff --git a/cli/koji.conf b/cli/koji.conf index 96e7bf43..c1d50dc1 100644 --- a/cli/koji.conf +++ b/cli/koji.conf @@ -16,21 +16,12 @@ ;configuration for Kerberos authentication -;the service name of the principal being used by the hub -;krbservice = host - ;the principal to auth as for automated clients ;principal = client@EXAMPLE.COM ;the keytab to auth as for automated clients ;keytab = /etc/krb5.keytab -;enable to lookup dns canonical hostname for krb auth -;krb_canon_host = no - -;The realm of server principal. Using client's realm if not set -;krb_server_realm = EXAMPLE.COM - ;configuration for SSL authentication diff --git a/cli/koji_cli/lib.py b/cli/koji_cli/lib.py index a85e5378..1c967bf9 100644 --- a/cli/koji_cli/lib.py +++ b/cli/koji_cli/lib.py @@ -20,11 +20,6 @@ import koji from koji import parse_arches from koji.util import md5_constructor, to_list -try: - import krbV -except ImportError: # pragma: no cover - krbV = None - # for compatibility with plugins based on older version of lib # Use optparse imports directly in new code. @@ -663,18 +658,6 @@ def warn(msg): sys.stderr.flush() -def has_krb_creds(): - if krbV is None: - return False - try: - ctx = krbV.default_context() - ccache = ctx.default_ccache() - ccache.principal() - return True - except krbV.Krb5Error: - return False - - def activate_session(session, options): """Test and login the session is applicable""" if isinstance(options, dict): @@ -692,7 +675,7 @@ def activate_session(session, options): and options.authtype is None: # authenticate using user/password session.login() - elif options.authtype == "kerberos" or has_krb_creds() and options.authtype is None: + elif options.authtype == "kerberos" or options.authtype is None: try: if getattr(options, 'keytab', None) and getattr(options, 'principal', None): session.gssapi_login(principal=options.principal, keytab=options.keytab, diff --git a/docs/source/kojid_conf.rst b/docs/source/kojid_conf.rst index 2f61507f..e2082951 100644 --- a/docs/source/kojid_conf.rst +++ b/docs/source/kojid_conf.rst @@ -242,27 +242,6 @@ Kerberos Authentication keytab=/etc/kojid/kojid.keytab Location of the keytab. - krb_canon_host=False - Kerberos authentication requires correct hostnames. If this option is - specified, dns is used to get the correct hostname for the - server (i.e. resolve any CNAMEs). Note, this option will not function - unless ``python-dns`` is installed. - The ``krb_rdns`` option takes a different approach. - - krb_principal=None - Explicit principal used for login. If it is not specified, it is - created via ``host_principal_format``. - - krb_rdns=True - Kerberos authentication needs correct hostname. If this option is - specified, ``socket.getfqdn(host)`` is used to determine reverse DNS - records. Otherwise, ``host`` is used directly. Playing with this option - can help you in some firewalled setups. ``krb_canon_host`` takes - precedence over this option and takes a different approach. - - krbservice=host - The service name of the principal being used by the hub. - SSL Authentication ^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/server_howto.rst b/docs/source/server_howto.rst index 3a29aff5..b428750a 100644 --- a/docs/source/server_howto.rst +++ b/docs/source/server_howto.rst @@ -883,11 +883,6 @@ For a simple test, all we need is the ``server`` and authentication sections. ;path to the koji top directory topdir = /mnt/koji - ; configuration for Kerberos authentication - - ;the service name of the principal being used by the hub - ;krbservice = host - ; configuration for SSL athentication ;client certificate @@ -1351,12 +1346,6 @@ Authentication Configuration ;location of the keytab ;keytab = /etc/kojira/kojira.keytab - ;the service name of the principal being used by the hub - ;krbservice = host - - ;The realm of server principal. Using client's realm if not set - ;krb_server_realm = EXAMPLE.COM - ``/etc/sysconfig/kojira`` The local user kojira runs as needs to be able to read and write to ``/mnt/koji/repos/``. If the volume that directory resides on is diff --git a/koji.spec b/koji.spec index 16adcb26..d8e3a083 100644 --- a/koji.spec +++ b/koji.spec @@ -125,11 +125,7 @@ Requires: rpm-python %endif Requires: pyOpenSSL Requires: python-requests -%if 0%{?fedora} || 0%{?rhel} >= 7 Requires: python-requests-kerberos -%else -Requires: python-krbV >= 1.0.13 -%endif Requires: python-dateutil Requires: python-six diff --git a/koji/__init__.py b/koji/__init__.py index 5511dd81..8741689d 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -62,16 +62,6 @@ from six.moves import range, zip from koji.xmlrpcplus import Fault, dumps, getparser, loads, xmlrpc_client from . import util -krbV = None -try: - import krbV -except ImportError: # pragma: no cover - pass -dns_resolver = None -try: - import dns.resolver as dns_resolver -except ImportError: # pragma: no cover - pass SSL_Error = None try: from OpenSSL.SSL import Error as SSL_Error @@ -1899,10 +1889,6 @@ def read_config(profile_name, user_config=None): 'use_fast_upload': False, 'upload_blocksize': 1048576, 'poll_interval': 6, - 'krbservice': 'host', - 'krb_rdns': True, - 'krb_canon_host': False, - 'krb_server_realm': None, 'principal': None, 'keytab': None, 'cert': None, @@ -1949,9 +1935,8 @@ def read_config(profile_name, user_config=None): # options *can* be set via the config file. Such options should # not have a default value set in the option parser. if name in result: - if name in ('anon_retry', 'offline_retry', - 'use_fast_upload', 'krb_rdns', 'debug', - 'debug_xmlrpc', 'krb_canon_host'): + if name in ('anon_retry', 'offline_retry', 'use_fast_upload', + 'debug', 'debug_xmlrpc'): result[name] = config.getboolean(profile_name, name) elif name in ('max_retries', 'retry_interval', 'offline_retry_interval', 'poll_interval', @@ -2371,7 +2356,6 @@ def grab_session_options(options): s_opts = ( 'user', 'password', - 'krbservice', 'debug_xmlrpc', 'debug', 'max_retries', @@ -2383,9 +2367,6 @@ def grab_session_options(options): 'auth_timeout', 'use_fast_upload', 'upload_blocksize', - 'krb_rdns', - 'krb_canon_host', - 'krb_server_realm', 'no_ssl_verify', 'serverca', ) @@ -2473,121 +2454,6 @@ class ClientSession(object): sinfo = self.callMethod('subsession') return type(self)(self.baseurl, self.opts, sinfo) - def krb_login(self, principal=None, keytab=None, ccache=None, proxyuser=None, ctx=None): - """Log in using Kerberos. If principal is not None and keytab is - not None, then get credentials for the given principal from the given keytab. - If both are None, authenticate using existing local credentials (as obtained - from kinit). ccache is the absolute path to use for the credential cache. If - not specified, the default ccache will be used. If proxyuser is specified, - log in the given user instead of the user associated with the Kerberos - principal. The principal must be in the "ProxyPrincipals" list on - the server side. ctx is the Kerberos context to use, and should be unique - per thread. If ctx is not specified, the default context is used.""" - - util.deprecated("Please use gssapi_login instead, krb_login will be removed in koji 1.22") - try: - # Silently try GSSAPI first - if self.gssapi_login(principal, keytab, ccache, proxyuser=proxyuser): - return True - except Exception as e: - if krbV: - e_str = ''.join(traceback.format_exception_only(type(e), e)) - self.logger.debug('gssapi auth failed: %s', e_str) - pass - else: - raise - - if not krbV: - raise PythonImportError( - "Please install python-krbV to use kerberos." - ) - - if not ctx: - ctx = krbV.default_context() - - if ccache is not None: - ccache = krbV.CCache(name=ccache, context=ctx) - else: - ccache = ctx.default_ccache() - - if principal is not None: - if keytab is not None: - cprinc = krbV.Principal(name=principal, context=ctx) - keytab = krbV.Keytab(name=keytab, context=ctx) - ccache.init(cprinc) - ccache.init_creds_keytab(principal=cprinc, keytab=keytab) - else: - raise AuthError('cannot specify a principal without a keytab') - else: - # We're trying to log ourself in. Connect using existing credentials. - cprinc = ccache.principal() - - self.logger.debug('Authenticating as: %s', cprinc.name) - sprinc = krbV.Principal(name=self._serverPrincipal(cprinc), context=ctx) - - ac = krbV.AuthContext(context=ctx) - ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME - ac.rcache = ctx.default_rcache() - - # create and encode the authentication request - (ac, req) = ctx.mk_req(server=sprinc, client=cprinc, - auth_context=ac, ccache=ccache, - options=krbV.AP_OPTS_MUTUAL_REQUIRED) - req_enc = base64.encodestring(req) - - # ask the server to authenticate us - (rep_enc, sinfo_enc, addrinfo) = self.callMethod('krbLogin', req_enc, proxyuser) - # Set the addrinfo we received from the server - # (necessary before calling rd_priv()) - # addrinfo is in (serveraddr, serverport, clientaddr, clientport) - # format, so swap the pairs because clientaddr is now the local addr - ac.addrs = tuple((addrinfo[2], addrinfo[3], addrinfo[0], addrinfo[1])) - - # decode and read the reply from the server - rep = base64.b64decode(rep_enc) - ctx.rd_rep(rep, auth_context=ac) - - # decode and decrypt the login info - sinfo_priv = base64.b64decode(sinfo_enc) - sinfo_str = ac.rd_priv(sinfo_priv) - sinfo = dict(zip(['session-id', 'session-key'], sinfo_str.split())) - - if not sinfo: - self.logger.warning('No session info received') - return False - self.setSession(sinfo) - - self.krb_principal = cprinc.name - self.authtype = AUTHTYPE_KERB - return True - - def _serverPrincipal(self, cprinc): - """Get the Kerberos principal of the server we're connecting - to, based on baseurl.""" - - host = six.moves.urllib.parse.urlparse(self.baseurl).hostname - servername = self._fix_krb_host(host) - realm = self.opts.get('krb_server_realm') - if not realm: - realm = cprinc.realm - service = self.opts.get('krbservice', 'host') - - ret = '%s/%s@%s' % (service, servername, realm) - self.logger.debug('Using server principal: %s', ret) - return ret - - def _fix_krb_host(self, host): - if self.opts.get('krb_canon_host', False): - if dns_resolver is None: - self.logger.warning('python-dns missing -- cannot resolve hostname') - else: - answer = dns_resolver.query(host, 'A') - return answer.canonical_name.to_text(omit_final_dot=True) - if self.opts.get('krb_rdns', True): - return socket.getfqdn(host) - # else - return host - def gssapi_login(self, principal=None, keytab=None, ccache=None, proxyuser=None): if not requests_kerberos: raise PythonImportError( diff --git a/koji/auth.py b/koji/auth.py index bc73c02c..ee422774 100644 --- a/koji/auth.py +++ b/koji/auth.py @@ -21,7 +21,6 @@ from __future__ import absolute_import -import base64 import random import re import socket @@ -34,11 +33,6 @@ import koji from .context import context from .util import to_list -try: - import krbV -except ImportError: - krbV = None - # 1 - load session if provided # - check uri for session id # - load session info from db @@ -300,82 +294,6 @@ class Session(object): context.cnx.commit() return sinfo - def krbLogin(self, krb_req, proxyuser=None): - """Authenticate the user using the base64-encoded - AP_REQ message in krb_req. If proxyuser is not None, - log in that user instead of the user associated with the - Kerberos principal. The principal must be an authorized - "proxy_principal" in the server config.""" - if self.logged_in: - raise koji.AuthError("Already logged in") - - if krbV is None: - # python3 is not supported - raise koji.AuthError("krbV module not installed") - - if not (context.opts.get('AuthPrincipal') and context.opts.get('AuthKeytab')): - raise koji.AuthError('not configured for Kerberos authentication') - - ctx = krbV.default_context() - srvprinc = krbV.Principal(name=context.opts.get('AuthPrincipal'), context=ctx) - srvkt = krbV.Keytab(name=context.opts.get('AuthKeytab'), context=ctx) - - ac = krbV.AuthContext(context=ctx) - ac.flags = krbV.KRB5_AUTH_CONTEXT_DO_SEQUENCE | krbV.KRB5_AUTH_CONTEXT_DO_TIME - conninfo = self.getConnInfo() - ac.addrs = conninfo - - # decode and read the authentication request - req = base64.b64decode(krb_req) - ac, opts, sprinc, ccreds = ctx.rd_req(req, server=srvprinc, keytab=srvkt, - auth_context=ac, - options=krbV.AP_OPTS_MUTUAL_REQUIRED) - cprinc = ccreds[2] - - # Successfully authenticated via Kerberos, now log in - if proxyuser: - proxyprincs = [princ.strip() - for princ in context.opts.get('ProxyPrincipals', '').split(',')] - if cprinc.name in proxyprincs: - login_principal = proxyuser - else: - raise koji.AuthError( - 'Kerberos principal %s is not authorized to log in other users' % cprinc.name) - else: - login_principal = cprinc.name - - if '@' in login_principal: - user_id = self.getUserIdFromKerberos(login_principal) - else: - # backward compatible - # it's only possible when proxyuser is username, but we shouldn't - # allow this. - user_id = self.getUserId(login_principal) - - if not user_id: - # Only do autocreate if we also couldn't find by username AND the proxyuser - # looks like a krb5 principal - if context.opts.get('LoginCreatesUser') and '@' in login_principal: - user_id = self.createUserFromKerberos(login_principal) - else: - raise koji.AuthError('Unknown Kerberos principal: %s' % login_principal) - - self.checkLoginAllowed(user_id) - - hostip = self.get_remote_ip() - - sinfo = self.createSession(user_id, hostip, koji.AUTHTYPE_KERB) - - # encode the reply - rep = ctx.mk_rep(auth_context=ac) - rep_enc = base64.encodestring(rep) - - # encrypt and encode the login info - sinfo_priv = ac.mk_priv('%(session-id)s %(session-key)s' % sinfo) - sinfo_enc = base64.encodestring(sinfo_priv) - - return (rep_enc, sinfo_enc, conninfo) - def getConnInfo(self): """Return a tuple containing connection information in the following format: diff --git a/setup.py b/setup.py index 529a573f..45acb149 100644 --- a/setup.py +++ b/setup.py @@ -20,10 +20,6 @@ def get_install_requires(): # 'rpm-py-installer', # it is optional feature # 'rpm', ] - if sys.version_info[0] < 3: - # optional auth library for older hubs - # hubs >= 1.12 are using requests' default GSSAPI - requires.append('python-krbV') # since pyOpenSSL-18.0.0, py26 support is dropped # see https://pagure.io/koji/issue/1060 if sys.version_info[0] == 2 and sys.version_info[1] < 7: diff --git a/tests/test_cli/test_activate_session.py b/tests/test_cli/test_activate_session.py index b1ee20a9..70c099e6 100644 --- a/tests/test_cli/test_activate_session.py +++ b/tests/test_cli/test_activate_session.py @@ -17,8 +17,6 @@ class TestActivateSession(unittest.TestCase): self.warn = mock.patch('koji_cli.lib.warn').start() self.error = mock.patch('koji_cli.lib.error').start() # self.ensure_connection = mock.patch('koji_cli.lib.warn.ensure_connection').start() - self.has_krb_creds = mock.patch('koji_cli.lib.has_krb_creds').start() - self.has_krb_creds.return_value = False def tearDown(self): mock.patch.stopall() @@ -33,7 +31,6 @@ class TestActivateSession(unittest.TestCase): activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_not_called() def test_activate_session_ssl(self): @@ -48,7 +45,6 @@ class TestActivateSession(unittest.TestCase): session.ssl_login.assert_called_once_with(certfile, None, 'SERVERCA', proxyuser=None) session.login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_not_called() def test_activate_session_ssl_implicit(self): @@ -64,7 +60,6 @@ class TestActivateSession(unittest.TestCase): session.ssl_login.assert_called_once_with(certfile, None, 'SERVERCA', proxyuser=None) session.login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_not_called() def test_activate_session_pw(self): @@ -74,7 +69,6 @@ class TestActivateSession(unittest.TestCase): activate_session(session, options) session.login.assert_called_once_with() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_not_called() def test_activate_session_pw_implicit(self): @@ -85,7 +79,6 @@ class TestActivateSession(unittest.TestCase): activate_session(session, options) session.login.assert_called_once_with() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_not_called() def test_activate_session_krb(self): @@ -96,7 +89,6 @@ class TestActivateSession(unittest.TestCase): activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_called_once_with(proxyuser=None) def test_activate_session_krb_implicit(self): @@ -104,11 +96,9 @@ class TestActivateSession(unittest.TestCase): session.logged_in = True options = {'authtype': None, 'debug': False, 'cert': '', 'keytab': None, 'principal': None} - self.has_krb_creds.return_value = True activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_called_once_with(proxyuser=None) def test_activate_session_krb_keytab(self): @@ -119,7 +109,6 @@ class TestActivateSession(unittest.TestCase): activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() session.gssapi_login.assert_called_once_with(principal='PRINCIPAL', keytab='KEYTAB', proxyuser=None) @@ -127,10 +116,8 @@ class TestActivateSession(unittest.TestCase): session = mock.MagicMock() session.logged_in = False options = {'authtype': None, 'debug': False, 'cert': ''} - self.has_krb_creds.return_value = False activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() - session.krb_login.assert_not_called() - session.gssapi_login.assert_not_called() + session.gssapi_login.assert_called_once() self.error.assert_called_once() diff --git a/tests/test_lib/test_auth.py b/tests/test_lib/test_auth.py index 7aa27d45..e92a12b2 100644 --- a/tests/test_lib/test_auth.py +++ b/tests/test_lib/test_auth.py @@ -170,79 +170,6 @@ class TestAuthSession(unittest.TestCase): with self.assertRaises(koji.AuthError): s.login('user', 'password') - @mock.patch('koji.auth.context') - @mock.patch('koji.auth.socket') - @mock.patch('koji.auth.base64') - def test_krbLogin(self, base64, socket, context): - # TODO - s, cntext, cursor = self.get_session() - context.cnx = cntext.cnx - - with self.assertRaises(koji.AuthError) as cm: - s.krbLogin('krb_req', 'proxyuser') - self.assertEqual(cm.exception.args[0], 'Already logged in') - - s.logged_in = False - if six.PY3: - with self.assertRaises(koji.AuthError) as cm: - s.krbLogin('krb_req', 'proxyuser') - self.assertEqual(cm.exception.args[0], 'krbV module not installed') - else: - with mock.patch('koji.auth.krbV', create=True) as krbV: - princ = mock.MagicMock() - princ.name = 'princ_name' - krbV.default_context.return_value \ - .rd_req.return_value = (mock.MagicMock(), 2, 3, - [1, 2, princ]) - with self.assertRaises(koji.AuthError) as cm: - s.krbLogin('krb_req', 'proxyuser') - self.assertEqual(cm.exception.args[0], - 'Kerberos principal princ_name is' - ' not authorized to log in other users') - context.opts = {'ProxyPrincipals': 'anyothers,' + princ.name, - 'AuthPrincipal': 'authprinc', - 'AuthKeytab': 'authkeytab', - 'LoginCreatesUser': False, - 'CheckClientIP': False} - with self.assertRaises(koji.AuthError) as cm: - s.krbLogin('krb_req', 'proxyuser@realm.com') - self.assertEqual(cm.exception.args[0], - 'Unknown Kerberos principal:' - ' proxyuser@realm.com') - # case: create user by kerberos - context.opts['LoginCreatesUser'] = True - context.cnx.cursor.return_value. \ - fetchone.side_effect = [None, - (1,), - ('name', 'type', - koji.USER_STATUS['NORMAL']), - ('session-id',)] - context.cnx.cursor.return_value.fetchall.return_value = None - s.krbLogin('krb_req', 'proxyuser@realm.com') - self.assertEqual(context.cnx.cursor.return_value.execute. - call_count, 14) - # case: create user by username, proxyuser is username - context.cnx.cursor.return_value. \ - fetchone.side_effect = [None] - context.cnx.cursor.return_value.fetchall.return_value = None - with self.assertRaises(koji.AuthError) as cm: - s.krbLogin('krb_req', 'proxyuser') - self.assertEqual(cm.exception.args[0], - 'Unknown Kerberos principal: proxyuser') - # case: create user by kerberos - set krb princ - context.opts['LoginCreatesUser'] = True - context.cnx.cursor.return_value. \ - fetchone.side_effect = [None, - (1,), - ('name', 'type', - koji.USER_STATUS['NORMAL']), - ('session-id',)] - context.cnx.cursor.return_value.fetchall. \ - return_value = [('proxyuser', 'proxyuser@otherrealm.com')] - s.krbLogin('krb_req', 'proxyuser@realm.com') - self.assertEqual(context.cnx.cursor.return_value.execute. - call_count, 22) - @mock.patch('koji.auth.context') def test_checkKrbPrincipal(self, context): s, cntext, cursor = self.get_session() diff --git a/tests/test_lib/test_client_session.py b/tests/test_lib/test_client_session.py index 48cbcbe9..269d64a5 100644 --- a/tests/test_lib/test_client_session.py +++ b/tests/test_lib/test_client_session.py @@ -12,31 +12,6 @@ from koji.xmlrpcplus import Fault class TestClientSession(unittest.TestCase): - - @mock.patch('socket.getfqdn') - def test_server_principal_rdns(self, getfqdn): - opts = {'krb_rdns': True} - session = koji.ClientSession('http://koji.example.com:30/kojihub', opts) - cprinc = mock.MagicMock() - cprinc.realm = "REALM" - getfqdn.return_value = 'koji02.example.com' - - princ = session._serverPrincipal(cprinc) - self.assertEqual(princ, 'host/koji02.example.com@REALM') - getfqdn.assert_called_with('koji.example.com') - - @mock.patch('socket.getfqdn') - def test_server_principal_no_rdns(self, getfqdn): - opts = {'krb_rdns': False} - session = koji.ClientSession('http://koji.example.com/kojihub', opts) - cprinc = mock.MagicMock() - cprinc.realm = "REALM" - getfqdn.return_value = 'koji02.example.com' - - princ = session._serverPrincipal(cprinc) - self.assertEqual(princ, 'host/koji.example.com@REALM') - getfqdn.assert_not_called() - @mock.patch('requests.Session') def test_new_session(self, rsession): koji.ClientSession('http://koji.example.com/kojihub') diff --git a/tests/test_lib/test_grab_session_options.py b/tests/test_lib/test_grab_session_options.py index a89fe93c..d46cefd2 100644 --- a/tests/test_lib/test_grab_session_options.py +++ b/tests/test_lib/test_grab_session_options.py @@ -9,7 +9,6 @@ import koji NORMAL_VAL = {'user': 'jdoe', 'password': 'fakepwd', - 'krbservice': 'fakekrbservice', 'debug_xmlrpc': True, 'debug': False, 'max_retries': 3, @@ -20,8 +19,6 @@ NORMAL_VAL = {'user': 'jdoe', 'timeout': 30000, 'use_fast_upload': False, 'upload_blocksize': 1024, - 'krb_rdns': 'fakerdns', - 'krb_canon_host': 'fakehost', 'no_ssl_verify': True, 'serverca': '/fake/serverca.cert', } @@ -30,7 +27,6 @@ EMPTY_VAL = {} NONE_VAL = {'user': None, 'password': None, - 'krbservice': None, 'debug_xmlrpc': None, 'debug': None, 'max_retries': None, @@ -41,8 +37,6 @@ NONE_VAL = {'user': None, 'timeout': None, 'use_fast_upload': None, 'upload_blocksize': None, - 'krb_rdns': None, - 'krb_canon_host': None, 'no_ssl_verify': None, 'serverca': None, } @@ -53,13 +47,11 @@ MIXED_VAL = {'user': None, 'password': None, 'anon_retry': 3, 'timeout': 100, - 'krb_rdns': 'fakerdns', 'meaningless': 'wow', 'nonval': None} MIXED_REL = {'anon_retry': 3, 'timeout': 100, - 'krb_rdns': 'fakerdns', } diff --git a/tests/test_lib/test_krbv.py b/tests/test_lib/test_krbv.py deleted file mode 100644 index 2201f357..00000000 --- a/tests/test_lib/test_krbv.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import absolute_import - -import base64 -# This is python-mock, not the rpm mock tool we know and love -import mock -import six -try: - import unittest2 as unittest -except ImportError: - import unittest - -import koji - - -class KrbVTestCase(unittest.TestCase): - @mock.patch('koji.krbV', new=None) - @mock.patch('koji.requests_kerberos', new=None) - def test_krbv_disabled(self): - """Test that when krbV and gssapi are absent, we behave rationally""" - self.assertEquals(koji.krbV, None) - session = koji.ClientSession('whatever') - with self.assertRaises(ImportError): - session.krb_login() - - # this case should work on python3, but skipped still - @unittest.skipIf(six.PY3, "skipped on python3 since missing of python-krbV") - @mock.patch('koji.krbV', create=True) - @mock.patch('requests_kerberos.__version__', new='0.7.0') - @mock.patch('koji.ClientSession._serverPrincipal') - def test_krbv_old_requests_kerberos(self, _serverPrincipal_mock, krbV_mock): - self.assertIsNotNone(koji.krbV) - ctx = koji.krbV.default_context.return_value - ctx.mk_req = mock.MagicMock() - ac = mock.MagicMock() - ctx.mk_req.return_value = (ac, six.b('req')) - ac.rd_priv = mock.MagicMock(return_value='session-id session-key') - session = koji.ClientSession('whatever') - session._callMethod = mock.MagicMock( - return_value=(base64.encodestring(six.b('a')), base64.encodestring(six.b('b')), [0, 1, 2, 3])) - rv = session.krb_login(principal='any@SOMEWHERE.COM', keytab='/path/to/keytab') - self.assertTrue(rv) diff --git a/util/koji-gc.conf b/util/koji-gc.conf index eff07040..1e69785e 100644 --- a/util/koji-gc.conf +++ b/util/koji-gc.conf @@ -16,12 +16,6 @@ unprotected_keys = server = https://koji.fedoraproject.org/kojihub weburl = https://koji.fedoraproject.org/koji -# The service name of the principal being used by the hub -#krbservice = host - -## The realm of server principal. Using client's realm if not set -# krb_server_realm = EXAMPLE.COM - # The domain name that will be appended to Koji usernames # when creating email notifications #email_domain = fedoraproject.org diff --git a/util/koji-shadow b/util/koji-shadow index 52d2e0c6..656c7eb5 100755 --- a/util/koji-shadow +++ b/util/koji-shadow @@ -44,11 +44,6 @@ from six.moves import range import koji from koji.util import to_list -try: - import krbV -except ImportError: # pragma: no cover - krbV = None - # koji.fp.o keeps stalling, probably network errors... # better to time out than to stall socket.setdefaulttimeout(180) # XXX - too short? @@ -82,8 +77,6 @@ def get_options(): help=_("use alternate configuration file")) parser.add_option("--keytab", help=_("specify a Kerberos keytab to use")) parser.add_option("--principal", help=_("specify a Kerberos principal to use")) - parser.add_option("--krbservice", help=_("the service name of the" - " principal being used by the hub")) parser.add_option("--runas", metavar="USER", help=_("run as the specified user (requires special privileges)")) parser.add_option("--user", help=_("specify user")) @@ -305,17 +298,12 @@ def activate_session(session): elif options.user: # authenticate using user/password session.login() - elif krbV: - try: - if options.keytab and options.principal: - session.krb_login(principal=options.principal, keytab=options.keytab, - proxyuser=options.runas) - else: - session.krb_login(proxyuser=options.runas) - except krbV.Krb5Error as e: - error(_("Kerberos authentication failed: '%s' (%s)") % (e.args[1], e.args[0])) - except socket.error as e: - warn(_("Could not connect to Kerberos authentication service: '%s'") % e.args[1]) + else: + if options.keytab and options.principal: + session.gssapi_login(principal=options.principal, keytab=options.keytab, + proxyuser=options.runas) + else: + session.gssapi_login(proxyuser=options.runas) if not options.noauth and not session.logged_in: error(_("Error: unable to log in")) ensure_connection(session) diff --git a/util/koji-shadow.conf b/util/koji-shadow.conf index daf3bac1..94d92147 100644 --- a/util/koji-shadow.conf +++ b/util/koji-shadow.conf @@ -3,8 +3,4 @@ [main] server=http://localhost/kojihub/ -krbservice=host remote=https://koji.fedoraproject.org/kojihub - -## The realm of server principal. Using client's realm if not set -# krb_server_realm = EXAMPLE.COM diff --git a/util/koji-sidetag-cleanup b/util/koji-sidetag-cleanup index 10a62c6c..b066d12e 100644 --- a/util/koji-sidetag-cleanup +++ b/util/koji-sidetag-cleanup @@ -33,8 +33,6 @@ def get_options(): parser.add_option("-s", "--server", help=_("url of koji XMLRPC server")) parser.add_option("--keytab", help=_("specify a Kerberos keytab to use")) parser.add_option("--principal", help=_("specify a Kerberos principal to use")) - parser.add_option("--krbservice", default="host", - help=_("the service name of the principal being used by the hub")) parser.add_option("--krb-rdns", action="store_true", default=False, help=_("get reverse dns FQDN for krb target")) parser.add_option("--krb-canon-host", action="store_true", default=False, @@ -88,9 +86,6 @@ def get_options(): # name, alias, type ['keytab', None, 'string'], ['principal', None, 'string'], - ['krbservice', None, 'string'], - ['krb_rdns', None, 'boolean'], - ['krb_canon_host', None, 'boolean'], ['runas', None, 'string'], ['user', None, 'string'], ['password', None, 'string'], diff --git a/util/kojira b/util/kojira index 4f54772f..0637a4ee 100755 --- a/util/kojira +++ b/util/kojira @@ -1082,10 +1082,6 @@ def get_options(): 'principal': None, 'keytab': '/etc/kojira/kojira.keytab', 'ccache': '/var/tmp/kojira.ccache', - 'krbservice': 'host', - 'krb_rdns': True, - 'krb_canon_host': False, - 'krb_server_realm': None, 'retry_interval': 60, 'max_retries': 120, 'offline_retry': True, @@ -1114,10 +1110,10 @@ def get_options(): 'delete_batch_size', 'dist_repo_lifetime', 'sleeptime', 'recent_tasks_lifetime') str_opts = ('topdir', 'server', 'user', 'password', 'logfile', 'principal', 'keytab', - 'krbservice', 'cert', 'ca', 'serverca', 'debuginfo_tags', 'queue_file', + 'cert', 'ca', 'serverca', 'debuginfo_tags', 'queue_file', 'source_tags', 'separate_source_tags', 'ignore_tags') # FIXME: remove ca here bool_opts = ('verbose', 'debug', 'ignore_stray_repos', 'offline_retry', - 'krb_rdns', 'krb_canon_host', 'no_ssl_verify', 'check_external_repos') + 'no_ssl_verify', 'check_external_repos') legacy_opts = ('with_src') for name in config.options(section): if name in int_opts: @@ -1195,8 +1191,8 @@ if __name__ == "__main__": elif options.user: # authenticate using user/password session.login() - elif (koji.krbV or koji.requests_kerberos) and options.principal and options.keytab: - session.krb_login(options.principal, options.keytab, options.ccache) + elif koji.requests_kerberos and options.principal and options.keytab: + session.gssapi_login(options.principal, options.keytab, options.ccache) else: quit("No username/password/certificate supplied and Kerberos missing or not configured") # get an exclusive session diff --git a/util/kojira.conf b/util/kojira.conf index e5cb8e7f..e3bb2d08 100644 --- a/util/kojira.conf +++ b/util/kojira.conf @@ -20,12 +20,6 @@ logfile=/var/log/kojira.log ;location of the keytab ;keytab = /etc/kojira/kojira.keytab -;the service name of the principal being used by the hub -;krbservice = host - -;The realm of server principal. Using client's realm if not set -;krb_server_realm = EXAMPLE.COM - ;configuration for SSL authentication ;client certificate diff --git a/vm/kojivmd b/vm/kojivmd index 3366d0b3..5c403c23 100755 --- a/vm/kojivmd +++ b/vm/kojivmd @@ -57,11 +57,6 @@ from koji.tasks import ( # noqa: F401 ServerRestart ) -try: - import krbV -except ImportError: # pragma: no cover - krbV = None - # Register libvirt handler def libvirt_callback(ignore, err): @@ -135,10 +130,6 @@ def get_options(): 'host_principal_format': 'compile/%s@EXAMPLE.COM', 'keytab': '/etc/kojivmd/kojivmd.keytab', 'ccache': '/var/tmp/kojivmd.ccache', - 'krbservice': 'host', - 'krb_rdns': True, - 'krb_canon_host': False, - 'krb_server_realm': None, 'server': None, 'user': None, 'password': None, @@ -160,8 +151,7 @@ def get_options(): defaults[name] = int(value) except ValueError: quit("value for %s option must be a valid integer" % name) - elif name in ['offline_retry', 'krb_rdns', 'krb_canon_host', - 'no_ssl_verify']: + elif name in ['offline_retry', 'no_ssl_verify']: defaults[name] = config.getboolean('kojivmd', name) elif name in ['plugin', 'plugins']: defaults['plugin'] = value.split() @@ -1156,20 +1146,13 @@ if __name__ == "__main__": quit("Error: Unable to log in. Bad credentials?") except requests.exceptions.ConnectionError: quit("Error: Unable to connect to server %s" % (options.server)) - elif krbV: + else: krb_principal = options.krb_principal if krb_principal is None: krb_principal = options.host_principal_format % socket.getfqdn() - try: - session.krb_login(principal=krb_principal, - keytab=options.keytab, - ccache=options.ccache) - except krbV.Krb5Error as e: - quit("Kerberos authentication failed: '%s' (%s)" % (e.args[1], e.args[0])) - except socket.error as e: - quit("Could not connect to Kerberos authentication service: '%s'" % e.args[1]) - else: - quit("No username/password supplied and Kerberos missing or not configured") + session.gssapi_login(principal=krb_principal, + keytab=options.keytab, + ccache=options.ccache) # make session exclusive try: session.exclusiveSession(force=options.force_lock) diff --git a/vm/kojivmd.conf b/vm/kojivmd.conf index 802b19a4..78e3f249 100644 --- a/vm/kojivmd.conf +++ b/vm/kojivmd.conf @@ -42,12 +42,6 @@ from_addr=Koji Build System ;location of the keytab ;keytab = /etc/kojivmd/kojivmd.keytab -;the service name of the principal being used by the hub -;krbservice = host - -;The realm of server principal. Using client's realm if not set -;krb_server_realm = EXAMPLE.COM - ;configuration for SSL authentication ;client certificate diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py index bde4674a..9c3fd02d 100644 --- a/www/kojiweb/index.py +++ b/www/kojiweb/index.py @@ -118,13 +118,13 @@ def _getUserCookie(environ): return user -def _krbLogin(environ, session, principal): +def _gssapiLogin(environ, session, principal): options = environ['koji.options'] wprinc = options['WebPrincipal'] keytab = options['WebKeytab'] ccache = options['WebCCache'] - return session.krb_login(principal=wprinc, keytab=keytab, - ccache=ccache, proxyuser=principal) + return session.gssapi_login(principal=wprinc, keytab=keytab, + ccache=ccache, proxyuser=principal) def _sslLogin(environ, session, username): @@ -146,7 +146,7 @@ def _assertLogin(environ): if not _sslLogin(environ, session, environ['koji.currentLogin']): raise koji.AuthError('could not login %s via SSL' % environ['koji.currentLogin']) elif options['WebPrincipal']: - if not _krbLogin(environ, environ['koji.session'], environ['koji.currentLogin']): + if not _gssapiLogin(environ, environ['koji.session'], environ['koji.currentLogin']): raise koji.AuthError( 'could not login using principal: %s' % environ['koji.currentLogin']) else: @@ -174,12 +174,7 @@ def _assertLogin(environ): def _getServer(environ): opts = environ['koji.options'] - s_opts = {'krbservice': opts['KrbService'], - 'krb_rdns': opts['KrbRDNS'], - 'krb_canon_host': opts['KrbCanonHost'], - 'krb_server_realm': opts['KrbServerRealm'] - } - session = koji.ClientSession(opts['KojiHubURL'], opts=s_opts) + session = koji.ClientSession(opts['KojiHubURL']) environ['koji.currentLogin'] = _getUserCookie(environ) if environ['koji.currentLogin']: @@ -273,7 +268,7 @@ def login(environ, page=None): 'configuration error: mod_auth_gssapi should have performed authentication before ' 'presenting this page') - if not _krbLogin(environ, session, principal): + if not _gssapiLogin(environ, session, principal): raise koji.AuthError('could not login using principal: %s' % principal) username = principal