aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2020-09-16 15:07:09 -0400
committerGreg Hudson <ghudson@mit.edu>2020-11-18 11:28:19 -0500
commitf54b49d06cd2e468abb499df1b9d577054a4fb20 (patch)
tree3330b9d99a4f5f08dc78e921856376735a6ff0cd /src
parent938b535145a9cc312e42f99782af75067cfec588 (diff)
downloadkrb5-f54b49d06cd2e468abb499df1b9d577054a4fb20.zip
krb5-f54b49d06cd2e468abb499df1b9d577054a4fb20.tar.gz
krb5-f54b49d06cd2e468abb499df1b9d577054a4fb20.tar.bz2
Add password option to cred store
Add an option for initial creds acquisition via password to gss_acquire_cred_from(), storing credentials in a new MEMORY ccache. Move existing cred store tests from t_gssapi.py to t_credstore.py and add new ones for password acquisition. [ghudson@mit.edu: squashed commits; rewrote commit message] ticket: 8962 (new)
Diffstat (limited to 'src')
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c26
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h1
-rw-r--r--src/tests/gssapi/Makefile.in1
-rw-r--r--src/tests/gssapi/t_credstore.c6
-rw-r--r--src/tests/gssapi/t_credstore.py50
-rwxr-xr-xsrc/tests/gssapi/t_gssapi.py21
6 files changed, 81 insertions, 24 deletions
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 519abae..4270bdf 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -1182,6 +1182,8 @@ acquire_cred_from(OM_uint32 *minor_status, const gss_name_t desired_name,
krb5_keytab keytab = NULL;
krb5_ccache ccache = NULL;
const char *rcname, *value;
+ gss_buffer_desc pwbuf;
+ gss_buffer_t password = NULL;
OM_uint32 ret;
code = gss_krb5int_initialize_library();
@@ -1241,7 +1243,29 @@ acquire_cred_from(OM_uint32 *minor_status, const gss_name_t desired_name,
if (GSS_ERROR(ret))
goto out;
- ret = acquire_cred_context(context, minor_status, desired_name, NULL,
+ ret = kg_value_from_cred_store(cred_store, KRB5_CS_PASSWORD_URN, &value);
+ if (GSS_ERROR(ret))
+ goto out;
+
+ if (value) {
+ /* We must be acquiring an initiator cred with an explicit name. A
+ * password is mutually exclusive with a client keytab or ccache. */
+ if (desired_name == GSS_C_NO_NAME) {
+ ret = GSS_S_BAD_NAME;
+ goto out;
+ }
+ if (cred_usage == GSS_C_ACCEPT || desired_name == GSS_C_NO_NAME ||
+ ccache != NULL || client_keytab != NULL) {
+ *minor_status = (OM_uint32)G_BAD_USAGE;
+ ret = GSS_S_FAILURE;
+ goto out;
+ }
+ pwbuf.length = strlen(value);
+ pwbuf.value = (void *)value;
+ password = &pwbuf;
+ }
+
+ ret = acquire_cred_context(context, minor_status, desired_name, password,
time_req, cred_usage, ccache, client_keytab,
keytab, rcname, iakerb, output_cred_handle,
time_rec);
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index f21a7de..3214eb9 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1296,6 +1296,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer)
#define KRB5_CS_KEYTAB_URN "keytab"
#define KRB5_CS_CCACHE_URN "ccache"
#define KRB5_CS_RCACHE_URN "rcache"
+#define KRB5_CS_PASSWORD_URN "password"
OM_uint32
kg_value_from_cred_store(gss_const_key_value_set_t cred_store,
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index 828c2b7..23f7d0e 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -50,6 +50,7 @@ check-pytests: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect \
t_export_name t_imp_cred t_inq_cred t_inq_ctx t_inq_mechs_name t_iov \
t_lifetime t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs
$(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_credstore.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_bindings.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS)
diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c
index 0278581..1e36369 100644
--- a/src/tests/gssapi/t_credstore.c
+++ b/src/tests/gssapi/t_credstore.c
@@ -42,7 +42,7 @@ main(int argc, char *argv[])
{
OM_uint32 minor, major;
gss_key_value_set_desc store;
- gss_name_t name;
+ gss_name_t name = GSS_C_NO_NAME;
gss_cred_usage_t cred_usage = GSS_C_BOTH;
gss_OID_set mechs = GSS_C_NO_OID_SET;
gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
@@ -71,7 +71,9 @@ main(int argc, char *argv[])
/* Get the principal name. */
if (*argv == NULL)
usage();
- name = import_name(*argv++);
+ if (**argv != '\0')
+ name = import_name(*argv);
+ argv++;
/* Put any remaining arguments into the store. */
store.elements = calloc(argc, sizeof(struct gss_key_value_element_struct));
diff --git a/src/tests/gssapi/t_credstore.py b/src/tests/gssapi/t_credstore.py
new file mode 100644
index 0000000..ebb79d8
--- /dev/null
+++ b/src/tests/gssapi/t_credstore.py
@@ -0,0 +1,50 @@
+from k5test import *
+
+realm = K5Realm()
+
+mark('gss_store_cred_into() and ccache/keytab')
+storagecache = 'FILE:' + os.path.join(realm.testdir, 'user_store')
+servicekeytab = os.path.join(realm.testdir, 'kt')
+service_cs = 'service/cs@%s' % realm.realm
+realm.addprinc(service_cs)
+realm.extract_keytab(service_cs, servicekeytab)
+realm.kinit(service_cs, None, ['-k', '-t', servicekeytab])
+msgs = ('Storing %s -> %s in %s' % (service_cs, realm.krbtgt_princ,
+ storagecache),
+ 'Retrieving %s from FILE:%s' % (service_cs, servicekeytab))
+realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache,
+ 'keytab', servicekeytab], expected_trace=msgs)
+
+mark('rcache')
+# t_credstore -r should produce a replay error normally, but not with
+# rcache set to "none:".
+output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ],
+ expected_code=1)
+if 'gss_accept_sec_context(2): Request is a replay' not in output:
+ fail('Expected replay error not seen in t_credstore output')
+realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ,
+ 'rcache', 'none:'])
+
+# Test password feature.
+mark('password')
+# Must be used with a desired name.
+realm.run(['./t_credstore', '-i', '', 'password', 'pw'],
+ expected_code=1, expected_msg='An invalid name was supplied')
+# Must not be used with a client keytab.
+realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ,
+ 'password', 'pw', 'client_keytab', servicekeytab],
+ expected_code=1, expected_msg='Credential usage type is unknown')
+# Must not be used with a ccache.
+realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ,
+ 'password', 'pw', 'ccache', storagecache],
+ expected_code=1, expected_msg='Credential usage type is unknown')
+# Must be acquiring initiator credentials.
+realm.run(['./t_credstore', '-a', 'u:' + realm.user_princ, 'password', 'pw'],
+ expected_code=1, expected_msg='Credential usage type is unknown')
+msgs = ('Getting initial credentials for %s' % realm.user_princ,
+ 'Storing %s -> %s in MEMORY:' % (realm.user_princ, realm.krbtgt_princ),
+ 'Destroying ccache MEMORY:')
+realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password',
+ password('user')], expected_trace=msgs)
+
+success('Credential store tests')
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
index ecf9826..ff2e248 100755
--- a/src/tests/gssapi/t_gssapi.py
+++ b/src/tests/gssapi/t_gssapi.py
@@ -67,27 +67,6 @@ realm.run(['./t_imp_cred', 'p:service1/andrew', 'service1/abraham'])
realm.run(['./t_imp_cred', 'p:service2/dwight'], expected_code=1,
expected_msg=' not found in keytab')
-# Test credential store extension.
-tmpccname = 'FILE:' + os.path.join(realm.testdir, 'def_cache')
-realm.env['KRB5CCNAME'] = tmpccname
-storagecache = 'FILE:' + os.path.join(realm.testdir, 'user_store')
-servicekeytab = os.path.join(realm.testdir, 'kt')
-service_cs = 'service/cs@%s' % realm.realm
-realm.addprinc(service_cs)
-realm.extract_keytab(service_cs, servicekeytab)
-realm.kinit(service_cs, None, ['-k', '-t', servicekeytab])
-realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache,
- 'keytab', servicekeytab])
-
-# Test rcache feature of cred stores. t_credstore -r should produce a
-# replay error normally, but not with rcache set to "none:".
-output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ],
- expected_code=1)
-if 'gss_accept_sec_context(2): Request is a replay' not in output:
- fail('Expected replay error not seen in t_credstore output')
-realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ,
- 'rcache', 'none:'])
-
# Verify that we can't acquire acceptor creds without a keytab.
os.remove(realm.keytab)
output = realm.run(['./t_accname', 'p:abc'], expected_code=1)