1 /*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Ssh client program. This program can be used to log into a remote machine.
6 * The software supports strong authentication, encryption, and forwarding
7 * of X11, TCP/IP, and authentication connections.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 *
15 * Copyright (c) 1999 Niels Provos. All rights reserved.
16 * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
17 *
18 * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
19 * in Canada (German citizen).
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
39 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41 /*
42 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
43 * Use is subject to license terms.
44 */
45
46 #include "includes.h"
47 RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $");
48
49 #include <openssl/err.h>
50
51 #include "ssh.h"
52 #include "ssh1.h"
53 #include "ssh2.h"
54 #include "compat.h"
55 #include "cipher.h"
56 #include "xmalloc.h"
57 #include "packet.h"
58 #include "buffer.h"
59 #include "channels.h"
60 #include "key.h"
61 #include "authfd.h"
62 #include "authfile.h"
63 #include "pathnames.h"
64 #include "clientloop.h"
65 #include "log.h"
66 #include "readconf.h"
67 #include "sshconnect.h"
68 #include "tildexpand.h"
69 #include "dispatch.h"
70 #include "misc.h"
71 #include "kex.h"
72 #include "mac.h"
73 #include "sshtty.h"
74
75 #include "g11n.h"
76
77 #ifdef HAVE___PROGNAME
78 extern char *__progname;
79 #else
80 char *__progname;
81 #endif
82
83 /* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
84 Default value is AF_UNSPEC means both IPv4 and IPv6. */
85 #ifdef IPV4_DEFAULT
86 int IPv4or6 = AF_INET;
87 #else
88 int IPv4or6 = AF_UNSPEC;
89 #endif
90
91 /* Flag indicating whether debug mode is on. This can be set on the command line. */
92 int debug_flag = 0;
93
94 /* Flag indicating whether a tty should be allocated */
95 int tty_flag = 0;
96 int no_tty_flag = 0;
97 int force_tty_flag = 0;
98
99 /* don't exec a shell */
100 int no_shell_flag = 0;
101
102 /*
103 * Flag indicating that nothing should be read from stdin. This can be set
104 * on the command line.
105 */
106 int stdin_null_flag = 0;
107
108 /*
109 * Flag indicating that ssh should fork after authentication. This is useful
110 * so that the passphrase can be entered manually, and then ssh goes to the
111 * background.
112 */
113 int fork_after_authentication_flag = 0;
114
115 /*
116 * General data structure for command line options and options configurable
117 * in configuration files. See readconf.h.
118 */
119 Options options;
120
121 /* optional user configfile */
122 char *config = NULL;
123
124 /*
125 * Name of the host we are connecting to. This is the name given on the
126 * command line, or the HostName specified for the user-supplied name in a
127 * configuration file.
128 */
129 char *host;
130
131 /* socket address the host resolves to */
132 struct sockaddr_storage hostaddr;
133
134 /* Private host keys. */
135 Sensitive sensitive_data;
136
137 /* Original real UID. */
138 uid_t original_real_uid;
139 uid_t original_effective_uid;
140
141 /* command to be executed */
142 Buffer command;
143
144 /* Should we execute a command or invoke a subsystem? */
145 int subsystem_flag = 0;
146
147 /* # of replies received for global requests */
148 static int client_global_request_id = 0;
149
150 /* pid of proxycommand child process */
151 pid_t proxy_command_pid = 0;
152
153 /* Prints a help message to the user. This function never returns. */
154
155 static void
usage(void)156 usage(void)
157 {
158 fprintf(stderr,
159 gettext("Usage: %s [options] host [command]\n"
160 "Options:\n"
161 " -l user Log in using this user name.\n"
162 " -n Redirect input from /dev/null.\n"
163 " -F config Config file (default: ~/%s).\n"
164 " -A Enable authentication agent forwarding.\n"
165 " -a Disable authentication agent forwarding "
166 "(default).\n"
167 #ifdef AFS
168 " -k Disable Kerberos ticket and AFS token "
169 "forwarding.\n"
170 #endif /* AFS */
171 " -X Enable X11 connection forwarding.\n"
172 " -x Disable X11 connection forwarding (default).\n"
173 " -i file Identity for public key authentication "
174 "(default: ~/.ssh/identity)\n"
175 " -t Tty; allocate a tty even if command is given.\n"
176 " -T Do not allocate a tty.\n"
177 " -v Verbose; display verbose debugging messages.\n"
178 " Multiple -v increases verbosity.\n"
179 " -V Display version number only.\n"
180 " -q Quiet; don't display any warning messages.\n"
181 " -f Fork into background after authentication.\n"
182 " -e char Set escape character; ``none'' = disable "
183 "(default: ~).\n"
184 " -c cipher Select encryption algorithm\n"
185 " -m macs Specify MAC algorithms for protocol version 2.\n"
186 " -p port Connect to this port. Server must be "
187 "on the same port.\n"
188 " -L listen-port:host:port Forward local port to "
189 "remote address\n"
190 " -R listen-port:host:port Forward remote port to "
191 "local address\n"
192 " These cause %s to listen for connections "
193 "on a port, and\n"
194 " forward them to the other side by "
195 "connecting to host:port.\n"
196 " -D port Enable dynamic application-level "
197 "port forwarding.\n"
198 " -C Enable compression.\n"
199 " -N Do not execute a shell or command.\n"
200 " -g Allow remote hosts to connect to forwarded "
201 "ports.\n"
202 " -1 Force protocol version 1.\n"
203 " -2 Force protocol version 2.\n"
204 " -4 Use IPv4 only.\n"
205 " -6 Use IPv6 only.\n"
206 " -o 'option' Process the option as if it was read "
207 "from a configuration file.\n"
208 " -s Invoke command (mandatory) as SSH2 subsystem.\n"
209 " -b addr Local IP address.\n"),
210 __progname, _PATH_SSH_USER_CONFFILE, __progname);
211 exit(1);
212 }
213
214 static int ssh_session(void);
215 static int ssh_session2(void);
216 static void load_public_identity_files(void);
217 static void rsh_connect(char *host, char *user, Buffer * command);
218
219 /*
220 * Main program for the ssh client.
221 */
222 int
main(int ac,char ** av)223 main(int ac, char **av)
224 {
225 int i, opt, exit_status;
226 char *p, *cp, buf[256], *pw_name, *pw_dir;
227 struct stat st;
228 struct passwd *pw;
229 int dummy;
230 extern int optind, optreset;
231 extern char *optarg;
232 Forward fwd;
233
234 __progname = get_progname(av[0]);
235
236 (void) g11n_setlocale(LC_ALL, "");
237
238 init_rng();
239
240 /*
241 * Save the original real uid. It will be needed later (uid-swapping
242 * may clobber the real uid).
243 */
244 original_real_uid = getuid();
245 original_effective_uid = geteuid();
246
247 /*
248 * Use uid-swapping to give up root privileges for the duration of
249 * option processing. We will re-instantiate the rights when we are
250 * ready to create the privileged port, and will permanently drop
251 * them when the port has been created (actually, when the connection
252 * has been made, as we may need to create the port several times).
253 */
254 PRIV_END;
255
256 #ifdef HAVE_SETRLIMIT
257 /* If we are installed setuid root be careful to not drop core. */
258 if (original_real_uid != original_effective_uid) {
259 struct rlimit rlim;
260 rlim.rlim_cur = rlim.rlim_max = 0;
261 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
262 fatal("setrlimit failed: %.100s", strerror(errno));
263 }
264 #endif
265 /*
266 * Get user data. It may happen that NIS or LDAP connection breaks down
267 * during the user's session. We should try to do our best and use the
268 * HOME and LOGNAME variables. Remember that the SSH client might be the
269 * only tool available to fix the problem with the naming services.
270 */
271 pw = getpwuid(original_real_uid);
272 if (pw == NULL) {
273 if ((pw_dir = getenv("HOME")) == NULL) {
274 log("User account's password entry not found and HOME "
275 "not set. Set it manually and try again. "
276 "Exiting.");
277 exit(1);
278 }
279 log("User account's password entry not found, using "
280 "the HOME variable.");
281
282 if ((pw_name = getenv("LOGNAME")) == NULL) {
283 log("Need a local user name but LOGNAME is not set. "
284 "Set it manually and try again. Exiting.");
285 exit(1);
286 }
287 log("Local user name '%s' set from the LOGNAME variable.",
288 pw_name);
289
290 pw_dir = xstrdup(pw_dir);
291 pw_name = xstrdup(pw_name);
292 } else {
293 pw_name = xstrdup(pw->pw_name);
294 pw_dir = xstrdup(pw->pw_dir);
295 }
296
297 /*
298 * Set our umask to something reasonable, as some files are created
299 * with the default umask. This will make them world-readable but
300 * writable only by the owner, which is ok for all files for which we
301 * don't set the modes explicitly.
302 */
303 umask(022);
304
305 /* Initialize option structure to indicate that no values have been set. */
306 initialize_options(&options);
307
308 /* Parse command-line arguments. */
309 host = NULL;
310
311 again:
312 while ((opt = getopt(ac, av,
313 "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
314 switch (opt) {
315 case '1':
316 options.protocol = SSH_PROTO_1;
317 break;
318 case '2':
319 options.protocol = SSH_PROTO_2;
320 break;
321 case '4':
322 IPv4or6 = AF_INET;
323 break;
324 case '6':
325 IPv4or6 = AF_INET6;
326 break;
327 case 'n':
328 stdin_null_flag = 1;
329 break;
330 case 'f':
331 fork_after_authentication_flag = 1;
332 stdin_null_flag = 1;
333 break;
334 case 'x':
335 options.forward_x11 = 0;
336 break;
337 case 'X':
338 options.forward_x11 = 1;
339 break;
340 case 'g':
341 options.gateway_ports = 1;
342 break;
343 case 'P': /* deprecated */
344 fprintf(stderr, gettext("Warning: Option -P has "
345 "been deprecated\n"));
346 options.use_privileged_port = 0;
347 break;
348 case 'a':
349 options.forward_agent = 0;
350 break;
351 case 'A':
352 options.forward_agent = 1;
353 break;
354 #ifdef AFS
355 case 'k':
356 options.kerberos_tgt_passing = 0;
357 options.afs_token_passing = 0;
358 break;
359 #endif
360 case 'i':
361 if (stat(optarg, &st) < 0) {
362 fprintf(stderr,
363 gettext("Warning: Identity file %s "
364 "does not exist.\n"), optarg);
365 break;
366 }
367 if (options.num_identity_files >=
368 SSH_MAX_IDENTITY_FILES)
369 fatal("Too many identity files specified "
370 "(max %d)", SSH_MAX_IDENTITY_FILES);
371 options.identity_files[options.num_identity_files++] =
372 xstrdup(optarg);
373 break;
374 case 'I':
375 fprintf(stderr, "no support for smartcards.\n");
376 break;
377 case 't':
378 if (tty_flag)
379 force_tty_flag = 1;
380 tty_flag = 1;
381 break;
382 case 'v':
383 if (0 == debug_flag) {
384 debug_flag = 1;
385 options.log_level = SYSLOG_LEVEL_DEBUG1;
386 } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) {
387 options.log_level++;
388 break;
389 } else
390 fatal("Too high debugging level.");
391 /* FALLTHROUGH */
392 case 'V':
393 fprintf(stderr,
394 gettext("%s, SSH protocols %d.%d/%d.%d, "
395 "OpenSSL 0x%8.8lx\n"),
396 SSH_VERSION,
397 PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
398 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
399 SSLeay());
400 if (opt == 'V')
401 exit(0);
402 break;
403 case 'q':
404 options.log_level = SYSLOG_LEVEL_QUIET;
405 break;
406 case 'e':
407 if (optarg[0] == '^' && optarg[2] == 0 &&
408 (u_char) optarg[1] >= 64 &&
409 (u_char) optarg[1] < 128)
410 options.escape_char = (u_char) optarg[1] & 31;
411 else if (strlen(optarg) == 1)
412 options.escape_char = (u_char) optarg[0];
413 else if (strcmp(optarg, "none") == 0)
414 options.escape_char = SSH_ESCAPECHAR_NONE;
415 else {
416 fprintf(stderr,
417 gettext("Bad escape character '%s'.\n"),
418 optarg);
419 exit(1);
420 }
421 break;
422 case 'c':
423 if (ciphers_valid(optarg)) {
424 /* SSH2 only */
425 options.ciphers = xstrdup(optarg);
426 options.cipher = SSH_CIPHER_ILLEGAL;
427 } else {
428 /* SSH1 only */
429 options.cipher = cipher_number(optarg);
430 if (options.cipher == -1) {
431 fprintf(stderr,
432 gettext("Unknown cipher "
433 "type '%s'\n"),
434 optarg);
435 exit(1);
436 }
437 if (options.cipher == SSH_CIPHER_3DES)
438 options.ciphers = "3des-cbc";
439 else if (options.cipher == SSH_CIPHER_BLOWFISH)
440 options.ciphers = "blowfish-cbc";
441 else
442 options.ciphers = (char *)-1;
443 }
444 break;
445 case 'm':
446 if (mac_valid(optarg))
447 options.macs = xstrdup(optarg);
448 else {
449 fprintf(stderr,
450 gettext("Unknown mac type '%s'\n"),
451 optarg);
452 exit(1);
453 }
454 break;
455 case 'p':
456 options.port = a2port(optarg);
457 if (options.port == 0) {
458 fprintf(stderr, gettext("Bad port '%s'\n"),
459 optarg);
460 exit(1);
461 }
462 break;
463 case 'l':
464 options.user = optarg;
465 break;
466
467 case 'L':
468 if (parse_forward(1, &fwd, optarg))
469 add_local_forward(&options, &fwd);
470 else
471 fatal("Bad local forwarding specification "
472 "'%s'\n", optarg);
473 break;
474
475 case 'R':
476 if (parse_forward(1, &fwd, optarg))
477 add_remote_forward(&options, &fwd);
478 else
479 fatal("Bad remote forwarding specification "
480 "'%s'\n", optarg);
481 break;
482
483 case 'D':
484 if (parse_forward(0, &fwd, optarg) == 0)
485 fatal("Bad dynamic forwarding specification "
486 "'%s'\n", optarg);
487 fwd.connect_host = "socks";
488 add_local_forward(&options, &fwd);
489 break;
490
491 case 'C':
492 options.compression = 1;
493 break;
494 case 'N':
495 no_shell_flag = 1;
496 no_tty_flag = 1;
497 break;
498 case 'T':
499 no_tty_flag = 1;
500 break;
501 case 'o':
502 dummy = 1;
503 if (process_config_line(&options, host ? host : "",
504 optarg, "command-line", 0, &dummy) != 0)
505 exit(1);
506 break;
507 case 's':
508 subsystem_flag = 1;
509 break;
510 case 'b':
511 options.bind_address = optarg;
512 break;
513 case 'F':
514 config = optarg;
515 break;
516 default:
517 usage();
518 }
519 }
520
521 ac -= optind;
522 av += optind;
523
524 if (ac > 0 && !host && **av != '-') {
525 if (strchr(*av, '@')) {
526 p = xstrdup(*av);
527 cp = strchr(p, '@');
528 if (cp == NULL || cp == p)
529 usage();
530 options.user = p;
531 *cp = '\0';
532 host = ++cp;
533 } else
534 host = *av;
535 ac--, av++;
536 if (ac > 0) {
537 optind = 0;
538 optreset = 1;
539 goto again;
540 }
541 }
542
543 /* Check that we got a host name. */
544 if (!host)
545 usage();
546
547 SSLeay_add_all_algorithms();
548 ERR_load_crypto_strings();
549 channel_set_af(IPv4or6);
550
551 /* Initialize the command to execute on remote host. */
552 buffer_init(&command);
553
554 /*
555 * Save the command to execute on the remote host in a buffer. There
556 * is no limit on the length of the command, except by the maximum
557 * packet size. Also sets the tty flag if there is no command.
558 */
559 if (!ac) {
560 /* No command specified - execute shell on a tty. */
561 tty_flag = 1;
562 if (subsystem_flag) {
563 fprintf(stderr,
564 gettext("You must specify a subsystem "
565 "to invoke.\n"));
566 usage();
567 }
568 } else {
569 /* A command has been specified. Store it into the buffer. */
570 for (i = 0; i < ac; i++) {
571 if (i)
572 buffer_append(&command, " ", 1);
573 buffer_append(&command, av[i], strlen(av[i]));
574 }
575 }
576
577 /* Cannot fork to background if no command. */
578 if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag)
579 fatal("Cannot fork into background without a command to execute.");
580
581 /* Allocate a tty by default if no command specified. */
582 if (buffer_len(&command) == 0)
583 tty_flag = 1;
584
585 /* Force no tty */
586 if (no_tty_flag)
587 tty_flag = 0;
588 /* Do not allocate a tty if stdin is not a tty. */
589 if (!isatty(fileno(stdin)) && !force_tty_flag) {
590 if (tty_flag)
591 log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
592 tty_flag = 0;
593 }
594
595 /*
596 * Initialize "log" output. Since we are the client all output
597 * actually goes to stderr.
598 */
599 log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
600 SYSLOG_FACILITY_USER, 1);
601
602 /*
603 * Read per-user configuration file. Ignore the system wide config
604 * file if the user specifies a config file on the command line.
605 */
606 if (config != NULL) {
607 if (!read_config_file(config, host, &options))
608 fatal("Can't open user config file %.100s: "
609 "%.100s", config, strerror(errno));
610 } else {
611 snprintf(buf, sizeof buf, "%.100s/%.100s", pw_dir,
612 _PATH_SSH_USER_CONFFILE);
613 (void)read_config_file(buf, host, &options);
614
615 /* Read systemwide configuration file after use config. */
616 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host, &options);
617 }
618
619 process_unknown_options(&options);
620
621 /* Fill configuration defaults. */
622 fill_default_options(&options);
623
624 /* reinit */
625 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
626
627 seed_rng();
628
629 if (options.user == NULL)
630 options.user = xstrdup(pw_name);
631
632 if (options.hostname != NULL)
633 host = options.hostname;
634
635 /* Disable rhosts authentication if not running as root. */
636 #ifdef HAVE_CYGWIN
637 /* Ignore uid if running under Windows */
638 if (!options.use_privileged_port) {
639 #else
640 if (original_effective_uid != 0 || !options.use_privileged_port) {
641 #endif
642 debug("Rhosts Authentication disabled, "
643 "originating port will not be trusted.");
644 options.rhosts_authentication = 0;
645 }
646 /* Open a connection to the remote host. */
647
648 /* XXX OpenSSH has deprecated UseRsh */
649 if (options.use_rsh) {
650 seteuid(original_real_uid);
651 setuid(original_real_uid);
652 rsh_connect(host, options.user, &command);
653 fatal("rsh_connect returned");
654 }
655
656 if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
657 options.connection_attempts,
658 #ifdef HAVE_CYGWIN
659 options.use_privileged_port,
660 #else
661 original_effective_uid == 0 && options.use_privileged_port,
662 #endif
663 options.proxy_command) != 0) {
664 /* XXX OpenSSH has deprecated FallbackToRsh */
665 if (options.fallback_to_rsh) {
666 seteuid(original_real_uid);
667 setuid(original_real_uid);
668 rsh_connect(host, options.user, &command);
669 fatal("rsh_connect returned");
670 }
671 exit(1);
672 }
673
674 /*
675 * If we successfully made the connection, load the host private key
676 * in case we will need it later for combined rsa-rhosts
677 * authentication. This must be done before releasing extra
678 * privileges, because the file is only readable by root.
679 * If we cannot access the private keys, load the public keys
680 * instead and try to execute the ssh-keysign helper instead.
681 */
682 sensitive_data.nkeys = 0;
683 sensitive_data.keys = NULL;
684 sensitive_data.external_keysign = 0;
685 if (options.rhosts_rsa_authentication ||
686 options.hostbased_authentication) {
687 sensitive_data.nkeys = 3;
688 sensitive_data.keys = xmalloc(sensitive_data.nkeys *
689 sizeof(Key));
690
691 PRIV_START;
692 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
693 _PATH_HOST_KEY_FILE, "", NULL);
694 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
695 _PATH_HOST_DSA_KEY_FILE, "", NULL);
696 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
697 _PATH_HOST_RSA_KEY_FILE, "", NULL);
698 PRIV_END;
699
700 if (options.hostbased_authentication == 1 &&
701 sensitive_data.keys[0] == NULL &&
702 sensitive_data.keys[1] == NULL &&
703 sensitive_data.keys[2] == NULL) {
704 sensitive_data.keys[1] = key_load_public(
705 _PATH_HOST_DSA_KEY_FILE, NULL);
706 sensitive_data.keys[2] = key_load_public(
707 _PATH_HOST_RSA_KEY_FILE, NULL);
708 sensitive_data.external_keysign = 1;
709 }
710 }
711 /*
712 * Get rid of any extra privileges that we may have. We will no
713 * longer need them. Also, extra privileges could make it very hard
714 * to read identity files and other non-world-readable files from the
715 * user's home directory if it happens to be on a NFS volume where
716 * root is mapped to nobody.
717 */
718 seteuid(original_real_uid);
719 setuid(original_real_uid);
720
721 /*
722 * Now that we are back to our own permissions, create ~/.ssh
723 * directory if it doesn\'t already exist.
724 */
725 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw_dir,
726 strcmp(pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
727 xfree(pw_dir);
728 if (stat(buf, &st) < 0)
729 if (mkdir(buf, 0700) < 0)
730 error("Could not create directory '%.200s'.", buf);
731
732 /* load options.identity_files */
733 load_public_identity_files();
734
735 /* Expand ~ in known host file names. */
736 /* XXX mem-leaks: */
737 options.system_hostfile =
738 tilde_expand_filename(options.system_hostfile, original_real_uid);
739 options.user_hostfile =
740 tilde_expand_filename(options.user_hostfile, original_real_uid);
741 options.system_hostfile2 =
742 tilde_expand_filename(options.system_hostfile2, original_real_uid);
743 options.user_hostfile2 =
744 tilde_expand_filename(options.user_hostfile2, original_real_uid);
745
746 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
747
748 /* Log into the remote system. This never returns if the login fails. */
749 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw_name);
750 xfree(pw_name);
751
752 /* We no longer need the private host keys. Clear them now. */
753 if (sensitive_data.nkeys != 0) {
754 for (i = 0; i < sensitive_data.nkeys; i++) {
755 if (sensitive_data.keys[i] != NULL) {
756 /* Destroys contents safely */
757 debug3("clear hostkey %d", i);
758 key_free(sensitive_data.keys[i]);
759 sensitive_data.keys[i] = NULL;
760 }
761 }
762 xfree(sensitive_data.keys);
763 }
764 for (i = 0; i < options.num_identity_files; i++) {
765 if (options.identity_files[i]) {
766 xfree(options.identity_files[i]);
767 options.identity_files[i] = NULL;
768 }
769 if (options.identity_keys[i]) {
770 key_free(options.identity_keys[i]);
771 options.identity_keys[i] = NULL;
772 }
773 }
774
775 exit_status = compat20 ? ssh_session2() : ssh_session();
776 packet_close();
777
778 /*
779 * Send SIGHUP to proxy command if used. We don't wait() in
780 * case it hangs and instead rely on init to reap the child
781 */
782 if (proxy_command_pid > 1)
783 kill(proxy_command_pid, SIGHUP);
784
785 return exit_status;
786 }
787
788 static void
789 ssh_init_forwarding(void)
790 {
791 int success = 0;
792 int i;
793
794 /* Initiate local TCP/IP port forwardings. */
795 for (i = 0; i < options.num_local_forwards; i++) {
796 debug("Local connections to %.200s:%d forwarded to remote "
797 "address %.200s:%d",
798 (options.local_forwards[i].listen_host == NULL) ?
799 (options.gateway_ports ? "*" : "LOCALHOST") :
800 options.local_forwards[i].listen_host,
801 options.local_forwards[i].listen_port,
802 options.local_forwards[i].connect_host,
803 options.local_forwards[i].connect_port);
804 success += channel_setup_local_fwd_listener(
805 options.local_forwards[i].listen_host,
806 options.local_forwards[i].listen_port,
807 options.local_forwards[i].connect_host,
808 options.local_forwards[i].connect_port,
809 options.gateway_ports);
810 }
811 if (i > 0 && success == 0)
812 error("Could not request local forwarding.");
813
814 /* Initiate remote TCP/IP port forwardings. */
815 for (i = 0; i < options.num_remote_forwards; i++) {
816 debug("Remote connections from %.200s:%d forwarded to "
817 "local address %.200s:%d",
818 (options.remote_forwards[i].listen_host == NULL) ?
819 "LOCALHOST" : options.remote_forwards[i].listen_host,
820 options.remote_forwards[i].listen_port,
821 options.remote_forwards[i].connect_host,
822 options.remote_forwards[i].connect_port);
823 if (channel_request_remote_forwarding(
824 options.remote_forwards[i].listen_host,
825 options.remote_forwards[i].listen_port,
826 options.remote_forwards[i].connect_host,
827 options.remote_forwards[i].connect_port) < 0) {
828 log("Warning: Could not request remote forwarding.");
829 }
830 }
831 }
832
833 static void
834 check_agent_present(void)
835 {
836 if (options.forward_agent) {
837 /* Clear agent forwarding if we don't have an agent. */
838 if (!ssh_agent_present())
839 options.forward_agent = 0;
840 }
841 }
842
843 static int
844 ssh_session(void)
845 {
846 int type;
847 int interactive = 0;
848 int have_tty = 0;
849 struct winsize ws;
850 char *cp;
851 const char *display;
852
853 /* Enable compression if requested. */
854 if (options.compression) {
855 debug("Requesting compression at level %d.", options.compression_level);
856
857 if (options.compression_level < 1 || options.compression_level > 9)
858 fatal("Compression level must be from 1 (fast) to 9 (slow, best).");
859
860 /* Send the request. */
861 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
862 packet_put_int(options.compression_level);
863 packet_send();
864 packet_write_wait();
865 type = packet_read();
866 if (type == SSH_SMSG_SUCCESS)
867 packet_start_compression(options.compression_level);
868 else if (type == SSH_SMSG_FAILURE)
869 log("Warning: Remote host refused compression.");
870 else
871 packet_disconnect("Protocol error waiting for compression response.");
872 }
873 /* Allocate a pseudo tty if appropriate. */
874 if (tty_flag) {
875 debug("Requesting pty.");
876
877 /* Start the packet. */
878 packet_start(SSH_CMSG_REQUEST_PTY);
879
880 /* Store TERM in the packet. There is no limit on the
881 length of the string. */
882 cp = getenv("TERM");
883 if (!cp)
884 cp = "";
885 packet_put_cstring(cp);
886
887 /* Store window size in the packet. */
888 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
889 memset(&ws, 0, sizeof(ws));
890 packet_put_int(ws.ws_row);
891 packet_put_int(ws.ws_col);
892 packet_put_int(ws.ws_xpixel);
893 packet_put_int(ws.ws_ypixel);
894
895 /* Store tty modes in the packet. */
896 tty_make_modes(fileno(stdin), NULL);
897
898 /* Send the packet, and wait for it to leave. */
899 packet_send();
900 packet_write_wait();
901
902 /* Read response from the server. */
903 type = packet_read();
904 if (type == SSH_SMSG_SUCCESS) {
905 interactive = 1;
906 have_tty = 1;
907 } else if (type == SSH_SMSG_FAILURE)
908 log("Warning: Remote host failed or refused to allocate a pseudo tty.");
909 else
910 packet_disconnect("Protocol error waiting for pty request response.");
911 }
912 /* Request X11 forwarding if enabled and DISPLAY is set. */
913 display = getenv("DISPLAY");
914 if (options.forward_x11 && display != NULL) {
915 char *proto, *data;
916 /* Get reasonable local authentication information. */
917 client_x11_get_proto(display, options.xauth_location,
918 options.forward_x11_trusted, &proto, &data);
919 /* Request forwarding with authentication spoofing. */
920 debug("Requesting X11 forwarding with authentication spoofing.");
921 x11_request_forwarding_with_spoofing(0, display, proto, data);
922
923 /* Read response from the server. */
924 type = packet_read();
925 if (type == SSH_SMSG_SUCCESS) {
926 interactive = 1;
927 } else if (type == SSH_SMSG_FAILURE) {
928 log("Warning: Remote host denied X11 forwarding.");
929 } else {
930 packet_disconnect("Protocol error waiting for X11 forwarding");
931 }
932 }
933 /* Tell the packet module whether this is an interactive session. */
934 packet_set_interactive(interactive);
935
936 /* Request authentication agent forwarding if appropriate. */
937 check_agent_present();
938
939 if (options.forward_agent) {
940 debug("Requesting authentication agent forwarding.");
941 auth_request_forwarding();
942
943 /* Read response from the server. */
944 type = packet_read();
945 packet_check_eom();
946 if (type != SSH_SMSG_SUCCESS)
947 log("Warning: Remote host denied authentication agent forwarding.");
948 }
949
950 /* Initiate port forwardings. */
951 ssh_init_forwarding();
952
953 /* If requested, let ssh continue in the background. */
954 if (fork_after_authentication_flag)
955 if (daemon(1, 1) < 0)
956 fatal("daemon() failed: %.200s", strerror(errno));
957
958 /*
959 * If a command was specified on the command line, execute the
960 * command now. Otherwise request the server to start a shell.
961 */
962 if (buffer_len(&command) > 0) {
963 int len = buffer_len(&command);
964 if (len > 900)
965 len = 900;
966 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
967 packet_start(SSH_CMSG_EXEC_CMD);
968 packet_put_string(buffer_ptr(&command), buffer_len(&command));
969 packet_send();
970 packet_write_wait();
971 } else {
972 debug("Requesting shell.");
973 packet_start(SSH_CMSG_EXEC_SHELL);
974 packet_send();
975 packet_write_wait();
976 }
977
978 /* Enter the interactive session. */
979 return client_loop(have_tty, tty_flag ?
980 options.escape_char : SSH_ESCAPECHAR_NONE, 0);
981 }
982
983 static void
984 client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
985 {
986 int id, len;
987
988 id = packet_get_int();
989 len = buffer_len(&command);
990 if (len > 900)
991 len = 900;
992 packet_check_eom();
993 if (type == SSH2_MSG_CHANNEL_FAILURE)
994 fatal("Request for subsystem '%.*s' failed on channel %d",
995 len, (u_char *)buffer_ptr(&command), id);
996 }
997
998 void
999 client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
1000 {
1001 int i;
1002
1003 i = client_global_request_id++;
1004 if (i >= options.num_remote_forwards)
1005 return;
1006 debug("remote forward %s for: listen %d, connect %s:%d",
1007 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
1008 options.remote_forwards[i].listen_port,
1009 options.remote_forwards[i].connect_host,
1010 options.remote_forwards[i].connect_port);
1011 if (type == SSH2_MSG_REQUEST_FAILURE)
1012 log("Warning: remote port forwarding failed for listen port %d",
1013 options.remote_forwards[i].listen_port);
1014 }
1015
1016 static
1017 void
1018 ssh_session2_setlocale(int id)
1019 {
1020 char *loc;
1021
1022 #define remote_setlocale(envvar) \
1023 if ((loc = getenv(envvar)) != NULL) {\
1024 channel_request_start(id, "env", 0);\
1025 debug2("Sent request for environment variable %s=%s", envvar, \
1026 loc); \
1027 packet_put_cstring(envvar);\
1028 packet_put_cstring(loc);\
1029 packet_send();\
1030 }
1031
1032 remote_setlocale("LANG")
1033
1034 remote_setlocale("LC_CTYPE")
1035 remote_setlocale("LC_COLLATE")
1036 remote_setlocale("LC_TIME")
1037 remote_setlocale("LC_NUMERIC")
1038 remote_setlocale("LC_MONETARY")
1039 remote_setlocale("LC_MESSAGES")
1040
1041 remote_setlocale("LC_ALL")
1042 }
1043
1044 /* request pty/x11/agent/tcpfwd/shell for channel */
1045 static void
1046 ssh_session2_setup(int id, void *arg)
1047 {
1048 int len;
1049 const char *display;
1050 int interactive = 0;
1051 struct termios tio;
1052
1053 debug("ssh_session2_setup: id %d", id);
1054
1055 ssh_session2_setlocale(id);
1056
1057 if (tty_flag) {
1058 struct winsize ws;
1059 char *cp;
1060 cp = getenv("TERM");
1061 if (!cp)
1062 cp = "";
1063 /* Store window size in the packet. */
1064 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1065 memset(&ws, 0, sizeof(ws));
1066
1067 channel_request_start(id, "pty-req", 0);
1068 packet_put_cstring(cp);
1069 packet_put_int(ws.ws_col);
1070 packet_put_int(ws.ws_row);
1071 packet_put_int(ws.ws_xpixel);
1072 packet_put_int(ws.ws_ypixel);
1073 tio = get_saved_tio();
1074 tty_make_modes(/*ignored*/ 0, &tio);
1075 packet_send();
1076 interactive = 1;
1077 /* XXX wait for reply */
1078 }
1079
1080 display = getenv("DISPLAY");
1081 if (options.forward_x11 && display != NULL) {
1082 char *proto, *data;
1083 /* Get reasonable local authentication information. */
1084 client_x11_get_proto(display, options.xauth_location,
1085 options.forward_x11_trusted, &proto, &data);
1086 /* Request forwarding with authentication spoofing. */
1087 debug("Requesting X11 forwarding with authentication spoofing.");
1088 x11_request_forwarding_with_spoofing(id, display, proto, data);
1089 interactive = 1;
1090 /* XXX wait for reply */
1091 }
1092
1093 check_agent_present();
1094 if (options.forward_agent) {
1095 debug("Requesting authentication agent forwarding.");
1096 channel_request_start(id, "auth-agent-req@openssh.com", 0);
1097 packet_send();
1098 }
1099
1100 len = buffer_len(&command);
1101 if (len > 0) {
1102 if (len > 900)
1103 len = 900;
1104 if (subsystem_flag) {
1105 debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));
1106 channel_request_start(id, "subsystem", /*want reply*/ 1);
1107 /* register callback for reply */
1108 /* XXX we assume that client_loop has already been called */
1109 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
1110 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
1111 } else {
1112 debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
1113 channel_request_start(id, "exec", 0);
1114 }
1115 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1116 packet_send();
1117 } else {
1118 channel_request_start(id, "shell", 0);
1119 packet_send();
1120 }
1121
1122 packet_set_interactive(interactive);
1123 }
1124
1125 /* open new channel for a session */
1126 static int
1127 ssh_session2_open(void)
1128 {
1129 Channel *c;
1130 int window, packetmax, in, out, err;
1131
1132 if (stdin_null_flag) {
1133 in = open(_PATH_DEVNULL, O_RDONLY);
1134 } else {
1135 in = dup(STDIN_FILENO);
1136 }
1137 out = dup(STDOUT_FILENO);
1138 err = dup(STDERR_FILENO);
1139
1140 if (in < 0 || out < 0 || err < 0)
1141 fatal("dup() in/out/err failed");
1142
1143 /* enable nonblocking unless tty */
1144 if (!isatty(in))
1145 set_nonblock(in);
1146 if (!isatty(out))
1147 set_nonblock(out);
1148 if (!isatty(err))
1149 set_nonblock(err);
1150
1151 window = CHAN_SES_WINDOW_DEFAULT;
1152 packetmax = CHAN_SES_PACKET_DEFAULT;
1153 if (tty_flag) {
1154 window >>= 1;
1155 packetmax >>= 1;
1156 }
1157 c = channel_new(
1158 "session", SSH_CHANNEL_OPENING, in, out, err,
1159 window, packetmax, CHAN_EXTENDED_WRITE,
1160 xstrdup("client-session"), /*nonblock*/0);
1161
1162 debug3("ssh_session2_open: channel_new: %d", c->self);
1163
1164 channel_send_open(c->self);
1165 if (!no_shell_flag)
1166 channel_register_confirm(c->self, ssh_session2_setup);
1167
1168 return c->self;
1169 }
1170
1171 static int
1172 ssh_session2(void)
1173 {
1174 int id = -1;
1175
1176 /* XXX should be pre-session */
1177 ssh_init_forwarding();
1178
1179 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1180 id = ssh_session2_open();
1181
1182 /* If requested, let ssh continue in the background. */
1183 if (fork_after_authentication_flag)
1184 client_daemonize();
1185
1186 return (client_loop(tty_flag, tty_flag ?
1187 options.escape_char : SSH_ESCAPECHAR_NONE, id));
1188 }
1189
1190 static void
1191 load_public_identity_files(void)
1192 {
1193 char *filename;
1194 int i = 0;
1195 Key *public;
1196
1197 for (; i < options.num_identity_files; i++) {
1198 filename = tilde_expand_filename(options.identity_files[i],
1199 original_real_uid);
1200 public = key_load_public(filename, NULL);
1201 debug("identity file %s type %d", filename,
1202 public ? public->type : -1);
1203 xfree(options.identity_files[i]);
1204 options.identity_files[i] = filename;
1205 options.identity_keys[i] = public;
1206 }
1207 }
1208
1209 /*
1210 * Connects to the given host using rsh(or prints an error message and exits
1211 * if rsh is not available). This function never returns.
1212 */
1213 static void
1214 rsh_connect(char *host, char *user, Buffer * command)
1215 {
1216 char *args[10];
1217 int i;
1218
1219 log("Using rsh. WARNING: Connection will not be encrypted.");
1220 /* Build argument list for rsh. */
1221 i = 0;
1222 args[i++] = _PATH_RSH;
1223 /* host may have to come after user on some systems */
1224 args[i++] = host;
1225 if (user) {
1226 args[i++] = "-l";
1227 args[i++] = user;
1228 }
1229 if (buffer_len(command) > 0) {
1230 buffer_append(command, "\0", 1);
1231 args[i++] = buffer_ptr(command);
1232 }
1233 args[i++] = NULL;
1234 if (debug_flag) {
1235 for (i = 0; args[i]; i++) {
1236 if (i != 0)
1237 (void) fprintf(stderr, " ");
1238 (void) fprintf(stderr, "%s", args[i]);
1239 }
1240 (void) fprintf(stderr, "\n");
1241 }
1242 (void) execv(_PATH_RSH, args);
1243 perror(_PATH_RSH);
1244 exit(1);
1245 }
1246