summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
committerColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
commitb7e40fa9da0b5491534a429dadb321eab5a77558 (patch)
treebed1da11e9f829925797aa093e379fc0b5868ecd /channels.c
parent4f84beedf1005e44ff33c854abd6b711ffc0adb7 (diff)
parent086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff)
* New upstream release (closes: #395507, #397961, #420035). Important
changes not previously backported to 4.3p2: - 4.4/4.4p1 (http://www.openssh.org/txt/release-4.4): + On portable OpenSSH, fix a GSSAPI authentication abort that could be used to determine the validity of usernames on some platforms. + Implemented conditional configuration in sshd_config(5) using the "Match" directive. This allows some configuration options to be selectively overridden if specific criteria (based on user, group, hostname and/or address) are met. So far a useful subset of post-authentication options are supported and more are expected to be added in future releases. + Add support for Diffie-Hellman group exchange key agreement with a final hash of SHA256. + Added a "ForceCommand" directive to sshd_config(5). Similar to the command="..." option accepted in ~/.ssh/authorized_keys, this forces the execution of the specified command regardless of what the user requested. This is very useful in conjunction with the new "Match" option. + Add a "PermitOpen" directive to sshd_config(5). This mirrors the permitopen="..." authorized_keys option, allowing fine-grained control over the port-forwardings that a user is allowed to establish. + Add optional logging of transactions to sftp-server(8). + ssh(1) will now record port numbers for hosts stored in ~/.ssh/known_hosts when a non-standard port has been requested (closes: #50612). + Add an "ExitOnForwardFailure" option to cause ssh(1) to exit (with a non-zero exit code) when requested port forwardings could not be established. + Extend sshd_config(5) "SubSystem" declarations to allow the specification of command-line arguments. + Replacement of all integer overflow susceptible invocations of malloc(3) and realloc(3) with overflow-checking equivalents. + Many manpage fixes and improvements. + Add optional support for OpenSSL hardware accelerators (engines), enabled using the --with-ssl-engine configure option. + Tokens in configuration files may be double-quoted in order to contain spaces (closes: #319639). + Move a debug() call out of a SIGCHLD handler, fixing a hang when the session exits very quickly (closes: #307890). + Fix some incorrect buffer allocation calculations (closes: #410599). + ssh-add doesn't ask for a passphrase if key file permissions are too liberal (closes: #103677). + Likewise, ssh doesn't ask either (closes: #99675). - 4.6/4.6p1 (http://www.openssh.org/txt/release-4.6): + sshd now allows the enabling and disabling of authentication methods on a per user, group, host and network basis via the Match directive in sshd_config. + Fixed an inconsistent check for a terminal when displaying scp progress meter (closes: #257524). + Fix "hang on exit" when background processes are running at the time of exit on a ttyful/login session (closes: #88337). * Update to current GSSAPI patch from http://www.sxw.org.uk/computing/patches/openssh-4.6p1-gsskex-20070312.patch; install ChangeLog.gssapi.
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c303
1 files changed, 202 insertions, 101 deletions
diff --git a/channels.c b/channels.c
index 92448da77..530c0d460 100644
--- a/channels.c
+++ b/channels.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: channels.c,v 1.268 2007/01/03 03:01:40 stevesk Exp $ */
1/* 2/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -39,22 +40,41 @@
39 */ 40 */
40 41
41#include "includes.h" 42#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $");
43 43
44#include <sys/types.h>
45#include <sys/ioctl.h>
46#include <sys/un.h>
47#include <sys/socket.h>
48#ifdef HAVE_SYS_TIME_H
49# include <sys/time.h>
50#endif
51
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <errno.h>
56#include <netdb.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <termios.h>
61#include <unistd.h>
62#include <stdarg.h>
63
64#include "xmalloc.h"
44#include "ssh.h" 65#include "ssh.h"
45#include "ssh1.h" 66#include "ssh1.h"
46#include "ssh2.h" 67#include "ssh2.h"
47#include "packet.h" 68#include "packet.h"
48#include "xmalloc.h"
49#include "log.h" 69#include "log.h"
50#include "misc.h" 70#include "misc.h"
71#include "buffer.h"
51#include "channels.h" 72#include "channels.h"
52#include "compat.h" 73#include "compat.h"
53#include "canohost.h" 74#include "canohost.h"
54#include "key.h" 75#include "key.h"
55#include "authfd.h" 76#include "authfd.h"
56#include "pathnames.h" 77#include "pathnames.h"
57#include "bufaux.h"
58 78
59/* -- channel core */ 79/* -- channel core */
60 80
@@ -91,11 +111,18 @@ typedef struct {
91 u_short listen_port; /* Remote side should listen port number. */ 111 u_short listen_port; /* Remote side should listen port number. */
92} ForwardPermission; 112} ForwardPermission;
93 113
94/* List of all permitted host/port pairs to connect. */ 114/* List of all permitted host/port pairs to connect by the user. */
95static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; 115static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
96 116
97/* Number of permitted host/port pairs in the array. */ 117/* List of all permitted host/port pairs to connect by the admin. */
118static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
119
120/* Number of permitted host/port pairs in the array permitted by the user. */
98static int num_permitted_opens = 0; 121static int num_permitted_opens = 0;
122
123/* Number of permitted host/port pair in the array permitted by the admin. */
124static int num_adm_permitted_opens = 0;
125
99/* 126/*
100 * If this is true, all opens are permitted. This is the case on the server 127 * If this is true, all opens are permitted. This is the case on the server
101 * on which we have to trust the client anyway, and the user could do 128 * on which we have to trust the client anyway, and the user could do
@@ -123,7 +150,7 @@ static u_int x11_saved_data_len = 0;
123 * Fake X11 authentication data. This is what the server will be sending us; 150 * Fake X11 authentication data. This is what the server will be sending us;
124 * we should replace any occurrences of this by the real data. 151 * we should replace any occurrences of this by the real data.
125 */ 152 */
126static char *x11_fake_data = NULL; 153static u_char *x11_fake_data = NULL;
127static u_int x11_fake_data_len; 154static u_int x11_fake_data_len;
128 155
129 156
@@ -168,7 +195,7 @@ channel_lookup(int id)
168 if ((c = channel_by_id(id)) == NULL) 195 if ((c = channel_by_id(id)) == NULL)
169 return (NULL); 196 return (NULL);
170 197
171 switch(c->type) { 198 switch (c->type) {
172 case SSH_CHANNEL_X11_OPEN: 199 case SSH_CHANNEL_X11_OPEN:
173 case SSH_CHANNEL_LARVAL: 200 case SSH_CHANNEL_LARVAL:
174 case SSH_CHANNEL_CONNECTING: 201 case SSH_CHANNEL_CONNECTING:
@@ -178,7 +205,6 @@ channel_lookup(int id)
178 case SSH_CHANNEL_INPUT_DRAINING: 205 case SSH_CHANNEL_INPUT_DRAINING:
179 case SSH_CHANNEL_OUTPUT_DRAINING: 206 case SSH_CHANNEL_OUTPUT_DRAINING:
180 return (c); 207 return (c);
181 break;
182 } 208 }
183 logit("Non-public channel %d, type %d.", id, c->type); 209 logit("Non-public channel %d, type %d.", id, c->type);
184 return (NULL); 210 return (NULL);
@@ -188,7 +214,6 @@ channel_lookup(int id)
188 * Register filedescriptors for a channel, used when allocating a channel or 214 * Register filedescriptors for a channel, used when allocating a channel or
189 * when the channel consumer/producer is ready, e.g. shell exec'd 215 * when the channel consumer/producer is ready, e.g. shell exec'd
190 */ 216 */
191
192static void 217static void
193channel_register_fds(Channel *c, int rfd, int wfd, int efd, 218channel_register_fds(Channel *c, int rfd, int wfd, int efd,
194 int extusage, int nonblock) 219 int extusage, int nonblock)
@@ -235,7 +260,6 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
235 * Allocate a new channel object and set its type and socket. This will cause 260 * Allocate a new channel object and set its type and socket. This will cause
236 * remote_name to be freed. 261 * remote_name to be freed.
237 */ 262 */
238
239Channel * 263Channel *
240channel_new(char *ctype, int type, int rfd, int wfd, int efd, 264channel_new(char *ctype, int type, int rfd, int wfd, int efd,
241 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) 265 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
@@ -247,7 +271,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
247 /* Do initial allocation if this is the first call. */ 271 /* Do initial allocation if this is the first call. */
248 if (channels_alloc == 0) { 272 if (channels_alloc == 0) {
249 channels_alloc = 10; 273 channels_alloc = 10;
250 channels = xmalloc(channels_alloc * sizeof(Channel *)); 274 channels = xcalloc(channels_alloc, sizeof(Channel *));
251 for (i = 0; i < channels_alloc; i++) 275 for (i = 0; i < channels_alloc; i++)
252 channels[i] = NULL; 276 channels[i] = NULL;
253 } 277 }
@@ -264,16 +288,15 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
264 if (channels_alloc > 10000) 288 if (channels_alloc > 10000)
265 fatal("channel_new: internal error: channels_alloc %d " 289 fatal("channel_new: internal error: channels_alloc %d "
266 "too big.", channels_alloc); 290 "too big.", channels_alloc);
267 channels = xrealloc(channels, 291 channels = xrealloc(channels, channels_alloc + 10,
268 (channels_alloc + 10) * sizeof(Channel *)); 292 sizeof(Channel *));
269 channels_alloc += 10; 293 channels_alloc += 10;
270 debug2("channel: expanding %d", channels_alloc); 294 debug2("channel: expanding %d", channels_alloc);
271 for (i = found; i < channels_alloc; i++) 295 for (i = found; i < channels_alloc; i++)
272 channels[i] = NULL; 296 channels[i] = NULL;
273 } 297 }
274 /* Initialize and return new channel. */ 298 /* Initialize and return new channel. */
275 c = channels[found] = xmalloc(sizeof(Channel)); 299 c = channels[found] = xcalloc(1, sizeof(Channel));
276 memset(c, 0, sizeof(Channel));
277 buffer_init(&c->input); 300 buffer_init(&c->input);
278 buffer_init(&c->output); 301 buffer_init(&c->output);
279 buffer_init(&c->extended); 302 buffer_init(&c->extended);
@@ -337,7 +360,6 @@ channel_close_fd(int *fdp)
337} 360}
338 361
339/* Close all channel fd/socket. */ 362/* Close all channel fd/socket. */
340
341static void 363static void
342channel_close_fds(Channel *c) 364channel_close_fds(Channel *c)
343{ 365{
@@ -352,7 +374,6 @@ channel_close_fds(Channel *c)
352} 374}
353 375
354/* Free the channel and close its fd/socket. */ 376/* Free the channel and close its fd/socket. */
355
356void 377void
357channel_free(Channel *c) 378channel_free(Channel *c)
358{ 379{
@@ -399,7 +420,6 @@ channel_free_all(void)
399 * Closes the sockets/fds of all channels. This is used to close extra file 420 * Closes the sockets/fds of all channels. This is used to close extra file
400 * descriptors after a fork. 421 * descriptors after a fork.
401 */ 422 */
402
403void 423void
404channel_close_all(void) 424channel_close_all(void)
405{ 425{
@@ -413,7 +433,6 @@ channel_close_all(void)
413/* 433/*
414 * Stop listening to channels. 434 * Stop listening to channels.
415 */ 435 */
416
417void 436void
418channel_stop_listening(void) 437channel_stop_listening(void)
419{ 438{
@@ -440,7 +459,6 @@ channel_stop_listening(void)
440 * Returns true if no channel has too much buffered data, and false if one or 459 * Returns true if no channel has too much buffered data, and false if one or
441 * more channel is overfull. 460 * more channel is overfull.
442 */ 461 */
443
444int 462int
445channel_not_very_much_buffered_data(void) 463channel_not_very_much_buffered_data(void)
446{ 464{
@@ -470,7 +488,6 @@ channel_not_very_much_buffered_data(void)
470} 488}
471 489
472/* Returns true if any channel is still open. */ 490/* Returns true if any channel is still open. */
473
474int 491int
475channel_still_open(void) 492channel_still_open(void)
476{ 493{
@@ -513,7 +530,6 @@ channel_still_open(void)
513} 530}
514 531
515/* Returns the id of an open channel suitable for keepaliving */ 532/* Returns the id of an open channel suitable for keepaliving */
516
517int 533int
518channel_find_open(void) 534channel_find_open(void)
519{ 535{
@@ -558,7 +574,6 @@ channel_find_open(void)
558 * suitable for sending to the client. The message contains crlf pairs for 574 * suitable for sending to the client. The message contains crlf pairs for
559 * newlines. 575 * newlines.
560 */ 576 */
561
562char * 577char *
563channel_open_message(void) 578channel_open_message(void)
564{ 579{
@@ -643,6 +658,7 @@ channel_request_start(int id, char *service, int wantconfirm)
643 packet_put_cstring(service); 658 packet_put_cstring(service);
644 packet_put_char(wantconfirm); 659 packet_put_char(wantconfirm);
645} 660}
661
646void 662void
647channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) 663channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
648{ 664{
@@ -655,6 +671,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
655 c->confirm = fn; 671 c->confirm = fn;
656 c->confirm_ctx = ctx; 672 c->confirm_ctx = ctx;
657} 673}
674
658void 675void
659channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) 676channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
660{ 677{
@@ -667,6 +684,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
667 c->detach_user = fn; 684 c->detach_user = fn;
668 c->detach_close = do_close; 685 c->detach_close = do_close;
669} 686}
687
670void 688void
671channel_cancel_cleanup(int id) 689channel_cancel_cleanup(int id)
672{ 690{
@@ -679,6 +697,7 @@ channel_cancel_cleanup(int id)
679 c->detach_user = NULL; 697 c->detach_user = NULL;
680 c->detach_close = 0; 698 c->detach_close = 0;
681} 699}
700
682void 701void
683channel_register_filter(int id, channel_infilter_fn *ifn, 702channel_register_filter(int id, channel_infilter_fn *ifn,
684 channel_outfilter_fn *ofn) 703 channel_outfilter_fn *ofn)
@@ -718,25 +737,27 @@ channel_set_fds(int id, int rfd, int wfd, int efd,
718 * 'channel_post*': perform any appropriate operations for channels which 737 * 'channel_post*': perform any appropriate operations for channels which
719 * have events pending. 738 * have events pending.
720 */ 739 */
721typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset); 740typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset);
722chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; 741chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
723chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; 742chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
724 743
744/* ARGSUSED */
725static void 745static void
726channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset) 746channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset)
727{ 747{
728 FD_SET(c->sock, readset); 748 FD_SET(c->sock, readset);
729} 749}
730 750
751/* ARGSUSED */
731static void 752static void
732channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset) 753channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)
733{ 754{
734 debug3("channel %d: waiting for connection", c->self); 755 debug3("channel %d: waiting for connection", c->self);
735 FD_SET(c->sock, writeset); 756 FD_SET(c->sock, writeset);
736} 757}
737 758
738static void 759static void
739channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset) 760channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
740{ 761{
741 if (buffer_len(&c->input) < packet_get_maxsize()) 762 if (buffer_len(&c->input) < packet_get_maxsize())
742 FD_SET(c->sock, readset); 763 FD_SET(c->sock, readset);
@@ -745,16 +766,14 @@ channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
745} 766}
746 767
747static void 768static void
748channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset) 769channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
749{ 770{
750 u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); 771 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
751 772
752 /* check buffer limits */
753 limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
754
755 if (c->istate == CHAN_INPUT_OPEN && 773 if (c->istate == CHAN_INPUT_OPEN &&
756 limit > 0 && 774 limit > 0 &&
757 buffer_len(&c->input) < limit) 775 buffer_len(&c->input) < limit &&
776 buffer_check_alloc(&c->input, CHAN_RBUF))
758 FD_SET(c->rfd, readset); 777 FD_SET(c->rfd, readset);
759 if (c->ostate == CHAN_OUTPUT_OPEN || 778 if (c->ostate == CHAN_OUTPUT_OPEN ||
760 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 779 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
@@ -784,8 +803,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
784 FD_SET(c->ctl_fd, readset); 803 FD_SET(c->ctl_fd, readset);
785} 804}
786 805
806/* ARGSUSED */
787static void 807static void
788channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) 808channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
789{ 809{
790 if (buffer_len(&c->input) == 0) { 810 if (buffer_len(&c->input) == 0) {
791 packet_start(SSH_MSG_CHANNEL_CLOSE); 811 packet_start(SSH_MSG_CHANNEL_CLOSE);
@@ -796,8 +816,9 @@ channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
796 } 816 }
797} 817}
798 818
819/* ARGSUSED */
799static void 820static void
800channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) 821channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
801{ 822{
802 if (buffer_len(&c->output) == 0) 823 if (buffer_len(&c->output) == 0)
803 chan_mark_dead(c); 824 chan_mark_dead(c);
@@ -873,7 +894,7 @@ x11_open_helper(Buffer *b)
873} 894}
874 895
875static void 896static void
876channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) 897channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
877{ 898{
878 int ret = x11_open_helper(&c->output); 899 int ret = x11_open_helper(&c->output);
879 900
@@ -899,7 +920,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
899} 920}
900 921
901static void 922static void
902channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) 923channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
903{ 924{
904 int ret = x11_open_helper(&c->output); 925 int ret = x11_open_helper(&c->output);
905 926
@@ -925,8 +946,9 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
925} 946}
926 947
927/* try to decode a socks4 header */ 948/* try to decode a socks4 header */
949/* ARGSUSED */
928static int 950static int
929channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) 951channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
930{ 952{
931 char *p, *host; 953 char *p, *host;
932 u_int len, have, i, found; 954 u_int len, have, i, found;
@@ -990,7 +1012,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
990 s4_rsp.command = 90; /* cd: req granted */ 1012 s4_rsp.command = 90; /* cd: req granted */
991 s4_rsp.dest_port = 0; /* ignored */ 1013 s4_rsp.dest_port = 0; /* ignored */
992 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ 1014 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */
993 buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp)); 1015 buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp));
994 return 1; 1016 return 1;
995} 1017}
996 1018
@@ -1003,8 +1025,9 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
1003#define SSH_SOCKS5_CONNECT 0x01 1025#define SSH_SOCKS5_CONNECT 0x01
1004#define SSH_SOCKS5_SUCCESS 0x00 1026#define SSH_SOCKS5_SUCCESS 0x00
1005 1027
1028/* ARGSUSED */
1006static int 1029static int
1007channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) 1030channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1008{ 1031{
1009 struct { 1032 struct {
1010 u_int8_t version; 1033 u_int8_t version;
@@ -1014,7 +1037,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1014 } s5_req, s5_rsp; 1037 } s5_req, s5_rsp;
1015 u_int16_t dest_port; 1038 u_int16_t dest_port;
1016 u_char *p, dest_addr[255+1]; 1039 u_char *p, dest_addr[255+1];
1017 u_int have, i, found, nmethods, addrlen, af; 1040 u_int have, need, i, found, nmethods, addrlen, af;
1018 1041
1019 debug2("channel %d: decode socks5", c->self); 1042 debug2("channel %d: decode socks5", c->self);
1020 p = buffer_ptr(&c->input); 1043 p = buffer_ptr(&c->input);
@@ -1029,8 +1052,8 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1029 if (have < nmethods + 2) 1052 if (have < nmethods + 2)
1030 return 0; 1053 return 0;
1031 /* look for method: "NO AUTHENTICATION REQUIRED" */ 1054 /* look for method: "NO AUTHENTICATION REQUIRED" */
1032 for (found = 0, i = 2 ; i < nmethods + 2; i++) { 1055 for (found = 0, i = 2; i < nmethods + 2; i++) {
1033 if (p[i] == SSH_SOCKS5_NOAUTH ) { 1056 if (p[i] == SSH_SOCKS5_NOAUTH) {
1034 found = 1; 1057 found = 1;
1035 break; 1058 break;
1036 } 1059 }
@@ -1051,7 +1074,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1051 debug2("channel %d: socks5 post auth", c->self); 1074 debug2("channel %d: socks5 post auth", c->self);
1052 if (have < sizeof(s5_req)+1) 1075 if (have < sizeof(s5_req)+1)
1053 return 0; /* need more */ 1076 return 0; /* need more */
1054 memcpy((char *)&s5_req, p, sizeof(s5_req)); 1077 memcpy(&s5_req, p, sizeof(s5_req));
1055 if (s5_req.version != 0x05 || 1078 if (s5_req.version != 0x05 ||
1056 s5_req.command != SSH_SOCKS5_CONNECT || 1079 s5_req.command != SSH_SOCKS5_CONNECT ||
1057 s5_req.reserved != 0x00) { 1080 s5_req.reserved != 0x00) {
@@ -1075,7 +1098,10 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1075 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); 1098 debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
1076 return -1; 1099 return -1;
1077 } 1100 }
1078 if (have < 4 + addrlen + 2) 1101 need = sizeof(s5_req) + addrlen + 2;
1102 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1103 need++;
1104 if (have < need)
1079 return 0; 1105 return 0;
1080 buffer_consume(&c->input, sizeof(s5_req)); 1106 buffer_consume(&c->input, sizeof(s5_req));
1081 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) 1107 if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
@@ -1099,15 +1125,15 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
1099 ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY; 1125 ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
1100 dest_port = 0; /* ignored */ 1126 dest_port = 0; /* ignored */
1101 1127
1102 buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp)); 1128 buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp));
1103 buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr)); 1129 buffer_append(&c->output, &dest_addr, sizeof(struct in_addr));
1104 buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port)); 1130 buffer_append(&c->output, &dest_port, sizeof(dest_port));
1105 return 1; 1131 return 1;
1106} 1132}
1107 1133
1108/* dynamic port forwarding */ 1134/* dynamic port forwarding */
1109static void 1135static void
1110channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) 1136channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
1111{ 1137{
1112 u_char *p; 1138 u_char *p;
1113 u_int have; 1139 u_int have;
@@ -1150,8 +1176,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
1150} 1176}
1151 1177
1152/* This is our fake X11 server socket. */ 1178/* This is our fake X11 server socket. */
1179/* ARGSUSED */
1153static void 1180static void
1154channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) 1181channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
1155{ 1182{
1156 Channel *nc; 1183 Channel *nc;
1157 struct sockaddr addr; 1184 struct sockaddr addr;
@@ -1275,8 +1302,9 @@ channel_set_reuseaddr(int fd)
1275/* 1302/*
1276 * This socket is listening for connections to a forwarded TCP/IP port. 1303 * This socket is listening for connections to a forwarded TCP/IP port.
1277 */ 1304 */
1305/* ARGSUSED */
1278static void 1306static void
1279channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) 1307channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1280{ 1308{
1281 Channel *nc; 1309 Channel *nc;
1282 struct sockaddr addr; 1310 struct sockaddr addr;
@@ -1332,8 +1360,9 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
1332 * This is the authentication agent socket listening for connections from 1360 * This is the authentication agent socket listening for connections from
1333 * clients. 1361 * clients.
1334 */ 1362 */
1363/* ARGSUSED */
1335static void 1364static void
1336channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) 1365channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
1337{ 1366{
1338 Channel *nc; 1367 Channel *nc;
1339 int newsock; 1368 int newsock;
@@ -1365,8 +1394,9 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
1365 } 1394 }
1366} 1395}
1367 1396
1397/* ARGSUSED */
1368static void 1398static void
1369channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset) 1399channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1370{ 1400{
1371 int err = 0; 1401 int err = 0;
1372 socklen_t sz = sizeof(err); 1402 socklen_t sz = sizeof(err);
@@ -1411,18 +1441,26 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
1411 } 1441 }
1412} 1442}
1413 1443
1444/* ARGSUSED */
1414static int 1445static int
1415channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) 1446channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
1416{ 1447{
1417 char buf[CHAN_RBUF]; 1448 char buf[CHAN_RBUF];
1418 int len; 1449 int len;
1419 1450
1420 if (c->rfd != -1 && 1451 if (c->rfd != -1 &&
1421 FD_ISSET(c->rfd, readset)) { 1452 (c->detach_close || FD_ISSET(c->rfd, readset))) {
1453 errno = 0;
1422 len = read(c->rfd, buf, sizeof(buf)); 1454 len = read(c->rfd, buf, sizeof(buf));
1423 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1455 if (len < 0 && (errno == EINTR ||
1456 (errno == EAGAIN && !(c->isatty && c->detach_close))))
1424 return 1; 1457 return 1;
1458#ifndef PTY_ZEROREAD
1425 if (len <= 0) { 1459 if (len <= 0) {
1460#else
1461 if ((!c->isatty && len <= 0) ||
1462 (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
1463#endif
1426 debug2("channel %d: read<=0 rfd %d len %d", 1464 debug2("channel %d: read<=0 rfd %d len %d",
1427 c->self, c->rfd, len); 1465 c->self, c->rfd, len);
1428 if (c->type != SSH_CHANNEL_OPEN) { 1466 if (c->type != SSH_CHANNEL_OPEN) {
@@ -1451,8 +1489,10 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
1451 } 1489 }
1452 return 1; 1490 return 1;
1453} 1491}
1492
1493/* ARGSUSED */
1454static int 1494static int
1455channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) 1495channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
1456{ 1496{
1457 struct termios tio; 1497 struct termios tio;
1458 u_char *data = NULL, *buf; 1498 u_char *data = NULL, *buf;
@@ -1538,8 +1578,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
1538 } 1578 }
1539 return 1; 1579 return 1;
1540} 1580}
1581
1541static int 1582static int
1542channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) 1583channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
1543{ 1584{
1544 char buf[CHAN_RBUF]; 1585 char buf[CHAN_RBUF];
1545 int len; 1586 int len;
@@ -1564,11 +1605,12 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
1564 c->local_consumed += len; 1605 c->local_consumed += len;
1565 } 1606 }
1566 } else if (c->extended_usage == CHAN_EXTENDED_READ && 1607 } else if (c->extended_usage == CHAN_EXTENDED_READ &&
1567 FD_ISSET(c->efd, readset)) { 1608 (c->detach_close || FD_ISSET(c->efd, readset))) {
1568 len = read(c->efd, buf, sizeof(buf)); 1609 len = read(c->efd, buf, sizeof(buf));
1569 debug2("channel %d: read %d from efd %d", 1610 debug2("channel %d: read %d from efd %d",
1570 c->self, len, c->efd); 1611 c->self, len, c->efd);
1571 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 1612 if (len < 0 && (errno == EINTR ||
1613 (errno == EAGAIN && !c->detach_close)))
1572 return 1; 1614 return 1;
1573 if (len <= 0) { 1615 if (len <= 0) {
1574 debug2("channel %d: closing read-efd %d", 1616 debug2("channel %d: closing read-efd %d",
@@ -1581,8 +1623,10 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
1581 } 1623 }
1582 return 1; 1624 return 1;
1583} 1625}
1626
1627/* ARGSUSED */
1584static int 1628static int
1585channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset) 1629channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
1586{ 1630{
1587 char buf[16]; 1631 char buf[16];
1588 int len; 1632 int len;
@@ -1608,6 +1652,7 @@ channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
1608 } 1652 }
1609 return 1; 1653 return 1;
1610} 1654}
1655
1611static int 1656static int
1612channel_check_window(Channel *c) 1657channel_check_window(Channel *c)
1613{ 1658{
@@ -1629,7 +1674,7 @@ channel_check_window(Channel *c)
1629} 1674}
1630 1675
1631static void 1676static void
1632channel_post_open(Channel *c, fd_set * readset, fd_set * writeset) 1677channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
1633{ 1678{
1634 if (c->delayed) 1679 if (c->delayed)
1635 return; 1680 return;
@@ -1642,8 +1687,9 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
1642 channel_check_window(c); 1687 channel_check_window(c);
1643} 1688}
1644 1689
1690/* ARGSUSED */
1645static void 1691static void
1646channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset) 1692channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
1647{ 1693{
1648 int len; 1694 int len;
1649 1695
@@ -1760,7 +1806,7 @@ channel_garbage_collect(Channel *c)
1760} 1806}
1761 1807
1762static void 1808static void
1763channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) 1809channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
1764{ 1810{
1765 static int did_init = 0; 1811 static int did_init = 0;
1766 u_int i; 1812 u_int i;
@@ -1788,15 +1834,20 @@ void
1788channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 1834channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
1789 u_int *nallocp, int rekeying) 1835 u_int *nallocp, int rekeying)
1790{ 1836{
1791 u_int n, sz; 1837 u_int n, sz, nfdset;
1792 1838
1793 n = MAX(*maxfdp, channel_max_fd); 1839 n = MAX(*maxfdp, channel_max_fd);
1794 1840
1795 sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); 1841 nfdset = howmany(n+1, NFDBITS);
1842 /* Explicitly test here, because xrealloc isn't always called */
1843 if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask))
1844 fatal("channel_prepare_select: max_fd (%d) is too large", n);
1845 sz = nfdset * sizeof(fd_mask);
1846
1796 /* perhaps check sz < nalloc/2 and shrink? */ 1847 /* perhaps check sz < nalloc/2 and shrink? */
1797 if (*readsetp == NULL || sz > *nallocp) { 1848 if (*readsetp == NULL || sz > *nallocp) {
1798 *readsetp = xrealloc(*readsetp, sz); 1849 *readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask));
1799 *writesetp = xrealloc(*writesetp, sz); 1850 *writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask));
1800 *nallocp = sz; 1851 *nallocp = sz;
1801 } 1852 }
1802 *maxfdp = n; 1853 *maxfdp = n;
@@ -1812,14 +1863,13 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
1812 * events pending. 1863 * events pending.
1813 */ 1864 */
1814void 1865void
1815channel_after_select(fd_set * readset, fd_set * writeset) 1866channel_after_select(fd_set *readset, fd_set *writeset)
1816{ 1867{
1817 channel_handler(channel_post, readset, writeset); 1868 channel_handler(channel_post, readset, writeset);
1818} 1869}
1819 1870
1820 1871
1821/* If there is data to send to the connection, enqueue some of it now. */ 1872/* If there is data to send to the connection, enqueue some of it now. */
1822
1823void 1873void
1824channel_output_poll(void) 1874channel_output_poll(void)
1825{ 1875{
@@ -1940,6 +1990,7 @@ channel_output_poll(void)
1940 1990
1941/* -- protocol input */ 1991/* -- protocol input */
1942 1992
1993/* ARGSUSED */
1943void 1994void
1944channel_input_data(int type, u_int32_t seq, void *ctxt) 1995channel_input_data(int type, u_int32_t seq, void *ctxt)
1945{ 1996{
@@ -1999,6 +2050,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
1999 xfree(data); 2050 xfree(data);
2000} 2051}
2001 2052
2053/* ARGSUSED */
2002void 2054void
2003channel_input_extended_data(int type, u_int32_t seq, void *ctxt) 2055channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
2004{ 2056{
@@ -2045,6 +2097,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
2045 xfree(data); 2097 xfree(data);
2046} 2098}
2047 2099
2100/* ARGSUSED */
2048void 2101void
2049channel_input_ieof(int type, u_int32_t seq, void *ctxt) 2102channel_input_ieof(int type, u_int32_t seq, void *ctxt)
2050{ 2103{
@@ -2068,6 +2121,7 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
2068 2121
2069} 2122}
2070 2123
2124/* ARGSUSED */
2071void 2125void
2072channel_input_close(int type, u_int32_t seq, void *ctxt) 2126channel_input_close(int type, u_int32_t seq, void *ctxt)
2073{ 2127{
@@ -2106,6 +2160,7 @@ channel_input_close(int type, u_int32_t seq, void *ctxt)
2106} 2160}
2107 2161
2108/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ 2162/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
2163/* ARGSUSED */
2109void 2164void
2110channel_input_oclose(int type, u_int32_t seq, void *ctxt) 2165channel_input_oclose(int type, u_int32_t seq, void *ctxt)
2111{ 2166{
@@ -2118,6 +2173,7 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
2118 chan_rcvd_oclose(c); 2173 chan_rcvd_oclose(c);
2119} 2174}
2120 2175
2176/* ARGSUSED */
2121void 2177void
2122channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) 2178channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
2123{ 2179{
@@ -2134,6 +2190,7 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
2134 channel_free(c); 2190 channel_free(c);
2135} 2191}
2136 2192
2193/* ARGSUSED */
2137void 2194void
2138channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) 2195channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
2139{ 2196{
@@ -2181,6 +2238,7 @@ reason2txt(int reason)
2181 return "unknown reason"; 2238 return "unknown reason";
2182} 2239}
2183 2240
2241/* ARGSUSED */
2184void 2242void
2185channel_input_open_failure(int type, u_int32_t seq, void *ctxt) 2243channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2186{ 2244{
@@ -2212,6 +2270,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2212 channel_free(c); 2270 channel_free(c);
2213} 2271}
2214 2272
2273/* ARGSUSED */
2215void 2274void
2216channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) 2275channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
2217{ 2276{
@@ -2236,6 +2295,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
2236 c->remote_window += adjust; 2295 c->remote_window += adjust;
2237} 2296}
2238 2297
2298/* ARGSUSED */
2239void 2299void
2240channel_input_port_open(int type, u_int32_t seq, void *ctxt) 2300channel_input_port_open(int type, u_int32_t seq, void *ctxt)
2241{ 2301{
@@ -2454,7 +2514,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
2454 * the secure channel to host:port from local side. 2514 * the secure channel to host:port from local side.
2455 */ 2515 */
2456 2516
2457void 2517int
2458channel_request_remote_forwarding(const char *listen_host, u_short listen_port, 2518channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2459 const char *host_to_connect, u_short port_to_connect) 2519 const char *host_to_connect, u_short port_to_connect)
2460{ 2520{
@@ -2467,11 +2527,18 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2467 /* Send the forward request to the remote side. */ 2527 /* Send the forward request to the remote side. */
2468 if (compat20) { 2528 if (compat20) {
2469 const char *address_to_bind; 2529 const char *address_to_bind;
2470 if (listen_host == NULL) 2530 if (listen_host == NULL) {
2471 address_to_bind = "localhost"; 2531 if (datafellows & SSH_BUG_RFWD_ADDR)
2472 else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) 2532 address_to_bind = "127.0.0.1";
2473 address_to_bind = ""; 2533 else
2474 else 2534 address_to_bind = "localhost";
2535 } else if (*listen_host == '\0' ||
2536 strcmp(listen_host, "*") == 0) {
2537 if (datafellows & SSH_BUG_RFWD_ADDR)
2538 address_to_bind = "0.0.0.0";
2539 else
2540 address_to_bind = "";
2541 } else
2475 address_to_bind = listen_host; 2542 address_to_bind = listen_host;
2476 2543
2477 packet_start(SSH2_MSG_GLOBAL_REQUEST); 2544 packet_start(SSH2_MSG_GLOBAL_REQUEST);
@@ -2498,7 +2565,6 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2498 success = 1; 2565 success = 1;
2499 break; 2566 break;
2500 case SSH_SMSG_FAILURE: 2567 case SSH_SMSG_FAILURE:
2501 logit("Warning: Server denied remote port forwarding.");
2502 break; 2568 break;
2503 default: 2569 default:
2504 /* Unknown packet */ 2570 /* Unknown packet */
@@ -2512,6 +2578,7 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
2512 permitted_opens[num_permitted_opens].listen_port = listen_port; 2578 permitted_opens[num_permitted_opens].listen_port = listen_port;
2513 num_permitted_opens++; 2579 num_permitted_opens++;
2514 } 2580 }
2581 return (success ? 0 : -1);
2515} 2582}
2516 2583
2517/* 2584/*
@@ -2551,13 +2618,13 @@ channel_request_rforward_cancel(const char *host, u_short port)
2551/* 2618/*
2552 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 2619 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
2553 * listening for the port, and sends back a success reply (or disconnect 2620 * listening for the port, and sends back a success reply (or disconnect
2554 * message if there was an error). This never returns if there was an error. 2621 * message if there was an error).
2555 */ 2622 */
2556 2623int
2557void
2558channel_input_port_forward_request(int is_root, int gateway_ports) 2624channel_input_port_forward_request(int is_root, int gateway_ports)
2559{ 2625{
2560 u_short port, host_port; 2626 u_short port, host_port;
2627 int success = 0;
2561 char *hostname; 2628 char *hostname;
2562 2629
2563 /* Get arguments from the packet. */ 2630 /* Get arguments from the packet. */
@@ -2579,11 +2646,13 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
2579#endif 2646#endif
2580 2647
2581 /* Initiate forwarding */ 2648 /* Initiate forwarding */
2582 channel_setup_local_fwd_listener(NULL, port, hostname, 2649 success = channel_setup_local_fwd_listener(NULL, port, hostname,
2583 host_port, gateway_ports); 2650 host_port, gateway_ports);
2584 2651
2585 /* Free the argument string. */ 2652 /* Free the argument string. */
2586 xfree(hostname); 2653 xfree(hostname);
2654
2655 return (success ? 0 : -1);
2587} 2656}
2588 2657
2589/* 2658/*
@@ -2602,7 +2671,7 @@ void
2602channel_add_permitted_opens(char *host, int port) 2671channel_add_permitted_opens(char *host, int port)
2603{ 2672{
2604 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) 2673 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
2605 fatal("channel_request_remote_forwarding: too many forwards"); 2674 fatal("channel_add_permitted_opens: too many forwards");
2606 debug("allow port forwarding to host %s port %d", host, port); 2675 debug("allow port forwarding to host %s port %d", host, port);
2607 2676
2608 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); 2677 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
@@ -2612,6 +2681,19 @@ channel_add_permitted_opens(char *host, int port)
2612 all_opens_permitted = 0; 2681 all_opens_permitted = 0;
2613} 2682}
2614 2683
2684int
2685channel_add_adm_permitted_opens(char *host, int port)
2686{
2687 if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
2688 fatal("channel_add_adm_permitted_opens: too many forwards");
2689 debug("config allows port forwarding to host %s port %d", host, port);
2690
2691 permitted_adm_opens[num_adm_permitted_opens].host_to_connect
2692 = xstrdup(host);
2693 permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
2694 return ++num_adm_permitted_opens;
2695}
2696
2615void 2697void
2616channel_clear_permitted_opens(void) 2698channel_clear_permitted_opens(void)
2617{ 2699{
@@ -2621,9 +2703,18 @@ channel_clear_permitted_opens(void)
2621 if (permitted_opens[i].host_to_connect != NULL) 2703 if (permitted_opens[i].host_to_connect != NULL)
2622 xfree(permitted_opens[i].host_to_connect); 2704 xfree(permitted_opens[i].host_to_connect);
2623 num_permitted_opens = 0; 2705 num_permitted_opens = 0;
2624
2625} 2706}
2626 2707
2708void
2709channel_clear_adm_permitted_opens(void)
2710{
2711 int i;
2712
2713 for (i = 0; i < num_adm_permitted_opens; i++)
2714 if (permitted_adm_opens[i].host_to_connect != NULL)
2715 xfree(permitted_adm_opens[i].host_to_connect);
2716 num_adm_permitted_opens = 0;
2717}
2627 2718
2628/* return socket to remote host, port */ 2719/* return socket to remote host, port */
2629static int 2720static int
@@ -2701,7 +2792,7 @@ channel_connect_by_listen_address(u_short listen_port)
2701int 2792int
2702channel_connect_to(const char *host, u_short port) 2793channel_connect_to(const char *host, u_short port)
2703{ 2794{
2704 int i, permit; 2795 int i, permit, permit_adm = 1;
2705 2796
2706 permit = all_opens_permitted; 2797 permit = all_opens_permitted;
2707 if (!permit) { 2798 if (!permit) {
@@ -2710,9 +2801,19 @@ channel_connect_to(const char *host, u_short port)
2710 permitted_opens[i].port_to_connect == port && 2801 permitted_opens[i].port_to_connect == port &&
2711 strcmp(permitted_opens[i].host_to_connect, host) == 0) 2802 strcmp(permitted_opens[i].host_to_connect, host) == 0)
2712 permit = 1; 2803 permit = 1;
2804 }
2713 2805
2806 if (num_adm_permitted_opens > 0) {
2807 permit_adm = 0;
2808 for (i = 0; i < num_adm_permitted_opens; i++)
2809 if (permitted_adm_opens[i].host_to_connect != NULL &&
2810 permitted_adm_opens[i].port_to_connect == port &&
2811 strcmp(permitted_adm_opens[i].host_to_connect, host)
2812 == 0)
2813 permit_adm = 1;
2714 } 2814 }
2715 if (!permit) { 2815
2816 if (!permit || !permit_adm) {
2716 logit("Received request to connect to host %.100s port %d, " 2817 logit("Received request to connect to host %.100s port %d, "
2717 "but the request was denied.", host, port); 2818 "but the request was denied.", host, port);
2718 return -1; 2819 return -1;
@@ -2733,10 +2834,10 @@ channel_send_window_changes(void)
2733 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) 2834 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
2734 continue; 2835 continue;
2735 channel_request_start(i, "window-change", 0); 2836 channel_request_start(i, "window-change", 0);
2736 packet_put_int(ws.ws_col); 2837 packet_put_int((u_int)ws.ws_col);
2737 packet_put_int(ws.ws_row); 2838 packet_put_int((u_int)ws.ws_row);
2738 packet_put_int(ws.ws_xpixel); 2839 packet_put_int((u_int)ws.ws_xpixel);
2739 packet_put_int(ws.ws_ypixel); 2840 packet_put_int((u_int)ws.ws_ypixel);
2740 packet_send(); 2841 packet_send();
2741 } 2842 }
2742} 2843}
@@ -2848,7 +2949,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
2848 } 2949 }
2849 2950
2850 /* Allocate a channel for each socket. */ 2951 /* Allocate a channel for each socket. */
2851 *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); 2952 *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
2852 for (n = 0; n < num_socks; n++) { 2953 for (n = 0; n < num_socks; n++) {
2853 sock = socks[n]; 2954 sock = socks[n];
2854 nc = channel_new("x11 listener", 2955 nc = channel_new("x11 listener",
@@ -2877,7 +2978,7 @@ connect_local_xsocket(u_int dnr)
2877 memset(&addr, 0, sizeof(addr)); 2978 memset(&addr, 0, sizeof(addr));
2878 addr.sun_family = AF_UNIX; 2979 addr.sun_family = AF_UNIX;
2879 snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr); 2980 snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
2880 if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0) 2981 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
2881 return sock; 2982 return sock;
2882 close(sock); 2983 close(sock);
2883 error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); 2984 error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
@@ -2887,12 +2988,12 @@ connect_local_xsocket(u_int dnr)
2887int 2988int
2888x11_connect_display(void) 2989x11_connect_display(void)
2889{ 2990{
2890 int display_number, sock = 0; 2991 u_int display_number;
2891 const char *display; 2992 const char *display;
2892 char buf[1024], *cp; 2993 char buf[1024], *cp;
2893 struct addrinfo hints, *ai, *aitop; 2994 struct addrinfo hints, *ai, *aitop;
2894 char strport[NI_MAXSERV]; 2995 char strport[NI_MAXSERV];
2895 int gaierr; 2996 int gaierr, sock = 0;
2896 2997
2897 /* Try to open a socket for the local X server. */ 2998 /* Try to open a socket for the local X server. */
2898 display = getenv("DISPLAY"); 2999 display = getenv("DISPLAY");
@@ -2912,7 +3013,7 @@ x11_connect_display(void)
2912 if (strncmp(display, "unix:", 5) == 0 || 3013 if (strncmp(display, "unix:", 5) == 0 ||
2913 display[0] == ':') { 3014 display[0] == ':') {
2914 /* Connect to the unix domain socket. */ 3015 /* Connect to the unix domain socket. */
2915 if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) { 3016 if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) {
2916 error("Could not parse display number from DISPLAY: %.100s", 3017 error("Could not parse display number from DISPLAY: %.100s",
2917 display); 3018 display);
2918 return -1; 3019 return -1;
@@ -2937,7 +3038,7 @@ x11_connect_display(void)
2937 } 3038 }
2938 *cp = 0; 3039 *cp = 0;
2939 /* buf now contains the host name. But first we parse the display number. */ 3040 /* buf now contains the host name. But first we parse the display number. */
2940 if (sscanf(cp + 1, "%d", &display_number) != 1) { 3041 if (sscanf(cp + 1, "%u", &display_number) != 1) {
2941 error("Could not parse display number from DISPLAY: %.100s", 3042 error("Could not parse display number from DISPLAY: %.100s",
2942 display); 3043 display);
2943 return -1; 3044 return -1;
@@ -2947,7 +3048,7 @@ x11_connect_display(void)
2947 memset(&hints, 0, sizeof(hints)); 3048 memset(&hints, 0, sizeof(hints));
2948 hints.ai_family = IPv4or6; 3049 hints.ai_family = IPv4or6;
2949 hints.ai_socktype = SOCK_STREAM; 3050 hints.ai_socktype = SOCK_STREAM;
2950 snprintf(strport, sizeof strport, "%d", 6000 + display_number); 3051 snprintf(strport, sizeof strport, "%u", 6000 + display_number);
2951 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { 3052 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
2952 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); 3053 error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
2953 return -1; 3054 return -1;
@@ -2961,7 +3062,7 @@ x11_connect_display(void)
2961 } 3062 }
2962 /* Connect it to the display. */ 3063 /* Connect it to the display. */
2963 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 3064 if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
2964 debug2("connect %.100s port %d: %.100s", buf, 3065 debug2("connect %.100s port %u: %.100s", buf,
2965 6000 + display_number, strerror(errno)); 3066 6000 + display_number, strerror(errno));
2966 close(sock); 3067 close(sock);
2967 continue; 3068 continue;
@@ -2971,7 +3072,7 @@ x11_connect_display(void)
2971 } 3072 }
2972 freeaddrinfo(aitop); 3073 freeaddrinfo(aitop);
2973 if (!ai) { 3074 if (!ai) {
2974 error("connect %.100s port %d: %.100s", buf, 6000 + display_number, 3075 error("connect %.100s port %u: %.100s", buf, 6000 + display_number,
2975 strerror(errno)); 3076 strerror(errno));
2976 return -1; 3077 return -1;
2977 } 3078 }
@@ -2985,6 +3086,7 @@ x11_connect_display(void)
2985 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. 3086 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
2986 */ 3087 */
2987 3088
3089/* ARGSUSED */
2988void 3090void
2989x11_input_open(int type, u_int32_t seq, void *ctxt) 3091x11_input_open(int type, u_int32_t seq, void *ctxt)
2990{ 3092{
@@ -3028,6 +3130,7 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
3028} 3130}
3029 3131
3030/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ 3132/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
3133/* ARGSUSED */
3031void 3134void
3032deny_input_open(int type, u_int32_t seq, void *ctxt) 3135deny_input_open(int type, u_int32_t seq, void *ctxt)
3033{ 3136{
@@ -3074,13 +3177,11 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
3074 return; 3177 return;
3075 } 3178 }
3076 3179
3077 cp = disp; 3180 cp = strchr(disp, ':');
3078 if (disp)
3079 cp = strchr(disp, ':');
3080 if (cp) 3181 if (cp)
3081 cp = strchr(cp, '.'); 3182 cp = strchr(cp, '.');
3082 if (cp) 3183 if (cp)
3083 screen_number = atoi(cp + 1); 3184 screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
3084 else 3185 else
3085 screen_number = 0; 3186 screen_number = 0;
3086 3187