Share handling of lucid_sec_context for Heimdal and MIT
[nfs-utils.git] / utils / gssd / context_mit.c
index 37b8b8e..94b2266 100644 (file)
 */
 
 #include "config.h"
 */
 
 #include "config.h"
+
+#ifndef HAVE_LUCID_CONTEXT_SUPPORT
+#ifdef HAVE_KRB5
+
 #include <stdio.h>
 #include <syslog.h>
 #include <string.h>
 #include <stdio.h>
 #include <syslog.h>
 #include <string.h>
 #include "err_util.h"
 #include "context.h"
 
 #include "err_util.h"
 #include "context.h"
 
-#ifdef HAVE_KRB5
 #include <krb5.h>
 
 #include <krb5.h>
 
-/* XXX spkm3 seems to actually want it this big, yipes. */
-#define MAX_CTX_LEN 4096
-
-#ifdef HAVE_LUCID_CONTEXT_SUPPORT
-
-/* Don't use the private structure, use the exported lucid structure */
-#include <gssapi/gssapi_krb5.h>
-
-#elif (KRB5_VERSION > 131)
+#if (KRB5_VERSION > 131)
 /* XXX argggg, there's gotta be a better way than just duplicating this
  * whole struct.  Unfortunately, this is in a "private" header file,
  * so this is our best choice at this point :-/
 /* XXX argggg, there's gotta be a better way than just duplicating this
  * whole struct.  Unfortunately, this is in a "private" header file,
  * so this is our best choice at this point :-/
@@ -86,7 +81,7 @@ typedef struct _krb5_gss_ctx_id_rec {
    uint64_t seq_recv;          /* gssint_uint64 */
    void *seqstate;
    krb5_auth_context auth_context;
    uint64_t seq_recv;          /* gssint_uint64 */
    void *seqstate;
    krb5_auth_context auth_context;
-   gss_buffer_desc *mech_used; /* gss_OID_desc */
+   gss_OID_desc *mech_used;    /* gss_OID_desc */
     /* Protocol spec revision
        0 => RFC 1964 with 3DES and RC4 enhancements
        1 => draft-ietf-krb-wg-gssapi-cfx-01
     /* Protocol spec revision
        0 => RFC 1964 with 3DES and RC4 enhancements
        1 => draft-ietf-krb-wg-gssapi-cfx-01
@@ -123,7 +118,7 @@ typedef struct _krb5_gss_ctx_id_rec {
        int established;
        int big_endian;
        krb5_auth_context auth_context;
        int established;
        int big_endian;
        krb5_auth_context auth_context;
-       gss_buffer_desc *mech_used;
+       gss_OID_desc *mech_used;
        int nctypes;
        krb5_cksumtype *ctypes;
 } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
        int nctypes;
        krb5_cksumtype *ctypes;
 } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
@@ -131,162 +126,6 @@ typedef struct _krb5_gss_ctx_id_rec {
 #endif /* KRB5_VERSION */
 
 
 #endif /* KRB5_VERSION */
 
 
-#ifdef HAVE_LUCID_CONTEXT_SUPPORT /* Lucid context support */
-static int
-write_lucid_keyblock(char **p, char *end, gss_krb5_lucid_key_t *key)
-{
-       gss_buffer_desc tmp;
-
-       if (WRITE_BYTES(p, end, key->type)) return -1;
-       tmp.length = key->length;
-       tmp.value = key->data;
-       if (write_buffer(p, end, &tmp)) return -1;
-       return 0;
-}
-
-static int
-prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx,
-       gss_buffer_desc *buf)
-{
-       char *p, *end;
-       static int constant_zero = 0;
-       unsigned char fakeseed[16];
-       uint32_t word_send_seq;
-       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
-        * does not include the seed or seed_init fields
-        * because we never really use them.  But for now,
-        * send down a fake buffer so we can use the same
-        * 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;
-       p = buf->value;
-       end = buf->value + MAX_CTX_LEN;
-
-       if (WRITE_BYTES(&p, end, lctx->initiate)) goto out_err;
-
-       /* seed_init and seed not used by kernel anyway */
-       if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
-       if (write_bytes(&p, end, &fakeseed, 16)) goto out_err;
-
-       if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.sign_alg)) goto out_err;
-       if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.seal_alg)) goto out_err;
-       if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
-       word_send_seq = lctx->send_seq; /* XXX send_seq is 64-bit */
-       if (WRITE_BYTES(&p, end, word_send_seq)) goto out_err;
-       if (write_buffer(&p, end, (gss_buffer_desc*)&krb5oid)) goto out_err;
-
-       printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
-                "enctype %d and length %d\n",
-                lctx->rfc1964_kd.ctx_key.type,
-                lctx->rfc1964_kd.ctx_key.length);
-
-       /* derive the encryption key and copy it into buffer */
-       enc_key.type = lctx->rfc1964_kd.ctx_key.type;
-       enc_key.length = lctx->rfc1964_kd.ctx_key.length;
-       if ((enc_key.data = calloc(1, enc_key.length)) == NULL)
-               goto out_err;
-       skd = (char *) lctx->rfc1964_kd.ctx_key.data;
-       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);
-               goto out_err;
-       }
-       free(enc_key.data);
-
-       if (write_lucid_keyblock(&p, end, &lctx->rfc1964_kd.ctx_key))
-               goto out_err;
-
-       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);
-       buf->length = 0;
-       if (enc_key.data) free(enc_key.data);
-       return -1;
-}
-
-static int
-prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
-       gss_buffer_desc *buf)
-{
-       printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
-       return -1;
-}
-
-
-int
-serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf)
-{
-       OM_uint32 maj_stat, min_stat;
-       void *return_ctx = 0;
-       OM_uint32 vers;
-       gss_krb5_lucid_context_v1_t *lctx = 0;
-       int retcode = 0;
-
-       printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n");
-       maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx,
-                                               1, &return_ctx);
-       if (maj_stat != GSS_S_COMPLETE) {
-               pgsserr("gss_export_lucid_sec_context",
-                       maj_stat, min_stat, &krb5oid);
-               goto out_err;
-       }
-
-       /* Check the version returned, we only support v1 right now */
-       vers = ((gss_krb5_lucid_context_version_t *)return_ctx)->version;
-       switch (vers) {
-       case 1:
-               lctx = (gss_krb5_lucid_context_v1_t *) return_ctx;
-               break;
-       default:
-               printerr(0, "ERROR: unsupported lucid sec context version %d\n",
-                       vers);
-               goto out_err;
-               break;
-       }
-
-       /* Now lctx points to a lucid context that we can send down to kernel */
-       if (lctx->protocol == 0)
-               retcode = prepare_krb5_rfc1964_buffer(lctx, buf);
-       else
-               retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf);
-
-       maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
-       if (maj_stat != GSS_S_COMPLETE) {
-               pgsserr("gss_export_lucid_sec_context",
-                       maj_stat, min_stat, &krb5oid);
-               printerr(0, "WARN: failed to free lucid sec context\n");
-       }
-
-       if (retcode) {
-               printerr(1, "serialize_krb5_ctx: prepare_krb5_*_buffer "
-                        "failed (retcode = %d)\n", retcode);
-               goto out_err;
-       }
-
-       return 0;
-
-out_err:
-       printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
-       return -1;
-}
-
-
-#else /* HAVE_LUCID_CONTEXT_SUPPORT */
-
 static int
 write_keyblock(char **p, char *end, struct _krb5_keyblock *arg)
 {
 static int
 write_keyblock(char **p, char *end, struct _krb5_keyblock *arg)
 {
@@ -343,7 +182,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf)
        if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
        word_seq_send = kctx->seq_send;
        if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
        if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
        word_seq_send = kctx->seq_send;
        if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
-       if (write_buffer(&p, end, kctx->mech_used)) goto out_err;
+       if (write_oid(&p, end, kctx->mech_used)) goto out_err;
 
        printerr(2, "serialize_krb5_ctx: serializing keys with "
                 "enctype %d and length %d\n",
 
        printerr(2, "serialize_krb5_ctx: serializing keys with "
                 "enctype %d and length %d\n",
@@ -360,6 +199,6 @@ out_err:
        buf->length = 0;
        return -1;
 }
        buf->length = 0;
        return -1;
 }
-#endif /* HAVE_LUCID_CONTEXT_SUPPORT */
 
 #endif /* HAVE_KRB5 */
 
 #endif /* HAVE_KRB5 */
+#endif /* HAVE_LUCID_CONTEXT_SUPPORT */