krb5 commit: Add test for cross realm S4U2Self using referrals

Greg Hudson ghudson at mit.edu
Wed Oct 17 16:13:10 EDT 2018


https://github.com/krb5/krb5/commit/aec6e0f51bfc20be67b70a7d81808b4add22838a
commit aec6e0f51bfc20be67b70a7d81808b4add22838a
Author: Isaac Boukris <iboukris at gmail.com>
Date:   Sat Oct 13 16:27:02 2018 +0300

    Add test for cross realm S4U2Self using referrals
    
    [ghudson at mit.edu: factored out tgtname() in kdb_test.c; added trace
    messages to tests and removed old redundant test]
    
    ticket: 8747

 src/plugins/kdb/test/kdb_test.c |   37 +++++++++++++++++++++++++++++---
 src/tests/gssapi/t_s4u.py       |   44 +++++++++++++++++++++++++++++---------
 2 files changed, 66 insertions(+), 15 deletions(-)

diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c
index 776dda3..bc65bfb 100644
--- a/src/plugins/kdb/test/kdb_test.c
+++ b/src/plugins/kdb/test/kdb_test.c
@@ -64,6 +64,9 @@
  * Key values are generated using a hash of the kvno, enctype, salt type, and
  * principal name.  This module does not use master key encryption, so it
  * serves as a partial test of the DAL's ability to avoid that.
+ *
+ * For cross realm, just add outbound 'krbtgt/OTHER_REALM' principal to each
+ * kdc configuration, while for inbound trust the local krbtgt will be used.
  */
 
 #include "k5-int.h"
@@ -297,12 +300,27 @@ test_close(krb5_context context)
     return 0;
 }
 
+/* Return the principal name krbtgt/tgs_realm at our_realm. */
+static krb5_principal
+tgtname(krb5_context context, const krb5_data *tgs_realm,
+        const krb5_data *our_realm)
+{
+    krb5_principal princ;
+
+    check(krb5_build_principal_ext(context, &princ,
+                                   our_realm->length, our_realm->data,
+                                   KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
+                                   tgs_realm->length, tgs_realm->data, 0));
+    princ->type = KRB5_NT_SRV_INST;
+    return princ;
+}
+
 static krb5_error_code
 test_get_principal(krb5_context context, krb5_const_principal search_for,
                    unsigned int flags, krb5_db_entry **entry)
 {
     krb5_error_code ret;
-    krb5_principal princ = NULL;
+    krb5_principal princ = NULL, tgtprinc;
     krb5_principal_data empty_princ = { KV5M_PRINCIPAL };
     testhandle h = context->dal_handle->db_context;
     char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings;
@@ -330,14 +348,25 @@ test_get_principal(krb5_context context, krb5_const_principal search_for,
                 princ = NULL;
                 ret = 0;
                 goto cleanup;
+            } else if (flags & KRB5_KDB_FLAG_CANONICALIZE) {
+                /* Generate a server referral by looking up the TGT for the
+                 * canonical name's realm. */
+                tgtprinc = tgtname(context, &princ->realm, &search_for->realm);
+                krb5_free_principal(context, princ);
+                princ = tgtprinc;
+
+                krb5_free_unparsed_name(context, search_name);
+                check(krb5_unparse_name_flags(context, princ,
+                                              KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+                                              &search_name));
+                ename = search_name;
             } else {
-                /* We could look up a cross-realm TGS entry, but we don't need
-                 * that behavior yet. */
                 ret = KRB5_KDB_NOENTRY;
                 goto cleanup;
             }
+        } else {
+            ename = canon;
         }
-        ename = canon;
     } else {
         check(krb5_copy_principal(context, search_for, &princ));
         ename = search_name;
diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py
index 35bc9e4..eb9545d 100755
--- a/src/tests/gssapi/t_s4u.py
+++ b/src/tests/gssapi/t_s4u.py
@@ -139,21 +139,43 @@ if 'auth1: user@' not in out or 'auth2: user@' not in out:
 
 realm.stop()
 
-# Exercise cross-realm S4U2Self.  The query in the foreign realm will
-# fail, but we can check that the right server principal was used.
+# Test cross realm S4U2Self using server referrals.
+mark('cross-realm S4U2Self')
+testprincs = {'krbtgt/SREALM': {'keys': 'aes128-cts'},
+              'krbtgt/UREALM': {'keys': 'aes128-cts'},
+              'user': {'keys': 'aes128-cts'}}
+kdcconf1 = {'realms': {'$realm': {'database_module': 'test'}},
+            'dbmodules': {'test': {'db_library': 'test',
+                                   'princs': testprincs }}}
+kdcconf2 = {'realms': {'$realm': {'database_module': 'test'}},
+            'dbmodules': {'test': {'db_library': 'test',
+                                   'princs': testprincs,
+                                   'alias': {'user at SREALM': '@SREALM'}}}}
+r1, r2 = cross_realms(2, xtgts=(),
+                      args=({'realm': 'SREALM', 'kdc_conf': kdcconf1},
+                            {'realm': 'UREALM', 'kdc_conf': kdcconf2}),
+                      create_kdb=False)
+
+r1.start_kdc()
+r2.start_kdc()
+r1.extract_keytab(r1.user_princ, r1.keytab)
+r1.kinit(r1.user_princ, None, ['-k', '-t', r1.keytab])
+
 # Include a regression test for #8741 by unsetting the default realm.
-r1, r2 = cross_realms(2, create_user=False)
-r1.run([kinit, '-k', r1.host_princ])
 remove_default = {'libdefaults': {'default_realm': None}}
 no_default = r1.special_env('no_default', False, krb5_conf=remove_default)
-r1.run(['./t_s4u', 'p:' + r2.host_princ], env=no_default, expected_code=1,
-       expected_msg='Server not found in Kerberos database')
+msgs = ('Getting credentials user at UREALM -> user at SREALM',
+        '/Matching credential not found',
+        'Getting credentials user at SREALM -> krbtgt/UREALM at SREALM',
+        'Received creds for desired service krbtgt/UREALM at SREALM',
+        'via TGT krbtgt/UREALM at SREALM after requesting user\\@SREALM at UREALM',
+        'krbtgt/SREALM at UREALM differs from requested user\\@SREALM at UREALM',
+        'via TGT krbtgt/SREALM at UREALM after requesting user at SREALM',
+        'TGS reply is for user at UREALM -> user at SREALM')
+r1.run(['./t_s4u', 'p:' + r2.user_princ, '-', r1.keytab], env=no_default,
+       expected_trace=msgs)
+
 r1.stop()
 r2.stop()
-with open(os.path.join(r2.testdir, 'kdc.log')) as f:
-    kdclog = f.read()
-exp_princ = r1.host_princ.replace('/', '\\/').replace('@', '\\@')
-if ('for %s@%s, Server not found' % (exp_princ, r2.realm)) not in kdclog:
-    fail('cross-realm s4u2self (kdc log)')
 
 success('S4U test cases')


More information about the cvs-krb5 mailing list