diff options
| author | Andrew Bartlett <abartlet@samba.org> | 2010-11-08 17:38:38 +1100 | 
|---|---|---|
| committer | Andrew Tridgell <tridge@samba.org> | 2010-11-08 07:58:09 +0000 | 
| commit | cb3d6c407e9ab3e5e8dffeae5e2e77769056d75a (patch) | |
| tree | 5d329574bbc794a68051af5e5f4350d7a8c30cd9 /source4/heimdal/lib/gssapi | |
| parent | 10c82d0619f71e8c6dac5755d2b327c2a543cca4 (diff) | |
| download | samba-cb3d6c407e9ab3e5e8dffeae5e2e77769056d75a.tar.gz samba-cb3d6c407e9ab3e5e8dffeae5e2e77769056d75a.tar.bz2 samba-cb3d6c407e9ab3e5e8dffeae5e2e77769056d75a.zip  | |
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
Autobuild-User: Andrew Tridgell <tridge@samba.org>
Autobuild-Date: Mon Nov  8 07:58:09 UTC 2010 on sn-devel-104
Diffstat (limited to 'source4/heimdal/lib/gssapi')
| -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);  | 
