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