]> andersk Git - openssh.git/blob - clientloop.c
- stevesk@cvs.openbsd.org 2006/02/20 17:02:44
[openssh.git] / clientloop.c
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * The main loop for the interactive session (client side).
6  *
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.
35  *
36  *
37  * SSH2 support added by Markus Friedl.
38  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
39  *
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.
59  */
60
61 #include "includes.h"
62 RCSID("$OpenBSD: clientloop.c,v 1.154 2006/02/20 17:19:54 stevesk Exp $");
63
64 #include <sys/types.h>
65 #ifdef HAVE_SYS_STAT_H
66 # include <sys/stat.h>
67 #endif
68 #include <sys/ioctl.h>
69
70 #include <paths.h>
71 #include <termios.h>
72
73 #include "ssh.h"
74 #include "ssh1.h"
75 #include "ssh2.h"
76 #include "xmalloc.h"
77 #include "packet.h"
78 #include "buffer.h"
79 #include "compat.h"
80 #include "channels.h"
81 #include "dispatch.h"
82 #include "buffer.h"
83 #include "bufaux.h"
84 #include "key.h"
85 #include "kex.h"
86 #include "log.h"
87 #include "readconf.h"
88 #include "clientloop.h"
89 #include "sshconnect.h"
90 #include "authfd.h"
91 #include "atomicio.h"
92 #include "sshpty.h"
93 #include "misc.h"
94 #include "monitor_fdpass.h"
95 #include "match.h"
96 #include "msg.h"
97
98 /* import options */
99 extern Options options;
100
101 /* Flag indicating that stdin should be redirected from /dev/null. */
102 extern int stdin_null_flag;
103
104 /* Flag indicating that no shell has been requested */
105 extern int no_shell_flag;
106
107 /* Control socket */
108 extern int control_fd;
109
110 /*
111  * Name of the host we are connecting to.  This is the name given on the
112  * command line, or the HostName specified for the user-supplied name in a
113  * configuration file.
114  */
115 extern char *host;
116
117 /*
118  * Flag to indicate that we have received a window change signal which has
119  * not yet been processed.  This will cause a message indicating the new
120  * window size to be sent to the server a little later.  This is volatile
121  * because this is updated in a signal handler.
122  */
123 static volatile sig_atomic_t received_window_change_signal = 0;
124 static volatile sig_atomic_t received_signal = 0;
125
126 /* Flag indicating whether the user's terminal is in non-blocking mode. */
127 static int in_non_blocking_mode = 0;
128
129 /* Common data for the client loop code. */
130 static int quit_pending;        /* Set to non-zero to quit the client loop. */
131 static int escape_char;         /* Escape character. */
132 static int escape_pending;      /* Last character was the escape character */
133 static int last_was_cr;         /* Last character was a newline. */
134 static int exit_status;         /* Used to store the exit status of the command. */
135 static int stdin_eof;           /* EOF has been encountered on standard error. */
136 static Buffer stdin_buffer;     /* Buffer for stdin data. */
137 static Buffer stdout_buffer;    /* Buffer for stdout data. */
138 static Buffer stderr_buffer;    /* Buffer for stderr data. */
139 static u_long stdin_bytes, stdout_bytes, stderr_bytes;
140 static u_int buffer_high;/* Soft max buffer size. */
141 static int connection_in;       /* Connection to server (input). */
142 static int connection_out;      /* Connection to server (output). */
143 static int need_rekeying;       /* Set to non-zero if rekeying is requested. */
144 static int session_closed = 0;  /* In SSH2: login session closed. */
145 static int server_alive_timeouts = 0;
146
147 static void client_init_dispatch(void);
148 int     session_ident = -1;
149
150 struct confirm_ctx {
151         int want_tty;
152         int want_subsys;
153         int want_x_fwd;
154         int want_agent_fwd;
155         Buffer cmd;
156         char *term;
157         struct termios tio;
158         char **env;
159 };
160
161 /*XXX*/
162 extern Kex *xxx_kex;
163
164 void ssh_process_session2_setup(int, int, int, Buffer *);
165
166 /* Restores stdin to blocking mode. */
167
168 static void
169 leave_non_blocking(void)
170 {
171         if (in_non_blocking_mode) {
172                 unset_nonblock(fileno(stdin));
173                 in_non_blocking_mode = 0;
174         }
175 }
176
177 /* Puts stdin terminal in non-blocking mode. */
178
179 static void
180 enter_non_blocking(void)
181 {
182         in_non_blocking_mode = 1;
183         set_nonblock(fileno(stdin));
184 }
185
186 /*
187  * Signal handler for the window change signal (SIGWINCH).  This just sets a
188  * flag indicating that the window has changed.
189  */
190
191 static void
192 window_change_handler(int sig)
193 {
194         received_window_change_signal = 1;
195         signal(SIGWINCH, window_change_handler);
196 }
197
198 /*
199  * Signal handler for signals that cause the program to terminate.  These
200  * signals must be trapped to restore terminal modes.
201  */
202
203 static void
204 signal_handler(int sig)
205 {
206         received_signal = sig;
207         quit_pending = 1;
208 }
209
210 /*
211  * Returns current time in seconds from Jan 1, 1970 with the maximum
212  * available resolution.
213  */
214
215 static double
216 get_current_time(void)
217 {
218         struct timeval tv;
219         gettimeofday(&tv, NULL);
220         return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
221 }
222
223 #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
224 void
225 client_x11_get_proto(const char *display, const char *xauth_path,
226     u_int trusted, char **_proto, char **_data)
227 {
228         char cmd[1024];
229         char line[512];
230         char xdisplay[512];
231         static char proto[512], data[512];
232         FILE *f;
233         int got_data = 0, generated = 0, do_unlink = 0, i;
234         char *xauthdir, *xauthfile;
235         struct stat st;
236
237         xauthdir = xauthfile = NULL;
238         *_proto = proto;
239         *_data = data;
240         proto[0] = data[0] = '\0';
241
242         if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) {
243                 debug("No xauth program.");
244         } else {
245                 if (display == NULL) {
246                         debug("x11_get_proto: DISPLAY not set");
247                         return;
248                 }
249                 /*
250                  * Handle FamilyLocal case where $DISPLAY does
251                  * not match an authorization entry.  For this we
252                  * just try "xauth list unix:displaynum.screennum".
253                  * XXX: "localhost" match to determine FamilyLocal
254                  *      is not perfect.
255                  */
256                 if (strncmp(display, "localhost:", 10) == 0) {
257                         snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
258                             display + 10);
259                         display = xdisplay;
260                 }
261                 if (trusted == 0) {
262                         xauthdir = xmalloc(MAXPATHLEN);
263                         xauthfile = xmalloc(MAXPATHLEN);
264                         strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
265                         if (mkdtemp(xauthdir) != NULL) {
266                                 do_unlink = 1;
267                                 snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
268                                     xauthdir);
269                                 snprintf(cmd, sizeof(cmd),
270                                     "%s -f %s generate %s " SSH_X11_PROTO
271                                     " untrusted timeout 1200 2>" _PATH_DEVNULL,
272                                     xauth_path, xauthfile, display);
273                                 debug2("x11_get_proto: %s", cmd);
274                                 if (system(cmd) == 0)
275                                         generated = 1;
276                         }
277                 }
278                 snprintf(cmd, sizeof(cmd),
279                     "%s %s%s list %s 2>" _PATH_DEVNULL,
280                     xauth_path,
281                     generated ? "-f " : "" ,
282                     generated ? xauthfile : "",
283                     display);
284                 debug2("x11_get_proto: %s", cmd);
285                 f = popen(cmd, "r");
286                 if (f && fgets(line, sizeof(line), f) &&
287                     sscanf(line, "%*s %511s %511s", proto, data) == 2)
288                         got_data = 1;
289                 if (f)
290                         pclose(f);
291         }
292
293         if (do_unlink) {
294                 unlink(xauthfile);
295                 rmdir(xauthdir);
296         }
297         if (xauthdir)
298                 xfree(xauthdir);
299         if (xauthfile)
300                 xfree(xauthfile);
301
302         /*
303          * If we didn't get authentication data, just make up some
304          * data.  The forwarding code will check the validity of the
305          * response anyway, and substitute this data.  The X11
306          * server, however, will ignore this fake data and use
307          * whatever authentication mechanisms it was using otherwise
308          * for the local connection.
309          */
310         if (!got_data) {
311                 u_int32_t rnd = 0;
312
313                 logit("Warning: No xauth data; "
314                     "using fake authentication data for X11 forwarding.");
315                 strlcpy(proto, SSH_X11_PROTO, sizeof proto);
316                 for (i = 0; i < 16; i++) {
317                         if (i % 4 == 0)
318                                 rnd = arc4random();
319                         snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
320                             rnd & 0xff);
321                         rnd >>= 8;
322                 }
323         }
324 }
325
326 /*
327  * This is called when the interactive is entered.  This checks if there is
328  * an EOF coming on stdin.  We must check this explicitly, as select() does
329  * not appear to wake up when redirecting from /dev/null.
330  */
331
332 static void
333 client_check_initial_eof_on_stdin(void)
334 {
335         int len;
336         char buf[1];
337
338         /*
339          * If standard input is to be "redirected from /dev/null", we simply
340          * mark that we have seen an EOF and send an EOF message to the
341          * server. Otherwise, we try to read a single character; it appears
342          * that for some files, such /dev/null, select() never wakes up for
343          * read for this descriptor, which means that we never get EOF.  This
344          * way we will get the EOF if stdin comes from /dev/null or similar.
345          */
346         if (stdin_null_flag) {
347                 /* Fake EOF on stdin. */
348                 debug("Sending eof.");
349                 stdin_eof = 1;
350                 packet_start(SSH_CMSG_EOF);
351                 packet_send();
352         } else {
353                 enter_non_blocking();
354
355                 /* Check for immediate EOF on stdin. */
356                 len = read(fileno(stdin), buf, 1);
357                 if (len == 0) {
358                         /* EOF.  Record that we have seen it and send EOF to server. */
359                         debug("Sending eof.");
360                         stdin_eof = 1;
361                         packet_start(SSH_CMSG_EOF);
362                         packet_send();
363                 } else if (len > 0) {
364                         /*
365                          * Got data.  We must store the data in the buffer,
366                          * and also process it as an escape character if
367                          * appropriate.
368                          */
369                         if ((u_char) buf[0] == escape_char)
370                                 escape_pending = 1;
371                         else
372                                 buffer_append(&stdin_buffer, buf, 1);
373                 }
374                 leave_non_blocking();
375         }
376 }
377
378
379 /*
380  * Make packets from buffered stdin data, and buffer them for sending to the
381  * connection.
382  */
383
384 static void
385 client_make_packets_from_stdin_data(void)
386 {
387         u_int len;
388
389         /* Send buffered stdin data to the server. */
390         while (buffer_len(&stdin_buffer) > 0 &&
391             packet_not_very_much_data_to_write()) {
392                 len = buffer_len(&stdin_buffer);
393                 /* Keep the packets at reasonable size. */
394                 if (len > packet_get_maxsize())
395                         len = packet_get_maxsize();
396                 packet_start(SSH_CMSG_STDIN_DATA);
397                 packet_put_string(buffer_ptr(&stdin_buffer), len);
398                 packet_send();
399                 buffer_consume(&stdin_buffer, len);
400                 stdin_bytes += len;
401                 /* If we have a pending EOF, send it now. */
402                 if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
403                         packet_start(SSH_CMSG_EOF);
404                         packet_send();
405                 }
406         }
407 }
408
409 /*
410  * Checks if the client window has changed, and sends a packet about it to
411  * the server if so.  The actual change is detected elsewhere (by a software
412  * interrupt on Unix); this just checks the flag and sends a message if
413  * appropriate.
414  */
415
416 static void
417 client_check_window_change(void)
418 {
419         struct winsize ws;
420
421         if (! received_window_change_signal)
422                 return;
423         /** XXX race */
424         received_window_change_signal = 0;
425
426         debug2("client_check_window_change: changed");
427
428         if (compat20) {
429                 channel_send_window_changes();
430         } else {
431                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
432                         return;
433                 packet_start(SSH_CMSG_WINDOW_SIZE);
434                 packet_put_int(ws.ws_row);
435                 packet_put_int(ws.ws_col);
436                 packet_put_int(ws.ws_xpixel);
437                 packet_put_int(ws.ws_ypixel);
438                 packet_send();
439         }
440 }
441
442 static void
443 client_global_request_reply(int type, u_int32_t seq, void *ctxt)
444 {
445         server_alive_timeouts = 0;
446         client_global_request_reply_fwd(type, seq, ctxt);
447 }
448
449 static void
450 server_alive_check(void)
451 {
452         if (++server_alive_timeouts > options.server_alive_count_max)
453                 packet_disconnect("Timeout, server not responding.");
454         packet_start(SSH2_MSG_GLOBAL_REQUEST);
455         packet_put_cstring("keepalive@openssh.com");
456         packet_put_char(1);     /* boolean: want reply */
457         packet_send();
458 }
459
460 /*
461  * Waits until the client can do something (some data becomes available on
462  * one of the file descriptors).
463  */
464 static void
465 client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
466     int *maxfdp, u_int *nallocp, int rekeying)
467 {
468         struct timeval tv, *tvp;
469         int ret;
470
471         /* Add any selections by the channel mechanism. */
472         channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
473
474         if (!compat20) {
475                 /* Read from the connection, unless our buffers are full. */
476                 if (buffer_len(&stdout_buffer) < buffer_high &&
477                     buffer_len(&stderr_buffer) < buffer_high &&
478                     channel_not_very_much_buffered_data())
479                         FD_SET(connection_in, *readsetp);
480                 /*
481                  * Read from stdin, unless we have seen EOF or have very much
482                  * buffered data to send to the server.
483                  */
484                 if (!stdin_eof && packet_not_very_much_data_to_write())
485                         FD_SET(fileno(stdin), *readsetp);
486
487                 /* Select stdout/stderr if have data in buffer. */
488                 if (buffer_len(&stdout_buffer) > 0)
489                         FD_SET(fileno(stdout), *writesetp);
490                 if (buffer_len(&stderr_buffer) > 0)
491                         FD_SET(fileno(stderr), *writesetp);
492         } else {
493                 /* channel_prepare_select could have closed the last channel */
494                 if (session_closed && !channel_still_open() &&
495                     !packet_have_data_to_write()) {
496                         /* clear mask since we did not call select() */
497                         memset(*readsetp, 0, *nallocp);
498                         memset(*writesetp, 0, *nallocp);
499                         return;
500                 } else {
501                         FD_SET(connection_in, *readsetp);
502                 }
503         }
504
505         /* Select server connection if have data to write to the server. */
506         if (packet_have_data_to_write())
507                 FD_SET(connection_out, *writesetp);
508
509         if (control_fd != -1)
510                 FD_SET(control_fd, *readsetp);
511
512         /*
513          * Wait for something to happen.  This will suspend the process until
514          * some selected descriptor can be read, written, or has some other
515          * event pending.
516          */
517
518         if (options.server_alive_interval == 0 || !compat20)
519                 tvp = NULL;
520         else {
521                 tv.tv_sec = options.server_alive_interval;
522                 tv.tv_usec = 0;
523                 tvp = &tv;
524         }
525         ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
526         if (ret < 0) {
527                 char buf[100];
528
529                 /*
530                  * We have to clear the select masks, because we return.
531                  * We have to return, because the mainloop checks for the flags
532                  * set by the signal handlers.
533                  */
534                 memset(*readsetp, 0, *nallocp);
535                 memset(*writesetp, 0, *nallocp);
536
537                 if (errno == EINTR)
538                         return;
539                 /* Note: we might still have data in the buffers. */
540                 snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno));
541                 buffer_append(&stderr_buffer, buf, strlen(buf));
542                 quit_pending = 1;
543         } else if (ret == 0)
544                 server_alive_check();
545 }
546
547 static void
548 client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
549 {
550         /* Flush stdout and stderr buffers. */
551         if (buffer_len(bout) > 0)
552                 atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout));
553         if (buffer_len(berr) > 0)
554                 atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr));
555
556         leave_raw_mode();
557
558         /*
559          * Free (and clear) the buffer to reduce the amount of data that gets
560          * written to swap.
561          */
562         buffer_free(bin);
563         buffer_free(bout);
564         buffer_free(berr);
565
566         /* Send the suspend signal to the program itself. */
567         kill(getpid(), SIGTSTP);
568
569         /* Reset window sizes in case they have changed */
570         received_window_change_signal = 1;
571
572         /* OK, we have been continued by the user. Reinitialize buffers. */
573         buffer_init(bin);
574         buffer_init(bout);
575         buffer_init(berr);
576
577         enter_raw_mode();
578 }
579
580 static void
581 client_process_net_input(fd_set * readset)
582 {
583         int len;
584         char buf[8192];
585
586         /*
587          * Read input from the server, and add any such data to the buffer of
588          * the packet subsystem.
589          */
590         if (FD_ISSET(connection_in, readset)) {
591                 /* Read as much as possible. */
592                 len = read(connection_in, buf, sizeof(buf));
593                 if (len == 0) {
594                         /* Received EOF.  The remote host has closed the connection. */
595                         snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
596                                  host);
597                         buffer_append(&stderr_buffer, buf, strlen(buf));
598                         quit_pending = 1;
599                         return;
600                 }
601                 /*
602                  * There is a kernel bug on Solaris that causes select to
603                  * sometimes wake up even though there is no data available.
604                  */
605                 if (len < 0 && (errno == EAGAIN || errno == EINTR))
606                         len = 0;
607
608                 if (len < 0) {
609                         /* An error has encountered.  Perhaps there is a network problem. */
610                         snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n",
611                                  host, strerror(errno));
612                         buffer_append(&stderr_buffer, buf, strlen(buf));
613                         quit_pending = 1;
614                         return;
615                 }
616                 packet_process_incoming(buf, len);
617         }
618 }
619
620 static void
621 client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
622 {
623         int id;
624         Channel *c;
625
626         id = packet_get_int();
627         packet_check_eom();
628
629         if ((c = channel_lookup(id)) == NULL) {
630                 error("%s: no channel for id %d", __func__, id);
631                 return;
632         }
633
634         if (type == SSH2_MSG_CHANNEL_SUCCESS)
635                 debug2("Request suceeded on channel %d", id);
636         else if (type == SSH2_MSG_CHANNEL_FAILURE) {
637                 error("Request failed on channel %d", id);
638                 channel_free(c);
639         }
640 }
641
642 static void
643 client_extra_session2_setup(int id, void *arg)
644 {
645         struct confirm_ctx *cctx = arg;
646         const char *display;
647         Channel *c;
648         int i;
649
650         if (cctx == NULL)
651                 fatal("%s: cctx == NULL", __func__);
652         if ((c = channel_lookup(id)) == NULL)
653                 fatal("%s: no channel for id %d", __func__, id);
654
655         display = getenv("DISPLAY");
656         if (cctx->want_x_fwd && options.forward_x11 && display != NULL) {
657                 char *proto, *data;
658                 /* Get reasonable local authentication information. */
659                 client_x11_get_proto(display, options.xauth_location,
660                     options.forward_x11_trusted, &proto, &data);
661                 /* Request forwarding with authentication spoofing. */
662                 debug("Requesting X11 forwarding with authentication spoofing.");
663                 x11_request_forwarding_with_spoofing(id, display, proto, data);
664                 /* XXX wait for reply */
665         }
666
667         if (cctx->want_agent_fwd && options.forward_agent) {
668                 debug("Requesting authentication agent forwarding.");
669                 channel_request_start(id, "auth-agent-req@openssh.com", 0);
670                 packet_send();
671         }
672
673         client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
674             cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env,
675             client_subsystem_reply);
676
677         c->confirm_ctx = NULL;
678         buffer_free(&cctx->cmd);
679         xfree(cctx->term);
680         if (cctx->env != NULL) {
681                 for (i = 0; cctx->env[i] != NULL; i++)
682                         xfree(cctx->env[i]);
683                 xfree(cctx->env);
684         }
685         xfree(cctx);
686 }
687
688 static void
689 client_process_control(fd_set * readset)
690 {
691         Buffer m;
692         Channel *c;
693         int client_fd, new_fd[3], ver, allowed;
694         socklen_t addrlen;
695         struct sockaddr_storage addr;
696         struct confirm_ctx *cctx;
697         char *cmd;
698         u_int i, len, env_len, command, flags;
699         uid_t euid;
700         gid_t egid;
701
702         /*
703          * Accept connection on control socket
704          */
705         if (control_fd == -1 || !FD_ISSET(control_fd, readset))
706                 return;
707
708         memset(&addr, 0, sizeof(addr));
709         addrlen = sizeof(addr);
710         if ((client_fd = accept(control_fd,
711             (struct sockaddr*)&addr, &addrlen)) == -1) {
712                 error("%s accept: %s", __func__, strerror(errno));
713                 return;
714         }
715
716         if (getpeereid(client_fd, &euid, &egid) < 0) {
717                 error("%s getpeereid failed: %s", __func__, strerror(errno));
718                 close(client_fd);
719                 return;
720         }
721         if ((euid != 0) && (getuid() != euid)) {
722                 error("control mode uid mismatch: peer euid %u != uid %u",
723                     (u_int) euid, (u_int) getuid());
724                 close(client_fd);
725                 return;
726         }
727
728         unset_nonblock(client_fd);
729
730         /* Read command */
731         buffer_init(&m);
732         if (ssh_msg_recv(client_fd, &m) == -1) {
733                 error("%s: client msg_recv failed", __func__);
734                 close(client_fd);
735                 buffer_free(&m);
736                 return;
737         }
738         if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
739                 error("%s: wrong client version %d", __func__, ver);
740                 buffer_free(&m);
741                 close(client_fd);
742                 return;
743         }
744
745         allowed = 1;
746         command = buffer_get_int(&m);
747         flags = buffer_get_int(&m);
748
749         buffer_clear(&m);
750
751         switch (command) {
752         case SSHMUX_COMMAND_OPEN:
753                 if (options.control_master == SSHCTL_MASTER_ASK ||
754                     options.control_master == SSHCTL_MASTER_AUTO_ASK)
755                         allowed = ask_permission("Allow shared connection "
756                             "to %s? ", host);
757                 /* continue below */
758                 break;
759         case SSHMUX_COMMAND_TERMINATE:
760                 if (options.control_master == SSHCTL_MASTER_ASK ||
761                     options.control_master == SSHCTL_MASTER_AUTO_ASK)
762                         allowed = ask_permission("Terminate shared connection "
763                             "to %s? ", host);
764                 if (allowed)
765                         quit_pending = 1;
766                 /* FALLTHROUGH */
767         case SSHMUX_COMMAND_ALIVE_CHECK:
768                 /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
769                 buffer_clear(&m);
770                 buffer_put_int(&m, allowed);
771                 buffer_put_int(&m, getpid());
772                 if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
773                         error("%s: client msg_send failed", __func__);
774                         close(client_fd);
775                         buffer_free(&m);
776                         return;
777                 }
778                 buffer_free(&m);
779                 close(client_fd);
780                 return;
781         default:
782                 error("Unsupported command %d", command);
783                 buffer_free(&m);
784                 close(client_fd);
785                 return;
786         }
787
788         /* Reply for SSHMUX_COMMAND_OPEN */
789         buffer_clear(&m);
790         buffer_put_int(&m, allowed);
791         buffer_put_int(&m, getpid());
792         if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
793                 error("%s: client msg_send failed", __func__);
794                 close(client_fd);
795                 buffer_free(&m);
796                 return;
797         }
798
799         if (!allowed) {
800                 error("Refused control connection");
801                 close(client_fd);
802                 buffer_free(&m);
803                 return;
804         }
805
806         buffer_clear(&m);
807         if (ssh_msg_recv(client_fd, &m) == -1) {
808                 error("%s: client msg_recv failed", __func__);
809                 close(client_fd);
810                 buffer_free(&m);
811                 return;
812         }
813         if ((ver = buffer_get_char(&m)) != SSHMUX_VER) {
814                 error("%s: wrong client version %d", __func__, ver);
815                 buffer_free(&m);
816                 close(client_fd);
817                 return;
818         }
819
820         cctx = xmalloc(sizeof(*cctx));
821         memset(cctx, 0, sizeof(*cctx));
822         cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
823         cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
824         cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
825         cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0;
826         cctx->term = buffer_get_string(&m, &len);
827
828         cmd = buffer_get_string(&m, &len);
829         buffer_init(&cctx->cmd);
830         buffer_append(&cctx->cmd, cmd, strlen(cmd));
831
832         env_len = buffer_get_int(&m);
833         env_len = MIN(env_len, 4096);
834         debug3("%s: receiving %d env vars", __func__, env_len);
835         if (env_len != 0) {
836                 cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1));
837                 for (i = 0; i < env_len; i++)
838                         cctx->env[i] = buffer_get_string(&m, &len);
839                 cctx->env[i] = NULL;
840         }
841
842         debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
843             cctx->want_tty, cctx->want_subsys, cmd);
844
845         /* Gather fds from client */
846         new_fd[0] = mm_receive_fd(client_fd);
847         new_fd[1] = mm_receive_fd(client_fd);
848         new_fd[2] = mm_receive_fd(client_fd);
849
850         debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
851             new_fd[0], new_fd[1], new_fd[2]);
852
853         /* Try to pick up ttymodes from client before it goes raw */
854         if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)
855                 error("%s: tcgetattr: %s", __func__, strerror(errno));
856
857         /* This roundtrip is just for synchronisation of ttymodes */
858         buffer_clear(&m);
859         if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) {
860                 error("%s: client msg_send failed", __func__);
861                 close(client_fd);
862                 close(new_fd[0]);
863                 close(new_fd[1]);
864                 close(new_fd[2]);
865                 buffer_free(&m);
866                 xfree(cctx->term);
867                 if (env_len != 0) {
868                         for (i = 0; i < env_len; i++)
869                                 xfree(cctx->env[i]);
870                         xfree(cctx->env);
871                 }
872                 return;
873         }
874         buffer_free(&m);
875
876         /* enable nonblocking unless tty */
877         if (!isatty(new_fd[0]))
878                 set_nonblock(new_fd[0]);
879         if (!isatty(new_fd[1]))
880                 set_nonblock(new_fd[1]);
881         if (!isatty(new_fd[2]))
882                 set_nonblock(new_fd[2]);
883
884         set_nonblock(client_fd);
885
886         c = channel_new("session", SSH_CHANNEL_OPENING,
887             new_fd[0], new_fd[1], new_fd[2],
888             CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT,
889             CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
890
891         /* XXX */
892         c->ctl_fd = client_fd;
893
894         debug3("%s: channel_new: %d", __func__, c->self);
895
896         channel_send_open(c->self);
897         channel_register_confirm(c->self, client_extra_session2_setup, cctx);
898 }
899
900 static void
901 process_cmdline(void)
902 {
903         void (*handler)(int);
904         char *s, *cmd, *cancel_host;
905         int delete = 0;
906         int local = 0;
907         u_short cancel_port;
908         Forward fwd;
909
910         leave_raw_mode();
911         handler = signal(SIGINT, SIG_IGN);
912         cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
913         if (s == NULL)
914                 goto out;
915         while (*s && isspace(*s))
916                 s++;
917         if (*s == '-')
918                 s++;    /* Skip cmdline '-', if any */
919         if (*s == '\0')
920                 goto out;
921
922         if (*s == 'h' || *s == 'H' || *s == '?') {
923                 logit("Commands:");
924                 logit("      -Lport:host:hostport    Request local forward");
925                 logit("      -Rport:host:hostport    Request remote forward");
926                 logit("      -KRhostport             Cancel remote forward");
927                 if (!options.permit_local_command)
928                         goto out;
929                 logit("      !args                   Execute local command");
930                 goto out;
931         }
932
933         if (*s == '!' && options.permit_local_command) {
934                 s++;
935                 ssh_local_cmd(s);
936                 goto out;
937         }
938
939         if (*s == 'K') {
940                 delete = 1;
941                 s++;
942         }
943         if (*s != 'L' && *s != 'R') {
944                 logit("Invalid command.");
945                 goto out;
946         }
947         if (*s == 'L')
948                 local = 1;
949         if (local && delete) {
950                 logit("Not supported.");
951                 goto out;
952         }
953         if ((!local || delete) && !compat20) {
954                 logit("Not supported for SSH protocol version 1.");
955                 goto out;
956         }
957
958         s++;
959         while (*s && isspace(*s))
960                 s++;
961
962         if (delete) {
963                 cancel_port = 0;
964                 cancel_host = hpdelim(&s);      /* may be NULL */
965                 if (s != NULL) {
966                         cancel_port = a2port(s);
967                         cancel_host = cleanhostname(cancel_host);
968                 } else {
969                         cancel_port = a2port(cancel_host);
970                         cancel_host = NULL;
971                 }
972                 if (cancel_port == 0) {
973                         logit("Bad forwarding close port");
974                         goto out;
975                 }
976                 channel_request_rforward_cancel(cancel_host, cancel_port);
977         } else {
978                 if (!parse_forward(&fwd, s)) {
979                         logit("Bad forwarding specification.");
980                         goto out;
981                 }
982                 if (local) {
983                         if (channel_setup_local_fwd_listener(fwd.listen_host,
984                             fwd.listen_port, fwd.connect_host,
985                             fwd.connect_port, options.gateway_ports) < 0) {
986                                 logit("Port forwarding failed.");
987                                 goto out;
988                         }
989                 } else {
990                         channel_request_remote_forwarding(fwd.listen_host,
991                             fwd.listen_port, fwd.connect_host,
992                             fwd.connect_port);
993                 }
994
995                 logit("Forwarding port.");
996         }
997
998 out:
999         signal(SIGINT, handler);
1000         enter_raw_mode();
1001         if (cmd)
1002                 xfree(cmd);
1003 }
1004
1005 /* process the characters one by one */
1006 static int
1007 process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
1008 {
1009         char string[1024];
1010         pid_t pid;
1011         int bytes = 0;
1012         u_int i;
1013         u_char ch;
1014         char *s;
1015
1016         if (len <= 0)
1017                 return (0);
1018
1019         for (i = 0; i < (u_int)len; i++) {
1020                 /* Get one character at a time. */
1021                 ch = buf[i];
1022
1023                 if (escape_pending) {
1024                         /* We have previously seen an escape character. */
1025                         /* Clear the flag now. */
1026                         escape_pending = 0;
1027
1028                         /* Process the escaped character. */
1029                         switch (ch) {
1030                         case '.':
1031                                 /* Terminate the connection. */
1032                                 snprintf(string, sizeof string, "%c.\r\n", escape_char);
1033                                 buffer_append(berr, string, strlen(string));
1034
1035                                 quit_pending = 1;
1036                                 return -1;
1037
1038                         case 'Z' - 64:
1039                                 /* Suspend the program. */
1040                                 /* Print a message to that effect to the user. */
1041                                 snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char);
1042                                 buffer_append(berr, string, strlen(string));
1043
1044                                 /* Restore terminal modes and suspend. */
1045                                 client_suspend_self(bin, bout, berr);
1046
1047                                 /* We have been continued. */
1048                                 continue;
1049
1050                         case 'B':
1051                                 if (compat20) {
1052                                         snprintf(string, sizeof string,
1053                                             "%cB\r\n", escape_char);
1054                                         buffer_append(berr, string,
1055                                             strlen(string));
1056                                         channel_request_start(session_ident,
1057                                             "break", 0);
1058                                         packet_put_int(1000);
1059                                         packet_send();
1060                                 }
1061                                 continue;
1062
1063                         case 'R':
1064                                 if (compat20) {
1065                                         if (datafellows & SSH_BUG_NOREKEY)
1066                                                 logit("Server does not support re-keying");
1067                                         else
1068                                                 need_rekeying = 1;
1069                                 }
1070                                 continue;
1071
1072                         case '&':
1073                                 /*
1074                                  * Detach the program (continue to serve connections,
1075                                  * but put in background and no more new connections).
1076                                  */
1077                                 /* Restore tty modes. */
1078                                 leave_raw_mode();
1079
1080                                 /* Stop listening for new connections. */
1081                                 channel_stop_listening();
1082
1083                                 snprintf(string, sizeof string,
1084                                     "%c& [backgrounded]\n", escape_char);
1085                                 buffer_append(berr, string, strlen(string));
1086
1087                                 /* Fork into background. */
1088                                 pid = fork();
1089                                 if (pid < 0) {
1090                                         error("fork: %.100s", strerror(errno));
1091                                         continue;
1092                                 }
1093                                 if (pid != 0) { /* This is the parent. */
1094                                         /* The parent just exits. */
1095                                         exit(0);
1096                                 }
1097                                 /* The child continues serving connections. */
1098                                 if (compat20) {
1099                                         buffer_append(bin, "\004", 1);
1100                                         /* fake EOF on stdin */
1101                                         return -1;
1102                                 } else if (!stdin_eof) {
1103                                         /*
1104                                          * Sending SSH_CMSG_EOF alone does not always appear
1105                                          * to be enough.  So we try to send an EOF character
1106                                          * first.
1107                                          */
1108                                         packet_start(SSH_CMSG_STDIN_DATA);
1109                                         packet_put_string("\004", 1);
1110                                         packet_send();
1111                                         /* Close stdin. */
1112                                         stdin_eof = 1;
1113                                         if (buffer_len(bin) == 0) {
1114                                                 packet_start(SSH_CMSG_EOF);
1115                                                 packet_send();
1116                                         }
1117                                 }
1118                                 continue;
1119
1120                         case '?':
1121                                 snprintf(string, sizeof string,
1122 "%c?\r\n\
1123 Supported escape sequences:\r\n\
1124 %c.  - terminate connection\r\n\
1125 %cB  - send a BREAK to the remote system\r\n\
1126 %cC  - open a command line\r\n\
1127 %cR  - Request rekey (SSH protocol 2 only)\r\n\
1128 %c^Z - suspend ssh\r\n\
1129 %c#  - list forwarded connections\r\n\
1130 %c&  - background ssh (when waiting for connections to terminate)\r\n\
1131 %c?  - this message\r\n\
1132 %c%c  - send the escape character by typing it twice\r\n\
1133 (Note that escapes are only recognized immediately after newline.)\r\n",
1134                                     escape_char, escape_char, escape_char, escape_char,
1135                                     escape_char, escape_char, escape_char, escape_char,
1136                                     escape_char, escape_char, escape_char);
1137                                 buffer_append(berr, string, strlen(string));
1138                                 continue;
1139
1140                         case '#':
1141                                 snprintf(string, sizeof string, "%c#\r\n", escape_char);
1142                                 buffer_append(berr, string, strlen(string));
1143                                 s = channel_open_message();
1144                                 buffer_append(berr, s, strlen(s));
1145                                 xfree(s);
1146                                 continue;
1147
1148                         case 'C':
1149                                 process_cmdline();
1150                                 continue;
1151
1152                         default:
1153                                 if (ch != escape_char) {
1154                                         buffer_put_char(bin, escape_char);
1155                                         bytes++;
1156                                 }
1157                                 /* Escaped characters fall through here */
1158                                 break;
1159                         }
1160                 } else {
1161                         /*
1162                          * The previous character was not an escape char. Check if this
1163                          * is an escape.
1164                          */
1165                         if (last_was_cr && ch == escape_char) {
1166                                 /* It is. Set the flag and continue to next character. */
1167                                 escape_pending = 1;
1168                                 continue;
1169                         }
1170                 }
1171
1172                 /*
1173                  * Normal character.  Record whether it was a newline,
1174                  * and append it to the buffer.
1175                  */
1176                 last_was_cr = (ch == '\r' || ch == '\n');
1177                 buffer_put_char(bin, ch);
1178                 bytes++;
1179         }
1180         return bytes;
1181 }
1182
1183 static void
1184 client_process_input(fd_set * readset)
1185 {
1186         int len;
1187         char buf[8192];
1188
1189         /* Read input from stdin. */
1190         if (FD_ISSET(fileno(stdin), readset)) {
1191                 /* Read as much as possible. */
1192                 len = read(fileno(stdin), buf, sizeof(buf));
1193                 if (len < 0 && (errno == EAGAIN || errno == EINTR))
1194                         return;         /* we'll try again later */
1195                 if (len <= 0) {
1196                         /*
1197                          * Received EOF or error.  They are treated
1198                          * similarly, except that an error message is printed
1199                          * if it was an error condition.
1200                          */
1201                         if (len < 0) {
1202                                 snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno));
1203                                 buffer_append(&stderr_buffer, buf, strlen(buf));
1204                         }
1205                         /* Mark that we have seen EOF. */
1206                         stdin_eof = 1;
1207                         /*
1208                          * Send an EOF message to the server unless there is
1209                          * data in the buffer.  If there is data in the
1210                          * buffer, no message will be sent now.  Code
1211                          * elsewhere will send the EOF when the buffer
1212                          * becomes empty if stdin_eof is set.
1213                          */
1214                         if (buffer_len(&stdin_buffer) == 0) {
1215                                 packet_start(SSH_CMSG_EOF);
1216                                 packet_send();
1217                         }
1218                 } else if (escape_char == SSH_ESCAPECHAR_NONE) {
1219                         /*
1220                          * Normal successful read, and no escape character.
1221                          * Just append the data to buffer.
1222                          */
1223                         buffer_append(&stdin_buffer, buf, len);
1224                 } else {
1225                         /*
1226                          * Normal, successful read.  But we have an escape character
1227                          * and have to process the characters one by one.
1228                          */
1229                         if (process_escapes(&stdin_buffer, &stdout_buffer,
1230                             &stderr_buffer, buf, len) == -1)
1231                                 return;
1232                 }
1233         }
1234 }
1235
1236 static void
1237 client_process_output(fd_set * writeset)
1238 {
1239         int len;
1240         char buf[100];
1241
1242         /* Write buffered output to stdout. */
1243         if (FD_ISSET(fileno(stdout), writeset)) {
1244                 /* Write as much data as possible. */
1245                 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1246                     buffer_len(&stdout_buffer));
1247                 if (len <= 0) {
1248                         if (errno == EINTR || errno == EAGAIN)
1249                                 len = 0;
1250                         else {
1251                                 /*
1252                                  * An error or EOF was encountered.  Put an
1253                                  * error message to stderr buffer.
1254                                  */
1255                                 snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno));
1256                                 buffer_append(&stderr_buffer, buf, strlen(buf));
1257                                 quit_pending = 1;
1258                                 return;
1259                         }
1260                 }
1261                 /* Consume printed data from the buffer. */
1262                 buffer_consume(&stdout_buffer, len);
1263                 stdout_bytes += len;
1264         }
1265         /* Write buffered output to stderr. */
1266         if (FD_ISSET(fileno(stderr), writeset)) {
1267                 /* Write as much data as possible. */
1268                 len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1269                     buffer_len(&stderr_buffer));
1270                 if (len <= 0) {
1271                         if (errno == EINTR || errno == EAGAIN)
1272                                 len = 0;
1273                         else {
1274                                 /* EOF or error, but can't even print error message. */
1275                                 quit_pending = 1;
1276                                 return;
1277                         }
1278                 }
1279                 /* Consume printed characters from the buffer. */
1280                 buffer_consume(&stderr_buffer, len);
1281                 stderr_bytes += len;
1282         }
1283 }
1284
1285 /*
1286  * Get packets from the connection input buffer, and process them as long as
1287  * there are packets available.
1288  *
1289  * Any unknown packets received during the actual
1290  * session cause the session to terminate.  This is
1291  * intended to make debugging easier since no
1292  * confirmations are sent.  Any compatible protocol
1293  * extensions must be negotiated during the
1294  * preparatory phase.
1295  */
1296
1297 static void
1298 client_process_buffered_input_packets(void)
1299 {
1300         dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL);
1301 }
1302
1303 /* scan buf[] for '~' before sending data to the peer */
1304
1305 static int
1306 simple_escape_filter(Channel *c, char *buf, int len)
1307 {
1308         /* XXX we assume c->extended is writeable */
1309         return process_escapes(&c->input, &c->output, &c->extended, buf, len);
1310 }
1311
1312 static void
1313 client_channel_closed(int id, void *arg)
1314 {
1315         channel_cancel_cleanup(id);
1316         session_closed = 1;
1317         leave_raw_mode();
1318 }
1319
1320 /*
1321  * Implements the interactive session with the server.  This is called after
1322  * the user has been authenticated, and a command has been started on the
1323  * remote host.  If escape_char != SSH_ESCAPECHAR_NONE, it is the character
1324  * used as an escape character for terminating or suspending the session.
1325  */
1326
1327 int
1328 client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1329 {
1330         fd_set *readset = NULL, *writeset = NULL;
1331         double start_time, total_time;
1332         int max_fd = 0, max_fd2 = 0, len, rekeying = 0;
1333         u_int nalloc = 0;
1334         char buf[100];
1335
1336         debug("Entering interactive session.");
1337
1338         start_time = get_current_time();
1339
1340         /* Initialize variables. */
1341         escape_pending = 0;
1342         last_was_cr = 1;
1343         exit_status = -1;
1344         stdin_eof = 0;
1345         buffer_high = 64 * 1024;
1346         connection_in = packet_get_connection_in();
1347         connection_out = packet_get_connection_out();
1348         max_fd = MAX(connection_in, connection_out);
1349         if (control_fd != -1)
1350                 max_fd = MAX(max_fd, control_fd);
1351
1352         if (!compat20) {
1353                 /* enable nonblocking unless tty */
1354                 if (!isatty(fileno(stdin)))
1355                         set_nonblock(fileno(stdin));
1356                 if (!isatty(fileno(stdout)))
1357                         set_nonblock(fileno(stdout));
1358                 if (!isatty(fileno(stderr)))
1359                         set_nonblock(fileno(stderr));
1360                 max_fd = MAX(max_fd, fileno(stdin));
1361                 max_fd = MAX(max_fd, fileno(stdout));
1362                 max_fd = MAX(max_fd, fileno(stderr));
1363         }
1364         stdin_bytes = 0;
1365         stdout_bytes = 0;
1366         stderr_bytes = 0;
1367         quit_pending = 0;
1368         escape_char = escape_char_arg;
1369
1370         /* Initialize buffers. */
1371         buffer_init(&stdin_buffer);
1372         buffer_init(&stdout_buffer);
1373         buffer_init(&stderr_buffer);
1374
1375         client_init_dispatch();
1376
1377         /*
1378          * Set signal handlers, (e.g. to restore non-blocking mode)
1379          * but don't overwrite SIG_IGN, matches behaviour from rsh(1)
1380          */
1381         if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
1382                 signal(SIGHUP, signal_handler);
1383         if (signal(SIGINT, SIG_IGN) != SIG_IGN)
1384                 signal(SIGINT, signal_handler);
1385         if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
1386                 signal(SIGQUIT, signal_handler);
1387         if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
1388                 signal(SIGTERM, signal_handler);
1389         signal(SIGWINCH, window_change_handler);
1390
1391         if (have_pty)
1392                 enter_raw_mode();
1393
1394         if (compat20) {
1395                 session_ident = ssh2_chan_id;
1396                 if (escape_char != SSH_ESCAPECHAR_NONE)
1397                         channel_register_filter(session_ident,
1398                             simple_escape_filter, NULL);
1399                 if (session_ident != -1)
1400                         channel_register_cleanup(session_ident,
1401                             client_channel_closed, 0);
1402         } else {
1403                 /* Check if we should immediately send eof on stdin. */
1404                 client_check_initial_eof_on_stdin();
1405         }
1406
1407         /* Main loop of the client for the interactive session mode. */
1408         while (!quit_pending) {
1409
1410                 /* Process buffered packets sent by the server. */
1411                 client_process_buffered_input_packets();
1412
1413                 if (compat20 && session_closed && !channel_still_open())
1414                         break;
1415
1416                 rekeying = (xxx_kex != NULL && !xxx_kex->done);
1417
1418                 if (rekeying) {
1419                         debug("rekeying in progress");
1420                 } else {
1421                         /*
1422                          * Make packets of buffered stdin data, and buffer
1423                          * them for sending to the server.
1424                          */
1425                         if (!compat20)
1426                                 client_make_packets_from_stdin_data();
1427
1428                         /*
1429                          * Make packets from buffered channel data, and
1430                          * enqueue them for sending to the server.
1431                          */
1432                         if (packet_not_very_much_data_to_write())
1433                                 channel_output_poll();
1434
1435                         /*
1436                          * Check if the window size has changed, and buffer a
1437                          * message about it to the server if so.
1438                          */
1439                         client_check_window_change();
1440
1441                         if (quit_pending)
1442                                 break;
1443                 }
1444                 /*
1445                  * Wait until we have something to do (something becomes
1446                  * available on one of the descriptors).
1447                  */
1448                 max_fd2 = max_fd;
1449                 client_wait_until_can_do_something(&readset, &writeset,
1450                     &max_fd2, &nalloc, rekeying);
1451
1452                 if (quit_pending)
1453                         break;
1454
1455                 /* Do channel operations unless rekeying in progress. */
1456                 if (!rekeying) {
1457                         channel_after_select(readset, writeset);
1458                         if (need_rekeying || packet_need_rekeying()) {
1459                                 debug("need rekeying");
1460                                 xxx_kex->done = 0;
1461                                 kex_send_kexinit(xxx_kex);
1462                                 need_rekeying = 0;
1463                         }
1464                 }
1465
1466                 /* Buffer input from the connection.  */
1467                 client_process_net_input(readset);
1468
1469                 /* Accept control connections.  */
1470                 client_process_control(readset);
1471
1472                 if (quit_pending)
1473                         break;
1474
1475                 if (!compat20) {
1476                         /* Buffer data from stdin */
1477                         client_process_input(readset);
1478                         /*
1479                          * Process output to stdout and stderr.  Output to
1480                          * the connection is processed elsewhere (above).
1481                          */
1482                         client_process_output(writeset);
1483                 }
1484
1485                 /* Send as much buffered packet data as possible to the sender. */
1486                 if (FD_ISSET(connection_out, writeset))
1487                         packet_write_poll();
1488         }
1489         if (readset)
1490                 xfree(readset);
1491         if (writeset)
1492                 xfree(writeset);
1493
1494         /* Terminate the session. */
1495
1496         /* Stop watching for window change. */
1497         signal(SIGWINCH, SIG_DFL);
1498
1499         channel_free_all();
1500
1501         if (have_pty)
1502                 leave_raw_mode();
1503
1504         /* restore blocking io */
1505         if (!isatty(fileno(stdin)))
1506                 unset_nonblock(fileno(stdin));
1507         if (!isatty(fileno(stdout)))
1508                 unset_nonblock(fileno(stdout));
1509         if (!isatty(fileno(stderr)))
1510                 unset_nonblock(fileno(stderr));
1511
1512         /*
1513          * If there was no shell or command requested, there will be no remote
1514          * exit status to be returned.  In that case, clear error code if the
1515          * connection was deliberately terminated at this end.
1516          */
1517         if (no_shell_flag && received_signal == SIGTERM) {
1518                 received_signal = 0;
1519                 exit_status = 0;
1520         }
1521
1522         if (received_signal)
1523                 fatal("Killed by signal %d.", (int) received_signal);
1524
1525         /*
1526          * In interactive mode (with pseudo tty) display a message indicating
1527          * that the connection has been closed.
1528          */
1529         if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
1530                 snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
1531                 buffer_append(&stderr_buffer, buf, strlen(buf));
1532         }
1533
1534         /* Output any buffered data for stdout. */
1535         while (buffer_len(&stdout_buffer) > 0) {
1536                 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1537                     buffer_len(&stdout_buffer));
1538                 if (len <= 0) {
1539                         error("Write failed flushing stdout buffer.");
1540                         break;
1541                 }
1542                 buffer_consume(&stdout_buffer, len);
1543                 stdout_bytes += len;
1544         }
1545
1546         /* Output any buffered data for stderr. */
1547         while (buffer_len(&stderr_buffer) > 0) {
1548                 len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1549                     buffer_len(&stderr_buffer));
1550                 if (len <= 0) {
1551                         error("Write failed flushing stderr buffer.");
1552                         break;
1553                 }
1554                 buffer_consume(&stderr_buffer, len);
1555                 stderr_bytes += len;
1556         }
1557
1558         /* Clear and free any buffers. */
1559         memset(buf, 0, sizeof(buf));
1560         buffer_free(&stdin_buffer);
1561         buffer_free(&stdout_buffer);
1562         buffer_free(&stderr_buffer);
1563
1564         /* Report bytes transferred, and transfer rates. */
1565         total_time = get_current_time() - start_time;
1566         debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds",
1567             stdin_bytes, stdout_bytes, stderr_bytes, total_time);
1568         if (total_time > 0)
1569                 debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f",
1570                     stdin_bytes / total_time, stdout_bytes / total_time,
1571                     stderr_bytes / total_time);
1572
1573         /* Return the exit status of the program. */
1574         debug("Exit status %d", exit_status);
1575         return exit_status;
1576 }
1577
1578 /*********/
1579
1580 static void
1581 client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1582 {
1583         u_int data_len;
1584         char *data = packet_get_string(&data_len);
1585         packet_check_eom();
1586         buffer_append(&stdout_buffer, data, data_len);
1587         memset(data, 0, data_len);
1588         xfree(data);
1589 }
1590 static void
1591 client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1592 {
1593         u_int data_len;
1594         char *data = packet_get_string(&data_len);
1595         packet_check_eom();
1596         buffer_append(&stderr_buffer, data, data_len);
1597         memset(data, 0, data_len);
1598         xfree(data);
1599 }
1600 static void
1601 client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1602 {
1603         exit_status = packet_get_int();
1604         packet_check_eom();
1605         /* Acknowledge the exit. */
1606         packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1607         packet_send();
1608         /*
1609          * Must wait for packet to be sent since we are
1610          * exiting the loop.
1611          */
1612         packet_write_wait();
1613         /* Flag that we want to exit. */
1614         quit_pending = 1;
1615 }
1616 static void
1617 client_input_agent_open(int type, u_int32_t seq, void *ctxt)
1618 {
1619         Channel *c = NULL;
1620         int remote_id, sock;
1621
1622         /* Read the remote channel number from the message. */
1623         remote_id = packet_get_int();
1624         packet_check_eom();
1625
1626         /*
1627          * Get a connection to the local authentication agent (this may again
1628          * get forwarded).
1629          */
1630         sock = ssh_get_authentication_socket();
1631
1632         /*
1633          * If we could not connect the agent, send an error message back to
1634          * the server. This should never happen unless the agent dies,
1635          * because authentication forwarding is only enabled if we have an
1636          * agent.
1637          */
1638         if (sock >= 0) {
1639                 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
1640                     -1, 0, 0, 0, "authentication agent connection", 1);
1641                 c->remote_id = remote_id;
1642                 c->force_drain = 1;
1643         }
1644         if (c == NULL) {
1645                 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1646                 packet_put_int(remote_id);
1647         } else {
1648                 /* Send a confirmation to the remote host. */
1649                 debug("Forwarding authentication connection.");
1650                 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1651                 packet_put_int(remote_id);
1652                 packet_put_int(c->self);
1653         }
1654         packet_send();
1655 }
1656
1657 static Channel *
1658 client_request_forwarded_tcpip(const char *request_type, int rchan)
1659 {
1660         Channel *c = NULL;
1661         char *listen_address, *originator_address;
1662         int listen_port, originator_port;
1663         int sock;
1664
1665         /* Get rest of the packet */
1666         listen_address = packet_get_string(NULL);
1667         listen_port = packet_get_int();
1668         originator_address = packet_get_string(NULL);
1669         originator_port = packet_get_int();
1670         packet_check_eom();
1671
1672         debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
1673             listen_address, listen_port, originator_address, originator_port);
1674
1675         sock = channel_connect_by_listen_address(listen_port);
1676         if (sock < 0) {
1677                 xfree(originator_address);
1678                 xfree(listen_address);
1679                 return NULL;
1680         }
1681         c = channel_new("forwarded-tcpip",
1682             SSH_CHANNEL_CONNECTING, sock, sock, -1,
1683             CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1684             originator_address, 1);
1685         xfree(originator_address);
1686         xfree(listen_address);
1687         return c;
1688 }
1689
1690 static Channel *
1691 client_request_x11(const char *request_type, int rchan)
1692 {
1693         Channel *c = NULL;
1694         char *originator;
1695         int originator_port;
1696         int sock;
1697
1698         if (!options.forward_x11) {
1699                 error("Warning: ssh server tried X11 forwarding.");
1700                 error("Warning: this is probably a break-in attempt by a malicious server.");
1701                 return NULL;
1702         }
1703         originator = packet_get_string(NULL);
1704         if (datafellows & SSH_BUG_X11FWD) {
1705                 debug2("buggy server: x11 request w/o originator_port");
1706                 originator_port = 0;
1707         } else {
1708                 originator_port = packet_get_int();
1709         }
1710         packet_check_eom();
1711         /* XXX check permission */
1712         debug("client_request_x11: request from %s %d", originator,
1713             originator_port);
1714         xfree(originator);
1715         sock = x11_connect_display();
1716         if (sock < 0)
1717                 return NULL;
1718         c = channel_new("x11",
1719             SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1720             CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
1721         c->force_drain = 1;
1722         return c;
1723 }
1724
1725 static Channel *
1726 client_request_agent(const char *request_type, int rchan)
1727 {
1728         Channel *c = NULL;
1729         int sock;
1730
1731         if (!options.forward_agent) {
1732                 error("Warning: ssh server tried agent forwarding.");
1733                 error("Warning: this is probably a break-in attempt by a malicious server.");
1734                 return NULL;
1735         }
1736         sock =  ssh_get_authentication_socket();
1737         if (sock < 0)
1738                 return NULL;
1739         c = channel_new("authentication agent connection",
1740             SSH_CHANNEL_OPEN, sock, sock, -1,
1741             CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1742             "authentication agent connection", 1);
1743         c->force_drain = 1;
1744         return c;
1745 }
1746
1747 /* XXXX move to generic input handler */
1748 static void
1749 client_input_channel_open(int type, u_int32_t seq, void *ctxt)
1750 {
1751         Channel *c = NULL;
1752         char *ctype;
1753         int rchan;
1754         u_int rmaxpack, rwindow, len;
1755
1756         ctype = packet_get_string(&len);
1757         rchan = packet_get_int();
1758         rwindow = packet_get_int();
1759         rmaxpack = packet_get_int();
1760
1761         debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
1762             ctype, rchan, rwindow, rmaxpack);
1763
1764         if (strcmp(ctype, "forwarded-tcpip") == 0) {
1765                 c = client_request_forwarded_tcpip(ctype, rchan);
1766         } else if (strcmp(ctype, "x11") == 0) {
1767                 c = client_request_x11(ctype, rchan);
1768         } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
1769                 c = client_request_agent(ctype, rchan);
1770         }
1771 /* XXX duplicate : */
1772         if (c != NULL) {
1773                 debug("confirm %s", ctype);
1774                 c->remote_id = rchan;
1775                 c->remote_window = rwindow;
1776                 c->remote_maxpacket = rmaxpack;
1777                 if (c->type != SSH_CHANNEL_CONNECTING) {
1778                         packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1779                         packet_put_int(c->remote_id);
1780                         packet_put_int(c->self);
1781                         packet_put_int(c->local_window);
1782                         packet_put_int(c->local_maxpacket);
1783                         packet_send();
1784                 }
1785         } else {
1786                 debug("failure %s", ctype);
1787                 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1788                 packet_put_int(rchan);
1789                 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
1790                 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1791                         packet_put_cstring("open failed");
1792                         packet_put_cstring("");
1793                 }
1794                 packet_send();
1795         }
1796         xfree(ctype);
1797 }
1798 static void
1799 client_input_channel_req(int type, u_int32_t seq, void *ctxt)
1800 {
1801         Channel *c = NULL;
1802         int exitval, id, reply, success = 0;
1803         char *rtype;
1804
1805         id = packet_get_int();
1806         rtype = packet_get_string(NULL);
1807         reply = packet_get_char();
1808
1809         debug("client_input_channel_req: channel %d rtype %s reply %d",
1810             id, rtype, reply);
1811
1812         if (id == -1) {
1813                 error("client_input_channel_req: request for channel -1");
1814         } else if ((c = channel_lookup(id)) == NULL) {
1815                 error("client_input_channel_req: channel %d: unknown channel", id);
1816         } else if (strcmp(rtype, "exit-status") == 0) {
1817                 exitval = packet_get_int();
1818                 if (id == session_ident) {
1819                         success = 1;
1820                         exit_status = exitval;
1821                 } else if (c->ctl_fd == -1) {
1822                         error("client_input_channel_req: unexpected channel %d",
1823                             session_ident);
1824                 } else {
1825                         atomicio(vwrite, c->ctl_fd, &exitval, sizeof(exitval));
1826                         success = 1;
1827                 }
1828                 packet_check_eom();
1829         }
1830         if (reply) {
1831                 packet_start(success ?
1832                     SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1833                 packet_put_int(id);
1834                 packet_send();
1835         }
1836         xfree(rtype);
1837 }
1838 static void
1839 client_input_global_request(int type, u_int32_t seq, void *ctxt)
1840 {
1841         char *rtype;
1842         int want_reply;
1843         int success = 0;
1844
1845         rtype = packet_get_string(NULL);
1846         want_reply = packet_get_char();
1847         debug("client_input_global_request: rtype %s want_reply %d",
1848             rtype, want_reply);
1849         if (want_reply) {
1850                 packet_start(success ?
1851                     SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
1852                 packet_send();
1853                 packet_write_wait();
1854         }
1855         xfree(rtype);
1856 }
1857
1858 void
1859 client_session2_setup(int id, int want_tty, int want_subsystem,
1860     const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env,
1861     dispatch_fn *subsys_repl)
1862 {
1863         int len;
1864         Channel *c = NULL;
1865
1866         debug2("%s: id %d", __func__, id);
1867
1868         if ((c = channel_lookup(id)) == NULL)
1869                 fatal("client_session2_setup: channel %d: unknown channel", id);
1870
1871         if (want_tty) {
1872                 struct winsize ws;
1873                 struct termios tio;
1874
1875                 /* Store window size in the packet. */
1876                 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
1877                         memset(&ws, 0, sizeof(ws));
1878
1879                 channel_request_start(id, "pty-req", 0);
1880                 packet_put_cstring(term != NULL ? term : "");
1881                 packet_put_int(ws.ws_col);
1882                 packet_put_int(ws.ws_row);
1883                 packet_put_int(ws.ws_xpixel);
1884                 packet_put_int(ws.ws_ypixel);
1885                 tio = get_saved_tio();
1886                 tty_make_modes(-1, tiop != NULL ? tiop : &tio);
1887                 packet_send();
1888                 /* XXX wait for reply */
1889                 c->client_tty = 1;
1890         }
1891
1892         /* Transfer any environment variables from client to server */
1893         if (options.num_send_env != 0 && env != NULL) {
1894                 int i, j, matched;
1895                 char *name, *val;
1896
1897                 debug("Sending environment.");
1898                 for (i = 0; env[i] != NULL; i++) {
1899                         /* Split */
1900                         name = xstrdup(env[i]);
1901                         if ((val = strchr(name, '=')) == NULL) {
1902                                 xfree(name);
1903                                 continue;
1904                         }
1905                         *val++ = '\0';
1906
1907                         matched = 0;
1908                         for (j = 0; j < options.num_send_env; j++) {
1909                                 if (match_pattern(name, options.send_env[j])) {
1910                                         matched = 1;
1911                                         break;
1912                                 }
1913                         }
1914                         if (!matched) {
1915                                 debug3("Ignored env %s", name);
1916                                 xfree(name);
1917                                 continue;
1918                         }
1919
1920                         debug("Sending env %s = %s", name, val);
1921                         channel_request_start(id, "env", 0);
1922                         packet_put_cstring(name);
1923                         packet_put_cstring(val);
1924                         packet_send();
1925                         xfree(name);
1926                 }
1927         }
1928
1929         len = buffer_len(cmd);
1930         if (len > 0) {
1931                 if (len > 900)
1932                         len = 900;
1933                 if (want_subsystem) {
1934                         debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd));
1935                         channel_request_start(id, "subsystem", subsys_repl != NULL);
1936                         if (subsys_repl != NULL) {
1937                                 /* register callback for reply */
1938                                 /* XXX we assume that client_loop has already been called */
1939                                 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl);
1940                                 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl);
1941                         }
1942                 } else {
1943                         debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd));
1944                         channel_request_start(id, "exec", 0);
1945                 }
1946                 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
1947                 packet_send();
1948         } else {
1949                 channel_request_start(id, "shell", 0);
1950                 packet_send();
1951         }
1952 }
1953
1954 static void
1955 client_init_dispatch_20(void)
1956 {
1957         dispatch_init(&dispatch_protocol_error);
1958
1959         dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
1960         dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
1961         dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
1962         dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
1963         dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
1964         dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1965         dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1966         dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
1967         dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1968         dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
1969
1970         /* rekeying */
1971         dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
1972
1973         /* global request reply messages */
1974         dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
1975         dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
1976 }
1977 static void
1978 client_init_dispatch_13(void)
1979 {
1980         dispatch_init(NULL);
1981         dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
1982         dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
1983         dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
1984         dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1985         dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1986         dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
1987         dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
1988         dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
1989         dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
1990
1991         dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
1992             &client_input_agent_open : &deny_input_open);
1993         dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
1994             &x11_input_open : &deny_input_open);
1995 }
1996 static void
1997 client_init_dispatch_15(void)
1998 {
1999         client_init_dispatch_13();
2000         dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
2001         dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
2002 }
2003 static void
2004 client_init_dispatch(void)
2005 {
2006         if (compat20)
2007                 client_init_dispatch_20();
2008         else if (compat13)
2009                 client_init_dispatch_13();
2010         else
2011                 client_init_dispatch_15();
2012 }
2013
2014 /* client specific fatal cleanup */
2015 void
2016 cleanup_exit(int i)
2017 {
2018         leave_raw_mode();
2019         leave_non_blocking();
2020         if (options.control_path != NULL && control_fd != -1)
2021                 unlink(options.control_path);
2022         _exit(i);
2023 }
This page took 0.567907 seconds and 5 git commands to generate.