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