krb5 commit: Improve internal API for GSS sequence numbers
Greg Hudson
ghudson at MIT.EDU
Tue Mar 18 12:23:41 EDT 2014
https://github.com/krb5/krb5/commit/23a378046bd8122839e501b3e47bb807b66e1c03
commit 23a378046bd8122839e501b3e47bb807b66e1c03
Author: Greg Hudson <ghudson at mit.edu>
Date: Mon Mar 10 23:01:40 2014 -0400
Improve internal API for GSS sequence numbers
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.
src/lib/gssapi/generic/gssapiP_generic.h | 35 ++++++++--------
src/lib/gssapi/generic/t_seqstate.c | 10 ++--
src/lib/gssapi/generic/util_ordering.c | 64 +++++++++++++-----------------
src/lib/gssapi/krb5/accept_sec_context.c | 11 ++++-
src/lib/gssapi/krb5/delete_sec_context.c | 2 +-
src/lib/gssapi/krb5/gssapiP_krb5.h | 2 +-
src/lib/gssapi/krb5/init_sec_context.c | 26 +++++++++---
src/lib/gssapi/krb5/k5sealv3.c | 4 +-
src/lib/gssapi/krb5/k5sealv3iov.c | 4 +-
src/lib/gssapi/krb5/k5unseal.c | 2 +-
src/lib/gssapi/krb5/k5unsealiov.c | 2 +-
src/lib/gssapi/krb5/ser_sctx.c | 32 +++++++-------
src/util/gss-kernel-lib/kernel_gss.c | 4 +-
13 files changed, 103 insertions(+), 95 deletions(-)
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index 16da0fb..5e32186 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -109,12 +109,12 @@
#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);
diff --git a/src/lib/gssapi/generic/t_seqstate.c b/src/lib/gssapi/generic/t_seqstate.c
index 6be4b2e..c7250b9 100644
--- a/src/lib/gssapi/generic/t_seqstate.c
+++ b/src/lib/gssapi/generic/t_seqstate.c
@@ -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);
}
}
diff --git a/src/lib/gssapi/generic/util_ordering.c b/src/lib/gssapi/generic/util_ordering.c
index 22c6be2..d6feed1 100644
--- a/src/lib/gssapi/generic/util_ordering.c
+++ b/src/lib/gssapi/generic/util_ordering.c
@@ -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;
}
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index f3a9803..af7f0dc 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -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)
diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c
index 2bc818a..89228ca 100644
--- a/src/lib/gssapi/krb5/delete_sec_context.c
+++ b/src/lib/gssapi/krb5/delete_sec_context.c
@@ -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);
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index ef71a5a..0b19981 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -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;
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 1bc69ca..dc47053 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -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) ||
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index 429dc8e..f3ade5e 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -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) {
diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
index 1cf0c2e..960f31b 100644
--- a/src/lib/gssapi/krb5/k5sealv3iov.c
+++ b/src/lib/gssapi/krb5/k5sealv3iov.c
@@ -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;
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index ef7a745..30c12b9 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -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 */
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index dc01180..f7828b8 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -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);
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 8f86acc..79c4c71 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -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;
}
diff --git a/src/util/gss-kernel-lib/kernel_gss.c b/src/util/gss-kernel-lib/kernel_gss.c
index f33b83d..f7a6ae1 100644
--- a/src/util/gss-kernel-lib/kernel_gss.c
+++ b/src/util/gss-kernel-lib/kernel_gss.c
@@ -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);
More information about the cvs-krb5
mailing list