Annotation of src/usr.bin/ssh/session.c, Revision 1.60
1.1 markus 1: /*
2: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3: * All rights reserved
1.37 deraadt 4: *
5: * As far as I am concerned, the code I have written for this software
6: * can be used freely for any purpose. Any derived versions of this
7: * software must be clearly marked as such, and if the derived work is
8: * incompatible with the protocol description in the RFC file, it must be
9: * called by a name other than "ssh" or "Secure Shell".
10: *
1.2 markus 11: * SSH2 support by Markus Friedl.
1.58 deraadt 12: * Copyright (c) 2000 Markus Friedl. All rights reserved.
1.37 deraadt 13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.2 markus 33: */
1.1 markus 34:
35: #include "includes.h"
1.60 ! markus 36: RCSID("$OpenBSD: session.c,v 1.59 2001/03/04 01:46:30 djm Exp $");
1.1 markus 37:
1.51 markus 38: #include "ssh.h"
39: #include "ssh1.h"
40: #include "ssh2.h"
1.1 markus 41: #include "xmalloc.h"
1.59 djm 42: #include "sshpty.h"
1.1 markus 43: #include "packet.h"
44: #include "buffer.h"
45: #include "mpaux.h"
46: #include "uidswap.h"
47: #include "compat.h"
48: #include "channels.h"
49: #include "nchan.h"
1.2 markus 50: #include "bufaux.h"
51: #include "auth.h"
1.19 markus 52: #include "auth-options.h"
1.50 markus 53: #include "pathnames.h"
1.51 markus 54: #include "log.h"
55: #include "servconf.h"
1.59 djm 56: #include "sshlogin.h"
1.51 markus 57: #include "serverloop.h"
58: #include "canohost.h"
1.55 itojun 59: #include "session.h"
1.2 markus 60:
1.28 millert 61: #ifdef HAVE_LOGIN_CAP
62: #include <login_cap.h>
63: #endif
64:
1.1 markus 65: /* types */
66:
67: #define TTYSZ 64
68: typedef struct Session Session;
69: struct Session {
70: int used;
71: int self;
1.7 markus 72: int extended;
1.1 markus 73: struct passwd *pw;
74: pid_t pid;
75: /* tty */
76: char *term;
77: int ptyfd, ttyfd, ptymaster;
78: int row, col, xpixel, ypixel;
79: char tty[TTYSZ];
80: /* X11 */
81: char *display;
82: int screen;
83: char *auth_proto;
84: char *auth_data;
1.7 markus 85: int single_connection;
1.1 markus 86: /* proto 2 */
87: int chanid;
88: };
89:
90: /* func */
91:
92: Session *session_new(void);
93: void session_set_fds(Session *s, int fdin, int fdout, int fderr);
94: void session_pty_cleanup(Session *s);
1.9 markus 95: void session_proctitle(Session *s);
1.1 markus 96: void do_exec_pty(Session *s, const char *command, struct passwd * pw);
97: void do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
1.41 markus 98: void do_login(Session *s, const char *command);
1.60 ! markus 99: void do_child(Session *s, const char *command);
1.1 markus 100:
101: /* import */
102: extern ServerOptions options;
103: extern char *__progname;
104: extern int log_stderr;
105: extern int debug_flag;
1.45 markus 106: extern u_int utmp_len;
1.1 markus 107:
1.21 markus 108: extern int startup_pipe;
109:
1.1 markus 110: /* Local Xauthority file. */
111: static char *xauthfile;
112:
1.34 markus 113: /* original command from peer. */
1.53 stevesk 114: char *original_command = NULL;
1.34 markus 115:
1.1 markus 116: /* data */
117: #define MAX_SESSIONS 10
118: Session sessions[MAX_SESSIONS];
119:
1.28 millert 120: #ifdef HAVE_LOGIN_CAP
121: static login_cap_t *lc;
122: #endif
123:
1.1 markus 124: /*
125: * Remove local Xauthority file.
126: */
127: void
128: xauthfile_cleanup_proc(void *ignore)
129: {
130: debug("xauthfile_cleanup_proc called");
131:
132: if (xauthfile != NULL) {
133: char *p;
134: unlink(xauthfile);
135: p = strrchr(xauthfile, '/');
136: if (p != NULL) {
137: *p = '\0';
138: rmdir(xauthfile);
139: }
140: xfree(xauthfile);
141: xauthfile = NULL;
142: }
143: }
144:
145: /*
146: * Function to perform cleanup if we get aborted abnormally (e.g., due to a
147: * dropped connection).
148: */
1.4 markus 149: void
1.1 markus 150: pty_cleanup_proc(void *session)
151: {
152: Session *s=session;
153: if (s == NULL)
154: fatal("pty_cleanup_proc: no session");
155: debug("pty_cleanup_proc: %s", s->tty);
156:
157: if (s->pid != 0) {
158: /* Record that the user has logged out. */
159: record_logout(s->pid, s->tty);
160: }
161:
162: /* Release the pseudo-tty. */
163: pty_release(s->tty);
164: }
165:
166: /*
167: * Prepares for an interactive session. This is called after the user has
168: * been successfully authenticated. During this message exchange, pseudo
169: * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
170: * are requested, etc.
171: */
1.4 markus 172: void
1.1 markus 173: do_authenticated(struct passwd * pw)
174: {
175: Session *s;
1.33 markus 176: int type, fd;
1.1 markus 177: int compression_level = 0, enable_compression_after_reply = 0;
178: int have_pty = 0;
179: char *command;
180: int n_bytes;
181: int plen;
1.45 markus 182: u_int proto_len, data_len, dlen;
1.57 markus 183: int screen_flag;
1.1 markus 184:
185: /*
186: * Cancel the alarm we set to limit the time taken for
187: * authentication.
188: */
189: alarm(0);
1.23 deraadt 190: if (startup_pipe != -1) {
191: close(startup_pipe);
192: startup_pipe = -1;
193: }
1.1 markus 194:
195: /*
196: * Inform the channel mechanism that we are the server side and that
197: * the client may request to connect to any port at all. (The user
198: * could do it anyway, and we wouldn\'t know what is permitted except
199: * by the client telling us, so we can equally well trust the client
200: * not to request anything bogus.)
201: */
1.39 markus 202: if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
1.1 markus 203: channel_permit_all_opens();
204:
205: s = session_new();
1.7 markus 206: s->pw = pw;
1.1 markus 207:
1.28 millert 208: #ifdef HAVE_LOGIN_CAP
209: if ((lc = login_getclass(pw->pw_class)) == NULL) {
210: error("unable to get login class");
211: return;
212: }
213: #endif
214:
1.1 markus 215: /*
216: * We stay in this loop until the client requests to execute a shell
217: * or a command.
218: */
219: for (;;) {
220: int success = 0;
221:
222: /* Get a packet from the client. */
223: type = packet_read(&plen);
224:
225: /* Process the packet. */
226: switch (type) {
227: case SSH_CMSG_REQUEST_COMPRESSION:
228: packet_integrity_check(plen, 4, type);
229: compression_level = packet_get_int();
230: if (compression_level < 1 || compression_level > 9) {
231: packet_send_debug("Received illegal compression level %d.",
232: compression_level);
233: break;
234: }
235: /* Enable compression after we have responded with SUCCESS. */
236: enable_compression_after_reply = 1;
237: success = 1;
238: break;
239:
240: case SSH_CMSG_REQUEST_PTY:
241: if (no_pty_flag) {
242: debug("Allocating a pty not permitted for this authentication.");
243: break;
244: }
245: if (have_pty)
246: packet_disconnect("Protocol error: you already have a pty.");
247:
248: debug("Allocating pty.");
249:
250: /* Allocate a pty and open it. */
251: if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
252: sizeof(s->tty))) {
253: error("Failed to allocate pty.");
254: break;
255: }
256: fatal_add_cleanup(pty_cleanup_proc, (void *)s);
257: pty_setowner(pw, s->tty);
258:
259: /* Get TERM from the packet. Note that the value may be of arbitrary length. */
260: s->term = packet_get_string(&dlen);
261: packet_integrity_check(dlen, strlen(s->term), type);
262: /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */
263: /* Remaining bytes */
264: n_bytes = plen - (4 + dlen + 4 * 4);
265:
266: if (strcmp(s->term, "") == 0) {
267: xfree(s->term);
268: s->term = NULL;
269: }
270: /* Get window size from the packet. */
271: s->row = packet_get_int();
272: s->col = packet_get_int();
273: s->xpixel = packet_get_int();
274: s->ypixel = packet_get_int();
275: pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
276:
277: /* Get tty modes from the packet. */
278: tty_parse_modes(s->ttyfd, &n_bytes);
279: packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type);
1.10 markus 280:
281: session_proctitle(s);
1.1 markus 282:
283: /* Indicate that we now have a pty. */
284: success = 1;
285: have_pty = 1;
286: break;
287:
288: case SSH_CMSG_X11_REQUEST_FORWARDING:
289: if (!options.x11_forwarding) {
290: packet_send_debug("X11 forwarding disabled in server configuration file.");
291: break;
292: }
1.16 markus 293: if (!options.xauth_location) {
294: packet_send_debug("No xauth program; cannot forward with spoofing.");
295: break;
296: }
1.1 markus 297: if (no_x11_forwarding_flag) {
298: packet_send_debug("X11 forwarding not permitted for this authentication.");
299: break;
300: }
301: debug("Received request for X11 forwarding with auth spoofing.");
302: if (s->display != NULL)
303: packet_disconnect("Protocol error: X11 display already set.");
304:
305: s->auth_proto = packet_get_string(&proto_len);
306: s->auth_data = packet_get_string(&data_len);
307:
1.57 markus 308: screen_flag = packet_get_protocol_flags() &
309: SSH_PROTOFLAG_SCREEN_NUMBER;
310: debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
311:
312: if (packet_remaining() == 4) {
313: if (!screen_flag)
314: debug2("Buggy client: "
315: "X11 screen flag missing");
1.56 markus 316: packet_integrity_check(plen,
317: 4 + proto_len + 4 + data_len + 4, type);
1.1 markus 318: s->screen = packet_get_int();
1.56 markus 319: } else {
320: packet_integrity_check(plen,
321: 4 + proto_len + 4 + data_len, type);
1.1 markus 322: s->screen = 0;
1.56 markus 323: }
1.1 markus 324: s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
325:
326: if (s->display == NULL)
327: break;
328:
329: /* Setup to always have a local .Xauthority. */
330: xauthfile = xmalloc(MAXPATHLEN);
331: strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
332: temporarily_use_uid(pw->pw_uid);
333: if (mkdtemp(xauthfile) == NULL) {
334: restore_uid();
335: error("private X11 dir: mkdtemp %s failed: %s",
336: xauthfile, strerror(errno));
337: xfree(xauthfile);
338: xauthfile = NULL;
1.7 markus 339: /* XXXX remove listening channels */
1.1 markus 340: break;
341: }
342: strlcat(xauthfile, "/cookies", MAXPATHLEN);
1.33 markus 343: fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
344: if (fd >= 0)
345: close(fd);
1.1 markus 346: restore_uid();
347: fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
348: success = 1;
349: break;
350:
351: case SSH_CMSG_AGENT_REQUEST_FORWARDING:
352: if (no_agent_forwarding_flag || compat13) {
353: debug("Authentication agent forwarding not permitted for this authentication.");
354: break;
355: }
356: debug("Received authentication agent forwarding request.");
1.15 markus 357: success = auth_input_request_forwarding(pw);
1.1 markus 358: break;
359:
360: case SSH_CMSG_PORT_FORWARD_REQUEST:
361: if (no_port_forwarding_flag) {
362: debug("Port forwarding not permitted for this authentication.");
1.39 markus 363: break;
364: }
365: if (!options.allow_tcp_forwarding) {
366: debug("Port forwarding not permitted.");
1.1 markus 367: break;
368: }
369: debug("Received TCP/IP port forwarding request.");
1.12 markus 370: channel_input_port_forward_request(pw->pw_uid == 0, options.gateway_ports);
1.1 markus 371: success = 1;
372: break;
373:
374: case SSH_CMSG_MAX_PACKET_SIZE:
375: if (packet_set_maxsize(packet_get_int()) > 0)
376: success = 1;
377: break;
378:
379: case SSH_CMSG_EXEC_SHELL:
380: case SSH_CMSG_EXEC_CMD:
381: if (type == SSH_CMSG_EXEC_CMD) {
382: command = packet_get_string(&dlen);
383: debug("Exec command '%.500s'", command);
384: packet_integrity_check(plen, 4 + dlen, type);
385: } else {
386: command = NULL;
387: packet_integrity_check(plen, 0, type);
388: }
389: if (forced_command != NULL) {
1.34 markus 390: original_command = command;
1.1 markus 391: command = forced_command;
392: debug("Forced command '%.500s'", forced_command);
393: }
394: if (have_pty)
395: do_exec_pty(s, command, pw);
396: else
397: do_exec_no_pty(s, command, pw);
398:
399: if (command != NULL)
400: xfree(command);
401: /* Cleanup user's local Xauthority file. */
402: if (xauthfile)
403: xauthfile_cleanup_proc(NULL);
404: return;
405:
406: default:
407: /*
408: * Any unknown messages in this phase are ignored,
409: * and a failure message is returned.
410: */
411: log("Unknown packet type received after authentication: %d", type);
412: }
413: packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
414: packet_send();
415: packet_write_wait();
416:
417: /* Enable compression now that we have replied if appropriate. */
418: if (enable_compression_after_reply) {
419: enable_compression_after_reply = 0;
420: packet_start_compression(compression_level);
421: }
422: }
423: }
424:
425: /*
426: * This is called to fork and execute a command when we have no tty. This
427: * will call do_child from the child, and server_loop from the parent after
428: * setting up file descriptors and such.
429: */
1.4 markus 430: void
1.1 markus 431: do_exec_no_pty(Session *s, const char *command, struct passwd * pw)
432: {
433: int pid;
434:
435: #ifdef USE_PIPES
436: int pin[2], pout[2], perr[2];
437: /* Allocate pipes for communicating with the program. */
438: if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
439: packet_disconnect("Could not create pipes: %.100s",
440: strerror(errno));
441: #else /* USE_PIPES */
442: int inout[2], err[2];
443: /* Uses socket pairs to communicate with the program. */
444: if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
445: socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
446: packet_disconnect("Could not create socket pairs: %.100s",
447: strerror(errno));
448: #endif /* USE_PIPES */
449: if (s == NULL)
450: fatal("do_exec_no_pty: no session");
451:
1.9 markus 452: session_proctitle(s);
1.1 markus 453:
454: /* Fork the child. */
455: if ((pid = fork()) == 0) {
456: /* Child. Reinitialize the log since the pid has changed. */
457: log_init(__progname, options.log_level, options.log_facility, log_stderr);
458:
459: /*
460: * Create a new session and process group since the 4.4BSD
461: * setlogin() affects the entire process group.
462: */
463: if (setsid() < 0)
464: error("setsid failed: %.100s", strerror(errno));
465:
466: #ifdef USE_PIPES
467: /*
468: * Redirect stdin. We close the parent side of the socket
469: * pair, and make the child side the standard input.
470: */
471: close(pin[1]);
472: if (dup2(pin[0], 0) < 0)
473: perror("dup2 stdin");
474: close(pin[0]);
475:
476: /* Redirect stdout. */
477: close(pout[0]);
478: if (dup2(pout[1], 1) < 0)
479: perror("dup2 stdout");
480: close(pout[1]);
481:
482: /* Redirect stderr. */
483: close(perr[0]);
484: if (dup2(perr[1], 2) < 0)
485: perror("dup2 stderr");
486: close(perr[1]);
487: #else /* USE_PIPES */
488: /*
489: * Redirect stdin, stdout, and stderr. Stdin and stdout will
490: * use the same socket, as some programs (particularly rdist)
491: * seem to depend on it.
492: */
493: close(inout[1]);
494: close(err[1]);
495: if (dup2(inout[0], 0) < 0) /* stdin */
496: perror("dup2 stdin");
497: if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */
498: perror("dup2 stdout");
499: if (dup2(err[0], 2) < 0) /* stderr */
500: perror("dup2 stderr");
501: #endif /* USE_PIPES */
502:
503: /* Do processing for the child (exec command etc). */
1.60 ! markus 504: do_child(s, command);
1.1 markus 505: /* NOTREACHED */
506: }
507: if (pid < 0)
508: packet_disconnect("fork failed: %.100s", strerror(errno));
509: s->pid = pid;
1.47 markus 510: /* Set interactive/non-interactive mode. */
1.48 markus 511: packet_set_interactive(s->display != NULL);
1.1 markus 512: #ifdef USE_PIPES
513: /* We are the parent. Close the child sides of the pipes. */
514: close(pin[0]);
515: close(pout[1]);
516: close(perr[1]);
517:
1.2 markus 518: if (compat20) {
1.7 markus 519: session_set_fds(s, pin[1], pout[0], s->extended ? perr[0] : -1);
1.2 markus 520: } else {
521: /* Enter the interactive session. */
522: server_loop(pid, pin[1], pout[0], perr[0]);
523: /* server_loop has closed pin[1], pout[1], and perr[1]. */
524: }
1.1 markus 525: #else /* USE_PIPES */
526: /* We are the parent. Close the child sides of the socket pairs. */
527: close(inout[0]);
528: close(err[0]);
529:
530: /*
531: * Enter the interactive session. Note: server_loop must be able to
532: * handle the case that fdin and fdout are the same.
533: */
1.2 markus 534: if (compat20) {
1.7 markus 535: session_set_fds(s, inout[1], inout[1], s->extended ? err[1] : -1);
1.2 markus 536: } else {
537: server_loop(pid, inout[1], inout[1], err[1]);
538: /* server_loop has closed inout[1] and err[1]. */
539: }
1.1 markus 540: #endif /* USE_PIPES */
541: }
542:
543: /*
544: * This is called to fork and execute a command when we have a tty. This
545: * will call do_child from the child, and server_loop from the parent after
546: * setting up file descriptors, controlling tty, updating wtmp, utmp,
547: * lastlog, and other such operations.
548: */
1.4 markus 549: void
1.1 markus 550: do_exec_pty(Session *s, const char *command, struct passwd * pw)
551: {
552: int fdout, ptyfd, ttyfd, ptymaster;
553: pid_t pid;
554:
555: if (s == NULL)
556: fatal("do_exec_pty: no session");
557: ptyfd = s->ptyfd;
558: ttyfd = s->ttyfd;
559:
560: /* Fork the child. */
561: if ((pid = fork()) == 0) {
1.24 markus 562: /* Child. Reinitialize the log because the pid has changed. */
1.1 markus 563: log_init(__progname, options.log_level, options.log_facility, log_stderr);
564:
565: /* Close the master side of the pseudo tty. */
566: close(ptyfd);
567:
568: /* Make the pseudo tty our controlling tty. */
569: pty_make_controlling_tty(&ttyfd, s->tty);
570:
571: /* Redirect stdin from the pseudo tty. */
572: if (dup2(ttyfd, fileno(stdin)) < 0)
573: error("dup2 stdin failed: %.100s", strerror(errno));
574:
575: /* Redirect stdout to the pseudo tty. */
576: if (dup2(ttyfd, fileno(stdout)) < 0)
577: error("dup2 stdin failed: %.100s", strerror(errno));
578:
579: /* Redirect stderr to the pseudo tty. */
580: if (dup2(ttyfd, fileno(stderr)) < 0)
581: error("dup2 stdin failed: %.100s", strerror(errno));
582:
583: /* Close the extra descriptor for the pseudo tty. */
584: close(ttyfd);
585:
1.24 markus 586: /* record login, etc. similar to login(1) */
1.41 markus 587: if (!(options.use_login && command == NULL))
588: do_login(s, command);
1.1 markus 589:
590: /* Do common processing for the child, such as execing the command. */
1.60 ! markus 591: do_child(s, command);
1.1 markus 592: /* NOTREACHED */
593: }
594: if (pid < 0)
595: packet_disconnect("fork failed: %.100s", strerror(errno));
596: s->pid = pid;
597:
598: /* Parent. Close the slave side of the pseudo tty. */
599: close(ttyfd);
600:
601: /*
602: * Create another descriptor of the pty master side for use as the
603: * standard input. We could use the original descriptor, but this
604: * simplifies code in server_loop. The descriptor is bidirectional.
605: */
606: fdout = dup(ptyfd);
607: if (fdout < 0)
608: packet_disconnect("dup #1 failed: %.100s", strerror(errno));
609:
610: /* we keep a reference to the pty master */
611: ptymaster = dup(ptyfd);
612: if (ptymaster < 0)
613: packet_disconnect("dup #2 failed: %.100s", strerror(errno));
614: s->ptymaster = ptymaster;
615:
616: /* Enter interactive session. */
1.47 markus 617: packet_set_interactive(1);
1.2 markus 618: if (compat20) {
619: session_set_fds(s, ptyfd, fdout, -1);
620: } else {
621: server_loop(pid, ptyfd, fdout, -1);
622: /* server_loop _has_ closed ptyfd and fdout. */
623: session_pty_cleanup(s);
1.24 markus 624: }
625: }
626:
1.25 markus 627: const char *
628: get_remote_name_or_ip(void)
629: {
630: static const char *remote = "";
631: if (utmp_len > 0)
1.52 markus 632: remote = get_canonical_hostname(options.reverse_mapping_check);
1.25 markus 633: if (utmp_len == 0 || strlen(remote) > utmp_len)
634: remote = get_remote_ipaddr();
635: return remote;
636: }
637:
1.24 markus 638: /* administrative, login(1)-like work */
639: void
1.41 markus 640: do_login(Session *s, const char *command)
1.24 markus 641: {
642: FILE *f;
643: char *time_string;
644: char buf[256];
1.35 markus 645: char hostname[MAXHOSTNAMELEN];
1.24 markus 646: socklen_t fromlen;
647: struct sockaddr_storage from;
648: struct stat st;
649: time_t last_login_time;
650: struct passwd * pw = s->pw;
651: pid_t pid = getpid();
652:
653: /*
654: * Get IP address of client. If the connection is not a socket, let
655: * the address be 0.0.0.0.
656: */
657: memset(&from, 0, sizeof(from));
658: if (packet_connection_is_on_socket()) {
659: fromlen = sizeof(from);
660: if (getpeername(packet_get_connection_in(),
661: (struct sockaddr *) & from, &fromlen) < 0) {
662: debug("getpeername: %.100s", strerror(errno));
663: fatal_cleanup();
664: }
665: }
1.25 markus 666:
1.35 markus 667: /* Get the time and hostname when the user last logged in. */
1.36 markus 668: hostname[0] = '\0';
1.35 markus 669: last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
670: hostname, sizeof(hostname));
671:
1.24 markus 672: /* Record that there was a login on that tty from the remote host. */
673: record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
1.25 markus 674: get_remote_name_or_ip(), (struct sockaddr *)&from);
1.24 markus 675:
1.41 markus 676: /* Done if .hushlogin exists or a command given. */
677: if (command != NULL)
678: return;
1.24 markus 679: snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
1.28 millert 680: #ifdef HAVE_LOGIN_CAP
681: if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
682: #else
1.24 markus 683: if (stat(buf, &st) >= 0)
1.28 millert 684: #endif
1.24 markus 685: return;
686: if (last_login_time != 0) {
687: time_string = ctime(&last_login_time);
688: if (strchr(time_string, '\n'))
689: *strchr(time_string, '\n') = 0;
1.40 markus 690: if (strcmp(hostname, "") == 0)
1.24 markus 691: printf("Last login: %s\r\n", time_string);
692: else
1.36 markus 693: printf("Last login: %s from %s\r\n", time_string, hostname);
1.24 markus 694: }
695: if (options.print_motd) {
1.28 millert 696: #ifdef HAVE_LOGIN_CAP
697: f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
698: "/etc/motd"), "r");
699: #else
1.24 markus 700: f = fopen("/etc/motd", "r");
1.28 millert 701: #endif
1.24 markus 702: if (f) {
703: while (fgets(buf, sizeof(buf), f))
704: fputs(buf, stdout);
705: fclose(f);
706: }
1.2 markus 707: }
1.1 markus 708: }
709:
710: /*
711: * Sets the value of the given variable in the environment. If the variable
712: * already exists, its value is overriden.
713: */
1.4 markus 714: void
1.45 markus 715: child_set_env(char ***envp, u_int *envsizep, const char *name,
1.1 markus 716: const char *value)
717: {
1.45 markus 718: u_int i, namelen;
1.1 markus 719: char **env;
720:
721: /*
722: * Find the slot where the value should be stored. If the variable
723: * already exists, we reuse the slot; otherwise we append a new slot
724: * at the end of the array, expanding if necessary.
725: */
726: env = *envp;
727: namelen = strlen(name);
728: for (i = 0; env[i]; i++)
729: if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
730: break;
731: if (env[i]) {
732: /* Reuse the slot. */
733: xfree(env[i]);
734: } else {
735: /* New variable. Expand if necessary. */
736: if (i >= (*envsizep) - 1) {
737: (*envsizep) += 50;
738: env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
739: }
740: /* Need to set the NULL pointer at end of array beyond the new slot. */
741: env[i + 1] = NULL;
742: }
743:
744: /* Allocate space and format the variable in the appropriate slot. */
745: env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
746: snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
747: }
748:
749: /*
750: * Reads environment variables from the given file and adds/overrides them
751: * into the environment. If the file does not exist, this does nothing.
752: * Otherwise, it must consist of empty lines, comments (line starts with '#')
753: * and assignments of the form name=value. No other forms are allowed.
754: */
1.4 markus 755: void
1.45 markus 756: read_environment_file(char ***env, u_int *envsize,
1.1 markus 757: const char *filename)
758: {
759: FILE *f;
760: char buf[4096];
761: char *cp, *value;
762:
763: f = fopen(filename, "r");
764: if (!f)
765: return;
766:
767: while (fgets(buf, sizeof(buf), f)) {
768: for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
769: ;
770: if (!*cp || *cp == '#' || *cp == '\n')
771: continue;
772: if (strchr(cp, '\n'))
773: *strchr(cp, '\n') = '\0';
774: value = strchr(cp, '=');
775: if (value == NULL) {
776: fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
777: continue;
778: }
1.14 deraadt 779: /*
780: * Replace the equals sign by nul, and advance value to
781: * the value string.
782: */
1.1 markus 783: *value = '\0';
784: value++;
785: child_set_env(env, envsize, cp, value);
786: }
787: fclose(f);
788: }
789:
790: /*
791: * Performs common processing for the child, such as setting up the
792: * environment, closing extra file descriptors, setting the user and group
793: * ids, and executing the command or shell.
794: */
1.4 markus 795: void
1.60 ! markus 796: do_child(Session *s, const char *command)
1.1 markus 797: {
1.32 markus 798: const char *shell, *hostname = NULL, *cp = NULL;
1.60 ! markus 799: struct passwd * pw = s->pw;
1.1 markus 800: char buf[256];
1.16 markus 801: char cmd[1024];
1.27 millert 802: FILE *f = NULL;
1.45 markus 803: u_int envsize, i;
1.1 markus 804: char **env;
805: extern char **environ;
806: struct stat st;
807: char *argv[10];
1.60 ! markus 808: int do_xauth = s->auth_proto != NULL && s->auth_data != NULL;
1.17 markus 809:
810: /* login(1) is only called if we execute the login shell */
811: if (options.use_login && command != NULL)
812: options.use_login = 0;
1.1 markus 813:
1.27 millert 814: if (!options.use_login) {
1.28 millert 815: #ifdef HAVE_LOGIN_CAP
816: if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
817: f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
818: _PATH_NOLOGIN), "r");
819: #else
1.27 millert 820: if (pw->pw_uid)
821: f = fopen(_PATH_NOLOGIN, "r");
1.28 millert 822: #endif
1.27 millert 823: if (f) {
824: /* /etc/nologin exists. Print its contents and exit. */
825: while (fgets(buf, sizeof(buf), f))
826: fputs(buf, stderr);
827: fclose(f);
1.1 markus 828: exit(254);
1.27 millert 829: }
1.1 markus 830: }
1.28 millert 831: /* Set login name, uid, gid, and groups. */
1.1 markus 832: /* Login(1) does this as well, and it needs uid 0 for the "-h"
833: switch, so we let login(1) to this for us. */
834: if (!options.use_login) {
835: if (getuid() == 0 || geteuid() == 0) {
1.28 millert 836: #ifdef HAVE_LOGIN_CAP
837: if (setusercontext(lc, pw, pw->pw_uid,
838: (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
839: perror("unable to set user context");
840: exit(1);
1.53 stevesk 841:
1.28 millert 842: }
843: #else
844: if (setlogin(pw->pw_name) < 0)
845: error("setlogin failed: %s", strerror(errno));
1.1 markus 846: if (setgid(pw->pw_gid) < 0) {
847: perror("setgid");
848: exit(1);
849: }
850: /* Initialize the group list. */
851: if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
852: perror("initgroups");
853: exit(1);
854: }
855: endgrent();
856:
857: /* Permanently switch to the desired uid. */
858: permanently_set_uid(pw->pw_uid);
1.28 millert 859: #endif
1.1 markus 860: }
861: if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1.31 deraadt 862: fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1.1 markus 863: }
864: /*
865: * Get the shell from the password data. An empty shell field is
866: * legal, and means /bin/sh.
867: */
868: shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1.28 millert 869: #ifdef HAVE_LOGIN_CAP
870: shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
871: #endif
1.1 markus 872:
873: #ifdef AFS
874: /* Try to get AFS tokens for the local cell. */
875: if (k_hasafs()) {
876: char cell[64];
877:
878: if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
879: krb_afslog(cell, 0);
880:
881: krb_afslog(0, 0);
882: }
883: #endif /* AFS */
884:
885: /* Initialize the environment. */
886: envsize = 100;
887: env = xmalloc(envsize * sizeof(char *));
888: env[0] = NULL;
889:
890: if (!options.use_login) {
891: /* Set basic environment. */
892: child_set_env(&env, &envsize, "USER", pw->pw_name);
893: child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
894: child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1.28 millert 895: #ifdef HAVE_LOGIN_CAP
1.29 millert 896: (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
897: child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1.28 millert 898: #else
1.29 millert 899: child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1.28 millert 900: #endif
1.1 markus 901:
902: snprintf(buf, sizeof buf, "%.200s/%.50s",
903: _PATH_MAILDIR, pw->pw_name);
904: child_set_env(&env, &envsize, "MAIL", buf);
905:
906: /* Normal systems set SHELL by default. */
907: child_set_env(&env, &envsize, "SHELL", shell);
908: }
909: if (getenv("TZ"))
910: child_set_env(&env, &envsize, "TZ", getenv("TZ"));
911:
912: /* Set custom environment options from RSA authentication. */
913: while (custom_environment) {
914: struct envstring *ce = custom_environment;
915: char *s = ce->s;
916: int i;
917: for (i = 0; s[i] != '=' && s[i]; i++);
918: if (s[i] == '=') {
919: s[i] = 0;
920: child_set_env(&env, &envsize, s, s + i + 1);
921: }
922: custom_environment = ce->next;
923: xfree(ce->s);
924: xfree(ce);
925: }
926:
927: snprintf(buf, sizeof buf, "%.50s %d %d",
928: get_remote_ipaddr(), get_remote_port(), get_local_port());
929: child_set_env(&env, &envsize, "SSH_CLIENT", buf);
930:
1.60 ! markus 931: if (s->ttyfd != -1)
! 932: child_set_env(&env, &envsize, "SSH_TTY", s->tty);
! 933: if (s->term)
! 934: child_set_env(&env, &envsize, "TERM", s->term);
! 935: if (s->display)
! 936: child_set_env(&env, &envsize, "DISPLAY", s->display);
1.34 markus 937: if (original_command)
938: child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
939: original_command);
1.1 markus 940:
941: #ifdef KRB4
942: {
943: extern char *ticket;
944:
945: if (ticket)
946: child_set_env(&env, &envsize, "KRBTKFILE", ticket);
947: }
948: #endif /* KRB4 */
949:
950: if (xauthfile)
951: child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
952: if (auth_get_socket_name() != NULL)
953: child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
954: auth_get_socket_name());
955:
956: /* read $HOME/.ssh/environment. */
957: if (!options.use_login) {
1.14 deraadt 958: snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
959: pw->pw_dir);
1.1 markus 960: read_environment_file(&env, &envsize, buf);
961: }
962: if (debug_flag) {
963: /* dump the environment */
964: fprintf(stderr, "Environment:\n");
965: for (i = 0; env[i]; i++)
966: fprintf(stderr, " %.200s\n", env[i]);
967: }
1.26 millert 968: /* we have to stash the hostname before we close our socket. */
969: if (options.use_login)
970: hostname = get_remote_name_or_ip();
1.1 markus 971: /*
972: * Close the connection descriptors; note that this is the child, and
973: * the server will still have the socket open, and it is important
974: * that we do not shutdown it. Note that the descriptors cannot be
975: * closed before building the environment, as we call
976: * get_remote_ipaddr there.
977: */
978: if (packet_get_connection_in() == packet_get_connection_out())
979: close(packet_get_connection_in());
980: else {
981: close(packet_get_connection_in());
982: close(packet_get_connection_out());
983: }
984: /*
985: * Close all descriptors related to channels. They will still remain
986: * open in the parent.
987: */
988: /* XXX better use close-on-exec? -markus */
989: channel_close_all();
990:
991: /*
992: * Close any extra file descriptors. Note that there may still be
993: * descriptors left by system functions. They will be closed later.
994: */
995: endpwent();
996:
997: /*
998: * Close any extra open file descriptors so that we don\'t have them
999: * hanging around in clients. Note that we want to do this after
1000: * initgroups, because at least on Solaris 2.3 it leaves file
1001: * descriptors open.
1002: */
1003: for (i = 3; i < 64; i++)
1004: close(i);
1005:
1006: /* Change current directory to the user\'s home directory. */
1.28 millert 1007: if (chdir(pw->pw_dir) < 0) {
1.1 markus 1008: fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1009: pw->pw_dir, strerror(errno));
1.28 millert 1010: #ifdef HAVE_LOGIN_CAP
1011: if (login_getcapbool(lc, "requirehome", 0))
1012: exit(1);
1013: #endif
1014: }
1.1 markus 1015:
1016: /*
1017: * Must take new environment into use so that .ssh/rc, /etc/sshrc and
1018: * xauth are run in the proper environment.
1019: */
1020: environ = env;
1021:
1022: /*
1023: * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
1024: * in this order).
1025: */
1026: if (!options.use_login) {
1.50 markus 1027: if (stat(_PATH_SSH_USER_RC, &st) >= 0) {
1.1 markus 1028: if (debug_flag)
1.60 ! markus 1029: fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
! 1030: _PATH_SSH_USER_RC);
1.50 markus 1031: f = popen(_PATH_BSHELL " " _PATH_SSH_USER_RC, "w");
1.1 markus 1032: if (f) {
1.60 ! markus 1033: if (do_xauth)
! 1034: fprintf(f, "%s %s\n", s->auth_proto,
! 1035: s->auth_data);
1.1 markus 1036: pclose(f);
1037: } else
1.60 ! markus 1038: fprintf(stderr, "Could not run %s\n",
! 1039: _PATH_SSH_USER_RC);
1.50 markus 1040: } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1.1 markus 1041: if (debug_flag)
1.60 ! markus 1042: fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
! 1043: _PATH_SSH_SYSTEM_RC);
1.50 markus 1044: f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1.1 markus 1045: if (f) {
1.60 ! markus 1046: if (do_xauth)
! 1047: fprintf(f, "%s %s\n", s->auth_proto,
! 1048: s->auth_data);
1.1 markus 1049: pclose(f);
1050: } else
1.60 ! markus 1051: fprintf(stderr, "Could not run %s\n",
! 1052: _PATH_SSH_SYSTEM_RC);
! 1053: } else if (do_xauth && options.xauth_location != NULL) {
1.1 markus 1054: /* Add authority data to .Xauthority if appropriate. */
1.60 ! markus 1055: char *screen = strchr(s->display, ':');
! 1056:
! 1057: if (debug_flag) {
! 1058: fprintf(stderr,
! 1059: "Running %.100s add "
! 1060: "%.100s %.100s %.100s\n",
! 1061: options.xauth_location, s->display,
! 1062: s->auth_proto, s->auth_data);
! 1063: if (screen != NULL)
1.14 deraadt 1064: fprintf(stderr,
1.60 ! markus 1065: "Adding %.*s/unix%s %s %s\n",
! 1066: (int)(screen - s->display),
! 1067: s->display, screen,
! 1068: s->auth_proto, s->auth_data);
! 1069: }
! 1070: snprintf(cmd, sizeof cmd, "%s -q -",
! 1071: options.xauth_location);
! 1072: f = popen(cmd, "w");
! 1073: if (f) {
! 1074: fprintf(f, "add %s %s %s\n", s->display,
! 1075: s->auth_proto, s->auth_data);
! 1076: if (screen != NULL)
! 1077: fprintf(f, "add %.*s/unix%s %s %s\n",
! 1078: (int)(screen - s->display),
! 1079: s->display, screen,
! 1080: s->auth_proto,
! 1081: s->auth_data);
! 1082: pclose(f);
! 1083: } else {
! 1084: fprintf(stderr, "Could not run %s\n",
! 1085: cmd);
1.1 markus 1086: }
1087: }
1088: /* Get the last component of the shell name. */
1089: cp = strrchr(shell, '/');
1090: if (cp)
1091: cp++;
1092: else
1093: cp = shell;
1094: }
1095: /*
1096: * If we have no command, execute the shell. In this case, the shell
1097: * name to be passed in argv[0] is preceded by '-' to indicate that
1098: * this is a login shell.
1099: */
1100: if (!command) {
1101: if (!options.use_login) {
1102: char buf[256];
1103:
1104: /*
1105: * Check for mail if we have a tty and it was enabled
1106: * in server options.
1107: */
1.60 ! markus 1108: if (s->ttyfd != -1 && options.check_mail) {
1.1 markus 1109: char *mailbox;
1110: struct stat mailstat;
1.60 ! markus 1111:
1.1 markus 1112: mailbox = getenv("MAIL");
1113: if (mailbox != NULL) {
1.14 deraadt 1114: if (stat(mailbox, &mailstat) != 0 ||
1115: mailstat.st_size == 0)
1.1 markus 1116: printf("No mail.\n");
1117: else if (mailstat.st_mtime < mailstat.st_atime)
1118: printf("You have mail.\n");
1119: else
1120: printf("You have new mail.\n");
1121: }
1122: }
1123: /* Start the shell. Set initial character to '-'. */
1124: buf[0] = '-';
1125: strncpy(buf + 1, cp, sizeof(buf) - 1);
1126: buf[sizeof(buf) - 1] = 0;
1127:
1128: /* Execute the shell. */
1129: argv[0] = buf;
1130: argv[1] = NULL;
1131: execve(shell, argv, env);
1132:
1133: /* Executing the shell failed. */
1134: perror(shell);
1135: exit(1);
1136:
1137: } else {
1138: /* Launch login(1). */
1139:
1.26 millert 1140: execl("/usr/bin/login", "login", "-h", hostname,
1.25 markus 1141: "-p", "-f", "--", pw->pw_name, NULL);
1.1 markus 1142:
1143: /* Login couldn't be executed, die. */
1144:
1145: perror("login");
1146: exit(1);
1147: }
1148: }
1149: /*
1150: * Execute the command using the user's shell. This uses the -c
1151: * option to execute the command.
1152: */
1153: argv[0] = (char *) cp;
1154: argv[1] = "-c";
1155: argv[2] = (char *) command;
1156: argv[3] = NULL;
1157: execve(shell, argv, env);
1158: perror(shell);
1159: exit(1);
1160: }
1161:
1162: Session *
1163: session_new(void)
1164: {
1165: int i;
1166: static int did_init = 0;
1167: if (!did_init) {
1168: debug("session_new: init");
1169: for(i = 0; i < MAX_SESSIONS; i++) {
1170: sessions[i].used = 0;
1171: sessions[i].self = i;
1172: }
1173: did_init = 1;
1174: }
1175: for(i = 0; i < MAX_SESSIONS; i++) {
1176: Session *s = &sessions[i];
1177: if (! s->used) {
1178: s->pid = 0;
1.7 markus 1179: s->extended = 0;
1.1 markus 1180: s->chanid = -1;
1181: s->ptyfd = -1;
1182: s->ttyfd = -1;
1183: s->term = NULL;
1184: s->pw = NULL;
1185: s->display = NULL;
1186: s->screen = 0;
1187: s->auth_data = NULL;
1188: s->auth_proto = NULL;
1189: s->used = 1;
1.7 markus 1190: s->pw = NULL;
1.1 markus 1191: debug("session_new: session %d", i);
1192: return s;
1193: }
1194: }
1195: return NULL;
1196: }
1197:
1198: void
1199: session_dump(void)
1200: {
1201: int i;
1202: for(i = 0; i < MAX_SESSIONS; i++) {
1203: Session *s = &sessions[i];
1204: debug("dump: used %d session %d %p channel %d pid %d",
1205: s->used,
1206: s->self,
1207: s,
1208: s->chanid,
1209: s->pid);
1210: }
1211: }
1212:
1.2 markus 1213: int
1214: session_open(int chanid)
1215: {
1216: Session *s = session_new();
1217: debug("session_open: channel %d", chanid);
1218: if (s == NULL) {
1219: error("no more sessions");
1220: return 0;
1221: }
1.7 markus 1222: s->pw = auth_get_user();
1223: if (s->pw == NULL)
1.54 stevesk 1224: fatal("no user for session %d", s->self);
1.2 markus 1225: debug("session_open: session %d: link with channel %d", s->self, chanid);
1226: s->chanid = chanid;
1227: return 1;
1228: }
1229:
1230: Session *
1231: session_by_channel(int id)
1232: {
1233: int i;
1234: for(i = 0; i < MAX_SESSIONS; i++) {
1235: Session *s = &sessions[i];
1236: if (s->used && s->chanid == id) {
1237: debug("session_by_channel: session %d channel %d", i, id);
1238: return s;
1239: }
1240: }
1241: debug("session_by_channel: unknown channel %d", id);
1242: session_dump();
1243: return NULL;
1244: }
1245:
1246: Session *
1247: session_by_pid(pid_t pid)
1248: {
1249: int i;
1250: debug("session_by_pid: pid %d", pid);
1251: for(i = 0; i < MAX_SESSIONS; i++) {
1252: Session *s = &sessions[i];
1253: if (s->used && s->pid == pid)
1254: return s;
1255: }
1256: error("session_by_pid: unknown pid %d", pid);
1257: session_dump();
1258: return NULL;
1259: }
1260:
1261: int
1262: session_window_change_req(Session *s)
1263: {
1264: s->col = packet_get_int();
1265: s->row = packet_get_int();
1266: s->xpixel = packet_get_int();
1267: s->ypixel = packet_get_int();
1.3 markus 1268: packet_done();
1.2 markus 1269: pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1270: return 1;
1271: }
1272:
1273: int
1274: session_pty_req(Session *s)
1275: {
1.45 markus 1276: u_int len;
1.3 markus 1277: char *term_modes; /* encoded terminal modes */
1.2 markus 1278:
1.19 markus 1279: if (no_pty_flag)
1280: return 0;
1.2 markus 1281: if (s->ttyfd != -1)
1.3 markus 1282: return 0;
1.2 markus 1283: s->term = packet_get_string(&len);
1284: s->col = packet_get_int();
1285: s->row = packet_get_int();
1286: s->xpixel = packet_get_int();
1287: s->ypixel = packet_get_int();
1.3 markus 1288: term_modes = packet_get_string(&len);
1289: packet_done();
1.2 markus 1290:
1291: if (strcmp(s->term, "") == 0) {
1292: xfree(s->term);
1293: s->term = NULL;
1294: }
1295: /* Allocate a pty and open it. */
1296: if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
1297: xfree(s->term);
1298: s->term = NULL;
1299: s->ptyfd = -1;
1300: s->ttyfd = -1;
1301: error("session_pty_req: session %d alloc failed", s->self);
1.3 markus 1302: xfree(term_modes);
1303: return 0;
1.2 markus 1304: }
1305: debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1306: /*
1307: * Add a cleanup function to clear the utmp entry and record logout
1308: * time in case we call fatal() (e.g., the connection gets closed).
1309: */
1310: fatal_add_cleanup(pty_cleanup_proc, (void *)s);
1311: pty_setowner(s->pw, s->tty);
1312: /* Get window size from the packet. */
1313: pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1314:
1.9 markus 1315: session_proctitle(s);
1316:
1.3 markus 1317: /* XXX parse and set terminal modes */
1318: xfree(term_modes);
1.2 markus 1319: return 1;
1320: }
1321:
1.7 markus 1322: int
1323: session_subsystem_req(Session *s)
1324: {
1.45 markus 1325: u_int len;
1.7 markus 1326: int success = 0;
1327: char *subsys = packet_get_string(&len);
1.18 jakob 1328: int i;
1.7 markus 1329:
1330: packet_done();
1331: log("subsystem request for %s", subsys);
1.18 jakob 1332:
1333: for (i = 0; i < options.num_subsystems; i++) {
1334: if(strcmp(subsys, options.subsystem_name[i]) == 0) {
1335: debug("subsystem: exec() %s", options.subsystem_command[i]);
1336: do_exec_no_pty(s, options.subsystem_command[i], s->pw);
1337: success = 1;
1338: }
1339: }
1340:
1341: if (!success)
1342: log("subsystem request for %s failed, subsystem not found", subsys);
1.7 markus 1343:
1344: xfree(subsys);
1345: return success;
1346: }
1347:
1348: int
1349: session_x11_req(Session *s)
1350: {
1.33 markus 1351: int fd;
1.22 deraadt 1352: if (no_x11_forwarding_flag) {
1.19 markus 1353: debug("X11 forwarding disabled in user configuration file.");
1354: return 0;
1355: }
1.7 markus 1356: if (!options.x11_forwarding) {
1357: debug("X11 forwarding disabled in server configuration file.");
1358: return 0;
1359: }
1360: if (xauthfile != NULL) {
1361: debug("X11 fwd already started.");
1362: return 0;
1363: }
1364:
1365: debug("Received request for X11 forwarding with auth spoofing.");
1366: if (s->display != NULL)
1367: packet_disconnect("Protocol error: X11 display already set.");
1368:
1369: s->single_connection = packet_get_char();
1370: s->auth_proto = packet_get_string(NULL);
1371: s->auth_data = packet_get_string(NULL);
1372: s->screen = packet_get_int();
1373: packet_done();
1374:
1375: s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
1376: if (s->display == NULL) {
1377: xfree(s->auth_proto);
1378: xfree(s->auth_data);
1379: return 0;
1380: }
1381: xauthfile = xmalloc(MAXPATHLEN);
1382: strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
1383: temporarily_use_uid(s->pw->pw_uid);
1384: if (mkdtemp(xauthfile) == NULL) {
1385: restore_uid();
1386: error("private X11 dir: mkdtemp %s failed: %s",
1387: xauthfile, strerror(errno));
1388: xfree(xauthfile);
1389: xauthfile = NULL;
1390: xfree(s->auth_proto);
1391: xfree(s->auth_data);
1392: /* XXXX remove listening channels */
1393: return 0;
1394: }
1395: strlcat(xauthfile, "/cookies", MAXPATHLEN);
1.33 markus 1396: fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1397: if (fd >= 0)
1398: close(fd);
1.7 markus 1399: restore_uid();
1400: fatal_add_cleanup(xauthfile_cleanup_proc, s);
1401: return 1;
1402: }
1403:
1.19 markus 1404: int
1405: session_shell_req(Session *s)
1406: {
1407: /* if forced_command == NULL, the shell is execed */
1408: char *shell = forced_command;
1409: packet_done();
1410: s->extended = 1;
1411: if (s->ttyfd == -1)
1412: do_exec_no_pty(s, shell, s->pw);
1413: else
1414: do_exec_pty(s, shell, s->pw);
1415: return 1;
1416: }
1417:
1418: int
1419: session_exec_req(Session *s)
1420: {
1.45 markus 1421: u_int len;
1.19 markus 1422: char *command = packet_get_string(&len);
1423: packet_done();
1424: if (forced_command) {
1.34 markus 1425: original_command = command;
1.19 markus 1426: command = forced_command;
1427: debug("Forced command '%.500s'", forced_command);
1428: }
1429: s->extended = 1;
1430: if (s->ttyfd == -1)
1431: do_exec_no_pty(s, command, s->pw);
1432: else
1433: do_exec_pty(s, command, s->pw);
1434: if (forced_command == NULL)
1435: xfree(command);
1436: return 1;
1437: }
1438:
1.43 markus 1439: int
1440: session_auth_agent_req(Session *s)
1441: {
1442: static int called = 0;
1443: packet_done();
1.44 markus 1444: if (no_agent_forwarding_flag) {
1445: debug("session_auth_agent_req: no_agent_forwarding_flag");
1446: return 0;
1447: }
1.43 markus 1448: if (called) {
1449: return 0;
1450: } else {
1451: called = 1;
1452: return auth_input_request_forwarding(s->pw);
1453: }
1454: }
1455:
1.2 markus 1456: void
1457: session_input_channel_req(int id, void *arg)
1458: {
1.45 markus 1459: u_int len;
1.2 markus 1460: int reply;
1461: int success = 0;
1462: char *rtype;
1463: Session *s;
1464: Channel *c;
1465:
1466: rtype = packet_get_string(&len);
1467: reply = packet_get_char();
1468:
1469: s = session_by_channel(id);
1470: if (s == NULL)
1471: fatal("session_input_channel_req: channel %d: no session", id);
1472: c = channel_lookup(id);
1473: if (c == NULL)
1474: fatal("session_input_channel_req: channel %d: bad channel", id);
1475:
1476: debug("session_input_channel_req: session %d channel %d request %s reply %d",
1477: s->self, id, rtype, reply);
1478:
1479: /*
1480: * a session is in LARVAL state until a shell
1481: * or programm is executed
1482: */
1483: if (c->type == SSH_CHANNEL_LARVAL) {
1484: if (strcmp(rtype, "shell") == 0) {
1.19 markus 1485: success = session_shell_req(s);
1.2 markus 1486: } else if (strcmp(rtype, "exec") == 0) {
1.19 markus 1487: success = session_exec_req(s);
1.2 markus 1488: } else if (strcmp(rtype, "pty-req") == 0) {
1.3 markus 1489: success = session_pty_req(s);
1.7 markus 1490: } else if (strcmp(rtype, "x11-req") == 0) {
1491: success = session_x11_req(s);
1.43 markus 1492: } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1493: success = session_auth_agent_req(s);
1.7 markus 1494: } else if (strcmp(rtype, "subsystem") == 0) {
1495: success = session_subsystem_req(s);
1.2 markus 1496: }
1497: }
1498: if (strcmp(rtype, "window-change") == 0) {
1499: success = session_window_change_req(s);
1500: }
1501:
1502: if (reply) {
1503: packet_start(success ?
1504: SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1505: packet_put_int(c->remote_id);
1506: packet_send();
1507: }
1508: xfree(rtype);
1509: }
1510:
1511: void
1512: session_set_fds(Session *s, int fdin, int fdout, int fderr)
1513: {
1514: if (!compat20)
1515: fatal("session_set_fds: called for proto != 2.0");
1516: /*
1517: * now that have a child and a pipe to the child,
1518: * we can activate our channel and register the fd's
1519: */
1520: if (s->chanid == -1)
1521: fatal("no channel for session %d", s->self);
1522: channel_set_fds(s->chanid,
1523: fdout, fdin, fderr,
1.42 markus 1524: fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1525: 1);
1.2 markus 1526: }
1527:
1.1 markus 1528: void
1529: session_pty_cleanup(Session *s)
1530: {
1531: if (s == NULL || s->ttyfd == -1)
1532: return;
1533:
1.54 stevesk 1534: debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
1.1 markus 1535:
1536: /* Cancel the cleanup function. */
1537: fatal_remove_cleanup(pty_cleanup_proc, (void *)s);
1538:
1539: /* Record that the user has logged out. */
1540: record_logout(s->pid, s->tty);
1541:
1542: /* Release the pseudo-tty. */
1543: pty_release(s->tty);
1544:
1545: /*
1546: * Close the server side of the socket pairs. We must do this after
1547: * the pty cleanup, so that another process doesn't get this pty
1548: * while we're still cleaning up.
1549: */
1550: if (close(s->ptymaster) < 0)
1551: error("close(s->ptymaster): %s", strerror(errno));
1.2 markus 1552: }
1553:
1554: void
1555: session_exit_message(Session *s, int status)
1556: {
1557: Channel *c;
1558: if (s == NULL)
1559: fatal("session_close: no session");
1560: c = channel_lookup(s->chanid);
1561: if (c == NULL)
1562: fatal("session_close: session %d: no channel %d",
1563: s->self, s->chanid);
1564: debug("session_exit_message: session %d channel %d pid %d",
1565: s->self, s->chanid, s->pid);
1566:
1567: if (WIFEXITED(status)) {
1568: channel_request_start(s->chanid,
1569: "exit-status", 0);
1570: packet_put_int(WEXITSTATUS(status));
1571: packet_send();
1572: } else if (WIFSIGNALED(status)) {
1573: channel_request_start(s->chanid,
1574: "exit-signal", 0);
1575: packet_put_int(WTERMSIG(status));
1576: packet_put_char(WCOREDUMP(status));
1577: packet_put_cstring("");
1578: packet_put_cstring("");
1579: packet_send();
1580: } else {
1581: /* Some weird exit cause. Just exit. */
1582: packet_disconnect("wait returned status %04x.", status);
1583: }
1584:
1585: /* disconnect channel */
1586: debug("session_exit_message: release channel %d", s->chanid);
1587: channel_cancel_cleanup(s->chanid);
1.5 markus 1588: /*
1589: * emulate a write failure with 'chan_write_failed', nobody will be
1590: * interested in data we write.
1591: * Note that we must not call 'chan_read_failed', since there could
1592: * be some more data waiting in the pipe.
1593: */
1.8 markus 1594: if (c->ostate != CHAN_OUTPUT_CLOSED)
1595: chan_write_failed(c);
1.2 markus 1596: s->chanid = -1;
1597: }
1598:
1599: void
1600: session_free(Session *s)
1601: {
1602: debug("session_free: session %d pid %d", s->self, s->pid);
1603: if (s->term)
1604: xfree(s->term);
1605: if (s->display)
1606: xfree(s->display);
1607: if (s->auth_data)
1608: xfree(s->auth_data);
1609: if (s->auth_proto)
1610: xfree(s->auth_proto);
1611: s->used = 0;
1612: }
1613:
1614: void
1615: session_close(Session *s)
1616: {
1617: session_pty_cleanup(s);
1618: session_free(s);
1.9 markus 1619: session_proctitle(s);
1.2 markus 1620: }
1621:
1622: void
1623: session_close_by_pid(pid_t pid, int status)
1624: {
1625: Session *s = session_by_pid(pid);
1626: if (s == NULL) {
1627: debug("session_close_by_pid: no session for pid %d", s->pid);
1628: return;
1629: }
1630: if (s->chanid != -1)
1631: session_exit_message(s, status);
1632: session_close(s);
1633: }
1634:
1635: /*
1636: * this is called when a channel dies before
1637: * the session 'child' itself dies
1638: */
1639: void
1640: session_close_by_channel(int id, void *arg)
1641: {
1642: Session *s = session_by_channel(id);
1643: if (s == NULL) {
1644: debug("session_close_by_channel: no session for channel %d", id);
1645: return;
1646: }
1647: /* disconnect channel */
1648: channel_cancel_cleanup(s->chanid);
1649: s->chanid = -1;
1650:
1651: debug("session_close_by_channel: channel %d kill %d", id, s->pid);
1652: if (s->pid == 0) {
1653: /* close session immediately */
1654: session_close(s);
1655: } else {
1656: /* notify child, delay session cleanup */
1657: if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
1658: error("session_close_by_channel: kill %d: %s",
1659: s->pid, strerror(errno));
1660: }
1.9 markus 1661: }
1662:
1663: char *
1664: session_tty_list(void)
1665: {
1666: static char buf[1024];
1667: int i;
1668: buf[0] = '\0';
1669: for(i = 0; i < MAX_SESSIONS; i++) {
1670: Session *s = &sessions[i];
1671: if (s->used && s->ttyfd != -1) {
1672: if (buf[0] != '\0')
1673: strlcat(buf, ",", sizeof buf);
1674: strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1675: }
1676: }
1677: if (buf[0] == '\0')
1678: strlcpy(buf, "notty", sizeof buf);
1679: return buf;
1680: }
1681:
1682: void
1683: session_proctitle(Session *s)
1684: {
1685: if (s->pw == NULL)
1686: error("no user for session %d", s->self);
1687: else
1688: setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
1.2 markus 1689: }
1690:
1691: void
1.49 markus 1692: do_authenticated2(Authctxt *authctxt)
1.2 markus 1693: {
1694: /*
1695: * Cancel the alarm we set to limit the time taken for
1696: * authentication.
1697: */
1698: alarm(0);
1.23 deraadt 1699: if (startup_pipe != -1) {
1700: close(startup_pipe);
1701: startup_pipe = -1;
1702: }
1.28 millert 1703: #ifdef HAVE_LOGIN_CAP
1.49 markus 1704: if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
1.28 millert 1705: error("unable to get login class");
1706: return;
1707: }
1708: #endif
1.2 markus 1709: server_loop2();
1.7 markus 1710: if (xauthfile)
1711: xauthfile_cleanup_proc(NULL);
1.1 markus 1712: }