summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/ssh.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/ssh.c')
-rw-r--r--crypto/openssh/ssh.c125
1 files changed, 78 insertions, 47 deletions
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 1d21f93..7fdae3a 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 djm Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -113,13 +113,16 @@ __RCSID("$FreeBSD$");
extern char *__progname;
+/* Saves a copy of argv for setproctitle emulation */
+#ifndef HAVE_SETPROCTITLE
+static char **saved_av;
+#endif
+
/* Flag indicating whether debug mode is on. May be set on the command line. */
int debug_flag = 0;
-/* Flag indicating whether a tty should be allocated */
+/* Flag indicating whether a tty should be requested */
int tty_flag = 0;
-int no_tty_flag = 0;
-int force_tty_flag = 0;
/* don't exec a shell */
int no_shell_flag = 0;
@@ -137,7 +140,7 @@ int stdin_null_flag = 0;
int need_controlpersist_detach = 0;
/* Copies of flags for ControlPersist foreground slave */
-int ostdin_null_flag, ono_shell_flag, ono_tty_flag, otty_flag;
+int ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;
/*
* Flag indicating that ssh should fork after authentication. This is useful
@@ -216,6 +219,20 @@ static void main_sigchld_handler(int);
void muxclient(const char *);
void muxserver_listen(void);
+/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
+static void
+tilde_expand_paths(char **paths, u_int num_paths)
+{
+ u_int i;
+ char *cp;
+
+ for (i = 0; i < num_paths; i++) {
+ cp = tilde_expand_filename(paths[i], original_real_uid);
+ xfree(paths[i]);
+ paths[i] = cp;
+ }
+}
+
/*
* Main program for the ssh client.
*/
@@ -224,11 +241,13 @@ main(int ac, char **av)
{
int i, r, opt, exit_status, use_syslog;
char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg;
+ char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
struct stat st;
struct passwd *pw;
int dummy, timeout_ms;
extern int optind, optreset;
extern char *optarg;
+
struct servent *sp;
Forward fwd;
@@ -236,7 +255,17 @@ main(int ac, char **av)
sanitise_stdfd();
__progname = ssh_get_progname(av[0]);
- init_rng();
+
+#ifndef HAVE_SETPROCTITLE
+ /* Prepare for later setproctitle emulation */
+ /* Save argv so it isn't clobbered by setproctitle() emulation */
+ saved_av = xcalloc(ac + 1, sizeof(*saved_av));
+ for (i = 0; i < ac; i++)
+ saved_av[i] = xstrdup(av[i]);
+ saved_av[i] = NULL;
+ compat_init_setproctitle(ac, av);
+ av = saved_av;
+#endif
/*
* Discard other fds that are hanging around. These can cause problem
@@ -348,6 +377,8 @@ main(int ac, char **av)
muxclient_command = SSHMUX_COMMAND_FORWARD;
else if (strcmp(optarg, "exit") == 0)
muxclient_command = SSHMUX_COMMAND_TERMINATE;
+ else if (strcmp(optarg, "stop") == 0)
+ muxclient_command = SSHMUX_COMMAND_STOP;
else
fatal("Invalid multiplex command.");
break;
@@ -389,9 +420,10 @@ main(int ac, char **av)
#endif
break;
case 't':
- if (tty_flag)
- force_tty_flag = 1;
- tty_flag = 1;
+ if (options.request_tty == REQUEST_TTY_YES)
+ options.request_tty = REQUEST_TTY_FORCE;
+ else
+ options.request_tty = REQUEST_TTY_YES;
break;
case 'v':
if (debug_flag == 0) {
@@ -434,7 +466,7 @@ main(int ac, char **av)
optarg);
exit(255);
}
- no_tty_flag = 1;
+ options.request_tty = REQUEST_TTY_NO;
no_shell_flag = 1;
options.clear_forwardings = 1;
options.exit_on_forward_failure = 1;
@@ -543,10 +575,10 @@ main(int ac, char **av)
break;
case 'N':
no_shell_flag = 1;
- no_tty_flag = 1;
+ options.request_tty = REQUEST_TTY_NO;
break;
case 'T':
- no_tty_flag = 1;
+ options.request_tty = REQUEST_TTY_NO;
#ifdef NONE_CIPHER_ENABLED
/*
* Ensure that the user does not try to backdoor a
@@ -615,6 +647,10 @@ main(int ac, char **av)
/* Initialize the command to execute on remote host. */
buffer_init(&command);
+ if (options.request_tty == REQUEST_TTY_YES ||
+ options.request_tty == REQUEST_TTY_FORCE)
+ tty_flag = 1;
+
/*
* Save the command to execute on the remote host in a buffer. There
* is no limit on the length of the command, except by the maximum
@@ -622,7 +658,7 @@ main(int ac, char **av)
*/
if (!ac) {
/* No command specified - execute shell on a tty. */
- tty_flag = 1;
+ tty_flag = options.request_tty != REQUEST_TTY_NO;
if (subsystem_flag) {
fprintf(stderr,
"You must specify a subsystem to invoke.\n");
@@ -645,13 +681,14 @@ main(int ac, char **av)
/* Allocate a tty by default if no command specified. */
if (buffer_len(&command) == 0)
- tty_flag = 1;
+ tty_flag = options.request_tty != REQUEST_TTY_NO;
/* Force no tty */
- if (no_tty_flag || muxclient_command != 0)
+ if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
tty_flag = 0;
/* Do not allocate a tty if stdin is not a tty. */
- if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
+ if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
+ options.request_tty != REQUEST_TTY_FORCE) {
if (tty_flag)
logit("Pseudo-terminal will not be allocated because "
"stdin is not a terminal.");
@@ -680,7 +717,7 @@ main(int ac, char **av)
if (r > 0 && (size_t)r < sizeof(buf))
(void)read_config_file(buf, host, &options, 1);
- /* Read systemwide configuration file after use config. */
+ /* Read systemwide configuration file after user config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
&options, 0);
}
@@ -711,17 +748,19 @@ main(int ac, char **av)
"h", host, (char *)NULL);
}
- if (options.local_command != NULL) {
- char thishost[NI_MAXHOST];
+ if (gethostname(thishost, sizeof(thishost)) == -1)
+ fatal("gethostname: %s", strerror(errno));
+ strlcpy(shorthost, thishost, sizeof(shorthost));
+ shorthost[strcspn(thishost, ".")] = '\0';
+ snprintf(portstr, sizeof(portstr), "%d", options.port);
- if (gethostname(thishost, sizeof(thishost)) == -1)
- fatal("gethostname: %s", strerror(errno));
- snprintf(buf, sizeof(buf), "%d", options.port);
+ if (options.local_command != NULL) {
debug3("expanding LocalCommand: %s", options.local_command);
cp = options.local_command;
options.local_command = percent_expand(cp, "d", pw->pw_dir,
"h", host, "l", thishost, "n", host_arg, "r", options.user,
- "p", buf, "u", pw->pw_name, (char *)NULL);
+ "p", portstr, "u", pw->pw_name, "L", shorthost,
+ (char *)NULL);
debug3("expanded LocalCommand: %s", options.local_command);
xfree(cp);
}
@@ -762,16 +801,13 @@ main(int ac, char **av)
}
if (options.control_path != NULL) {
- char thishost[NI_MAXHOST];
-
- if (gethostname(thishost, sizeof(thishost)) == -1)
- fatal("gethostname: %s", strerror(errno));
- snprintf(buf, sizeof(buf), "%d", options.port);
cp = tilde_expand_filename(options.control_path,
original_real_uid);
xfree(options.control_path);
- options.control_path = percent_expand(cp, "p", buf, "h", host,
- "r", options.user, "l", thishost, (char *)NULL);
+ options.control_path = percent_expand(cp, "h", host,
+ "l", thishost, "n", host_arg, "r", options.user,
+ "p", portstr, "u", pw->pw_name, "L", shorthost,
+ (char *)NULL);
xfree(cp);
}
if (muxclient_command != 0 && options.control_path == NULL)
@@ -892,15 +928,9 @@ main(int ac, char **av)
load_public_identity_files();
/* Expand ~ in known host file names. */
- /* XXX mem-leaks: */
- options.system_hostfile =
- tilde_expand_filename(options.system_hostfile, original_real_uid);
- options.user_hostfile =
- tilde_expand_filename(options.user_hostfile, original_real_uid);
- options.system_hostfile2 =
- tilde_expand_filename(options.system_hostfile2, original_real_uid);
- options.user_hostfile2 =
- tilde_expand_filename(options.user_hostfile2, original_real_uid);
+ tilde_expand_paths(options.system_hostfiles,
+ options.num_system_hostfiles);
+ tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
signal(SIGCHLD, main_sigchld_handler);
@@ -973,8 +1003,7 @@ control_persist_detach(void)
/* Parent: set up mux slave to connect to backgrounded master */
debug2("%s: background process is %ld", __func__, (long)pid);
stdin_null_flag = ostdin_null_flag;
- no_shell_flag = ono_shell_flag;
- no_tty_flag = ono_tty_flag;
+ options.request_tty = orequest_tty;
tty_flag = otty_flag;
close(muxserver_sock);
muxserver_sock = -1;
@@ -993,6 +1022,7 @@ control_persist_detach(void)
if (devnull > STDERR_FILENO)
close(devnull);
}
+ setproctitle("%s [mux]", options.control_path);
}
/* Do fork() after authentication. Used by "ssh -f" */
@@ -1237,8 +1267,8 @@ ssh_session(void)
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
- x11_request_forwarding_with_spoofing(0, display, proto, data);
-
+ x11_request_forwarding_with_spoofing(0, display, proto,
+ data, 0);
/* Read response from the server. */
type = packet_read();
if (type == SSH_SMSG_SUCCESS) {
@@ -1336,9 +1366,11 @@ ssh_session2_setup(int id, int success, void *arg)
/* Request forwarding with authentication spoofing. */
debug("Requesting X11 forwarding with authentication "
"spoofing.");
- x11_request_forwarding_with_spoofing(id, display, proto, data);
+ x11_request_forwarding_with_spoofing(id, display, proto,
+ data, 1);
+ client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
+ /* XXX exit_on_forward_failure */
interactive = 1;
- /* XXX wait for reply */
}
check_agent_present();
@@ -1461,11 +1493,10 @@ ssh_session2(void)
if (options.control_persist && muxserver_sock != -1) {
ostdin_null_flag = stdin_null_flag;
ono_shell_flag = no_shell_flag;
- ono_tty_flag = no_tty_flag;
+ orequest_tty = options.request_tty;
otty_flag = tty_flag;
stdin_null_flag = 1;
no_shell_flag = 1;
- no_tty_flag = 1;
tty_flag = 0;
if (!fork_after_authentication_flag)
need_controlpersist_detach = 1;
OpenPOWER on IntegriCloud