]> andersk Git - openssh.git/blobdiff - serverloop.c
- djm@cvs.openbsd.org 2008/01/19 22:37:19
[openssh.git] / serverloop.c
index e370f63a3ada40394a870ce9c8e8a6ef2f8f33c7..81888d0e5a17fc29f619d15d841355bd38060b5f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.135 2006/03/25 18:30:55 deraadt Exp $ */
+/* $OpenBSD: serverloop.c,v 1.146 2007/12/28 15:32:24 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include "includes.h"
 
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/wait.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
 
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
 #include <signal.h>
+#include <string.h>
 #include <termios.h>
+#include <unistd.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "packet.h"
 #include "compat.h"
 #include "ssh1.h"
 #include "ssh2.h"
+#include "key.h"
+#include "cipher.h"
+#include "kex.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "session.h"
 #include "dispatch.h"
 #include "auth-options.h"
 #include "serverloop.h"
 #include "misc.h"
-#include "kex.h"
 
 extern ServerOptions options;
 
@@ -232,8 +248,10 @@ client_alive_check(void)
        int channel_id;
 
        /* timeout, check to see how many we have had */
-       if (++client_alive_timeouts > options.client_alive_count_max)
-               packet_disconnect("Timeout, your session not responding.");
+       if (++client_alive_timeouts > options.client_alive_count_max) {
+               logit("Timeout, client not responding.");
+               cleanup_exit(255);
+       }
 
        /*
         * send a bogus global/channel request with "wantreply",
@@ -262,6 +280,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
        struct timeval tv, *tvp;
        int ret;
        int client_alive_scheduled = 0;
+       int program_alive_scheduled = 0;
 
        /*
         * if using client_alive, set the max timeout accordingly,
@@ -299,6 +318,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
                 * the client, try to get some more data from the program.
                 */
                if (packet_not_very_much_data_to_write()) {
+                       program_alive_scheduled = child_terminated;
                        if (!fdout_eof)
                                FD_SET(fdout, *readsetp);
                        if (!fderr_eof)
@@ -344,8 +364,16 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
                memset(*writesetp, 0, *nallocp);
                if (errno != EINTR)
                        error("select: %.100s", strerror(errno));
-       } else if (ret == 0 && client_alive_scheduled)
-               client_alive_check();
+       } else {
+               if (ret == 0 && client_alive_scheduled)
+                       client_alive_check();
+               if (!compat20 && program_alive_scheduled && fdin_is_tty) {
+                       if (!fdout_eof)
+                               FD_SET(fdout, *readsetp);
+                       if (!fderr_eof)
+                               FD_SET(fderr, *readsetp);
+               }
+       }
 
        notify_done(*readsetp);
 }
@@ -389,12 +417,14 @@ process_input(fd_set *readset)
        if (!fdout_eof && FD_ISSET(fdout, readset)) {
                errno = 0;
                len = read(fdout, buf, sizeof(buf));
-               if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
+               if (len < 0 && (errno == EINTR ||
+                   (errno == EAGAIN && !child_terminated))) {
                        /* do nothing */
 #ifndef PTY_ZEROREAD
                } else if (len <= 0) {
 #else
-               } else if (len < 0 || (len == 0 && errno != 0)) {
+               } else if ((!isatty(fdout) && len <= 0) ||
+                   (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
 #endif
                        fdout_eof = 1;
                } else {
@@ -406,12 +436,14 @@ process_input(fd_set *readset)
        if (!fderr_eof && FD_ISSET(fderr, readset)) {
                errno = 0;
                len = read(fderr, buf, sizeof(buf));
-               if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
+               if (len < 0 && (errno == EINTR ||
+                   (errno == EAGAIN && !child_terminated))) {
                        /* do nothing */
 #ifndef PTY_ZEROREAD
                } else if (len <= 0) {
 #else
-               } else if (len < 0 || (len == 0 && errno != 0)) {
+               } else if ((!isatty(fderr) && len <= 0) ||
+                   (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
 #endif
                        fderr_eof = 1;
                } else {
@@ -1161,6 +1193,8 @@ server_init_dispatch_20(void)
        dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
        dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
        dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
+       dispatch_set(SSH2_MSG_IGNORE, &server_input_keep_alive);
+       dispatch_set(SSH2_MSG_UNIMPLEMENTED, &server_input_keep_alive);
        /* rekeying */
        dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
 }
This page took 0.046026 seconds and 4 git commands to generate.