summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/ssh.c b/ssh.c
index 4419f7642..9409fa713 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.346 2010/08/12 21:49:44 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 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>
@@ -182,9 +183,6 @@ int subsystem_flag = 0;
182/* # of replies received for global requests */ 183/* # of replies received for global requests */
183static int remote_forward_confirms_received = 0; 184static int remote_forward_confirms_received = 0;
184 185
185/* pid of proxycommand child process */
186pid_t proxy_command_pid = 0;
187
188/* mux.c */ 186/* mux.c */
189extern int muxserver_sock; 187extern int muxserver_sock;
190extern u_int muxclient_command; 188extern u_int muxclient_command;
@@ -210,6 +208,7 @@ usage(void)
210static int ssh_session(void); 208static int ssh_session(void);
211static int ssh_session2(void); 209static int ssh_session2(void);
212static void load_public_identity_files(void); 210static void load_public_identity_files(void);
211static void main_sigchld_handler(int);
213 212
214/* from muxclient.c */ 213/* from muxclient.c */
215void muxclient(const char *); 214void muxclient(const char *);
@@ -222,7 +221,7 @@ int
222main(int ac, char **av) 221main(int ac, char **av)
223{ 222{
224 int i, r, opt, exit_status, use_syslog; 223 int i, r, opt, exit_status, use_syslog;
225 char *p, *cp, *line, *argv0, buf[MAXPATHLEN]; 224 char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg;
226 struct stat st; 225 struct stat st;
227 struct passwd *pw; 226 struct passwd *pw;
228 int dummy, timeout_ms; 227 int dummy, timeout_ms;
@@ -599,7 +598,7 @@ main(int ac, char **av)
599 if (!host) 598 if (!host)
600 usage(); 599 usage();
601 600
602 SSLeay_add_all_algorithms(); 601 OpenSSL_add_all_algorithms();
603 ERR_load_crypto_strings(); 602 ERR_load_crypto_strings();
604 603
605 /* Initialize the command to execute on remote host. */ 604 /* Initialize the command to execute on remote host. */
@@ -694,6 +693,8 @@ main(int ac, char **av)
694 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; 693 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
695 } 694 }
696 695
696 /* preserve host name given on command line for %n expansion */
697 host_arg = host;
697 if (options.hostname != NULL) { 698 if (options.hostname != NULL) {
698 host = percent_expand(options.hostname, 699 host = percent_expand(options.hostname,
699 "h", host, (char *)NULL); 700 "h", host, (char *)NULL);
@@ -708,7 +709,7 @@ main(int ac, char **av)
708 debug3("expanding LocalCommand: %s", options.local_command); 709 debug3("expanding LocalCommand: %s", options.local_command);
709 cp = options.local_command; 710 cp = options.local_command;
710 options.local_command = percent_expand(cp, "d", pw->pw_dir, 711 options.local_command = percent_expand(cp, "d", pw->pw_dir,
711 "h", host, "l", thishost, "n", host, "r", options.user, 712 "h", host, "l", thishost, "n", host_arg, "r", options.user,
712 "p", buf, "u", pw->pw_name, (char *)NULL); 713 "p", buf, "u", pw->pw_name, (char *)NULL);
713 debug3("expanded LocalCommand: %s", options.local_command); 714 debug3("expanded LocalCommand: %s", options.local_command);
714 xfree(cp); 715 xfree(cp);
@@ -780,34 +781,53 @@ main(int ac, char **av)
780 sensitive_data.external_keysign = 0; 781 sensitive_data.external_keysign = 0;
781 if (options.rhosts_rsa_authentication || 782 if (options.rhosts_rsa_authentication ||
782 options.hostbased_authentication) { 783 options.hostbased_authentication) {
783 sensitive_data.nkeys = 5; 784 sensitive_data.nkeys = 7;
784 sensitive_data.keys = xcalloc(sensitive_data.nkeys, 785 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
785 sizeof(Key)); 786 sizeof(Key));
787 for (i = 0; i < sensitive_data.nkeys; i++)
788 sensitive_data.keys[i] = NULL;
786 789
787 PRIV_START; 790 PRIV_START;
788 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 791 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
789 _PATH_HOST_KEY_FILE, "", NULL, NULL); 792 _PATH_HOST_KEY_FILE, "", NULL, NULL);
790 sensitive_data.keys[1] = key_load_private_cert(KEY_DSA, 793 sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
791 _PATH_HOST_DSA_KEY_FILE, "", NULL); 794 _PATH_HOST_DSA_KEY_FILE, "", NULL);
792 sensitive_data.keys[2] = key_load_private_cert(KEY_RSA, 795#ifdef OPENSSL_HAS_ECC
796 sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
797 _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
798#endif
799 sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
793 _PATH_HOST_RSA_KEY_FILE, "", NULL); 800 _PATH_HOST_RSA_KEY_FILE, "", NULL);
794 sensitive_data.keys[3] = key_load_private_type(KEY_DSA, 801 sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
795 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); 802 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
796 sensitive_data.keys[4] = key_load_private_type(KEY_RSA, 803#ifdef OPENSSL_HAS_ECC
804 sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
805 _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
806#endif
807 sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
797 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); 808 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
798 PRIV_END; 809 PRIV_END;
799 810
800 if (options.hostbased_authentication == 1 && 811 if (options.hostbased_authentication == 1 &&
801 sensitive_data.keys[0] == NULL && 812 sensitive_data.keys[0] == NULL &&
802 sensitive_data.keys[3] == NULL && 813 sensitive_data.keys[4] == NULL &&
803 sensitive_data.keys[4] == NULL) { 814 sensitive_data.keys[5] == NULL &&
815 sensitive_data.keys[6] == NULL) {
804 sensitive_data.keys[1] = key_load_cert( 816 sensitive_data.keys[1] = key_load_cert(
805 _PATH_HOST_DSA_KEY_FILE); 817 _PATH_HOST_DSA_KEY_FILE);
818#ifdef OPENSSL_HAS_ECC
806 sensitive_data.keys[2] = key_load_cert( 819 sensitive_data.keys[2] = key_load_cert(
820 _PATH_HOST_ECDSA_KEY_FILE);
821#endif
822 sensitive_data.keys[3] = key_load_cert(
807 _PATH_HOST_RSA_KEY_FILE); 823 _PATH_HOST_RSA_KEY_FILE);
808 sensitive_data.keys[3] = key_load_public(
809 _PATH_HOST_DSA_KEY_FILE, NULL);
810 sensitive_data.keys[4] = key_load_public( 824 sensitive_data.keys[4] = key_load_public(
825 _PATH_HOST_DSA_KEY_FILE, NULL);
826#ifdef OPENSSL_HAS_ECC
827 sensitive_data.keys[5] = key_load_public(
828 _PATH_HOST_ECDSA_KEY_FILE, NULL);
829#endif
830 sensitive_data.keys[6] = key_load_public(
811 _PATH_HOST_RSA_KEY_FILE, NULL); 831 _PATH_HOST_RSA_KEY_FILE, NULL);
812 sensitive_data.external_keysign = 1; 832 sensitive_data.external_keysign = 1;
813 } 833 }
@@ -830,10 +850,19 @@ main(int ac, char **av)
830 */ 850 */
831 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir, 851 r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
832 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); 852 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
833 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) 853 if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
854#ifdef WITH_SELINUX
855 char *scon;
856
857 matchpathcon(buf, 0700, &scon);
858 setfscreatecon(scon);
859#endif
834 if (mkdir(buf, 0700) < 0) 860 if (mkdir(buf, 0700) < 0)
835 error("Could not create directory '%.200s'.", buf); 861 error("Could not create directory '%.200s'.", buf);
836 862#ifdef WITH_SELINUX
863 setfscreatecon(NULL);
864#endif
865 }
837 /* load options.identity_files */ 866 /* load options.identity_files */
838 load_public_identity_files(); 867 load_public_identity_files();
839 868
@@ -849,10 +878,11 @@ main(int ac, char **av)
849 tilde_expand_filename(options.user_hostfile2, original_real_uid); 878 tilde_expand_filename(options.user_hostfile2, original_real_uid);
850 879
851 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ 880 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
881 signal(SIGCHLD, main_sigchld_handler);
852 882
853 /* Log into the remote system. Never returns if the login fails. */ 883 /* Log into the remote system. Never returns if the login fails. */
854 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, 884 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
855 pw, timeout_ms); 885 options.port, pw, timeout_ms);
856 886
857 if (packet_connection_is_on_socket()) { 887 if (packet_connection_is_on_socket()) {
858 verbose("Authenticated to %s ([%s]:%d).", host, 888 verbose("Authenticated to %s ([%s]:%d).", host,
@@ -890,12 +920,8 @@ main(int ac, char **av)
890 if (options.control_path != NULL && muxserver_sock != -1) 920 if (options.control_path != NULL && muxserver_sock != -1)
891 unlink(options.control_path); 921 unlink(options.control_path);
892 922
893 /* 923 /* Kill ProxyCommand if it is running. */
894 * Send SIGHUP to proxy command if used. We don't wait() in 924 ssh_kill_proxy_command();
895 * case it hangs and instead rely on init to reap the child
896 */
897 if (proxy_command_pid > 1)
898 kill(proxy_command_pid, SIGHUP);
899 925
900 return exit_status; 926 return exit_status;
901} 927}
@@ -927,6 +953,7 @@ control_persist_detach(void)
927 tty_flag = otty_flag; 953 tty_flag = otty_flag;
928 close(muxserver_sock); 954 close(muxserver_sock);
929 muxserver_sock = -1; 955 muxserver_sock = -1;
956 options.control_master = SSHCTL_MASTER_NO;
930 muxclient(options.control_path); 957 muxclient(options.control_path);
931 /* muxclient() doesn't return on success. */ 958 /* muxclient() doesn't return on success. */
932 fatal("Failed to connect to new control master"); 959 fatal("Failed to connect to new control master");
@@ -1199,7 +1226,8 @@ ssh_session(void)
1199 } 1226 }
1200 } 1227 }
1201 /* Tell the packet module whether this is an interactive session. */ 1228 /* Tell the packet module whether this is an interactive session. */
1202 packet_set_interactive(interactive); 1229 packet_set_interactive(interactive,
1230 options.ip_qos_interactive, options.ip_qos_bulk);
1203 1231
1204 /* Request authentication agent forwarding if appropriate. */ 1232 /* Request authentication agent forwarding if appropriate. */
1205 check_agent_present(); 1233 check_agent_present();
@@ -1297,8 +1325,6 @@ ssh_session2_setup(int id, int success, void *arg)
1297 1325
1298 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1326 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1299 NULL, fileno(stdin), &command, environ); 1327 NULL, fileno(stdin), &command, environ);
1300
1301 packet_set_interactive(interactive);
1302} 1328}
1303 1329
1304/* open new channel for a session */ 1330/* open new channel for a session */
@@ -1516,3 +1542,19 @@ load_public_identity_files(void)
1516 bzero(pwdir, strlen(pwdir)); 1542 bzero(pwdir, strlen(pwdir));
1517 xfree(pwdir); 1543 xfree(pwdir);
1518} 1544}
1545
1546static void
1547main_sigchld_handler(int sig)
1548{
1549 int save_errno = errno;
1550 pid_t pid;
1551 int status;
1552
1553 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
1554 (pid < 0 && errno == EINTR))
1555 ;
1556
1557 signal(sig, main_sigchld_handler);
1558 errno = save_errno;
1559}
1560