]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Limit ticket lifetime to 2^31-1 seconds 699/head
authorGreg Hudson <ghudson@mit.edu>
Thu, 24 Aug 2017 20:00:33 +0000 (16:00 -0400)
committerGreg Hudson <ghudson@mit.edu>
Fri, 8 Sep 2017 15:56:10 +0000 (11:56 -0400)
Although timestamps above 2^31-1 are now valid, intervals exceeding
2^31-1 seconds may be treated incorrectly by comparison operations.

The initially computed interval in kdc_get_ticket_endtime() could be
negative if the requested end time is far in the future, causing the
function to yield an incorrect result.  (With the new larger value of
kdc_infinity, this could specifically happen if a KDC-REQ contains a
zero till field.)  Cap the interval at the maximum valid value.
Reported by Weijun Wang.

Avoid delta comparisons in favor of timestamp comparions in
krb5int_validate_times(), ksu's krb5_check_exp(), and clockskew
checks.

Also use a y2038-safe timestamp comparison in set_request_times() when
comparing the requested renewable end time to the requested ticket end
time.

ticket: 8352

src/clients/ksu/ccache.c
src/include/k5-int.h
src/kdc/kdc_util.c
src/kdc/replay.c
src/kdc/t_replay.c
src/lib/krb5/krb/gc_via_tkt.c
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/int-proto.h
src/lib/krb5/krb/valid_times.c
src/lib/krb5/os/timeofday.c

index 236313b7b868a835f4d69d0f89ab29a7c535f393..2a99521d4b2bee191b873024786843eec65581b8 100644 (file)
@@ -282,7 +282,7 @@ krb5_error_code krb5_check_exp(context, tkt_time)
 
     }
 
-    if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) {
+    if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) {
         retval = KRB5KRB_AP_ERR_TKT_EXPIRED ;
         return retval;
     }
index 023e4bb55aa2c728086afbf1bf34ab51748df936..e1b1cb040d5e11cf205519577ebc3641b269fa26 100644 (file)
@@ -2386,6 +2386,13 @@ ts_after(krb5_timestamp a, krb5_timestamp b)
     return (uint32_t)a > (uint32_t)b;
 }
 
+/* Return true if a and b are within d seconds. */
+static inline krb5_boolean
+ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d)
+{
+    return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d));
+}
+
 krb5_error_code KRB5_CALLCONV
 krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
                               krb5_ccache ccache,
index c3ef6af0ba6aee2be2d4ccae8344803462d865d1..754570c013108330364fdfc330cd4083aaefa430 100644 (file)
@@ -1759,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
                        krb5_db_entry *server,
                        krb5_timestamp *out_endtime)
 {
-    krb5_timestamp until, life;
+    krb5_timestamp until;
+    krb5_deltat life;
 
     if (till == 0)
         till = kdc_infinity;
 
     until = ts_min(till, endtime);
 
+    /* Determine the requested lifetime, capped at the maximum valid time
+     * interval. */
     life = ts_delta(until, starttime);
+    if (ts_after(until, starttime) && life < 0)
+        life = INT32_MAX;
 
     if (client != NULL && client->max_life != 0)
         life = min(life, client->max_life);
index fab39cf8839fb695194e08585c91494ccbd94716..caca783bf1ab294ff1aaf1ba766144afb2ce99aa 100644 (file)
@@ -61,7 +61,7 @@ static size_t total_size = 0;
 static krb5_ui_4 seed;
 
 #define STALE_TIME      (2*60)            /* two minutes */
-#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME)
+#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME)))
 
 /* Return x rotated to the left by r bits. */
 static inline krb5_ui_4
index fe49560edad244a04f329bc21e425619c27c3e8f..00bb39012680959be892ce52cc281afcc42e1c8b 100644 (file)
@@ -906,7 +906,7 @@ test_kdc_insert_lookaside_cache_expire(void **state)
     assert_non_null(e);
     e->num_hits = 5;
 
-    time_return(STALE_TIME, 0);
+    time_return(STALE_TIME + 1, 0);
     kdc_insert_lookaside(context, &req2, NULL);
 
     assert_null(K5_LIST_FIRST(&hash_table[req_hash1]));
index cf1ea361fb7751aca78dbf40d337039ca22b1c43..5b9bb9573e27feda964d1c78e036c7cfa9253b90 100644 (file)
@@ -306,8 +306,8 @@ krb5int_process_tgs_reply(krb5_context context,
         goto cleanup;
 
     if (!in_cred->times.starttime &&
-        !in_clock_skew(context, dec_rep->enc_part2->times.starttime,
-                       timestamp)) {
+        !ts_within(dec_rep->enc_part2->times.starttime, timestamp,
+                   context->clockskew)) {
         retval = KRB5_KDCREP_SKEW;
         goto cleanup;
     }
index f9691a19cb64067c67673ef50c0af5351803a087..35d58e8eba1904b3f71267887084a1787ec68e31 100644 (file)
@@ -269,8 +269,8 @@ verify_as_reply(krb5_context            context,
             return retval;
     } else {
         if ((request->from == 0) &&
-            !in_clock_skew(context, as_reply->enc_part2->times.starttime,
-                           time_now))
+            !ts_within(as_reply->enc_part2->times.starttime, time_now,
+                       context->clockskew))
             return (KRB5_KDCREP_SKEW);
     }
     return 0;
@@ -766,7 +766,7 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx)
     if (ctx->renew_life > 0) {
         /* Don't ask for a smaller renewable time than the lifetime. */
         ctx->request->rtime = ts_incr(from, ctx->renew_life);
-        if (ctx->request->rtime < ctx->request->till)
+        if (ts_after(ctx->request->till, ctx->request->rtime))
             ctx->request->rtime = ctx->request->till;
         ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK;
     } else {
index 6a45c6f11e8619d82c309b8a021e641d45918d27..cda9010e34a3d7dbe06469e50724af0797b9f72b 100644 (file)
@@ -83,9 +83,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
                                  krb5_creds *in_creds, krb5_creds *mcreds,
                                  krb5_flags *fields);
 
-#define in_clock_skew(context, date, now)               \
-    (labs(ts_delta(date, now)) < (context)->clockskew)
-
 #define IS_TGS_PRINC(p) ((p)->length == 2 &&                            \
                          data_eq_string((p)->data[0], KRB5_TGS_NAME))
 
index 9e509b2dd3af7a59a6b63867121e8f0ec00f40fa..294761a882c5011455a586c041e1f2d4a28a6a5c 100644 (file)
@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times)
     else
         starttime = times->authtime;
 
-    if (ts_delta(starttime, currenttime) > context->clockskew)
+    if (ts_after(starttime, ts_incr(currenttime, context->clockskew)))
         return KRB5KRB_AP_ERR_TKT_NYV;  /* ticket not yet valid */
 
-    if (ts_delta(currenttime, times->endtime) > context->clockskew)
+    if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew)))
         return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */
 
     return 0;
index 887f24c22103461d5bcfbca402d129c07b3b9258..d4e36b1c7572d31c0833eec09371da3c6ba49275 100644 (file)
@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date)
     retval = krb5_timeofday(context, &currenttime);
     if (retval)
         return retval;
-    if (labs(ts_delta(date, currenttime)) >= context->clockskew)
+    if (!ts_within(date, currenttime, context->clockskew))
         return KRB5KRB_AP_ERR_SKEW;
 
     return 0;