#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <stdlib.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_ext.h>
#include "gssd.h"
#include <rpc/rpc.h>
#define _KERNEL
#include <gssapi/gssapi.h>
#undef _KERNEL
int gss_major_code;
int gss_minor_code;
int init_sec_context_phase = 0;
int accept_sec_context_phase = 0;
gss_ctx_id_t initiator_context_handle;
gss_ctx_id_t acceptor_context_handle;
gss_cred_id_t acceptor_credentials;
gss_buffer_desc init_token_buffer;
gss_buffer_desc accept_token_buffer;
gss_buffer_desc delete_token_buffer;
gss_buffer_desc message_buffer;
gss_buffer_desc msg_token;
#define LOOP_COUNTER 100
#define GSS_KRB5_MECH_OID "1.2.840.113554.1.2.2"
#define GSS_DUMMY_MECH_OID "1.3.6.1.4.1.42.2.26.1.2"
#ifdef _KERNEL
#define OCTAL_MACRO "%03o."
#define MALLOC(n) kmem_alloc((n), KM_SLEEP)
#define CALLOC(n, s) kmem_zalloc((n)*(s), KM_SLEEP)
#define FREE(x, n) kmem_free((x), (n))
#define memcpy(dst, src, n) bcopy((src), (dst), (n))
#define fprintf(s, m) printf(m)
#define isspace(s) ((s) == ' ' || (s) == '\t' || (s) == '\n' || \
(s) == '\r' || (s) == '\v' || (s) == '\f')
static char *strdup(const char *s)
{
int len = strlen(s);
char *new = MALLOC(len+1);
strcpy(new, s);
return (new);
}
#else
#define OCTAL_MACRO "%03.3o."
#define MALLOC(n) malloc(n)
#define CALLOC(n, s) calloc((n), (s))
#define FREE(x, n) free(x)
#endif
static gss_OID gss_str2oid(char *);
static char * gss_oid2str(gss_OID);
static void instructs();
static void usage();
static int parse_input_line(char *, int *, char ***);
extern uid_t getuid();
static void _gss_init_sec_context(int, char **);
static void _gss_acquire_cred(int, char **);
static void _gss_add_cred(int, char **);
static void _gss_sign(int, char **);
static void _gss_release_cred(int, char **);
static void _gss_accept_sec_context(int, char **);
static void _gss_process_context_token(int, char **);
static void _gss_delete_sec_context(int, char **);
static void _gss_context_time(int, char **);
static void _gss_verify(int, char **);
static void _gss_seal(int, char **);
static void _gss_unseal(int, char **);
static void _gss_display_status(int, char **);
static void _gss_indicate_mechs(int, char **);
static void _gss_inquire_cred(int, char **);
static void _gssd_expname_to_unix_cred(int, char **);
static void _gssd_name_to_unix_cred(int, char **);
static void _gssd_get_group_info(int, char **);
static int do_gssdtest(char *buf);
#ifndef _KERNEL
static int read_line(char *buf, int size)
{
int len;
printf(gettext("\n> "));
if (fgets(buf, size, stdin) == NULL)
return (0);
len = strlen(buf);
buf[--len] = '\0';
return (len);
}
int
main()
{
char buf[512];
int len, ret;
instructs();
usage();
do {
len = read_line(buf, 512);
if (len)
ret = do_gssdtest(buf);
} while (len && !ret);
return (0);
}
#endif
static int
do_gssdtest(char *buf)
{
int argc, seal_argc;
int i;
char **argv, **argv_array;
char *cmd;
char *seal_ini_array [] = { "initiator", " Hello"};
char *seal_acc_array [] = { "acceptor", " Hello"};
char *unseal_acc_array [] = {"acceptor"};
char *unseal_ini_array [] = {"initiator"};
char *delet_acc_array [] = {"acceptor"};
char *delet_ini_array [] = {"initiator"};
argv = 0;
if (parse_input_line(buf, &argc, &argv) == 0) {
printf(gettext("\n"));
return (1);
}
if (argc == 0) {
usage();
FREE(argv_array, (argc+1)*sizeof (char *));
return (0);
}
argv_array = argv;
cmd = argv[0];
argc--;
argv++;
if (strcmp(cmd, "gss_loop") == 0 ||
strcmp(cmd, "loop") == 0) {
if (argc < 1) {
usage();
FREE(argv_array, (argc+2) * sizeof (char *));
return (0);
}
for (i = 0; i < LOOP_COUNTER; i++) {
printf(gettext("Loop Count is %d \n"), i);
_gss_acquire_cred(argc, argv);
_gss_init_sec_context(argc, argv);
_gss_accept_sec_context(0, argv);
_gss_init_sec_context(argc, argv);
seal_argc = 2;
_gss_seal(seal_argc, seal_ini_array);
seal_argc = 1;
_gss_unseal(seal_argc, unseal_acc_array);
seal_argc = 2;
_gss_seal(seal_argc, seal_acc_array);
seal_argc = 1;
_gss_unseal(seal_argc, unseal_ini_array);
seal_argc = 2;
_gss_sign(seal_argc, seal_ini_array);
seal_argc = 1;
_gss_verify(seal_argc, unseal_acc_array);
seal_argc = 2;
_gss_sign(seal_argc, seal_acc_array);
seal_argc = 1;
_gss_verify(seal_argc, unseal_ini_array);
_gss_delete_sec_context(argc, delet_acc_array);
_gss_delete_sec_context(argc, delet_ini_array);
}
}
if (strcmp(cmd, "gss_all") == 0 ||
strcmp(cmd, "all") == 0) {
_gss_acquire_cred(argc, argv);
_gss_init_sec_context(argc, argv);
_gss_accept_sec_context(0, argv);
_gss_init_sec_context(argc, argv);
seal_argc = 2;
_gss_seal(seal_argc, seal_acc_array);
seal_argc = 1;
_gss_unseal(seal_argc, unseal_ini_array);
seal_argc = 2;
_gss_seal(seal_argc, seal_ini_array);
seal_argc = 1;
_gss_unseal(seal_argc, unseal_acc_array);
seal_argc = 2;
_gss_sign(seal_argc, seal_ini_array);
seal_argc = 1;
_gss_verify(seal_argc, unseal_acc_array);
seal_argc = 2;
_gss_sign(seal_argc, seal_acc_array);
seal_argc = 1;
_gss_verify(seal_argc, unseal_ini_array);
}
if (strcmp(cmd, "gss_acquire_cred") == 0 ||
strcmp(cmd, "acquire") == 0) {
_gss_acquire_cred(argc, argv);
if (argc == 1)
_gss_add_cred(argc, argv);
}
else if (strcmp(cmd, "gss_release_cred") == 0 ||
strcmp(cmd, "release") == 0)
_gss_release_cred(argc, argv);
else if (strcmp(cmd, "gss_init_sec_context") == 0 ||
strcmp(cmd, "init") == 0)
_gss_init_sec_context(argc, argv);
else if (strcmp(cmd, "gss_accept_sec_context") == 0 ||
strcmp(cmd, "accept") == 0)
_gss_accept_sec_context(argc, argv);
else if (strcmp(cmd, "gss_process_context_token") == 0 ||
strcmp(cmd, "process") == 0)
_gss_process_context_token(argc, argv);
else if (strcmp(cmd, "gss_delete_sec_context") == 0 ||
strcmp(cmd, "delete") == 0)
_gss_delete_sec_context(argc, argv);
else if (strcmp(cmd, "gss_context_time") == 0 ||
strcmp(cmd, "time") == 0)
_gss_context_time(argc, argv);
else if (strcmp(cmd, "gss_sign") == 0 ||
strcmp(cmd, "sign") == 0)
_gss_sign(argc, argv);
else if (strcmp(cmd, "gss_verify") == 0 ||
strcmp(cmd, "verify") == 0)
_gss_verify(argc, argv);
else if (strcmp(cmd, "gss_seal") == 0 ||
strcmp(cmd, "seal") == 0)
_gss_seal(argc, argv);
else if (strcmp(cmd, "gss_unseal") == 0 ||
strcmp(cmd, "unseal") == 0)
_gss_unseal(argc, argv);
else if (strcmp(cmd, "gss_display_status") == 0||
strcmp(cmd, "status") == 0)
_gss_display_status(argc, argv);
else if (strcmp(cmd, "gss_indicate_mechs") == 0 ||
strcmp(cmd, "indicate") == 0)
_gss_indicate_mechs(argc, argv);
else if (strcmp(cmd, "gss_inquire_cred") == 0 ||
strcmp(cmd, "inquire") == 0)
_gss_inquire_cred(argc, argv);
else if (strcmp(cmd, "expname2unixcred") == 0 ||
strcmp(cmd, "gsscred_expname_to_unix_cred") == 0)
_gssd_expname_to_unix_cred(argc, argv);
else if (strcmp(cmd, "name2unixcred") == 0 ||
strcmp(cmd, "gsscred_name_to_unix_cred") == 0)
_gssd_name_to_unix_cred(argc, argv);
else if (strcmp(cmd, "grpinfo") == 0 ||
strcmp(cmd, "gss_get_group_info") == 0)
_gssd_get_group_info(argc, argv);
else if (strcmp(cmd, "exit") == 0) {
printf(gettext("\n"));
FREE(argv_array, (argc+2) * sizeof (char *));
return (1);
} else
usage();
FREE(argv_array, (argc+2) * sizeof (char *));
return (0);
}
static void
_gss_acquire_cred(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status, minor_status;
gss_buffer_desc name;
gss_name_t desired_name = (gss_name_t) 0;
OM_uint32 time_req;
gss_OID_set_desc desired_mechs_desc;
gss_OID_set desired_mechs = &desired_mechs_desc;
int cred_usage;
gss_OID_set actual_mechs = GSS_C_NULL_OID_SET;
gss_OID_set inquire_mechs = GSS_C_NULL_OID_SET;
OM_UINT32 time_rec;
char * string;
char * inq_string;
uid_t uid;
gss_OID mech_type;
time_req = (OM_uint32) 0;
cred_usage = GSS_C_ACCEPT;
uid = getuid();
if (argc == 0) {
usage();
return;
}
name.length = strlen(argv[0])+1;
name.value = argv[0];
if ((status = gss_import_name(&minor_status, &name,
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE, &desired_name))
!= GSS_S_COMPLETE) {
printf(gettext(
"could not parse desired name: err (octal) %o (%s)\n"),
status, gettext("gss_acquire_cred error"));
return;
}
argc--;
argv++;
if (argc == 0) {
printf(gettext("Assuming Kerberos V5 as the mechanism\n"));
printf(gettext(
"The mech OID 1.2.840.113554.1.2.2 will be used\n"));
mech_type = gss_str2oid((char *)GSS_KRB5_MECH_OID);
} else
mech_type = gss_str2oid(argv[0]);
if (mech_type == 0 || mech_type->length == 0) {
printf(gettext("improperly formated mechanism OID\n"));
return;
}
desired_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_desc));
desired_mechs->count = 1;
desired_mechs->elements = mech_type;
status = kgss_acquire_cred(
&minor_status,
desired_name,
time_req,
desired_mechs,
cred_usage,
&acceptor_credentials,
&actual_mechs,
&time_rec,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status == GSS_S_COMPLETE) {
printf(gettext("\nacquire succeeded\n\n"));
if ((string = gss_oid2str(actual_mechs->elements)) == 0) {
printf(gettext("actual mechs == NULL\n\n"));
} else {
printf(gettext("actual mechs = %s\n\n"), string);
FREE(string, (actual_mechs->elements->length+1)*4+1);
}
if (cred_usage == GSS_C_BOTH)
printf(gettext("GSS_C_BOTH\n\n"));
if (cred_usage == GSS_C_INITIATE)
printf(gettext("GSS_C_INITIATE\n\n"));
if (cred_usage == GSS_C_ACCEPT)
printf(gettext("GSS_C_ACCEPT\n\n"));
status = kgss_inquire_cred(
&minor_status,
acceptor_credentials,
NULL,
&time_req,
&cred_usage,
&inquire_mechs,
uid);
if (status != GSS_S_COMPLETE)
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_inquire_cred error"));
else {
if ((inq_string =
gss_oid2str(inquire_mechs->elements)) == 0) {
printf(gettext
("mechs from inquire == NULL\n\n"));
} else {
printf(gettext
("mechs from inquiry = %s\n\n"),
inq_string);
FREE(inq_string,
(inquire_mechs->elements->length+1)*4+1);
}
printf(gettext("inquire_cred successful \n\n"));
}
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_acquire_cred error"));
}
if (actual_mechs != GSS_C_NULL_OID_SET)
gss_release_oid_set_and_oids(&minor_status, &actual_mechs);
if (inquire_mechs != GSS_C_NULL_OID_SET)
gss_release_oid_set_and_oids(&minor_status, &inquire_mechs);
gss_release_name(&minor_status, &desired_name);
FREE(mech_type->elements, mech_type->length);
FREE(mech_type, sizeof (gss_OID_desc));
FREE(desired_mechs, sizeof (gss_OID_desc));
}
static void
_gss_add_cred(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status, minor_status;
gss_buffer_desc name;
gss_name_t desired_name = (gss_name_t) 0;
OM_uint32 time_req;
OM_uint32 initiator_time_req;
OM_uint32 acceptor_time_req;
int cred_usage;
gss_OID_set actual_mechs = GSS_C_NULL_OID_SET;
gss_OID_set inquire_mechs = GSS_C_NULL_OID_SET;
char * string;
uid_t uid;
gss_OID mech_type;
int i;
initiator_time_req = (OM_uint32) 0;
acceptor_time_req = (OM_uint32) 0;
cred_usage = GSS_C_ACCEPT;
uid = getuid();
if (argc == 0) {
usage();
return;
}
name.length = strlen(argv[0])+1;
name.value = argv[0];
if ((status = gss_import_name(&minor_status, &name,
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE, &desired_name))
!= GSS_S_COMPLETE) {
printf(gettext(
"could not parse desired name: err (octal) %o (%s)\n"),
status, gettext("gss_acquire_cred error"));
return;
}
argc--;
argv++;
if (argc == 0) {
printf(gettext("Assuming dummy as the mechanism\n"));
printf(gettext(
"The mech OID 1.3.6.1.4.1.42.2.26.1.2 will be used\n"));
mech_type = gss_str2oid((char *)GSS_DUMMY_MECH_OID);
} else
mech_type = gss_str2oid(argv[0]);
if (mech_type == 0 || mech_type->length == 0) {
printf(gettext("improperly formated mechanism OID\n"));
return;
}
status = kgss_add_cred(
&minor_status,
acceptor_credentials,
desired_name,
mech_type,
cred_usage,
initiator_time_req,
acceptor_time_req,
&actual_mechs,
NULL,
NULL,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status == GSS_S_COMPLETE) {
printf(gettext("\nadd succeeded\n\n"));
if (actual_mechs) {
for (i = 0; i < actual_mechs->count; i++) {
if ((string =
gss_oid2str
(&actual_mechs->elements[i])) == 0) {
printf(gettext
("actual mechs == NULL\n\n"));
} else {
printf(gettext
("actual mechs = %s\n\n"), string);
FREE(string,
(actual_mechs->elements->length+1)*4+1);
}
}
}
status = kgss_add_cred(
&minor_status,
acceptor_credentials,
desired_name,
mech_type,
cred_usage,
initiator_time_req,
acceptor_time_req,
NULL,
NULL,
NULL,
uid);
if (status != GSS_S_DUPLICATE_ELEMENT) {
printf(gettext("Expected duplicate element, Got "
" (octal) %o (%s)\n"),
status, gettext("gss_add_cred error"));
}
status = kgss_inquire_cred(
&minor_status,
acceptor_credentials,
NULL,
&time_req,
&cred_usage,
&inquire_mechs,
uid);
if (status != GSS_S_COMPLETE)
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_inquire_cred error"));
else {
for (i = 0; i < inquire_mechs->count; i++) {
if ((string =
gss_oid2str
(&inquire_mechs->elements[i])) == 0) {
printf(gettext
("inquire_mechs mechs == NULL\n\n"));
} else {
printf(gettext
("inquire_cred mechs = %s\n\n"),
string);
FREE(string,
(inquire_mechs->elements->length+1)*4
+1);
}
}
printf(gettext("inquire_cred successful \n\n"));
}
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_acquire_cred error"));
}
status = kgss_inquire_cred_by_mech(
&minor_status,
acceptor_credentials,
mech_type,
uid);
if (status != GSS_S_COMPLETE)
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_inquire_cred_by_mech"));
else
printf(gettext("gss_inquire_cred_by_mech successful"));
FREE(mech_type->elements, mech_type->length);
FREE(mech_type, sizeof (gss_OID_desc));
mech_type = gss_str2oid((char *)GSS_KRB5_MECH_OID);
status = kgss_inquire_cred_by_mech(
&minor_status,
acceptor_credentials,
mech_type,
uid);
if (status != GSS_S_COMPLETE)
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext
("gss_inquire_cred_by_mech for dummy mech error"));
if (actual_mechs != GSS_C_NULL_OID_SET)
gss_release_oid_set_and_oids(&minor_status, &actual_mechs);
if (inquire_mechs != GSS_C_NULL_OID_SET)
gss_release_oid_set_and_oids(&minor_status, &inquire_mechs);
gss_release_name(&minor_status, &desired_name);
FREE(mech_type->elements, mech_type->length);
FREE(mech_type, sizeof (gss_OID_desc));
}
static void
_gss_release_cred(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_UINT32 minor_status;
uid_t uid;
if (argc != 0) {
usage();
return;
}
uid = getuid();
status = kgss_release_cred(
&minor_status,
&acceptor_credentials,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status == GSS_S_COMPLETE) {
printf(gettext("\nrelease succeeded\n\n"));
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_release_cred error"));
}
}
static void
_gss_init_sec_context(argc, argv)
int argc;
char **argv;
{
OM_uint32 status;
OM_uint32 minor_status;
gss_cred_id_t claimant_cred_handle;
gss_name_t target_name = (gss_name_t) 0;
gss_OID mech_type = (gss_OID) 0;
int req_flags;
OM_uint32 time_req;
gss_channel_bindings_t input_chan_bindings;
gss_buffer_t input_token;
gss_buffer_desc context_token;
gss_OID actual_mech_type;
int ret_flags;
OM_uint32 time_rec;
uid_t uid;
char * string;
gss_buffer_desc name;
if (init_sec_context_phase == 0) {
initiator_context_handle = GSS_C_NO_CONTEXT;
input_token = GSS_C_NO_BUFFER;
init_sec_context_phase = 1;
} else
input_token = &init_token_buffer;
claimant_cred_handle = GSS_C_NO_CREDENTIAL;
req_flags = GSS_C_MUTUAL_FLAG;
time_req = (OM_uint32) 0;
input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
uid = getuid();
if (argc == 0) {
usage();
return;
}
name.length = strlen(argv[0])+1;
name.value = argv[0];
if ((status = gss_import_name(&minor_status, &name,
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE, &target_name))
!= GSS_S_COMPLETE) {
printf(gettext(
"could not parse target name: err (octal) %o (%s)\n"),
status,
gettext("gss_init_sec_context error"));
if (input_token != GSS_C_NO_BUFFER)
gss_release_buffer(&minor_status, &init_token_buffer);
init_sec_context_phase = 0;
return;
}
argc--;
argv++;
if (argc == 0) {
printf(gettext("Assuming Kerberos V5 as the mechanism\n"));
printf(gettext(
"The mech OID 1.2.840.113554.1.2.2 will be used\n"));
mech_type = gss_str2oid((char *)GSS_KRB5_MECH_OID);
} else {
mech_type = gss_str2oid(argv[0]);
}
if (mech_type == 0 || mech_type->length == 0) {
printf(gettext("improperly formated mechanism OID\n"));
if (input_token != GSS_C_NO_BUFFER)
gss_release_buffer(&minor_status, &init_token_buffer);
init_sec_context_phase = 0;
return;
}
status = kgss_init_sec_context(&minor_status,
claimant_cred_handle,
&initiator_context_handle,
target_name,
mech_type,
req_flags,
time_req,
input_chan_bindings,
input_token,
&actual_mech_type,
&accept_token_buffer,
&ret_flags,
&time_rec,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE &&
status != GSS_S_CONTINUE_NEEDED) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, "gss_init_sec_context error");
init_sec_context_phase = 0;
if (status == GSS_S_NO_CRED)
printf(gettext(" : no credentials"));
if (input_token != GSS_C_NO_BUFFER)
gss_release_buffer(&minor_status, &init_token_buffer);
if (status != GSS_S_FAILURE && minor_status != 0xffffffff)
status = kgss_delete_sec_context(&minor_status,
&initiator_context_handle,
&msg_token);
return;
} else if (status == GSS_S_COMPLETE) {
printf(gettext("\ninit succeeded\n\n"));
if ((string = gss_oid2str(actual_mech_type)) == 0) {
printf(gettext(
"gssapi internal err : actual "
"mech type null\n"));
init_sec_context_phase = 0;
if (input_token != GSS_C_NO_BUFFER)
gss_release_buffer(&minor_status,
&init_token_buffer);
gss_release_buffer(&minor_status, &accept_token_buffer);
status = kgss_delete_sec_context(&minor_status,
&initiator_context_handle,
&msg_token);
return;
} else {
printf(gettext("actual mech type = %s\n\n"), string);
FREE(string, (actual_mech_type->length+1)*4+1);
}
if (ret_flags & GSS_C_DELEG_FLAG)
printf(gettext("GSS_C_DELEG_FLAG = True\n"));
else
printf(gettext("GSS_C_DELEG_FLAG = False\n"));
if (ret_flags & GSS_C_MUTUAL_FLAG)
printf(gettext("GSS_C_MUTUAL_FLAG = True\n"));
else
printf(gettext("GSS_C_MUTUAL_FLAG = False\n"));
if (ret_flags & GSS_C_REPLAY_FLAG)
printf(gettext("GSS_C_REPLAY_FLAG = True\n"));
else
printf(gettext("GSS_C_REPLAY_FLAG = False\n"));
if (ret_flags & GSS_C_SEQUENCE_FLAG)
printf(gettext("GSS_C_SEQUENCE_FLAG = True\n"));
else
printf(gettext("GSS_C_SEQUENCE_FLAG = False\n"));
if (ret_flags & GSS_C_CONF_FLAG)
printf(gettext("GSS_C_CONF_FLAG = True\n"));
else
printf(gettext("GSS_C_CONF_FLAG = False\n"));
if (ret_flags & GSS_C_INTEG_FLAG)
printf(gettext("GSS_C_INTEG_FLAG = True\n\n"));
else
printf(gettext("GSS_C_INTEG_FLAG = False\n\n"));
printf(gettext("time_req = %u seconds\n\n"), time_rec);
FREE(mech_type->elements, mech_type->length);
FREE(mech_type, sizeof (gss_OID_desc));
FREE(actual_mech_type->elements, actual_mech_type->length);
FREE(actual_mech_type, sizeof (gss_OID_desc));
gss_release_name(&minor_status, &target_name);
if (input_token != GSS_C_NO_BUFFER)
gss_release_buffer(&minor_status, &init_token_buffer);
init_sec_context_phase = 0;
status = kgss_export_sec_context(&minor_status,
&initiator_context_handle,
&context_token);
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_export_sec_context_error"));
return;
}
status = kgss_import_sec_context(&minor_status,
&context_token,
&initiator_context_handle);
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_import_sec_context_error"));
return;
}
(void) gss_release_buffer(&minor_status, &context_token);
printf(gettext("\nexport and import of contexts succeeded\n"));
printf(gettext("\ninit completed"));
} else {
printf(gettext("\nfirst phase of init succeeded"));
printf(gettext("\ninit must be called again\n\n"));
}
}
static void
_gss_accept_sec_context(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_uint32 minor_status;
gss_channel_bindings_t input_chan_bindings;
gss_OID mech_type;
int ret_flags;
OM_uint32 time_rec;
gss_cred_id_t delegated_cred_handle;
uid_t uid;
char *string;
gss_buffer_desc src_name, src_name_string;
gss_buffer_desc output_token;
gss_name_t gss_name;
gss_buffer_desc context_token;
if (accept_sec_context_phase == 0) {
acceptor_context_handle = GSS_C_NO_CONTEXT;
accept_sec_context_phase = 1;
}
input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
uid = (uid_t) getuid();
if (argc != 0) {
usage();
return;
}
status = kgss_accept_sec_context(&minor_status,
&acceptor_context_handle,
acceptor_credentials,
&accept_token_buffer,
input_chan_bindings,
&src_name,
&mech_type,
&init_token_buffer,
&ret_flags,
&time_rec,
&delegated_cred_handle,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_accept_sec_context error"));
gss_release_buffer(&minor_status, &accept_token_buffer);
return;
} else if (status == GSS_S_COMPLETE) {
printf(gettext("\naccept succeeded\n\n"));
if ((status = gss_import_name(&minor_status, &src_name,
(gss_OID) GSS_C_NT_EXPORT_NAME, &gss_name))
!= GSS_S_COMPLETE) {
printf(gettext(
"could not import src name 0x%x\n"), status);
accept_sec_context_phase = 0;
status = kgss_delete_sec_context(&minor_status,
&acceptor_context_handle,
&output_token);
gss_release_buffer(&minor_status, &accept_token_buffer);
if (status == GSS_S_CONTINUE_NEEDED)
gss_release_buffer(&minor_status,
&init_token_buffer);
gss_release_buffer(&minor_status, &src_name);
return;
}
memset(&src_name_string, 0, sizeof (src_name_string));
if ((status = gss_display_name(&minor_status, gss_name,
&src_name_string, NULL)) != GSS_S_COMPLETE) {
printf(gettext("could not display src name: "
"err (octal) %o (%s)\n"), status,
"gss_init_sec_context error");
accept_sec_context_phase = 0;
status = kgss_delete_sec_context(&minor_status,
&acceptor_context_handle,
&output_token);
gss_release_buffer(&minor_status, &accept_token_buffer);
if (status == GSS_S_CONTINUE_NEEDED)
gss_release_buffer(&minor_status,
&init_token_buffer);
gss_release_buffer(&minor_status, &src_name);
return;
}
printf(gettext("src name = %s\n"), src_name_string.value);
gss_release_name(&minor_status, &gss_name);
gss_release_buffer(&minor_status, &src_name_string);
gss_release_buffer(&minor_status, &src_name);
if ((string = gss_oid2str(mech_type)) == 0) {
printf(gettext(
"gssapi internal err :"
" actual mech type null\n"));
accept_sec_context_phase = 0;
status = kgss_delete_sec_context(&minor_status,
&acceptor_context_handle,
&output_token);
gss_release_buffer(&minor_status, &accept_token_buffer);
if (status == GSS_S_CONTINUE_NEEDED)
gss_release_buffer(&minor_status,
&init_token_buffer);
return;
} else {
printf(gettext("actual mech type = %s\n\n"), string);
FREE(string, (mech_type->length+1)*4+1);
}
status = kgss_export_sec_context(&minor_status,
&initiator_context_handle,
&context_token);
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_export_sec_context_error"));
return;
}
status = kgss_import_sec_context(&minor_status,
&context_token,
&initiator_context_handle);
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_import_sec_context_error"));
return;
}
(void) gss_release_buffer(&minor_status, &context_token);
if (ret_flags & GSS_C_DELEG_FLAG)
printf(gettext("GSS_C_DELEG_FLAG = True\n"));
else
printf(gettext("GSS_C_DELEG_FLAG = False\n"));
if (ret_flags & GSS_C_MUTUAL_FLAG)
printf(gettext("GSS_C_MUTUAL_FLAG = True\n"));
else
printf(gettext("GSS_C_MUTUAL_FLAG = False\n"));
if (ret_flags & GSS_C_REPLAY_FLAG)
printf(gettext("GSS_C_REPLAY_FLAG = True\n"));
else
printf(gettext("GSS_C_REPLAY_FLAG = False\n"));
if (ret_flags & GSS_C_SEQUENCE_FLAG)
printf(gettext("GSS_C_SEQUENCE_FLAG = True\n"));
else
printf(gettext("GSS_C_SEQUENCE_FLAG = False\n"));
if (ret_flags & GSS_C_CONF_FLAG)
printf(gettext("GSS_C_CONF_FLAG = True\n"));
else
printf(gettext("GSS_C_CONF_FLAG = False\n"));
if (ret_flags & GSS_C_INTEG_FLAG)
printf(gettext("GSS_C_INTEG_FLAG = True\n\n"));
else
printf(gettext("GSS_C_INTEG_FLAG = False\n\n"));
printf(gettext("time_rec = %d seconds\n\n"), time_rec);
printf(gettext("\nexport and import of contexts succeeded\n"));
FREE(mech_type->elements, mech_type->length);
FREE(mech_type, sizeof (gss_OID_desc));
} else {
printf(gettext("\nfirst phase of accept succeeded"));
printf(gettext("\naccept must be called again\n\n"));
}
gss_release_buffer(&minor_status, &accept_token_buffer);
if (status == GSS_S_COMPLETE)
accept_sec_context_phase = 0;
}
void
_gss_process_context_token(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
gss_ctx_id_t context_handle;
OM_uint32 minor_status;
uid_t uid;
uid = (uid_t) getuid();
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0)
context_handle = initiator_context_handle;
else if (strcmp(argv[0], "acceptor") == 0)
context_handle = acceptor_context_handle;
else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_process_context_token(&minor_status,
context_handle,
delete_token_buffer,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_process_context_token error"));
return;
} else {
printf(gettext("\nprocess succeeded\n\n"));
return;
}
}
static void
_gss_delete_sec_context(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
gss_ctx_id_t *context_handle;
OM_uint32 minor_status;
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0) {
context_handle = &initiator_context_handle;
} else if (strcmp(argv[0], "acceptor") == 0) {
context_handle = &acceptor_context_handle;
} else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_delete_sec_context(&minor_status,
context_handle,
&delete_token_buffer);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_delete_sec_context error"));
return;
} else {
printf(gettext("\ndelete succeeded\n\n"));
return;
}
}
static void
_gss_context_time(argc, argv)
int argc;
char **argv;
{
printf(gettext("\nunimplemented function"));
}
static void
_gss_sign(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_uint32 minor_status;
gss_ctx_id_t context_handle;
int qop_req;
uid_t uid;
uid = (uid_t) getuid();
qop_req = GSS_C_QOP_DEFAULT;
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0)
context_handle = initiator_context_handle;
else if (strcmp(argv[0], "acceptor") == 0)
context_handle = acceptor_context_handle;
else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc == 0) {
usage();
return;
}
message_buffer.length = strlen(argv[0])+1;
message_buffer.value = (void *) MALLOC(message_buffer.length);
strcpy(message_buffer.value, argv[0]);
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_sign(&minor_status,
context_handle,
qop_req,
&message_buffer,
&msg_token,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_sign error"));
return;
} else {
printf(gettext("\nsign succeeded\n\n"));
return;
}
}
static void
_gss_verify(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status, minor_status;
gss_ctx_id_t context_handle;
int qop_state;
uid_t uid;
uid = (uid_t) getuid();
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0)
context_handle = initiator_context_handle;
else if (strcmp(argv[0], "acceptor") == 0)
context_handle = acceptor_context_handle;
else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_verify(&minor_status,
context_handle,
&message_buffer,
&msg_token,
&qop_state,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_verify error"));
return;
} else {
printf(gettext(
"verified message = \"%s\"\n\n"), message_buffer.value);
printf(gettext("quality of protection = %d \n\n"), qop_state);
gss_release_buffer(&minor_status, &message_buffer);
gss_release_buffer(&minor_status, &msg_token);
return;
}
}
static void
_gss_seal(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_uint32 minor_status;
gss_ctx_id_t context_handle;
int conf_req_flag;
int qop_req;
gss_buffer_desc input_message_buffer;
int conf_state;
uid_t uid;
uid = (uid_t) getuid();
conf_req_flag = 1;
qop_req = GSS_C_QOP_DEFAULT;
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0)
context_handle = initiator_context_handle;
else if (strcmp(argv[0], "acceptor") == 0)
context_handle = acceptor_context_handle;
else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc == 0) {
usage();
return;
}
input_message_buffer.length = strlen(argv[0])+1;
input_message_buffer.value =
(void *) MALLOC(input_message_buffer.length);
strcpy(input_message_buffer.value, argv[0]);
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_seal(&minor_status,
context_handle,
conf_req_flag,
qop_req,
&input_message_buffer,
&conf_state,
&message_buffer,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
gss_release_buffer(&minor_status, &input_message_buffer);
if (status != GSS_S_COMPLETE) {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_seal error"));
return;
} else {
printf(gettext("\nseal succeeded\n\n"));
return;
}
}
static void
_gss_unseal(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_uint32 minor_status;
gss_ctx_id_t context_handle;
gss_buffer_desc output_message_buffer;
int conf_state;
int qop_state;
uid_t uid;
uid = (uid_t) getuid();
if (argc == 0) {
usage();
return;
}
if (strcmp(argv[0], "initiator") == 0)
context_handle = initiator_context_handle;
else if (strcmp(argv[0], "acceptor") == 0)
context_handle = acceptor_context_handle;
else {
printf(gettext(
"must specify either \"initiator\" or \"acceptor\"\n"));
return;
}
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_unseal(&minor_status,
context_handle,
&message_buffer,
&output_message_buffer,
&conf_state,
&qop_state,
uid);
gss_major_code = status;
gss_minor_code = minor_status;
if (status == GSS_S_COMPLETE) {
printf(gettext("\nunseal succeeded\n\n"));
printf(gettext("unsealed message = \"%s\"\n\n"),
output_message_buffer.value);
if (conf_state)
printf(gettext("confidentiality and integrity used\n"));
else
printf(gettext("only integrity used\n"));
printf(gettext("quality of protection = %d\n\n"), qop_state);
gss_release_buffer(&minor_status, &output_message_buffer);
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_unseal error"));
}
gss_release_buffer(&minor_status, &message_buffer);
}
static void
_gss_display_status(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_uint32 minor_status;
int status_type;
int status_value;
gss_OID mech_type = (gss_OID) 0;
int message_context;
gss_buffer_desc status_string;
uid_t uid;
uid = (uid_t) getuid();
message_context = 0;
if (argc == 0) {
printf(gettext("Assuming Kerberos V5 as the mechanism\n"));
printf(gettext(
"The mech OID 1.2.840.113554.1.2.2 will be used\n"));
mech_type = gss_str2oid((char *)GSS_KRB5_MECH_OID);
} else
mech_type = gss_str2oid(argv[0]);
if (mech_type == 0 || mech_type->length == 0) {
printf(gettext("improperly formated mechanism OID\n"));
return;
}
if (strcmp(argv[0], "major") == 0) {
status_type = GSS_C_GSS_CODE;
status_value = gss_major_code;
} else if (strcmp(argv[0], "minor") == 0) {
status_type = GSS_C_MECH_CODE;
status_value = gss_minor_code;
} else {
printf(gettext("must specify either \"major\" or \"minor\"\n"));
return;
}
argc--;
argv++;
if (argc != 0) {
usage();
return;
}
status = kgss_display_status(&minor_status,
status_value,
status_type,
mech_type,
&message_context,
&status_string,
uid);
if (status == GSS_S_COMPLETE) {
printf(gettext("status =\n %s\n\n"), status_string.value);
} else if (status == GSS_S_BAD_MECH) {
printf(gettext("invalide mechanism OID\n\n"));
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_display_status error"));
}
}
static void
_gss_indicate_mechs(argc, argv)
int argc;
char **argv;
{
OM_UINT32 status;
OM_UINT32 minor_status;
gss_OID_set oid_set = GSS_C_NULL_OID_SET;
uid_t uid;
uid = (uid_t) getuid();
if (argc != 0) {
usage();
return;
}
status = kgss_indicate_mechs(&minor_status, &oid_set, uid);
if (status == GSS_S_COMPLETE) {
int i;
char *string;
printf(gettext("%d supported mechanism%s%s\n"), oid_set->count,
(oid_set->count == 1) ? "" : "s",
(oid_set->count > 0) ? ":" : "");
for (i = 0; i < oid_set->count; i++) {
string = gss_oid2str(&oid_set->elements[i]);
printf(gettext("\t%s\n"), string);
FREE(string, ((oid_set->elements[i].length+1)*4)+1);
}
printf("\n");
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
status, gettext("gss_indicate_mechs error"));
}
if (oid_set)
gss_release_oid_set_and_oids(&minor_status, &oid_set);
}
static void
_gss_inquire_cred(argc, argv)
int argc;
char **argv;
{
if (argc != 0) {
usage();
return;
}
printf(gettext("\nUnsupported function"));
}
static char hexChars[] = "0123456789ABCDEF";
static void
_gssd_expname_to_unix_cred(argc, argv)
int argc;
char **argv;
{
OM_uint32 major;
gss_buffer_desc expName;
char krb5_root_name[] = "040100092A864886F712010202000000"
"25000A2A864886F71201020101726F6F744053554E534F46"
"542E454E472E53554E2E434F4D00";
unsigned char *byteStr, *hexStr;
uid_t uidOut, uidIn;
gid_t *gids, gidOut;
int gidsLen, i, newLen;
uidIn = (uid_t) getuid();
if (argc < 1) {
printf(gettext(
"Using principal name of root for krberos_v5\n"));
expName.value = (void*)krb5_root_name;
expName.length = strlen(krb5_root_name);
} else {
expName.value = (void*)argv[0];
expName.length = strlen(argv[0]);
}
hexStr = (unsigned char *)expName.value;
newLen = expName.length/2;
byteStr = (unsigned char *)MALLOC(newLen+1);
expName.value = (char *)byteStr;
for (i = 0; i < expName.length; i += 2) {
*byteStr = (strchr(hexChars, *hexStr++) - hexChars) << 4;
*byteStr += (strchr(hexChars, *hexStr++) - hexChars);
byteStr++;
}
expName.length = newLen;
major = kgsscred_expname_to_unix_cred(&expName, &uidOut, &gidOut,
&gids, &gidsLen, uidIn);
FREE(expName.value, newLen);
if (major == GSS_S_COMPLETE) {
printf(gettext("uid = <%d>\tgid = <%d>\t"), uidOut, gidOut);
if (gidsLen > 0)
printf(gettext(" %d gids <"), gidsLen);
else
printf(gettext(
" no supplementary group information\n"));
for (i = 0; i < gidsLen; i++)
printf(" %d ", gids[i]);
if (gidsLen > 0) {
printf(">\n");
FREE(gids, gidsLen * sizeof (gid_t));
}
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
major, gettext("gsscred_expname_to_unix_cred"));
}
}
static void
_gssd_name_to_unix_cred(argc, argv)
int argc;
char **argv;
{
OM_uint32 major, minor;
gss_name_t gssName;
gss_buffer_desc gssBuf = GSS_C_EMPTY_BUFFER;
int gidsLen, i;
gid_t *gids, gidOut;
uid_t uidOut, uid;
char defaultPrincipal[] = "root";
gss_OID mechType, nameType;
uid = getuid();
if (argc > 0) {
gssBuf.value = (void *)argv[0];
gssBuf.length = strlen((char *)argv[0]);
} else {
gssBuf.value = (void *)defaultPrincipal;
gssBuf.length = strlen(defaultPrincipal);
}
printf(gettext(
"Using <%s> as the principal name.\n"), (char *)gssBuf.value);
if (argc > 1)
nameType = gss_str2oid((char *) argv[1]);
else
nameType = (gss_OID)GSS_C_NT_USER_NAME;
if (nameType == NULL || nameType->length == 0) {
printf(gettext("improperly formated name OID\n"));
return;
}
printf(gettext("Principal name of type: <%s>.\n"),
(argc > 1) ? argv[1] : "GSS_C_NT_USER_NAME");
if (argc > 2)
mechType = gss_str2oid(argv[2]);
else
mechType = gss_str2oid((char *)GSS_KRB5_MECH_OID);
if (mechType == NULL || mechType->length == 0) {
FREE(nameType->elements, nameType->length);
FREE(nameType, sizeof (gss_OID_desc));
printf(gettext("improperly formated mech OID\n"));
return;
}
printf(gettext("Mechanism oid: <%s>.\n"),
(argc > 2) ? argv[2] :
(char *)GSS_KRB5_MECH_OID "(Kerberos v5)");
if ((major = gss_import_name(&minor, &gssBuf,
nameType, &gssName)) != GSS_S_COMPLETE) {
printf(gettext("could not parse name: err (octal) %o (%s)\n"),
major, "gss_import_name");
FREE(nameType->elements, nameType->length);
FREE(nameType, sizeof (gss_OID_desc));
return;
}
major = kgsscred_name_to_unix_cred(gssName, mechType, &uidOut,
&gidOut, &gids, &gidsLen, uid);
gss_release_name(&minor, &gssName);
FREE(mechType->elements, mechType->length);
FREE(mechType, sizeof (gss_OID_desc));
if (argc > 1) {
FREE(nameType->elements, nameType->length);
FREE(nameType, sizeof (gss_OID_desc));
}
if (major == GSS_S_COMPLETE) {
printf("uid = <%d>\tgid = <%d>\t", uidOut, gidOut);
if (gidsLen > 0)
printf(gettext(" %d gids <"), gidsLen);
else
printf(gettext(
" no supplementary group information\n"));
for (i = 0; i < gidsLen; i++)
printf(" %d ", gids[i]);
if (gidsLen > 0) {
printf(">\n");
FREE(gids, gidsLen * sizeof (gid_t));
}
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
major, gettext("gsscred_name_to_unix_cred"));
}
}
static void
_gssd_get_group_info(argc, argv)
int argc;
char **argv;
{
OM_uint32 major;
uid_t puid, uidIn;
gid_t *gids, gidOut;
int gidsLen, i;
uidIn = (uid_t) getuid();
if (argc < 1)
puid = 0;
else
puid = atol(argv[0]);
printf(gettext("Retrieving group info for uid of <%d>\n"), puid);
major = kgss_get_group_info(puid, &gidOut, &gids, &gidsLen, uidIn);
if (major == GSS_S_COMPLETE) {
printf(gettext("group id = <%d>\t"), gidOut);
if (gidsLen > 0)
printf(gettext(" %d gids <"), gidsLen);
else
printf(gettext(
" no supplementary group information\n"));
for (i = 0; i < gidsLen; i++)
printf(" %d ", gids[i]);
if (gidsLen > 0) {
printf(">\n");
FREE(gids, gidsLen * sizeof (gid_t));
}
} else {
printf(gettext("server ret err (octal) %o (%s)\n"),
major, "gss_get_group_info");
}
}
static gss_OID
gss_str2oid(string)
char * string;
{
OM_uint32 minor;
gss_buffer_desc abuf;
gss_OID oidOut;
abuf.value = (void*)string;
abuf.length = strlen(string);
if (gss_str_to_oid(&minor, &abuf, &oidOut) != GSS_S_COMPLETE)
return (NULL);
return (oidOut);
}
static char *
gss_oid2str(oid)
gss_OID oid;
{
OM_uint32 minor;
gss_buffer_desc oidStr;
if (gss_oid_to_str(&minor, oid, &oidStr) != GSS_S_COMPLETE)
return (NULL);
return ((char *)oidStr.value);
}
static void
instructs()
{
fprintf(stderr,
gettext(
"\nThis program must be run as root. Root must be installed on the KDC\n"
"and exist in srvtab as root/<hostname>, where <hostname> is the machine on\n"
"which the test runs. Before running gssdtest for Kerberos mechanism, the\n"
"operator running as root must kinit as some other principal, e.g., test.\n"
"There are two mechanisms avaialble: dummy and Kerberos(default).\n"
"The OID for dummy mechanism is 1.3.6.1.4.1.42.2.26.1.2.\n"
"The OID for Kerberos mechanism is 1.2.840.113554.1.2.2.\n"
"The order of context establishment calls is important. First, acquire must"
"\nbe called. This obtains the credentials used by accept. Acquire need\n"
"only be called once, since the credentials it returns are used each time\n"
"accept is called. Then init is called, followed by accept. Calling init\n"
"twice without calling accept or calling these in a different order gives\n"
"erroneous results and will cause memory leaks in the gssapi daemon. \n"
"Finally, after calling init and accept, init must be called again to\n"
"finish context establishment. So an example sequence (with data valid for\n"
"the Kerberos mechanism and running on the machine \"elrond\" in the realm\n"
"FOO.BAR.SUN.COM is :\n"));
fprintf(stderr,
gettext("\nacquire service@host 1.2.840.113554.1.2.2\n"
"init service@host 1.2.840.113554.1.2.2\n"
"accept\ninit service@host 1.2.840.113554.1.2.2\n"
"\nAfter a context is established, sign, seal,\n"
"verify and unseal may be called. Here are some examples\n"
"for these routines : \n\n"
"sign initiator ThisTestMessageIsForSigning\n"
"verify acceptor\nseal initiator ThisTestMessageIsForSealing\n"
"unseal acceptor\n\nEach input line is terminated by <cr>.\n"
"The program is terminated by cntl-d\nor the command \"exit\""
"\nfrom the prompt\n\n"));
}
static void
usage()
{
fprintf(stderr,
gettext(
"\nusage:\t[acquire | gss_acquire_cred]"
"desired_name mech_type\n"
"\t[release | gss_release_cred]\n"
"\t[init | gss_init_sec_context] target_name mech_type\n"
"\t[accept | gss_accept_sec_context]\n"
"\t[process | gss_process_context_token] initiator | acceptor\n"
"\t[delete | gss_delete_sec_context] initiator | acceptor\n"
"\t[time | gss_context_time] {not yet implemented}\n"
"\t[sign | gss_sign] initiator | acceptor message-to-sign\n"
"\t[verify | gss_verify] initiator | acceptor\n"
"\t[seal | gss_seal] initiator | acceptor message-to-seal\n"
"\t[unseal | gss_unseal] initiator | acceptor\n"
"\t[status | gss_display_status] mech_type [major | minor] \n"
"\t[indicate | gss_indicate_mechs]\n"
"\t[inquire | gss_inquire_cred] {not yet implemented}\n"
"\t[expname2unixcred | gsscred_expname_to_unix_cred]"
" export-name\n"
"\t[name2unixcred | gsscred_name_to_unix_cred] "
"pname [name_type mech_type]\n"
"\t[grpinfo | gss_get_group_info] uid\n"
"\t[gss_all | all] desired_name\n"
"\t[gss_loop | loop] desired_name\n"
"\texit\n\n"));
}
static int
parse_input_line(input_line, argc, argv)
char *input_line;
int * argc;
char ***argv;
{
const char nil = '\0';
char * chptr;
int chr_cnt;
int arg_cnt = 0;
int ch_was_space = 1;
int ch_is_space;
chr_cnt = strlen(input_line);
*argc = 1;
for (chptr = &input_line[0]; *chptr != nil; chptr++) {
ch_is_space = isspace(*chptr);
if (ch_is_space && !ch_was_space) {
(*argc)++;
}
ch_was_space = ch_is_space;
}
if (ch_was_space) {
(*argc)--;
}
*argv = (char **) CALLOC((*argc)+1, sizeof (char *));
chptr = (char *) (&input_line[0]);
for (ch_was_space = 1; *chptr != nil; chptr++) {
ch_is_space = isspace(*chptr);
if (ch_is_space) {
*chptr = nil;
} else if (ch_was_space) {
(*argv)[arg_cnt++] = chptr;
}
ch_was_space = ch_is_space;
}
return (chr_cnt);
}