comparison sshpty.c @ 4:fe6bca95afa7

Makefile.in contains updated files required
author Matt Johnston <matt@ucc.asn.au>
date Tue, 01 Jun 2004 02:46:09 +0000
parents
children 5c6f9d27ea1c
comparison
equal deleted inserted replaced
-1:000000000000 4:fe6bca95afa7
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copied from OpenSSH-3.5p1 source, modified by Matt Johnston 2003
5 *
6 * Author: Tatu Ylonen <[email protected]>
7 * Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
8 * All rights reserved
9 * Allocating a pseudo-terminal, and making it the controlling tty.
10 *
11 * As far as I am concerned, the code I have written for this software
12 * can be used freely for any purpose. Any derived versions of this
13 * software must be clearly marked as such, and if the derived work is
14 * incompatible with the protocol description in the RFC file, it must be
15 * called by a name other than "ssh" or "Secure Shell".
16 */
17
18 /*RCSID("$OpenBSD: sshpty.c,v 1.7 2002/06/24 17:57:20 deraadt Exp $");*/
19
20 #include "includes.h"
21 #include "dbutil.h"
22 #include "errno.h"
23 #include "sshpty.h"
24
25 /* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
26 #if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
27 #undef HAVE_DEV_PTMX
28 #endif
29
30 #ifdef HAVE_PTY_H
31 # include <pty.h>
32 #endif
33 #if defined(USE_DEV_PTMX) && defined(HAVE_STROPTS_H)
34 # include <stropts.h>
35 #endif
36
37 #ifndef O_NOCTTY
38 #define O_NOCTTY 0
39 #endif
40
41 /*
42 * Allocates and opens a pty. Returns 0 if no pty could be allocated, or
43 * nonzero if a pty was successfully allocated. On success, open file
44 * descriptors for the pty and tty sides and the name of the tty side are
45 * returned (the buffer must be able to hold at least 64 characters).
46 */
47
48 int
49 pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
50 {
51 #if defined(HAVE_OPENPTY)
52 /* exists in recent (4.4) BSDs and OSF/1 */
53 char *name;
54 int i;
55
56 i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
57 if (i < 0) {
58 dropbear_log(LOG_WARNING,
59 "pty_allocate: openpty: %.100s", strerror(errno));
60 return 0;
61 }
62 name = ttyname(*ttyfd);
63 if (!name) {
64 dropbear_exit("ttyname fails for openpty device");
65 }
66
67 strlcpy(namebuf, name, namebuflen); /* possible truncation */
68 return 1;
69 #else /* HAVE_OPENPTY */
70 #ifdef HAVE__GETPTY
71 /*
72 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
73 * pty's automagically when needed
74 */
75 char *slave;
76
77 slave = _getpty(ptyfd, O_RDWR, 0622, 0);
78 if (slave == NULL) {
79 dropbear_log(LOG_WARNING,
80 "pty_allocate: _getpty: %.100s", strerror(errno));
81 return 0;
82 }
83 strlcpy(namebuf, slave, namebuflen);
84 /* Open the slave side. */
85 *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
86 if (*ttyfd < 0) {
87 dropbear_log(LOG_WARNING,
88 "pty_allocate error: ttyftd open error");
89 close(*ptyfd);
90 return 0;
91 }
92 return 1;
93 #else /* HAVE__GETPTY */
94 #if defined(USE_DEV_PTMX)
95 /*
96 * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
97 * also has bsd-style ptys, but they simply do not work.)
98 *
99 * Linux systems may have the /dev/ptmx device, but this code won't work.
100 */
101 int ptm;
102 char *pts;
103
104 ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
105 if (ptm < 0) {
106 dropbear_log(LOG_WARNING,
107 "pty_allocate: /dev/ptmx: %.100s", strerror(errno));
108 return 0;
109 }
110 if (grantpt(ptm) < 0) {
111 dropbear_log(LOG_WARNING,
112 "grantpt: %.100s", strerror(errno));
113 return 0;
114 }
115 if (unlockpt(ptm) < 0) {
116 dropbear_log(LOG_WARNING,
117 "unlockpt: %.100s", strerror(errno));
118 return 0;
119 }
120 pts = ptsname(ptm);
121 if (pts == NULL) {
122 dropbear_log(LOG_WARNING,
123 "Slave pty side name could not be obtained.");
124 }
125 strlcpy(namebuf, pts, namebuflen);
126 *ptyfd = ptm;
127
128 /* Open the slave side. */
129 *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
130 if (*ttyfd < 0) {
131 dropbear_log(LOG_ERR,
132 "error opening pts %.100s: %.100s", namebuf, strerror(errno));
133 close(*ptyfd);
134 return 0;
135 }
136 #ifndef HAVE_CYGWIN
137 /*
138 * Push the appropriate streams modules, as described in Solaris pts(7).
139 * HP-UX pts(7) doesn't have ttcompat module.
140 */
141 if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) {
142 dropbear_log(LOG_WARNING,
143 "ioctl I_PUSH ptem: %.100s", strerror(errno));
144 }
145 if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) {
146 dropbear_log(LOG_WARNING,
147 "ioctl I_PUSH ldterm: %.100s", strerror(errno));
148 }
149 #ifndef __hpux
150 if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) {
151 dropbear_log(LOG_WARNING,
152 "ioctl I_PUSH ttcompat: %.100s", strerror(errno));
153 }
154 #endif
155 #endif
156 return 1;
157 #else /* USE_DEV_PTMX */
158 #ifdef HAVE_DEV_PTS_AND_PTC
159 /* AIX-style pty code. */
160 const char *name;
161
162 *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
163 if (*ptyfd < 0) {
164 dropbear_log(LOG_ERR,
165 "Could not open /dev/ptc: %.100s", strerror(errno));
166 return 0;
167 }
168 name = ttyname(*ptyfd);
169 if (!name) {
170 dropbear_exit("ttyname fails for /dev/ptc device");
171 }
172 strlcpy(namebuf, name, namebuflen);
173 *ttyfd = open(name, O_RDWR | O_NOCTTY);
174 if (*ttyfd < 0) {