Use getarg. Implement forwarding.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2628 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1997-07-25 15:32:09 +00:00
parent b5b6216a77
commit 5962efedfa

View File

@@ -41,6 +41,7 @@ RCSID("$Id$");
enum auth_method auth_method; enum auth_method auth_method;
int do_encrypt; int do_encrypt;
int do_forward;
krb5_context context; krb5_context context;
krb5_keyblock *keyblock; krb5_keyblock *keyblock;
des_key_schedule schedule; des_key_schedule schedule;
@@ -51,17 +52,7 @@ des_cblock iv;
* *
*/ */
static int no_input; static int input; /* Read from stdin */
static void
usage (void)
{
errx (1, "Usage: %s [-"
#ifdef KRB4
"4"
#endif
"5nx] [-p port] [-l user] host command", __progname);
}
static int static int
loop (int s, int errsock) loop (int s, int errsock)
@@ -72,7 +63,7 @@ loop (int s, int errsock)
FD_ZERO(&real_readset); FD_ZERO(&real_readset);
FD_SET(s, &real_readset); FD_SET(s, &real_readset);
FD_SET(errsock, &real_readset); FD_SET(errsock, &real_readset);
if(!no_input) { if(input) {
FD_SET(STDIN_FILENO, &real_readset); FD_SET(STDIN_FILENO, &real_readset);
} }
@@ -158,6 +149,77 @@ send_krb4_auth(int s, struct sockaddr_in thisaddr,
} }
#endif /* KRB4 */ #endif /* KRB4 */
static int
krb5_forward_cred (krb5_auth_context auth_context,
int s,
char *hostname)
{
krb5_error_code ret;
krb5_ccache ccache;
krb5_creds creds;
krb5_kdc_flags flags;
krb5_data out_data;
krb5_principal principal;
ret = krb5_cc_default (context, &ccache);
if (ret) {
warnx ("could not forward creds: krb5_cc_default: %s",
krb5_get_err_text (context, ret));
return 1;
}
ret = krb5_cc_get_principal (context, ccache, &principal);
if (ret) {
warnx ("could not forward creds: krb5_cc_get_principal: %s",
krb5_get_err_text (context, ret));
return 1;
}
creds.client = principal;
ret = krb5_build_principal (context,
&creds.server,
strlen(principal->realm),
principal->realm,
"krbtgt",
principal->realm,
NULL);
if (ret) {
warnx ("could not forward creds: krb5_build_principal: %s",
krb5_get_err_text (context, ret));
return 1;
}
creds.times.endtime = 0;
flags.i = 0;
flags.b.forwarded = 1;
ret = krb5_get_forwarded_creds (context,
auth_context,
ccache,
flags.i,
hostname,
&creds,
&out_data);
if (ret) {
warnx ("could not forward creds: krb5_get_forwarded_creds: %s",
krb5_get_err_text (context, ret));
return 1;
}
ret = krb5_write_message (context,
(void *)&s,
&out_data);
krb5_data_free (&out_data);
if (ret)
warnx ("could not forward creds: krb5_write_message: %s",
krb5_get_err_text (context, ret));
return 0;
}
static void static void
send_krb5_auth(int s, struct sockaddr_in thisaddr, send_krb5_auth(int s, struct sockaddr_in thisaddr,
struct sockaddr_in thataddr, struct sockaddr_in thataddr,
@@ -226,12 +288,13 @@ send_krb5_auth(int s, struct sockaddr_in thisaddr,
if (net_write (s, remote_user, len) != len) if (net_write (s, remote_user, len) != len)
err (1, "write"); err (1, "write");
{ if (!do_forward || krb5_forward_cred (auth_context, s, hostname)) {
/* Empty forwarding info */ /* Empty forwarding info */
u_int32_t zero = 0; u_char zero[4] = {0, 0, 0, 0};
write (s, &zero, 4); write (s, &zero, 4);
} }
krb5_auth_con_free (context, auth_context);
} }
@@ -386,73 +449,119 @@ doit (char *hostname, char *remote_user, int port, int argc, char **argv)
return 1; return 1;
} }
#ifdef KRB4
static int use_v4 = 0;
#endif
static int use_v5 = 1;
static char *port_str;
static char *user;
static int do_version;
static int do_help;
struct getargs args[] = {
#ifdef KRB4
{ "krb4", '4', arg_flag, &use_v4, "Use Kerberos V4",
NULL },
#endif
{ "krb5", '5', arg_flag, &use_v5, "Use Kerberos V5",
NULL },
{ "input", 'n', arg_negative_flag, &input, "Close stdin",
NULL },
{ "encrypt", 'x', arg_flag, &do_encrypt, "Encrypt connection",
NULL },
{ "forward", 'f', arg_flag, &do_forward, "Forward credentials",
NULL },
{ "port", 'p', arg_string, &port_str, "Use this port",
"number-or-service" },
{ "user", 'l', arg_string, &user, "Run as this user",
NULL },
{ "version", 0, arg_flag, &do_version, "Print version",
NULL },
{ "help", 0, arg_flag, &do_help, NULL,
NULL }
};
static void
usage (int ret)
{
arg_printusage (args,
sizeof(args) / sizeof(args[0]),
"host command");
exit (ret);
}
/* /*
* rsh host command * main
*/ */
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int c;
char *remote_user = NULL;
int port = 0; int port = 0;
int optind = 0;
int ret = 1;
set_progname (argv[0]); set_progname (argv[0]);
auth_method = AUTH_KRB5; if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
while ((c = getopt(argc, argv, "45l:nxp:")) != EOF) { &optind))
switch (c) { usage (1);
#ifdef KRB4
case '4':
auth_method = AUTH_KRB4;
break;
#endif
case '5':
auth_method = AUTH_KRB5;
break;
case 'l':
remote_user = optarg;
break;
case 'n':
no_input = 1;
break;
case 'x':
do_encrypt = 1;
break;
case 'p': {
struct servent *s = getservbyname (optarg, "tcp");
if (s)
port = s->s_port;
else {
char *ptr;
port = strtol (optarg, &ptr, 10);
if (port == 0 && ptr == optarg)
errx (1, "Bad port `%s'", optarg);
port = htons(port);
}
break;
}
default:
usage ();
break;
}
}
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (argc < 1) if (do_help)
usage (); usage (0);
if (port == 0) if (do_version) {
#ifdef KRB4 printf ("%s (%s-%s)\n", __progname, PACKAGE, VERSION);
if (do_encrypt && auth_method == AUTH_KRB4) return 0;
port = k_getportbyname ("ekshell", "tcp", htons(545)); }
if (argc < 2)
usage (1);
if (port_str) {
struct servent *s = getservbyname (port_str, "tcp");
if (s)
port = s->s_port;
else {
char *ptr;
port = strtol (port_str, &ptr, 10);
if (port == 0 && ptr == port_str)
errx (1, "Bad port `%s'", port_str);
port = htons(port);
}
}
if (ret && use_v5) {
int tmp_port;
if (port)
tmp_port = port;
else else
#endif /* KRB4 */ tmp_port = krb5_getportbyname ("kshell", "tcp", htons(544));
port = krb5_getportbyname ("kshell", "tcp", htons(544));
return doit (*argv, remote_user, port, auth_method = AUTH_KRB5;
argc - 1, argv + 1); ret = doit (*argv, user, tmp_port, argc - 1, argv + 1);
}
#ifdef KRB4
if (ret && use_v4) {
int tmp_port;
if (port)
tmp_port = port;
else if (do_encrypt)
tmp_port = k_getportbyname ("ekshell", "tcp", htons(545));
else
tmp_port = krb5_getportbyname ("kshell", "tcp", htons(544));
auth_method = AUTH_KRB4;
ret = doit (*argv, user, tmp_port, argc - 1, argv + 1);
}
#endif
return ret;
} }