From: Kevin Coffman Update gssd and svcgssd to use the new gss mech glue lucid context calls. Signed-off-by: Andy Adamson --- nfs-utils-1.0.7-kwc/utils/gssd/context.c | 176 ++++++++++++++++-------------- nfs-utils-1.0.7-kwc/utils/gssd/gss_util.h | 6 + 2 files changed, 103 insertions(+), 79 deletions(-) diff -puN utils/gssd/context.c~spkm3_lucid_context utils/gssd/context.c --- nfs-utils-1.0.7/utils/gssd/context.c~spkm3_lucid_context 2005-10-18 15:52:32.123769000 -0400 +++ nfs-utils-1.0.7-kwc/utils/gssd/context.c 2005-10-25 10:39:30.801287000 -0400 @@ -42,6 +42,24 @@ #include "err_util.h" #include "context.h" +/* this stuff is in spkm/spkm3_lucid.h */ +typedef struct gss_spkm3_lucid_key_t { + int version; /* version = 1 */ + gss_buffer_desc ctx_id; + int qop; + gss_buffer_desc mech_used; + OM_uint32 ret_flags; + OM_uint32 req_flags; + gss_buffer_desc share_key; + gss_buffer_desc derived_conf_key; + gss_buffer_desc derived_integ_key; + /* openssl NID's of the negotiated algorithms */ + int keyestb_alg; + int owf_alg; + int intg_alg; + int conf_alg; +} gss_spkm3_lucid_key_t; + /* spkm3 seems to actually want it this big, yipes. */ #define MAX_CTX_LEN 4096 @@ -133,49 +151,6 @@ typedef struct _krb5_gss_ctx_id_rec { #endif /* KRB5_VERSION */ #endif /* HAVE_KRB5 */ -/* XXX We have the same issue as above. We can require SPKM-3 source - * at the time we compile gssd, or copy the context structure definitions - * here. - */ - -/* structure typedefs */ - -typedef struct spkm3_ctx_id_t { - int length; - unsigned char *data; -} spkm3_ctx_id, - *spkm3_ctx_id_t; - -/* first pass at spkm3 context. will add a bunch of stuff .... */ - -typedef struct spkm3_gss_ctx_id_desc_t { - spkm3_ctx_id ctx_id; /* per spkm token contextid */ - int established; - int qop; /* negotiated qop */ - gss_OID mech_used; - OM_uint32 ret_flags; - OM_uint32 req_flags; - /* DH should be abstracted to an EVP_ struct able to hold - * various kalg results */ - /* XXX The following is defined as "DH *dh" in the original - * header we're gonna cheat and use "void *dh" here. */ - void *dh; - gss_buffer_desc share_key; - /* derived keys are result from applying the owf_alg to the - * shared key - see spkm3_derive_supkey */ - gss_buffer_desc derived_conf_key; - gss_buffer_desc derived_integ_key; - /* openssl NID's of the negotiated algorithms */ - int keyestb_alg; /* key establishment */ - int owf_alg; /* one way function */ - int intg_alg; /* integrity */ - int conf_alg; /* privacy */ - /* der encoded REQ_TOKEN reqcontets and length */ - unsigned char *der_reqcontents; - int der_req_len; -} spkm3_gss_ctx_id_desc; - - /* adapted from mit kerberos 5 ../lib/gssapi/mechglue/mglueP.h * this is what gets passed around when the mechglue code is enabled : */ typedef struct gss_union_ctx_id_t { @@ -292,6 +267,7 @@ prepare_krb5_rfc_cfx_buffer(gss_krb5_luc return -1; } + static int serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) { @@ -303,7 +279,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n"); maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, &ctx, - 1, &return_ctx); + 1, &return_ctx); if (maj_stat != GSS_S_COMPLETE) goto out_err; @@ -392,61 +368,103 @@ out_err: #endif /* HAVE_KRB5 */ -/* ANDROS: need to determine which fields of the spkm3_gss_ctx_id_desc_t - * are needed in the kernel for get_mic, validate, wrap, unwrap, and destroy - * and only export those fields to the kernel. - */ +/* + * Function: prepare_spkm3_ctx_buffer() + * + * Prepare spkm3 lucid context for the kernel + * + * buf->length should be: + * + * ctx_id 4 + 12 + * qop 4 + * mech_used 4 + 7 + * ret_fl 4 + * req_fl 4 + * share 4 + 16 + * conf_alg 4 + * d_conf_key 4 + 0 + * intg_alg 4 + * d_intg_key 4 + 0 + * kyestb 4 + * owl alg 4 +*/ static int -serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +prepare_spkm3_ctx_buffer(gss_spkm3_lucid_key_t *key, gss_buffer_desc *buf) { - spkm3_gss_ctx_id_desc *sctx = (spkm3_gss_ctx_id_desc *)ctx; char *p, *end; - printerr(1, "serialize_spkm3_ctx called\n"); - if (!(buf->value = calloc(1, MAX_CTX_LEN))) goto out_err; p = buf->value; end = buf->value + MAX_CTX_LEN; -/* buf->length -ctx_id 4 + 12 -qop 4 -mech_used 4 + 7 -ret_fl 4 -req_fl 4 -share 4 + 16 -conf_alg 4 -d_conf_key 4 + 0 -intg_alg 4 -d_intg_key 4 + 0 -kyestb 4 -owl alg 4 -*/ - if (write_buffer(&p, end, (gss_buffer_desc *)&sctx->ctx_id)) + + if (write_buffer(&p, end, &key->ctx_id)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->qop)) goto out_err; - if (write_buffer(&p, end, (gss_buffer_desc *)sctx->mech_used)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->ret_flags)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->req_flags)) goto out_err; - if (write_buffer(&p, end, &sctx->share_key)) + if (WRITE_BYTES(&p, end, key->qop)) goto out_err; + if (write_buffer(&p, end, &key->mech_used)) goto out_err; + if (WRITE_BYTES(&p, end, key->ret_flags)) goto out_err; + if (WRITE_BYTES(&p, end, key->req_flags)) goto out_err; + if (write_buffer(&p, end, &key->share_key)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->conf_alg)) goto out_err; - if (write_buffer(&p, end, &sctx->derived_conf_key)) + if (WRITE_BYTES(&p, end, key->conf_alg)) goto out_err; + if (write_buffer(&p, end, &key->derived_conf_key)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->intg_alg)) goto out_err; - if (write_buffer(&p, end, &sctx->derived_integ_key)) + if (WRITE_BYTES(&p, end, key->intg_alg)) goto out_err; + if (write_buffer(&p, end, &key->derived_integ_key)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->keyestb_alg)) goto out_err; - if (WRITE_BYTES(&p, end, sctx->owf_alg)) goto out_err; + if (WRITE_BYTES(&p, end, key->keyestb_alg)) goto out_err; + if (WRITE_BYTES(&p, end, key->owf_alg)) goto out_err; buf->length = p - (char *)buf->value; return 0; out_err: + printerr(0, "ERROR: failed serializing spkm3 context for kernel\n"); if (buf->value) free(buf->value); buf->length = 0; + + return -1; +} + +/* ANDROS: need to determine which fields of the spkm3_gss_ctx_id_desc_t + * are needed in the kernel for get_mic, validate, wrap, unwrap, and destroy + * and only export those fields to the kernel. + */ +static int +serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + OM_uint32 vers, ret, maj_stat, min_stat; + void *ret_ctx = 0; + gss_spkm3_lucid_key_t *key; + + printerr(1, "serialize_spkm3_ctx called\n"); + + printerr(2, "DEBUG: serialize_spkm3_ctx: lucid version!\n"); + maj_stat = gss_export_lucid_sec_context(&min_stat, ctx, 1, &ret_ctx); + if (maj_stat != GSS_S_COMPLETE) + goto out_err; + + key = (gss_spkm3_lucid_key_t *)ret_ctx; + + vers = key->version; + if (vers != 1) { + printerr(0, "ERROR: unsupported spkm3 context version %d\n", + vers); + goto out_err; + } + ret = prepare_spkm3_ctx_buffer(key, buf); + + maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, ret_ctx); + + if (maj_stat != GSS_S_COMPLETE) + printerr(0, "WARN: failed to free lucid sec context\n"); + if (ret) + goto out_err; + return 0; + +out_err: return -1; } @@ -458,7 +476,7 @@ serialize_context_for_kernel(gss_ctx_id_ if (g_OID_equal(&krb5oid, uctx->mech_type)) return serialize_krb5_ctx(uctx->internal_ctx_id, buf); else if (g_OID_equal(&spkm3oid, uctx->mech_type)) - return serialize_spkm3_ctx(uctx->internal_ctx_id, buf); + return serialize_spkm3_ctx(uctx, buf); else { printerr(0, "ERROR: attempting to serialize context with " "unknown mechanism oid\n"); diff -puN utils/gssd/gss_util.h~spkm3_lucid_context utils/gssd/gss_util.h --- nfs-utils-1.0.7/utils/gssd/gss_util.h~spkm3_lucid_context 2005-10-18 15:52:32.131769000 -0400 +++ nfs-utils-1.0.7-kwc/utils/gssd/gss_util.h 2005-10-18 15:52:32.161769000 -0400 @@ -41,4 +41,10 @@ int gssd_acquire_cred(char *server_name) void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, const gss_OID mech); +u_int32_t gss_export_lucid_sec_context (u_int32_t *minor_status, void *ctx, + u_int32_t version, void *internal_buffer); + +u_int32_t gss_free_lucid_sec_context (u_int32_t *minor_status, void *ctx, + void *internal_buffer); + #endif /* _GSS_UTIL_H_ */ _