This is an automated email from the git hooks/post-receive script.
rharwood pushed a change to branch master in repository gssproxy.
from 348d5df Appease Coverity new 71f3039 Fix potential memleak from gpm_release_cred new 60505f6 Local vs Remote cred check fixes new dedcd44 Add a helper function to pack options new 172bede Add ability to sync creds back on modification new d8b46bb Do not re-export unchanged creds new cf9074c Rework gpp_cred_handle management new bdf7ffd Add utility function to compare gssx_creds new 833f539 Always request cred sync on init_sec_context new bcd4ecd If credentials changed try to store them new 94478d4 Change tests to always exercise ccache sycns
The 10 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference.
Summary of changes: proxy/man/gssproxy.conf.5.xml | 14 ++ proxy/src/client/gpm_acquire_cred.c | 27 +--- proxy/src/client/gpm_init_sec_context.c | 39 ++++- proxy/src/client/gpm_release_handle.c | 2 + proxy/src/client/gssapi_gpm.h | 3 +- proxy/src/gp_common.h | 9 ++ proxy/src/gp_config.c | 8 + proxy/src/gp_creds.c | 173 +++++++++++++++++++++ proxy/src/gp_proxy.h | 1 + proxy/src/gp_rpc_acquire_cred.c | 14 +- proxy/src/gp_rpc_creds.h | 13 ++ proxy/src/gp_rpc_init_sec_context.c | 23 +++ proxy/src/gp_util.c | 43 ++++++ proxy/src/mechglue/gpp_accept_sec_context.c | 6 +- proxy/src/mechglue/gpp_acquire_cred.c | 68 +++++---- proxy/src/mechglue/gpp_creds.c | 227 ++++++++++++++++++++++------ proxy/src/mechglue/gpp_init_sec_context.c | 53 ++++--- proxy/src/mechglue/gss_plugin.h | 10 ++ proxy/tests/cli_srv_comm.c | 1 + proxy/tests/t_impersonate.c | 47 +++--- proxy/tests/t_impersonate.py | 21 +-- proxy/tests/testlib.py | 8 +- 22 files changed, 642 insertions(+), 168 deletions(-)
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 71f3039ec7149efee66f446aca316121762d8123 Author: Simo Sorce simo@redhat.com Date: Thu Mar 2 19:32:43 2017 -0500
Fix potential memleak from gpm_release_cred
Signed-off-by: Simo Sorce simo@redhat.com Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/client/gpm_release_handle.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/proxy/src/client/gpm_release_handle.c b/proxy/src/client/gpm_release_handle.c index 2da25d2..7a6aaed 100644 --- a/proxy/src/client/gpm_release_handle.c +++ b/proxy/src/client/gpm_release_handle.c @@ -51,6 +51,8 @@ rel_done: gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); done: xdr_free((xdrproc_t)xdr_gssx_cred, (char *)r); + free(r); + *cred_handle = NULL; return ret; }
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 60505f66de0928e4189a0526f2c11a148f97fcfd Author: Simo Sorce simo@redhat.com Date: Tue Feb 28 11:58:38 2017 -0500
Local vs Remote cred check fixes
Do not check for remote cred in LOCAL_ONLY case, since we are instructed to specifically not check with the proxy. However, still fall back to remote with cred_store, since it may simply indicate what ccache to use to store the remote credentials reference and not where to fetch the credential from.
Related-to: #51 Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: Shrink commit message and typos] Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/mechglue/gpp_acquire_cred.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c index 277e61a..fb5bda0 100644 --- a/proxy/src/mechglue/gpp_acquire_cred.c +++ b/proxy/src/mechglue/gpp_acquire_cred.c @@ -120,20 +120,22 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, } }
- in_cred_remote = calloc(1, sizeof(gssx_cred)); - if (!in_cred_remote) { - maj = GSS_S_FAILURE; - min = ENOMEM; - goto done; - } - maj = gppint_retrieve_remote_creds(&min, ccache_name, NULL, - in_cred_remote); - if (maj == GSS_S_COMPLETE) { - behavior = GPP_REMOTE_ONLY; - } else { - safefree(in_cred_remote); - if (ccache_name) { - behavior = GPP_LOCAL_ONLY; + if (behavior != GPP_LOCAL_ONLY) { + in_cred_remote = calloc(1, sizeof(gssx_cred)); + if (!in_cred_remote) { + maj = GSS_S_FAILURE; + min = ENOMEM; + goto done; + } + maj = gppint_retrieve_remote_creds(&min, ccache_name, NULL, + in_cred_remote); + if (maj == GSS_S_COMPLETE) { + behavior = GPP_REMOTE_FIRST; + } else { + safefree(in_cred_remote); + if (ccache_name) { + behavior = GPP_LOCAL_FIRST; + } } }
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit dedcd443d2b1d67181a155e440e75eaae529bf46 Author: Simo Sorce simo@redhat.com Date: Tue Feb 28 12:09:52 2017 -0500
Add a helper function to pack options
Signed-off-by: Simo Sorce simo@redhat.com Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/client/gpm_acquire_cred.c | 27 ++++++----------------- proxy/src/gp_common.h | 4 ++++ proxy/src/gp_util.c | 43 +++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/proxy/src/client/gpm_acquire_cred.c b/proxy/src/client/gpm_acquire_cred.c index a2ac068..632973d 100644 --- a/proxy/src/client/gpm_acquire_cred.c +++ b/proxy/src/client/gpm_acquire_cred.c @@ -90,29 +90,16 @@ OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status,
/* impersonate calls use input cred and a special option */ if (impersonate) { - gssx_option *opt; - arg->options.options_val = calloc(1, sizeof(gssx_option)); - if (!arg->options.options_val) { + ret_min = gp_add_option(&arg->options.options_val, + &arg->options.options_len, + ACQUIRE_TYPE_OPTION, + sizeof(ACQUIRE_TYPE_OPTION), + ACQUIRE_IMPERSONATE_NAME, + sizeof(ACQUIRE_IMPERSONATE_NAME)); + if (ret_min) { ret_maj = GSS_S_FAILURE; - ret_min = ENOMEM; goto done; } - arg->options.options_len = 1; - opt = &arg->options.options_val[0]; - opt->option.octet_string_val = strdup(ACQUIRE_TYPE_OPTION); - if (!opt->option.octet_string_val) { - ret_maj = GSS_S_FAILURE; - ret_min = ENOMEM; - goto done; - } - opt->option.octet_string_len = sizeof(ACQUIRE_TYPE_OPTION); - opt->value.octet_string_val = strdup(ACQUIRE_IMPERSONATE_NAME); - if (!opt->value.octet_string_val) { - ret_maj = GSS_S_FAILURE; - ret_min = ENOMEM; - goto done; - } - opt->value.octet_string_len = sizeof(ACQUIRE_IMPERSONATE_NAME); }
/* execute proxy request */ diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h index 5b9b9b2..9f23f3e 100644 --- a/proxy/src/gp_common.h +++ b/proxy/src/gp_common.h @@ -117,4 +117,8 @@ do { \ #define ACQUIRE_TYPE_OPTION "acquire_type" #define ACQUIRE_IMPERSONATE_NAME "impersonate_name"
+uint32_t gp_add_option(gssx_option **options_val, u_int *options_len, + const void *option, size_t option_len, + const void *value, size_t value_len); + #endif /* _GP_COMMON_H_ */ diff --git a/proxy/src/gp_util.c b/proxy/src/gp_util.c index ff1cfed..a91f392 100644 --- a/proxy/src/gp_util.c +++ b/proxy/src/gp_util.c @@ -143,3 +143,46 @@ ssize_t gp_safe_write(int fd, const void *buf, size_t count)
return len; } + +uint32_t gp_add_option(gssx_option **options_val, u_int *options_len, + const void *option, size_t option_len, + const void *value, size_t value_len) +{ + gssx_option opt = { 0 }; + gssx_option *out; + uint32_t ret; + + opt.option.octet_string_val = malloc(option_len); + if (!opt.option.octet_string_val) { + ret = ENOMEM; + goto done; + } + memcpy(opt.option.octet_string_val, option, option_len); + opt.option.octet_string_len = option_len; + + opt.value.octet_string_val = malloc(value_len); + if (!opt.value.octet_string_val) { + ret = ENOMEM; + goto done; + } + memcpy(opt.value.octet_string_val, value, value_len); + opt.value.octet_string_len = value_len; + + out = realloc(*options_val, (*options_len + 1) * sizeof(gssx_option)); + if (!out) { + ret = ENOMEM; + goto done; + } + + out[*options_len] = opt; + *options_val = out; + (*options_len)++; + + ret = 0; + +done: + if (ret) { + xdr_free((xdrproc_t)xdr_gssx_option, (char *)&opt); + } + return ret; +}
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 172bedea74bb8a0d465bfa8150d1eb02761554d7 Author: Simo Sorce simo@redhat.com Date: Mon Feb 27 15:15:17 2017 -0500
Add ability to sync creds back on modification
If enabled and if the client requests it, the server will check if new credentials are available and send back a fresh copy to the client if they are.
Works only if: - allow_client_ccache_sync is True - a custom ccache is not set for the service - the client explicitly requests a sync for the call
Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: Style fixes, typo in comment, commit message tweak] Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/man/gssproxy.conf.5.xml | 14 +++ proxy/src/gp_common.h | 5 ++ proxy/src/gp_config.c | 8 ++ proxy/src/gp_creds.c | 173 ++++++++++++++++++++++++++++++++++++ proxy/src/gp_proxy.h | 1 + proxy/src/gp_rpc_creds.h | 13 +++ proxy/src/gp_rpc_init_sec_context.c | 23 +++++ proxy/src/mechglue/gpp_creds.c | 1 - 8 files changed, 237 insertions(+), 1 deletion(-)
diff --git a/proxy/man/gssproxy.conf.5.xml b/proxy/man/gssproxy.conf.5.xml index 7ddb2fb..ad9d96f 100644 --- a/proxy/man/gssproxy.conf.5.xml +++ b/proxy/man/gssproxy.conf.5.xml @@ -126,6 +126,20 @@ </varlistentry>
<varlistentry> + <term>allow_client_ccache_sync (boolean)</term> + <listitem> + <para>Allow clients to request credentials to be sent back for better + caching.</para> + <para>This option allows the proxy, in certain circumstances, to send back + an additional option in the response structure of certain calls when + it determines that a new ticket may have been added to the internal + ccache. Clients can then replace their (encrypted) copy with the + updated ccache.</para> + <para>Default: false</para> + </listitem> + </varlistentry> + + <varlistentry> <term>cred_usage (string)</term> <listitem> <para>Allow to restrict the kind of operations permitted for this service.</para> diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h index 9f23f3e..36fd843 100644 --- a/proxy/src/gp_common.h +++ b/proxy/src/gp_common.h @@ -116,6 +116,11 @@ do { \
#define ACQUIRE_TYPE_OPTION "acquire_type" #define ACQUIRE_IMPERSONATE_NAME "impersonate_name" +#define CRED_SYNC_OPTION "sync_modified_creds" +#define CRED_SYNC_DEFAULT "default" +#define CRED_SYNC_PAYLOAD "sync_creds" + +#define GPKRB_MAX_CRED_SIZE 1024 * 512
uint32_t gp_add_option(gssx_option **options_val, u_int *options_len, const void *option, size_t option_len, diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index 184f59e..1b833fd 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -387,6 +387,14 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx) } }
+ ret = gp_config_get_string(ctx, secname, + "allow_client_ccache_sync", &value); + if (ret == 0) { + if (gp_boolean_is_true(value)) { + cfg->svcs[n]->allow_cc_sync = true; + } + } + ret = gp_config_get_string(ctx, secname, "trusted", &value); if (ret == 0) { if (gp_boolean_is_true(value)) { diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c index db5b4b2..5d84904 100644 --- a/proxy/src/gp_creds.c +++ b/proxy/src/gp_creds.c @@ -15,6 +15,7 @@ #include "gp_rpc_creds.h" #include "gp_creds.h" #include "gp_conv.h" +#include "gp_export.h"
#define GSS_MECH_KRB5_OID_LENGTH 9 #define GSS_MECH_KRB5_OID "\052\206\110\206\367\022\001\002\002" @@ -871,3 +872,175 @@ done: *min = ret_min; return ret_maj; } + +uint32_t gp_count_tickets(uint32_t *min, gss_cred_id_t cred, uint32_t *ccsum) +{ + uint32_t ret_maj = 0; + uint32_t ret_min = 0; + char *memcache = NULL; + krb5_context context = NULL; + krb5_ccache ccache = NULL; + krb5_cc_cursor cursor = NULL; + krb5_creds creds; + int err; + + err = krb5_init_context(&context); + if (err != 0) { + ret_min = err; + ret_maj = GSS_S_FAILURE; + goto done; + } + + /* Create a memory ccache we can iterate with libkrb5 functions */ + gss_key_value_element_desc ccelement = { "ccache", NULL }; + gss_key_value_set_desc cred_store = { 1, &ccelement }; + + err = asprintf(&memcache, "MEMORY:cred_allowed_%p", &memcache); + if (err == -1) { + memcache = NULL; + ret_min = ENOMEM; + ret_maj = GSS_S_FAILURE; + goto done; + } + cred_store.elements[0].value = memcache; + + ret_maj = gss_store_cred_into(&ret_min, cred, GSS_C_INITIATE, + discard_const(gss_mech_krb5), 1, 0, + &cred_store, NULL, NULL); + if (ret_maj != GSS_S_COMPLETE) { + goto done; + } + + err = krb5_cc_resolve(context, memcache, &ccache); + if (err != 0) { + ret_min = err; + ret_maj = GSS_S_FAILURE; + goto done; + } + + err = krb5_cc_start_seq_get(context, ccache, &cursor); + if (err != 0) { + ret_min = err; + ret_maj = GSS_S_FAILURE; + goto done; + } + + do { + err = krb5_cc_next_cred(context, ccache, &cursor, &creds); + if (err != 0 && err != KRB5_CC_END) { + ret_min = err; + ret_maj = GSS_S_FAILURE; + goto done; + } + + /* TODO: Should we do a real checksum over all creds->ticket data and + * flags in future ? */ + (*ccsum)++; + + } while (err == 0); + + err = krb5_cc_end_seq_get(context, ccache, &cursor); + if (err != 0) { + ret_min = err; + ret_maj = GSS_S_FAILURE; + goto done; + } + +done: + if (context) { + /* NOTE: destroy only if we created a MEMORY ccache */ + if (ccache) { + if (memcache) { + krb5_cc_destroy(context, ccache); + } else { + krb5_cc_close(context, ccache); + } + } + krb5_free_context(context); + } + free(memcache); + *min = ret_min; + return ret_maj; +} + +/* Check if cred refresh is being requested by the client. + * if so, take a snapshot of the cred so that later we can check if anything + * was added */ +uint32_t gp_check_sync_creds(struct gp_cred_check_handle *h, + gss_cred_id_t cred) +{ + uint32_t ret_maj = 0; + uint32_t ret_min = 0; + struct gp_service *svc = h->ctx->service; + struct gssx_option *opt = NULL; + uint32_t ccsum = 0; + + if (!svc->allow_cc_sync) + return 0; + + gp_options_find(opt, h->options, CRED_SYNC_OPTION, + sizeof(CRED_SYNC_OPTION)); + if (!opt) { + return 0; + } + if (!gpopt_string_match(&opt->value, CRED_SYNC_DEFAULT, + sizeof(CRED_SYNC_DEFAULT))) { + return 0; + } + + for (size_t i = 0; i < svc->krb5.store.count; i++) { + if (strcmp(svc->krb5.store.elements[i].key, "ccache") == 0) { + /* Saving in local ccache no need to sync up to client */ + return 0; + } + } + + ret_maj = gp_count_tickets(&ret_min, cred, &ccsum); + if (ret_maj) { + return 0; + } + + return ccsum; +} + +uint32_t gp_export_sync_creds(uint32_t *min, struct gp_call_ctx *gpcall, + gss_cred_id_t *cred, + gssx_option **options_val, u_int *options_len) +{ + uint32_t ret_maj = 0; + uint32_t ret_min = 0; + gssx_cred creds = { 0 }; + char value[GPKRB_MAX_CRED_SIZE]; + size_t len; + XDR xdrctx; + bool xdrok; + + ret_maj = gp_export_gssx_cred(&ret_min, gpcall, cred, &creds); + if (ret_maj) { + goto done; + } + + xdrmem_create(&xdrctx, value, GPKRB_MAX_CRED_SIZE, XDR_ENCODE); + xdrok = xdr_gssx_cred(&xdrctx, &creds); + if (!xdrok) { + ret_min = ENOSPC; + ret_maj = GSS_S_FAILURE; + goto done; + } + len = xdr_getpos(&xdrctx); + + ret_min = gp_add_option(options_val, options_len, CRED_SYNC_PAYLOAD, + sizeof(CRED_SYNC_PAYLOAD), value, len); + if (ret_min) { + ret_maj = GSS_S_FAILURE; + goto done; + } + + ret_min = 0; + ret_maj = GSS_S_COMPLETE; + +done: + xdr_free((xdrproc_t)xdr_gssx_cred, (char *)&creds); + *min = ret_min; + return ret_maj; +} diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index 869000d..971a7b6 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -32,6 +32,7 @@ struct gp_service { bool any_uid; bool allow_proto_trans; bool allow_const_deleg; + bool allow_cc_sync; bool trusted; bool kernel_nfsd; bool impersonate; diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h index 93df7e1..54fe482 100644 --- a/proxy/src/gp_rpc_creds.h +++ b/proxy/src/gp_rpc_creds.h @@ -38,4 +38,17 @@ uint32_t gp_cred_allowed(uint32_t *min,
void gp_filter_flags(struct gp_call_ctx *gpcall, uint32_t *flags);
+struct gp_cred_check_handle { + struct gp_call_ctx *ctx; + struct { + u_int options_len; + gssx_option *options_val; + } options; +}; +uint32_t gp_check_sync_creds(struct gp_cred_check_handle *h, + gss_cred_id_t cred); +uint32_t gp_export_sync_creds(uint32_t *min, struct gp_call_ctx *gpcall, + gss_cred_id_t *cred, + gssx_option **options_val, u_int *options_len); + #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 f3dc11d..767a3ff 100644 --- a/proxy/src/gp_rpc_init_sec_context.c +++ b/proxy/src/gp_rpc_init_sec_context.c @@ -26,6 +26,13 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, uint32_t init_maj; uint32_t init_min; int exp_ctx_type; + struct gp_cred_check_handle gcch = { + .ctx = gpcall, + .options.options_len = arg->init_sec_context.options.options_len, + .options.options_val = arg->init_sec_context.options.options_val, + }; + uint32_t gccn_before = 0; + uint32_t gccn_after = 0; int ret;
isca = &arg->init_sec_context; @@ -54,6 +61,8 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, if (ret_maj) { goto done; } + + gccn_before = gp_check_sync_creds(&gcch, ich); }
ret_maj = gp_conv_gssx_to_name(&ret_min, isca->target_name, &target_name); @@ -157,6 +166,20 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall, } }
+ gccn_after = gp_check_sync_creds(&gcch, ich); + + if (gccn_before != gccn_after) { + /* export creds back to client for sync up */ + ret_maj = gp_export_sync_creds(&ret_min, gpcall, &ich, + &iscr->options.options_val, + &iscr->options.options_len); + if (ret_maj) { + /* not fatal, log and continue */ + GPDEBUG("Failed to export sync creds (%d: %d)", + (int)ret_maj, (int)ret_min); + } + } + ret_maj = GSS_S_COMPLETE;
done: diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index 8fcef36..21ecabd 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -4,7 +4,6 @@ #include <gssapi/gssapi_krb5.h>
#define GPKRB_SRV_NAME "Encrypted/Credentials/v1@X-GSSPROXY:" -#define GPKRB_MAX_CRED_SIZE 1024 * 512
uint32_t gpp_store_remote_creds(uint32_t *min, gss_const_key_value_set_t cred_store,
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit d8b46bb2f1a57d305d15b5a316cd9c4ed3e7c535 Author: Simo Sorce simo@redhat.com Date: Thu Mar 2 17:27:15 2017 -0500
Do not re-export unchanged creds
This avoids a needless re-encryption operation and also insures the client receives back the exact same input; this way the client can detect if credentials have changed.
Signed-off-by: Simo Sorce simo@redhat.com Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/gp_rpc_acquire_cred.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/proxy/src/gp_rpc_acquire_cred.c b/proxy/src/gp_rpc_acquire_cred.c index 7f40c64..9a55937 100644 --- a/proxy/src/gp_rpc_acquire_cred.c +++ b/proxy/src/gp_rpc_acquire_cred.c @@ -137,10 +137,16 @@ int gp_acquire_cred(struct gp_call_ctx *gpcall, ret_min = ENOMEM; goto done; } - ret_maj = gp_export_gssx_cred(&ret_min, gpcall, - &out_cred, acr->output_cred_handle); - if (ret_maj) { - goto done; + + if (out_cred == in_cred) { + acr->output_cred_handle = aca->input_cred_handle; + aca->input_cred_handle = NULL; + } else { + ret_maj = gp_export_gssx_cred(&ret_min, gpcall, + &out_cred, acr->output_cred_handle); + if (ret_maj) { + goto done; + } }
done:
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit cf9074cde4f286a3bdf80463c0cf1ece6d4166eb Author: Simo Sorce simo@redhat.com Date: Tue Feb 28 12:01:39 2017 -0500
Rework gpp_cred_handle management
Provide helper functions to create and free gpp_cred_handle, and also record if the credential is a default credential or there is a custom ccache name associated with it.
This is in preparation of following patches.
Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: style fixups, typos in commit message] Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/mechglue/gpp_accept_sec_context.c | 6 +- proxy/src/mechglue/gpp_acquire_cred.c | 29 +++-- proxy/src/mechglue/gpp_creds.c | 168 +++++++++++++++++++++------- proxy/src/mechglue/gpp_init_sec_context.c | 37 +++--- proxy/src/mechglue/gss_plugin.h | 9 ++ 5 files changed, 162 insertions(+), 87 deletions(-)
diff --git a/proxy/src/mechglue/gpp_accept_sec_context.c b/proxy/src/mechglue/gpp_accept_sec_context.c index 3c3244f..a46b6e8 100644 --- a/proxy/src/mechglue/gpp_accept_sec_context.c +++ b/proxy/src/mechglue/gpp_accept_sec_context.c @@ -79,10 +79,8 @@ OM_uint32 gssi_accept_sec_context(OM_uint32 *minor_status, }
if (delegated_cred_handle) { - deleg_cred = calloc(1, sizeof(struct gpp_cred_handle)); - if (!deleg_cred) { - maj = GSS_S_FAILURE; - min = ENOMEM; + maj = gpp_cred_handle_init(&min, false, NULL, &deleg_cred); + if (maj != GSS_S_COMPLETE) { goto done; } } diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c index fb5bda0..5cdf7a6 100644 --- a/proxy/src/mechglue/gpp_acquire_cred.c +++ b/proxy/src/mechglue/gpp_acquire_cred.c @@ -102,13 +102,6 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, tmaj = GSS_S_COMPLETE; tmin = 0;
- out_cred_handle = calloc(1, sizeof(struct gpp_cred_handle)); - if (!out_cred_handle) { - maj = GSS_S_FAILURE; - min = ENOMEM; - goto done; - } - name = (struct gpp_name_handle *)desired_name; behavior = gpp_get_behavior();
@@ -120,6 +113,12 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, } }
+ maj = gpp_cred_handle_init(&min, !ccache_name, ccache_name, + &out_cred_handle); + if (maj != GSS_S_COMPLETE) { + goto done; + } + if (behavior != GPP_LOCAL_ONLY) { in_cred_remote = calloc(1, sizeof(gssx_cred)); if (!in_cred_remote) { @@ -196,7 +195,7 @@ done: if (maj == GSS_S_COMPLETE) { *output_cred_handle = (gss_cred_id_t)out_cred_handle; } else { - free(out_cred_handle); + (void)gpp_cred_handle_free(&tmin, out_cred_handle); } *minor_status = gpp_map_error(min); return maj; @@ -329,10 +328,10 @@ OM_uint32 gssi_acquire_cred_with_password(OM_uint32 *minor_status,
behavior = gpp_get_behavior();
- out_cred_handle = calloc(1, sizeof(struct gpp_cred_handle)); - if (!out_cred_handle) { - *minor_status = gpp_map_error(ENOMEM); - return GSS_S_FAILURE; + maj = gpp_cred_handle_init(&min, false, NULL, &out_cred_handle); + if (maj != GSS_S_COMPLETE) { + *minor_status = gpp_map_error(min); + return maj; }
switch (behavior) { @@ -426,10 +425,8 @@ OM_uint32 gssi_acquire_cred_impersonate_name(OM_uint32 *minor_status, tmaj = GSS_S_COMPLETE; tmin = 0;
- out_cred_handle = calloc(1, sizeof(struct gpp_cred_handle)); - if (!out_cred_handle) { - maj = GSS_S_FAILURE; - min = ENOMEM; + maj = gpp_cred_handle_init(&min, false, NULL, &out_cred_handle); + if (maj != GSS_S_COMPLETE) { goto done; }
diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index 21ecabd..2103156 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -5,7 +5,87 @@
#define GPKRB_SRV_NAME "Encrypted/Credentials/v1@X-GSSPROXY:"
-uint32_t gpp_store_remote_creds(uint32_t *min, +uint32_t gpp_cred_handle_init(uint32_t *min, bool defcred, const char *ccache, + struct gpp_cred_handle **out_handle) +{ + struct gpp_cred_handle *h = NULL; + uint32_t maj = 0; + + h = calloc(1, sizeof(struct gpp_cred_handle)); + if (!h) { + *min = ENOMEM; + return GSS_S_FAILURE; + } + + h->default_creds = defcred; + + if (ccache) { + h->store.elements = calloc(1, sizeof(gss_key_value_element_desc)); + if (!h->store.elements) { + *min = ENOMEM; + maj = GSS_S_FAILURE; + goto done; + } + h->store.count = 1; + + h->store.elements[0].key = strdup("ccache"); + if (!h->store.elements[0].key) { + *min = ENOMEM; + maj = GSS_S_FAILURE; + goto done; + } + + h->store.elements[0].value = strdup(ccache); + if (!h->store.elements[0].value) { + *min = ENOMEM; + maj = GSS_S_FAILURE; + goto done; + } + } + +done: + if (maj) { + uint32_t tmp; + (void)gpp_cred_handle_free(&tmp, h); + } else { + *out_handle = h; + } + return maj; +} + +uint32_t gpp_cred_handle_free(uint32_t *min, struct gpp_cred_handle *handle) +{ + uint32_t maj = GSS_S_COMPLETE; + + *min = 0; + + if (!handle) { + return GSS_S_COMPLETE; + } + + if (handle->local) { + maj = gss_release_cred(min, &handle->local); + } + + if (handle->remote) { + xdr_free((xdrproc_t)xdr_gssx_cred, (char *)handle->remote); + free(handle->remote); + } + + if (handle->store.count > 0) { + for (size_t i = 0; i < handle->store.count; i++) { + free((void *)handle->store.elements[i].key); + free((void *)handle->store.elements[i].value); + } + free(handle->store.elements); + handle->store.count = 0; + } + + free(handle); + return maj; +} + +uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds, gss_const_key_value_set_t cred_store, gssx_cred *creds) { @@ -35,6 +115,10 @@ uint32_t gpp_store_remote_creds(uint32_t *min, } } if (!ccache) { + if (!default_creds) { + ret = ENOMEDIUM; + goto done; + } ret = krb5_cc_default(ctx, &ccache); if (ret) goto done; } @@ -140,7 +224,7 @@ done: static OM_uint32 get_local_def_creds(OM_uint32 *minor_status, struct gpp_name_handle *name, gss_cred_usage_t cred_usage, - struct gpp_cred_handle *cred_handle) + gss_cred_id_t *cred_handle) { gss_OID_set interposed_mechs = GSS_C_NO_OID_SET; gss_OID_set special_mechs = GSS_C_NO_OID_SET; @@ -159,7 +243,7 @@ static OM_uint32 get_local_def_creds(OM_uint32 *minor_status, }
maj = gss_acquire_cred(&min, name ? name->local : NULL, 0, special_mechs, - cred_usage, &cred_handle->local, NULL, NULL); + cred_usage, cred_handle, NULL, NULL); done: *minor_status = min; (void)gss_release_oid_set(&min, &special_mechs); @@ -179,17 +263,21 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, OM_uint32 maj = GSS_S_FAILURE; OM_uint32 min = 0;
- cred = calloc(1, sizeof(struct gpp_cred_handle)); - if (!cred) { - min = ENOMEM; - goto done; + if (*cred_handle) { + cred = *cred_handle; + } else { + maj = gpp_cred_handle_init(&min, true, NULL, &cred); + if (maj != GSS_S_COMPLETE) { + *minor_status = min; + return maj; + } }
/* See if we should try local first */ if (behavior == GPP_LOCAL_ONLY || behavior == GPP_LOCAL_FIRST) {
- maj = get_local_def_creds(&min, name, cred_usage, cred); - if (maj != GSS_S_NO_CRED || behavior != GPP_LOCAL_FIRST) { + maj = get_local_def_creds(&min, name, cred_usage, &cred->local); + if (maj == GSS_S_COMPLETE || behavior == GPP_LOCAL_ONLY) { goto done; }
@@ -199,7 +287,7 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, }
/* Then try with remote */ - if (behavior == GPP_REMOTE_ONLY || behavior == GPP_REMOTE_FIRST) { + if (behavior != GPP_LOCAL_ONLY) { gssx_cred remote; gssx_cred *premote = NULL;
@@ -219,12 +307,14 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status,
xdr_free((xdrproc_t)xdr_gssx_cred, (char *)&remote);
- if (maj == GSS_S_COMPLETE || behavior == GPP_REMOTE_ONLY) { + if (maj == GSS_S_COMPLETE) { goto done; }
- /* So remote failed, but we can fallback to local, try that */ - maj = get_local_def_creds(&min, name, cred_usage, cred); + if (behavior == GPP_REMOTE_FIRST) { + /* So remote failed, but we can fallback to local, try that */ + maj = get_local_def_creds(&min, name, cred_usage, &cred->local); + } }
done: @@ -234,7 +324,9 @@ done: } *minor_status = min; if (maj != GSS_S_COMPLETE) { - gssi_release_cred(&min, (gss_cred_id_t *)&cred); + if (cred != *cred_handle) { + gssi_release_cred(&min, (gss_cred_id_t *)&cred); + } } *cred_handle = cred; return maj; @@ -543,7 +635,8 @@ OM_uint32 gssi_store_cred_into(OM_uint32 *minor_status, cred = (struct gpp_cred_handle *)input_cred_handle;
if (cred->remote) { - maj = gpp_store_remote_creds(&min, cred_store, cred->remote); + maj = gpp_store_remote_creds(&min, default_cred != 0, cred_store, + cred->remote); goto done; }
@@ -559,40 +652,31 @@ done: OM_uint32 gssi_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) { - struct gpp_cred_handle *cred; - OM_uint32 maj, min; - OM_uint32 rmaj = GSS_S_COMPLETE; + struct gpp_cred_handle *handle; + uint32_t tmaj; + uint32_t tmin; + uint32_t maj; + uint32_t min;
GSSI_TRACE();
if (cred_handle == NULL) { - return GSS_S_NO_CRED | GSS_S_CALL_INACCESSIBLE_READ; - } else if (*cred_handle == GSS_C_NO_CREDENTIAL) { - *minor_status = 0; - return GSS_S_COMPLETE; + return GSS_S_CALL_INACCESSIBLE_READ; }
- cred = (struct gpp_cred_handle *)*cred_handle; + handle = (struct gpp_cred_handle *)*cred_handle;
- if (cred->local) { - maj = gss_release_cred(&min, &cred->local); - if (maj != GSS_S_COMPLETE) { - rmaj = maj; - *minor_status = gpp_map_error(min); - } - } + tmaj = gpm_release_cred(&tmin, &handle->remote);
- if (cred->remote) { - maj = gpm_release_cred(&min, &cred->remote); - if (maj && rmaj == GSS_S_COMPLETE) { - rmaj = maj; - *minor_status = gpp_map_error(min); - } + maj = gpp_cred_handle_free(&min, handle); + if (tmaj && maj == GSS_S_COMPLETE) { + maj = tmaj; + min = tmin; }
- free(cred); *cred_handle = GSS_C_NO_CREDENTIAL; - return rmaj; + *minor_status = min; + return maj; }
OM_uint32 gssi_export_cred(OM_uint32 *minor_status, @@ -638,10 +722,9 @@ OM_uint32 gssi_import_cred_by_mech(OM_uint32 *minor_status,
GSSI_TRACE();
- cred = calloc(1, sizeof(struct gpp_cred_handle)); - if (!cred) { - *minor_status = 0; - return GSS_S_FAILURE; + maj = gpp_cred_handle_init(minor_status, false, NULL, &cred); + if (maj) { + return maj; }
/* NOTE: it makes no sense to import a cred remotely atm, @@ -679,4 +762,3 @@ done: (void)gss_release_buffer(&min, &wrap_token); return maj; } - diff --git a/proxy/src/mechglue/gpp_init_sec_context.c b/proxy/src/mechglue/gpp_init_sec_context.c index 7b10400..70a83d4 100644 --- a/proxy/src/mechglue/gpp_init_sec_context.c +++ b/proxy/src/mechglue/gpp_init_sec_context.c @@ -110,10 +110,8 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, goto done; } } else { - cred_handle = calloc(1, sizeof(struct gpp_cred_handle)); - if (!cred_handle) { - maj = GSS_S_FAILURE; - min = ENOMEM; + maj = gpp_cred_handle_init(&min, true, NULL, &cred_handle); + if (maj) { goto done; } } @@ -143,7 +141,6 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status,
/* Then try with remote */ if (behavior != GPP_LOCAL_ONLY) { - if (name->local && !name->remote) { maj = gpp_local_to_name(&min, name->local, &name->remote); if (maj) { @@ -152,18 +149,9 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, }
if (!cred_handle->remote) { - struct gpp_cred_handle *r_creds; - - maj = gppint_get_def_creds(&min, - GPP_REMOTE_ONLY, - NULL, - GSS_C_INITIATE, - &r_creds); - if (maj == GSS_S_COMPLETE) { - /* steal result */ - cred_handle->remote = r_creds->remote; - free(r_creds); - } + /* we ignore failures here */ + (void)gppint_get_def_creds(&min, GPP_REMOTE_ONLY, NULL, + GSS_C_INITIATE, &cred_handle); }
maj = gpm_init_sec_context(&min, @@ -179,16 +167,17 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, output_token, ret_flags, time_rec); - if (maj == GSS_S_COMPLETE || maj == GSS_S_CONTINUE_NEEDED || - behavior == GPP_REMOTE_ONLY) { + if (maj == GSS_S_COMPLETE || maj == GSS_S_CONTINUE_NEEDED) { goto done; }
- /* So remote failed, but we can fallback to local, try that */ - maj = init_ctx_local(&min, cred_handle, ctx_handle, name, - mech_type, req_flags, time_req, input_cb, - input_token, actual_mech_type, output_token, - ret_flags, time_rec); + if (behavior == GPP_REMOTE_FIRST) { + /* So remote failed, but we can fallback to local, try that */ + maj = init_ctx_local(&min, cred_handle, ctx_handle, name, + mech_type, req_flags, time_req, input_cb, + input_token, actual_mech_type, output_token, + ret_flags, time_rec); + } }
done: diff --git a/proxy/src/mechglue/gss_plugin.h b/proxy/src/mechglue/gss_plugin.h index d32f2bc..7b87519 100644 --- a/proxy/src/mechglue/gss_plugin.h +++ b/proxy/src/mechglue/gss_plugin.h @@ -7,9 +7,12 @@
struct gpp_cred_handle { gssx_cred *remote; + gss_key_value_set_desc store; + bool default_creds; gss_cred_id_t local; };
+ struct gpp_context_handle { gssx_ctx *remote; gss_ctx_id_t local; @@ -69,6 +72,12 @@ uint32_t gpp_name_to_local(uint32_t *minor, gssx_name *name, gss_OID mech_type, gss_name_t *mech_name); uint32_t gpp_local_to_name(uint32_t *minor, gss_name_t local_name, gssx_name **name); +uint32_t gpp_cred_handle_init(uint32_t *min, bool defcred, const char *ccache, + struct gpp_cred_handle **out_handle); +uint32_t gpp_cred_handle_free(uint32_t *min, struct gpp_cred_handle *handle); +uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds, + gss_const_key_value_set_t cred_store, + gssx_cred *creds);
OM_uint32 gssi_internal_release_oid(OM_uint32 *minor_status, gss_OID *oid);
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit bdf7ffd64db519f85b44b8d6b177956a13a30e94 Author: Simo Sorce simo@redhat.com Date: Thu Mar 2 17:28:54 2017 -0500
Add utility function to compare gssx_creds
This is not a full comparison, just enough to detect if creds have changed in an acquire_cred loop to a proxy.
Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: style fixups, language in comment] Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/mechglue/gpp_creds.c | 51 +++++++++++++++++++++++++++++++++++++++++ proxy/src/mechglue/gss_plugin.h | 1 + 2 files changed, 52 insertions(+)
diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index 2103156..42d21c5 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -85,6 +85,57 @@ uint32_t gpp_cred_handle_free(uint32_t *min, struct gpp_cred_handle *handle) return maj; }
+/* NOTE: currently the only things we check for are the cred name and the + * cred_handle_reference. We do NOT check each cred element beyond that they + * match in number */ +bool gpp_creds_are_equal(gssx_cred *a, gssx_cred *b) +{ + gssx_buffer *ta; + gssx_buffer *tb; + + if (!a && !b) { + return true; + } else if (!a || !b) { + return false; + } + + ta = &a->desired_name.display_name; + tb = &b->desired_name.display_name; + if (ta->octet_string_len != tb->octet_string_len) { + return false; + } else if (!ta->octet_string_val && tb->octet_string_val) { + return false; + } else if (ta->octet_string_val) { + if (!tb->octet_string_val) { + return false; + } else if (memcmp(ta->octet_string_val, tb->octet_string_val, + ta->octet_string_len) != 0) { + return false; + } + } + + if (a->elements.elements_len != b->elements.elements_len) { + return false; + } + + ta = &a->cred_handle_reference; + tb = &b->cred_handle_reference; + if (ta->octet_string_len != tb->octet_string_len) { + return false; + } else if (!ta->octet_string_val && tb->octet_string_val) { + return false; + } else if (ta->octet_string_val) { + if (!tb->octet_string_val) { + return false; + } else if (memcmp(ta->octet_string_val, tb->octet_string_val, + ta->octet_string_len) != 0) { + return false; + } + } + + return true; +} + uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds, gss_const_key_value_set_t cred_store, gssx_cred *creds) diff --git a/proxy/src/mechglue/gss_plugin.h b/proxy/src/mechglue/gss_plugin.h index 7b87519..333d63c 100644 --- a/proxy/src/mechglue/gss_plugin.h +++ b/proxy/src/mechglue/gss_plugin.h @@ -75,6 +75,7 @@ uint32_t gpp_local_to_name(uint32_t *minor, uint32_t gpp_cred_handle_init(uint32_t *min, bool defcred, const char *ccache, struct gpp_cred_handle **out_handle); uint32_t gpp_cred_handle_free(uint32_t *min, struct gpp_cred_handle *handle); +bool gpp_creds_are_equal(gssx_cred *a, gssx_cred *b); uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds, gss_const_key_value_set_t cred_store, gssx_cred *creds);
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 833f5398fb2b19cdf0680ab01a56ca4e9bfc7922 Author: Simo Sorce simo@redhat.com Date: Tue Feb 28 12:12:46 2017 -0500
Always request cred sync on init_sec_context
Signed-off-by: Simo Sorce simo@redhat.com Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/client/gpm_init_sec_context.c | 39 ++++++++++++++++++++++++++++++- proxy/src/client/gssapi_gpm.h | 3 ++- proxy/src/mechglue/gpp_init_sec_context.c | 3 ++- proxy/tests/cli_srv_comm.c | 1 + 4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c index 82c84ee..bea2010 100644 --- a/proxy/src/client/gpm_init_sec_context.c +++ b/proxy/src/client/gpm_init_sec_context.c @@ -3,6 +3,26 @@ #include "gssapi_gpm.h" #include "src/gp_conv.h"
+static void return_new_cred_handle(struct gssx_option *val, + gssx_cred **out_cred_handle) +{ + gssx_cred *creds; + XDR xdrctx; + bool xdrok; + + creds = calloc(1, sizeof(*creds)); + if (creds) { + xdrmem_create(&xdrctx, val->value.octet_string_val, + val->value.octet_string_len, XDR_DECODE); + xdrok = xdr_gssx_cred(&xdrctx, creds); + if (xdrok) { + *out_cred_handle = creds; + } else { + free(creds); + } + } +} + OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, gssx_cred *cred_handle, gssx_ctx **context_handle, @@ -15,7 +35,8 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, - OM_uint32 *time_rec) + OM_uint32 *time_rec, + gssx_cred **out_cred_handle) { union gp_rpc_arg uarg; union gp_rpc_res ures; @@ -40,6 +61,12 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, arg->context_handle = *context_handle; }
+ /* always try request cred sync, ignore errors, not critical */ + (void)gp_add_option(&arg->options.options_val, + &arg->options.options_len, + CRED_SYNC_OPTION, sizeof(CRED_SYNC_OPTION), + CRED_SYNC_DEFAULT, sizeof(CRED_SYNC_DEFAULT)); + arg->target_name = target_name;
ret = gp_conv_oid_to_gssx(mech_type, &arg->mech_type); @@ -96,6 +123,16 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, } }
+ /* check if a sync cred was returned to us, don't fail on errors */ + if (out_cred_handle && res->options.options_len > 0) { + struct gssx_option *val = NULL; + gp_options_find(val, res->options, CRED_SYNC_PAYLOAD, + sizeof(CRED_SYNC_PAYLOAD)); + if (val) { + return_new_cred_handle(val, out_cred_handle); + } + } + ret_maj = res->status.major_status; ret_min = res->status.minor_status; gpm_save_status(&res->status); diff --git a/proxy/src/client/gssapi_gpm.h b/proxy/src/client/gssapi_gpm.h index 667b0e0..22beecf 100644 --- a/proxy/src/client/gssapi_gpm.h +++ b/proxy/src/client/gssapi_gpm.h @@ -158,7 +158,8 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, - OM_uint32 *time_rec); + OM_uint32 *time_rec, + gssx_cred **out_cred_handle); OM_uint32 gpm_inquire_context(OM_uint32 *minor_status, gssx_ctx *context_handle, gssx_name **src_name, diff --git a/proxy/src/mechglue/gpp_init_sec_context.c b/proxy/src/mechglue/gpp_init_sec_context.c index 70a83d4..76e0311 100644 --- a/proxy/src/mechglue/gpp_init_sec_context.c +++ b/proxy/src/mechglue/gpp_init_sec_context.c @@ -166,7 +166,8 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, actual_mech_type, output_token, ret_flags, - time_rec); + time_rec, + NULL); if (maj == GSS_S_COMPLETE || maj == GSS_S_CONTINUE_NEEDED) { goto done; } diff --git a/proxy/tests/cli_srv_comm.c b/proxy/tests/cli_srv_comm.c index ae0851c..4138743 100644 --- a/proxy/tests/cli_srv_comm.c +++ b/proxy/tests/cli_srv_comm.c @@ -154,6 +154,7 @@ void *client_thread(void *pvt) NULL, &out_token, NULL, + NULL, NULL); if (ret_maj != GSS_S_COMPLETE && ret_maj != GSS_S_CONTINUE_NEEDED) {
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit bcd4ecdf75b88f6b73db778a079e87acf5ef093c Author: Simo Sorce simo@redhat.com Date: Thu Mar 2 17:33:09 2017 -0500
If credentials changed try to store them
This allows for efficient caching when new tickets are added on the proxy side when using memory ccaches. It also allows us to store changes in flags and other ccache ancillary modifications.
Fix impersonate tests to cope with the acquire_cred behavior change.
Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: fix induced merge conflict, hoist gssx_cred, tweak commit message body, fix extra argument to DEBUG in t_impersonate.c] Reviewed-by: Robbie Harwood rharwood@redhat.com --- proxy/src/mechglue/gpp_acquire_cred.c | 13 ++++++++- proxy/src/mechglue/gpp_creds.c | 7 +++++ proxy/src/mechglue/gpp_init_sec_context.c | 15 +++++++++- proxy/tests/t_impersonate.c | 47 +++++++++++++------------------ proxy/tests/t_impersonate.py | 21 ++++++++------ 5 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/proxy/src/mechglue/gpp_acquire_cred.c b/proxy/src/mechglue/gpp_acquire_cred.c index 5cdf7a6..d876699 100644 --- a/proxy/src/mechglue/gpp_acquire_cred.c +++ b/proxy/src/mechglue/gpp_acquire_cred.c @@ -170,7 +170,18 @@ OM_uint32 gssi_acquire_cred_from(OM_uint32 *minor_status, &out_cred_handle->remote, actual_mechs, time_rec); - if (maj == GSS_S_COMPLETE || behavior == GPP_REMOTE_ONLY) { + if (maj == GSS_S_COMPLETE) { + /* store back creds if they changed */ + if (out_cred_handle->remote && + !gpp_creds_are_equal(in_cred_remote, out_cred_handle->remote)) { + tmaj = gpp_store_remote_creds(&tmin, + out_cred_handle->default_creds, + &out_cred_handle->store, + out_cred_handle->remote); + if (tmaj != GSS_S_COMPLETE) { + maj = tmaj; + } + } goto done; }
diff --git a/proxy/src/mechglue/gpp_creds.c b/proxy/src/mechglue/gpp_creds.c index 42d21c5..12709b2 100644 --- a/proxy/src/mechglue/gpp_creds.c +++ b/proxy/src/mechglue/gpp_creds.c @@ -355,6 +355,13 @@ OM_uint32 gppint_get_def_creds(OM_uint32 *minor_status, maj = gpm_acquire_cred(&min, premote, NULL, 0, NULL, cred_usage, false, &cred->remote, NULL, NULL); + if (maj == GSS_S_COMPLETE) { + if (premote && + !gpp_creds_are_equal(premote, cred->remote)) { + maj = gpp_store_remote_creds(&min, cred->default_creds, + &cred->store, cred->remote); + } + }
xdr_free((xdrproc_t)xdr_gssx_cred, (char *)&remote);
diff --git a/proxy/src/mechglue/gpp_init_sec_context.c b/proxy/src/mechglue/gpp_init_sec_context.c index 76e0311..94d9b01 100644 --- a/proxy/src/mechglue/gpp_init_sec_context.c +++ b/proxy/src/mechglue/gpp_init_sec_context.c @@ -62,6 +62,7 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, enum gpp_behavior behavior = GPP_UNINITIALIZED; struct gpp_context_handle *ctx_handle = NULL; struct gpp_cred_handle *cred_handle = NULL; + gssx_cred *out_cred = NULL; struct gpp_name_handle *name; OM_uint32 tmaj, tmin; OM_uint32 maj, min; @@ -167,8 +168,20 @@ OM_uint32 gssi_init_sec_context(OM_uint32 *minor_status, output_token, ret_flags, time_rec, - NULL); + &out_cred); if (maj == GSS_S_COMPLETE || maj == GSS_S_CONTINUE_NEEDED) { + if (out_cred) { + xdr_free((xdrproc_t)xdr_gssx_cred, + (char *)cred_handle->remote); + free(cred_handle->remote); + cred_handle->remote = out_cred; + out_cred = NULL; + /* failuire is not fatal */ + (void)gpp_store_remote_creds(&tmin, + cred_handle->default_creds, + &cred_handle->store, + cred_handle->remote); + } goto done; }
diff --git a/proxy/tests/t_impersonate.c b/proxy/tests/t_impersonate.c index 42d59a4..8ca6e9c 100644 --- a/proxy/tests/t_impersonate.c +++ b/proxy/tests/t_impersonate.c @@ -22,9 +22,10 @@ int main(int argc, const char *argv[]) int ret = -1; bool selfhalf = false; bool proxyhalf = false; - const char *deleg_ccache = NULL; + gss_key_value_element_desc ccelement = { "ccache", NULL }; + gss_key_value_set_desc cred_store = { 1, &ccelement };
- if (argc < 4) return -1; + if (argc < 5) return -1;
ret = t_string_to_name(argv[1], &user_name, GSS_C_NT_USER_NAME); if (ret) { @@ -49,29 +50,22 @@ int main(int argc, const char *argv[]) goto done; }
- if (argc > 4) { - if (strcmp(argv[4], "s4u2self") == 0) { + ccelement.value = argv[4]; + + if (argc > 5) { + if (strcmp(argv[5], "s4u2self") == 0) { selfhalf = true; - } else if (strcmp(argv[4], "s4u2proxy") == 0) { + } else if (strcmp(argv[5], "s4u2proxy") == 0) { proxyhalf = true; } else { - DEBUG("Invalid argument 4: %s\n", argv[4]); - ret = -1; - goto done; - } - if (argc < 6) { - DEBUG("Option %s requires additional arguments\n", argv[4]); + DEBUG("Invalid argument 5: %s\n", argv[5]); ret = -1; goto done; } - deleg_ccache = argv[5]; - DEBUG("S4U2%s half [ccache %s]\n", selfhalf?"Self":"Proxy", argv[5]); + DEBUG("S4U2%s half\n", selfhalf ? "Self" : "Proxy"); }
if (proxyhalf) { - gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; - gss_key_value_set_desc cred_store = { 1, &ccelement }; - ret_maj = gss_acquire_cred_from(&ret_min, user_name, GSS_C_INDEFINITE, @@ -90,15 +84,17 @@ int main(int argc, const char *argv[]) flags = GSS_C_MUTUAL_FLAG; } else {
- ret_maj = gss_acquire_cred(&ret_min, - proxy_name, - GSS_C_INDEFINITE, - &oid_set, - GSS_C_BOTH, - &impersonator_cred_handle, - NULL, NULL); + ret_maj = gss_acquire_cred_from(&ret_min, + proxy_name, + GSS_C_INDEFINITE, + &oid_set, + GSS_C_BOTH, + &cred_store, + &impersonator_cred_handle, + NULL, NULL); if (ret_maj != GSS_S_COMPLETE) { - DEBUG("gss_acquire_cred() failed\n"); + DEBUG("gss_acquire_cred_from() [%s] failed\n", + selfhalf ? "s4u2self" : "impersonate"); t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); ret = -1; goto done; @@ -121,9 +117,6 @@ int main(int argc, const char *argv[]) }
if (selfhalf) { - gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; - gss_key_value_set_desc cred_store = { 1, &ccelement }; - ret_maj = gss_store_cred_into(&ret_min, cred_handle, GSS_C_INITIATE, diff --git a/proxy/tests/t_impersonate.py b/proxy/tests/t_impersonate.py index 499b9a1..3e25962 100755 --- a/proxy/tests/t_impersonate.py +++ b/proxy/tests/t_impersonate.py @@ -75,40 +75,43 @@ def run(testdir, env, conf):
# Test all permitted socket = os.path.join(testdir, 'impersonate.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate", socket, cmd, False) rets.append(r)
#Test fail socket = os.path.join(testdir, 'impersonate-proxyonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate fail self", socket, cmd, True) rets.append(r)
#Test fail socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache'] r = run_cmd(testdir, env, conf, "Impersonate fail proxy", socket, cmd, True) rets.append(r)
#Test s4u2self half succeed socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2self', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2self'] r = run_cmd(testdir, env, conf, "s4u2self delegation", socket, cmd, False) rets.append(r)
#Test s4u2proxy half fail socket = os.path.join(testdir, 'impersonate-selfonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2proxy', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2proxy'] r = run_cmd(testdir, env, conf, "s4u2proxy fail", socket, cmd, True) rets.append(r)
#Test s4u2proxy half succeed socket = os.path.join(testdir, 'impersonate-proxyonly.socket') - cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, 's4u2proxy', - path_prefix + 'impersonate-proxy.ccache'] + cmd = ["./tests/t_impersonate", USR_NAME, HOST_GSS, PROXY_GSS, + path_prefix + 'impersonate.cache', 's4u2proxy'] r = run_cmd(testdir, env, conf, "s4u2proxy", socket, cmd, False) rets.append(r)
This is an automated email from the git hooks/post-receive script.
rharwood pushed a commit to branch master in repository gssproxy.
commit 94478d4df56fa48d81d434a6386138d6736ee60f Author: Simo Sorce simo@redhat.com Date: Mon Feb 27 16:23:36 2017 -0500
Change tests to always exercise ccache sycns
Do not use a gssproxy side ccache in tests; instead, let them use the new default temporary memcache for operations. Additionally, allow the proxy to always sync back ccaches on operations so that the sync path is exercised as well.
Signed-off-by: Simo Sorce simo@redhat.com [rharwood@redhat.com: tweak commit message body] Reviewed-by: Robbie Harwood rharwood@redhat.com Merges: #162 --- proxy/tests/testlib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/proxy/tests/testlib.py b/proxy/tests/testlib.py index bb210d3..08dfdd6 100755 --- a/proxy/tests/testlib.py +++ b/proxy/tests/testlib.py @@ -535,10 +535,10 @@ GSSPROXY_CONF_TEMPLATE = ''' [service/test] mechs = krb5 cred_store = keytab:${GSSPROXY_KEYTAB} - cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} trusted = yes euid = ${UIDNUMBER} + allow_client_ccache_sync = yes
[service/badkeytab] mechs = krb5 @@ -553,10 +553,10 @@ GSSPROXY_CONF_MINIMAL_TEMPLATE = ''' [service/dontuse] mechs = krb5 cred_store = keytab:${GSSPROXY_KEYTAB} - cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} trusted = yes euid = nobody + allow_client_ccache_sync = yes '''
GSSPROXY_CONF_SOCKET_TEMPLATE = ''' @@ -566,11 +566,11 @@ GSSPROXY_CONF_SOCKET_TEMPLATE = ''' [service/test] mechs = krb5 cred_store = keytab:${GSSPROXY_KEYTAB} - cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} trusted = yes euid = ${UIDNUMBER} socket = ${SECOND_SOCKET} + allow_client_ccache_sync = yes '''
GSSPROXY_MULTI_TEMPLATE = ''' @@ -580,10 +580,10 @@ GSSPROXY_MULTI_TEMPLATE = ''' [service/test] mechs = krb5 cred_store = keytab:${GSSPROXY_KEYTAB} - cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} krb5_principal = ${GSSPROXY_CLIENT_PRINCIPAL} trusted = yes euid = ${UIDNUMBER} + allow_client_ccache_sync = yes '''
def update_gssproxy_conf(testdir, env, template):
gss-proxy@lists.fedorahosted.org