Python, Kerberos and ticket forwarding ..... please help

Greg Hudson ghudson at MIT.EDU
Mon Jul 22 11:49:29 EDT 2013

On 07/22/2013 04:49 AM, message adams wrote:
> As time was running out, as a last resort I thought I'd throw the question
> out to the experts (you guys:-). I know you are all busy, but I would
> really appreciate any guidance, or ideally some example code, to
> demonstrate how the Python Kerberos wrapper can be used to forward a
> client's ticket. (Note - the client's ticket is already configured as F
> 'forwardable').

I hadn't heard of this particular Python wrapper before.  From a brief
look, it may lack the necessary server-side support for what you want to do.

As Dmitri mentioned, there are two different ways of doing three-tier
apps with Kerberos authentication: traditional TGT forwarding and
S4U2Proxy.  I will cover both of them.

Traditional TGT forwarding

Traditional TGT forwarding is probably best matched to a login-type
service where the server should have access to the full range of the
user's privileges, and a single security context is used for a
relatively long-lived session.  It does not map well onto web browser
authentication, where many security contexts are used and the web server
should only have access to a limited range of the user's privileges.

In this scenario, a client calls gss_init_sec_context with the
GSS_C_DELEG_FLAG flag (or perhaps the GSS_C_DELEG_POLICY_FLAG if it
wants to respect the KDC configuration of the service principal).  The
client will obtain a fresh TGT from the KDC and forward it to the
server, which receives the forwarded credential in the
delegated_cred_handle output parameter of gss_accept_sec_context.  The
server can use gss_store_cred to store the delegated cred in a ticket
cache, or it can just pass it to gss_init_sec_context to contact the
third service.

The Python wrapper has client-side support for this scenario;
authGSSClientInit has an optional gssflags argument, and the module
defines the GSS_C_DELEG_FLAG value.  However, I don't see meaningful
server support.  The wrapper's call to gss_accept_sec_context receives
delegated client creds and puts them into its internal state object, but
it never does anything with them except release them later.


S4U2Proxy is best matched to a scenario where the intermediate service
should have access to only a particular target service (e.g. a web
server which should be able to access an IMAP server to read users'
email), but you aren't especially worried about the intermediate service
impersonating users who haven't made a deliberate decision to allow it
access.  S4U2Proxy can work when the client uses Kerberos authentication
to the intermediate server, or the intermediate server can (if it is
allowed to) use a second facility called S4U2Self to obtain tickets to
itself on behalf of the client.  I will only talk about the first
variant here.

In this scenario, a client does nothing special except to obtain
forwardable service tickets (which is normal if it has a forwardable
TGT).  It calls gss_init_sec_context normally, and does not take any
special protocol action beyond authenticating with the forwardable
service ticket.

The intermediate service calls gss_acquire_cred with GSS_C_BOTH in the
cred_usage parameter, and passes the resulting cred object as the
acceptor_cred_handle parameter to gss_accept_sec_context.  When it does
so, it receives a synthesized "delegated credential" in the
delegated_cred_handle output parameter.  This can be stored with
gss_store_cred or simply used with gss_init_sec_context.  When it is
used with gss_init_sec_context, the service makes an S4U2Proxy request
to the KDC to obtain a service ticket on behalf of the user to the
target service.

The Python wrapper does not appear to have server-side support for this
scenario.  It only ever obtains acceptor creds with the GSS_C_ACCEPT
usage, and as noted previously, it never does anything with delegated
client creds when it receives them.

More information about the krbdev mailing list