From 40ec34c822595b8a8881d5896f07b7c6e5d16e52 Mon Sep 17 00:00:00 2001 From: Assar Westerlund Date: Sat, 29 Nov 1997 07:29:39 +0000 Subject: [PATCH] updated to use getarg. changed `struct fd_set' to `fd_set' implemented broken/BSD authentication (requires iruserok) git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4076 ec53bebd-3082-4978-b11e-865c3cabbd6b --- appl/rsh/rshd.c | 199 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 144 insertions(+), 55 deletions(-) diff --git a/appl/rsh/rshd.c b/appl/rsh/rshd.c index 29ad9c2f7..aede0b62b 100644 --- a/appl/rsh/rshd.c +++ b/appl/rsh/rshd.c @@ -46,7 +46,7 @@ krb5_keyblock *keyblock; des_key_schedule schedule; des_cblock iv; -int do_encrypt; +int do_encrypt = 0; static void syslog_and_die (const char *m, ...) @@ -89,6 +89,28 @@ read_str (int s, char *str, size_t sz, char *expl) fatal (s, "%s too long", expl); } +static int +recv_bsd_auth (int s, u_char *buf, + struct sockaddr_in thisaddr, + struct sockaddr_in thataddr, + char *client_username, + char *server_username, + char *cmd) +{ + struct passwd *pwd; + + read_str (s, client_username, USERNAME_SZ, "local username"); + read_str (s, server_username, USERNAME_SZ, "remote username"); + read_str (s, cmd, COMMAND_SZ, "command"); + pwd = getpwnam(server_username); + if (pwd == NULL) + fatal(s, "Login incorrect."); + if (iruserok(thataddr.sin_addr.s_addr, pwd->pw_uid == 0, client_username, + server_username)) + fatal(s, "Login incorrect."); + return 0; +} + #ifdef KRB4 static int recv_krb4_auth (int s, u_char *buf, @@ -309,7 +331,7 @@ loop (int from0, int to0, int to1, int from1, int to2, int from2) { - struct fd_set real_readset; + fd_set real_readset; int max_fd; int count = 2; @@ -320,7 +342,7 @@ loop (int from0, int to0, max_fd = max(from0, max(from1, from2)) + 1; for (;;) { int ret; - struct fd_set readset = real_readset; + fd_set readset = real_readset; char buf[RSH_BUFSIZ]; ret = select (max_fd, &readset, NULL, NULL, NULL); @@ -405,8 +427,14 @@ setup_copier (void) } } +static int +is_reserved(u_short port) +{ + return ntohs(port) < IPPORT_RESERVED; +} + static void -doit (void) +doit (int do_kerberos, int check_rhosts) { u_char buf[BUFSIZ]; u_char *p; @@ -431,6 +459,9 @@ doit (void) syslog_and_die ("getpeername: %m"); } + if (!do_kerberos && !is_reserved(thataddr.sin_port)) + fatal(s, "Permission denied"); + p = buf; port = 0; for(;;) { @@ -443,6 +474,10 @@ doit (void) else syslog_and_die ("non-digit in port number: %c", *p); } + + if (!do_kerberos && !is_reserved(htons(port))) + fatal(s, "Permission denied"); + if (port) { int priv_port = IPPORT_RESERVED - 1; @@ -463,25 +498,35 @@ doit (void) syslog_and_die ("connect: %m"); } - if (net_read (s, buf, 4) != 4) - syslog_and_die ("reading auth info: %m"); + if(do_kerberos) { + if (net_read (s, buf, 4) != 4) + syslog_and_die ("reading auth info: %m"); #ifdef KRB4 - if (recv_krb4_auth (s, buf, thisaddr, thataddr, - client_user, - server_user, - cmd) == 0) - auth_method = AUTH_KRB4; - else -#endif /* KRB4 */ - if(recv_krb5_auth (s, buf, thisaddr, thataddr, + if (recv_krb4_auth (s, buf, thisaddr, thataddr, client_user, server_user, cmd) == 0) - auth_method = AUTH_KRB5; - else - syslog_and_die ("unrecognized auth protocol: %x %x %x %x", - buf[0], buf[1], buf[2], buf[3]); + auth_method = AUTH_KRB4; + else +#endif /* KRB4 */ + if(recv_krb5_auth (s, buf, thisaddr, thataddr, + client_user, + server_user, + cmd) == 0) + auth_method = AUTH_KRB5; + else + syslog_and_die ("unrecognized auth protocol: %x %x %x %x", + buf[0], buf[1], buf[2], buf[3]); + } else { + if(recv_bsd_auth (s, buf, thisaddr, thataddr, + client_user, + server_user, + cmd) == 0) + auth_method = AUTH_BROKEN; + else + syslog_and_die("recv_bsd_auth failed"); + } pwd = getpwnam (server_user); if (pwd == NULL) @@ -535,58 +580,102 @@ doit (void) } static void -usage (void) +usage (int ret) { - syslog (LOG_ERR, "Usage: %s [-ix] [-p port]", __progname); - exit (1); + syslog (LOG_ERR, "Usage: %s [-ixkl] [-p port]", __progname); + exit (ret); +} + +static int do_inetd = 1; +static char *port_str; +static int do_rhosts; +static int do_kerberos = 0; +static int do_version; +static int do_help = 0; + +struct getargs args[] = { + { "inetd", 'i', arg_negative_flag, &do_inetd, + "Expect to be started by inetd", NULL }, + { "kerberos", 'k', arg_flag, &do_kerberos, + "Implement kerberised services", NULL }, + { "encrypt", 'x', arg_flag, &do_encrypt, + "Implement encrypted service", NULL }, + { "rhosts", 'l', arg_negative_flag, &do_rhosts, + "Check users .rhosts", NULL }, + { "port", 'p', arg_string, &port_str, "Use this port", + "number-or-service" }, + { "version", 0, arg_flag, &do_version, "Print version", + NULL }, + { "help", 0, arg_flag, &do_help, NULL, + NULL } +}; + +#if 0 + +static void +usage (int ret) +{ + arg_printusage (args, + sizeof(args) / sizeof(args[0]), + "host command"); + exit (ret); } +#endif + int main(int argc, char **argv) { - int c; - int inetd = 0; + int optind = 0; int port = 0; set_progname (argv[0]); roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH); - while ((c = getopt(argc, argv, "ixp:")) != EOF) { - switch (c) { - case 'i' : - inetd = 1; - break; - case 'x' : - do_encrypt = 1; - break; - case 'p': { - struct servent *s = roken_getservbyname (optarg, "tcp"); - - if (s) - port = s->s_port; - else { - char *ptr; - - port = strtol (optarg, &ptr, 10); - if (port == 0 && ptr == optarg) - syslog_and_die ("Bad port `%s'", optarg); - port = htons(port); - } - break; - } - default : - usage (); + if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, + &optind)) + usage(1); + + if(do_help) + usage (0); + + if (do_version) { + printf ("%s (%s-%s)\n", __progname, PACKAGE, VERSION); + return 0; + } + + if(port_str) { + struct servent *s = roken_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) + syslog_and_die("Bad port `%s'", port_str); + port = htons(port); } } - if (inetd) { - if (port == 0) - if (do_encrypt) - port = krb5_getportbyname (context, "ekshell", "tcp", 545); - else - port = krb5_getportbyname (context, "kshell", "tcp", 544); + + if (do_encrypt) + do_kerberos = 1; + + if (!do_inetd) { + if (port == 0) { + if (do_kerberos) { + if (do_encrypt) + port = krb5_getportbyname (context, "ekshell", "tcp", 545); + else + port = krb5_getportbyname (context, "kshell", "tcp", 544); + } else { + port = krb5_getportbyname(context, "shell", "tcp", 514); + } + } mini_inetd (port); } - doit (); + doit (do_kerberos, do_rhosts); return 0; } -- 2.11.4.GIT