From 591fad86aba3520a76eaf75aa0fd5e585fac94a5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 13 Nov 2013 19:54:27 -0500 Subject: [PATCH 1/5] Autoinitialize creds on init_sec_context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the remote client tries to initialize the context without first acquiring credentials, try to acquire appropriate credentials if the service allows it. Reviewed-by: Günther Deschner --- proxy/src/gp_rpc_init_sec_context.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c index 2781238..76ffaab 100644 --- a/proxy/src/gp_rpc_init_sec_context.c +++ b/proxy/src/gp_rpc_init_sec_context.c @@ -24,6 +24,7 @@ */ #include "gp_rpc_process.h" +#include int gp_init_sec_context(struct gp_call_ctx *gpcall, union gp_rpc_arg *arg, @@ -74,13 +75,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, if (ret_maj) { goto done; } - } else { - /* FIXME: get ccache from gpsvc ? */ - ret_maj = GSS_S_CRED_UNAVAIL; - ret_min = 0; - goto done; } - ret_maj = gp_conv_gssx_to_name(&ret_min, isca->target_name, &target_name); if (ret_maj) { goto done; @@ -107,6 +102,23 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, gp_conv_gssx_to_buffer(isca->input_token, &ibuf); } + if (!isca->cred_handle) { + if (gss_oid_equal(mech_type, gss_mech_krb5)) { + ret_maj = gp_add_krb5_creds(&ret_min, gpcall, + NULL, NULL, + GSS_C_INITIATE, + time_req, 0, &ich, + NULL, NULL, NULL); + } else { + ret_maj = GSS_S_NO_CRED; + ret_min = 0; + } + + if (ret_maj) { + goto done; + } + } + ret_maj = gss_init_sec_context(&ret_min, ich, &ctx, @@ -170,5 +182,6 @@ done: &iscr->status); gss_release_name(&ret_min, &target_name); gss_release_oid(&ret_min, &mech_type); + gss_release_cred(&ret_min, &ich); return ret; } -- 1.8.3.1 From 32b1d5aa0497c4e3677b4575cc7e299590df5618 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 13 Nov 2013 20:03:53 -0500 Subject: [PATCH 2/5] Try impersonation even when a name is not provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases a name may not be provided, still try to perform impersonation if the service is configured that way. Reviewed-by: Günther Deschner --- proxy/src/gp_creds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c index e02a667..5337390 100644 --- a/proxy/src/gp_creds.c +++ b/proxy/src/gp_creds.c @@ -289,6 +289,11 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall, } *requested_name = name; } + } else { + /* No name provided */ + if (svc->euid != target_uid) { + user_requested = true; + } } /* impersonation case (only for initiation) */ -- 1.8.3.1 From 6a096c0a0a37d2fa9e0b03edce05929a7d98f390 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 Nov 2013 17:01:24 -0500 Subject: [PATCH 3/5] config: Add code to source flag filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2 New configuration options are made available: - filter_flags - enforce_flags Any GSS Flags listed in the filter_flags option is forcibly filtered out before a gss_init_sec_context() call is invoked. Any GSS Flags listed in the enforce_flags option is forcibly added to the list of flags requested by a gss_init_sec_context() call is invoked. Flags can be either literals or numeric and must be preceded by the sign + (to add to the list) or - (to remove from the list). Resolves: https://fedorahosted.org/gss-proxy/ticket/109 Reviewed-by: Günther Deschner --- proxy/src/gp_config.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ proxy/src/gp_proxy.h | 2 ++ 2 files changed, 90 insertions(+) diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index 8da291b..e21e70d 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -32,6 +32,27 @@ #include "gp_config.h" #include "gp_selinux.h" +#include + +struct gp_flag_def { + const char *name; + uint32_t value; +}; + +struct gp_flag_def flag_names[] = { + { "DELEGATE", GSS_C_DELEG_FLAG }, + { "MUTUAL_AUTH", GSS_C_MUTUAL_FLAG }, + { "REPLAY_DETECT", GSS_C_REPLAY_FLAG }, + { "SEQUENCE", GSS_C_SEQUENCE_FLAG }, + { "CONFIDENTIALITY", GSS_C_CONF_FLAG }, + { "INTEGRITIY", GSS_C_INTEG_FLAG }, + { "ANONYMOUS", GSS_C_ANON_FLAG }, + { NULL, 0 } +}; + +#define DEFAULT_FILTERED_FLAGS GSS_C_DELEG_FLAG +#define DEFAULT_ENFORCED_FLAGS 0 + static void free_str_array(const char ***a, int *count) { const char **array; @@ -117,6 +138,60 @@ static int get_krb5_mech_cfg(struct gp_service *svc, return ret; } +static int parse_flags(const char *value, uint32_t *storage) +{ + char *handle; + char *token; + char *str; + bool add; + unsigned long int conv; + uint32_t flagval; + int i; + + str = strdup(value); + if (!str) { + return ENOMEM; + } + + token = strtok_r(str, ", ", &handle); + for (token = strtok_r(str, ", ", &handle); + token != NULL; + token = strtok_r(NULL, ", ", &handle)) { + switch (token[0]) { + case '+': + add = true; + break; + case '-': + add = false; + break; + default: + GPERROR("Ignoring flag [%s], missing +/- qualifier.\n", token); + continue; + } + token++; + for (i = 0; flag_names[i].name != NULL; i++) { + if (strcasecmp(token, flag_names[i].name) == 0) { + flagval = flag_names[i].value; + break; + } + } + if (flag_names[i].name == NULL) { + conv = strtoul(token, &handle, 0); + if (conv == 0 || conv == ULONG_MAX || *handle != '\0') { + GPERROR("Ignoring flag [%s], unrecognized value.\n", token); + continue; + } + flagval = conv; + } + GPDEBUG("%s Flag %s (%u).\n", add?"Add":"Remove", token, flagval); + if (add) *storage |= flagval; + else *storage &= ~flagval; + } + safefree(str); + + return 0; +} + static int setup_service_creds_handle(struct gp_service *svc) { uint32_t ret_maj, ret_min; @@ -297,6 +372,19 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx) goto done; } } + + cfg->svcs[n]->filter_flags = DEFAULT_FILTERED_FLAGS; + ret = gp_config_get_string(ctx, secname, "filter_flags", &value); + if (ret == 0) { + parse_flags(value, &cfg->svcs[n]->filter_flags); + } + + cfg->svcs[n]->enforce_flags = DEFAULT_ENFORCED_FLAGS; + ret = gp_config_get_string(ctx, secname, "enforce_flags", &value); + if (ret == 0) { + ret = parse_flags(value, &cfg->svcs[n]->enforce_flags); + if (ret) goto done; + } } safefree(secname); } diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index 8390f5d..b6c64ae 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -57,6 +57,8 @@ struct gp_service { char *socket; SELINUX_CTX selinux_ctx; gss_cred_usage_t cred_usage; + uint32_t filter_flags; + uint32_t enforce_flags; uint32_t mechs; struct gp_cred_krb5 krb5; -- 1.8.3.1 From 3df6ac81f4a6d8cf6ff514e7d7f2cbe58840c393 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 Nov 2013 17:09:45 -0500 Subject: [PATCH 4/5] server: Implement flag filtering enforcement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://fedorahosted.org/gss-proxy/ticket/109 Reviewed-by: Günther Deschner --- proxy/src/gp_creds.c | 6 ++++++ proxy/src/gp_rpc_creds.h | 3 +++ proxy/src/gp_rpc_init_sec_context.c | 2 ++ 3 files changed, 11 insertions(+) diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c index 5337390..60c4e12 100644 --- a/proxy/src/gp_creds.c +++ b/proxy/src/gp_creds.c @@ -548,3 +548,9 @@ done: return ret_maj; } + +void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags) +{ + *flags |= gpcall->service->enforce_flags; + *flags &= ~gpcall->service->filter_flags; +} diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h index 6389ebe..4c8febb 100644 --- a/proxy/src/gp_rpc_creds.h +++ b/proxy/src/gp_rpc_creds.h @@ -46,4 +46,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min, gss_OID_set *actual_mechs, uint32_t *initiator_time_rec, uint32_t *acceptor_time_rec); + +void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags); + #endif /* _GP_RPC_CREDS_H_ */ diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c index 76ffaab..5e5d6f1 100644 --- a/proxy/src/gp_rpc_init_sec_context.c +++ b/proxy/src/gp_rpc_init_sec_context.c @@ -119,6 +119,8 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, } } + gp_filter_flags(gpcall, &req_flags); + ret_maj = gss_init_sec_context(&ret_min, ich, &ctx, -- 1.8.3.1 From c8386418a754211da5ddf5469a0f1c0fddf21240 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 Nov 2013 17:27:52 -0500 Subject: [PATCH 5/5] man: Describe new flag filtering/enforcing options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://fedorahosted.org/gss-proxy/ticket/109 Reviewed-by: Günther Deschner --- proxy/man/gssproxy.conf.5.xml | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/proxy/man/gssproxy.conf.5.xml b/proxy/man/gssproxy.conf.5.xml index b0012b5..b4d5add 100644 --- a/proxy/man/gssproxy.conf.5.xml +++ b/proxy/man/gssproxy.conf.5.xml @@ -162,6 +162,64 @@ + enforce_flags (string) + + + A list of GSS Request Flags that are added + unconditionally to every context initialization + call. + Flags can only be added to the list or removed + from the list by prepending a +/- sign to the + flag name or value. + + + Recognized flag names: DELEGATE, MUTUAL_AUTH, + REPLAY_DETECT, SEQUENCE, CONFIDENTIALITY, + INTEGRITY, ANONYMOUS + + Examples: + + enforce_flags = +REPLAY_DETECT + enforce_flags = -0x0001 + + + Default: enforce_flags = + + + + + filter_flags (string) + + + A list of GSS Request Flags that are filtered + unconditionally from every context initialization + call. + Flags can only be added to the list or removed + from the list by prepending a +/- sign to the + flag name or value. + + + NOTE: Because often gssproxy is used to withold + access to credentials the Delegate Flag is filtered + by default. To allow a service to delegate + credentials use the first example below. + + + Recognized flag names: DELEGATE, MUTUAL_AUTH, + REPLAY_DETECT, SEQUENCE, CONFIDENTIALITY, + INTEGRITY, ANONYMOUS + + Examples: + + filter_flags = -DELEGATE + filter_flags = -0x0001 +ANONYMOUS + + + Default: filter_flags = +DELEGATE + + + + impersonate (boolean) Use impersonation (s4u2self + s4u2proxy) to obtain credentials -- 1.8.3.1 From 8b147c9196d9068d0fc5e5a8919b84e8cbb97ef4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 6 Dec 2013 17:51:14 -0500 Subject: [PATCH] Fix config token parsing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://fedorahosted.org/gss-proxy/ticket/112 Signed-off-by: Simo Sorce Reviewed-by: Günther Deschner --- proxy/src/gp_config.c | 1 - 1 file changed, 1 deletion(-) diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index 2fc4a6f..ee96975 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -153,7 +153,6 @@ static int parse_flags(const char *value, uint32_t *storage) return ENOMEM; } - token = strtok_r(str, ", ", &handle); for (token = strtok_r(str, ", ", &handle); token != NULL; token = strtok_r(NULL, ", ", &handle)) { -- 1.8.3.1