|
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 |
} |