]> andersk Git - openssh.git/blob - serverloop.c
- djm@cvs.openbsd.org 2006/07/06 10:47:57
[openssh.git] / serverloop.c
1 /* $OpenBSD: serverloop.c,v 1.136 2006/07/05 02:42:09 stevesk Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Server main loop for handling the interactive session.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  *
14  * SSH2 support by Markus Friedl.
15  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37
38 #include "includes.h"
39
40 #include <sys/types.h>
41 #include <sys/wait.h>
42 #include <sys/socket.h>
43
44 #include <netinet/in.h>
45
46 #include <signal.h>
47 #include <termios.h>
48
49 #include "xmalloc.h"
50 #include "packet.h"
51 #include "buffer.h"
52 #include "log.h"
53 #include "servconf.h"
54 #include "canohost.h"
55 #include "sshpty.h"
56 #include "channels.h"
57 #include "compat.h"
58 #include "ssh1.h"
59 #include "ssh2.h"
60 #include "auth.h"
61 #include "session.h"
62 #include "dispatch.h"
63 #include "auth-options.h"
64 #include "serverloop.h"
65 #include "misc.h"
66 #include "kex.h"
67
68 extern ServerOptions options;
69
70 /* XXX */
71 extern Kex *xxx_kex;
72 extern Authctxt *the_authctxt;
73 extern int use_privsep;
74
75 static Buffer stdin_buffer;     /* Buffer for stdin data. */
76 static Buffer stdout_buffer;    /* Buffer for stdout data. */
77 static Buffer stderr_buffer;    /* Buffer for stderr data. */
78 static int fdin;                /* Descriptor for stdin (for writing) */
79 static int fdout;               /* Descriptor for stdout (for reading);
80                                    May be same number as fdin. */
81 static int fderr;               /* Descriptor for stderr.  May be -1. */
82 static long stdin_bytes = 0;    /* Number of bytes written to stdin. */
83 static long stdout_bytes = 0;   /* Number of stdout bytes sent to client. */
84 static long stderr_bytes = 0;   /* Number of stderr bytes sent to client. */
85 static long fdout_bytes = 0;    /* Number of stdout bytes read from program. */
86 static int stdin_eof = 0;       /* EOF message received from client. */
87 static int fdout_eof = 0;       /* EOF encountered reading from fdout. */
88 static int fderr_eof = 0;       /* EOF encountered readung from fderr. */
89 static int fdin_is_tty = 0;     /* fdin points to a tty. */
90 static int connection_in;       /* Connection to client (input). */
91 static int connection_out;      /* Connection to client (output). */
92 static int connection_closed = 0;       /* Connection to client closed. */
93 static u_int buffer_high;       /* "Soft" max buffer size. */
94 static int client_alive_timeouts = 0;
95
96 /*
97  * This SIGCHLD kludge is used to detect when the child exits.  The server
98  * will exit after that, as soon as forwarded connections have terminated.
99  */
100
101 static volatile sig_atomic_t child_terminated = 0;      /* The child has terminated. */
102
103 /* Cleanup on signals (!use_privsep case only) */
104 static volatile sig_atomic_t received_sigterm = 0;
105
106 /* prototypes */
107 static void server_init_dispatch(void);
108
109 /*
110  * we write to this pipe if a SIGCHLD is caught in order to avoid
111  * the race between select() and child_terminated
112  */
113 static int notify_pipe[2];
114 static void
115 notify_setup(void)
116 {
117         if (pipe(notify_pipe) < 0) {
118                 error("pipe(notify_pipe) failed %s", strerror(errno));
119         } else if ((fcntl(notify_pipe[0], F_SETFD, 1) == -1) ||
120             (fcntl(notify_pipe[1], F_SETFD, 1) == -1)) {
121                 error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
122                 close(notify_pipe[0]);
123                 close(notify_pipe[1]);
124         } else {
125                 set_nonblock(notify_pipe[0]);
126                 set_nonblock(notify_pipe[1]);
127                 return;
128         }
129         notify_pipe[0] = -1;    /* read end */
130         notify_pipe[1] = -1;    /* write end */
131 }
132 static void
133 notify_parent(void)
134 {
135         if (notify_pipe[1] != -1)
136                 write(notify_pipe[1], "", 1);
137 }
138 static void
139 notify_prepare(fd_set *readset)
140 {
141         if (notify_pipe[0] != -1)
142                 FD_SET(notify_pipe[0], readset);
143 }
144 static void
145 notify_done(fd_set *readset)
146 {
147         char c;
148
149         if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
150                 while (read(notify_pipe[0], &c, 1) != -1)
151                         debug2("notify_done: reading");
152 }
153
154 /*ARGSUSED*/
155 static void
156 sigchld_handler(int sig)
157 {
158         int save_errno = errno;
159         child_terminated = 1;
160 #ifndef _UNICOS
161         mysignal(SIGCHLD, sigchld_handler);
162 #endif
163         notify_parent();
164         errno = save_errno;
165 }
166
167 /*ARGSUSED*/
168 static void
169 sigterm_handler(int sig)
170 {
171         received_sigterm = sig;
172 }
173
174 /*
175  * Make packets from buffered stderr data, and buffer it for sending
176  * to the client.
177  */
178 static void
179 make_packets_from_stderr_data(void)
180 {
181         u_int len;
182
183         /* Send buffered stderr data to the client. */
184         while (buffer_len(&stderr_buffer) > 0 &&
185             packet_not_very_much_data_to_write()) {
186                 len = buffer_len(&stderr_buffer);
187                 if (packet_is_interactive()) {
188                         if (len > 512)
189                                 len = 512;
190                 } else {
191                         /* Keep the packets at reasonable size. */
192                         if (len > packet_get_maxsize())
193                                 len = packet_get_maxsize();
194                 }
195                 packet_start(SSH_SMSG_STDERR_DATA);
196                 packet_put_string(buffer_ptr(&stderr_buffer), len);
197                 packet_send();
198                 buffer_consume(&stderr_buffer, len);
199                 stderr_bytes += len;
200         }
201 }
202
203 /*
204  * Make packets from buffered stdout data, and buffer it for sending to the
205  * client.
206  */
207 static void
208 make_packets_from_stdout_data(void)
209 {
210         u_int len;
211
212         /* Send buffered stdout data to the client. */
213         while (buffer_len(&stdout_buffer) > 0 &&
214             packet_not_very_much_data_to_write()) {
215                 len = buffer_len(&stdout_buffer);
216                 if (packet_is_interactive()) {
217                         if (len > 512)
218                                 len = 512;
219                 } else {
220                         /* Keep the packets at reasonable size. */
221                         if (len > packet_get_maxsize())
222                                 len = packet_get_maxsize();
223                 }
224                 packet_start(SSH_SMSG_STDOUT_DATA);
225                 packet_put_string(buffer_ptr(&stdout_buffer), len);
226                 packet_send();
227                 buffer_consume(&stdout_buffer, len);
228                 stdout_bytes += len;
229         }
230 }
231
232 static void
233 client_alive_check(void)
234 {
235         int channel_id;
236
237         /* timeout, check to see how many we have had */
238         if (++client_alive_timeouts > options.client_alive_count_max)
239                 packet_disconnect("Timeout, your session not responding.");
240
241         /*
242          * send a bogus global/channel request with "wantreply",
243          * we should get back a failure
244          */
245         if ((channel_id = channel_find_open()) == -1) {
246                 packet_start(SSH2_MSG_GLOBAL_REQUEST);
247                 packet_put_cstring("keepalive@openssh.com");
248                 packet_put_char(1);     /* boolean: want reply */
249         } else {
250                 channel_request_start(channel_id, "keepalive@openssh.com", 1);
251         }
252         packet_send();
253 }
254
255 /*
256  * Sleep in select() until we can do something.  This will initialize the
257  * select masks.  Upon return, the masks will indicate which descriptors
258  * have data or can accept data.  Optionally, a maximum time can be specified
259  * for the duration of the wait (0 = infinite).
260  */
261 static void
262 wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
263     u_int *nallocp, u_int max_time_milliseconds)
264 {
265         struct timeval tv, *tvp;
266         int ret;
267         int client_alive_scheduled = 0;
268
269         /*
270          * if using client_alive, set the max timeout accordingly,
271          * and indicate that this particular timeout was for client
272          * alive by setting the client_alive_scheduled flag.
273          *
274          * this could be randomized somewhat to make traffic
275          * analysis more difficult, but we're not doing it yet.
276          */
277         if (compat20 &&
278             max_time_milliseconds == 0 && options.client_alive_interval) {
279                 client_alive_scheduled = 1;
280                 max_time_milliseconds = options.client_alive_interval * 1000;
281         }
282
283         /* Allocate and update select() masks for channel descriptors. */
284         channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0);
285
286         if (compat20) {
287 #if 0
288                 /* wrong: bad condition XXX */
289                 if (channel_not_very_much_buffered_data())
290 #endif
291                 FD_SET(connection_in, *readsetp);
292         } else {
293                 /*
294                  * Read packets from the client unless we have too much
295                  * buffered stdin or channel data.
296                  */
297                 if (buffer_len(&stdin_buffer) < buffer_high &&
298                     channel_not_very_much_buffered_data())
299                         FD_SET(connection_in, *readsetp);
300                 /*
301                  * If there is not too much data already buffered going to
302                  * the client, try to get some more data from the program.
303                  */
304                 if (packet_not_very_much_data_to_write()) {
305                         if (!fdout_eof)
306                                 FD_SET(fdout, *readsetp);
307                         if (!fderr_eof)
308                                 FD_SET(fderr, *readsetp);
309                 }
310                 /*
311                  * If we have buffered data, try to write some of that data
312                  * to the program.
313                  */
314                 if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
315                         FD_SET(fdin, *writesetp);
316         }
317         notify_prepare(*readsetp);
318
319         /*
320          * If we have buffered packet data going to the client, mark that
321          * descriptor.
322          */
323         if (packet_have_data_to_write())
324                 FD_SET(connection_out, *writesetp);
325
326         /*
327          * If child has terminated and there is enough buffer space to read
328          * from it, then read as much as is available and exit.
329          */
330         if (child_terminated && packet_not_very_much_data_to_write())
331                 if (max_time_milliseconds == 0 || client_alive_scheduled)
332                         max_time_milliseconds = 100;
333
334         if (max_time_milliseconds == 0)
335                 tvp = NULL;
336         else {
337                 tv.tv_sec = max_time_milliseconds / 1000;
338                 tv.tv_usec = 1000 * (max_time_milliseconds % 1000);
339                 tvp = &tv;
340         }
341
342         /* Wait for something to happen, or the timeout to expire. */
343         ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
344
345         if (ret == -1) {
346                 memset(*readsetp, 0, *nallocp);
347                 memset(*writesetp, 0, *nallocp);
348                 if (errno != EINTR)
349                         error("select: %.100s", strerror(errno));
350         } else if (ret == 0 && client_alive_scheduled)
351                 client_alive_check();
352
353         notify_done(*readsetp);
354 }
355
356 /*
357  * Processes input from the client and the program.  Input data is stored
358  * in buffers and processed later.
359  */
360 static void
361 process_input(fd_set *readset)
362 {
363         int len;
364         char buf[16384];
365
366         /* Read and buffer any input data from the client. */
367         if (FD_ISSET(connection_in, readset)) {
368                 len = read(connection_in, buf, sizeof(buf));
369                 if (len == 0) {
370                         verbose("Connection closed by %.100s",
371                             get_remote_ipaddr());
372                         connection_closed = 1;
373                         if (compat20)
374                                 return;
375                         cleanup_exit(255);
376                 } else if (len < 0) {
377                         if (errno != EINTR && errno != EAGAIN) {
378                                 verbose("Read error from remote host "
379                                     "%.100s: %.100s",
380                                     get_remote_ipaddr(), strerror(errno));
381                                 cleanup_exit(255);
382                         }
383                 } else {
384                         /* Buffer any received data. */
385                         packet_process_incoming(buf, len);
386                 }
387         }
388         if (compat20)
389                 return;
390
391         /* Read and buffer any available stdout data from the program. */
392         if (!fdout_eof && FD_ISSET(fdout, readset)) {
393                 errno = 0;
394                 len = read(fdout, buf, sizeof(buf));
395                 if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
396                         /* do nothing */
397 #ifndef PTY_ZEROREAD
398                 } else if (len <= 0) {
399 #else
400                 } else if ((!isatty(fdout) && len <= 0) ||
401                     (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
402 #endif
403                         fdout_eof = 1;
404                 } else {
405                         buffer_append(&stdout_buffer, buf, len);
406                         fdout_bytes += len;
407                 }
408         }
409         /* Read and buffer any available stderr data from the program. */
410         if (!fderr_eof && FD_ISSET(fderr, readset)) {
411                 errno = 0;
412                 len = read(fderr, buf, sizeof(buf));
413                 if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
414                         /* do nothing */
415 #ifndef PTY_ZEROREAD
416                 } else if (len <= 0) {
417 #else
418                 } else if ((!isatty(fderr) && len <= 0) ||
419                     (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
420 #endif
421                         fderr_eof = 1;
422                 } else {
423                         buffer_append(&stderr_buffer, buf, len);
424                 }
425         }
426 }
427
428 /*
429  * Sends data from internal buffers to client program stdin.
430  */
431 static void
432 process_output(fd_set *writeset)
433 {
434         struct termios tio;
435         u_char *data;
436         u_int dlen;
437         int len;
438
439         /* Write buffered data to program stdin. */
440         if (!compat20 && fdin != -1 && FD_ISSET(fdin, writeset)) {
441                 data = buffer_ptr(&stdin_buffer);
442                 dlen = buffer_len(&stdin_buffer);
443                 len = write(fdin, data, dlen);
444                 if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
445                         /* do nothing */
446                 } else if (len <= 0) {
447                         if (fdin != fdout)
448                                 close(fdin);
449                         else
450                                 shutdown(fdin, SHUT_WR); /* We will no longer send. */
451                         fdin = -1;
452                 } else {
453                         /* Successful write. */
454                         if (fdin_is_tty && dlen >= 1 && data[0] != '\r' &&
455                             tcgetattr(fdin, &tio) == 0 &&
456                             !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
457                                 /*
458                                  * Simulate echo to reduce the impact of
459                                  * traffic analysis
460                                  */
461                                 packet_send_ignore(len);
462                                 packet_send();
463                         }
464                         /* Consume the data from the buffer. */
465                         buffer_consume(&stdin_buffer, len);
466                         /* Update the count of bytes written to the program. */
467                         stdin_bytes += len;
468                 }
469         }
470         /* Send any buffered packet data to the client. */
471         if (FD_ISSET(connection_out, writeset))
472                 packet_write_poll();
473 }
474
475 /*
476  * Wait until all buffered output has been sent to the client.
477  * This is used when the program terminates.
478  */
479 static void
480 drain_output(void)
481 {
482         /* Send any buffered stdout data to the client. */
483         if (buffer_len(&stdout_buffer) > 0) {
484                 packet_start(SSH_SMSG_STDOUT_DATA);
485                 packet_put_string(buffer_ptr(&stdout_buffer),
486                                   buffer_len(&stdout_buffer));
487                 packet_send();
488                 /* Update the count of sent bytes. */
489                 stdout_bytes += buffer_len(&stdout_buffer);
490         }
491         /* Send any buffered stderr data to the client. */
492         if (buffer_len(&stderr_buffer) > 0) {
493                 packet_start(SSH_SMSG_STDERR_DATA);
494                 packet_put_string(buffer_ptr(&stderr_buffer),
495                                   buffer_len(&stderr_buffer));
496                 packet_send();
497                 /* Update the count of sent bytes. */
498                 stderr_bytes += buffer_len(&stderr_buffer);
499         }
500         /* Wait until all buffered data has been written to the client. */
501         packet_write_wait();
502 }
503
504 static void
505 process_buffered_input_packets(void)
506 {
507         dispatch_run(DISPATCH_NONBLOCK, NULL, compat20 ? xxx_kex : NULL);
508 }
509
510 /*
511  * Performs the interactive session.  This handles data transmission between
512  * the client and the program.  Note that the notion of stdin, stdout, and
513  * stderr in this function is sort of reversed: this function writes to
514  * stdin (of the child program), and reads from stdout and stderr (of the
515  * child program).
516  */
517 void
518 server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
519 {
520         fd_set *readset = NULL, *writeset = NULL;
521         int max_fd = 0;
522         u_int nalloc = 0;
523         int wait_status;        /* Status returned by wait(). */
524         pid_t wait_pid;         /* pid returned by wait(). */
525         int waiting_termination = 0;    /* Have displayed waiting close message. */
526         u_int max_time_milliseconds;
527         u_int previous_stdout_buffer_bytes;
528         u_int stdout_buffer_bytes;
529         int type;
530
531         debug("Entering interactive session.");
532
533         /* Initialize the SIGCHLD kludge. */
534         child_terminated = 0;
535         mysignal(SIGCHLD, sigchld_handler);
536
537         if (!use_privsep) {
538                 signal(SIGTERM, sigterm_handler);
539                 signal(SIGINT, sigterm_handler);
540                 signal(SIGQUIT, sigterm_handler);
541         }
542
543         /* Initialize our global variables. */
544         fdin = fdin_arg;
545         fdout = fdout_arg;
546         fderr = fderr_arg;
547
548         /* nonblocking IO */
549         set_nonblock(fdin);
550         set_nonblock(fdout);
551         /* we don't have stderr for interactive terminal sessions, see below */
552         if (fderr != -1)
553                 set_nonblock(fderr);
554
555         if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
556                 fdin_is_tty = 1;
557
558         connection_in = packet_get_connection_in();
559         connection_out = packet_get_connection_out();
560
561         notify_setup();
562
563         previous_stdout_buffer_bytes = 0;
564
565         /* Set approximate I/O buffer size. */
566         if (packet_is_interactive())
567                 buffer_high = 4096;
568         else
569                 buffer_high = 64 * 1024;
570
571 #if 0
572         /* Initialize max_fd to the maximum of the known file descriptors. */
573         max_fd = MAX(connection_in, connection_out);
574         max_fd = MAX(max_fd, fdin);
575         max_fd = MAX(max_fd, fdout);
576         if (fderr != -1)
577                 max_fd = MAX(max_fd, fderr);
578 #endif
579
580         /* Initialize Initialize buffers. */
581         buffer_init(&stdin_buffer);
582         buffer_init(&stdout_buffer);
583         buffer_init(&stderr_buffer);
584
585         /*
586          * If we have no separate fderr (which is the case when we have a pty
587          * - there we cannot make difference between data sent to stdout and
588          * stderr), indicate that we have seen an EOF from stderr.  This way
589          * we don't need to check the descriptor everywhere.
590          */
591         if (fderr == -1)
592                 fderr_eof = 1;
593
594         server_init_dispatch();
595
596         /* Main loop of the server for the interactive session mode. */
597         for (;;) {
598
599                 /* Process buffered packets from the client. */
600                 process_buffered_input_packets();
601
602                 /*
603                  * If we have received eof, and there is no more pending
604                  * input data, cause a real eof by closing fdin.
605                  */
606                 if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
607                         if (fdin != fdout)
608                                 close(fdin);
609                         else
610                                 shutdown(fdin, SHUT_WR); /* We will no longer send. */
611                         fdin = -1;
612                 }
613                 /* Make packets from buffered stderr data to send to the client. */
614                 make_packets_from_stderr_data();
615
616                 /*
617                  * Make packets from buffered stdout data to send to the
618                  * client. If there is very little to send, this arranges to
619                  * not send them now, but to wait a short while to see if we
620                  * are getting more data. This is necessary, as some systems
621                  * wake up readers from a pty after each separate character.
622                  */
623                 max_time_milliseconds = 0;
624                 stdout_buffer_bytes = buffer_len(&stdout_buffer);
625                 if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
626                     stdout_buffer_bytes != previous_stdout_buffer_bytes) {
627                         /* try again after a while */
628                         max_time_milliseconds = 10;
629                 } else {
630                         /* Send it now. */
631                         make_packets_from_stdout_data();
632                 }
633                 previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);
634
635                 /* Send channel data to the client. */
636                 if (packet_not_very_much_data_to_write())
637                         channel_output_poll();
638
639                 /*
640                  * Bail out of the loop if the program has closed its output
641                  * descriptors, and we have no more data to send to the
642                  * client, and there is no pending buffered data.
643                  */
644                 if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
645                     buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
646                         if (!channel_still_open())
647                                 break;
648                         if (!waiting_termination) {
649                                 const char *s = "Waiting for forwarded connections to terminate...\r\n";
650                                 char *cp;
651                                 waiting_termination = 1;
652                                 buffer_append(&stderr_buffer, s, strlen(s));
653
654                                 /* Display list of open channels. */
655                                 cp = channel_open_message();
656                                 buffer_append(&stderr_buffer, cp, strlen(cp));
657                                 xfree(cp);
658                         }
659                 }
660                 max_fd = MAX(connection_in, connection_out);
661                 max_fd = MAX(max_fd, fdin);
662                 max_fd = MAX(max_fd, fdout);
663                 max_fd = MAX(max_fd, fderr);
664                 max_fd = MAX(max_fd, notify_pipe[0]);
665
666                 /* Sleep in select() until we can do something. */
667                 wait_until_can_do_something(&readset, &writeset, &max_fd,
668                     &nalloc, max_time_milliseconds);
669
670                 if (received_sigterm) {
671                         logit("Exiting on signal %d", received_sigterm);
672                         /* Clean up sessions, utmp, etc. */
673                         cleanup_exit(255);
674                 }
675
676                 /* Process any channel events. */
677                 channel_after_select(readset, writeset);
678
679                 /* Process input from the client and from program stdout/stderr. */
680                 process_input(readset);
681
682                 /* Process output to the client and to program stdin. */
683                 process_output(writeset);
684         }
685         if (readset)
686                 xfree(readset);
687         if (writeset)
688                 xfree(writeset);
689
690         /* Cleanup and termination code. */
691
692         /* Wait until all output has been sent to the client. */
693         drain_output();
694
695         debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
696             stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
697
698         /* Free and clear the buffers. */
699         buffer_free(&stdin_buffer);
700         buffer_free(&stdout_buffer);
701         buffer_free(&stderr_buffer);
702
703         /* Close the file descriptors. */
704         if (fdout != -1)
705                 close(fdout);
706         fdout = -1;
707         fdout_eof = 1;
708         if (fderr != -1)
709                 close(fderr);
710         fderr = -1;
711         fderr_eof = 1;
712         if (fdin != -1)
713                 close(fdin);
714         fdin = -1;
715
716         channel_free_all();
717
718         /* We no longer want our SIGCHLD handler to be called. */
719         mysignal(SIGCHLD, SIG_DFL);
720
721         while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
722                 if (errno != EINTR)
723                         packet_disconnect("wait: %.100s", strerror(errno));
724         if (wait_pid != pid)
725                 error("Strange, wait returned pid %ld, expected %ld",
726                     (long)wait_pid, (long)pid);
727
728         /* Check if it exited normally. */
729         if (WIFEXITED(wait_status)) {
730                 /* Yes, normal exit.  Get exit status and send it to the client. */
731                 debug("Command exited with status %d.", WEXITSTATUS(wait_status));
732                 packet_start(SSH_SMSG_EXITSTATUS);
733                 packet_put_int(WEXITSTATUS(wait_status));
734                 packet_send();
735                 packet_write_wait();
736
737                 /*
738                  * Wait for exit confirmation.  Note that there might be
739                  * other packets coming before it; however, the program has
740                  * already died so we just ignore them.  The client is
741                  * supposed to respond with the confirmation when it receives
742                  * the exit status.
743                  */
744                 do {
745                         type = packet_read();
746                 }
747                 while (type != SSH_CMSG_EXIT_CONFIRMATION);
748
749                 debug("Received exit confirmation.");
750                 return;
751         }
752         /* Check if the program terminated due to a signal. */
753         if (WIFSIGNALED(wait_status))
754                 packet_disconnect("Command terminated on signal %d.",
755                                   WTERMSIG(wait_status));
756
757         /* Some weird exit cause.  Just exit. */
758         packet_disconnect("wait returned status %04x.", wait_status);
759         /* NOTREACHED */
760 }
761
762 static void
763 collect_children(void)
764 {
765         pid_t pid;
766         sigset_t oset, nset;
767         int status;
768
769         /* block SIGCHLD while we check for dead children */
770         sigemptyset(&nset);
771         sigaddset(&nset, SIGCHLD);
772         sigprocmask(SIG_BLOCK, &nset, &oset);
773         if (child_terminated) {
774                 debug("Received SIGCHLD.");
775                 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
776                     (pid < 0 && errno == EINTR))
777                         if (pid > 0)
778                                 session_close_by_pid(pid, status);
779                 child_terminated = 0;
780         }
781         sigprocmask(SIG_SETMASK, &oset, NULL);
782 }
783
784 void
785 server_loop2(Authctxt *authctxt)
786 {
787         fd_set *readset = NULL, *writeset = NULL;
788         int rekeying = 0, max_fd, nalloc = 0;
789
790         debug("Entering interactive session for SSH2.");
791
792         mysignal(SIGCHLD, sigchld_handler);
793         child_terminated = 0;
794         connection_in = packet_get_connection_in();
795         connection_out = packet_get_connection_out();
796
797         if (!use_privsep) {
798                 signal(SIGTERM, sigterm_handler);
799                 signal(SIGINT, sigterm_handler);
800                 signal(SIGQUIT, sigterm_handler);
801         }
802
803         notify_setup();
804
805         max_fd = MAX(connection_in, connection_out);
806         max_fd = MAX(max_fd, notify_pipe[0]);
807
808         server_init_dispatch();
809
810         for (;;) {
811                 process_buffered_input_packets();
812
813                 rekeying = (xxx_kex != NULL && !xxx_kex->done);
814
815                 if (!rekeying && packet_not_very_much_data_to_write())
816                         channel_output_poll();
817                 wait_until_can_do_something(&readset, &writeset, &max_fd,
818                     &nalloc, 0);
819
820                 if (received_sigterm) {
821                         logit("Exiting on signal %d", received_sigterm);
822                         /* Clean up sessions, utmp, etc. */
823                         cleanup_exit(255);
824                 }
825
826                 collect_children();
827                 if (!rekeying) {
828                         channel_after_select(readset, writeset);
829                         if (packet_need_rekeying()) {
830                                 debug("need rekeying");
831                                 xxx_kex->done = 0;
832                                 kex_send_kexinit(xxx_kex);
833                         }
834                 }
835                 process_input(readset);
836                 if (connection_closed)
837                         break;
838                 process_output(writeset);
839         }
840         collect_children();
841
842         if (readset)
843                 xfree(readset);
844         if (writeset)
845                 xfree(writeset);
846
847         /* free all channels, no more reads and writes */
848         channel_free_all();
849
850         /* free remaining sessions, e.g. remove wtmp entries */
851         session_destroy_all(NULL);
852 }
853
854 static void
855 server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
856 {
857         debug("Got %d/%u for keepalive", type, seq);
858         /*
859          * reset timeout, since we got a sane answer from the client.
860          * even if this was generated by something other than
861          * the bogus CHANNEL_REQUEST we send for keepalives.
862          */
863         client_alive_timeouts = 0;
864 }
865
866 static void
867 server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
868 {
869         char *data;
870         u_int data_len;
871
872         /* Stdin data from the client.  Append it to the buffer. */
873         /* Ignore any data if the client has closed stdin. */
874         if (fdin == -1)
875                 return;
876         data = packet_get_string(&data_len);
877         packet_check_eom();
878         buffer_append(&stdin_buffer, data, data_len);
879         memset(data, 0, data_len);
880         xfree(data);
881 }
882
883 static void
884 server_input_eof(int type, u_int32_t seq, void *ctxt)
885 {
886         /*
887          * Eof from the client.  The stdin descriptor to the
888          * program will be closed when all buffered data has
889          * drained.
890          */
891         debug("EOF received for stdin.");
892         packet_check_eom();
893         stdin_eof = 1;
894 }
895
896 static void
897 server_input_window_size(int type, u_int32_t seq, void *ctxt)
898 {
899         u_int row = packet_get_int();
900         u_int col = packet_get_int();
901         u_int xpixel = packet_get_int();
902         u_int ypixel = packet_get_int();
903
904         debug("Window change received.");
905         packet_check_eom();
906         if (fdin != -1)
907                 pty_change_window_size(fdin, row, col, xpixel, ypixel);
908 }
909
910 static Channel *
911 server_request_direct_tcpip(void)
912 {
913         Channel *c;
914         int sock;
915         char *target, *originator;
916         int target_port, originator_port;
917
918         target = packet_get_string(NULL);
919         target_port = packet_get_int();
920         originator = packet_get_string(NULL);
921         originator_port = packet_get_int();
922         packet_check_eom();
923
924         debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
925             originator, originator_port, target, target_port);
926
927         /* XXX check permission */
928         sock = channel_connect_to(target, target_port);
929         xfree(target);
930         xfree(originator);
931         if (sock < 0)
932                 return NULL;
933         c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
934             sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
935             CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
936         return c;
937 }
938
939 static Channel *
940 server_request_tun(void)
941 {
942         Channel *c = NULL;
943         int mode, tun;
944         int sock;
945
946         mode = packet_get_int();
947         switch (mode) {
948         case SSH_TUNMODE_POINTOPOINT:
949         case SSH_TUNMODE_ETHERNET:
950                 break;
951         default:
952                 packet_send_debug("Unsupported tunnel device mode.");
953                 return NULL;
954         }
955         if ((options.permit_tun & mode) == 0) {
956                 packet_send_debug("Server has rejected tunnel device "
957                     "forwarding");
958                 return NULL;
959         }
960
961         tun = packet_get_int();
962         if (forced_tun_device != -1) {
963                 if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
964                         goto done;
965                 tun = forced_tun_device;
966         }
967         sock = tun_open(tun, mode);
968         if (sock < 0)
969                 goto done;
970         c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
971             CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
972         c->datagram = 1;
973 #if defined(SSH_TUN_FILTER)
974         if (mode == SSH_TUNMODE_POINTOPOINT)
975                 channel_register_filter(c->self, sys_tun_infilter,
976                     sys_tun_outfilter);
977 #endif
978
979  done:
980         if (c == NULL)
981                 packet_send_debug("Failed to open the tunnel device.");
982         return c;
983 }
984
985 static Channel *
986 server_request_session(void)
987 {
988         Channel *c;
989
990         debug("input_session_request");
991         packet_check_eom();
992         /*
993          * A server session has no fd to read or write until a
994          * CHANNEL_REQUEST for a shell is made, so we set the type to
995          * SSH_CHANNEL_LARVAL.  Additionally, a callback for handling all
996          * CHANNEL_REQUEST messages is registered.
997          */
998         c = channel_new("session", SSH_CHANNEL_LARVAL,
999             -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
1000             0, "server-session", 1);
1001         if (session_open(the_authctxt, c->self) != 1) {
1002                 debug("session open failed, free channel %d", c->self);
1003                 channel_free(c);
1004                 return NULL;
1005         }
1006         channel_register_cleanup(c->self, session_close_by_channel, 0);
1007         return c;
1008 }
1009
1010 static void
1011 server_input_channel_open(int type, u_int32_t seq, void *ctxt)
1012 {
1013         Channel *c = NULL;
1014         char *ctype;
1015         int rchan;
1016         u_int rmaxpack, rwindow, len;
1017
1018         ctype = packet_get_string(&len);
1019         rchan = packet_get_int();
1020         rwindow = packet_get_int();
1021         rmaxpack = packet_get_int();
1022
1023         debug("server_input_channel_open: ctype %s rchan %d win %d max %d",
1024             ctype, rchan, rwindow, rmaxpack);
1025
1026         if (strcmp(ctype, "session") == 0) {
1027                 c = server_request_session();
1028         } else if (strcmp(ctype, "direct-tcpip") == 0) {
1029                 c = server_request_direct_tcpip();
1030         } else if (strcmp(ctype, "tun@openssh.com") == 0) {
1031                 c = server_request_tun();
1032         }
1033         if (c != NULL) {
1034                 debug("server_input_channel_open: confirm %s", ctype);
1035                 c->remote_id = rchan;
1036                 c->remote_window = rwindow;
1037                 c->remote_maxpacket = rmaxpack;
1038                 if (c->type != SSH_CHANNEL_CONNECTING) {
1039                         packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1040                         packet_put_int(c->remote_id);
1041                         packet_put_int(c->self);
1042                         packet_put_int(c->local_window);
1043                         packet_put_int(c->local_maxpacket);
1044                         packet_send();
1045                 }
1046         } else {
1047                 debug("server_input_channel_open: failure %s", ctype);
1048                 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1049                 packet_put_int(rchan);
1050                 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
1051                 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1052                         packet_put_cstring("open failed");
1053                         packet_put_cstring("");
1054                 }
1055                 packet_send();
1056         }
1057         xfree(ctype);
1058 }
1059
1060 static void
1061 server_input_global_request(int type, u_int32_t seq, void *ctxt)
1062 {
1063         char *rtype;
1064         int want_reply;
1065         int success = 0;
1066
1067         rtype = packet_get_string(NULL);
1068         want_reply = packet_get_char();
1069         debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
1070
1071         /* -R style forwarding */
1072         if (strcmp(rtype, "tcpip-forward") == 0) {
1073                 struct passwd *pw;
1074                 char *listen_address;
1075                 u_short listen_port;
1076
1077                 pw = the_authctxt->pw;
1078                 if (pw == NULL || !the_authctxt->valid)
1079                         fatal("server_input_global_request: no/invalid user");
1080                 listen_address = packet_get_string(NULL);
1081                 listen_port = (u_short)packet_get_int();
1082                 debug("server_input_global_request: tcpip-forward listen %s port %d",
1083                     listen_address, listen_port);
1084
1085                 /* check permissions */
1086                 if (!options.allow_tcp_forwarding ||
1087                     no_port_forwarding_flag
1088 #ifndef NO_IPPORT_RESERVED_CONCEPT
1089                     || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
1090 #endif
1091                     ) {
1092                         success = 0;
1093                         packet_send_debug("Server has disabled port forwarding.");
1094                 } else {
1095                         /* Start listening on the port */
1096                         success = channel_setup_remote_fwd_listener(
1097                             listen_address, listen_port, options.gateway_ports);
1098                 }
1099                 xfree(listen_address);
1100         } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
1101                 char *cancel_address;
1102                 u_short cancel_port;
1103
1104                 cancel_address = packet_get_string(NULL);
1105                 cancel_port = (u_short)packet_get_int();
1106                 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
1107                     cancel_address, cancel_port);
1108
1109                 success = channel_cancel_rport_listener(cancel_address,
1110                     cancel_port);
1111                 xfree(cancel_address);
1112         }
1113         if (want_reply) {
1114                 packet_start(success ?
1115                     SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
1116                 packet_send();
1117                 packet_write_wait();
1118         }
1119         xfree(rtype);
1120 }
1121
1122 static void
1123 server_input_channel_req(int type, u_int32_t seq, void *ctxt)
1124 {
1125         Channel *c;
1126         int id, reply, success = 0;
1127         char *rtype;
1128
1129         id = packet_get_int();
1130         rtype = packet_get_string(NULL);
1131         reply = packet_get_char();
1132
1133         debug("server_input_channel_req: channel %d request %s reply %d",
1134             id, rtype, reply);
1135
1136         if ((c = channel_lookup(id)) == NULL)
1137                 packet_disconnect("server_input_channel_req: "
1138                     "unknown channel %d", id);
1139         if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN)
1140                 success = session_input_channel_req(c, rtype);
1141         if (reply) {
1142                 packet_start(success ?
1143                     SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1144                 packet_put_int(c->remote_id);
1145                 packet_send();
1146         }
1147         xfree(rtype);
1148 }
1149
1150 static void
1151 server_init_dispatch_20(void)
1152 {
1153         debug("server_init_dispatch_20");
1154         dispatch_init(&dispatch_protocol_error);
1155         dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
1156         dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
1157         dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
1158         dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
1159         dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
1160         dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1161         dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1162         dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
1163         dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1164         dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
1165         /* client_alive */
1166         dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
1167         dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
1168         dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
1169         /* rekeying */
1170         dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
1171 }
1172 static void
1173 server_init_dispatch_13(void)
1174 {
1175         debug("server_init_dispatch_13");
1176         dispatch_init(NULL);
1177         dispatch_set(SSH_CMSG_EOF, &server_input_eof);
1178         dispatch_set(SSH_CMSG_STDIN_DATA, &server_input_stdin_data);
1179         dispatch_set(SSH_CMSG_WINDOW_SIZE, &server_input_window_size);
1180         dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
1181         dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
1182         dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
1183         dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
1184         dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
1185         dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
1186 }
1187 static void
1188 server_init_dispatch_15(void)
1189 {
1190         server_init_dispatch_13();
1191         debug("server_init_dispatch_15");
1192         dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
1193         dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_oclose);
1194 }
1195 static void
1196 server_init_dispatch(void)
1197 {
1198         if (compat20)
1199                 server_init_dispatch_20();
1200         else if (compat13)
1201                 server_init_dispatch_13();
1202         else
1203                 server_init_dispatch_15();
1204 }
This page took 0.124241 seconds and 5 git commands to generate.