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();
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);
#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,
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)
{
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;
/* 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));
--- /dev/null
+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')
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)