71 |
# include <sys/select.h> |
# include <sys/select.h> |
72 |
#endif |
#endif |
73 |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
74 |
#include <sys/stat.h> /* Needed for chmod() */ |
#include <sys/stat.h> /* Needed for chmod() */ |
75 |
|
|
76 |
/* |
/* |
77 |
The TIOCPKT_* macros may not be implemented in the pty driver. |
The TIOCPKT_* macros may not be implemented in the pty driver. |
82 |
# define TIOCPKT_NOSTOP 0x10 |
# define TIOCPKT_NOSTOP 0x10 |
83 |
# define TIOCPKT_DOSTOP 0x20 |
# define TIOCPKT_DOSTOP 0x20 |
84 |
#endif /*TIOCPKT*/ |
#endif /*TIOCPKT*/ |
|
|
|
85 |
#ifndef TIOCPKT_WINDOW |
#ifndef TIOCPKT_WINDOW |
86 |
# define TIOCPKT_WINDOW 0x80 |
# define TIOCPKT_WINDOW 0x80 |
87 |
#endif |
#endif |
|
|
|
88 |
/* `defaults' for tty settings. */ |
/* `defaults' for tty settings. */ |
89 |
#ifndef TTYDEF_IFLAG |
#ifndef TTYDEF_IFLAG |
90 |
#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY) |
#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY) |
98 |
#ifndef TTYDEF_LFLAG |
#ifndef TTYDEF_LFLAG |
99 |
#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) |
#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL) |
100 |
#endif |
#endif |
101 |
|
#define AUTH_KERBEROS_SHISHI 1 |
102 |
#define AUTH_KERBEROS_4 4 |
#define AUTH_KERBEROS_4 4 |
103 |
#define AUTH_KERBEROS_5 5 |
#define AUTH_KERBEROS_5 5 |
104 |
|
#if defined(KERBEROS) || defined(SHISHI) |
|
#ifdef KERBEROS |
|
|
# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" |
|
105 |
# ifdef KRB4 |
# ifdef KRB4 |
106 |
|
# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" |
107 |
# include <kerberosIV/des.h> |
# include <kerberosIV/des.h> |
108 |
# include <kerberosIV/krb.h> |
# include <kerberosIV/krb.h> |
109 |
# define kerberos_error_string(c) krb_err_txt[c] |
# define kerberos_error_string(c) krb_err_txt[c] |
110 |
# define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_4 |
# define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_4 |
111 |
# elif defined(KRB5) |
# elif defined(KRB5) |
112 |
|
# define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" |
113 |
# include <krb5.h> |
# include <krb5.h> |
114 |
# include <kerberosIV/krb.h> |
# include <kerberosIV/krb.h> |
115 |
# define kerberos_error_string(c) error_message (c) |
# define kerberos_error_string(c) error_message (c) |
116 |
# define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_5 |
# define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_5 |
117 |
|
# elif defined(SHISHI) |
118 |
|
# define SECURE_MESSAGE "This rlogin session is using encryption for all transmissions.\r\n" |
119 |
|
# include <shishi.h> |
120 |
|
# include "shishi_def.h" |
121 |
|
# define AUTH_KERBEROS_DEFAULT AUTH_KERBEROS_SHISHI |
122 |
|
# define kerberos_error_string(c) shishi_strerror(c) |
123 |
# endif |
# endif |
124 |
#endif /* KERBEROS */ |
#endif /* KERBEROS */ |
|
|
|
125 |
#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ |
#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ |
|
|
|
126 |
#ifndef DEFMAXCHILDREN |
#ifndef DEFMAXCHILDREN |
127 |
# define DEFMAXCHILDREN 10 /* Default maximum number of children */ |
# define DEFMAXCHILDREN 10 /* Default maximum number of children */ |
128 |
#endif |
#endif |
129 |
#ifndef DEFPORT |
#ifndef DEFPORT |
130 |
# define DEFPORT 513 |
# define DEFPORT 513 |
131 |
#endif |
#endif |
132 |
|
extern int __check_rhosts_file; |
133 |
|
|
134 |
extern int __check_rhosts_file; |
#ifndef SHISHI |
|
|
|
135 |
struct auth_data |
struct auth_data |
136 |
{ |
{ |
137 |
struct sockaddr_in from; |
struct sockaddr_in from; |
138 |
char *hostname; |
char *hostname; |
139 |
char *lusername; |
char *lusername; |
140 |
char *rusername; |
char *rusername; |
141 |
char *term; |
char *term; |
142 |
char *env[2]; |
char *env[2]; |
143 |
#ifdef KERBEROS |
#ifdef KERBEROS |
144 |
#ifdef KRB5 |
#ifdef KRB5 |
145 |
int kerberos_version; |
int kerberos_version; |
146 |
krb5_principal client; |
krb5_principal client; |
147 |
krb5_context context; |
krb5_context context; |
148 |
krb5_ccache ccache; |
krb5_ccache ccache; |
149 |
krb5_keytab keytab; |
krb5_keytab keytab; |
150 |
#endif |
#endif |
151 |
#endif |
#endif |
152 |
}; |
}; |
153 |
|
#endif |
154 |
|
|
155 |
static const char *short_options = "aD::d::hk::L:lnp:orxV"; |
static const char *short_options = "aD::d::hk::L:lnp:orxV"; |
156 |
static struct option long_options[] = |
static struct option long_options[] = { |
|
{ |
|
157 |
{"allow-root", no_argument, 0, 'o'}, |
{"allow-root", no_argument, 0, 'o'}, |
158 |
{"verify-hostname", no_argument, 0, 'a'}, |
{"verify-hostname", no_argument, 0, 'a'}, |
159 |
{"daemon", optional_argument, 0, 'd'}, |
{"daemon", optional_argument, 0, 'd'}, |
170 |
{0, 0, 0, 0} |
{0, 0, 0, 0} |
171 |
}; |
}; |
172 |
|
|
173 |
int allow_root = 0; |
int allow_root = 0; |
174 |
int verify_hostname = 0; |
int verify_hostname = 0; |
175 |
int keepalive = 1; |
int keepalive = 1; |
176 |
#ifdef KERBEROS |
|
177 |
int kerberos = 0; |
#if defined(KERBEROS) || defined(SHISHI) |
178 |
|
int kerberos = 0; |
179 |
|
|
180 |
#ifdef ENCRYPTION |
#ifdef ENCRYPTION |
181 |
int encrypt_io = 0; |
int encrypt_io = 0; |
182 |
#endif /* ENCRYPTION */ |
#endif /* ENCRYPTION */ |
183 |
#endif /* KERBEROS */ |
#endif /* KERBEROS */ |
184 |
int reverse_required = 0; |
int reverse_required = 0; |
185 |
int debug_level = 0; |
int debug_level = 0; |
186 |
|
|
187 |
int numchildren; |
int numchildren; |
188 |
int netf; |
int netf; |
189 |
char line[1024]; /* FIXME */ |
char line[1024]; /* FIXME */ |
190 |
int confirmed; |
int confirmed; |
191 |
const char *path_login = PATH_LOGIN; |
const char *path_login = PATH_LOGIN; |
192 |
char *local_domain_name; |
char *local_domain_name; |
193 |
int local_dot_count; |
int local_dot_count; |
194 |
|
|
195 |
struct winsize win = {0, 0, 0, 0}; |
struct winsize win = { 0, 0, 0, 0 }; |
196 |
|
|
197 |
void usage __P ((void)); |
void usage __P ((void)); |
198 |
void rlogin_daemon __P ((int maxchildren, int port)); |
void rlogin_daemon __P ((int maxchildren, int port)); |
199 |
int rlogind_auth __P ((int fd, struct auth_data *ap)); |
int rlogind_auth __P ((int fd, struct auth_data * ap)); |
200 |
void setup_tty __P ((int fd, struct auth_data *ap)); |
void setup_tty __P ((int fd, struct auth_data * ap)); |
201 |
void exec_login __P ((int authenticated, struct auth_data *ap)); |
void exec_login __P ((int authenticated, struct auth_data * ap)); |
202 |
int rlogind_mainloop __P ((int infd, int outfd)); |
int rlogind_mainloop __P ((int infd, int outfd)); |
203 |
int do_rlogin __P ((int infd, struct auth_data *ap)); |
int do_rlogin __P ((int infd, struct auth_data * ap)); |
204 |
int do_krb_login __P ((int infd, struct auth_data *ap, const char **msg)); |
int do_krb_login __P ((int infd, struct auth_data * ap, const char **msg)); |
205 |
void getstr __P ((int infd, char **ptr, const char *prefix)); |
void getstr __P ((int infd, char **ptr, const char *prefix)); |
206 |
void protocol __P ((int f, int p)); |
void protocol __P ((int f, int p, struct auth_data * ap)); |
207 |
int control __P ((int pty, char *cp, size_t n)); |
int control __P ((int pty, char *cp, size_t n)); |
208 |
RETSIGTYPE cleanup __P ((int signo)); |
RETSIGTYPE cleanup __P ((int signo)); |
209 |
void fatal __P ((int f, const char *msg, int syserr)); |
void fatal __P ((int f, const char *msg, int syserr)); |
210 |
int in_local_domain __P ((char *hostname)); |
int in_local_domain __P ((char *hostname)); |
211 |
char *topdomain __P ((char *name, int max_dots)); |
char *topdomain __P ((char *name, int max_dots)); |
212 |
|
|
213 |
RETSIGTYPE |
RETSIGTYPE |
214 |
rlogind_sigchld (int sig) |
rlogind_sigchld (int sig) |
215 |
{ |
{ |
216 |
pid_t pid; |
pid_t pid; |
217 |
int status; |
int status; |
218 |
|
|
219 |
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) |
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) |
220 |
--numchildren; |
--numchildren; |
224 |
#define MODE_INETD 0 |
#define MODE_INETD 0 |
225 |
#define MODE_DAEMON 1 |
#define MODE_DAEMON 1 |
226 |
|
|
227 |
#if defined(KERBEROS) && defined(ENCRYPTION) |
#if defined(KERBEROS) && defined (ENCRYPTION) |
228 |
# define ENCRYPT_IO encrypt_io |
# define ENCRYPT_IO encrypt_io |
229 |
# define IF_ENCRYPT(stmt) if (encrypt_io) stmt |
# define IF_ENCRYPT(stmt) if (encrypt_io) stmt |
230 |
# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt |
# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt |
231 |
# define ENC_READ(c, fd, buf, size) \ |
# define ENC_READ(c, fd, buf, size, ap) \ |
232 |
if (encrypt_io) \ |
if (encrypt_io) \ |
233 |
c = des_read(fd, buf, size); \ |
c = des_read(fd, buf, size); \ |
234 |
else \ |
else \ |
235 |
c = read(fd, buf, size); |
c = read(fd, buf, size); |
236 |
# define ENC_WRITE(c, fd, buf, size) \ |
# define EN_WRITE(c, fd, buf, size, ap) \ |
237 |
if (encrypt_io) \ |
if (encrypt_io) \ |
238 |
c = des_write(fd, buf, size); \ |
c = des_write(fd, buf, size); \ |
239 |
else \ |
else \ |
240 |
c = write(fd, buf, size); |
c = write(fd, buf, size); |
241 |
|
#elif defined(SHISHI) && defined (ENCRYPTION) |
242 |
|
# define ENCRYPT_IO encrypt_io |
243 |
|
# define IF_ENCRYPT(stmt) if (encrypt_io) stmt |
244 |
|
# define IF_NOT_ENCRYPT(stmt) if (!encrypt_io) stmt |
245 |
|
# define ENC_READ(c, fd, buf, size, ap) \ |
246 |
|
if (encrypt_io) \ |
247 |
|
readenc (ap->h, fd, buf, &c, &ap->iv1, ap->enckey, ap->protocol); \ |
248 |
|
else \ |
249 |
|
c = read(fd, buf, size); |
250 |
|
# define ENC_WRITE(c, fd, buf, size, ap) \ |
251 |
|
if (encrypt_io) \ |
252 |
|
writeenc (ap->h, fd, buf, size, &c, &ap->iv2, ap->enckey, ap->protocol); \ |
253 |
|
else \ |
254 |
|
c = write(fd, buf, size); |
255 |
#else |
#else |
256 |
# define ENCRYPT_IO 0 |
# define ENCRYPT_IO 0 |
257 |
# define IF_ENCRYPT(stmt) |
# define IF_ENCRYPT(stmt) |
258 |
# define IF_NOT_ENCRYPT(stmt) stmt |
# define IF_NOT_ENCRYPT(stmt) stmt |
259 |
# define ENC_READ(c, fd, buf, size) c = read (fd, buf, size) |
# define ENC_READ(c, fd, buf, size, ap) c = read (fd, buf, size) |
260 |
# define ENC_WRITE(c, fd, buf, size) c = write (fd, buf, size) |
# define ENC_WRITE(c, fd, buf, size, ap) c = write (fd, buf, size) |
261 |
#endif |
#endif |
262 |
|
|
263 |
int |
int |
264 |
main (int argc, char *argv[]) |
main (int argc, char *argv[]) |
265 |
{ |
{ |
266 |
int port = 0; |
int port = 0; |
267 |
int maxchildren = DEFMAXCHILDREN; |
int maxchildren = DEFMAXCHILDREN; |
268 |
int mode = MODE_INETD; |
int mode = MODE_INETD; |
269 |
int c; |
int c; |
270 |
|
|
271 |
while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) |
while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) |
272 |
!= EOF) |
!= EOF) |
291 |
break; |
break; |
292 |
|
|
293 |
case 'l': |
case 'l': |
294 |
__check_rhosts_file = 0; /* FIXME: extern var? */ |
__check_rhosts_file = 0; /* FIXME: extern var? */ |
295 |
break; |
break; |
296 |
|
|
297 |
case 'L': |
case 'L': |
302 |
keepalive = 0; |
keepalive = 0; |
303 |
break; |
break; |
304 |
|
|
305 |
#ifdef KERBEROS |
#if defined(KERBEROS) || defined(SHISHI) |
306 |
case 'k': |
case 'k': |
307 |
if (optarg) |
if (optarg) |
308 |
{ |
{ |
319 |
case 'x': |
case 'x': |
320 |
encrypt_io = 1; |
encrypt_io = 1; |
321 |
break; |
break; |
322 |
# endif /* ENCRYPTION */ |
# endif /* ENCRYPTION */ |
323 |
#endif /* KERBEROS */ |
#endif /* KERBEROS */ |
324 |
|
|
325 |
case 'o': |
case 'o': |
369 |
} |
} |
370 |
else |
else |
371 |
{ |
{ |
372 |
char *p; |
char *p; |
373 |
|
|
374 |
local_dot_count = 0; |
local_dot_count = 0; |
375 |
for (p = local_domain_name; *p; p++) |
for (p = local_domain_name; *p; p++) |
376 |
if (*p == '.') |
if (*p == '.') |
382 |
else |
else |
383 |
exit (rlogind_mainloop (fileno (stdin), fileno (stdout))); |
exit (rlogind_mainloop (fileno (stdin), fileno (stdout))); |
384 |
|
|
385 |
|
|
386 |
/* To pacify lint */ |
/* To pacify lint */ |
387 |
return 0; |
return 0; |
388 |
} |
} |
391 |
void |
void |
392 |
rlogin_daemon (int maxchildren, int port) |
rlogin_daemon (int maxchildren, int port) |
393 |
{ |
{ |
394 |
pid_t pid; |
pid_t pid; |
395 |
size_t size; |
size_t size; |
396 |
struct sockaddr_in saddr; |
struct sockaddr_in saddr; |
397 |
int listenfd, fd; |
int listenfd, fd; |
398 |
|
|
399 |
if (port == 0) |
if (port == 0) |
400 |
{ |
{ |
427 |
} |
} |
428 |
|
|
429 |
{ |
{ |
430 |
int on = 1; |
int on = 1; |
431 |
|
|
432 |
setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); |
setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on); |
433 |
} |
} |
434 |
|
|
439 |
saddr.sin_port = htons (port); |
saddr.sin_port = htons (port); |
440 |
|
|
441 |
size = sizeof saddr; |
size = sizeof saddr; |
442 |
if (bind (listenfd, (struct sockaddr *)&saddr, size) == -1) |
if (bind (listenfd, (struct sockaddr *) &saddr, size) == -1) |
443 |
{ |
{ |
444 |
syslog (LOG_ERR, "bind: %s", strerror (errno)); |
syslog (LOG_ERR, "bind: %s", strerror (errno)); |
445 |
exit (1); |
exit (1); |
454 |
while (1) |
while (1) |
455 |
{ |
{ |
456 |
if (numchildren > maxchildren) |
if (numchildren > maxchildren) |
457 |
{ |
{ |
458 |
syslog (LOG_ERR, "too many children (%d)", numchildren); |
syslog (LOG_ERR, "too many children (%d)", numchildren); |
459 |
pause (); |
pause (); |
460 |
continue; |
continue; |
461 |
} |
} |
462 |
|
|
463 |
size = sizeof saddr; |
size = sizeof saddr; |
464 |
fd = accept (listenfd, (struct sockaddr *)&saddr, &size); |
fd = accept (listenfd, (struct sockaddr *) &saddr, &size); |
465 |
|
|
466 |
if (fd == -1) |
if (fd == -1) |
467 |
{ |
{ |
474 |
pid = fork (); |
pid = fork (); |
475 |
if (pid == -1) |
if (pid == -1) |
476 |
syslog (LOG_ERR, "fork: %s", strerror (errno)); |
syslog (LOG_ERR, "fork: %s", strerror (errno)); |
477 |
else if (pid == 0) /* child */ |
else if (pid == 0) /* child */ |
478 |
{ |
{ |
479 |
close (listenfd); |
close (listenfd); |
480 |
exit (rlogind_mainloop (fd, fd)); |
exit (rlogind_mainloop (fd, fd)); |
489 |
rlogind_auth (int fd, struct auth_data *ap) |
rlogind_auth (int fd, struct auth_data *ap) |
490 |
{ |
{ |
491 |
struct hostent *hp; |
struct hostent *hp; |
492 |
char *hostname; |
char *hostname; |
493 |
int authenticated = 0; |
int authenticated = 0; |
494 |
|
|
495 |
|
#ifdef SHISHI |
496 |
|
int len, c; |
497 |
|
#endif |
498 |
|
|
499 |
confirmed = 0; |
confirmed = 0; |
500 |
|
|
515 |
|
|
516 |
if (verify_hostname || in_local_domain (ap->hostname)) |
if (verify_hostname || in_local_domain (ap->hostname)) |
517 |
{ |
{ |
518 |
int match = 0; |
int match = 0; |
519 |
|
|
520 |
for (hp = gethostbyname (ap->hostname); hp && !match; hp->h_addr_list++) |
for (hp = gethostbyname (ap->hostname); hp && !match; hp->h_addr_list++) |
521 |
{ |
{ |
522 |
if (hp->h_addr_list[0] == NULL) |
if (hp->h_addr_list[0] == NULL) |
532 |
} |
} |
533 |
} |
} |
534 |
|
|
535 |
#ifdef KERBEROS |
#if defined(KERBEROS) || defined(SHISHI) |
536 |
if (kerberos) |
if (kerberos) |
537 |
{ |
{ |
538 |
const char *err_msg; |
const char *err_msg; |
539 |
int c = 0; |
int c = 0; |
540 |
|
|
541 |
if (do_krb_login (fd, ap, &err_msg) == 0) |
if (do_krb_login (fd, ap, &err_msg) == 0) |
542 |
authenticated++; |
authenticated++; |
543 |
else |
else |
544 |
fatal (fd, err_msg, 0); |
fatal (fd, err_msg, 0); |
545 |
write (fd, &c, 1); |
write (fd, &c, 1); |
546 |
confirmed = 1; /* we sent the null! */ |
confirmed = 1; /* we sent the null! */ |
548 |
else |
else |
549 |
#endif |
#endif |
550 |
{ |
{ |
551 |
int port = ntohs(ap->from.sin_port); |
int port = ntohs (ap->from.sin_port); |
552 |
|
|
553 |
if (ap->from.sin_family != AF_INET || |
if (ap->from.sin_family != AF_INET || |
554 |
port >= IPPORT_RESERVED || |
port >= IPPORT_RESERVED || port < IPPORT_RESERVED / 2) |
|
port < IPPORT_RESERVED / 2) |
|
555 |
{ |
{ |
556 |
syslog (LOG_NOTICE, "Connection from %s on illegal port %d", |
syslog (LOG_NOTICE, "Connection from %s on illegal port %d", |
557 |
inet_ntoa (ap->from.sin_addr), port); |
inet_ntoa (ap->from.sin_addr), port); |
559 |
} |
} |
560 |
#ifdef IP_OPTIONS |
#ifdef IP_OPTIONS |
561 |
{ |
{ |
562 |
u_char optbuf[BUFSIZ / 3], *cp; |
u_char optbuf[BUFSIZ / 3], *cp; |
563 |
char lbuf[BUFSIZ], *lp; |
char lbuf[BUFSIZ], *lp; |
564 |
int optsize = sizeof (optbuf), ipproto; |
int optsize = sizeof (optbuf), ipproto; |
565 |
struct protoent *ip; |
struct protoent *ip; |
566 |
|
|
567 |
if ((ip = getprotobyname ("ip")) != NULL) |
if ((ip = getprotobyname ("ip")) != NULL) |
574 |
lp = lbuf; |
lp = lbuf; |
575 |
for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) |
for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) |
576 |
sprintf (lp, " %2.2x", *cp); |
sprintf (lp, " %2.2x", *cp); |
577 |
syslog (LOG_NOTICE, |
syslog (LOG_NOTICE, "Ignoring IP options: %s", lbuf); |
|
"Ignoring IP options: %s", lbuf); |
|
578 |
if (setsockopt (0, ipproto, IP_OPTIONS, (char *) NULL, optsize)) |
if (setsockopt (0, ipproto, IP_OPTIONS, (char *) NULL, optsize)) |
579 |
{ |
{ |
580 |
syslog (LOG_ERR, "setsockopt IP_OPTIONS NULL: %m"); |
syslog (LOG_ERR, "setsockopt IP_OPTIONS NULL: %m"); |
592 |
write (fd, "", 1); |
write (fd, "", 1); |
593 |
confirmed = 1; /* we sent the null! */ |
confirmed = 1; /* we sent the null! */ |
594 |
} |
} |
595 |
|
#ifdef SHISHI |
596 |
|
len = sizeof (SECURE_MESSAGE) - 1; |
597 |
|
IF_ENCRYPT (writeenc |
598 |
|
(ap->h, fd, SECURE_MESSAGE, len, &c, &ap->iv2, ap->enckey, |
599 |
|
ap->protocol)); |
600 |
|
#else |
601 |
IF_ENCRYPT (des_write (fd, SECURE_MESSAGE, sizeof (SECURE_MESSAGE) - 1)); |
IF_ENCRYPT (des_write (fd, SECURE_MESSAGE, sizeof (SECURE_MESSAGE) - 1)); |
602 |
|
#endif |
603 |
return authenticated; |
return authenticated; |
604 |
} |
} |
605 |
|
|
606 |
void |
void |
607 |
setup_tty (int fd, struct auth_data *ap) |
setup_tty (int fd, struct auth_data *ap) |
608 |
{ |
{ |
609 |
register char *cp = strchr (ap->term + ENVSIZE, '/'); |
register char *cp = strchr (ap->term + ENVSIZE, '/'); |
610 |
char *speed; |
char *speed; |
611 |
struct termios tt; |
struct termios tt; |
612 |
|
|
613 |
tcgetattr (fd, &tt); |
tcgetattr (fd, &tt); |
614 |
if (cp) |
if (cp) |
634 |
} |
} |
635 |
|
|
636 |
#ifdef UTMPX |
#ifdef UTMPX |
637 |
char *utmp_ptsid (); /*FIXME*/ |
char *utmp_ptsid (); |
638 |
void utmp_init (); |
/*FIXME*/ void utmp_init (); |
639 |
|
|
640 |
void |
void |
641 |
setup_utmp (char *line) |
setup_utmp (char *line) |
642 |
{ |
{ |
643 |
char *ut_id = utmp_ptsid (line, "rl"); |
char *ut_id = utmp_ptsid (line, "rl"); |
644 |
|
|
645 |
utmp_init (line + sizeof ("/dev/") - 1, ".rlogin", ut_id); |
utmp_init (line + sizeof ("/dev/") - 1, ".rlogin", ut_id); |
646 |
} |
} |
647 |
#else |
#else |
649 |
#endif |
#endif |
650 |
|
|
651 |
void |
void |
652 |
exec_login(int authenticated, struct auth_data *ap) |
exec_login (int authenticated, struct auth_data *ap) |
653 |
{ |
{ |
654 |
if (authenticated) |
if (authenticated) |
655 |
{ |
{ |
659 |
ap->lusername, NULL, ap->env); |
ap->lusername, NULL, ap->env); |
660 |
#else |
#else |
661 |
execle (path_login, "login", "-p", |
execle (path_login, "login", "-p", |
662 |
"-h", ap->hostname, "-f", |
"-h", ap->hostname, "-f", ap->lusername, NULL, ap->env); |
|
ap->lusername, NULL, ap->env); |
|
663 |
#endif |
#endif |
664 |
} |
} |
665 |
else |
else |
670 |
ap->lusername, NULL, ap->env); |
ap->lusername, NULL, ap->env); |
671 |
#else |
#else |
672 |
execle (path_login, "login", "-p", |
execle (path_login, "login", "-p", |
673 |
"-h", ap->hostname, |
"-h", ap->hostname, ap->lusername, NULL, ap->env); |
|
ap->lusername, NULL, ap->env); |
|
674 |
#endif |
#endif |
675 |
} |
} |
676 |
syslog(LOG_ERR, "can't exec login: %m"); |
syslog (LOG_ERR, "can't exec login: %m"); |
677 |
} |
} |
678 |
|
|
679 |
int |
int |
680 |
rlogind_mainloop (int infd, int outfd) |
rlogind_mainloop (int infd, int outfd) |
681 |
{ |
{ |
682 |
size_t size; |
size_t size; |
683 |
struct auth_data auth_data; |
struct auth_data auth_data; |
684 |
int true; |
int true; |
685 |
char c; |
char c; |
686 |
int authenticated; |
int authenticated; |
687 |
pid_t pid; |
pid_t pid; |
688 |
int master; |
int master; |
689 |
|
|
690 |
memset (&auth_data, 0, sizeof auth_data); |
memset (&auth_data, 0, sizeof auth_data); |
691 |
size = sizeof auth_data.from; |
size = sizeof auth_data.from; |
695 |
fatal (outfd, "Can't get peer name of remote host", 1); |
fatal (outfd, "Can't get peer name of remote host", 1); |
696 |
} |
} |
697 |
|
|
698 |
syslog (LOG_INFO, "Connect from %s:%d", |
syslog (LOG_INFO, "Connect from %s:%d", |
699 |
inet_ntoa(auth_data.from.sin_addr), ntohs(auth_data.from.sin_port)); |
inet_ntoa (auth_data.from.sin_addr), |
700 |
|
ntohs (auth_data.from.sin_port)); |
701 |
|
|
702 |
true = 1; |
true = 1; |
703 |
if (keepalive |
if (keepalive |
704 |
&& setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0) |
&& setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0) |
705 |
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); |
syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); |
706 |
|
|
707 |
#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY) |
#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY) |
708 |
true = IPTOS_LOWDELAY; |
true = IPTOS_LOWDELAY; |
710 |
syslog (LOG_WARNING, "setsockopt (IP_TOS): %m"); |
syslog (LOG_WARNING, "setsockopt (IP_TOS): %m"); |
711 |
#endif |
#endif |
712 |
|
|
713 |
alarm (60); /* Wait at most 60 seconds. FIXME: configurable? */ |
alarm (60); /* Wait at most 60 seconds. FIXME: configurable? */ |
714 |
|
|
715 |
/* Read the null byte */ |
/* Read the null byte */ |
716 |
if (read (infd, &c, 1) != 1 || c != 0) |
if (read (infd, &c, 1) != 1 || c != 0) |
757 |
IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true)); |
IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true)); |
758 |
ioctl (master, FIONBIO, &true); |
ioctl (master, FIONBIO, &true); |
759 |
ioctl (master, TIOCPKT, &true); |
ioctl (master, TIOCPKT, &true); |
760 |
netf = infd; /* Needed for cleanup() */ |
netf = infd; /* Needed for cleanup() */ |
761 |
signal (SIGCHLD, cleanup); |
signal (SIGCHLD, cleanup); |
762 |
protocol (infd, master); |
protocol (infd, master, &auth_data); |
763 |
signal (SIGCHLD, SIG_IGN); |
signal (SIGCHLD, SIG_IGN); |
764 |
cleanup (0); |
cleanup (0); |
765 |
|
|
766 |
|
#ifdef SHISHI |
767 |
|
if (kerberos) |
768 |
|
{ |
769 |
|
int i; |
770 |
|
|
771 |
|
shishi_done (auth_data.h); |
772 |
|
#ifdef ENCRYPTION |
773 |
|
if (encrypt_io) |
774 |
|
{ |
775 |
|
shishi_key_done (auth_data.enckey); |
776 |
|
for (i = 0; i < 2; i++) |
777 |
|
{ |
778 |
|
shishi_crypto_close (auth_data.ivtab[i]->ctx); |
779 |
|
free (auth_data.ivtab[i]->iv); |
780 |
|
} |
781 |
|
} |
782 |
|
#endif |
783 |
|
} |
784 |
|
#endif |
785 |
|
|
786 |
return 0; |
return 0; |
787 |
} |
} |
788 |
|
|
789 |
|
|
790 |
int |
int |
791 |
do_rlogin(int infd, struct auth_data *ap) |
do_rlogin (int infd, struct auth_data *ap) |
792 |
{ |
{ |
793 |
struct passwd *pwd; |
struct passwd *pwd; |
794 |
int rc; |
int rc; |
795 |
|
|
796 |
getstr (infd, &ap->rusername, NULL); |
getstr (infd, &ap->rusername, NULL); |
797 |
getstr (infd, &ap->lusername, NULL); |
getstr (infd, &ap->lusername, NULL); |
800 |
pwd = getpwnam (ap->lusername); |
pwd = getpwnam (ap->lusername); |
801 |
if (pwd == NULL) |
if (pwd == NULL) |
802 |
{ |
{ |
803 |
syslog(LOG_ERR, "no passwd entry for %s", ap->lusername); |
syslog (LOG_ERR, "no passwd entry for %s", ap->lusername); |
804 |
fatal(infd, "Permission denied", 0); |
fatal (infd, "Permission denied", 0); |
805 |
} |
} |
806 |
if (!allow_root && pwd->pw_uid == 0) |
if (!allow_root && pwd->pw_uid == 0) |
807 |
{ |
{ |
808 |
syslog(LOG_ERR, "root logins not permitted"); |
syslog (LOG_ERR, "root logins not permitted"); |
809 |
fatal(infd, "Permission denied", 0); |
fatal (infd, "Permission denied", 0); |
810 |
} |
} |
811 |
|
|
812 |
rc = iruserok (ap->from.sin_addr.s_addr, 0, |
rc = iruserok (ap->from.sin_addr.s_addr, 0, ap->rusername, ap->lusername); |
|
ap->rusername, ap->lusername); |
|
813 |
if (rc) |
if (rc) |
814 |
syslog(LOG_ERR, "iruserok failed: rusername=%s, lusername=%s", |
syslog (LOG_ERR, "iruserok failed: rusername=%s, lusername=%s", |
815 |
ap->rusername, ap->lusername); |
ap->rusername, ap->lusername); |
816 |
return rc; |
return rc; |
817 |
} |
} |
818 |
|
|
819 |
#ifdef KERBEROS |
#if defined(KERBEROS) || defined(SHISHI) |
820 |
int |
int |
821 |
do_krb_login (int infd, struct auth_data *ap, const char **err_msg) |
do_krb_login (int infd, struct auth_data *ap, const char **err_msg) |
822 |
{ |
{ |
823 |
int rc; |
int rc; |
824 |
|
|
825 |
err_msg = NULL; |
err_msg = NULL; |
826 |
#if defined(KRB5) |
#if defined(KRB5) |
827 |
if (kerberos == AUTH_KERBEROS_5) |
if (kerberos == AUTH_KERBEROS_5) |
828 |
rc = do_krb5_login (infd, ap, err_msg); |
rc = do_krb5_login (infd, ap, err_msg); |
829 |
else |
else |
830 |
|
#elif defined(SHISHI) |
831 |
|
if (kerberos == AUTH_KERBEROS_SHISHI) |
832 |
|
rc = do_shishi_login (infd, ap, err_msg); |
833 |
|
else |
834 |
|
#else |
835 |
|
rc = do_krb4_login (infd, ap, err_msg); |
836 |
#endif |
#endif |
837 |
rc = do_krb4_login (infd, ap, err_msg); |
|
|
|
|
838 |
if (rc && !err_msg) |
if (rc && !err_msg) |
839 |
*err_msg = kerberos_error_string (rc); |
*err_msg = kerberos_error_string (rc); |
840 |
|
|
841 |
return rc; |
return rc; |
842 |
} |
} |
843 |
|
|
844 |
|
#ifdef KRB4 |
845 |
int |
int |
846 |
do_krb4_login (int infd, struct auth_data *ap, const char **err_msg) |
do_krb4_login (int infd, struct auth_data *ap, const char **err_msg) |
847 |
{ |
{ |
848 |
int rc; |
int rc; |
849 |
char instance[INST_SZ], version[VERSION_SZ]; |
char instance[INST_SZ], version[VERSION_SZ]; |
850 |
long authopts = 0L; /* !mutual */ |
long authopts = 0L; /* !mutual */ |
851 |
struct sockaddr_in faddr; |
struct sockaddr_in faddr; |
852 |
u_char auth_buf[sizeof (AUTH_DAT)]; |
u_char auth_buf[sizeof (AUTH_DAT)]; |
853 |
u_char tick_buf[sizeof (KTEXT_ST)]; |
u_char tick_buf[sizeof (KTEXT_ST)]; |
854 |
Key_schedule schedule; |
Key_schedule schedule; |
855 |
AUTH_DAT *kdata; |
AUTH_DAT *kdata; |
856 |
KTEXT ticket; |
KTEXT ticket; |
857 |
struct passwd *pwd; |
struct passwd *pwd; |
858 |
|
|
859 |
kdata = (AUTH_DAT *) auth_buf; |
kdata = (AUTH_DAT *) auth_buf; |
860 |
ticket = (KTEXT) tick_buf; |
ticket = (KTEXT) tick_buf; |
861 |
|
|
884 |
#endif |
#endif |
885 |
rc = krb_recvauth (authopts, 0, |
rc = krb_recvauth (authopts, 0, |
886 |
ticket, "rcmd", |
ticket, "rcmd", |
887 |
instance, &ap->from, NULL, |
instance, &ap->from, NULL, kdata, "", NULL, version); |
|
kdata, "", NULL, version); |
|
888 |
|
|
889 |
if (rc != KSUCCESS) |
if (rc != KSUCCESS) |
890 |
return 1; |
return 1; |
891 |
|
|
892 |
getstr (infd, &ap->lusername, NULL); |
getstr (infd, &ap->lusername, NULL); |
893 |
/* get the "cmd" in the rcmd protocol */ |
/* get the "cmd" in the rcmd protocol */ |
894 |
getstr (infd, &ap->term, "TERM="); |
getstr (infd, &ap->term, "TERM="); |
916 |
|
|
917 |
return 0; |
return 0; |
918 |
} |
} |
919 |
|
#endif |
920 |
|
|
921 |
#ifdef KRB5 |
#ifdef KRB5 |
922 |
int |
int |
924 |
{ |
{ |
925 |
krb5_auth_context auth_ctx = NULL; |
krb5_auth_context auth_ctx = NULL; |
926 |
krb5_error_code status; |
krb5_error_code status; |
927 |
krb5_data inbuf; |
krb5_data inbuf; |
928 |
krb5_data version; |
krb5_data version; |
929 |
krb5_authenticator *authenticator; |
krb5_authenticator *authenticator; |
930 |
krb5_rcache rcache; |
krb5_rcache rcache; |
931 |
krb5_keyblock *key; |
krb5_keyblock *key; |
932 |
krb5_ticket *ticket; |
krb5_ticket *ticket; |
933 |
struct sockaddr_in laddr; |
struct sockaddr_in laddr; |
934 |
int len; |
int len; |
935 |
struct passwd *pwd; |
struct passwd *pwd; |
936 |
char *name; |
char *name; |
937 |
|
|
938 |
if (status = krb5_init_context (&ap->context)) |
if (status = krb5_init_context (&ap->context)) |
939 |
{ |
{ |
940 |
syslog (LOG_ERR, "Error initializing krb5: %s", |
syslog (LOG_ERR, "Error initializing krb5: %s", error_message (status)); |
|
error_message (status)); |
|
941 |
return status; |
return status; |
942 |
} |
} |
943 |
|
|
944 |
if ((status = krb5_auth_con_init (ap->context, &auth_ctx)) |
if ((status = krb5_auth_con_init (ap->context, &auth_ctx)) |
945 |
|| (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd, |
|| (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd, |
946 |
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) |
KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) |
947 |
|| (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache))) |
|| (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache))) |
948 |
return status; |
return status; |
949 |
|
|
950 |
if (!rcache) |
if (!rcache) |
951 |
{ |
{ |
952 |
krb5_principal server; |
krb5_principal server; |
953 |
|
|
954 |
status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST, |
status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST, |
955 |
&server); |
&server); |
956 |
if (status) |
if (status) |
957 |
return status; |
return status; |
958 |
|
|
959 |
status = krb5_get_server_rcache (ap->context, |
status = krb5_get_server_rcache (ap->context, |
960 |
krb5_princ_component (ap->context, server, 0), |
krb5_princ_component (ap->context, |
961 |
&rcache); |
server, 0), |
962 |
krb5_free_principal(ap->context, server); |
&rcache); |
963 |
|
krb5_free_principal (ap->context, server); |
964 |
|
|
965 |
if (status) |
if (status) |
966 |
return status; |
return status; |
967 |
|
|
968 |
status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache); |
status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache); |
969 |
if (status) |
if (status) |
970 |
return status; |
return status; |
971 |
} |
} |
972 |
|
|
973 |
len = sizeof (laddr); |
len = sizeof (laddr); |
974 |
if (getsockname (infd, (struct sockaddr *)&laddr, &len)) |
if (getsockname (infd, (struct sockaddr *) &laddr, &len)) |
975 |
return errno; |
return errno; |
976 |
|
|
977 |
status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0, |
status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0, |
982 |
if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx, |
if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx, |
983 |
&authenticator))) |
&authenticator))) |
984 |
return status; |
return status; |
985 |
|
|
986 |
getstr (infd, &ap->lusername, NULL); |
getstr (infd, &ap->lusername, NULL); |
987 |
getstr (infd, &ap->term, "TERM="); |
getstr (infd, &ap->term, "TERM="); |
988 |
|
|
989 |
pwd = getpwnam (ap->lusername); |
pwd = getpwnam (ap->lusername); |
990 |
if (pwd == NULL) |
if (pwd == NULL) |
991 |
{ |
{ |
993 |
syslog (LOG_ERR, "getpwnam failed: %m"); |
syslog (LOG_ERR, "getpwnam failed: %m"); |
994 |
return 1; |
return 1; |
995 |
} |
} |
996 |
|
|
997 |
getstr (infd, &ap->rusername, NULL); |
getstr (infd, &ap->rusername, NULL); |
998 |
|
|
999 |
if ((status = krb5_copy_principal(ap->context, |
if ((status = krb5_copy_principal (ap->context, |
1000 |
ticket->enc_part2->client, |
ticket->enc_part2->client, &ap->client))) |
|
&ap->client))) |
|
1001 |
return status; |
return status; |
1002 |
|
|
1003 |
/*OK::*/ |
/*OK:: */ |
1004 |
if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername)) |
if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername)) |
1005 |
return 1; |
return 1; |
1006 |
|
|
1007 |
krb5_unparse_name (ap->context, ap->client, &name); |
krb5_unparse_name (ap->context, ap->client, &name); |
1008 |
|
|
1009 |
syslog (LOG_INFO | LOG_AUTH, |
syslog (LOG_INFO | LOG_AUTH, |
1010 |
"%sKerberos V login from %s on %s\n", |
"%sKerberos V login from %s on %s\n", |
1011 |
(pwd->pw_uid == 0) ? "ROOT " : "", |
(pwd->pw_uid == 0) ? "ROOT " : "", name, ap->hostname); |
|
name, ap->hostname); |
|
1012 |
free (name); |
free (name); |
1013 |
|
|
1014 |
return 0; |
return 0; |
1015 |
} |
} |
1016 |
|
|
1017 |
#endif |
#endif |
1018 |
|
|
1019 |
|
#ifdef SHISHI |
1020 |
|
int |
1021 |
|
do_shishi_login (int infd, struct auth_data *ad, const char **err_msg) |
1022 |
|
{ |
1023 |
|
int rc; |
1024 |
|
int error = 0; |
1025 |
|
int keylen, keytype; |
1026 |
|
struct passwd *pwd = NULL; |
1027 |
|
int cksumtype, cksumlen = 30; |
1028 |
|
char *cksum; |
1029 |
|
char *compcksum; |
1030 |
|
size_t compcksumlen; |
1031 |
|
char cksumdata[100]; |
1032 |
|
struct sockaddr_in sock; |
1033 |
|
size_t socklen = sizeof (struct sockaddr_in); |
1034 |
|
|
1035 |
|
#ifdef ENCRYPTION |
1036 |
|
rc = get_auth (infd, &ad->h, &ad->ap, &ad->enckey, err_msg, &ad->protocol, |
1037 |
|
&cksumtype, &cksum, &cksumlen); |
1038 |
|
#else |
1039 |
|
rc = get_auth (infd, &ad->h, &ad->ap, NULL, err_msg, &ad->protocol, |
1040 |
|
&cksumtype, &cksum, &cksumlen); |
1041 |
|
#endif |
1042 |
|
if (rc != SHISHI_OK) |
1043 |
|
return rc; |
1044 |
|
|
1045 |
|
#ifdef ENCRYPTION |
1046 |
|
/* init IV */ |
1047 |
|
if (encrypt_io) |
1048 |
|
{ |
1049 |
|
int i; |
1050 |
|
char *iv; |
1051 |
|
|
1052 |
|
ad->ivtab[0] = &ad->iv1; |
1053 |
|
ad->ivtab[1] = &ad->iv2; |
1054 |
|
|
1055 |
|
keytype = shishi_key_type (ad->enckey); |
1056 |
|
keylen = shishi_cipher_blocksize (keytype); |
1057 |
|
|
1058 |
|
for (i = 0; i < 2; i++) |
1059 |
|
{ |
1060 |
|
ad->ivtab[i]->ivlen = keylen; |
1061 |
|
|
1062 |
|
switch (keytype) |
1063 |
|
{ |
1064 |
|
case SHISHI_DES_CBC_CRC: |
1065 |
|
case SHISHI_DES_CBC_MD4: |
1066 |
|
case SHISHI_DES_CBC_MD5: |
1067 |
|
case SHISHI_DES_CBC_NONE: |
1068 |
|
case SHISHI_DES3_CBC_HMAC_SHA1_KD: |
1069 |
|
ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES; |
1070 |
|
ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen); |
1071 |
|
memset (ad->ivtab[i]->iv, i, ad->ivtab[i]->ivlen); |
1072 |
|
ad->ivtab[i]->ctx = |
1073 |
|
shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, |
1074 |
|
shishi_key_type (ad->enckey), ad->ivtab[i]->iv, |
1075 |
|
ad->ivtab[i]->ivlen); |
1076 |
|
break; |
1077 |
|
case SHISHI_ARCFOUR_HMAC: |
1078 |
|
case SHISHI_ARCFOUR_HMAC_EXP: |
1079 |
|
ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i; |
1080 |
|
ad->ivtab[i]->ctx = |
1081 |
|
shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, |
1082 |
|
shishi_key_type (ad->enckey), NULL, 0); |
1083 |
|
break; |
1084 |
|
default: |
1085 |
|
ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i; |
1086 |
|
ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen); |
1087 |
|
memset (ad->ivtab[i]->iv, 0, ad->ivtab[i]->ivlen); |
1088 |
|
if (ad->protocol == 2) |
1089 |
|
ad->ivtab[i]->ctx = |
1090 |
|
shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage, |
1091 |
|
shishi_key_type (ad->enckey), |
1092 |
|
ad->ivtab[i]->iv, ad->ivtab[i]->ivlen); |
1093 |
|
} |
1094 |
|
} |
1095 |
|
} |
1096 |
|
#endif |
1097 |
|
|
1098 |
|
getstr (infd, &ad->lusername, NULL); |
1099 |
|
getstr (infd, &ad->term, "TERM="); |
1100 |
|
getstr (infd, &ad->rusername, NULL); |
1101 |
|
|
1102 |
|
rc = read (infd, &error, sizeof (int)); |
1103 |
|
if ((rc != sizeof (int)) && rc) |
1104 |
|
{ |
1105 |
|
free (pwd); |
1106 |
|
free (cksum); |
1107 |
|
return 1; |
1108 |
|
} |
1109 |
|
|
1110 |
|
/* |
1111 |
|
getpwnam crash !!!! |
1112 |
|
|
1113 |
|
pwd = getpwnam (ad->lusername); |
1114 |
|
if (pwd == NULL) |
1115 |
|
{ |
1116 |
|
*err_msg = "getpwnam failed"; |
1117 |
|
syslog (LOG_ERR, "getpwnam failed: %m"); |
1118 |
|
return 1; |
1119 |
|
} |
1120 |
|
|
1121 |
|
syslog (LOG_INFO | LOG_AUTH, |
1122 |
|
"%sKerberos V login from %s on %s\n", |
1123 |
|
(pwd->pw_uid == 0) ? "ROOT " : "", |
1124 |
|
ad->lusername, ad->hostname); |
1125 |
|
|
1126 |
|
*/ |
1127 |
|
|
1128 |
|
free (pwd); |
1129 |
|
|
1130 |
|
syslog (LOG_INFO | LOG_AUTH, |
1131 |
|
"Kerberos V login from %s on %s\n", ad->lusername, ad->hostname); |
1132 |
|
|
1133 |
|
/* verify checksum */ |
1134 |
|
|
1135 |
|
if (getsockname (infd, (struct sockaddr *) &sock, &socklen) < 0) |
1136 |
|
{ |
1137 |
|
syslog (LOG_ERR, "Can't get sock name"); |
1138 |
|
fatal (infd, "Can't get sockname", 1); |
1139 |
|
} |
1140 |
|
|
1141 |
|
snprintf (cksumdata, 100, "%u:%s%s", ntohs (sock.sin_port), ad->term + 5, |
1142 |
|
ad->lusername); |
1143 |
|
rc = shishi_checksum (ad->h, ad->enckey, 0, cksumtype, cksumdata, |
1144 |
|
strlen (cksumdata), &compcksum, &compcksumlen); |
1145 |
|
free (cksum); |
1146 |
|
if (rc != SHISHI_OK |
1147 |
|
|| compcksumlen != cksumlen |
1148 |
|
|| memcmp (compcksum, cksum, cksumlen) != 0) |
1149 |
|
{ |
1150 |
|
/* err_msg crash ? */ |
1151 |
|
/* *err_msg = "checksum verify failed"; */ |
1152 |
|
syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (ad->h)); |
1153 |
|
free (compcksum); |
1154 |
|
return 1; |
1155 |
|
} |
1156 |
|
|
1157 |
|
free (compcksum); |
1158 |
|
|
1159 |
|
rc = shishi_authorized_p (ad->h, shishi_ap_tkt (ad->ap), ad->lusername); |
1160 |
|
if (!rc) |
1161 |
|
{ |
1162 |
|
syslog (LOG_ERR, "User is not authorized to log in as: %s", |
1163 |
|
ad->lusername); |
1164 |
|
shishi_ap_done (ad->ap); |
1165 |
|
return 1; |
1166 |
|
} |
1167 |
|
|
1168 |
|
shishi_ap_done (ad->ap); |
1169 |
|
|
1170 |
|
return SHISHI_OK; |
1171 |
|
} |
1172 |
|
#endif |
1173 |
#endif |
#endif |
1174 |
|
|
1175 |
#define BUFFER_SIZE 128 |
#define BUFFER_SIZE 128 |
1176 |
|
|
1177 |
void |
void |
1178 |
getstr(int infd, char **ptr, const char *prefix) |
getstr (int infd, char **ptr, const char *prefix) |
1179 |
{ |
{ |
1180 |
char c; |
char c; |
1181 |
char *buf; |
char *buf; |
1182 |
int pos; |
int pos; |
1183 |
int size = BUFFER_SIZE; |
int size = BUFFER_SIZE; |
1184 |
|
|
1185 |
if (prefix) |
if (prefix) |
1186 |
{ |
{ |
1187 |
int len = strlen(prefix); |
int len = strlen (prefix); |
1188 |
|
|
1189 |
if (size < len + 1) |
if (size < len + 1) |
1190 |
size = len + 1; |
size = len + 1; |
1191 |
} |
} |
1229 |
|
|
1230 |
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) |
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) |
1231 |
|
|
1232 |
char magic[2] = {0377, 0377}; |
char magic[2] = { 0377, 0377 }; |
1233 |
char oobdata[] = {TIOCPKT_WINDOW}; /* May be modified by protocol/control */ |
char oobdata[] = { TIOCPKT_WINDOW }; /* May be modified by protocol/control */ |
1234 |
|
|
1235 |
|
#ifdef SHISHI |
1236 |
|
char oobdata_new[] = { 0377, 0377, 'o', 'o', TIOCPKT_WINDOW }; |
1237 |
|
#endif |
1238 |
|
|
1239 |
void |
void |
1240 |
protocol (int f, int p) |
protocol (int f, int p, struct auth_data *ap) |
1241 |
{ |
{ |
1242 |
char fibuf[1024], *pbp = NULL, *fbp = NULL; |
char fibuf[1024], *pbp = NULL, *fbp = NULL; |
1243 |
int pcc = 0, fcc = 0; |
int pcc = 0, fcc = 0; |
1244 |
int cc, nfd, n; |
int cc, nfd, n; |
1245 |
char cntl; |
char cntl; |
1246 |
|
|
1247 |
#ifdef TIOCPKT |
#ifdef TIOCPKT |
1248 |
int tiocpkt_on = 0; |
int tiocpkt_on = 0; |
1249 |
#endif |
#endif |
1250 |
|
|
1251 |
/* |
/* |
1254 |
* (our controlling tty is the master pty). |
* (our controlling tty is the master pty). |
1255 |
*/ |
*/ |
1256 |
signal (SIGTTOU, SIG_IGN); |
signal (SIGTTOU, SIG_IGN); |
1257 |
send (f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ |
#ifdef SHISHI |
1258 |
|
if (kerberos && (ap->protocol == 2)) |
1259 |
|
{ |
1260 |
|
ENC_WRITE (n, f, oobdata_new, 5, ap); |
1261 |
|
} |
1262 |
|
else |
1263 |
|
#endif |
1264 |
|
send (f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ |
1265 |
if (f > p) |
if (f > p) |
1266 |
nfd = f + 1; |
nfd = f + 1; |
1267 |
else |
else |
1274 |
|
|
1275 |
while (1) |
while (1) |
1276 |
{ |
{ |
1277 |
fd_set ibits, obits, ebits, *omask; |
fd_set ibits, obits, ebits, *omask; |
1278 |
|
|
1279 |
FD_ZERO (&ebits); |
FD_ZERO (&ebits); |
1280 |
FD_ZERO (&ibits); |
FD_ZERO (&ibits); |
1332 |
|
|
1333 |
if (FD_ISSET (f, &ibits)) |
if (FD_ISSET (f, &ibits)) |
1334 |
{ |
{ |
1335 |
ENC_READ (fcc, f, fibuf, sizeof (fibuf)); |
ENC_READ (fcc, f, fibuf, sizeof (fibuf), ap); |
1336 |
|
|
1337 |
if (fcc < 0 && errno == EWOULDBLOCK) |
if (fcc < 0 && errno == EWOULDBLOCK) |
1338 |
fcc = 0; |
fcc = 0; |
1339 |
else |
else |
1340 |
{ |
{ |
1341 |
register char *cp; |
register char *cp; |
1342 |
int left; |
int left; |
1343 |
|
|
1344 |
if (fcc <= 0) |
if (fcc <= 0) |
1345 |
break; |
break; |
1348 |
for (cp = fibuf; cp < fibuf + fcc - 1; cp++) |
for (cp = fibuf; cp < fibuf + fcc - 1; cp++) |
1349 |
if (cp[0] == magic[0] && cp[1] == magic[1]) |
if (cp[0] == magic[0] && cp[1] == magic[1]) |
1350 |
{ |
{ |
1351 |
int len; |
int len; |
1352 |
|
|
1353 |
left = fcc - (cp - fibuf); |
left = fcc - (cp - fibuf); |
1354 |
len = control (p, cp, left); |
len = control (p, cp, left); |
1355 |
if (len) |
if (len) |
1377 |
|
|
1378 |
if (FD_ISSET (p, &ibits)) |
if (FD_ISSET (p, &ibits)) |
1379 |
{ |
{ |
1380 |
char dbuf[1024 + 1]; |
char dbuf[1024 + 1]; |
1381 |
|
|
1382 |
pcc = read (p, dbuf, sizeof dbuf); |
pcc = read (p, dbuf, sizeof dbuf); |
1383 |
|
|
1412 |
|
|
1413 |
if ((FD_ISSET (f, &obits)) && pcc > 0) |
if ((FD_ISSET (f, &obits)) && pcc > 0) |
1414 |
{ |
{ |
1415 |
ENC_WRITE (cc, f, pbp, pcc); |
ENC_WRITE (cc, f, pbp, pcc, ap); |
1416 |
|
|
1417 |
if (cc < 0 && errno == EWOULDBLOCK) |
if (cc < 0 && errno == EWOULDBLOCK) |
1418 |
{ |
{ |
1440 |
int |
int |
1441 |
control (int pty, char *cp, size_t n) |
control (int pty, char *cp, size_t n) |
1442 |
{ |
{ |
1443 |
struct winsize w; |
struct winsize w; |
1444 |
|
|
1445 |
if (n < 4 + sizeof (w) || cp[2] != 's' || cp[3] != 's') |
if (n < 4 + sizeof (w) || cp[2] != 's' || cp[3] != 's') |
1446 |
return (0); |
return (0); |
1457 |
RETSIGTYPE |
RETSIGTYPE |
1458 |
cleanup (int signo) |
cleanup (int signo) |
1459 |
{ |
{ |
1460 |
char *p; |
char *p; |
1461 |
(void)signo; |
|
1462 |
|
signo; |
1463 |
|
|
1464 |
p = line + sizeof (PATH_DEV) - 1; |
p = line + sizeof (PATH_DEV) - 1; |
1465 |
#ifdef UTMPX |
#ifdef UTMPX |
1482 |
int |
int |
1483 |
in_local_domain (char *hostname) |
in_local_domain (char *hostname) |
1484 |
{ |
{ |
1485 |
char *p = topdomain (hostname, local_dot_count); |
char *p = topdomain (hostname, local_dot_count); |
1486 |
|
|
1487 |
return p && strcasecmp (p, local_domain_name) == 0; |
return p && strcasecmp (p, local_domain_name) == 0; |
1488 |
} |
} |
1489 |
|
|
1490 |
char * |
char * |
1491 |
topdomain (char *name, int max_dots) |
topdomain (char *name, int max_dots) |
1492 |
{ |
{ |
1493 |
char *p; |
char *p; |
1494 |
int dot_count = 0; |
int dot_count = 0; |
1495 |
|
|
1496 |
for (p = name + strlen (name) - 1; p >= name; p--) |
for (p = name + strlen (name) - 1; p >= name; p--) |
1497 |
{ |
{ |
1504 |
void |
void |
1505 |
fatal (int f, const char *msg, int syserr) |
fatal (int f, const char *msg, int syserr) |
1506 |
{ |
{ |
1507 |
int len; |
int len; |
1508 |
char buf[BUFSIZ], *bp = buf; |
char buf[BUFSIZ], *bp = buf; |
1509 |
|
|
1510 |
/* |
/* |
1511 |
* Prepend binary one to message if we haven't sent |
* Prepend binary one to message if we haven't sent |
1524 |
} |
} |
1525 |
|
|
1526 |
static const char usage_str[] = |
static const char usage_str[] = |
1527 |
"usage: rlogind [options]\n" |
"usage: rlogind [options]\n" |
1528 |
"\n" |
"\n" |
1529 |
"Options are:\n" |
"Options are:\n" |
1530 |
" -a, --verify-hostname Ask hostname for verification\n" |
" -a, --verify-hostname Ask hostname for verification\n" |
1531 |
" -d, --daemon Daemon mode\n" |
" -d, --daemon Daemon mode\n" |
1532 |
" -l, --no-rhosts Ignore .rhosts file\n" |
" -l, --no-rhosts Ignore .rhosts file\n" |
1533 |
" -L, --local-domain=NAME Set local domain name\n" |
" -L, --local-domain=NAME Set local domain name\n" |
1534 |
" -n, --no-keepalive Do not set SO_KEEPALIVE\n" |
" -n, --no-keepalive Do not set SO_KEEPALIVE\n" |
1535 |
#ifdef KERBEROS |
#if defined(KERBEROS) || defined(SHISHI) |
1536 |
" -k, --kerberos Use kerberos IV authentication\n" |
" -k, --kerberos Use kerberos IV/V authentication\n" |
1537 |
#ifdef ENCRYPTION |
#ifdef ENCRYPTION |
1538 |
" -x, --encrypt Use DES encryption\n" |
" -x, --encrypt Use DES encryption\n" |
1539 |
#endif /* ENCRYPTION */ |
#endif /* ENCRYPTION */ |
1540 |
#endif /* KERBEROS */ |
#endif /* KERBEROS */ |
1541 |
" -D, --debug[=LEVEL] Set debug level\n" |
" -D, --debug[=LEVEL] Set debug level\n" |
1542 |
" -h, --help Display usage instructions\n" |
" -h, --help Display usage instructions\n" |
1543 |
" -V, --version Display program version\n" |
" -V, --version Display program version\n" |
1544 |
" -o, --allow-root Allow uid == 0 to login, disable by default\n" |
" -o, --allow-root Allow uid == 0 to login, disable by default\n" |
1545 |
" -p, --port PORT Listen on given port (valid only in daemon mode)\n" |
" -p, --port PORT Listen on given port (valid only in daemon mode)\n" |
1546 |
" -r, --reverse-required Require reverse resolving of a remote host IP\n"; |
" -r, --reverse-required Require reverse resolving of a remote host IP\n"; |
1547 |
|
|
1548 |
void |
void |
1549 |
usage() |
usage () |
1550 |
{ |
{ |
1551 |
printf ("%s\n" |
printf ("%s\n" "Send bug reports to %s\n", usage_str, PACKAGE_BUGREPORT); |
|
"Send bug reports to %s\n", |
|
|
usage_str, PACKAGE_BUGREPORT); |
|
1552 |
} |
} |
1553 |
|
|
1554 |
int volatile _st; |
int volatile _st; |
1555 |
stop() |
|
1556 |
|
stop () |
1557 |
{ |
{ |
1558 |
for (_st=0; !_st;) |
for (_st = 0; !_st;) |
1559 |
_st=_st; |
_st = _st; |
1560 |
} |
} |