Bug 204899

Summary: security/py-kerberos: authGSSClientStep raises GSSError UNKNOWN_SERVER
Product: Ports & Packages Reporter: John W. O'Brien <john>
Component: Individual Port(s)Assignee: Dan Langille <dvl>
Status: Closed FIXED    
Severity: Affects Only Me CC: python
Priority: --- Keywords: needs-qa
Version: LatestFlags: bugzilla: maintainer-feedback? (dvl)
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=199123
Attachments:
Description Flags
hostB operational state
none
hostH operational state
none
hostM operational state
none
hostB failing test case
none
hostH failing test case
none
hostM suceeding test case
none
hostB operational state with py-kerberos 1.2.4
none
hostH operational state with py-kerberos 1.2.4
none
hostM operational state with py-kerberos 1.2.4
none
hostB failing test case with py-kerberos 1.2.4
none
hostH failing test case with py-kerberos 1.2.4
none
hostM suceeding test case with py-kerberos 1.2.4
none
security/py-kerberos: Fix name type for BASE and HEIMDAL john: maintainer-approval?

Description John W. O'Brien 2015-11-29 20:35:13 UTC
Summary:
========

When security/py-kerberos 1.1.1 is built with either GSSAPI_BASE or GSSAPI_HEIMDAL, the first invocation of authGSSClientStep raises kerberos.GSSError after failing to acquire a ticket for the krbtgt service on the intended host rather than the specified service.


Expected result:
================

authGSSClientStep should request a service ticket for the specified service and return successfully.


Test environment:
=================

I have three hosts (hostB, hostH, and hostM)---running security/py-kerberos built with GSSAPI_BASE, GSSAPI_HEIMDAL, and GSSAPI_MIT respectively---in the Kerberos realm EXAMPLE.COM, which is running an MIT Kerberos KDC on a third host. For each of the three hosts, I have created service principals for the 'example' service, and performed a kinit to obtain a TGT for my own user principal. Attached are three files showing the (sanitized) output of

    uname -a
    pkg info -xAf kerb heim krb5
    ktutil -k example.keytab l
    klist

on each of the three test hosts.


Test results:
=============

To demonstrate the failure, I use the test.py script from the upstream, PyKerberos-1.1.1 distribution. The invocation and output of the test script is also attached for each of the three test hosts.

I observed the following log lines on the KDC during the failing test cases.

    UNKNOWN_SERVER: authtime 0,  john@EXAMPLE.COM for krbtgt/hostB.example.com@EXAMPLE.COM, Server not found in Kerberos database

    UNKNOWN_SERVER: authtime 0,  john@EXAMPLE.COM for krbtgt/hostH.example.com@EXAMPLE.COM, Server not found in Kerberos database

I observed the following log line on the KDC during the successful test case.

    ISSUE: authtime 1448823471, etypes {rep=18 tkt=18 ses=18}, john@EXAMPLE.COM for example/hostM.example.com@EXAMPLE.COM

Thereafter, on hostM, the output of kinit shows that the credential cache has a ticket for example/hostM.example.com@EXAMPLE.COM.


Fix/Workaround:
===============

Unknown.
Comment 1 John W. O'Brien 2015-11-29 20:35:50 UTC
Created attachment 163659 [details]
hostB operational state
Comment 2 John W. O'Brien 2015-11-29 20:36:09 UTC
Created attachment 163660 [details]
hostH operational state
Comment 3 John W. O'Brien 2015-11-29 20:36:23 UTC
Created attachment 163661 [details]
hostM operational state
Comment 4 John W. O'Brien 2015-11-29 20:36:41 UTC
Created attachment 163662 [details]
hostB failing test case
Comment 5 John W. O'Brien 2015-11-29 20:36:58 UTC
Created attachment 163663 [details]
hostH failing test case
Comment 6 John W. O'Brien 2015-11-29 20:37:16 UTC
Created attachment 163664 [details]
hostM suceeding test case
Comment 7 Kubilay Kocak freebsd_committer freebsd_triage 2015-11-30 01:18:52 UTC
@John is this a regression since the last port update?
Comment 8 John W. O'Brien 2015-11-30 03:03:14 UTC
@koobs: No, it isn't a regression. Prior to ports r401816, via enhancement bug #199123, it was not possible to build security/py-kerberos against the BASE nor HEIMDAL Kerberos implementations. My test case passes when using the MIT Kerberos. There is no net reduction in functionality, just not the intended increase.

"needs-qa" is premature, especially without "needs-patch". Is there a "needs-analysis" or comparable keyword?
Comment 9 Kubilay Kocak freebsd_committer freebsd_triage 2015-11-30 03:41:06 UTC
(In reply to John W. O'Brien from comment #8)

needs-qa is used to cover all the 'has questions / needs checking' cases at the moment for simplicity. Correct current descriptions can be seen here

https://bugs.freebsd.org/bugzilla/describekeywords.cgi
Comment 10 Dan Langille freebsd_committer freebsd_triage 2016-05-03 00:49:15 UTC
Now that security/py-kerberos is on 1.2.4, can someone test for this bug please?
Comment 11 John W. O'Brien 2016-05-15 00:15:30 UTC
Created attachment 170294 [details]
hostB operational state with py-kerberos 1.2.4
Comment 12 John W. O'Brien 2016-05-15 00:16:10 UTC
Created attachment 170295 [details]
hostH operational state with py-kerberos 1.2.4
Comment 13 John W. O'Brien 2016-05-15 00:16:40 UTC
Created attachment 170296 [details]
hostM operational state with py-kerberos 1.2.4
Comment 14 John W. O'Brien 2016-05-15 00:17:21 UTC
Created attachment 170297 [details]
hostB failing test case with py-kerberos 1.2.4
Comment 15 John W. O'Brien 2016-05-15 00:17:53 UTC
Created attachment 170298 [details]
hostH failing test case with py-kerberos 1.2.4
Comment 16 John W. O'Brien 2016-05-15 00:18:24 UTC
Created attachment 170299 [details]
hostM suceeding test case with py-kerberos 1.2.4
Comment 17 John W. O'Brien 2016-05-15 00:19:25 UTC
(In reply to Dan Langille from comment #10)

I reproduced this bug with security/py-kerberos 1.2.4 and updated the attached operational state records and test case results.
Comment 18 John W. O'Brien 2018-01-15 15:18:14 UTC
The problem lies in how the principal name type in the main call to gss_import_name is patched from MIT to Heimdal.

py-kerberos uses [0] gss_krb5_nt_service_name, which krb5 defines as [1] gss_nt_service_name. That symbol is, in turn, set to [2] the OID defined as [3] 1.2.840.113554.1.2.1.4, a.k.a. GSS_C_NT_HOSTBASED_SERVICE. This is consistent with  the API docs for authGSSClientInit [4] and the standard for that name type [5]: "service@hostname". Under the hood, both heimdal and krb5 parse names of that type by splitting on '@' and producing a krb5 principal with two components, the left and right sides.

The adaptation [6] from krb5 to heimdal erroneously pivoted on the "krb5" part of the name instead of the "service" part of the name, and ends up using GSS_KRB5_NT_PRINCIPAL_NAME [7] as a result, which expects a principal of a different form. That name type treats '@' as the separator between multiple '/'-separated components and the realm ("service/hostname@REALM"), not as the separator of two principal components. This explains why, as revealed in the KDC logs for the failing test cases, the client tries to traverse a cross realm trust (krbtgt/hostX.example.com@EXAMPLE.COM) as if the intended hostname were a foreign realm.

I have prepared a patch that I will test and post shortly.

[0] https://github.com/apple/ccs-pykerberos/blob/PyKerberos-1.2.5/src/kerberosgss.c#L153
[1] https://github.com/krb5/krb5/blob/krb5-1.15.2-final/src/lib/gssapi/krb5/gssapi_krb5.h#L101
[2] https://github.com/krb5/krb5/blob/krb5-1.15.2-final/src/lib/gssapi/generic/gssapi_generic.c#L182
[3] https://github.com/krb5/krb5/blob/krb5-1.15.2-final/src/lib/gssapi/generic/gssapi_generic.c#L93
[4] https://github.com/apple/ccs-pykerberos/blob/PyKerberos-1.2.5/pysrc/kerberos.py#L150
[5] https://tools.ietf.org/html/rfc2743#page-85 Section 4.1
[6] https://svnweb.freebsd.org/ports/head/security/py-kerberos/files/extra-patch-src_kerberosgss.h?view=markup&pathrev=401816
[7] https://tools.ietf.org/html/rfc1964#page-13 Section 2.1.1
Comment 19 John W. O'Brien 2018-01-15 16:47:05 UTC
Created attachment 189754 [details]
security/py-kerberos: Fix name type for BASE and HEIMDAL

Changelog
=========

*   Ensure GSSAPI_BASE and GSSAPI_HEIMDAL builds accept the same principal
    name type (GSS_C_NT_HOSTBASED_SERVICE) as GSSAPI_MIT.


QA
==

portlint: OK
poudriere: OK -- testport with py27 using GSSAPI_{BASE,HEIMDAL,MIT}
Comment 20 John W. O'Brien 2018-01-15 16:48:30 UTC
(In reply to John W. O'Brien from comment #19)

Oops. Small typo in the patch. UPDATING should say "built with" not "build with". Please fix before committing.
Comment 21 commit-hook freebsd_committer freebsd_triage 2018-01-30 02:20:51 UTC
A commit references this bug:

Author: dvl
Date: Tue Jan 30 02:20:10 UTC 2018
New revision: 460369
URL: https://svnweb.freebsd.org/changeset/ports/460369

Log:
  Fix for use with either GSSAPI_BASE or GSSAPI_HEIMDAL

  Without, the first invocation of authGSSClientStep raises kerberos.GSSError
  after failing to acquire a ticket for the krbtgt service on the intended host
  rather than the specified service.

  PR:		204899
  Submitted by:	John W. O'Brien <john@saltant.com>

Changes:
  head/security/py-kerberos/Makefile
  head/security/py-kerberos/files/extra-patch-src_kerberosgss.c
  head/security/py-kerberos/files/extra-patch-src_kerberosgss.h
Comment 22 Dan Langille freebsd_committer freebsd_triage 2018-01-30 02:21:35 UTC
Sorry for the delay. Thank you for your work.