[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
This commit is contained in:
Damien Miller 2004-01-21 17:07:16 +11:00
parent e4f5a82d6e
commit f4da3bb6ca
5 changed files with 225 additions and 197 deletions

View File

@ -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
@ -1695,4 +1701,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.3176 2004/01/21 03:11:05 djm Exp $
$Id: ChangeLog,v 1.3177 2004/01/21 06:07:16 djm Exp $

View File

@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.29 2003/10/07 07:49:57 dtucker Exp $
# $Id: Makefile.in,v 1.30 2004/01/21 06:07:23 djm Exp $
sysconfdir=@sysconfdir@
piddir=@piddir@
@ -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

View File

@ -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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 <util.h>
#endif /* HAVE_UTIL_H */
#ifdef HAVE_PTY_H
# include <pty.h>
#endif
#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
# include <sys/stropts.h>
#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) */

View File

@ -1,4 +1,4 @@
/* $Id: openbsd-compat.h,v 1.24 2003/08/29 16:59:52 mouring Exp $ */
/* $Id: openbsd-compat.h,v 1.25 2004/01/21 06:07:23 djm Exp $ */
/*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@ -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 <sys/types.h> XXX needed? For size_t */

192
sshpty.c
View File

@ -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 <util.h>
@ -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 <pty.h>
#endif
#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
# include <sys/stropts.h>
#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. */