[28313] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Refactor KDC option/flag processing

daemon@ATHENA.MIT.EDU (Tom Yu)
Tue Apr 29 16:42:38 2014

Date: Tue, 29 Apr 2014 16:42:33 -0400
From: Tom Yu <tlyu@mit.edu>
Message-Id: <201404292042.s3TKgX6A023468@drugstore.mit.edu>
To: cvs-krb5@mit.edu
Reply-To: krbdev@mit.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/4d08c9abfee0b5978d9db2280c10c85b3bf2ae11
commit 4d08c9abfee0b5978d9db2280c10c85b3bf2ae11
Author: Tom Yu <tlyu@mit.edu>
Date:   Thu Apr 24 17:10:58 2014 -0400

    Refactor KDC option/flag processing
    
    A lot of KDC code was spent copying options to flags, and copying
    header_ticket flags to the output ticket.
    
    Behavior change: previous code didn't copy PROXY from the
    header_ticket, but this seems to have been a minor bug rather than
    intentional.  This also seems to have been an omission from RFC 4120.

 src/kdc/do_as_req.c  |   18 +++----------
 src/kdc/do_tgs_req.c |   46 ++++++++-------------------------
 src/kdc/kdc_util.h   |   68 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 82 insertions(+), 50 deletions(-)

diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 5057067..a1db924 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -2,8 +2,8 @@
 /* kdc/do_as_req.c */
 /*
  * Portions Copyright (C) 2007 Apple Inc.
- * Copyright 1990, 1991, 2007, 2008, 2009, 2013 by the Massachusetts Institute
- * of Technology.  All Rights Reserved.
+ * Copyright 1990, 1991, 2007, 2008, 2009, 2013, 2014 by the
+ * Massachusetts Institute of Technology.  All Rights Reserved.
  *
  * Export of this software from the United States of America may
  *   require a specific license from the United States Government.
@@ -686,7 +686,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
         state->ticket_reply.server = state->request->server;
     }
 
-    state->enc_tkt_reply.flags = 0;
+    /* Copy options that request the corresponding ticket flags. */
+    state->enc_tkt_reply.flags = OPTS2FLAGS(state->request->kdc_options);
     state->enc_tkt_reply.times.authtime = state->authtime;
 
     setflag(state->enc_tkt_reply.flags, TKT_FLG_INITIAL);
@@ -698,15 +699,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
      * realms may refuse to issue renewable tickets
      */
 
-    if (isflagset(state->request->kdc_options, KDC_OPT_FORWARDABLE))
-        setflag(state->enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
-
-    if (isflagset(state->request->kdc_options, KDC_OPT_PROXIABLE))
-        setflag(state->enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
-
-    if (isflagset(state->request->kdc_options, KDC_OPT_ALLOW_POSTDATE))
-        setflag(state->enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
-
     state->enc_tkt_reply.session = &state->session_key;
     if (isflagset(state->c_flags, KRB5_KDB_FLAG_CANONICALIZE)) {
         state->client_princ = *(state->client->princ);
@@ -720,7 +712,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
     state->enc_tkt_reply.transited.tr_contents = empty_string;
 
     if (isflagset(state->request->kdc_options, KDC_OPT_POSTDATED)) {
-        setflag(state->enc_tkt_reply.flags, TKT_FLG_POSTDATED);
         setflag(state->enc_tkt_reply.flags, TKT_FLG_INVALID);
         state->enc_tkt_reply.times.starttime = state->request->from;
     } else
@@ -757,7 +748,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
             state->status = "VALIDATE_ANONYMOUS_PRINCIPAL";
             goto errout;
         }
-        setflag(state->enc_tkt_reply.flags, TKT_FLG_ANONYMOUS);
         krb5_free_principal(kdc_context, state->request->client);
         state->request->client = NULL;
         errcode = krb5_copy_principal(kdc_context, krb5_anonymous_principal(),
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 49a6ea6..fce478e 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -1,8 +1,8 @@
 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 /* kdc/do_tgs_req.c - KDC Routines to deal with TGS_REQ's */
 /*
- * Copyright 1990, 1991, 2001, 2007, 2008, 2009, 2013 by the Massachusetts
- * Institute of Technology.  All Rights Reserved.
+ * Copyright 1990, 1991, 2001, 2007, 2008, 2009, 2013, 2014 by the
+ * Massachusetts Institute of Technology.  All Rights Reserved.
  *
  * Export of this software from the United States of America may
  *   require a specific license from the United States Government.
@@ -376,7 +376,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
     else
         ticket_reply.server = request->server; /* XXX careful for realm... */
 
-    enc_tkt_reply.flags = 0;
+    enc_tkt_reply.flags = OPTS2FLAGS(request->kdc_options);
+    enc_tkt_reply.flags |= COPY_TKT_FLAGS(header_enc_tkt->flags);
     enc_tkt_reply.times.starttime = 0;
 
     if (isflagset(server->attributes, KRB5_KDB_OK_AS_DELEGATE))
@@ -404,7 +405,6 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
      */
 
     if (isflagset(request->kdc_options, KDC_OPT_FORWARDABLE)) {
-        setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDABLE);
 
         if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) {
             /*
@@ -435,34 +435,21 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
         }
     }
 
-    if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) {
-        setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
+    if (isflagset(request->kdc_options, KDC_OPT_FORWARDED) ||
+        isflagset(request->kdc_options, KDC_OPT_PROXY)) {
 
         /* include new addresses in ticket & reply */
 
         enc_tkt_reply.caddrs = request->addresses;
         reply_encpart.caddrs = request->addresses;
     }
-    if (isflagset(header_enc_tkt->flags, TKT_FLG_FORWARDED))
-        setflag(enc_tkt_reply.flags, TKT_FLG_FORWARDED);
-
-    if (isflagset(request->kdc_options, KDC_OPT_PROXIABLE))
-        setflag(enc_tkt_reply.flags, TKT_FLG_PROXIABLE);
-
-    if (isflagset(request->kdc_options, KDC_OPT_PROXY)) {
-        setflag(enc_tkt_reply.flags, TKT_FLG_PROXY);
-
-        /* include new addresses in ticket & reply */
-
-        enc_tkt_reply.caddrs = request->addresses;
-        reply_encpart.caddrs = request->addresses;
-    }
-
-    if (isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE))
-        setflag(enc_tkt_reply.flags, TKT_FLG_MAY_POSTDATE);
+    /* We don't currently handle issuing anonymous tickets based on
+     * non-anonymous ones, so just ignore the option. */
+    if (isflagset(request->kdc_options, KDC_OPT_REQUEST_ANONYMOUS) &&
+        !isflagset(header_enc_tkt->flags, TKT_FLG_ANONYMOUS))
+        clear(enc_tkt_reply.flags, TKT_FLG_ANONYMOUS);
 
     if (isflagset(request->kdc_options, KDC_OPT_POSTDATED)) {
-        setflag(enc_tkt_reply.flags, TKT_FLG_POSTDATED);
         setflag(enc_tkt_reply.flags, TKT_FLG_INVALID);
         enc_tkt_reply.times.starttime = request->from;
     } else
@@ -506,22 +493,11 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
     kdc_get_ticket_renewtime(kdc_active_realm, request, header_enc_tkt, client,
                              server, &enc_tkt_reply);
 
-    if (isflagset(header_enc_tkt->flags, TKT_FLG_ANONYMOUS))
-        setflag(enc_tkt_reply.flags, TKT_FLG_ANONYMOUS);
     /*
      * Set authtime to be the same as header or evidence ticket's
      */
     enc_tkt_reply.times.authtime = authtime;
 
-    /*
-     * Propagate the preauthentication flags through to the returned ticket.
-     */
-    if (isflagset(header_enc_tkt->flags, TKT_FLG_PRE_AUTH))
-        setflag(enc_tkt_reply.flags, TKT_FLG_PRE_AUTH);
-
-    if (isflagset(header_enc_tkt->flags, TKT_FLG_HW_AUTH))
-        setflag(enc_tkt_reply.flags, TKT_FLG_HW_AUTH);
-
     /* starttime is optional, and treated as authtime if not present.
        so we can nuke it if it matches */
     if (enc_tkt_reply.times.starttime == enc_tkt_reply.times.authtime)
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 6c54333..479a13c 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -2,7 +2,7 @@
 /* kdc/kdc_util.h */
 /*
  * Portions Copyright (C) 2007 Apple Inc.
- * Copyright 1990, 2007 by the Massachusetts Institute of Technology.
+ * Copyright 1990, 2007, 2014 by the Massachusetts Institute of Technology.
  *
  * Export of this software from the United States of America may
  *   require a specific license from the United States Government.
@@ -414,6 +414,72 @@ struct krb5_kdcpreauth_rock_st {
 /* TGS-REQ options which are not compatible with referrals */
 #define NO_REFERRAL_OPTION (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)
 
+/*
+ * Mask of KDC options that request the corresponding ticket flag with
+ * the same number.  Some of these are invalid for AS-REQs, but
+ * validate_as_request() takes care of that.  KDC_OPT_RENEWABLE isn't
+ * here because it needs special handling in
+ * kdc_get_ticket_renewtime().
+ *
+ * According to RFC 4120 section 3.1.3 the following AS-REQ options
+ * request their corresponding ticket flags if local policy allows:
+ *
+ * KDC_OPT_FORWARDABLE  KDC_OPT_ALLOW_POSTDATE
+ * KDC_OPT_POSTDATED    KDC_OPT_PROXIABLE
+ * KDC_OPT_RENEWABLE
+ *
+ * RFC 1510 section A.6 shows pseudocode indicating that the following
+ * TGS-REQ options request their corresponding ticket flags if local
+ * policy allows:
+ *
+ * KDC_OPT_FORWARDABLE  KDC_OPT_FORWARDED
+ * KDC_OPT_PROXIABLE    KDC_OPT_PROXY
+ * KDC_OPT_POSTDATED    KDC_OPT_RENEWABLE
+ *
+ * The above list omits KDC_OPT_ALLOW_POSTDATE, but RFC 4120 section
+ * 5.4.1 says the TGS also handles it.
+ *
+ * RFC 6112 makes KDC_OPT_REQUEST_ANONYMOUS the same bit number as
+ * TKT_FLG_ANONYMOUS.
+ */
+#define OPTS_COMMON_FLAGS_MASK                                  \
+    (KDC_OPT_FORWARDABLE        | KDC_OPT_FORWARDED     |       \
+     KDC_OPT_PROXIABLE          | KDC_OPT_PROXY         |       \
+     KDC_OPT_ALLOW_POSTDATE     | KDC_OPT_POSTDATED     |       \
+     KDC_OPT_REQUEST_ANONYMOUS)
+
+/* Copy KDC options that request the corresponding ticket flags. */
+#define OPTS2FLAGS(x) (x & OPTS_COMMON_FLAGS_MASK)
+
+/*
+ * Mask of ticket flags for the TGS to propagate from a ticket to a
+ * derivative ticket.
+ *
+ * RFC 4120 section 2.1 says the following flags are carried forward
+ * from an initial ticket to derivative tickets:
+ *
+ * TKT_FLG_PRE_AUTH
+ * TKT_FLG_HW_AUTH
+ *
+ * RFC 4120 section 2.6 says TKT_FLG_FORWARDED is carried forward to
+ * derivative tickets.  Proxy tickets are basically identical to
+ * forwarded tickets except that a TGT may never be proxied, therefore
+ * tickets derived from proxy tickets should have TKT_FLAG_PROXY set.
+ * RFC 4120 and RFC 1510 apparently have an accidental omission in not
+ * requiring that tickets derived from a proxy ticket have
+ * TKT_FLG_PROXY set.  Previous code also omitted this behavior.
+ *
+ * RFC 6112 section 4.2 implies that TKT_FLG_ANONYMOUS must be
+ * propagated from an anonymous ticket to derivative tickets.
+ */
+#define TGS_COPIED_FLAGS_MASK                           \
+    (TKT_FLG_FORWARDED  | TKT_FLG_PROXY         |       \
+     TKT_FLG_PRE_AUTH   | TKT_FLG_HW_AUTH       |       \
+     TKT_FLG_ANONYMOUS)
+
+/* Copy appropriate header ticket flags to new ticket. */
+#define COPY_TKT_FLAGS(x) (x & TGS_COPIED_FLAGS_MASK)
+
 int check_anon(kdc_realm_t *kdc_active_realm,
                krb5_principal client, krb5_principal server);
 int errcode_to_protocol(krb5_error_code code);
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post