From 1919bf9c7a8c0995e4a4bc0483732084b3b5f241 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 31 Jul 2012 18:15:12 -0400 Subject: Move client lib files in their own directory Make space for the actual mechglue plugin interface. The mechglue interface will use the client library to communicate with the gss-proxy but will reimplement all GSSAPI SPI as wrappers in order to properly handle fallbacks to local mechanism and other input/output transformations. --- proxy/Makefile.am | 18 +- proxy/src/client/gpm_accept_sec_context.c | 183 ++++++ proxy/src/client/gpm_acquire_cred.c | 289 ++++++++++ proxy/src/client/gpm_common.c | 520 ++++++++++++++++++ proxy/src/client/gpm_display_status.c | 124 +++++ proxy/src/client/gpm_import_and_canon_name.c | 342 ++++++++++++ proxy/src/client/gpm_indicate_mechs.c | 734 +++++++++++++++++++++++++ proxy/src/client/gpm_init_sec_context.c | 176 ++++++ proxy/src/client/gpm_release_handle.c | 131 +++++ proxy/src/client/gssapi_gpm.h | 162 ++++++ proxy/src/mechglue/README | 9 +- proxy/src/mechglue/gpm_accept_sec_context.c | 183 ------ proxy/src/mechglue/gpm_acquire_cred.c | 289 ---------- proxy/src/mechglue/gpm_common.c | 520 ------------------ proxy/src/mechglue/gpm_display_status.c | 124 ----- proxy/src/mechglue/gpm_import_and_canon_name.c | 342 ------------ proxy/src/mechglue/gpm_indicate_mechs.c | 734 ------------------------- proxy/src/mechglue/gpm_init_sec_context.c | 176 ------ proxy/src/mechglue/gpm_release_handle.c | 131 ----- proxy/src/mechglue/gssapi_gpm.h | 162 ------ proxy/tests/cli_srv_comm.c | 2 +- 21 files changed, 2673 insertions(+), 2678 deletions(-) create mode 100644 proxy/src/client/gpm_accept_sec_context.c create mode 100644 proxy/src/client/gpm_acquire_cred.c create mode 100644 proxy/src/client/gpm_common.c create mode 100644 proxy/src/client/gpm_display_status.c create mode 100644 proxy/src/client/gpm_import_and_canon_name.c create mode 100644 proxy/src/client/gpm_indicate_mechs.c create mode 100644 proxy/src/client/gpm_init_sec_context.c create mode 100644 proxy/src/client/gpm_release_handle.c create mode 100644 proxy/src/client/gssapi_gpm.h delete mode 100644 proxy/src/mechglue/gpm_accept_sec_context.c delete mode 100644 proxy/src/mechglue/gpm_acquire_cred.c delete mode 100644 proxy/src/mechglue/gpm_common.c delete mode 100644 proxy/src/mechglue/gpm_display_status.c delete mode 100644 proxy/src/mechglue/gpm_import_and_canon_name.c delete mode 100644 proxy/src/mechglue/gpm_indicate_mechs.c delete mode 100644 proxy/src/mechglue/gpm_init_sec_context.c delete mode 100644 proxy/src/mechglue/gpm_release_handle.c delete mode 100644 proxy/src/mechglue/gssapi_gpm.h diff --git a/proxy/Makefile.am b/proxy/Makefile.am index 15f29e2..ec6eb50 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -83,21 +83,21 @@ endif GP_RPCGEN_OBJ = rpcgen/gp_rpc_xdr.c rpcgen/gss_proxy_xdr.c GP_MECHGLUE_OBJ = \ - src/mechglue/gpm_display_status.c \ - src/mechglue/gpm_accept_sec_context.c \ - src/mechglue/gpm_release_handle.c \ - src/mechglue/gpm_acquire_cred.c \ - src/mechglue/gpm_indicate_mechs.c \ - src/mechglue/gpm_import_and_canon_name.c \ - src/mechglue/gpm_init_sec_context.c \ - src/mechglue/gpm_common.c + src/client/gpm_display_status.c \ + src/client/gpm_accept_sec_context.c \ + src/client/gpm_release_handle.c \ + src/client/gpm_acquire_cred.c \ + src/client/gpm_indicate_mechs.c \ + src/client/gpm_import_and_canon_name.c \ + src/client/gpm_init_sec_context.c \ + src/client/gpm_common.c dist_noinst_HEADERS = \ rpcgen/gp_rpc.h \ rpcgen/gss_proxy.h \ src/gp_rpc_process.h \ src/gp_proxy.h \ - src/mechglue/gssapi_gpm.h \ + src/client/gssapi_gpm.h \ src/gp_common.h \ src/gp_log.h \ src/gp_creds.h \ diff --git a/proxy/src/client/gpm_accept_sec_context.c b/proxy/src/client/gpm_accept_sec_context.c new file mode 100644 index 0000000..d5eeb8a --- /dev/null +++ b/proxy/src/client/gpm_accept_sec_context.c @@ -0,0 +1,183 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" +#include "src/gp_conv.h" + +OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_cred_id_t acceptor_cred_handle, + gss_buffer_t input_token_buffer, + gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_accept_sec_context *arg = &uarg.accept_sec_context; + gssx_res_accept_sec_context *res = &ures.accept_sec_context; + gssx_ctx *ctx = NULL; + gssx_name *name = NULL; + gss_OID_desc *mech = NULL; + gss_buffer_t outbuf = NULL; + uint32_t ret_maj; + int ret; + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + /* prepare proxy request */ + if (*context_handle) { + arg->context_handle = (gssx_ctx *)*context_handle; + } + + if (acceptor_cred_handle) { + arg->cred_handle = (gssx_cred *)acceptor_cred_handle; + } + + ret = gp_conv_buffer_to_gssx(input_token_buffer, &arg->input_token); + if (ret) { + goto done; + } + + if (input_chan_bindings) { + ret = gp_conv_cb_to_gssx_alloc(input_chan_bindings, &arg->input_cb); + if (ret) { + goto done; + } + } + + /* execute proxy request */ + ret = gpm_make_call(GSSX_ACCEPT_SEC_CONTEXT, &uarg, &ures); + if (ret) { + goto done; + } + + /* return values */ + if (mech_type) { + if (res->status.mech.octet_string_len) { + ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); + if (ret) { + goto done; + } + } + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + ret_maj = res->status.major_status; + *minor_status = res->status.minor_status; + ret = 0; + goto done; + } + + if (res->context_handle) { + ctx = res->context_handle; + /* we are stealing the delegated creds on success, so we do not want + * it to be freed by xdr_free */ + res->context_handle = NULL; + } + + if (src_name) { + ret = gp_copy_gssx_name_alloc(&ctx->src_name, &name); + if (ret) { + goto done; + } + } + + ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf); + if (ret) { + goto done; + } + + /* replace old ctx handle if any */ + if (*context_handle) { + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)*context_handle); + free(*context_handle); + } + *context_handle = (gss_ctx_id_t)ctx; + if (mech_type) { + *mech_type = mech; + } + if (src_name) { + *src_name = (gss_name_t)name; + } + if (outbuf) { + *output_token = *outbuf; + free(outbuf); + } + if (ret_flags) { + *ret_flags = ctx->ctx_flags; + } + if (time_rec) { + *time_rec = ctx->lifetime; + } + + if (res->delegated_cred_handle) { + if (delegated_cred_handle) { + *delegated_cred_handle = (gss_cred_id_t)res->delegated_cred_handle; + } + /* we are stealing the delegated creds on success, so we do not want + * it to be freed by xdr_free */ + res->delegated_cred_handle = NULL; + } + + *minor_status = 0; + ret_maj = GSS_S_COMPLETE; + +done: + /* we are putting our copy of these structures in here, + * and do not want it to be freed by xdr_free */ + arg->context_handle = NULL; + arg->cred_handle = NULL; + gpm_free_xdrs(GSSX_ACCEPT_SEC_CONTEXT, &uarg, &ures); + if (ret) { + if (ctx) { + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)ctx); + free(ctx); + } + if (name) { + xdr_free((xdrproc_t)xdr_gssx_name, (char *)name); + free(name); + } + if (mech) { + free(mech->elements); + free(mech); + } + if (outbuf) { + free(outbuf->value); + free(outbuf); + } + *minor_status = ret; + return GSS_S_FAILURE; + } + + return ret_maj; +} + diff --git a/proxy/src/client/gpm_acquire_cred.c b/proxy/src/client/gpm_acquire_cred.c new file mode 100644 index 0000000..8e9b010 --- /dev/null +++ b/proxy/src/client/gpm_acquire_cred.c @@ -0,0 +1,289 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" + +static int gpmint_cred_to_actual_mechs(gssx_cred *c, gss_OID_set *a) +{ + gssx_cred_element *e; + gss_OID_set m = GSS_C_NO_OID_SET; + int i; + + + if (c->elements.elements_len) { + + m = malloc(sizeof(gss_OID_set_desc)); + if (!m) { + return ENOMEM; + } + m->elements = calloc(c->elements.elements_len, + sizeof(gss_OID_desc)); + if (!m->elements) { + free(m); + return ENOMEM; + } + + for (i = 0; i < c->elements.elements_len; i++) { + e = &c->elements.elements_val[i]; + + m->elements[i].elements = gp_memdup(e->mech.octet_string_val, + e->mech.octet_string_len); + if (!m->elements[i].elements) { + while (i > 0) { + i--; + free(m->elements[i].elements); + } + free(m->elements); + free(m); + return ENOMEM; + } + m->elements[i].length = e->mech.octet_string_len; + } + } + + *a = m; + return 0; +} + +OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_acquire_cred *arg = &uarg.acquire_cred; + gssx_res_acquire_cred *res = &ures.acquire_cred; + uint32_t ret_min; + uint32_t ret_maj; + int ret = 0; + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + if (output_cred_handle == NULL) { + ret_maj = GSS_S_FAILURE; + ret_min = EINVAL; + goto done; + } + + /* ignore call_ctx for now */ + + if (desired_name) { + arg->desired_name = calloc(1, sizeof(gssx_name)); + if (!arg->desired_name) { + ret_maj = GSS_S_FAILURE; + ret_min = ENOMEM; + goto done; + } + ret_maj = gp_conv_name_to_gssx(&ret_min, + desired_name, arg->desired_name); + if (ret_maj) { + goto done; + } + } + if (desired_mechs) { + ret = gp_conv_oid_set_to_gssx(desired_mechs, &arg->desired_mechs); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + } + arg->time_req = time_req; + arg->cred_usage = gp_conv_cred_usage_to_gssx(cred_usage); + + /* execute proxy request */ + ret = gpm_make_call(GSSX_ACQUIRE_CRED, &uarg, &ures); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + ret_min = res->status.minor_status; + ret_maj = res->status.major_status; + goto done; + } + + if (actual_mechs) { + ret = gpmint_cred_to_actual_mechs(res->output_cred_handle, + actual_mechs); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + } + + if (time_rec) { + gssx_cred_element *e; + uint32_t t = 0; + + if (res->output_cred_handle->elements.elements_len) { + e = &res->output_cred_handle->elements.elements_val[0]; + if (e->initiator_time_rec < e->acceptor_time_rec) { + t = e->initiator_time_rec; + } else { + t = e->acceptor_time_rec; + } + } + + *time_rec = t; + } + + /* we steal the cred handler here */ + *output_cred_handle = (gss_cred_id_t)res->output_cred_handle; + res->output_cred_handle = NULL; + ret_maj = GSS_S_COMPLETE; + ret_min = 0; + +done: + gpm_free_xdrs(GSSX_ACQUIRE_CRED, &uarg, &ures); + *minor_status = ret_min; + return ret_maj; +} + +OM_uint32 gpm_add_cred(OM_uint32 *minor_status, + const gss_cred_id_t input_cred_handle, + const gss_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_acquire_cred *arg = &uarg.acquire_cred; + gssx_res_acquire_cred *res = &ures.acquire_cred; + gss_OID_set_desc mechs; + uint32_t ret_min; + uint32_t ret_maj; + int ret = 0; + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + /* ignore call_ctx for now */ + + if (input_cred_handle) { + arg->input_cred_handle = (gssx_cred *)input_cred_handle; + } + if (output_cred_handle != NULL) { + arg->add_cred_to_input_handle = true; + } + if (desired_name != GSS_C_NO_NAME) { + arg->desired_name = calloc(1, sizeof(gssx_name)); + if (!arg->desired_name) { + ret = ENOMEM; + goto done; + } + ret_maj = gp_conv_name_to_gssx(&ret_min, + desired_name, arg->desired_name); + if (ret_maj) { + goto done; + } + } + if (desired_mech != GSS_C_NO_OID) { + mechs.count = 1; + mechs.elements = desired_mech; + ret = gp_conv_oid_set_to_gssx(&mechs, &arg->desired_mechs); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + } + arg->cred_usage = gp_conv_cred_usage_to_gssx(cred_usage); + arg->initiator_time_req = initiator_time_req; + arg->acceptor_time_req = acceptor_time_req; + + /* execute proxy request */ + ret = gpm_make_call(GSSX_ACQUIRE_CRED, &uarg, &ures); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + ret_min = res->status.minor_status; + ret_maj = res->status.major_status; + goto done; + } + + if (actual_mechs) { + ret = gpmint_cred_to_actual_mechs(res->output_cred_handle, + actual_mechs); + if (ret) { + ret_maj = GSS_S_FAILURE; + ret_min = ret; + goto done; + } + } + + if (res->output_cred_handle->elements.elements_len) { + gssx_cred_element *e; + e = &res->output_cred_handle->elements.elements_val[0]; + if (initiator_time_rec) { + *initiator_time_rec = e->initiator_time_rec; + } + if (acceptor_time_rec) { + *acceptor_time_rec = e->initiator_time_rec; + } + } else { + if (initiator_time_rec) { + *initiator_time_rec = 0; + } + if (acceptor_time_rec) { + *acceptor_time_rec = 0; + } + } + + if (output_cred_handle) { + /* we steal the cred handler here */ + *output_cred_handle = (gss_cred_id_t)res->output_cred_handle; + res->output_cred_handle = NULL; + } + + ret_maj = GSS_S_COMPLETE; + ret_min = 0; + +done: + gpm_free_xdrs(GSSX_ACQUIRE_CRED, &uarg, &ures); + *minor_status = ret_min; + return ret_maj; +} diff --git a/proxy/src/client/gpm_common.c b/proxy/src/client/gpm_common.c new file mode 100644 index 0000000..16ea7d6 --- /dev/null +++ b/proxy/src/client/gpm_common.c @@ -0,0 +1,520 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" +#include +#include +#include +#include +#include + +#define FRAGMENT_BIT (1 << 31) + +struct gpm_ctx { + pthread_mutex_t lock; + int fd; + int next_xid; +}; + +/* a single global struct is not particularly efficient, + * but will do for now */ +struct gpm_ctx gpm_global_ctx; + +pthread_once_t gpm_init_once_control = PTHREAD_ONCE_INIT; + +static void gpm_init_once(void) +{ + pthread_mutexattr_t attr; + unsigned int seedp; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&gpm_global_ctx.lock, &attr); + + gpm_global_ctx.fd = -1; + + seedp = time(NULL) + getpid() + pthread_self(); + gpm_global_ctx.next_xid = rand_r(&seedp); + + pthread_mutexattr_destroy(&attr); +} + +#define GP_SOCKET_NAME "gssproxy.socket" + +static int get_pipe_name(struct gpm_ctx *gpmctx, char *name) +{ + int ret; + + /* TODO: get socket name from config file */ + + ret = snprintf(name, PATH_MAX, "%s/%s", PIPE_PATH, GP_SOCKET_NAME); + if (ret < 0 || ret >= PATH_MAX) { + return ENAMETOOLONG; + } + + return 0; +} + +static int gpm_open_socket(struct gpm_ctx *gpmctx) +{ + struct sockaddr_un addr = {0}; + char name[PATH_MAX]; + int ret; + int fd = -1; + + ret = get_pipe_name(gpmctx, name); + if (ret) { + return ret; + } + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, name, sizeof(addr.sun_path)-1); + addr.sun_path[sizeof(addr.sun_path)-1] = '\0'; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + ret = errno; + goto done; + } + + ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + +done: + if (ret) { + if (fd != -1) { + close(fd); + fd = -1; + } + } + gpmctx->fd = fd; + return ret; +} + +static void gpm_close_socket(struct gpm_ctx *gpmctx) +{ + int ret; + + do { + ret = close(gpmctx->fd); + /* in theory we should retry to close() on EINTR, + * but on same system the fd will be invalid after + * close() has been called, so closing again may + * cause a race with another thread that just happend + * to open an unrelated file descriptor. + * So until POSIX finally amends language around close() + * and at least the Linux kernel changes its behavior, + * it is better to risk a leak than closing an unrelated + * file descriptor */ + ret = 0; + } while (ret == EINTR); + + gpmctx->fd = -1; +} + +static int gpm_grab_sock(struct gpm_ctx *gpmctx) +{ + int ret; + + ret = pthread_mutex_lock(&gpmctx->lock); + if (ret) { + return ret; + } + + if (gpmctx->fd == -1) { + ret = gpm_open_socket(gpmctx); + } + + return ret; +} + +static int gpm_release_sock(struct gpm_ctx *gpmctx) +{ + return pthread_mutex_unlock(&gpmctx->lock); +} + +static int gpm_send_buffer(struct gpm_ctx *gpmctx, + char *buffer, uint32_t length) +{ + uint32_t size; + size_t wn; + size_t pos; + bool retry; + int ret; + + if (length > MAX_RPC_SIZE) { + return EINVAL; + } + + gpm_grab_sock(gpmctx); + + size = length | FRAGMENT_BIT; + size = htonl(size); + + retry = false; + do { + ret = 0; + do { + wn = write(gpmctx->fd, &size, sizeof(uint32_t)); + if (wn == -1) { + ret = errno; + } + } while (ret == EINTR); + if (wn != 4) { + /* reopen and retry once */ + if (retry == false) { + gpm_close_socket(gpmctx); + ret = gpm_open_socket(gpmctx); + if (ret == 0) { + retry = true; + continue; + } + } else { + ret = EIO; + } + goto done; + } + retry = false; + } while (retry); + + pos = 0; + while (length > pos) { + wn = write(gpmctx->fd, buffer + pos, length - pos); + if (wn == -1) { + if (errno == EINTR) { + continue; + } + ret = errno; + goto done; + } + pos += wn; + } + + ret = 0; + +done: + if (ret) { + /* on errors we can only close the fd and return */ + gpm_close_socket(gpmctx); + } + gpm_release_sock(gpmctx); + return ret; +} + +static int gpm_recv_buffer(struct gpm_ctx *gpmctx, + char *buffer, uint32_t *length) +{ + uint32_t size; + size_t rn; + size_t pos; + bool retry; + int ret; + + gpm_grab_sock(gpmctx); + + retry = false; + do { + ret = 0; + do { + rn = read(gpmctx->fd, &size, sizeof(uint32_t)); + if (rn == -1) { + ret = errno; + } + } while (ret == EINTR); + if (rn != 4) { + /* reopen and retry once */ + if (retry == false) { + gpm_close_socket(gpmctx); + ret = gpm_open_socket(gpmctx); + if (ret == 0) { + retry = true; + continue; + } + } else { + ret = EIO; + } + goto done; + } + retry = false; + } while (retry); + + *length = ntohl(size); + *length &= ~FRAGMENT_BIT; + + if (*length > MAX_RPC_SIZE) { + ret = EMSGSIZE; + goto done; + } + + pos = 0; + while (*length > pos) { + rn = read(gpmctx->fd, buffer + pos, *length - pos); + if (rn == -1) { + if (errno == EINTR) { + continue; + } + ret = errno; + goto done; + } + if (rn == 0) { + ret = EIO; + goto done; + } + pos += rn; + } + + ret = 0; + +done: + if (ret) { + /* on errors we can only close the fd and return */ + gpm_close_socket(gpmctx); + } + gpm_release_sock(gpmctx); + return ret; +} + +static int gpm_next_xid(struct gpm_ctx *gpmctx, uint32_t *xid) +{ + int ret; + + ret = gpm_grab_sock(gpmctx); + if (ret) { + goto done; + } + + if (gpmctx->next_xid < 0) { + *xid = 0; + gpmctx->next_xid = 1; + } else { + *xid = gpmctx->next_xid++; + } + +done: + gpm_release_sock(gpmctx); + return ret; +} + +static struct gpm_ctx *gpm_get_ctx(void) +{ + int ret; + + pthread_once(&gpm_init_once_control, gpm_init_once); + + ret = gpm_grab_sock(&gpm_global_ctx); + if (ret) { + return NULL; + } + + return &gpm_global_ctx; +} + +static void gpm_release_ctx(struct gpm_ctx *gpmctx) +{ + gpm_release_sock(gpmctx); +} + +OM_uint32 gpm_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer) +{ + if (buffer != GSS_C_NO_BUFFER) { + if (buffer->value) { + free(buffer->value); + } + buffer->length = 0; + buffer->value = NULL; + } + return GSS_S_COMPLETE; +} + +struct gpm_rpc_fn_set { + xdrproc_t arg_fn; + xdrproc_t res_fn; +} gpm_xdr_set[] = { + { /* NULLPROC */ + (xdrproc_t)xdr_void, + (xdrproc_t)xdr_void, + }, + { /* GSSX_INDICATE_MECHS */ + (xdrproc_t)xdr_gssx_arg_indicate_mechs, + (xdrproc_t)xdr_gssx_res_indicate_mechs, + }, + { /* GSSX_GET_CALL_CONTEXT */ + (xdrproc_t)xdr_gssx_arg_get_call_context, + (xdrproc_t)xdr_gssx_res_get_call_context, + }, + { /* GSSX_IMPORT_AND_CANON_NAME */ + (xdrproc_t)xdr_gssx_arg_import_and_canon_name, + (xdrproc_t)xdr_gssx_res_import_and_canon_name, + }, + { /* GSSX_EXPORT_CRED */ + (xdrproc_t)xdr_gssx_arg_export_cred, + (xdrproc_t)xdr_gssx_res_export_cred, + }, + { /* GSSX_IMPORT_CRED */ + (xdrproc_t)xdr_gssx_arg_import_cred, + (xdrproc_t)xdr_gssx_res_import_cred, + }, + { /* GSSX_ACQUIRE_CRED */ + (xdrproc_t)xdr_gssx_arg_acquire_cred, + (xdrproc_t)xdr_gssx_res_acquire_cred, + }, + { /* GSSX_STORE_CRED */ + (xdrproc_t)xdr_gssx_arg_store_cred, + (xdrproc_t)xdr_gssx_res_store_cred, + }, + { /* GSSX_INIT_SEC_CONTEXT */ + (xdrproc_t)xdr_gssx_arg_init_sec_context, + (xdrproc_t)xdr_gssx_res_init_sec_context, + }, + { /* GSSX_ACCEPT_SEC_CONTEXT */ + (xdrproc_t)xdr_gssx_arg_accept_sec_context, + (xdrproc_t)xdr_gssx_res_accept_sec_context, + }, + { /* GSSX_RELEASE_HANDLE */ + (xdrproc_t)xdr_gssx_arg_release_handle, + (xdrproc_t)xdr_gssx_res_release_handle, + }, + { /* GSSX_GET_MIC */ + (xdrproc_t)xdr_gssx_arg_get_mic, + (xdrproc_t)xdr_gssx_res_get_mic, + }, + { /* GSSX_VERIFY */ + (xdrproc_t)xdr_gssx_arg_verify_mic, + (xdrproc_t)xdr_gssx_res_verify_mic, + }, + { /* GSSX_WRAP */ + (xdrproc_t)xdr_gssx_arg_wrap, + (xdrproc_t)xdr_gssx_res_wrap, + }, + { /* GSSX_UNWRAP */ + (xdrproc_t)xdr_gssx_arg_unwrap, + (xdrproc_t)xdr_gssx_res_unwrap, + }, + { /* GSSX_WRAP_SIZE_LIMIT */ + (xdrproc_t)xdr_gssx_arg_wrap_size_limit, + (xdrproc_t)xdr_gssx_res_wrap_size_limit, + } +}; + +int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) +{ + struct gpm_ctx *gpmctx; + gp_rpc_msg msg; + XDR xdr_call_ctx; + XDR xdr_reply_ctx; + char buffer[MAX_RPC_SIZE]; + uint32_t length; + uint32_t xid; + bool xdrok; + int ret; + + xdrmem_create(&xdr_call_ctx, buffer, MAX_RPC_SIZE, XDR_ENCODE); + xdrmem_create(&xdr_reply_ctx, buffer, MAX_RPC_SIZE, XDR_DECODE); + + memset(&msg, 0, sizeof(gp_rpc_msg)); + msg.header.type = GP_RPC_CALL; + msg.header.gp_rpc_msg_union_u.chdr.rpcvers = 2; + msg.header.gp_rpc_msg_union_u.chdr.prog = GSSPROXY; + msg.header.gp_rpc_msg_union_u.chdr.vers = GSSPROXYVERS; + msg.header.gp_rpc_msg_union_u.chdr.proc = proc; + msg.header.gp_rpc_msg_union_u.chdr.cred.flavor = GP_RPC_AUTH_NONE; + msg.header.gp_rpc_msg_union_u.chdr.cred.body.body_len = 0; + msg.header.gp_rpc_msg_union_u.chdr.cred.body.body_val = NULL; + msg.header.gp_rpc_msg_union_u.chdr.verf.flavor = GP_RPC_AUTH_NONE; + msg.header.gp_rpc_msg_union_u.chdr.verf.body.body_len = 0; + msg.header.gp_rpc_msg_union_u.chdr.verf.body.body_val = NULL; + + gpmctx = gpm_get_ctx(); + if (!gpmctx) { + return EINVAL; + } + + ret = gpm_next_xid(gpmctx, &xid); + if (ret) { + goto done; + } + msg.xid = xid; + + /* encode header */ + xdrok = xdr_gp_rpc_msg(&xdr_call_ctx, &msg); + if (!xdrok) { + ret = EINVAL; + goto done; + } + + /* encode data */ + xdrok = gpm_xdr_set[proc].arg_fn(&xdr_call_ctx, (char *)arg); + if (!xdrok) { + ret = EINVAL; + goto done; + } + + /* send to proxy */ + ret = gpm_send_buffer(gpmctx, buffer, xdr_getpos(&xdr_call_ctx)); + if (ret) { + goto done; + } + + /* receive answer */ + ret = gpm_recv_buffer(gpmctx, buffer, &length); + if (ret) { + goto done; + } + + /* decode header */ + xdrok = xdr_gp_rpc_msg(&xdr_reply_ctx, &msg); + if (!xdrok) { + ret = EINVAL; + goto done; + } + + if (msg.xid != xid || + msg.header.type != GP_RPC_REPLY || + msg.header.gp_rpc_msg_union_u.rhdr.status != GP_RPC_MSG_ACCEPTED || + msg.header.gp_rpc_msg_union_u.rhdr.gp_rpc_reply_header_u.accepted.reply_data.status != GP_RPC_SUCCESS) { + ret = EINVAL; + goto done; + } + + /* decode answer */ + xdrok = gpm_xdr_set[proc].res_fn(&xdr_reply_ctx, (char *)res); + if (!xdrok) { + ret = EINVAL; + } + +done: + xdr_free((xdrproc_t)xdr_gp_rpc_msg, (char *)&msg); + xdr_destroy(&xdr_call_ctx); + xdr_destroy(&xdr_reply_ctx); + gpm_release_ctx(gpmctx); + return ret; +} + +void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) +{ + xdr_free(gpm_xdr_set[proc].arg_fn, (char *)arg); + xdr_free(gpm_xdr_set[proc].res_fn, (char *)res); +} diff --git a/proxy/src/client/gpm_display_status.c b/proxy/src/client/gpm_display_status.c new file mode 100644 index 0000000..cc5e3cc --- /dev/null +++ b/proxy/src/client/gpm_display_status.c @@ -0,0 +1,124 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" + +__thread gssx_status *tls_last_status = NULL; + +/* Thread local storage for return status. + * FIXME: it's not the most portable construct, so may need fixing in future */ +void gpm_save_status(gssx_status *status) +{ + int ret; + + if (tls_last_status) { + xdr_free((xdrproc_t)xdr_gssx_status, (char *)tls_last_status); + free(tls_last_status); + } + + ret = gp_copy_gssx_status_alloc(status, &tls_last_status); + if (ret) { + /* make sure tls_last_status is zeored on error */ + tls_last_status = NULL; + } +} + +/* This funciton is used to record internal mech errors that are + * generated by the proxy client code */ +void gpm_save_internal_status(uint32_t err, char *err_str) +{ + gssx_status status; + + memset(&status, 0, sizeof(gssx_status)); + +#define STD_MAJ_ERROR_STR "Internal gssproxy error" + status.major_status = GSS_S_FAILURE; + status.major_status_string.utf8string_val = STD_MAJ_ERROR_STR; + status.major_status_string.utf8string_len = sizeof(STD_MAJ_ERROR_STR); + status.minor_status = err; + status.minor_status_string.utf8string_val = err_str; + status.minor_status_string.utf8string_len = strlen(err_str) + 1; + gpm_save_status(&status); +} + +OM_uint32 gpm_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_context, + gss_buffer_t status_string) +{ + utf8string tmp; + int ret; + + switch(status_type) { + case GSS_C_GSS_CODE: + if (tls_last_status && + tls_last_status->major_status == status_value && + tls_last_status->major_status_string.utf8string_len) { + ret = gp_copy_utf8string(&tls_last_status->major_status_string, + &tmp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + status_string->value = tmp.utf8string_val; + status_string->length = tmp.utf8string_len; + *minor_status = 0; + return GSS_S_COMPLETE; + } else { + /* if we do not have it, make it clear */ + return GSS_S_UNAVAILABLE; + } + case GSS_C_MECH_CODE: + if (tls_last_status && + tls_last_status->minor_status == status_value && + tls_last_status->minor_status_string.utf8string_len) { + + if (*message_context) { + /* we do not support multiple messages for now */ + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + ret = gp_copy_utf8string(&tls_last_status->minor_status_string, + &tmp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + status_string->value = tmp.utf8string_val; + status_string->length = tmp.utf8string_len; + } else { + /* if we do not have it, make it clear */ + return GSS_S_UNAVAILABLE; + } + *minor_status = 0; + return GSS_S_COMPLETE; + default: + *minor_status = EINVAL; + return GSS_S_BAD_STATUS; + } +} diff --git a/proxy/src/client/gpm_import_and_canon_name.c b/proxy/src/client/gpm_import_and_canon_name.c new file mode 100644 index 0000000..5301d60 --- /dev/null +++ b/proxy/src/client/gpm_import_and_canon_name.c @@ -0,0 +1,342 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" + +OM_uint32 gpm_display_name(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type) +{ + gss_buffer_desc input_name_buffer = GSS_C_EMPTY_BUFFER; + gssx_name *output_name = NULL; + gss_name_t tmp; + gssx_name *name; + uint32_t ret_maj; + uint32_t ret_min; + uint32_t discard; + int ret; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + *minor_status = 0; + + if (!input_name) { + return GSS_S_CALL_INACCESSIBLE_READ; + } + if (!output_name_buffer) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + name = (gssx_name *)input_name; + + if (name->display_name.octet_string_len == 0) { + if (name->exported_name.octet_string_len == 0) { + return GSS_S_BAD_NAME; + } + + gp_conv_gssx_to_buffer(&name->exported_name, &input_name_buffer); + tmp = (gss_name_t)output_name; + + ret_maj = gpm_import_name(&ret_min, &input_name_buffer, + GSS_C_NT_EXPORT_NAME, &tmp); + if (ret_maj) { + goto done; + } + + /* steal display_name and name_type */ + name->display_name = output_name->display_name; + output_name->display_name.octet_string_len = 0; + output_name->display_name.octet_string_val = NULL; + name->name_type = output_name->name_type; + output_name->name_type.octet_string_len = 0; + output_name->name_type.octet_string_val = NULL; + } + + ret = gp_copy_gssx_to_buffer(&name->display_name, output_name_buffer); + if (ret) { + ret_min = ret; + ret_maj = GSS_S_FAILURE; + goto done; + } + + if (output_name_type) { + ret = gp_conv_gssx_to_oid_alloc(&name->name_type, output_name_type); + if (ret) { + gss_release_buffer(&discard, output_name_buffer); + ret_min = ret; + ret_maj = GSS_S_FAILURE; + goto done; + } + } + + ret_min = 0; + ret_maj = GSS_S_COMPLETE; + +done: + if (output_name) { + xdr_free((xdrproc_t)xdr_gssx_name, (char *)output_name); + free(output_name); + } + *minor_status = ret_min; + return ret_maj; +} + +OM_uint32 gpm_import_name(OM_uint32 *minor_status, + gss_buffer_t input_name_buffer, + gss_OID input_name_type, + gss_name_t *output_name) +{ + gssx_name *name; + int ret; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + *minor_status = 0; + + if (!input_name_buffer || !input_name_type) { + return GSS_S_CALL_INACCESSIBLE_READ; + } + if (!output_name) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + /* ignore call_ctx for now */ + + name = calloc(1, sizeof(gssx_name)); + if (!name) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = gp_conv_buffer_to_gssx(input_name_buffer, &name->display_name); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + ret = gp_conv_oid_to_gssx(input_name_type, &name->name_type); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + *output_name = (gss_name_t)name; + return GSS_S_COMPLETE; +} + +OM_uint32 gpm_export_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name) +{ + gssx_name *name; + int ret; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + *minor_status = 0; + + if (!input_name) { + return GSS_S_CALL_INACCESSIBLE_READ; + } + + name = (gssx_name *)input_name; + + if (name->exported_name.octet_string_len == 0) { + return GSS_S_NAME_NOT_MN; + } + + ret = gp_copy_gssx_to_buffer(&name->exported_name, exported_name); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + return GSS_S_COMPLETE; +} + +OM_uint32 gpm_duplicate_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_name_t *dest_name) +{ + gssx_name *name; + gssx_name *namecopy; + int ret; + + name = (gssx_name *)input_name; + + ret = gp_copy_gssx_name_alloc(name, &namecopy); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + *dest_name = (gss_name_t)namecopy; + return GSS_S_COMPLETE; +} + +OM_uint32 gpm_canonicalize_name(OM_uint32 *minor_status, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t *output_name) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_import_and_canon_name *arg = &uarg.import_and_canon_name; + gssx_res_import_and_canon_name *res = &ures.import_and_canon_name; + uint32_t ret_maj; + uint32_t ret_min; + gssx_name *name; + int ret; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + *minor_status = 0; + + if (!input_name || !mech_type) { + return GSS_S_CALL_INACCESSIBLE_READ; + } + if (!output_name) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + name = (gssx_name *)input_name; + + memset(arg, 0, sizeof(gssx_arg_import_and_canon_name)); + memset(res, 0, sizeof(gssx_res_import_and_canon_name)); + + /* ignore call_ctx for now */ + + ret = gp_copy_gssx_name(name, &arg->input_name); + if (ret) { + goto done; + } + ret = gp_conv_oid_to_gssx(mech_type, &arg->mech); + if (ret) { + goto done; + } + + /* execute proxy request */ + ret = gpm_make_call(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures); + if (ret) { + goto done; + } + + ret_min = res->status.minor_status; + ret_maj = res->status.major_status; + if (res->status.major_status) { + gpm_save_status(&res->status); + ret = 0; + goto done; + } + + /* steal output_name */ + *output_name = (gss_name_t)res->output_name; + res->output_name = NULL; + +done: + if (ret) { + ret_min = ret; + ret_maj = GSS_S_FAILURE; + } + gpm_free_xdrs(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures); + *minor_status = ret_min; + return ret_maj; +} + +OM_uint32 gpm_inquire_name(OM_uint32 *minor_status, + gss_name_t name, + int *name_is_MN, + gss_OID *MN_mech, + gss_buffer_set_t *attrs) +{ + gss_buffer_set_t xattrs = GSS_C_NO_BUFFER_SET; + gssx_name *xname; + uint32_t i; + int ret; + + *minor_status = 0; + xname = (gssx_name *)name; + + if (xname->exported_name.octet_string_len != 0) { + if (name_is_MN != NULL) { + *name_is_MN = 1; + } + } + + if (MN_mech != NULL) { + ret = gp_conv_gssx_to_oid_alloc(&xname->name_type, MN_mech); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + } + + if (xname->name_attributes.name_attributes_len != 0) { + xattrs = calloc(1, sizeof(gss_buffer_set_desc)); + if (!xattrs) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + xattrs->count = xname->name_attributes.name_attributes_len; + xattrs->elements = calloc(xattrs->count, sizeof(gss_buffer_desc)); + if (!xattrs->elements) { + free(xattrs); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + for (i = 0; i < xattrs->count; i++) { + ret = gp_copy_gssx_to_buffer( + &xname->name_attributes.name_attributes_val[i].attr, + &xattrs->elements[i]); + if (ret) { + for (--i; i >= 0; i--) { + free(xattrs->elements[i].value); + } + free(xattrs->elements); + free(xattrs); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + } + } + *attrs = xattrs; + + return GSS_S_COMPLETE; +} + +OM_uint32 gpm_release_name(OM_uint32 *minor_status, + gss_name_t *input_name) +{ + *minor_status = 0; + + if (*input_name != GSS_C_NO_NAME) { + xdr_free((xdrproc_t)xdr_gssx_name, (char *)(*input_name)); + free(*input_name); + *input_name = GSS_C_NO_NAME; + } + return GSS_S_COMPLETE; +} diff --git a/proxy/src/client/gpm_indicate_mechs.c b/proxy/src/client/gpm_indicate_mechs.c new file mode 100644 index 0000000..693e588 --- /dev/null +++ b/proxy/src/client/gpm_indicate_mechs.c @@ -0,0 +1,734 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" +#include + +struct gpm_mech_info { + gss_OID mech; + gss_OID_set name_types; + gss_OID_set mech_attrs; + gss_OID_set known_mech_attrs; + gss_OID_set cred_options; + gss_OID_set sec_ctx_options; + gss_buffer_t saslname_sasl_mech_name; + gss_buffer_t saslname_mech_name; + gss_buffer_t saslname_mech_desc; +}; + +struct gpm_mech_attr { + gss_OID attr; + gss_buffer_t name; + gss_buffer_t short_desc; + gss_buffer_t long_desc; +}; + +struct gpm_mechs { + bool initialized; + + gss_OID_set mech_set; + + size_t info_len; + struct gpm_mech_info *info; + + size_t desc_len; + struct gpm_mech_attr *desc; +}; + +pthread_mutex_t global_mechs_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_once_t indicate_mechs_once = PTHREAD_ONCE_INIT; +struct gpm_mechs global_mechs = { + .initialized = false, + .mech_set = GSS_C_NO_OID_SET, + .info_len = 0, + .info = NULL, + .desc_len = 0, + .desc = NULL, +}; + +static uint32_t gpm_copy_gss_OID_set(uint32_t *minor_status, + gss_OID_set oldset, gss_OID_set *newset) +{ + gss_OID_set n; + uint32_t ret_maj; + uint32_t ret_min; + int i; + + ret_maj = gss_create_empty_oid_set(&ret_min, &n); + if (ret_maj) { + *minor_status = ret_min; + return ret_maj; + } + + for (i = 0; i < oldset->count; i++) { + ret_maj = gss_add_oid_set_member(&ret_min, &oldset->elements[i], &n); + if (ret_maj) { + *minor_status = ret_min; + gss_release_oid_set(&ret_min, &n); + return ret_maj; + } + } + + *newset = n; + *minor_status = 0; + return GSS_S_COMPLETE; +} + +static uint32_t gpm_copy_gss_buffer(uint32_t *minor_status, + gss_buffer_t oldbuf, + gss_buffer_t newbuf) +{ + if (!oldbuf || oldbuf->length == 0) { + newbuf->value = NULL; + newbuf->length = 0; + *minor_status = 0; + return GSS_S_COMPLETE; + } + + newbuf->value = malloc(oldbuf->length); + if (!newbuf->value) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(newbuf->value, oldbuf->value, oldbuf->length); + newbuf->length = oldbuf->length; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + +static bool gpm_equal_oids(gss_const_OID a, gss_const_OID b) +{ + int ret; + + if (a->length == b->length) { + ret = memcmp(a->elements, b->elements, a->length); + if (ret == 0) { + return true; + } + } + + return false; +} + +static void gpmint_indicate_mechs(void) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_indicate_mechs *arg = &uarg.indicate_mechs; + gssx_res_indicate_mechs *res = &ures.indicate_mechs; + struct gpm_mech_info *gi; + struct gpm_mech_attr *ga; + gssx_mech_info *mi; + gssx_mech_attr *ma; + uint32_t discard; + uint32_t ret_min; + uint32_t ret_maj = 0; + int ret = 0; + int i; + + memset(arg, 0, sizeof(gssx_arg_indicate_mechs)); + memset(res, 0, sizeof(gssx_res_indicate_mechs)); + + /* ignore call_ctx for now */ + + /* execute proxy request */ + ret = gpm_make_call(GSSX_INDICATE_MECHS, &uarg, &ures); + if (ret) { + goto done; + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + ret_min = res->status.minor_status; + ret_maj = res->status.major_status; + ret = 0; + goto done; + } + + ret_maj = gss_create_empty_oid_set(&ret_min, &global_mechs.mech_set); + if (ret_maj) { + goto done; + } + + global_mechs.info = calloc(res->mechs.mechs_len, + sizeof(struct gpm_mech_info)); + if (!global_mechs.info) { + ret_maj = GSS_S_FAILURE; + ret_min = ENOMEM; + goto done; + } + + for (i = 0; i < res->mechs.mechs_len; i++) { + mi = &res->mechs.mechs_val[i]; + gi = &global_mechs.info[i]; + + ret = gp_conv_gssx_to_oid_alloc(&mi->mech, + &gi->mech); + if (ret) { + goto done; + } + ret_maj = gss_add_oid_set_member(&ret_min, gi->mech, + &global_mechs.mech_set); + if (ret_maj) { + goto done; + } + + ret = gp_conv_gssx_to_oid_set(&mi->name_types, + &gi->name_types); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_oid_set(&mi->mech_attrs, + &gi->mech_attrs); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_oid_set(&mi->known_mech_attrs, + &gi->known_mech_attrs); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_oid_set(&mi->cred_options, + &gi->cred_options); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_oid_set(&mi->sec_ctx_options, + &gi->sec_ctx_options); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_sasl_mech_name, + &gi->saslname_sasl_mech_name); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_mech_name, + &gi->saslname_mech_name); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_mech_desc, + &gi->saslname_mech_desc); + if (ret) { + goto done; + } + } + global_mechs.info_len = res->mechs.mechs_len; + + global_mechs.desc = calloc(res->mech_attr_descs.mech_attr_descs_len, + sizeof(struct gpm_mech_attr)); + if (!global_mechs.desc) { + goto done; + } + + for (i = 0; i < res->mech_attr_descs.mech_attr_descs_len; i++) { + ma = &res->mech_attr_descs.mech_attr_descs_val[i]; + ga = &global_mechs.desc[i]; + + ret = gp_conv_gssx_to_oid_alloc(&ma->attr, &ga->attr); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&ma->name, &ga->name); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&ma->short_desc, &ga->short_desc); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_buffer_alloc(&ma->long_desc, &ga->long_desc); + if (ret) { + goto done; + } + } + global_mechs.desc_len = res->mech_attr_descs.mech_attr_descs_len; + + global_mechs.initialized = true; + +done: + if (ret || ret_maj) { + for (i = 0; i < global_mechs.desc_len; i++) { + ga = &global_mechs.desc[i]; + gss_release_oid(&discard, &ga->attr); + gss_release_buffer(&discard, ga->name); + gss_release_buffer(&discard, ga->short_desc); + gss_release_buffer(&discard, ga->long_desc); + } + free(global_mechs.desc); + global_mechs.desc = NULL; + for (i = 0; i < global_mechs.info_len; i++) { + gi = &global_mechs.info[i]; + gss_release_oid(&discard, &gi->mech); + gss_release_oid_set(&discard, &gi->name_types); + gss_release_oid_set(&discard, &gi->mech_attrs); + gss_release_oid_set(&discard, &gi->known_mech_attrs); + gss_release_oid_set(&discard, &gi->cred_options); + gss_release_oid_set(&discard, &gi->sec_ctx_options); + gss_release_buffer(&discard, gi->saslname_sasl_mech_name); + gss_release_buffer(&discard, gi->saslname_mech_name); + gss_release_buffer(&discard, gi->saslname_mech_desc); + } + free(global_mechs.info); + global_mechs.info = NULL; + gss_release_oid_set(&discard, &global_mechs.mech_set); + } + gpm_free_xdrs(GSSX_INDICATE_MECHS, &uarg, &ures); +} + +static int gpmint_init_global_mechs(void) +{ + pthread_once(&indicate_mechs_once, gpmint_indicate_mechs); + + if (!global_mechs.initialized) { + /* this is quite a corner case. It means the pthread_once() call + * failed for some reason. In this case we need to use a mutex */ + + pthread_mutex_lock(&global_mechs_lock); + /* need to recheck once we acquired the lock, to avoid redoing + * if we were stuck after another thread that already did it */ + if (!global_mechs.initialized) { + gpmint_indicate_mechs(); + } + pthread_mutex_unlock(&global_mechs_lock); + + if (!global_mechs.initialized) { + /* if still it is not initialized, give up */ + return EIO; + } + } + + return 0; +} + +OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set) +{ + uint32_t ret_min; + uint32_t ret_maj; + int ret; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!mech_set) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret= gpmint_init_global_mechs(); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret_maj = gpm_copy_gss_OID_set(&ret_min, + global_mechs.mech_set, + mech_set); + *minor_status = ret_min; + return ret_maj; +} + +OM_uint32 gpm_inquire_names_for_mech(OM_uint32 *minor_status, + gss_OID mech_type, + gss_OID_set *mech_names) +{ + uint32_t ret_min; + uint32_t ret_maj; + int i; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!mech_names) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + for (i = 0; i < global_mechs.info_len; i++) { + if (!gpm_equal_oids(global_mechs.info[i].mech, mech_type)) { + continue; + } + ret_maj = gpm_copy_gss_OID_set(&ret_min, + global_mechs.info[i].name_types, + mech_names); + *minor_status = ret_min; + return ret_maj; + } + + *minor_status = 0; + return GSS_S_BAD_MECH; +} + +OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_OID_set *mech_types) +{ + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; + gssx_name *name; + gss_OID name_type = GSS_C_NO_OID; + int present; + int i; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!input_name || !mech_types) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + name = (gssx_name *)input_name; + ret_min = gp_conv_gssx_to_oid_alloc(&name->name_type, &name_type); + if (ret_min) { + ret_maj = GSS_S_FAILURE; + goto done; + } + + ret_maj = gss_create_empty_oid_set(&ret_min, mech_types); + if (ret_maj) { + goto done; + } + + for (i = 0; i < global_mechs.info_len; i++) { + ret_maj = gss_test_oid_set_member(&ret_min, name_type, + global_mechs.info[i].name_types, + &present); + if (ret_maj) { + /* skip on error */ + continue; + } + if (present) { + ret_maj = gss_add_oid_set_member(&ret_min, + global_mechs.info[i].mech, + mech_types); + } + if (ret_maj) { + goto done; + } + } + +done: + gss_release_oid(&discard, &name_type); + if (ret_maj) { + gss_release_oid_set(&discard, mech_types); + *minor_status = ret_min; + return ret_maj; + } + *minor_status = 0; + return GSS_S_COMPLETE; +} + +OM_uint32 gpm_inquire_attrs_for_mech(OM_uint32 *minor_status, + gss_OID mech, + gss_OID_set *mech_attrs, + gss_OID_set *known_mech_attrs) +{ + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; + int i; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!mech_attrs || !known_mech_attrs) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + for (i = 0; i < global_mechs.info_len; i++) { + if (!gpm_equal_oids(global_mechs.info[i].mech, mech)) { + continue; + } + ret_maj = gpm_copy_gss_OID_set(&ret_min, + global_mechs.info[i].mech_attrs, + mech_attrs); + if (ret_maj) { + *minor_status = ret_min; + return ret_maj; + } + ret_maj = gpm_copy_gss_OID_set(&ret_min, + global_mechs.info[i].known_mech_attrs, + known_mech_attrs); + if (ret_maj) { + gss_release_oid_set(&discard, known_mech_attrs); + } + *minor_status = ret_min; + return ret_maj; + } + + *minor_status = 0; + return GSS_S_BAD_MECH; +} + +OM_uint32 gpm_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description) +{ + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; + int i; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!sasl_mech_name || !mech_name || !mech_description) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + for (i = 0; i < global_mechs.info_len; i++) { + if (!gpm_equal_oids(global_mechs.info[i].mech, desired_mech)) { + continue; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.info[i].saslname_sasl_mech_name, + sasl_mech_name); + if (ret_maj) { + *minor_status = ret_min; + return ret_maj; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.info[i].saslname_mech_name, + mech_name); + if (ret_maj) { + gss_release_buffer(&discard, sasl_mech_name); + *minor_status = ret_min; + return ret_maj; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.info[i].saslname_mech_desc, + mech_description); + if (ret_maj) { + gss_release_buffer(&discard, sasl_mech_name); + gss_release_buffer(&discard, mech_name); + } + *minor_status = ret_min; + return ret_maj; + } + + *minor_status = 0; + return GSS_S_BAD_MECH; +} + +OM_uint32 gpm_display_mech_attr(OM_uint32 *minor_status, + gss_const_OID mech_attr, + gss_buffer_t name, + gss_buffer_t short_desc, + gss_buffer_t long_desc) +{ + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; + int i; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!name || !short_desc || !long_desc) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + for (i = 0; i < global_mechs.desc_len; i++) { + if (!gpm_equal_oids(global_mechs.desc[i].attr, mech_attr)) { + continue; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.desc[i].name, + name); + if (ret_maj) { + *minor_status = ret_min; + return ret_maj; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.desc[i].short_desc, + short_desc); + if (ret_maj) { + gss_release_buffer(&discard, name); + *minor_status = ret_min; + return ret_maj; + } + ret_maj = gpm_copy_gss_buffer(&ret_min, + global_mechs.desc[i].long_desc, + long_desc); + if (ret_maj) { + gss_release_buffer(&discard, name); + gss_release_buffer(&discard, short_desc); + } + *minor_status = ret_min; + return ret_maj; + } + + *minor_status = 0; + return GSS_S_BAD_MECH; +} + +OM_uint32 gpm_indicate_mechs_by_attrs(OM_uint32 *minor_status, + gss_const_OID_set desired_mech_attrs, + gss_const_OID_set except_mech_attrs, + gss_const_OID_set critical_mech_attrs, + gss_OID_set *mechs) +{ + uint32_t ret_min; + uint32_t ret_maj; + uint32_t discard; + int present; + int i, j; + + if (!minor_status) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + if (!mechs) { + *minor_status = 0; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + ret_min = gpmint_init_global_mechs(); + if (ret_min) { + *minor_status = ret_min; + return GSS_S_FAILURE; + } + + ret_maj = gss_create_empty_oid_set(&ret_min, mechs); + if (ret_maj) { + *minor_status = ret_min; + return ret_maj; + } + + for (i = 0; i < global_mechs.info_len; i++) { + if (desired_mech_attrs != GSS_C_NO_OID_SET) { + for (j = 0; j < desired_mech_attrs->count; j++) { + ret_maj = gss_test_oid_set_member(&ret_min, + &desired_mech_attrs->elements[j], + global_mechs.info[i].mech_attrs, + &present); + if (ret_maj) { + /* skip in case of errors */ + break; + } + if (!present) { + break; + } + } + /* if not desired skip */ + if (j != desired_mech_attrs->count) { + continue; + } + } + if (except_mech_attrs != GSS_C_NO_OID_SET) { + for (j = 0; j < except_mech_attrs->count; j++) { + ret_maj = gss_test_oid_set_member(&ret_min, + &except_mech_attrs->elements[j], + global_mechs.info[i].mech_attrs, + &present); + if (ret_maj) { + /* continue in case of errors */ + continue; + } + if (present) { + break; + } + } + /* if excepted skip */ + if (j == desired_mech_attrs->count) { + continue; + } + } + if (critical_mech_attrs != GSS_C_NO_OID_SET) { + for (j = 0; j < critical_mech_attrs->count; j++) { + ret_maj = gss_test_oid_set_member(&ret_min, + &critical_mech_attrs->elements[j], + global_mechs.info[i].known_mech_attrs, + &present); + if (ret_maj) { + /* skip in case of errors */ + break; + } + if (!present) { + break; + } + } + /* if not known skip */ + if (j != desired_mech_attrs->count) { + continue; + } + } + + /* passes all tests, add to list */ + ret_maj = gss_add_oid_set_member(&ret_min, + global_mechs.info[i].mech, mechs); + if (ret_maj) { + goto done; + } + } + +done: + if (ret_maj) { + gss_release_oid_set(&discard, mechs); + *minor_status = ret_min; + return ret_maj; + } + *minor_status = 0; + return GSS_S_COMPLETE; +} + diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c new file mode 100644 index 0000000..0769363 --- /dev/null +++ b/proxy/src/client/gpm_init_sec_context.c @@ -0,0 +1,176 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" +#include "src/gp_conv.h" + +OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, + gss_cred_id_t claimant_cred_handle, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + gss_channel_bindings_t input_cb, + gss_buffer_t input_token, + gss_OID *actual_mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_init_sec_context *arg = &uarg.init_sec_context; + gssx_res_init_sec_context *res = &ures.init_sec_context; + gssx_ctx *ctx = NULL; + gss_OID_desc *mech = NULL; + gss_buffer_t outbuf = NULL; + uint32_t ret_maj = GSS_S_COMPLETE; + uint32_t ret_min = 0; + int ret; + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + /* prepare proxy request */ + if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) { + arg->cred_handle = (gssx_cred *)claimant_cred_handle; + } + + if (*context_handle) { + arg->context_handle = (gssx_ctx *)*context_handle; + } + + if (target_name != GSS_C_NO_NAME) { + arg->target_name = (gssx_name *)target_name; + } + + ret = gp_conv_oid_to_gssx(mech_type, &arg->mech_type); + if (ret) { + goto done; + } + + if (input_cb) { + ret = gp_conv_cb_to_gssx_alloc(input_cb, &arg->input_cb); + if (ret) { + goto done; + } + } + + if (input_token != GSS_C_NO_BUFFER) { + ret = gp_conv_buffer_to_gssx_alloc(input_token, &arg->input_token); + if (ret) { + goto done; + } + } + + /* execute proxy request */ + ret = gpm_make_call(GSSX_INIT_SEC_CONTEXT, &uarg, &ures); + if (ret) { + gpm_save_internal_status(ret, strerror(ret)); + goto done; + } + + /* return values */ + if (actual_mech_type) { + if (res->status.mech.octet_string_len) { + ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); + if (ret) { + goto done; + } + } + } + + 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 + * it to be freed by xdr_free */ + 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; + } + +done: + if (ret != 0) { + ret_min = ret; + ret_maj = GSS_S_FAILURE; + } + + /* we are putting our copy of these structures in here, + * and do not want it to be freed by xdr_free */ + arg->context_handle = NULL; + arg->cred_handle = NULL; + arg->target_name = NULL; + gpm_free_xdrs(GSSX_INIT_SEC_CONTEXT, &uarg, &ures); + + if (ret_maj == GSS_S_COMPLETE || ret_maj == GSS_S_CONTINUE_NEEDED) { + /* replace old ctx handle if any */ + if (*context_handle) { + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)*context_handle); + free(*context_handle); + } + *context_handle = (gss_ctx_id_t)ctx; + if (actual_mech_type) { + *actual_mech_type = mech; + } + if (outbuf) { + *output_token = *outbuf; + free(outbuf); + } + if (ret_flags) { + *ret_flags = ctx->ctx_flags; + } + if (time_rec) { + *time_rec = ctx->lifetime; + } + } else { + if (ctx) { + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)ctx); + free(ctx); + } + if (mech) { + free(mech->elements); + free(mech); + } + if (outbuf) { + free(outbuf->value); + free(outbuf); + } + } + + *minor_status = ret_min; + return ret_maj; +} diff --git a/proxy/src/client/gpm_release_handle.c b/proxy/src/client/gpm_release_handle.c new file mode 100644 index 0000000..010c148 --- /dev/null +++ b/proxy/src/client/gpm_release_handle.c @@ -0,0 +1,131 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "gssapi_gpm.h" + +OM_uint32 gpm_release_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_release_handle *arg = &uarg.release_handle; + gssx_res_release_handle *res = &ures.release_handle; + gssx_cred *r; + int ret; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + return 0; + } + + r = (gssx_cred *)(*cred_handle); + + if (!r->needs_release) { + ret = GSS_S_COMPLETE; + goto done; + } + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + /* ignore call_ctx for now */ + + arg->cred_handle.handle_type = GSSX_C_HANDLE_CRED; + arg->cred_handle.gssx_handle_u.cred_info = *r; + + /* execute proxy request */ + ret = gpm_make_call(GSSX_RELEASE_HANDLE, &uarg, &ures); + if (ret) { + *minor_status = ret; + ret = GSS_S_FAILURE; + goto rel_done; + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + *minor_status = res->status.minor_status; + ret = res->status.major_status; + } + +rel_done: + /* we passed in our copy by value, so clean out to avoid double frees */ + memset(&arg->cred_handle.gssx_handle_u.cred_info, 0, sizeof(gssx_cred)); + gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); +done: + xdr_free((xdrproc_t)xdr_gssx_cred, (char *)r); + return ret; +} + +OM_uint32 gpm_delete_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token) +{ + union gp_rpc_arg uarg; + union gp_rpc_res ures; + gssx_arg_release_handle *arg = &uarg.release_handle; + gssx_res_release_handle *res = &ures.release_handle; + gssx_ctx *r; + int ret; + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { + return 0; + } + + r = (gssx_ctx *)(*context_handle); + + if (!r->needs_release) { + ret = GSS_S_COMPLETE; + goto done; + } + + memset(&uarg, 0, sizeof(union gp_rpc_arg)); + memset(&ures, 0, sizeof(union gp_rpc_res)); + + /* ignore call_ctx for now */ + + arg->cred_handle.handle_type = GSSX_C_HANDLE_SEC_CTX; + arg->cred_handle.gssx_handle_u.sec_ctx_info = *r; + + /* execute proxy request */ + ret = gpm_make_call(GSSX_RELEASE_HANDLE, &uarg, &ures); + if (ret) { + *minor_status = ret; + ret = GSS_S_FAILURE; + goto rel_done; + } + + if (res->status.major_status) { + gpm_save_status(&res->status); + *minor_status = res->status.minor_status; + ret = res->status.major_status; + } + +rel_done: + /* we passed in our copy by value, so clean out to avoid double frees */ + memset(&arg->cred_handle.gssx_handle_u.sec_ctx_info, 0, sizeof(gssx_cred)); + gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); +done: + xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)r); + return ret; +} diff --git a/proxy/src/client/gssapi_gpm.h b/proxy/src/client/gssapi_gpm.h new file mode 100644 index 0000000..f4faf3f --- /dev/null +++ b/proxy/src/client/gssapi_gpm.h @@ -0,0 +1,162 @@ +/* + GSS-PROXY + + Copyright (C) 2011 Red Hat, Inc. + Copyright (C) 2011 Simo Sorce + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef _GSSAPI_GPM_H_ +#define _GSSAPI_GPM_H_ + +#include "config.h" +#include +#include +#include +#include +#include +#include "rpcgen/gp_rpc.h" +#include "rpcgen/gss_proxy.h" +#include "src/gp_common.h" +#include "src/gp_conv.h" + +int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res); +void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res); + +OM_uint32 gpm_release_name(OM_uint32 *minor_status, + gss_name_t *input_name); +OM_uint32 gpm_release_buffer(OM_uint32 *minor_status, + gss_buffer_t buffer); + +void gpm_save_status(gssx_status *status); +void gpm_save_internal_status(uint32_t err, char *err_str); + +OM_uint32 gpm_display_status(OM_uint32 *minor_status, + OM_uint32 status_value, + int status_type, + const gss_OID mech_type, + OM_uint32 *message_context, + gss_buffer_t status_string); + +OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_cred_id_t acceptor_cred_handle, + gss_buffer_t input_token_buffer, + gss_channel_bindings_t input_chan_bindings, + gss_name_t *src_name, + gss_OID *mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec, + gss_cred_id_t *delegated_cred_handle); + +OM_uint32 gpm_release_cred(OM_uint32 *minor_status, + gss_cred_id_t *cred_handle); + +OM_uint32 gpm_delete_sec_context(OM_uint32 *minor_status, + gss_ctx_id_t *context_handle, + gss_buffer_t output_token); + +OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status, + const gss_name_t desired_name, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec); + +OM_uint32 gpm_add_cred(OM_uint32 *minor_status, + const gss_cred_id_t input_cred_handle, + const gss_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec); + +OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set); +OM_uint32 gpm_inquire_names_for_mech(OM_uint32 *minor_status, + gss_OID mech_type, + gss_OID_set *mech_names); +OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_OID_set *mech_types); +OM_uint32 gpm_inquire_attrs_for_mech(OM_uint32 *minor_status, + gss_OID mech, + gss_OID_set *mech_attrs, + gss_OID_set *known_mech_attrs); +OM_uint32 gpm_inquire_saslname_for_mech(OM_uint32 *minor_status, + const gss_OID desired_mech, + gss_buffer_t sasl_mech_name, + gss_buffer_t mech_name, + gss_buffer_t mech_description); +OM_uint32 gpm_display_mech_attr(OM_uint32 *minor_status, + gss_const_OID mech_attr, + gss_buffer_t name, + gss_buffer_t short_desc, + gss_buffer_t long_desc); +OM_uint32 gpm_indicate_mechs_by_attrs(OM_uint32 *minor_status, + gss_const_OID_set desired_mech_attrs, + gss_const_OID_set except_mech_attrs, + gss_const_OID_set critical_mech_attrs, + gss_OID_set *mechs); + +OM_uint32 gpm_display_name(OM_uint32 *minor_status, + gss_name_t input_name, + gss_buffer_t output_name_buffer, + gss_OID *output_name_type); +OM_uint32 gpm_import_name(OM_uint32 *minor_status, + gss_buffer_t input_name_buffer, + gss_OID input_name_type, + gss_name_t *output_name); +OM_uint32 gpm_export_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_buffer_t exported_name); +OM_uint32 gpm_duplicate_name(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_name_t *dest_name); +OM_uint32 gpm_canonicalize_name(OM_uint32 *minor_status, + const gss_name_t input_name, + const gss_OID mech_type, + gss_name_t *output_name); +OM_uint32 gpm_inquire_name(OM_uint32 *minor_status, + gss_name_t name, + int *name_is_NM, + gss_OID *NM_mech, + gss_buffer_set_t *attrs); + +OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, + gss_cred_id_t claimant_cred_handle, + gss_ctx_id_t *context_handle, + gss_name_t target_name, + gss_OID mech_type, + OM_uint32 req_flags, + OM_uint32 time_req, + gss_channel_bindings_t input_cb, + gss_buffer_t input_token, + gss_OID *actual_mech_type, + gss_buffer_t output_token, + OM_uint32 *ret_flags, + OM_uint32 *time_rec); +#endif /* _GSSAPI_GPM_H_ */ diff --git a/proxy/src/mechglue/README b/proxy/src/mechglue/README index a97d511..9a191ef 100644 --- a/proxy/src/mechglue/README +++ b/proxy/src/mechglue/README @@ -1,7 +1,2 @@ -Eventually here we will have the mechglue to module to be loaded in various gssapi -implementations. - -At the moment we just need a conformant client in order to test the server -implementation. So will just implement a simple RFC2744 API. It will -be easy to turn this API into the mechglue SPI later on. - +This directory now contains the actual mechglue plugin, +client functions have been moved to the client directory. diff --git a/proxy/src/mechglue/gpm_accept_sec_context.c b/proxy/src/mechglue/gpm_accept_sec_context.c deleted file mode 100644 index d5eeb8a..0000000 --- a/proxy/src/mechglue/gpm_accept_sec_context.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" -#include "src/gp_conv.h" - -OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_cred_id_t acceptor_cred_handle, - gss_buffer_t input_token_buffer, - gss_channel_bindings_t input_chan_bindings, - gss_name_t *src_name, - gss_OID *mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec, - gss_cred_id_t *delegated_cred_handle) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_accept_sec_context *arg = &uarg.accept_sec_context; - gssx_res_accept_sec_context *res = &ures.accept_sec_context; - gssx_ctx *ctx = NULL; - gssx_name *name = NULL; - gss_OID_desc *mech = NULL; - gss_buffer_t outbuf = NULL; - uint32_t ret_maj; - int ret; - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - /* prepare proxy request */ - if (*context_handle) { - arg->context_handle = (gssx_ctx *)*context_handle; - } - - if (acceptor_cred_handle) { - arg->cred_handle = (gssx_cred *)acceptor_cred_handle; - } - - ret = gp_conv_buffer_to_gssx(input_token_buffer, &arg->input_token); - if (ret) { - goto done; - } - - if (input_chan_bindings) { - ret = gp_conv_cb_to_gssx_alloc(input_chan_bindings, &arg->input_cb); - if (ret) { - goto done; - } - } - - /* execute proxy request */ - ret = gpm_make_call(GSSX_ACCEPT_SEC_CONTEXT, &uarg, &ures); - if (ret) { - goto done; - } - - /* return values */ - if (mech_type) { - if (res->status.mech.octet_string_len) { - ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); - if (ret) { - goto done; - } - } - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - ret_maj = res->status.major_status; - *minor_status = res->status.minor_status; - ret = 0; - goto done; - } - - if (res->context_handle) { - ctx = res->context_handle; - /* we are stealing the delegated creds on success, so we do not want - * it to be freed by xdr_free */ - res->context_handle = NULL; - } - - if (src_name) { - ret = gp_copy_gssx_name_alloc(&ctx->src_name, &name); - if (ret) { - goto done; - } - } - - ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf); - if (ret) { - goto done; - } - - /* replace old ctx handle if any */ - if (*context_handle) { - xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)*context_handle); - free(*context_handle); - } - *context_handle = (gss_ctx_id_t)ctx; - if (mech_type) { - *mech_type = mech; - } - if (src_name) { - *src_name = (gss_name_t)name; - } - if (outbuf) { - *output_token = *outbuf; - free(outbuf); - } - if (ret_flags) { - *ret_flags = ctx->ctx_flags; - } - if (time_rec) { - *time_rec = ctx->lifetime; - } - - if (res->delegated_cred_handle) { - if (delegated_cred_handle) { - *delegated_cred_handle = (gss_cred_id_t)res->delegated_cred_handle; - } - /* we are stealing the delegated creds on success, so we do not want - * it to be freed by xdr_free */ - res->delegated_cred_handle = NULL; - } - - *minor_status = 0; - ret_maj = GSS_S_COMPLETE; - -done: - /* we are putting our copy of these structures in here, - * and do not want it to be freed by xdr_free */ - arg->context_handle = NULL; - arg->cred_handle = NULL; - gpm_free_xdrs(GSSX_ACCEPT_SEC_CONTEXT, &uarg, &ures); - if (ret) { - if (ctx) { - xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)ctx); - free(ctx); - } - if (name) { - xdr_free((xdrproc_t)xdr_gssx_name, (char *)name); - free(name); - } - if (mech) { - free(mech->elements); - free(mech); - } - if (outbuf) { - free(outbuf->value); - free(outbuf); - } - *minor_status = ret; - return GSS_S_FAILURE; - } - - return ret_maj; -} - diff --git a/proxy/src/mechglue/gpm_acquire_cred.c b/proxy/src/mechglue/gpm_acquire_cred.c deleted file mode 100644 index 8e9b010..0000000 --- a/proxy/src/mechglue/gpm_acquire_cred.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" - -static int gpmint_cred_to_actual_mechs(gssx_cred *c, gss_OID_set *a) -{ - gssx_cred_element *e; - gss_OID_set m = GSS_C_NO_OID_SET; - int i; - - - if (c->elements.elements_len) { - - m = malloc(sizeof(gss_OID_set_desc)); - if (!m) { - return ENOMEM; - } - m->elements = calloc(c->elements.elements_len, - sizeof(gss_OID_desc)); - if (!m->elements) { - free(m); - return ENOMEM; - } - - for (i = 0; i < c->elements.elements_len; i++) { - e = &c->elements.elements_val[i]; - - m->elements[i].elements = gp_memdup(e->mech.octet_string_val, - e->mech.octet_string_len); - if (!m->elements[i].elements) { - while (i > 0) { - i--; - free(m->elements[i].elements); - } - free(m->elements); - free(m); - return ENOMEM; - } - m->elements[i].length = e->mech.octet_string_len; - } - } - - *a = m; - return 0; -} - -OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status, - const gss_name_t desired_name, - OM_uint32 time_req, - const gss_OID_set desired_mechs, - gss_cred_usage_t cred_usage, - gss_cred_id_t *output_cred_handle, - gss_OID_set *actual_mechs, - OM_uint32 *time_rec) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_acquire_cred *arg = &uarg.acquire_cred; - gssx_res_acquire_cred *res = &ures.acquire_cred; - uint32_t ret_min; - uint32_t ret_maj; - int ret = 0; - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - if (output_cred_handle == NULL) { - ret_maj = GSS_S_FAILURE; - ret_min = EINVAL; - goto done; - } - - /* ignore call_ctx for now */ - - if (desired_name) { - arg->desired_name = calloc(1, sizeof(gssx_name)); - if (!arg->desired_name) { - ret_maj = GSS_S_FAILURE; - ret_min = ENOMEM; - goto done; - } - ret_maj = gp_conv_name_to_gssx(&ret_min, - desired_name, arg->desired_name); - if (ret_maj) { - goto done; - } - } - if (desired_mechs) { - ret = gp_conv_oid_set_to_gssx(desired_mechs, &arg->desired_mechs); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - } - arg->time_req = time_req; - arg->cred_usage = gp_conv_cred_usage_to_gssx(cred_usage); - - /* execute proxy request */ - ret = gpm_make_call(GSSX_ACQUIRE_CRED, &uarg, &ures); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - ret_min = res->status.minor_status; - ret_maj = res->status.major_status; - goto done; - } - - if (actual_mechs) { - ret = gpmint_cred_to_actual_mechs(res->output_cred_handle, - actual_mechs); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - } - - if (time_rec) { - gssx_cred_element *e; - uint32_t t = 0; - - if (res->output_cred_handle->elements.elements_len) { - e = &res->output_cred_handle->elements.elements_val[0]; - if (e->initiator_time_rec < e->acceptor_time_rec) { - t = e->initiator_time_rec; - } else { - t = e->acceptor_time_rec; - } - } - - *time_rec = t; - } - - /* we steal the cred handler here */ - *output_cred_handle = (gss_cred_id_t)res->output_cred_handle; - res->output_cred_handle = NULL; - ret_maj = GSS_S_COMPLETE; - ret_min = 0; - -done: - gpm_free_xdrs(GSSX_ACQUIRE_CRED, &uarg, &ures); - *minor_status = ret_min; - return ret_maj; -} - -OM_uint32 gpm_add_cred(OM_uint32 *minor_status, - const gss_cred_id_t input_cred_handle, - const gss_name_t desired_name, - const gss_OID desired_mech, - gss_cred_usage_t cred_usage, - OM_uint32 initiator_time_req, - OM_uint32 acceptor_time_req, - gss_cred_id_t *output_cred_handle, - gss_OID_set *actual_mechs, - OM_uint32 *initiator_time_rec, - OM_uint32 *acceptor_time_rec) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_acquire_cred *arg = &uarg.acquire_cred; - gssx_res_acquire_cred *res = &ures.acquire_cred; - gss_OID_set_desc mechs; - uint32_t ret_min; - uint32_t ret_maj; - int ret = 0; - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - /* ignore call_ctx for now */ - - if (input_cred_handle) { - arg->input_cred_handle = (gssx_cred *)input_cred_handle; - } - if (output_cred_handle != NULL) { - arg->add_cred_to_input_handle = true; - } - if (desired_name != GSS_C_NO_NAME) { - arg->desired_name = calloc(1, sizeof(gssx_name)); - if (!arg->desired_name) { - ret = ENOMEM; - goto done; - } - ret_maj = gp_conv_name_to_gssx(&ret_min, - desired_name, arg->desired_name); - if (ret_maj) { - goto done; - } - } - if (desired_mech != GSS_C_NO_OID) { - mechs.count = 1; - mechs.elements = desired_mech; - ret = gp_conv_oid_set_to_gssx(&mechs, &arg->desired_mechs); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - } - arg->cred_usage = gp_conv_cred_usage_to_gssx(cred_usage); - arg->initiator_time_req = initiator_time_req; - arg->acceptor_time_req = acceptor_time_req; - - /* execute proxy request */ - ret = gpm_make_call(GSSX_ACQUIRE_CRED, &uarg, &ures); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - ret_min = res->status.minor_status; - ret_maj = res->status.major_status; - goto done; - } - - if (actual_mechs) { - ret = gpmint_cred_to_actual_mechs(res->output_cred_handle, - actual_mechs); - if (ret) { - ret_maj = GSS_S_FAILURE; - ret_min = ret; - goto done; - } - } - - if (res->output_cred_handle->elements.elements_len) { - gssx_cred_element *e; - e = &res->output_cred_handle->elements.elements_val[0]; - if (initiator_time_rec) { - *initiator_time_rec = e->initiator_time_rec; - } - if (acceptor_time_rec) { - *acceptor_time_rec = e->initiator_time_rec; - } - } else { - if (initiator_time_rec) { - *initiator_time_rec = 0; - } - if (acceptor_time_rec) { - *acceptor_time_rec = 0; - } - } - - if (output_cred_handle) { - /* we steal the cred handler here */ - *output_cred_handle = (gss_cred_id_t)res->output_cred_handle; - res->output_cred_handle = NULL; - } - - ret_maj = GSS_S_COMPLETE; - ret_min = 0; - -done: - gpm_free_xdrs(GSSX_ACQUIRE_CRED, &uarg, &ures); - *minor_status = ret_min; - return ret_maj; -} diff --git a/proxy/src/mechglue/gpm_common.c b/proxy/src/mechglue/gpm_common.c deleted file mode 100644 index 16ea7d6..0000000 --- a/proxy/src/mechglue/gpm_common.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" -#include -#include -#include -#include -#include - -#define FRAGMENT_BIT (1 << 31) - -struct gpm_ctx { - pthread_mutex_t lock; - int fd; - int next_xid; -}; - -/* a single global struct is not particularly efficient, - * but will do for now */ -struct gpm_ctx gpm_global_ctx; - -pthread_once_t gpm_init_once_control = PTHREAD_ONCE_INIT; - -static void gpm_init_once(void) -{ - pthread_mutexattr_t attr; - unsigned int seedp; - - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - - pthread_mutex_init(&gpm_global_ctx.lock, &attr); - - gpm_global_ctx.fd = -1; - - seedp = time(NULL) + getpid() + pthread_self(); - gpm_global_ctx.next_xid = rand_r(&seedp); - - pthread_mutexattr_destroy(&attr); -} - -#define GP_SOCKET_NAME "gssproxy.socket" - -static int get_pipe_name(struct gpm_ctx *gpmctx, char *name) -{ - int ret; - - /* TODO: get socket name from config file */ - - ret = snprintf(name, PATH_MAX, "%s/%s", PIPE_PATH, GP_SOCKET_NAME); - if (ret < 0 || ret >= PATH_MAX) { - return ENAMETOOLONG; - } - - return 0; -} - -static int gpm_open_socket(struct gpm_ctx *gpmctx) -{ - struct sockaddr_un addr = {0}; - char name[PATH_MAX]; - int ret; - int fd = -1; - - ret = get_pipe_name(gpmctx, name); - if (ret) { - return ret; - } - - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, name, sizeof(addr.sun_path)-1); - addr.sun_path[sizeof(addr.sun_path)-1] = '\0'; - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) { - ret = errno; - goto done; - } - - ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); - -done: - if (ret) { - if (fd != -1) { - close(fd); - fd = -1; - } - } - gpmctx->fd = fd; - return ret; -} - -static void gpm_close_socket(struct gpm_ctx *gpmctx) -{ - int ret; - - do { - ret = close(gpmctx->fd); - /* in theory we should retry to close() on EINTR, - * but on same system the fd will be invalid after - * close() has been called, so closing again may - * cause a race with another thread that just happend - * to open an unrelated file descriptor. - * So until POSIX finally amends language around close() - * and at least the Linux kernel changes its behavior, - * it is better to risk a leak than closing an unrelated - * file descriptor */ - ret = 0; - } while (ret == EINTR); - - gpmctx->fd = -1; -} - -static int gpm_grab_sock(struct gpm_ctx *gpmctx) -{ - int ret; - - ret = pthread_mutex_lock(&gpmctx->lock); - if (ret) { - return ret; - } - - if (gpmctx->fd == -1) { - ret = gpm_open_socket(gpmctx); - } - - return ret; -} - -static int gpm_release_sock(struct gpm_ctx *gpmctx) -{ - return pthread_mutex_unlock(&gpmctx->lock); -} - -static int gpm_send_buffer(struct gpm_ctx *gpmctx, - char *buffer, uint32_t length) -{ - uint32_t size; - size_t wn; - size_t pos; - bool retry; - int ret; - - if (length > MAX_RPC_SIZE) { - return EINVAL; - } - - gpm_grab_sock(gpmctx); - - size = length | FRAGMENT_BIT; - size = htonl(size); - - retry = false; - do { - ret = 0; - do { - wn = write(gpmctx->fd, &size, sizeof(uint32_t)); - if (wn == -1) { - ret = errno; - } - } while (ret == EINTR); - if (wn != 4) { - /* reopen and retry once */ - if (retry == false) { - gpm_close_socket(gpmctx); - ret = gpm_open_socket(gpmctx); - if (ret == 0) { - retry = true; - continue; - } - } else { - ret = EIO; - } - goto done; - } - retry = false; - } while (retry); - - pos = 0; - while (length > pos) { - wn = write(gpmctx->fd, buffer + pos, length - pos); - if (wn == -1) { - if (errno == EINTR) { - continue; - } - ret = errno; - goto done; - } - pos += wn; - } - - ret = 0; - -done: - if (ret) { - /* on errors we can only close the fd and return */ - gpm_close_socket(gpmctx); - } - gpm_release_sock(gpmctx); - return ret; -} - -static int gpm_recv_buffer(struct gpm_ctx *gpmctx, - char *buffer, uint32_t *length) -{ - uint32_t size; - size_t rn; - size_t pos; - bool retry; - int ret; - - gpm_grab_sock(gpmctx); - - retry = false; - do { - ret = 0; - do { - rn = read(gpmctx->fd, &size, sizeof(uint32_t)); - if (rn == -1) { - ret = errno; - } - } while (ret == EINTR); - if (rn != 4) { - /* reopen and retry once */ - if (retry == false) { - gpm_close_socket(gpmctx); - ret = gpm_open_socket(gpmctx); - if (ret == 0) { - retry = true; - continue; - } - } else { - ret = EIO; - } - goto done; - } - retry = false; - } while (retry); - - *length = ntohl(size); - *length &= ~FRAGMENT_BIT; - - if (*length > MAX_RPC_SIZE) { - ret = EMSGSIZE; - goto done; - } - - pos = 0; - while (*length > pos) { - rn = read(gpmctx->fd, buffer + pos, *length - pos); - if (rn == -1) { - if (errno == EINTR) { - continue; - } - ret = errno; - goto done; - } - if (rn == 0) { - ret = EIO; - goto done; - } - pos += rn; - } - - ret = 0; - -done: - if (ret) { - /* on errors we can only close the fd and return */ - gpm_close_socket(gpmctx); - } - gpm_release_sock(gpmctx); - return ret; -} - -static int gpm_next_xid(struct gpm_ctx *gpmctx, uint32_t *xid) -{ - int ret; - - ret = gpm_grab_sock(gpmctx); - if (ret) { - goto done; - } - - if (gpmctx->next_xid < 0) { - *xid = 0; - gpmctx->next_xid = 1; - } else { - *xid = gpmctx->next_xid++; - } - -done: - gpm_release_sock(gpmctx); - return ret; -} - -static struct gpm_ctx *gpm_get_ctx(void) -{ - int ret; - - pthread_once(&gpm_init_once_control, gpm_init_once); - - ret = gpm_grab_sock(&gpm_global_ctx); - if (ret) { - return NULL; - } - - return &gpm_global_ctx; -} - -static void gpm_release_ctx(struct gpm_ctx *gpmctx) -{ - gpm_release_sock(gpmctx); -} - -OM_uint32 gpm_release_buffer(OM_uint32 *minor_status, - gss_buffer_t buffer) -{ - if (buffer != GSS_C_NO_BUFFER) { - if (buffer->value) { - free(buffer->value); - } - buffer->length = 0; - buffer->value = NULL; - } - return GSS_S_COMPLETE; -} - -struct gpm_rpc_fn_set { - xdrproc_t arg_fn; - xdrproc_t res_fn; -} gpm_xdr_set[] = { - { /* NULLPROC */ - (xdrproc_t)xdr_void, - (xdrproc_t)xdr_void, - }, - { /* GSSX_INDICATE_MECHS */ - (xdrproc_t)xdr_gssx_arg_indicate_mechs, - (xdrproc_t)xdr_gssx_res_indicate_mechs, - }, - { /* GSSX_GET_CALL_CONTEXT */ - (xdrproc_t)xdr_gssx_arg_get_call_context, - (xdrproc_t)xdr_gssx_res_get_call_context, - }, - { /* GSSX_IMPORT_AND_CANON_NAME */ - (xdrproc_t)xdr_gssx_arg_import_and_canon_name, - (xdrproc_t)xdr_gssx_res_import_and_canon_name, - }, - { /* GSSX_EXPORT_CRED */ - (xdrproc_t)xdr_gssx_arg_export_cred, - (xdrproc_t)xdr_gssx_res_export_cred, - }, - { /* GSSX_IMPORT_CRED */ - (xdrproc_t)xdr_gssx_arg_import_cred, - (xdrproc_t)xdr_gssx_res_import_cred, - }, - { /* GSSX_ACQUIRE_CRED */ - (xdrproc_t)xdr_gssx_arg_acquire_cred, - (xdrproc_t)xdr_gssx_res_acquire_cred, - }, - { /* GSSX_STORE_CRED */ - (xdrproc_t)xdr_gssx_arg_store_cred, - (xdrproc_t)xdr_gssx_res_store_cred, - }, - { /* GSSX_INIT_SEC_CONTEXT */ - (xdrproc_t)xdr_gssx_arg_init_sec_context, - (xdrproc_t)xdr_gssx_res_init_sec_context, - }, - { /* GSSX_ACCEPT_SEC_CONTEXT */ - (xdrproc_t)xdr_gssx_arg_accept_sec_context, - (xdrproc_t)xdr_gssx_res_accept_sec_context, - }, - { /* GSSX_RELEASE_HANDLE */ - (xdrproc_t)xdr_gssx_arg_release_handle, - (xdrproc_t)xdr_gssx_res_release_handle, - }, - { /* GSSX_GET_MIC */ - (xdrproc_t)xdr_gssx_arg_get_mic, - (xdrproc_t)xdr_gssx_res_get_mic, - }, - { /* GSSX_VERIFY */ - (xdrproc_t)xdr_gssx_arg_verify_mic, - (xdrproc_t)xdr_gssx_res_verify_mic, - }, - { /* GSSX_WRAP */ - (xdrproc_t)xdr_gssx_arg_wrap, - (xdrproc_t)xdr_gssx_res_wrap, - }, - { /* GSSX_UNWRAP */ - (xdrproc_t)xdr_gssx_arg_unwrap, - (xdrproc_t)xdr_gssx_res_unwrap, - }, - { /* GSSX_WRAP_SIZE_LIMIT */ - (xdrproc_t)xdr_gssx_arg_wrap_size_limit, - (xdrproc_t)xdr_gssx_res_wrap_size_limit, - } -}; - -int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) -{ - struct gpm_ctx *gpmctx; - gp_rpc_msg msg; - XDR xdr_call_ctx; - XDR xdr_reply_ctx; - char buffer[MAX_RPC_SIZE]; - uint32_t length; - uint32_t xid; - bool xdrok; - int ret; - - xdrmem_create(&xdr_call_ctx, buffer, MAX_RPC_SIZE, XDR_ENCODE); - xdrmem_create(&xdr_reply_ctx, buffer, MAX_RPC_SIZE, XDR_DECODE); - - memset(&msg, 0, sizeof(gp_rpc_msg)); - msg.header.type = GP_RPC_CALL; - msg.header.gp_rpc_msg_union_u.chdr.rpcvers = 2; - msg.header.gp_rpc_msg_union_u.chdr.prog = GSSPROXY; - msg.header.gp_rpc_msg_union_u.chdr.vers = GSSPROXYVERS; - msg.header.gp_rpc_msg_union_u.chdr.proc = proc; - msg.header.gp_rpc_msg_union_u.chdr.cred.flavor = GP_RPC_AUTH_NONE; - msg.header.gp_rpc_msg_union_u.chdr.cred.body.body_len = 0; - msg.header.gp_rpc_msg_union_u.chdr.cred.body.body_val = NULL; - msg.header.gp_rpc_msg_union_u.chdr.verf.flavor = GP_RPC_AUTH_NONE; - msg.header.gp_rpc_msg_union_u.chdr.verf.body.body_len = 0; - msg.header.gp_rpc_msg_union_u.chdr.verf.body.body_val = NULL; - - gpmctx = gpm_get_ctx(); - if (!gpmctx) { - return EINVAL; - } - - ret = gpm_next_xid(gpmctx, &xid); - if (ret) { - goto done; - } - msg.xid = xid; - - /* encode header */ - xdrok = xdr_gp_rpc_msg(&xdr_call_ctx, &msg); - if (!xdrok) { - ret = EINVAL; - goto done; - } - - /* encode data */ - xdrok = gpm_xdr_set[proc].arg_fn(&xdr_call_ctx, (char *)arg); - if (!xdrok) { - ret = EINVAL; - goto done; - } - - /* send to proxy */ - ret = gpm_send_buffer(gpmctx, buffer, xdr_getpos(&xdr_call_ctx)); - if (ret) { - goto done; - } - - /* receive answer */ - ret = gpm_recv_buffer(gpmctx, buffer, &length); - if (ret) { - goto done; - } - - /* decode header */ - xdrok = xdr_gp_rpc_msg(&xdr_reply_ctx, &msg); - if (!xdrok) { - ret = EINVAL; - goto done; - } - - if (msg.xid != xid || - msg.header.type != GP_RPC_REPLY || - msg.header.gp_rpc_msg_union_u.rhdr.status != GP_RPC_MSG_ACCEPTED || - msg.header.gp_rpc_msg_union_u.rhdr.gp_rpc_reply_header_u.accepted.reply_data.status != GP_RPC_SUCCESS) { - ret = EINVAL; - goto done; - } - - /* decode answer */ - xdrok = gpm_xdr_set[proc].res_fn(&xdr_reply_ctx, (char *)res); - if (!xdrok) { - ret = EINVAL; - } - -done: - xdr_free((xdrproc_t)xdr_gp_rpc_msg, (char *)&msg); - xdr_destroy(&xdr_call_ctx); - xdr_destroy(&xdr_reply_ctx); - gpm_release_ctx(gpmctx); - return ret; -} - -void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res) -{ - xdr_free(gpm_xdr_set[proc].arg_fn, (char *)arg); - xdr_free(gpm_xdr_set[proc].res_fn, (char *)res); -} diff --git a/proxy/src/mechglue/gpm_display_status.c b/proxy/src/mechglue/gpm_display_status.c deleted file mode 100644 index cc5e3cc..0000000 --- a/proxy/src/mechglue/gpm_display_status.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" - -__thread gssx_status *tls_last_status = NULL; - -/* Thread local storage for return status. - * FIXME: it's not the most portable construct, so may need fixing in future */ -void gpm_save_status(gssx_status *status) -{ - int ret; - - if (tls_last_status) { - xdr_free((xdrproc_t)xdr_gssx_status, (char *)tls_last_status); - free(tls_last_status); - } - - ret = gp_copy_gssx_status_alloc(status, &tls_last_status); - if (ret) { - /* make sure tls_last_status is zeored on error */ - tls_last_status = NULL; - } -} - -/* This funciton is used to record internal mech errors that are - * generated by the proxy client code */ -void gpm_save_internal_status(uint32_t err, char *err_str) -{ - gssx_status status; - - memset(&status, 0, sizeof(gssx_status)); - -#define STD_MAJ_ERROR_STR "Internal gssproxy error" - status.major_status = GSS_S_FAILURE; - status.major_status_string.utf8string_val = STD_MAJ_ERROR_STR; - status.major_status_string.utf8string_len = sizeof(STD_MAJ_ERROR_STR); - status.minor_status = err; - status.minor_status_string.utf8string_val = err_str; - status.minor_status_string.utf8string_len = strlen(err_str) + 1; - gpm_save_status(&status); -} - -OM_uint32 gpm_display_status(OM_uint32 *minor_status, - OM_uint32 status_value, - int status_type, - const gss_OID mech_type, - OM_uint32 *message_context, - gss_buffer_t status_string) -{ - utf8string tmp; - int ret; - - switch(status_type) { - case GSS_C_GSS_CODE: - if (tls_last_status && - tls_last_status->major_status == status_value && - tls_last_status->major_status_string.utf8string_len) { - ret = gp_copy_utf8string(&tls_last_status->major_status_string, - &tmp); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - status_string->value = tmp.utf8string_val; - status_string->length = tmp.utf8string_len; - *minor_status = 0; - return GSS_S_COMPLETE; - } else { - /* if we do not have it, make it clear */ - return GSS_S_UNAVAILABLE; - } - case GSS_C_MECH_CODE: - if (tls_last_status && - tls_last_status->minor_status == status_value && - tls_last_status->minor_status_string.utf8string_len) { - - if (*message_context) { - /* we do not support multiple messages for now */ - *minor_status = EINVAL; - return GSS_S_FAILURE; - } - - ret = gp_copy_utf8string(&tls_last_status->minor_status_string, - &tmp); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - status_string->value = tmp.utf8string_val; - status_string->length = tmp.utf8string_len; - } else { - /* if we do not have it, make it clear */ - return GSS_S_UNAVAILABLE; - } - *minor_status = 0; - return GSS_S_COMPLETE; - default: - *minor_status = EINVAL; - return GSS_S_BAD_STATUS; - } -} diff --git a/proxy/src/mechglue/gpm_import_and_canon_name.c b/proxy/src/mechglue/gpm_import_and_canon_name.c deleted file mode 100644 index 5301d60..0000000 --- a/proxy/src/mechglue/gpm_import_and_canon_name.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" - -OM_uint32 gpm_display_name(OM_uint32 *minor_status, - gss_name_t input_name, - gss_buffer_t output_name_buffer, - gss_OID *output_name_type) -{ - gss_buffer_desc input_name_buffer = GSS_C_EMPTY_BUFFER; - gssx_name *output_name = NULL; - gss_name_t tmp; - gssx_name *name; - uint32_t ret_maj; - uint32_t ret_min; - uint32_t discard; - int ret; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; - - if (!input_name) { - return GSS_S_CALL_INACCESSIBLE_READ; - } - if (!output_name_buffer) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - name = (gssx_name *)input_name; - - if (name->display_name.octet_string_len == 0) { - if (name->exported_name.octet_string_len == 0) { - return GSS_S_BAD_NAME; - } - - gp_conv_gssx_to_buffer(&name->exported_name, &input_name_buffer); - tmp = (gss_name_t)output_name; - - ret_maj = gpm_import_name(&ret_min, &input_name_buffer, - GSS_C_NT_EXPORT_NAME, &tmp); - if (ret_maj) { - goto done; - } - - /* steal display_name and name_type */ - name->display_name = output_name->display_name; - output_name->display_name.octet_string_len = 0; - output_name->display_name.octet_string_val = NULL; - name->name_type = output_name->name_type; - output_name->name_type.octet_string_len = 0; - output_name->name_type.octet_string_val = NULL; - } - - ret = gp_copy_gssx_to_buffer(&name->display_name, output_name_buffer); - if (ret) { - ret_min = ret; - ret_maj = GSS_S_FAILURE; - goto done; - } - - if (output_name_type) { - ret = gp_conv_gssx_to_oid_alloc(&name->name_type, output_name_type); - if (ret) { - gss_release_buffer(&discard, output_name_buffer); - ret_min = ret; - ret_maj = GSS_S_FAILURE; - goto done; - } - } - - ret_min = 0; - ret_maj = GSS_S_COMPLETE; - -done: - if (output_name) { - xdr_free((xdrproc_t)xdr_gssx_name, (char *)output_name); - free(output_name); - } - *minor_status = ret_min; - return ret_maj; -} - -OM_uint32 gpm_import_name(OM_uint32 *minor_status, - gss_buffer_t input_name_buffer, - gss_OID input_name_type, - gss_name_t *output_name) -{ - gssx_name *name; - int ret; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; - - if (!input_name_buffer || !input_name_type) { - return GSS_S_CALL_INACCESSIBLE_READ; - } - if (!output_name) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - /* ignore call_ctx for now */ - - name = calloc(1, sizeof(gssx_name)); - if (!name) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - - ret = gp_conv_buffer_to_gssx(input_name_buffer, &name->display_name); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - ret = gp_conv_oid_to_gssx(input_name_type, &name->name_type); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - - *output_name = (gss_name_t)name; - return GSS_S_COMPLETE; -} - -OM_uint32 gpm_export_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_buffer_t exported_name) -{ - gssx_name *name; - int ret; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; - - if (!input_name) { - return GSS_S_CALL_INACCESSIBLE_READ; - } - - name = (gssx_name *)input_name; - - if (name->exported_name.octet_string_len == 0) { - return GSS_S_NAME_NOT_MN; - } - - ret = gp_copy_gssx_to_buffer(&name->exported_name, exported_name); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - return GSS_S_COMPLETE; -} - -OM_uint32 gpm_duplicate_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_name_t *dest_name) -{ - gssx_name *name; - gssx_name *namecopy; - int ret; - - name = (gssx_name *)input_name; - - ret = gp_copy_gssx_name_alloc(name, &namecopy); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - *dest_name = (gss_name_t)namecopy; - return GSS_S_COMPLETE; -} - -OM_uint32 gpm_canonicalize_name(OM_uint32 *minor_status, - const gss_name_t input_name, - const gss_OID mech_type, - gss_name_t *output_name) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_import_and_canon_name *arg = &uarg.import_and_canon_name; - gssx_res_import_and_canon_name *res = &ures.import_and_canon_name; - uint32_t ret_maj; - uint32_t ret_min; - gssx_name *name; - int ret; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - *minor_status = 0; - - if (!input_name || !mech_type) { - return GSS_S_CALL_INACCESSIBLE_READ; - } - if (!output_name) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - name = (gssx_name *)input_name; - - memset(arg, 0, sizeof(gssx_arg_import_and_canon_name)); - memset(res, 0, sizeof(gssx_res_import_and_canon_name)); - - /* ignore call_ctx for now */ - - ret = gp_copy_gssx_name(name, &arg->input_name); - if (ret) { - goto done; - } - ret = gp_conv_oid_to_gssx(mech_type, &arg->mech); - if (ret) { - goto done; - } - - /* execute proxy request */ - ret = gpm_make_call(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures); - if (ret) { - goto done; - } - - ret_min = res->status.minor_status; - ret_maj = res->status.major_status; - if (res->status.major_status) { - gpm_save_status(&res->status); - ret = 0; - goto done; - } - - /* steal output_name */ - *output_name = (gss_name_t)res->output_name; - res->output_name = NULL; - -done: - if (ret) { - ret_min = ret; - ret_maj = GSS_S_FAILURE; - } - gpm_free_xdrs(GSSX_IMPORT_AND_CANON_NAME, &uarg, &ures); - *minor_status = ret_min; - return ret_maj; -} - -OM_uint32 gpm_inquire_name(OM_uint32 *minor_status, - gss_name_t name, - int *name_is_MN, - gss_OID *MN_mech, - gss_buffer_set_t *attrs) -{ - gss_buffer_set_t xattrs = GSS_C_NO_BUFFER_SET; - gssx_name *xname; - uint32_t i; - int ret; - - *minor_status = 0; - xname = (gssx_name *)name; - - if (xname->exported_name.octet_string_len != 0) { - if (name_is_MN != NULL) { - *name_is_MN = 1; - } - } - - if (MN_mech != NULL) { - ret = gp_conv_gssx_to_oid_alloc(&xname->name_type, MN_mech); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - } - - if (xname->name_attributes.name_attributes_len != 0) { - xattrs = calloc(1, sizeof(gss_buffer_set_desc)); - if (!xattrs) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - xattrs->count = xname->name_attributes.name_attributes_len; - xattrs->elements = calloc(xattrs->count, sizeof(gss_buffer_desc)); - if (!xattrs->elements) { - free(xattrs); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - for (i = 0; i < xattrs->count; i++) { - ret = gp_copy_gssx_to_buffer( - &xname->name_attributes.name_attributes_val[i].attr, - &xattrs->elements[i]); - if (ret) { - for (--i; i >= 0; i--) { - free(xattrs->elements[i].value); - } - free(xattrs->elements); - free(xattrs); - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - } - } - *attrs = xattrs; - - return GSS_S_COMPLETE; -} - -OM_uint32 gpm_release_name(OM_uint32 *minor_status, - gss_name_t *input_name) -{ - *minor_status = 0; - - if (*input_name != GSS_C_NO_NAME) { - xdr_free((xdrproc_t)xdr_gssx_name, (char *)(*input_name)); - free(*input_name); - *input_name = GSS_C_NO_NAME; - } - return GSS_S_COMPLETE; -} diff --git a/proxy/src/mechglue/gpm_indicate_mechs.c b/proxy/src/mechglue/gpm_indicate_mechs.c deleted file mode 100644 index 693e588..0000000 --- a/proxy/src/mechglue/gpm_indicate_mechs.c +++ /dev/null @@ -1,734 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" -#include - -struct gpm_mech_info { - gss_OID mech; - gss_OID_set name_types; - gss_OID_set mech_attrs; - gss_OID_set known_mech_attrs; - gss_OID_set cred_options; - gss_OID_set sec_ctx_options; - gss_buffer_t saslname_sasl_mech_name; - gss_buffer_t saslname_mech_name; - gss_buffer_t saslname_mech_desc; -}; - -struct gpm_mech_attr { - gss_OID attr; - gss_buffer_t name; - gss_buffer_t short_desc; - gss_buffer_t long_desc; -}; - -struct gpm_mechs { - bool initialized; - - gss_OID_set mech_set; - - size_t info_len; - struct gpm_mech_info *info; - - size_t desc_len; - struct gpm_mech_attr *desc; -}; - -pthread_mutex_t global_mechs_lock = PTHREAD_MUTEX_INITIALIZER; -pthread_once_t indicate_mechs_once = PTHREAD_ONCE_INIT; -struct gpm_mechs global_mechs = { - .initialized = false, - .mech_set = GSS_C_NO_OID_SET, - .info_len = 0, - .info = NULL, - .desc_len = 0, - .desc = NULL, -}; - -static uint32_t gpm_copy_gss_OID_set(uint32_t *minor_status, - gss_OID_set oldset, gss_OID_set *newset) -{ - gss_OID_set n; - uint32_t ret_maj; - uint32_t ret_min; - int i; - - ret_maj = gss_create_empty_oid_set(&ret_min, &n); - if (ret_maj) { - *minor_status = ret_min; - return ret_maj; - } - - for (i = 0; i < oldset->count; i++) { - ret_maj = gss_add_oid_set_member(&ret_min, &oldset->elements[i], &n); - if (ret_maj) { - *minor_status = ret_min; - gss_release_oid_set(&ret_min, &n); - return ret_maj; - } - } - - *newset = n; - *minor_status = 0; - return GSS_S_COMPLETE; -} - -static uint32_t gpm_copy_gss_buffer(uint32_t *minor_status, - gss_buffer_t oldbuf, - gss_buffer_t newbuf) -{ - if (!oldbuf || oldbuf->length == 0) { - newbuf->value = NULL; - newbuf->length = 0; - *minor_status = 0; - return GSS_S_COMPLETE; - } - - newbuf->value = malloc(oldbuf->length); - if (!newbuf->value) { - *minor_status = ENOMEM; - return GSS_S_FAILURE; - } - memcpy(newbuf->value, oldbuf->value, oldbuf->length); - newbuf->length = oldbuf->length; - - *minor_status = 0; - return GSS_S_COMPLETE; -} - -static bool gpm_equal_oids(gss_const_OID a, gss_const_OID b) -{ - int ret; - - if (a->length == b->length) { - ret = memcmp(a->elements, b->elements, a->length); - if (ret == 0) { - return true; - } - } - - return false; -} - -static void gpmint_indicate_mechs(void) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_indicate_mechs *arg = &uarg.indicate_mechs; - gssx_res_indicate_mechs *res = &ures.indicate_mechs; - struct gpm_mech_info *gi; - struct gpm_mech_attr *ga; - gssx_mech_info *mi; - gssx_mech_attr *ma; - uint32_t discard; - uint32_t ret_min; - uint32_t ret_maj = 0; - int ret = 0; - int i; - - memset(arg, 0, sizeof(gssx_arg_indicate_mechs)); - memset(res, 0, sizeof(gssx_res_indicate_mechs)); - - /* ignore call_ctx for now */ - - /* execute proxy request */ - ret = gpm_make_call(GSSX_INDICATE_MECHS, &uarg, &ures); - if (ret) { - goto done; - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - ret_min = res->status.minor_status; - ret_maj = res->status.major_status; - ret = 0; - goto done; - } - - ret_maj = gss_create_empty_oid_set(&ret_min, &global_mechs.mech_set); - if (ret_maj) { - goto done; - } - - global_mechs.info = calloc(res->mechs.mechs_len, - sizeof(struct gpm_mech_info)); - if (!global_mechs.info) { - ret_maj = GSS_S_FAILURE; - ret_min = ENOMEM; - goto done; - } - - for (i = 0; i < res->mechs.mechs_len; i++) { - mi = &res->mechs.mechs_val[i]; - gi = &global_mechs.info[i]; - - ret = gp_conv_gssx_to_oid_alloc(&mi->mech, - &gi->mech); - if (ret) { - goto done; - } - ret_maj = gss_add_oid_set_member(&ret_min, gi->mech, - &global_mechs.mech_set); - if (ret_maj) { - goto done; - } - - ret = gp_conv_gssx_to_oid_set(&mi->name_types, - &gi->name_types); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_oid_set(&mi->mech_attrs, - &gi->mech_attrs); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_oid_set(&mi->known_mech_attrs, - &gi->known_mech_attrs); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_oid_set(&mi->cred_options, - &gi->cred_options); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_oid_set(&mi->sec_ctx_options, - &gi->sec_ctx_options); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_sasl_mech_name, - &gi->saslname_sasl_mech_name); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_mech_name, - &gi->saslname_mech_name); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&mi->saslname_mech_desc, - &gi->saslname_mech_desc); - if (ret) { - goto done; - } - } - global_mechs.info_len = res->mechs.mechs_len; - - global_mechs.desc = calloc(res->mech_attr_descs.mech_attr_descs_len, - sizeof(struct gpm_mech_attr)); - if (!global_mechs.desc) { - goto done; - } - - for (i = 0; i < res->mech_attr_descs.mech_attr_descs_len; i++) { - ma = &res->mech_attr_descs.mech_attr_descs_val[i]; - ga = &global_mechs.desc[i]; - - ret = gp_conv_gssx_to_oid_alloc(&ma->attr, &ga->attr); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&ma->name, &ga->name); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&ma->short_desc, &ga->short_desc); - if (ret) { - goto done; - } - ret = gp_conv_gssx_to_buffer_alloc(&ma->long_desc, &ga->long_desc); - if (ret) { - goto done; - } - } - global_mechs.desc_len = res->mech_attr_descs.mech_attr_descs_len; - - global_mechs.initialized = true; - -done: - if (ret || ret_maj) { - for (i = 0; i < global_mechs.desc_len; i++) { - ga = &global_mechs.desc[i]; - gss_release_oid(&discard, &ga->attr); - gss_release_buffer(&discard, ga->name); - gss_release_buffer(&discard, ga->short_desc); - gss_release_buffer(&discard, ga->long_desc); - } - free(global_mechs.desc); - global_mechs.desc = NULL; - for (i = 0; i < global_mechs.info_len; i++) { - gi = &global_mechs.info[i]; - gss_release_oid(&discard, &gi->mech); - gss_release_oid_set(&discard, &gi->name_types); - gss_release_oid_set(&discard, &gi->mech_attrs); - gss_release_oid_set(&discard, &gi->known_mech_attrs); - gss_release_oid_set(&discard, &gi->cred_options); - gss_release_oid_set(&discard, &gi->sec_ctx_options); - gss_release_buffer(&discard, gi->saslname_sasl_mech_name); - gss_release_buffer(&discard, gi->saslname_mech_name); - gss_release_buffer(&discard, gi->saslname_mech_desc); - } - free(global_mechs.info); - global_mechs.info = NULL; - gss_release_oid_set(&discard, &global_mechs.mech_set); - } - gpm_free_xdrs(GSSX_INDICATE_MECHS, &uarg, &ures); -} - -static int gpmint_init_global_mechs(void) -{ - pthread_once(&indicate_mechs_once, gpmint_indicate_mechs); - - if (!global_mechs.initialized) { - /* this is quite a corner case. It means the pthread_once() call - * failed for some reason. In this case we need to use a mutex */ - - pthread_mutex_lock(&global_mechs_lock); - /* need to recheck once we acquired the lock, to avoid redoing - * if we were stuck after another thread that already did it */ - if (!global_mechs.initialized) { - gpmint_indicate_mechs(); - } - pthread_mutex_unlock(&global_mechs_lock); - - if (!global_mechs.initialized) { - /* if still it is not initialized, give up */ - return EIO; - } - } - - return 0; -} - -OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set) -{ - uint32_t ret_min; - uint32_t ret_maj; - int ret; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!mech_set) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret= gpmint_init_global_mechs(); - if (ret) { - *minor_status = ret; - return GSS_S_FAILURE; - } - - ret_maj = gpm_copy_gss_OID_set(&ret_min, - global_mechs.mech_set, - mech_set); - *minor_status = ret_min; - return ret_maj; -} - -OM_uint32 gpm_inquire_names_for_mech(OM_uint32 *minor_status, - gss_OID mech_type, - gss_OID_set *mech_names) -{ - uint32_t ret_min; - uint32_t ret_maj; - int i; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!mech_names) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - for (i = 0; i < global_mechs.info_len; i++) { - if (!gpm_equal_oids(global_mechs.info[i].mech, mech_type)) { - continue; - } - ret_maj = gpm_copy_gss_OID_set(&ret_min, - global_mechs.info[i].name_types, - mech_names); - *minor_status = ret_min; - return ret_maj; - } - - *minor_status = 0; - return GSS_S_BAD_MECH; -} - -OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_OID_set *mech_types) -{ - uint32_t ret_min; - uint32_t ret_maj; - uint32_t discard; - gssx_name *name; - gss_OID name_type = GSS_C_NO_OID; - int present; - int i; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!input_name || !mech_types) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - name = (gssx_name *)input_name; - ret_min = gp_conv_gssx_to_oid_alloc(&name->name_type, &name_type); - if (ret_min) { - ret_maj = GSS_S_FAILURE; - goto done; - } - - ret_maj = gss_create_empty_oid_set(&ret_min, mech_types); - if (ret_maj) { - goto done; - } - - for (i = 0; i < global_mechs.info_len; i++) { - ret_maj = gss_test_oid_set_member(&ret_min, name_type, - global_mechs.info[i].name_types, - &present); - if (ret_maj) { - /* skip on error */ - continue; - } - if (present) { - ret_maj = gss_add_oid_set_member(&ret_min, - global_mechs.info[i].mech, - mech_types); - } - if (ret_maj) { - goto done; - } - } - -done: - gss_release_oid(&discard, &name_type); - if (ret_maj) { - gss_release_oid_set(&discard, mech_types); - *minor_status = ret_min; - return ret_maj; - } - *minor_status = 0; - return GSS_S_COMPLETE; -} - -OM_uint32 gpm_inquire_attrs_for_mech(OM_uint32 *minor_status, - gss_OID mech, - gss_OID_set *mech_attrs, - gss_OID_set *known_mech_attrs) -{ - uint32_t ret_min; - uint32_t ret_maj; - uint32_t discard; - int i; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!mech_attrs || !known_mech_attrs) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - for (i = 0; i < global_mechs.info_len; i++) { - if (!gpm_equal_oids(global_mechs.info[i].mech, mech)) { - continue; - } - ret_maj = gpm_copy_gss_OID_set(&ret_min, - global_mechs.info[i].mech_attrs, - mech_attrs); - if (ret_maj) { - *minor_status = ret_min; - return ret_maj; - } - ret_maj = gpm_copy_gss_OID_set(&ret_min, - global_mechs.info[i].known_mech_attrs, - known_mech_attrs); - if (ret_maj) { - gss_release_oid_set(&discard, known_mech_attrs); - } - *minor_status = ret_min; - return ret_maj; - } - - *minor_status = 0; - return GSS_S_BAD_MECH; -} - -OM_uint32 gpm_inquire_saslname_for_mech(OM_uint32 *minor_status, - const gss_OID desired_mech, - gss_buffer_t sasl_mech_name, - gss_buffer_t mech_name, - gss_buffer_t mech_description) -{ - uint32_t ret_min; - uint32_t ret_maj; - uint32_t discard; - int i; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!sasl_mech_name || !mech_name || !mech_description) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - for (i = 0; i < global_mechs.info_len; i++) { - if (!gpm_equal_oids(global_mechs.info[i].mech, desired_mech)) { - continue; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.info[i].saslname_sasl_mech_name, - sasl_mech_name); - if (ret_maj) { - *minor_status = ret_min; - return ret_maj; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.info[i].saslname_mech_name, - mech_name); - if (ret_maj) { - gss_release_buffer(&discard, sasl_mech_name); - *minor_status = ret_min; - return ret_maj; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.info[i].saslname_mech_desc, - mech_description); - if (ret_maj) { - gss_release_buffer(&discard, sasl_mech_name); - gss_release_buffer(&discard, mech_name); - } - *minor_status = ret_min; - return ret_maj; - } - - *minor_status = 0; - return GSS_S_BAD_MECH; -} - -OM_uint32 gpm_display_mech_attr(OM_uint32 *minor_status, - gss_const_OID mech_attr, - gss_buffer_t name, - gss_buffer_t short_desc, - gss_buffer_t long_desc) -{ - uint32_t ret_min; - uint32_t ret_maj; - uint32_t discard; - int i; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!name || !short_desc || !long_desc) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - for (i = 0; i < global_mechs.desc_len; i++) { - if (!gpm_equal_oids(global_mechs.desc[i].attr, mech_attr)) { - continue; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.desc[i].name, - name); - if (ret_maj) { - *minor_status = ret_min; - return ret_maj; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.desc[i].short_desc, - short_desc); - if (ret_maj) { - gss_release_buffer(&discard, name); - *minor_status = ret_min; - return ret_maj; - } - ret_maj = gpm_copy_gss_buffer(&ret_min, - global_mechs.desc[i].long_desc, - long_desc); - if (ret_maj) { - gss_release_buffer(&discard, name); - gss_release_buffer(&discard, short_desc); - } - *minor_status = ret_min; - return ret_maj; - } - - *minor_status = 0; - return GSS_S_BAD_MECH; -} - -OM_uint32 gpm_indicate_mechs_by_attrs(OM_uint32 *minor_status, - gss_const_OID_set desired_mech_attrs, - gss_const_OID_set except_mech_attrs, - gss_const_OID_set critical_mech_attrs, - gss_OID_set *mechs) -{ - uint32_t ret_min; - uint32_t ret_maj; - uint32_t discard; - int present; - int i, j; - - if (!minor_status) { - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - if (!mechs) { - *minor_status = 0; - return GSS_S_CALL_INACCESSIBLE_WRITE; - } - - ret_min = gpmint_init_global_mechs(); - if (ret_min) { - *minor_status = ret_min; - return GSS_S_FAILURE; - } - - ret_maj = gss_create_empty_oid_set(&ret_min, mechs); - if (ret_maj) { - *minor_status = ret_min; - return ret_maj; - } - - for (i = 0; i < global_mechs.info_len; i++) { - if (desired_mech_attrs != GSS_C_NO_OID_SET) { - for (j = 0; j < desired_mech_attrs->count; j++) { - ret_maj = gss_test_oid_set_member(&ret_min, - &desired_mech_attrs->elements[j], - global_mechs.info[i].mech_attrs, - &present); - if (ret_maj) { - /* skip in case of errors */ - break; - } - if (!present) { - break; - } - } - /* if not desired skip */ - if (j != desired_mech_attrs->count) { - continue; - } - } - if (except_mech_attrs != GSS_C_NO_OID_SET) { - for (j = 0; j < except_mech_attrs->count; j++) { - ret_maj = gss_test_oid_set_member(&ret_min, - &except_mech_attrs->elements[j], - global_mechs.info[i].mech_attrs, - &present); - if (ret_maj) { - /* continue in case of errors */ - continue; - } - if (present) { - break; - } - } - /* if excepted skip */ - if (j == desired_mech_attrs->count) { - continue; - } - } - if (critical_mech_attrs != GSS_C_NO_OID_SET) { - for (j = 0; j < critical_mech_attrs->count; j++) { - ret_maj = gss_test_oid_set_member(&ret_min, - &critical_mech_attrs->elements[j], - global_mechs.info[i].known_mech_attrs, - &present); - if (ret_maj) { - /* skip in case of errors */ - break; - } - if (!present) { - break; - } - } - /* if not known skip */ - if (j != desired_mech_attrs->count) { - continue; - } - } - - /* passes all tests, add to list */ - ret_maj = gss_add_oid_set_member(&ret_min, - global_mechs.info[i].mech, mechs); - if (ret_maj) { - goto done; - } - } - -done: - if (ret_maj) { - gss_release_oid_set(&discard, mechs); - *minor_status = ret_min; - return ret_maj; - } - *minor_status = 0; - return GSS_S_COMPLETE; -} - diff --git a/proxy/src/mechglue/gpm_init_sec_context.c b/proxy/src/mechglue/gpm_init_sec_context.c deleted file mode 100644 index 0769363..0000000 --- a/proxy/src/mechglue/gpm_init_sec_context.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" -#include "src/gp_conv.h" - -OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, - gss_cred_id_t claimant_cred_handle, - gss_ctx_id_t *context_handle, - gss_name_t target_name, - gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - gss_channel_bindings_t input_cb, - gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_init_sec_context *arg = &uarg.init_sec_context; - gssx_res_init_sec_context *res = &ures.init_sec_context; - gssx_ctx *ctx = NULL; - gss_OID_desc *mech = NULL; - gss_buffer_t outbuf = NULL; - uint32_t ret_maj = GSS_S_COMPLETE; - uint32_t ret_min = 0; - int ret; - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - /* prepare proxy request */ - if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) { - arg->cred_handle = (gssx_cred *)claimant_cred_handle; - } - - if (*context_handle) { - arg->context_handle = (gssx_ctx *)*context_handle; - } - - if (target_name != GSS_C_NO_NAME) { - arg->target_name = (gssx_name *)target_name; - } - - ret = gp_conv_oid_to_gssx(mech_type, &arg->mech_type); - if (ret) { - goto done; - } - - if (input_cb) { - ret = gp_conv_cb_to_gssx_alloc(input_cb, &arg->input_cb); - if (ret) { - goto done; - } - } - - if (input_token != GSS_C_NO_BUFFER) { - ret = gp_conv_buffer_to_gssx_alloc(input_token, &arg->input_token); - if (ret) { - goto done; - } - } - - /* execute proxy request */ - ret = gpm_make_call(GSSX_INIT_SEC_CONTEXT, &uarg, &ures); - if (ret) { - gpm_save_internal_status(ret, strerror(ret)); - goto done; - } - - /* return values */ - if (actual_mech_type) { - if (res->status.mech.octet_string_len) { - ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech); - if (ret) { - goto done; - } - } - } - - 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 - * it to be freed by xdr_free */ - 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; - } - -done: - if (ret != 0) { - ret_min = ret; - ret_maj = GSS_S_FAILURE; - } - - /* we are putting our copy of these structures in here, - * and do not want it to be freed by xdr_free */ - arg->context_handle = NULL; - arg->cred_handle = NULL; - arg->target_name = NULL; - gpm_free_xdrs(GSSX_INIT_SEC_CONTEXT, &uarg, &ures); - - if (ret_maj == GSS_S_COMPLETE || ret_maj == GSS_S_CONTINUE_NEEDED) { - /* replace old ctx handle if any */ - if (*context_handle) { - xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)*context_handle); - free(*context_handle); - } - *context_handle = (gss_ctx_id_t)ctx; - if (actual_mech_type) { - *actual_mech_type = mech; - } - if (outbuf) { - *output_token = *outbuf; - free(outbuf); - } - if (ret_flags) { - *ret_flags = ctx->ctx_flags; - } - if (time_rec) { - *time_rec = ctx->lifetime; - } - } else { - if (ctx) { - xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)ctx); - free(ctx); - } - if (mech) { - free(mech->elements); - free(mech); - } - if (outbuf) { - free(outbuf->value); - free(outbuf); - } - } - - *minor_status = ret_min; - return ret_maj; -} diff --git a/proxy/src/mechglue/gpm_release_handle.c b/proxy/src/mechglue/gpm_release_handle.c deleted file mode 100644 index 010c148..0000000 --- a/proxy/src/mechglue/gpm_release_handle.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "gssapi_gpm.h" - -OM_uint32 gpm_release_cred(OM_uint32 *minor_status, - gss_cred_id_t *cred_handle) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_release_handle *arg = &uarg.release_handle; - gssx_res_release_handle *res = &ures.release_handle; - gssx_cred *r; - int ret; - - if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { - return 0; - } - - r = (gssx_cred *)(*cred_handle); - - if (!r->needs_release) { - ret = GSS_S_COMPLETE; - goto done; - } - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - /* ignore call_ctx for now */ - - arg->cred_handle.handle_type = GSSX_C_HANDLE_CRED; - arg->cred_handle.gssx_handle_u.cred_info = *r; - - /* execute proxy request */ - ret = gpm_make_call(GSSX_RELEASE_HANDLE, &uarg, &ures); - if (ret) { - *minor_status = ret; - ret = GSS_S_FAILURE; - goto rel_done; - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - *minor_status = res->status.minor_status; - ret = res->status.major_status; - } - -rel_done: - /* we passed in our copy by value, so clean out to avoid double frees */ - memset(&arg->cred_handle.gssx_handle_u.cred_info, 0, sizeof(gssx_cred)); - gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); -done: - xdr_free((xdrproc_t)xdr_gssx_cred, (char *)r); - return ret; -} - -OM_uint32 gpm_delete_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_buffer_t output_token) -{ - union gp_rpc_arg uarg; - union gp_rpc_res ures; - gssx_arg_release_handle *arg = &uarg.release_handle; - gssx_res_release_handle *res = &ures.release_handle; - gssx_ctx *r; - int ret; - - if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) { - return 0; - } - - r = (gssx_ctx *)(*context_handle); - - if (!r->needs_release) { - ret = GSS_S_COMPLETE; - goto done; - } - - memset(&uarg, 0, sizeof(union gp_rpc_arg)); - memset(&ures, 0, sizeof(union gp_rpc_res)); - - /* ignore call_ctx for now */ - - arg->cred_handle.handle_type = GSSX_C_HANDLE_SEC_CTX; - arg->cred_handle.gssx_handle_u.sec_ctx_info = *r; - - /* execute proxy request */ - ret = gpm_make_call(GSSX_RELEASE_HANDLE, &uarg, &ures); - if (ret) { - *minor_status = ret; - ret = GSS_S_FAILURE; - goto rel_done; - } - - if (res->status.major_status) { - gpm_save_status(&res->status); - *minor_status = res->status.minor_status; - ret = res->status.major_status; - } - -rel_done: - /* we passed in our copy by value, so clean out to avoid double frees */ - memset(&arg->cred_handle.gssx_handle_u.sec_ctx_info, 0, sizeof(gssx_cred)); - gpm_free_xdrs(GSSX_RELEASE_HANDLE, &uarg, &ures); -done: - xdr_free((xdrproc_t)xdr_gssx_ctx, (char *)r); - return ret; -} diff --git a/proxy/src/mechglue/gssapi_gpm.h b/proxy/src/mechglue/gssapi_gpm.h deleted file mode 100644 index f4faf3f..0000000 --- a/proxy/src/mechglue/gssapi_gpm.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - GSS-PROXY - - Copyright (C) 2011 Red Hat, Inc. - Copyright (C) 2011 Simo Sorce - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#ifndef _GSSAPI_GPM_H_ -#define _GSSAPI_GPM_H_ - -#include "config.h" -#include -#include -#include -#include -#include -#include "rpcgen/gp_rpc.h" -#include "rpcgen/gss_proxy.h" -#include "src/gp_common.h" -#include "src/gp_conv.h" - -int gpm_make_call(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res); -void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res); - -OM_uint32 gpm_release_name(OM_uint32 *minor_status, - gss_name_t *input_name); -OM_uint32 gpm_release_buffer(OM_uint32 *minor_status, - gss_buffer_t buffer); - -void gpm_save_status(gssx_status *status); -void gpm_save_internal_status(uint32_t err, char *err_str); - -OM_uint32 gpm_display_status(OM_uint32 *minor_status, - OM_uint32 status_value, - int status_type, - const gss_OID mech_type, - OM_uint32 *message_context, - gss_buffer_t status_string); - -OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_cred_id_t acceptor_cred_handle, - gss_buffer_t input_token_buffer, - gss_channel_bindings_t input_chan_bindings, - gss_name_t *src_name, - gss_OID *mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec, - gss_cred_id_t *delegated_cred_handle); - -OM_uint32 gpm_release_cred(OM_uint32 *minor_status, - gss_cred_id_t *cred_handle); - -OM_uint32 gpm_delete_sec_context(OM_uint32 *minor_status, - gss_ctx_id_t *context_handle, - gss_buffer_t output_token); - -OM_uint32 gpm_acquire_cred(OM_uint32 *minor_status, - const gss_name_t desired_name, - OM_uint32 time_req, - const gss_OID_set desired_mechs, - gss_cred_usage_t cred_usage, - gss_cred_id_t *output_cred_handle, - gss_OID_set *actual_mechs, - OM_uint32 *time_rec); - -OM_uint32 gpm_add_cred(OM_uint32 *minor_status, - const gss_cred_id_t input_cred_handle, - const gss_name_t desired_name, - const gss_OID desired_mech, - gss_cred_usage_t cred_usage, - OM_uint32 initiator_time_req, - OM_uint32 acceptor_time_req, - gss_cred_id_t *output_cred_handle, - gss_OID_set *actual_mechs, - OM_uint32 *initiator_time_rec, - OM_uint32 *acceptor_time_rec); - -OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set); -OM_uint32 gpm_inquire_names_for_mech(OM_uint32 *minor_status, - gss_OID mech_type, - gss_OID_set *mech_names); -OM_uint32 gpm_inquire_mechs_for_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_OID_set *mech_types); -OM_uint32 gpm_inquire_attrs_for_mech(OM_uint32 *minor_status, - gss_OID mech, - gss_OID_set *mech_attrs, - gss_OID_set *known_mech_attrs); -OM_uint32 gpm_inquire_saslname_for_mech(OM_uint32 *minor_status, - const gss_OID desired_mech, - gss_buffer_t sasl_mech_name, - gss_buffer_t mech_name, - gss_buffer_t mech_description); -OM_uint32 gpm_display_mech_attr(OM_uint32 *minor_status, - gss_const_OID mech_attr, - gss_buffer_t name, - gss_buffer_t short_desc, - gss_buffer_t long_desc); -OM_uint32 gpm_indicate_mechs_by_attrs(OM_uint32 *minor_status, - gss_const_OID_set desired_mech_attrs, - gss_const_OID_set except_mech_attrs, - gss_const_OID_set critical_mech_attrs, - gss_OID_set *mechs); - -OM_uint32 gpm_display_name(OM_uint32 *minor_status, - gss_name_t input_name, - gss_buffer_t output_name_buffer, - gss_OID *output_name_type); -OM_uint32 gpm_import_name(OM_uint32 *minor_status, - gss_buffer_t input_name_buffer, - gss_OID input_name_type, - gss_name_t *output_name); -OM_uint32 gpm_export_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_buffer_t exported_name); -OM_uint32 gpm_duplicate_name(OM_uint32 *minor_status, - const gss_name_t input_name, - gss_name_t *dest_name); -OM_uint32 gpm_canonicalize_name(OM_uint32 *minor_status, - const gss_name_t input_name, - const gss_OID mech_type, - gss_name_t *output_name); -OM_uint32 gpm_inquire_name(OM_uint32 *minor_status, - gss_name_t name, - int *name_is_NM, - gss_OID *NM_mech, - gss_buffer_set_t *attrs); - -OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status, - gss_cred_id_t claimant_cred_handle, - gss_ctx_id_t *context_handle, - gss_name_t target_name, - gss_OID mech_type, - OM_uint32 req_flags, - OM_uint32 time_req, - gss_channel_bindings_t input_cb, - gss_buffer_t input_token, - gss_OID *actual_mech_type, - gss_buffer_t output_token, - OM_uint32 *ret_flags, - OM_uint32 *time_rec); -#endif /* _GSSAPI_GPM_H_ */ diff --git a/proxy/tests/cli_srv_comm.c b/proxy/tests/cli_srv_comm.c index 2d7d3eb..a866e8a 100644 --- a/proxy/tests/cli_srv_comm.c +++ b/proxy/tests/cli_srv_comm.c @@ -40,7 +40,7 @@ #include "src/gp_rpc_process.h" #include "src/gp_conv.h" #include "src/gp_debug.h" -#include "src/mechglue/gssapi_gpm.h" +#include "src/client/gssapi_gpm.h" #include "popt.h" int gp_send_buffer(int fd, char *buf, uint32_t len) -- cgit