diff options
author | Cy Schubert <cy@FreeBSD.org> | 2018-04-03 19:36:00 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2018-04-03 19:36:00 +0000 |
commit | b0e4d68d5124581ae353493d69bea352de4cff8a (patch) | |
tree | 43300ec43e83eccd367fd76fdfdefba2dcd7d8f4 /src/lib/gssapi | |
parent | 33a9b234e7087f573ef08cd7318c6497ba08b439 (diff) |
Notes
Diffstat (limited to 'src/lib/gssapi')
39 files changed, 276 insertions, 99 deletions
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h index 9ad44216d05e..9d3a7e736736 100644 --- a/src/lib/gssapi/generic/gssapi_ext.h +++ b/src/lib/gssapi/generic/gssapi_ext.h @@ -575,4 +575,15 @@ gss_import_cred( } #endif +/* + * When used with gss_inquire_sec_context_by_oid(), return a buffer set with + * the first member containing an unsigned 32-bit integer in network byte + * order. This is the Security Strength Factor (SSF) associated with the + * secure channel established by the security context. NOTE: This value is + * made available solely as an indication for use by APIs like Cyrus SASL that + * classify the strength of a secure channel via this number. The strength of + * a channel cannot necessarily be represented by a simple number. + */ +GSS_DLLIMP extern gss_OID GSS_C_SEC_CONTEXT_SASL_SSF; + #endif /* GSSAPI_EXT_H_ */ diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c index 5496aa33582c..fa144c2bf9cc 100644 --- a/src/lib/gssapi/generic/gssapi_generic.c +++ b/src/lib/gssapi/generic/gssapi_generic.c @@ -157,6 +157,13 @@ static const gss_OID_desc const_oids[] = { {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"}, {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"}, {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"}, + + /* + * GSS_SEC_CONTEXT_SASL_SSF_OID 1.2.840.113554.1.2.2.5.15 + * iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) krb5(2) krb5-gssapi-ext(5) sasl-ssf(15) + */ + {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"}, }; /* Here are the constants which point to the static structure above. @@ -218,6 +225,8 @@ GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33; GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34; GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35; +GSS_DLLIMP gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = oids+36; + static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 }; gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc; diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index 580d08cbf53e..06967aa2753a 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -351,8 +351,10 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle, if (mech_type) *mech_type = ctx->mech_used; - if (time_rec) - *time_rec = ctx->krb_times.endtime + ctx->k5_context->clockskew - now; + if (time_rec) { + *time_rec = ts_delta(ctx->krb_times.endtime, now) + + ctx->k5_context->clockskew; + } /* Never return GSS_C_DELEG_FLAG since we don't support DCE credential * delegation yet. */ @@ -1146,7 +1148,7 @@ kg_accept_krb5(minor_status, context_handle, /* Add the maximum allowable clock skew as a grace period for context * expiration, just as we do for the ticket. */ if (time_rec) - *time_rec = ctx->krb_times.endtime + context->clockskew - now; + *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew; if (ret_flags) *ret_flags = ctx->gss_flags; diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 03ee25ec1861..362ba9d86a42 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -550,7 +550,7 @@ set_refresh_time(krb5_context context, krb5_ccache ccache, char buf[128]; krb5_data d; - snprintf(buf, sizeof(buf), "%ld", (long)refresh_time); + snprintf(buf, sizeof(buf), "%u", (unsigned int)ts2tt(refresh_time)); d = string2data(buf); (void)krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, &d); @@ -566,8 +566,9 @@ kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred) if (krb5_timeofday(context, &now)) return FALSE; - if (cred->refresh_time != 0 && now >= cred->refresh_time) { - set_refresh_time(context, cred->ccache, cred->refresh_time + 30); + if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) { + set_refresh_time(context, cred->ccache, + ts_incr(cred->refresh_time, 30)); return TRUE; } return FALSE; @@ -586,7 +587,8 @@ kg_cred_set_initial_refresh(krb5_context context, krb5_gss_cred_id_rec *cred, return; /* Make a note to refresh these when they are halfway to expired. */ - refresh = times->starttime + (times->endtime - times->starttime) / 2; + refresh = ts_incr(times->starttime, + ts_delta(times->endtime, times->starttime) / 2); set_refresh_time(context, cred->ccache, refresh); } @@ -848,7 +850,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, GSS_C_NO_NAME); if (GSS_ERROR(ret)) goto error_out; - *time_rec = (cred->expire > now) ? (cred->expire - now) : 0; + *time_rec = ts_after(cred->expire, now) ? + ts_delta(cred->expire, now) : 0; k5_mutex_unlock(&cred->lock); } } diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c index a18cfb05b743..1fdb5a16f2b4 100644 --- a/src/lib/gssapi/krb5/context_time.c +++ b/src/lib/gssapi/krb5/context_time.c @@ -51,7 +51,10 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) return(GSS_S_FAILURE); } - if ((lifetime = ctx->krb_times.endtime - now) <= 0) { + lifetime = ts_delta(ctx->krb_times.endtime, now); + if (!ctx->initiate) + lifetime += ctx->k5_context->clockskew; + if (lifetime <= 0) { *time_rec = 0; *minor_status = 0; return(GSS_S_CONTEXT_EXPIRED); diff --git a/src/lib/gssapi/krb5/copy_ccache.c b/src/lib/gssapi/krb5/copy_ccache.c index f3d7666135cd..027ed4847476 100644 --- a/src/lib/gssapi/krb5/copy_ccache.c +++ b/src/lib/gssapi/krb5/copy_ccache.c @@ -8,8 +8,6 @@ gss_krb5int_copy_ccache(OM_uint32 *minor_status, const gss_buffer_t value) { krb5_gss_cred_id_t k5creds; - krb5_cc_cursor cursor; - krb5_creds creds; krb5_error_code code; krb5_context context; krb5_ccache out_ccache; @@ -37,7 +35,7 @@ gss_krb5int_copy_ccache(OM_uint32 *minor_status, return GSS_S_FAILURE; } - code = krb5_cc_start_seq_get(context, k5creds->ccache, &cursor); + code = krb5_cc_copy_creds(context, k5creds->ccache, out_ccache); if (code) { k5_mutex_unlock(&k5creds->lock); *minor_status = code; @@ -45,12 +43,6 @@ gss_krb5int_copy_ccache(OM_uint32 *minor_status, krb5_free_context(context); return(GSS_S_FAILURE); } - while (!code && !krb5_cc_next_cred(context, k5creds->ccache, &cursor, - &creds)) { - code = krb5_cc_store_cred(context, out_ccache, &creds); - krb5_free_cred_contents(context, &creds); - } - krb5_cc_end_seq_get(context, k5creds->ccache, &cursor); k5_mutex_unlock(&k5creds->lock); *minor_status = code; if (code) diff --git a/src/lib/gssapi/krb5/export_cred.c b/src/lib/gssapi/krb5/export_cred.c index 652b2604bda3..8054e4a77011 100644 --- a/src/lib/gssapi/krb5/export_cred.c +++ b/src/lib/gssapi/krb5/export_cred.c @@ -410,10 +410,11 @@ json_kgcred(krb5_context context, krb5_gss_cred_id_t cred, if (ret) goto cleanup; - ret = k5_json_array_fmt(&array, "ivvbbvvvvbiivs", cred->usage, name, imp, + ret = k5_json_array_fmt(&array, "ivvbbvvvvbLLvs", cred->usage, name, imp, cred->default_identity, cred->iakerb_mech, keytab, rcache, ccache, ckeytab, cred->have_tgt, - cred->expire, cred->refresh_time, etypes, + (long long)ts2tt(cred->expire), + (long long)ts2tt(cred->refresh_time), etypes, cred->password); if (ret) goto cleanup; diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index d7bdef7e28a3..e92be88b4730 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1144,6 +1144,12 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *, const gss_OID, gss_buffer_set_t *); +#define GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH 11 +#define GET_SEC_CONTEXT_SASL_SSF_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f" +OM_uint32 +gss_krb5int_sec_context_sasl_ssf(OM_uint32 *, const gss_ctx_id_t, + const gss_OID, gss_buffer_set_t *); + #define GSS_KRB5_IMPORT_CRED_OID_LENGTH 11 #define GSS_KRB5_IMPORT_CRED_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0d" @@ -1425,4 +1431,10 @@ iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle, * the format changes. */ #define CRED_EXPORT_MAGIC "K5C1" +OM_uint32 +gss_krb5int_get_cred_impersonator(OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set); + #endif /* _GSSAPIP_KRB5_H_ */ diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 99092ccab16b..43930dd61aa6 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -126,6 +126,8 @@ #define NO_CI_FLAGS_X_OID_LENGTH 6 #define NO_CI_FLAGS_X_OID "\x2a\x85\x70\x2b\x0d\x1d" +#define GET_CRED_IMPERSONATOR_OID_LENGTH 11 +#define GET_CRED_IMPERSONATOR_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0e" const gss_OID_desc krb5_gss_oid_array[] = { /* this is the official, rfc-specified OID */ @@ -148,6 +150,8 @@ const gss_OID_desc krb5_gss_oid_array[] = { /* gss_nt_krb5_principal. Object identifier for a krb5_principal. Do not use. */ {10, "\052\206\110\206\367\022\001\002\002\002"}, {NO_CI_FLAGS_X_OID_LENGTH, NO_CI_FLAGS_X_OID}, + /* this is an inquire cred OID */ + {GET_CRED_IMPERSONATOR_OID_LENGTH, GET_CRED_IMPERSONATOR_OID}, { 0, 0 } }; @@ -164,6 +168,7 @@ const gss_OID gss_nt_krb5_principal = &kg_oids[6]; const gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &kg_oids[5]; const gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &kg_oids[7]; +const gss_OID GSS_KRB5_GET_CRED_IMPERSONATOR = &kg_oids[8]; static const gss_OID_set_desc oidsets[] = { {1, &kg_oids[0]}, /* RFC OID */ @@ -352,6 +357,10 @@ static struct { { {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID}, gss_krb5int_extract_authtime_from_sec_context + }, + { + {GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH, GET_SEC_CONTEXT_SASL_SSF_OID}, + gss_krb5int_sec_context_sasl_ssf } }; @@ -400,13 +409,16 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, /* * gss_inquire_cred_by_oid() methods */ -#if 0 + static struct { gss_OID_desc oid; OM_uint32 (*func)(OM_uint32 *, const gss_cred_id_t, const gss_OID, gss_buffer_set_t *); } krb5_gss_inquire_cred_by_oid_ops[] = { + { + {GET_CRED_IMPERSONATOR_OID_LENGTH, GET_CRED_IMPERSONATOR_OID}, + gss_krb5int_get_cred_impersonator + } }; -#endif static OM_uint32 KRB5_CALLCONV krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status, @@ -415,9 +427,7 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status, gss_buffer_set_t *data_set) { OM_uint32 major_status = GSS_S_FAILURE; -#if 0 size_t i; -#endif if (minor_status == NULL) return GSS_S_CALL_INACCESSIBLE_WRITE; @@ -440,7 +450,6 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status, if (GSS_ERROR(major_status)) return major_status; -#if 0 for (i = 0; i < sizeof(krb5_gss_inquire_cred_by_oid_ops)/ sizeof(krb5_gss_inquire_cred_by_oid_ops[0]); i++) { if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_cred_by_oid_ops[i].oid)) { @@ -450,7 +459,6 @@ krb5_gss_inquire_cred_by_oid(OM_uint32 *minor_status, data_set); } } -#endif *minor_status = EINVAL; diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h index 390b00032cce..e145eec3b44c 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.h +++ b/src/lib/gssapi/krb5/gssapi_krb5.h @@ -96,6 +96,15 @@ GSS_DLLIMP extern const gss_OID_desc krb5_gss_oid_array[]; */ GSS_DLLIMP extern const gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X; +/* + * This OID can be used with gss_inquire_cred_by_oid(0 to retrieve the + * impersonator name (if any). + * + * iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5-gssapi-ext(5) get-cred-impersonator(14) + */ +GSS_DLLIMP extern const gss_OID GSS_KRB5_GET_CRED_IMPERSONATOR; + #define gss_krb5_nt_general_name gss_nt_krb5_name #define gss_krb5_nt_principal gss_nt_krb5_principal #define gss_krb5_nt_service_name gss_nt_service_name @@ -169,6 +178,11 @@ OM_uint32 KRB5_CALLCONV gss_krb5_get_tkt_flags( gss_ctx_id_t context_handle, krb5_flags *ticket_flags); +/* + * Copy krb5 creds from cred_handle into out_ccache, which must already be + * initialized. Use gss_store_cred_into() (new in krb5 1.11) instead, if + * possible. + */ OM_uint32 KRB5_CALLCONV gss_krb5_copy_ccache( OM_uint32 *minor_status, gss_cred_id_t cred_handle, diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c index 2dc4d0c1a4d5..bb1072fe4ac7 100644 --- a/src/lib/gssapi/krb5/iakerb.c +++ b/src/lib/gssapi/krb5/iakerb.c @@ -494,7 +494,7 @@ iakerb_tkt_creds_ctx(iakerb_ctx_id_t ctx, if (code != 0) goto cleanup; - creds.times.endtime = now + time_req; + creds.times.endtime = ts_incr(now, time_req); } if (cred->name->ad_context != NULL) { @@ -669,7 +669,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx, if (code != 0) goto cleanup; - in_creds.times.endtime = now + time_req; + in_creds.times.endtime = ts_incr(now, time_req); } /* Make an AS request if we have no creds or it's time to refresh them. */ diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 70f7955ae1ae..1be1b5878400 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -214,7 +214,8 @@ static krb5_error_code get_credentials(context, cred, server, now, * boundaries) because accept_sec_context code is also similarly * non-forgiving. */ - if (!krb5_gss_dbg_client_expcreds && result_creds->times.endtime < now) { + if (!krb5_gss_dbg_client_expcreds && + ts_after(now, result_creds->times.endtime)) { code = KRB5KRB_AP_ERR_TKT_EXPIRED; goto cleanup; } @@ -355,9 +356,6 @@ make_gss_checksum (krb5_context context, krb5_auth_context auth_context, TWRITE_STR(ptr, data->md5.contents, data->md5.length); TWRITE_INT(ptr, data->ctx->gss_flags, 0); - /* done with this, free it */ - xfree(data->md5.contents); - if (credmsg.data) { TWRITE_INT16(ptr, KRB5_GSS_FOR_CREDS_OPTION, 0); TWRITE_INT16(ptr, credmsg.length, 0); @@ -429,6 +427,7 @@ make_ap_req_v1(context, ctx, cred, k_cred, ad_context, code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, NULL, k_cred, &ap_req); krb5_auth_con_set_authdata_context(context, ctx->auth_context, NULL); + krb5_free_checksum_contents(context, &cksum_struct.md5); krb5_free_data_contents(context, &cksum_struct.checksum_data); if (code) goto cleanup; @@ -575,7 +574,7 @@ kg_new_connection( if (time_req == 0 || time_req == GSS_C_INDEFINITE) { ctx->krb_times.endtime = 0; } else { - ctx->krb_times.endtime = now + time_req; + ctx->krb_times.endtime = ts_incr(now, time_req); } if ((code = kg_duplicate_name(context, cred->name, &ctx->here))) @@ -659,7 +658,7 @@ kg_new_connection( if (time_rec) { if ((code = krb5_timeofday(context, &now))) goto cleanup; - *time_rec = ctx->krb_times.endtime - now; + *time_rec = ts_delta(ctx->krb_times.endtime, now); } /* set the other returns */ @@ -873,7 +872,7 @@ mutual_auth( if (time_rec) { if ((code = krb5_timeofday(context, &now))) goto fail; - *time_rec = ctx->krb_times.endtime - now; + *time_rec = ts_delta(ctx->krb_times.endtime, now); } if (ret_flags) diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c index 9024b3c7ea9c..cac024da1f01 100644 --- a/src/lib/gssapi/krb5/inq_context.c +++ b/src/lib/gssapi/krb5/inq_context.c @@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, /* Add the maximum allowable clock skew as a grace period for context * expiration, just as we do for the ticket during authentication. */ - lifetime = ctx->krb_times.endtime - now; + lifetime = ts_delta(ctx->krb_times.endtime, now); if (!ctx->initiate) lifetime += context->clockskew; if (lifetime < 0) @@ -310,3 +310,30 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); } + +OM_uint32 +gss_krb5int_sec_context_sasl_ssf(OM_uint32 *minor_status, + const gss_ctx_id_t context_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + krb5_gss_ctx_id_rec *ctx; + krb5_key key; + krb5_error_code code; + gss_buffer_desc ssfbuf; + unsigned int ssf; + uint8_t buf[4]; + + ctx = (krb5_gss_ctx_id_rec *)context_handle; + key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; + + code = k5_enctype_to_ssf(key->keyblock.enctype, &ssf); + if (code) + return GSS_S_FAILURE; + + store_32_be(ssf, buf); + ssfbuf.value = buf; + ssfbuf.length = sizeof(buf); + + return generic_gss_add_buffer_set_member(minor_status, &ssfbuf, data_set); +} diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index 4e35a056316f..3a73417c083d 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -130,8 +130,9 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, goto fail; } - if (cred->expire > 0) { - if ((lifetime = cred->expire - now) < 0) + if (cred->expire != 0) { + lifetime = ts_delta(cred->expire, now); + if (lifetime < 0) lifetime = 0; } else @@ -245,3 +246,44 @@ krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, } return(mstat); } + +OM_uint32 +gss_krb5int_get_cred_impersonator(OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + const gss_OID desired_object, + gss_buffer_set_t *data_set) +{ + krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t)cred_handle; + gss_buffer_desc rep = GSS_C_EMPTY_BUFFER; + krb5_context context = NULL; + char *impersonator = NULL; + krb5_error_code ret; + OM_uint32 major; + + *data_set = GSS_C_NO_BUFFER_SET; + + /* Return an empty buffer set if no impersonator is present */ + if (cred->impersonator == NULL) + return generic_gss_create_empty_buffer_set(minor_status, data_set); + + ret = krb5_gss_init_context(&context); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_unparse_name(context, cred->impersonator, &impersonator); + if (ret) { + krb5_free_context(context); + *minor_status = ret; + return GSS_S_FAILURE; + } + + rep.value = impersonator; + rep.length = strlen(impersonator); + major = generic_gss_add_buffer_set_member(minor_status, &rep, data_set); + + krb5_free_unparsed_name(context, impersonator); + krb5_free_context(context); + return major; +} diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c index 1a5c14c2713b..25d9f2711825 100644 --- a/src/lib/gssapi/krb5/k5sealv3.c +++ b/src/lib/gssapi/krb5/k5sealv3.c @@ -110,6 +110,7 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, krb5_data plain; krb5_enc_data cipher; size_t ec_max; + size_t encrypt_size; /* 300: Adds some slop. */ if (SIZE_MAX - 300 < message->length) @@ -128,7 +129,12 @@ gss_krb5int_make_seal_token_v3 (krb5_context context, return err; /* Get size of ciphertext. */ - bufsize = 16 + krb5_encrypt_size (plain.length, key->keyblock.enctype); + encrypt_size = krb5_encrypt_size(plain.length, key->keyblock.enctype); + if (encrypt_size > SIZE_MAX / 2) { + err = ENOMEM; + goto error; + } + bufsize = 16 + encrypt_size; /* Allocate space for header plus encrypted data. */ outbuf = gssalloc_malloc(bufsize); if (outbuf == NULL) { @@ -301,7 +307,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr, int *conf_state, gss_qop_t *qop_state, int toktype) { krb5_context context = *contextptr; - krb5_data plain; + krb5_data plain = empty_data(); uint64_t seqnum; size_t ec, rrc; int key_usage; diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 26a2d33e7a2c..57720c2eab98 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -219,7 +219,7 @@ kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, plainlen = tmsglen; conflen = kg_confounder_size(context, ctx->enc->keyblock.enctype); - if (tmsglen < conflen) { + if (tmsglen < (size_t)conflen) { if (sealalg != 0xffff) xfree(plain); *minor_status = 0; diff --git a/src/lib/gssapi/krb5/naming_exts.c b/src/lib/gssapi/krb5/naming_exts.c index 6062a6dd8052..5f00efe346e3 100644 --- a/src/lib/gssapi/krb5/naming_exts.c +++ b/src/lib/gssapi/krb5/naming_exts.c @@ -261,8 +261,7 @@ krb5_gss_inquire_name(OM_uint32 *minor_status, krb5_gss_name_t kname; krb5_data *kattrs = NULL; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; if (attrs != NULL) *attrs = GSS_C_NO_BUFFER_SET; @@ -319,11 +318,10 @@ krb5_gss_get_name_attribute(OM_uint32 *minor_status, krb5_data kattr; krb5_boolean kauthenticated; krb5_boolean kcomplete; - krb5_data kvalue; - krb5_data kdisplay_value; + krb5_data kvalue = empty_data(); + krb5_data kdisplay_value = empty_data(); - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { @@ -355,8 +353,8 @@ krb5_gss_get_name_attribute(OM_uint32 *minor_status, &kattr, &kauthenticated, &kcomplete, - value ? &kvalue : NULL, - display_value ? &kdisplay_value : NULL, + &kvalue, + &kdisplay_value, more); if (code == 0) { if (value != NULL) @@ -367,14 +365,13 @@ krb5_gss_get_name_attribute(OM_uint32 *minor_status, if (complete != NULL) *complete = kcomplete; - if (display_value != NULL) { - if (code == 0) - code = data_to_gss(&kdisplay_value, display_value); - else - free(kdisplay_value.data); - } + if (display_value != NULL && code == 0) + code = data_to_gss(&kdisplay_value, display_value); } + free(kdisplay_value.data); + free(kvalue.data); + k5_mutex_unlock(&kname->lock); krb5_free_context(context); @@ -394,8 +391,7 @@ krb5_gss_set_name_attribute(OM_uint32 *minor_status, krb5_data kattr; krb5_data kvalue; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { @@ -444,8 +440,7 @@ krb5_gss_delete_name_attribute(OM_uint32 *minor_status, krb5_gss_name_t kname; krb5_data kattr; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { @@ -491,8 +486,7 @@ krb5_gss_map_name_to_any(OM_uint32 *minor_status, krb5_gss_name_t kname; char *kmodule; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { @@ -543,8 +537,7 @@ krb5_gss_release_any_name_mapping(OM_uint32 *minor_status, krb5_gss_name_t kname; char *kmodule; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { @@ -599,8 +592,7 @@ krb5_gss_export_name_composite(OM_uint32 *minor_status, unsigned char *cp; size_t princlen; - if (minor_status != NULL) - *minor_status = 0; + *minor_status = 0; code = krb5_gss_init_context(&context); if (code != 0) { diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c index ff1c310bce5e..10848c1df810 100644 --- a/src/lib/gssapi/krb5/s4u_gss_glue.c +++ b/src/lib/gssapi/krb5/s4u_gss_glue.c @@ -284,7 +284,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status, if (code != 0) goto cleanup; - *time_rec = cred->expire - now; + *time_rec = ts_delta(cred->expire, now); } major_status = GSS_S_COMPLETE; diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports index 9facb3f42671..b07f69fd1572 100644 --- a/src/lib/gssapi/libgssapi_krb5.exports +++ b/src/lib/gssapi/libgssapi_krb5.exports @@ -10,6 +10,7 @@ GSS_C_NT_STRING_UID_NAME GSS_C_NT_USER_NAME GSS_KRB5_NT_PRINCIPAL_NAME GSS_KRB5_CRED_NO_CI_FLAGS_X +GSS_KRB5_GET_CRED_IMPERSONATOR GSS_C_MA_MECH_CONCRETE GSS_C_MA_MECH_PSEUDO GSS_C_MA_MECH_COMPOSITE @@ -37,6 +38,7 @@ GSS_C_MA_CBINDINGS GSS_C_MA_PFS GSS_C_MA_COMPRESS GSS_C_MA_CTX_TRANS +GSS_C_SEC_CONTEXT_SASL_SSF gss_accept_sec_context gss_acquire_cred gss_acquire_cred_with_password diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c index ddaf87412e9e..f28e2b14a903 100644 --- a/src/lib/gssapi/mechglue/g_accept_sec_context.c +++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c @@ -216,6 +216,8 @@ gss_cred_id_t * d_cred; } else { union_ctx_id = (gss_union_ctx_id_t)*context_handle; selected_mech = union_ctx_id->mech_type; + if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); } /* Now create a new context if we didn't get one. */ @@ -234,9 +236,6 @@ gss_cred_id_t * d_cred; free(union_ctx_id); return (status); } - - /* set the new context handle to caller's data */ - *context_handle = (gss_ctx_id_t)union_ctx_id; } /* @@ -277,8 +276,10 @@ gss_cred_id_t * d_cred; d_cred ? &tmp_d_cred : NULL); /* If there's more work to do, keep going... */ - if (status == GSS_S_CONTINUE_NEEDED) + if (status == GSS_S_CONTINUE_NEEDED) { + *context_handle = (gss_ctx_id_t)union_ctx_id; return GSS_S_CONTINUE_NEEDED; + } /* if the call failed, return with failure */ if (status != GSS_S_COMPLETE) { @@ -364,14 +365,22 @@ gss_cred_id_t * d_cred; *mech_type = gssint_get_public_oid(actual_mech); if (ret_flags != NULL) *ret_flags = temp_ret_flags; - return (status); + *context_handle = (gss_ctx_id_t)union_ctx_id; + return GSS_S_COMPLETE; } else { status = GSS_S_BAD_MECH; } error_out: - if (union_ctx_id) { + /* + * RFC 2744 5.1 requires that we not create a context on a failed first + * call to accept, and recommends that on a failed subsequent call we + * make the caller responsible for calling gss_delete_sec_context. + * Even if the mech deleted its context, keep the union context around + * for the caller to delete. + */ + if (union_ctx_id && *context_handle == GSS_C_NO_CONTEXT) { if (union_ctx_id->mech_type) { if (union_ctx_id->mech_type->elements) free(union_ctx_id->mech_type->elements); @@ -384,7 +393,6 @@ error_out: GSS_C_NO_BUFFER); } free(union_ctx_id); - *context_handle = GSS_C_NO_CONTEXT; } if (src_name) diff --git a/src/lib/gssapi/mechglue/g_complete_auth_token.c b/src/lib/gssapi/mechglue/g_complete_auth_token.c index 91815513017f..4bcb47e84b90 100644 --- a/src/lib/gssapi/mechglue/g_complete_auth_token.c +++ b/src/lib/gssapi/mechglue/g_complete_auth_token.c @@ -52,6 +52,8 @@ gss_complete_auth_token (OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism (ctx->mech_type); if (mech != NULL) { diff --git a/src/lib/gssapi/mechglue/g_context_time.c b/src/lib/gssapi/mechglue/g_context_time.c index 2ff8d0996ef0..c947e7646c10 100644 --- a/src/lib/gssapi/mechglue/g_context_time.c +++ b/src/lib/gssapi/mechglue/g_context_time.c @@ -58,6 +58,8 @@ OM_uint32 * time_rec; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_delete_sec_context.c b/src/lib/gssapi/mechglue/g_delete_sec_context.c index 4bf0dec5ce33..574ff02944b0 100644 --- a/src/lib/gssapi/mechglue/g_delete_sec_context.c +++ b/src/lib/gssapi/mechglue/g_delete_sec_context.c @@ -87,12 +87,14 @@ gss_buffer_t output_token; if (GSSINT_CHK_LOOP(ctx)) return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT); - status = gssint_delete_internal_sec_context(minor_status, - ctx->mech_type, - &ctx->internal_ctx_id, - output_token); - if (status) - return status; + if (ctx->internal_ctx_id != GSS_C_NO_CONTEXT) { + status = gssint_delete_internal_sec_context(minor_status, + ctx->mech_type, + &ctx->internal_ctx_id, + output_token); + if (status) + return status; + } /* now free up the space for the union context structure */ free(ctx->mech_type->elements); diff --git a/src/lib/gssapi/mechglue/g_dup_name.c b/src/lib/gssapi/mechglue/g_dup_name.c index 85306fcc1913..cc824fdf99b8 100644 --- a/src/lib/gssapi/mechglue/g_dup_name.c +++ b/src/lib/gssapi/mechglue/g_dup_name.c @@ -126,7 +126,7 @@ allocation_failure: if (dest_union->external_name) { if (dest_union->external_name->value) free(dest_union->external_name->value); - free(dest_union->external_name); + free(dest_union->external_name); } if (dest_union->name_type) (void) generic_gss_release_oid(minor_status, diff --git a/src/lib/gssapi/mechglue/g_exp_sec_context.c b/src/lib/gssapi/mechglue/g_exp_sec_context.c index b63745299f64..1d7990b1ca28 100644 --- a/src/lib/gssapi/mechglue/g_exp_sec_context.c +++ b/src/lib/gssapi/mechglue/g_exp_sec_context.c @@ -95,6 +95,8 @@ gss_buffer_t interprocess_token; */ ctx = (gss_union_ctx_id_t) *context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) return GSS_S_BAD_MECH; diff --git a/src/lib/gssapi/mechglue/g_glue.c b/src/lib/gssapi/mechglue/g_glue.c index 4aa3591a0d06..4cd2e8f8eb8c 100644 --- a/src/lib/gssapi/mechglue/g_glue.c +++ b/src/lib/gssapi/mechglue/g_glue.c @@ -189,7 +189,7 @@ OM_uint32 gssint_get_mech_type_oid(OID, token) gss_buffer_t token; { unsigned char * buffer_ptr; - int length; + size_t buflen, lenbytes, length, oidlen; /* * This routine reads the prefix of "token" in order to determine @@ -223,25 +223,33 @@ OM_uint32 gssint_get_mech_type_oid(OID, token) /* Skip past the APP/Sequnce byte and the token length */ buffer_ptr = (unsigned char *) token->value; + buflen = token->length; - if (*(buffer_ptr++) != 0x60) + if (buflen < 2 || *buffer_ptr++ != 0x60) return (GSS_S_DEFECTIVE_TOKEN); length = *buffer_ptr++; + buflen -= 2; /* check if token length is null */ if (length == 0) return (GSS_S_DEFECTIVE_TOKEN); if (length & 0x80) { - if ((length & 0x7f) > 4) + lenbytes = length & 0x7f; + if (lenbytes > 4 || lenbytes > buflen) return (GSS_S_DEFECTIVE_TOKEN); - buffer_ptr += length & 0x7f; + buffer_ptr += lenbytes; + buflen -= lenbytes; } - if (*(buffer_ptr++) != 0x06) + if (buflen < 2 || *buffer_ptr++ != 0x06) + return (GSS_S_DEFECTIVE_TOKEN); + oidlen = *buffer_ptr++; + buflen -= 2; + if (oidlen > 0x7f || oidlen > buflen) return (GSS_S_DEFECTIVE_TOKEN); - OID->length = (OM_uint32) *(buffer_ptr++); + OID->length = oidlen; OID->elements = (void *) buffer_ptr; return (GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c index 9f154b8936d0..e2df1ce261d7 100644 --- a/src/lib/gssapi/mechglue/g_init_sec_context.c +++ b/src/lib/gssapi/mechglue/g_init_sec_context.c @@ -192,8 +192,13 @@ OM_uint32 * time_rec; /* copy the supplied context handle */ union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT; - } else + } else { union_ctx_id = (gss_union_ctx_id_t)*context_handle; + if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) { + status = GSS_S_NO_CONTEXT; + goto end; + } + } /* * get the appropriate cred handle from the union cred struct. @@ -224,15 +229,13 @@ OM_uint32 * time_rec; if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) { /* - * The spec says the preferred method is to delete all context info on - * the first call to init, and on all subsequent calls make the caller - * responsible for calling gss_delete_sec_context. However, if the - * mechanism decided to delete the internal context, we should also - * delete the union context. + * RFC 2744 5.19 requires that we not create a context on a failed + * first call to init, and recommends that on a failed subsequent call + * we make the caller responsible for calling gss_delete_sec_context. + * Even if the mech deleted its context, keep the union context around + * for the caller to delete. */ map_error(minor_status, mech); - if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT) - *context_handle = GSS_C_NO_CONTEXT; if (*context_handle == GSS_C_NO_CONTEXT) { free(union_ctx_id->mech_type->elements); free(union_ctx_id->mech_type); diff --git a/src/lib/gssapi/mechglue/g_inq_context.c b/src/lib/gssapi/mechglue/g_inq_context.c index 6f1c71eede9d..6c0d98dd3348 100644 --- a/src/lib/gssapi/mechglue/g_inq_context.c +++ b/src/lib/gssapi/mechglue/g_inq_context.c @@ -104,6 +104,8 @@ gss_inquire_context( */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech || !mech->gss_inquire_context || !mech->gss_display_name || diff --git a/src/lib/gssapi/mechglue/g_inq_cred_oid.c b/src/lib/gssapi/mechglue/g_inq_cred_oid.c index 4c23dfcbd364..df51b44e9a5b 100644 --- a/src/lib/gssapi/mechglue/g_inq_cred_oid.c +++ b/src/lib/gssapi/mechglue/g_inq_cred_oid.c @@ -85,11 +85,6 @@ gss_inquire_cred_by_oid(OM_uint32 *minor_status, union_cred = (gss_union_cred_t) cred_handle; - status = gss_create_empty_buffer_set(minor_status, &ret_set); - if (status != GSS_S_COMPLETE) { - return status; - } - status = GSS_S_UNAVAILABLE; for (i = 0; i < union_cred->count; i++) { diff --git a/src/lib/gssapi/mechglue/g_prf.c b/src/lib/gssapi/mechglue/g_prf.c index fcca3e44c4c0..9e168adfe0d6 100644 --- a/src/lib/gssapi/mechglue/g_prf.c +++ b/src/lib/gssapi/mechglue/g_prf.c @@ -59,6 +59,8 @@ gss_pseudo_random (OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism (ctx->mech_type); if (mech != NULL) { diff --git a/src/lib/gssapi/mechglue/g_process_context.c b/src/lib/gssapi/mechglue/g_process_context.c index bc260aeb10b2..3968b5d9c675 100644 --- a/src/lib/gssapi/mechglue/g_process_context.c +++ b/src/lib/gssapi/mechglue/g_process_context.c @@ -61,6 +61,8 @@ gss_buffer_t token_buffer; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_seal.c b/src/lib/gssapi/mechglue/g_seal.c index f17241c90891..3db1ee095b39 100644 --- a/src/lib/gssapi/mechglue/g_seal.c +++ b/src/lib/gssapi/mechglue/g_seal.c @@ -92,6 +92,8 @@ gss_wrap( OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -226,6 +228,8 @@ gss_wrap_size_limit(OM_uint32 *minor_status, */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) diff --git a/src/lib/gssapi/mechglue/g_sign.c b/src/lib/gssapi/mechglue/g_sign.c index 86d641aa2e28..03fbd8c01f36 100644 --- a/src/lib/gssapi/mechglue/g_sign.c +++ b/src/lib/gssapi/mechglue/g_sign.c @@ -94,6 +94,8 @@ gss_buffer_t msg_token; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_unseal.c b/src/lib/gssapi/mechglue/g_unseal.c index 3e8053c6e9af..c208635b676a 100644 --- a/src/lib/gssapi/mechglue/g_unseal.c +++ b/src/lib/gssapi/mechglue/g_unseal.c @@ -76,6 +76,8 @@ gss_qop_t * qop_state; * call it. */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_unwrap_aead.c b/src/lib/gssapi/mechglue/g_unwrap_aead.c index e78bff2d3289..0682bd899820 100644 --- a/src/lib/gssapi/mechglue/g_unwrap_aead.c +++ b/src/lib/gssapi/mechglue/g_unwrap_aead.c @@ -186,6 +186,8 @@ gss_qop_t *qop_state; * call it. */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) diff --git a/src/lib/gssapi/mechglue/g_unwrap_iov.c b/src/lib/gssapi/mechglue/g_unwrap_iov.c index c0dd314b1be8..599be2c7b2fc 100644 --- a/src/lib/gssapi/mechglue/g_unwrap_iov.c +++ b/src/lib/gssapi/mechglue/g_unwrap_iov.c @@ -89,6 +89,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -128,6 +130,8 @@ gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; diff --git a/src/lib/gssapi/mechglue/g_verify.c b/src/lib/gssapi/mechglue/g_verify.c index 1578ae111092..8996fce8d596 100644 --- a/src/lib/gssapi/mechglue/g_verify.c +++ b/src/lib/gssapi/mechglue/g_verify.c @@ -65,6 +65,8 @@ gss_qop_t * qop_state; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { diff --git a/src/lib/gssapi/mechglue/g_wrap_aead.c b/src/lib/gssapi/mechglue/g_wrap_aead.c index 96cdf3ce6ab8..7fe3b7b35bda 100644 --- a/src/lib/gssapi/mechglue/g_wrap_aead.c +++ b/src/lib/gssapi/mechglue/g_wrap_aead.c @@ -256,6 +256,8 @@ gss_buffer_t output_message_buffer; * call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (!mech) return (GSS_S_BAD_MECH); diff --git a/src/lib/gssapi/mechglue/g_wrap_iov.c b/src/lib/gssapi/mechglue/g_wrap_iov.c index 40cd98fc91cd..14447c4ee1ad 100644 --- a/src/lib/gssapi/mechglue/g_wrap_iov.c +++ b/src/lib/gssapi/mechglue/g_wrap_iov.c @@ -93,6 +93,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -151,6 +153,8 @@ int iov_count; */ ctx = (gss_union_ctx_id_t) context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); mech = gssint_get_mechanism (ctx->mech_type); if (mech) { @@ -190,6 +194,8 @@ gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; @@ -218,6 +224,8 @@ gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, /* Select the approprate underlying mechanism routine and call it. */ ctx = (gss_union_ctx_id_t)context_handle; + if (ctx->internal_ctx_id == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; mech = gssint_get_mechanism(ctx->mech_type); if (mech == NULL) return GSS_S_BAD_MECH; |