X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fgss%2Fcontext_lucid.c;h=a24eda1778ba895e68b06189524c68acd56da5a7;hp=7eba6b6c8914bd84ea0617a6871652d8f347ffb3;hb=4d1d6ed7849b0532e44f2fd742d4e07b649d6f66;hpb=3fc1eb34d8a4d352e3482a4feec364ef3b7a5d75 diff --git a/lustre/utils/gss/context_lucid.c b/lustre/utils/gss/context_lucid.c index 7eba6b6..a24eda1 100644 --- a/lustre/utils/gss/context_lucid.c +++ b/lustre/utils/gss/context_lucid.c @@ -1,8 +1,9 @@ /* - * COPYRIGHT (c) 2006 - * The Regents of the University of Michigan + * COPYRIGHT (c) 2006 The Regents of the University of Michigan * ALL RIGHTS RESERVED * + * Copyright (c) 2012, 2014, Intel Corporation. + * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of @@ -59,13 +60,6 @@ typedef uint64_t OM_uint64; #include "write_bytes.h" #include "context.h" -extern OM_uint32 gss_export_lucid_sec_context(OM_uint32 *min_stat, - gss_ctx_id_t *ctx, - OM_uint32 version, - void **kctx); -extern OM_uint32 gss_free_lucid_sec_context(OM_uint32 *min_stat, - gss_ctx_id_t ctx, - void *kctx); static int write_lucid_keyblock(char **p, char *end, gss_krb5_lucid_key_t *key) @@ -90,7 +84,6 @@ prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, gss_krb5_lucid_key_t enc_key; int i; char *skd, *dkd; - gss_buffer_desc fakeoid; /* * The new Kerberos interface to get the gss context @@ -100,7 +93,6 @@ prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, * interface to the kernel. */ memset(&enc_key, 0, sizeof(enc_key)); - memset(&fakeoid, 0, sizeof(fakeoid)); if (!(buf->value = calloc(1, MAX_CTX_LEN))) goto out_err; @@ -146,20 +138,20 @@ prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, dkd = (char *) enc_key.data; for (i = 0; i < enc_key.length; i++) dkd[i] = skd[i] ^ 0xf0; - if (write_lucid_keyblock(&p, end, &enc_key)) { - free(enc_key.data); + if (write_lucid_keyblock(&p, end, &enc_key)) goto out_err; - } - free(enc_key.data); - if (write_lucid_keyblock(&p, end, &lctx->rfc1964_kd.ctx_key)) goto out_err; + free(enc_key.data); buf->length = p - (char *)buf->value; return 0; out_err: printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); - if (buf->value) free(buf->value); + if (buf->value) { + free(buf->value); + buf->value = NULL; + } buf->length = 0; if (enc_key.data) free(enc_key.data); return -1; @@ -204,15 +196,15 @@ enum seal_alg { * We don't have "legal" access to these MIT-only * structures located in libk5crypto */ -extern void krb5int_enc_arcfour; -extern void krb5int_enc_des3; -extern void krb5int_enc_aes128; -extern void krb5int_enc_aes256; +extern void *krb5int_enc_arcfour; +extern void *krb5int_enc_des3; +extern void *krb5int_enc_aes128; +extern void *krb5int_enc_aes256; static void key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout) { - memset(kout, '\0', sizeof(kout)); + memset(kout, 0, sizeof(*kout)); #ifdef HAVE_KRB5 kout->enctype = lin->type; kout->length = lin->length; @@ -224,19 +216,30 @@ key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout) #endif } -static void +static int key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout) { - memset(lout, '\0', sizeof(lout)); + memset(lout, 0, sizeof(*lout)); + #ifdef HAVE_KRB5 + lout->data = malloc(kin->length); + if (lout->data == NULL) + return KRB5_CC_NOMEM; + lout->type = kin->enctype; lout->length = kin->length; - lout->data = kin->contents; + memcpy(lout->data, kin->contents, kin->length); #else + lout->data = malloc(kin->keyvalue.length); + if (lout->data == NULL) + return KRB5_CC_NOMEM; + lout->type = kin->keytype; lout->length = kin->keyvalue.length; memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length); #endif + + return 0; } /* XXX Hack alert! XXX Do NOT submit upstream! XXX */ @@ -253,18 +256,20 @@ derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, krb5_error_code code; unsigned char constant_data[K5CLENGTH]; krb5_data datain; - int keylength; + int keylength __attribute__ ((unused)); +#ifdef HAVE_KRB5 void *enc; - krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */ +#endif + krb5_keyblock kin; /* must send krb5_keyblock, not lucid! */ #if defined(HAVE_HEIMDAL) || HAVE_KRB5INT_DERIVE_KEY krb5_context kcontext; + krb5_keyblock *outkey; +#else + krb5_keyblock kout; #endif #if HAVE_KRB5INT_DERIVE_KEY krb5_key key_in, key_out; #endif -#ifdef HAVE_HEIMDAL - krb5_keyblock *outkey; -#endif /* * XXX Hack alert. We don't have "legal" access to these @@ -297,17 +302,8 @@ derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, goto out; } - /* allocate memory for output key */ - if ((out->data = malloc(keylength)) == NULL) { - code = ENOMEM; - goto out; - } - out->length = keylength; - out->type = in->type; - /* Convert to correct format for call to krb5_derive_key */ key_lucid_to_krb5(in, &kin); - key_lucid_to_krb5(out, &kout); datain.data = (char *) constant_data; datain.length = K5CLENGTH; @@ -319,52 +315,57 @@ derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out, ((char *)(datain.data))[4] = (char) extra; -#ifdef HAVE_KRB5 -#if HAVE_KRB5INT_DERIVE_KEY + /* Step 1: Init context */ + /* Heimdal and newer MIT Kerberos require kcontext */ +#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL) code = krb5_init_context(&kcontext); - if (code) { - free(out->data); - out->data = NULL; + if (code) goto out; - } +#endif + + /* Step 2: Get the derived key */ +#ifdef HAVE_KRB5 +#if HAVE_KRB5INT_DERIVE_KEY code = krb5_k_create_key(kcontext, &kin, &key_in); - if (code) { - free(out->data); - out->data = NULL; - goto out; - } - code = krb5_k_create_key(kcontext, &kout, &key_out); - if (code) { - free(out->data); - out->data = NULL; + if (code) goto out; + + code = ll_krb5int_derive_key(enc, key_in, &key_out, &datain, + DERIVE_RFC3961); + + krb5_k_free_key(kcontext, key_in); + if (code == 0) { + krb5_k_key_keyblock(kcontext, key_out, &outkey); + krb5_k_free_key(kcontext, key_out); } - code = krb5int_derive_key(enc, key_in, &key_out, &datain, - DERIVE_RFC3961); #else /* !HAVE_KRB5INT_DERIVE_KEY */ + out->length = keylength; + out->type = in->type; + + key_lucid_to_krb5(out, &kout); + code = krb5_derive_key(enc, &kin, &kout, &datain); #endif /* HAVE_KRB5INT_DERIVE_KEY */ #else /* !defined(HAVE_KRB5) */ - if ((code = krb5_init_context(&kcontext))) { - } code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey); #endif /* defined(HAVE_KRB5) */ - if (code) { - free(out->data); - out->data = NULL; + + if (code) goto out; - } -#ifdef HAVE_KRB5 - key_krb5_to_lucid(&kout, out); -#if HAVE_KRB5INT_DERIVE_KEY - krb5_free_context(kcontext); -#endif /* HAVE_KRB5INT_DERIVE_KEY */ -#else /* !defined(HAVE_KRB5) */ - key_krb5_to_lucid(outkey, out); + + /* Step 3: Copy the key to out */ +#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL) + code = key_krb5_to_lucid(outkey, out); krb5_free_keyblock(kcontext, outkey); - krb5_free_context(kcontext); +#else /* !defined(HAVE_KRB5) */ + code = key_krb5_to_lucid(&kout, out); #endif /* defined(HAVE_KRB5) */ + /* Step 4: Free the context */ +#if defined(HAVE_KRB5INT_DERIVE_KEY) || defined(HAVE_HEIMDAL) + krb5_free_context(kcontext); +#endif + out: if (code) printerr(0, "ERROR: %s: returning error %d (%s)\n", @@ -507,27 +508,18 @@ prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx, else keyptr = &lctx->cfx_kd.ctx_key; -#if 0 - if (lctx->initiate == 1) { - sign_usage = KG_USAGE_INITIATOR_SIGN; - seal_usage = KG_USAGE_INITIATOR_SEAL; - } else { - sign_usage = KG_USAGE_ACCEPTOR_SIGN; - seal_usage = KG_USAGE_ACCEPTOR_SEAL; - } -#else /* FIXME - * These are from rfc4142, but I don't understand: if we supply - * different 'usage' value for client & server, then the peers - * will have different derived keys. How could this work? + * These are from rfc4142, but I don't understand: + * if we supply different 'usage' value for client & + * server, then the peers will have different derived + * keys. How could this work? * - * Here we simply use old SIGN/SEAL values until we find the - * answer. --ericm + * Here we simply use old SIGN/SEAL values until we + * find the answer. --ericm * FIXME */ sign_usage = KG_USAGE_SIGN; seal_usage = KG_USAGE_SEAL; -#endif /* derive and send down: Ke, Ki, and Kc */ @@ -586,10 +578,10 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) int retcode = 0; printerr(3, "lucid version!\n"); - maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx, + maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, &ctx, 1, &return_ctx); if (maj_stat != GSS_S_COMPLETE) { - pgsserr("gss_export_lucid_sec_context", + pgsserr("gss_krb5_export_lucid_sec_context", maj_stat, min_stat, &krb5oid); goto out_err; } @@ -622,9 +614,9 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) else retcode = prepare_krb5_rfc4121_buffer(lctx, buf); - maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx); + maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, return_ctx); if (maj_stat != GSS_S_COMPLETE) { - pgsserr("gss_export_lucid_sec_context", + pgsserr("gss_krb5_export_lucid_sec_context", maj_stat, min_stat, &krb5oid); printerr(0, "WARN: failed to free lucid sec context\n"); }