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;
int do_encrypt;
int do_forward;
krb5_context context;
krb5_keyblock *keyblock;
des_key_schedule schedule;
@@ -51,17 +52,7 @@ des_cblock iv;
*
*/
static int no_input;
static void
usage (void)
{
errx (1, "Usage: %s [-"
#ifdef KRB4
"4"
#endif
"5nx] [-p port] [-l user] host command", __progname);
}
static int input; /* Read from stdin */
static int
loop (int s, int errsock)
@@ -72,7 +63,7 @@ loop (int s, int errsock)
FD_ZERO(&real_readset);
FD_SET(s, &real_readset);
FD_SET(errsock, &real_readset);
if(!no_input) {
if(input) {
FD_SET(STDIN_FILENO, &real_readset);
}
@@ -158,6 +149,77 @@ send_krb4_auth(int s, struct sockaddr_in thisaddr,
}
#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
send_krb5_auth(int s, struct sockaddr_in thisaddr,
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)
err (1, "write");
{
if (!do_forward || krb5_forward_cred (auth_context, s, hostname)) {
/* Empty forwarding info */
u_int32_t zero = 0;
u_char zero[4] = {0, 0, 0, 0};
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;
}
#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
main(int argc, char **argv)
{
int c;
char *remote_user = NULL;
int port = 0;
int optind = 0;
int ret = 1;
set_progname (argv[0]);
auth_method = AUTH_KRB5;
while ((c = getopt(argc, argv, "45l:nxp:")) != EOF) {
switch (c) {
#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 (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
&optind))
usage (1);
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;
argv += optind;
if (argc < 1)
usage ();
if (do_help)
usage (0);
if (port == 0)
#ifdef KRB4
if (do_encrypt && auth_method == AUTH_KRB4)
port = k_getportbyname ("ekshell", "tcp", htons(545));
if (do_version) {
printf ("%s (%s-%s)\n", __progname, PACKAGE, VERSION);
return 0;
}
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
#endif /* KRB4 */
port = krb5_getportbyname ("kshell", "tcp", htons(544));
tmp_port = krb5_getportbyname ("kshell", "tcp", htons(544));
return doit (*argv, remote_user, port,
argc - 1, argv + 1);
auth_method = AUTH_KRB5;
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;
}