View | Details | Raw Unified | Return to bug 2393
Collapse All | Expand All

(-)a/channels.c (-70 / +222 lines)
Lines 219-224 channel_lookup(int id) Link Here
219
	case SSH_CHANNEL_LARVAL:
219
	case SSH_CHANNEL_LARVAL:
220
	case SSH_CHANNEL_CONNECTING:
220
	case SSH_CHANNEL_CONNECTING:
221
	case SSH_CHANNEL_DYNAMIC:
221
	case SSH_CHANNEL_DYNAMIC:
222
	case SSH_CHANNEL_RDYNAMIC:
222
	case SSH_CHANNEL_OPENING:
223
	case SSH_CHANNEL_OPENING:
223
	case SSH_CHANNEL_OPEN:
224
	case SSH_CHANNEL_OPEN:
224
	case SSH_CHANNEL_INPUT_DRAINING:
225
	case SSH_CHANNEL_INPUT_DRAINING:
Lines 556-561 channel_still_open(void) Link Here
556
			continue;
557
			continue;
557
		case SSH_CHANNEL_OPENING:
558
		case SSH_CHANNEL_OPENING:
558
		case SSH_CHANNEL_OPEN:
559
		case SSH_CHANNEL_OPEN:
560
		case SSH_CHANNEL_RDYNAMIC:
559
		case SSH_CHANNEL_X11_OPEN:
561
		case SSH_CHANNEL_X11_OPEN:
560
		case SSH_CHANNEL_MUX_CLIENT:
562
		case SSH_CHANNEL_MUX_CLIENT:
561
			return 1;
563
			return 1;
Lines 601-606 channel_find_open(void) Link Here
601
		case SSH_CHANNEL_LARVAL:
603
		case SSH_CHANNEL_LARVAL:
602
		case SSH_CHANNEL_AUTH_SOCKET:
604
		case SSH_CHANNEL_AUTH_SOCKET:
603
		case SSH_CHANNEL_OPEN:
605
		case SSH_CHANNEL_OPEN:
606
		case SSH_CHANNEL_RDYNAMIC:
604
		case SSH_CHANNEL_X11_OPEN:
607
		case SSH_CHANNEL_X11_OPEN:
605
			return i;
608
			return i;
606
		case SSH_CHANNEL_INPUT_DRAINING:
609
		case SSH_CHANNEL_INPUT_DRAINING:
Lines 654-659 channel_open_message(void) Link Here
654
		case SSH_CHANNEL_OPENING:
657
		case SSH_CHANNEL_OPENING:
655
		case SSH_CHANNEL_CONNECTING:
658
		case SSH_CHANNEL_CONNECTING:
656
		case SSH_CHANNEL_DYNAMIC:
659
		case SSH_CHANNEL_DYNAMIC:
660
		case SSH_CHANNEL_RDYNAMIC:
657
		case SSH_CHANNEL_OPEN:
661
		case SSH_CHANNEL_OPEN:
658
		case SSH_CHANNEL_X11_OPEN:
662
		case SSH_CHANNEL_X11_OPEN:
659
		case SSH_CHANNEL_INPUT_DRAINING:
663
		case SSH_CHANNEL_INPUT_DRAINING:
Lines 1041-1047 channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1041
/* try to decode a socks4 header */
1045
/* try to decode a socks4 header */
1042
/* ARGSUSED */
1046
/* ARGSUSED */
1043
static int
1047
static int
1044
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1048
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset,
1049
	Buffer * input, Buffer * output)
1045
{
1050
{
1046
	char *p, *host;
1051
	char *p, *host;
1047
	u_int len, have, i, found, need;
1052
	u_int len, have, i, found, need;
Lines 1055-1065 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1055
1060
1056
	debug2("channel %d: decode socks4", c->self);
1061
	debug2("channel %d: decode socks4", c->self);
1057
1062
1058
	have = buffer_len(&c->input);
1063
	have = buffer_len(input);
1059
	len = sizeof(s4_req);
1064
	len = sizeof(s4_req);
1060
	if (have < len)
1065
	if (have < len)
1061
		return 0;
1066
		return 0;
1062
	p = (char *)buffer_ptr(&c->input);
1067
	p = (char *)buffer_ptr(input);
1063
1068
1064
	need = 1;
1069
	need = 1;
1065
	/* SOCKS4A uses an invalid IP address 0.0.0.x */
1070
	/* SOCKS4A uses an invalid IP address 0.0.0.x */
Lines 1084-1106 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1084
	}
1089
	}
1085
	if (found < need)
1090
	if (found < need)
1086
		return 0;
1091
		return 0;
1087
	buffer_get(&c->input, (char *)&s4_req.version, 1);
1092
	buffer_get(input, (char *)&s4_req.version, 1);
1088
	buffer_get(&c->input, (char *)&s4_req.command, 1);
1093
	buffer_get(input, (char *)&s4_req.command, 1);
1089
	buffer_get(&c->input, (char *)&s4_req.dest_port, 2);
1094
	buffer_get(input, (char *)&s4_req.dest_port, 2);
1090
	buffer_get(&c->input, (char *)&s4_req.dest_addr, 4);
1095
	buffer_get(input, (char *)&s4_req.dest_addr, 4);
1091
	have = buffer_len(&c->input);
1096
	have = buffer_len(input);
1092
	p = (char *)buffer_ptr(&c->input);
1097
	p = (char *)buffer_ptr(input);
1093
	if (memchr(p, '\0', have) == NULL)
1098
	if (memchr(p, '\0', have) == NULL) {
1094
		fatal("channel %d: decode socks4: user not nul terminated",
1099
		error("channel %d: decode socks4: user not nul terminated",
1095
		    c->self);
1100
		    c->self);
1101
		return -1;
1102
	}
1096
	len = strlen(p);
1103
	len = strlen(p);
1097
	debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1104
	debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1098
	len++;					/* trailing '\0' */
1105
	len++;					/* trailing '\0' */
1099
	if (len > have)
1106
	if (len > have) {
1100
		fatal("channel %d: decode socks4: len %d > have %d",
1107
		error("channel %d: decode socks4: len %d > have %d",
1101
		    c->self, len, have);
1108
		    c->self, len, have);
1109
		return -1;
1110
	}
1102
	strlcpy(username, p, sizeof(username));
1111
	strlcpy(username, p, sizeof(username));
1103
	buffer_consume(&c->input, len);
1112
	buffer_consume(input, len);
1104
1113
1105
	free(c->path);
1114
	free(c->path);
1106
	c->path = NULL;
1115
	c->path = NULL;
Lines 1108-1129 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1108
		host = inet_ntoa(s4_req.dest_addr);
1117
		host = inet_ntoa(s4_req.dest_addr);
1109
		c->path = xstrdup(host);
1118
		c->path = xstrdup(host);
1110
	} else {				/* SOCKS4A: two strings */
1119
	} else {				/* SOCKS4A: two strings */
1111
		have = buffer_len(&c->input);
1120
		have = buffer_len(input);
1112
		p = (char *)buffer_ptr(&c->input);
1121
		p = (char *)buffer_ptr(input);
1113
		len = strlen(p);
1122
		len = strlen(p);
1114
		debug2("channel %d: decode socks4a: host %s/%d",
1123
		debug2("channel %d: decode socks4a: host %s/%d",
1115
		    c->self, p, len);
1124
		    c->self, p, len);
1116
		len++;				/* trailing '\0' */
1125
		len++;				/* trailing '\0' */
1117
		if (len > have)
1126
		if (len > have) {
1118
			fatal("channel %d: decode socks4a: len %d > have %d",
1127
			error("channel %d: decode socks4a: len %d > have %d",
1119
			    c->self, len, have);
1128
			    c->self, len, have);
1129
			return -1;
1130
		}
1120
		if (len > NI_MAXHOST) {
1131
		if (len > NI_MAXHOST) {
1121
			error("channel %d: hostname \"%.100s\" too long",
1132
			error("channel %d: hostname \"%.100s\" too long",
1122
			    c->self, p);
1133
			    c->self, p);
1123
			return -1;
1134
			return -1;
1124
		}
1135
		}
1125
		c->path = xstrdup(p);
1136
		c->path = xstrdup(p);
1126
		buffer_consume(&c->input, len);
1137
		buffer_consume(input, len);
1127
	}
1138
	}
1128
	c->host_port = ntohs(s4_req.dest_port);
1139
	c->host_port = ntohs(s4_req.dest_port);
1129
1140
Lines 1139-1145 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1139
	s4_rsp.command = 90;			/* cd: req granted */
1150
	s4_rsp.command = 90;			/* cd: req granted */
1140
	s4_rsp.dest_port = 0;			/* ignored */
1151
	s4_rsp.dest_port = 0;			/* ignored */
1141
	s4_rsp.dest_addr.s_addr = INADDR_ANY;	/* ignored */
1152
	s4_rsp.dest_addr.s_addr = INADDR_ANY;	/* ignored */
1142
	buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp));
1153
	buffer_append(output, &s4_rsp, sizeof(s4_rsp));
1143
	return 1;
1154
	return 1;
1144
}
1155
}
1145
1156
Lines 1154-1160 channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1154
1165
1155
/* ARGSUSED */
1166
/* ARGSUSED */
1156
static int
1167
static int
1157
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1168
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset,
1169
	Buffer * input, Buffer * output)
1158
{
1170
{
1159
	struct {
1171
	struct {
1160
		u_int8_t version;
1172
		u_int8_t version;
Lines 1168-1177 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1168
	u_int have, need, i, found, nmethods, addrlen, af;
1180
	u_int have, need, i, found, nmethods, addrlen, af;
1169
1181
1170
	debug2("channel %d: decode socks5", c->self);
1182
	debug2("channel %d: decode socks5", c->self);
1171
	p = buffer_ptr(&c->input);
1183
	p = buffer_ptr(input);
1172
	if (p[0] != 0x05)
1184
	if (p[0] != 0x05)
1173
		return -1;
1185
		return -1;
1174
	have = buffer_len(&c->input);
1186
	have = buffer_len(input);
1175
	if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
1187
	if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
1176
		/* format: ver | nmethods | methods */
1188
		/* format: ver | nmethods | methods */
1177
		if (have < 2)
1189
		if (have < 2)
Lines 1191-1200 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1191
			    c->self);
1203
			    c->self);
1192
			return -1;
1204
			return -1;
1193
		}
1205
		}
1194
		buffer_consume(&c->input, nmethods + 2);
1206
		buffer_consume(input, nmethods + 2);
1195
		buffer_put_char(&c->output, 0x05);		/* version */
1207
		buffer_put_char(output, 0x05);		/* version */
1196
		buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH);	/* method */
1208
		buffer_put_char(output, SSH_SOCKS5_NOAUTH);	/* method */
1197
		FD_SET(c->sock, writeset);
1209
1210
		if (c->type == SSH_CHANNEL_DYNAMIC)
1211
			FD_SET(c->sock, writeset);
1212
1198
		c->flags |= SSH_SOCKS5_AUTHDONE;
1213
		c->flags |= SSH_SOCKS5_AUTHDONE;
1199
		debug2("channel %d: socks5 auth done", c->self);
1214
		debug2("channel %d: socks5 auth done", c->self);
1200
		return 0;				/* need more */
1215
		return 0;				/* need more */
Lines 1231-1241 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1231
		need++;
1246
		need++;
1232
	if (have < need)
1247
	if (have < need)
1233
		return 0;
1248
		return 0;
1234
	buffer_consume(&c->input, sizeof(s5_req));
1249
	buffer_consume(input, sizeof(s5_req));
1235
	if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1250
	if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
1236
		buffer_consume(&c->input, 1);    /* host string length */
1251
		buffer_consume(input, 1);    /* host string length */
1237
	buffer_get(&c->input, &dest_addr, addrlen);
1252
	buffer_get(input, &dest_addr, addrlen);
1238
	buffer_get(&c->input, (char *)&dest_port, 2);
1253
	buffer_get(input, (char *)&dest_port, 2);
1239
	dest_addr[addrlen] = '\0';
1254
	dest_addr[addrlen] = '\0';
1240
	free(c->path);
1255
	free(c->path);
1241
	c->path = NULL;
1256
	c->path = NULL;
Lines 1262-1270 channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1262
	s5_rsp.atyp = SSH_SOCKS5_IPV4;
1277
	s5_rsp.atyp = SSH_SOCKS5_IPV4;
1263
	dest_port = 0;				/* ignored */
1278
	dest_port = 0;				/* ignored */
1264
1279
1265
	buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp));
1280
	buffer_append(output, &s5_rsp, sizeof(s5_rsp));
1266
	buffer_put_int(&c->output, ntohl(INADDR_ANY)); /* bind address */
1281
	buffer_put_int(output, ntohl(INADDR_ANY)); /* bind address */
1267
	buffer_append(&c->output, &dest_port, sizeof(dest_port));
1282
	buffer_append(output, &dest_port, sizeof(dest_port));
1268
	return 1;
1283
	return 1;
1269
}
1284
}
1270
1285
Lines 1298-1337 channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1298
{
1313
{
1299
	u_char *p;
1314
	u_char *p;
1300
	u_int have;
1315
	u_int have;
1301
	int ret;
1316
	int ret, gaierr, sock = -1;
1317
	char strport[NI_MAXSERV];
1318
	Buffer * inbuf, * outbuf;
1319
	struct addrinfo hints;
1320
	struct channel_connect cctx;
1321
1322
	if (c->type == SSH_CHANNEL_DYNAMIC) {
1323
		inbuf = &c->input;
1324
		outbuf = &c->output;
1325
	} else if (c->type == SSH_CHANNEL_RDYNAMIC) {
1326
		inbuf = &c->output;
1327
		outbuf = &c->input;
1328
	} else {
1329
		fatal("cannot happen");
1330
	}
1302
1331
1303
	have = buffer_len(&c->input);
1332
	have = buffer_len(inbuf);
1304
	debug2("channel %d: pre_dynamic: have %d", c->self, have);
1333
	debug2("channel %d: pre_dynamic: have %d", c->self, have);
1305
	/* buffer_dump(&c->input); */
1334
	/* buffer_dump(&c->input); */
1306
	/* check if the fixed size part of the packet is in buffer. */
1335
	/* check if the fixed size part of the packet is in buffer. */
1307
	if (have < 3) {
1336
	if (have < 3) {
1308
		/* need more */
1337
		/* need more */
1309
		FD_SET(c->sock, readset);
1338
		if (c->type == SSH_CHANNEL_DYNAMIC)
1339
			FD_SET(c->sock, readset);
1340
1310
		return;
1341
		return;
1311
	}
1342
	}
1312
	/* try to guess the protocol */
1343
	/* try to guess the protocol */
1313
	p = buffer_ptr(&c->input);
1344
	p = buffer_ptr(inbuf);
1314
	switch (p[0]) {
1345
	switch (p[0]) {
1315
	case 0x04:
1346
	case 0x04:
1316
		ret = channel_decode_socks4(c, readset, writeset);
1347
		ret = channel_decode_socks4(c, readset, writeset, inbuf, outbuf);
1317
		break;
1348
		break;
1318
	case 0x05:
1349
	case 0x05:
1319
		ret = channel_decode_socks5(c, readset, writeset);
1350
		ret = channel_decode_socks5(c, readset, writeset, inbuf, outbuf);
1320
		break;
1351
		break;
1321
	default:
1352
	default:
1322
		ret = -1;
1353
		ret = -1;
1323
		break;
1354
		break;
1324
	}
1355
	}
1325
	if (ret < 0) {
1356
	if (ret < 0) {
1326
		chan_mark_dead(c);
1357
		if (c->type == SSH_CHANNEL_DYNAMIC)
1358
			chan_mark_dead(c);
1359
		else {
1360
			close(c->sock);
1361
			c->sock = c->rfd = c->wfd = c->efd = -1;
1362
			buffer_clear(&c->input);
1363
			buffer_clear(&c->output);
1364
			if (compat20)
1365
				packet_start(SSH2_MSG_CHANNEL_CLOSE);
1366
			else
1367
				packet_start(SSH_MSG_CHANNEL_CLOSE);
1368
			packet_put_int(c->remote_id);
1369
			packet_send();
1370
			c->flags |= CHAN_CLOSE_SENT;
1371
			c->type = SSH_CHANNEL_ABANDONED;
1372
		}
1327
	} else if (ret == 0) {
1373
	} else if (ret == 0) {
1328
		debug2("channel %d: pre_dynamic: need more", c->self);
1374
		debug2("channel %d: pre_dynamic: need more", c->self);
1329
		/* need more */
1375
		/* need more */
1330
		FD_SET(c->sock, readset);
1376
		if (c->type == SSH_CHANNEL_DYNAMIC)
1377
			FD_SET(c->sock, readset);
1331
	} else {
1378
	} else {
1332
		/* switch to the next state */
1379
		if (c->type == SSH_CHANNEL_DYNAMIC) {
1333
		c->type = SSH_CHANNEL_OPENING;
1380
			/* switch to the next state */
1334
		port_open_helper(c, "direct-tcpip");
1381
			c->type = SSH_CHANNEL_OPENING;
1382
			port_open_helper(c, "direct-tcpip");
1383
		} else {
1384
			close(c->sock);
1385
			c->sock = c->rfd = c->wfd = c->efd = -1;
1386
			memset(&hints, 0, sizeof(hints));
1387
			hints.ai_family = IPv4or6;
1388
			hints.ai_socktype = SOCK_STREAM;
1389
			snprintf(strport, sizeof strport, "%d", c->host_port);
1390
			if ((gaierr = getaddrinfo(c->path, strport, &hints, &cctx.aitop)) != 0) {
1391
				error("channel_pre_dynamic %.100s: unknown host (%s)", c->path,
1392
					ssh_gai_strerror(gaierr));
1393
				buffer_clear(&c->input);
1394
				buffer_clear(&c->output);
1395
				if (compat20)
1396
					packet_start(SSH2_MSG_CHANNEL_CLOSE);
1397
				else
1398
					packet_start(SSH_MSG_CHANNEL_CLOSE);
1399
				packet_put_int(c->remote_id);
1400
				packet_send();
1401
				c->flags |= CHAN_CLOSE_SENT;
1402
				c->type = SSH_CHANNEL_ABANDONED;
1403
				return;
1404
			}
1405
1406
			cctx.host = xstrdup(c->path);
1407
			cctx.port = c->host_port;
1408
			cctx.ai = cctx.aitop;
1409
1410
			if ((sock = connect_next(&cctx)) == -1) {
1411
				error("connect to %.100s port %d failed: %s",
1412
					c->path, c->host_port, strerror(errno));
1413
				channel_connect_ctx_free(&cctx);
1414
				buffer_clear(&c->input);
1415
				buffer_clear(&c->output);
1416
				if (compat20)
1417
					packet_start(SSH2_MSG_CHANNEL_CLOSE);
1418
				else
1419
					packet_start(SSH_MSG_CHANNEL_CLOSE);
1420
				packet_put_int(c->remote_id);
1421
				packet_send();
1422
				c->flags |= CHAN_CLOSE_SENT;
1423
				c->type = SSH_CHANNEL_ABANDONED;
1424
				return;
1425
			}
1426
1427
			c->type = SSH_CHANNEL_CONNECTING;
1428
			c->connect_ctx = cctx;
1429
			c->rfd = sock;
1430
			c->wfd = sock;
1431
			c->flags |= CHAN_RD_ACKD;
1432
			channel_register_fds(c, c->rfd, c->wfd, c->efd, 0, 1, 0);
1433
			FD_SET(c->sock, writeset);
1434
		}
1335
	}
1435
	}
1336
}
1436
}
1337
1437
Lines 1587-1593 channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1587
static void
1687
static void
1588
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1688
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
1589
{
1689
{
1590
	int err = 0, sock;
1690
	int err = 0, sock, ackd = 0;
1591
	socklen_t sz = sizeof(err);
1691
	socklen_t sz = sizeof(err);
1592
1692
1593
	if (FD_ISSET(c->sock, writeset)) {
1693
	if (FD_ISSET(c->sock, writeset)) {
Lines 1600-1615 channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1600
			    c->self, c->connect_ctx.host, c->connect_ctx.port);
1700
			    c->self, c->connect_ctx.host, c->connect_ctx.port);
1601
			channel_connect_ctx_free(&c->connect_ctx);
1701
			channel_connect_ctx_free(&c->connect_ctx);
1602
			c->type = SSH_CHANNEL_OPEN;
1702
			c->type = SSH_CHANNEL_OPEN;
1603
			if (compat20) {
1703
			if (c->flags & CHAN_RD_ACKD) {
1604
				packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1704
				ackd = 1;
1605
				packet_put_int(c->remote_id);
1705
				c->flags &= ~CHAN_RD_ACKD;
1606
				packet_put_int(c->self);
1607
				packet_put_int(c->local_window);
1608
				packet_put_int(c->local_maxpacket);
1609
			} else {
1706
			} else {
1610
				packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1707
				if (compat20) {
1611
				packet_put_int(c->remote_id);
1708
					packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
1612
				packet_put_int(c->self);
1709
					packet_put_int(c->remote_id);
1710
					packet_put_int(c->self);
1711
					packet_put_int(c->local_window);
1712
					packet_put_int(c->local_maxpacket);
1713
				} else {
1714
					packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1715
					packet_put_int(c->remote_id);
1716
					packet_put_int(c->self);
1717
				}
1613
			}
1718
			}
1614
		} else {
1719
		} else {
1615
			debug("channel %d: connection failed: %s",
1720
			debug("channel %d: connection failed: %s",
Lines 1625-1645 channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) Link Here
1625
			error("connect_to %.100s port %d: failed.",
1730
			error("connect_to %.100s port %d: failed.",
1626
			    c->connect_ctx.host, c->connect_ctx.port);
1731
			    c->connect_ctx.host, c->connect_ctx.port);
1627
			channel_connect_ctx_free(&c->connect_ctx);
1732
			channel_connect_ctx_free(&c->connect_ctx);
1628
			if (compat20) {
1733
			if (c->flags & CHAN_RD_ACKD) {
1629
				packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1734
				ackd = 1;
1735
				c->flags &= ~CHAN_RD_ACKD;
1736
				close(c->sock);
1737
				c->sock = c->rfd = c->wfd = c->efd = -1;
1738
				buffer_clear(&c->input);
1739
				buffer_clear(&c->output);
1740
				if (compat20)
1741
					packet_start(SSH2_MSG_CHANNEL_CLOSE);
1742
				else
1743
					packet_start(SSH_MSG_CHANNEL_CLOSE);
1630
				packet_put_int(c->remote_id);
1744
				packet_put_int(c->remote_id);
1631
				packet_put_int(SSH2_OPEN_CONNECT_FAILED);
1745
				packet_send();
1632
				if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1746
				c->flags |= CHAN_CLOSE_SENT;
1633
					packet_put_cstring(strerror(err));
1747
				c->type = SSH_CHANNEL_ABANDONED;
1634
					packet_put_cstring("");
1635
				}
1636
			} else {
1748
			} else {
1637
				packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1749
				if (compat20) {
1638
				packet_put_int(c->remote_id);
1750
					packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
1751
					packet_put_int(c->remote_id);
1752
					packet_put_int(SSH2_OPEN_CONNECT_FAILED);
1753
					if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1754
						packet_put_cstring(strerror(err));
1755
						packet_put_cstring("");
1756
					}
1757
				} else {
1758
					packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1759
					packet_put_int(c->remote_id);
1760
				}
1639
			}
1761
			}
1640
			chan_mark_dead(c);
1762
			if (!ackd)
1763
				chan_mark_dead(c);
1641
		}
1764
		}
1642
		packet_send();
1765
1766
		if (!ackd)
1767
			packet_send();
1768
	}
1769
}
1770
1771
static void
1772
channel_post_rdynamic(Channel *c, fd_set *readset, fd_set *writeset)
1773
{
1774
	if (c->sock != -1) {
1775
		FD_SET(c->sock, readset);
1776
		FD_SET(c->sock, writeset);
1643
	}
1777
	}
1644
}
1778
}
1645
1779
Lines 2024-2029 channel_handler_init_20(void) Link Here
2024
	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
2158
	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
2025
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2159
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2026
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2160
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2161
	channel_pre[SSH_CHANNEL_RDYNAMIC] =			&channel_pre_dynamic;
2027
	channel_pre[SSH_CHANNEL_MUX_LISTENER] =		&channel_pre_listener;
2162
	channel_pre[SSH_CHANNEL_MUX_LISTENER] =		&channel_pre_listener;
2028
	channel_pre[SSH_CHANNEL_MUX_CLIENT] =		&channel_pre_mux_client;
2163
	channel_pre[SSH_CHANNEL_MUX_CLIENT] =		&channel_pre_mux_client;
2029
2164
Lines 2036-2041 channel_handler_init_20(void) Link Here
2036
	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
2171
	channel_post[SSH_CHANNEL_AUTH_SOCKET] =		&channel_post_auth_listener;
2037
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2172
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2038
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2173
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2174
	channel_post[SSH_CHANNEL_RDYNAMIC] =		&channel_post_rdynamic;
2039
	channel_post[SSH_CHANNEL_MUX_LISTENER] =	&channel_post_mux_listener;
2175
	channel_post[SSH_CHANNEL_MUX_LISTENER] =	&channel_post_mux_listener;
2040
	channel_post[SSH_CHANNEL_MUX_CLIENT] =		&channel_post_mux_client;
2176
	channel_post[SSH_CHANNEL_MUX_CLIENT] =		&channel_post_mux_client;
2041
}
2177
}
Lines 2052-2057 channel_handler_init_13(void) Link Here
2052
	channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_pre_output_draining;
2188
	channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_pre_output_draining;
2053
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2189
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2054
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2190
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2191
	channel_pre[SSH_CHANNEL_RDYNAMIC] =			&channel_pre_dynamic;
2055
2192
2056
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2193
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2057
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
2194
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
Lines 2060-2065 channel_handler_init_13(void) Link Here
2060
	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain_13;
2197
	channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =	&channel_post_output_drain_13;
2061
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2198
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2062
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2199
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2200
	channel_post[SSH_CHANNEL_RDYNAMIC] =		&channel_post_rdynamic;
2063
}
2201
}
2064
2202
2065
static void
2203
static void
Lines 2072-2077 channel_handler_init_15(void) Link Here
2072
	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
2210
	channel_pre[SSH_CHANNEL_AUTH_SOCKET] =		&channel_pre_listener;
2073
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2211
	channel_pre[SSH_CHANNEL_CONNECTING] =		&channel_pre_connecting;
2074
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2212
	channel_pre[SSH_CHANNEL_DYNAMIC] =		&channel_pre_dynamic;
2213
	channel_pre[SSH_CHANNEL_RDYNAMIC] =			&channel_pre_dynamic;
2075
2214
2076
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
2215
	channel_post[SSH_CHANNEL_X11_LISTENER] =	&channel_post_x11_listener;
2077
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
2216
	channel_post[SSH_CHANNEL_PORT_LISTENER] =	&channel_post_port_listener;
Lines 2079-2084 channel_handler_init_15(void) Link Here
2079
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2218
	channel_post[SSH_CHANNEL_OPEN] =		&channel_post_open;
2080
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2219
	channel_post[SSH_CHANNEL_CONNECTING] =		&channel_post_connecting;
2081
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2220
	channel_post[SSH_CHANNEL_DYNAMIC] =		&channel_post_open;
2221
	channel_post[SSH_CHANNEL_RDYNAMIC] =		&channel_post_rdynamic;
2082
}
2222
}
2083
2223
2084
static void
2224
static void
Lines 2234-2243 channel_output_poll(void) Link Here
2234
		 */
2374
		 */
2235
		if (compat13) {
2375
		if (compat13) {
2236
			if (c->type != SSH_CHANNEL_OPEN &&
2376
			if (c->type != SSH_CHANNEL_OPEN &&
2237
			    c->type != SSH_CHANNEL_INPUT_DRAINING)
2377
			    c->type != SSH_CHANNEL_INPUT_DRAINING &&
2378
				c->type != SSH_CHANNEL_RDYNAMIC)
2238
				continue;
2379
				continue;
2239
		} else {
2380
		} else {
2240
			if (c->type != SSH_CHANNEL_OPEN)
2381
			if (c->type != SSH_CHANNEL_OPEN &&
2382
				c->type != SSH_CHANNEL_RDYNAMIC)
2241
				continue;
2383
				continue;
2242
		}
2384
		}
2243
		if (compat20 &&
2385
		if (compat20 &&
Lines 2362-2368 channel_input_data(int type, u_int32_t seq, void *ctxt) Link Here
2362
2504
2363
	/* Ignore any data for non-open channels (might happen on close) */
2505
	/* Ignore any data for non-open channels (might happen on close) */
2364
	if (c->type != SSH_CHANNEL_OPEN &&
2506
	if (c->type != SSH_CHANNEL_OPEN &&
2365
	    c->type != SSH_CHANNEL_X11_OPEN)
2507
	    c->type != SSH_CHANNEL_X11_OPEN &&
2508
		c->type != SSH_CHANNEL_RDYNAMIC)
2366
		return 0;
2509
		return 0;
2367
2510
2368
	/* Get the data. */
2511
	/* Get the data. */
Lines 3296-3301 open_listen_match_tcpip(ForwardPermission *allowed_open, Link Here
3296
		return 0;
3439
		return 0;
3297
	if (allowed_open->listen_port != requestedport)
3440
	if (allowed_open->listen_port != requestedport)
3298
		return 0;
3441
		return 0;
3442
	if (allowed_open->port_to_connect == 0 &&
3443
		strcmp("socks", allowed_open->host_to_connect)==0 &&
3444
		allowed_open->listen_port == requestedport)
3445
		return 1;
3299
	if (!translate && allowed_open->listen_host == NULL &&
3446
	if (!translate && allowed_open->listen_host == NULL &&
3300
	    requestedhost == NULL)
3447
	    requestedhost == NULL)
3301
		return 1;
3448
		return 1;
Lines 3684-3690 connect_to(const char *name, int port, char *ctype, char *rname) Link Here
3684
3831
3685
	memset(&cctx, 0, sizeof(cctx));
3832
	memset(&cctx, 0, sizeof(cctx));
3686
3833
3687
	if (port == PORT_STREAMLOCAL) {
3834
	if (port == 0) {
3835
		sock = socket(AF_INET, SOCK_STREAM, 0);
3836
		c = channel_new(ctype, SSH_CHANNEL_RDYNAMIC, sock, sock, -1,
3837
		CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
3838
		return c;
3839
	} else if (port == PORT_STREAMLOCAL) {
3688
		struct sockaddr_un *sunaddr;
3840
		struct sockaddr_un *sunaddr;
3689
		struct addrinfo *ai;
3841
		struct addrinfo *ai;
3690
3842
(-)a/channels.h (-1 / +3 lines)
Lines 58-64 Link Here
58
#define SSH_CHANNEL_ABANDONED		17	/* Abandoned session, eg mux */
58
#define SSH_CHANNEL_ABANDONED		17	/* Abandoned session, eg mux */
59
#define SSH_CHANNEL_UNIX_LISTENER	18	/* Listening on a domain socket. */
59
#define SSH_CHANNEL_UNIX_LISTENER	18	/* Listening on a domain socket. */
60
#define SSH_CHANNEL_RUNIX_LISTENER	19	/* Listening to a R-style domain socket. */
60
#define SSH_CHANNEL_RUNIX_LISTENER	19	/* Listening to a R-style domain socket. */
61
#define SSH_CHANNEL_MAX_TYPE		20
61
#define SSH_CHANNEL_RDYNAMIC		20
62
#define SSH_CHANNEL_MAX_TYPE		21
62
63
63
#define CHANNEL_CANCEL_PORT_STATIC	-1
64
#define CHANNEL_CANCEL_PORT_STATIC	-1
64
65
Lines 193-198 struct Channel { Link Here
193
#define CHAN_EOF_SENT			0x04
194
#define CHAN_EOF_SENT			0x04
194
#define CHAN_EOF_RCVD			0x08
195
#define CHAN_EOF_RCVD			0x08
195
#define CHAN_LOCAL			0x10
196
#define CHAN_LOCAL			0x10
197
#define CHAN_RD_ACKD			0x20
196
198
197
#define CHAN_RBUF	16*1024
199
#define CHAN_RBUF	16*1024
198
200
(-)a/clientloop.c (-7 / +17 lines)
Lines 873-879 process_cmdline(void) Link Here
873
{
873
{
874
	void (*handler)(int);
874
	void (*handler)(int);
875
	char *s, *cmd;
875
	char *s, *cmd;
876
	int ok, delete = 0, local = 0, remote = 0, dynamic = 0;
876
	int ok, delete = 0, remote, dynamic;
877
	struct Forward fwd;
877
	struct Forward fwd;
878
878
879
	memset(&fwd, 0, sizeof(fwd));
879
	memset(&fwd, 0, sizeof(fwd));
Lines 898-909 process_cmdline(void) Link Here
898
		    "Request remote forward");
898
		    "Request remote forward");
899
		logit("      -D[bind_address:]port                  "
899
		logit("      -D[bind_address:]port                  "
900
		    "Request dynamic forward");
900
		    "Request dynamic forward");
901
		logit("      -d[bind_address:]port                  "
902
		    "Request remote dynamic forward");
901
		logit("      -KL[bind_address:]port                 "
903
		logit("      -KL[bind_address:]port                 "
902
		    "Cancel local forward");
904
		    "Cancel local forward");
903
		logit("      -KR[bind_address:]port                 "
905
		logit("      -KR[bind_address:]port                 "
904
		    "Cancel remote forward");
906
		    "Cancel remote forward");
905
		logit("      -KD[bind_address:]port                 "
907
		logit("      -KD[bind_address:]port                 "
906
		    "Cancel dynamic forward");
908
		    "Cancel dynamic forward");
909
		logit("      -Kd[bind_address:]port                 "
910
		    "Cancel remote dynamic forward");
907
		if (!options.permit_local_command)
911
		if (!options.permit_local_command)
908
			goto out;
912
			goto out;
909
		logit("      !args                                  "
913
		logit("      !args                                  "
Lines 921-933 process_cmdline(void) Link Here
921
		delete = 1;
925
		delete = 1;
922
		s++;
926
		s++;
923
	}
927
	}
924
	if (*s == 'L')
928
	if (*s == 'L') {
925
		local = 1;
929
		dynamic = 0;
926
	else if (*s == 'R')
930
		remote = 0;
931
	} else if (*s == 'R') {
932
		dynamic = 0;
927
		remote = 1;
933
		remote = 1;
928
	else if (*s == 'D')
934
	} else if (*s == 'D') {
929
		dynamic = 1;
935
		dynamic = 1;
930
	else {
936
		remote = 0;
937
	} else if (*s == 'd') {
938
		dynamic = 1;
939
		remote = 1;
940
	} else {
931
		logit("Invalid command.");
941
		logit("Invalid command.");
932
		goto out;
942
		goto out;
933
	}
943
	}
Lines 966-972 process_cmdline(void) Link Here
966
			logit("Bad forwarding specification.");
976
			logit("Bad forwarding specification.");
967
			goto out;
977
			goto out;
968
		}
978
		}
969
		if (local || dynamic) {
979
		if (!remote) {
970
			if (!channel_setup_local_fwd_listener(&fwd,
980
			if (!channel_setup_local_fwd_listener(&fwd,
971
			    &options.fwd_opts)) {
981
			    &options.fwd_opts)) {
972
				logit("Port forwarding failed.");
982
				logit("Port forwarding failed.");
(-)a/ssh.c (-1 / +12 lines)
Lines 596-602 main(int ac, char **av) Link Here
596
	argv0 = av[0];
596
	argv0 = av[0];
597
597
598
 again:
598
 again:
599
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
599
	while ((opt = getopt(ac, av, "1246ab:c:d:e:fgi:kl:m:no:p:qstvx"
600
	    "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
600
	    "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
601
		switch (opt) {
601
		switch (opt) {
602
		case '1':
602
		case '1':
Lines 876-881 main(int ac, char **av) Link Here
876
			}
876
			}
877
			break;
877
			break;
878
878
879
		case 'd':
880
			if (parse_forward(&fwd, optarg, 1, 1)) {
881
				add_remote_forward(&options, &fwd);
882
			} else {
883
				fprintf(stderr,
884
				    "Bad remote dynamic forwarding specification "
885
				    "'%s'\n", optarg);
886
				exit(255);
887
			}
888
			break;
889
879
		case 'C':
890
		case 'C':
880
			options.compression = 1;
891
			options.compression = 1;
881
			break;
892
			break;

Return to bug 2393