]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
add support for Heimdal's gss_context_query_attributes()
authorLuke Howard <lukeh@padl.com>
Sun, 22 Nov 2009 21:45:06 +0000 (21:45 +0000)
committerLuke Howard <lukeh@padl.com>
Sun, 22 Nov 2009 21:45:06 +0000 (21:45 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/gssextras@23312 dc483132-0cff-0310-8789-dd5450dbe970

12 files changed:
src/lib/gssapi/generic/gssapi_ext.h
src/lib/gssapi/generic/gssapi_generic.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/krb5/inq_context.c
src/lib/gssapi/libgssapi_krb5.exports
src/lib/gssapi/mechglue/g_initialize.c
src/lib/gssapi/mechglue/g_inq_context_oid.c
src/lib/gssapi/mechglue/mglueP.h
src/lib/gssapi/spnego/gssapiP_spnego.h
src/lib/gssapi/spnego/spnego_mech.c
src/tests/gssapi/t_prf.c

index 12216775adb6333d224eb34d275ed0d54b4ada93..cc5b5164cf009edd006968f58b78eed78e3e67ba 100644 (file)
@@ -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
  */
index 8b1e4def49d58e9cf0d9751c8b823efd32fc5b2a..49737840eda2de52238f586000b076c04196ae38 100644 (file)
@@ -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;
index fae3c838836865a1c63b97d9bbe27c7df184959d..792b49b5b4707293c03fc4aab1c95600a83677d9 100644 (file)
@@ -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);
index a6a9fade2ffe91e0e56bf14e436f7b2437b84729..780dde432c79313ed4f71dc13b23bbca0e6fb0bb 100644 (file)
@@ -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,
 };
 
 
index 5cec4b927ee3d6a6518ff08532556aa937a0a70a..52cf8c55cac72dc75b5e90b65353693f526059f2 100644 (file)
@@ -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;
+}
+
index de063da3abdb4ed22e9d02d193088cba4bd67819..94175c8eacc2079cb6d9c4cd971b1f5f9e430abe 100644 (file)
@@ -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
index e01d174742cd8a27108361363a4a87776a53c732..2f29693328906c11398891cc3a4cf50cd3c0bb7a 100644 (file)
@@ -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);
 
index 469aa7080976723c4b9d70d1a1e034c53d502c70..f15c419bf22baa85c9c74a6028f0791d364a4220 100644 (file)
@@ -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;
+}
index 517ca481b99c245b853f9b055a380381786a8bcd..57e56f35ac95b6c87926cbdc5847901a9b1878a5 100644 (file)
@@ -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 */
index 80c23e2838b3c50f5e8e4d24f22b1ba93d862678..2961d40c32192b4113511bf6e13a38c9fbb56384 100644 (file)
@@ -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
index 6357f1691a1e4039116a5be1490c1bb6d42333eb..f90a2786a6a1a91ee162b0021f6952b0b2a2a2ea 100644 (file)
@@ -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
index c6802f85ad3a1d8b45ab80128ed016e812fe1550..8b4a9197af9e9868ca9056e50a70a6bb88f29795 100644 (file)
@@ -278,6 +278,24 @@ initAcceptSecContext(OM_uint32 *minor,
         testPrf(minor, initiator_context, acceptor_context, GSS_C_PRF_KEY_PARTIAL);
     }
 
+    {
+        gss_context_stream_sizes sizes;
+
+        major = gss_context_query_attributes(minor, acceptor_context,
+                                             GSS_C_ATTR_STREAM_SIZES,
+                                             &sizes, sizeof(sizes));
+        if (major == GSS_S_COMPLETE) {
+            printf("\nContext attributes:\n");
+            printf("-----------------------------------\n\n");
+            printf("Header length:    %ld\n", sizes.header);
+            printf("Trailer length:   %ld\n", sizes.trailer);
+            printf("Maximum msg size: %ld\n", sizes.max_msg_size);
+            printf("Extra buffers:    %ld\n", sizes.buffers);
+            printf("Block size:       %ld\n", sizes.blocksize);
+        } else
+            displayStatus("gss_context_query_attributes", major, *minor);
+    }
+
     (void) gss_release_name(&tmp_minor, &source_name);
     (void) gss_delete_sec_context(&tmp_minor, &acceptor_context, NULL);
     (void) gss_delete_sec_context(minor, &initiator_context, NULL);