… | |
… | |
67 | * fd_tty _may_ also be set to an open fd to the slave device |
67 | * fd_tty _may_ also be set to an open fd to the slave device |
68 | */ |
68 | */ |
69 | static inline int |
69 | static inline int |
70 | get_pty_streams (int *fd_tty, char **ttydev) |
70 | get_pty_streams (int *fd_tty, char **ttydev) |
71 | { |
71 | { |
72 | #ifdef NO_SETOWNER_TTYDEV |
72 | #if defined(HAVE_GRANTPT) && defined(HAVE_UNLOCKPT) |
|
|
73 | # if defined(PTYS_ARE_GETPT) || defined(PTYS_ARE_POSIX) || defined(PTYS_ARE_PTMX) |
73 | int pfd; |
74 | int pfd; |
74 | |
75 | |
75 | # ifdef PTYS_ARE_GETPT |
76 | # if defined(PTYS_ARE_GETPT) |
76 | pfd = getpt(); |
77 | pfd = getpt(); |
77 | # else |
|
|
78 | # ifdef PTYS_ARE_POSIX |
78 | # elif defined(PTYS_ARE_POSIX) |
79 | pfd = posix_openpt (O_RDWR); |
79 | pfd = posix_openpt (O_RDWR); |
80 | # else |
80 | # else |
81 | pfd = open ("/dev/ptmx", O_RDWR | O_NOCTTY, 0); |
81 | pfd = open ("/dev/ptmx", O_RDWR | O_NOCTTY, 0); |
82 | # endif |
|
|
83 | # endif |
82 | # endif |
84 | if (pfd >= 0) |
83 | if (pfd >= 0) |
85 | { |
84 | { |
86 | if (grantpt (pfd) == 0 /* change slave permissions */ |
85 | if (grantpt (pfd) == 0 /* change slave permissions */ |
87 | && unlockpt (pfd) == 0) |
86 | && unlockpt (pfd) == 0) |
88 | { /* slave now unlocked */ |
87 | { /* slave now unlocked */ |
89 | *ttydev = strdup (ptsname (pfd)); /* get slave's name */ |
88 | *ttydev = strdup (ptsname (pfd)); /* get slave's name */ |
90 | return pfd; |
89 | return pfd; |
91 | } |
90 | } |
|
|
91 | |
92 | close (pfd); |
92 | close (pfd); |
93 | } |
93 | } |
94 | #endif |
94 | # endif |
|
|
95 | #endif |
|
|
96 | |
95 | return -1; |
97 | return -1; |
96 | } |
98 | } |
97 | |
99 | |
98 | static inline int |
100 | static inline int |
99 | get_pty_openpty (int *fd_tty, char **ttydev) |
101 | get_pty_openpty (int *fd_tty, char **ttydev) |
100 | { |
102 | { |
101 | #ifdef PTYS_ARE_OPENPTY |
103 | #ifdef PTYS_ARE_OPENPTY |
102 | int pfd; |
104 | int pfd; |
103 | int res; |
105 | int res; |
104 | char tty_name[sizeof "/dev/pts/????\0"]; |
106 | char tty_name[32]; |
105 | |
107 | |
106 | res = openpty (&pfd, fd_tty, tty_name, NULL, NULL); |
108 | res = openpty (&pfd, fd_tty, tty_name, NULL, NULL); |
107 | if (res != -1) |
109 | if (res != -1) |
108 | { |
110 | { |
109 | *ttydev = strdup (tty_name); |
111 | *ttydev = strdup (tty_name); |
110 | return pfd; |
112 | return pfd; |
111 | } |
113 | } |
112 | #endif |
114 | #endif |
|
|
115 | |
113 | return -1; |
116 | return -1; |
114 | } |
117 | } |
115 | |
118 | |
116 | static inline int |
119 | static inline int |
117 | get_pty__getpty (int *fd_tty, char **ttydev) |
120 | get_pty__getpty (int *fd_tty, char **ttydev) |
… | |
… | |
121 | |
124 | |
122 | *ttydev = _getpty (&pfd, O_RDWR | O_NONBLOCK | O_NOCTTY, 0622, 0); |
125 | *ttydev = _getpty (&pfd, O_RDWR | O_NONBLOCK | O_NOCTTY, 0622, 0); |
123 | if (*ttydev != NULL) |
126 | if (*ttydev != NULL) |
124 | return pfd; |
127 | return pfd; |
125 | #endif |
128 | #endif |
|
|
129 | |
126 | return -1; |
130 | return -1; |
127 | } |
131 | } |
128 | |
132 | |
129 | static inline int |
133 | static inline int |
130 | get_pty_ptc (int *fd_tty, char **ttydev) |
134 | get_pty_ptc (int *fd_tty, char **ttydev) |
… | |
… | |
136 | { |
140 | { |
137 | *ttydev = strdup (ttyname (pfd)); |
141 | *ttydev = strdup (ttyname (pfd)); |
138 | return pfd; |
142 | return pfd; |
139 | } |
143 | } |
140 | #endif |
144 | #endif |
|
|
145 | |
141 | return -1; |
146 | return -1; |
142 | } |
147 | } |
143 | |
148 | |
144 | static inline int |
149 | static inline int |
145 | get_pty_clone (int *fd_tty, char **ttydev) |
150 | get_pty_clone (int *fd_tty, char **ttydev) |
… | |
… | |
151 | { |
156 | { |
152 | *ttydev = strdup (ptsname (pfd)); |
157 | *ttydev = strdup (ptsname (pfd)); |
153 | return pfd; |
158 | return pfd; |
154 | } |
159 | } |
155 | #endif |
160 | #endif |
|
|
161 | |
156 | return -1; |
162 | return -1; |
157 | } |
163 | } |
158 | |
164 | |
159 | static inline int |
165 | static inline int |
160 | get_pty_numeric (int *fd_tty, char **ttydev) |
166 | get_pty_numeric (int *fd_tty, char **ttydev) |
161 | { |
167 | { |
162 | #ifdef PTYS_ARE_NUMERIC |
168 | #ifdef PTYS_ARE_NUMERIC |
163 | int pfd; |
169 | int pfd; |
164 | int idx; |
170 | int idx; |
165 | char *c1, *c2; |
171 | char *c1, *c2; |
166 | char pty_name[] = "/dev/ptyp???"; |
172 | char pty_name[] = "/dev/ptyp???"; |
167 | char tty_name[] = "/dev/ttyp???"; |
173 | char tty_name[] = "/dev/ttyp???"; |
168 | |
174 | |
169 | c1 = &(pty_name[sizeof (pty_name) - 4]); |
175 | c1 = &(pty_name[sizeof (pty_name) - 4]); |
170 | c2 = &(tty_name[sizeof (tty_name) - 4]); |
176 | c2 = &(tty_name[sizeof (tty_name) - 4]); |
|
|
177 | |
171 | for (idx = 0; idx < 256; idx++) |
178 | for (idx = 0; idx < 256; idx++) |
172 | { |
179 | { |
173 | sprintf (c1, "%d", idx); |
180 | sprintf (c1, "%d", idx); |
174 | sprintf (c2, "%d", idx); |
181 | sprintf (c2, "%d", idx); |
|
|
182 | |
175 | if (access (tty_name, F_OK) < 0) |
183 | if (access (tty_name, F_OK) < 0) |
176 | { |
184 | { |
177 | idx = 256; |
185 | idx = 256; |
178 | break; |
186 | break; |
179 | } |
187 | } |
180 | |
188 | |
181 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
189 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
182 | { |
190 | { |
183 | if (access (tty_name, R_OK | W_OK) == 0) |
191 | if (access (tty_name, R_OK | W_OK) == 0) |
184 | { |
192 | { |
185 | *ttydev = strdup (tty_name); |
193 | *ttydev = strdup (tty_name); |
186 | return pfd; |
194 | return pfd; |
187 | } |
195 | } |
188 | |
196 | |
189 | close (pfd); |
197 | close (pfd); |
190 | } |
198 | } |
191 | } |
199 | } |
192 | #endif |
200 | #endif |
|
|
201 | |
193 | return -1; |
202 | return -1; |
194 | } |
203 | } |
195 | |
204 | |
196 | static inline int |
205 | static inline int |
197 | get_pty_searched (int *fd_tty, char **ttydev) |
206 | get_pty_searched (int *fd_tty, char **ttydev) |
198 | { |
207 | { |
… | |
… | |
201 | # define PTYCHAR1 "pqrstuvwxyz" |
210 | # define PTYCHAR1 "pqrstuvwxyz" |
202 | # endif |
211 | # endif |
203 | # ifndef PTYCHAR2 |
212 | # ifndef PTYCHAR2 |
204 | # define PTYCHAR2 "0123456789abcdef" |
213 | # define PTYCHAR2 "0123456789abcdef" |
205 | # endif |
214 | # endif |
206 | int pfd; |
215 | int pfd; |
207 | const char *c1, *c2; |
216 | const char *c1, *c2; |
208 | char pty_name[] = "/dev/pty??"; |
217 | char pty_name[] = "/dev/pty??"; |
209 | char tty_name[] = "/dev/tty??"; |
218 | char tty_name[] = "/dev/tty??"; |
210 | |
219 | |
211 | for (c1 = PTYCHAR1; *c1; c1++) |
220 | for (c1 = PTYCHAR1; *c1; c1++) |
212 | { |
221 | { |
213 | pty_name[ (sizeof (pty_name) - 3)] = |
222 | pty_name[ (sizeof (pty_name) - 3)] = |
214 | tty_name[ (sizeof (pty_name) - 3)] = *c1; |
223 | tty_name[ (sizeof (pty_name) - 3)] = *c1; |
|
|
224 | |
215 | for (c2 = PTYCHAR2; *c2; c2++) |
225 | for (c2 = PTYCHAR2; *c2; c2++) |
216 | { |
226 | { |
217 | pty_name[ (sizeof (pty_name) - 2)] = |
227 | pty_name[ (sizeof (pty_name) - 2)] = |
218 | tty_name[ (sizeof (pty_name) - 2)] = *c2; |
228 | tty_name[ (sizeof (pty_name) - 2)] = *c2; |
|
|
229 | |
219 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
230 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
220 | { |
231 | { |
221 | if (access (tty_name, R_OK | W_OK) == 0) |
232 | if (access (tty_name, R_OK | W_OK) == 0) |
222 | { |
233 | { |
223 | *ttydev = strdup (tty_name); |
234 | *ttydev = strdup (tty_name); |
224 | return pfd; |
235 | return pfd; |
225 | } |
236 | } |
226 | |
237 | |
227 | close (pfd); |
238 | close (pfd); |
228 | } |
239 | } |
229 | } |
240 | } |
230 | } |
241 | } |
231 | #endif |
242 | #endif |
|
|
243 | |
232 | return -1; |
244 | return -1; |
233 | } |
245 | } |
234 | |
246 | |
235 | static int |
247 | static int |
236 | get_pty (int *fd_tty, char **ttydev) |
248 | get_pty (int *fd_tty, char **ttydev) |
237 | { |
249 | { |
… | |
… | |
243 | || (pfd = get_pty_ptc (fd_tty, ttydev)) != -1 |
255 | || (pfd = get_pty_ptc (fd_tty, ttydev)) != -1 |
244 | || (pfd = get_pty_clone (fd_tty, ttydev)) != -1 |
256 | || (pfd = get_pty_clone (fd_tty, ttydev)) != -1 |
245 | || (pfd = get_pty_numeric (fd_tty, ttydev)) != -1 |
257 | || (pfd = get_pty_numeric (fd_tty, ttydev)) != -1 |
246 | || (pfd = get_pty_searched (fd_tty, ttydev)) != -1) |
258 | || (pfd = get_pty_searched (fd_tty, ttydev)) != -1) |
247 | return pfd; |
259 | return pfd; |
|
|
260 | |
248 | return -1; |
261 | return -1; |
249 | } |
262 | } |
250 | |
263 | |
251 | /*----------------------------------------------------------------------*/ |
264 | /*----------------------------------------------------------------------*/ |
252 | /* |
265 | /* |
… | |
… | |
263 | * Make our tty a controlling tty so that /dev/tty points to us |
276 | * Make our tty a controlling tty so that /dev/tty points to us |
264 | */ |
277 | */ |
265 | static int |
278 | static int |
266 | control_tty (int fd_tty) |
279 | control_tty (int fd_tty) |
267 | { |
280 | { |
268 | int fd; |
|
|
269 | |
|
|
270 | /* ---------------------------------------- */ |
|
|
271 | setsid (); |
281 | setsid (); |
272 | |
282 | |
273 | /* ---------------------------------------- */ |
|
|
274 | # if defined(PTYS_ARE_PTMX) && defined(I_PUSH) |
283 | #if defined(PTYS_ARE_PTMX) && defined(I_PUSH) |
275 | /* |
284 | /* |
276 | * Push STREAMS modules: |
285 | * Push STREAMS modules: |
277 | * ptem: pseudo-terminal hardware emulation module. |
286 | * ptem: pseudo-terminal hardware emulation module. |
278 | * ldterm: standard terminal line discipline. |
287 | * ldterm: standard terminal line discipline. |
279 | * ttcompat: V7, 4BSD and XENIX STREAMS compatibility module. |
288 | * ttcompat: V7, 4BSD and XENIX STREAMS compatibility module. |
… | |
… | |
287 | * documentation is really unclear about whether it is any close () on |
296 | * documentation is really unclear about whether it is any close () on |
288 | * the master side or the last close () - i.e. a proper STREAMS dismantling |
297 | * the master side or the last close () - i.e. a proper STREAMS dismantling |
289 | * close () - on the master side which causes a hang up to be sent |
298 | * close () - on the master side which causes a hang up to be sent |
290 | * through - Geoff Wing |
299 | * through - Geoff Wing |
291 | */ |
300 | */ |
292 | # ifdef HAVE_ISASTREAM |
301 | # ifdef HAVE_ISASTREAM |
293 | if (isastream (fd_tty) == 1) |
302 | if (isastream (fd_tty) == 1) |
294 | # endif |
303 | # endif |
295 | { |
304 | { |
296 | ioctl (fd_tty, I_PUSH, "ptem"); |
305 | ioctl (fd_tty, I_PUSH, "ptem"); |
297 | ioctl (fd_tty, I_PUSH, "ldterm"); |
306 | ioctl (fd_tty, I_PUSH, "ldterm"); |
298 | ioctl (fd_tty, I_PUSH, "ttcompat"); |
307 | ioctl (fd_tty, I_PUSH, "ttcompat"); |
299 | } |
308 | } |
300 | # endif |
309 | #endif |
301 | /* ---------------------------------------- */ |
310 | |
302 | fd = ioctl (fd_tty, TIOCSCTTY, NULL); |
311 | ioctl (fd_tty, TIOCSCTTY, NULL); |
303 | /* ---------------------------------------- */ |
312 | |
304 | fd = open ("/dev/tty", O_WRONLY); |
313 | int fd = open ("/dev/tty", O_WRONLY); |
305 | if (fd < 0) |
314 | if (fd < 0) |
306 | return -1; /* fatal */ |
315 | return -1; /* fatal */ |
|
|
316 | |
307 | close (fd); |
317 | close (fd); |
308 | /* ---------------------------------------- */ |
|
|
309 | |
318 | |
310 | return 0; |
319 | return 0; |
311 | } |
320 | } |
312 | |
321 | |
313 | void |
322 | void |
… | |
… | |
351 | } |
360 | } |
352 | } |
361 | } |
353 | #endif |
362 | #endif |
354 | } |
363 | } |
355 | |
364 | |
356 | ///////////////////////////////////////////////////////////////////////////// |
|
|
357 | |
|
|
358 | #ifndef NO_SETOWNER_TTYDEV |
|
|
359 | static struct ttyconf { |
365 | static struct ttyconf { |
360 | gid_t gid; |
366 | gid_t gid; |
361 | mode_t mode; |
367 | mode_t mode; |
362 | |
368 | |
363 | ttyconf () |
369 | ttyconf () |
… | |
… | |
372 | } |
378 | } |
373 | else |
379 | else |
374 | #endif /* TTY_GID_SUPPORT */ |
380 | #endif /* TTY_GID_SUPPORT */ |
375 | { |
381 | { |
376 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
382 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
377 | gid = getgid (); |
383 | gid = 0; |
378 | } |
384 | } |
379 | } |
385 | } |
380 | } ttyconf; |
386 | } ttyconf; |
381 | |
|
|
382 | ///////////////////////////////////////////////////////////////////////////// |
|
|
383 | |
|
|
384 | void |
|
|
385 | rxvt_ptytty_unix::privileges (rxvt_privaction action) |
|
|
386 | { |
|
|
387 | if (!name || !*name) |
|
|
388 | return; |
|
|
389 | |
|
|
390 | if (action == SAVE) |
|
|
391 | { |
|
|
392 | # ifndef RESET_TTY_TO_COMMON_DEFAULTS |
|
|
393 | /* store original tty status for restoration rxvt_clean_exit () -- rgg 04/12/95 */ |
|
|
394 | if (lstat (name, &savestat) < 0) /* you lose out */ |
|
|
395 | ; |
|
|
396 | else |
|
|
397 | # endif |
|
|
398 | { |
|
|
399 | saved = true; |
|
|
400 | chown (name, getuid (), ttyconf.gid); /* fail silently */ |
|
|
401 | chmod (name, ttyconf.mode); |
|
|
402 | # ifdef HAVE_REVOKE |
|
|
403 | revoke (name); |
|
|
404 | # endif |
|
|
405 | } |
|
|
406 | } |
|
|
407 | else |
|
|
408 | { /* action == RESTORE */ |
|
|
409 | # ifndef RESET_TTY_TO_COMMON_DEFAULTS |
|
|
410 | if (saved) |
|
|
411 | { |
|
|
412 | chmod (name, savestat.st_mode); |
|
|
413 | chown (name, savestat.st_uid, savestat.st_gid); |
|
|
414 | } |
|
|
415 | # else |
|
|
416 | chmod (name, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); |
|
|
417 | chown (name, 0, 0); |
|
|
418 | # endif |
|
|
419 | |
|
|
420 | } |
|
|
421 | } |
|
|
422 | #endif |
|
|
423 | |
387 | |
424 | rxvt_ptytty_unix::rxvt_ptytty_unix () |
388 | rxvt_ptytty_unix::rxvt_ptytty_unix () |
425 | { |
389 | { |
426 | pty = tty = -1; |
390 | pty = tty = -1; |
427 | name = 0; |
391 | name = 0; |
428 | #ifndef NO_SETOWNER_TTYDEV |
|
|
429 | saved = false; |
|
|
430 | #endif |
|
|
431 | #if UTMP_SUPPORT |
392 | #if UTMP_SUPPORT |
432 | cmd_pid = 0; |
393 | cmd_pid = 0; |
433 | #endif |
394 | #endif |
434 | } |
395 | } |
435 | |
396 | |
… | |
… | |
442 | } |
403 | } |
443 | |
404 | |
444 | void |
405 | void |
445 | rxvt_ptytty_unix::put () |
406 | rxvt_ptytty_unix::put () |
446 | { |
407 | { |
447 | #ifndef NO_SETOWNER_TTYDEV |
408 | chmod (name, RESTORE_TTY_MODE); |
448 | privileges (RESTORE); |
409 | chown (name, 0, ttyconf.gid); |
449 | #endif |
|
|
450 | |
410 | |
451 | if (pty >= 0) close (pty); |
|
|
452 | close_tty (); |
411 | close_tty (); |
|
|
412 | |
|
|
413 | if (pty >= 0) |
|
|
414 | close (pty); |
|
|
415 | |
453 | free (name); |
416 | free (name); |
454 | |
417 | |
455 | pty = tty = -1; |
418 | pty = tty = -1; |
456 | name = 0; |
419 | name = 0; |
457 | } |
420 | } |
… | |
… | |
467 | |
430 | |
468 | /* get slave (tty) */ |
431 | /* get slave (tty) */ |
469 | if (tty < 0) |
432 | if (tty < 0) |
470 | { |
433 | { |
471 | #ifndef NO_SETOWNER_TTYDEV |
434 | #ifndef NO_SETOWNER_TTYDEV |
472 | privileges (SAVE); |
435 | chown (name, getuid (), ttyconf.gid); /* fail silently */ |
|
|
436 | chmod (name, ttyconf.mode); |
|
|
437 | # ifdef HAVE_REVOKE |
|
|
438 | revoke (name); |
|
|
439 | # endif |
473 | #endif |
440 | #endif |
474 | |
441 | |
475 | if ((tty = get_tty (name)) < 0) |
442 | if ((tty = get_tty (name)) < 0) |
476 | { |
443 | { |
477 | put (); |
444 | put (); |
… | |
… | |
630 | close (sv[1]); |
597 | close (sv[1]); |
631 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
598 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
632 | } |
599 | } |
633 | else |
600 | else |
634 | { |
601 | { |
635 | setgid (getegid ()); |
|
|
636 | setuid (geteuid ()); |
|
|
637 | |
|
|
638 | // server, pty-helper |
602 | // server, pty-helper |
639 | sock_fd = sv[1]; |
603 | sock_fd = sv[1]; |
640 | |
604 | |
641 | for (int fd = 0; fd < 1023; fd++) |
605 | for (int fd = 0; fd < 1023; fd++) |
642 | if (fd != sock_fd && fd != 1) |
606 | if (fd != sock_fd) |
643 | close (fd); |
607 | close (fd); |
644 | |
608 | |
645 | serve (); |
609 | serve (); |
646 | _exit (EXIT_SUCCESS); |
610 | _exit (EXIT_SUCCESS); |
647 | } |
611 | } |
648 | } |
612 | } |
|
|
613 | |
649 | #endif |
614 | #endif |
650 | |
615 | |
651 | // a "factory" *g* |
616 | // a "factory" *g* |
652 | rxvt_ptytty * |
617 | rxvt_ptytty * |
653 | rxvt_new_ptytty () |
618 | rxvt_new_ptytty () |