aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Boukris <iboukris@gmail.com>2019-01-17 11:36:46 +0200
committerGreg Hudson <ghudson@mit.edu>2019-03-13 19:22:53 -0400
commit01319a310cf06e4139b65afb12f998dbea636103 (patch)
treecceac4a3aef4a2b27606a61995e44c78f31d4f07
parent0fbfffbef2c266fedac557e00108b944e31e8d50 (diff)
downloadkrb5-01319a310cf06e4139b65afb12f998dbea636103.zip
krb5-01319a310cf06e4139b65afb12f998dbea636103.tar.gz
krb5-01319a310cf06e4139b65afb12f998dbea636103.tar.bz2
Add tests for S4U2Self with certificate
[ghudson@mit.edu: fixed memory leaks in test KDB method] ticket: 8781
-rw-r--r--src/plugins/kdb/test/kdb_test.c64
-rwxr-xr-xsrc/tests/gssapi/t_s4u.py73
2 files changed, 133 insertions, 4 deletions
diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c
index 6df2d58..8118e66 100644
--- a/src/plugins/kdb/test/kdb_test.c
+++ b/src/plugins/kdb/test/kdb_test.c
@@ -423,6 +423,64 @@ cleanup:
return ret;
}
+static void
+lookup_princ_by_cert(krb5_context context, const krb5_data *client_cert,
+ krb5_principal *princ)
+{
+ krb5_error_code ret;
+ char *cert_princ_name;
+
+ /* The test client sends a principal string instead of a cert. */
+ cert_princ_name = k5memdup0(client_cert->data, client_cert->length, &ret);
+ check(ret);
+
+ check(krb5_parse_name(context, cert_princ_name, princ));
+ free(cert_princ_name);
+}
+
+static krb5_error_code
+test_get_s4u_x509_principal(krb5_context context, const krb5_data *client_cert,
+ krb5_const_principal princ, unsigned int flags,
+ krb5_db_entry **entry)
+{
+ krb5_error_code ret;
+ krb5_principal cert_princ, canon_princ;
+ testhandle h = context->dal_handle->db_context;
+ krb5_boolean match;
+ char *canon, *princ_name;
+
+ lookup_princ_by_cert(context, client_cert, &cert_princ);
+
+ ret = test_get_principal(context, cert_princ, flags, entry);
+ krb5_free_principal(context, cert_princ);
+ if (ret || (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY))
+ return ret;
+
+ if (!krb5_realm_compare(context, princ, (*entry)->princ))
+ abort();
+
+ if (princ->length == 0 ||
+ krb5_principal_compare(context, princ, (*entry)->princ))
+ return 0;
+
+ check(krb5_unparse_name_flags(context, princ,
+ KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+ &princ_name));
+ canon = get_string(h, "alias", princ_name, NULL);
+ krb5_free_unparsed_name(context, princ_name);
+ if (canon != NULL &&
+ ((flags & KRB5_KDB_FLAG_ALIAS_OK) ||
+ princ->type == KRB5_NT_ENTERPRISE_PRINCIPAL)) {
+ check(krb5_parse_name(context, canon, &canon_princ));
+ match = krb5_principal_compare(context, canon_princ, (*entry)->princ);
+ krb5_free_principal(context, canon_princ);
+ if (match)
+ return 0;
+ }
+
+ return KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
+}
+
static krb5_error_code
test_fetch_master_key(krb5_context context, krb5_principal mname,
krb5_keyblock *key_out, krb5_kvno *kvno_out,
@@ -535,7 +593,7 @@ test_check_allowed_to_delegate(krb5_context context,
kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
KRB5_KDB_DAL_MAJOR_VERSION, /* major version number */
- 0, /* minor version number 0 */
+ 1, /* minor version number */
test_init,
test_cleanup,
test_open,
@@ -569,5 +627,7 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
NULL, /* check_policy_tgs */
NULL, /* audit_as_req */
NULL, /* refresh_config */
- test_check_allowed_to_delegate
+ test_check_allowed_to_delegate,
+ NULL, /* free_principal_e_data */
+ test_get_s4u_x509_principal
};
diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py
index 7aff9af..63183aa 100755
--- a/src/tests/gssapi/t_s4u.py
+++ b/src/tests/gssapi/t_s4u.py
@@ -1,4 +1,6 @@
from k5test import *
+from base64 import b64encode
+import shutil
realm = K5Realm(create_host=False, get_creds=False)
usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache')
@@ -159,7 +161,8 @@ for realm in multipass_realms(create_host=False, get_creds=False):
mark('cross-realm S4U2Self')
testprincs = {'krbtgt/SREALM': {'keys': 'aes128-cts'},
'krbtgt/UREALM': {'keys': 'aes128-cts'},
- 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}}
+ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'other': {'keys': 'aes128-cts'}}
kdcconf1 = {'realms': {'$realm': {'database_module': 'test'}},
'dbmodules': {'test': {'db_library': 'test',
'princs': testprincs,
@@ -178,6 +181,8 @@ r1.start_kdc()
r2.start_kdc()
r1.extract_keytab(r1.user_princ, r1.keytab)
r1.kinit(r1.user_princ, None, ['-k', '-t', r1.keytab])
+savefile = r1.ccache + '.save'
+shutil.copyfile(r1.ccache, savefile)
# Include a regression test for #8741 by unsetting the default realm.
remove_default = {'libdefaults': {'default_realm': None}}
@@ -193,7 +198,7 @@ msgs = ('Getting credentials user@UREALM -> user@SREALM',
r1.run(['./t_s4u', 'p:' + r2.user_princ, '-', r1.keytab], env=no_default,
expected_trace=msgs)
-# Test realm identification of enterprise principal names ([MS-S4U]
+# Test realm identification of enterprise principal names ([MS-SFU]
# 3.1.5.1.1.1). Attach a bogus realm to the enterprise name to verify
# that we start at the server realm.
mark('cross-realm S4U2Self with enterprise name')
@@ -209,6 +214,70 @@ msgs = ('Getting initial credentials for enterprise\\@abc@SREALM',
r1.run(['./t_s4u', 'e:enterprise@abc@NOREALM', '-', r1.keytab],
expected_trace=msgs)
+mark('S4U2Self using X509 certificate')
+
+# Encode name as a PEM certificate file (sort of) for use by kvno.
+def princ_cert(name):
+ enc = b64encode(name.encode('ascii')).decode('ascii')
+ return '-----BEGIN CERTIFICATE-----\n%s\n-----END y\n' % enc
+
+cert_path = os.path.join(r1.testdir, 'fake_cert')
+with open(cert_path, "w") as cert_file:
+ cert_file.write(princ_cert('other'))
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting initial credentials for @SREALM',
+ 'Identified realm of client principal as SREALM',
+ 'TGS reply is for other@SREALM',
+ 'Getting credentials other@SREALM',
+ 'Storing other@SREALM')
+r1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs)
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting credentials other@SREALM',
+ 'TGS reply is for other@SREALM',
+ 'Storing other@SREALM')
+r1.run([kvno, '-I', 'other', '-F', cert_path, r1.user_princ],
+ expected_trace=msgs)
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting initial credentials for other@SREALM',
+ 'Identified realm of client principal as SREALM',
+ 'Getting credentials other@SREALM',
+ 'TGS reply is for other@SREALM',
+ 'Storing other@SREALM')
+r1.run([kvno, '-U', 'other', '-F', cert_path, r1.user_princ],
+ expected_trace=msgs)
+
+mark('cross-realm S4U2Self using X509 certificate')
+
+with open(cert_path, "w") as cert_file:
+ cert_file.write(princ_cert('user@UREALM'))
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting initial credentials for @SREALM',
+ 'Identified realm of client principal as UREALM',
+ 'TGS reply is for user@UREALM',
+ 'Getting credentials user@UREALM',
+ 'Storing user@UREALM')
+r1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs)
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting credentials user@UREALM',
+ 'TGS reply is for user@UREALM',
+ 'Storing user@UREALM')
+r1.run([kvno, '-I', 'user@UREALM', '-F', cert_path, r1.user_princ],
+ expected_trace=msgs)
+
+shutil.copyfile(savefile, r1.ccache)
+msgs = ('Getting initial credentials for enterprise\\@abc@SREALM',
+ 'Identified realm of client principal as UREALM',
+ 'Getting credentials enterprise\\@abc@UREALM',
+ 'TGS reply is for enterprise\\@abc@UREALM',
+ 'Storing enterprise\\@abc@UREALM')
+r1.run([kvno, '-U', 'enterprise@abc', '-F', cert_path, r1.user_princ],
+ expected_trace=msgs)
+
r1.stop()
r2.stop()