pythongssapi / requests-gssapi

An authentication handler for using GSSAPI with Python Requests. Drop-in replacement for old requests-kerberos.
Other
32 stars 21 forks source link

Wrong realm name used in multi realm environments. #55

Closed tuxmaster5000 closed 1 month ago

tuxmaster5000 commented 1 month ago

What went wrong?

I have an multiple realm environment with the realms:

Using BAR.NET will working as expected, but using FOO.BAR.NET will result in an realm mix. Instant of krbtgt/FOO.BAR.NET@FOO.BAR.NET, krbtgt/BAR.NET@FOO.BAR.NET is requested for the TGT

How do we reproduce?

sample code:

import gssapi
import requests
from requests_gssapi import HTTPSPNEGOAuth
name = gssapi.Name("user@FOO.BAR.NET", gssapi.NameType.user)
creds = gssapi.Credentials(name=name, usage="initiate")
gssapi_auth = HTTPSPNEGOAuth(creds=creds)
r = requests.get("https://<URL>", auth=gssapi_auth)

Client component versions (requests-gssapi, Kerberos, OS / distro, etc.)

OS: Fedora-39 requests-gssapi: python3-requests-gssapi-1.2.3-9.fc39.noarch

Realm config:

[realms]
 FOO.BAR.NET = {
  kdc = kdc-foo.bar.net
  admin_server = kdc-foo.bar.net
 }

KRB5_TRACE:

[128572] 1721036833.397733: Matching user@FOO.BAR.NET in collection with result: 0/Success [128572] 1721036833.397734: Matching user@FOO.BAR.NET in collection with result: 0/Success [128572] 1721036833.397735: Getting credentials user@FOO.BAR.NET -> HTTP/@ using ccache KCM:1000 [128572] 1721036833.397736: Retrieving user@FOO.BAR.NET -> krb5_ccache_conf_data/start_realm@X-CACHECONF: from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397737: Retrieving user@FOO.BAR.NET -> HTTP/@ from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397738: Retrying user@FOO.BAR.NET -> HTTP/@FOO.BAR.NET with result: -1765328243/Matching credential not found [128572] 1721036833.397739: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397740: Retrieving user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET from KCM:1000 with result: 0/Success [128572] 1721036833.397741: Starting with TGT for client realm: user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397742: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397743: Requesting TGT krbtgt/BAR.NET@FOO.BAR.NET using TGT krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397744: Generated subkey for TGS request: aes256-cts/0842 [128572] 1721036833.397745: etypes requested in TGS request: aes256-sha2, aes128-sha2, aes256-cts, aes128-cts, camellia256-cts, camellia128-cts [128572] 1721036833.397747: Encoding request body and padata into FAST request [128572] 1721036833.397748: Sending request (1076 bytes) to FOO.BAR.NET [128572] 1721036833.397749: Resolving hostname [128572] 1721036833.397750: Initiating TCP connection to stream :88 [128572] 1721036833.397751: Sending TCP request to stream :88 [128572] 1721036833.397752: Received answer (454 bytes) from stream :88 [128572] 1721036833.397753: Terminating TCP connection to stream :88 [128572] 1721036833.397754: Sending DNS URI query for _kerberos.FOO.BAR.NET. [128572] 1721036833.397755: No URI records found [128572] 1721036833.397756: Sending DNS SRV query for _kerberos-master._udp.FOO.BAR.NET. [128572] 1721036833.397757: Sending DNS SRV query for _kerberos-master._tcp.FOO.BAR.NET. [128572] 1721036833.397758: No SRV records found [128572] 1721036833.397759: Response was not from primary KDC [128572] 1721036833.397760: Decoding FAST response [128572] 1721036833.397761: TGS request result: -1765328377/Server krbtgt/BAR.NET@FOO.BAR.NET not found in Kerberos database [128572] 1721036833.397762: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397763: Retrieving user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET from KCM:1000 with result: 0/Success [128572] 1721036833.397764: Starting with TGT for client realm: user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397765: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397766: Requesting TGT krbtgt/BAR.NET@FOO.BAR.NET using TGT krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397767: Generated subkey for TGS request: aes256-cts/A633 [128572] 1721036833.397768: etypes requested in TGS request: aes256-sha2, aes128-sha2, aes256-cts, aes128-cts, camellia256-cts, camellia128-cts [128572] 1721036833.397770: Encoding request body and padata into FAST request [128572] 1721036833.397771: Sending request (1076 bytes) to FOO.BAR.NET [128572] 1721036833.397772: Resolving hostname [128572] 1721036833.397773: Initiating TCP connection to stream :88 [128572] 1721036833.397774: Sending TCP request to stream :88 [128572] 1721036833.397775: Received answer (454 bytes) from stream :88 [128572] 1721036833.397776: Terminating TCP connection to stream :88 [128572] 1721036833.397777: Sending DNS URI query for _kerberos.FOO.BAR.NET. [128572] 1721036833.397778: No URI records found [128572] 1721036833.397779: Sending DNS SRV query for _kerberos-master._udp.FOO.BAR.NET. [128572] 1721036833.397780: Sending DNS SRV query for _kerberos-master._tcp.FOO.BAR.NET. [128572] 1721036833.397781: No SRV records found [128572] 1721036833.397782: Response was not from primary KDC [128572] 1721036833.397783: Decoding FAST response [128572] 1721036833.397784: TGS request result: -1765328377/Server krbtgt/BAR.NET@FOO.BAR.NET not found in Kerberos database [128572] 1721036833.397785: Getting credentials user@FOO.BAR.NET -> HTTP/@ using ccache KCM:1000 [128572] 1721036833.397786: Retrieving user@FOO.BAR.NET -> krb5_ccache_conf_data/start_realm@X-CACHECONF: from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397787: Retrieving user@FOO.BAR.NET -> HTTP/@ from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397788: Retrying user@FOO.BAR.NET -> HTTP/@FOO.BAR.NET with result: -1765328243/Matching credential not found [128572] 1721036833.397789: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397790: Retrieving user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET from KCM:1000 with result: 0/Success [128572] 1721036833.397791: Starting with TGT for client realm: user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397792: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397793: Requesting TGT krbtgt/BAR.NET@FOO.BAR.NET using TGT krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397794: Generated subkey for TGS request: aes256-cts/1174 [128572] 1721036833.397795: etypes requested in TGS request: aes256-sha2, aes128-sha2, aes256-cts, aes128-cts, camellia256-cts, camellia128-cts [128572] 1721036833.397797: Encoding request body and padata into FAST request [128572] 1721036833.397798: Sending request (1076 bytes) to FOO.BAR.NET [128572] 1721036833.397799: Resolving hostname [128572] 1721036833.397800: Initiating TCP connection to stream :88 [128572] 1721036833.397801: Sending TCP request to stream :88 [128572] 1721036833.397802: Received answer (454 bytes) from stream :88 [128572] 1721036833.397803: Terminating TCP connection to stream :88 [128572] 1721036833.397804: Sending DNS URI query for _kerberos.FOO.BAR.NET. [128572] 1721036833.397805: No URI records found [128572] 1721036833.397806: Sending DNS SRV query for _kerberos-master._udp.FOO.BAR.NET. [128572] 1721036833.397807: Sending DNS SRV query for _kerberos-master._tcp.FOO.BAR.NET. [128572] 1721036833.397808: No SRV records found [128572] 1721036833.397809: Response was not from primary KDC [128572] 1721036833.397810: Decoding FAST response [128572] 1721036833.397811: TGS request result: -1765328377/Server krbtgt/BAR.NET@FOO.BAR.NET not found in Kerberos database [128572] 1721036833.397812: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397813: Retrieving user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET from KCM:1000 with result: 0/Success [128572] 1721036833.397814: Starting with TGT for client realm: user@FOO.BAR.NET -> krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397815: Retrieving user@FOO.BAR.NET -> krbtgt/BAR.NET@BAR.NET from KCM:1000 with result: -1765328243/Matching credential not found [128572] 1721036833.397816: Requesting TGT krbtgt/BAR.NET@FOO.BAR.NET using TGT krbtgt/FOO.BAR.NET@FOO.BAR.NET [128572] 1721036833.397817: Generated subkey for TGS request: aes256-cts/7B89 [128572] 1721036833.397818: etypes requested in TGS request: aes256-sha2, aes128-sha2, aes256-cts, aes128-cts, camellia256-cts, camellia128-cts [128572] 1721036833.397820: Encoding request body and padata into FAST request [128572] 1721036833.397821: Sending request (1076 bytes) to FOO.BAR.NET [128572] 1721036833.397822: Resolving hostname [128572] 1721036833.397823: Initiating TCP connection to stream :88 [128572] 1721036833.397824: Sending TCP request to stream :88 [128572] 1721036833.397825: Received answer (454 bytes) from stream :88 [128572] 1721036833.397826: Terminating TCP connection to stream :88 [128572] 1721036833.397827: Sending DNS URI query for _kerberos.FOO.BAR.NET. [128572] 1721036833.397828: No URI records found [128572] 1721036833.397829: Sending DNS SRV query for _kerberos-master._udp.FOO.BAR.NET. [128572] 1721036833.397830: Sending DNS SRV query for _kerberos-master._tcp.FOO.BAR.NET. [128572] 1721036833.397831: No SRV records found [128572] 1721036833.397832: Response was not from primary KDC [128572] 1721036833.397833: Decoding FAST response [128572] 1721036833.397834: TGS request result: -1765328377/Server krbtgt/BAR.NET@FOO.BAR.NET not found in Kerberos database

jborean93 commented 1 month ago

This library and python-gssapi doesn't have the logic for what TGT is used in an authentication request. What happens is the username "name" and the service "name" is provided to the C library which does all the Kerberos logic. The username "name" is provided through the gssapi.Credentials whereas the service "name" either provided explicitly through the target_name kwarg or built from the hostname of the first response.

https://github.com/pythongssapi/requests-gssapi/blob/93660c3f59c9955dabd0a208981329c2357930cd/src/requests_gssapi/gssapi_.py#L149-L154

Basically the default SPN used will be f"HTTP@{urlparse(response.url).hostname}" and that is what will be provided to GSSAPI. The actual logic for selecting what to use for the TGT is all inside the C library so you can specify a custom SPN through the target_name kwarg but how that SPN is used is up to the C library and how it reads the configuration.

tuxmaster5000 commented 1 month ago

The HTTP request will not been made as you can see in the log. Of course this will be the second step after getting the TGT. But the TGT parts fails.

jborean93 commented 1 month ago

The default operation for this library is to make the HTTP request and then handle the authentication on the first 401 response from the server.

https://github.com/pythongssapi/requests-gssapi/blob/93660c3f59c9955dabd0a208981329c2357930cd/src/requests_gssapi/gssapi_.py#L198-L209

You can set opportunistic_auth=True as a kwarg to build the auth header before the request but it's also going to just use the hostname of the request as part of the SPN to target. As I said this library doesn't do anything special to build the SPN. It simply takes the hostname from either the request or response and uses http@hostname which is provided to the C library. If that is producing the wrong mapping then your either need to configure the /etc/krb5.conf to map that hostname in some way to the realm it needs.

tuxmaster5000 commented 1 month ago

After debug with wire shark I found the problem. The underlying library was doing the call to can wrong KDC.