mongodb / winkerberos

A native Kerberos client implementation for Python on Windows
Apache License 2.0
54 stars 15 forks source link

Fix explicit principal support #11

Closed behackett closed 7 years ago

behackett commented 8 years ago

The authGSSClientInit implementation in WinKerberos attempts to be fully compatible with pykerberos, including support for the "principal" parameter, while also supporting some SSPI specific options (user, domain, and password). The current support for the principal option appears to be incorrect.

First, some background information. On a *nix machine you login locally, then call kinit to get a TGT. Starting with krb5 1.10 you can take advantage of credential cache collections with the addition of kswitch and improvements to kinit to get TGTs for multiple principals. gss_acquire_cred can find the correct credentials in the correct cache for the principal you specify.

On Windows the situation is very different. First, there is no kinit or kswitch, and klist only lists existing tickets or tgts. The documentation for the pszPrincipal parameter of AcquireCredentialsHandle appears to be wrong. How it is supposed to work is a mystery. Comments here claim that it is ignored in the Kerberos SSP. This post from back in 2001 claims it must be NULL.

The solution to this problem appears to be using the principal argument, when provided, as explicit user and domain when calling AcquireCredentialsHandle. For backward compatibility we should continue to support the user and domain parameters, preferring them if provided.

See https://github.com/requests/requests-kerberos/pull/75 for the discussion leading to this ticket.

behackett commented 8 years ago

Possibly helpful functions:

CredUIParseUserName - https://msdn.microsoft.com/en-us/library/windows/desktop/aa375175(v=vs.85).aspx UrlUnescape - https://msdn.microsoft.com/en-us/library/windows/desktop/bb773791(v=vs.85).aspx

behackett commented 7 years ago

CredUIParseUserName isn't necessary, but UrlUnescapeW is very helpful.

behackett commented 7 years ago

Note that UrlUnescape expects %20 for space, not +, so percent encoding should be done with urllib.quote, not quote_plus.