~ubuntu-branches/ubuntu/lucid/openssh/lucid

« back to all changes in this revision

Viewing changes to serverloop.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2008-09-30 23:09:58 UTC
  • mfrom: (1.13.3 upstream) (29 hardy)
  • mto: This revision was merged to the branch mainline in revision 43.
  • Revision ID: james.westby@ubuntu.com-20080930230958-o6vsgn8c4mm959s0
Tags: 1:5.1p1-3
* Remove unnecessary ssh-vulnkey output in non-verbose mode when no
  compromised or unknown keys were found (closes: #496495).
* Configure with --disable-strip; dh_strip will deal with stripping
  binaries and will honour DEB_BUILD_OPTIONS (thanks, Bernhard R. Link;
  closes: #498681).
* Fix handling of zero-length server banners (thanks, Tomas Mraz; closes:
  #497026).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */
 
1
/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 djm Exp $ */
2
2
/*
3
3
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4
4
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
56
56
#include <unistd.h>
57
57
#include <stdarg.h>
58
58
 
 
59
#include "openbsd-compat/sys-queue.h"
59
60
#include "xmalloc.h"
60
61
#include "packet.h"
61
62
#include "buffer.h"
104
105
static int connection_out;      /* Connection to client (output). */
105
106
static int connection_closed = 0;       /* Connection to client closed. */
106
107
static u_int buffer_high;       /* "Soft" max buffer size. */
107
 
static int client_alive_timeouts = 0;
 
108
static int no_more_sessions = 0; /* Disallow further sessions. */
108
109
 
109
110
/*
110
111
 * This SIGCHLD kludge is used to detect when the child exits.  The server
248
249
        int channel_id;
249
250
 
250
251
        /* timeout, check to see how many we have had */
251
 
        if (++client_alive_timeouts > options.client_alive_count_max) {
 
252
        if (++keep_alive_timeouts > options.client_alive_count_max) {
252
253
                logit("Timeout, client not responding.");
253
254
                cleanup_exit(255);
254
255
        }
399
400
                                return;
400
401
                        cleanup_exit(255);
401
402
                } else if (len < 0) {
402
 
                        if (errno != EINTR && errno != EAGAIN) {
 
403
                        if (errno != EINTR && errno != EAGAIN &&
 
404
                            errno != EWOULDBLOCK) {
403
405
                                verbose("Read error from remote host "
404
406
                                    "%.100s: %.100s",
405
407
                                    get_remote_ipaddr(), strerror(errno));
417
419
        if (!fdout_eof && FD_ISSET(fdout, readset)) {
418
420
                errno = 0;
419
421
                len = read(fdout, buf, sizeof(buf));
420
 
                if (len < 0 && (errno == EINTR ||
421
 
                    (errno == EAGAIN && !child_terminated))) {
 
422
                if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
 
423
                    errno == EWOULDBLOCK) && !child_terminated))) {
422
424
                        /* do nothing */
423
425
#ifndef PTY_ZEROREAD
424
426
                } else if (len <= 0) {
436
438
        if (!fderr_eof && FD_ISSET(fderr, readset)) {
437
439
                errno = 0;
438
440
                len = read(fderr, buf, sizeof(buf));
439
 
                if (len < 0 && (errno == EINTR ||
440
 
                    (errno == EAGAIN && !child_terminated))) {
 
441
                if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
 
442
                    errno == EWOULDBLOCK) && !child_terminated))) {
441
443
                        /* do nothing */
442
444
#ifndef PTY_ZEROREAD
443
445
                } else if (len <= 0) {
468
470
                data = buffer_ptr(&stdin_buffer);
469
471
                dlen = buffer_len(&stdin_buffer);
470
472
                len = write(fdin, data, dlen);
471
 
                if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
 
473
                if (len < 0 &&
 
474
                    (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) {
472
475
                        /* do nothing */
473
476
                } else if (len <= 0) {
474
477
                        if (fdin != fdout)
887
890
         * even if this was generated by something other than
888
891
         * the bogus CHANNEL_REQUEST we send for keepalives.
889
892
         */
890
 
        client_alive_timeouts = 0;
 
893
        keep_alive_timeouts = 0;
891
894
}
892
895
 
893
896
static void
938
941
server_request_direct_tcpip(void)
939
942
{
940
943
        Channel *c;
941
 
        int sock;
942
944
        char *target, *originator;
943
945
        int target_port, originator_port;
944
946
 
948
950
        originator_port = packet_get_int();
949
951
        packet_check_eom();
950
952
 
951
 
        debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
952
 
            originator, originator_port, target, target_port);
 
953
        debug("server_request_direct_tcpip: originator %s port %d, target %s "
 
954
            "port %d", originator, originator_port, target, target_port);
953
955
 
954
956
        /* XXX check permission */
955
 
        sock = channel_connect_to(target, target_port);
 
957
        c = channel_connect_to(target, target_port,
 
958
            "direct-tcpip", "direct-tcpip");
 
959
 
 
960
        xfree(originator);
956
961
        xfree(target);
957
 
        xfree(originator);
958
 
        if (sock < 0)
959
 
                return NULL;
960
 
        c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
961
 
            sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
962
 
            CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
 
962
 
963
963
        return c;
964
964
}
965
965
 
1000
1000
#if defined(SSH_TUN_FILTER)
1001
1001
        if (mode == SSH_TUNMODE_POINTOPOINT)
1002
1002
                channel_register_filter(c->self, sys_tun_infilter,
1003
 
                    sys_tun_outfilter);
 
1003
                    sys_tun_outfilter, NULL, NULL);
1004
1004
#endif
1005
1005
 
1006
1006
 done:
1016
1016
 
1017
1017
        debug("input_session_request");
1018
1018
        packet_check_eom();
 
1019
 
 
1020
        if (no_more_sessions) {
 
1021
                packet_disconnect("Possible attack: attempt to open a session "
 
1022
                    "after additional sessions disabled");
 
1023
        }
 
1024
 
1019
1025
        /*
1020
1026
         * A server session has no fd to read or write until a
1021
1027
         * CHANNEL_REQUEST for a shell is made, so we set the type to
1136
1142
                success = channel_cancel_rport_listener(cancel_address,
1137
1143
                    cancel_port);
1138
1144
                xfree(cancel_address);
 
1145
        } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
 
1146
                no_more_sessions = 1;
 
1147
                success = 1;
1139
1148
        }
1140
1149
        if (want_reply) {
1141
1150
                packet_start(success ?
1163
1172
        if ((c = channel_lookup(id)) == NULL)
1164
1173
                packet_disconnect("server_input_channel_req: "
1165
1174
                    "unknown channel %d", id);
1166
 
        if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN)
 
1175
        if (!strcmp(rtype, "eow@openssh.com")) {
 
1176
                packet_check_eom();
 
1177
                chan_rcvd_eow(c);
 
1178
        } else if ((c->type == SSH_CHANNEL_LARVAL ||
 
1179
            c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
1167
1180
                success = session_input_channel_req(c, rtype);
1168
1181
        if (reply) {
1169
1182
                packet_start(success ?
1189
1202
        dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
1190
1203
        dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
1191
1204
        dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
 
1205
        dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
 
1206
        dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
1192
1207
        /* client_alive */
1193
 
        dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
1194
1208
        dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
1195
1209
        dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
1196
1210
        /* rekeying */