]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Improve internal API for GSS sequence numbers
authorGreg Hudson <ghudson@mit.edu>
Tue, 11 Mar 2014 03:01:40 +0000 (23:01 -0400)
committerGreg Hudson <ghudson@mit.edu>
Tue, 18 Mar 2014 15:58:50 +0000 (11:58 -0400)
Use an opaque structure type instead of a void pointer for the
sequence number state.  Rename all functions to use a g_seqstate
prefix rather than a mix of g_order and g_queue.  Remove the
unneccessary indirection from the state object parameter in
g_seqstate_check and g_seqstate_free.  Return OM_uint32 where we
return a GSS major code, long where we return an errno value, and void
where we can't fail.

13 files changed:
src/lib/gssapi/generic/gssapiP_generic.h
src/lib/gssapi/generic/t_seqstate.c
src/lib/gssapi/generic/util_ordering.c
src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/delete_sec_context.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/init_sec_context.c
src/lib/gssapi/krb5/k5sealv3.c
src/lib/gssapi/krb5/k5sealv3iov.c
src/lib/gssapi/krb5/k5unseal.c
src/lib/gssapi/krb5/k5unsealiov.c
src/lib/gssapi/krb5/ser_sctx.c
src/util/gss-kernel-lib/kernel_gss.c

index 16da0fb831b6460e2d29f3b212ee5a524bed7ab9..5e321867c543c1381146e22740d60501e758ddd0 100644 (file)
 #define g_verify_token_header   gssint_g_verify_token_header
 #define g_display_major_status  gssint_g_display_major_status
 #define g_display_com_err_status gssint_g_display_com_err_status
-#define g_order_init            gssint_g_order_init
-#define g_order_check           gssint_g_order_check
-#define g_order_free            gssint_g_order_free
-#define g_queue_size            gssint_g_queue_size
-#define g_queue_externalize     gssint_g_queue_externalize
-#define g_queue_internalize     gssint_g_queue_internalize
+#define g_seqstate_init         gssint_g_seqstate_init
+#define g_seqstate_check        gssint_g_seqstate_check
+#define g_seqstate_free         gssint_g_seqstate_free
+#define g_seqstate_size         gssint_g_seqstate_size
+#define g_seqstate_externalize  gssint_g_seqstate_externalize
+#define g_seqstate_internalize  gssint_g_seqstate_internalize
 #define g_canonicalize_host     gssint_g_canonicalize_host
 #define g_local_host_name       gssint_g_local_host_name
 #define g_strdup                gssint_g_strdup
@@ -126,6 +126,8 @@ typedef struct {
 } g_set;
 #define G_SET_INIT { K5_MUTEX_PARTIAL_INITIALIZER, 0 }
 
+typedef struct g_seqnum_state_st *g_seqnum_state;
+
 int g_set_init (g_set_elt *s);
 int g_set_destroy (g_set_elt *s);
 int g_set_entry_add (g_set_elt *s, void *key, void *value);
@@ -172,18 +174,15 @@ OM_uint32 g_display_com_err_status (OM_uint32 *minor_status,
                                     OM_uint32 status_value,
                                     gss_buffer_t status_string);
 
-gss_int32 g_order_init (void **queue, uint64_t seqnum,
-                        int do_replay, int do_sequence, int wide);
-
-gss_int32 g_order_check (void **queue, uint64_t seqnum);
-
-void g_order_free (void **queue);
-
-gss_uint32 g_queue_size(void *vqueue, size_t *sizep);
-gss_uint32 g_queue_externalize(void *vqueue, unsigned char **buf,
-                               size_t *lenremain);
-gss_uint32 g_queue_internalize(void **vqueue, unsigned char **buf,
-                               size_t *lenremain);
+long g_seqstate_init(g_seqnum_state *state_out, uint64_t seqnum,
+                     int do_replay, int do_sequence, int wide);
+OM_uint32 g_seqstate_check(g_seqnum_state state, uint64_t seqnum);
+void g_seqstate_free(g_seqnum_state state);
+void g_seqstate_size(g_seqnum_state state, size_t *sizep);
+long g_seqstate_externalize(g_seqnum_state state, unsigned char **buf,
+                            size_t *lenremain);
+long g_seqstate_internalize(g_seqnum_state *state_out, unsigned char **buf,
+                            size_t *lenremain);
 
 char *g_strdup (char *str);
 
index 6be4b2e82c6ae8423780b15357934ddda06087aa..c7250b9ad4325537ef22777d656311ff2abd74bb 100644 (file)
@@ -160,7 +160,7 @@ main()
     size_t i, j;
     enum width w;
     struct test *t;
-    void *seqstate;
+    g_seqnum_state seqstate;
     OM_uint32 status;
 
     for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
@@ -169,18 +169,18 @@ main()
         for (w = NARROW; w <= WIDE; w++) {
             if (t->wide_seqnums != BOTH && t->wide_seqnums != w)
                 continue;
-            if (g_order_init(&seqstate, t->initial, t->do_replay,
-                             t->do_sequence, w))
+            if (g_seqstate_init(&seqstate, t->initial, t->do_replay,
+                                t->do_sequence, w))
                 abort();
             for (j = 0; j < t->nseqs; j++) {
-                status = g_order_check(&seqstate, t->seqs[j].seqnum);
+                status = g_seqstate_check(seqstate, t->seqs[j].seqnum);
                 if (status != t->seqs[j].result) {
                     fprintf(stderr, "Test %d seq %d failed: %d != %d\n",
                             (int)i, (int)j, status, t->seqs[j].result);
                     return 1;
                 }
             }
-            g_order_free(&seqstate);
+            g_seqstate_free(seqstate);
         }
     }
 
index 22c6be2e3743d45200f29ea3f54814dde7a92b22..d6feed10d97b61e704b8ce2005f7fc239096266b 100644 (file)
@@ -34,7 +34,7 @@
 
 #define QUEUE_LENGTH 20
 
-typedef struct _queue {
+typedef struct g_seqnum_state_st {
     int do_replay;
     int do_sequence;
     int start;
@@ -88,9 +88,9 @@ queue_insert(queue *q, int after, uint64_t seqnum)
     }
 }
 
-gss_int32
-g_order_init(void **vqueue, uint64_t seqnum,
-             int do_replay, int do_sequence, int wide_nums)
+long
+g_seqstate_init(g_seqnum_state *state_out, uint64_t seqnum,
+                int do_replay, int do_sequence, int wide_nums)
 {
     queue *q;
 
@@ -112,19 +112,16 @@ g_order_init(void **vqueue, uint64_t seqnum,
     q->firstnum = seqnum;
     q->elem[q->start] = ((uint64_t)0 - 1) & q->mask;
 
-    *vqueue = (void *) q;
+    *state_out = q;
     return(0);
 }
 
-gss_int32
-g_order_check(void **vqueue, uint64_t seqnum)
+OM_uint32
+g_seqstate_check(g_seqnum_state q, uint64_t seqnum)
 {
-    queue *q;
     int i;
     uint64_t expected;
 
-    q = (queue *) (*vqueue);
-
     if (!q->do_replay && !q->do_sequence)
         return(GSS_S_COMPLETE);
 
@@ -217,51 +214,46 @@ g_order_check(void **vqueue, uint64_t seqnum)
 }
 
 void
-g_order_free(void **vqueue)
+g_seqstate_free(g_seqnum_state q)
 {
-    queue *q;
-
-    q = (queue *) (*vqueue);
-
     free(q);
-
-    *vqueue = NULL;
 }
 
 /*
  * These support functions are for the serialization routines
  */
-gss_uint32
-g_queue_size(void *vqueue, size_t *sizep)
+void
+g_seqstate_size(g_seqnum_state q, size_t *sizep)
 {
-    *sizep += sizeof(queue);
-    return 0;
+    *sizep += sizeof(*q);
 }
 
-gss_uint32
-g_queue_externalize(void *vqueue, unsigned char **buf, size_t *lenremain)
+long
+g_seqstate_externalize(g_seqnum_state q, unsigned char **buf,
+                       size_t *lenremain)
 {
-    if (*lenremain < sizeof(queue))
+    if (*lenremain < sizeof(*q))
         return ENOMEM;
-    memcpy(*buf, vqueue, sizeof(queue));
-    *buf += sizeof(queue);
-    *lenremain -= sizeof(queue);
+    memcpy(*buf, q, sizeof(*q));
+    *buf += sizeof(*q);
+    *lenremain -= sizeof(*q);
 
     return 0;
 }
 
-gss_uint32
-g_queue_internalize(void **vqueue, unsigned char **buf, size_t *lenremain)
+long
+g_seqstate_internalize(g_seqnum_state *state_out, unsigned char **buf,
+                       size_t *lenremain)
 {
-    void *q;
+    queue *q;
 
-    if (*lenremain < sizeof(queue))
+    if (*lenremain < sizeof(*q))
         return EINVAL;
-    if ((q = malloc(sizeof(queue))) == 0)
+    if ((q = malloc(sizeof(*q))) == 0)
         return ENOMEM;
-    memcpy(q, *buf, sizeof(queue));
-    *buf += sizeof(queue);
-    *lenremain -= sizeof(queue);
-    *vqueue = q;
+    memcpy(q, *buf, sizeof(*q));
+    *buf += sizeof(*q);
+    *lenremain -= sizeof(*q);
+    *state_out = q;
     return 0;
 }
index f3a9803cca70dc66ed9187ad0d64a475e9ec81d3..af7f0dcd561206d7d98f8d83aa6ee512bcab9b13 100644 (file)
@@ -987,9 +987,14 @@ kg_accept_krb5(minor_status, context_handle,
         goto fail;
     }
 
-    g_order_init(&(ctx->seqstate), ctx->seq_recv,
-                 (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-                 (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
+    code = g_seqstate_init(&ctx->seqstate, ctx->seq_recv,
+                           (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+                           (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0,
+                           ctx->proto);
+    if (code) {
+        major_status = GSS_S_FAILURE;
+        goto fail;
+    }
 
     /* DCE_STYLE implies mutual authentication */
     if (ctx->gss_flags & GSS_C_DCE_STYLE)
index 2bc818a642541b66c8c7b69e4780387b7afc9b79..89228ca782842a83c6cd8e766c0a9131ab06216d 100644 (file)
@@ -53,7 +53,7 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token)
     /* free all the context state */
 
     if (ctx->seqstate)
-        g_order_free(&(ctx->seqstate));
+        g_seqstate_free(ctx->seqstate);
 
     if (ctx->enc)
         krb5_k_free_key(context, ctx->enc);
index ef71a5aa32a800f58bd59000589d7ddbfd5085f7..0b199814ad7237d6dcd79c9873c2c463e801288b 100644 (file)
@@ -223,7 +223,7 @@ typedef struct _krb5_gss_ctx_id_rec {
        affects the wire encoding. */
     uint64_t seq_send;
     uint64_t seq_recv;
-    void *seqstate;
+    g_seqnum_state seqstate;
     krb5_context k5_context;
     krb5_auth_context auth_context;
     gss_OID_desc *mech_used;
index 1bc69ca31b6258fa635cd76ba29644c7dfc5d2a9..dc47053297f76486604a1d1ae5778969efe90516 100644 (file)
@@ -639,6 +639,17 @@ kg_new_connection(
     if (code != 0)
         goto cleanup;
 
+    if (!(ctx->gss_flags & GSS_C_MUTUAL_FLAG)) {
+        /* There will be no AP-REP, so set up sequence state now. */
+        ctx->seq_recv = ctx->seq_send;
+        code = g_seqstate_init(&ctx->seqstate, ctx->seq_recv,
+                               (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+                               (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0,
+                               ctx->proto);
+        if (code != 0)
+            goto cleanup;
+    }
+
     /* compute time_rec */
     if (time_rec) {
         if ((code = krb5_timeofday(context, &now)))
@@ -663,10 +674,6 @@ kg_new_connection(
         ctx->established = 0;
         major_status = GSS_S_CONTINUE_NEEDED;
     } else {
-        ctx->seq_recv = ctx->seq_send;
-        g_order_init(&(ctx->seqstate), ctx->seq_recv,
-                     (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-                     (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0, ctx->proto);
         ctx->gss_flags |= GSS_C_PROT_READY_FLAG;
         ctx->established = 1;
         major_status = GSS_S_COMPLETE;
@@ -811,9 +818,14 @@ mutual_auth(
 
     /* store away the sequence number */
     ctx->seq_recv = ap_rep_data->seq_number;
-    g_order_init(&(ctx->seqstate), ctx->seq_recv,
-                 (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
-                 (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) !=0, ctx->proto);
+    code = g_seqstate_init(&ctx->seqstate, ctx->seq_recv,
+                           (ctx->gss_flags & GSS_C_REPLAY_FLAG) != 0,
+                           (ctx->gss_flags & GSS_C_SEQUENCE_FLAG) != 0,
+                           ctx->proto);
+    if (code) {
+        krb5_free_ap_rep_enc_part(context, ap_rep_data);
+        goto fail;
+    }
 
     if (ap_rep_data->subkey != NULL &&
         (ctx->proto == 1 || (ctx->gss_flags & GSS_C_DCE_STYLE) ||
index 429dc8e33b24b54a9ea024301f5ea80372be37b2..f3ade5e79f9182afcc574a6ca4444633101bdd77 100644 (file)
@@ -464,7 +464,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
                 goto no_mem;
             memcpy(message_buffer->value, plain.data, message_buffer->length);
         }
-        err = g_order_check(&ctx->seqstate, seqnum);
+        err = g_seqstate_check(ctx->seqstate, seqnum);
         *minor_status = 0;
         return err;
     } else if (toktype == KG_TOK_MIC_MSG) {
@@ -501,7 +501,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
             *minor_status = 0;
             return GSS_S_BAD_SIG;
         }
-        err = g_order_check(&ctx->seqstate, seqnum);
+        err = g_seqstate_check(ctx->seqstate, seqnum);
         *minor_status = 0;
         return err;
     } else if (toktype == KG_TOK_DEL_CTX) {
index 1cf0c2e502ca74992a4c6d0dcc14d0960e749b1f..960f31b7e4b2a012e80988e7e766be3ab4adb81b 100644 (file)
@@ -428,7 +428,7 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
             }
         }
 
-        code = g_order_check(&ctx->seqstate, seqnum);
+        code = g_seqstate_check(ctx->seqstate, seqnum);
     } else if (toktype == KG_TOK_MIC_MSG) {
         if (load_16_be(ptr) != KG2_TOK_MIC_MSG)
             goto defective;
@@ -448,7 +448,7 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
             *minor_status = code;
             return GSS_S_BAD_SIG;
         }
-        code = g_order_check(&ctx->seqstate, seqnum);
+        code = g_seqstate_check(ctx->seqstate, seqnum);
     } else if (toktype == KG_TOK_DEL_CTX) {
         if (load_16_be(ptr) != KG2_TOK_DEL_CTX)
             goto defective;
index ef7a745ca337a24c8bc5c7ac44df8b520a54a71a..30c12b91ef0be93722067a6cf4d0ea9033be1ee8 100644 (file)
@@ -435,7 +435,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
         return(GSS_S_BAD_SIG);
     }
 
-    retval = g_order_check(&(ctx->seqstate), (uint64_t)seqnum);
+    retval = g_seqstate_check(ctx->seqstate, (uint64_t)seqnum);
 
     /* success or ordering violation */
 
index dc01180b1432ebb0373fc2398575c5d341c8157c..f7828b89a18ba2ab9aefe3423576c95aa7eef0ea 100644 (file)
@@ -280,7 +280,7 @@ kg_unseal_v1_iov(krb5_context context,
     }
 
     code = 0;
-    retval = g_order_check(&ctx->seqstate, (uint64_t)seqnum);
+    retval = g_seqstate_check(ctx->seqstate, (uint64_t)seqnum);
 
 cleanup:
     krb5_free_checksum_contents(context, &md5cksum);
index 8f86acc959fb9aad8e29ff41fc681789f73afa5c..79c4c710e6d4d697506d0dc28ee821a8c10d938c 100644 (file)
@@ -150,25 +150,25 @@ kg_oid_size(kcontext, arg, sizep)
 }
 
 static krb5_error_code
-kg_queue_externalize(kcontext, arg, buffer, lenremain)
+kg_seqstate_externalize(kcontext, arg, buffer, lenremain)
     krb5_context        kcontext;
-    krb5_pointer        arg;
+    g_seqnum_state      arg;
     krb5_octet          **buffer;
     size_t              *lenremain;
 {
     krb5_error_code err;
     err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
     if (err == 0)
-        err = g_queue_externalize(arg, buffer, lenremain);
+        err = g_seqstate_externalize(arg, buffer, lenremain);
     if (err == 0)
         err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
     return err;
 }
 
 static krb5_error_code
-kg_queue_internalize(kcontext, argp, buffer, lenremain)
+kg_seqstate_internalize(kcontext, argp, buffer, lenremain)
     krb5_context        kcontext;
-    krb5_pointer        *argp;
+    g_seqnum_state      *argp;
     krb5_octet          **buffer;
     size_t              *lenremain;
 {
@@ -187,18 +187,18 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain)
     if (ibuf != KV5M_GSS_QUEUE)
         return (EINVAL);
 
-    err = g_queue_internalize(argp, &bp, &remain);
+    err = g_seqstate_internalize(argp, &bp, &remain);
     if (err)
         return err;
 
     /* Read in and check our trailing magic number */
     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
-        g_order_free(argp);
+        g_seqstate_free(*argp);
         return (EINVAL);
     }
 
     if (ibuf != KV5M_GSS_QUEUE) {
-        g_order_free(argp);
+        g_seqstate_free(*argp);
         return (EINVAL);
     }
 
@@ -208,9 +208,9 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain)
 }
 
 static krb5_error_code
-kg_queue_size(kcontext, arg, sizep)
+kg_seqstate_size(kcontext, arg, sizep)
     krb5_context        kcontext;
-    krb5_pointer        arg;
+    g_seqnum_state      arg;
     size_t              *sizep;
 {
     krb5_error_code kret;
@@ -219,7 +219,7 @@ kg_queue_size(kcontext, arg, sizep)
     kret = EINVAL;
     if (arg) {
         required = 2*sizeof(krb5_int32); /* For the header and trailer */
-        g_queue_size(arg, &required);
+        g_seqstate_size(arg, &required);
 
         kret = 0;
         *sizep += required;
@@ -319,7 +319,7 @@ kg_ctx_size(kcontext, arg, sizep)
                                &required);
 
         if (!kret && ctx->seqstate)
-            kret = kg_queue_size(kcontext, ctx->seqstate, &required);
+            kret = kg_seqstate_size(kcontext, ctx->seqstate, &required);
 
         if (!kret)
             kret = krb5_size_opaque(kcontext,
@@ -468,8 +468,8 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
                                                &bp, &remain);
 
             if (!kret && ctx->seqstate)
-                kret = kg_queue_externalize(kcontext,
-                                            ctx->seqstate, &bp, &remain);
+                kret = kg_seqstate_externalize(kcontext,
+                                               ctx->seqstate, &bp, &remain);
 
             if (!kret)
                 kret = krb5_externalize_opaque(kcontext,
@@ -695,8 +695,8 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
             }
 
             if (!kret) {
-                kret = kg_queue_internalize(kcontext, &ctx->seqstate,
-                                            &bp, &remain);
+                kret = kg_seqstate_internalize(kcontext, &ctx->seqstate,
+                                               &bp, &remain);
                 if (kret == EINVAL)
                     kret = 0;
             }
index f33b83db7edfc1f8c3e66f00194489d90840d236..f7a6ae170cacffe633477c6b7f5cd64f078c6183 100644 (file)
@@ -125,7 +125,7 @@ import_lucid_sec_context_v1(const gss_krb5_lucid_context_v1_t *lctx,
      * the protocol needs replay or sequence protection.  Assume we don't
      * (because RPCSEC_GSS doesn't).
      */
-    g_order_init(&gctx->seqstate, gctx->seq_recv, 0, 0, gctx->proto);
+    g_seqstate_init(&gctx->seqstate, gctx->seq_recv, 0, 0, gctx->proto);
 
     *context_handle_out = (gss_ctx_id_t)gctx;
     gctx = NULL;
@@ -174,7 +174,7 @@ krb5_gss_delete_sec_context(OM_uint32 *minor_status,
         return GSS_S_COMPLETE;
 
     ctx = (krb5_gss_ctx_id_t)*context_handle;
-    g_order_free(&ctx->seqstate);
+    g_seqstate_free(ctx->seqstate);
     krb5_k_free_key(NULL, ctx->enc);
     krb5_k_free_key(NULL, ctx->seq);
     krb5_k_free_key(NULL, ctx->subkey);