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