From e706ad39d55dc8e56ae6457a99828c05bb5223ec Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Tue, 10 Feb 2004 04:35:14 +0000 Subject: [PATCH] * ser_sctx.c (kg_oid_externalize): Check for errors. (kg_oid_internalize): Check for errors. Free allocated storage on error. (kg_queue_externalize): Check for errorrs. (kg_queue_internalize): Check for errors. Free allocated storage on error. (kg_ctx_size): Update for new context data. (kg_ctx_externalize): Update for new context data. Check for error storing trailer. (kg_ctx_internalize): Update for new context data. Check for errors in a few more cases. ticket: 2166 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16050 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/krb5/ChangeLog | 14 +++ src/lib/gssapi/krb5/ser_sctx.c | 189 ++++++++++++++++++++++++--------- 2 files changed, 154 insertions(+), 49 deletions(-) diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index 95d98cd53..7a02d16fc 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,17 @@ +2004-02-09 Ken Raeburn + + * ser_sctx.c (kg_oid_externalize): Check for errors. + (kg_oid_internalize): Check for errors. Free allocated storage on + error. + (kg_queue_externalize): Check for errorrs. + (kg_queue_internalize): Check for errors. Free allocated storage + on error. + (kg_ctx_size): Update for new context data. + (kg_ctx_externalize): Update for new context data. Check for + error storing trailer. + (kg_ctx_internalize): Update for new context data. Check for + errors in a few more cases. + 2004-02-05 Jeffrey Altman * gssapiP_krb5.h: remove KG_IMPLFLAGS macro diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 4c5564609..e0d0ee0af 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -51,14 +51,21 @@ kg_oid_externalize(kcontext, arg, buffer, lenremain) size_t *lenremain; { gss_OID oid = (gss_OID) arg; + krb5_error_code err; - (void) krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); - (void) krb5_ser_pack_int32((krb5_int32) oid->length, - buffer, lenremain); - (void) krb5_ser_pack_bytes((krb5_octet *) oid->elements, - oid->length, buffer, lenremain); - (void) krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); - return 0; + err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); + if (err) + return err; + err = krb5_ser_pack_int32((krb5_int32) oid->length, + buffer, lenremain); + if (err) + return err; + err = krb5_ser_pack_bytes((krb5_octet *) oid->elements, + oid->length, buffer, lenremain); + if (err) + return err; + err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); + return err; } static krb5_error_code @@ -86,22 +93,35 @@ kg_oid_internalize(kcontext, argp, buffer, lenremain) oid = (gss_OID) malloc(sizeof(gss_OID_desc)); if (oid == NULL) return ENOMEM; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { + free(oid); + return EINVAL; + } oid->length = ibuf; oid->elements = malloc(ibuf); if (oid->elements == 0) { free(oid); return ENOMEM; } - (void) krb5_ser_unpack_bytes((krb5_octet *) oid->elements, - oid->length, &bp, &remain); + if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements, + oid->length, &bp, &remain)) { + free(oid->elements); + free(oid); + return EINVAL; + } /* Read in and check our trailing magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - return (EINVAL); + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { + free(oid->elements); + free(oid); + return (EINVAL); + } - if (ibuf != KV5M_GSS_OID) + if (ibuf != KV5M_GSS_OID) { + free(oid->elements); + free(oid); return (EINVAL); + } *buffer = bp; *lenremain = remain; @@ -140,10 +160,13 @@ kg_queue_externalize(kcontext, arg, buffer, lenremain) krb5_octet **buffer; size_t *lenremain; { - (void) krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); - g_queue_externalize(arg, buffer, lenremain); - (void) krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); - return 0; + krb5_error_code err; + err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); + if (err == 0) + err = g_queue_externalize(arg, buffer, lenremain); + if (err == 0) + err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); + return err; } static krb5_error_code @@ -156,6 +179,7 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain) krb5_int32 ibuf; krb5_octet *bp; size_t remain; + krb5_error_code err; bp = *buffer; remain = *lenremain; @@ -167,14 +191,20 @@ kg_queue_internalize(kcontext, argp, buffer, lenremain) if (ibuf != KV5M_GSS_QUEUE) return (EINVAL); - g_queue_internalize(argp, &bp, &remain); + err = g_queue_internalize(argp, &bp, &remain); + if (err) + return err; /* Read in and check our trailing magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - return (EINVAL); + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { + g_order_free(argp); + return (EINVAL); + } - if (ibuf != KV5M_GSS_QUEUE) + if (ibuf != KV5M_GSS_QUEUE) { + g_order_free(argp); return (EINVAL); + } *buffer = bp; *lenremain = remain; @@ -218,24 +248,37 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_gss_ctx_id_rec requires: * krb5_int32 for KG_CONTEXT * krb5_int32 for initiate. - * krb5_int32 for mutual. + * krb5_int32 for established. + * krb5_int32 for big_endian. + * krb5_int32 for have_acceptor_subkey. * krb5_int32 for seed_init. + * krb5_int32 for gss_flags. * sizeof(seed) for seed + * ... for here + * ... for there + * ... for subkey * krb5_int32 for signalg. * krb5_int32 for cksum_size. * krb5_int32 for sealalg. + * ... for enc + * ... for seq * krb5_int32 for endtime. * krb5_int32 for flags. - * krb5_int32 for seq_send. - * krb5_int32 for seq_recv. - * krb5_int32 for established. - * krb5_int32 for big_endian. - * krb5_int32 for nctypes. + * krb5_int64 for seq_send. + * krb5_int64 for seq_recv. + * ... for seqstate + * ... for auth_context + * ... for mech_used + * krb5_int32 for proto + * krb5_int32 for cksumtype + * ... for acceptor_subkey + * krb5_int32 for acceptor_key_cksumtype * krb5_int32 for trailer. */ kret = EINVAL; if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { required = 16*sizeof(krb5_int32); + required += 2*sizeof(krb5_int64); required += sizeof(ctx->seed); kret = 0; @@ -282,6 +325,11 @@ kg_ctx_size(kcontext, arg, sizep) KV5M_AUTH_CONTEXT, (krb5_pointer) ctx->auth_context, &required); + if (!kret && ctx->acceptor_subkey) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->acceptor_subkey, + &required); if (!kret) *sizep += required; } @@ -303,7 +351,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) size_t required; krb5_octet *bp; size_t remain; - int i; krb5int_access kaccess; kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); @@ -324,10 +371,16 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) /* Now static data */ (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags, + (void) krb5_ser_pack_int32((krb5_int32) ctx->established, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init, &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags, + &bp, &remain); (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed, sizeof(ctx->seed), &bp, &remain); @@ -345,10 +398,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->established, - &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, - &bp, &remain); /* Now dynamic data */ kret = 0; @@ -397,8 +446,25 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) (krb5_pointer) ctx->auth_context, &bp, &remain); + if (!kret) + kret = krb5_ser_pack_int32((krb5_int32) ctx->proto, + &bp, &remain); + if (!kret) + kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype, + &bp, &remain); + if (!kret && ctx->acceptor_subkey) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->acceptor_subkey, + &bp, &remain); + if (!kret) + kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype, + &bp, &remain); + + /* trailer */ + if (!kret) + kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); if (!kret) { - (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); *buffer = bp; *lenremain = remain; } @@ -422,7 +488,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) krb5_int32 ibuf; krb5_octet *bp; size_t remain; - int i; krb5int_access kaccess; kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); @@ -439,7 +504,9 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) kret = ENOMEM; /* Get a context */ - if ((remain >= ((10*sizeof(krb5_int32))+sizeof(ctx->seed))) && + if ((remain >= (16*sizeof(krb5_int32) + + 2*sizeof(krb5_int64) + + sizeof(ctx->seed))) && (ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec)))) { memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); @@ -448,9 +515,15 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->initiate = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->gss_flags = (int) ibuf; + ctx->established = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->big_endian = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->have_acceptor_subkey = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->seed_init = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->gss_flags = (int) ibuf; (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed, sizeof(ctx->seed), &bp, &remain); @@ -465,11 +538,11 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->krb_flags = (krb5_flags) ibuf; (void) (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_send, &bp, &remain); - (void) (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_recv, &bp, &remain); - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->established = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->big_endian = (int) ibuf; + kret = (*kaccess.krb5_ser_unpack_int64)(&ctx->seq_recv, &bp, &remain); + if (kret) { + free(ctx); + return kret; + } if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, &remain))) { @@ -530,17 +603,35 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (krb5_pointer *) &ctx->auth_context, &bp, &remain); - /* Get trailer */ + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->proto = ibuf; + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->cksumtype = ibuf; if (!kret && - !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && - (ibuf == KG_CONTEXT)) { + (kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) &ctx->acceptor_subkey, + &bp, &remain))) { + if (kret == EINVAL) + kret = 0; + } + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->acceptor_subkey_cksumtype = ibuf; + + /* Get trailer */ + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (!kret && ibuf != KG_CONTEXT) + kret = EINVAL; + + if (!kret) { *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) ctx; - } - else { - if (!kret && (ibuf != KG_CONTEXT)) - kret = EINVAL; + } else { if (ctx->seq) krb5_free_keyblock(kcontext, ctx->seq); if (ctx->enc) -- 2.26.2