return (krb5_deltat)((uint32_t)a - (uint32_t)b);
}
+/* Return (end - start) as an unsigned 32-bit value, or 0 if start > end. */
+static inline uint32_t
+ts_interval(krb5_timestamp start, krb5_timestamp end)
+{
+ if ((uint32_t)start > (uint32_t)end)
+ return 0;
+ return (uint32_t)end - (uint32_t)start;
+}
+
/* Increment a timestamp by a signed 32-bit interval, without relying on
* undefined behavior. */
static inline krb5_timestamp
*mech_type = ctx->mech_used;
if (time_rec) {
- *time_rec = ts_delta(ctx->krb_times.endtime, now) +
- ctx->k5_context->clockskew;
+ *time_rec = ts_interval(ts_incr(now, -ctx->k5_context->clockskew),
+ ctx->krb_times.endtime);
}
/* Never return GSS_C_DELEG_FLAG since we don't support DCE credential
/* 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 = ts_delta(ctx->krb_times.endtime, now) + context->clockskew;
+ if (time_rec) {
+ *time_rec = ts_interval(ts_incr(now, -context->clockskew),
+ ctx->krb_times.endtime);
+ }
if (ret_flags)
*ret_flags = ctx->gss_flags;
GSS_C_NO_NAME);
if (GSS_ERROR(ret))
goto error_out;
- *time_rec = ts_after(cred->expire, now) ?
- ts_delta(cred->expire, now) : 0;
+ *time_rec = ts_interval(now, cred->expire);
k5_mutex_unlock(&cred->lock);
}
}
{
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx;
- krb5_timestamp now;
- krb5_deltat lifetime;
+ krb5_timestamp now, start;
ctx = (krb5_gss_ctx_id_rec *) context_handle;
return(GSS_S_FAILURE);
}
- 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);
- } else {
- *time_rec = lifetime;
- *minor_status = 0;
- return(GSS_S_COMPLETE);
- }
+ /* Add the maximum allowable clock skew for acceptor contexts. */
+ start = ctx->initiate ? now : ts_incr(now, -ctx->k5_context->clockskew);
+ *time_rec = ts_interval(start, ctx->krb_times.endtime);
+ *minor_status = 0;
+ return (*time_rec == 0) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
}
if (time_rec) {
if ((code = krb5_timeofday(context, &now)))
goto cleanup;
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
}
/* set the other returns */
if (time_rec) {
if ((code = krb5_timeofday(context, &now)))
goto fail;
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
}
if (ret_flags)
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx;
krb5_gss_name_t initiator, acceptor;
- krb5_timestamp now;
- krb5_deltat lifetime;
+ krb5_timestamp now, start;
+ OM_uint32 lifetime;
if (initiator_name)
*initiator_name = (gss_name_t) NULL;
/* Add the maximum allowable clock skew as a grace period for context
* expiration, just as we do for the ticket during authentication. */
- lifetime = ts_delta(ctx->krb_times.endtime, now);
- if (!ctx->initiate)
- lifetime += context->clockskew;
- if (lifetime < 0)
- lifetime = 0;
+ start = ctx->initiate ? now : ts_incr(now, -context->clockskew);
+ lifetime = ts_interval(start, ctx->krb_times.endtime);
if (initiator_name) {
code = kg_duplicate_name(context,
}
if (cred->expire != 0) {
- lifetime = ts_delta(cred->expire, now);
+ lifetime = ts_interval(now, cred->expire);
if (lifetime < 0)
lifetime = 0;
}
if (code != 0)
goto cleanup;
- *time_rec = ts_delta(cred->expire, now);
+ *time_rec = ts_interval(now, cred->expire);
}
major_status = GSS_S_COMPLETE;
/* Setting the timeout to zero would reset the timeout, so we set it to one
* second instead if creds are already expired. */
- timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1;
+ timeout = ts_after(endtime, now) ? ts_interval(now, endtime) : 1;
(void)keyctl_set_timeout(data->cache_id, timeout);
}
if (ts_after(creds->times.endtime, now)) {
(void)keyctl_set_timeout(cred_key,
- ts_delta(creds->times.endtime, now));
+ ts_interval(now, creds->times.endtime));
}
update_keyring_expiration(context, id);
void *expire_data;
krb5_timestamp pw_exp, acct_exp, now;
krb5_boolean is_last_req;
- krb5_deltat delta;
+ uint32_t interval;
char ts[256], banner[1024];
if (as_reply == NULL || as_reply->enc_part2 == NULL)
ret = krb5_timeofday(context, &now);
if (ret != 0)
return;
- if (!is_last_req &&
- (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
+ interval = ts_interval(now, pw_exp);
+ if (!is_last_req && (!interval || interval > 7 * 24 * 60 * 60))
return;
if (!prompter)
if (ret != 0)
return;
- delta = ts_delta(pw_exp, now);
- if (delta < 3600) {
+ if (interval < 3600) {
snprintf(banner, sizeof(banner),
_("Warning: Your password will expire in less than one hour "
"on %s"), ts);
- } else if (delta < 86400 * 2) {
+ } else if (interval < 86400 * 2) {
snprintf(banner, sizeof(banner),
_("Warning: Your password will expire in %d hour%s on %s"),
- delta / 3600, delta < 7200 ? "" : "s", ts);
+ interval / 3600, interval < 7200 ? "" : "s", ts);
} else {
snprintf(banner, sizeof(banner),
_("Warning: Your password will expire in %d days on %s"),
- delta / 86400, ts);
+ interval / 86400, ts);
}
/* PROMPTER_INVOCATION */