From a4de116322ed81d2721fa9af372532124e1777f1 Mon Sep 17 00:00:00 2001 From: djm Date: Wed, 21 Jan 2004 06:07:16 +0000 Subject: [PATCH] - deraadt@cvs.openbsd.org 2004/01/11 21:55:06 [sshpty.c] for pty opening, only use the openpty() path. the other stuff only needs to be in openssh-p; markus ok - (djm) [openbsd-compat/bsd-openpty.c] Rework old sshpty.c code into an openpty() replacement --- ChangeLog | 6 + openbsd-compat/Makefile.in | 2 +- openbsd-compat/bsd-openpty.c | 211 ++++++++++++++++++++++++++++++++ openbsd-compat/openbsd-compat.h | 5 +- sshpty.c | 192 +---------------------------- 5 files changed, 222 insertions(+), 194 deletions(-) create mode 100644 openbsd-compat/bsd-openpty.c diff --git a/ChangeLog b/ChangeLog index dc788f5b..70c20549 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,12 @@ - djm@cvs.openbsd.org 2004/01/21 03:07:59 [sftp.c] initialise infile in main, rather than statically - from portable + - deraadt@cvs.openbsd.org 2004/01/11 21:55:06 + [sshpty.c] + for pty opening, only use the openpty() path. the other stuff only needs + to be in openssh-p; markus ok + - (djm) [openbsd-compat/bsd-openpty.c] Rework old sshpty.c code into an + openpty() replacement 20040114 - (dtucker) [auth-pam.c] Have monitor die if PAM authentication thread exits diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index a4aea7a3..8b06199e 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtoul.o vis.o -COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o +COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o PORTS=port-irix.o port-aix.o diff --git a/openbsd-compat/bsd-openpty.c b/openbsd-compat/bsd-openpty.c new file mode 100644 index 00000000..0a3c5e21 --- /dev/null +++ b/openbsd-compat/bsd-openpty.c @@ -0,0 +1,211 @@ +/* + * Please note: this implementation of openpty() is far from complete. + * it is just enough for portable OpenSSH's needs. + */ + +/* + * Copyright (c) 2004 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Author: Tatu Ylonen + * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland + * All rights reserved + * Allocating a pseudo-terminal, and making it the controlling tty. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" +#if !defined(HAVE_OPENPTY) + +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +int +openpty(int *amaster, int *aslave, char *name, struct termios *termp, + struct winsize *winp) +{ +#if defined(HAVE__GETPTY) + /* + * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more + * pty's automagically when needed + */ + char *slave; + + if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL) + return (-1); + + /* Open the slave side. */ + if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + +#elif defined(HAVE_DEV_PTMX) + /* + * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 + * also has bsd-style ptys, but they simply do not work.) + */ + int ptm; + char *pts; + mysig_t old_signal; + + if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) + return (-1); + + /* XXX: need to close ptm on error? */ + old_signal = signal(SIGCHLD, SIG_DFL); + if (grantpt(ptm) < 0) + return (-1); + signal(SIGCHLD, old_signal); + + if (unlockpt(ptm) < 0) + return (-1); + + if ((pts = ptsname(ptm)) == NULL) + return (-1); + *amaster = ptm; + + /* Open the slave side. */ + if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + +#ifndef HAVE_CYGWIN + /* + * Try to push the appropriate streams modules, as described + * in Solaris pts(7). + */ + ioctl(*aslave, I_PUSH, "ptem"); + ioctl(*aslave, I_PUSH, "ldterm"); +# ifndef __hpux + ioctl(*aslave, I_PUSH, "ttcompat"); +# endif /* __hpux */ +#endif /* HAVE_CYGWIN */ + + return (0); + +#elif defined(HAVE_DEV_PTS_AND_PTC) + /* AIX-style pty code. */ + const char *ttname; + + if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1) + return (-1); + if ((ttname = ttyname(*amaster)) == NULL) + return (-1); + if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + +#elif defined(_UNICOS) + char ptbuf[64], ttbuf[64]; + int i; + int highpty; + + highpty = 128; +#ifdef _SC_CRAY_NPTY + if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1) + highpty = 128; +#endif /* _SC_CRAY_NPTY */ + + for (i = 0; i < highpty; i++) { + snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i); + snprintf(ttbuf, sideof(ttbuf), "/dev/ttyp%03d", i); + if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1) + continue; + /* Open the slave side. */ + if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + return (0); + } + return (-1); + +#else + /* BSD-style pty code. */ + char ptbuf[64], ttbuf[64]; + int i; + const char *ptymajors = "pqrstuvwxyzabcdefghijklmno" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptyminors = "0123456789abcdef"; + int num_minors = strlen(ptyminors); + int num_ptys = strlen(ptymajors) * num_minors; + struct termios tio; + + for (i = 0; i < num_ptys; i++) { + snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c", + ptymajors[i / num_minors], ptyminors[i % num_minors]); + + if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) { + /* Try SCO style naming */ + snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i); + snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i); + if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) + continue; + } + + /* Open the slave side. */ + if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) { + close(*amaster); + return (-1); + } + /* set tty modes to a sane state for broken clients */ + if (tcgetattr(*amaster, &tio) != -1) { + tio.c_lflag |= (ECHO | ISIG | ICANON); + tio.c_oflag |= (OPOST | ONLCR); + tio.c_iflag |= ICRNL; + tcsetattr(*amaster, TCSANOW, &tio); + } + + return (0); + } + return (-1); +#endif +} + +#endif /* !defined(HAVE_OPENPTY) */ + diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index ebb5fd00..8f8b3fb4 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -138,8 +138,9 @@ unsigned int arc4random(void); void arc4random_stir(void); #endif /* !HAVE_ARC4RANDOM */ - - +#ifndef HAVE_OPENPTY +int openpty(int *, int *, char *, struct termios *, struct winsize *); +#endif /* HAVE_OPENPTY */ /* #include XXX needed? For size_t */ diff --git a/sshpty.c b/sshpty.c index 50b1f2ba..0fe3891b 100644 --- a/sshpty.c +++ b/sshpty.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); +RCSID("$OpenBSD: sshpty.c,v 1.11 2004/01/11 21:55:06 deraadt Exp $"); #ifdef HAVE_UTIL_H # include @@ -22,17 +22,9 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); #include "log.h" #include "misc.h" -/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ -#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) -#undef HAVE_DEV_PTMX -#endif - #ifdef HAVE_PTY_H # include #endif -#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) -# include -#endif #ifndef O_NOCTTY #define O_NOCTTY 0 @@ -48,7 +40,6 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { -#if defined(HAVE_OPENPTY) || defined(BSD4_4) /* openpty(3) exists in OSF/1 and some other os'es */ char *name; int i; @@ -64,187 +55,6 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) strlcpy(namebuf, name, namebuflen); /* possible truncation */ return 1; -#else /* HAVE_OPENPTY */ -#ifdef HAVE__GETPTY - /* - * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more - * pty's automagically when needed - */ - char *slave; - - slave = _getpty(ptyfd, O_RDWR, 0622, 0); - if (slave == NULL) { - error("_getpty: %.100s", strerror(errno)); - return 0; - } - strlcpy(namebuf, slave, namebuflen); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.200s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE__GETPTY */ -#if defined(HAVE_DEV_PTMX) - /* - * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 - * also has bsd-style ptys, but they simply do not work.) - */ - int ptm; - char *pts; - mysig_t old_signal; - - ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); - if (ptm < 0) { - error("/dev/ptmx: %.100s", strerror(errno)); - return 0; - } - old_signal = signal(SIGCHLD, SIG_DFL); - if (grantpt(ptm) < 0) { - error("grantpt: %.100s", strerror(errno)); - return 0; - } - signal(SIGCHLD, old_signal); - if (unlockpt(ptm) < 0) { - error("unlockpt: %.100s", strerror(errno)); - return 0; - } - pts = ptsname(ptm); - if (pts == NULL) - error("Slave pty side name could not be obtained."); - strlcpy(namebuf, pts, namebuflen); - *ptyfd = ptm; - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } -#ifndef HAVE_CYGWIN - /* - * Push the appropriate streams modules, as described in Solaris pts(7). - * HP-UX pts(7) doesn't have ttcompat module. - */ - if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) - error("ioctl I_PUSH ptem: %.100s", strerror(errno)); - if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) - error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); -#ifndef __hpux - if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) - error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); -#endif -#endif - return 1; -#else /* HAVE_DEV_PTMX */ -#ifdef HAVE_DEV_PTS_AND_PTC - /* AIX-style pty code. */ - const char *name; - - *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - error("Could not open /dev/ptc: %.100s", strerror(errno)); - return 0; - } - name = ttyname(*ptyfd); - if (!name) - fatal("Open of /dev/ptc returns device for which ttyname fails."); - strlcpy(namebuf, name, namebuflen); - *ttyfd = open(name, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("Could not open pty slave side %.100s: %.100s", - name, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; -#else /* HAVE_DEV_PTS_AND_PTC */ -#ifdef _UNICOS - char buf[64]; - int i; - int highpty; - -#ifdef _SC_CRAY_NPTY - highpty = sysconf(_SC_CRAY_NPTY); - if (highpty == -1) - highpty = 128; -#else - highpty = 128; -#endif - - for (i = 0; i < highpty; i++) { - snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); - *ptyfd = open(buf, O_RDWR|O_NOCTTY); - if (*ptyfd < 0) - continue; - snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - return 1; - } - return 0; -#else - /* BSD-style pty code. */ - char buf[64]; - int i; - const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const char *ptyminors = "0123456789abcdef"; - int num_minors = strlen(ptyminors); - int num_ptys = strlen(ptymajors) * num_minors; - struct termios tio; - - for (i = 0; i < num_ptys; i++) { - snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], - ptyminors[i % num_minors]); - snprintf(namebuf, namebuflen, "/dev/tty%c%c", - ptymajors[i / num_minors], ptyminors[i % num_minors]); - - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) { - /* Try SCO style naming */ - snprintf(buf, sizeof buf, "/dev/ptyp%d", i); - snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) - continue; - } - - /* Open the slave side. */ - *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); - if (*ttyfd < 0) { - error("%.100s: %.100s", namebuf, strerror(errno)); - close(*ptyfd); - return 0; - } - /* set tty modes to a sane state for broken clients */ - if (tcgetattr(*ptyfd, &tio) < 0) - logit("Getting tty modes for pty failed: %.100s", strerror(errno)); - else { - tio.c_lflag |= (ECHO | ISIG | ICANON); - tio.c_oflag |= (OPOST | ONLCR); - tio.c_iflag |= ICRNL; - - /* Set the new modes for the terminal. */ - if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) - logit("Setting tty modes for pty failed: %.100s", strerror(errno)); - } - - return 1; - } - return 0; -#endif /* CRAY */ -#endif /* HAVE_DEV_PTS_AND_PTC */ -#endif /* HAVE_DEV_PTMX */ -#endif /* HAVE__GETPTY */ -#endif /* HAVE_OPENPTY */ } /* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ -- 2.45.1