Skip to content

Commit

Permalink
Add hostname canonicalization helper to k5test.py
Browse files Browse the repository at this point in the history
To facilitate fallback tests, add a canonicalize_hostname() function
to k5test.py which works similarly to krb5_expand_hostname().  Use it
in t_gssapi.py for the recently-added acceptor name fallback test.
  • Loading branch information
greghudson committed Jan 28, 2021
1 parent fcdaede commit 225fffe
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
11 changes: 3 additions & 8 deletions src/tests/gssapi/t_gssapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
realm.run(['./t_iov', '-s', 'p:' + realm.host_princ])
realm.run(['./t_pcontok', 'p:' + realm.host_princ])

realm = K5Realm(krb5_conf={'libdefaults': {'rdns': 'false'}})
realm = K5Realm()

# Test gss_add_cred().
realm.run(['./t_add_cred'])
Expand Down Expand Up @@ -62,13 +62,8 @@
expected_msg=' not found in keytab')

# If possible, test with an acceptor name requiring fallback to match
# against a keytab entry. Forward-canonicalize the hostname, relying
# on the rdns=false realm setting.
try:
ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
(family, socktype, proto, canonname, sockaddr) = ai[0]
except socket.gaierror:
canonname = hostname
# against a keytab entry.
canonname = canonicalize_hostname(hostname)
if canonname != hostname:
os.rename(realm.keytab, realm.keytab + '.save')
canonprinc = 'host/' + canonname
Expand Down
22 changes: 22 additions & 0 deletions src/util/k5test.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@
* password(name): Return a weakly random password based on name. The
password will be consistent across calls with the same name.
* canonicalize_hostname(name, rdns=True): Return the DNS
canonicalization of name, optionally using reverse DNS. On error,
return name converted to lowercase.
* stop_daemon(proc): Stop a daemon process started with
realm.start_server() or realm.start_in_inetd(). Only necessary if
the port needs to be reused; daemon processes will be stopped
Expand Down Expand Up @@ -458,6 +462,24 @@ def password(name):
return name + str(os.getpid())


def canonicalize_hostname(name, rdns=True):
"""Canonicalize name using DNS, optionally with reverse DNS."""
try:
ai = socket.getaddrinfo(name, None, 0, 0, 0, socket.AI_CANONNAME)
except socket.gaierror as e:
return name.lower()
(family, socktype, proto, canonname, sockaddr) = ai[0]

if not rdns:
return canonname.lower()

try:
rname = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
except socket.gaierror:
return canonname.lower()
return rname[0].lower()


# Exit handler which ensures processes are cleaned up and, on failure,
# prints messages to help developers debug the problem.
def _onexit():
Expand Down

0 comments on commit 225fffe

Please sign in to comment.