heimdal Add clock-skew handling to DCE-style GSSAPI

The clock skew handling was previously only on properly wrapped
GSSAPI, and was skipped for DCE-style.  This allows the ASN.1 errors
from the krb5_rd_req to suggest parsing as a kerberos error packet.

Andrew Bartlett

Signed-off-by: Love Hornquist Astrand <lha@h5l.org>
This commit is contained in:
Andrew Bartlett
2010-11-08 17:38:38 +11:00
committed by Love Hornquist Astrand
parent f178458310
commit 526aeef0c7

View File

@@ -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);