Annotation of src/usr.bin/ssh/clientloop.c, Revision 1.112.2.1
1.1 deraadt 1: /*
1.12 deraadt 2: * Author: Tatu Ylonen <ylo@cs.hut.fi>
3: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4: * All rights reserved
1.33 deraadt 5: * The main loop for the interactive session (client side).
1.20 markus 6: *
1.33 deraadt 7: * As far as I am concerned, the code I have written for this software
8: * can be used freely for any purpose. Any derived versions of this
9: * software must be clearly marked as such, and if the derived work is
10: * incompatible with the protocol description in the RFC file, it must be
11: * called by a name other than "ssh" or "Secure Shell".
12: *
13: *
14: * Copyright (c) 1999 Theo de Raadt. All rights reserved.
15: *
16: * Redistribution and use in source and binary forms, with or without
17: * modification, are permitted provided that the following conditions
18: * are met:
19: * 1. Redistributions of source code must retain the above copyright
20: * notice, this list of conditions and the following disclaimer.
21: * 2. Redistributions in binary form must reproduce the above copyright
22: * notice, this list of conditions and the following disclaimer in the
23: * documentation and/or other materials provided with the distribution.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.20 markus 35: *
36: *
1.33 deraadt 37: * SSH2 support added by Markus Friedl.
1.78 markus 38: * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
1.20 markus 39: *
1.33 deraadt 40: * Redistribution and use in source and binary forms, with or without
41: * modification, are permitted provided that the following conditions
42: * are met:
43: * 1. Redistributions of source code must retain the above copyright
44: * notice, this list of conditions and the following disclaimer.
45: * 2. Redistributions in binary form must reproduce the above copyright
46: * notice, this list of conditions and the following disclaimer in the
47: * documentation and/or other materials provided with the distribution.
48: *
49: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.12 deraadt 59: */
1.1 deraadt 60:
61: #include "includes.h"
1.112.2.1! brad 62: RCSID("$OpenBSD: clientloop.c,v 1.117 2003/12/16 15:49:51 markus Exp $");
1.1 deraadt 63:
1.45 markus 64: #include "ssh.h"
65: #include "ssh1.h"
66: #include "ssh2.h"
1.1 deraadt 67: #include "xmalloc.h"
68: #include "packet.h"
69: #include "buffer.h"
1.15 markus 70: #include "compat.h"
1.74 markus 71: #include "channels.h"
1.15 markus 72: #include "dispatch.h"
1.30 markus 73: #include "buffer.h"
74: #include "bufaux.h"
1.40 markus 75: #include "key.h"
1.54 markus 76: #include "kex.h"
1.45 markus 77: #include "log.h"
78: #include "readconf.h"
79: #include "clientloop.h"
1.40 markus 80: #include "authfd.h"
1.45 markus 81: #include "atomicio.h"
1.62 stevesk 82: #include "sshtty.h"
1.63 markus 83: #include "misc.h"
1.97 jakob 84: #include "readpass.h"
1.39 markus 85:
86: /* import options */
87: extern Options options;
88:
1.1 deraadt 89: /* Flag indicating that stdin should be redirected from /dev/null. */
90: extern int stdin_null_flag;
91:
1.112.2.1! brad 92: /* Flag indicating that no shell has been requested */
! 93: extern int no_shell_flag;
! 94:
1.13 markus 95: /*
96: * Name of the host we are connecting to. This is the name given on the
97: * command line, or the HostName specified for the user-supplied name in a
98: * configuration file.
99: */
1.1 deraadt 100: extern char *host;
101:
1.13 markus 102: /*
103: * Flag to indicate that we have received a window change signal which has
104: * not yet been processed. This will cause a message indicating the new
105: * window size to be sent to the server a little later. This is volatile
106: * because this is updated in a signal handler.
107: */
1.88 markus 108: static volatile sig_atomic_t received_window_change_signal = 0;
109: static volatile sig_atomic_t received_signal = 0;
1.1 deraadt 110:
111: /* Flag indicating whether the user\'s terminal is in non-blocking mode. */
112: static int in_non_blocking_mode = 0;
113:
114: /* Common data for the client loop code. */
1.31 markus 115: static int quit_pending; /* Set to non-zero to quit the client loop. */
116: static int escape_char; /* Escape character. */
1.11 markus 117: static int escape_pending; /* Last character was the escape character */
118: static int last_was_cr; /* Last character was a newline. */
119: static int exit_status; /* Used to store the exit status of the command. */
120: static int stdin_eof; /* EOF has been encountered on standard error. */
121: static Buffer stdin_buffer; /* Buffer for stdin data. */
122: static Buffer stdout_buffer; /* Buffer for stdout data. */
123: static Buffer stderr_buffer; /* Buffer for stderr data. */
1.42 markus 124: static u_long stdin_bytes, stdout_bytes, stderr_bytes;
125: static u_int buffer_high;/* Soft max buffer size. */
1.11 markus 126: static int connection_in; /* Connection to server (input). */
127: static int connection_out; /* Connection to server (output). */
1.56 markus 128: static int need_rekeying; /* Set to non-zero if rekeying is requested. */
1.60 markus 129: static int session_closed = 0; /* In SSH2: login session closed. */
1.112.2.1! brad 130: static int server_alive_timeouts = 0;
1.1 deraadt 131:
1.77 itojun 132: static void client_init_dispatch(void);
1.16 markus 133: int session_ident = -1;
134:
1.54 markus 135: /*XXX*/
136: extern Kex *xxx_kex;
137:
1.1 deraadt 138: /* Restores stdin to blocking mode. */
139:
1.77 itojun 140: static void
1.49 itojun 141: leave_non_blocking(void)
1.1 deraadt 142: {
1.11 markus 143: if (in_non_blocking_mode) {
144: (void) fcntl(fileno(stdin), F_SETFL, 0);
145: in_non_blocking_mode = 0;
146: }
1.1 deraadt 147: }
148:
1.11 markus 149: /* Puts stdin terminal in non-blocking mode. */
150:
1.77 itojun 151: static void
1.49 itojun 152: enter_non_blocking(void)
1.1 deraadt 153: {
1.11 markus 154: in_non_blocking_mode = 1;
155: (void) fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
1.1 deraadt 156: }
157:
1.13 markus 158: /*
159: * Signal handler for the window change signal (SIGWINCH). This just sets a
160: * flag indicating that the window has changed.
161: */
1.1 deraadt 162:
1.77 itojun 163: static void
1.11 markus 164: window_change_handler(int sig)
1.1 deraadt 165: {
1.11 markus 166: received_window_change_signal = 1;
167: signal(SIGWINCH, window_change_handler);
1.1 deraadt 168: }
169:
1.13 markus 170: /*
171: * Signal handler for signals that cause the program to terminate. These
172: * signals must be trapped to restore terminal modes.
173: */
1.1 deraadt 174:
1.77 itojun 175: static void
1.11 markus 176: signal_handler(int sig)
1.1 deraadt 177: {
1.75 markus 178: received_signal = sig;
179: quit_pending = 1;
1.1 deraadt 180: }
181:
1.13 markus 182: /*
183: * Returns current time in seconds from Jan 1, 1970 with the maximum
184: * available resolution.
185: */
1.1 deraadt 186:
1.77 itojun 187: static double
1.49 itojun 188: get_current_time(void)
1.1 deraadt 189: {
1.11 markus 190: struct timeval tv;
191: gettimeofday(&tv, NULL);
192: return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
1.1 deraadt 193: }
194:
1.13 markus 195: /*
196: * This is called when the interactive is entered. This checks if there is
197: * an EOF coming on stdin. We must check this explicitly, as select() does
198: * not appear to wake up when redirecting from /dev/null.
199: */
1.1 deraadt 200:
1.77 itojun 201: static void
1.49 itojun 202: client_check_initial_eof_on_stdin(void)
1.1 deraadt 203: {
1.11 markus 204: int len;
205: char buf[1];
1.1 deraadt 206:
1.13 markus 207: /*
208: * If standard input is to be "redirected from /dev/null", we simply
209: * mark that we have seen an EOF and send an EOF message to the
210: * server. Otherwise, we try to read a single character; it appears
211: * that for some files, such /dev/null, select() never wakes up for
212: * read for this descriptor, which means that we never get EOF. This
213: * way we will get the EOF if stdin comes from /dev/null or similar.
214: */
1.11 markus 215: if (stdin_null_flag) {
216: /* Fake EOF on stdin. */
217: debug("Sending eof.");
218: stdin_eof = 1;
219: packet_start(SSH_CMSG_EOF);
220: packet_send();
221: } else {
222: enter_non_blocking();
223:
224: /* Check for immediate EOF on stdin. */
225: len = read(fileno(stdin), buf, 1);
226: if (len == 0) {
1.13 markus 227: /* EOF. Record that we have seen it and send EOF to server. */
1.11 markus 228: debug("Sending eof.");
229: stdin_eof = 1;
230: packet_start(SSH_CMSG_EOF);
231: packet_send();
232: } else if (len > 0) {
1.13 markus 233: /*
234: * Got data. We must store the data in the buffer,
235: * and also process it as an escape character if
236: * appropriate.
237: */
1.42 markus 238: if ((u_char) buf[0] == escape_char)
1.11 markus 239: escape_pending = 1;
1.52 markus 240: else
1.11 markus 241: buffer_append(&stdin_buffer, buf, 1);
242: }
243: leave_non_blocking();
244: }
1.1 deraadt 245: }
246:
247:
1.13 markus 248: /*
249: * Make packets from buffered stdin data, and buffer them for sending to the
250: * connection.
251: */
1.1 deraadt 252:
1.77 itojun 253: static void
1.49 itojun 254: client_make_packets_from_stdin_data(void)
1.1 deraadt 255: {
1.42 markus 256: u_int len;
1.1 deraadt 257:
1.11 markus 258: /* Send buffered stdin data to the server. */
259: while (buffer_len(&stdin_buffer) > 0 &&
1.90 deraadt 260: packet_not_very_much_data_to_write()) {
1.11 markus 261: len = buffer_len(&stdin_buffer);
262: /* Keep the packets at reasonable size. */
263: if (len > packet_get_maxsize())
264: len = packet_get_maxsize();
265: packet_start(SSH_CMSG_STDIN_DATA);
266: packet_put_string(buffer_ptr(&stdin_buffer), len);
267: packet_send();
268: buffer_consume(&stdin_buffer, len);
1.52 markus 269: stdin_bytes += len;
1.11 markus 270: /* If we have a pending EOF, send it now. */
271: if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
272: packet_start(SSH_CMSG_EOF);
273: packet_send();
274: }
1.1 deraadt 275: }
276: }
277:
1.13 markus 278: /*
279: * Checks if the client window has changed, and sends a packet about it to
280: * the server if so. The actual change is detected elsewhere (by a software
281: * interrupt on Unix); this just checks the flag and sends a message if
282: * appropriate.
283: */
1.1 deraadt 284:
1.77 itojun 285: static void
1.49 itojun 286: client_check_window_change(void)
1.1 deraadt 287: {
1.16 markus 288: struct winsize ws;
289:
290: if (! received_window_change_signal)
291: return;
292: /** XXX race */
293: received_window_change_signal = 0;
294:
295: if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
296: return;
297:
1.37 markus 298: debug2("client_check_window_change: changed");
1.16 markus 299:
300: if (compat20) {
301: channel_request_start(session_ident, "window-change", 0);
302: packet_put_int(ws.ws_col);
303: packet_put_int(ws.ws_row);
304: packet_put_int(ws.ws_xpixel);
305: packet_put_int(ws.ws_ypixel);
306: packet_send();
307: } else {
308: packet_start(SSH_CMSG_WINDOW_SIZE);
309: packet_put_int(ws.ws_row);
310: packet_put_int(ws.ws_col);
311: packet_put_int(ws.ws_xpixel);
312: packet_put_int(ws.ws_ypixel);
313: packet_send();
1.1 deraadt 314: }
315: }
316:
1.112.2.1! brad 317: static void
! 318: client_global_request_reply(int type, u_int32_t seq, void *ctxt)
! 319: {
! 320: server_alive_timeouts = 0;
! 321: client_global_request_reply_fwd(type, seq, ctxt);
! 322: }
! 323:
! 324: static void
! 325: server_alive_check(void)
! 326: {
! 327: if (++server_alive_timeouts > options.server_alive_count_max)
! 328: packet_disconnect("Timeout, server not responding.");
! 329: packet_start(SSH2_MSG_GLOBAL_REQUEST);
! 330: packet_put_cstring("keepalive@openssh.com");
! 331: packet_put_char(1); /* boolean: want reply */
! 332: packet_send();
! 333: }
! 334:
1.13 markus 335: /*
336: * Waits until the client can do something (some data becomes available on
337: * one of the file descriptors).
338: */
1.1 deraadt 339:
1.77 itojun 340: static void
1.46 markus 341: client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
1.81 markus 342: int *maxfdp, int *nallocp, int rekeying)
1.11 markus 343: {
1.112.2.1! brad 344: struct timeval tv, *tvp;
! 345: int ret;
! 346:
1.46 markus 347: /* Add any selections by the channel mechanism. */
1.81 markus 348: channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
1.11 markus 349:
1.16 markus 350: if (!compat20) {
1.17 markus 351: /* Read from the connection, unless our buffers are full. */
1.16 markus 352: if (buffer_len(&stdout_buffer) < buffer_high &&
353: buffer_len(&stderr_buffer) < buffer_high &&
354: channel_not_very_much_buffered_data())
1.46 markus 355: FD_SET(connection_in, *readsetp);
1.17 markus 356: /*
357: * Read from stdin, unless we have seen EOF or have very much
358: * buffered data to send to the server.
359: */
360: if (!stdin_eof && packet_not_very_much_data_to_write())
1.46 markus 361: FD_SET(fileno(stdin), *readsetp);
1.17 markus 362:
363: /* Select stdout/stderr if have data in buffer. */
364: if (buffer_len(&stdout_buffer) > 0)
1.46 markus 365: FD_SET(fileno(stdout), *writesetp);
1.17 markus 366: if (buffer_len(&stderr_buffer) > 0)
1.46 markus 367: FD_SET(fileno(stderr), *writesetp);
1.16 markus 368: } else {
1.71 markus 369: /* channel_prepare_select could have closed the last channel */
1.84 markus 370: if (session_closed && !channel_still_open() &&
371: !packet_have_data_to_write()) {
372: /* clear mask since we did not call select() */
1.87 markus 373: memset(*readsetp, 0, *nallocp);
374: memset(*writesetp, 0, *nallocp);
1.84 markus 375: return;
1.71 markus 376: } else {
377: FD_SET(connection_in, *readsetp);
378: }
1.16 markus 379: }
1.11 markus 380:
381: /* Select server connection if have data to write to the server. */
382: if (packet_have_data_to_write())
1.46 markus 383: FD_SET(connection_out, *writesetp);
1.11 markus 384:
1.13 markus 385: /*
386: * Wait for something to happen. This will suspend the process until
387: * some selected descriptor can be read, written, or has some other
1.112.2.1! brad 388: * event pending.
1.13 markus 389: */
1.11 markus 390:
1.112.2.1! brad 391: if (options.server_alive_interval == 0 || !compat20)
! 392: tvp = NULL;
! 393: else {
! 394: tv.tv_sec = options.server_alive_interval;
! 395: tv.tv_usec = 0;
! 396: tvp = &tv;
! 397: }
! 398: ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
! 399: if (ret < 0) {
1.11 markus 400: char buf[100];
1.51 markus 401:
402: /*
403: * We have to clear the select masks, because we return.
404: * We have to return, because the mainloop checks for the flags
405: * set by the signal handlers.
406: */
1.87 markus 407: memset(*readsetp, 0, *nallocp);
408: memset(*writesetp, 0, *nallocp);
1.50 deraadt 409:
1.11 markus 410: if (errno == EINTR)
411: return;
412: /* Note: we might still have data in the buffers. */
413: snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
414: buffer_append(&stderr_buffer, buf, strlen(buf));
415: quit_pending = 1;
1.112.2.1! brad 416: } else if (ret == 0)
! 417: server_alive_check();
1.11 markus 418: }
419:
1.77 itojun 420: static void
1.31 markus 421: client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
1.1 deraadt 422: {
1.11 markus 423: struct winsize oldws, newws;
424:
425: /* Flush stdout and stderr buffers. */
1.31 markus 426: if (buffer_len(bout) > 0)
1.112 deraadt 427: atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout));
1.31 markus 428: if (buffer_len(berr) > 0)
1.112 deraadt 429: atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr));
1.11 markus 430:
431: leave_raw_mode();
432:
1.13 markus 433: /*
434: * Free (and clear) the buffer to reduce the amount of data that gets
435: * written to swap.
436: */
1.31 markus 437: buffer_free(bin);
438: buffer_free(bout);
439: buffer_free(berr);
1.11 markus 440:
441: /* Save old window size. */
442: ioctl(fileno(stdin), TIOCGWINSZ, &oldws);
443:
444: /* Send the suspend signal to the program itself. */
445: kill(getpid(), SIGTSTP);
446:
447: /* Check if the window size has changed. */
448: if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
449: (oldws.ws_row != newws.ws_row ||
1.90 deraadt 450: oldws.ws_col != newws.ws_col ||
451: oldws.ws_xpixel != newws.ws_xpixel ||
452: oldws.ws_ypixel != newws.ws_ypixel))
1.11 markus 453: received_window_change_signal = 1;
454:
455: /* OK, we have been continued by the user. Reinitialize buffers. */
1.31 markus 456: buffer_init(bin);
457: buffer_init(bout);
458: buffer_init(berr);
1.11 markus 459:
460: enter_raw_mode();
461: }
462:
1.77 itojun 463: static void
1.17 markus 464: client_process_net_input(fd_set * readset)
1.11 markus 465: {
1.17 markus 466: int len;
467: char buf[8192];
1.11 markus 468:
1.13 markus 469: /*
470: * Read input from the server, and add any such data to the buffer of
471: * the packet subsystem.
472: */
1.11 markus 473: if (FD_ISSET(connection_in, readset)) {
474: /* Read as much as possible. */
475: len = read(connection_in, buf, sizeof(buf));
476: if (len == 0) {
477: /* Received EOF. The remote host has closed the connection. */
478: snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
479: host);
1.1 deraadt 480: buffer_append(&stderr_buffer, buf, strlen(buf));
481: quit_pending = 1;
482: return;
1.11 markus 483: }
1.13 markus 484: /*
485: * There is a kernel bug on Solaris that causes select to
486: * sometimes wake up even though there is no data available.
487: */
1.53 millert 488: if (len < 0 && (errno == EAGAIN || errno == EINTR))
1.11 markus 489: len = 0;
490:
491: if (len < 0) {
492: /* An error has encountered. Perhaps there is a network problem. */
493: snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n",
494: host, strerror(errno));
495: buffer_append(&stderr_buffer, buf, strlen(buf));
496: quit_pending = 1;
497: return;
498: }
499: packet_process_incoming(buf, len);
500: }
1.17 markus 501: }
1.16 markus 502:
1.97 jakob 503: static void
1.99 markus 504: process_cmdline(void)
1.97 jakob 505: {
506: void (*handler)(int);
507: char *s, *cmd;
508: u_short fwd_port, fwd_host_port;
509: char buf[1024], sfwd_port[6], sfwd_host_port[6];
510: int local = 0;
511:
512: leave_raw_mode();
1.101 markus 513: handler = signal(SIGINT, SIG_IGN);
1.99 markus 514: cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
1.97 jakob 515: if (s == NULL)
516: goto out;
517: while (*s && isspace(*s))
518: s++;
519: if (*s == 0)
520: goto out;
521: if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
1.109 itojun 522: logit("Invalid command.");
1.97 jakob 523: goto out;
524: }
525: if (s[1] == 'L')
526: local = 1;
527: if (!local && !compat20) {
1.109 itojun 528: logit("Not supported for SSH protocol version 1.");
1.97 jakob 529: goto out;
530: }
531: s += 2;
532: while (*s && isspace(*s))
533: s++;
534:
535: if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
536: sfwd_port, buf, sfwd_host_port) != 3 &&
537: sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
538: sfwd_port, buf, sfwd_host_port) != 3) {
1.109 itojun 539: logit("Bad forwarding specification.");
1.97 jakob 540: goto out;
541: }
542: if ((fwd_port = a2port(sfwd_port)) == 0 ||
543: (fwd_host_port = a2port(sfwd_host_port)) == 0) {
1.109 itojun 544: logit("Bad forwarding port(s).");
1.97 jakob 545: goto out;
546: }
547: if (local) {
1.99 markus 548: if (channel_setup_local_fwd_listener(fwd_port, buf,
549: fwd_host_port, options.gateway_ports) < 0) {
1.109 itojun 550: logit("Port forwarding failed.");
1.97 jakob 551: goto out;
552: }
553: } else
554: channel_request_remote_forwarding(fwd_port, buf,
555: fwd_host_port);
1.109 itojun 556: logit("Forwarding port.");
1.97 jakob 557: out:
558: signal(SIGINT, handler);
559: enter_raw_mode();
560: if (cmd)
561: xfree(cmd);
562: }
563:
1.31 markus 564: /* process the characters one by one */
1.77 itojun 565: static int
1.31 markus 566: process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
567: {
1.32 markus 568: char string[1024];
1.31 markus 569: pid_t pid;
570: int bytes = 0;
1.42 markus 571: u_int i;
572: u_char ch;
1.31 markus 573: char *s;
574:
575: for (i = 0; i < len; i++) {
576: /* Get one character at a time. */
577: ch = buf[i];
578:
579: if (escape_pending) {
580: /* We have previously seen an escape character. */
581: /* Clear the flag now. */
582: escape_pending = 0;
583:
584: /* Process the escaped character. */
585: switch (ch) {
586: case '.':
587: /* Terminate the connection. */
1.32 markus 588: snprintf(string, sizeof string, "%c.\r\n", escape_char);
589: buffer_append(berr, string, strlen(string));
1.31 markus 590:
591: quit_pending = 1;
592: return -1;
593:
594: case 'Z' - 64:
595: /* Suspend the program. */
596: /* Print a message to that effect to the user. */
1.32 markus 597: snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);
598: buffer_append(berr, string, strlen(string));
1.31 markus 599:
600: /* Restore terminal modes and suspend. */
601: client_suspend_self(bin, bout, berr);
602:
603: /* We have been continued. */
604: continue;
605:
1.111 markus 606: case 'B':
607: if (compat20) {
608: snprintf(string, sizeof string,
609: "%cB\r\n", escape_char);
610: buffer_append(berr, string,
611: strlen(string));
612: channel_request_start(session_ident,
613: "break", 0);
614: packet_put_int(1000);
615: packet_send();
616: }
617: continue;
618:
1.54 markus 619: case 'R':
1.59 markus 620: if (compat20) {
621: if (datafellows & SSH_BUG_NOREKEY)
1.109 itojun 622: logit("Server does not support re-keying");
1.59 markus 623: else
624: need_rekeying = 1;
625: }
1.54 markus 626: continue;
627:
1.31 markus 628: case '&':
629: /*
630: * Detach the program (continue to serve connections,
631: * but put in background and no more new connections).
632: */
633: /* Restore tty modes. */
634: leave_raw_mode();
635:
636: /* Stop listening for new connections. */
1.86 markus 637: channel_stop_listening();
1.31 markus 638:
1.86 markus 639: snprintf(string, sizeof string,
640: "%c& [backgrounded]\n", escape_char);
641: buffer_append(berr, string, strlen(string));
1.31 markus 642:
643: /* Fork into background. */
644: pid = fork();
645: if (pid < 0) {
646: error("fork: %.100s", strerror(errno));
647: continue;
648: }
649: if (pid != 0) { /* This is the parent. */
650: /* The parent just exits. */
651: exit(0);
652: }
653: /* The child continues serving connections. */
1.86 markus 654: if (compat20) {
655: buffer_append(bin, "\004", 1);
656: /* fake EOF on stdin */
657: return -1;
658: } else if (!stdin_eof) {
659: /*
660: * Sending SSH_CMSG_EOF alone does not always appear
661: * to be enough. So we try to send an EOF character
662: * first.
663: */
664: packet_start(SSH_CMSG_STDIN_DATA);
665: packet_put_string("\004", 1);
666: packet_send();
667: /* Close stdin. */
668: stdin_eof = 1;
669: if (buffer_len(bin) == 0) {
670: packet_start(SSH_CMSG_EOF);
671: packet_send();
672: }
673: }
674: continue;
1.31 markus 675:
676: case '?':
1.32 markus 677: snprintf(string, sizeof string,
1.31 markus 678: "%c?\r\n\
679: Supported escape sequences:\r\n\
1.104 stevesk 680: %c. - terminate connection\r\n\
1.111 markus 681: %cB - send a BREAK to the remote system\r\n\
1.104 stevesk 682: %cC - open a command line\r\n\
683: %cR - Request rekey (SSH protocol 2 only)\r\n\
684: %c^Z - suspend ssh\r\n\
685: %c# - list forwarded connections\r\n\
686: %c& - background ssh (when waiting for connections to terminate)\r\n\
687: %c? - this message\r\n\
688: %c%c - send the escape character by typing it twice\r\n\
1.31 markus 689: (Note that escapes are only recognized immediately after newline.)\r\n",
1.104 stevesk 690: escape_char, escape_char, escape_char, escape_char,
691: escape_char, escape_char, escape_char, escape_char,
1.111 markus 692: escape_char, escape_char, escape_char);
1.32 markus 693: buffer_append(berr, string, strlen(string));
1.31 markus 694: continue;
695:
696: case '#':
1.32 markus 697: snprintf(string, sizeof string, "%c#\r\n", escape_char);
698: buffer_append(berr, string, strlen(string));
1.31 markus 699: s = channel_open_message();
700: buffer_append(berr, s, strlen(s));
701: xfree(s);
1.97 jakob 702: continue;
703:
704: case 'C':
1.99 markus 705: process_cmdline();
1.31 markus 706: continue;
707:
708: default:
709: if (ch != escape_char) {
710: buffer_put_char(bin, escape_char);
711: bytes++;
712: }
713: /* Escaped characters fall through here */
714: break;
715: }
716: } else {
717: /*
718: * The previous character was not an escape char. Check if this
719: * is an escape.
720: */
721: if (last_was_cr && ch == escape_char) {
722: /* It is. Set the flag and continue to next character. */
723: escape_pending = 1;
724: continue;
725: }
726: }
727:
728: /*
729: * Normal character. Record whether it was a newline,
730: * and append it to the buffer.
731: */
732: last_was_cr = (ch == '\r' || ch == '\n');
733: buffer_put_char(bin, ch);
734: bytes++;
735: }
736: return bytes;
737: }
738:
1.77 itojun 739: static void
1.17 markus 740: client_process_input(fd_set * readset)
741: {
1.21 deraadt 742: int len;
1.31 markus 743: char buf[8192];
1.16 markus 744:
1.11 markus 745: /* Read input from stdin. */
746: if (FD_ISSET(fileno(stdin), readset)) {
747: /* Read as much as possible. */
748: len = read(fileno(stdin), buf, sizeof(buf));
1.64 markus 749: if (len < 0 && (errno == EAGAIN || errno == EINTR))
750: return; /* we'll try again later */
1.11 markus 751: if (len <= 0) {
1.13 markus 752: /*
753: * Received EOF or error. They are treated
754: * similarly, except that an error message is printed
755: * if it was an error condition.
756: */
1.11 markus 757: if (len < 0) {
758: snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno));
759: buffer_append(&stderr_buffer, buf, strlen(buf));
760: }
761: /* Mark that we have seen EOF. */
762: stdin_eof = 1;
1.13 markus 763: /*
764: * Send an EOF message to the server unless there is
765: * data in the buffer. If there is data in the
766: * buffer, no message will be sent now. Code
767: * elsewhere will send the EOF when the buffer
768: * becomes empty if stdin_eof is set.
769: */
1.11 markus 770: if (buffer_len(&stdin_buffer) == 0) {
1.1 deraadt 771: packet_start(SSH_CMSG_EOF);
772: packet_send();
1.11 markus 773: }
1.72 stevesk 774: } else if (escape_char == SSH_ESCAPECHAR_NONE) {
1.13 markus 775: /*
776: * Normal successful read, and no escape character.
777: * Just append the data to buffer.
778: */
1.11 markus 779: buffer_append(&stdin_buffer, buf, len);
780: } else {
1.13 markus 781: /*
782: * Normal, successful read. But we have an escape character
783: * and have to process the characters one by one.
784: */
1.52 markus 785: if (process_escapes(&stdin_buffer, &stdout_buffer,
786: &stderr_buffer, buf, len) == -1)
1.31 markus 787: return;
1.11 markus 788: }
789: }
790: }
791:
1.77 itojun 792: static void
1.11 markus 793: client_process_output(fd_set * writeset)
794: {
795: int len;
796: char buf[100];
1.1 deraadt 797:
1.11 markus 798: /* Write buffered output to stdout. */
799: if (FD_ISSET(fileno(stdout), writeset)) {
800: /* Write as much data as possible. */
801: len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1.14 deraadt 802: buffer_len(&stdout_buffer));
1.11 markus 803: if (len <= 0) {
1.64 markus 804: if (errno == EINTR || errno == EAGAIN)
1.11 markus 805: len = 0;
806: else {
1.13 markus 807: /*
808: * An error or EOF was encountered. Put an
809: * error message to stderr buffer.
810: */
1.11 markus 811: snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno));
812: buffer_append(&stderr_buffer, buf, strlen(buf));
813: quit_pending = 1;
814: return;
815: }
816: }
817: /* Consume printed data from the buffer. */
818: buffer_consume(&stdout_buffer, len);
1.57 markus 819: stdout_bytes += len;
1.11 markus 820: }
821: /* Write buffered output to stderr. */
822: if (FD_ISSET(fileno(stderr), writeset)) {
823: /* Write as much data as possible. */
824: len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1.14 deraadt 825: buffer_len(&stderr_buffer));
1.11 markus 826: if (len <= 0) {
1.64 markus 827: if (errno == EINTR || errno == EAGAIN)
1.11 markus 828: len = 0;
829: else {
1.13 markus 830: /* EOF or error, but can't even print error message. */
1.11 markus 831: quit_pending = 1;
832: return;
833: }
834: }
835: /* Consume printed characters from the buffer. */
836: buffer_consume(&stderr_buffer, len);
1.57 markus 837: stderr_bytes += len;
1.11 markus 838: }
1.1 deraadt 839: }
840:
1.13 markus 841: /*
1.15 markus 842: * Get packets from the connection input buffer, and process them as long as
843: * there are packets available.
844: *
845: * Any unknown packets received during the actual
846: * session cause the session to terminate. This is
847: * intended to make debugging easier since no
848: * confirmations are sent. Any compatible protocol
849: * extensions must be negotiated during the
850: * preparatory phase.
851: */
852:
1.77 itojun 853: static void
1.49 itojun 854: client_process_buffered_input_packets(void)
1.15 markus 855: {
1.54 markus 856: dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL);
1.15 markus 857: }
858:
1.31 markus 859: /* scan buf[] for '~' before sending data to the peer */
1.30 markus 860:
1.77 itojun 861: static int
1.31 markus 862: simple_escape_filter(Channel *c, char *buf, int len)
1.30 markus 863: {
1.31 markus 864: /* XXX we assume c->extended is writeable */
865: return process_escapes(&c->input, &c->output, &c->extended, buf, len);
1.30 markus 866: }
867:
1.77 itojun 868: static void
1.60 markus 869: client_channel_closed(int id, void *arg)
870: {
871: if (id != session_ident)
872: error("client_channel_closed: id %d != session_ident %d",
873: id, session_ident);
1.83 markus 874: channel_cancel_cleanup(id);
1.60 markus 875: session_closed = 1;
1.112.2.1! brad 876: leave_raw_mode();
1.60 markus 877: }
878:
1.15 markus 879: /*
1.13 markus 880: * Implements the interactive session with the server. This is called after
881: * the user has been authenticated, and a command has been started on the
1.72 stevesk 882: * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
883: * used as an escape character for terminating or suspending the session.
1.13 markus 884: */
1.1 deraadt 885:
1.20 markus 886: int
1.30 markus 887: client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1.1 deraadt 888: {
1.46 markus 889: fd_set *readset = NULL, *writeset = NULL;
1.11 markus 890: double start_time, total_time;
1.81 markus 891: int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
1.11 markus 892: char buf[100];
893:
894: debug("Entering interactive session.");
895:
896: start_time = get_current_time();
897:
898: /* Initialize variables. */
899: escape_pending = 0;
900: last_was_cr = 1;
901: exit_status = -1;
902: stdin_eof = 0;
903: buffer_high = 64 * 1024;
904: connection_in = packet_get_connection_in();
905: connection_out = packet_get_connection_out();
1.46 markus 906: max_fd = MAX(connection_in, connection_out);
907:
908: if (!compat20) {
1.63 markus 909: /* enable nonblocking unless tty */
910: if (!isatty(fileno(stdin)))
911: set_nonblock(fileno(stdin));
912: if (!isatty(fileno(stdout)))
913: set_nonblock(fileno(stdout));
914: if (!isatty(fileno(stderr)))
915: set_nonblock(fileno(stderr));
1.46 markus 916: max_fd = MAX(max_fd, fileno(stdin));
917: max_fd = MAX(max_fd, fileno(stdout));
918: max_fd = MAX(max_fd, fileno(stderr));
919: }
1.11 markus 920: stdin_bytes = 0;
921: stdout_bytes = 0;
922: stderr_bytes = 0;
923: quit_pending = 0;
924: escape_char = escape_char_arg;
925:
926: /* Initialize buffers. */
927: buffer_init(&stdin_buffer);
928: buffer_init(&stdout_buffer);
929: buffer_init(&stderr_buffer);
930:
1.15 markus 931: client_init_dispatch();
932:
1.105 markus 933: /*
934: * Set signal handlers, (e.g. to restore non-blocking mode)
935: * but don't overwrite SIG_IGN, matches behaviour from rsh(1)
936: */
937: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
938: signal(SIGINT, signal_handler);
939: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
940: signal(SIGQUIT, signal_handler);
941: if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
942: signal(SIGTERM, signal_handler);
1.11 markus 943: if (have_pty)
944: signal(SIGWINCH, window_change_handler);
945:
946: if (have_pty)
947: enter_raw_mode();
948:
1.48 markus 949: if (compat20) {
950: session_ident = ssh2_chan_id;
1.72 stevesk 951: if (escape_char != SSH_ESCAPECHAR_NONE)
1.48 markus 952: channel_register_filter(session_ident,
953: simple_escape_filter);
1.60 markus 954: if (session_ident != -1)
955: channel_register_cleanup(session_ident,
956: client_channel_closed);
1.48 markus 957: } else {
958: /* Check if we should immediately send eof on stdin. */
1.16 markus 959: client_check_initial_eof_on_stdin();
1.48 markus 960: }
1.30 markus 961:
1.11 markus 962: /* Main loop of the client for the interactive session mode. */
963: while (!quit_pending) {
964:
1.13 markus 965: /* Process buffered packets sent by the server. */
1.11 markus 966: client_process_buffered_input_packets();
967:
1.60 markus 968: if (compat20 && session_closed && !channel_still_open())
969: break;
970:
1.56 markus 971: rekeying = (xxx_kex != NULL && !xxx_kex->done);
1.16 markus 972:
1.56 markus 973: if (rekeying) {
974: debug("rekeying in progress");
975: } else {
976: /*
977: * Make packets of buffered stdin data, and buffer
978: * them for sending to the server.
979: */
980: if (!compat20)
981: client_make_packets_from_stdin_data();
1.11 markus 982:
1.56 markus 983: /*
984: * Make packets from buffered channel data, and
985: * enqueue them for sending to the server.
986: */
987: if (packet_not_very_much_data_to_write())
988: channel_output_poll();
1.11 markus 989:
1.56 markus 990: /*
991: * Check if the window size has changed, and buffer a
992: * message about it to the server if so.
993: */
994: client_check_window_change();
1.11 markus 995:
1.56 markus 996: if (quit_pending)
997: break;
998: }
1.13 markus 999: /*
1000: * Wait until we have something to do (something becomes
1001: * available on one of the descriptors).
1002: */
1.81 markus 1003: max_fd2 = max_fd;
1.56 markus 1004: client_wait_until_can_do_something(&readset, &writeset,
1.81 markus 1005: &max_fd2, &nalloc, rekeying);
1.11 markus 1006:
1007: if (quit_pending)
1008: break;
1009:
1.56 markus 1010: /* Do channel operations unless rekeying in progress. */
1011: if (!rekeying) {
1012: channel_after_select(readset, writeset);
1.108 markus 1013: if (need_rekeying || packet_need_rekeying()) {
1014: debug("need rekeying");
1.56 markus 1015: xxx_kex->done = 0;
1016: kex_send_kexinit(xxx_kex);
1017: need_rekeying = 0;
1018: }
1019: }
1.11 markus 1020:
1.17 markus 1021: /* Buffer input from the connection. */
1.46 markus 1022: client_process_net_input(readset);
1.17 markus 1023:
1024: if (quit_pending)
1025: break;
1.11 markus 1026:
1.17 markus 1027: if (!compat20) {
1028: /* Buffer data from stdin */
1.46 markus 1029: client_process_input(readset);
1.17 markus 1030: /*
1031: * Process output to stdout and stderr. Output to
1032: * the connection is processed elsewhere (above).
1033: */
1.46 markus 1034: client_process_output(writeset);
1.17 markus 1035: }
1.11 markus 1036:
1.13 markus 1037: /* Send as much buffered packet data as possible to the sender. */
1.46 markus 1038: if (FD_ISSET(connection_out, writeset))
1.11 markus 1039: packet_write_poll();
1040: }
1.46 markus 1041: if (readset)
1042: xfree(readset);
1043: if (writeset)
1044: xfree(writeset);
1.11 markus 1045:
1046: /* Terminate the session. */
1047:
1048: /* Stop watching for window change. */
1049: if (have_pty)
1050: signal(SIGWINCH, SIG_DFL);
1051:
1.76 markus 1052: channel_free_all();
1.11 markus 1053:
1.75 markus 1054: if (have_pty)
1055: leave_raw_mode();
1056:
1057: /* restore blocking io */
1058: if (!isatty(fileno(stdin)))
1059: unset_nonblock(fileno(stdin));
1060: if (!isatty(fileno(stdout)))
1061: unset_nonblock(fileno(stdout));
1062: if (!isatty(fileno(stderr)))
1063: unset_nonblock(fileno(stderr));
1064:
1.112.2.1! brad 1065: /*
! 1066: * If there was no shell or command requested, there will be no remote
! 1067: * exit status to be returned. In that case, clear error code if the
! 1068: * connection was deliberately terminated at this end.
! 1069: */
! 1070: if (no_shell_flag && received_signal == SIGTERM) {
! 1071: received_signal = 0;
! 1072: exit_status = 0;
1.75 markus 1073: }
1074:
1.112.2.1! brad 1075: if (received_signal)
! 1076: fatal("Killed by signal %d.", (int) received_signal);
! 1077:
1.13 markus 1078: /*
1079: * In interactive mode (with pseudo tty) display a message indicating
1080: * that the connection has been closed.
1081: */
1.11 markus 1082: if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
1083: snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
1084: buffer_append(&stderr_buffer, buf, strlen(buf));
1085: }
1.70 markus 1086:
1.11 markus 1087: /* Output any buffered data for stdout. */
1.70 markus 1088: while (buffer_len(&stdout_buffer) > 0) {
1089: len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1.14 deraadt 1090: buffer_len(&stdout_buffer));
1.70 markus 1091: if (len <= 0) {
1.11 markus 1092: error("Write failed flushing stdout buffer.");
1.70 markus 1093: break;
1094: }
1.11 markus 1095: buffer_consume(&stdout_buffer, len);
1.57 markus 1096: stdout_bytes += len;
1.11 markus 1097: }
1098:
1099: /* Output any buffered data for stderr. */
1.70 markus 1100: while (buffer_len(&stderr_buffer) > 0) {
1101: len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1.14 deraadt 1102: buffer_len(&stderr_buffer));
1.70 markus 1103: if (len <= 0) {
1.11 markus 1104: error("Write failed flushing stderr buffer.");
1.70 markus 1105: break;
1106: }
1.11 markus 1107: buffer_consume(&stderr_buffer, len);
1.57 markus 1108: stderr_bytes += len;
1.11 markus 1109: }
1110:
1111: /* Clear and free any buffers. */
1112: memset(buf, 0, sizeof(buf));
1113: buffer_free(&stdin_buffer);
1114: buffer_free(&stdout_buffer);
1115: buffer_free(&stderr_buffer);
1116:
1117: /* Report bytes transferred, and transfer rates. */
1118: total_time = get_current_time() - start_time;
1119: debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds",
1.90 deraadt 1120: stdin_bytes, stdout_bytes, stderr_bytes, total_time);
1.11 markus 1121: if (total_time > 0)
1122: debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f",
1.90 deraadt 1123: stdin_bytes / total_time, stdout_bytes / total_time,
1124: stderr_bytes / total_time);
1.11 markus 1125:
1126: /* Return the exit status of the program. */
1127: debug("Exit status %d", exit_status);
1128: return exit_status;
1.15 markus 1129: }
1130:
1131: /*********/
1132:
1.77 itojun 1133: static void
1.94 markus 1134: client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1.15 markus 1135: {
1.42 markus 1136: u_int data_len;
1.15 markus 1137: char *data = packet_get_string(&data_len);
1.93 markus 1138: packet_check_eom();
1.15 markus 1139: buffer_append(&stdout_buffer, data, data_len);
1140: memset(data, 0, data_len);
1141: xfree(data);
1142: }
1.77 itojun 1143: static void
1.94 markus 1144: client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1.15 markus 1145: {
1.42 markus 1146: u_int data_len;
1.15 markus 1147: char *data = packet_get_string(&data_len);
1.93 markus 1148: packet_check_eom();
1.15 markus 1149: buffer_append(&stderr_buffer, data, data_len);
1150: memset(data, 0, data_len);
1151: xfree(data);
1152: }
1.77 itojun 1153: static void
1.94 markus 1154: client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1.15 markus 1155: {
1156: exit_status = packet_get_int();
1.93 markus 1157: packet_check_eom();
1.15 markus 1158: /* Acknowledge the exit. */
1159: packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1160: packet_send();
1161: /*
1162: * Must wait for packet to be sent since we are
1163: * exiting the loop.
1164: */
1165: packet_write_wait();
1166: /* Flag that we want to exit. */
1167: quit_pending = 1;
1168: }
1.112.2.1! brad 1169: static void
! 1170: client_input_agent_open(int type, u_int32_t seq, void *ctxt)
! 1171: {
! 1172: Channel *c = NULL;
! 1173: int remote_id, sock;
! 1174:
! 1175: /* Read the remote channel number from the message. */
! 1176: remote_id = packet_get_int();
! 1177: packet_check_eom();
! 1178:
! 1179: /*
! 1180: * Get a connection to the local authentication agent (this may again
! 1181: * get forwarded).
! 1182: */
! 1183: sock = ssh_get_authentication_socket();
! 1184:
! 1185: /*
! 1186: * If we could not connect the agent, send an error message back to
! 1187: * the server. This should never happen unless the agent dies,
! 1188: * because authentication forwarding is only enabled if we have an
! 1189: * agent.
! 1190: */
! 1191: if (sock >= 0) {
! 1192: c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
! 1193: -1, 0, 0, 0, "authentication agent connection", 1);
! 1194: c->remote_id = remote_id;
! 1195: c->force_drain = 1;
! 1196: }
! 1197: if (c == NULL) {
! 1198: packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
! 1199: packet_put_int(remote_id);
! 1200: } else {
! 1201: /* Send a confirmation to the remote host. */
! 1202: debug("Forwarding authentication connection.");
! 1203: packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
! 1204: packet_put_int(remote_id);
! 1205: packet_put_int(c->self);
! 1206: }
! 1207: packet_send();
! 1208: }
1.15 markus 1209:
1.77 itojun 1210: static Channel *
1.40 markus 1211: client_request_forwarded_tcpip(const char *request_type, int rchan)
1212: {
1.103 deraadt 1213: Channel *c = NULL;
1.40 markus 1214: char *listen_address, *originator_address;
1215: int listen_port, originator_port;
1.67 markus 1216: int sock;
1.40 markus 1217:
1218: /* Get rest of the packet */
1219: listen_address = packet_get_string(NULL);
1220: listen_port = packet_get_int();
1221: originator_address = packet_get_string(NULL);
1222: originator_port = packet_get_int();
1.93 markus 1223: packet_check_eom();
1.40 markus 1224:
1225: debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
1226: listen_address, listen_port, originator_address, originator_port);
1227:
1.80 stevesk 1228: sock = channel_connect_by_listen_address(listen_port);
1.67 markus 1229: if (sock < 0) {
1230: xfree(originator_address);
1231: xfree(listen_address);
1232: return NULL;
1233: }
1234: c = channel_new("forwarded-tcpip",
1235: SSH_CHANNEL_CONNECTING, sock, sock, -1,
1236: CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1.110 markus 1237: originator_address, 1);
1.40 markus 1238: xfree(originator_address);
1239: xfree(listen_address);
1240: return c;
1241: }
1242:
1.103 deraadt 1243: static Channel *
1.40 markus 1244: client_request_x11(const char *request_type, int rchan)
1245: {
1246: Channel *c = NULL;
1247: char *originator;
1248: int originator_port;
1.67 markus 1249: int sock;
1.40 markus 1250:
1251: if (!options.forward_x11) {
1252: error("Warning: ssh server tried X11 forwarding.");
1253: error("Warning: this is probably a break in attempt by a malicious server.");
1254: return NULL;
1255: }
1256: originator = packet_get_string(NULL);
1257: if (datafellows & SSH_BUG_X11FWD) {
1258: debug2("buggy server: x11 request w/o originator_port");
1259: originator_port = 0;
1260: } else {
1261: originator_port = packet_get_int();
1262: }
1.93 markus 1263: packet_check_eom();
1.40 markus 1264: /* XXX check permission */
1.47 markus 1265: debug("client_request_x11: request from %s %d", originator,
1266: originator_port);
1.67 markus 1267: xfree(originator);
1.40 markus 1268: sock = x11_connect_display();
1.67 markus 1269: if (sock < 0)
1270: return NULL;
1271: c = channel_new("x11",
1272: SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1.110 markus 1273: CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
1.82 markus 1274: c->force_drain = 1;
1.40 markus 1275: return c;
1276: }
1277:
1.103 deraadt 1278: static Channel *
1.40 markus 1279: client_request_agent(const char *request_type, int rchan)
1280: {
1281: Channel *c = NULL;
1.67 markus 1282: int sock;
1.40 markus 1283:
1284: if (!options.forward_agent) {
1285: error("Warning: ssh server tried agent forwarding.");
1286: error("Warning: this is probably a break in attempt by a malicious server.");
1287: return NULL;
1288: }
1289: sock = ssh_get_authentication_socket();
1.67 markus 1290: if (sock < 0)
1291: return NULL;
1292: c = channel_new("authentication agent connection",
1293: SSH_CHANNEL_OPEN, sock, sock, -1,
1294: CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1.110 markus 1295: "authentication agent connection", 1);
1.82 markus 1296: c->force_drain = 1;
1.40 markus 1297: return c;
1298: }
1299:
1.22 markus 1300: /* XXXX move to generic input handler */
1.77 itojun 1301: static void
1.94 markus 1302: client_input_channel_open(int type, u_int32_t seq, void *ctxt)
1.22 markus 1303: {
1304: Channel *c = NULL;
1305: char *ctype;
1306: int rchan;
1.102 markus 1307: u_int rmaxpack, rwindow, len;
1.22 markus 1308:
1309: ctype = packet_get_string(&len);
1310: rchan = packet_get_int();
1311: rwindow = packet_get_int();
1312: rmaxpack = packet_get_int();
1313:
1.24 markus 1314: debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
1.22 markus 1315: ctype, rchan, rwindow, rmaxpack);
1316:
1.40 markus 1317: if (strcmp(ctype, "forwarded-tcpip") == 0) {
1318: c = client_request_forwarded_tcpip(ctype, rchan);
1319: } else if (strcmp(ctype, "x11") == 0) {
1320: c = client_request_x11(ctype, rchan);
1321: } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
1322: c = client_request_agent(ctype, rchan);
1.22 markus 1323: }
1324: /* XXX duplicate : */
1325: if (c != NULL) {
1326: debug("confirm %s", ctype);
1327: c->remote_id = rchan;
1328: c->remote_window = rwindow;
1329: c->remote_maxpacket = rmaxpack;
1.69 markus 1330: if (c->type != SSH_CHANNEL_CONNECTING) {
1331: packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1332: packet_put_int(c->remote_id);
1333: packet_put_int(c->self);
1334: packet_put_int(c->local_window);
1335: packet_put_int(c->local_maxpacket);
1336: packet_send();
1337: }
1.22 markus 1338: } else {
1339: debug("failure %s", ctype);
1340: packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1341: packet_put_int(rchan);
1342: packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
1.66 markus 1343: if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1.69 markus 1344: packet_put_cstring("open failed");
1.66 markus 1345: packet_put_cstring("");
1346: }
1.22 markus 1347: packet_send();
1348: }
1349: xfree(ctype);
1350: }
1.77 itojun 1351: static void
1.94 markus 1352: client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1.48 markus 1353: {
1354: Channel *c = NULL;
1355: int id, reply, success = 0;
1356: char *rtype;
1357:
1358: id = packet_get_int();
1359: rtype = packet_get_string(NULL);
1360: reply = packet_get_char();
1361:
1362: debug("client_input_channel_req: channel %d rtype %s reply %d",
1363: id, rtype, reply);
1364:
1365: if (session_ident == -1) {
1366: error("client_input_channel_req: no channel %d", session_ident);
1367: } else if (id != session_ident) {
1368: error("client_input_channel_req: channel %d: wrong channel: %d",
1369: session_ident, id);
1370: }
1371: c = channel_lookup(id);
1372: if (c == NULL) {
1373: error("client_input_channel_req: channel %d: unknown channel", id);
1374: } else if (strcmp(rtype, "exit-status") == 0) {
1375: success = 1;
1376: exit_status = packet_get_int();
1.93 markus 1377: packet_check_eom();
1.48 markus 1378: }
1379: if (reply) {
1380: packet_start(success ?
1381: SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1382: packet_put_int(c->remote_id);
1383: packet_send();
1384: }
1385: xfree(rtype);
1386: }
1.95 markus 1387: static void
1388: client_input_global_request(int type, u_int32_t seq, void *ctxt)
1389: {
1390: char *rtype;
1391: int want_reply;
1392: int success = 0;
1393:
1394: rtype = packet_get_string(NULL);
1395: want_reply = packet_get_char();
1.112.2.1! brad 1396: debug("client_input_global_request: rtype %s want_reply %d",
! 1397: rtype, want_reply);
1.95 markus 1398: if (want_reply) {
1399: packet_start(success ?
1400: SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
1401: packet_send();
1402: packet_write_wait();
1403: }
1404: xfree(rtype);
1405: }
1.22 markus 1406:
1.77 itojun 1407: static void
1.49 itojun 1408: client_init_dispatch_20(void)
1.16 markus 1409: {
1.55 markus 1410: dispatch_init(&dispatch_protocol_error);
1.100 markus 1411:
1.16 markus 1412: dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
1413: dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
1414: dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
1415: dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
1.22 markus 1416: dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
1.16 markus 1417: dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1418: dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1.48 markus 1419: dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
1.16 markus 1420: dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1.95 markus 1421: dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
1.55 markus 1422:
1423: /* rekeying */
1424: dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
1.100 markus 1425:
1426: /* global request reply messages */
1427: dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
1428: dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
1.16 markus 1429: }
1.77 itojun 1430: static void
1.49 itojun 1431: client_init_dispatch_13(void)
1.15 markus 1432: {
1433: dispatch_init(NULL);
1434: dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
1435: dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
1436: dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
1437: dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1438: dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1439: dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
1440: dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
1441: dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
1442: dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
1.39 markus 1443:
1444: dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
1.112.2.1! brad 1445: &client_input_agent_open : &deny_input_open);
1.39 markus 1446: dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
1447: &x11_input_open : &deny_input_open);
1.15 markus 1448: }
1.77 itojun 1449: static void
1.49 itojun 1450: client_init_dispatch_15(void)
1.15 markus 1451: {
1452: client_init_dispatch_13();
1453: dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
1454: dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
1455: }
1.79 stevesk 1456: static void
1.49 itojun 1457: client_init_dispatch(void)
1.15 markus 1458: {
1.16 markus 1459: if (compat20)
1460: client_init_dispatch_20();
1461: else if (compat13)
1.15 markus 1462: client_init_dispatch_13();
1463: else
1464: client_init_dispatch_15();
1.112.2.1! brad 1465: }
! 1466:
! 1467: /* client specific fatal cleanup */
! 1468: void
! 1469: cleanup_exit(int i)
! 1470: {
! 1471: leave_raw_mode();
! 1472: leave_non_blocking();
! 1473: _exit(i);
1.1 deraadt 1474: }