From 1dd267f3196295c7883985e9dac6c5c5afda2d3f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 6 Feb 2012 17:49:09 -0500 Subject: Implement server side import_and_canon_name() Also fix name conversion functions, to properly handle exporting/importing names. --- proxy/Makefile.am | 1 + proxy/src/gp_conv.c | 83 +++++++++++++++++++++++----- proxy/src/gp_conv.h | 1 + proxy/src/gp_rpc_import_and_canon_name.c | 92 ++++++++++++++++++++++++++++++++ proxy/src/gp_rpc_process.c | 4 -- 5 files changed, 164 insertions(+), 17 deletions(-) create mode 100644 proxy/src/gp_rpc_import_and_canon_name.c diff --git a/proxy/Makefile.am b/proxy/Makefile.am index ee82efd..7e2ce6a 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -109,6 +109,7 @@ gssproxy_SOURCES = \ src/gp_rpc_release_handle.c \ src/gp_rpc_acquire_cred.c \ src/gp_rpc_indicate_mechs.c \ + src/gp_rpc_import_and_canon_name.c \ src/gssproxy.c accept_context_SOURCES = \ diff --git a/proxy/src/gp_conv.c b/proxy/src/gp_conv.c index 56516ca..5136b91 100644 --- a/proxy/src/gp_conv.c +++ b/proxy/src/gp_conv.c @@ -317,14 +317,19 @@ int gp_conv_name_to_gssx(gss_name_t in, gssx_name *out) } ret_maj = gss_export_name(&ret_min, in, &exported_name); - if (ret_maj) { - ret = -1; - goto done; - } - - ret = gp_conv_buffer_to_gssx(&exported_name, &out->exported_name); - if (ret) { - goto done; + if (ret_maj == 0) { + ret = gp_conv_buffer_to_gssx(&exported_name, &out->exported_name); + if (ret) { + goto done; + } + } else { + /* In case the error is GSS_S_NAME_NOT_MN the name was not + * canonicalized but that is ok we simply do not export the name + * in this case */ + if (ret_maj != GSS_S_NAME_NOT_MN) { + ret = -1; + goto done; + } } /* out->exported_composite_name */ @@ -341,17 +346,69 @@ done: return ret; } +int gp_conv_name_to_gssx_alloc(gss_name_t in, gssx_name **out) +{ + gssx_name *o; + int ret; + + o = calloc(1, sizeof(gssx_name)); + if (!o) { + return ENOMEM; + } + + ret = gp_conv_name_to_gssx(in, o); + + if (ret) { + free(o); + } + + *out = o; + return ret; +} + int gp_conv_gssx_to_name(gssx_name *in, gss_name_t *out) { - uint32_t ret_min; + gss_buffer_t input_name = GSS_C_NO_BUFFER; + gss_OID name_type = GSS_C_NO_OID; gss_buffer_desc name_buffer; - gss_OID_desc name_type; + uint32_t ret_maj; + uint32_t ret_min; + int ret; + + if (in->display_name.octet_string_len != 0) { + /* ok we have a display name. + * In this case always import and canonicalize it so we can + * safely export the name using the original form, even if we + * already have exported_name */ + ret = gp_conv_gssx_to_buffer_alloc(&in->display_name, &input_name); + if (ret) { + goto done; + } + ret = gp_conv_gssx_to_oid_alloc(&in->name_type, &name_type); + if (ret) { + goto done; + } - gp_conv_gssx_to_oid(&in->name_type, &name_type); + ret_maj = gss_import_name(&ret_min, input_name, name_type, out); + if (ret_maj) { + ret = ret_maj; + goto done; + } + } else { + gp_conv_gssx_to_buffer(&in->exported_name, &name_buffer); - gp_conv_gssx_to_buffer(&in->exported_name, &name_buffer); + ret_maj = gss_import_name(&ret_min, &name_buffer, + GSS_C_NT_EXPORT_NAME, out); + if (ret_maj) { + ret = ret_maj; + goto done; + } + } - return gss_import_name(&ret_min, &name_buffer, &name_type, out); +done: + gss_release_buffer(&ret_min, input_name); + gss_release_oid(&ret_min, &name_type); + return ret; } int gp_conv_ctx_id_to_gssx(gss_ctx_id_t *in, gssx_ctx *out) diff --git a/proxy/src/gp_conv.h b/proxy/src/gp_conv.h index 02c8c52..82228b7 100644 --- a/proxy/src/gp_conv.h +++ b/proxy/src/gp_conv.h @@ -54,6 +54,7 @@ int gp_conv_err_to_gssx_string(uint32_t status, int type, gss_OID oid, utf8string *ret_str); int gp_conv_name_to_gssx(gss_name_t in, gssx_name *out); +int gp_conv_name_to_gssx_alloc(gss_name_t in, gssx_name **out); int gp_conv_gssx_to_name(gssx_name *in, gss_name_t *out); int gp_conv_ctx_id_to_gssx(gss_ctx_id_t *in, gssx_ctx *out); diff --git a/proxy/src/gp_rpc_import_and_canon_name.c b/proxy/src/gp_rpc_import_and_canon_name.c new file mode 100644 index 0000000..be25f95 --- /dev/null +++ b/proxy/src/gp_rpc_import_and_canon_name.c @@ -0,0 +1,92 @@ +/* + 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 "gp_rpc_process.h" + + +/* NOTE: Very Important, before ever touching this function please read + * carefully RFC 2744 section 3.10 "Names". + * I am not kidding, if you hav not read it, go back and do it now, or do not + * touch this function */ + +int gp_import_and_canon_name(struct gssproxy_ctx *gpctx, + union gp_rpc_arg *arg, + union gp_rpc_res *res) +{ + struct gssx_arg_import_and_canon_name *icna; + struct gssx_res_import_and_canon_name *icnr; + gss_OID mech = GSS_C_NO_OID; + gss_name_t import_name = GSS_C_NO_NAME; + gss_name_t output_name = GSS_C_NO_NAME; + uint32_t ret_maj = 0; + uint32_t ret_min = 0; + int ret; + + icna = &arg->import_and_canon_name; + icnr = &res->import_and_canon_name; + + if (icna->input_name.display_name.octet_string_len == 0 && + icna->input_name.exported_name.octet_string_len == 0) { + ret = EINVAL; + goto done; + } + + ret = gp_conv_gssx_to_name(&icna->input_name, &import_name); + if (ret) { + goto done; + } + + if (icna->mech.octet_string_len != 0) { + + ret = gp_conv_gssx_to_oid_alloc(&icna->mech, &mech); + if (ret) { + goto done; + } + + ret_maj = gss_canonicalize_name(&ret_min, import_name, + mech, &output_name); + if (ret_maj) { + goto done; + } + + ret = gp_conv_name_to_gssx_alloc(output_name, &icnr->output_name); + } else { + ret = gp_conv_name_to_gssx_alloc(import_name, &icnr->output_name); + } + + /* TODO: check also icna->input_name.exported_composite_name */ + /* TODO: icna->name_attributes */ + +done: + if (!ret) { + ret = gp_conv_status_to_gssx(&icna->call_ctx, + ret_maj, ret_min, GSS_C_NO_OID, + &icnr->status); + } + gss_release_oid(&ret_min, &mech); + gss_release_name(&ret_min, &import_name); + gss_release_name(&ret_min, &output_name); + return ret; +} diff --git a/proxy/src/gp_rpc_process.c b/proxy/src/gp_rpc_process.c index ae170eb..ed125b8 100644 --- a/proxy/src/gp_rpc_process.c +++ b/proxy/src/gp_rpc_process.c @@ -374,10 +374,6 @@ int gp_get_call_context(gp_exec_std_args) { return 0; } -int gp_import_and_canon_name(gp_exec_std_args) -{ - return 0; -} int gp_export_cred(gp_exec_std_args) { return 0; -- cgit