summaryrefslogtreecommitdiffstats
path: root/src/appl
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-04-30 21:22:48 +0000
committerGreg Hudson <ghudson@mit.edu>2010-04-30 21:22:48 +0000
commitbaea9a7a27d781581505f0bb6d0ac4e4f24053aa (patch)
treeaf04244ed8b910bed378296d0b263c5f2b3a3ffc /src/appl
parentd20d802b8e44178017fd1a1da55a72194f50da55 (diff)
downloadkrb5-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.c90
-rw-r--r--src/appl/gss-sample/gss-server.c13
-rw-r--r--src/appl/gss-sample/t_gss_sample.py46
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 ad314c2706..d922cc3bd5 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 8b59eb2769..0ddfaeee87 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 8a09b21239..09d0803ce1 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')