summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2010-08-23 22:56:08 +0100
committerColin Watson <cjwatson@debian.org>2010-08-23 22:56:08 +0100
commit31e30b835fd9695d3b6647cab4867001b092e28f (patch)
tree138e715c25661825457c7280cd66e3f4853d474c /ssh.c
parent78eedc2c60ff4718200f9271d8ee4f437da3a0c5 (diff)
parent43094ebf14c9b16f1ea398bc5b65a7335e947288 (diff)
merge 5.6p1
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c199
1 files changed, 160 insertions, 39 deletions
diff --git a/ssh.c b/ssh.c
index b9553d3e1..4419f7642 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.346 2010/08/12 21:49:44 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
@@ -79,6 +79,7 @@
79#include "ssh.h" 79#include "ssh.h"
80#include "ssh1.h" 80#include "ssh1.h"
81#include "ssh2.h" 81#include "ssh2.h"
82#include "canohost.h"
82#include "compat.h" 83#include "compat.h"
83#include "cipher.h" 84#include "cipher.h"
84#include "packet.h" 85#include "packet.h"
@@ -127,6 +128,15 @@ int no_shell_flag = 0;
127int stdin_null_flag = 0; 128int stdin_null_flag = 0;
128 129
129/* 130/*
131 * Flag indicating that the current process should be backgrounded and
132 * a new slave launched in the foreground for ControlPersist.
133 */
134int need_controlpersist_detach = 0;
135
136/* Copies of flags for ControlPersist foreground slave */
137int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag;
138
139/*
130 * Flag indicating that ssh should fork after authentication. This is useful 140 * Flag indicating that ssh should fork after authentication. This is useful
131 * so that the passphrase can be entered manually, and then ssh goes to the 141 * so that the passphrase can be entered manually, and then ssh goes to the
132 * background. 142 * background.
@@ -228,6 +238,12 @@ main(int ac, char **av)
228 init_rng(); 238 init_rng();
229 239
230 /* 240 /*
241 * Discard other fds that are hanging around. These can cause problem
242 * with backgrounded ssh processes started by ControlPersist.
243 */
244 closefrom(STDERR_FILENO + 1);
245
246 /*
231 * Save the original real uid. It will be needed later (uid-swapping 247 * Save the original real uid. It will be needed later (uid-swapping
232 * may clobber the real uid). 248 * may clobber the real uid).
233 */ 249 */
@@ -327,6 +343,8 @@ main(int ac, char **av)
327 fatal("Multiplexing command already specified"); 343 fatal("Multiplexing command already specified");
328 if (strcmp(optarg, "check") == 0) 344 if (strcmp(optarg, "check") == 0)
329 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; 345 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
346 else if (strcmp(optarg, "forward") == 0)
347 muxclient_command = SSHMUX_COMMAND_FORWARD;
330 else if (strcmp(optarg, "exit") == 0) 348 else if (strcmp(optarg, "exit") == 0)
331 muxclient_command = SSHMUX_COMMAND_TERMINATE; 349 muxclient_command = SSHMUX_COMMAND_TERMINATE;
332 else 350 else
@@ -620,7 +638,7 @@ main(int ac, char **av)
620 tty_flag = 1; 638 tty_flag = 1;
621 639
622 /* Force no tty */ 640 /* Force no tty */
623 if (no_tty_flag) 641 if (no_tty_flag || muxclient_command != 0)
624 tty_flag = 0; 642 tty_flag = 0;
625 /* Do not allocate a tty if stdin is not a tty. */ 643 /* Do not allocate a tty if stdin is not a tty. */
626 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { 644 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
@@ -676,6 +694,11 @@ main(int ac, char **av)
676 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 694 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
677 } 695 }
678 696
697 if (options.hostname != NULL) {
698 host = percent_expand(options.hostname,
699 "h", host, (char *)NULL);
700 }
701
679 if (options.local_command != NULL) { 702 if (options.local_command != NULL) {
680 char thishost[NI_MAXHOST]; 703 char thishost[NI_MAXHOST];
681 704
@@ -685,16 +708,12 @@ main(int ac, char **av)
685 debug3("expanding LocalCommand: %s", options.local_command); 708 debug3("expanding LocalCommand: %s", options.local_command);
686 cp = options.local_command; 709 cp = options.local_command;
687 options.local_command = percent_expand(cp, "d", pw->pw_dir, 710 options.local_command = percent_expand(cp, "d", pw->pw_dir,
688 "h", options.hostname? options.hostname : host, 711 "h", host, "l", thishost, "n", host, "r", options.user,
689 "l", thishost, "n", host, "r", options.user, "p", buf, 712 "p", buf, "u", pw->pw_name, (char *)NULL);
690 "u", pw->pw_name, (char *)NULL);
691 debug3("expanded LocalCommand: %s", options.local_command); 713 debug3("expanded LocalCommand: %s", options.local_command);
692 xfree(cp); 714 xfree(cp);
693 } 715 }
694 716
695 if (options.hostname != NULL)
696 host = options.hostname;
697
698 /* force lowercase for hostkey matching */ 717 /* force lowercase for hostkey matching */
699 if (options.host_key_alias != NULL) { 718 if (options.host_key_alias != NULL) {
700 for (p = options.host_key_alias; *p; p++) 719 for (p = options.host_key_alias; *p; p++)
@@ -761,26 +780,34 @@ main(int ac, char **av)
761 sensitive_data.external_keysign = 0; 780 sensitive_data.external_keysign = 0;
762 if (options.rhosts_rsa_authentication || 781 if (options.rhosts_rsa_authentication ||
763 options.hostbased_authentication) { 782 options.hostbased_authentication) {
764 sensitive_data.nkeys = 3; 783 sensitive_data.nkeys = 5;
765 sensitive_data.keys = xcalloc(sensitive_data.nkeys, 784 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
766 sizeof(Key)); 785 sizeof(Key));
767 786
768 PRIV_START; 787 PRIV_START;
769 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 788 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
770 _PATH_HOST_KEY_FILE, "", NULL, NULL); 789 _PATH_HOST_KEY_FILE, "", NULL, NULL);
771 sensitive_data.keys[1] = key_load_private_type(KEY_DSA, 790 sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
791 _PATH_HOST_DSA_KEY_FILE, "", NULL);
792 sensitive_data.keys[2] = key_load_private_cert(KEY_RSA,
793 _PATH_HOST_RSA_KEY_FILE, "", NULL);
794 sensitive_data.keys[3] = key_load_private_type(KEY_DSA,
772 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); 795 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
773 sensitive_data.keys[2] = key_load_private_type(KEY_RSA, 796 sensitive_data.keys[4] = key_load_private_type(KEY_RSA,
774 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); 797 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
775 PRIV_END; 798 PRIV_END;
776 799
777 if (options.hostbased_authentication == 1 && 800 if (options.hostbased_authentication == 1 &&
778 sensitive_data.keys[0] == NULL && 801 sensitive_data.keys[0] == NULL &&
779 sensitive_data.keys[1] == NULL && 802 sensitive_data.keys[3] == NULL &&
780 sensitive_data.keys[2] == NULL) { 803 sensitive_data.keys[4] == NULL) {
781 sensitive_data.keys[1] = key_load_public( 804 sensitive_data.keys[1] = key_load_cert(
805 _PATH_HOST_DSA_KEY_FILE);
806 sensitive_data.keys[2] = key_load_cert(
807 _PATH_HOST_RSA_KEY_FILE);
808 sensitive_data.keys[3] = key_load_public(
782 _PATH_HOST_DSA_KEY_FILE, NULL); 809 _PATH_HOST_DSA_KEY_FILE, NULL);
783 sensitive_data.keys[2] = key_load_public( 810 sensitive_data.keys[4] = key_load_public(
784 _PATH_HOST_RSA_KEY_FILE, NULL); 811 _PATH_HOST_RSA_KEY_FILE, NULL);
785 sensitive_data.external_keysign = 1; 812 sensitive_data.external_keysign = 1;
786 } 813 }
@@ -827,6 +854,13 @@ main(int ac, char **av)
827 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, 854 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
828 pw, timeout_ms); 855 pw, timeout_ms);
829 856
857 if (packet_connection_is_on_socket()) {
858 verbose("Authenticated to %s ([%s]:%d).", host,
859 get_remote_ipaddr(), get_remote_port());
860 } else {
861 verbose("Authenticated to %s (via proxy).", host);
862 }
863
830 /* We no longer need the private host keys. Clear them now. */ 864 /* We no longer need the private host keys. Clear them now. */
831 if (sensitive_data.nkeys != 0) { 865 if (sensitive_data.nkeys != 0) {
832 for (i = 0; i < sensitive_data.nkeys; i++) { 866 for (i = 0; i < sensitive_data.nkeys; i++) {
@@ -866,6 +900,61 @@ main(int ac, char **av)
866 return exit_status; 900 return exit_status;
867} 901}
868 902
903static void
904control_persist_detach(void)
905{
906 pid_t pid;
907 int devnull;
908
909 debug("%s: backgrounding master process", __func__);
910
911 /*
912 * master (current process) into the background, and make the
913 * foreground process a client of the backgrounded master.
914 */
915 switch ((pid = fork())) {
916 case -1:
917 fatal("%s: fork: %s", __func__, strerror(errno));
918 case 0:
919 /* Child: master process continues mainloop */
920 break;
921 default:
922 /* Parent: set up mux slave to connect to backgrounded master */
923 debug2("%s: background process is %ld", __func__, (long)pid);
924 stdin_null_flag = ostdin_null_flag;
925 no_shell_flag = ono_shell_flag;
926 no_tty_flag = ono_tty_flag;
927 tty_flag = otty_flag;
928 close(muxserver_sock);
929 muxserver_sock = -1;
930 muxclient(options.control_path);
931 /* muxclient() doesn't return on success. */
932 fatal("Failed to connect to new control master");
933 }
934 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
935 error("%s: open(\"/dev/null\"): %s", __func__,
936 strerror(errno));
937 } else {
938 if (dup2(devnull, STDIN_FILENO) == -1 ||
939 dup2(devnull, STDOUT_FILENO) == -1)
940 error("%s: dup2: %s", __func__, strerror(errno));
941 if (devnull > STDERR_FILENO)
942 close(devnull);
943 }
944}
945
946/* Do fork() after authentication. Used by "ssh -f" */
947static void
948fork_postauth(void)
949{
950 if (need_controlpersist_detach)
951 control_persist_detach();
952 debug("forking to background");
953 fork_after_authentication_flag = 0;
954 if (daemon(1, 1) < 0)
955 fatal("daemon() failed: %.200s", strerror(errno));
956}
957
869/* Callback for remote forward global requests */ 958/* Callback for remote forward global requests */
870static void 959static void
871ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 960ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
@@ -877,9 +966,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
877 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", 966 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
878 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); 967 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
879 if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { 968 if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
969 rfwd->allocated_port = packet_get_int();
880 logit("Allocated port %u for remote forward to %s:%d", 970 logit("Allocated port %u for remote forward to %s:%d",
881 packet_get_int(), 971 rfwd->allocated_port,
882 rfwd->connect_host, rfwd->connect_port); 972 rfwd->connect_host, rfwd->connect_port);
883 } 973 }
884 974
885 if (type == SSH2_MSG_REQUEST_FAILURE) { 975 if (type == SSH2_MSG_REQUEST_FAILURE) {
@@ -892,12 +982,8 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
892 } 982 }
893 if (++remote_forward_confirms_received == options.num_remote_forwards) { 983 if (++remote_forward_confirms_received == options.num_remote_forwards) {
894 debug("All remote forwarding requests processed"); 984 debug("All remote forwarding requests processed");
895 if (fork_after_authentication_flag) { 985 if (fork_after_authentication_flag)
896 fork_after_authentication_flag = 0; 986 fork_postauth();
897 if (daemon(1, 1) < 0)
898 fatal("daemon() failed: %.200s",
899 strerror(errno));
900 }
901 } 987 }
902} 988}
903 989
@@ -1093,7 +1179,9 @@ ssh_session(void)
1093 char *proto, *data; 1179 char *proto, *data;
1094 /* Get reasonable local authentication information. */ 1180 /* Get reasonable local authentication information. */
1095 client_x11_get_proto(display, options.xauth_location, 1181 client_x11_get_proto(display, options.xauth_location,
1096 options.forward_x11_trusted, &proto, &data); 1182 options.forward_x11_trusted,
1183 options.forward_x11_timeout,
1184 &proto, &data);
1097 /* Request forwarding with authentication spoofing. */ 1185 /* Request forwarding with authentication spoofing. */
1098 debug("Requesting X11 forwarding with authentication " 1186 debug("Requesting X11 forwarding with authentication "
1099 "spoofing."); 1187 "spoofing.");
@@ -1139,12 +1227,13 @@ ssh_session(void)
1139 * If requested and we are not interested in replies to remote 1227 * If requested and we are not interested in replies to remote
1140 * forwarding requests, then let ssh continue in the background. 1228 * forwarding requests, then let ssh continue in the background.
1141 */ 1229 */
1142 if (fork_after_authentication_flag && 1230 if (fork_after_authentication_flag) {
1143 (!options.exit_on_forward_failure || 1231 if (options.exit_on_forward_failure &&
1144 options.num_remote_forwards == 0)) { 1232 options.num_remote_forwards > 0) {
1145 fork_after_authentication_flag = 0; 1233 debug("deferring postauth fork until remote forward "
1146 if (daemon(1, 1) < 0) 1234 "confirmation received");
1147 fatal("daemon() failed: %.200s", strerror(errno)); 1235 } else
1236 fork_postauth();
1148 } 1237 }
1149 1238
1150 /* 1239 /*
@@ -1175,18 +1264,22 @@ ssh_session(void)
1175 1264
1176/* request pty/x11/agent/tcpfwd/shell for channel */ 1265/* request pty/x11/agent/tcpfwd/shell for channel */
1177static void 1266static void
1178ssh_session2_setup(int id, void *arg) 1267ssh_session2_setup(int id, int success, void *arg)
1179{ 1268{
1180 extern char **environ; 1269 extern char **environ;
1181 const char *display; 1270 const char *display;
1182 int interactive = tty_flag; 1271 int interactive = tty_flag;
1183 1272
1273 if (!success)
1274 return; /* No need for error message, channels code sens one */
1275
1184 display = getenv("DISPLAY"); 1276 display = getenv("DISPLAY");
1185 if (options.forward_x11 && display != NULL) { 1277 if (options.forward_x11 && display != NULL) {
1186 char *proto, *data; 1278 char *proto, *data;
1187 /* Get reasonable local authentication information. */ 1279 /* Get reasonable local authentication information. */
1188 client_x11_get_proto(display, options.xauth_location, 1280 client_x11_get_proto(display, options.xauth_location,
1189 options.forward_x11_trusted, &proto, &data); 1281 options.forward_x11_trusted,
1282 options.forward_x11_timeout, &proto, &data);
1190 /* Request forwarding with authentication spoofing. */ 1283 /* Request forwarding with authentication spoofing. */
1191 debug("Requesting X11 forwarding with authentication " 1284 debug("Requesting X11 forwarding with authentication "
1192 "spoofing."); 1285 "spoofing.");
@@ -1263,6 +1356,31 @@ ssh_session2(void)
1263 /* XXX should be pre-session */ 1356 /* XXX should be pre-session */
1264 ssh_init_forwarding(); 1357 ssh_init_forwarding();
1265 1358
1359 /* Start listening for multiplex clients */
1360 muxserver_listen();
1361
1362 /*
1363 * If we are in control persist mode, then prepare to background
1364 * ourselves and have a foreground client attach as a control
1365 * slave. NB. we must save copies of the flags that we override for
1366 * the backgrounding, since we defer attachment of the slave until
1367 * after the connection is fully established (in particular,
1368 * async rfwd replies have been received for ExitOnForwardFailure).
1369 */
1370 if (options.control_persist && muxserver_sock != -1) {
1371 ostdin_null_flag = stdin_null_flag;
1372 ono_shell_flag = no_shell_flag;
1373 ono_tty_flag = no_tty_flag;
1374 otty_flag = tty_flag;
1375 stdin_null_flag = 1;
1376 no_shell_flag = 1;
1377 no_tty_flag = 1;
1378 tty_flag = 0;
1379 if (!fork_after_authentication_flag)
1380 need_controlpersist_detach = 1;
1381 fork_after_authentication_flag = 1;
1382 }
1383
1266 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1384 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1267 id = ssh_session2_open(); 1385 id = ssh_session2_open();
1268 1386
@@ -1281,14 +1399,17 @@ ssh_session2(void)
1281 options.permit_local_command) 1399 options.permit_local_command)
1282 ssh_local_cmd(options.local_command); 1400 ssh_local_cmd(options.local_command);
1283 1401
1284 /* Start listening for multiplex clients */ 1402 /*
1285 muxserver_listen(); 1403 * If requested and we are not interested in replies to remote
1286 1404 * forwarding requests, then let ssh continue in the background.
1287 /* If requested, let ssh continue in the background. */ 1405 */
1288 if (fork_after_authentication_flag) { 1406 if (fork_after_authentication_flag) {
1289 fork_after_authentication_flag = 0; 1407 if (options.exit_on_forward_failure &&
1290 if (daemon(1, 1) < 0) 1408 options.num_remote_forwards > 0) {
1291 fatal("daemon() failed: %.200s", strerror(errno)); 1409 debug("deferring postauth fork until remote forward "
1410 "confirmation received");
1411 } else
1412 fork_postauth();
1292 } 1413 }
1293 1414
1294 if (options.use_roaming) 1415 if (options.use_roaming)