]> andersk Git - gssapi-openssh.git/blobdiff - openssh/channels.c
Import of OpenSSH 3.6.1p1
[gssapi-openssh.git] / openssh / channels.c
index d34411e18787d56ca764702680334a41a12c7201..1937b02446b5a9357b6f92532a888794893ffec2 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.175 2002/06/10 22:28:41 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -186,6 +186,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
        } else {
                c->isatty = 0;
        }
+       c->wfd_isatty = isatty(c->wfd);
 
        /* enable nonblocking mode */
        if (nonblock) {
@@ -205,7 +206,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
 
 Channel *
 channel_new(char *ctype, int type, int rfd, int wfd, int efd,
-    int window, int maxpack, int extusage, char *remote_name, int nonblock)
+    u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
 {
        int i, found;
        Channel *c;
@@ -229,6 +230,9 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
                /* There are no free slots.  Take last+1 slot and expand the array.  */
                found = channels_alloc;
                channels_alloc += 10;
+               if (channels_alloc > 10000)
+                       fatal("channel_new: internal error: channels_alloc %d "
+                           "too big.", channels_alloc);
                debug2("channel: expanding %d", channels_alloc);
                channels = xrealloc(channels, channels_alloc * sizeof(Channel *));
                for (i = found; i < channels_alloc; i++)
@@ -409,13 +413,13 @@ channel_not_very_much_buffered_data(void)
 #if 0
                        if (!compat20 &&
                            buffer_len(&c->input) > packet_get_maxsize()) {
-                               debug("channel %d: big input buffer %d",
+                               debug2("channel %d: big input buffer %d",
                                    c->self, buffer_len(&c->input));
                                return 0;
                        }
 #endif
                        if (buffer_len(&c->output) > packet_get_maxsize()) {
-                               debug("channel %d: big output buffer %d > %d",
+                               debug2("channel %d: big output buffer %d > %d",
                                    c->self, buffer_len(&c->output),
                                    packet_get_maxsize());
                                return 0;
@@ -569,11 +573,12 @@ void
 channel_send_open(int id)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL) {
                log("channel_send_open: %d: bad id", id);
                return;
        }
-       debug("send channel open %d", id);
+       debug2("channel %d: send open", id);
        packet_start(SSH2_MSG_CHANNEL_OPEN);
        packet_put_cstring(c->ctype);
        packet_put_int(c->self);
@@ -583,14 +588,15 @@ channel_send_open(int id)
 }
 
 void
-channel_request_start(int local_id, char *service, int wantconfirm)
+channel_request_start(int id, char *service, int wantconfirm)
 {
-       Channel *c = channel_lookup(local_id);
+       Channel *c = channel_lookup(id);
+
        if (c == NULL) {
-               log("channel_request_start: %d: unknown channel id", local_id);
+               log("channel_request_start: %d: unknown channel id", id);
                return;
        }
-       debug("channel request %d: %s", local_id, service) ;
+       debug("channel %d: request %s", id, service) ;
        packet_start(SSH2_MSG_CHANNEL_REQUEST);
        packet_put_int(c->remote_id);
        packet_put_cstring(service);
@@ -600,6 +606,7 @@ void
 channel_register_confirm(int id, channel_callback_fn *fn)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL) {
                log("channel_register_comfirm: %d: bad id", id);
                return;
@@ -610,6 +617,7 @@ void
 channel_register_cleanup(int id, channel_callback_fn *fn)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL) {
                log("channel_register_cleanup: %d: bad id", id);
                return;
@@ -620,6 +628,7 @@ void
 channel_cancel_cleanup(int id)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL) {
                log("channel_cancel_cleanup: %d: bad id", id);
                return;
@@ -630,6 +639,7 @@ void
 channel_register_filter(int id, channel_filter_fn *fn)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL) {
                log("channel_register_filter: %d: bad id", id);
                return;
@@ -642,6 +652,7 @@ channel_set_fds(int id, int rfd, int wfd, int efd,
     int extusage, int nonblock, u_int window_max)
 {
        Channel *c = channel_lookup(id);
+
        if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
                fatal("channel_activate for non-larval channel %d.", id);
        channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
@@ -812,6 +823,7 @@ static void
 channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
 {
        int ret = x11_open_helper(&c->output);
+
        if (ret == 1) {
                /* Start normal processing for the channel. */
                c->type = SSH_CHANNEL_OPEN;
@@ -863,7 +875,7 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
 static int
 channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
 {
-       u_char *p, *host;
+       char *p, *host;
        int len, have, i, found;
        char username[256];
        struct {
@@ -1275,6 +1287,11 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
            buffer_len(&c->output) > 0) {
                data = buffer_ptr(&c->output);
                dlen = buffer_len(&c->output);
+#ifdef _AIX
+               /* XXX: Later AIX versions can't push as much data to tty */ 
+               if (compat20 && c->wfd_isatty && dlen > 8*1024)
+                       dlen = 8*1024;
+#endif
                len = write(c->wfd, data, dlen);
                if (len < 0 && (errno == EINTR || errno == EAGAIN))
                        return 1;
@@ -1392,6 +1409,7 @@ static void
 channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
 {
        int len;
+
        /* Send buffered output data to the socket. */
        if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
                len = write(c->sock, buffer_ptr(&c->output),
@@ -1469,6 +1487,7 @@ static void
 channel_handler_init(void)
 {
        int i;
+
        for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
                channel_pre[i] = NULL;
                channel_post[i] = NULL;
@@ -1568,8 +1587,9 @@ channel_after_select(fd_set * readset, fd_set * writeset)
 void
 channel_output_poll(void)
 {
-       int len, i;
        Channel *c;
+       int i;
+       u_int len;
 
        for (i = 0; i < channels_alloc; i++) {
                c = channels[i];
@@ -1647,7 +1667,7 @@ channel_output_poll(void)
                    c->remote_window > 0 &&
                    (len = buffer_len(&c->extended)) > 0 &&
                    c->extended_usage == CHAN_EXTENDED_READ) {
-                       debug2("channel %d: rwin %d elen %d euse %d",
+                       debug2("channel %d: rwin %u elen %u euse %d",
                            c->self, c->remote_window, buffer_len(&c->extended),
                            c->extended_usage);
                        if (len > c->remote_window)
@@ -1717,9 +1737,8 @@ void
 channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
 {
        int id;
-       int tcode;
        char *data;
-       u_int data_len;
+       u_int data_len, tcode;
        Channel *c;
 
        /* Get the channel number and verify it. */
@@ -1874,7 +1893,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
                        c->confirm(c->self, NULL);
                        debug2("callback done");
                }
-               debug("channel %d: open confirm rwindow %d rmax %d", c->self,
+               debug("channel %d: open confirm rwindow %u rmax %u", c->self,
                    c->remote_window, c->remote_maxpacket);
        }
        packet_check_eom();
@@ -1931,7 +1950,8 @@ void
 channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
-       int id, adjust;
+       int id;
+       u_int adjust;
 
        if (!compat20)
                return;
@@ -1947,7 +1967,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
        }
        adjust = packet_get_int();
        packet_check_eom();
-       debug2("channel %d: rcvd adjust %d", id, adjust);
+       debug2("channel %d: rcvd adjust %u", id, adjust);
        c->remote_window += adjust;
 }
 
@@ -1977,6 +1997,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
                c->remote_id = remote_id;
        }
        if (c == NULL) {
+               xfree(originator_string);
                packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                packet_put_int(remote_id);
                packet_send();
@@ -2002,7 +2023,6 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
        struct addrinfo hints, *ai, *aitop;
        const char *host;
        char ntop[NI_MAXHOST], strport[NI_MAXSERV];
-       struct linger linger;
 
        success = 0;
        host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
@@ -2045,13 +2065,13 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                        continue;
                }
                /*
-                * Set socket options.  We would like the socket to disappear
-                * as soon as it has been closed for whatever reason.
+                * Set socket options.
+                * Allow local port reuse in TIME_WAIT.
                 */
-               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-               linger.l_onoff = 1;
-               linger.l_linger = 5;
-               setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
+               if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
+                   sizeof(on)) == -1)
+                       error("setsockopt SO_REUSEADDR: %s", strerror(errno));
+
                debug("Local forwarding listening on %s port %s.", ntop, strport);
 
                /* Bind the socket to the address. */
@@ -2262,7 +2282,10 @@ connect_to(const char *host, u_short port)
                }
                sock = socket(ai->ai_family, SOCK_STREAM, 0);
                if (sock < 0) {
-                       error("socket: %.100s", strerror(errno));
+                       if (ai->ai_next == NULL)
+                               error("socket: %.100s", strerror(errno));
+                       else
+                               verbose("socket: %.100s", strerror(errno));
                        continue;
                }
                if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
@@ -2328,12 +2351,12 @@ channel_connect_to(const char *host, u_short port)
 
 /*
  * Creates an internet domain socket for listening for X11 connections.
- * Returns a suitable display number for the DISPLAY variable, or -1 if
- * an error occurs.
+ * Returns 0 and a suitable display number for the DISPLAY variable
+ * stored in display_numberp , or -1 if an error occurs.
  */
 int
 x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
-    int single_connection)
+    int single_connection, u_int *display_numberp)
 {
        Channel *nc = NULL;
        int display_number, sock;
@@ -2431,7 +2454,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
        }
 
        /* Return the display number for the DISPLAY environment variable. */
-       return display_number;
+       *display_numberp = display_number;
+       return (0);
 }
 
 static int
@@ -2586,6 +2610,7 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
                /* Send refusal to the remote host. */
                packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
                packet_put_int(remote_id);
+               xfree(remote_host);
        } else {
                /* Send a confirmation to the remote host. */
                packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
@@ -2600,6 +2625,7 @@ void
 deny_input_open(int type, u_int32_t seq, void *ctxt)
 {
        int rchan = packet_get_int();
+
        switch (type) {
        case SSH_SMSG_AGENT_OPEN:
                error("Warning: ssh server tried agent forwarding.");
This page took 0.224351 seconds and 4 git commands to generate.