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