]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - crypto/openssh/ssh.c
MFC r224638,224640,224642 (by brooks):
[FreeBSD/stable/8.git] / crypto / openssh / ssh.c
1 /* $OpenBSD: ssh.c,v 1.335 2010/02/26 20:29:54 djm Exp $ */
2 /* $FreeBSD$ */
3 /*
4  * Author: Tatu Ylonen <ylo@cs.hut.fi>
5  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6  *                    All rights reserved
7  * Ssh client program.  This program can be used to log into a remote machine.
8  * The software supports strong authentication, encryption, and forwarding
9  * of X11, TCP/IP, and authentication connections.
10  *
11  * As far as I am concerned, the code I have written for this software
12  * can be used freely for any purpose.  Any derived versions of this
13  * software must be clearly marked as such, and if the derived work is
14  * incompatible with the protocol description in the RFC file, it must be
15  * called by a name other than "ssh" or "Secure Shell".
16  *
17  * Copyright (c) 1999 Niels Provos.  All rights reserved.
18  * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl.  All rights reserved.
19  *
20  * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
21  * in Canada (German citizen).
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
33  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
35  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
36  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
41  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  */
43
44 #include "includes.h"
45 __RCSID("$FreeBSD$");
46
47 #include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
49 # include <sys/stat.h>
50 #endif
51 #include <sys/resource.h>
52 #include <sys/ioctl.h>
53 #include <sys/param.h>
54 #include <sys/socket.h>
55
56 #include <ctype.h>
57 #include <errno.h>
58 #include <fcntl.h>
59 #include <netdb.h>
60 #ifdef HAVE_PATHS_H
61 #include <paths.h>
62 #endif
63 #include <pwd.h>
64 #include <signal.h>
65 #include <stdarg.h>
66 #include <stddef.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <unistd.h>
71
72 #include <netinet/in.h>
73 #include <arpa/inet.h>
74
75 #include <openssl/evp.h>
76 #include <openssl/err.h>
77 #include "openbsd-compat/openssl-compat.h"
78 #include "openbsd-compat/sys-queue.h"
79
80 #include "xmalloc.h"
81 #include "ssh.h"
82 #include "ssh1.h"
83 #include "ssh2.h"
84 #include "compat.h"
85 #include "cipher.h"
86 #include "packet.h"
87 #include "buffer.h"
88 #include "channels.h"
89 #include "key.h"
90 #include "authfd.h"
91 #include "authfile.h"
92 #include "pathnames.h"
93 #include "dispatch.h"
94 #include "clientloop.h"
95 #include "log.h"
96 #include "readconf.h"
97 #include "sshconnect.h"
98 #include "misc.h"
99 #include "kex.h"
100 #include "mac.h"
101 #include "sshpty.h"
102 #include "match.h"
103 #include "msg.h"
104 #include "uidswap.h"
105 #include "roaming.h"
106 #include "version.h"
107
108 #ifdef ENABLE_PKCS11
109 #include "ssh-pkcs11.h"
110 #endif
111
112 extern char *__progname;
113
114 /* Flag indicating whether debug mode is on.  May be set on the command line. */
115 int debug_flag = 0;
116
117 /* Flag indicating whether a tty should be allocated */
118 int tty_flag = 0;
119 int no_tty_flag = 0;
120 int force_tty_flag = 0;
121
122 /* don't exec a shell */
123 int no_shell_flag = 0;
124
125 /*
126  * Flag indicating that nothing should be read from stdin.  This can be set
127  * on the command line.
128  */
129 int stdin_null_flag = 0;
130
131 /*
132  * Flag indicating that ssh should fork after authentication.  This is useful
133  * so that the passphrase can be entered manually, and then ssh goes to the
134  * background.
135  */
136 int fork_after_authentication_flag = 0;
137
138 /* forward stdio to remote host and port */
139 char *stdio_forward_host = NULL;
140 int stdio_forward_port = 0;
141
142 /*
143  * General data structure for command line options and options configurable
144  * in configuration files.  See readconf.h.
145  */
146 Options options;
147
148 /* optional user configfile */
149 char *config = NULL;
150
151 /*
152  * Name of the host we are connecting to.  This is the name given on the
153  * command line, or the HostName specified for the user-supplied name in a
154  * configuration file.
155  */
156 char *host;
157
158 /* socket address the host resolves to */
159 struct sockaddr_storage hostaddr;
160
161 /* Private host keys. */
162 Sensitive sensitive_data;
163
164 /* Original real UID. */
165 uid_t original_real_uid;
166 uid_t original_effective_uid;
167
168 /* command to be executed */
169 Buffer command;
170
171 /* Should we execute a command or invoke a subsystem? */
172 int subsystem_flag = 0;
173
174 /* # of replies received for global requests */
175 static int remote_forward_confirms_received = 0;
176
177 /* pid of proxycommand child process */
178 pid_t proxy_command_pid = 0;
179
180 /* mux.c */
181 extern int muxserver_sock;
182 extern u_int muxclient_command;
183
184 /* Prints a help message to the user.  This function never returns. */
185
186 static void
187 usage(void)
188 {
189         fprintf(stderr,
190 "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
191 "           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
192 "           [-I pkcs11] [-i identity_file]\n"
193 "           [-L [bind_address:]port:host:hostport]\n"
194 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
195 "           [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
196 "           [-W host:port] [-w local_tun[:remote_tun]]\n"
197 "           [user@]hostname [command]\n"
198         );
199         exit(255);
200 }
201
202 static int ssh_session(void);
203 static int ssh_session2(void);
204 static void load_public_identity_files(void);
205
206 /* from muxclient.c */
207 void muxclient(const char *);
208 void muxserver_listen(void);
209
210 /*
211  * Main program for the ssh client.
212  */
213 int
214 main(int ac, char **av)
215 {
216         int i, r, opt, exit_status, use_syslog;
217         char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
218         struct stat st;
219         struct passwd *pw;
220         int dummy, timeout_ms;
221         extern int optind, optreset;
222         extern char *optarg;
223         struct servent *sp;
224         Forward fwd;
225
226         /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
227         sanitise_stdfd();
228
229         __progname = ssh_get_progname(av[0]);
230         init_rng();
231
232         /*
233          * Save the original real uid.  It will be needed later (uid-swapping
234          * may clobber the real uid).
235          */
236         original_real_uid = getuid();
237         original_effective_uid = geteuid();
238
239         /*
240          * Use uid-swapping to give up root privileges for the duration of
241          * option processing.  We will re-instantiate the rights when we are
242          * ready to create the privileged port, and will permanently drop
243          * them when the port has been created (actually, when the connection
244          * has been made, as we may need to create the port several times).
245          */
246         PRIV_END;
247
248 #ifdef HAVE_SETRLIMIT
249         /* If we are installed setuid root be careful to not drop core. */
250         if (original_real_uid != original_effective_uid) {
251                 struct rlimit rlim;
252                 rlim.rlim_cur = rlim.rlim_max = 0;
253                 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
254                         fatal("setrlimit failed: %.100s", strerror(errno));
255         }
256 #endif
257         /* Get user data. */
258         pw = getpwuid(original_real_uid);
259         if (!pw) {
260                 logit("You don't exist, go away!");
261                 exit(255);
262         }
263         /* Take a copy of the returned structure. */
264         pw = pwcopy(pw);
265
266         /*
267          * Set our umask to something reasonable, as some files are created
268          * with the default umask.  This will make them world-readable but
269          * writable only by the owner, which is ok for all files for which we
270          * don't set the modes explicitly.
271          */
272         umask(022);
273
274         /*
275          * Initialize option structure to indicate that no values have been
276          * set.
277          */
278         initialize_options(&options);
279
280         /* Parse command-line arguments. */
281         host = NULL;
282         use_syslog = 0;
283         argv0 = av[0];
284
285  again:
286         while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
287             "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
288                 switch (opt) {
289                 case '1':
290                         options.protocol = SSH_PROTO_1;
291                         break;
292                 case '2':
293                         options.protocol = SSH_PROTO_2;
294                         break;
295                 case '4':
296                         options.address_family = AF_INET;
297                         break;
298                 case '6':
299                         options.address_family = AF_INET6;
300                         break;
301                 case 'n':
302                         stdin_null_flag = 1;
303                         break;
304                 case 'f':
305                         fork_after_authentication_flag = 1;
306                         stdin_null_flag = 1;
307                         break;
308                 case 'x':
309                         options.forward_x11 = 0;
310                         break;
311                 case 'X':
312                         options.forward_x11 = 1;
313                         break;
314                 case 'y':
315                         use_syslog = 1;
316                         break;
317                 case 'Y':
318                         options.forward_x11 = 1;
319                         options.forward_x11_trusted = 1;
320                         break;
321                 case 'g':
322                         options.gateway_ports = 1;
323                         break;
324                 case 'O':
325                         if (stdio_forward_host != NULL)
326                                 fatal("Cannot specify multiplexing "
327                                     "command with -W");
328                         else if (muxclient_command != 0)
329                                 fatal("Multiplexing command already specified");
330                         if (strcmp(optarg, "check") == 0)
331                                 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
332                         else if (strcmp(optarg, "exit") == 0)
333                                 muxclient_command = SSHMUX_COMMAND_TERMINATE;
334                         else
335                                 fatal("Invalid multiplex command.");
336                         break;
337                 case 'P':       /* deprecated */
338                         options.use_privileged_port = 0;
339                         break;
340                 case 'a':
341                         options.forward_agent = 0;
342                         break;
343                 case 'A':
344                         options.forward_agent = 1;
345                         break;
346                 case 'k':
347                         options.gss_deleg_creds = 0;
348                         break;
349                 case 'K':
350                         options.gss_authentication = 1;
351                         options.gss_deleg_creds = 1;
352                         break;
353                 case 'i':
354                         if (stat(optarg, &st) < 0) {
355                                 fprintf(stderr, "Warning: Identity file %s "
356                                     "not accessible: %s.\n", optarg,
357                                     strerror(errno));
358                                 break;
359                         }
360                         if (options.num_identity_files >=
361                             SSH_MAX_IDENTITY_FILES)
362                                 fatal("Too many identity files specified "
363                                     "(max %d)", SSH_MAX_IDENTITY_FILES);
364                         options.identity_files[options.num_identity_files++] =
365                             xstrdup(optarg);
366                         break;
367                 case 'I':
368 #ifdef ENABLE_PKCS11
369                         options.pkcs11_provider = xstrdup(optarg);
370 #else
371                         fprintf(stderr, "no support for PKCS#11.\n");
372 #endif
373                         break;
374                 case 't':
375                         if (tty_flag)
376                                 force_tty_flag = 1;
377                         tty_flag = 1;
378                         break;
379                 case 'v':
380                         if (debug_flag == 0) {
381                                 debug_flag = 1;
382                                 options.log_level = SYSLOG_LEVEL_DEBUG1;
383                         } else {
384                                 if (options.log_level < SYSLOG_LEVEL_DEBUG3)
385                                         options.log_level++;
386                                 break;
387                         }
388                         /* FALLTHROUGH */
389                 case 'V':
390                         fprintf(stderr, "%s, %s\n",
391                             SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
392                         if (opt == 'V')
393                                 exit(0);
394                         break;
395                 case 'w':
396                         if (options.tun_open == -1)
397                                 options.tun_open = SSH_TUNMODE_DEFAULT;
398                         options.tun_local = a2tun(optarg, &options.tun_remote);
399                         if (options.tun_local == SSH_TUNID_ERR) {
400                                 fprintf(stderr,
401                                     "Bad tun device '%s'\n", optarg);
402                                 exit(255);
403                         }
404                         break;
405                 case 'W':
406                         if (stdio_forward_host != NULL)
407                                 fatal("stdio forward already specified");
408                         if (muxclient_command != 0)
409                                 fatal("Cannot specify stdio forward with -O");
410                         if (parse_forward(&fwd, optarg, 1, 0)) {
411                                 stdio_forward_host = fwd.listen_host;
412                                 stdio_forward_port = fwd.listen_port;
413                                 xfree(fwd.connect_host);
414                         } else {
415                                 fprintf(stderr,
416                                     "Bad stdio forwarding specification '%s'\n",
417                                     optarg);
418                                 exit(255);
419                         }
420                         no_tty_flag = 1;
421                         no_shell_flag = 1;
422                         options.clear_forwardings = 1;
423                         options.exit_on_forward_failure = 1;
424                         break;
425                 case 'q':
426                         options.log_level = SYSLOG_LEVEL_QUIET;
427                         break;
428                 case 'e':
429                         if (optarg[0] == '^' && optarg[2] == 0 &&
430                             (u_char) optarg[1] >= 64 &&
431                             (u_char) optarg[1] < 128)
432                                 options.escape_char = (u_char) optarg[1] & 31;
433                         else if (strlen(optarg) == 1)
434                                 options.escape_char = (u_char) optarg[0];
435                         else if (strcmp(optarg, "none") == 0)
436                                 options.escape_char = SSH_ESCAPECHAR_NONE;
437                         else {
438                                 fprintf(stderr, "Bad escape character '%s'.\n",
439                                     optarg);
440                                 exit(255);
441                         }
442                         break;
443                 case 'c':
444                         if (ciphers_valid(optarg)) {
445                                 /* SSH2 only */
446                                 options.ciphers = xstrdup(optarg);
447                                 options.cipher = SSH_CIPHER_INVALID;
448                         } else {
449                                 /* SSH1 only */
450                                 options.cipher = cipher_number(optarg);
451                                 if (options.cipher == -1) {
452                                         fprintf(stderr,
453                                             "Unknown cipher type '%s'\n",
454                                             optarg);
455                                         exit(255);
456                                 }
457                                 if (options.cipher == SSH_CIPHER_3DES)
458                                         options.ciphers = "3des-cbc";
459                                 else if (options.cipher == SSH_CIPHER_BLOWFISH)
460                                         options.ciphers = "blowfish-cbc";
461                                 else
462                                         options.ciphers = (char *)-1;
463                         }
464                         break;
465                 case 'm':
466                         if (mac_valid(optarg))
467                                 options.macs = xstrdup(optarg);
468                         else {
469                                 fprintf(stderr, "Unknown mac type '%s'\n",
470                                     optarg);
471                                 exit(255);
472                         }
473                         break;
474                 case 'M':
475                         if (options.control_master == SSHCTL_MASTER_YES)
476                                 options.control_master = SSHCTL_MASTER_ASK;
477                         else
478                                 options.control_master = SSHCTL_MASTER_YES;
479                         break;
480                 case 'p':
481                         options.port = a2port(optarg);
482                         if (options.port <= 0) {
483                                 fprintf(stderr, "Bad port '%s'\n", optarg);
484                                 exit(255);
485                         }
486                         break;
487                 case 'l':
488                         options.user = optarg;
489                         break;
490
491                 case 'L':
492                         if (parse_forward(&fwd, optarg, 0, 0))
493                                 add_local_forward(&options, &fwd);
494                         else {
495                                 fprintf(stderr,
496                                     "Bad local forwarding specification '%s'\n",
497                                     optarg);
498                                 exit(255);
499                         }
500                         break;
501
502                 case 'R':
503                         if (parse_forward(&fwd, optarg, 0, 1)) {
504                                 add_remote_forward(&options, &fwd);
505                         } else {
506                                 fprintf(stderr,
507                                     "Bad remote forwarding specification "
508                                     "'%s'\n", optarg);
509                                 exit(255);
510                         }
511                         break;
512
513                 case 'D':
514                         if (parse_forward(&fwd, optarg, 1, 0)) {
515                                 add_local_forward(&options, &fwd);
516                         } else {
517                                 fprintf(stderr,
518                                     "Bad dynamic forwarding specification "
519                                     "'%s'\n", optarg);
520                                 exit(255);
521                         }
522                         break;
523
524                 case 'C':
525                         options.compression = 1;
526                         break;
527                 case 'N':
528                         no_shell_flag = 1;
529                         no_tty_flag = 1;
530                         break;
531                 case 'T':
532                         no_tty_flag = 1;
533 #ifdef  NONE_CIPHER_ENABLED
534                         /*
535                          * Ensure that the user does not try to backdoor a
536                          * NONE cipher switch on an interactive session by
537                          * explicitly disabling it if the user asks for a
538                          * session without a tty.
539                          */
540                         options.none_switch = 0;
541 #endif
542                         break;
543                 case 'o':
544                         dummy = 1;
545                         line = xstrdup(optarg);
546                         if (process_config_line(&options, host ? host : "",
547                             line, "command-line", 0, &dummy) != 0)
548                                 exit(255);
549                         xfree(line);
550                         break;
551                 case 's':
552                         subsystem_flag = 1;
553                         break;
554                 case 'S':
555                         if (options.control_path != NULL)
556                                 free(options.control_path);
557                         options.control_path = xstrdup(optarg);
558                         break;
559                 case 'b':
560                         options.bind_address = optarg;
561                         break;
562                 case 'F':
563                         config = optarg;
564                         break;
565                 default:
566                         usage();
567                 }
568         }
569
570         ac -= optind;
571         av += optind;
572
573         if (ac > 0 && !host) {
574                 if (strrchr(*av, '@')) {
575                         p = xstrdup(*av);
576                         cp = strrchr(p, '@');
577                         if (cp == NULL || cp == p)
578                                 usage();
579                         options.user = p;
580                         *cp = '\0';
581                         host = ++cp;
582                 } else
583                         host = *av;
584                 if (ac > 1) {
585                         optind = optreset = 1;
586                         goto again;
587                 }
588                 ac--, av++;
589         }
590
591         /* Check that we got a host name. */
592         if (!host)
593                 usage();
594
595         SSLeay_add_all_algorithms();
596         ERR_load_crypto_strings();
597
598         /* Initialize the command to execute on remote host. */
599         buffer_init(&command);
600
601         /*
602          * Save the command to execute on the remote host in a buffer. There
603          * is no limit on the length of the command, except by the maximum
604          * packet size.  Also sets the tty flag if there is no command.
605          */
606         if (!ac) {
607                 /* No command specified - execute shell on a tty. */
608                 tty_flag = 1;
609                 if (subsystem_flag) {
610                         fprintf(stderr,
611                             "You must specify a subsystem to invoke.\n");
612                         usage();
613                 }
614         } else {
615                 /* A command has been specified.  Store it into the buffer. */
616                 for (i = 0; i < ac; i++) {
617                         if (i)
618                                 buffer_append(&command, " ", 1);
619                         buffer_append(&command, av[i], strlen(av[i]));
620                 }
621         }
622
623         /* Cannot fork to background if no command. */
624         if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
625             !no_shell_flag)
626                 fatal("Cannot fork into background without a command "
627                     "to execute.");
628
629         /* Allocate a tty by default if no command specified. */
630         if (buffer_len(&command) == 0)
631                 tty_flag = 1;
632
633         /* Force no tty */
634         if (no_tty_flag)
635                 tty_flag = 0;
636         /* Do not allocate a tty if stdin is not a tty. */
637         if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
638                 if (tty_flag)
639                         logit("Pseudo-terminal will not be allocated because "
640                             "stdin is not a terminal.");
641                 tty_flag = 0;
642         }
643
644         /*
645          * Initialize "log" output.  Since we are the client all output
646          * actually goes to stderr.
647          */
648         log_init(argv0,
649             options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
650             SYSLOG_FACILITY_USER, !use_syslog);
651
652         /*
653          * Read per-user configuration file.  Ignore the system wide config
654          * file if the user specifies a config file on the command line.
655          */
656         if (config != NULL) {
657                 if (!read_config_file(config, host, &options, 0))
658                         fatal("Can't open user config file %.100s: "
659                             "%.100s", config, strerror(errno));
660         } else {
661                 r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
662                     _PATH_SSH_USER_CONFFILE);
663                 if (r > 0 && (size_t)r < sizeof(buf))
664                         (void)read_config_file(buf, host, &options, 1);
665
666                 /* Read systemwide configuration file after use config. */
667                 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
668                     &options, 0);
669         }
670
671         /* Fill configuration defaults. */
672         fill_default_options(&options);
673
674         channel_set_af(options.address_family);
675
676         /* reinit */
677         log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
678
679         seed_rng();
680
681         if (options.user == NULL)
682                 options.user = xstrdup(pw->pw_name);
683
684         /* Get default port if port has not been set. */
685         if (options.port == 0) {
686                 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
687                 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
688         }
689
690         if (options.local_command != NULL) {
691                 char thishost[NI_MAXHOST];
692
693                 if (gethostname(thishost, sizeof(thishost)) == -1)
694                         fatal("gethostname: %s", strerror(errno));
695                 snprintf(buf, sizeof(buf), "%d", options.port);
696                 debug3("expanding LocalCommand: %s", options.local_command);
697                 cp = options.local_command;
698                 options.local_command = percent_expand(cp, "d", pw->pw_dir,
699                     "h", options.hostname? options.hostname : host,
700                     "l", thishost, "n", host, "r", options.user, "p", buf,
701                     "u", pw->pw_name, (char *)NULL);
702                 debug3("expanded LocalCommand: %s", options.local_command);
703                 xfree(cp);
704         }
705
706         if (options.hostname != NULL)
707                 host = options.hostname;
708
709         /* Find canonic host name. */
710         if (strchr(host, '.') == 0) {
711                 struct addrinfo hints;
712                 struct addrinfo *ai = NULL;
713                 int errgai;
714                 memset(&hints, 0, sizeof(hints));
715                 hints.ai_family = options.address_family;
716                 hints.ai_flags = AI_CANONNAME;
717                 hints.ai_socktype = SOCK_STREAM;
718                 errgai = getaddrinfo(host, NULL, &hints, &ai);
719                 if (errgai == 0) {
720                         if (ai->ai_canonname != NULL)
721                                 host = xstrdup(ai->ai_canonname);
722                         freeaddrinfo(ai);
723                 }
724         }
725
726         /* force lowercase for hostkey matching */
727         if (options.host_key_alias != NULL) {
728                 for (p = options.host_key_alias; *p; p++)
729                         if (isupper(*p))
730                                 *p = (char)tolower(*p);
731         }
732
733         if (options.proxy_command != NULL &&
734             strcmp(options.proxy_command, "none") == 0) {
735                 xfree(options.proxy_command);
736                 options.proxy_command = NULL;
737         }
738         if (options.control_path != NULL &&
739             strcmp(options.control_path, "none") == 0) {
740                 xfree(options.control_path);
741                 options.control_path = NULL;
742         }
743
744         if (options.control_path != NULL) {
745                 char thishost[NI_MAXHOST];
746
747                 if (gethostname(thishost, sizeof(thishost)) == -1)
748                         fatal("gethostname: %s", strerror(errno));
749                 snprintf(buf, sizeof(buf), "%d", options.port);
750                 cp = tilde_expand_filename(options.control_path,
751                     original_real_uid);
752                 xfree(options.control_path);
753                 options.control_path = percent_expand(cp, "p", buf, "h", host,
754                     "r", options.user, "l", thishost, (char *)NULL);
755                 xfree(cp);
756         }
757         if (muxclient_command != 0 && options.control_path == NULL)
758                 fatal("No ControlPath specified for \"-O\" command");
759         if (options.control_path != NULL)
760                 muxclient(options.control_path);
761
762         timeout_ms = options.connection_timeout * 1000;
763
764         /* Open a connection to the remote host. */
765         if (ssh_connect(host, &hostaddr, options.port,
766             options.address_family, options.connection_attempts, &timeout_ms,
767             options.tcp_keep_alive, 
768 #ifdef HAVE_CYGWIN
769             options.use_privileged_port,
770 #else
771             original_effective_uid == 0 && options.use_privileged_port,
772 #endif
773             options.proxy_command) != 0)
774                 exit(255);
775
776         if (timeout_ms > 0)
777                 debug3("timeout: %d ms remain after connect", timeout_ms);
778
779         /*
780          * If we successfully made the connection, load the host private key
781          * in case we will need it later for combined rsa-rhosts
782          * authentication. This must be done before releasing extra
783          * privileges, because the file is only readable by root.
784          * If we cannot access the private keys, load the public keys
785          * instead and try to execute the ssh-keysign helper instead.
786          */
787         sensitive_data.nkeys = 0;
788         sensitive_data.keys = NULL;
789         sensitive_data.external_keysign = 0;
790         if (options.rhosts_rsa_authentication ||
791             options.hostbased_authentication) {
792                 sensitive_data.nkeys = 3;
793                 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
794                     sizeof(Key));
795
796                 PRIV_START;
797                 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
798                     _PATH_HOST_KEY_FILE, "", NULL, NULL);
799                 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
800                     _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
801                 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
802                     _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
803                 PRIV_END;
804
805                 if (options.hostbased_authentication == 1 &&
806                     sensitive_data.keys[0] == NULL &&
807                     sensitive_data.keys[1] == NULL &&
808                     sensitive_data.keys[2] == NULL) {
809                         sensitive_data.keys[1] = key_load_public(
810                             _PATH_HOST_DSA_KEY_FILE, NULL);
811                         sensitive_data.keys[2] = key_load_public(
812                             _PATH_HOST_RSA_KEY_FILE, NULL);
813                         sensitive_data.external_keysign = 1;
814                 }
815         }
816         /*
817          * Get rid of any extra privileges that we may have.  We will no
818          * longer need them.  Also, extra privileges could make it very hard
819          * to read identity files and other non-world-readable files from the
820          * user's home directory if it happens to be on a NFS volume where
821          * root is mapped to nobody.
822          */
823         if (original_effective_uid == 0) {
824                 PRIV_START;
825                 permanently_set_uid(pw);
826         }
827
828         /*
829          * Now that we are back to our own permissions, create ~/.ssh
830          * directory if it doesn't already exist.
831          */
832         r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
833             strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
834         if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
835                 if (mkdir(buf, 0700) < 0)
836                         error("Could not create directory '%.200s'.", buf);
837
838         /* load options.identity_files */
839         load_public_identity_files();
840
841         /* Expand ~ in known host file names. */
842         /* XXX mem-leaks: */
843         options.system_hostfile =
844             tilde_expand_filename(options.system_hostfile, original_real_uid);
845         options.user_hostfile =
846             tilde_expand_filename(options.user_hostfile, original_real_uid);
847         options.system_hostfile2 =
848             tilde_expand_filename(options.system_hostfile2, original_real_uid);
849         options.user_hostfile2 =
850             tilde_expand_filename(options.user_hostfile2, original_real_uid);
851
852         signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
853
854         /* Log into the remote system.  Never returns if the login fails. */
855         ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
856             pw, timeout_ms);
857
858         /* We no longer need the private host keys.  Clear them now. */
859         if (sensitive_data.nkeys != 0) {
860                 for (i = 0; i < sensitive_data.nkeys; i++) {
861                         if (sensitive_data.keys[i] != NULL) {
862                                 /* Destroys contents safely */
863                                 debug3("clear hostkey %d", i);
864                                 key_free(sensitive_data.keys[i]);
865                                 sensitive_data.keys[i] = NULL;
866                         }
867                 }
868                 xfree(sensitive_data.keys);
869         }
870         for (i = 0; i < options.num_identity_files; i++) {
871                 if (options.identity_files[i]) {
872                         xfree(options.identity_files[i]);
873                         options.identity_files[i] = NULL;
874                 }
875                 if (options.identity_keys[i]) {
876                         key_free(options.identity_keys[i]);
877                         options.identity_keys[i] = NULL;
878                 }
879         }
880
881         exit_status = compat20 ? ssh_session2() : ssh_session();
882         packet_close();
883
884         if (options.control_path != NULL && muxserver_sock != -1)
885                 unlink(options.control_path);
886
887         /*
888          * Send SIGHUP to proxy command if used. We don't wait() in
889          * case it hangs and instead rely on init to reap the child
890          */
891         if (proxy_command_pid > 1)
892                 kill(proxy_command_pid, SIGHUP);
893
894         return exit_status;
895 }
896
897 /* Callback for remote forward global requests */
898 static void
899 ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
900 {
901         Forward *rfwd = (Forward *)ctxt;
902
903         /* XXX verbose() on failure? */
904         debug("remote forward %s for: listen %d, connect %s:%d",
905             type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
906             rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
907         if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
908                 logit("Allocated port %u for remote forward to %s:%d",
909                         packet_get_int(),
910                         rfwd->connect_host, rfwd->connect_port);
911         }
912         
913         if (type == SSH2_MSG_REQUEST_FAILURE) {
914                 if (options.exit_on_forward_failure)
915                         fatal("Error: remote port forwarding failed for "
916                             "listen port %d", rfwd->listen_port);
917                 else
918                         logit("Warning: remote port forwarding failed for "
919                             "listen port %d", rfwd->listen_port);
920         }
921         if (++remote_forward_confirms_received == options.num_remote_forwards) {
922                 debug("All remote forwarding requests processed");
923                 if (fork_after_authentication_flag) {
924                         fork_after_authentication_flag = 0;
925                         if (daemon(1, 1) < 0)
926                                 fatal("daemon() failed: %.200s",
927                                     strerror(errno));
928                 }
929         }
930 }
931
932 static void
933 client_cleanup_stdio_fwd(int id, void *arg)
934 {
935         debug("stdio forwarding: done");
936         cleanup_exit(0);
937 }
938
939 static int
940 client_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect)
941 {
942         Channel *c;
943         int in, out;
944
945         debug3("client_setup_stdio_fwd %s:%d", host_to_connect,
946             port_to_connect);
947
948         in = dup(STDIN_FILENO);
949         out = dup(STDOUT_FILENO);
950         if (in < 0 || out < 0)
951                 fatal("channel_connect_stdio_fwd: dup() in/out failed");
952
953         if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect,
954             in, out)) == NULL)
955                 return 0;
956         channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
957         return 1;
958 }
959
960 static void
961 ssh_init_forwarding(void)
962 {
963         int success = 0;
964         int i;
965
966         if (stdio_forward_host != NULL) {
967                 if (!compat20) {
968                         fatal("stdio forwarding require Protocol 2");
969                 }
970                 if (!client_setup_stdio_fwd(stdio_forward_host,
971                     stdio_forward_port))
972                         fatal("Failed to connect in stdio forward mode.");
973         }
974
975         /* Initiate local TCP/IP port forwardings. */
976         for (i = 0; i < options.num_local_forwards; i++) {
977                 debug("Local connections to %.200s:%d forwarded to remote "
978                     "address %.200s:%d",
979                     (options.local_forwards[i].listen_host == NULL) ?
980                     (options.gateway_ports ? "*" : "LOCALHOST") :
981                     options.local_forwards[i].listen_host,
982                     options.local_forwards[i].listen_port,
983                     options.local_forwards[i].connect_host,
984                     options.local_forwards[i].connect_port);
985                 success += channel_setup_local_fwd_listener(
986                     options.local_forwards[i].listen_host,
987                     options.local_forwards[i].listen_port,
988                     options.local_forwards[i].connect_host,
989                     options.local_forwards[i].connect_port,
990                     options.gateway_ports);
991         }
992         if (i > 0 && success != i && options.exit_on_forward_failure)
993                 fatal("Could not request local forwarding.");
994         if (i > 0 && success == 0)
995                 error("Could not request local forwarding.");
996
997         /* Initiate remote TCP/IP port forwardings. */
998         for (i = 0; i < options.num_remote_forwards; i++) {
999                 debug("Remote connections from %.200s:%d forwarded to "
1000                     "local address %.200s:%d",
1001                     (options.remote_forwards[i].listen_host == NULL) ?
1002                     "LOCALHOST" : options.remote_forwards[i].listen_host,
1003                     options.remote_forwards[i].listen_port,
1004                     options.remote_forwards[i].connect_host,
1005                     options.remote_forwards[i].connect_port);
1006                 if (channel_request_remote_forwarding(
1007                     options.remote_forwards[i].listen_host,
1008                     options.remote_forwards[i].listen_port,
1009                     options.remote_forwards[i].connect_host,
1010                     options.remote_forwards[i].connect_port) < 0) {
1011                         if (options.exit_on_forward_failure)
1012                                 fatal("Could not request remote forwarding.");
1013                         else
1014                                 logit("Warning: Could not request remote "
1015                                     "forwarding.");
1016                 }
1017                 client_register_global_confirm(ssh_confirm_remote_forward,
1018                     &options.remote_forwards[i]);
1019         }
1020
1021         /* Initiate tunnel forwarding. */
1022         if (options.tun_open != SSH_TUNMODE_NO) {
1023                 if (client_request_tun_fwd(options.tun_open,
1024                     options.tun_local, options.tun_remote) == -1) {
1025                         if (options.exit_on_forward_failure)
1026                                 fatal("Could not request tunnel forwarding.");
1027                         else
1028                                 error("Could not request tunnel forwarding.");
1029                 }
1030         }                       
1031 }
1032
1033 static void
1034 check_agent_present(void)
1035 {
1036         if (options.forward_agent) {
1037                 /* Clear agent forwarding if we don't have an agent. */
1038                 if (!ssh_agent_present())
1039                         options.forward_agent = 0;
1040         }
1041 }
1042
1043 static int
1044 ssh_session(void)
1045 {
1046         int type;
1047         int interactive = 0;
1048         int have_tty = 0;
1049         struct winsize ws;
1050         char *cp;
1051         const char *display;
1052
1053         /* Enable compression if requested. */
1054         if (options.compression) {
1055                 debug("Requesting compression at level %d.",
1056                     options.compression_level);
1057
1058                 if (options.compression_level < 1 ||
1059                     options.compression_level > 9)
1060                         fatal("Compression level must be from 1 (fast) to "
1061                             "9 (slow, best).");
1062
1063                 /* Send the request. */
1064                 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
1065                 packet_put_int(options.compression_level);
1066                 packet_send();
1067                 packet_write_wait();
1068                 type = packet_read();
1069                 if (type == SSH_SMSG_SUCCESS)
1070                         packet_start_compression(options.compression_level);
1071                 else if (type == SSH_SMSG_FAILURE)
1072                         logit("Warning: Remote host refused compression.");
1073                 else
1074                         packet_disconnect("Protocol error waiting for "
1075                             "compression response.");
1076         }
1077         /* Allocate a pseudo tty if appropriate. */
1078         if (tty_flag) {
1079                 debug("Requesting pty.");
1080
1081                 /* Start the packet. */
1082                 packet_start(SSH_CMSG_REQUEST_PTY);
1083
1084                 /* Store TERM in the packet.  There is no limit on the
1085                    length of the string. */
1086                 cp = getenv("TERM");
1087                 if (!cp)
1088                         cp = "";
1089                 packet_put_cstring(cp);
1090
1091                 /* Store window size in the packet. */
1092                 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1093                         memset(&ws, 0, sizeof(ws));
1094                 packet_put_int((u_int)ws.ws_row);
1095                 packet_put_int((u_int)ws.ws_col);
1096                 packet_put_int((u_int)ws.ws_xpixel);
1097                 packet_put_int((u_int)ws.ws_ypixel);
1098
1099                 /* Store tty modes in the packet. */
1100                 tty_make_modes(fileno(stdin), NULL);
1101
1102                 /* Send the packet, and wait for it to leave. */
1103                 packet_send();
1104                 packet_write_wait();
1105
1106                 /* Read response from the server. */
1107                 type = packet_read();
1108                 if (type == SSH_SMSG_SUCCESS) {
1109                         interactive = 1;
1110                         have_tty = 1;
1111                 } else if (type == SSH_SMSG_FAILURE)
1112                         logit("Warning: Remote host failed or refused to "
1113                             "allocate a pseudo tty.");
1114                 else
1115                         packet_disconnect("Protocol error waiting for pty "
1116                             "request response.");
1117         }
1118         /* Request X11 forwarding if enabled and DISPLAY is set. */
1119         display = getenv("DISPLAY");
1120         if (options.forward_x11 && display != NULL) {
1121                 char *proto, *data;
1122                 /* Get reasonable local authentication information. */
1123                 client_x11_get_proto(display, options.xauth_location,
1124                     options.forward_x11_trusted, &proto, &data);
1125                 /* Request forwarding with authentication spoofing. */
1126                 debug("Requesting X11 forwarding with authentication "
1127                     "spoofing.");
1128                 x11_request_forwarding_with_spoofing(0, display, proto, data);
1129
1130                 /* Read response from the server. */
1131                 type = packet_read();
1132                 if (type == SSH_SMSG_SUCCESS) {
1133                         interactive = 1;
1134                 } else if (type == SSH_SMSG_FAILURE) {
1135                         logit("Warning: Remote host denied X11 forwarding.");
1136                 } else {
1137                         packet_disconnect("Protocol error waiting for X11 "
1138                             "forwarding");
1139                 }
1140         }
1141         /* Tell the packet module whether this is an interactive session. */
1142         packet_set_interactive(interactive);
1143
1144         /* Request authentication agent forwarding if appropriate. */
1145         check_agent_present();
1146
1147         if (options.forward_agent) {
1148                 debug("Requesting authentication agent forwarding.");
1149                 auth_request_forwarding();
1150
1151                 /* Read response from the server. */
1152                 type = packet_read();
1153                 packet_check_eom();
1154                 if (type != SSH_SMSG_SUCCESS)
1155                         logit("Warning: Remote host denied authentication agent forwarding.");
1156         }
1157
1158         /* Initiate port forwardings. */
1159         ssh_init_forwarding();
1160
1161         /* Execute a local command */
1162         if (options.local_command != NULL &&
1163             options.permit_local_command)
1164                 ssh_local_cmd(options.local_command);
1165
1166         /*
1167          * If requested and we are not interested in replies to remote
1168          * forwarding requests, then let ssh continue in the background.
1169          */
1170         if (fork_after_authentication_flag &&
1171             (!options.exit_on_forward_failure ||
1172             options.num_remote_forwards == 0)) {
1173                 fork_after_authentication_flag = 0;
1174                 if (daemon(1, 1) < 0)
1175                         fatal("daemon() failed: %.200s", strerror(errno));
1176         }
1177
1178         /*
1179          * If a command was specified on the command line, execute the
1180          * command now. Otherwise request the server to start a shell.
1181          */
1182         if (buffer_len(&command) > 0) {
1183                 int len = buffer_len(&command);
1184                 if (len > 900)
1185                         len = 900;
1186                 debug("Sending command: %.*s", len,
1187                     (u_char *)buffer_ptr(&command));
1188                 packet_start(SSH_CMSG_EXEC_CMD);
1189                 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1190                 packet_send();
1191                 packet_write_wait();
1192         } else {
1193                 debug("Requesting shell.");
1194                 packet_start(SSH_CMSG_EXEC_SHELL);
1195                 packet_send();
1196                 packet_write_wait();
1197         }
1198
1199         /* Enter the interactive session. */
1200         return client_loop(have_tty, tty_flag ?
1201             options.escape_char : SSH_ESCAPECHAR_NONE, 0);
1202 }
1203
1204 /* request pty/x11/agent/tcpfwd/shell for channel */
1205 static void
1206 ssh_session2_setup(int id, void *arg)
1207 {
1208         extern char **environ;
1209         const char *display;
1210         int interactive = tty_flag;
1211
1212         display = getenv("DISPLAY");
1213         if (options.forward_x11 && display != NULL) {
1214                 char *proto, *data;
1215                 /* Get reasonable local authentication information. */
1216                 client_x11_get_proto(display, options.xauth_location,
1217                     options.forward_x11_trusted, &proto, &data);
1218                 /* Request forwarding with authentication spoofing. */
1219                 debug("Requesting X11 forwarding with authentication "
1220                     "spoofing.");
1221                 x11_request_forwarding_with_spoofing(id, display, proto, data);
1222                 interactive = 1;
1223                 /* XXX wait for reply */
1224         }
1225
1226         check_agent_present();
1227         if (options.forward_agent) {
1228                 debug("Requesting authentication agent forwarding.");
1229                 channel_request_start(id, "auth-agent-req@openssh.com", 0);
1230                 packet_send();
1231         }
1232
1233         client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
1234             NULL, fileno(stdin), &command, environ);
1235
1236         packet_set_interactive(interactive);
1237 }
1238
1239 /* open new channel for a session */
1240 static int
1241 ssh_session2_open(void)
1242 {
1243         Channel *c;
1244         int window, packetmax, in, out, err;
1245
1246         if (stdin_null_flag) {
1247                 in = open(_PATH_DEVNULL, O_RDONLY);
1248         } else {
1249                 in = dup(STDIN_FILENO);
1250         }
1251         out = dup(STDOUT_FILENO);
1252         err = dup(STDERR_FILENO);
1253
1254         if (in < 0 || out < 0 || err < 0)
1255                 fatal("dup() in/out/err failed");
1256
1257         /* enable nonblocking unless tty */
1258         if (!isatty(in))
1259                 set_nonblock(in);
1260         if (!isatty(out))
1261                 set_nonblock(out);
1262         if (!isatty(err))
1263                 set_nonblock(err);
1264
1265         /*
1266          * We need to check to see what to do about buffer sizes here.
1267          * - In an HPN to non-HPN connection we want to limit the window size to
1268          *   something reasonable in case the far side has the large window bug.
1269          * - In an HPN to HPN connection we want to use the max window size but
1270          *   allow the user to override it.
1271          * - Lastly if HPN is disabled then use the ssh standard window size.
1272          *
1273          * We cannot just do a getsockopt() here and set the ssh window to that
1274          * as in case of autotuning of socket buffers the window would get stuck
1275          * at the initial buffer size, generally less than 96k.  Therefore we
1276          * need to set the maximum ssh window size to the maximum HPN buffer
1277          * size unless the user has set TcpRcvBufPoll to no.  In that case we
1278          * can just set the window to the minimum of HPN buffer size and TCP
1279          * receive buffer size.
1280          */
1281         if (tty_flag)
1282                 options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
1283         else
1284                 options.hpn_buffer_size = CHAN_HPN_MIN_WINDOW_DEFAULT;
1285
1286         if (datafellows & SSH_BUG_LARGEWINDOW) {
1287                 debug("HPN to Non-HPN Connection");
1288         } else if (options.tcp_rcv_buf_poll <= 0) {
1289                 sock_get_rcvbuf(&options.hpn_buffer_size, 0);
1290                 debug("HPNBufferSize set to TCP RWIN: %d",
1291                     options.hpn_buffer_size);
1292         } else if (options.tcp_rcv_buf > 0) {
1293                 sock_get_rcvbuf(&options.hpn_buffer_size,
1294                     options.tcp_rcv_buf);
1295                 debug("HPNBufferSize set to user TCPRcvBuf: %d",
1296                     options.hpn_buffer_size);
1297         }
1298         debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
1299         channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
1300         window = options.hpn_buffer_size;
1301
1302         packetmax = CHAN_SES_PACKET_DEFAULT;
1303         if (tty_flag) {
1304                 window = CHAN_SES_WINDOW_DEFAULT;
1305                 window >>= 1;
1306                 packetmax >>= 1;
1307         }
1308         c = channel_new(
1309             "session", SSH_CHANNEL_OPENING, in, out, err,
1310             window, packetmax, CHAN_EXTENDED_WRITE,
1311             "client-session", /*nonblock*/0);
1312         if (!options.hpn_disabled && options.tcp_rcv_buf_poll > 0) {
1313                 c->dynamic_window = 1;
1314                 debug("Enabled Dynamic Window Scaling\n");
1315         }
1316         debug3("ssh_session2_open: channel_new: %d", c->self);
1317
1318         channel_send_open(c->self);
1319         if (!no_shell_flag)
1320                 channel_register_open_confirm(c->self,
1321                     ssh_session2_setup, NULL);
1322
1323         return c->self;
1324 }
1325
1326 static int
1327 ssh_session2(void)
1328 {
1329         int id = -1;
1330
1331         /* XXX should be pre-session */
1332         ssh_init_forwarding();
1333
1334         if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1335                 id = ssh_session2_open();
1336
1337         /* If we don't expect to open a new session, then disallow it */
1338         if (options.control_master == SSHCTL_MASTER_NO &&
1339             (datafellows & SSH_NEW_OPENSSH)) {
1340                 debug("Requesting no-more-sessions@openssh.com");
1341                 packet_start(SSH2_MSG_GLOBAL_REQUEST);
1342                 packet_put_cstring("no-more-sessions@openssh.com");
1343                 packet_put_char(0);
1344                 packet_send();
1345         }
1346
1347         /* Execute a local command */
1348         if (options.local_command != NULL &&
1349             options.permit_local_command)
1350                 ssh_local_cmd(options.local_command);
1351
1352         /* Start listening for multiplex clients */
1353         muxserver_listen();
1354
1355         /* If requested, let ssh continue in the background. */
1356         if (fork_after_authentication_flag) {
1357                 fork_after_authentication_flag = 0;
1358                 if (daemon(1, 1) < 0)
1359                         fatal("daemon() failed: %.200s", strerror(errno));
1360         }
1361
1362         if (options.use_roaming)
1363                 request_roaming();
1364
1365         return client_loop(tty_flag, tty_flag ?
1366             options.escape_char : SSH_ESCAPECHAR_NONE, id);
1367 }
1368
1369 static void
1370 load_public_identity_files(void)
1371 {
1372         char *filename, *cp, thishost[NI_MAXHOST];
1373         char *pwdir = NULL, *pwname = NULL;
1374         int i = 0;
1375         Key *public;
1376         struct passwd *pw;
1377         u_int n_ids;
1378         char *identity_files[SSH_MAX_IDENTITY_FILES];
1379         Key *identity_keys[SSH_MAX_IDENTITY_FILES];
1380 #ifdef ENABLE_PKCS11
1381         Key **keys;
1382         int nkeys;
1383 #endif /* PKCS11 */
1384
1385         n_ids = 0;
1386         bzero(identity_files, sizeof(identity_files));
1387         bzero(identity_keys, sizeof(identity_keys));
1388
1389 #ifdef ENABLE_PKCS11
1390         if (options.pkcs11_provider != NULL &&
1391             options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
1392             (pkcs11_init(!options.batch_mode) == 0) &&
1393             (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
1394             &keys)) > 0) {
1395                 for (i = 0; i < nkeys; i++) {
1396                         if (n_ids >= SSH_MAX_IDENTITY_FILES) {
1397                                 key_free(keys[i]);
1398                                 continue;
1399                         }
1400                         identity_keys[n_ids] = keys[i];
1401                         identity_files[n_ids] =
1402                             xstrdup(options.pkcs11_provider); /* XXX */
1403                         n_ids++;
1404                 }
1405                 xfree(keys);
1406         }
1407 #endif /* ENABLE_PKCS11 */
1408         if ((pw = getpwuid(original_real_uid)) == NULL)
1409                 fatal("load_public_identity_files: getpwuid failed");
1410         pwname = xstrdup(pw->pw_name);
1411         pwdir = xstrdup(pw->pw_dir);
1412         if (gethostname(thishost, sizeof(thishost)) == -1)
1413                 fatal("load_public_identity_files: gethostname: %s",
1414                     strerror(errno));
1415         for (i = 0; i < options.num_identity_files; i++) {
1416                 if (n_ids >= SSH_MAX_IDENTITY_FILES) {
1417                         xfree(options.identity_files[i]);
1418                         continue;
1419                 }
1420                 cp = tilde_expand_filename(options.identity_files[i],
1421                     original_real_uid);
1422                 filename = percent_expand(cp, "d", pwdir,
1423                     "u", pwname, "l", thishost, "h", host,
1424                     "r", options.user, (char *)NULL);
1425                 xfree(cp);
1426                 public = key_load_public(filename, NULL);
1427                 debug("identity file %s type %d", filename,
1428                     public ? public->type : -1);
1429                 xfree(options.identity_files[i]);
1430                 identity_files[n_ids] = filename;
1431                 identity_keys[n_ids] = public;
1432
1433                 if (++n_ids >= SSH_MAX_IDENTITY_FILES)
1434                         continue;
1435
1436                 /* Try to add the certificate variant too */
1437                 xasprintf(&cp, "%s-cert", filename);
1438                 public = key_load_public(cp, NULL);
1439                 debug("identity file %s type %d", cp,
1440                     public ? public->type : -1);
1441                 if (public == NULL) {
1442                         xfree(cp);
1443                         continue;
1444                 }
1445                 if (!key_is_cert(public)) {
1446                         debug("%s: key %s type %s is not a certificate",
1447                             __func__, cp, key_type(public));
1448                         key_free(public);
1449                         xfree(cp);
1450                         continue;
1451                 }
1452                 identity_keys[n_ids] = public;
1453                 /* point to the original path, most likely the private key */
1454                 identity_files[n_ids] = xstrdup(filename);
1455                 n_ids++;
1456         }
1457         options.num_identity_files = n_ids;
1458         memcpy(options.identity_files, identity_files, sizeof(identity_files));
1459         memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
1460
1461         bzero(pwname, strlen(pwname));
1462         xfree(pwname);
1463         bzero(pwdir, strlen(pwdir));
1464         xfree(pwdir);
1465 }