summaryrefslogtreecommitdiff
path: root/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh.c')
-rw-r--r--ssh.c125
1 files changed, 78 insertions, 47 deletions
diff --git a/ssh.c b/ssh.c
index aa2ad4a2f..44b005687 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 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
@@ -111,13 +111,16 @@
111 111
112extern char *__progname; 112extern char *__progname;
113 113
114/* Saves a copy of argv for setproctitle emulation */
115#ifndef HAVE_SETPROCTITLE
116static char **saved_av;
117#endif
118
114/* Flag indicating whether debug mode is on. May be set on the command line. */ 119/* Flag indicating whether debug mode is on. May be set on the command line. */
115int debug_flag = 0; 120int debug_flag = 0;
116 121
117/* Flag indicating whether a tty should be allocated */ 122/* Flag indicating whether a tty should be requested */
118int tty_flag = 0; 123int tty_flag = 0;
119int no_tty_flag = 0;
120int force_tty_flag = 0;
121 124
122/* don't exec a shell */ 125/* don't exec a shell */
123int no_shell_flag = 0; 126int no_shell_flag = 0;
@@ -135,7 +138,7 @@ int stdin_null_flag = 0;
135int need_controlpersist_detach = 0; 138int need_controlpersist_detach = 0;
136 139
137/* Copies of flags for ControlPersist foreground slave */ 140/* Copies of flags for ControlPersist foreground slave */
138int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag; 141int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;
139 142
140/* 143/*
141 * Flag indicating that ssh should fork after authentication. This is useful 144 * Flag indicating that ssh should fork after authentication. This is useful
@@ -214,6 +217,20 @@ static void main_sigchld_handler(int);
214void muxclient(const char *); 217void muxclient(const char *);
215void muxserver_listen(void); 218void muxserver_listen(void);
216 219
220/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
221static void
222tilde_expand_paths(char **paths, u_int num_paths)
223{
224 u_int i;
225 char *cp;
226
227 for (i = 0; i < num_paths; i++) {
228 cp = tilde_expand_filename(paths[i], original_real_uid);
229 xfree(paths[i]);
230 paths[i] = cp;
231 }
232}
233
217/* 234/*
218 * Main program for the ssh client. 235 * Main program for the ssh client.
219 */ 236 */
@@ -222,11 +239,13 @@ main(int ac, char **av)
222{ 239{
223 int i, r, opt, exit_status, use_syslog; 240 int i, r, opt, exit_status, use_syslog;
224 char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg; 241 char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg;
242 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
225 struct stat st; 243 struct stat st;
226 struct passwd *pw; 244 struct passwd *pw;
227 int dummy, timeout_ms; 245 int dummy, timeout_ms;
228 extern int optind, optreset; 246 extern int optind, optreset;
229 extern char *optarg; 247 extern char *optarg;
248
230 struct servent *sp; 249 struct servent *sp;
231 Forward fwd; 250 Forward fwd;
232 251
@@ -234,7 +253,17 @@ main(int ac, char **av)
234 sanitise_stdfd(); 253 sanitise_stdfd();
235 254
236 __progname = ssh_get_progname(av[0]); 255 __progname = ssh_get_progname(av[0]);
237 init_rng(); 256
257#ifndef HAVE_SETPROCTITLE
258 /* Prepare for later setproctitle emulation */
259 /* Save argv so it isn't clobbered by setproctitle() emulation */
260 saved_av = xcalloc(ac + 1, sizeof(*saved_av));
261 for (i = 0; i < ac; i++)
262 saved_av[i] = xstrdup(av[i]);
263 saved_av[i] = NULL;
264 compat_init_setproctitle(ac, av);
265 av = saved_av;
266#endif
238 267
239 /* 268 /*
240 * Discard other fds that are hanging around. These can cause problem 269 * Discard other fds that are hanging around. These can cause problem
@@ -346,6 +375,8 @@ main(int ac, char **av)
346 muxclient_command = SSHMUX_COMMAND_FORWARD; 375 muxclient_command = SSHMUX_COMMAND_FORWARD;
347 else if (strcmp(optarg, "exit") == 0) 376 else if (strcmp(optarg, "exit") == 0)
348 muxclient_command = SSHMUX_COMMAND_TERMINATE; 377 muxclient_command = SSHMUX_COMMAND_TERMINATE;
378 else if (strcmp(optarg, "stop") == 0)
379 muxclient_command = SSHMUX_COMMAND_STOP;
349 else 380 else
350 fatal("Invalid multiplex command."); 381 fatal("Invalid multiplex command.");
351 break; 382 break;
@@ -387,9 +418,10 @@ main(int ac, char **av)
387#endif 418#endif
388 break; 419 break;
389 case 't': 420 case 't':
390 if (tty_flag) 421 if (options.request_tty == REQUEST_TTY_YES)
391 force_tty_flag = 1; 422 options.request_tty = REQUEST_TTY_FORCE;
392 tty_flag = 1; 423 else
424 options.request_tty = REQUEST_TTY_YES;
393 break; 425 break;
394 case 'v': 426 case 'v':
395 if (debug_flag == 0) { 427 if (debug_flag == 0) {
@@ -432,7 +464,7 @@ main(int ac, char **av)
432 optarg); 464 optarg);
433 exit(255); 465 exit(255);
434 } 466 }
435 no_tty_flag = 1; 467 options.request_tty = REQUEST_TTY_NO;
436 no_shell_flag = 1; 468 no_shell_flag = 1;
437 options.clear_forwardings = 1; 469 options.clear_forwardings = 1;
438 options.exit_on_forward_failure = 1; 470 options.exit_on_forward_failure = 1;
@@ -541,10 +573,10 @@ main(int ac, char **av)
541 break; 573 break;
542 case 'N': 574 case 'N':
543 no_shell_flag = 1; 575 no_shell_flag = 1;
544 no_tty_flag = 1; 576 options.request_tty = REQUEST_TTY_NO;
545 break; 577 break;
546 case 'T': 578 case 'T':
547 no_tty_flag = 1; 579 options.request_tty = REQUEST_TTY_NO;
548 break; 580 break;
549 case 'o': 581 case 'o':
550 dummy = 1; 582 dummy = 1;
@@ -604,6 +636,10 @@ main(int ac, char **av)
604 /* Initialize the command to execute on remote host. */ 636 /* Initialize the command to execute on remote host. */
605 buffer_init(&command); 637 buffer_init(&command);
606 638
639 if (options.request_tty == REQUEST_TTY_YES ||
640 options.request_tty == REQUEST_TTY_FORCE)
641 tty_flag = 1;
642
607 /* 643 /*
608 * Save the command to execute on the remote host in a buffer. There 644 * Save the command to execute on the remote host in a buffer. There
609 * is no limit on the length of the command, except by the maximum 645 * is no limit on the length of the command, except by the maximum
@@ -611,7 +647,7 @@ main(int ac, char **av)
611 */ 647 */
612 if (!ac) { 648 if (!ac) {
613 /* No command specified - execute shell on a tty. */ 649 /* No command specified - execute shell on a tty. */
614 tty_flag = 1; 650 tty_flag = options.request_tty != REQUEST_TTY_NO;
615 if (subsystem_flag) { 651 if (subsystem_flag) {
616 fprintf(stderr, 652 fprintf(stderr,
617 "You must specify a subsystem to invoke.\n"); 653 "You must specify a subsystem to invoke.\n");
@@ -634,13 +670,14 @@ main(int ac, char **av)
634 670
635 /* Allocate a tty by default if no command specified. */ 671 /* Allocate a tty by default if no command specified. */
636 if (buffer_len(&command) == 0) 672 if (buffer_len(&command) == 0)
637 tty_flag = 1; 673 tty_flag = options.request_tty != REQUEST_TTY_NO;
638 674
639 /* Force no tty */ 675 /* Force no tty */
640 if (no_tty_flag || muxclient_command != 0) 676 if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
641 tty_flag = 0; 677 tty_flag = 0;
642 /* Do not allocate a tty if stdin is not a tty. */ 678 /* Do not allocate a tty if stdin is not a tty. */
643 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { 679 if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
680 options.request_tty != REQUEST_TTY_FORCE) {
644 if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) 681 if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
645 logit("Pseudo-terminal will not be allocated because " 682 logit("Pseudo-terminal will not be allocated because "
646 "stdin is not a terminal."); 683 "stdin is not a terminal.");
@@ -669,7 +706,7 @@ main(int ac, char **av)
669 if (r > 0 && (size_t)r < sizeof(buf)) 706 if (r > 0 && (size_t)r < sizeof(buf))
670 (void)read_config_file(buf, host, &options, 1); 707 (void)read_config_file(buf, host, &options, 1);
671 708
672 /* Read systemwide configuration file after use config. */ 709 /* Read systemwide configuration file after user config. */
673 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, 710 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
674 &options, 0); 711 &options, 0);
675 } 712 }
@@ -700,17 +737,19 @@ main(int ac, char **av)
700 "h", host, (char *)NULL); 737 "h", host, (char *)NULL);
701 } 738 }
702 739
703 if (options.local_command != NULL) { 740 if (gethostname(thishost, sizeof(thishost)) == -1)
704 char thishost[NI_MAXHOST]; 741 fatal("gethostname: %s", strerror(errno));
742 strlcpy(shorthost, thishost, sizeof(shorthost));
743 shorthost[strcspn(thishost, ".")] = '\0';
744 snprintf(portstr, sizeof(portstr), "%d", options.port);
705 745
706 if (gethostname(thishost, sizeof(thishost)) == -1) 746 if (options.local_command != NULL) {
707 fatal("gethostname: %s", strerror(errno));
708 snprintf(buf, sizeof(buf), "%d", options.port);
709 debug3("expanding LocalCommand: %s", options.local_command); 747 debug3("expanding LocalCommand: %s", options.local_command);
710 cp = options.local_command; 748 cp = options.local_command;
711 options.local_command = percent_expand(cp, "d", pw->pw_dir, 749 options.local_command = percent_expand(cp, "d", pw->pw_dir,
712 "h", host, "l", thishost, "n", host_arg, "r", options.user, 750 "h", host, "l", thishost, "n", host_arg, "r", options.user,
713 "p", buf, "u", pw->pw_name, (char *)NULL); 751 "p", portstr, "u", pw->pw_name, "L", shorthost,
752 (char *)NULL);
714 debug3("expanded LocalCommand: %s", options.local_command); 753 debug3("expanded LocalCommand: %s", options.local_command);
715 xfree(cp); 754 xfree(cp);
716 } 755 }
@@ -734,16 +773,13 @@ main(int ac, char **av)
734 } 773 }
735 774
736 if (options.control_path != NULL) { 775 if (options.control_path != NULL) {
737 char thishost[NI_MAXHOST];
738
739 if (gethostname(thishost, sizeof(thishost)) == -1)
740 fatal("gethostname: %s", strerror(errno));
741 snprintf(buf, sizeof(buf), "%d", options.port);
742 cp = tilde_expand_filename(options.control_path, 776 cp = tilde_expand_filename(options.control_path,
743 original_real_uid); 777 original_real_uid);
744 xfree(options.control_path); 778 xfree(options.control_path);
745 options.control_path = percent_expand(cp, "p", buf, "h", host, 779 options.control_path = percent_expand(cp, "h", host,
746 "r", options.user, "l", thishost, (char *)NULL); 780 "l", thishost, "n", host_arg, "r", options.user,
781 "p", portstr, "u", pw->pw_name, "L", shorthost,
782 (char *)NULL);
747 xfree(cp); 783 xfree(cp);
748 } 784 }
749 if (muxclient_command != 0 && options.control_path == NULL) 785 if (muxclient_command != 0 && options.control_path == NULL)
@@ -864,15 +900,9 @@ main(int ac, char **av)
864 load_public_identity_files(); 900 load_public_identity_files();
865 901
866 /* Expand ~ in known host file names. */ 902 /* Expand ~ in known host file names. */
867 /* XXX mem-leaks: */ 903 tilde_expand_paths(options.system_hostfiles,
868 options.system_hostfile = 904 options.num_system_hostfiles);
869 tilde_expand_filename(options.system_hostfile, original_real_uid); 905 tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
870 options.user_hostfile =
871 tilde_expand_filename(options.user_hostfile, original_real_uid);
872 options.system_hostfile2 =
873 tilde_expand_filename(options.system_hostfile2, original_real_uid);
874 options.user_hostfile2 =
875 tilde_expand_filename(options.user_hostfile2, original_real_uid);
876 906
877 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ 907 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
878 signal(SIGCHLD, main_sigchld_handler); 908 signal(SIGCHLD, main_sigchld_handler);
@@ -945,8 +975,7 @@ control_persist_detach(void)
945 /* Parent: set up mux slave to connect to backgrounded master */ 975 /* Parent: set up mux slave to connect to backgrounded master */
946 debug2("%s: background process is %ld", __func__, (long)pid); 976 debug2("%s: background process is %ld", __func__, (long)pid);
947 stdin_null_flag = ostdin_null_flag; 977 stdin_null_flag = ostdin_null_flag;
948 no_shell_flag = ono_shell_flag; 978 options.request_tty = orequest_tty;
949 no_tty_flag = ono_tty_flag;
950 tty_flag = otty_flag; 979 tty_flag = otty_flag;
951 close(muxserver_sock); 980 close(muxserver_sock);
952 muxserver_sock = -1; 981 muxserver_sock = -1;
@@ -965,6 +994,7 @@ control_persist_detach(void)
965 if (devnull > STDERR_FILENO) 994 if (devnull > STDERR_FILENO)
966 close(devnull); 995 close(devnull);
967 } 996 }
997 setproctitle("%s [mux]", options.control_path);
968} 998}
969 999
970/* Do fork() after authentication. Used by "ssh -f" */ 1000/* Do fork() after authentication. Used by "ssh -f" */
@@ -1209,8 +1239,8 @@ ssh_session(void)
1209 /* Request forwarding with authentication spoofing. */ 1239 /* Request forwarding with authentication spoofing. */
1210 debug("Requesting X11 forwarding with authentication " 1240 debug("Requesting X11 forwarding with authentication "
1211 "spoofing."); 1241 "spoofing.");
1212 x11_request_forwarding_with_spoofing(0, display, proto, data); 1242 x11_request_forwarding_with_spoofing(0, display, proto,
1213 1243 data, 0);
1214 /* Read response from the server. */ 1244 /* Read response from the server. */
1215 type = packet_read(); 1245 type = packet_read();
1216 if (type == SSH_SMSG_SUCCESS) { 1246 if (type == SSH_SMSG_SUCCESS) {
@@ -1308,9 +1338,11 @@ ssh_session2_setup(int id, int success, void *arg)
1308 /* Request forwarding with authentication spoofing. */ 1338 /* Request forwarding with authentication spoofing. */
1309 debug("Requesting X11 forwarding with authentication " 1339 debug("Requesting X11 forwarding with authentication "
1310 "spoofing."); 1340 "spoofing.");
1311 x11_request_forwarding_with_spoofing(id, display, proto, data); 1341 x11_request_forwarding_with_spoofing(id, display, proto,
1342 data, 1);
1343 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
1344 /* XXX exit_on_forward_failure */
1312 interactive = 1; 1345 interactive = 1;
1313 /* XXX wait for reply */
1314 } 1346 }
1315 1347
1316 check_agent_present(); 1348 check_agent_present();
@@ -1393,11 +1425,10 @@ ssh_session2(void)
1393 if (options.control_persist && muxserver_sock != -1) { 1425 if (options.control_persist && muxserver_sock != -1) {
1394 ostdin_null_flag = stdin_null_flag; 1426 ostdin_null_flag = stdin_null_flag;
1395 ono_shell_flag = no_shell_flag; 1427 ono_shell_flag = no_shell_flag;
1396 ono_tty_flag = no_tty_flag; 1428 orequest_tty = options.request_tty;
1397 otty_flag = tty_flag; 1429 otty_flag = tty_flag;
1398 stdin_null_flag = 1; 1430 stdin_null_flag = 1;
1399 no_shell_flag = 1; 1431 no_shell_flag = 1;
1400 no_tty_flag = 1;
1401 tty_flag = 0; 1432 tty_flag = 0;
1402 if (!fork_after_authentication_flag) 1433 if (!fork_after_authentication_flag)
1403 need_controlpersist_detach = 1; 1434 need_controlpersist_detach = 1;