summaryrefslogtreecommitdiff
path: root/pty.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /pty.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'pty.c')
-rw-r--r--pty.c398
1 files changed, 187 insertions, 211 deletions
diff --git a/pty.c b/pty.c
index bbe18fd03..34ed48d61 100644
--- a/pty.c
+++ b/pty.c
@@ -1,28 +1,28 @@
1/* 1/*
2 2 *
3pty.c 3 * pty.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Fri Mar 17 04:37:25 1995 ylo 10 * Created: Fri Mar 17 04:37:25 1995 ylo
11 11 *
12Allocating a pseudo-terminal, and making it the controlling tty. 12 * Allocating a pseudo-terminal, and making it the controlling tty.
13 13 *
14*/ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: pty.c,v 1.3 1999/11/15 04:40:55 damien Exp $"); 17RCSID("$Id: pty.c,v 1.4 1999/11/24 13:26:22 damien Exp $");
18
19#include "pty.h"
20#include "ssh.h"
18 21
19#ifdef HAVE_PTY_H 22#ifdef HAVE_PTY_H
20#include <pty.h> 23#include <pty.h>
21#endif /* HAVE_PTY_H */ 24#endif /* HAVE_PTY_H */
22 25
23#include "pty.h"
24#include "ssh.h"
25
26/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ 26/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
27#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) 27#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
28#undef HAVE_DEV_PTMX 28#undef HAVE_DEV_PTMX
@@ -34,235 +34,211 @@ RCSID("$Id: pty.c,v 1.3 1999/11/15 04:40:55 damien Exp $");
34 34
35/* Allocates and opens a pty. Returns 0 if no pty could be allocated, 35/* Allocates and opens a pty. Returns 0 if no pty could be allocated,
36 or nonzero if a pty was successfully allocated. On success, open file 36 or nonzero if a pty was successfully allocated. On success, open file
37 descriptors for the pty and tty sides and the name of the tty side are 37 descriptors for the pty and tty sides and the name of the tty side are
38 returned (the buffer must be able to hold at least 64 characters). */ 38 returned (the buffer must be able to hold at least 64 characters). */
39 39
40int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf) 40int
41pty_allocate(int *ptyfd, int *ttyfd, char *namebuf)
41{ 42{
42#ifdef HAVE_OPENPTY 43#ifdef HAVE_OPENPTY
44 /* openpty(3) exists in OSF/1 and some other os'es */
45 int i;
43 46
44 /* openpty(3) exists in OSF/1 and some other os'es */ 47 i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL);
45 48 if (i < 0) {
46 int i; 49 error("openpty: %.100s", strerror(errno));
47 50 return 0;
48 i = openpty(ptyfd, ttyfd, namebuf, NULL, NULL); 51 }
49 52 return 1;
50 if (i < 0)
51 {
52 error("openpty: %.100s", strerror(errno));
53 return 0;
54 }
55
56 return 1;
57
58#else /* HAVE_OPENPTY */ 53#else /* HAVE_OPENPTY */
59#ifdef HAVE__GETPTY 54#ifdef HAVE__GETPTY
60 55 /* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates
61 /* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more 56 more pty's automagically when needed */
62 pty's automagically when needed */ 57 char *slave;
63 58
64 char *slave; 59 slave = _getpty(ptyfd, O_RDWR, 0622, 0);
65 60 if (slave == NULL) {
66 slave = _getpty(ptyfd, O_RDWR, 0622, 0); 61 error("_getpty: %.100s", strerror(errno));
67 if (slave == NULL) 62 return 0;
68 { 63 }
69 error("_getpty: %.100s", strerror(errno)); 64 strcpy(namebuf, slave);
70 return 0; 65 /* Open the slave side. */
71 } 66 *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
72 strcpy(namebuf, slave); 67 if (*ttyfd < 0) {
73 /* Open the slave side. */ 68 error("%.200s: %.100s", namebuf, strerror(errno));
74 *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); 69 close(*ptyfd);
75 if (*ttyfd < 0) 70 return 0;
76 { 71 }
77 error("%.200s: %.100s", namebuf, strerror(errno)); 72 return 1;
78 close(*ptyfd);
79 return 0;
80 }
81 return 1;
82
83#else /* HAVE__GETPTY */ 73#else /* HAVE__GETPTY */
84#ifdef HAVE_DEV_PTMX 74#ifdef HAVE_DEV_PTMX
85 /* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 also has 75 /* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
86 bsd-style ptys, but they simply do not work.) */ 76 also has bsd-style ptys, but they simply do not work.) */
87 77 int ptm;
88 int ptm; 78 char *pts;
89 char *pts; 79
90 80 ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
91 ptm = open("/dev/ptmx", O_RDWR|O_NOCTTY); 81 if (ptm < 0) {
92 if (ptm < 0) 82 error("/dev/ptmx: %.100s", strerror(errno));
93 { 83 return 0;
94 error("/dev/ptmx: %.100s", strerror(errno)); 84 }
95 return 0; 85 if (grantpt(ptm) < 0) {
96 } 86 error("grantpt: %.100s", strerror(errno));
97 if (grantpt(ptm) < 0) 87 return 0;
98 { 88 }
99 error("grantpt: %.100s", strerror(errno)); 89 if (unlockpt(ptm) < 0) {
100 return 0; 90 error("unlockpt: %.100s", strerror(errno));
101 } 91 return 0;
102 if (unlockpt(ptm) < 0) 92 }
103 { 93 pts = ptsname(ptm);
104 error("unlockpt: %.100s", strerror(errno)); 94 if (pts == NULL)
105 return 0; 95 error("Slave pty side name could not be obtained.");
106 } 96 strcpy(namebuf, pts);
107 pts = ptsname(ptm); 97 *ptyfd = ptm;
108 if (pts == NULL) 98
109 error("Slave pty side name could not be obtained."); 99 /* Open the slave side. */
110 strcpy(namebuf, pts); 100 *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
111 *ptyfd = ptm; 101 if (*ttyfd < 0) {
112 102 error("%.100s: %.100s", namebuf, strerror(errno));
113 /* Open the slave side. */ 103 close(*ptyfd);
114 *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); 104 return 0;
115 if (*ttyfd < 0) 105 }
116 { 106 /* Push the appropriate streams modules, as described in Solaris
117 error("%.100s: %.100s", namebuf, strerror(errno)); 107 pts(7). */
118 close(*ptyfd); 108 if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
119 return 0; 109 error("ioctl I_PUSH ptem: %.100s", strerror(errno));
120 } 110 if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
121 /* Push the appropriate streams modules, as described in Solaris pts(7). */ 111 error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
122 if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) 112 if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
123 error("ioctl I_PUSH ptem: %.100s", strerror(errno)); 113 error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
124 if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) 114 return 1;
125 error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
126 if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
127 error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
128 return 1;
129
130#else /* HAVE_DEV_PTMX */ 115#else /* HAVE_DEV_PTMX */
131#ifdef HAVE_DEV_PTS_AND_PTC 116#ifdef HAVE_DEV_PTS_AND_PTC
117 /* AIX-style pty code. */
118 const char *name;
132 119
133 /* AIX-style pty code. */ 120 *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
134 121 if (*ptyfd < 0) {
135 const char *name; 122 error("Could not open /dev/ptc: %.100s", strerror(errno));
136 123 return 0;
137 *ptyfd = open("/dev/ptc", O_RDWR|O_NOCTTY); 124 }
138 if (*ptyfd < 0) 125 name = ttyname(*ptyfd);
139 { 126 if (!name)
140 error("Could not open /dev/ptc: %.100s", strerror(errno)); 127 fatal("Open of /dev/ptc returns device for which ttyname fails.");
141 return 0; 128 strcpy(namebuf, name);
142 } 129 *ttyfd = open(name, O_RDWR | O_NOCTTY);
143 name = ttyname(*ptyfd); 130 if (*ttyfd < 0) {
144 if (!name) 131 error("Could not open pty slave side %.100s: %.100s",
145 fatal("Open of /dev/ptc returns device for which ttyname fails."); 132 name, strerror(errno));
146 strcpy(namebuf, name); 133 close(*ptyfd);
147 *ttyfd = open(name, O_RDWR|O_NOCTTY); 134 return 0;
148 if (*ttyfd < 0) 135 }
149 { 136 return 1;
150 error("Could not open pty slave side %.100s: %.100s",
151 name, strerror(errno));
152 close(*ptyfd);
153 return 0;
154 }
155 return 1;
156
157#else /* HAVE_DEV_PTS_AND_PTC */ 137#else /* HAVE_DEV_PTS_AND_PTC */
158 /* BSD-style pty code. */ 138 /* BSD-style pty code. */
159 139 char buf[64];
160 char buf[64]; 140 int i;
161 int i; 141 const char *ptymajors =
162 const char *ptymajors = 142 "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
163 "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; 143 const char *ptyminors = "0123456789abcdef";
164 const char *ptyminors = "0123456789abcdef"; 144 int num_minors = strlen(ptyminors);
165 int num_minors = strlen(ptyminors); 145 int num_ptys = strlen(ptymajors) * num_minors;
166 int num_ptys = strlen(ptymajors) * num_minors; 146
167 147 for (i = 0; i < num_ptys; i++) {
168 for (i = 0; i < num_ptys; i++) 148 snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
169 { 149 ptyminors[i % num_minors]);
170 snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], 150 *ptyfd = open(buf, O_RDWR | O_NOCTTY);
171 ptyminors[i % num_minors]); 151 if (*ptyfd < 0)
172 *ptyfd = open(buf, O_RDWR|O_NOCTTY); 152 continue;
173 if (*ptyfd < 0) 153 snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors],
174 continue; 154 ptyminors[i % num_minors]);
175 snprintf(namebuf, sizeof buf, "/dev/tty%c%c", ptymajors[i / num_minors], 155
176 ptyminors[i % num_minors]); 156 /* Open the slave side. */
177 157 *ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
178 /* Open the slave side. */ 158 if (*ttyfd < 0) {
179 *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); 159 error("%.100s: %.100s", namebuf, strerror(errno));
180 if (*ttyfd < 0) 160 close(*ptyfd);
181 { 161 return 0;
182 error("%.100s: %.100s", namebuf, strerror(errno)); 162 }
183 close(*ptyfd); 163 return 1;
184 return 0;
185 } 164 }
186 return 1; 165 return 0;
187 }
188 return 0;
189#endif /* HAVE_DEV_PTS_AND_PTC */ 166#endif /* HAVE_DEV_PTS_AND_PTC */
190#endif /* HAVE_DEV_PTMX */ 167#endif /* HAVE_DEV_PTMX */
191#endif /* HAVE__GETPTY */ 168#endif /* HAVE__GETPTY */
192#endif /* HAVE_OPENPTY */ 169#endif /* HAVE_OPENPTY */
193} 170}
194 171
195/* Releases the tty. Its ownership is returned to root, and permissions to 172/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */
196 0666. */
197 173
198void pty_release(const char *ttyname) 174void
175pty_release(const char *ttyname)
199{ 176{
200 if (chown(ttyname, (uid_t)0, (gid_t)0) < 0) 177 if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0)
201 debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); 178 debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno));
202 if (chmod(ttyname, (mode_t)0666) < 0) 179 if (chmod(ttyname, (mode_t) 0666) < 0)
203 debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); 180 debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));
204} 181}
205 182
206/* Makes the tty the processes controlling tty and sets it to sane modes. */ 183/* Makes the tty the processes controlling tty and sets it to sane modes. */
207 184
208void pty_make_controlling_tty(int *ttyfd, const char *ttyname) 185void
186pty_make_controlling_tty(int *ttyfd, const char *ttyname)
209{ 187{
210 int fd; 188 int fd;
211 189
212 /* First disconnect from the old controlling tty. */ 190 /* First disconnect from the old controlling tty. */
213#ifdef TIOCNOTTY 191#ifdef TIOCNOTTY
214 fd = open("/dev/tty", O_RDWR|O_NOCTTY); 192 fd = open("/dev/tty", O_RDWR | O_NOCTTY);
215 if (fd >= 0) 193 if (fd >= 0) {
216 { 194 (void) ioctl(fd, TIOCNOTTY, NULL);
217 (void)ioctl(fd, TIOCNOTTY, NULL); 195 close(fd);
218 close(fd); 196 }
219 }
220#endif /* TIOCNOTTY */ 197#endif /* TIOCNOTTY */
221 if (setsid() < 0) 198 if (setsid() < 0)
222 error("setsid: %.100s", strerror(errno)); 199 error("setsid: %.100s", strerror(errno));
223 200
224 /* Verify that we are successfully disconnected from the controlling tty. */ 201 /* Verify that we are successfully disconnected from the
225 fd = open("/dev/tty", O_RDWR|O_NOCTTY); 202 controlling tty. */
226 if (fd >= 0) 203 fd = open("/dev/tty", O_RDWR | O_NOCTTY);
227 { 204 if (fd >= 0) {
228 error("Failed to disconnect from controlling tty."); 205 error("Failed to disconnect from controlling tty.");
229 close(fd); 206 close(fd);
230 } 207 }
231 208 /* Make it our controlling tty. */
232 /* Make it our controlling tty. */
233#ifdef TIOCSCTTY 209#ifdef TIOCSCTTY
234 debug("Setting controlling tty using TIOCSCTTY."); 210 debug("Setting controlling tty using TIOCSCTTY.");
235 /* We ignore errors from this, because HPSUX defines TIOCSCTTY, but returns 211 /* We ignore errors from this, because HPSUX defines TIOCSCTTY,
236 EINVAL with these arguments, and there is absolutely no documentation. */ 212 but returns EINVAL with these arguments, and there is
237 ioctl(*ttyfd, TIOCSCTTY, NULL); 213 absolutely no documentation. */
214 ioctl(*ttyfd, TIOCSCTTY, NULL);
238#endif /* TIOCSCTTY */ 215#endif /* TIOCSCTTY */
239 fd = open(ttyname, O_RDWR); 216 fd = open(ttyname, O_RDWR);
240 if (fd < 0) 217 if (fd < 0)
241 error("%.100s: %.100s", ttyname, strerror(errno)); 218 error("%.100s: %.100s", ttyname, strerror(errno));
242 else 219 else
243 close(fd); 220 close(fd);
244 221
245 /* Verify that we now have a controlling tty. */ 222 /* Verify that we now have a controlling tty. */
246 fd = open("/dev/tty", O_WRONLY); 223 fd = open("/dev/tty", O_WRONLY);
247 if (fd < 0) 224 if (fd < 0)
248 error("open /dev/tty failed - could not set controlling tty: %.100s", 225 error("open /dev/tty failed - could not set controlling tty: %.100s",
249 strerror(errno)); 226 strerror(errno));
250 else 227 else {
251 { 228 close(fd);
252 close(fd); 229 }
253 }
254} 230}
255 231
256/* Changes the window size associated with the pty. */ 232/* Changes the window size associated with the pty. */
257 233
258void pty_change_window_size(int ptyfd, int row, int col, 234void
259 int xpixel, int ypixel) 235pty_change_window_size(int ptyfd, int row, int col,
236 int xpixel, int ypixel)
260{ 237{
261 struct winsize w; 238 struct winsize w;
262 w.ws_row = row; 239 w.ws_row = row;
263 w.ws_col = col; 240 w.ws_col = col;
264 w.ws_xpixel = xpixel; 241 w.ws_xpixel = xpixel;
265 w.ws_ypixel = ypixel; 242 w.ws_ypixel = ypixel;
266 (void)ioctl(ptyfd, TIOCSWINSZ, &w); 243 (void) ioctl(ptyfd, TIOCSWINSZ, &w);
267} 244}
268