summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2012-01-22 01:14:30 -0500
committerSimo Sorce <simo@redhat.com>2012-01-25 00:15:46 -0500
commit3da72377d3b34a46389769808eb2458467254618 (patch)
tree68b9ca85c35473559b38d531fec2d7877a1ba2d7
parent765fae6e702248c050f8eae403db44025953ca8a (diff)
downloadgss-proxy-3da72377d3b34a46389769808eb2458467254618.tar.gz
gss-proxy-3da72377d3b34a46389769808eb2458467254618.tar.xz
gss-proxy-3da72377d3b34a46389769808eb2458467254618.zip
Add gssx conversion functions
-rw-r--r--proxy/Makefile.am1
-rw-r--r--proxy/src/gp_conv.c335
-rw-r--r--proxy/src/gp_conv.h53
3 files changed, 389 insertions, 0 deletions
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 0510eb7..d8f2562 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -92,6 +92,7 @@ gssproxy_SOURCES = \
src/gp_workers.c \
$(GP_RPCGEN_OBJ) \
src/gp_rpc_process.c \
+ src/gp_conv.c \
src/gssproxy.c
gssproxy_LDADD = \
diff --git a/proxy/src/gp_conv.c b/proxy/src/gp_conv.c
new file mode 100644
index 0000000..18d7e78
--- /dev/null
+++ b/proxy/src/gp_conv.c
@@ -0,0 +1,335 @@
+/*
+ GSS-PROXY
+
+ Copyright (C) 2011 Red Hat, Inc.
+ Copyright (C) 2011 Simo Sorce <simo.sorce@redhat.com>
+
+ 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 "config.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include "gp_conv.h"
+
+int gp_conv_octet_string(size_t length, void *value, octet_string *out)
+{
+ out->octet_string_val = malloc(length);
+ if (!out->octet_string_val) {
+ return ENOMEM;
+ }
+ memcpy(out->octet_string_val, value, length);
+ out->octet_string_len = length;
+ return 0;
+}
+
+void gp_conv_gssx_to_oid(gssx_OID *in, gss_OID out)
+{
+ out->length = in->octet_string_len;
+ out->elements = (void *)in->octet_string_val;
+}
+
+int gp_conv_oid_to_gssx(gss_OID in, gssx_OID *out)
+{
+ return gp_conv_octet_string(in->length, in->elements, out);
+}
+
+void gp_conv_gssx_to_buffer(gssx_buffer *in, gss_buffer_t out)
+{
+ out->length = in->octet_string_len;
+ out->value = (void *)in->octet_string_val;
+}
+
+int gp_conv_buffer_to_gssx(gss_buffer_t in, gssx_buffer *out)
+{
+ return gp_conv_octet_string(in->length, in->value, out);
+}
+
+void gp_conv_gssx_to_cb(gssx_cb *in, gss_channel_bindings_t out)
+{
+ out->initiator_addrtype = in->initiator_addrtype;
+ gp_conv_gssx_to_buffer(&in->initiator_address, &out->initiator_address);
+ out->acceptor_addrtype = in->acceptor_addrtype;
+ gp_conv_gssx_to_buffer(&in->acceptor_address, &out->acceptor_address);
+ gp_conv_gssx_to_buffer(&in->application_data, &out->application_data);
+}
+
+int gp_conv_cb_to_gssx(gss_channel_bindings_t in, gssx_cb *out)
+{
+ int ret;
+
+ out->initiator_addrtype = in->initiator_addrtype;
+ ret = gp_conv_buffer_to_gssx(&in->initiator_address,
+ &out->initiator_address);
+ if (ret) {
+ goto done;
+ }
+ out->acceptor_addrtype = in->acceptor_addrtype;
+ ret = gp_conv_buffer_to_gssx(&in->acceptor_address,
+ &out->acceptor_address);
+ if (ret) {
+ goto done;
+ }
+ ret = gp_conv_buffer_to_gssx(&in->application_data,
+ &out->application_data);
+ if (ret) {
+ goto done;
+ }
+
+ ret = 0;
+
+done:
+ if (ret) {
+ xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->initiator_address);
+ xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->acceptor_address);
+ xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->application_data);
+ }
+ return ret;
+}
+
+gssx_cred_usage gp_conv_cred_usage_to_gssx(gss_cred_usage_t in)
+{
+ switch (in) {
+ case GSS_C_BOTH:
+ return GSSX_C_BOTH;
+ case GSS_C_INITIATE:
+ return GSSX_C_INITIATE;
+ case GSS_C_ACCEPT:
+ return GSSX_C_ACCEPT;
+ default:
+ return 0;
+ }
+}
+
+gss_cred_usage_t gp_conv_gssx_to_cred_usage(gssx_cred_usage in)
+{
+ switch (in) {
+ case GSSX_C_BOTH:
+ return GSS_C_BOTH;
+ case GSSX_C_INITIATE:
+ return GSS_C_INITIATE;
+ case GSSX_C_ACCEPT:
+ return GSS_C_ACCEPT;
+ default:
+ return 0;
+ }
+}
+
+int gp_conv_err_to_gssx_string(uint32_t status, int type, gss_OID oid,
+ utf8string *ret_str)
+{
+ uint32_t ret_maj;
+ uint32_t ret_min;
+ uint32_t msg_ctx;
+ gss_buffer_desc gssbuf;
+ char *str, *t;
+ int ret;
+
+ msg_ctx = 0;
+ str = NULL;
+ do {
+ ret_maj = gss_display_status(&ret_min,
+ status, type, oid,
+ &msg_ctx, &gssbuf);
+ if (ret_maj == 0) {
+ if (str) {
+ ret = asprintf(&t, "%s, %s", str, (char *)gssbuf.value);
+ if (ret == -1) {
+ ret_maj = ENOMEM;
+ } else {
+ free(str);
+ str = t;
+ }
+ } else {
+ str = strdup((char *)gssbuf.value);
+ if (!str) {
+ ret_maj = ENOMEM;
+ }
+ }
+ gss_release_buffer(&ret_min, &gssbuf);
+ }
+ if (ret_maj) {
+ goto done;
+ }
+ } while (msg_ctx);
+
+ ret_str->utf8string_len = strlen(str + 1);
+ ret_str->utf8string_val = str;
+
+done:
+ free(str);
+ return ret_maj;
+}
+
+int gp_conv_name_to_gssx(gss_name_t in, gssx_name *out)
+{
+ uint32_t ret_maj;
+ uint32_t ret_min;
+ gss_buffer_desc name_buffer;
+ gss_OID name_type;
+ gss_buffer_desc exported_name;
+ int ret;
+
+ ret_maj = gss_display_name(&ret_min, in, &name_buffer, &name_type);
+ if (ret_maj) {
+ return -1;
+ }
+
+ out->display_name = calloc(1, sizeof(gssx_buffer));
+ if (!out->display_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = gp_conv_buffer_to_gssx(&name_buffer, out->display_name);
+ if (ret) {
+ goto done;
+ }
+ ret = gp_conv_oid_to_gssx(name_type, &out->name_type);
+ if (ret) {
+ goto done;
+ }
+
+ ret_maj = gss_export_name(&ret_min, in, &exported_name);
+ if (ret_maj) {
+ ret = -1;
+ goto done;
+ }
+
+ out->exported_name.exported_name_len = 1;
+ out->exported_name.exported_name_val = calloc(1, sizeof(gssx_buffer));
+ if (!out->exported_name.exported_name_val) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = gp_conv_buffer_to_gssx(&exported_name,
+ out->exported_name.exported_name_val);
+ if (ret) {
+ goto done;
+ }
+
+ /* out->exported_composite_name */
+ /* out->name_attributes */
+
+done:
+ gss_release_buffer(&ret_min, &name_buffer);
+ gss_release_buffer(&ret_min, &exported_name);
+ if (ret) {
+ if (out->display_name) {
+ xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)out->display_name);
+ free(out->display_name);
+ }
+ xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&out->name_type);
+ if (out->exported_name.exported_name_val) {
+ xdr_free((xdrproc_t)xdr_gssx_buffer,
+ (char *)out->exported_name.exported_name_val);
+ free(out->exported_name.exported_name_val);
+ }
+ }
+ return ret;
+}
+
+int gp_conv_ctx_id_to_gssx(gss_ctx_id_t *in, gssx_ctx *out)
+{
+ uint32_t ret_maj;
+ uint32_t ret_min;
+ gss_name_t src_name = GSS_C_NO_NAME;
+ gss_name_t targ_name = GSS_C_NO_NAME;
+ gss_buffer_desc export_buffer = GSS_C_EMPTY_BUFFER;
+ uint32_t lifetime_rec;
+ gss_OID mech_type;
+ uint32_t ctx_flags;
+ int is_locally_initiated;
+ int is_open;
+ int ret;
+
+ /* TODO: For mechs that need multiple roundtrips to complete */
+ /* out->state; */
+
+ /* we do not need the client to release anything nutil we handle state */
+ out->needs_release = false;
+
+ ret_maj = gss_inquire_context(&ret_min, *in, &src_name, &targ_name,
+ &lifetime_rec, &mech_type, &ctx_flags,
+ &is_locally_initiated, &is_open);
+ if (ret_maj) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = gp_conv_oid_to_gssx(mech_type, &out->mech);
+ if (ret) {
+ goto done;
+ }
+
+ ret = gp_conv_name_to_gssx(src_name, &out->src_name);
+ if (ret) {
+ goto done;
+ }
+
+ ret = gp_conv_name_to_gssx(targ_name, &out->targ_name);
+ if (ret) {
+ goto done;
+ }
+
+ out->lifetime = lifetime_rec;
+
+ out->ctx_flags = ctx_flags;
+
+ if (is_locally_initiated) {
+ out->locally_initiated = true;
+ }
+
+ if (is_open) {
+ out->open = true;
+ }
+
+ /* note: once converted the original context token is not usable anymore,
+ * so this must be the last call to use it */
+ out->exported_context_token = calloc(1, sizeof(octet_string));
+ if (!out->exported_context_token) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret_maj = gss_export_sec_context(&ret_min, in, &export_buffer);
+ if (ret_maj) {
+ ret = EINVAL;
+ goto done;
+ }
+ ret = gp_conv_buffer_to_gssx(&export_buffer, out->exported_context_token);
+ if (ret) {
+ goto done;
+ }
+
+ /* Leave this empty, used only on the way in for init_sec_context */
+ /* out->gssx_option */
+
+done:
+ gss_release_name(&ret_min, &src_name);
+ gss_release_name(&ret_min, &targ_name);
+ gss_release_buffer(&ret_min, &export_buffer);
+ if (ret) {
+ xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&out->mech);
+ xdr_free((xdrproc_t)xdr_gssx_name, (char *)&out->src_name);
+ xdr_free((xdrproc_t)xdr_gssx_name, (char *)&out->targ_name);
+ }
+ return ret;
+}
+
diff --git a/proxy/src/gp_conv.h b/proxy/src/gp_conv.h
new file mode 100644
index 0000000..e364df6
--- /dev/null
+++ b/proxy/src/gp_conv.h
@@ -0,0 +1,53 @@
+/*
+ GSS-PROXY
+
+ Copyright (C) 2011 Red Hat, Inc.
+ Copyright (C) 2011 Simo Sorce <simo.sorce@redhat.com>
+
+ 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 _GSS_CONV_H_
+#define _GSS_CONV_H_
+
+#include <gssapi/gssapi.h>
+#include "rpcgen/gss_proxy.h"
+
+int gp_conv_octet_string(size_t length, void *value, octet_string *out);
+
+void gp_conv_gssx_to_oid(gssx_OID *in, gss_OID out);
+int gp_conv_oid_to_gssx(gss_OID in, gssx_OID *out);
+
+void gp_conv_gssx_to_buffer(gssx_buffer *in, gss_buffer_t out);
+int gp_conv_buffer_to_gssx(gss_buffer_t in, gssx_buffer *out);
+
+void gp_conv_gssx_to_cb(gssx_cb *in, gss_channel_bindings_t out);
+int gp_conv_cb_to_gssx(gss_channel_bindings_t in, gssx_cb *out);
+
+gssx_cred_usage gp_conv_cred_usage_to_gssx(gss_cred_usage_t in);
+gss_cred_usage_t gp_conv_gssx_to_cred_usage(gssx_cred_usage in);
+
+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_ctx_id_to_gssx(gss_ctx_id_t *in, gssx_ctx *out);
+
+#endif /* _GSS_CONV_H_ */