diff --git a/lib/gssapi/gss-token.1 b/lib/gssapi/gss-token.1 index 20c38f9b3..7bd50b0e8 100644 --- a/lib/gssapi/gss-token.1 +++ b/lib/gssapi/gss-token.1 @@ -17,6 +17,7 @@ .Op Fl C Ar ccache .Op Fl S Ar maxsize .Op Fl c count +.Op Fl m mech .Op Ar service@host .Sh DESCRIPTION .Nm @@ -66,6 +67,13 @@ This flag only changes the behaviour when operating in initiator mode. This is good for very basic benchmarking. .It Fl l loop indefinitely in acceptor mode. +.It Fl m Ar mech +specifies the GSS mechanism that will be used in initiator mode. +If a mechanism name of +.Do ? Dc +is specified, a list of supported mechanisms will be output and +.Nm +will exit. .It Fl n do not output the generated tokens. .It Fl r diff --git a/lib/gssapi/gss-token.c b/lib/gssapi/gss-token.c index cba795f7b..c59b29279 100644 --- a/lib/gssapi/gss-token.c +++ b/lib/gssapi/gss-token.c @@ -91,6 +91,7 @@ int Sflag = 0; int nflag = 0; +gss_OID global_mech = GSS_C_NO_OID; static char * gss_mk_err(OM_uint32 maj_stat, OM_uint32 min_stat, const char *preamble) @@ -339,7 +340,7 @@ initiate_one(gss_name_t service, int delegate, int negotiate) } maj = gss_init_sec_context(&min, GSS_C_NO_CREDENTIAL, &ctx, - service, GSS_C_NO_OID, flags, 0, + service, global_mech, flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &in, NULL, &out, NULL, NULL); @@ -548,6 +549,26 @@ bail: return svc; } +static void +print_all_mechs(void) +{ + OM_uint32 maj, min; + gss_OID_set mech_set; + size_t i; + int ret = 0; + + maj = gss_indicate_mechs(&min, &mech_set); + GBAIL("gss_indicate_mechs", maj, min); + + for (i=0; i < mech_set->count; i++) + printf("%s\n", gss_oid_to_name(&mech_set->elements[i])); + + maj = gss_release_oid_set(&min, &mech_set); + +bail: + exit(ret); +} + static void usage(int ecode) { @@ -574,6 +595,7 @@ main(int argc, char **argv) int ret = 0; int optidx = 0; char *ccname = NULL; + char *mech = NULL; struct getargs args[] = { { "help", 'h', arg_flag, &hflag, NULL, NULL }, { "version", 0, arg_flag, &version_flag, NULL, NULL }, @@ -584,6 +606,7 @@ main(int argc, char **argv) { NULL, 'S', arg_integer, &Sflag, NULL, NULL }, { NULL, 'c', arg_integer, &count, NULL, NULL }, { NULL, 'l', arg_flag, &lflag, NULL, NULL }, + { NULL, 'm', arg_string, &mech, NULL, NULL }, { NULL, 'n', arg_flag, &nflag, NULL, NULL }, { NULL, 'r', arg_flag, &rflag, NULL, NULL }, }; @@ -602,6 +625,18 @@ main(int argc, char **argv) argc -= optidx; argv += optidx; + if (mech) { + if (mech[0] == '?' && mech[1] == '\0') { + print_all_mechs(); + exit(0); + } + global_mech = gss_name_to_oid(mech); + if (!global_mech) { + fprintf(stderr, "Invalid mech \"%s\".\n", mech); + usage(1); + } + } + if (argc > 0) service = import_service(*argv);