From edda41100ce625e2e3d502a9ab877beeb902422f Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 27 2017 19:32:25 +0000
Subject: [PATCH 1/3] krb_canon_host option to canonicalize hostname via dns


---

diff --git a/koji/__init__.py b/koji/__init__.py
index cfc47d2..305cca3 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -34,6 +34,11 @@ except ImportError:  # pragma: no cover
     pass
 import base64
 import datetime
+dns_resolver = None
+try:
+    import dns.resolver as dns_resolver
+except ImportError:  # pragma: no cover
+    pass
 import six.moves.configparser
 import errno
 from fnmatch import fnmatch
@@ -1641,6 +1646,7 @@ def read_config(profile_name, user_config=None):
         'poll_interval': 6,
         'krbservice': 'host',
         'krb_rdns': True,
+        'krb_canon_host': False,
         'principal': None,
         'keytab': None,
         'cert': None,
@@ -1703,7 +1709,7 @@ def read_config(profile_name, user_config=None):
                 if name in result:
                     if name in ('anon_retry', 'offline_retry', 'keepalive',
                                 'use_fast_upload', 'krb_rdns', 'use_old_ssl',
-                                'debug', 'debug_xmlrpc'):
+                                'debug', 'debug_xmlrpc', 'krb_canon_host'):
                         result[name] = config.getboolean(profile_name, name)
                     elif name in ('max_retries', 'retry_interval',
                                   'offline_retry_interval', 'poll_interval', 'timeout',
@@ -2027,6 +2033,7 @@ def grab_session_options(options):
         'use_fast_upload',
         'upload_blocksize',
         'krb_rdns',
+        'krb_canon_host',
         'use_old_ssl',
         'no_ssl_verify',
         'serverca',
@@ -2194,14 +2201,25 @@ class ClientSession(object):
         to, based on baseurl."""
 
         host = six.moves.urllib.parse.urlparse(self.baseurl).hostname
-        if self.opts.get('krb_rdns', True):
-            servername = socket.getfqdn(host)
-        else:
-            servername = host
+        servername = self._fix_krb_host(host)
         realm = cprinc.realm
         service = self.opts.get('krbservice', 'host')
 
-        return '%s/%s@%s' % (service, servername, realm)
+        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()
+        if self.opts.get('krb_rdns', True):
+            return socket.getfqdn(host)
+        # else
+        return host
 
     def gssapi_login(self, proxyuser=None):
         if not HTTPKerberosAuth:

From 900767cf4b800e79ef3756622a5cd3093e70cd95 Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 27 2017 19:32:25 +0000
Subject: [PATCH 2/3] add krb_canon_host option to various clients


---

diff --git a/builder/kojid b/builder/kojid
index 258949a..98e1fb5 100755
--- a/builder/kojid
+++ b/builder/kojid
@@ -5603,6 +5603,7 @@ def get_options():
                 'ccache': '/var/tmp/kojid.ccache',
                 'krbservice': 'host',
                 'krb_rdns': True,
+                'krb_canon_host': False,
                 'server': None,
                 'user': None,
                 'password': None,
@@ -5640,7 +5641,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', 'keepalive', 'use_fast_upload',
-                          'support_rpm_source_layout', 'krb_rdns',
+                          'support_rpm_source_layout', 'krb_rdns', 'krb_canon_host',
                           'build_arch_can_fail', 'use_old_ssl', 'no_ssl_verify']:
                 defaults[name] = config.getboolean('kojid', name)
             elif name in ['plugin', 'plugins']:
diff --git a/util/koji-gc b/util/koji-gc
index bea2cd3..9c20cdb 100755
--- a/util/koji-gc
+++ b/util/koji-gc
@@ -54,6 +54,8 @@ def get_options():
                       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,
+                      help=_("get canonical hostname for krb target"))
     parser.add_option("--runas", metavar="USER",
                       help=_("run as the specified user (requires special privileges)"))
     parser.add_option("--user", help=_("specify user"))
@@ -134,6 +136,7 @@ def get_options():
             ['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/koji-shadow b/util/koji-shadow
index 37c2811..12f9997 100755
--- a/util/koji-shadow
+++ b/util/koji-shadow
@@ -91,6 +91,8 @@ def get_options():
     parser.add_option("--password", help=_("specify password"))
     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,
+                      help=_("get canonical hostname for krb target"))
     parser.add_option("--noauth", action="store_true", default=False,
                       help=_("do not authenticate"))
     parser.add_option("-n", "--test", action="store_true", default=False,
diff --git a/util/kojira b/util/kojira
index 02ca19f..ba8d6fd 100755
--- a/util/kojira
+++ b/util/kojira
@@ -739,6 +739,7 @@ def get_options():
                 'ccache': '/var/tmp/kojira.ccache',
                 'krbservice': 'host',
                 'krb_rdns': True,
+                'krb_canon_host': False,
                 'retry_interval': 60,
                 'max_retries': 120,
                 'offline_retry': True,
@@ -766,7 +767,7 @@ def get_options():
         str_opts = ('topdir', 'server', 'user', 'password', 'logfile', 'principal', 'keytab', 'krbservice',
                     'cert', 'ca', 'serverca', 'debuginfo_tags', 'source_tags')  # FIXME: remove ca here
         bool_opts = ('with_src','verbose','debug','ignore_stray_repos', 'offline_retry',
-                     'krb_rdns', 'use_old_ssl', 'no_ssl_verify')
+                     'krb_rdns', 'krb_canon_host', 'use_old_ssl', 'no_ssl_verify')
         for name in config.options(section):
             if name in int_opts:
                 defaults[name] = config.getint(section, name)
diff --git a/vm/kojivmd b/vm/kojivmd
index d2a2e90..9df9cbb 100755
--- a/vm/kojivmd
+++ b/vm/kojivmd
@@ -123,6 +123,7 @@ def get_options():
                 'ccache': '/var/tmp/kojivmd.ccache',
                 'krbservice': 'host',
                 'krb_rdns': True,
+                'krb_canon_host': False,
                 'server': None,
                 'user': None,
                 'password': None,
@@ -145,8 +146,8 @@ 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', 'use_old_ssl',
-                          'no_ssl_verify']:
+            elif name in ['offline_retry', 'krb_rdns', 'krb_canon_host',
+                          'use_old_ssl', 'no_ssl_verify']:
                 defaults[name] = config.getboolean('kojivmd', name)
             elif name in ['plugin', 'plugins']:
                 defaults['plugin'] = value.split()
diff --git a/www/kojiweb/index.py b/www/kojiweb/index.py
index 237e7d0..3eaf46e 100644
--- a/www/kojiweb/index.py
+++ b/www/kojiweb/index.py
@@ -158,9 +158,11 @@ def _assertLogin(environ):
 
 def _getServer(environ):
     opts = environ['koji.options']
-    session = koji.ClientSession(opts['KojiHubURL'],
-                                 opts={'krbservice': opts['KrbService'],
-                                       'krb_rdns': opts['KrbRDNS']})
+    s_opts = {'krbservice': opts['KrbService'],
+              'krb_rdns': opts['KrbRDNS'],
+              'krb_canon_host': opts['KrbCanonHost'],
+              }
+    session = koji.ClientSession(opts['KojiHubURL'], opts=s_opts)
 
     environ['koji.currentLogin'] = _getUserCookie(environ)
     if environ['koji.currentLogin']:
diff --git a/www/kojiweb/wsgi_publisher.py b/www/kojiweb/wsgi_publisher.py
index c69559e..778d992 100644
--- a/www/kojiweb/wsgi_publisher.py
+++ b/www/kojiweb/wsgi_publisher.py
@@ -76,6 +76,7 @@ class Dispatcher(object):
         ['WebCCache', 'string', '/var/tmp/kojiweb.ccache'],
         ['KrbService', 'string', 'host'],
         ['KrbRDNS', 'boolean', True],
+        ['KrbCanonHost', 'boolean', False],
 
         ['WebCert', 'string', None],
         ['KojiHubCA', 'string', '/etc/kojiweb/kojihubca.crt'],

From d8fb302780e7c64972c6f64fc2ee223b9fd14eed Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 27 2017 19:32:25 +0000
Subject: [PATCH 3/3] add krb_canon_host example in koji.conf


---

diff --git a/cli/koji.conf b/cli/koji.conf
index fe237fc..26c24cf 100644
--- a/cli/koji.conf
+++ b/cli/koji.conf
@@ -25,6 +25,10 @@
 ;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
+
+
 ;configuration for SSL authentication
 
 ;client certificate

