Skip to content

Commit 5401c93

Browse files
committed
Add S4U2Proxy support
SU2Proxy support is enabled when GssapiUseS4U2Proxy is set to On When S4U2Proxy is enabled GssapiDelegCcacheDir is used to determine where delegated credentials are stored. The ccache type used is always of type FILE and is located in the provided directory (defaults to /tmp). The credentials are stored in a file named after the client credentials so the directory SHOUL NOT be world writeable if a mutiuser system is used as ccache file names are predictable.
1 parent 6e86569 commit 5401c93

File tree

2 files changed

+127
-21
lines changed

2 files changed

+127
-21
lines changed

src/mod_auth_gssapi.c

Lines changed: 124 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,39 @@ static bool mag_conn_is_https(conn_rec *c)
115115
return false;
116116
}
117117

118+
static void mag_store_deleg_creds(request_rec *req,
119+
char *dir, char *clientname,
120+
gss_cred_id_t delegated_cred,
121+
char **ccachefile)
122+
{
123+
gss_key_value_element_desc element;
124+
gss_key_value_set_desc store;
125+
char *value;
126+
uint32_t maj, min;
127+
128+
value = apr_psprintf(req->pool, "FILE:%s/%s", dir, clientname);
129+
if (!value) {
130+
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
131+
"OOM storing delegated credentials");
132+
return;
133+
}
134+
135+
element.key = "ccache";
136+
element.value = value;
137+
store.elements = &element;
138+
store.count = 1;
139+
140+
maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE,
141+
GSS_C_NULL_OID, 1, 1, &store, NULL, NULL);
142+
if (GSS_ERROR(maj)) {
143+
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
144+
mag_error(req, "failed to store delegated creds",
145+
maj, min));
146+
}
147+
148+
*ccachefile = value;
149+
}
150+
118151
static int mag_auth(request_rec *req)
119152
{
120153
const char *type;
@@ -129,6 +162,7 @@ static int mag_auth(request_rec *req)
129162
gss_buffer_desc output = GSS_C_EMPTY_BUFFER;
130163
gss_buffer_desc name = GSS_C_EMPTY_BUFFER;
131164
gss_name_t client = GSS_C_NO_NAME;
165+
gss_cred_id_t acquired_cred = GSS_C_NO_CREDENTIAL;
132166
gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
133167
uint32_t flags;
134168
uint32_t vtime;
@@ -209,7 +243,22 @@ static int mag_auth(request_rec *req)
209243
if (!input.value) goto done;
210244
input.length = apr_base64_decode(input.value, auth_header_value);
211245

212-
maj = gss_accept_sec_context(&min, pctx, GSS_C_NO_CREDENTIAL,
246+
#ifdef HAVE_GSS_ACQUIRE_CRED_FROM
247+
if (cfg->use_s4u2proxy) {
248+
maj = gss_acquire_cred_from(&min, GSS_C_NO_NAME, 0,
249+
GSS_C_NO_OID_SET, GSS_C_BOTH,
250+
cfg->cred_store, &acquired_cred,
251+
NULL, NULL);
252+
if (GSS_ERROR(maj)) {
253+
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, req,
254+
mag_error(req, "gss_acquire_cred_from() failed",
255+
maj, min));
256+
goto done;
257+
}
258+
}
259+
#endif
260+
261+
maj = gss_accept_sec_context(&min, pctx, acquired_cred,
213262
&input, GSS_C_NO_CHANNEL_BINDINGS,
214263
&client, &mech_type, &output, &flags, &vtime,
215264
&delegated_cred);
@@ -234,16 +283,6 @@ static int mag_auth(request_rec *req)
234283
goto done;
235284
}
236285

237-
#ifdef HAVE_GSS_STORE_CRED_INTO
238-
if (cfg->cred_store.count != 0 && delegated_cred != GSS_C_NO_CREDENTIAL) {
239-
gss_key_value_set_desc store = {0, NULL};
240-
/* FIXME: run substitutions */
241-
242-
maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE,
243-
GSS_C_NULL_OID, 1, 1, &store, NULL, NULL);
244-
}
245-
#endif
246-
247286
req->ap_auth_type = apr_pstrdup(req->pool, "Negotiate");
248287

249288
/* Always set the GSS name in an env var */
@@ -257,6 +296,19 @@ static int mag_auth(request_rec *req)
257296
clientname = apr_pstrndup(req->pool, name.value, name.length);
258297
apr_table_set(req->subprocess_env, "GSS_NAME", clientname);
259298

299+
#ifdef HAVE_GSS_STORE_CRED_INTO
300+
if (cfg->deleg_ccache_dir && delegated_cred != GSS_C_NO_CREDENTIAL) {
301+
char *ccachefile = NULL;
302+
303+
mag_store_deleg_creds(req, cfg->deleg_ccache_dir, clientname,
304+
delegated_cred, &ccachefile);
305+
306+
if (ccachefile) {
307+
apr_table_set(req->subprocess_env, "KRB5CCNAME", ccachefile);
308+
}
309+
}
310+
#endif
311+
260312
if (cfg->map_to_local) {
261313
maj = gss_localname(&min, client, mech_type, &lname);
262314
if (maj != GSS_S_COMPLETE) {
@@ -346,6 +398,21 @@ static const char *mag_use_sess(cmd_parms *parms, void *mconfig, int on)
346398
return NULL;
347399
}
348400

401+
static const char *mag_use_s4u2p(cmd_parms *parms, void *mconfig, int on)
402+
{
403+
struct mag_config *cfg = (struct mag_config *)mconfig;
404+
cfg->use_s4u2proxy = on ? true : false;
405+
406+
if (cfg->deleg_ccache_dir == NULL) {
407+
cfg->deleg_ccache_dir = apr_pstrdup(parms->pool, "/tmp");
408+
if (!cfg->deleg_ccache_dir) {
409+
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0,
410+
parms->server, "%s", "OOM setting deleg_ccache_dir.");
411+
}
412+
}
413+
return NULL;
414+
}
415+
349416
static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
350417
{
351418
struct mag_config *cfg = (struct mag_config *)mconfig;
@@ -387,6 +454,8 @@ static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
387454
return NULL;
388455
}
389456

457+
#define MAX_CRED_OPTIONS 10
458+
390459
static const char *mag_cred_store(cmd_parms *parms, void *mconfig,
391460
const char *w)
392461
{
@@ -413,22 +482,49 @@ static const char *mag_cred_store(cmd_parms *parms, void *mconfig,
413482
return NULL;
414483
}
415484

416-
size = sizeof(gss_key_value_element_desc) * cfg->cred_store.count + 1;
417-
elements = apr_palloc(parms->pool, size);
418-
if (!elements) {
485+
if (!cfg->cred_store) {
486+
cfg->cred_store = apr_pcalloc(parms->pool,
487+
sizeof(gss_key_value_set_desc));
488+
if (!cfg->cred_store) {
489+
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server,
490+
"%s", "OOM handling GssapiCredStore option");
491+
return NULL;
492+
}
493+
size = sizeof(gss_key_value_element_desc) * MAX_CRED_OPTIONS;
494+
cfg->cred_store->elements = apr_palloc(parms->pool, size);
495+
if (!cfg->cred_store->elements) {
496+
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server,
497+
"%s", "OOM handling GssapiCredStore option");
498+
}
499+
}
500+
501+
elements = cfg->cred_store->elements;
502+
count = cfg->cred_store->count;
503+
504+
if (count >= MAX_CRED_OPTIONS) {
419505
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server,
420-
"%s", "OOM handling GssapiCredStore option");
506+
"Too many GssapiCredStore options (MAX: %d)",
507+
MAX_CRED_OPTIONS);
421508
return NULL;
422509
}
510+
cfg->cred_store->count++;
423511

424-
for (count = 0; count < cfg->cred_store.count; count++) {
425-
elements[count] = cfg->cred_store.elements[count];
426-
}
427512
elements[count].key = key;
428513
elements[count].value = value;
429514

430-
cfg->cred_store.elements = elements;
431-
cfg->cred_store.count = count;
515+
return NULL;
516+
}
517+
518+
static const char *mag_deleg_ccache_dir(cmd_parms *parms, void *mconfig,
519+
const char *value)
520+
{
521+
struct mag_config *cfg = (struct mag_config *)mconfig;
522+
523+
cfg->deleg_ccache_dir = apr_pstrdup(parms->pool, value);
524+
if (!cfg->deleg_ccache_dir) {
525+
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, parms->server,
526+
"%s", "OOM handling GssapiDelegCcacheDir option");
527+
}
432528

433529
return NULL;
434530
}
@@ -444,8 +540,16 @@ static const command_rec mag_commands[] = {
444540
"Authentication uses mod_sessions to hold status"),
445541
AP_INIT_RAW_ARGS("GssapiSessionKey", mag_sess_key, NULL, OR_AUTHCFG,
446542
"Key Used to seal session data."),
543+
#ifdef HAVE_GSS_ACQUIRE_CRED_FROM
544+
AP_INIT_FLAG("GssapiUseS4U2Proxy", mag_use_s4u2p, NULL, OR_AUTHCFG,
545+
"Initializes credentials for s4u2proxy usage"),
546+
#endif
547+
#ifdef HAVE_GSS_STORE_CRED_INTO
447548
AP_INIT_ITERATE("GssapiCredStore", mag_cred_store, NULL, OR_AUTHCFG,
448549
"Credential Store"),
550+
AP_INIT_RAW_ARGS("GssapiDelegCcacheDir", mag_deleg_ccache_dir, NULL,
551+
OR_AUTHCFG, "Directory to store delegated credentials"),
552+
#endif
449553
{ NULL }
450554
};
451555

src/mod_auth_gssapi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ struct mag_config {
3939
bool map_to_local;
4040
bool gss_conn_ctx;
4141
bool use_sessions;
42-
gss_key_value_set_desc cred_store;
42+
bool use_s4u2proxy;
43+
char *deleg_ccache_dir;
44+
gss_key_value_set_desc *cred_store;
4345
struct seal_key *mag_skey;
4446
};
4547

0 commit comments

Comments
 (0)