summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/ssh.c b/ssh.c
index 44b005687..7dd41f59a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.368 2011/10/24 02:10:46 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -377,6 +377,8 @@ main(int ac, char **av)
377 muxclient_command = SSHMUX_COMMAND_TERMINATE; 377 muxclient_command = SSHMUX_COMMAND_TERMINATE;
378 else if (strcmp(optarg, "stop") == 0) 378 else if (strcmp(optarg, "stop") == 0)
379 muxclient_command = SSHMUX_COMMAND_STOP; 379 muxclient_command = SSHMUX_COMMAND_STOP;
380 else if (strcmp(optarg, "cancel") == 0)
381 muxclient_command = SSHMUX_COMMAND_CANCEL_FWD;
380 else 382 else
381 fatal("Invalid multiplex command."); 383 fatal("Invalid multiplex command.");
382 break; 384 break;
@@ -884,17 +886,20 @@ main(int ac, char **av)
884 * Now that we are back to our own permissions, create ~/.ssh 886 * Now that we are back to our own permissions, create ~/.ssh
885 * directory if it doesn't already exist. 887 * directory if it doesn't already exist.
886 */ 888 */
887 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir, 889 if (config == NULL) {
888 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 890 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
889 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) { 891 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
892 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
890#ifdef WITH_SELINUX 893#ifdef WITH_SELINUX
891 ssh_selinux_setfscreatecon(buf); 894 ssh_selinux_setfscreatecon(buf);
892#endif 895#endif
893 if (mkdir(buf, 0700) < 0) 896 if (mkdir(buf, 0700) < 0)
894 error("Could not create directory '%.200s'.", buf); 897 error("Could not create directory '%.200s'.",
898 buf);
895#ifdef WITH_SELINUX 899#ifdef WITH_SELINUX
896 ssh_selinux_setfscreatecon(NULL); 900 ssh_selinux_setfscreatecon(NULL);
897#endif 901#endif
902 }
898 } 903 }
899 /* load options.identity_files */ 904 /* load options.identity_files */
900 load_public_identity_files(); 905 load_public_identity_files();
@@ -1019,11 +1024,17 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1019 debug("remote forward %s for: listen %d, connect %s:%d", 1024 debug("remote forward %s for: listen %d, connect %s:%d",
1020 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 1025 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1021 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 1026 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
1022 if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { 1027 if (rfwd->listen_port == 0) {
1023 rfwd->allocated_port = packet_get_int(); 1028 if (type == SSH2_MSG_REQUEST_SUCCESS) {
1024 logit("Allocated port %u for remote forward to %s:%d", 1029 rfwd->allocated_port = packet_get_int();
1025 rfwd->allocated_port, 1030 logit("Allocated port %u for remote forward to %s:%d",
1026 rfwd->connect_host, rfwd->connect_port); 1031 rfwd->allocated_port,
1032 rfwd->connect_host, rfwd->connect_port);
1033 channel_update_permitted_opens(rfwd->handle,
1034 rfwd->allocated_port);
1035 } else {
1036 channel_update_permitted_opens(rfwd->handle, -1);
1037 }
1027 } 1038 }
1028 1039
1029 if (type == SSH2_MSG_REQUEST_FAILURE) { 1040 if (type == SSH2_MSG_REQUEST_FAILURE) {
@@ -1048,25 +1059,26 @@ client_cleanup_stdio_fwd(int id, void *arg)
1048 cleanup_exit(0); 1059 cleanup_exit(0);
1049} 1060}
1050 1061
1051static int 1062static void
1052client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect) 1063ssh_init_stdio_forwarding(void)
1053{ 1064{
1054 Channel *c; 1065 Channel *c;
1055 int in, out; 1066 int in, out;
1056 1067
1057 debug3("client_setup_stdio_fwd %s:%d", host_to_connect, 1068 if (stdio_forward_host == NULL)
1058 port_to_connect); 1069 return;
1070 if (!compat20)
1071 fatal("stdio forwarding require Protocol 2");
1059 1072
1060 in = dup(STDIN_FILENO); 1073 debug3("%s: %s:%d", __func__, stdio_forward_host, stdio_forward_port);
1061 out = dup(STDOUT_FILENO);
1062 if (in < 0 || out < 0)
1063 fatal("channel_connect_stdio_fwd: dup() in/out failed");
1064 1074
1065 if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect, 1075 if ((in = dup(STDIN_FILENO)) < 0 ||
1066 in, out)) == NULL) 1076 (out = dup(STDOUT_FILENO)) < 0)
1067 return 0; 1077 fatal("channel_connect_stdio_fwd: dup() in/out failed");
1078 if ((c = channel_connect_stdio_fwd(stdio_forward_host,
1079 stdio_forward_port, in, out)) == NULL)
1080 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1068 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1081 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
1069 return 1;
1070} 1082}
1071 1083
1072static void 1084static void
@@ -1075,15 +1087,6 @@ ssh_init_forwarding(void)
1075 int success = 0; 1087 int success = 0;
1076 int i; 1088 int i;
1077 1089
1078 if (stdio_forward_host != NULL) {
1079 if (!compat20) {
1080 fatal("stdio forwarding require Protocol 2");
1081 }
1082 if (!client_setup_stdio_fwd(stdio_forward_host,
1083 stdio_forward_port))
1084 fatal("Failed to connect in stdio forward mode.");
1085 }
1086
1087 /* Initiate local TCP/IP port forwardings. */ 1090 /* Initiate local TCP/IP port forwardings. */
1088 for (i = 0; i < options.num_local_forwards; i++) { 1091 for (i = 0; i < options.num_local_forwards; i++) {
1089 debug("Local connections to %.200s:%d forwarded to remote " 1092 debug("Local connections to %.200s:%d forwarded to remote "
@@ -1115,19 +1118,22 @@ ssh_init_forwarding(void)
1115 options.remote_forwards[i].listen_port, 1118 options.remote_forwards[i].listen_port,
1116 options.remote_forwards[i].connect_host, 1119 options.remote_forwards[i].connect_host,
1117 options.remote_forwards[i].connect_port); 1120 options.remote_forwards[i].connect_port);
1118 if (channel_request_remote_forwarding( 1121 options.remote_forwards[i].handle =
1122 channel_request_remote_forwarding(
1119 options.remote_forwards[i].listen_host, 1123 options.remote_forwards[i].listen_host,
1120 options.remote_forwards[i].listen_port, 1124 options.remote_forwards[i].listen_port,
1121 options.remote_forwards[i].connect_host, 1125 options.remote_forwards[i].connect_host,
1122 options.remote_forwards[i].connect_port) < 0) { 1126 options.remote_forwards[i].connect_port);
1127 if (options.remote_forwards[i].handle < 0) {
1123 if (options.exit_on_forward_failure) 1128 if (options.exit_on_forward_failure)
1124 fatal("Could not request remote forwarding."); 1129 fatal("Could not request remote forwarding.");
1125 else 1130 else
1126 logit("Warning: Could not request remote " 1131 logit("Warning: Could not request remote "
1127 "forwarding."); 1132 "forwarding.");
1133 } else {
1134 client_register_global_confirm(ssh_confirm_remote_forward,
1135 &options.remote_forwards[i]);
1128 } 1136 }
1129 client_register_global_confirm(ssh_confirm_remote_forward,
1130 &options.remote_forwards[i]);
1131 } 1137 }
1132 1138
1133 /* Initiate tunnel forwarding. */ 1139 /* Initiate tunnel forwarding. */
@@ -1271,6 +1277,7 @@ ssh_session(void)
1271 } 1277 }
1272 1278
1273 /* Initiate port forwardings. */ 1279 /* Initiate port forwardings. */
1280 ssh_init_stdio_forwarding();
1274 ssh_init_forwarding(); 1281 ssh_init_forwarding();
1275 1282
1276 /* Execute a local command */ 1283 /* Execute a local command */
@@ -1409,15 +1416,18 @@ ssh_session2(void)
1409 int id = -1; 1416 int id = -1;
1410 1417
1411 /* XXX should be pre-session */ 1418 /* XXX should be pre-session */
1419 if (!options.control_persist)
1420 ssh_init_stdio_forwarding();
1412 ssh_init_forwarding(); 1421 ssh_init_forwarding();
1413 1422
1414 /* Start listening for multiplex clients */ 1423 /* Start listening for multiplex clients */
1415 muxserver_listen(); 1424 muxserver_listen();
1416 1425
1417 /* 1426 /*
1418 * If we are in control persist mode, then prepare to background 1427 * If we are in control persist mode and have a working mux listen
1419 * ourselves and have a foreground client attach as a control 1428 * socket, then prepare to background ourselves and have a foreground
1420 * slave. NB. we must save copies of the flags that we override for 1429 * client attach as a control slave.
1430 * NB. we must save copies of the flags that we override for
1421 * the backgrounding, since we defer attachment of the slave until 1431 * the backgrounding, since we defer attachment of the slave until
1422 * after the connection is fully established (in particular, 1432 * after the connection is fully established (in particular,
1423 * async rfwd replies have been received for ExitOnForwardFailure). 1433 * async rfwd replies have been received for ExitOnForwardFailure).
@@ -1434,6 +1444,12 @@ ssh_session2(void)
1434 need_controlpersist_detach = 1; 1444 need_controlpersist_detach = 1;
1435 fork_after_authentication_flag = 1; 1445 fork_after_authentication_flag = 1;
1436 } 1446 }
1447 /*
1448 * ControlPersist mux listen socket setup failed, attempt the
1449 * stdio forward setup that we skipped earlier.
1450 */
1451 if (options.control_persist && muxserver_sock == -1)
1452 ssh_init_stdio_forwarding();
1437 1453
1438 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1454 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1439 id = ssh_session2_open(); 1455 id = ssh_session2_open();