diff options
author | Simo Sorce <simo@redhat.com> | 2020-09-16 15:07:09 -0400 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2020-11-18 11:28:19 -0500 |
commit | f54b49d06cd2e468abb499df1b9d577054a4fb20 (patch) | |
tree | 3330b9d99a4f5f08dc78e921856376735a6ff0cd /src | |
parent | 938b535145a9cc312e42f99782af75067cfec588 (diff) | |
download | krb5-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.c | 26 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapiP_krb5.h | 1 | ||||
-rw-r--r-- | src/tests/gssapi/Makefile.in | 1 | ||||
-rw-r--r-- | src/tests/gssapi/t_credstore.c | 6 | ||||
-rw-r--r-- | src/tests/gssapi/t_credstore.py | 50 | ||||
-rwxr-xr-x | src/tests/gssapi/t_gssapi.py | 21 |
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) |