summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README13
-rw-r--r--src/asn1c/GSSSessionData.c17
-rw-r--r--src/asn1c/GSSSessionData.h2
-rw-r--r--src/asn1c/Uint32.c1
-rw-r--r--src/asn1c/Uint32.h1
-rw-r--r--src/asn1c/session.asn13
-rw-r--r--src/environ.c17
-rw-r--r--src/mod_auth_gssapi.c65
-rw-r--r--src/mod_auth_gssapi.h8
-rw-r--r--src/sessions.c10
10 files changed, 103 insertions, 34 deletions
diff --git a/README b/README
index b4eca28..781f3ea 100644
--- a/README
+++ b/README
@@ -171,6 +171,19 @@ A user foo@EXAMPLE.COM delegating its credentials would cause the server to
create a ccache file named /var/run/httpd/clientcaches/foo@EXAMPLE.COM
+### GssapiDelegCcacheUnique
+
+Enables using unique ccache names for delegation. ccache files will be placed
+in GssapiDelegCcacheDir and named using the principal and a six-digit unique
+suffix.
+
+**Note:** Consuming application must delete the ccache otherwise it will
+litter the filesystem if sessions are used. An example sweeper can be found
+in the contrib directory.
+
+#### Example
+ GssapiDelegCcacheUnique On
+
### GssapiUseS4U2Proxy
Enables the use of the s4u2Proxy Kerberos extension also known as
diff --git a/src/asn1c/GSSSessionData.c b/src/asn1c/GSSSessionData.c
index 12a98e3..f0dcc2e 100644
--- a/src/asn1c/GSSSessionData.c
+++ b/src/asn1c/GSSSessionData.c
@@ -2,7 +2,6 @@
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
* From ASN.1 module "GssapiSessionModule"
* found in "session.asn1"
- * `asn1c -fskeletons-copy`
*/
#include "GSSSessionData.h"
@@ -62,6 +61,15 @@ static asn_TYPE_member_t asn_MBR_GSSSessionData_1[] = {
0,
"basichash"
},
+ { ATF_NOFLAGS, 0, offsetof(struct GSSSessionData, ccname),
+ (ASN_TAG_CLASS_CONTEXT | (6 << 2)),
+ +1, /* EXPLICIT tag at current level */
+ &asn_DEF_OCTET_STRING,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ccname"
+ },
};
static ber_tlv_tag_t asn_DEF_GSSSessionData_tags_1[] = {
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
@@ -72,13 +80,14 @@ static asn_TYPE_tag2member_t asn_MAP_GSSSessionData_tag2el_1[] = {
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* expiration */
{ (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* username */
{ (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 }, /* gssname */
- { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 } /* basichash */
+ { (ASN_TAG_CLASS_CONTEXT | (5 << 2)), 5, 0, 0 }, /* basichash */
+ { (ASN_TAG_CLASS_CONTEXT | (6 << 2)), 6, 0, 0 } /* ccname */
};
static asn_SEQUENCE_specifics_t asn_SPC_GSSSessionData_specs_1 = {
sizeof(struct GSSSessionData),
offsetof(struct GSSSessionData, _asn_ctx),
asn_MAP_GSSSessionData_tag2el_1,
- 6, /* Count of tags in the map */
+ 7, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */
-1, /* Start extensions */
-1 /* Stop extensions */
@@ -103,7 +112,7 @@ asn_TYPE_descriptor_t asn_DEF_GSSSessionData = {
/sizeof(asn_DEF_GSSSessionData_tags_1[0]), /* 1 */
0, /* No PER visible constraints */
asn_MBR_GSSSessionData_1,
- 6, /* Elements count */
+ 7, /* Elements count */
&asn_SPC_GSSSessionData_specs_1 /* Additional specs */
};
diff --git a/src/asn1c/GSSSessionData.h b/src/asn1c/GSSSessionData.h
index 53556d8..4ae224f 100644
--- a/src/asn1c/GSSSessionData.h
+++ b/src/asn1c/GSSSessionData.h
@@ -2,7 +2,6 @@
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
* From ASN.1 module "GssapiSessionModule"
* found in "session.asn1"
- * `asn1c -fskeletons-copy`
*/
#ifndef _GSSSessionData_H_
@@ -29,6 +28,7 @@ typedef struct GSSSessionData {
OCTET_STRING_t username;
OCTET_STRING_t gssname;
OCTET_STRING_t basichash;
+ OCTET_STRING_t ccname;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
diff --git a/src/asn1c/Uint32.c b/src/asn1c/Uint32.c
index 794f98b..f5d125a 100644
--- a/src/asn1c/Uint32.c
+++ b/src/asn1c/Uint32.c
@@ -2,7 +2,6 @@
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
* From ASN.1 module "GssapiSessionModule"
* found in "session.asn1"
- * `asn1c -fskeletons-copy`
*/
#include "Uint32.h"
diff --git a/src/asn1c/Uint32.h b/src/asn1c/Uint32.h
index a0ed876..436e26e 100644
--- a/src/asn1c/Uint32.h
+++ b/src/asn1c/Uint32.h
@@ -2,7 +2,6 @@
* Generated by asn1c-0.9.27 (http://lionet.info/asn1c)
* From ASN.1 module "GssapiSessionModule"
* found in "session.asn1"
- * `asn1c -fskeletons-copy`
*/
#ifndef _Uint32_H_
diff --git a/src/asn1c/session.asn1 b/src/asn1c/session.asn1
index 1762812..f499779 100644
--- a/src/asn1c/session.asn1
+++ b/src/asn1c/session.asn1
@@ -8,6 +8,7 @@ GssapiSessionModule DEFINITIONS ::= BEGIN
expiration [2] Uint32,
username [3] OCTET STRING,
gssname [4] OCTET STRING,
- basichash [5] OCTET STRING
+ basichash [5] OCTET STRING,
+ ccname [6] OCTET STRING
}
END
diff --git a/src/environ.c b/src/environ.c
index 1fffc90..c9378b1 100644
--- a/src/environ.c
+++ b/src/environ.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015 mod_auth_gssapi contributors - See COPYING for (C) terms */
+/* Copyright (C) 2015, 2016 mod_auth_gssapi contributors - See COPYING for (C) terms */
#include "mod_auth_gssapi.h"
@@ -243,7 +243,8 @@ static void mag_set_name_attributes(request_rec *req, struct mag_conn *mc)
}
}
-static void mag_set_KRB5CCANME(request_rec *req, char *ccname)
+static void mag_set_KRB5CCANME(request_rec *req, const char *dir,
+ const char *ccname)
{
apr_status_t status;
apr_finfo_t finfo;
@@ -256,7 +257,7 @@ static void mag_set_KRB5CCANME(request_rec *req, char *ccname)
"KRB5CCNAME file (%s) lookup failed!", ccname);
}
- value = apr_psprintf(req->pool, "FILE:%s", ccname);
+ value = apr_psprintf(req->pool, "FILE:%s/%s", dir, ccname);
apr_table_set(req->subprocess_env, "KRB5CCNAME", value);
}
@@ -277,14 +278,8 @@ void mag_set_req_data(request_rec *req,
}
#ifdef HAVE_CRED_STORE
- if (cfg->deleg_ccache_dir && mc->delegated) {
- char *ccname;
- ccname = mag_gss_name_to_ccache_name(req,
- cfg->deleg_ccache_dir,
- mc->gss_name);
- if (ccname) {
- mag_set_KRB5CCANME(req, ccname);
- }
+ if (cfg->deleg_ccache_dir && mc->delegated && mc->ccname) {
+ mag_set_KRB5CCANME(req, cfg->deleg_ccache_dir, mc->ccname);
}
#endif
}
diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c
index 35bb9a1..d2b5d2b 100644
--- a/src/mod_auth_gssapi.c
+++ b/src/mod_auth_gssapi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 mod_auth_gssapi contributors - See COPYING for (C) terms */
+/* Copyright (C) 2014, 2016 mod_auth_gssapi contributors - See COPYING for (C) terms */
#include "mod_auth_gssapi.h"
@@ -202,10 +202,11 @@ static char *escape(apr_pool_t *pool, const char *name,
return escaped;
}
-char *mag_gss_name_to_ccache_name(request_rec *req,
- char *dir, const char *gss_name)
+static char *get_ccache_name(request_rec *req, char *dir, const char *gss_name,
+ bool use_unique, struct mag_conn *mc)
{
- char *escaped;
+ char *ccname, *escaped;
+ int ccachefd;
/* We need to escape away '/', we can't have path separators in
* a ccache file name */
@@ -214,22 +215,32 @@ char *mag_gss_name_to_ccache_name(request_rec *req,
/* then escape away the separator (/) if any */
escaped = escape(req->pool, escaped, '/', "~");
- return apr_psprintf(req->pool, "%s/%s", dir, escaped);
+ if (use_unique == false) {
+ return apr_psprintf(req->pool, "%s/%s", dir, escaped);
+ }
+
+ ccname = apr_psprintf(mc->pool, "%s/%s-XXXXXX", dir, escaped);
+
+ ccachefd = mkstemp(ccname);
+ if (ccachefd == -1) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, req,
+ "creating unique ccache file %s failed", ccname);
+ return NULL;
+ }
+ close(ccachefd);
+ return ccname;
}
-static void mag_store_deleg_creds(request_rec *req,
- char *dir, const char *gss_name,
+static void mag_store_deleg_creds(request_rec *req, const char *ccname,
gss_cred_id_t delegated_cred)
{
gss_key_value_element_desc element;
gss_key_value_set_desc store;
- char *ccname;
uint32_t maj, min;
element.key = "ccache";
store.elements = &element;
store.count = 1;
- ccname = mag_gss_name_to_ccache_name(req, dir, gss_name);
element.value = apr_psprintf(req->pool, "FILE:%s", ccname);
maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE,
@@ -877,9 +888,30 @@ complete:
#ifdef HAVE_CRED_STORE
if (cfg->deleg_ccache_dir && delegated_cred != GSS_C_NO_CREDENTIAL) {
- mag_store_deleg_creds(req, cfg->deleg_ccache_dir, mc->gss_name,
- delegated_cred);
+ char *ccache_path;
+
+ mc->ccname = 0;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, req,
+ "requester: %s", mc->gss_name);
+
+ ccache_path = get_ccache_name(req, cfg->deleg_ccache_dir, mc->gss_name,
+ cfg->deleg_ccache_unique, mc);
+ if (ccache_path == NULL) {
+ goto done;
+ }
+
+ mag_store_deleg_creds(req, ccache_path, delegated_cred);
mc->delegated = true;
+
+ if (!req_cfg->use_sessions && cfg->deleg_ccache_unique) {
+ /* queue removing ccache to avoid littering filesystem */
+ apr_pool_cleanup_register(mc->pool, ccache_path,
+ (int (*)(void *)) unlink,
+ apr_pool_cleanup_null);
+ }
+
+ /* extract filename from full path */
+ mc->ccname = strrchr(ccache_path, '/') + 1;
}
#endif
@@ -1006,6 +1038,15 @@ static const char *mag_use_s4u2p(cmd_parms *parms, void *mconfig, int on)
return NULL;
}
+
+static const char *mag_deleg_ccache_unique(cmd_parms *parms, void *mconfig,
+ int on)
+{
+ struct mag_config *cfg = (struct mag_config *)mconfig;
+ cfg->deleg_ccache_unique = on ? true : false;
+ return NULL;
+}
+
#endif
static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
@@ -1330,6 +1371,8 @@ static const command_rec mag_commands[] = {
"Credential Store"),
AP_INIT_RAW_ARGS("GssapiDelegCcacheDir", mag_deleg_ccache_dir, NULL,
OR_AUTHCFG, "Directory to store delegated credentials"),
+ AP_INIT_FLAG("GssapiDelegCcacheUnique", mag_deleg_ccache_unique, NULL,
+ OR_AUTHCFG, "Use unique ccaches for delgation"),
#endif
#ifdef HAVE_GSS_ACQUIRE_CRED_WITH_PASSWORD
AP_INIT_FLAG("GssapiBasicAuth", mag_use_basic_auth, NULL, OR_AUTHCFG,
diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h
index 1973b2b..0c77b8b 100644
--- a/src/mod_auth_gssapi.h
+++ b/src/mod_auth_gssapi.h
@@ -1,8 +1,10 @@
-/* Copyright (C) 2014 mod_auth_gssapi contributors - See COPYING for (C) terms */
+/* Copyright (C) 2014, 2016 mod_auth_gssapi contributors - See COPYING for (C) terms */
#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>
#include <time.h>
+#include <unistd.h>
#define APR_WANT_STRFUNC
#include "apr_want.h"
@@ -68,6 +70,7 @@ struct mag_config {
bool use_s4u2proxy;
char *deleg_ccache_dir;
gss_key_value_set_desc *cred_store;
+ bool deleg_ccache_unique;;
#endif
struct seal_key *mag_skey;
@@ -112,12 +115,11 @@ struct mag_conn {
bool is_preserved;
int na_count;
struct mag_attr *name_attributes;
+ const char *ccname;
};
#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
struct mag_conn *mag_new_conn_ctx(apr_pool_t *pool);
const char *mag_str_auth_type(int auth_type);
-char *mag_gss_name_to_ccache_name(request_rec *req,
- char *dir, const char *gss_name);
char *mag_error(request_rec *req, const char *msg, uint32_t maj, uint32_t min);
diff --git a/src/sessions.c b/src/sessions.c
index d8c4873..d99b92d 100644
--- a/src/sessions.c
+++ b/src/sessions.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 mod_auth_gssapi contributors - See COPYING for (C) terms */
+/* Copyright (C) 2014, 2016 mod_auth_gssapi contributors - See COPYING for (C) terms */
#include "mod_auth_gssapi.h"
#include "asn1c/GSSSessionData.h"
@@ -179,6 +179,12 @@ void mag_check_session(struct mag_req_cfg *cfg, struct mag_conn **conn)
memcpy(mc->basic_hash.value,
gsessdata->basichash.buf, gsessdata->basichash.size);
+ /* ccname */
+ mc->ccname = apr_pstrndup(mc->pool,
+ (char *)gsessdata->ccname.buf,
+ gsessdata->ccname.size);
+ if (!mc->ccname) goto done;
+
/* OK we have a valid token */
mc->established = true;
@@ -224,6 +230,8 @@ void mag_attempt_session(struct mag_req_cfg *cfg, struct mag_conn *mc)
(const char *)mc->basic_hash.value,
mc->basic_hash.length) != 0)
goto done;
+ if (OCTET_STRING_fromString(&gsessdata.ccname, mc->ccname) != 0)
+ goto done;
ret = encode_GSSSessionData(req->pool, &gsessdata,
&plainbuf.value, &plainbuf.length);
if (ret == false) {