View | Details | Raw Unified | Return to bug 2417 | Differences between
and this patch

Collapse All | Expand All

(-)a/channels.c (-13 / +75 lines)
Lines 82-87 Link Here
82
#include "key.h"
82
#include "key.h"
83
#include "authfd.h"
83
#include "authfd.h"
84
#include "pathnames.h"
84
#include "pathnames.h"
85
#include "ssherr.h"
85
86
86
/* -- channel core */
87
/* -- channel core */
87
88
Lines 1161-1177 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1161
#define SSH_SOCKS5_IPV6		0x04
1162
#define SSH_SOCKS5_IPV6		0x04
1162
#define SSH_SOCKS5_CONNECT	0x01
1163
#define SSH_SOCKS5_CONNECT	0x01
1163
#define SSH_SOCKS5_SUCCESS	0x00
1164
#define SSH_SOCKS5_SUCCESS	0x00
1165
#define SSH_SOCKS5_GENERICERROR	0x01
1166
#define SSH_SOCKS5_RULESETBLOCK	0x02
1167
#define SSH_SOCKS5_CONNREFUSED	0x05
1168
#define SSH_SOCKS5_BADATYP	0x08
1169
1170
struct socks5_msg {
1171
	u_int8_t version;
1172
	u_int8_t command;
1173
	u_int8_t reserved;
1174
	u_int8_t atyp;
1175
};
1176
1177
static void
1178
socks5_error(Channel *c, u_int8_t code)
1179
{
1180
	struct socks5_msg e;
1181
	int r;
1182
1183
	memset(&e, 0, sizeof(e));
1184
	if ((r = sshbuf_put_u8(&c->output, 5)) != 0 ||	/* version */
1185
	    (r = sshbuf_put_u8(&c->output, code)) != 0 ||
1186
	    (r = sshbuf_put_u8(&c->output, 0)) != 0 ||	/* reserved */
1187
	    (r = sshbuf_put_u8(&c->output, SSH_SOCKS5_DOMAIN)) != 0 ||
1188
	    (r = sshbuf_put_u8(&c->output, 0)) != 0 ||	/* fake addr len = 0 */
1189
	    (r = sshbuf_put_u16(&c->output, 0)) != 0)	/* fake port number */
1190
		fatal("%s: construct SOCKS5 reply: %s", __func__, ssh_err(r));
1191
	/* Don't try to do anything further with this request */
1192
	sshbuf_reset(&c->input);
1193
}
1164
1194
1165
/* ARGSUSED */
1195
/* ARGSUSED */
1166
static int
1196
static int
1167
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1197
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1168
{
1198
{
1169
	struct {
1199
	struct socks5_msg s5_req, s5_rsp;
1170
		u_int8_t version;
1171
		u_int8_t command;
1172
		u_int8_t reserved;
1173
		u_int8_t atyp;
1174
	} s5_req, s5_rsp;
1175
	u_int16_t dest_port;
1200
	u_int16_t dest_port;
1176
	char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
1201
	char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
1177
	u_char *p;
1202
	u_char *p;
Lines 1199-1204 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1199
		if (!found) {
1224
		if (!found) {
1200
			debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
1225
			debug("channel %d: method SSH_SOCKS5_NOAUTH not found",
1201
			    c->self);
1226
			    c->self);
1227
			socks5_error(c, SSH_SOCKS5_GENERICERROR);
1228
			FD_SET(c->sock, writeset);
1202
			return -1;
1229
			return -1;
1203
		}
1230
		}
1204
		buffer_consume(&c->input, nmethods + 2);
1231
		buffer_consume(&c->input, nmethods + 2);
Lines 1217-1222 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1217
	    s5_req.command != SSH_SOCKS5_CONNECT ||
1244
	    s5_req.command != SSH_SOCKS5_CONNECT ||
1218
	    s5_req.reserved != 0x00) {
1245
	    s5_req.reserved != 0x00) {
1219
		debug2("channel %d: only socks5 connect supported", c->self);
1246
		debug2("channel %d: only socks5 connect supported", c->self);
1247
		socks5_error(c, SSH_SOCKS5_GENERICERROR);
1248
		FD_SET(c->sock, writeset);
1220
		return -1;
1249
		return -1;
1221
	}
1250
	}
1222
	switch (s5_req.atyp){
1251
	switch (s5_req.atyp){
Lines 1234-1239 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1234
		break;
1263
		break;
1235
	default:
1264
	default:
1236
		debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
1265
		debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
1266
		socks5_error(c, SSH_SOCKS5_BADATYP);
1267
		FD_SET(c->sock, writeset);
1237
		return -1;
1268
		return -1;
1238
	}
1269
	}
1239
	need = sizeof(s5_req) + addrlen + 2;
1270
	need = sizeof(s5_req) + addrlen + 2;
Lines 1253-1264 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1253
		if (addrlen >= NI_MAXHOST) {
1284
		if (addrlen >= NI_MAXHOST) {
1254
			error("channel %d: dynamic request: socks5 hostname "
1285
			error("channel %d: dynamic request: socks5 hostname "
1255
			    "\"%.100s\" too long", c->self, dest_addr);
1286
			    "\"%.100s\" too long", c->self, dest_addr);
1287
			socks5_error(c, SSH_SOCKS5_RULESETBLOCK);
1288
			FD_SET(c->sock, writeset);
1256
			return -1;
1289
			return -1;
1257
		}
1290
		}
1258
		c->path = xstrdup(dest_addr);
1291
		c->path = xstrdup(dest_addr);
1259
	} else {
1292
	} else {
1260
		if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)
1293
		if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) {
1294
			error("channel %d: dynamic request: socks5 address "
1295
			    "invalid", c->self);
1296
			socks5_error(c, SSH_SOCKS5_RULESETBLOCK);
1297
			FD_SET(c->sock, writeset);
1261
			return -1;
1298
			return -1;
1299
		}
1262
		c->path = xstrdup(ntop);
1300
		c->path = xstrdup(ntop);
1263
	}
1301
	}
1264
	c->host_port = ntohs(dest_port);
1302
	c->host_port = ntohs(dest_port);
Lines 1333-1339 channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1333
		break;
1371
		break;
1334
	}
1372
	}
1335
	if (ret < 0) {
1373
	if (ret < 0) {
1336
		chan_mark_dead(c);
1374
		chan_read_failed(c);
1375
		c->type = SSH_CHANNEL_OUTPUT_DRAINING;
1337
	} else if (ret == 0) {
1376
	} else if (ret == 0) {
1338
		debug2("channel %d: pre_dynamic: need more", c->self);
1377
		debug2("channel %d: pre_dynamic: need more", c->self);
1339
		/* need more */
1378
		/* need more */
Lines 2012-2018 channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset) Link Here
2012
2051
2013
/* ARGSUSED */
2052
/* ARGSUSED */
2014
static void
2053
static void
2015
channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
2054
channel_post_output_drain(Channel *c, fd_set *readset, fd_set *writeset)
2016
{
2055
{
2017
	int len;
2056
	int len;
2018
2057
Lines 2043-2048 channel_handler_init_20(void) Link Here
2043
	channel_pre[SSH_CHANNEL_MUX_LISTENER] =		&channel_pre_listener;
2082
	channel_pre[SSH_CHANNEL_MUX_LISTENER] =		&channel_pre_listener;
2044
	channel_pre[SSH_CHANNEL_MUX_CLIENT] =		&channel_pre_mux_client;
2083
	channel_pre[SSH_CHANNEL_MUX_CLIENT] =		&channel_pre_mux_client;
2045
2084
2085
	channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_pre_output_draining;
2046
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2086
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2047
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
2087
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
2048
	channel_post[SSH_CHANNEL_RPORT_LISTENER] =	&channel_post_port_listener;
2088
	channel_post[SSH_CHANNEL_RPORT_LISTENER] =	&channel_post_port_listener;
Lines 2054-2059 channel_handler_init_20(void) Link Here
2054
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2094
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2055
	channel_post[SSH_CHANNEL_MUX_LISTENER] =	&channel_post_mux_listener;
2095
	channel_post[SSH_CHANNEL_MUX_LISTENER] =	&channel_post_mux_listener;
2056
	channel_post[SSH_CHANNEL_MUX_CLIENT] =		&channel_post_mux_client;
2096
	channel_post[SSH_CHANNEL_MUX_CLIENT] =		&channel_post_mux_client;
2097
	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain;
2057
}
2098
}
2058
2099
2059
static void
2100
static void
Lines 2073-2079 channel_handler_init_13(void) Link Here
2073
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
2114
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
2074
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
2115
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
2075
	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
2116
	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
2076
	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain_13;
2117
	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain;
2077
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2118
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2078
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2119
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2079
}
2120
}
Lines 2199-2205 channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, Link Here
2199
	u_int n, sz, nfdset;
2240
	u_int n, sz, nfdset;
2200
2241
2201
	n = MAX(*maxfdp, channel_max_fd);
2242
	n = MAX(*maxfdp, channel_max_fd);
2202
2203
	nfdset = howmany(n+1, NFDBITS);
2243
	nfdset = howmany(n+1, NFDBITS);
2204
	/* Explicitly test here, because xrealloc isn't always called */
2244
	/* Explicitly test here, because xrealloc isn't always called */
2205
	if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask))
2245
	if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask))
Lines 2615-2620 reason2txt(int reason) Link Here
2615
	return "unknown reason";
2655
	return "unknown reason";
2616
}
2656
}
2617
2657
2658
static int
2659
reason_to_socks5(int reason)
2660
{
2661
	switch (reason) {
2662
	case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
2663
		return SSH_SOCKS5_RULESETBLOCK;
2664
	case SSH2_OPEN_CONNECT_FAILED:
2665
		return SSH_SOCKS5_CONNREFUSED;
2666
	}
2667
	return SSH_SOCKS5_GENERICERROR;
2668
}
2669
2618
/* ARGSUSED */
2670
/* ARGSUSED */
2619
int
2671
int
2620
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
2672
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
Lines 2626-2632 channel_input_open_failure(int type, u_int32_t seq, void *ctxt) Link Here
2626
	id = packet_get_int();
2678
	id = packet_get_int();
2627
	c = channel_lookup(id);
2679
	c = channel_lookup(id);
2628
2680
2629
	if (c==NULL || c->type != SSH_CHANNEL_OPENING)
2681
	if (c == NULL || c->type != SSH_CHANNEL_OPENING)
2630
		packet_disconnect("Received open failure for "
2682
		packet_disconnect("Received open failure for "
2631
		    "non-opening channel %d.", id);
2683
		    "non-opening channel %d.", id);
2632
	if (compat20) {
2684
	if (compat20) {
Lines 2639-2644 channel_input_open_failure(int type, u_int32_t seq, void *ctxt) Link Here
2639
		    reason2txt(reason), msg ? ": ": "", msg ? msg : "");
2691
		    reason2txt(reason), msg ? ": ": "", msg ? msg : "");
2640
		free(msg);
2692
		free(msg);
2641
		free(lang);
2693
		free(lang);
2694
2695
		/* Translate failures to SOCKS codes */
2696
		if (c->remote_name != NULL &&
2697
		    strcmp(c->remote_name, "dynamic-tcpip") == 0 &&
2698
		    (c->flags & SSH_SOCKS5_AUTHDONE)) {
2699
			socks5_error(c, reason_to_socks5(reason));
2700
			/* XXX wakeup c->sock for reply */
2701
		}
2702
2642
		if (c->open_confirm) {
2703
		if (c->open_confirm) {
2643
			debug2("callback start");
2704
			debug2("callback start");
2644
			c->open_confirm(c->self, 0, c->open_confirm_ctx);
2705
			c->open_confirm(c->self, 0, c->open_confirm_ctx);
Lines 2647-2653 channel_input_open_failure(int type, u_int32_t seq, void *ctxt) Link Here
2647
	}
2708
	}
2648
	packet_check_eom();
2709
	packet_check_eom();
2649
	/* Schedule the channel for cleanup/deletion. */
2710
	/* Schedule the channel for cleanup/deletion. */
2650
	chan_mark_dead(c);
2711
	chan_read_failed(c);
2712
	c->type = SSH_CHANNEL_OUTPUT_DRAINING;
2651
	return 0;
2713
	return 0;
2652
}
2714
}
2653
2715
(-)a/regress/netcat.c (-1 / +3 lines)
Lines 1542-1548 socks_connect(const char *host, const char *port, Link Here
1542
			buf[0] = SOCKS_V5;
1542
			buf[0] = SOCKS_V5;
1543
			buf[1] = SOCKS_CONNECT;
1543
			buf[1] = SOCKS_CONNECT;
1544
			buf[2] = 0;
1544
			buf[2] = 0;
1545
			buf[3] = SOCKS_DOMAIN;
1545
			buf[3] = 99;
1546
			buf[4] = hlen;
1546
			buf[4] = hlen;
1547
			memcpy(buf + 5, host, hlen);			
1547
			memcpy(buf + 5, host, hlen);			
1548
			memcpy(buf + 5 + hlen, &serverport, sizeof serverport);
1548
			memcpy(buf + 5 + hlen, &serverport, sizeof serverport);
Lines 1554-1559 socks_connect(const char *host, const char *port, Link Here
1554
			buf[1] = SOCKS_CONNECT;
1554
			buf[1] = SOCKS_CONNECT;
1555
			buf[2] = 0;
1555
			buf[2] = 0;
1556
			buf[3] = SOCKS_IPV4;
1556
			buf[3] = SOCKS_IPV4;
1557
			buf[3] = 99;
1557
			memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
1558
			memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
1558
			memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port);
1559
			memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port);
1559
			wlen = 10;
1560
			wlen = 10;
Lines 1564-1569 socks_connect(const char *host, const char *port, Link Here
1564
			buf[1] = SOCKS_CONNECT;
1565
			buf[1] = SOCKS_CONNECT;
1565
			buf[2] = 0;
1566
			buf[2] = 0;
1566
			buf[3] = SOCKS_IPV6;
1567
			buf[3] = SOCKS_IPV6;
1568
			buf[3] = 99;
1567
			memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr);
1569
			memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr);
1568
			memcpy(buf + 20, &in6->sin6_port,
1570
			memcpy(buf + 20, &in6->sin6_port,
1569
			    sizeof in6->sin6_port);
1571
			    sizeof in6->sin6_port);

Return to bug 2417