New upstream release 0.3.1:

* Fix use of gssproxy for client initiation
  * Add new enforcing and filtering options for context initialization
  * Fix potential thread safety issues
- resolves: https://fedorahosted.org/gss-proxy/ticket/110
- resolves: https://fedorahosted.org/gss-proxy/ticket/111
This commit is contained in:
Günther Deschner 2013-11-26 15:06:48 +01:00
parent b4f5223d51
commit a3731ae64d
7 changed files with 12 additions and 984 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@
/gssproxy-0.2.2.tar.gz
/gssproxy-0.2.3.tar.gz
/gssproxy-0.3.0.tar.gz
/gssproxy-0.3.1.tar.gz

View File

@ -1,331 +0,0 @@
From 556ea844a5783f9876ee748e1c686bb268f54e8a Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Fri, 15 Nov 2013 10:33:52 -0500
Subject: [PATCH] Fix continuations in context establishment calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Properly support continuations, including returning the rigth error code
and exporting partial contexts.
Fixes multistep authentications in particular for the initialization case
which always uses continuations.
Resolves: https://fedorahosted.org/gss-proxy/ticket/108
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
---
proxy/src/client/gpm_init_sec_context.c | 21 ++++++++++-----------
proxy/src/gp_export.c | 33 +++++++++++++++++++++++++++++----
proxy/src/gp_export.h | 3 ++-
proxy/src/gp_rpc_accept_sec_context.c | 20 +++++++++++++++++---
proxy/src/gp_rpc_get_mic.c | 2 +-
proxy/src/gp_rpc_init_sec_context.c | 16 +++++++++++++++-
proxy/src/gp_rpc_unwrap.c | 2 +-
proxy/src/gp_rpc_verify_mic.c | 2 +-
proxy/src/gp_rpc_wrap.c | 2 +-
9 files changed, 77 insertions(+), 24 deletions(-)
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c
index b6ce34f..f6dfe53 100644
--- a/proxy/src/client/gpm_init_sec_context.c
+++ b/proxy/src/client/gpm_init_sec_context.c
@@ -104,13 +104,6 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
}
}
- if (res->status.major_status) {
- gpm_save_status(&res->status);
- ret_maj = res->status.major_status;
- ret_min = res->status.minor_status;
- goto done;
- }
-
if (res->context_handle) {
ctx = res->context_handle;
/* we are stealing the delegated creds on success, so we do not want
@@ -118,12 +111,18 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
res->context_handle = NULL;
}
- ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
- if (ret) {
- gpm_save_internal_status(ret, strerror(ret));
- goto done;
+ if (res->output_token) {
+ ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
+ if (ret) {
+ gpm_save_internal_status(ret, strerror(ret));
+ goto done;
+ }
}
+ ret_maj = res->status.major_status;
+ ret_min = res->status.minor_status;
+ gpm_save_status(&res->status);
+
done:
if (ret != 0) {
ret_min = ret;
diff --git a/proxy/src/gp_export.c b/proxy/src/gp_export.c
index 51dd686..3cd5148 100644
--- a/proxy/src/gp_export.c
+++ b/proxy/src/gp_export.c
@@ -390,6 +390,7 @@ done:
#define LINUX_LUCID_V1 "linux_lucid_v1"
enum exp_ctx_types {
+ EXP_CTX_PARTIAL = -1, /* cannot be specified by client */
EXP_CTX_DEFAULT = 0,
EXP_CTX_LINUX_LUCID_V1 = 1,
};
@@ -418,6 +419,11 @@ int gp_get_exported_context_type(struct gssx_call_ctx *ctx)
return EXP_CTX_DEFAULT;
}
+int gp_get_continue_needed_type(void)
+{
+ return EXP_CTX_PARTIAL;
+}
+
#define KRB5_CTX_FLAG_INITIATOR 0x00000001
#define KRB5_CTX_FLAG_CFX 0x00000002
#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
@@ -513,7 +519,7 @@ done:
}
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
gss_ctx_id_t *in, gssx_ctx *out)
{
uint32_t ret_maj;
@@ -529,9 +535,6 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
int is_open;
int ret;
-/* TODO: For mechs that need multiple roundtrips to complete */
- /* out->state; */
-
/* we do not need the client to release anything until we handle state */
out->needs_release = false;
@@ -539,6 +542,11 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
&lifetime_rec, &mech_type, &ctx_flags,
&is_locally_initiated, &is_open);
if (ret_maj) {
+ if (type == EXP_CTX_PARTIAL) {
+ /* This may happen on partially established context,
+ * so just go on and put in what we can */
+ goto export;
+ }
goto done;
}
@@ -571,9 +579,26 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
out->open = true;
}
+export:
/* note: once converted the original context token is not usable anymore,
* so this must be the last call to use it */
switch (type) {
+ case EXP_CTX_PARTIAL:
+ /* this happens only when a init_sec_context call returns a partially
+ * initialized context so we return only what we have, not much */
+ ret = gp_conv_oid_to_gssx(mech, &out->mech);
+ if (ret) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = ret;
+ goto done;
+ }
+
+ out->locally_initiated = true;
+ out->open = false;
+
+ /* out->state; */
+
+ /* fall through */
case EXP_CTX_DEFAULT:
ret_maj = gss_export_sec_context(&ret_min, in, &export_buffer);
if (ret_maj) {
diff --git a/proxy/src/gp_export.h b/proxy/src/gp_export.h
index 58c0040..03e5d18 100644
--- a/proxy/src/gp_export.h
+++ b/proxy/src/gp_export.h
@@ -37,7 +37,8 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
gssx_cred *cred, gss_cred_id_t *out);
int gp_get_exported_context_type(struct gssx_call_ctx *ctx);
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
+int gp_get_continue_needed_type(void);
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
gss_ctx_id_t *in, gssx_ctx *out);
uint32_t gp_import_gssx_to_ctx_id(uint32_t *min, int type,
gssx_ctx *in, gss_ctx_id_t *out);
diff --git a/proxy/src/gp_rpc_accept_sec_context.c b/proxy/src/gp_rpc_accept_sec_context.c
index 40370aa..efbf07a 100644
--- a/proxy/src/gp_rpc_accept_sec_context.c
+++ b/proxy/src/gp_rpc_accept_sec_context.c
@@ -46,6 +46,8 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
gss_cred_id_t *pdch = NULL;
int exp_ctx_type;
int exp_creds_type;
+ uint32_t acpt_maj;
+ uint32_t acpt_min;
int ret;
asca = &arg->accept_sec_context;
@@ -109,17 +111,25 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
&ret_flags,
NULL,
pdch);
- if (ret_maj) {
+ if (ret_maj != GSS_S_COMPLETE &&
+ ret_maj != GSS_S_CONTINUE_NEEDED) {
goto done;
+ } else {
+ acpt_maj = ret_maj;
+ acpt_min = ret_min;
+ }
+ if (acpt_maj == GSS_S_CONTINUE_NEEDED) {
+ exp_ctx_type = gp_get_continue_needed_type();
}
+
ascr->context_handle = calloc(1, sizeof(gssx_ctx));
if (!ascr->context_handle) {
ret_maj = GSS_S_FAILURE;
ret_min = ENOMEM;
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, oid,
&ctx, ascr->context_handle);
if (ret_maj) {
goto done;
@@ -138,7 +148,7 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
goto done;
}
- if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred) {
+ if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred && dch) {
ascr->delegated_cred_handle = calloc(1, sizeof(gssx_cred));
if (!ascr->delegated_cred_handle) {
ret_maj = GSS_S_FAILURE;
@@ -159,6 +169,10 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
&ascr->options.options_val);
done:
+ if (ret_maj == GSS_S_COMPLETE) {
+ ret_maj = acpt_maj;
+ ret_min = acpt_min;
+ }
ret = gp_conv_status_to_gssx(&asca->call_ctx,
ret_maj, ret_min, oid,
&ascr->status);
diff --git a/proxy/src/gp_rpc_get_mic.c b/proxy/src/gp_rpc_get_mic.c
index ca60fe4..2db7d3f 100644
--- a/proxy/src/gp_rpc_get_mic.c
+++ b/proxy/src/gp_rpc_get_mic.c
@@ -73,7 +73,7 @@ int gp_get_mic(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
gmr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
index 944389c..2781238 100644
--- a/proxy/src/gp_rpc_init_sec_context.c
+++ b/proxy/src/gp_rpc_init_sec_context.c
@@ -45,6 +45,8 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
gss_buffer_desc obuf = GSS_C_EMPTY_BUFFER;
uint32_t ret_maj;
uint32_t ret_min;
+ uint32_t init_maj;
+ uint32_t init_min;
int exp_ctx_type;
int ret;
@@ -121,6 +123,12 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
if (ret_maj != GSS_S_COMPLETE &&
ret_maj != GSS_S_CONTINUE_NEEDED) {
goto done;
+ } else {
+ init_maj = ret_maj;
+ init_min = ret_min;
+ }
+ if (init_maj == GSS_S_CONTINUE_NEEDED) {
+ exp_ctx_type = gp_get_continue_needed_type();
}
iscr->context_handle = calloc(1, sizeof(gssx_ctx));
@@ -129,7 +137,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
ret_min = ENOMEM;
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, mech_type,
&ctx, iscr->context_handle);
if (ret_maj) {
goto done;
@@ -150,7 +158,13 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
}
}
+ ret_maj = GSS_S_COMPLETE;
+
done:
+ if (ret_maj == GSS_S_COMPLETE) {
+ ret_maj = init_maj;
+ ret_min = init_min;
+ }
ret = gp_conv_status_to_gssx(&isca->call_ctx,
ret_maj, ret_min, mech_type,
&iscr->status);
diff --git a/proxy/src/gp_rpc_unwrap.c b/proxy/src/gp_rpc_unwrap.c
index a20b8ea..faffa82 100644
--- a/proxy/src/gp_rpc_unwrap.c
+++ b/proxy/src/gp_rpc_unwrap.c
@@ -85,7 +85,7 @@ int gp_unwrap(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
uwr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_verify_mic.c b/proxy/src/gp_rpc_verify_mic.c
index 68369a0..a2d3f7e 100644
--- a/proxy/src/gp_rpc_verify_mic.c
+++ b/proxy/src/gp_rpc_verify_mic.c
@@ -76,7 +76,7 @@ int gp_verify_mic(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
vmr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_wrap.c b/proxy/src/gp_rpc_wrap.c
index d17c292..c2da7ba 100644
--- a/proxy/src/gp_rpc_wrap.c
+++ b/proxy/src/gp_rpc_wrap.c
@@ -85,7 +85,7 @@ int gp_wrap(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle, wr->context_handle);
if (ret_maj) {
goto done;
--
1.8.3.1

View File

@ -1,420 +0,0 @@
From 591fad86aba3520a76eaf75aa0fd5e585fac94a5 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
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 <gdeschner@redhat.com>
---
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 <gssapi/gssapi_krb5.h>
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 <simo@redhat.com>
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 <gdeschner@redhat.com>
---
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 <simo@redhat.com>
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 <gdeschner@redhat.com>
---
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 <gssapi/gssapi.h>
+
+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 <simo@redhat.com>
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 <gdeschner@redhat.com>
---
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 <simo@redhat.com>
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 <gdeschner@redhat.com>
---
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 @@
</varlistentry>
<varlistentry>
+ <term>enforce_flags (string)</term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ <para>
+ Recognized flag names: DELEGATE, MUTUAL_AUTH,
+ REPLAY_DETECT, SEQUENCE, CONFIDENTIALITY,
+ INTEGRITY, ANONYMOUS
+ </para>
+ <para>Examples:
+<programlisting>
+ <userinput moreinfo="none">enforce_flags = +REPLAY_DETECT</userinput>
+ <userinput moreinfo="none">enforce_flags = -0x0001</userinput>
+</programlisting>
+ </para>
+ <para>Default: enforce_flags =</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>filter_flags (string)</term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ Recognized flag names: DELEGATE, MUTUAL_AUTH,
+ REPLAY_DETECT, SEQUENCE, CONFIDENTIALITY,
+ INTEGRITY, ANONYMOUS
+ </para>
+ <para>Examples:
+<programlisting>
+ <userinput moreinfo="none">filter_flags = -DELEGATE</userinput>
+ <userinput moreinfo="none">filter_flags = -0x0001 +ANONYMOUS</userinput>
+</programlisting>
+ </para>
+ <para>Default: filter_flags = +DELEGATE</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>impersonate (boolean)</term>
<listitem>
<para>Use impersonation (s4u2self + s4u2proxy) to obtain credentials</para>
--
1.8.3.1

View File

@ -1,36 +0,0 @@
From cc538c36ca32850e0b3280b7d8524d23345eed9e Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Wed, 13 Nov 2013 17:57:06 -0500
Subject: [PATCH 1/3] Preserve requested flags and lifetime
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
These arguments have been accidentally forgotten causing failures for
applications that specify non default flags and non indefinite lifetime.
https://fedorahosted.org/gss-proxy/ticket/106
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
---
proxy/src/client/gpm_init_sec_context.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c
index 12df858..b6ce34f 100644
--- a/proxy/src/client/gpm_init_sec_context.c
+++ b/proxy/src/client/gpm_init_sec_context.c
@@ -70,6 +70,9 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
goto done;
}
+ arg->req_flags = req_flags;
+ arg->time_req = time_req;
+
if (input_cb) {
ret = gp_conv_cb_to_gssx_alloc(input_cb, &arg->input_cb);
if (ret) {
--
1.8.3.1

View File

@ -1,186 +0,0 @@
From 122b35f7adf37bc81f6d53bb5f9e058b68334cbb Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Wed, 13 Nov 2013 18:12:44 -0500
Subject: [PATCH 2/3] Add way to return regular oid from special
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In some cases we need to pass on the corresponding real oid, after we
are given a special oid.
Add helper functions to do that.
https://fedorahosted.org/gss-proxy/ticket/107
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
---
proxy/src/mechglue/gss_plugin.c | 55 +++++++++++++++++++++++++++++++----------
proxy/src/mechglue/gss_plugin.h | 1 +
2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/proxy/src/mechglue/gss_plugin.c b/proxy/src/mechglue/gss_plugin.c
index 0e62990..5b40df9 100644
--- a/proxy/src/mechglue/gss_plugin.c
+++ b/proxy/src/mechglue/gss_plugin.c
@@ -176,7 +176,8 @@ static bool gpp_special_equal(const gss_OID s, const gss_OID n)
}
struct gpp_special_oid_list {
- gss_OID_desc oid;
+ gss_OID_desc regular_oid;
+ gss_OID_desc special_oid;
struct gpp_special_oid_list *next;
sig_atomic_t next_is_set;
};
@@ -250,19 +251,25 @@ static const gss_OID gpp_new_special_mech(const gss_OID n)
if (!item) {
return GSS_C_NO_OID;
}
- item->oid.length = base->length + n->length;
- item->oid.elements = malloc(item->oid.length);
- if (!item->oid.elements) {
+ item->regular_oid.length = n->length;
+ item->regular_oid.elements = malloc(n->length);
+ item->special_oid.length = base->length + n->length;
+ item->special_oid.elements = malloc(item->special_oid.length);
+ if (!item->regular_oid.elements ||
+ !item->special_oid.elements) {
+ free(item->regular_oid.elements);
+ free(item->special_oid.elements);
free(item);
return GSS_C_NO_OID;
}
- memcpy(item->oid.elements, base->elements, base->length);
- memcpy(item->oid.elements + base->length, n->elements, n->length);
+ memcpy(item->regular_oid.elements, n->elements, n->length);
+ memcpy(item->special_oid.elements, base->elements, base->length);
+ memcpy(item->special_oid.elements + base->length, n->elements, n->length);
gpp_add_special_oids(item);
- return (const gss_OID)&item->oid;
+ return (const gss_OID)&item->special_oid;
}
const gss_OID gpp_special_mech(const gss_OID mech_type)
@@ -278,14 +285,14 @@ const gss_OID gpp_special_mech(const gss_OID mech_type)
if (mech_type == GSS_C_NO_OID) {
/* return the first special one if none specified */
if (item) {
- return (const gss_OID)&item->oid;
+ return (const gss_OID)&item->special_oid;
}
return GSS_C_NO_OID;
}
while (item) {
- if (gpp_special_equal(&item->oid, mech_type)) {
- return (const gss_OID)&item->oid;
+ if (gpp_special_equal(&item->special_oid, mech_type)) {
+ return (const gss_OID)&item->special_oid;
}
item = gpp_next_special_oids(item);
}
@@ -294,6 +301,26 @@ const gss_OID gpp_special_mech(const gss_OID mech_type)
return gpp_new_special_mech(mech_type);
}
+const gss_OID gpp_unspecial_mech(const gss_OID mech_type)
+{
+ struct gpp_special_oid_list *item = NULL;
+
+ if (!gpp_is_special_oid(mech_type)) {
+ return mech_type;
+ }
+
+ item = gpp_get_special_oids();
+ while (item) {
+ if (gss_oid_equal(&item->special_oid, mech_type)) {
+ return (const gss_OID)&item->regular_oid;
+ }
+ item = gpp_next_special_oids(item);
+ }
+
+ /* none matched */
+ return mech_type;
+}
+
gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs)
{
gss_OID_set amechs = GSS_C_NO_OID_SET;
@@ -318,8 +345,9 @@ gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs)
}
break;
}
- if (gpp_special_equal(&item->oid, &mechs->elements[i])) {
- maj = gss_add_oid_set_member(&min, &item->oid, &amechs);
+ if (gpp_special_equal(&item->special_oid, &mechs->elements[i])) {
+ maj = gss_add_oid_set_member(&min, &item->special_oid,
+ &amechs);
if (maj != GSS_S_COMPLETE) {
goto done;
}
@@ -362,7 +390,8 @@ OM_uint32 gssi_internal_release_oid(OM_uint32 *minor_status, gss_OID *oid)
item = gpp_get_special_oids();
while (item) {
- if (&item->oid == *oid) {
+ if ((&item->regular_oid == *oid) ||
+ (&item->special_oid == *oid)) {
*oid = GSS_C_NO_OID;
return GSS_S_COMPLETE;
}
diff --git a/proxy/src/mechglue/gss_plugin.h b/proxy/src/mechglue/gss_plugin.h
index 26e04c5..739ec26 100644
--- a/proxy/src/mechglue/gss_plugin.h
+++ b/proxy/src/mechglue/gss_plugin.h
@@ -78,6 +78,7 @@ gss_OID_set gss_mech_interposer(gss_OID mech_type);
enum gpp_behavior gpp_get_behavior(void);
bool gpp_is_special_oid(const gss_OID mech_type);
const gss_OID gpp_special_mech(const gss_OID mech_type);
+const gss_OID gpp_unspecial_mech(const gss_OID mech_type);
gss_OID_set gpp_special_available_mechs(const gss_OID_set mechs);
uint32_t gpp_map_error(uint32_t err);
uint32_t gpp_unmap_error(uint32_t err);
--
1.8.3.1
From b8901d1d20a5d0ef1a3118bfe5816e04c09e6cf5 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Wed, 13 Nov 2013 18:13:44 -0500
Subject: [PATCH 3/3] Fix calling gpm_inquire_cred_by_mech
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We need to pass the real mechanism oid here, not the spcial oid.
special oids are used exclusively by the interposer and gssapi
machinery that calls the interposer, they must never be propagated
to clients or servers.
https://fedorahosted.org/gss-proxy/ticket/107
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
---
proxy/src/mechglue/gpp_creds.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c
index aaaf577..dff9c44 100644
--- a/proxy/src/mechglue/gpp_creds.c
+++ b/proxy/src/mechglue/gpp_creds.c
@@ -213,7 +213,8 @@ OM_uint32 gssi_inquire_cred_by_mech(OM_uint32 *minor_status,
initiator_lifetime, acceptor_lifetime,
cred_usage);
} else if (cred->remote) {
- maj = gpm_inquire_cred_by_mech(&min, cred->remote, mech_type,
+ maj = gpm_inquire_cred_by_mech(&min, cred->remote,
+ gpp_unspecial_mech(mech_type),
gpname ? &gpname->remote : NULL,
initiator_lifetime, acceptor_lifetime,
cred_usage);
--
1.8.3.1

View File

@ -1,6 +1,6 @@
Name: gssproxy
Version: 0.3.0
Release: 3%{?dist}
Version: 0.3.1
Release: 0%{?dist}
Summary: GSSAPI Proxy
Group: System Environment/Libraries
@ -8,10 +8,6 @@ License: MIT
URL: http://fedorahosted.org/gss-proxy
Source0: http://fedorahosted.org/released/gss-proxy/%{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
Patch0: gssproxy-0.3.0-gss_init_sec_context.patch
Patch1: gssproxy-0.3.0-gss_inquire_cred_by_mech.patch
Patch2: gssproxy-0.3.0-continuations.patch
Patch3: gssproxy-0.3.0-flags_handling.patch
%global servicename gssproxy
%global pubconfpath %{_sysconfdir}/gssproxy
@ -56,10 +52,6 @@ A proxy for GSSAPI credential handling
%prep
%setup -q
%patch0 -p2 -b .gss_init_sec_context
%patch1 -p2 -b .gss_inquire_cred_by_mech
%patch2 -p2 -b .continuations
%patch3 -p2 -b .flags_handling
%build
autoreconf -f -i
@ -112,6 +104,14 @@ rm -rf %{buildroot}
%systemd_postun_with_restart gssproxy.service
%changelog
* Tue Nov 26 2013 Guenther Deschner <gdeschner@redhat.com> 0.3.1-0
- New upstream release 0.3.1:
* Fix use of gssproxy for client initiation
* Add new enforcing and filtering options for context initialization
* Fix potential thread safety issues
- resolves: https://fedorahosted.org/gss-proxy/ticket/110
- resolves: https://fedorahosted.org/gss-proxy/ticket/111
* Tue Nov 19 2013 Guenther Deschner <gdeschner@redhat.com> 0.3.0-3
- Fix flags handling in gss_init_sec_context()
- resolves: https://fedorahosted.org/gss-proxy/ticket/106

View File

@ -1 +1 @@
082fdf0fd3d79ee0d3b67a73367eeed7 gssproxy-0.3.0.tar.gz
f455f4e483ecda8274d235942fa8e943 gssproxy-0.3.1.tar.gz