diff options
author | Simo Sorce <simo@redhat.com> | 2017-01-13 12:35:31 -0500 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2017-01-13 20:10:52 -0500 |
commit | e7e9534d7b438f9e99a529496b89d94f6a45cdf3 (patch) | |
tree | 68dda7e71ce3dec0e8c369831335656b34f6170e | |
parent | e1a6805083903a23e9b3287b051f035a3f9f1f01 (diff) | |
download | gss-proxy-allow_s4u2s.tar.gz gss-proxy-allow_s4u2s.tar.xz gss-proxy-allow_s4u2s.zip |
Add more impersonation testsallow_s4u2s
Sets up separate service to test multiple configurations.
Signed-off-by: Simo Sorce <simo@redhat.com>
-rw-r--r-- | proxy/tests/t_impersonate.c | 124 | ||||
-rwxr-xr-x[-rw-r--r--] | proxy/tests/t_impersonate.py | 111 | ||||
-rwxr-xr-x[-rw-r--r--] | proxy/tests/testlib.py | 55 |
3 files changed, 244 insertions, 46 deletions
diff --git a/proxy/tests/t_impersonate.c b/proxy/tests/t_impersonate.c index 1e54a2b..3ff463d 100644 --- a/proxy/tests/t_impersonate.c +++ b/proxy/tests/t_impersonate.c @@ -2,13 +2,13 @@ #include "t_utils.h" #include <unistd.h> +#include <stdbool.h> int main(int argc, const char *argv[]) { char buffer[MAX_RPC_SIZE]; uint32_t buflen; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; - gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; gss_ctx_id_t init_ctx = GSS_C_NO_CONTEXT; gss_ctx_id_t accept_ctx = GSS_C_NO_CONTEXT; @@ -20,9 +20,13 @@ int main(int argc, const char *argv[]) uint32_t ret_maj; uint32_t ret_min; uint32_t time_rec; + uint32_t flags = GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG; int ret = -1; + bool selfhalf = false; + bool proxyhalf = false; + const char *deleg_ccache = NULL; - if (argc != 3) return -1; + if (argc < 3) return -1; ret = t_string_to_name(argv[1], &user_name, GSS_C_NT_USER_NAME); if (ret) { @@ -39,41 +43,100 @@ int main(int argc, const char *argv[]) goto done; } - ret_maj = gss_acquire_cred(&ret_min, - GSS_C_NO_NAME, - GSS_C_INDEFINITE, - &oid_set, - GSS_C_BOTH, - &impersonator_cred_handle, - NULL, NULL); - if (ret_maj != GSS_S_COMPLETE) { - DEBUG("gss_acquire_cred() failed\n"); - t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); - ret = -1; - goto done; + if (argc > 3) { + if (strcmp(argv[3], "s4u2self") == 0) { + selfhalf = true; + } else if (strcmp(argv[3], "s4u2proxy") == 0) { + proxyhalf = true; + } else { + DEBUG("Invalid argument 3: %s\n", argv[3]); + ret = -1; + goto done; + } + if (argc < 5) { + DEBUG("Option %s requires additional arguments\n", argv[3]); + ret = -1; + goto done; + } + deleg_ccache = argv[4]; + DEBUG("S4U2%s half [ccache %s]\n", selfhalf?"Self":"Proxy", argv[4]); } - ret_maj = gss_acquire_cred_impersonate_name(&ret_min, - impersonator_cred_handle, - user_name, - GSS_C_INDEFINITE, - &oid_set, - GSS_C_INITIATE, - &user_cred_handle, - NULL, NULL); - if (ret_maj != GSS_S_COMPLETE) { - DEBUG("gss_acquire_cred_impersonate_name() failed\n"); - t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); - ret = -1; + if (proxyhalf) { + gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; + gss_key_value_set_desc cred_store = { 1, &ccelement }; + + ret_maj = gss_acquire_cred_from(&ret_min, + GSS_C_NO_NAME, + GSS_C_INDEFINITE, + &oid_set, + GSS_C_INITIATE, + &cred_store, + &cred_handle, + NULL, NULL); + if (ret_maj != GSS_S_COMPLETE) { + DEBUG("gss_acquire_cred_from() [s4u2proxy] failed\n"); + t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); + ret = -1; + goto done; + } + + flags = GSS_C_MUTUAL_FLAG; + } else { + + ret_maj = gss_acquire_cred(&ret_min, + GSS_C_NO_NAME, + GSS_C_INDEFINITE, + &oid_set, + GSS_C_BOTH, + &impersonator_cred_handle, + NULL, NULL); + if (ret_maj != GSS_S_COMPLETE) { + DEBUG("gss_acquire_cred() failed\n"); + t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); + ret = -1; + goto done; + } + + ret_maj = gss_acquire_cred_impersonate_name(&ret_min, + impersonator_cred_handle, + user_name, + GSS_C_INDEFINITE, + &oid_set, + GSS_C_INITIATE, + &cred_handle, + NULL, NULL); + if (ret_maj != GSS_S_COMPLETE) { + DEBUG("gss_acquire_cred_impersonate_name() failed\n"); + t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); + ret = -1; + goto done; + } + } + + if (selfhalf) { + gss_key_value_element_desc ccelement = { "ccache", deleg_ccache }; + gss_key_value_set_desc cred_store = { 1, &ccelement }; + + ret_maj = gss_store_cred_into(&ret_min, + cred_handle, + GSS_C_INITIATE, + discard_const(gss_mech_krb5), 1, 0, + &cred_store, NULL, NULL); + if (ret_maj != GSS_S_COMPLETE) { + DEBUG("gss_store_cred_into() failed\n"); + t_log_failure(GSS_C_NO_OID, ret_maj, ret_min); + ret = -1; + } goto done; } ret_maj = gss_init_sec_context(&ret_min, - user_cred_handle, + cred_handle, &init_ctx, target_name, GSS_C_NO_OID, - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &in_token, @@ -123,11 +186,11 @@ int main(int argc, const char *argv[]) gss_release_buffer(&ret_min, &out_token); ret_maj = gss_init_sec_context(&ret_min, - user_cred_handle, + cred_handle, &init_ctx, target_name, GSS_C_NO_OID, - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &in_token, @@ -147,6 +210,7 @@ int main(int argc, const char *argv[]) done: gss_release_buffer(&ret_min, &in_token); gss_release_buffer(&ret_min, &out_token); + gss_release_cred(&ret_min, &impersonator_cred_handle); gss_release_cred(&ret_min, &cred_handle); return ret; } diff --git a/proxy/tests/t_impersonate.py b/proxy/tests/t_impersonate.py index 43bb084..9bfd2cd 100644..100755 --- a/proxy/tests/t_impersonate.py +++ b/proxy/tests/t_impersonate.py @@ -3,21 +3,54 @@ from testlib import * -def run(testdir, env, conf, expected_failure=False): - print("Testing impersonate creds...", file=sys.stderr) - logfile = conf['logfile'] +IMPERSONATE_CONF_TEMPLATE = ''' +[gssproxy] + debug_level = 2 - testenv = {'KRB5CCNAME': os.path.join(testdir, 't' + conf['prefix'] + - '_impersonate.ccache'), - 'KRB5_KTNAME': conf['keytab'], - 'KRB5_TRACE': os.path.join(testdir, 't' + conf['prefix'] + - '_impersonate.trace'), - 'GSS_USE_PROXY': 'yes', - 'GSSPROXY_BEHAVIOR': 'REMOTE_FIRST'} - testenv.update(env) +[service/impersonate] + socket = ${TESTDIR}/impersonate.socket + mechs = krb5 + cred_store = keytab:${GSSPROXY_KEYTAB} + cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} + cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} + allow_protocol_transition = yes + allow_constrained_delegation = yes + euid = ${UIDNUMBER} - cmd = ["./tests/t_impersonate", USR_NAME, conf['svc_name']] - print("[COMMAND]\n%s\n[ENVIRONMENT]\n%s\n" % (cmd, env), file=logfile) +[service/selfonly] + socket = ${TESTDIR}/impersonate-selfonly.socket + mechs = krb5 + cred_store = keytab:${GSSPROXY_KEYTAB} + cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} + cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} + allow_protocol_transition = yes + euid = ${UIDNUMBER} + +[service/proxyonly] + socket = ${TESTDIR}/impersonate-proxyonly.socket + mechs = krb5 + cred_store = keytab:${GSSPROXY_KEYTAB} + cred_store = ccache:FILE:${GSSPROXY_CLIENT_CCACHE} + cred_store = client_keytab:${GSSPROXY_CLIENT_KEYTAB} + allow_constrained_delegation = yes + euid = ${UIDNUMBER} + +''' + +def run_cmd(testdir, env, conf, name, socket, cmd, expected_failure): + + logfile = conf['logfile'] + testenv = env.copy() + testenv.update({'KRB5CCNAME': os.path.join(testdir, 't' + conf['prefix'] + + '_impersonate.ccache'), + 'KRB5_KTNAME': os.path.join(testdir, PROXY_KTNAME), + 'KRB5_TRACE': os.path.join(testdir, 't' + conf['prefix'] + + '_impersonate.trace'), + 'GSS_USE_PROXY': 'yes', + 'GSSPROXY_SOCKET': socket, + 'GSSPROXY_BEHAVIOR': 'REMOTE_FIRST'}) + + print("[COMMAND]\n%s\n[ENVIRONMENT]\n%s\n" % (cmd, testenv), file=logfile) logfile.flush() p1 = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=logfile, @@ -27,4 +60,54 @@ def run(testdir, env, conf, expected_failure=False): except subprocess.TimeoutExpired: # p1.returncode is set to None here pass - print_return(p1.returncode, "Impersonate", expected_failure) + print_return(p1.returncode, name, expected_failure) + + +def run(testdir, env, conf, expected_failure=False): + print("Testing impersonate creds...", file=sys.stderr) + path_prefix = os.path.join(testdir, 't' + conf['prefix'] + '_') + + # Change gssproxy conf for our test + keysenv = conf["keysenv"].copy() + keysenv['KRB5_KTNAME'] = os.path.join(testdir, PROXY_KTNAME) + update_gssproxy_conf(testdir, keysenv, IMPERSONATE_CONF_TEMPLATE) + os.kill(conf["gpid"], signal.SIGHUP) + time.sleep(1) #Let gssproxy reload everything + + # Test all permitted + socket = os.path.join(testdir, 'impersonate.socket') + cmd = ["./tests/t_impersonate", USR_NAME, conf['svc_name']] + run_cmd(testdir, env, conf, "Impersonate", socket, cmd, False) + + #Test fail + socket = os.path.join(testdir, 'impersonate-proxyonly.socket') + cmd = ["./tests/t_impersonate", USR_NAME, conf['svc_name']] + run_cmd(testdir, env, conf, "Impersonate fail self", socket, cmd, True) + + #Test fail + socket = os.path.join(testdir, 'impersonate-selfonly.socket') + cmd = ["./tests/t_impersonate", USR_NAME, conf['svc_name']] + run_cmd(testdir, env, conf, "Impersonate fail proxy", socket, cmd, True) + + #Test s4u2self half succeed + socket = os.path.join(testdir, 'impersonate-selfonly.socket') + cmd = ["./tests/t_impersonate", USR_NAME, conf['svc_name'], 's4u2self', + path_prefix + 'impersonate-proxy.ccache'] + run_cmd(testdir, env, conf, "s4u2self delegation", socket, cmd, False) + + #Test s4u2proxy half fail + socket = os.path.join(testdir, 'impersonate-selfonly.socket') + cmd = ["./tests/t_impersonate", USR_NAME, PROXY_GSS, 's4u2proxy', + path_prefix + 'impersonate-proxy.ccache'] + run_cmd(testdir, env, conf, "s4u2proxy fail", socket, cmd, True) + + #Test s4u2proxy half succeed + socket = os.path.join(testdir, 'impersonate-proxyonly.socket') + cmd = ["./tests/t_impersonate", USR_NAME, PROXY_GSS, 's4u2proxy', + path_prefix + 'impersonate-proxy.ccache'] + run_cmd(testdir, env, conf, "s4u2proxy", socket, cmd, False) + + # Reset back gssproxy conf + update_gssproxy_conf(testdir, keysenv, GSSPROXY_CONF_TEMPLATE) + os.kill(conf["gpid"], signal.SIGHUP) + time.sleep(1) #Let gssproxy reload everything diff --git a/proxy/tests/testlib.py b/proxy/tests/testlib.py index aa2c914..80b88d6 100644..100755 --- a/proxy/tests/testlib.py +++ b/proxy/tests/testlib.py @@ -344,6 +344,43 @@ USR2_PWD = "usrpwd" MULTI_KTNAME = "multi.gssproxy.keytab" MULTI_UPN = "multi$" MULTI_SVC = "multi/%s" % WRAP_HOSTNAME +HOST_SVC = "host/%s" % WRAP_HOSTNAME +PROXY_SVC = "proxy/%s" % WRAP_HOSTNAME +PROXY_GSS = "proxy@%s" % WRAP_HOSTNAME +PROXY_KTNAME = "proxy.keytab" + +PROXY_LDIF_TEMPLATE = """ +dn: krbPrincipalName=${HOST_SVC}@${TESTREALM},cn=${TESTREALM},cn=${KRB5_CN},${LDAP_REALM} +changetype: modify +add: krbAllowedToDelegateTo +krbAllowedToDelegateTo: ${PROXY_SVC}@${TESTREALM} +- +""" + +def authorize_to_proxy(testdir, env): + testlog = os.path.join(testdir, 'kerbsetup.log') + + t = Template(PROXY_LDIF_TEMPLATE) + text = t.substitute({"HOST_SVC": HOST_SVC, + "PROXY_SVC": PROXY_SVC, + "TESTREALM": TESTREALM, + "LDAP_REALM": LDAP_REALM, + "KRB5_CN": KRB5_CN}) + ldif = os.path.join(testdir, "ldap", "k5proxy.ldif") + with open(ldif, "w+") as f: + f.write(text) + + with open(testlog, "a") as logfile: + lmod = subprocess.Popen(["ldapmodify", "-w", LDAP_PW, "-H", + "ldap://%s" % WRAP_HOSTNAME, "-D", + "%s,%s" % (KRB5_USER, LDAP_REALM), + "-f", ldif], + stdout=logfile, stderr=logfile, env=env, + preexec_fn=os.setsid) + + lmod.wait() + if lmod.returncode != 0: + raise ValueError("Proxy princ setup failed") def setup_keys(testdir, env): @@ -351,7 +388,8 @@ def setup_keys(testdir, env): svc_name = "host/%s" % WRAP_HOSTNAME svc_keytab = os.path.join(testdir, SVC_KTNAME) - cmd = "addprinc -randkey -e %s %s" % (KEY_TYPE, svc_name) + cmd = "addprinc -randkey -e %s +ok_to_auth_as_delegate %s" % (KEY_TYPE, + svc_name) with (open(testlog, 'a')) as logfile: kadmin_local(cmd, env, logfile) cmd = "ktadd -k %s -e %s %s" % (svc_keytab, KEY_TYPE, svc_name) @@ -370,6 +408,18 @@ def setup_keys(testdir, env): with (open(testlog, 'a')) as logfile: kadmin_local(cmd, env, logfile) + proxy_keytab = os.path.join(testdir, PROXY_KTNAME) + cmd = "addprinc -randkey -e %s -requires_preauth %s" % (KEY_TYPE, + PROXY_SVC) + with (open(testlog, 'a')) as logfile: + kadmin_local(cmd, env, logfile) + shutil.copy(svc_keytab, proxy_keytab) + cmd = "ktadd -k %s -e %s %s" % (proxy_keytab, KEY_TYPE, PROXY_SVC) + with (open(testlog, 'a')) as logfile: + kadmin_local(cmd, env, logfile) + + authorize_to_proxy(testdir, env) + keys_env = {"client_keytab": usr_keytab, "KRB5_KTNAME": svc_keytab} keys_env.update(env) @@ -532,7 +582,8 @@ def update_gssproxy_conf(testdir, env, template): 'GSSPROXY_CLIENT_CCACHE': ccache, 'GSSPROXY_CLIENT_KEYTAB': ckeytab, 'UIDNUMBER': os.getuid(), - 'SECOND_SOCKET': socket2} + 'SECOND_SOCKET': socket2, + 'TESTDIR': testdir} if 'client_name' in env: subs['GSSPROXY_CLIENT_PRINCIPAL'] = env['client_name'] text = t.substitute(subs) |