Main Page | Namespace List | Class List | Directories | File List | Class Members | File Members

channels.c File Reference

#include "includes.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "misc.h"
#include "channels.h"
#include "compat.h"
#include "canohost.h"
#include "key.h"
#include "authfd.h"
#include "pathnames.h"
#include "bufaux.h"

Go to the source code of this file.

Classes

struct  ForwardPermission

Defines

#define MAX_DISPLAYS   1000
#define NUM_SOCKS   10
#define SSH_SOCKS5_AUTHDONE   0x1000
#define SSH_SOCKS5_NOAUTH   0x00
#define SSH_SOCKS5_IPV4   0x01
#define SSH_SOCKS5_DOMAIN   0x03
#define SSH_SOCKS5_IPV6   0x04
#define SSH_SOCKS5_CONNECT   0x01
#define SSH_SOCKS5_SUCCESS   0x00

Typedefs

typedef void chan_fn (Channel *c, fd_set *readset, fd_set *writeset)

Functions

 RCSID ("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $")
static void port_open_helper (Channel *c, char *rtype)
Channelchannel_by_id (int id)
Channelchannel_lookup (int id)
static void channel_register_fds (Channel *c, int rfd, int wfd, int efd, int extusage, int nonblock)
Channelchannel_new (char *ctype, int type, int rfd, int wfd, int efd, u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
static int channel_find_maxfd (void)
int channel_close_fd (int *fdp)
static void channel_close_fds (Channel *c)
void channel_free (Channel *c)
void channel_free_all (void)
void channel_close_all (void)
void channel_stop_listening (void)
int channel_not_very_much_buffered_data (void)
int channel_still_open (void)
int channel_find_open (void)
charchannel_open_message (void)
void channel_send_open (int id)
void channel_request_start (int id, char *service, int wantconfirm)
void channel_register_confirm (int id, channel_callback_fn *fn, void *ctx)
void channel_register_cleanup (int id, channel_callback_fn *fn, int do_close)
void channel_cancel_cleanup (int id)
void channel_register_filter (int id, channel_infilter_fn *ifn, channel_outfilter_fn *ofn)
void channel_set_fds (int id, int rfd, int wfd, int efd, int extusage, int nonblock, u_int window_max)
static void channel_pre_listener (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_connecting (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_open_13 (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_open (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_input_draining (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_output_draining (Channel *c, fd_set *readset, fd_set *writeset)
static int x11_open_helper (Buffer *b)
static void channel_pre_x11_open_13 (Channel *c, fd_set *readset, fd_set *writeset)
static void 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)
static int channel_decode_socks5 (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_pre_dynamic (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_post_x11_listener (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_set_reuseaddr (int fd)
static void channel_post_port_listener (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_post_auth_listener (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_post_connecting (Channel *c, fd_set *readset, fd_set *writeset)
static int channel_handle_rfd (Channel *c, fd_set *readset, fd_set *writeset)
static int channel_handle_wfd (Channel *c, fd_set *readset, fd_set *writeset)
static int channel_handle_efd (Channel *c, fd_set *readset, fd_set *writeset)
static int channel_handle_ctl (Channel *c, fd_set *readset, fd_set *writeset)
static int channel_check_window (Channel *c)
static void channel_post_open (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_post_output_drain_13 (Channel *c, fd_set *readset, fd_set *writeset)
static void channel_handler_init_20 (void)
static void channel_handler_init_13 (void)
static void channel_handler_init_15 (void)
static void channel_handler_init (void)
static void channel_garbage_collect (Channel *c)
static void channel_handler (chan_fn *ftab[], fd_set *readset, fd_set *writeset)
void channel_prepare_select (fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, int rekeying)
void channel_after_select (fd_set *readset, fd_set *writeset)
void channel_output_poll (void)
void channel_input_data (int type, u_int32_t seq, void *ctxt)
void channel_input_extended_data (int type, u_int32_t seq, void *ctxt)
void channel_input_ieof (int type, u_int32_t seq, void *ctxt)
void channel_input_close (int type, u_int32_t seq, void *ctxt)
void channel_input_oclose (int type, u_int32_t seq, void *ctxt)
void channel_input_close_confirmation (int type, u_int32_t seq, void *ctxt)
void channel_input_open_confirmation (int type, u_int32_t seq, void *ctxt)
static charreason2txt (int reason)
void channel_input_open_failure (int type, u_int32_t seq, void *ctxt)
void channel_input_window_adjust (int type, u_int32_t seq, void *ctxt)
void channel_input_port_open (int type, u_int32_t seq, void *ctxt)
void channel_set_af (int af)
static int channel_setup_fwd_listener (int type, const char *listen_addr, u_short listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports)
int channel_cancel_rport_listener (const char *host, u_short port)
int channel_setup_local_fwd_listener (const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports)
int channel_setup_remote_fwd_listener (const char *listen_address, u_short listen_port, int gateway_ports)
void channel_request_remote_forwarding (const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect)
void channel_request_rforward_cancel (const char *host, u_short port)
void channel_input_port_forward_request (int is_root, int gateway_ports)
void channel_permit_all_opens (void)
void channel_add_permitted_opens (char *host, int port)
void channel_clear_permitted_opens (void)
static int connect_to (const char *host, u_short port)
int channel_connect_by_listen_address (u_short listen_port)
int channel_connect_to (const char *host, u_short port)
void channel_send_window_changes (void)
int x11_create_display_inet (int x11_display_offset, int x11_use_localhost, int single_connection, u_int *display_numberp, int **chanids)
static int connect_local_xsocket (u_int dnr)
int x11_connect_display (void)
void x11_input_open (int type, u_int32_t seq, void *ctxt)
void deny_input_open (int type, u_int32_t seq, void *ctxt)
void x11_request_forwarding_with_spoofing (int client_session_id, const char *disp, const char *proto, const char *data)
void auth_request_forwarding (void)

Variables

static Channel ** channels = NULL
static u_int channels_alloc = 0
static int channel_max_fd = 0
static ForwardPermission permitted_opens [SSH_MAX_FORWARDS_PER_DIRECTION]
static int num_permitted_opens = 0
static int all_opens_permitted = 0
static charx11_saved_display = NULL
static charx11_saved_proto = NULL
static charx11_saved_data = NULL
static u_int x11_saved_data_len = 0
static charx11_fake_data = NULL
static u_int x11_fake_data_len
static int IPv4or6 = AF_UNSPEC
chan_fnchannel_pre [SSH_CHANNEL_MAX_TYPE]
chan_fnchannel_post [SSH_CHANNEL_MAX_TYPE]


Define Documentation

#define MAX_DISPLAYS   1000
 

Definition at line 110 of file channels.c.

Referenced by x11_create_display_inet().

#define NUM_SOCKS   10
 

Definition at line 132 of file channels.c.

Referenced by x11_create_display_inet().

#define SSH_SOCKS5_AUTHDONE   0x1000
 

Definition at line 998 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_CONNECT   0x01
 

Definition at line 1003 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_DOMAIN   0x03
 

Definition at line 1001 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_IPV4   0x01
 

Definition at line 1000 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_IPV6   0x04
 

Definition at line 1002 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_NOAUTH   0x00
 

Definition at line 999 of file channels.c.

Referenced by channel_decode_socks5().

#define SSH_SOCKS5_SUCCESS   0x00
 

Definition at line 1004 of file channels.c.

Referenced by channel_decode_socks5().


Typedef Documentation

typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset)
 

Definition at line 721 of file channels.c.


Function Documentation

void auth_request_forwarding void   ) 
 

Definition at line 3130 of file channels.c.

References packet_send(), packet_start(), packet_write_wait(), and SSH_CMSG_AGENT_REQUEST_FORWARDING.

Referenced by ssh_session().

void channel_add_permitted_opens char host,
int  port
 

Definition at line 2602 of file channels.c.

References all_opens_permitted, debug(), fatal(), ForwardPermission::host_to_connect, num_permitted_opens, ForwardPermission::port_to_connect, SSH_MAX_FORWARDS_PER_DIRECTION, and xstrdup().

Referenced by auth_parse_options().

02603 {
02604         if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
02605                 fatal("channel_request_remote_forwarding: too many forwards");
02606         debug("allow port forwarding to host %s port %d", host, port);
02607 
02608         permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
02609         permitted_opens[num_permitted_opens].port_to_connect = port;
02610         num_permitted_opens++;
02611 
02612         all_opens_permitted = 0;
02613 }

void channel_after_select fd_set *  readset,
fd_set *  writeset
 

Definition at line 1815 of file channels.c.

References channel_handler(), and channel_post.

Referenced by client_loop(), server_loop(), and server_loop2().

01816 {
01817         channel_handler(channel_post, readset, writeset);
01818 }

Channel* channel_by_id int  id  ) 
 

Definition at line 143 of file channels.c.

References channels_alloc, and logit().

Referenced by channel_cancel_cleanup(), channel_lookup(), channel_register_cleanup(), and session_close_x11().

00144 {
00145         Channel *c;
00146 
00147         if (id < 0 || (u_int)id >= channels_alloc) {
00148                 logit("channel_by_id: %d: bad id", id);
00149                 return NULL;
00150         }
00151         c = channels[id];
00152         if (c == NULL) {
00153                 logit("channel_by_id: %d: bad id: channel free", id);
00154                 return NULL;
00155         }
00156         return c;
00157 }

void channel_cancel_cleanup int  id  ) 
 

Definition at line 671 of file channels.c.

References channel_by_id(), Channel::detach_close, Channel::detach_user, and logit().

Referenced by client_channel_closed(), session_close_by_channel(), session_close_single_x11(), and session_close_x11().

00672 {
00673         Channel *c = channel_by_id(id);
00674 
00675         if (c == NULL) {
00676                 logit("channel_cancel_cleanup: %d: bad id", id);
00677                 return;
00678         }
00679         c->detach_user = NULL;
00680         c->detach_close = 0;
00681 }

int channel_cancel_rport_listener const char host,
u_short  port
 

Definition at line 2413 of file channels.c.

References __func__, channel_free(), channels_alloc, debug2(), Channel::listening_port, Channel::path, SSH_CHANNEL_RPORT_LISTENER, and Channel::type.

Referenced by server_input_global_request().

02414 {
02415         u_int i;
02416         int found = 0;
02417 
02418         for (i = 0; i < channels_alloc; i++) {
02419                 Channel *c = channels[i];
02420 
02421                 if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
02422                     strncmp(c->path, host, sizeof(c->path)) == 0 &&
02423                     c->listening_port == port) {
02424                         debug2("%s: close channel %d", __func__, i);
02425                         channel_free(c);
02426                         found = 1;
02427                 }
02428         }
02429 
02430         return (found);
02431 }

static int channel_check_window Channel c  )  [static]
 

Definition at line 1612 of file channels.c.

References CHAN_CLOSE_RCVD, CHAN_CLOSE_SENT, debug2(), Channel::flags, Channel::local_consumed, Channel::local_window, Channel::local_window_max, packet_put_int(), packet_send(), packet_start(), Channel::remote_id, Channel::self, SSH2_MSG_CHANNEL_WINDOW_ADJUST, SSH_CHANNEL_OPEN, and Channel::type.

Referenced by channel_post_open().

01613 {
01614         if (c->type == SSH_CHANNEL_OPEN &&
01615             !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
01616             c->local_window < c->local_window_max/2 &&
01617             c->local_consumed > 0) {
01618                 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
01619                 packet_put_int(c->remote_id);
01620                 packet_put_int(c->local_consumed);
01621                 packet_send();
01622                 debug2("channel %d: window %d sent adjust %d",
01623                     c->self, c->local_window,
01624                     c->local_consumed);
01625                 c->local_window += c->local_consumed;
01626                 c->local_consumed = 0;
01627         }
01628         return 1;
01629 }

void channel_clear_permitted_opens void   ) 
 

Definition at line 2616 of file channels.c.

References num_permitted_opens, and xfree().

Referenced by auth_clear_options().

02617 {
02618         int i;
02619 
02620         for (i = 0; i < num_permitted_opens; i++)
02621                 if (permitted_opens[i].host_to_connect != NULL)
02622                         xfree(permitted_opens[i].host_to_connect);
02623         num_permitted_opens = 0;
02624 
02625 }

void channel_close_all void   ) 
 

Definition at line 404 of file channels.c.

References channel_close_fds(), and channels_alloc.

Referenced by child_close_fds(), and packet_disconnect().

00405 {
00406         u_int i;
00407 
00408         for (i = 0; i < channels_alloc; i++)
00409                 if (channels[i] != NULL)
00410                         channel_close_fds(channels[i]);
00411 }

int channel_close_fd int *  fdp  ) 
 

Definition at line 326 of file channels.c.

References channel_find_maxfd(), and channel_max_fd.

Referenced by chan_shutdown_read(), chan_shutdown_write(), channel_close_fds(), channel_handle_efd(), channel_post_x11_listener(), channel_pre_x11_open_13(), and channel_stop_listening().

00327 {
00328         int ret = 0, fd = *fdp;
00329 
00330         if (fd != -1) {
00331                 ret = close(fd);
00332                 *fdp = -1;
00333                 if (fd == channel_max_fd)
00334                         channel_max_fd = channel_find_maxfd();
00335         }
00336         return ret;
00337 }

static void channel_close_fds Channel c  )  [static]
 

Definition at line 342 of file channels.c.

References channel_close_fd(), Channel::ctl_fd, debug3(), Channel::efd, Channel::rfd, Channel::self, Channel::sock, and Channel::wfd.

Referenced by channel_close_all(), and channel_free().

00343 {
00344         debug3("channel %d: close_fds r %d w %d e %d c %d",
00345             c->self, c->rfd, c->wfd, c->efd, c->ctl_fd);
00346 
00347         channel_close_fd(&c->sock);
00348         channel_close_fd(&c->ctl_fd);
00349         channel_close_fd(&c->rfd);
00350         channel_close_fd(&c->wfd);
00351         channel_close_fd(&c->efd);
00352 }

int channel_connect_by_listen_address u_short  listen_port  ) 
 

Definition at line 2685 of file channels.c.

References connect_to(), error(), and num_permitted_opens.

Referenced by client_request_forwarded_tcpip().

02686 {
02687         int i;
02688 
02689         for (i = 0; i < num_permitted_opens; i++)
02690                 if (permitted_opens[i].host_to_connect != NULL &&
02691                     permitted_opens[i].listen_port == listen_port)
02692                         return connect_to(
02693                             permitted_opens[i].host_to_connect,
02694                             permitted_opens[i].port_to_connect);
02695         error("WARNING: Server requests forwarding for unknown listen_port %d",
02696             listen_port);
02697         return -1;
02698 }

int channel_connect_to const char host,
u_short  port
 

Definition at line 2702 of file channels.c.

References all_opens_permitted, connect_to(), logit(), and num_permitted_opens.

Referenced by channel_input_port_open(), and server_request_direct_tcpip().

02703 {
02704         int i, permit;
02705 
02706         permit = all_opens_permitted;
02707         if (!permit) {
02708                 for (i = 0; i < num_permitted_opens; i++)
02709                         if (permitted_opens[i].host_to_connect != NULL &&
02710                             permitted_opens[i].port_to_connect == port &&
02711                             strcmp(permitted_opens[i].host_to_connect, host) == 0)
02712                                 permit = 1;
02713 
02714         }
02715         if (!permit) {
02716                 logit("Received request to connect to host %.100s port %d, "
02717                     "but the request was denied.", host, port);
02718                 return -1;
02719         }
02720         return connect_to(host, port);
02721 }

static int channel_decode_socks4 Channel c,
fd_set *  readset,
fd_set *  writeset
[static]
 

Definition at line 929 of file channels.c.

References buffer_append(), buffer_consume(), buffer_get(), buffer_len(), buffer_ptr(), command, debug(), debug2(), fatal(), host, Channel::host_port, inet_ntoa(), Channel::input, Channel::output, Channel::path, Channel::self, strlcpy(), and version.

Referenced by channel_pre_dynamic().

00930 {
00931         char *p, *host;
00932         u_int len, have, i, found;
00933         char username[256];
00934         struct {
00935                 u_int8_t version;
00936                 u_int8_t command;
00937                 u_int16_t dest_port;
00938                 struct in_addr dest_addr;
00939         } s4_req, s4_rsp;
00940 
00941         debug2("channel %d: decode socks4", c->self);
00942 
00943         have = buffer_len(&c->input);
00944         len = sizeof(s4_req);
00945         if (have < len)
00946                 return 0;
00947         p = buffer_ptr(&c->input);
00948         for (found = 0, i = len; i < have; i++) {
00949                 if (p[i] == '\0') {
00950                         found = 1;
00951                         break;
00952                 }
00953                 if (i > 1024) {
00954                         /* the peer is probably sending garbage */
00955                         debug("channel %d: decode socks4: too long",
00956                             c->self);
00957                         return -1;
00958                 }
00959         }
00960         if (!found)
00961                 return 0;
00962         buffer_get(&c->input, (char *)&s4_req.version, 1);
00963         buffer_get(&c->input, (char *)&s4_req.command, 1);
00964         buffer_get(&c->input, (char *)&s4_req.dest_port, 2);
00965         buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
00966         have = buffer_len(&c->input);
00967         p = buffer_ptr(&c->input);
00968         len = strlen(p);
00969         debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
00970         if (len > have)
00971                 fatal("channel %d: decode socks4: len %d > have %d",
00972                     c->self, len, have);
00973         strlcpy(username, p, sizeof(username));
00974         buffer_consume(&c->input, len);
00975         buffer_consume(&c->input, 1);           /* trailing '\0' */
00976 
00977         host = inet_ntoa(s4_req.dest_addr);
00978         strlcpy(c->path, host, sizeof(c->path));
00979         c->host_port = ntohs(s4_req.dest_port);
00980 
00981         debug2("channel %d: dynamic request: socks4 host %s port %u command %u",
00982             c->self, host, c->host_port, s4_req.command);
00983 
00984         if (s4_req.command != 1) {
00985                 debug("channel %d: cannot handle: socks4 cn %d",
00986                     c->self, s4_req.command);
00987                 return -1;
00988         }
00989         s4_rsp.version = 0;                     /* vn: 0 for reply */
00990         s4_rsp.command = 90;                    /* cd: req granted */
00991         s4_rsp.dest_port = 0;                   /* ignored */
00992         s4_rsp.dest_addr.s_addr = INADDR_ANY;   /* ignored */
00993         buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp));
00994         return 1;
00995 }

static int channel_decode_socks5 Channel c,
fd_set *  readset,
fd_set *  writeset
[static]
 

Definition at line 1007 of file channels.c.

References AF_INET6, buffer_append(), buffer_consume(), buffer_get(), buffer_len(), buffer_ptr(), buffer_put_char(), command, debug(), debug2(), Channel::flags, Channel::host_port, inet_ntop(), Channel::input, Channel::output, Channel::path, Channel::self, Channel::sock, SSH_SOCKS5_AUTHDONE, SSH_SOCKS5_CONNECT, SSH_SOCKS5_DOMAIN, SSH_SOCKS5_IPV4, SSH_SOCKS5_IPV6, SSH_SOCKS5_NOAUTH, SSH_SOCKS5_SUCCESS, strlcpy(), and version.

Referenced by channel_pre_dynamic().

01008 {
01009         struct {
01010                 u_int8_t version;
01011                 u_int8_t command;
01012                 u_int8_t reserved;
01013                 u_int8_t atyp;
01014         } s5_req, s5_rsp;
01015         u_int16_t dest_port;
01016         u_char *p, dest_addr[255+1];
01017         u_int have, i, found, nmethods, addrlen, af;
01018 
01019         debug2("channel %d: decode socks5", c->self);
01020         p = buffer_ptr(&c->input);
01021         if (p[0] != 0x05)
01022                 return -1;
01023         have = buffer_len(&c->input);
01024         if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
01025                 /* format: ver | nmethods | methods */
01026                 if (have < 2)
01027                         return 0;
01028                 nmethods = p[1];
01029                 if (have < nmethods + 2)
01030                         return 0;
01031                 /* look for method: "NO AUTHENTICATION REQUIRED" */
01032                 for (found = 0, i = 2 ; i < nmethods + 2; i++) {
01033                         if (p[i] == SSH_SOCKS5_NOAUTH ) {
01034                                 found = 1;
01035                                 break;
01036                         }
01037                 }
01038                 if (!found) {
01039                         debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
01040                             c->self);
01041                         return -1;
01042                 }
01043                 buffer_consume(&c->input, nmethods + 2);
01044                 buffer_put_char(&c->output, 0x05);              /* version */
01045                 buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */
01046                 FD_SET(c->sock, writeset);
01047                 c->flags |= SSH_SOCKS5_AUTHDONE;
01048                 debug2("channel %d: socks5 auth done", c->self);
01049                 return 0;                               /* need more */
01050         }
01051         debug2("channel %d: socks5 post auth", c->self);
01052         if (have < sizeof(s5_req)+1)
01053                 return 0;                       /* need more */
01054         memcpy((char *)&s5_req, p, sizeof(s5_req));
01055         if (s5_req.version != 0x05 ||
01056             s5_req.command != SSH_SOCKS5_CONNECT ||
01057             s5_req.reserved != 0x00) {
01058                 debug2("channel %d: only socks5 connect supported", c->self);
01059                 return -1;
01060         }
01061         switch (s5_req.atyp){
01062         case SSH_SOCKS5_IPV4:
01063                 addrlen = 4;
01064                 af = AF_INET;
01065                 break;
01066         case SSH_SOCKS5_DOMAIN:
01067                 addrlen = p[sizeof(s5_req)];
01068                 af = -1;
01069                 break;
01070         case SSH_SOCKS5_IPV6:
01071                 addrlen = 16;
01072                 af = AF_INET6;
01073                 break;
01074         default:
01075                 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
01076                 return -1;
01077         }
01078         if (have < 4 + addrlen + 2)
01079                 return 0;
01080         buffer_consume(&c->input, sizeof(s5_req));
01081         if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
01082                 buffer_consume(&c->input, 1);    /* host string length */
01083         buffer_get(&c->input, (char *)&dest_addr, addrlen);
01084         buffer_get(&c->input, (char *)&dest_port, 2);
01085         dest_addr[addrlen] = '\0';
01086         if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
01087                 strlcpy(c->path, (char *)dest_addr, sizeof(c->path));
01088         else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL)
01089                 return -1;
01090         c->host_port = ntohs(dest_port);
01091 
01092         debug2("channel %d: dynamic request: socks5 host %s port %u command %u",
01093             c->self, c->path, c->host_port, s5_req.command);
01094 
01095         s5_rsp.version = 0x05;
01096         s5_rsp.command = SSH_SOCKS5_SUCCESS;
01097         s5_rsp.reserved = 0;                    /* ignored */
01098         s5_rsp.atyp = SSH_SOCKS5_IPV4;
01099         ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
01100         dest_port = 0;                          /* ignored */
01101 
01102         buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
01103         buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
01104         buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
01105         return 1;
01106 }

static int channel_find_maxfd void   )  [static]
 

Definition at line 308 of file channels.c.

References channels_alloc, Channel::efd, MAX, Channel::rfd, and Channel::wfd.

Referenced by channel_close_fd().

00309 {
00310         u_int i;
00311         int max = 0;
00312         Channel *c;
00313 
00314         for (i = 0; i < channels_alloc; i++) {
00315                 c = channels[i];
00316                 if (c != NULL) {
00317                         max = MAX(max, c->rfd);
00318                         max = MAX(max, c->wfd);
00319                         max = MAX(max, c->efd);
00320                 }
00321         }
00322         return max;
00323 }

int channel_find_open void   ) 
 

Definition at line 518 of file channels.c.

References channels_alloc, compat13, fatal(), Channel::remote_id, SSH_CHANNEL_AUTH_SOCKET, SSH_CHANNEL_CLOSED, SSH_CHANNEL_CONNECTING, SSH_CHANNEL_DYNAMIC, SSH_CHANNEL_INPUT_DRAINING, SSH_CHANNEL_LARVAL, SSH_CHANNEL_OPEN, SSH_CHANNEL_OPENING, SSH_CHANNEL_OUTPUT_DRAINING, SSH_CHANNEL_PORT_LISTENER, SSH_CHANNEL_RPORT_LISTENER, SSH_CHANNEL_X11_LISTENER, SSH_CHANNEL_X11_OPEN, SSH_CHANNEL_ZOMBIE, and Channel::type.

Referenced by client_alive_check().

00519 {
00520         u_int i;
00521         Channel *c;
00522 
00523         for (i = 0; i < channels_alloc; i++) {
00524                 c = channels[i];
00525                 if (c == NULL || c->remote_id < 0)
00526                         continue;
00527                 switch (c->type) {
00528                 case SSH_CHANNEL_CLOSED:
00529                 case SSH_CHANNEL_DYNAMIC:
00530                 case SSH_CHANNEL_X11_LISTENER:
00531                 case SSH_CHANNEL_PORT_LISTENER:
00532                 case SSH_CHANNEL_RPORT_LISTENER:
00533                 case SSH_CHANNEL_OPENING:
00534                 case SSH_CHANNEL_CONNECTING:
00535                 case SSH_CHANNEL_ZOMBIE:
00536                         continue;
00537                 case SSH_CHANNEL_LARVAL:
00538                 case SSH_CHANNEL_AUTH_SOCKET:
00539                 case SSH_CHANNEL_OPEN:
00540                 case SSH_CHANNEL_X11_OPEN:
00541                         return i;
00542                 case SSH_CHANNEL_INPUT_DRAINING:
00543                 case SSH_CHANNEL_OUTPUT_DRAINING:
00544                         if (!compat13)
00545                                 fatal("cannot happen: OUT_DRAIN");
00546                         return i;
00547                 default:
00548                         fatal("channel_find_open: bad channel type %d", c->type);
00549                         /* NOTREACHED */
00550                 }
00551         }
00552         return -1;
00553 }

void channel_free Channel c  ) 
 

Definition at line 357 of file channels.c.

References buffer_free(), channel_close_fds(), channel_open_message(), channels_alloc, Channel::ctl_fd, debug(), debug3(), Channel::extended, Channel::input, Channel::output, Channel::remote_name, Channel::self, SHUT_RDWR, Channel::sock, and xfree().

Referenced by channel_cancel_rport_listener(), channel_free_all(), channel_garbage_collect(), channel_input_close_confirmation(), channel_input_open_failure(), channel_stop_listening(), client_subsystem_reply(), and server_request_session().

00358 {
00359         char *s;
00360         u_int i, n;
00361 
00362         for (n = 0, i = 0; i < channels_alloc; i++)
00363                 if (channels[i])
00364                         n++;
00365         debug("channel %d: free: %s, nchannels %u", c->self,
00366             c->remote_name ? c->remote_name : "???", n);
00367 
00368         s = channel_open_message();
00369         debug3("channel %d: status: %s", c->self, s);
00370         xfree(s);
00371 
00372         if (c->sock != -1)
00373                 shutdown(c->sock, SHUT_RDWR);
00374         if (c->ctl_fd != -1)
00375                 shutdown(c->ctl_fd, SHUT_RDWR);
00376         channel_close_fds(c);
00377         buffer_free(&c->input);
00378         buffer_free(&c->output);
00379         buffer_free(&c->extended);
00380         if (c->remote_name) {
00381                 xfree(c->remote_name);
00382                 c->remote_name = NULL;
00383         }
00384         channels[c->self] = NULL;
00385         xfree(c);
00386 }

void channel_free_all void   ) 
 

Definition at line 389 of file channels.c.

References channel_free(), and channels_alloc.

Referenced by client_loop(), server_loop(), and server_loop2().

00390 {
00391         u_int i;
00392 
00393         for (i = 0; i < channels_alloc; i++)
00394                 if (channels[i] != NULL)
00395                         channel_free(channels[i]);
00396 }

static void channel_garbage_collect Channel c  )  [static]
 

Definition at line 1742 of file channels.c.

References chan_is_dead(), channel_free(), debug2(), Channel::detach_close, Channel::detach_user, and Channel::self.

Referenced by channel_handler().

01743 {
01744         if (c == NULL)
01745                 return;
01746         if (c->detach_user != NULL) {
01747                 if (!chan_is_dead(c, c->detach_close))
01748                         return;
01749                 debug2("channel %d: gc: notify user", c->self);
01750                 c->detach_user(c->self, NULL);
01751                 /* if we still have a callback */
01752                 if (c->detach_user != NULL)
01753                         return;
01754                 debug2("channel %d: gc: user detached", c->self);
01755         }
01756         if (!chan_is_dead(c, 1))
01757                 return;
01758         debug2("channel %d: garbage collecting", c->self);
01759         channel_free(c);
01760 }

static int channel_handle_ctl Channel c,