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

Collapse All | Expand All

(-)clientloop.c (-2 / +65 lines)
Lines 169-174 Link Here
169
extern Kex *xxx_kex;
169
extern Kex *xxx_kex;
170
170
171
void ssh_process_session2_setup(int, int, int, Buffer *);
171
void ssh_process_session2_setup(int, int, int, Buffer *);
172
static void client_process_control_forward(int client_fd, Buffer m);
172
173
173
/* Restores stdin to blocking mode. */
174
/* Restores stdin to blocking mode. */
174
175
Lines 765-772 Link Here
765
	command = buffer_get_int(&m);
766
	command = buffer_get_int(&m);
766
	flags = buffer_get_int(&m);
767
	flags = buffer_get_int(&m);
767
768
768
	buffer_clear(&m);
769
770
	switch (command) {
769
	switch (command) {
771
	case SSHMUX_COMMAND_OPEN:
770
	case SSHMUX_COMMAND_OPEN:
772
		if (options.control_master == SSHCTL_MASTER_ASK ||
771
		if (options.control_master == SSHCTL_MASTER_ASK ||
Lines 797-802 Link Here
797
		buffer_free(&m);
796
		buffer_free(&m);
798
		close(client_fd);
797
		close(client_fd);
799
		return;
798
		return;
799
	case SSHMUX_COMMAND_FORWARD:
800
		client_process_control_forward(client_fd, m);
801
		buffer_free(&m);
802
		close(client_fd);
803
		return;
800
	default:
804
	default:
801
		error("Unsupported command %d", command);
805
		error("Unsupported command %d", command);
802
		buffer_free(&m);
806
		buffer_free(&m);
Lines 933-938 Link Here
933
937
934
	channel_send_open(c->self);
938
	channel_send_open(c->self);
935
	channel_register_confirm(c->self, client_extra_session2_setup, cctx);
939
	channel_register_confirm(c->self, client_extra_session2_setup, cctx);
940
}
941
942
static void
943
client_process_control_forward(int client_fd, Buffer m)
944
{
945
	int local, gateway_ports, success;
946
	char *listen_host, *connect_host;
947
	u_short listen_port, connect_port;
948
949
	local = buffer_get_char(&m);
950
	listen_host = buffer_get_string(&m, NULL);
951
	listen_port = buffer_get_short(&m);
952
	connect_host = buffer_get_string(&m, NULL);
953
	connect_port = buffer_get_short(&m);
954
	gateway_ports = buffer_get_char(&m);
955
956
	if ((options.control_master == SSHCTL_MASTER_ASK ||
957
	    options.control_master == SSHCTL_MASTER_AUTO_ASK)
958
	    && !ask_permission("Allow %s forward %s:%d -> %s:%d",
959
		(local ? "local" : "remote"),
960
		(gateway_ports ? "*" :
961
		    (listen_host ? listen_host : "LOCALHOST")),
962
		listen_port, connect_host, connect_port)) {
963
		success = 0;
964
		goto send_reply;
965
	}
966
967
	if (local) {
968
		success = channel_setup_local_fwd_listener(listen_host,
969
		    listen_port, connect_host, connect_port, gateway_ports);
970
		debug("Local connections to %.200s:%d forwarded to remote "
971
		    "address %.200s:%d",
972
		    (*listen_host == '\0') ?
973
		    (gateway_ports ? "*" : "LOCALHOST") : listen_host,
974
		    listen_port, connect_host, connect_port);
975
	} else {
976
		if (channel_request_remote_forwarding(listen_host, listen_port,
977
		    connect_host, connect_port) < 0) {
978
			success = 0;
979
		} else {
980
			success = 1;
981
		}
982
		debug("Remote connections from %.200s:%d forwarded to "
983
		    "local address %.200s:%d",
984
		    (*listen_host == '\0') ? "LOCALHOST" : listen_host,
985
		    listen_port, connect_host, connect_port);
986
	}
987
988
	if (!success) {
989
		error("Could not request %s forwarding.",
990
		    (local ? "local" : "remote"));
991
	}
992
993
send_reply:
994
	buffer_clear(&m);
995
	buffer_put_int(&m, 1);
996
	buffer_put_int(&m, success);
997
	if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1)
998
		error("%s: client msg_send failed", __func__);
936
}
999
}
937
1000
938
static void
1001
static void
(-)clientloop.h (-1 / +2 lines)
Lines 47-58 Link Here
47
int	 client_request_tun_fwd(int, int, int);
47
int	 client_request_tun_fwd(int, int, int);
48
48
49
/* Multiplexing protocol version */
49
/* Multiplexing protocol version */
50
#define SSHMUX_VER			1
50
#define SSHMUX_VER			2
51
51
52
/* Multiplexing control protocol flags */
52
/* Multiplexing control protocol flags */
53
#define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
53
#define SSHMUX_COMMAND_OPEN		1	/* Open new connection */
54
#define SSHMUX_COMMAND_ALIVE_CHECK	2	/* Check master is alive */
54
#define SSHMUX_COMMAND_ALIVE_CHECK	2	/* Check master is alive */
55
#define SSHMUX_COMMAND_TERMINATE	3	/* Ask master to exit */
55
#define SSHMUX_COMMAND_TERMINATE	3	/* Ask master to exit */
56
#define SSHMUX_COMMAND_FORWARD		4	/* Open port forward */
56
57
57
#define SSHMUX_FLAG_TTY			(1)	/* Request tty on open */
58
#define SSHMUX_FLAG_TTY			(1)	/* Request tty on open */
58
#define SSHMUX_FLAG_SUBSYS		(1<<1)	/* Subsystem request on open */
59
#define SSHMUX_FLAG_SUBSYS		(1<<1)	/* Subsystem request on open */
(-)ssh.c (-34 / +128 lines)
Lines 191-196 Link Here
191
static int ssh_session2(void);
191
static int ssh_session2(void);
192
static void load_public_identity_files(void);
192
static void load_public_identity_files(void);
193
static void control_client(const char *path);
193
static void control_client(const char *path);
194
static int control_client_connect(const char *path);
195
static int control_client_get_reply(int sock);
196
static int control_client_request_forward(const char *path, int local,
197
					  const char *listen_host,
198
					  u_short listen_port,
199
					  const char *connect_host,
200
					  u_short connect_port);
194
201
195
/*
202
/*
196
 * Main program for the ssh client.
203
 * Main program for the ssh client.
Lines 1293-1306 Link Here
1293
static void
1300
static void
1294
control_client(const char *path)
1301
control_client(const char *path)
1295
{
1302
{
1296
	struct sockaddr_un addr;
1297
	int i, r, fd, sock, exitval[2], num_env;
1303
	int i, r, fd, sock, exitval[2], num_env;
1298
	Buffer m;
1304
	Buffer m;
1299
	char *term;
1305
	char *term;
1300
	extern char **environ;
1306
	extern char **environ;
1301
	u_int  flags;
1307
	u_int  flags;
1302
1308
1303
	if (mux_command == 0)
1309
	if (mux_command == 0 && no_shell_flag &&
1310
	    (options.num_local_forwards || options.num_remote_forwards)) {
1311
		mux_command = SSHMUX_COMMAND_FORWARD;
1312
	} else if (mux_command == 0)
1304
		mux_command = SSHMUX_COMMAND_OPEN;
1313
		mux_command = SSHMUX_COMMAND_OPEN;
1305
1314
1306
	switch (options.control_master) {
1315
	switch (options.control_master) {
Lines 1314-1346 Link Here
1314
		return;
1323
		return;
1315
	}
1324
	}
1316
1325
1317
	memset(&addr, '\0', sizeof(addr));
1326
	/* Open requested forwards */
1318
	addr.sun_family = AF_UNIX;
1327
	if (options.num_local_forwards || options.num_remote_forwards) {
1319
	addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
1328
		for (i=0; i<options.num_local_forwards; i++) {
1320
	    strlen(path) + 1;
1329
			if (control_client_request_forward(path, 1,
1321
1330
			    options.local_forwards[i].listen_host,
1322
	if (strlcpy(addr.sun_path, path,
1331
			    options.local_forwards[i].listen_port,
1323
	    sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
1332
			    options.local_forwards[i].connect_host,
1324
		fatal("ControlPath too long");
1333
			    options.local_forwards[i].connect_port))
1325
1334
				goto fail;
1326
	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1327
		fatal("%s socket(): %s", __func__, strerror(errno));
1328
1329
	if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
1330
		if (mux_command != SSHMUX_COMMAND_OPEN) {
1331
			fatal("Control socket connect(%.100s): %s", path,
1332
			    strerror(errno));
1333
		}
1335
		}
1334
		if (errno == ENOENT)
1336
		for (i=0; i<options.num_remote_forwards; i++) {
1335
			debug("Control socket \"%.100s\" does not exist", path);
1337
			if (control_client_request_forward(path, 0,
1336
		else {
1338
			    options.remote_forwards[i].listen_host,
1337
			error("Control socket connect(%.100s): %s", path,
1339
			    options.remote_forwards[i].listen_port,
1338
			    strerror(errno));
1340
			    options.remote_forwards[i].connect_host,
1341
			    options.remote_forwards[i].connect_port))
1342
				goto fail;
1339
		}
1343
		}
1340
		close(sock);
1341
		return;
1342
	}
1344
	}
1343
1345
1346
	if (mux_command == SSHMUX_COMMAND_FORWARD)
1347
		exit(0);
1348
1349
	if ((sock = control_client_connect(path)) == -1)
1350
		goto fail;
1351
1344
	if (stdin_null_flag) {
1352
	if (stdin_null_flag) {
1345
		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1353
		if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
1346
			fatal("open(/dev/null): %s", strerror(errno));
1354
			fatal("open(/dev/null): %s", strerror(errno));
Lines 1372-1386 Link Here
1372
	buffer_clear(&m);
1380
	buffer_clear(&m);
1373
1381
1374
	/* Get authorisation status and PID of controlee */
1382
	/* Get authorisation status and PID of controlee */
1375
	if (ssh_msg_recv(sock, &m) == -1)
1383
	control_server_pid = control_client_get_reply(sock);
1376
		fatal("%s: msg_recv", __func__);
1377
	if (buffer_get_char(&m) != SSHMUX_VER)
1378
		fatal("%s: wrong version", __func__);
1379
	if (buffer_get_int(&m) != 1)
1380
		fatal("Connection to master denied");
1381
	control_server_pid = buffer_get_int(&m);
1382
1383
	buffer_clear(&m);
1384
1384
1385
	switch (mux_command) {
1385
	switch (mux_command) {
1386
	case SSHMUX_COMMAND_ALIVE_CHECK:
1386
	case SSHMUX_COMMAND_ALIVE_CHECK:
Lines 1484-1487 Link Here
1484
		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
1484
		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
1485
1485
1486
	exit(exitval[0]);
1486
	exit(exitval[0]);
1487
1488
 fail:
1489
	if (mux_command != SSHMUX_COMMAND_OPEN) {
1490
		fatal("Control socket connect(%.100s): %s", path,
1491
		    strerror(errno));
1492
	}
1493
	if (errno == ENOENT)
1494
		debug("Control socket \"%.100s\" does not exist", path);
1495
	else {
1496
		error("Control socket connect(%.100s): %s", path,
1497
		    strerror(errno));
1498
	}
1499
}
1500
1501
static int
1502
control_client_connect(const char *path)
1503
{
1504
	struct sockaddr_un addr;
1505
	int sock;
1506
1507
	debug3("Connect to master");
1508
	memset(&addr, '\0', sizeof(addr));
1509
	addr.sun_family = AF_UNIX;
1510
	addr.sun_len = offsetof(struct sockaddr_un, sun_path) +
1511
	    strlen(path) + 1;
1512
1513
	if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path))
1514
	    >= sizeof(addr.sun_path))
1515
		fatal("ControlPath too long");
1516
1517
	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1518
		fatal("%s socket(): %s", __func__, strerror(errno));
1519
1520
	if (connect(sock, (struct sockaddr *)&addr, addr.sun_len) == -1) {
1521
		close(sock);
1522
		return -1;
1523
	}
1524
	return sock;
1525
}
1526
1527
static int
1528
control_client_get_reply(int sock)
1529
{
1530
	Buffer m;
1531
	int r;
1532
1533
	buffer_init(&m);
1534
	if (ssh_msg_recv(sock, &m) == -1)
1535
		fatal("%s: msg_recv", __func__);
1536
	if (buffer_get_char(&m) != SSHMUX_VER)
1537
		fatal("%s: wrong version", __func__);
1538
	if (buffer_get_int(&m) != 1)
1539
		fatal("Connection to master denied");
1540
	r = buffer_get_int(&m);
1541
	buffer_clear(&m);
1542
	return r;
1543
}
1544
1545
static int
1546
control_client_request_forward(const char *path, int local,
1547
			       const char *listen_host, u_short listen_port,
1548
			       const char *connect_host, u_short connect_port)
1549
{
1550
	Buffer m;
1551
	int sock;
1552
1553
	if ((sock = control_client_connect(path)) == -1)
1554
		return 1;
1555
1556
	/* Send our command to server */
1557
	buffer_init(&m);
1558
	buffer_put_int(&m, SSHMUX_COMMAND_FORWARD);
1559
	buffer_put_int(&m, 0);
1560
	buffer_put_char(&m, local);
1561
	buffer_put_cstring(&m, listen_host ? listen_host : "");
1562
	buffer_put_short(&m, listen_port);
1563
	buffer_put_cstring(&m, connect_host);
1564
	buffer_put_short(&m, connect_port);
1565
	buffer_put_char(&m, options.gateway_ports);
1566
	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1567
		fatal("%s: msg_send", __func__);
1568
	buffer_clear(&m);
1569
1570
	if (!control_client_get_reply(sock))
1571
		fatal("Master denied our forward request to %s:%d",
1572
		    connect_host, connect_port);
1573
	close(sock);
1574
1575
	debug("Local connections to %.200s:%d forwarded to remote "
1576
	    "address %.200s:%d",
1577
	    (listen_host == NULL) ?
1578
	    (options.gateway_ports ? "*" : "LOCALHOST") :
1579
		listen_host, listen_port, connect_host, connect_port);
1580
	return 0;
1487
}
1581
}

Return to bug 993