diff options
| author | Greg Hudson <ghudson@mit.edu> | 2010-04-30 21:22:48 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2010-04-30 21:22:48 +0000 |
| commit | baea9a7a27d781581505f0bb6d0ac4e4f24053aa (patch) | |
| tree | af04244ed8b910bed378296d0b263c5f2b3a3ffc /src/appl | |
| parent | d20d802b8e44178017fd1a1da55a72194f50da55 (diff) | |
| download | krb5-baea9a7a27d781581505f0bb6d0ac4e4f24053aa.tar.gz krb5-baea9a7a27d781581505f0bb6d0ac4e4f24053aa.tar.xz krb5-baea9a7a27d781581505f0bb6d0ac4e4f24053aa.zip | |
Add IAKERB mechanism and gss_acquire_cred_with_password
Merge branches/iakerb to trunk. Includes the following:
* New IAKERB mechanism.
* New gss_acquire_cred_with_password mechglue function.
* ASN.1 encoders and decoders for IAKERB structures (with tests).
* New shortcuts in gss-sample client and server.
* Tests to exercise SPNEGO and IAKERB using gss-sample application.
ticket: 6712
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23960 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl')
| -rw-r--r-- | src/appl/gss-sample/gss-client.c | 90 | ||||
| -rw-r--r-- | src/appl/gss-sample/gss-server.c | 13 | ||||
| -rw-r--r-- | src/appl/gss-sample/t_gss_sample.py | 46 |
3 files changed, 136 insertions, 13 deletions
diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c index ad314c270..d922cc3bd 100644 --- a/src/appl/gss-sample/gss-client.c +++ b/src/appl/gss-sample/gss-client.c @@ -64,6 +64,8 @@ #endif #include <gssapi/gssapi_generic.h> +#include <gssapi/gssapi_krb5.h> +#include <gssapi/gssapi_ext.h> #include "gss-misc.h" static int verbose = 1; @@ -72,7 +74,7 @@ static void usage() { fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n"); - fprintf(stderr, " [-seq] [-noreplay] [-nomutual]"); + fprintf(stderr, " [-seq] [-noreplay] [-nomutual] [-user user] [-pass pw]"); #ifdef _WIN32 fprintf(stderr, " [-threads num]"); #endif @@ -162,6 +164,7 @@ connect_to_server(char *host, u_short port) static int client_establish_context(int s, char *service_name, OM_uint32 gss_flags, int auth_flag, int v1_format, gss_OID oid, + char *username, char *password, gss_ctx_id_t *gss_context, OM_uint32 *ret_flags) { if (auth_flag) { @@ -169,6 +172,53 @@ client_establish_context(int s, char *service_name, OM_uint32 gss_flags, gss_name_t target_name; OM_uint32 maj_stat, min_stat, init_sec_min_stat; int token_flags; + gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; + gss_name_t gss_username = GSS_C_NO_NAME; + gss_OID_set_desc mechs, *mechsp = GSS_C_NO_OID_SET; + + if (oid != GSS_C_NO_OID) { + mechs.elements = oid; + mechs.count = 1; + mechsp = &mechs; + } + + if (username != NULL) { + send_tok.value = username; + send_tok.length = strlen(username); + + maj_stat = gss_import_name(&min_stat, &send_tok, + (gss_OID) gss_nt_user_name, + &gss_username); + if (maj_stat != GSS_S_COMPLETE) { + display_status("parsing client name", maj_stat, min_stat); + return -1; + } + } + + if (password != NULL) { + gss_buffer_desc pwbuf; + + pwbuf.value = password; + pwbuf.length = strlen(password); + + maj_stat = gss_acquire_cred_with_password(&min_stat, + gss_username, + &pwbuf, 0, + mechsp, GSS_C_INITIATE, + &cred, NULL, NULL); + } else if (gss_username != GSS_C_NO_NAME) { + maj_stat = gss_acquire_cred(&min_stat, + gss_username, 0, + mechsp, GSS_C_INITIATE, + &cred, NULL, NULL); + } else + maj_stat = GSS_S_COMPLETE; + if (maj_stat != GSS_S_COMPLETE) { + display_status("acquiring creds", maj_stat, min_stat); + gss_release_name(&min_stat, &gss_username); + return -1; + } + gss_release_name(&min_stat, &gss_username); /* * Import the name into target_name. Use send_tok to save @@ -213,7 +263,7 @@ client_establish_context(int s, char *service_name, OM_uint32 gss_flags, do { maj_stat = gss_init_sec_context(&init_sec_min_stat, - GSS_C_NO_CREDENTIAL, gss_context, + cred, gss_context, target_name, oid, gss_flags, 0, NULL, /* channel bindings */ token_ptr, NULL, /* mech type */ @@ -260,6 +310,7 @@ client_establish_context(int s, char *service_name, OM_uint32 gss_flags, printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); + (void) gss_release_cred(&min_stat, &cred); (void) gss_release_name(&min_stat, &target_name); } else { if (send_token(s, TOKEN_NOOP, empty_token) < 0) @@ -344,7 +395,7 @@ read_file(file_name, in_buf) static int call_server(host, port, oid, service_name, gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format, msg, use_file, - mcount) + mcount, username, password) char *host; u_short port; gss_OID oid; @@ -355,6 +406,8 @@ call_server(host, port, oid, service_name, gss_flags, auth_flag, char *msg; int use_file; int mcount; + char *username; + char *password; { gss_ctx_id_t context; gss_buffer_desc in_buf, out_buf; @@ -380,7 +433,8 @@ call_server(host, port, oid, service_name, gss_flags, auth_flag, /* Establish context */ if (client_establish_context(s, service_name, gss_flags, auth_flag, - v1_format, oid, &context, &ret_flags) < 0) { + v1_format, oid, username, password, + &context, &ret_flags) < 0) { (void) close(s); return -1; } @@ -663,13 +717,15 @@ static OM_uint32 min_stat; static gss_OID oid = GSS_C_NULL_OID; static int mcount = 1, ccount = 1; static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; +static char *username = NULL; +static char *password = NULL; static void worker_bee(void *unused) { if (call_server(server_host, port, oid, service_name, gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, - v1_format, msg, use_file, mcount) < 0) + v1_format, msg, use_file, mcount, username, password) < 0) exit(1); #ifdef _WIN32 @@ -705,17 +761,33 @@ main(argc, argv) if (!argc) usage(); mechanism = *argv; - } + } else if (strcmp(*argv, "-user") == 0) { + argc--; + argv++; + if (!argc) + usage(); + username = *argv; + } else if (strcmp(*argv, "-pass") == 0) { + argc--; + argv++; + if (!argc) + usage(); + password = *argv; + } else if (strcmp(*argv, "-iakerb") == 0) { + mechanism = "{ 1 3 6 1 5 2 5 }"; + } else if (strcmp(*argv, "-spnego") == 0) { + mechanism = "{ 1 3 6 1 5 5 2 }"; + } else if (strcmp(*argv, "-krb5") == 0) { + mechanism = "{ 1 3 5 1 5 2 }"; #ifdef _WIN32 - else if (strcmp(*argv, "-threads") == 0) { + } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); - } #endif - else if (strcmp(*argv, "-d") == 0) { + } else if (strcmp(*argv, "-d") == 0) { gss_flags |= GSS_C_DELEG_FLAG; } else if (strcmp(*argv, "-seq") == 0) { gss_flags |= GSS_C_SEQUENCE_FLAG; diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c index 8b59eb276..0ddfaeee8 100644 --- a/src/appl/gss-sample/gss-server.c +++ b/src/appl/gss-sample/gss-server.c @@ -58,6 +58,7 @@ #include <ctype.h> #include <gssapi/gssapi_generic.h> +#include <gssapi/gssapi_krb5.h> #include "gss-misc.h" #ifdef HAVE_STRING_H @@ -75,7 +76,8 @@ usage() #endif fprintf(stderr, "\n"); fprintf(stderr, - " [-inetd] [-export] [-logfile file] service_name\n"); + " [-inetd] [-export] [-logfile file] [-keytab keytab]\n" + " service_name\n"); exit(1); } @@ -690,6 +692,15 @@ main(int argc, char **argv) exit(1); } } + } else if (strcmp(*argv, "-keytab") == 0) { + argc--; + argv++; + if (!argc) + usage(); + if (krb5_gss_register_acceptor_identity(*argv)) { + fprintf(stderr, "failed to register keytab\n"); + exit(1); + } } else break; argc--; diff --git a/src/appl/gss-sample/t_gss_sample.py b/src/appl/gss-sample/t_gss_sample.py index 8a09b2123..09d0803ce 100644 --- a/src/appl/gss-sample/t_gss_sample.py +++ b/src/appl/gss-sample/t_gss_sample.py @@ -27,14 +27,54 @@ appdir = os.path.join(buildtop, 'appl', 'gss-sample') gss_client = os.path.join(appdir, 'gss-client') gss_server = os.path.join(appdir, 'gss-server') -for realm in multipass_realms(): +# Run a gss-server process and a gss-client process, with additional +# gss-client flags given by options. Verify that gss-client displayed +# the expected output for a successful negotiation, and that we +# obtained credentials for the host service. +def server_client_test(realm, options): portstr = str(realm.server_port()) server = realm.start_server([gss_server, '-port', portstr, 'host'], 'starting...') - output = realm.run_as_client([gss_client, '-port', portstr, - hostname, 'host', 'testmsg']) + output = realm.run_as_client([gss_client, '-port', portstr] + options + + [hostname, 'host', 'testmsg']) if 'Signature verified.' not in output: fail('Expected message not seen in gss-client output') stop_daemon(server) + realm.klist(realm.user_princ, realm.host_princ) + +# Make up a filename to hold user's initial credentials. +def ccache_savefile(realm): + return os.path.join(realm.testdir, 'ccache.copy') + +# Move user's initial credentials into the save file. +def ccache_save(realm): + os.rename(realm.ccache, ccache_savefile(realm)) + +# Copy user's initial credentials from the save file into the ccache. +def ccache_restore(realm): + shutil.copyfile(ccache_savefile(realm), realm.ccache) + +# Perform a regular (TGS path) test of the server and client. +def tgs_test(realm, options): + ccache_restore(realm) + server_client_test(realm, options) + +# Perform a test of the server and client with initial credentials +# obtained through gss_acquire_cred_with_password(). +def as_test(realm, options): + os.remove(realm.ccache) + server_client_test(realm, options + ['-user', realm.user_princ, + '-pass', password('user')]) + +for realm in multipass_realms(): + ccache_save(realm) + + tgs_test(realm, ['-krb5']) + tgs_test(realm, ['-spnego']) + tgs_test(realm, ['-iakerb']) + + as_test(realm, ['-krb5']) + as_test(realm, ['-spnego']) + as_test(realm, ['-iakerb']) success('GSS sample application') |
