Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc

*** 240,250 **** #define TS_WONT 6 /* wont " */ #define TS_DO 7 /* do " */ #define TS_DONT 8 /* dont " */ static int ncc; ! static int master; /* master side of pty */ static int pty; /* side of pty that gets ioctls */ static int net; static int inter; extern char **environ; static char *line; --- 240,250 ---- #define TS_WONT 6 /* wont " */ #define TS_DO 7 /* do " */ #define TS_DONT 8 /* dont " */ static int ncc; ! static int manager; /* manager side of pty */ static int pty; /* side of pty that gets ioctls */ static int net; static int inter; extern char **environ; static char *line;
*** 2752,2783 **** struct sockaddr_in6 *sin6; socklen_t wholen; char username[MAXUSERNAMELEN]; int len; uchar_t passthru; ! char *slavename; if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { fatalperror(f, "open /dev/ptmx", errno); } if (grantpt(p) == -1) ! fatal(f, "could not grant slave pty"); if (unlockpt(p) == -1) ! fatal(f, "could not unlock slave pty"); ! if ((slavename = ptsname(p)) == NULL) ! fatal(f, "could not enable slave pty"); (void) dup2(f, 0); ! if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1) ! fatal(f, "could not open slave pty"); if (ioctl(t, I_PUSH, "ptem") == -1) fatalperror(f, "ioctl I_PUSH ptem", errno); if (ioctl(t, I_PUSH, "ldterm") == -1) fatalperror(f, "ioctl I_PUSH ldterm", errno); if (ioctl(t, I_PUSH, "ttcompat") == -1) fatalperror(f, "ioctl I_PUSH ttcompat", errno); ! line = slavename; pty = t; if (ioctl(t, TIOCGETP, &b) == -1) syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n"); --- 2752,2783 ---- struct sockaddr_in6 *sin6; socklen_t wholen; char username[MAXUSERNAMELEN]; int len; uchar_t passthru; ! char *subsidname; if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) { fatalperror(f, "open /dev/ptmx", errno); } if (grantpt(p) == -1) ! fatal(f, "could not grant subsidiary pty"); if (unlockpt(p) == -1) ! fatal(f, "could not unlock subsidiary pty"); ! if ((subsidname = ptsname(p)) == NULL) ! fatal(f, "could not enable subsidiary pty"); (void) dup2(f, 0); ! if ((t = open(subsidname, O_RDWR | O_NOCTTY)) == -1) ! fatal(f, "could not open subsidiary pty"); if (ioctl(t, I_PUSH, "ptem") == -1) fatalperror(f, "ioctl I_PUSH ptem", errno); if (ioctl(t, I_PUSH, "ldterm") == -1) fatalperror(f, "ioctl I_PUSH ldterm", errno); if (ioctl(t, I_PUSH, "ttcompat") == -1) fatalperror(f, "ioctl I_PUSH ttcompat", errno); ! line = subsidname; pty = t; if (ioctl(t, TIOCGETP, &b) == -1) syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n");
*** 3037,3047 **** if (ioctl(ptmfd, I_STR, &telnetmod) < 0) fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); net = netfd; ! master = ptmfd; cryptmod_fd = netfd; /* * Show banner that getty never gave, but * only if the user did not automatically authenticate. --- 3037,3047 ---- if (ioctl(ptmfd, I_STR, &telnetmod) < 0) fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n"); net = netfd; ! manager = ptmfd; cryptmod_fd = netfd; /* * Show banner that getty never gave, but * only if the user did not automatically authenticate.
*** 3098,3112 **** remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK; if ((pid = fork()) < 0) fatalperror(netfd, "fork", errno); if (pid) ! telnet(net, master); /* * The child process needs to be the session leader * and have the pty as its controlling tty. Thus we need ! * to re-open the slave side of the pty no without * the O_NOCTTY flag that we have been careful to * use up to this point. */ (void) setsid(); --- 3098,3112 ---- remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK; if ((pid = fork()) < 0) fatalperror(netfd, "fork", errno); if (pid) ! telnet(net, manager); /* * The child process needs to be the session leader * and have the pty as its controlling tty. Thus we need ! * to re-open the subsidiary side of the pty no without * the O_NOCTTY flag that we have been careful to * use up to this point. */ (void) setsid();
*** 3190,3200 **** (auth_status == AUTH_VALID || auth_status == AUTH_USER) && ((krb5_name != NULL) && strlen(krb5_name)) && ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { (void) execl(LOGIN_PROGRAM, "login", "-p", ! "-d", slavename, "-h", host, "-u", krb5_name, "-s", pam_svc_name, "-R", KRB5_REPOSITORY_NAME, AuthenticatingUser, 0); --- 3190,3200 ---- (auth_status == AUTH_VALID || auth_status == AUTH_USER) && ((krb5_name != NULL) && strlen(krb5_name)) && ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) { (void) execl(LOGIN_PROGRAM, "login", "-p", ! "-d", subsidname, "-h", host, "-u", krb5_name, "-s", pam_svc_name, "-R", KRB5_REPOSITORY_NAME, AuthenticatingUser, 0);
*** 3206,3224 **** * If we only know the name but not the principal, * login will have to authenticate further. */ (void) execl(LOGIN_PROGRAM, "login", "-p", ! "-d", slavename, "-h", host, "-s", pam_svc_name, "--", (AuthenticatingUser != NULL ? AuthenticatingUser : getenv("USER")), 0); } else /* default, no auth. info available, login does it all */ { (void) execl(LOGIN_PROGRAM, "login", ! "-p", "-h", host, "-d", slavename, "--", getenv("USER"), 0); } fatalperror(netfd, LOGIN_PROGRAM, errno); /*NOTREACHED*/ --- 3206,3224 ---- * If we only know the name but not the principal, * login will have to authenticate further. */ (void) execl(LOGIN_PROGRAM, "login", "-p", ! "-d", subsidname, "-h", host, "-s", pam_svc_name, "--", (AuthenticatingUser != NULL ? AuthenticatingUser : getenv("USER")), 0); } else /* default, no auth. info available, login does it all */ { (void) execl(LOGIN_PROGRAM, "login", ! "-p", "-h", host, "-d", subsidname, "--", getenv("USER"), 0); } fatalperror(netfd, LOGIN_PROGRAM, errno); /*NOTREACHED*/
*** 3252,3262 **** * when it receives telnet protocol. Regular data * flow between pty and network takes place through * inkernel telnet streams module (telmod). */ static void ! telnet(int net, int master) { int on = 1; char mode; struct strioctl telnetmod; int nsize = 0; --- 3252,3262 ---- * when it receives telnet protocol. Regular data * flow between pty and network takes place through * inkernel telnet streams module (telmod). */ static void ! telnet(int net, int manager) { int on = 1; char mode; struct strioctl telnetmod; int nsize = 0;
*** 3263,3273 **** char binary_in = 0; char binary_out = 0; if (ioctl(net, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); ! if (ioctl(master, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGCHLD, (void (*)())cleanup); (void) setpgrp(); --- 3263,3273 ---- char binary_in = 0; char binary_out = 0; if (ioctl(net, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO net: %m\n"); ! if (ioctl(manager, FIONBIO, &on) == -1) syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n"); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGCHLD, (void (*)())cleanup); (void) setpgrp();
*** 3300,3310 **** /* * Never look for input if there's still * stuff in the corresponding output buffer */ if (pfrontp - pbackp) { ! FD_SET(master, &obits); } else { FD_SET(net, &ibits); } if (!SYNCHing) { FD_SET(net, &xbits); --- 3300,3310 ---- /* * Never look for input if there's still * stuff in the corresponding output buffer */ if (pfrontp - pbackp) { ! FD_SET(manager, &obits); } else { FD_SET(net, &ibits); } if (!SYNCHing) { FD_SET(net, &xbits);
*** 3388,3398 **** if (ioctl(net, I_STR, &telnetmod) < 0) fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); } ! if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits, (struct timeval *)0)) < 1) { if (c == -1) { if (errno == EINTR) { continue; } --- 3388,3398 ---- if (ioctl(net, I_STR, &telnetmod) < 0) fatal(net, "ioctl TEL_IOC_GETBLK failed\n"); } ! if ((c = select(max(net, manager) + 1, &ibits, &obits, &xbits, (struct timeval *)0)) < 1) { if (c == -1) { if (errno == EINTR) { continue; }
*** 3425,3435 **** if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) netflush(); if (ncc > 0) telrcv(); ! if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0) ptyflush(); } cleanup(0); } --- 3425,3435 ---- if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0) netflush(); if (ncc > 0) telrcv(); ! if (FD_ISSET(manager, &obits) && (pfrontp - pbackp) > 0) ptyflush(); } cleanup(0); }
*** 4277,4287 **** ptyflush(void) { int n; if ((n = pfrontp - pbackp) > 0) ! n = write(master, pbackp, n); if (n < 0) return; pbackp += n; if (pbackp == pfrontp) pbackp = pfrontp = ptyobuf; --- 4277,4287 ---- ptyflush(void) { int n; if ((n = pfrontp - pbackp) > 0) ! n = write(manager, pbackp, n); if (n < 0) return; pbackp += n; if (pbackp == pfrontp) pbackp = pfrontp = ptyobuf;
*** 4445,4457 **** cleanup(int signum) { /* * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to * handle closing differently. We close "net" first and then ! * "master" in that order. We do close(net) first because * we have no other way to disconnect forwarding between the network ! * and master. So by issuing the close()'s we ensure that no further * data rises from TCP. A more complex fix would be adding proper * support for throwing a "stop" switch for forwarding data between * logindmux peers. It's possible to block in the close of the tty * while the network still receives data and the telmod module is * TEL_STOPPED. A denial-of-service attack generates this case, --- 4445,4457 ---- cleanup(int signum) { /* * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to * handle closing differently. We close "net" first and then ! * "manager" in that order. We do close(net) first because * we have no other way to disconnect forwarding between the network ! * and manager. So by issuing the close()'s we ensure that no further * data rises from TCP. A more complex fix would be adding proper * support for throwing a "stop" switch for forwarding data between * logindmux peers. It's possible to block in the close of the tty * while the network still receives data and the telmod module is * TEL_STOPPED. A denial-of-service attack generates this case,
*** 4458,4468 **** * see 4102102. */ if (!telmod_init_done) { (void) close(net); ! (void) close(master); } rmut(); exit(EXIT_FAILURE); } --- 4458,4468 ---- * see 4102102. */ if (!telmod_init_done) { (void) close(net); ! (void) close(manager); } rmut(); exit(EXIT_FAILURE); }