diff --git a/lib/asn1/krb5.asn1 b/lib/asn1/krb5.asn1 index 42a4bd59a..6916e25f6 100644 --- a/lib/asn1/krb5.asn1 +++ b/lib/asn1/krb5.asn1 @@ -213,6 +213,7 @@ AUTHDATA-TYPE ::= INTEGER { KRB5-AUTHDATA-SIGNTICKET-OLDER(-17), KRB5-AUTHDATA-SIGNTICKET-OLD(142), KRB5-AUTHDATA-SIGNTICKET(512), + KRB5-AUTHDATA-AP-OPTIONS(143), -- N.B. these assignments have not been confirmed yet. -- -- DO NOT USE in production yet! diff --git a/lib/gssapi/krb5/8003.c b/lib/gssapi/krb5/8003.c index 777da59a7..36c2a9a44 100644 --- a/lib/gssapi/krb5/8003.c +++ b/lib/gssapi/krb5/8003.c @@ -163,6 +163,50 @@ _gsskrb5_create_8003_checksum ( return GSS_S_COMPLETE; } +static krb5_error_code +check_ap_options_cbt(void *ad_data, size_t ad_len, + krb5_boolean *client_asserted_cb) +{ + uint32_t ad_ap_options; + + *client_asserted_cb = FALSE; + + if (ad_len != sizeof(uint32_t)) + return KRB5KRB_AP_ERR_MSG_TYPE; + + _gss_mg_decode_le_uint32(ad_data, &ad_ap_options); + + if (ad_ap_options & KERB_AP_OPTIONS_CBT) + *client_asserted_cb = TRUE; + + return 0; +} + +static krb5_error_code +find_ap_options(krb5_context context, + krb5_authenticator authenticator, + krb5_boolean *client_asserted_cb) +{ + krb5_error_code ret; + krb5_authdata *ad; + krb5_data data; + + *client_asserted_cb = FALSE; + + ad = authenticator->authorization_data; + if (ad == NULL) + return 0; + + ret = _krb5_get_ad(context, ad, NULL, KRB5_AUTHDATA_AP_OPTIONS, &data); + if (ret) + return ret == ENOENT ? 0 : ret; + + ret = check_ap_options_cbt(data.data, data.length, client_asserted_cb); + krb5_data_free(&data); + + return ret; +} + /* * verify the checksum in `cksum' over `input_chan_bindings' * returning `flags' and `fwd_data' @@ -170,9 +214,10 @@ _gsskrb5_create_8003_checksum ( OM_uint32 _gsskrb5_verify_8003_checksum( + krb5_context context, OM_uint32 *minor_status, const gss_channel_bindings_t input_chan_bindings, - const Checksum *cksum, + krb5_authenticator authenticator, OM_uint32 *flags, krb5_data *fwd_data) { @@ -182,6 +227,9 @@ _gsskrb5_verify_8003_checksum( int DlgOpt; static unsigned char zeros[16]; krb5_boolean channel_bound = FALSE; + const Checksum *cksum = authenticator->cksum; + krb5_boolean client_asserted_cb; + krb5_error_code ret; /* XXX should handle checksums > 24 bytes */ if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) { @@ -198,8 +246,14 @@ _gsskrb5_verify_8003_checksum( p += 4; + ret = find_ap_options(context, authenticator, &client_asserted_cb); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS - && memcmp(p, zeros, sizeof(zeros)) != 0) { + && (memcmp(p, zeros, sizeof(zeros)) != 0 || client_asserted_cb)) { if(hash_input_chan_bindings(input_chan_bindings, hash) != 0) { *minor_status = 0; return GSS_S_BAD_BINDINGS; diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index 6cb199e87..171c143d1 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -566,9 +566,10 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, if (authenticator->cksum != NULL && authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) { - ret = _gsskrb5_verify_8003_checksum(minor_status, + ret = _gsskrb5_verify_8003_checksum(context, + minor_status, input_chan_bindings, - authenticator->cksum, + authenticator, &ctx->flags, &ctx->fwd_data); diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h index e0651e591..8130412e2 100644 --- a/lib/krb5/krb5_locl.h +++ b/lib/krb5/krb5_locl.h @@ -391,4 +391,7 @@ struct krb5_pk_init_ctx_data { # define ISPATHSEP(x) (x == '/') #endif +/* Flag in KRB5_AUTHDATA_AP_OPTIONS */ +#define KERB_AP_OPTIONS_CBT 0x00004000 + #endif /* __KRB5_LOCL_H__ */ diff --git a/lib/krb5/libkrb5-exports.def.in b/lib/krb5/libkrb5-exports.def.in index 73b6f1a94..4bfcaf0a5 100644 --- a/lib/krb5/libkrb5-exports.def.in +++ b/lib/krb5/libkrb5-exports.def.in @@ -788,6 +788,7 @@ EXPORTS _krb5_kt_client_default_name _krb5_have_debug _krb5_SP800_108_HMAC_KDF + _krb5_get_ad ; Shared with libkadm5 _krb5_load_plugins diff --git a/lib/krb5/version-script.map b/lib/krb5/version-script.map index 056ad1058..158e2ce61 100644 --- a/lib/krb5/version-script.map +++ b/lib/krb5/version-script.map @@ -780,6 +780,7 @@ HEIMDAL_KRB5_2.0 { _krb5_kt_client_default_name; _krb5_have_debug; _krb5_SP800_108_HMAC_KDF; + _krb5_get_ad; # Shared with libkadm5 _krb5_load_plugins;