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
This commit is contained in:
149
appl/rsh/rshd.c
149
appl/rsh/rshd.c
@@ -46,7 +46,7 @@ krb5_keyblock *keyblock;
|
|||||||
des_key_schedule schedule;
|
des_key_schedule schedule;
|
||||||
des_cblock iv;
|
des_cblock iv;
|
||||||
|
|
||||||
int do_encrypt;
|
int do_encrypt = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
syslog_and_die (const char *m, ...)
|
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);
|
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
|
#ifdef KRB4
|
||||||
static int
|
static int
|
||||||
recv_krb4_auth (int s, u_char *buf,
|
recv_krb4_auth (int s, u_char *buf,
|
||||||
@@ -309,7 +331,7 @@ loop (int from0, int to0,
|
|||||||
int to1, int from1,
|
int to1, int from1,
|
||||||
int to2, int from2)
|
int to2, int from2)
|
||||||
{
|
{
|
||||||
struct fd_set real_readset;
|
fd_set real_readset;
|
||||||
int max_fd;
|
int max_fd;
|
||||||
int count = 2;
|
int count = 2;
|
||||||
|
|
||||||
@@ -320,7 +342,7 @@ loop (int from0, int to0,
|
|||||||
max_fd = max(from0, max(from1, from2)) + 1;
|
max_fd = max(from0, max(from1, from2)) + 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ret;
|
int ret;
|
||||||
struct fd_set readset = real_readset;
|
fd_set readset = real_readset;
|
||||||
char buf[RSH_BUFSIZ];
|
char buf[RSH_BUFSIZ];
|
||||||
|
|
||||||
ret = select (max_fd, &readset, NULL, NULL, NULL);
|
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
|
static void
|
||||||
doit (void)
|
doit (int do_kerberos, int check_rhosts)
|
||||||
{
|
{
|
||||||
u_char buf[BUFSIZ];
|
u_char buf[BUFSIZ];
|
||||||
u_char *p;
|
u_char *p;
|
||||||
@@ -431,6 +459,9 @@ doit (void)
|
|||||||
syslog_and_die ("getpeername: %m");
|
syslog_and_die ("getpeername: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!do_kerberos && !is_reserved(thataddr.sin_port))
|
||||||
|
fatal(s, "Permission denied");
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
port = 0;
|
port = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
@@ -443,6 +474,10 @@ doit (void)
|
|||||||
else
|
else
|
||||||
syslog_and_die ("non-digit in port number: %c", *p);
|
syslog_and_die ("non-digit in port number: %c", *p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!do_kerberos && !is_reserved(htons(port)))
|
||||||
|
fatal(s, "Permission denied");
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
int priv_port = IPPORT_RESERVED - 1;
|
int priv_port = IPPORT_RESERVED - 1;
|
||||||
|
|
||||||
@@ -463,6 +498,7 @@ doit (void)
|
|||||||
syslog_and_die ("connect: %m");
|
syslog_and_die ("connect: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(do_kerberos) {
|
||||||
if (net_read (s, buf, 4) != 4)
|
if (net_read (s, buf, 4) != 4)
|
||||||
syslog_and_die ("reading auth info: %m");
|
syslog_and_die ("reading auth info: %m");
|
||||||
|
|
||||||
@@ -482,6 +518,15 @@ doit (void)
|
|||||||
else
|
else
|
||||||
syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
|
syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
|
||||||
buf[0], buf[1], buf[2], buf[3]);
|
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);
|
pwd = getpwnam (server_user);
|
||||||
if (pwd == NULL)
|
if (pwd == NULL)
|
||||||
@@ -535,58 +580,102 @@ doit (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage (void)
|
usage (int ret)
|
||||||
{
|
{
|
||||||
syslog (LOG_ERR, "Usage: %s [-ix] [-p port]", __progname);
|
syslog (LOG_ERR, "Usage: %s [-ixkl] [-p port]", __progname);
|
||||||
exit (1);
|
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
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int optind = 0;
|
||||||
int inetd = 0;
|
|
||||||
int port = 0;
|
int port = 0;
|
||||||
|
|
||||||
set_progname (argv[0]);
|
set_progname (argv[0]);
|
||||||
roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH);
|
roken_openlog ("rshd", LOG_ODELAY | LOG_PID, LOG_AUTH);
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "ixp:")) != EOF) {
|
if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv,
|
||||||
switch (c) {
|
&optind))
|
||||||
case 'i' :
|
usage(1);
|
||||||
inetd = 1;
|
|
||||||
break;
|
if(do_help)
|
||||||
case 'x' :
|
usage (0);
|
||||||
do_encrypt = 1;
|
|
||||||
break;
|
if (do_version) {
|
||||||
case 'p': {
|
printf ("%s (%s-%s)\n", __progname, PACKAGE, VERSION);
|
||||||
struct servent *s = roken_getservbyname (optarg, "tcp");
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(port_str) {
|
||||||
|
struct servent *s = roken_getservbyname (port_str, "tcp");
|
||||||
|
|
||||||
if (s)
|
if (s)
|
||||||
port = s->s_port;
|
port = s->s_port;
|
||||||
else {
|
else {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
port = strtol (optarg, &ptr, 10);
|
port = strtol (port_str, &ptr, 10);
|
||||||
if (port == 0 && ptr == optarg)
|
if (port == 0 && ptr == port_str)
|
||||||
syslog_and_die ("Bad port `%s'", optarg);
|
syslog_and_die("Bad port `%s'", port_str);
|
||||||
port = htons(port);
|
port = htons(port);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default :
|
|
||||||
usage ();
|
if (do_encrypt)
|
||||||
}
|
do_kerberos = 1;
|
||||||
}
|
|
||||||
if (inetd) {
|
if (!do_inetd) {
|
||||||
if (port == 0)
|
if (port == 0) {
|
||||||
|
if (do_kerberos) {
|
||||||
if (do_encrypt)
|
if (do_encrypt)
|
||||||
port = krb5_getportbyname (context, "ekshell", "tcp", 545);
|
port = krb5_getportbyname (context, "ekshell", "tcp", 545);
|
||||||
else
|
else
|
||||||
port = krb5_getportbyname (context, "kshell", "tcp", 544);
|
port = krb5_getportbyname (context, "kshell", "tcp", 544);
|
||||||
|
} else {
|
||||||
|
port = krb5_getportbyname(context, "shell", "tcp", 514);
|
||||||
|
}
|
||||||
|
}
|
||||||
mini_inetd (port);
|
mini_inetd (port);
|
||||||
}
|
}
|
||||||
|
|
||||||
doit ();
|
doit (do_kerberos, do_rhosts);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user