better realm transit path checking for app server
authorKen Raeburn <raeburn@mit.edu>
Wed, 26 Sep 2001 03:47:47 +0000 (03:47 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 26 Sep 2001 03:47:47 +0000 (03:47 +0000)
transit path checking enforcement for kdc; supporting code, doc update
[merged from 1.2.3 release branch]

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13758 dc483132-0cff-0310-8789-dd5450dbe970

15 files changed:
doc/ChangeLog
doc/admin.texinfo
doc/copyright.texinfo
src/include/ChangeLog
src/include/krb5.hin
src/include/krb5/ChangeLog
src/include/krb5/adm.h
src/kdc/ChangeLog
src/kdc/do_tgs_req.c
src/kdc/extern.h
src/kdc/main.c
src/kdc/rtest.c
src/lib/kadm5/ChangeLog
src/lib/kadm5/admin.h
src/lib/kadm5/alt_prof.c

index d85ad0849782c7d7132733895fe4defa9cb0075e..4591171e2ec534473418edb3179d9fd02a9919d5 100644 (file)
@@ -1,3 +1,8 @@
+2001-09-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * admin.texinfo (realms (kdc.conf)): Add description of
+       reject_bad_transit realm option.
+
 2001-06-26  Ezra Peisach  <epeisach@mit.edu>
 
        * user-guide.texinfo, install.texinfo: Cleanup makeinfo warning of
index 77d066ab09cd0e833c9b2f4cca2ce097036d76ea..fea52d48181cff4659bc1c24724a31b04abde279 100644 (file)
@@ -928,6 +928,38 @@ List of key:salt strings.  Specifies the permitted key/salt combinations
 of principals for this realm.  You should set this tag to
 @samp{des3-hmac-sha1:normal des-cbc-crc:normal des-cbc-crc:v4}.
 
+@itemx reject_bad_transit
+A boolean value (@code{true}, @code{false}).  If set to @code{true}, the
+KDC will check the list of transited realms for cross-realm tickets
+against the transit path computed from the realm names and the
+@code{capaths} section of its @code{krb5.conf} file; if the path in the
+ticket to be issued contains any realms not in the computed path, the
+ticket will not be issued, and an error will be returned to the client
+instead.  If this value is set to @code{false}, such tickets will be
+issued anyways, and it will be left up to the application server to
+validate the realm transit path.
+
+If the @code{disable-transited-check} flag is set in the incoming
+request, this check is not performed at all.  Having the
+@code{reject_bad_transit} option will cause such ticket requests to be
+rejected always.
+
+This transit path checking and config file option currently apply only
+to TGS requests.
+
+Earlier versions of the MIT release (before 1.2.3) had bugs in the
+application server support such that the server-side checks may not be
+performed correctly.  We recommend turning this option on, unless you
+know that all application servers in this realm have been updated to
+fixed versions of the software, and for whatever reason, you don't want
+the KDC to do the validation.
+
+This is a per-realm option so that multiple-realm KDCs may control it
+separately for each realm, in case (for example) one realm has had the
+software on its application servers updated but another has not.
+
+This option defaults to @code{true}.
+
 @end table
 
 @node Sample kdc.conf File,  , realms (kdc.conf), kdc.conf
index 83fe7ef65075f7ade77f72b1a365c8bc5673d9e6..355cad1a8a6e28ba66c04268f73f06cdf5dc24b8 100644 (file)
@@ -1,4 +1,4 @@
-Copyright @copyright{} 1985-2000 by the Massachusetts Institute of Technology. 
+Copyright @copyright{} 1985-2001 by the Massachusetts Institute of Technology. 
 
 @quotation  
 Export of software employing encryption from the United States of
index 6695c20e9572da7b4bef296fe0f10cbcc36f142c..c7f210c61b78e8ddd66f61e28811e0c8d0a210a3 100644 (file)
@@ -4,6 +4,8 @@
        TKT_FLG_OK_AS_DELEGATE, TKT_FLG_ANONYMOUS): New macros.
        (KDC_OPT_REQUEST_ANONYMOUS, KDC_OPT_DISABLE_TRANSITED_CHECK):
        Likewise.
+       (krb5_check_transited_list): Pointed-to krb5_data structures are
+       now all const.
 
 2001-09-05  Ken Raeburn  <raeburn@mit.edu>
 
index a7fe2b7125cc9d6bdfddad4f00c2cc3aa24c5dae..fab9f8acb54b0f4c42d7b1310e60ae51a26142c1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * include/krb5.h
  *
- * Copyright 1989,1990,1995 by the Massachusetts Institute of Technology.
+ * Copyright 1989,1990,1995,2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
index 2fa911042b19e5ef0dcb8dc33f958a97756d0deb..a330549afb7c2e0f40b60b3365108fed94c86e41 100644 (file)
@@ -1,3 +1,9 @@
+2001-09-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * adm.h (struct __krb5_realm_params): Added fields
+       realm_reject_bad_transit, realm_reject_bad_transit_valid; deleted
+       field realm_filler.
+
 2001-07-25  Ezra Peisach  <epeisach@mit.edu>
 
        * kdb.h: For structs krb5_tl_data (tl_data_length), krb5_key_data
index b3a2b6af354e0585babb375e653065b96739b6d1..820f652b9c488b00e463ba2273119c957310c92d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * include/krb5/adm.h
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995,2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -208,13 +208,14 @@ typedef struct __krb5_realm_params {
     krb5_timestamp     realm_expiration;
     krb5_flags         realm_flags;
     krb5_key_salt_tuple        *realm_keysalts;
+    unsigned int       realm_reject_bad_transit:1;
     unsigned int       realm_kadmind_port_valid:1;
     unsigned int       realm_enctype_valid:1;
     unsigned int       realm_max_life_valid:1;
     unsigned int       realm_max_rlife_valid:1;
     unsigned int       realm_expiration_valid:1;
     unsigned int       realm_flags_valid:1;
-    unsigned int       realm_filler:7;
+    unsigned int       realm_reject_bad_transit_valid:1;
     krb5_int32         realm_num_keysalts;
 } krb5_realm_params;
 #endif /* KRB5_ADM_H__ */
index 6ceb53f27923bd9d46887e849fbbc575f1aa18bb..e9958da7efd35d78e1d7a9bfcb1a592ff15fb6aa 100644 (file)
@@ -1,3 +1,18 @@
+2001-09-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * do_tgs_req.c (process_tgs_req): If disable-transited-check
+       option isn't set, try to verify transit path.  If
+       reject_bad_transit flag is set and transit path isn't verified,
+       reject the request.  Use a temporary variable to simplify
+       references to the second ticket.
+       * extern.h (struct __kdc_realm_data): Add new field
+       realm_reject_bad_transit.
+       (find_realm_data): Declare.
+       (reject_bad_transit): New macro.
+       * main.c (find_realm_data): Delete declaration.
+       (init_realm): Copy reject-bad-transit value or use default.
+       * rtest.c (find_realm_data): Define dummy version.
+
 2001-09-24  Mitchell Berger  <mitchb@mit.edu>
 
        * krb5kdc.M: Document the -n option.  Thanks to Dennis Davis
index 202284cbdd0479aac30c6f0708d9b5be1199192d..439b86caad57c8e610cbcc341cf2687d90316826 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * kdc/do_tgs_req.c
  *
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -490,6 +490,36 @@ tgt_again:
        }
        newtransited = 1;
     }
+    if (!isflagset (request->kdc_options, KDC_OPT_DISABLE_TRANSITED_CHECK)) {
+       errcode = krb5_check_transited_list (kdc_context,
+                                            &enc_tkt_reply.transited.tr_contents,
+                                            krb5_princ_realm (kdc_context, header_ticket->enc_part2->client),
+                                            krb5_princ_realm (kdc_context, request->server));
+       if (errcode == 0) {
+           setflag (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED);
+       } else if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT)
+           krb5_klog_syslog (LOG_INFO,
+                             "bad realm transit path from '%s' to '%s' via '%.*s'",
+                             cname ? cname : "<unknown client>",
+                             sname ? sname : "<unknown server>",
+                             enc_tkt_transited.tr_contents.length,
+                             enc_tkt_transited.tr_contents.data);
+       else
+           krb5_klog_syslog (LOG_ERR,
+                             "unexpected error checking transit from '%s' to '%s' via '%.*s': %s",
+                             cname ? cname : "<unknown client>",
+                             sname ? sname : "<unknown server>",
+                             enc_tkt_transited.tr_contents.length,
+                             enc_tkt_transited.tr_contents.data,
+                             error_message (errcode));
+    } else
+       krb5_klog_syslog (LOG_ERR, "not checking transit path");
+    if (reject_bad_transit
+       && !isflagset (enc_tkt_reply.flags, TKT_FLG_TRANSIT_POLICY_CHECKED)) {
+       errcode = KRB5KDC_ERR_POLICY;
+       status = "BAD_TRANSIT";
+       goto cleanup;
+    }
 
     ticket_reply.enc_part2 = &enc_tkt_reply;
 
@@ -504,27 +534,26 @@ tgt_again:
         * Make sure the client for the second ticket matches
         * requested server.
         */
-       if (!krb5_principal_compare(kdc_context, request->server,
-                                   request->second_ticket[st_idx]->enc_part2->client)) {
-               if ((errcode = krb5_unparse_name(kdc_context,
-                                               request->second_ticket[st_idx]->enc_part2->client,
-                                               &tmp)))
+       krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
+       krb5_principal client2 = t2enc->client;
+       if (!krb5_principal_compare(kdc_context, request->server, client2)) {
+               if ((errcode = krb5_unparse_name(kdc_context, client2, &tmp)))
                        tmp = 0;
-               krb5_klog_syslog(LOG_INFO, "TGS_REQ %s(%d): 2ND_TKT_MISMATCH: authtime %d, %s for %s, 2nd tkt client %s",
-                      fromstring, portnum, authtime,
-                      cname ? cname : "<unknown client>",
-                      sname ? sname : "<unknown server>",
-                      tmp ? tmp : "<unknown>");
+               krb5_klog_syslog(LOG_INFO,
+                                "TGS_REQ %s(%d): 2ND_TKT_MISMATCH: "
+                                "authtime %d, %s for %s, 2nd tkt client %s",
+                                fromstring, portnum, authtime,
+                                cname ? cname : "<unknown client>",
+                                sname ? sname : "<unknown server>",
+                                tmp ? tmp : "<unknown>");
                errcode = KRB5KDC_ERR_SERVER_NOMATCH;
                goto cleanup;
        }
            
        ticket_reply.enc_part.kvno = 0;
-       ticket_reply.enc_part.enctype =
-               request->second_ticket[st_idx]->enc_part2->session->enctype;
-       if ((errcode = krb5_encrypt_tkt_part(kdc_context, 
-                                           request->second_ticket[st_idx]->enc_part2->session,
-                                           &ticket_reply))) {
+       ticket_reply.enc_part.enctype = t2enc->session->enctype;
+       if ((errcode = krb5_encrypt_tkt_part(kdc_context, t2enc->session,
+                                            &ticket_reply))) {
            status = "2ND_TKT_ENCRYPT";
            goto cleanup;
        }
index 01a267d271caa6f7e6c8d7774e23de6bf0e7524a..556cc5710f962bb5f94a2f5ffdb5396371ac5149 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * kdc/extern.h
  *
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2001 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.
@@ -67,12 +67,15 @@ typedef struct __kdc_realm_data {
     krb5_deltat                realm_maxrlife; /* Maximum renewable life for realm */
     void               *realm_kstypes; /* Key/Salts supported for realm    */
     krb5_int32         realm_nkstypes; /* Number of key/salts              */
+    krb5_boolean       realm_reject_bad_transit; /* Accept unverifiable transited_realm ? */
 } kdc_realm_t;
 
 extern kdc_realm_t     **kdc_realmlist;
 extern int             kdc_numrealms;
 extern kdc_realm_t     *kdc_active_realm;
 
+kdc_realm_t *find_realm_data (char *, krb5_ui_4);
+
 /*
  * Replace previously used global variables with the active (e.g. request's)
  * realm data.  This allows us to support multiple realms with minimal logic
@@ -89,6 +92,7 @@ extern kdc_realm_t    *kdc_active_realm;
 #define        tgs_server                      kdc_active_realm->realm_tgsprinc
 #define        dbm_db_name                     kdc_active_realm->realm_dbname
 #define        primary_port                    kdc_active_realm->realm_pport
+#define reject_bad_transit             kdc_active_realm->realm_reject_bad_transit
 
 /* various externs for KDC */
 extern krb5_data       empty_string;   /* an empty string */
index 77340723ad584091e8c49e9e740f36ed1946930e..f487cf89fed02ec045a7467c104d514ea36144d1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * kdc/main.c
  *
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990,2001 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.
@@ -52,8 +52,6 @@
 extern int daemon(int, int);
 #endif
 
-kdc_realm_t *find_realm_data (char *, krb5_ui_4);
-
 void usage (char *);
 
 krb5_sigtype request_exit (int);
@@ -238,6 +236,12 @@ init_realm(progname, rdp, realm, def_dbname, def_mpname,
     else
        rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
 
+    /* Handle reject-bad-transit flag */
+    if (rparams && rparams->realm_reject_bad_transit_valid)
+       rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
+    else
+       rdp->realm_reject_bad_transit = 1;
+
     /* Handle ticket maximum life */
     rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
        rparams->realm_max_life : KRB5_KDB_MAX_LIFE;
index 9450bf2a505bddea54ab8db20cd40c9a16a2ec98..23e88f6c1178094f6d278b27e8e4fc5e8cd8422b 100644 (file)
@@ -114,3 +114,4 @@ main(argc,argv)
     }
 
 void krb5_klog_syslog() {}
+kdc_realm_t *find_realm_data (char *rname, krb5_ui_4 rsize) { return 0; }
index 4a1184156a4654b4fbe8ca52f2917fa0dbe87ea2..aef48537146397007f265dead8ee39e7335b0885 100644 (file)
@@ -1,3 +1,12 @@
+2001-09-25  Ken Raeburn  <raeburn@mit.edu>
+
+       * admin.h (krb5_realm_params): Add fields realm_reject_bad_transit
+       and realm_reject_bad_transit_valid; delete field realm_filler.
+       * alt_prof.c (string_to_boolean, krb5_aprof_get_boolean): New
+       functions.
+       (krb5_read_realm_params): Parse "reject_bad_transit" value as
+       boolean and save it.
+
 2001-07-25  Ezra Peisach  <epeisach@mit.edu>
 
        * kadm_rpc_xdr.c: Add xdr_krb5_ui_2. 
index 5df8f8ef9e5ddc49b67c69a29fa0ec5eceab053e..c3242c03504e3941b0c894058ebc70074c08896a 100644 (file)
@@ -1,3 +1,29 @@
+/*
+ * lib/kadm5/admin.h
+ *
+ * Copyright 2001 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.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ */
 /*
  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
  *
@@ -234,13 +260,14 @@ typedef struct __krb5_realm_params {
     krb5_timestamp     realm_expiration;
     krb5_flags         realm_flags;
     krb5_key_salt_tuple        *realm_keysalts;
+    unsigned int       realm_reject_bad_transit:1;
     unsigned int       realm_kadmind_port_valid:1;
     unsigned int       realm_enctype_valid:1;
     unsigned int       realm_max_life_valid:1;
     unsigned int       realm_max_rlife_valid:1;
     unsigned int       realm_expiration_valid:1;
     unsigned int       realm_flags_valid:1;
-    unsigned int       realm_filler:7;
+    unsigned int       realm_reject_bad_transit_valid:1;
     krb5_int32         realm_num_keysalts;
 } krb5_realm_params;
 
index c6156f69859ddcf6d4b37df1d6b11ff22183c2bc..2d729e938f7943443a213398c7afaf19eaa9176d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/kadm/alt_prof.c
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995,2001 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -115,6 +115,64 @@ krb5_aprof_getvals(acontext, hierarchy, retdata)
                              retdata));
 }
 
+/*
+ * krb5_aprof_get_boolean()
+ *
+ * Parameters:
+ *     acontext        - opaque context for alternate profile
+ *     hierarchy       - hierarchy of value to retrieve
+ *     retdata         - Returned data value
+ * Returns:
+ *     error codes
+ */
+
+static krb5_error_code
+string_to_boolean (const char *string, krb5_boolean *out)
+{
+    static const char *const yes[] = { "y", "yes", "true", "t", "1", "on" };
+    static const char *const no[] = { "n", "no", "false", "f", "nil", "0", "off" };
+    int i;
+
+    for (i = 0; i < sizeof(yes)/sizeof(yes[0]); i++)
+       if (!strcasecmp(string, yes[i])) {
+           *out = 1;
+           return 0;
+       }
+    for (i = 0; i < sizeof(no)/sizeof(no[0]); i++)
+       if (!strcasecmp(string, no[i])) {
+           *out = 0;
+           return 0;
+       }
+    return PROF_BAD_BOOLEAN;
+}
+
+krb5_error_code
+krb5_aprof_get_boolean(krb5_pointer acontext, const char **hierarchy,
+                      int uselast, int *retdata)
+{
+    krb5_error_code kret;
+    char **values;
+    char *valp;
+    int idx;
+    krb5_boolean val;
+
+    kret = krb5_aprof_getvals (acontext, hierarchy, &values);
+    if (kret)
+       return kret;
+    idx = 0;
+    if (uselast) {
+       while (values[idx])
+           idx++;
+       idx--;
+    }
+    valp = values[idx];
+    kret = string_to_boolean (valp, &val);
+    if (kret)
+       return kret;
+    *retdata = val;
+    return 0;
+}
+
 /*
  * krb5_aprof_get_deltat()     - Get a delta time value from the alternate
  *                               profile.
@@ -736,6 +794,7 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
     const char         *hierarchy[4];
     char               *svalue;
     krb5_int32         ivalue;
+    krb5_boolean       bvalue;
     krb5_deltat                dtvalue;
 
     krb5_error_code    kret;
@@ -832,7 +891,13 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
            rparams->realm_expiration_valid = 1;
        krb5_xfree(svalue);
     }
-           
+
+    hierarchy[2] = "reject_bad_transit";
+    if (!krb5_aprof_get_boolean(aprofile, hierarchy, TRUE, &bvalue)) {
+       rparams->realm_reject_bad_transit = bvalue;
+       rparams->realm_reject_bad_transit_valid = 1;
+    }
+
     /* Get the value for the default principal flags */
     hierarchy[2] = "default_principal_flags";
     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {