From c4bc72a768c9cb7ffa7c9495e16b3ad25c49d8c8 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 22 Nov 2009 21:45:06 +0000 Subject: add support for Heimdal's gss_context_query_attributes() git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/gssextras@23312 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/generic/gssapi_ext.h | 19 +++++++++ src/lib/gssapi/generic/gssapi_generic.c | 2 + src/lib/gssapi/krb5/gssapiP_krb5.h | 10 +++++ src/lib/gssapi/krb5/gssapi_krb5.c | 61 +++++++++++++++++++++++++++++ src/lib/gssapi/krb5/inq_context.c | 48 +++++++++++++++++++++++ src/lib/gssapi/libgssapi_krb5.exports | 2 + src/lib/gssapi/mechglue/g_initialize.c | 1 + src/lib/gssapi/mechglue/g_inq_context_oid.c | 43 ++++++++++++++++++++ src/lib/gssapi/mechglue/mglueP.h | 9 +++++ src/lib/gssapi/spnego/gssapiP_spnego.h | 10 +++++ src/lib/gssapi/spnego/spnego_mech.c | 19 +++++++++ 11 files changed, 224 insertions(+) (limited to 'src/lib') diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h index 1221677..cc5b516 100644 --- a/src/lib/gssapi/generic/gssapi_ext.h +++ b/src/lib/gssapi/generic/gssapi_ext.h @@ -254,6 +254,25 @@ OM_uint32 KRB5_CALLCONV gss_release_iov_buffer gss_iov_buffer_desc *, /* iov */ int); /* iov_count */ +typedef struct gss_context_stream_sizes_struct { + size_t header; + size_t trailer; + size_t max_msg_size; + size_t buffers; + size_t blocksize; +} gss_context_stream_sizes; + +GSS_DLLIMP extern gss_OID GSS_C_ATTR_STREAM_SIZES; + +OM_uint32 KRB5_CALLCONV gss_context_query_attributes +( + OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_OID, /* attribute */ + void *, /* data */ + size_t /* len */ +); + /* * Protocol transition */ diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c index 8b1e4de..4973784 100644 --- a/src/lib/gssapi/generic/gssapi_generic.c +++ b/src/lib/gssapi/generic/gssapi_generic.c @@ -122,6 +122,7 @@ static const gss_OID_desc const_oids[] = { /* GSS_C_INQ_SSPI_SESSION_KEY 1.2.840.113554.1.2.2.5.5 */ {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"}, + {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"}, }; /* Here are the constants which point to the static structure above. @@ -152,3 +153,4 @@ GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME = oids+6; gss_OID gss_nt_exported_name = oids+6; GSS_DLLIMP gss_OID GSS_C_INQ_SSPI_SESSION_KEY = oids+7; +GSS_DLLIMP gss_OID GSS_C_ATTR_STREAM_SIZES = oids+8; diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index fae3c83..792b49b 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1052,6 +1052,16 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *, const gss_OID, gss_buffer_set_t *); +#define GSS_KRB5_CONTEXT_ATTR_STREAM_SIZES_LENGTH 10 +#define GSS_KRB5_CONTEXT_ATTR_STREAM_SIZES "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03" + +OM_uint32 +gss_krb5int_context_query_stream_sizes(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_oid, + void *data, + size_t len); + #ifdef _GSS_STATIC_LINK int gss_krb5int_lib_init(void); void gss_krb5int_lib_fini(void); diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index a6a9fad..780dde4 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -624,6 +624,66 @@ krb5_gssspi_mech_invoke (OM_uint32 *minor_status, return GSS_S_UNAVAILABLE; } +/* + * gss_context_query_attributes() methods + */ +static struct { + gss_OID_desc oid; + OM_uint32 (*func)(OM_uint32 *, const gss_ctx_id_t, const gss_OID, void *, size_t); +} krb5_gss_context_query_attributes_ops[] = { + { + {GSS_KRB5_CONTEXT_ATTR_STREAM_SIZES_LENGTH, GSS_KRB5_CONTEXT_ATTR_STREAM_SIZES}, + gss_krb5int_context_query_stream_sizes + }, +}; + +static OM_uint32 +krb5_gss_context_query_attributes(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + void *data, + size_t len) +{ + krb5_gss_ctx_id_rec *ctx; + size_t i; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + *minor_status = 0; + + if (desired_object == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (data == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + memset(data, 0, len); + + if (!kg_validate_ctx_id(context_handle)) + return GSS_S_NO_CONTEXT; + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + if (!ctx->established) + return GSS_S_NO_CONTEXT; + + for (i = 0; i < sizeof(krb5_gss_context_query_attributes_ops)/ + sizeof(krb5_gss_context_query_attributes_ops[0]); i++) { + if (g_OID_prefix_equal(desired_object, &krb5_gss_context_query_attributes_ops[i].oid)) { + return (*krb5_gss_context_query_attributes_ops[i].func)(minor_status, + context_handle, + desired_object, + data, + len); + } + } + + *minor_status = EINVAL; + + return GSS_S_UNAVAILABLE; +} + static struct gss_config krb5_mechanism = { { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID }, NULL, @@ -694,6 +754,7 @@ static struct gss_config krb5_mechanism = { krb5_gss_map_name_to_any, krb5_gss_release_any_name_mapping, krb5_gss_pseudo_random, + krb5_gss_context_query_attributes, }; diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c index 5cec4b9..52cf8c5 100644 --- a/src/lib/gssapi/krb5/inq_context.c +++ b/src/lib/gssapi/krb5/inq_context.c @@ -300,3 +300,51 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); } + +OM_uint32 +gss_krb5int_context_query_stream_sizes(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_oid, + void *data, + size_t len) +{ + const krb5_gss_ctx_id_t ctx = (const krb5_gss_ctx_id_t)context_handle; + gss_context_stream_sizes *sizes = (gss_context_stream_sizes *)data; + gss_iov_buffer_desc iov[4]; + OM_uint32 major_status; + OM_uint32 max_input_size; + + if (len != sizeof(*sizes)) { + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + + iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; + iov[1].type = GSS_IOV_BUFFER_TYPE_TRAILER; + iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; + iov[2].buffer.length = 1; + iov[2].buffer.value = ""; + iov[3].type = GSS_IOV_BUFFER_TYPE_PADDING; + + major_status = kg_seal_iov_length(minor_status, context_handle, + 1, GSS_C_QOP_DEFAULT, NULL, + iov, sizeof(iov)); + if (GSS_ERROR(major_status)) + return major_status; + + sizes->header = iov[0].buffer.length; + sizes->trailer = iov[1].buffer.length; + sizes->buffers = 0; + sizes->blocksize = 1 + iov[3].buffer.length; + + major_status = krb5_gss_wrap_size_limit(minor_status, context_handle, + 1, GSS_C_QOP_DEFAULT, + (OM_uint32)-1, &max_input_size); + if (GSS_ERROR(major_status)) + return major_status; + + sizes->max_msg_size = max_input_size; + + return GSS_S_COMPLETE; +} + diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports index de063da..94175c8 100644 --- a/src/lib/gssapi/libgssapi_krb5.exports +++ b/src/lib/gssapi/libgssapi_krb5.exports @@ -1,3 +1,4 @@ +GSS_C_ATTR_STREAM_SIZES GSS_C_INQ_SSPI_SESSION_KEY GSS_C_NT_ANONYMOUS GSS_C_NT_EXPORT_NAME @@ -17,6 +18,7 @@ gss_add_oid_set_member gss_canonicalize_name gss_compare_name gss_complete_auth_token +gss_context_query_attributes gss_context_time gss_create_empty_buffer_set gss_create_empty_oid_set diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c index e01d174..2f29693 100644 --- a/src/lib/gssapi/mechglue/g_initialize.c +++ b/src/lib/gssapi/mechglue/g_initialize.c @@ -775,6 +775,7 @@ build_dynamicMech(void *dl, const gss_OID mech_type) GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_release_any_name_mapping); /* RFC 4401 (introduced in 1.8) */ GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_pseudo_random); + GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_context_query_attributes); assert(mech_type != GSS_C_NO_OID); diff --git a/src/lib/gssapi/mechglue/g_inq_context_oid.c b/src/lib/gssapi/mechglue/g_inq_context_oid.c index 469aa70..f15c419 100644 --- a/src/lib/gssapi/mechglue/g_inq_context_oid.c +++ b/src/lib/gssapi/mechglue/g_inq_context_oid.c @@ -69,3 +69,46 @@ gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, return GSS_S_BAD_MECH; } + +OM_uint32 KRB5_CALLCONV +gss_context_query_attributes (OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + void *data, + size_t len) +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = gssint_get_mechanism (ctx->mech_type); + + if (mech != NULL) { + if (mech->gss_inquire_sec_context_by_oid != NULL) { + status = mech->gss_context_query_attributes(minor_status, + ctx->internal_ctx_id, + desired_object, + data, + len); + if (status != GSS_S_COMPLETE) + map_error(minor_status, mech); + } else + status = GSS_S_UNAVAILABLE; + + return status; + } + + return GSS_S_BAD_MECH; +} diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index 517ca48..57e56f3 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -583,6 +583,15 @@ typedef struct gss_config { gss_buffer_t /* prf_out */ /* */); + OM_uint32 (*gss_context_query_attributes) + ( + OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_OID, /* OID */ + void *, /* data */ + size_t /* length */ + /* */ ); + } *gss_mechanism; /* This structure MUST NOT be used by any code outside libgss */ diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h index 80c23e2..2961d40 100644 --- a/src/lib/gssapi/spnego/gssapiP_spnego.h +++ b/src/lib/gssapi/spnego/gssapiP_spnego.h @@ -530,6 +530,16 @@ spnego_gss_pseudo_random gss_buffer_t prf_out ); +OM_uint32 +spnego_gss_context_query_attributes +( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + void *data, + size_t length +); + #ifdef __cplusplus } #endif diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index 6357f16..f90a278 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -269,6 +269,7 @@ static struct gss_config spnego_mechanism = spnego_gss_map_name_to_any, spnego_gss_release_any_name_mapping, spnego_gss_pseudo_random, + spnego_gss_context_query_attributes, }; #ifdef _GSS_STATIC_LINK @@ -2504,6 +2505,24 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status, return (ret); } +OM_uint32 +spnego_gss_context_query_attributes( + OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + void *data, + size_t length) +{ + OM_uint32 ret; + ret = gss_context_query_attributes(minor_status, + context_handle, + desired_object, + data, + length); + return (ret); +} + + /* * We will release everything but the ctx_handle so that it * can be passed back to init/accept context. This routine should -- cgit v1.1