Annotation of src/usr.bin/ssh/session.c, Revision 1.191
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.191 ! djm 36: RCSID("$OpenBSD: session.c,v 1.190 2005/12/17 21:13:05 stevesk 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"
1.173 djm 45: #include "match.h"
1.1 markus 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.186 markus 59: #include "kex.h"
1.130 provos 60: #include "monitor_wrap.h"
1.171 markus 61:
62: #ifdef KRB5
63: #include <kafs.h>
64: #endif
1.1 markus 65:
1.161 markus 66: #ifdef GSSAPI
67: #include "ssh-gss.h"
68: #endif
69:
1.1 markus 70: /* func */
71:
72: Session *session_new(void);
1.94 itojun 73: void session_set_fds(Session *, int, int, int);
1.165 markus 74: void session_pty_cleanup(Session *);
1.94 itojun 75: void session_proctitle(Session *);
76: int session_setup_x11fwd(Session *);
77: void do_exec_pty(Session *, const char *);
78: void do_exec_no_pty(Session *, const char *);
79: void do_exec(Session *, const char *);
80: void do_login(Session *, const char *);
81: void do_child(Session *, const char *);
1.73 djm 82: void do_motd(void);
1.94 itojun 83: int check_quietlogin(Session *, const char *);
1.1 markus 84:
1.94 itojun 85: static void do_authenticated1(Authctxt *);
86: static void do_authenticated2(Authctxt *);
87:
88: static int session_pty_req(Session *);
1.65 markus 89:
1.1 markus 90: /* import */
91: extern ServerOptions options;
92: extern char *__progname;
93: extern int log_stderr;
94: extern int debug_flag;
1.45 markus 95: extern u_int utmp_len;
1.21 markus 96: extern int startup_pipe;
1.74 markus 97: extern void destroy_sensitive_data(void);
1.179 dtucker 98: extern Buffer loginmsg;
1.21 markus 99:
1.34 markus 100: /* original command from peer. */
1.92 markus 101: const char *original_command = NULL;
1.34 markus 102:
1.1 markus 103: /* data */
104: #define MAX_SESSIONS 10
105: Session sessions[MAX_SESSIONS];
106:
1.28 millert 107: #ifdef HAVE_LOGIN_CAP
1.129 provos 108: login_cap_t *lc;
1.28 millert 109: #endif
110:
1.165 markus 111: static int is_child = 0;
112:
1.136 markus 113: /* Name and directory of socket for authentication agent forwarding. */
114: static char *auth_sock_name = NULL;
115: static char *auth_sock_dir = NULL;
116:
117: /* removes the agent forwarding socket */
118:
119: static void
1.165 markus 120: auth_sock_cleanup_proc(struct passwd *pw)
1.136 markus 121: {
122: if (auth_sock_name != NULL) {
123: temporarily_use_uid(pw);
124: unlink(auth_sock_name);
125: rmdir(auth_sock_dir);
126: auth_sock_name = NULL;
127: restore_uid();
128: }
129: }
130:
131: static int
132: auth_input_request_forwarding(struct passwd * pw)
133: {
134: Channel *nc;
135: int sock;
136: struct sockaddr_un sunaddr;
137:
138: if (auth_sock_name != NULL) {
139: error("authentication forwarding requested twice.");
140: return 0;
141: }
142:
143: /* Temporarily drop privileged uid for mkdir/bind. */
144: temporarily_use_uid(pw);
145:
146: /* Allocate a buffer for the socket name, and format the name. */
147: auth_sock_name = xmalloc(MAXPATHLEN);
148: auth_sock_dir = xmalloc(MAXPATHLEN);
1.166 markus 149: strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
1.136 markus 150:
151: /* Create private directory for socket */
152: if (mkdtemp(auth_sock_dir) == NULL) {
153: packet_send_debug("Agent forwarding disabled: "
154: "mkdtemp() failed: %.100s", strerror(errno));
155: restore_uid();
156: xfree(auth_sock_name);
157: xfree(auth_sock_dir);
158: auth_sock_name = NULL;
159: auth_sock_dir = NULL;
160: return 0;
161: }
1.137 mpech 162: snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
163: auth_sock_dir, (long) getpid());
1.136 markus 164:
165: /* Create the socket. */
166: sock = socket(AF_UNIX, SOCK_STREAM, 0);
167: if (sock < 0)
168: packet_disconnect("socket: %.100s", strerror(errno));
169:
170: /* Bind it to the name. */
171: memset(&sunaddr, 0, sizeof(sunaddr));
172: sunaddr.sun_family = AF_UNIX;
173: strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
174:
175: if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
176: packet_disconnect("bind: %.100s", strerror(errno));
177:
178: /* Restore the privileged uid. */
179: restore_uid();
180:
181: /* Start listening on the socket. */
1.169 markus 182: if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
1.136 markus 183: packet_disconnect("listen: %.100s", strerror(errno));
184:
185: /* Allocate a channel for the authentication agent socket. */
186: nc = channel_new("auth socket",
187: SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
188: CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
1.156 markus 189: 0, "auth socket", 1);
1.136 markus 190: strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
191: return 1;
192: }
193:
1.179 dtucker 194: static void
195: display_loginmsg(void)
196: {
1.183 djm 197: if (buffer_len(&loginmsg) > 0) {
198: buffer_append(&loginmsg, "\0", 1);
199: printf("%s", (char *)buffer_ptr(&loginmsg));
200: buffer_clear(&loginmsg);
201: }
1.179 dtucker 202: }
1.136 markus 203:
1.65 markus 204: void
205: do_authenticated(Authctxt *authctxt)
206: {
1.153 markus 207: setproctitle("%s", authctxt->pw->pw_name);
208:
1.65 markus 209: /* setup the channel layer */
210: if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
211: channel_permit_all_opens();
212:
213: if (compat20)
214: do_authenticated2(authctxt);
215: else
216: do_authenticated1(authctxt);
1.79 markus 217:
1.165 markus 218: do_cleanup(authctxt);
1.65 markus 219: }
220:
1.1 markus 221: /*
222: * Prepares for an interactive session. This is called after the user has
223: * been successfully authenticated. During this message exchange, pseudo
224: * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
225: * are requested, etc.
226: */
1.94 itojun 227: static void
1.65 markus 228: do_authenticated1(Authctxt *authctxt)
1.1 markus 229: {
230: Session *s;
1.65 markus 231: char *command;
1.117 markus 232: int success, type, screen_flag;
1.139 deraadt 233: int enable_compression_after_reply = 0;
234: u_int proto_len, data_len, dlen, compression_level = 0;
1.1 markus 235:
1.61 markus 236: s = session_new();
1.181 markus 237: if (s == NULL) {
238: error("no more sessions");
239: return;
240: }
1.96 dugsong 241: s->authctxt = authctxt;
1.65 markus 242: s->pw = authctxt->pw;
1.28 millert 243:
1.1 markus 244: /*
245: * We stay in this loop until the client requests to execute a shell
246: * or a command.
247: */
248: for (;;) {
1.65 markus 249: success = 0;
1.1 markus 250:
251: /* Get a packet from the client. */
1.117 markus 252: type = packet_read();
1.1 markus 253:
254: /* Process the packet. */
255: switch (type) {
256: case SSH_CMSG_REQUEST_COMPRESSION:
257: compression_level = packet_get_int();
1.116 markus 258: packet_check_eom();
1.1 markus 259: if (compression_level < 1 || compression_level > 9) {
1.180 markus 260: packet_send_debug("Received invalid compression level %d.",
1.112 deraadt 261: compression_level);
1.138 markus 262: break;
263: }
1.186 markus 264: if (options.compression == COMP_NONE) {
1.138 markus 265: debug2("compression disabled");
1.1 markus 266: break;
267: }
268: /* Enable compression after we have responded with SUCCESS. */
269: enable_compression_after_reply = 1;
270: success = 1;
271: break;
272:
273: case SSH_CMSG_REQUEST_PTY:
1.86 markus 274: success = session_pty_req(s);
1.1 markus 275: break;
276:
277: case SSH_CMSG_X11_REQUEST_FORWARDING:
278: s->auth_proto = packet_get_string(&proto_len);
279: s->auth_data = packet_get_string(&data_len);
280:
1.57 markus 281: screen_flag = packet_get_protocol_flags() &
282: SSH_PROTOFLAG_SCREEN_NUMBER;
283: debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
284:
285: if (packet_remaining() == 4) {
286: if (!screen_flag)
287: debug2("Buggy client: "
288: "X11 screen flag missing");
1.1 markus 289: s->screen = packet_get_int();
1.56 markus 290: } else {
1.1 markus 291: s->screen = 0;
1.56 markus 292: }
1.116 markus 293: packet_check_eom();
1.81 markus 294: success = session_setup_x11fwd(s);
295: if (!success) {
296: xfree(s->auth_proto);
297: xfree(s->auth_data);
1.84 markus 298: s->auth_proto = NULL;
299: s->auth_data = NULL;
1.1 markus 300: }
301: break;
302:
303: case SSH_CMSG_AGENT_REQUEST_FORWARDING:
304: if (no_agent_forwarding_flag || compat13) {
305: debug("Authentication agent forwarding not permitted for this authentication.");
306: break;
307: }
308: debug("Received authentication agent forwarding request.");
1.65 markus 309: success = auth_input_request_forwarding(s->pw);
1.1 markus 310: break;
311:
312: case SSH_CMSG_PORT_FORWARD_REQUEST:
313: if (no_port_forwarding_flag) {
314: debug("Port forwarding not permitted for this authentication.");
1.39 markus 315: break;
316: }
317: if (!options.allow_tcp_forwarding) {
318: debug("Port forwarding not permitted.");
1.1 markus 319: break;
320: }
321: debug("Received TCP/IP port forwarding request.");
1.65 markus 322: channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
1.1 markus 323: success = 1;
324: break;
325:
326: case SSH_CMSG_MAX_PACKET_SIZE:
327: if (packet_set_maxsize(packet_get_int()) > 0)
328: success = 1;
329: break;
330:
331: case SSH_CMSG_EXEC_SHELL:
332: case SSH_CMSG_EXEC_CMD:
333: if (type == SSH_CMSG_EXEC_CMD) {
334: command = packet_get_string(&dlen);
335: debug("Exec command '%.500s'", command);
1.92 markus 336: do_exec(s, command);
337: xfree(command);
1.1 markus 338: } else {
1.92 markus 339: do_exec(s, NULL);
1.1 markus 340: }
1.116 markus 341: packet_check_eom();
1.82 markus 342: session_close(s);
1.1 markus 343: return;
344:
345: default:
346: /*
347: * Any unknown messages in this phase are ignored,
348: * and a failure message is returned.
349: */
1.155 itojun 350: logit("Unknown packet type received after authentication: %d", type);
1.1 markus 351: }
352: packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
353: packet_send();
354: packet_write_wait();
355:
356: /* Enable compression now that we have replied if appropriate. */
357: if (enable_compression_after_reply) {
358: enable_compression_after_reply = 0;
359: packet_start_compression(compression_level);
360: }
361: }
362: }
363:
364: /*
365: * This is called to fork and execute a command when we have no tty. This
366: * will call do_child from the child, and server_loop from the parent after
367: * setting up file descriptors and such.
368: */
1.4 markus 369: void
1.63 markus 370: do_exec_no_pty(Session *s, const char *command)
1.1 markus 371: {
1.137 mpech 372: pid_t pid;
1.1 markus 373:
374: #ifdef USE_PIPES
375: int pin[2], pout[2], perr[2];
376: /* Allocate pipes for communicating with the program. */
377: if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
378: packet_disconnect("Could not create pipes: %.100s",
379: strerror(errno));
380: #else /* USE_PIPES */
381: int inout[2], err[2];
382: /* Uses socket pairs to communicate with the program. */
383: if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
384: socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
385: packet_disconnect("Could not create socket pairs: %.100s",
386: strerror(errno));
387: #endif /* USE_PIPES */
388: if (s == NULL)
389: fatal("do_exec_no_pty: no session");
390:
1.9 markus 391: session_proctitle(s);
1.1 markus 392:
393: /* Fork the child. */
394: if ((pid = fork()) == 0) {
1.165 markus 395: is_child = 1;
1.144 markus 396:
1.1 markus 397: /* Child. Reinitialize the log since the pid has changed. */
398: log_init(__progname, options.log_level, options.log_facility, log_stderr);
399:
400: /*
401: * Create a new session and process group since the 4.4BSD
402: * setlogin() affects the entire process group.
403: */
404: if (setsid() < 0)
405: error("setsid failed: %.100s", strerror(errno));
406:
407: #ifdef USE_PIPES
408: /*
409: * Redirect stdin. We close the parent side of the socket
410: * pair, and make the child side the standard input.
411: */
412: close(pin[1]);
413: if (dup2(pin[0], 0) < 0)
414: perror("dup2 stdin");
415: close(pin[0]);
416:
417: /* Redirect stdout. */
418: close(pout[0]);
419: if (dup2(pout[1], 1) < 0)
420: perror("dup2 stdout");
421: close(pout[1]);
422:
423: /* Redirect stderr. */
424: close(perr[0]);
425: if (dup2(perr[1], 2) < 0)
426: perror("dup2 stderr");
427: close(perr[1]);
428: #else /* USE_PIPES */
429: /*
430: * Redirect stdin, stdout, and stderr. Stdin and stdout will
431: * use the same socket, as some programs (particularly rdist)
432: * seem to depend on it.
433: */
434: close(inout[1]);
435: close(err[1]);
436: if (dup2(inout[0], 0) < 0) /* stdin */
437: perror("dup2 stdin");
438: if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */
439: perror("dup2 stdout");
440: if (dup2(err[0], 2) < 0) /* stderr */
441: perror("dup2 stderr");
442: #endif /* USE_PIPES */
443:
444: /* Do processing for the child (exec command etc). */
1.60 markus 445: do_child(s, command);
1.1 markus 446: /* NOTREACHED */
447: }
448: if (pid < 0)
449: packet_disconnect("fork failed: %.100s", strerror(errno));
450: s->pid = pid;
1.47 markus 451: /* Set interactive/non-interactive mode. */
1.48 markus 452: packet_set_interactive(s->display != NULL);
1.1 markus 453: #ifdef USE_PIPES
454: /* We are the parent. Close the child sides of the pipes. */
455: close(pin[0]);
456: close(pout[1]);
457: close(perr[1]);
458:
1.2 markus 459: if (compat20) {
1.176 djm 460: if (s->is_subsystem) {
461: close(perr[0]);
462: perr[0] = -1;
463: }
464: session_set_fds(s, pin[1], pout[0], perr[0]);
1.2 markus 465: } else {
466: /* Enter the interactive session. */
467: server_loop(pid, pin[1], pout[0], perr[0]);
1.64 markus 468: /* server_loop has closed pin[1], pout[0], and perr[0]. */
1.2 markus 469: }
1.1 markus 470: #else /* USE_PIPES */
471: /* We are the parent. Close the child sides of the socket pairs. */
472: close(inout[0]);
473: close(err[0]);
474:
475: /*
476: * Enter the interactive session. Note: server_loop must be able to
477: * handle the case that fdin and fdout are the same.
478: */
1.2 markus 479: if (compat20) {
1.64 markus 480: session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
1.2 markus 481: } else {
482: server_loop(pid, inout[1], inout[1], err[1]);
483: /* server_loop has closed inout[1] and err[1]. */
484: }
1.1 markus 485: #endif /* USE_PIPES */
486: }
487:
488: /*
489: * This is called to fork and execute a command when we have a tty. This
490: * will call do_child from the child, and server_loop from the parent after
491: * setting up file descriptors, controlling tty, updating wtmp, utmp,
492: * lastlog, and other such operations.
493: */
1.4 markus 494: void
1.63 markus 495: do_exec_pty(Session *s, const char *command)
1.1 markus 496: {
497: int fdout, ptyfd, ttyfd, ptymaster;
498: pid_t pid;
499:
500: if (s == NULL)
501: fatal("do_exec_pty: no session");
502: ptyfd = s->ptyfd;
503: ttyfd = s->ttyfd;
504:
505: /* Fork the child. */
506: if ((pid = fork()) == 0) {
1.165 markus 507: is_child = 1;
1.97 markus 508:
1.24 markus 509: /* Child. Reinitialize the log because the pid has changed. */
1.1 markus 510: log_init(__progname, options.log_level, options.log_facility, log_stderr);
511: /* Close the master side of the pseudo tty. */
512: close(ptyfd);
513:
514: /* Make the pseudo tty our controlling tty. */
515: pty_make_controlling_tty(&ttyfd, s->tty);
516:
1.103 markus 517: /* Redirect stdin/stdout/stderr from the pseudo tty. */
518: if (dup2(ttyfd, 0) < 0)
519: error("dup2 stdin: %s", strerror(errno));
520: if (dup2(ttyfd, 1) < 0)
521: error("dup2 stdout: %s", strerror(errno));
522: if (dup2(ttyfd, 2) < 0)
523: error("dup2 stderr: %s", strerror(errno));
1.1 markus 524:
525: /* Close the extra descriptor for the pseudo tty. */
526: close(ttyfd);
527:
1.24 markus 528: /* record login, etc. similar to login(1) */
1.41 markus 529: if (!(options.use_login && command == NULL))
530: do_login(s, command);
1.1 markus 531:
532: /* Do common processing for the child, such as execing the command. */
1.60 markus 533: do_child(s, command);
1.1 markus 534: /* NOTREACHED */
535: }
536: if (pid < 0)
537: packet_disconnect("fork failed: %.100s", strerror(errno));
538: s->pid = pid;
539:
540: /* Parent. Close the slave side of the pseudo tty. */
541: close(ttyfd);
542:
543: /*
544: * Create another descriptor of the pty master side for use as the
545: * standard input. We could use the original descriptor, but this
546: * simplifies code in server_loop. The descriptor is bidirectional.
547: */
548: fdout = dup(ptyfd);
549: if (fdout < 0)
550: packet_disconnect("dup #1 failed: %.100s", strerror(errno));
551:
552: /* we keep a reference to the pty master */
553: ptymaster = dup(ptyfd);
554: if (ptymaster < 0)
555: packet_disconnect("dup #2 failed: %.100s", strerror(errno));
556: s->ptymaster = ptymaster;
557:
558: /* Enter interactive session. */
1.47 markus 559: packet_set_interactive(1);
1.2 markus 560: if (compat20) {
561: session_set_fds(s, ptyfd, fdout, -1);
562: } else {
563: server_loop(pid, ptyfd, fdout, -1);
564: /* server_loop _has_ closed ptyfd and fdout. */
1.24 markus 565: }
566: }
567:
1.90 markus 568: /*
569: * This is called to fork and execute a command. If another command is
570: * to be forced, execute that instead.
571: */
572: void
573: do_exec(Session *s, const char *command)
574: {
575: if (forced_command) {
576: original_command = command;
577: command = forced_command;
578: debug("Forced command '%.900s'", command);
579: }
1.163 markus 580:
581: #ifdef GSSAPI
582: if (options.gss_authentication) {
583: temporarily_use_uid(s->pw);
584: ssh_gssapi_storecreds();
585: restore_uid();
586: }
587: #endif
1.90 markus 588:
589: if (s->ttyfd != -1)
590: do_exec_pty(s, command);
591: else
592: do_exec_no_pty(s, command);
593:
1.92 markus 594: original_command = NULL;
1.179 dtucker 595:
596: /*
597: * Clear loginmsg: it's the child's responsibility to display
598: * it to the user, otherwise multiple sessions may accumulate
599: * multiple copies of the login messages.
600: */
601: buffer_clear(&loginmsg);
1.90 markus 602: }
603:
604:
1.24 markus 605: /* administrative, login(1)-like work */
606: void
1.41 markus 607: do_login(Session *s, const char *command)
1.24 markus 608: {
609: socklen_t fromlen;
610: struct sockaddr_storage from;
611: struct passwd * pw = s->pw;
612: pid_t pid = getpid();
613:
614: /*
615: * Get IP address of client. If the connection is not a socket, let
616: * the address be 0.0.0.0.
617: */
618: memset(&from, 0, sizeof(from));
1.148 stevesk 619: fromlen = sizeof(from);
1.24 markus 620: if (packet_connection_is_on_socket()) {
621: if (getpeername(packet_get_connection_in(),
1.112 deraadt 622: (struct sockaddr *) & from, &fromlen) < 0) {
1.24 markus 623: debug("getpeername: %.100s", strerror(errno));
1.165 markus 624: cleanup_exit(255);
1.24 markus 625: }
626: }
1.25 markus 627:
1.24 markus 628: /* Record that there was a login on that tty from the remote host. */
1.133 markus 629: if (!use_privsep)
630: record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
631: get_remote_name_or_ip(utmp_len,
1.158 markus 632: options.use_dns),
1.148 stevesk 633: (struct sockaddr *)&from, fromlen);
1.24 markus 634:
1.73 djm 635: if (check_quietlogin(s, command))
1.24 markus 636: return;
1.73 djm 637:
1.179 dtucker 638: display_loginmsg();
1.73 djm 639:
640: do_motd();
641: }
642:
643: /*
644: * Display the message of the day.
645: */
646: void
647: do_motd(void)
648: {
649: FILE *f;
650: char buf[256];
651:
1.24 markus 652: if (options.print_motd) {
1.28 millert 653: #ifdef HAVE_LOGIN_CAP
654: f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
655: "/etc/motd"), "r");
656: #else
1.24 markus 657: f = fopen("/etc/motd", "r");
1.28 millert 658: #endif
1.24 markus 659: if (f) {
660: while (fgets(buf, sizeof(buf), f))
661: fputs(buf, stdout);
662: fclose(f);
663: }
1.2 markus 664: }
1.73 djm 665: }
666:
667:
668: /*
669: * Check for quiet login, either .hushlogin or command given.
670: */
671: int
672: check_quietlogin(Session *s, const char *command)
673: {
674: char buf[256];
1.96 dugsong 675: struct passwd *pw = s->pw;
1.73 djm 676: struct stat st;
677:
678: /* Return 1 if .hushlogin exists or a command given. */
679: if (command != NULL)
680: return 1;
681: snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
682: #ifdef HAVE_LOGIN_CAP
683: if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
684: return 1;
685: #else
686: if (stat(buf, &st) >= 0)
687: return 1;
688: #endif
689: return 0;
1.1 markus 690: }
691:
692: /*
693: * Sets the value of the given variable in the environment. If the variable
694: * already exists, its value is overriden.
695: */
1.161 markus 696: void
1.45 markus 697: child_set_env(char ***envp, u_int *envsizep, const char *name,
1.112 deraadt 698: const char *value)
1.1 markus 699: {
1.164 markus 700: char **env;
701: u_int envsize;
1.45 markus 702: u_int i, namelen;
1.1 markus 703:
704: /*
705: * Find the slot where the value should be stored. If the variable
706: * already exists, we reuse the slot; otherwise we append a new slot
707: * at the end of the array, expanding if necessary.
708: */
709: env = *envp;
710: namelen = strlen(name);
711: for (i = 0; env[i]; i++)
712: if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
713: break;
714: if (env[i]) {
715: /* Reuse the slot. */
716: xfree(env[i]);
717: } else {
718: /* New variable. Expand if necessary. */
1.164 markus 719: envsize = *envsizep;
720: if (i >= envsize - 1) {
721: if (envsize >= 1000)
722: fatal("child_set_env: too many env vars");
723: envsize += 50;
724: env = (*envp) = xrealloc(env, envsize * sizeof(char *));
725: *envsizep = envsize;
1.1 markus 726: }
727: /* Need to set the NULL pointer at end of array beyond the new slot. */
728: env[i + 1] = NULL;
729: }
730:
731: /* Allocate space and format the variable in the appropriate slot. */
732: env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
733: snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
734: }
735:
736: /*
737: * Reads environment variables from the given file and adds/overrides them
738: * into the environment. If the file does not exist, this does nothing.
739: * Otherwise, it must consist of empty lines, comments (line starts with '#')
740: * and assignments of the form name=value. No other forms are allowed.
741: */
1.94 itojun 742: static void
1.45 markus 743: read_environment_file(char ***env, u_int *envsize,
1.112 deraadt 744: const char *filename)
1.1 markus 745: {
746: FILE *f;
747: char buf[4096];
748: char *cp, *value;
1.142 deraadt 749: u_int lineno = 0;
1.1 markus 750:
751: f = fopen(filename, "r");
752: if (!f)
753: return;
754:
755: while (fgets(buf, sizeof(buf), f)) {
1.142 deraadt 756: if (++lineno > 1000)
757: fatal("Too many lines in environment file %s", filename);
1.1 markus 758: for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
759: ;
760: if (!*cp || *cp == '#' || *cp == '\n')
761: continue;
762: if (strchr(cp, '\n'))
763: *strchr(cp, '\n') = '\0';
764: value = strchr(cp, '=');
765: if (value == NULL) {
1.142 deraadt 766: fprintf(stderr, "Bad line %u in %.100s\n", lineno,
767: filename);
1.1 markus 768: continue;
769: }
1.14 deraadt 770: /*
771: * Replace the equals sign by nul, and advance value to
772: * the value string.
773: */
1.1 markus 774: *value = '\0';
775: value++;
776: child_set_env(env, envsize, cp, value);
777: }
778: fclose(f);
779: }
780:
1.127 markus 781: static char **
782: do_setup_env(Session *s, const char *shell)
1.1 markus 783: {
784: char buf[256];
1.127 markus 785: u_int i, envsize;
1.154 markus 786: char **env, *laddr;
1.127 markus 787: struct passwd *pw = s->pw;
1.1 markus 788:
789: /* Initialize the environment. */
790: envsize = 100;
791: env = xmalloc(envsize * sizeof(char *));
792: env[0] = NULL;
793:
1.161 markus 794: #ifdef GSSAPI
1.168 djm 795: /* Allow any GSSAPI methods that we've used to alter
1.161 markus 796: * the childs environment as they see fit
797: */
798: ssh_gssapi_do_child(&env, &envsize);
799: #endif
800:
1.1 markus 801: if (!options.use_login) {
802: /* Set basic environment. */
1.173 djm 803: for (i = 0; i < s->num_env; i++)
1.178 deraadt 804: child_set_env(&env, &envsize, s->env[i].name,
1.173 djm 805: s->env[i].val);
806:
1.1 markus 807: child_set_env(&env, &envsize, "USER", pw->pw_name);
808: child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
809: child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1.28 millert 810: #ifdef HAVE_LOGIN_CAP
1.145 markus 811: if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0)
812: child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
813: else
814: child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1.28 millert 815: #else
1.29 millert 816: child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1.28 millert 817: #endif
1.1 markus 818:
819: snprintf(buf, sizeof buf, "%.200s/%.50s",
820: _PATH_MAILDIR, pw->pw_name);
821: child_set_env(&env, &envsize, "MAIL", buf);
822:
823: /* Normal systems set SHELL by default. */
824: child_set_env(&env, &envsize, "SHELL", shell);
825: }
826: if (getenv("TZ"))
827: child_set_env(&env, &envsize, "TZ", getenv("TZ"));
828:
829: /* Set custom environment options from RSA authentication. */
1.110 markus 830: if (!options.use_login) {
831: while (custom_environment) {
832: struct envstring *ce = custom_environment;
1.143 deraadt 833: char *str = ce->s;
1.127 markus 834:
1.143 deraadt 835: for (i = 0; str[i] != '=' && str[i]; i++)
1.110 markus 836: ;
1.143 deraadt 837: if (str[i] == '=') {
838: str[i] = 0;
839: child_set_env(&env, &envsize, str, str + i + 1);
1.110 markus 840: }
841: custom_environment = ce->next;
842: xfree(ce->s);
843: xfree(ce);
1.1 markus 844: }
845: }
846:
1.149 stevesk 847: /* SSH_CLIENT deprecated */
1.1 markus 848: snprintf(buf, sizeof buf, "%.50s %d %d",
1.127 markus 849: get_remote_ipaddr(), get_remote_port(), get_local_port());
1.1 markus 850: child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1.149 stevesk 851:
1.154 markus 852: laddr = get_local_ipaddr(packet_get_connection_in());
1.149 stevesk 853: snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1.154 markus 854: get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
855: xfree(laddr);
1.149 stevesk 856: child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1.1 markus 857:
1.60 markus 858: if (s->ttyfd != -1)
859: child_set_env(&env, &envsize, "SSH_TTY", s->tty);
860: if (s->term)
861: child_set_env(&env, &envsize, "TERM", s->term);
862: if (s->display)
863: child_set_env(&env, &envsize, "DISPLAY", s->display);
1.34 markus 864: if (original_command)
865: child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
866: original_command);
1.96 dugsong 867: #ifdef KRB5
868: if (s->authctxt->krb5_ticket_file)
869: child_set_env(&env, &envsize, "KRB5CCNAME",
1.112 deraadt 870: s->authctxt->krb5_ticket_file);
1.96 dugsong 871: #endif
1.136 markus 872: if (auth_sock_name != NULL)
1.1 markus 873: child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1.136 markus 874: auth_sock_name);
1.1 markus 875:
876: /* read $HOME/.ssh/environment. */
1.146 markus 877: if (options.permit_user_env && !options.use_login) {
1.14 deraadt 878: snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
879: pw->pw_dir);
1.1 markus 880: read_environment_file(&env, &envsize, buf);
881: }
882: if (debug_flag) {
883: /* dump the environment */
884: fprintf(stderr, "Environment:\n");
885: for (i = 0; env[i]; i++)
886: fprintf(stderr, " %.200s\n", env[i]);
887: }
1.127 markus 888: return env;
889: }
890:
891: /*
892: * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
893: * first in this order).
894: */
895: static void
896: do_rc_files(Session *s, const char *shell)
897: {
898: FILE *f = NULL;
899: char cmd[1024];
900: int do_xauth;
901: struct stat st;
902:
903: do_xauth =
904: s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
905:
906: /* ignore _PATH_SSH_USER_RC for subsystems */
907: if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
908: snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
909: shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
910: if (debug_flag)
911: fprintf(stderr, "Running %s\n", cmd);
912: f = popen(cmd, "w");
913: if (f) {
914: if (do_xauth)
915: fprintf(f, "%s %s\n", s->auth_proto,
916: s->auth_data);
917: pclose(f);
918: } else
919: fprintf(stderr, "Could not run %s\n",
920: _PATH_SSH_USER_RC);
921: } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
922: if (debug_flag)
923: fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
924: _PATH_SSH_SYSTEM_RC);
925: f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
926: if (f) {
927: if (do_xauth)
928: fprintf(f, "%s %s\n", s->auth_proto,
929: s->auth_data);
930: pclose(f);
931: } else
932: fprintf(stderr, "Could not run %s\n",
933: _PATH_SSH_SYSTEM_RC);
934: } else if (do_xauth && options.xauth_location != NULL) {
935: /* Add authority data to .Xauthority if appropriate. */
936: if (debug_flag) {
937: fprintf(stderr,
1.151 stevesk 938: "Running %.500s remove %.100s\n",
1.165 markus 939: options.xauth_location, s->auth_display);
1.151 stevesk 940: fprintf(stderr,
941: "%.500s add %.100s %.100s %.100s\n",
1.127 markus 942: options.xauth_location, s->auth_display,
943: s->auth_proto, s->auth_data);
944: }
945: snprintf(cmd, sizeof cmd, "%s -q -",
946: options.xauth_location);
947: f = popen(cmd, "w");
948: if (f) {
1.151 stevesk 949: fprintf(f, "remove %s\n",
950: s->auth_display);
1.127 markus 951: fprintf(f, "add %s %s %s\n",
952: s->auth_display, s->auth_proto,
953: s->auth_data);
954: pclose(f);
955: } else {
956: fprintf(stderr, "Could not run %s\n",
957: cmd);
958: }
959: }
960: }
961:
962: static void
963: do_nologin(struct passwd *pw)
964: {
965: FILE *f = NULL;
966: char buf[1024];
967:
968: #ifdef HAVE_LOGIN_CAP
969: if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
970: f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
971: _PATH_NOLOGIN), "r");
972: #else
973: if (pw->pw_uid)
974: f = fopen(_PATH_NOLOGIN, "r");
975: #endif
976: if (f) {
977: /* /etc/nologin exists. Print its contents and exit. */
1.155 itojun 978: logit("User %.100s not allowed because %s exists",
1.150 stevesk 979: pw->pw_name, _PATH_NOLOGIN);
1.127 markus 980: while (fgets(buf, sizeof(buf), f))
981: fputs(buf, stderr);
982: fclose(f);
983: exit(254);
984: }
985: }
986:
987: /* Set login name, uid, gid, and groups. */
1.130 provos 988: void
1.127 markus 989: do_setusercontext(struct passwd *pw)
990: {
991: if (getuid() == 0 || geteuid() == 0) {
992: #ifdef HAVE_LOGIN_CAP
993: if (setusercontext(lc, pw, pw->pw_uid,
994: (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
995: perror("unable to set user context");
996: exit(1);
997: }
998: #else
999: if (setlogin(pw->pw_name) < 0)
1000: error("setlogin failed: %s", strerror(errno));
1001: if (setgid(pw->pw_gid) < 0) {
1002: perror("setgid");
1003: exit(1);
1004: }
1005: /* Initialize the group list. */
1006: if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1007: perror("initgroups");
1008: exit(1);
1009: }
1010: endgrent();
1011:
1012: /* Permanently switch to the desired uid. */
1013: permanently_set_uid(pw);
1014: #endif
1015: }
1016: if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1017: fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1018: }
1019:
1.131 markus 1020: static void
1.172 markus 1021: do_pwchange(Session *s)
1022: {
1.179 dtucker 1023: fflush(NULL);
1.172 markus 1024: fprintf(stderr, "WARNING: Your password has expired.\n");
1025: if (s->ttyfd != -1) {
1.178 deraadt 1026: fprintf(stderr,
1.172 markus 1027: "You must change your password now and login again!\n");
1028: execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
1029: perror("passwd");
1030: } else {
1031: fprintf(stderr,
1032: "Password change required but no TTY available.\n");
1033: }
1034: exit(1);
1035: }
1036:
1037: static void
1.130 provos 1038: launch_login(struct passwd *pw, const char *hostname)
1039: {
1040: /* Launch login(1). */
1041:
1042: execl("/usr/bin/login", "login", "-h", hostname,
1043: "-p", "-f", "--", pw->pw_name, (char *)NULL);
1044:
1045: /* Login couldn't be executed, die. */
1046:
1047: perror("login");
1048: exit(1);
1049: }
1050:
1.172 markus 1051: static void
1052: child_close_fds(void)
1053: {
1054: int i;
1055:
1056: if (packet_get_connection_in() == packet_get_connection_out())
1057: close(packet_get_connection_in());
1058: else {
1059: close(packet_get_connection_in());
1060: close(packet_get_connection_out());
1061: }
1062: /*
1063: * Close all descriptors related to channels. They will still remain
1064: * open in the parent.
1065: */
1066: /* XXX better use close-on-exec? -markus */
1067: channel_close_all();
1068:
1069: /*
1070: * Close any extra file descriptors. Note that there may still be
1071: * descriptors left by system functions. They will be closed later.
1072: */
1073: endpwent();
1074:
1075: /*
1.188 djm 1076: * Close any extra open file descriptors so that we don't have them
1.172 markus 1077: * hanging around in clients. Note that we want to do this after
1078: * initgroups, because at least on Solaris 2.3 it leaves file
1079: * descriptors open.
1080: */
1081: for (i = 3; i < 64; i++)
1082: close(i);
1083: }
1084:
1.127 markus 1085: /*
1086: * Performs common processing for the child, such as setting up the
1087: * environment, closing extra file descriptors, setting the user and group
1088: * ids, and executing the command or shell.
1089: */
1090: void
1091: do_child(Session *s, const char *command)
1092: {
1093: extern char **environ;
1094: char **env;
1095: char *argv[10];
1096: const char *shell, *shell0, *hostname = NULL;
1097: struct passwd *pw = s->pw;
1098:
1099: /* remove hostkey from the child's memory */
1100: destroy_sensitive_data();
1101:
1.172 markus 1102: /* Force a password change */
1103: if (s->authctxt->force_pwchange) {
1104: do_setusercontext(pw);
1105: child_close_fds();
1106: do_pwchange(s);
1107: exit(1);
1108: }
1109:
1.127 markus 1110: /* login(1) is only called if we execute the login shell */
1111: if (options.use_login && command != NULL)
1112: options.use_login = 0;
1113:
1114: /*
1115: * Login(1) does this as well, and it needs uid 0 for the "-h"
1116: * switch, so we let login(1) to this for us.
1117: */
1118: if (!options.use_login) {
1119: do_nologin(pw);
1120: do_setusercontext(pw);
1121: }
1122:
1123: /*
1124: * Get the shell from the password data. An empty shell field is
1125: * legal, and means /bin/sh.
1126: */
1127: shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1.152 markus 1128:
1129: /*
1130: * Make sure $SHELL points to the shell from the password file,
1131: * even if shell is overridden from login.conf
1132: */
1133: env = do_setup_env(s, shell);
1134:
1.127 markus 1135: #ifdef HAVE_LOGIN_CAP
1136: shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1137: #endif
1138:
1.26 millert 1139: /* we have to stash the hostname before we close our socket. */
1140: if (options.use_login)
1.70 stevesk 1141: hostname = get_remote_name_or_ip(utmp_len,
1.158 markus 1142: options.use_dns);
1.1 markus 1143: /*
1144: * Close the connection descriptors; note that this is the child, and
1145: * the server will still have the socket open, and it is important
1146: * that we do not shutdown it. Note that the descriptors cannot be
1147: * closed before building the environment, as we call
1148: * get_remote_ipaddr there.
1149: */
1.172 markus 1150: child_close_fds();
1.1 markus 1151:
1152: /*
1.125 deraadt 1153: * Must take new environment into use so that .ssh/rc,
1154: * /etc/ssh/sshrc and xauth are run in the proper environment.
1.1 markus 1155: */
1156: environ = env;
1.170 jakob 1157:
1158: #ifdef KRB5
1159: /*
1160: * At this point, we check to see if AFS is active and if we have
1161: * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
1162: * if we can (and need to) extend the ticket into an AFS token. If
1163: * we don't do this, we run into potential problems if the user's
1164: * home directory is in AFS and it's not world-readable.
1165: */
1166:
1167: if (options.kerberos_get_afs_token && k_hasafs() &&
1.185 djm 1168: (s->authctxt->krb5_ctx != NULL)) {
1.170 jakob 1169: char cell[64];
1170:
1171: debug("Getting AFS token");
1172:
1173: k_setpag();
1174:
1175: if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1176: krb5_afslog(s->authctxt->krb5_ctx,
1177: s->authctxt->krb5_fwd_ccache, cell, NULL);
1178:
1179: krb5_afslog_home(s->authctxt->krb5_ctx,
1180: s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
1181: }
1182: #endif
1.104 markus 1183:
1.188 djm 1184: /* Change current directory to the user's home directory. */
1.104 markus 1185: if (chdir(pw->pw_dir) < 0) {
1186: fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1187: pw->pw_dir, strerror(errno));
1188: #ifdef HAVE_LOGIN_CAP
1189: if (login_getcapbool(lc, "requirehome", 0))
1190: exit(1);
1191: #endif
1192: }
1.1 markus 1193:
1.127 markus 1194: if (!options.use_login)
1195: do_rc_files(s, shell);
1.67 markus 1196:
1197: /* restore SIGPIPE for child */
1198: signal(SIGPIPE, SIG_DFL);
1199:
1.127 markus 1200: if (options.use_login) {
1.130 provos 1201: launch_login(pw, hostname);
1202: /* NEVERREACHED */
1.127 markus 1203: }
1204:
1205: /* Get the last component of the shell name. */
1206: if ((shell0 = strrchr(shell, '/')) != NULL)
1207: shell0++;
1208: else
1209: shell0 = shell;
1210:
1.1 markus 1211: /*
1212: * If we have no command, execute the shell. In this case, the shell
1213: * name to be passed in argv[0] is preceded by '-' to indicate that
1214: * this is a login shell.
1215: */
1216: if (!command) {
1.127 markus 1217: char argv0[256];
1.1 markus 1218:
1.127 markus 1219: /* Start the shell. Set initial character to '-'. */
1220: argv0[0] = '-';
1.1 markus 1221:
1.127 markus 1222: if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1.128 markus 1223: >= sizeof(argv0) - 1) {
1.127 markus 1224: errno = EINVAL;
1.1 markus 1225: perror(shell);
1226: exit(1);
1.127 markus 1227: }
1.1 markus 1228:
1.127 markus 1229: /* Execute the shell. */
1230: argv[0] = argv0;
1231: argv[1] = NULL;
1232: execve(shell, argv, env);
1233:
1234: /* Executing the shell failed. */
1235: perror(shell);
1236: exit(1);
1.1 markus 1237: }
1238: /*
1239: * Execute the command using the user's shell. This uses the -c
1240: * option to execute the command.
1241: */
1.127 markus 1242: argv[0] = (char *) shell0;
1.1 markus 1243: argv[1] = "-c";
1244: argv[2] = (char *) command;
1245: argv[3] = NULL;
1246: execve(shell, argv, env);
1247: perror(shell);
1248: exit(1);
1249: }
1250:
1251: Session *
1252: session_new(void)
1253: {
1254: int i;
1255: static int did_init = 0;
1256: if (!did_init) {
1257: debug("session_new: init");
1.112 deraadt 1258: for (i = 0; i < MAX_SESSIONS; i++) {
1.1 markus 1259: sessions[i].used = 0;
1260: }
1261: did_init = 1;
1262: }
1.112 deraadt 1263: for (i = 0; i < MAX_SESSIONS; i++) {
1.1 markus 1264: Session *s = &sessions[i];
1265: if (! s->used) {
1.68 djm 1266: memset(s, 0, sizeof(*s));
1.1 markus 1267: s->chanid = -1;
1268: s->ptyfd = -1;
1269: s->ttyfd = -1;
1270: s->used = 1;
1.85 markus 1271: s->self = i;
1.184 djm 1272: s->x11_chanids = NULL;
1.1 markus 1273: debug("session_new: session %d", i);
1274: return s;
1275: }
1276: }
1277: return NULL;
1278: }
1279:
1.94 itojun 1280: static void
1.1 markus 1281: session_dump(void)
1282: {
1283: int i;
1.112 deraadt 1284: for (i = 0; i < MAX_SESSIONS; i++) {
1.1 markus 1285: Session *s = &sessions[i];
1.137 mpech 1286: debug("dump: used %d session %d %p channel %d pid %ld",
1.1 markus 1287: s->used,
1288: s->self,
1289: s,
1290: s->chanid,
1.137 mpech 1291: (long)s->pid);
1.1 markus 1292: }
1293: }
1294:
1.2 markus 1295: int
1.97 markus 1296: session_open(Authctxt *authctxt, int chanid)
1.2 markus 1297: {
1298: Session *s = session_new();
1299: debug("session_open: channel %d", chanid);
1300: if (s == NULL) {
1301: error("no more sessions");
1302: return 0;
1303: }
1.97 markus 1304: s->authctxt = authctxt;
1305: s->pw = authctxt->pw;
1.167 djm 1306: if (s->pw == NULL || !authctxt->valid)
1.54 stevesk 1307: fatal("no user for session %d", s->self);
1.2 markus 1308: debug("session_open: session %d: link with channel %d", s->self, chanid);
1309: s->chanid = chanid;
1310: return 1;
1311: }
1312:
1.130 provos 1313: Session *
1314: session_by_tty(char *tty)
1315: {
1316: int i;
1317: for (i = 0; i < MAX_SESSIONS; i++) {
1318: Session *s = &sessions[i];
1319: if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1320: debug("session_by_tty: session %d tty %s", i, tty);
1321: return s;
1322: }
1323: }
1324: debug("session_by_tty: unknown tty %.100s", tty);
1325: session_dump();
1326: return NULL;
1327: }
1328:
1.94 itojun 1329: static Session *
1.2 markus 1330: session_by_channel(int id)
1331: {
1332: int i;
1.112 deraadt 1333: for (i = 0; i < MAX_SESSIONS; i++) {
1.2 markus 1334: Session *s = &sessions[i];
1335: if (s->used && s->chanid == id) {
1336: debug("session_by_channel: session %d channel %d", i, id);
1337: return s;
1338: }
1339: }
1340: debug("session_by_channel: unknown channel %d", id);
1341: session_dump();
1342: return NULL;
1343: }
1344:
1.94 itojun 1345: static Session *
1.184 djm 1346: session_by_x11_channel(int id)
1347: {
1348: int i, j;
1349:
1350: for (i = 0; i < MAX_SESSIONS; i++) {
1351: Session *s = &sessions[i];
1352:
1353: if (s->x11_chanids == NULL || !s->used)
1354: continue;
1355: for (j = 0; s->x11_chanids[j] != -1; j++) {
1356: if (s->x11_chanids[j] == id) {
1357: debug("session_by_x11_channel: session %d "
1358: "channel %d", s->self, id);
1359: return s;
1360: }
1361: }
1362: }
1363: debug("session_by_x11_channel: unknown channel %d", id);
1364: session_dump();
1365: return NULL;
1366: }
1367:
1368: static Session *
1.2 markus 1369: session_by_pid(pid_t pid)
1370: {
1371: int i;
1.137 mpech 1372: debug("session_by_pid: pid %ld", (long)pid);
1.112 deraadt 1373: for (i = 0; i < MAX_SESSIONS; i++) {
1.2 markus 1374: Session *s = &sessions[i];
1375: if (s->used && s->pid == pid)
1376: return s;
1377: }
1.137 mpech 1378: error("session_by_pid: unknown pid %ld", (long)pid);
1.2 markus 1379: session_dump();
1380: return NULL;
1381: }
1382:
1.94 itojun 1383: static int
1.2 markus 1384: session_window_change_req(Session *s)
1385: {
1386: s->col = packet_get_int();
1387: s->row = packet_get_int();
1388: s->xpixel = packet_get_int();
1389: s->ypixel = packet_get_int();
1.116 markus 1390: packet_check_eom();
1.2 markus 1391: pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1392: return 1;
1393: }
1394:
1.94 itojun 1395: static int
1.2 markus 1396: session_pty_req(Session *s)
1397: {
1.45 markus 1398: u_int len;
1.72 stevesk 1399: int n_bytes;
1.132 markus 1400:
1.86 markus 1401: if (no_pty_flag) {
1402: debug("Allocating a pty not permitted for this authentication.");
1.19 markus 1403: return 0;
1.86 markus 1404: }
1405: if (s->ttyfd != -1) {
1406: packet_disconnect("Protocol error: you already have a pty.");
1.3 markus 1407: return 0;
1.86 markus 1408: }
1409:
1.2 markus 1410: s->term = packet_get_string(&len);
1.86 markus 1411:
1412: if (compat20) {
1413: s->col = packet_get_int();
1414: s->row = packet_get_int();
1415: } else {
1416: s->row = packet_get_int();
1417: s->col = packet_get_int();
1418: }
1.2 markus 1419: s->xpixel = packet_get_int();
1420: s->ypixel = packet_get_int();
1421:
1422: if (strcmp(s->term, "") == 0) {
1423: xfree(s->term);
1424: s->term = NULL;
1425: }
1.86 markus 1426:
1.2 markus 1427: /* Allocate a pty and open it. */
1.86 markus 1428: debug("Allocating pty.");
1.130 provos 1429: if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
1.86 markus 1430: if (s->term)
1431: xfree(s->term);
1.2 markus 1432: s->term = NULL;
1433: s->ptyfd = -1;
1434: s->ttyfd = -1;
1435: error("session_pty_req: session %d alloc failed", s->self);
1.3 markus 1436: return 0;
1.2 markus 1437: }
1438: debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1.86 markus 1439:
1440: /* for SSH1 the tty modes length is not given */
1441: if (!compat20)
1442: n_bytes = packet_remaining();
1443: tty_parse_modes(s->ttyfd, &n_bytes);
1444:
1.130 provos 1445: if (!use_privsep)
1446: pty_setowner(s->pw, s->tty);
1.86 markus 1447:
1448: /* Set window size from the packet. */
1.2 markus 1449: pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1450:
1.116 markus 1451: packet_check_eom();
1.9 markus 1452: session_proctitle(s);
1.2 markus 1453: return 1;
1454: }
1455:
1.94 itojun 1456: static int
1.7 markus 1457: session_subsystem_req(Session *s)
1458: {
1.105 markus 1459: struct stat st;
1.45 markus 1460: u_int len;
1.7 markus 1461: int success = 0;
1.105 markus 1462: char *cmd, *subsys = packet_get_string(&len);
1.182 djm 1463: u_int i;
1.7 markus 1464:
1.116 markus 1465: packet_check_eom();
1.155 itojun 1466: logit("subsystem request for %.100s", subsys);
1.18 jakob 1467:
1468: for (i = 0; i < options.num_subsystems; i++) {
1.105 markus 1469: if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1470: cmd = options.subsystem_command[i];
1471: if (stat(cmd, &st) < 0) {
1472: error("subsystem: cannot stat %s: %s", cmd,
1473: strerror(errno));
1474: break;
1475: }
1476: debug("subsystem: exec() %s", cmd);
1.64 markus 1477: s->is_subsystem = 1;
1.105 markus 1478: do_exec(s, cmd);
1.18 jakob 1479: success = 1;
1.122 markus 1480: break;
1.18 jakob 1481: }
1482: }
1483:
1484: if (!success)
1.155 itojun 1485: logit("subsystem request for %.100s failed, subsystem not found",
1.105 markus 1486: subsys);
1.7 markus 1487:
1488: xfree(subsys);
1489: return success;
1490: }
1491:
1.94 itojun 1492: static int
1.7 markus 1493: session_x11_req(Session *s)
1494: {
1.81 markus 1495: int success;
1.7 markus 1496:
1.184 djm 1497: if (s->auth_proto != NULL || s->auth_data != NULL) {
1498: error("session_x11_req: session %d: "
1.190 stevesk 1499: "x11 forwarding already active", s->self);
1.184 djm 1500: return 0;
1501: }
1.7 markus 1502: s->single_connection = packet_get_char();
1503: s->auth_proto = packet_get_string(NULL);
1504: s->auth_data = packet_get_string(NULL);
1505: s->screen = packet_get_int();
1.116 markus 1506: packet_check_eom();
1.7 markus 1507:
1.81 markus 1508: success = session_setup_x11fwd(s);
1509: if (!success) {
1.7 markus 1510: xfree(s->auth_proto);
1511: xfree(s->auth_data);
1.84 markus 1512: s->auth_proto = NULL;
1513: s->auth_data = NULL;
1.7 markus 1514: }
1.81 markus 1515: return success;
1.7 markus 1516: }
1517:
1.94 itojun 1518: static int
1.19 markus 1519: session_shell_req(Session *s)
1520: {
1.116 markus 1521: packet_check_eom();
1.90 markus 1522: do_exec(s, NULL);
1.19 markus 1523: return 1;
1524: }
1525:
1.94 itojun 1526: static int
1.19 markus 1527: session_exec_req(Session *s)
1528: {
1.45 markus 1529: u_int len;
1.19 markus 1530: char *command = packet_get_string(&len);
1.116 markus 1531: packet_check_eom();
1.90 markus 1532: do_exec(s, command);
1.92 markus 1533: xfree(command);
1.19 markus 1534: return 1;
1535: }
1536:
1.94 itojun 1537: static int
1.157 markus 1538: session_break_req(Session *s)
1539: {
1540:
1.175 deraadt 1541: packet_get_int(); /* ignored */
1.157 markus 1542: packet_check_eom();
1543:
1.160 markus 1544: if (s->ttyfd == -1 ||
1545: tcsendbreak(s->ttyfd, 0) < 0)
1.157 markus 1546: return 0;
1547: return 1;
1548: }
1549:
1550: static int
1.173 djm 1551: session_env_req(Session *s)
1552: {
1553: char *name, *val;
1554: u_int name_len, val_len, i;
1555:
1556: name = packet_get_string(&name_len);
1557: val = packet_get_string(&val_len);
1558: packet_check_eom();
1559:
1560: /* Don't set too many environment variables */
1561: if (s->num_env > 128) {
1562: debug2("Ignoring env request %s: too many env vars", name);
1563: goto fail;
1564: }
1565:
1566: for (i = 0; i < options.num_accept_env; i++) {
1567: if (match_pattern(name, options.accept_env[i])) {
1568: debug2("Setting env %d: %s=%s", s->num_env, name, val);
1569: s->env = xrealloc(s->env, sizeof(*s->env) *
1570: (s->num_env + 1));
1571: s->env[s->num_env].name = name;
1572: s->env[s->num_env].val = val;
1573: s->num_env++;
1574: return (1);
1575: }
1576: }
1577: debug2("Ignoring env request %s: disallowed name", name);
1578:
1579: fail:
1580: xfree(name);
1581: xfree(val);
1582: return (0);
1583: }
1584:
1585: static int
1.43 markus 1586: session_auth_agent_req(Session *s)
1587: {
1588: static int called = 0;
1.116 markus 1589: packet_check_eom();
1.44 markus 1590: if (no_agent_forwarding_flag) {
1591: debug("session_auth_agent_req: no_agent_forwarding_flag");
1592: return 0;
1593: }
1.43 markus 1594: if (called) {
1595: return 0;
1596: } else {
1597: called = 1;
1598: return auth_input_request_forwarding(s->pw);
1599: }
1600: }
1601:
1.123 markus 1602: int
1603: session_input_channel_req(Channel *c, const char *rtype)
1.2 markus 1604: {
1605: int success = 0;
1606: Session *s;
1607:
1.123 markus 1608: if ((s = session_by_channel(c->self)) == NULL) {
1.155 itojun 1609: logit("session_input_channel_req: no session %d req %.100s",
1.123 markus 1610: c->self, rtype);
1611: return 0;
1612: }
1613: debug("session_input_channel_req: session %d req %s", s->self, rtype);
1.2 markus 1614:
1615: /*
1.64 markus 1616: * a session is in LARVAL state until a shell, a command
1617: * or a subsystem is executed
1.2 markus 1618: */
1619: if (c->type == SSH_CHANNEL_LARVAL) {
1620: if (strcmp(rtype, "shell") == 0) {
1.19 markus 1621: success = session_shell_req(s);
1.2 markus 1622: } else if (strcmp(rtype, "exec") == 0) {
1.19 markus 1623: success = session_exec_req(s);
1.2 markus 1624: } else if (strcmp(rtype, "pty-req") == 0) {
1.3 markus 1625: success = session_pty_req(s);
1.7 markus 1626: } else if (strcmp(rtype, "x11-req") == 0) {
1627: success = session_x11_req(s);
1.43 markus 1628: } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1629: success = session_auth_agent_req(s);
1.7 markus 1630: } else if (strcmp(rtype, "subsystem") == 0) {
1631: success = session_subsystem_req(s);
1.173 djm 1632: } else if (strcmp(rtype, "env") == 0) {
1633: success = session_env_req(s);
1.2 markus 1634: }
1635: }
1636: if (strcmp(rtype, "window-change") == 0) {
1637: success = session_window_change_req(s);
1.177 djm 1638: } else if (strcmp(rtype, "break") == 0) {
1639: success = session_break_req(s);
1.2 markus 1640: }
1.177 djm 1641:
1.123 markus 1642: return success;
1.2 markus 1643: }
1644:
1645: void
1646: session_set_fds(Session *s, int fdin, int fdout, int fderr)
1647: {
1648: if (!compat20)
1649: fatal("session_set_fds: called for proto != 2.0");
1650: /*
1651: * now that have a child and a pipe to the child,
1652: * we can activate our channel and register the fd's
1653: */
1654: if (s->chanid == -1)
1655: fatal("no channel for session %d", s->self);
1656: channel_set_fds(s->chanid,
1657: fdout, fdin, fderr,
1.42 markus 1658: fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1.126 markus 1659: 1,
1660: CHAN_SES_WINDOW_DEFAULT);
1.2 markus 1661: }
1662:
1.85 markus 1663: /*
1664: * Function to perform pty cleanup. Also called if we get aborted abnormally
1665: * (e.g., due to a dropped connection).
1666: */
1.130 provos 1667: void
1.165 markus 1668: session_pty_cleanup2(Session *s)
1.1 markus 1669: {
1.85 markus 1670: if (s == NULL) {
1671: error("session_pty_cleanup: no session");
1672: return;
1673: }
1674: if (s->ttyfd == -1)
1.1 markus 1675: return;
1676:
1.54 stevesk 1677: debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
1.1 markus 1678:
1679: /* Record that the user has logged out. */
1.85 markus 1680: if (s->pid != 0)
1681: record_logout(s->pid, s->tty);
1.1 markus 1682:
1683: /* Release the pseudo-tty. */
1.130 provos 1684: if (getuid() == 0)
1685: pty_release(s->tty);
1.1 markus 1686:
1687: /*
1688: * Close the server side of the socket pairs. We must do this after
1689: * the pty cleanup, so that another process doesn't get this pty
1690: * while we're still cleaning up.
1691: */
1692: if (close(s->ptymaster) < 0)
1.130 provos 1693: error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno));
1.108 markus 1694:
1695: /* unlink pty from session */
1696: s->ttyfd = -1;
1.2 markus 1697: }
1698:
1.130 provos 1699: void
1.165 markus 1700: session_pty_cleanup(Session *s)
1.130 provos 1701: {
1.165 markus 1702: PRIVSEP(session_pty_cleanup2(s));
1.130 provos 1703: }
1704:
1.147 markus 1705: static char *
1706: sig2name(int sig)
1707: {
1708: #define SSH_SIG(x) if (sig == SIG ## x) return #x
1709: SSH_SIG(ABRT);
1710: SSH_SIG(ALRM);
1711: SSH_SIG(FPE);
1712: SSH_SIG(HUP);
1713: SSH_SIG(ILL);
1714: SSH_SIG(INT);
1715: SSH_SIG(KILL);
1716: SSH_SIG(PIPE);
1717: SSH_SIG(QUIT);
1718: SSH_SIG(SEGV);
1719: SSH_SIG(TERM);
1720: SSH_SIG(USR1);
1721: SSH_SIG(USR2);
1722: #undef SSH_SIG
1723: return "SIG@openssh.com";
1724: }
1725:
1.94 itojun 1726: static void
1.184 djm 1727: session_close_x11(int id)
1728: {
1729: Channel *c;
1730:
1.189 markus 1731: if ((c = channel_by_id(id)) == NULL) {
1.184 djm 1732: debug("session_close_x11: x11 channel %d missing", id);
1733: } else {
1734: /* Detach X11 listener */
1735: debug("session_close_x11: detach x11 channel %d", id);
1736: channel_cancel_cleanup(id);
1737: if (c->ostate != CHAN_OUTPUT_CLOSED)
1738: chan_mark_dead(c);
1739: }
1740: }
1741:
1742: static void
1743: session_close_single_x11(int id, void *arg)
1744: {
1745: Session *s;
1746: u_int i;
1747:
1748: debug3("session_close_single_x11: channel %d", id);
1749: channel_cancel_cleanup(id);
1750: if ((s = session_by_x11_channel(id)) == NULL)
1751: fatal("session_close_single_x11: no x11 channel %d", id);
1752: for (i = 0; s->x11_chanids[i] != -1; i++) {
1753: debug("session_close_single_x11: session %d: "
1754: "closing channel %d", s->self, s->x11_chanids[i]);
1755: /*
1756: * The channel "id" is already closing, but make sure we
1757: * close all of its siblings.
1758: */
1759: if (s->x11_chanids[i] != id)
1760: session_close_x11(s->x11_chanids[i]);
1761: }
1762: xfree(s->x11_chanids);
1763: s->x11_chanids = NULL;
1764: if (s->display) {
1765: xfree(s->display);
1766: s->display = NULL;
1767: }
1768: if (s->auth_proto) {
1769: xfree(s->auth_proto);
1770: s->auth_proto = NULL;
1771: }
1772: if (s->auth_data) {
1773: xfree(s->auth_data);
1774: s->auth_data = NULL;
1775: }
1776: if (s->auth_display) {
1777: xfree(s->auth_display);
1778: s->auth_display = NULL;
1779: }
1780: }
1781:
1782: static void
1.2 markus 1783: session_exit_message(Session *s, int status)
1784: {
1785: Channel *c;
1.124 markus 1786:
1787: if ((c = channel_lookup(s->chanid)) == NULL)
1.85 markus 1788: fatal("session_exit_message: session %d: no channel %d",
1.2 markus 1789: s->self, s->chanid);
1.137 mpech 1790: debug("session_exit_message: session %d channel %d pid %ld",
1791: s->self, s->chanid, (long)s->pid);
1.2 markus 1792:
1793: if (WIFEXITED(status)) {
1.124 markus 1794: channel_request_start(s->chanid, "exit-status", 0);
1.2 markus 1795: packet_put_int(WEXITSTATUS(status));
1796: packet_send();
1797: } else if (WIFSIGNALED(status)) {
1.124 markus 1798: channel_request_start(s->chanid, "exit-signal", 0);
1.147 markus 1799: packet_put_cstring(sig2name(WTERMSIG(status)));
1.2 markus 1800: packet_put_char(WCOREDUMP(status));
1801: packet_put_cstring("");
1802: packet_put_cstring("");
1803: packet_send();
1804: } else {
1805: /* Some weird exit cause. Just exit. */
1806: packet_disconnect("wait returned status %04x.", status);
1807: }
1808:
1809: /* disconnect channel */
1810: debug("session_exit_message: release channel %d", s->chanid);
1.187 djm 1811: s->pid = 0;
1812:
1813: /*
1814: * Adjust cleanup callback attachment to send close messages when
1815: * the channel gets EOF. The session will be then be closed
1816: * by session_close_by_channel when the childs close their fds.
1817: */
1818: channel_register_cleanup(c->self, session_close_by_channel, 1);
1819:
1.5 markus 1820: /*
1821: * emulate a write failure with 'chan_write_failed', nobody will be
1822: * interested in data we write.
1823: * Note that we must not call 'chan_read_failed', since there could
1824: * be some more data waiting in the pipe.
1825: */
1.8 markus 1826: if (c->ostate != CHAN_OUTPUT_CLOSED)
1827: chan_write_failed(c);
1.2 markus 1828: }
1829:
1.130 provos 1830: void
1.85 markus 1831: session_close(Session *s)
1.2 markus 1832: {
1.182 djm 1833: u_int i;
1.173 djm 1834:
1.137 mpech 1835: debug("session_close: session %d pid %ld", s->self, (long)s->pid);
1.165 markus 1836: if (s->ttyfd != -1)
1.85 markus 1837: session_pty_cleanup(s);
1.2 markus 1838: if (s->term)
1839: xfree(s->term);
1840: if (s->display)
1841: xfree(s->display);
1.184 djm 1842: if (s->x11_chanids)
1843: xfree(s->x11_chanids);
1.118 stevesk 1844: if (s->auth_display)
1845: xfree(s->auth_display);
1.2 markus 1846: if (s->auth_data)
1847: xfree(s->auth_data);
1848: if (s->auth_proto)
1849: xfree(s->auth_proto);
1850: s->used = 0;
1.173 djm 1851: for (i = 0; i < s->num_env; i++) {
1852: xfree(s->env[i].name);
1853: xfree(s->env[i].val);
1854: }
1855: if (s->env != NULL)
1856: xfree(s->env);
1.9 markus 1857: session_proctitle(s);
1.2 markus 1858: }
1859:
1860: void
1861: session_close_by_pid(pid_t pid, int status)
1862: {
1863: Session *s = session_by_pid(pid);
1864: if (s == NULL) {
1.137 mpech 1865: debug("session_close_by_pid: no session for pid %ld",
1866: (long)pid);
1.2 markus 1867: return;
1868: }
1869: if (s->chanid != -1)
1870: session_exit_message(s, status);
1.187 djm 1871: if (s->ttyfd != -1)
1872: session_pty_cleanup(s);
1.98 markus 1873: }
1874:
1.2 markus 1875: /*
1876: * this is called when a channel dies before
1877: * the session 'child' itself dies
1878: */
1879: void
1880: session_close_by_channel(int id, void *arg)
1881: {
1882: Session *s = session_by_channel(id);
1.187 djm 1883: u_int i;
1.184 djm 1884:
1.2 markus 1885: if (s == NULL) {
1.107 markus 1886: debug("session_close_by_channel: no session for id %d", id);
1.2 markus 1887: return;
1888: }
1.137 mpech 1889: debug("session_close_by_channel: channel %d child %ld",
1890: id, (long)s->pid);
1.107 markus 1891: if (s->pid != 0) {
1892: debug("session_close_by_channel: channel %d: has child", id);
1.108 markus 1893: /*
1894: * delay detach of session, but release pty, since
1895: * the fd's to the child are already closed
1896: */
1.165 markus 1897: if (s->ttyfd != -1)
1.108 markus 1898: session_pty_cleanup(s);
1.107 markus 1899: return;
1900: }
1901: /* detach by removing callback */
1.2 markus 1902: channel_cancel_cleanup(s->chanid);
1.187 djm 1903:
1904: /* Close any X11 listeners associated with this session */
1905: if (s->x11_chanids != NULL) {
1906: for (i = 0; s->x11_chanids[i] != -1; i++) {
1907: session_close_x11(s->x11_chanids[i]);
1908: s->x11_chanids[i] = -1;
1909: }
1910: }
1911:
1.2 markus 1912: s->chanid = -1;
1.106 markus 1913: session_close(s);
1914: }
1915:
1916: void
1.130 provos 1917: session_destroy_all(void (*closefunc)(Session *))
1.106 markus 1918: {
1919: int i;
1.112 deraadt 1920: for (i = 0; i < MAX_SESSIONS; i++) {
1.106 markus 1921: Session *s = &sessions[i];
1.130 provos 1922: if (s->used) {
1923: if (closefunc != NULL)
1924: closefunc(s);
1925: else
1926: session_close(s);
1927: }
1.2 markus 1928: }
1.9 markus 1929: }
1930:
1.94 itojun 1931: static char *
1.9 markus 1932: session_tty_list(void)
1933: {
1934: static char buf[1024];
1935: int i;
1936: buf[0] = '\0';
1.112 deraadt 1937: for (i = 0; i < MAX_SESSIONS; i++) {
1.9 markus 1938: Session *s = &sessions[i];
1939: if (s->used && s->ttyfd != -1) {
1940: if (buf[0] != '\0')
1941: strlcat(buf, ",", sizeof buf);
1942: strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1943: }
1944: }
1945: if (buf[0] == '\0')
1946: strlcpy(buf, "notty", sizeof buf);
1947: return buf;
1948: }
1949:
1950: void
1951: session_proctitle(Session *s)
1952: {
1953: if (s->pw == NULL)
1954: error("no user for session %d", s->self);
1955: else
1956: setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
1.81 markus 1957: }
1958:
1959: int
1960: session_setup_x11fwd(Session *s)
1961: {
1962: struct stat st;
1.109 stevesk 1963: char display[512], auth_display[512];
1964: char hostname[MAXHOSTNAMELEN];
1.184 djm 1965: u_int i;
1.81 markus 1966:
1967: if (no_x11_forwarding_flag) {
1968: packet_send_debug("X11 forwarding disabled in user configuration file.");
1969: return 0;
1970: }
1971: if (!options.x11_forwarding) {
1972: debug("X11 forwarding disabled in server configuration file.");
1973: return 0;
1974: }
1975: if (!options.xauth_location ||
1976: (stat(options.xauth_location, &st) == -1)) {
1977: packet_send_debug("No xauth program; cannot forward with spoofing.");
1.91 markus 1978: return 0;
1979: }
1980: if (options.use_login) {
1981: packet_send_debug("X11 forwarding disabled; "
1982: "not compatible with UseLogin=yes.");
1.81 markus 1983: return 0;
1984: }
1.87 markus 1985: if (s->display != NULL) {
1.81 markus 1986: debug("X11 display already set.");
1987: return 0;
1988: }
1.140 deraadt 1989: if (x11_create_display_inet(options.x11_display_offset,
1990: options.x11_use_localhost, s->single_connection,
1.184 djm 1991: &s->display_number, &s->x11_chanids) == -1) {
1.87 markus 1992: debug("x11_create_display_inet failed.");
1.81 markus 1993: return 0;
1.184 djm 1994: }
1995: for (i = 0; s->x11_chanids[i] != -1; i++) {
1996: channel_register_cleanup(s->x11_chanids[i],
1.187 djm 1997: session_close_single_x11, 0);
1.81 markus 1998: }
1.109 stevesk 1999:
2000: /* Set up a suitable value for the DISPLAY variable. */
2001: if (gethostname(hostname, sizeof(hostname)) < 0)
2002: fatal("gethostname: %.100s", strerror(errno));
2003: /*
2004: * auth_display must be used as the displayname when the
2005: * authorization entry is added with xauth(1). This will be
2006: * different than the DISPLAY string for localhost displays.
2007: */
1.119 stevesk 2008: if (options.x11_use_localhost) {
1.140 deraadt 2009: snprintf(display, sizeof display, "localhost:%u.%u",
1.109 stevesk 2010: s->display_number, s->screen);
1.140 deraadt 2011: snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
1.118 stevesk 2012: s->display_number, s->screen);
1.109 stevesk 2013: s->display = xstrdup(display);
1.118 stevesk 2014: s->auth_display = xstrdup(auth_display);
1.109 stevesk 2015: } else {
1.140 deraadt 2016: snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
1.109 stevesk 2017: s->display_number, s->screen);
2018: s->display = xstrdup(display);
1.118 stevesk 2019: s->auth_display = xstrdup(display);
1.109 stevesk 2020: }
2021:
1.81 markus 2022: return 1;
1.2 markus 2023: }
2024:
1.94 itojun 2025: static void
1.49 markus 2026: do_authenticated2(Authctxt *authctxt)
1.2 markus 2027: {
1.97 markus 2028: server_loop2(authctxt);
1.165 markus 2029: }
2030:
2031: void
2032: do_cleanup(Authctxt *authctxt)
2033: {
2034: static int called = 0;
2035:
2036: debug("do_cleanup");
2037:
2038: /* no cleanup if we're in the child for login shell */
2039: if (is_child)
2040: return;
2041:
2042: /* avoid double cleanup */
2043: if (called)
2044: return;
2045: called = 1;
2046:
2047: if (authctxt == NULL)
2048: return;
2049: #ifdef KRB5
2050: if (options.kerberos_ticket_cleanup &&
2051: authctxt->krb5_ctx)
2052: krb5_cleanup_proc(authctxt);
1.161 markus 2053: #endif
1.165 markus 2054:
2055: #ifdef GSSAPI
2056: if (compat20 && options.gss_cleanup_creds)
2057: ssh_gssapi_cleanup_creds();
2058: #endif
2059:
2060: /* remove agent socket */
2061: auth_sock_cleanup_proc(authctxt->pw);
2062:
2063: /*
2064: * Cleanup ptys/utmp only if privsep is disabled,
2065: * or if running in monitor.
2066: */
2067: if (!use_privsep || mm_is_monitor())
2068: session_destroy_all(session_pty_cleanup2);
1.1 markus 2069: }