Skip to content

Instantly share code, notes, and snippets.

@riton
Last active August 29, 2015 14:09
Show Gist options
  • Save riton/bdf6df5b589a20d46c6e to your computer and use it in GitHub Desktop.
Save riton/bdf6df5b589a20d46c6e to your computer and use it in GitHub Desktop.
remctl_gssapi_s4u2proxy
/**
* Modified version of https://github.com/rra/remctl/blob/master/client/open.c#L187-L243
*/
bool
internal_open(struct remctl *r, const char *host, const char *principal)
{
// [...]
/**
* I've just introduced the flag *GSS_C_DELEG_FLAG*
*/
static const OM_uint32 wanted_gss_flags
= (GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG
| GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG);
static const OM_uint32 req_gss_flags
= (GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG);
// [...]
do {
major = gss_init_sec_context(&init_minor, gss_cred, &gss_context,
name, (const gss_OID) GSS_KRB5_MECHANISM, wanted_gss_flags,
0, NULL, token_ptr, NULL, &send_tok, &gss_flags, NULL);
// [...]
} while (major == GSS_S_CONTINUE_NEEDED);
// [...]
}
/*
* Server implementation of generic protocol functions.
*
* These are the server protocol functions that can be shared between the v1
* and v2 protocol.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Based on work by Anton Ushakov
* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013,
* 2014 The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
/*
* Create a new client struct from a file descriptor and establish a GSS-API
* context as a specified service with an incoming client and fills out the
* client struct. Returns a new client struct on success and NULL on failure,
* logging an appropriate error message.
*/
struct client *
server_new_client(int fd, gss_cred_id_t creds)
{
// [...]
/* Now, do the real work of negotiating the context. */
do {
// [...]
major = gss_accept_sec_context(&acc_minor,
&client->context,
creds,
&recv_tok,
GSS_C_NO_CHANNEL_BINDINGS,
&name,
&doid,
&send_tok,
&client->flags,
NULL,
/**
* Question here:
* When the client uses *GSS_C_DELEG_FLAG* flag,
* the structure above should contain
* the user TGT, isn't it ?
*
* If so, we're already doing unconstrained delegation...
* and that's not what we want here.
*/
&delegated_creds);
/**
* Is there any way to access the TGS sent by the client and
* extract the *service principal* that was used ?
*/
// [...]
} while (major == GSS_S_CONTINUE_NEEDED);
// [...]
if (delegated_creds) {
/**
* Try S4U2Self
* This step is optional but allows us to be sure
* that the KDC permit this operation and the S4U2Self
* operations
*/
majorStatus = gss_acquire_cred_impersonate_name(&minorStatus,
delegated_creds,
/**
* Not sure what to put here for *desired_name*
* The remctl server could use the special
* *GSS_C_NO_CREDENTIAL* value in the previous
* gss_accept_sec_context() call that says that every
* service entry from the keytab could be used.
* So we don't really know wich one was used.
*
* How could we know what our *desired_name* is ?
*
* I know that the client sent a TGS and that this one contains
* the service_name that was used. However, I don't know how
* I could find this TGS and from which structure I should extract it.
*
* Is there any way to find which *principal* was contained in the TGS
* just after the gss_accept_sec_context() call ?
*/
service_name, // We want to retrieve a ticket for ourself
GSS_C_INDEFINITE,
&desired_mechs,
GSS_C_INITIATE,
&impersonated_cred, // Should contain a ticket for ourself
// that belongs to the user owning delegated_creds.
NULL,
NULL);
/* Try S4U2Proxy */
/**
* I'm quite confused here.
* For doing proper S4U2Proxy I didn't really
* figure out:
* - which creds should be used for gss_init_sec_context()
* - which creds should be used for gss_accept_sec_context()
*/
majorStatus = gss_init_sec_context(&minorStatus,
/**
* Which creds should be used here ?
* - user delegated ones ?
* - impersonated ones ?
* - remctl service ones ?
*/
some_creds,
&initiator_context,
/**
* Not sure what to put here for *target_name*
* The remctl server could use the special
* *GSS_C_NO_CREDENTIAL* value that says that every
* service entry from the keytab could be used.
*
* How could we know what our *target_name* is ?
*/
A_gss_name_t, // CHANGE_ME
(const gss_OID) GSS_KRB5_MECHANISM,
GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
GSS_C_INDEFINITE,
GSS_C_NO_CHANNEL_BINDINGS,
GSS_C_NO_BUFFER,
NULL,
&init_token,
NULL,
NULL);
majorStatus = gss_accept_sec_context(&minorStatus,
&acceptor_context,
/**
* Which creds should be used here ?
* - user delegated ones ?
* - impersonated ones ?
* - remctl service ones ?
*/
some_other_creds,
&init_token,
GSS_C_NO_CHANNEL_BINDINGS,
NULL,
NULL,
&accept_token,
NULL,
NULL,
/**
* This is the cred_handle that contains the
* *restrained* credentials and that should
* be written to a Ccache
*/
&output_cred_handle);
// [...]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment