e98d94d2bc
In addition to basing the contents of an encrypted-timestamp preauth data item on the server's idea of the current time, go ahead and do the same for the times in the request.
145 lines
5.8 KiB
Diff
145 lines
5.8 KiB
Diff
>From 51ab359d7cc6643cfd4fac28def2e1c756553201 Mon Sep 17 00:00:00 2001
|
|
From: Stef Walter <stefw@redhat.com>
|
|
Date: Thu, 23 May 2013 08:44:43 +0200
|
|
Subject: [PATCH 2/2] krb5: Fix ticket start and end time to respect skew
|
|
|
|
Since the kerberos protocol uses timestamp rather than duration deltas
|
|
for its starttime, endtime, and renewtime KDC AS REQ fields, we have
|
|
to calculate these with respect to the offsets we know about received
|
|
from the server.
|
|
|
|
Leverage the unauthenticated server time we received during preauth when
|
|
calculating these these timestamps from the duration deltas we use
|
|
in our krb5 api and tools.
|
|
|
|
In order to do this we have to update certain fields of the AS REQ
|
|
each time we encode it for sending to the KDC.
|
|
---
|
|
src/lib/krb5/krb/get_in_tkt.c | 44 +++++++++++++++++++++++--------------------
|
|
src/lib/krb5/krb/int-proto.h | 5 +++++
|
|
src/lib/krb5/krb/preauth2.c | 8 ++++++++
|
|
3 files changed, 37 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
|
index 1058112..694c9b0b 100644
|
|
--- a/src/lib/krb5/krb/get_in_tkt.c
|
|
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
|
@@ -656,6 +656,8 @@ update_req_before_encoding(krb5_context context, krb5_init_creds_context ctx)
|
|
krb5_error_code code = 0;
|
|
unsigned char random_buf[4];
|
|
krb5_data random_data;
|
|
+ krb5_timestamp from;
|
|
+ krb5_int32 unused;
|
|
|
|
/*
|
|
* RFC 6113 requires a new nonce for the inner request on each try. It's
|
|
@@ -674,6 +676,28 @@ update_req_before_encoding(krb5_context context, krb5_init_creds_context ctx)
|
|
*/
|
|
ctx->request->nonce = 0x7fffffff & load_32_n(random_buf);
|
|
|
|
+ code = k5_preauth_get_time(context, &ctx->preauth_rock, TRUE, &ctx->request_time, &unused);
|
|
+ if (code != 0)
|
|
+ goto cleanup;
|
|
+
|
|
+ /* Omit request start time in the common case. MIT and Heimdal KDCs will
|
|
+ * ignore it for non-postdated tickets anyway. */
|
|
+ from = krb5int_addint32(ctx->request_time, ctx->start_time);
|
|
+ if (ctx->start_time != 0)
|
|
+ ctx->request->from = from;
|
|
+ ctx->request->till = krb5int_addint32(from, ctx->tkt_life);
|
|
+
|
|
+ if (ctx->renew_life > 0) {
|
|
+ ctx->request->rtime =
|
|
+ krb5int_addint32(from, ctx->renew_life);
|
|
+ if (ctx->request->rtime < ctx->request->till) {
|
|
+ /* don't ask for a smaller renewable time than the lifetime */
|
|
+ ctx->request->rtime = ctx->request->till;
|
|
+ }
|
|
+ ctx->request->kdc_options &= ~(KDC_OPT_RENEWABLE_OK);
|
|
+ } else
|
|
+ ctx->request->rtime = 0;
|
|
+
|
|
cleanup:
|
|
return code;
|
|
}
|
|
@@ -692,7 +716,6 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
|
|
krb5_pa_data **padata)
|
|
{
|
|
krb5_error_code code = 0;
|
|
- krb5_timestamp from;
|
|
|
|
if (ctx->preauth_to_use) {
|
|
krb5_free_pa_data(context, ctx->preauth_to_use);
|
|
@@ -732,8 +755,6 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
|
|
if (code != 0)
|
|
goto cleanup;
|
|
|
|
- ctx->request_time = time(NULL);
|
|
-
|
|
code = krb5int_fast_as_armor(context, ctx->fast_state,
|
|
ctx->opte, ctx->request);
|
|
if (code != 0)
|
|
@@ -747,23 +768,6 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
|
|
/* give the preauth plugins a chance to prep the request body */
|
|
krb5_preauth_prepare_request(context, ctx->opte, ctx->request);
|
|
|
|
- /* Omit request start time in the common case. MIT and Heimdal KDCs will
|
|
- * ignore it for non-postdated tickets anyway. */
|
|
- from = krb5int_addint32(ctx->request_time, ctx->start_time);
|
|
- if (ctx->start_time != 0)
|
|
- ctx->request->from = from;
|
|
- ctx->request->till = krb5int_addint32(from, ctx->tkt_life);
|
|
-
|
|
- if (ctx->renew_life > 0) {
|
|
- ctx->request->rtime =
|
|
- krb5int_addint32(from, ctx->renew_life);
|
|
- if (ctx->request->rtime < ctx->request->till) {
|
|
- /* don't ask for a smaller renewable time than the lifetime */
|
|
- ctx->request->rtime = ctx->request->till;
|
|
- }
|
|
- ctx->request->kdc_options &= ~(KDC_OPT_RENEWABLE_OK);
|
|
- } else
|
|
- ctx->request->rtime = 0;
|
|
code = krb5int_fast_prep_req_body(context, ctx->fast_state,
|
|
ctx->request,
|
|
&ctx->outer_request_body);
|
|
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
|
|
index 3326154..83a47c0 100644
|
|
--- a/src/lib/krb5/krb/int-proto.h
|
|
+++ b/src/lib/krb5/krb/int-proto.h
|
|
@@ -142,6 +142,11 @@ krb5_preauth_supply_preauth_data(krb5_context context,
|
|
const char *value);
|
|
|
|
krb5_error_code
|
|
+k5_preauth_get_time(krb5_context context, krb5_clpreauth_rock rock,
|
|
+ krb5_boolean allow_unauth_time, krb5_timestamp *time_out,
|
|
+ krb5_int32 *usec_out);
|
|
+
|
|
+krb5_error_code
|
|
clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
|
|
int min_ver, krb5_plugin_vtable vtable);
|
|
|
|
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
|
|
index 747611e..167f611 100644
|
|
--- a/src/lib/krb5/krb/preauth2.c
|
|
+++ b/src/lib/krb5/krb/preauth2.c
|
|
@@ -397,6 +397,15 @@ get_preauth_time(krb5_context context, krb5_clpreauth_rock rock,
|
|
krb5_boolean allow_unauth_time, krb5_timestamp *time_out,
|
|
krb5_int32 *usec_out)
|
|
{
|
|
+ return k5_preauth_get_time(context, rock, allow_unauth_time,
|
|
+ time_out, usec_out);
|
|
+}
|
|
+
|
|
+krb5_error_code
|
|
+k5_preauth_get_time(krb5_context context, krb5_clpreauth_rock rock,
|
|
+ krb5_boolean allow_unauth_time, krb5_timestamp *time_out,
|
|
+ krb5_int32 *usec_out)
|
|
+{
|
|
if (rock->pa_offset_state != NO_OFFSET &&
|
|
(allow_unauth_time || rock->pa_offset_state == AUTH_OFFSET) &&
|
|
(context->library_options & KRB5_LIBOPT_SYNC_KDCTIME)) {
|
|
--
|
|
1.8.1.4
|
|
|