6 * Copyright (c) 1983 The Regents of the University of California.
9 * Redistribution and use in source and binary forms are permitted
10 * provided that the above copyright notice and this paragraph are
11 * duplicated in all such forms and that any documentation,
12 * advertising materials, and other materials related to such
13 * distribution and use acknowledge that the software was developed
14 * by the University of California, Berkeley. The name of the
15 * University may not be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
25 All rights reserved.\n";
28 /* based on @(#)rlogind.c 5.17 (Berkeley) 8/31/88 */
31 * remote login server:
39 * This is the rlogin daemon. The very basic protocol for checking
40 * authentication and authorization is:
41 * 1) Check authentication.
42 * 2) Check authorization via the access-control files:
43 * ~/.k5login (using krb5_kuserok) and/or
44 * 3) Prompt for password if any checks fail, or if so configured.
45 * Allow login if all goes well either by calling the accompanying
46 * login.krb5 or /bin/login, according to the definition of
47 * DO_NOT_USE_K_LOGIN.l
49 * The configuration is done either by command-line arguments passed by
50 * inetd, or by the name of the daemon. If command-line arguments are
51 * present, they take priority. The options are:
52 * -k means trust krb4 or krb5
55 * -p and -P means prompt for password.
56 * If the -P option is passed, then the password is verified in
57 * addition to all other checks. If -p is not passed with -k or -r,
58 * and both checks fail, then login permission is denied.
59 * - -e means use encryption.
61 * If no command-line arguments are present, then the presence of the
62 * letters kKrRexpP in the program-name before "logind" determine the
63 * behaviour of the program exactly as with the command-line arguments.
65 * If the ruserok check is to be used, then the client should connect
66 * from a privileged port, else deny permission.
70 * KERBEROS - Define this if application is to be kerberised.
71 * CRYPT - Define this if encryption is to be an option.
72 * DO_NOT_USE_K_LOGIN - Define this if you want to use /bin/login
73 * instead of the accompanying login.krb5.
74 * KRB5_KRB4_COMPAT - Define this if v4 rlogin clients are also to be served.
75 * ALWAYS_V5_KUSEROK - Define this if you want .k5login to be
76 * checked even for v4 clients (instead of .klogin).
77 * LOG_ALL_LOGINS - Define this if you want to log all logins.
78 * LOG_OTHER_USERS - Define this if you want to log all principals
79 * that do not map onto the local user.
80 * LOG_REMOTE_REALM - Define this if you want to log all principals from
82 * Note: Root logins are always logged.
86 * This is usually done in the Makefile. Actually, these sources may
87 * not work without the KERBEROS #defined.
91 #define LOG_REMOTE_REALM
99 #include <sys/unistd.h>
106 #include <sys/types.h>
107 #include <sys/stat.h>
109 /* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
110 #include <sys/socket.h>
112 #include <sys/ioctl.h>
113 #include <sys/wait.h>
114 #include <sys/file.h>
115 #include <sys/time.h>
118 #include <netinet/in.h>
122 #ifdef HAVE_SYS_LABEL_H
124 #include <sys/label.h>
125 #include <sys/audit.h>
131 #if defined(hpux) || defined(__hpux)
132 #include <sys/ptyio.h>
138 #ifdef HAVE_SYS_SELECT_H
139 #include <sys/select.h>
143 #include <sys/stream.h>
144 #include <sys/stropts.h>
147 #if defined(POSIX_TERMIOS) && !defined(ultrix)
154 /* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
159 #include <sys/param.h>
162 /* krlogin doesn't test sys/tty... */
163 #ifdef HAVE_SYS_TTY_H
167 #ifdef HAVE_SYS_PTYVAR_H
168 /* Solaris actually uses packet mode, so the real macros are needed too */
169 #include <sys/ptyvar.h>
174 #ifndef TIOCPKT_NOSTOP
175 /* These values are over-the-wire protocol, *not* local values */
176 #define TIOCPKT_NOSTOP 0x10
177 #define TIOCPKT_DOSTOP 0x20
178 #define TIOCPKT_FLUSHWRITE 0x02
181 #ifdef HAVE_SYS_FILIO_H
182 /* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
183 #include <sys/filio.h>
187 #define killpg(pid, sig) kill(-(pid), (sig))
191 /* HP/UX 9.04 has but does not declare ptsname. */
192 extern char *ptsname ();
197 unsigned short ws_row, ws_col;
198 unsigned short ws_xpixel, ws_ypixel;
200 #endif /* NO_WINSIZE */
203 #define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
209 #include <kerberosIV/krb.h>
215 int auth_sys = 0; /* Which version of Kerberos used to authenticate */
217 #define KRB5_RECVAUTH_V4 4
218 #define KRB5_RECVAUTH_V5 5
220 int non_privileged = 0; /* set when connection is seen to be from */
221 /* a non-privileged port */
224 Key_schedule v4_schedule;
225 int v4_des_read(), v4_des_write();
227 #define RLOGIND_BUFSIZ 5120
229 int v5_des_read(), v5_des_write();
233 #define SECURE_MESSAGE "This rlogin session is using DES encryption for all data transmissions.\r\n"
235 * Note that the encrypted rlogin packets take the form of a four-byte
236 *length followed by encrypted data. On writing the data out, a significant
237 * performance penalty is suffered (at least one RTT per character, two if we
238 * are waiting for a shell to echo) by writing the data separately from the
239 * length. So, unlike the input buffer, which just contains the output
240 * data, the output buffer represents the entire packet.
242 int (*des_read)(), (*des_write)();
243 char des_inbuf[2*RLOGIND_BUFSIZ]; /* needs to be > largest read size */
244 char des_outpkt[2*RLOGIND_BUFSIZ+4];/* needs to be > largest write size */
245 krb5_data desinbuf,desoutbuf;
246 krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
248 krb5_authenticator *kdata;
249 krb5_ticket *ticket = 0;
250 krb5_context bsd_context;
251 krb5_ccache ccache = NULL;
253 krb5_keytab keytab = NULL;
255 #define ARGSTR "k54ciepPD:S:M:L:f?"
256 #else /* !KERBEROS */
257 #define ARGSTR "rpPD:f?"
258 #define (*des_read) read
259 #define (*des_write) write
260 #endif /* KERBEROS */
262 #ifndef LOGIN_PROGRAM
263 #ifdef DO_NOT_USE_K_LOGIN
265 #define LOGIN_PROGRAM "/bin/remlogin"
267 #define LOGIN_PROGRAM "/bin/login"
269 #else /* DO_NOT_USE_K_LOGIN */
270 #define LOGIN_PROGRAM KRB5_PATH_LOGIN
271 #endif /* DO_NOT_USE_K_LOGIN */
272 #endif /* LOGIN_PROGRAM */
274 char *login_program = LOGIN_PROGRAM;
277 #define MAX_PROG_NAME 16
279 #ifndef UT_NAMESIZE /* linux defines it directly in <utmp.h> */
280 #define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
283 char lusername[UT_NAMESIZE+1];
284 char rusername[UT_NAMESIZE+1];
285 char *krusername = 0;
287 char rhost_name[128];
288 krb5_principal client;
295 #if (defined(_AIX) && defined(i386)) || defined(ibm032) || (defined(vax) && !defined(ultrix)) || (defined(SunOS) && SunOS > 40) || defined(solaris20)
300 #define VHANG_LAST /* vhangup must occur on close, not open */
303 void fatal(), fatalperror(), doit(), usage(), do_krb_login(), getstr();
305 int princ_maps_to_lname(), default_realm();
306 krb5_sigtype cleanup();
307 krb5_error_code recvauth();
309 /* There are two authentication related masks:
310 * auth_ok and auth_sent.
311 * The auth_ok mask is the oring of authentication systems any one
312 * of which can be used.
313 * The auth_sent mask is the oring of one or more authentication/authorization
314 * systems that succeeded. If the anding
315 * of these two masks is true, then authorization is successful.
317 #define AUTH_KRB4 (0x1)
318 #define AUTH_KRB5 (0x2)
319 int auth_ok = 0, auth_sent = 0;
320 int do_encrypt = 0, passwd_if_fail = 0, passwd_req = 0;
321 int checksum_required = 0, checksum_ignored = 0;
327 extern int opterr, optind;
328 extern char * optarg;
329 int on = 1, fromlen, ch, i;
330 struct sockaddr_in from;
336 krb5_error_code status;
347 #ifndef LOG_AUTH /* 4.2 syslog */
348 openlog(progname, LOG_PID | LOG_NDELAY);
350 openlog(progname, LOG_PID | LOG_NDELAY, LOG_AUTH);
351 #endif /* 4.2 syslog */
354 status = krb5_init_context(&bsd_context);
356 syslog(LOG_ERR, "Error initializing krb5: %s",
357 error_message(status));
362 /* Analyse parameters. */
364 while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
368 #ifdef KRB5_KRB4_COMPAT
369 auth_ok |= (AUTH_KRB5|AUTH_KRB4);
371 auth_ok |= AUTH_KRB5;
372 #endif /* KRB5_KRB4_COMPAT*/
376 auth_ok |= AUTH_KRB5;
379 checksum_required = 1;
382 checksum_ignored = 1;
385 #ifdef KRB5_KRB4_COMPAT
387 auth_ok |= AUTH_KRB4;
391 case 'x': /* Use encryption. */
399 if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
400 com_err(progname, status, "while resolving srvtab file %s",
406 krb5_set_default_realm(bsd_context, optarg);
410 passwd_if_fail = 1; /* Passwd reqd if any check fails */
412 case 'P': /* passwd is a must */
416 debug_port = atoi(optarg);
419 login_program = optarg;
433 fromlen = sizeof (from);
435 if (debug_port || do_fork) {
438 struct sockaddr_in sin;
442 ent = getservbyname("eklogin", "tcp");
446 debug_port = ent->s_port;
448 ent = getservbyname("klogin", "tcp");
452 debug_port = ent->s_port;
455 if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
456 fprintf(stderr, "Error in socket: %s\n", strerror(errno));
459 memset((char *) &sin, 0,sizeof(sin));
460 sin.sin_family = AF_INET;
461 sin.sin_port = htons(debug_port);
462 sin.sin_addr.s_addr = INADDR_ANY;
465 (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
466 (char *)&on, sizeof(on));
468 if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
469 fprintf(stderr, "Error in bind: %s\n", strerror(errno));
473 if ((listen(s, 5)) < 0) {
474 fprintf(stderr, "Error in listen: %s\n", strerror(errno));
480 fprintf(stderr, "daemon() failed\n");
486 fd = accept(s, (struct sockaddr *) &from, &fromlen);
489 syslog(LOG_ERR, "accept: %s", error_message(errno));
495 syslog(LOG_ERR, "fork: %s", error_message(errno));
508 if ((fd = accept(s, (struct sockaddr *) &from, &fromlen)) < 0) {
509 fprintf(stderr, "Error in accept: %s\n", strerror(errno));
514 } else { /* !do_fork && !debug_port */
515 if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
516 syslog(LOG_ERR,"Can't get peer name of remote host: %m");
518 fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
520 fatal(2, "Can't get peer name of remote host", 1);
538 char line[MAXPATHLEN];
539 extern char *inet_ntoa();
542 struct winsize win = { 0, 0, 0, 0 };
545 int pid; /* child process id */
549 struct sockaddr_in *fromp;
552 register struct hostent *hp;
562 if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE,
563 (const char *) &on, sizeof (on)) < 0)
564 syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
566 syslog(LOG_CRIT, "No authentication systems were enabled; all connections will be refused.");
567 fatal(f, "All authentication systems disabled; connection refused.");
570 if (checksum_required&&checksum_ignored) {
571 syslog( LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
572 fatal(f, "Configuration error: mutually exclusive options specified");
583 /* Initialize syncpipe */
584 if (pipe( syncpipe ) < 0 )
585 fatalperror ( f , "");
589 /* Initialize "sa" structure. */
590 (void) sigemptyset(&sa.sa_mask);
594 fromp->sin_port = ntohs((u_short)fromp->sin_port);
595 hp = gethostbyaddr((char *) &fromp->sin_addr, sizeof (struct in_addr),
599 * Only the name is used below.
601 sprintf(rhost_name,"%s",inet_ntoa(fromp->sin_addr));
604 /* Save hostent information.... */
606 strncpy(rhost_name,hp->h_name,sizeof (rhost_name));
607 rhost_name[sizeof (rhost_name) - 1] = '\0';
610 if (fromp->sin_family != AF_INET)
611 fatal(f, "Permission denied - Malformed from address\n");
615 /* setup des buffers */
616 desinbuf.data = des_inbuf;
617 desoutbuf.data = des_outpkt+4; /* Set up des buffers */
619 #else /* !KERBEROS */
620 if (fromp->sin_port >= IPPORT_RESERVED ||
621 fromp->sin_port < IPPORT_RESERVED/2)
622 fatal(f, "Permission denied - Connection from bad port");
623 #endif /* KERBEROS */
625 /* Set global netf to f now : we may need to drop everything
629 #if defined(KERBEROS)
630 /* All validation, and authorization goes through do_krb_login() */
631 do_krb_login(rhost_name);
633 getstr(f, rusername, sizeof(rusername), "remuser");
634 getstr(f, lusername, sizeof(lusername), "locuser");
635 getstr(f, term, sizeof(term), "Terminal type");
639 if ((retval = pty_getpty(&p,line, sizeof(line)))) {
640 com_err(progname, retval, "while getting master pty");
646 (void) ioctl(p, TIOCSWINSZ, &win);
650 sa.sa_handler = cleanup;
651 (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
652 (void) sigaction(SIGTERM, &sa, (struct sigaction *)0);
654 signal(SIGCHLD, cleanup);
655 signal(SIGTERM, cleanup);
661 #if defined(POSIX_TERMIOS) && !defined(ultrix)
662 struct termios new_termio;
665 #endif /* POSIX_TERMIOS */
666 if ((retval = pty_open_slave(line, &t))) {
667 fatal(f, error_message(retval));
672 #if defined(POSIX_TERMIOS) && !defined(ultrix)
673 tcgetattr(t,&new_termio);
674 #if !defined(USE_LOGIN_F)
675 new_termio.c_lflag &= ~(ICANON|ECHO|ISIG|IEXTEN);
676 new_termio.c_iflag &= ~(IXON|IXANY|BRKINT|INLCR|ICRNL);
678 new_termio.c_lflag |= (ICANON|ECHO|ISIG|IEXTEN);
679 new_termio.c_oflag |= (ONLCR|OPOST);
680 new_termio.c_iflag |= (IXON|IXANY|BRKINT|INLCR|ICRNL);
681 #endif /*Do we need binary stream?*/
682 new_termio.c_iflag &= ~(ISTRIP);
683 /* new_termio.c_iflag = 0; */
684 /* new_termio.c_oflag = 0; */
685 new_termio.c_cc[VMIN] = 1;
686 new_termio.c_cc[VTIME] = 0;
687 tcsetattr(t,TCSANOW,&new_termio);
689 (void)ioctl(t, TIOCGETP, &b);
690 b.sg_flags = RAW|ANYP;
691 (void)ioctl(t, TIOCSETP, &b);
692 #endif /* POSIX_TERMIOS */
694 pid = 0; /*reset pid incase exec fails*/
697 ** signal the parent that we have turned off echo
698 ** on the slave side of the pty ... he's waiting
699 ** because otherwise the rlogin protocol junk gets
700 ** echo'd to the user (locuser^@remuser^@term/baud)
701 ** and we don't get the right tty affiliation, and
702 ** other kinds of hell breaks loose ...
704 (void) write(syncpipe[1], &c, 1);
705 (void) close(syncpipe[1]);
706 (void) close(syncpipe[0]);
709 dup2(t, 0), dup2(t, 1), dup2(t, 2);
714 setcompat (COMPAT_CLRPGROUP | (getcompat() & ~COMPAT_BSDTTY));
717 /* Log access to account */
718 pwd = (struct passwd *) getpwnam(lusername);
719 if (pwd && (pwd->pw_uid == 0)) {
721 syslog(LOG_NOTICE, "ROOT login by %s (%s@%s) forcing password access",
722 krusername ? krusername : "", rusername, rhost_name);
724 syslog(LOG_NOTICE, "ROOT login by %s (%s@%s) ",
725 krusername ? krusername : "", rusername, rhost_name);
728 #if defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
729 /* Log if principal is from a remote realm */
730 else if (client && !default_realm(client))
731 #endif /* LOG_REMOTE_REALM */
733 #if defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
734 /* Log if principal name does not map to local username */
735 else if (client && !princ_maps_to_lname(client, lusername))
736 #endif /* LOG_OTHER_USERS */
738 #if defined(LOG_ALL_LOGINS)
740 #endif /* LOG_ALL_LOGINS */
742 #if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
746 "login by %s (%s@%s) as %s forcing password access\n",
747 krusername ? krusername : "", rusername,
748 rhost_name, lusername);
751 "login by %s (%s@%s) as %s\n",
752 krusername ? krusername : "", rusername,
753 rhost_name, lusername);
755 #endif /* LOG_REMOTE_REALM || LOG_OTHER_USERS || LOG_ALL_LOGINS */
756 #endif /* KERBEROS */
761 pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line,
762 ""/*host*/, PTY_TTYSLOT_USABLE);
767 /* use the vendors login, which has -p and -f. Tested on
768 * AIX 4.1.4 and HPUX 10
772 if ((cp = strchr(term,'/')))
774 setenv("TERM",term, 1);
778 execl(login_program, "login", "-p", "-h", rhost_name,
781 execl(login_program, "login", "-p", "-h", rhost_name,
783 #else /* USE_LOGIN_F */
784 execl(login_program, "login", "-r", rhost_name, 0);
785 #endif /* USE_LOGIN_F */
787 fatalperror(2, login_program);
789 } /* if (pid == 0) */
792 ** wait for child to start ... read one byte
793 ** -- see the child, who writes one byte after
794 ** turning off echo on the slave side ...
795 ** The master blocks here until it reads a byte.
798 (void) close(syncpipe[1]);
799 if (read(syncpipe[0], &c, 1) != 1) {
801 * Problems read failed ...
803 sprintf(buferror, "Cannot read slave pty %s ",line);
804 fatalperror(p,buferror);
809 #if defined(KERBEROS)
811 if (((*des_write)(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE))) < 0){
812 sprintf(buferror, "Cannot encrypt-write network.");
818 * if encrypting, don't turn on NBIO, else the read/write routines
819 * will fail to work properly
821 #endif /* KERBEROS */
822 ioctl(f, FIONBIO, &on);
823 ioctl(p, FIONBIO, &on);
825 /* FIONBIO doesn't always work on ptys, use fcntl to set O_NDELAY? */
826 (void) fcntl(p,F_SETFL,fcntl(p,F_GETFL,0) | O_NDELAY);
829 sa.sa_handler = SIG_IGN;
830 (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
832 signal(SIGTSTP, SIG_IGN);
836 #if !defined(USE_LOGIN_F)
837 /* Pass down rusername and lusername to login. */
838 (void) write(p, rusername, strlen(rusername) +1);
839 (void) write(p, lusername, strlen(lusername) +1);
840 /* stuff term info down to login */
841 if ((write(p, term, strlen(term)+1) != (int) strlen(term)+1)) {
843 * Problems write failed ...
845 sprintf(buferror,"Cannot write slave pty %s ",line);
846 fatalperror(f,buferror);
851 signal(SIGCHLD, SIG_IGN);
855 unsigned char magic[2] = { 0377, 0377 };
857 #ifndef TIOCPKT_WINDOW
858 #define TIOCPKT_WINDOW 0x80
860 unsigned char oobdata[] = {TIOCPKT_WINDOW};
862 char oobdata[] = {0};
866 * Handle a "control" request (signaled by magic being present)
867 * in the data stream. For now, we are only willing to handle
868 * window size changes.
870 int control(pty, cp, n)
878 if (n < (int) 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
881 oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
882 memcpy((char *)&w,cp+4, sizeof(w));
883 w.ws_row = ntohs(w.ws_row);
884 w.ws_col = ntohs(w.ws_col);
885 w.ws_xpixel = ntohs(w.ws_xpixel);
886 w.ws_ypixel = ntohs(w.ws_ypixel);
887 (void)ioctl(pty, TIOCSWINSZ, &w);
888 #ifdef HAVE_TCGETPGRP
889 pgrp = tcgetpgrp (pty);
890 got_pgrp = pgrp != -1;
892 got_pgrp = ioctl(pty, TIOCGPGRP, &pgrp) >= 0;
895 (void) killpg(pgrp, SIGWINCH);
897 return (4+sizeof (w));
903 * rlogin "protocol" machine.
908 unsigned char pibuf[1024], fibuf[1024], *pbp, *fbp;
909 register pcc = 0, fcc = 0;
916 register tiocpkt_on = 0;
920 #if defined(TIOCPKT) && !defined(__svr4__) || defined(solaris20)
921 /* if system has TIOCPKT, try to turn it on. Some drivers
922 * may not support it. Save flag for later.
924 if ( ioctl(p, TIOCPKT, &on) < 0)
930 * Must ignore SIGTTOU, otherwise we'll stop
931 * when we try and set slave pty's window shape
932 * (our controlling tty is the master pty).
935 (void) sigemptyset(&sa.sa_mask);
937 sa.sa_handler = SIG_IGN;
938 (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
940 signal(SIGTTOU, SIG_IGN);
943 send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */
946 fd_set ibits, obits, ebits;
963 if (select(8*sizeof(ibits), &ibits, &obits, &ebits, 0) < 0) {
966 fatalperror(f, "select");
968 #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
969 if (FD_ISSET(p, &ebits)) {
970 cc = read(p, &cntl, 1);
971 if (cc == 1 && pkcontrol(cntl)) {
973 send(f, &cntl, 1, MSG_OOB);
974 if (cntl & TIOCPKT_FLUSHWRITE) {
980 if (FD_ISSET(f, &ibits)) {
981 fcc = (*des_read)(f, fibuf, sizeof (fibuf));
982 if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
985 register unsigned char *cp;
993 for (cp = fibuf; cp < fibuf+fcc-1; cp++)
994 if (cp[0] == magic[0] &&
996 left = fcc - (cp-fibuf);
997 n = control(p, cp, left);
1001 memmove(cp, cp+n, left);
1009 if (FD_ISSET(p, &obits) && fcc > 0) {
1010 cc = write(p, fbp, fcc);
1017 if (FD_ISSET(p, &ibits)) {
1018 pcc = read(p, pibuf, sizeof (pibuf));
1020 if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1025 else if (tiocpkt_on) {
1029 if (pkcontrol(pibuf[0])) {
1030 pibuf[0] |= oobdata[0];
1031 send(f, &pibuf[0], 1, MSG_OOB);
1038 if (FD_ISSET(f, &obits) && pcc > 0) {
1039 cc = (*des_write)(f, pbp, pcc);
1040 if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
1041 /* also shouldn't happen */
1055 krb5_sigtype cleanup()
1057 pty_cleanup (line, pid, 1);
1060 krb5_cc_destroy(bsd_context, ccache);
1070 int out = 1 ; /* Output queue of f */
1071 #ifdef POSIX_SIGNALS
1072 struct sigaction sa;
1075 buf[0] = '\01'; /* error indicator */
1076 (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg);
1077 if ((f == netf) && (pid > 0))
1078 (void) (*des_write)(f, buf, strlen(buf));
1080 (void) write(f, buf, strlen(buf));
1081 syslog(LOG_ERR,"%s\n",msg);
1083 #ifdef POSIX_SIGNALS
1084 (void) sigemptyset(&sa.sa_mask);
1086 sa.sa_handler = SIG_IGN;
1087 (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
1089 signal(SIGCHLD,SIG_IGN);
1093 (void) ioctl(f, TIOCFLUSH, (char *)&out);
1095 (void) ioctl(f, TCFLSH, out);
1104 void fatalperror(f, msg)
1110 (void) sprintf(buf, "%s: %s", msg, error_message(errno));
1120 krb5_error_code status;
1122 char *msg_fail = NULL;
1129 /* Check authentication. This can be either Kerberos V5, */
1130 /* Kerberos V4, or host-based. */
1131 if ((status = recvauth(&valid_checksum))) {
1133 krb5_free_ticket(bsd_context, ticket);
1136 "Authentication failed from %s: %s\n",
1137 host,error_message(status));
1138 fatal(netf, "Kerberos authentication failed");
1142 /* OK we have authenticated this user - now check authorization. */
1143 /* The Kerberos authenticated programs must use krb5_kuserok or kuserok*/
1145 #ifndef KRB5_KRB4_COMPAT
1146 if (auth_sys == KRB5_RECVAUTH_V4) {
1147 fatal(netf, "This server does not support Kerberos V4");
1152 #if (defined(ALWAYS_V5_KUSEROK) || !defined(KRB5_KRB4_COMPAT))
1153 /* krb5_kuserok returns 1 if OK */
1154 if (client && krb5_kuserok(bsd_context, client, lusername))
1155 auth_sent |= ((auth_sys == KRB5_RECVAUTH_V4)?AUTH_KRB4:AUTH_KRB5);
1157 if (auth_sys == KRB5_RECVAUTH_V4) {
1158 /* kuserok returns 0 if OK */
1159 if (!kuserok(v4_kdata, lusername))
1160 auth_sent |= AUTH_KRB4;
1162 /* krb5_kuserok returns 1 if OK */
1163 if (client && krb5_kuserok(bsd_context, client, lusername))
1164 auth_sent |= AUTH_KRB5;
1170 if (checksum_required && !valid_checksum) {
1171 if (auth_sent & AUTH_KRB5) {
1172 syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
1174 fatal(netf, "You are using an old Kerberos5 without initial connection support; only newer clients are authorized.");
1177 "Configuration error: Requiring checksums with -c is inconsistent with allowing Kerberos V4 connections.");
1180 if (auth_ok&auth_sent) /* This should be bitwise.*/
1184 krb5_free_ticket(bsd_context, ticket);
1187 msg_fail = (char *)malloc(strlen(krusername) + strlen(lusername) + 80);
1189 fatal(netf, "User is not authorized to login to specified account");
1192 sprintf(msg_fail, "Access denied because of improper credentials");
1194 sprintf(msg_fail, "User %s is not authorized to login to account %s",
1195 krusername, lusername);
1197 fatal(netf, msg_fail);
1203 void getstr(fd, buf, cnt, err)
1213 if (read(fd, &c, 1) != 1) {
1217 printf("%s too long\r\n", err);
1226 char storage[2*RLOGIND_BUFSIZ]; /* storage for the decryption */
1228 char *store_ptr = storage;
1231 v5_des_read(fd, buf, len)
1237 krb5_ui_4 net_len,rd_len;
1240 unsigned char len_buf[4];
1244 return(read(fd, buf, len));
1246 if (nstored >= len) {
1247 memcpy(buf, store_ptr, len);
1251 } else if (nstored) {
1252 memcpy(buf, store_ptr, nstored);
1253 nreturned += nstored;
1260 if ((cc = krb5_net_read(bsd_context, fd, (char *)len_buf, 4)) != 4) {
1261 if ((cc < 0) && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1263 /* XXX can't read enough, pipe must have closed */
1267 (((krb5_ui_4)len_buf[0]<<24) |
1268 ((krb5_ui_4)len_buf[1]<<16) |
1269 ((krb5_ui_4)len_buf[2]<<8) |
1270 (krb5_ui_4)len_buf[3]);
1276 /* See the comment in v4_des_read. */
1278 cc = krb5_net_read(bsd_context, fd, &c, 1);
1279 /* we should check for non-blocking here, but we'd have
1280 to make it save partial reads as well. */
1281 if (cc <= 0) return 0; /* read error */
1283 if (c == 0) gotzero = 1;
1287 if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
1289 if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
1290 rd_len = (rd_len << 8) | c;
1291 if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
1292 rd_len = (rd_len << 8) | c;
1295 net_len = krb5_encrypt_size(rd_len,eblock.crypto_entry);
1296 /* note net_len is unsigned */
1297 if (net_len > sizeof(des_inbuf)) {
1298 /* XXX preposterous length, probably out of sync.
1299 act as if pipe closed */
1300 syslog(LOG_ERR,"Read size problem.");
1305 if ((cc = krb5_net_read(bsd_context,fd,desinbuf.data,net_len)) != net_len) {
1306 /* XXX can't read enough, pipe must have closed */
1307 if ((cc < 0) && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
1310 if (retry > MAXRETRIES){
1312 "des_read retry count exceeded %d\n",
1319 "Read data received %d != expected %d.",
1324 if ((krb5_decrypt(bsd_context, desinbuf.data,
1325 (krb5_pointer) storage,
1328 syslog(LOG_ERR,"Read decrypt problem.");
1331 store_ptr = storage;
1333 if (nstored > len) {
1334 memcpy(buf, store_ptr, len);
1339 memcpy(buf, store_ptr, nstored);
1340 nreturned += nstored;
1348 v5_des_write(fd, buf, len)
1353 unsigned char *len_buf = (unsigned char *) des_outpkt;
1356 return(write(fd, buf, len));
1359 desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
1360 if (desoutbuf.length > sizeof(des_outpkt)-4){
1361 syslog(LOG_ERR,"Write size problem.");
1364 if ((krb5_encrypt(bsd_context, (krb5_pointer)buf,
1369 syslog(LOG_ERR,"Write encrypt problem.");
1373 len_buf[0] = (len & 0xff000000) >> 24;
1374 len_buf[1] = (len & 0xff0000) >> 16;
1375 len_buf[2] = (len & 0xff00) >> 8;
1376 len_buf[3] = (len & 0xff);
1378 if (write(fd, des_outpkt,desoutbuf.length+4) != desoutbuf.length+4){
1379 syslog(LOG_ERR,"Could not write out all data.");
1384 #endif /* KERBEROS */
1390 "usage: klogind [-ke45pPf] [-D port] or [r/R][k/K][x/e][p/P]logind");
1393 "usage: rlogind [-rpPf] [-D port] or [r/R][p/P]logind");
1400 int princ_maps_to_lname(principal, luser)
1401 krb5_principal principal;
1405 if (!(krb5_aname_to_localname(bsd_context, principal,
1406 sizeof(kuser), kuser))
1407 && (strcmp(kuser, luser) == 0)) {
1413 int default_realm(principal)
1414 krb5_principal principal;
1420 realm_length = krb5_princ_realm(bsd_context, principal)->length;
1422 if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
1426 if ((realm_length != strlen(def_realm)) ||
1427 (memcmp(def_realm, krb5_princ_realm(bsd_context, principal)->data, realm_length))) {
1436 #ifndef KRB_SENDAUTH_VLEN
1437 #define KRB_SENDAUTH_VLEN 8 /* length for version strings */
1440 #define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
1444 recvauth(valid_checksum)
1445 int *valid_checksum;
1447 krb5_auth_context auth_context = NULL;
1448 krb5_error_code status;
1449 struct sockaddr_in peersin, laddr;
1452 char v4_instance[INST_SZ]; /* V4 Instance */
1454 krb5_authenticator *authenticator;
1457 *valid_checksum = 0;
1458 len = sizeof(laddr);
1459 if (getsockname(netf, (struct sockaddr *)&laddr, &len)) {
1463 len = sizeof(peersin);
1464 if (getpeername(netf, (struct sockaddr *)&peersin, &len)) {
1465 syslog(LOG_ERR, "get peer name failed %d", netf);
1469 strcpy(v4_instance, "*");
1471 if ((status = krb5_auth_con_init(bsd_context, &auth_context)))
1474 /* Only need remote address for rd_cred() to verify client */
1475 if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
1476 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
1479 status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
1480 if (status) return status;
1483 krb5_principal server;
1485 status = krb5_sname_to_principal(bsd_context, 0, 0,
1486 KRB5_NT_SRV_HST, &server);
1487 if (status) return status;
1489 status = krb5_get_server_rcache(bsd_context,
1490 krb5_princ_component(bsd_context, server, 0),
1492 krb5_free_principal(bsd_context, server);
1493 if (status) return status;
1495 status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
1496 if (status) return status;
1499 if ((status = krb5_compat_recvauth(bsd_context, &auth_context, &netf,
1501 NULL, /* Specify daemon principal */
1503 keytab, /* normally NULL to use v5srvtab */
1505 do_encrypt ? KOPT_DO_MUTUAL : 0, /*v4_opts*/
1506 "rcmd", /* v4_service */
1507 v4_instance, /* v4_instance */
1508 &peersin, /* foriegn address */
1509 &laddr, /* our local address */
1510 "", /* use default srvtab */
1512 &ticket, /* return ticket */
1513 &auth_sys, /* which authentication system*/
1514 &v4_kdata, v4_schedule, v4_version))) {
1516 if (auth_sys == KRB5_RECVAUTH_V5) {
1518 * clean up before exiting
1520 getstr(netf, lusername, sizeof (lusername), "locuser");
1521 getstr(netf, term, sizeof(term), "Terminal type");
1522 getstr(netf, rusername, sizeof(rusername), "remuser");
1527 getstr(netf, lusername, sizeof (lusername), "locuser");
1528 getstr(netf, term, sizeof(term), "Terminal type");
1529 if ((auth_sys == KRB5_RECVAUTH_V5) && !checksum_ignored) {
1531 if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
1535 if (authenticator->checksum) {
1536 struct sockaddr_in adr;
1537 int adr_length = sizeof(adr);
1538 char * chksumbuf = (char *) malloc(strlen(term)+strlen(lusername)+32);
1539 if (getsockname(netf, (struct sockaddr *) &adr, &adr_length) != 0)
1544 sprintf(chksumbuf,"%u:", ntohs(adr.sin_port));
1545 strcat(chksumbuf,term);
1546 strcat(chksumbuf,lusername);
1548 status = krb5_verify_checksum(bsd_context,
1549 authenticator->checksum->checksum_type,
1550 authenticator->checksum,
1551 chksumbuf, strlen(chksumbuf),
1552 ticket->enc_part2->session->contents,
1553 ticket->enc_part2->session->length);
1558 krb5_free_authenticator(bsd_context, authenticator);
1561 *valid_checksum = 1;
1563 krb5_free_authenticator(bsd_context, authenticator);
1567 #ifdef KRB5_KRB4_COMPAT
1568 if (auth_sys == KRB5_RECVAUTH_V4) {
1570 des_read = v4_des_read;
1571 des_write = v4_des_write;
1573 /* We do not really know the remote user's login name.
1574 * Assume it to be the same as the first component of the
1577 strcpy(rusername, v4_kdata->pname);
1579 status = krb5_425_conv_principal(bsd_context, v4_kdata->pname,
1580 v4_kdata->pinst, v4_kdata->prealm,
1582 if (status) return status;
1584 status = krb5_unparse_name(bsd_context, client, &krusername);
1592 if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
1596 des_read = v5_des_read;
1597 des_write = v5_des_write;
1599 getstr(netf, rusername, sizeof(rusername), "remuser");
1601 if ((status = krb5_unparse_name(bsd_context, client, &krusername)))
1604 /* Setup up eblock if encrypted login session */
1605 /* otherwise zero out session key */
1607 krb5_use_enctype(bsd_context, &eblock,
1608 ticket->enc_part2->session->enctype);
1609 if ((status = krb5_process_key(bsd_context, &eblock,
1610 ticket->enc_part2->session)))
1611 fatal(netf, "Permission denied");
1614 if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netf, &inbuf)))
1615 fatal(netf, "Error reading message");
1617 if ((inbuf.length) && /* Forwarding being done, read creds */
1618 (status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
1619 ticket, &ccache))) {
1620 fatal(netf, "Can't get forwarded credentials");
1626 #ifdef KRB5_KRB4_COMPAT
1629 v4_des_read(fd, buf, len)
1635 krb5_ui_4 net_len, rd_len;
1638 unsigned char len_buf[4];
1642 return(read(fd, buf, len));
1644 if (nstored >= len) {
1645 memcpy(buf, store_ptr, len);
1649 } else if (nstored) {
1650 memcpy(buf, store_ptr, nstored);
1651 nreturned += nstored;
1658 if ((cc = krb_net_read(fd, (char *)len_buf, 4)) != 4) {
1659 /* XXX can't read enough, pipe
1663 net_len = (((krb5_ui_4)len_buf[0]<<24) |
1664 ((krb5_ui_4)len_buf[1]<<16) |
1665 ((krb5_ui_4)len_buf[2]<<8) |
1666 (krb5_ui_4)len_buf[3]);
1672 /* We're fetching the length which is MSB first, and the MSB
1673 has to be zero unless the client is sending more than 2^24
1674 (16M) bytes in a single write (which is why this code is in
1675 rlogin but not rcp or rsh.) The only reasons we'd get something
1676 other than zero are:
1677 -- corruption of the tcp stream (which will show up when
1678 everything else is out of sync too)
1679 -- un-caught Berkeley-style "pseudo out-of-band data" which
1680 happens any time the user hits ^C twice.
1681 The latter is *very* common, as shown by an 'rlogin -x -d'
1682 using the CNS V4 rlogin. Mark EIchin 1/95
1685 cc = krb_net_read(fd, &c, 1);
1686 if (cc <= 0) return 0; /* read error */
1688 if (c == 0) gotzero = 1;
1692 if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1694 if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1695 net_len = (net_len << 8) | c;
1696 if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1697 net_len = (net_len << 8) | c;
1701 /* Note: net_len is unsigned */
1702 if (net_len > sizeof(des_inbuf)) {
1703 /* XXX preposterous length, probably out of sync.
1704 act as if pipe closed */
1707 /* the writer tells us how much real data we are getting, but
1708 we need to read the pad bytes (8-byte boundary) */
1709 rd_len = roundup(net_len, 8);
1710 if ((cc = krb_net_read(fd, des_inbuf, rd_len)) != rd_len) {
1711 /* XXX can't read enough, pipe
1715 (void) pcbc_encrypt(des_inbuf,
1717 (net_len < 8) ? 8 : net_len,
1722 * when the cleartext block is < 8 bytes, it is "right-justified"
1723 * in the block, so we need to adjust the pointer to the data
1726 store_ptr = storage + 8 - net_len;
1728 store_ptr = storage;
1730 if (nstored > len) {
1731 memcpy(buf, store_ptr, len);
1736 memcpy(buf, store_ptr, nstored);
1737 nreturned += nstored;
1745 v4_des_write(fd, buf, len)
1750 static char garbage_buf[8];
1751 unsigned char *len_buf = (unsigned char *) des_outpkt;
1754 return(write(fd, buf, len));
1757 * pcbc_encrypt outputs in 8-byte (64 bit) increments
1759 * it zero-fills the cleartext to 8-byte padding,
1760 * so if we have cleartext of < 8 bytes, we want
1761 * to insert random garbage before it so that the ciphertext
1762 * differs for each transmission of the same cleartext.
1763 * if len < 8 - sizeof(long), sizeof(long) bytes of random
1764 * garbage should be sufficient; leave the rest as-is in the buffer.
1765 * if len > 8 - sizeof(long), just garbage fill the rest.
1771 #define min(a,b) ((a < b) ? a : b)
1774 krb5_random_confounder(8 - len, garbage_buf);
1775 /* this "right-justifies" the data in the buffer */
1776 (void) memcpy(garbage_buf + 8 - len, buf, len);
1778 (void) pcbc_encrypt((len < 8) ? garbage_buf : buf,
1780 (len < 8) ? 8 : len,
1785 /* tell the other end the real amount, but send an 8-byte padded
1787 len_buf[0] = (len & 0xff000000) >> 24;
1788 len_buf[1] = (len & 0xff0000) >> 16;
1789 len_buf[2] = (len & 0xff00) >> 8;
1790 len_buf[3] = (len & 0xff);
1791 (void) write(fd, des_outpkt, roundup(len,8)+4);
1795 #endif /* KRB5_KRB4_COMPAT */
1796 #endif /* KERBEROS */