diff options
-rw-r--r-- | source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 104 |
1 files changed, 65 insertions, 39 deletions
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index f4e103a7a5..4538a5376e 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -698,6 +698,44 @@ failure: return ret; } +static krb5_error_code +handle_error_packet(krb5_context context, + gsskrb5_ctx ctx, + krb5_data indata) +{ + krb5_error_code kret; + KRB_ERROR error; + + kret = krb5_rd_error(context, &indata, &error); + if (kret == 0) { + kret = krb5_error_from_rd_error(context, &error, NULL); + + /* save the time skrew for this host */ + if (kret == KRB5KRB_AP_ERR_SKEW) { + krb5_data timedata; + unsigned char p[4]; + int32_t t = error.stime - time(NULL); + + p[0] = (t >> 24) & 0xFF; + p[1] = (t >> 16) & 0xFF; + p[2] = (t >> 8) & 0xFF; + p[3] = (t >> 0) & 0xFF; + + timedata.data = p; + timedata.length = sizeof(p); + + krb5_cc_set_config(context, ctx->ccache, ctx->target, + "time-offset", &timedata); + + if ((ctx->more_flags & RETRIED) == 0) + ctx->state = INITIATOR_RESTART; + ctx->more_flags |= RETRIED; + } + free_KRB_ERROR (&error); + } + return kret; +} + static OM_uint32 repl_mutual @@ -730,6 +768,24 @@ repl_mutual /* There is no OID wrapping. */ indata.length = input_token->length; indata.data = input_token->value; + kret = krb5_rd_rep (context, + ctx->auth_context, + &indata, + &repl); + if (kret >= ASN1_BAD_TIMEFORMAT && kret <= ASN1_INDEF_EXTRA_DATA) { + ret = _gsskrb5_decapsulate (minor_status, + input_token, + &indata, + "\x03\x00", + GSS_KRB5_MECHANISM); + if (ret == GSS_S_COMPLETE) { + *minor_status = handle_error_packet(context, ctx, indata); + return GSS_S_FAILURE; + } + } else if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; + } } else { ret = _gsskrb5_decapsulate (minor_status, input_token, @@ -744,50 +800,20 @@ repl_mutual "\x03\x00", GSS_KRB5_MECHANISM); if (ret == GSS_S_COMPLETE) { - KRB_ERROR error; - - kret = krb5_rd_error(context, &indata, &error); - if (kret == 0) { - kret = krb5_error_from_rd_error(context, &error, NULL); - - /* save the time skrew for this host */ - if (kret == KRB5KRB_AP_ERR_SKEW) { - krb5_data timedata; - unsigned char p[4]; - int32_t t = error.stime - time(NULL); - - p[0] = (t >> 24) & 0xFF; - p[1] = (t >> 16) & 0xFF; - p[2] = (t >> 8) & 0xFF; - p[3] = (t >> 0) & 0xFF; - - timedata.data = p; - timedata.length = sizeof(p); - - krb5_cc_set_config(context, ctx->ccache, ctx->target, - "time-offset", &timedata); - - if ((ctx->more_flags & RETRIED) == 0) - ctx->state = INITIATOR_RESTART; - ctx->more_flags |= RETRIED; - } - free_KRB_ERROR (&error); - } - *minor_status = kret; + *minor_status = handle_error_packet(context, ctx, indata); return GSS_S_FAILURE; } - return ret; + } + kret = krb5_rd_rep (context, + ctx->auth_context, + &indata, + &repl); + if (kret) { + *minor_status = kret; + return GSS_S_FAILURE; } } - kret = krb5_rd_rep (context, - ctx->auth_context, - &indata, - &repl); - if (kret) { - *minor_status = kret; - return GSS_S_FAILURE; - } krb5_free_ap_rep_enc_part (context, repl); |