11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: ssh.c,v 1.364 2011/08/02 23:15:03 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi>
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *                    All rights reserved
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Ssh client program.  This program can be used to log into a remote machine.
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The software supports strong authentication, encryption, and forwarding
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * of X11, TCP/IP, and authentication connections.
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose.  Any derived versions of this
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell".
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1999 Niels Provos.  All rights reserved.
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl.  All rights reserved.
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * in Canada (German citizen).
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met:
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer.
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer in the
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    documentation and/or other materials provided with the distribution.
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_STAT_H
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/stat.h>
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/resource.h>
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/ioctl.h>
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h>
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h>
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/wait.h>
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <ctype.h>
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h>
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h>
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netdb.h>
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <paths.h>
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h>
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h>
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stddef.h>
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h>
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h>
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h>
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <arpa/inet.h>
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/evp.h>
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/err.h>
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/openssl-compat.h"
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h"
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h"
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h"
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h"
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h"
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "canohost.h"
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h"
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h"
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h"
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "channels.h"
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h"
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfd.h"
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfile.h"
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "pathnames.h"
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dispatch.h"
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "clientloop.h"
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "readconf.h"
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshconnect.h"
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h"
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h"
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "mac.h"
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshpty.h"
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h"
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "msg.h"
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "uidswap.h"
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "roaming.h"
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "version.h"
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-pkcs11.h"
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *__progname;
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Saves a copy of argv for setproctitle emulation */
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_SETPROCTITLE
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char **saved_av;
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Flag indicating whether debug mode is on.  May be set on the command line. */
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint debug_flag = 0;
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Flag indicating whether a tty should be requested */
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint tty_flag = 0;
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* don't exec a shell */
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint no_shell_flag = 0;
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Flag indicating that nothing should be read from stdin.  This can be set
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * on the command line.
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint stdin_null_flag = 0;
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Flag indicating that the current process should be backgrounded and
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a new slave launched in the foreground for ControlPersist.
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint need_controlpersist_detach = 0;
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Copies of flags for ControlPersist foreground slave */
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Flag indicating that ssh should fork after authentication.  This is useful
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * so that the passphrase can be entered manually, and then ssh goes to the
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * background.
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint fork_after_authentication_flag = 0;
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* forward stdio to remote host and port */
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *stdio_forward_host = NULL;
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint stdio_forward_port = 0;
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * General data structure for command line options and options configurable
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * in configuration files.  See readconf.h.
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodOptions options;
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* optional user configfile */
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *config = NULL;
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Name of the host we are connecting to.  This is the name given on the
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * command line, or the HostName specified for the user-supplied name in a
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * configuration file.
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *host;
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* socket address the host resolves to */
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct sockaddr_storage hostaddr;
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Private host keys. */
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSensitive sensitive_data;
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Original real UID. */
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduid_t original_real_uid;
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduid_t original_effective_uid;
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* command to be executed */
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodBuffer command;
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Should we execute a command or invoke a subsystem? */
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint subsystem_flag = 0;
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* # of replies received for global requests */
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int remote_forward_confirms_received = 0;
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* mux.c */
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int muxserver_sock;
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern u_int muxclient_command;
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Prints a help message to the user.  This function never returns. */
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodusage(void)
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr,
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-I pkcs11] [-i identity_file]\n"
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-L [bind_address:]port:host:hostport]\n"
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [-W host:port] [-w local_tun[:remote_tun]]\n"
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood"           [user@]hostname [command]\n"
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	);
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	exit(255);
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int ssh_session(void);
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int ssh_session2(void);
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void load_public_identity_files(void);
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void main_sigchld_handler(int);
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* from muxclient.c */
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid muxclient(const char *);
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid muxserver_listen(void);
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtilde_expand_paths(char **paths, u_int num_paths)
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int i;
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *cp;
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < num_paths; i++) {
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = tilde_expand_filename(paths[i], original_real_uid);
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(paths[i]);
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		paths[i] = cp;
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Main program for the ssh client.
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmain(int ac, char **av)
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, r, opt, exit_status, use_syslog;
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg;
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct stat st;
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct passwd *pw;
2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int dummy, timeout_ms;
2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	extern int optind, optreset;
2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	extern char *optarg;
2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct servent *sp;
2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Forward fwd;
2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	sanitise_stdfd();
2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	__progname = ssh_get_progname(av[0]);
2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_SETPROCTITLE
2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Prepare for later setproctitle emulation */
2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Save argv so it isn't clobbered by setproctitle() emulation */
2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	saved_av = xcalloc(ac + 1, sizeof(*saved_av));
2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < ac; i++)
2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		saved_av[i] = xstrdup(av[i]);
2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	saved_av[i] = NULL;
2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	compat_init_setproctitle(ac, av);
2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	av = saved_av;
2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Discard other fds that are hanging around. These can cause problem
2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * with backgrounded ssh processes started by ControlPersist.
2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	closefrom(STDERR_FILENO + 1);
2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Save the original real uid.  It will be needed later (uid-swapping
2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * may clobber the real uid).
2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	original_real_uid = getuid();
2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	original_effective_uid = geteuid();
2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Use uid-swapping to give up root privileges for the duration of
2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * option processing.  We will re-instantiate the rights when we are
2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * ready to create the privileged port, and will permanently drop
2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * them when the port has been created (actually, when the connection
2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * has been made, as we may need to create the port several times).
2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	PRIV_END;
2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SETRLIMIT
2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* If we are installed setuid root be careful to not drop core. */
2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (original_real_uid != original_effective_uid) {
2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		struct rlimit rlim;
2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rlim.rlim_cur = rlim.rlim_max = 0;
2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (setrlimit(RLIMIT_CORE, &rlim) < 0)
2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("setrlimit failed: %.100s", strerror(errno));
2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get user data. */
3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pw = getpwuid(original_real_uid);
3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!pw) {
3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("You don't exist, go away!");
3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		exit(255);
3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Take a copy of the returned structure. */
3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pw = pwcopy(pw);
3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Set our umask to something reasonable, as some files are created
3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * with the default umask.  This will make them world-readable but
3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * writable only by the owner, which is ok for all files for which we
3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * don't set the modes explicitly.
3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	umask(022);
3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Initialize option structure to indicate that no values have been
3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * set.
3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	initialize_options(&options);
3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Parse command-line arguments. */
3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	host = NULL;
3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	use_syslog = 0;
3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	argv0 = av[0];
3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood again:
3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) {
3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		switch (opt) {
3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case '1':
3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.protocol = SSH_PROTO_1;
3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case '2':
3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.protocol = SSH_PROTO_2;
3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case '4':
3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.address_family = AF_INET;
3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case '6':
3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.address_family = AF_INET6;
3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'n':
3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			stdin_null_flag = 1;
3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'f':
3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fork_after_authentication_flag = 1;
3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			stdin_null_flag = 1;
3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'x':
3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_x11 = 0;
3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'X':
3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_x11 = 1;
3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'y':
3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			use_syslog = 1;
3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'Y':
3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_x11 = 1;
3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_x11_trusted = 1;
3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'g':
3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.gateway_ports = 1;
3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'O':
3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (stdio_forward_host != NULL)
3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Cannot specify multiplexing "
3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "command with -W");
3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (muxclient_command != 0)
3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Multiplexing command already specified");
3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (strcmp(optarg, "check") == 0)
3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (strcmp(optarg, "forward") == 0)
3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				muxclient_command = SSHMUX_COMMAND_FORWARD;
3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (strcmp(optarg, "exit") == 0)
3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				muxclient_command = SSHMUX_COMMAND_TERMINATE;
3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (strcmp(optarg, "stop") == 0)
3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				muxclient_command = SSHMUX_COMMAND_STOP;
3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Invalid multiplex command.");
3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'P':	/* deprecated */
3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.use_privileged_port = 0;
3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'a':
3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_agent = 0;
3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'A':
3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_agent = 1;
3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'k':
3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.gss_deleg_creds = 0;
3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'K':
3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.gss_authentication = 1;
3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.gss_deleg_creds = 1;
3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'i':
4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (stat(optarg, &st) < 0) {
4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr, "Warning: Identity file %s "
4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "not accessible: %s.\n", optarg,
4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    strerror(errno));
4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.num_identity_files >=
4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    SSH_MAX_IDENTITY_FILES)
4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Too many identity files specified "
4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "(max %d)", SSH_MAX_IDENTITY_FILES);
4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.identity_files[options.num_identity_files++] =
4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    xstrdup(optarg);
4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'I':
4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11
4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.pkcs11_provider = xstrdup(optarg);
4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fprintf(stderr, "no support for PKCS#11.\n");
4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 't':
4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.request_tty == REQUEST_TTY_YES)
4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.request_tty = REQUEST_TTY_FORCE;
4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.request_tty = REQUEST_TTY_YES;
4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'v':
4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (debug_flag == 0) {
4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug_flag = 1;
4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.log_level = SYSLOG_LEVEL_DEBUG1;
4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (options.log_level < SYSLOG_LEVEL_DEBUG3)
4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					options.log_level++;
4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			/* FALLTHROUGH */
4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'V':
4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fprintf(stderr, "%s, %s\n",
4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (opt == 'V')
4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(0);
4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'w':
4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.tun_open == -1)
4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.tun_open = SSH_TUNMODE_DEFAULT;
4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.tun_local = a2tun(optarg, &options.tun_remote);
4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.tun_local == SSH_TUNID_ERR) {
4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr,
4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "Bad tun device '%s'\n", optarg);
4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'W':
4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (stdio_forward_host != NULL)
4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("stdio forward already specified");
4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (muxclient_command != 0)
4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Cannot specify stdio forward with -O");
4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (parse_forward(&fwd, optarg, 1, 0)) {
4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				stdio_forward_host = fwd.listen_host;
4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				stdio_forward_port = fwd.listen_port;
4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(fwd.connect_host);
4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr,
4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "Bad stdio forwarding specification '%s'\n",
4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    optarg);
4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.request_tty = REQUEST_TTY_NO;
4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			no_shell_flag = 1;
4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.clear_forwardings = 1;
4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.exit_on_forward_failure = 1;
4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'q':
4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.log_level = SYSLOG_LEVEL_QUIET;
4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'e':
4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (optarg[0] == '^' && optarg[2] == 0 &&
4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    (u_char) optarg[1] >= 64 &&
4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    (u_char) optarg[1] < 128)
4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.escape_char = (u_char) optarg[1] & 31;
4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (strlen(optarg) == 1)
4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.escape_char = (u_char) optarg[0];
4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else if (strcmp(optarg, "none") == 0)
4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.escape_char = SSH_ESCAPECHAR_NONE;
4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else {
4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr, "Bad escape character '%s'.\n",
4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    optarg);
4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'c':
4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (ciphers_valid(optarg)) {
4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* SSH2 only */
4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.ciphers = xstrdup(optarg);
4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.cipher = SSH_CIPHER_INVALID;
4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* SSH1 only */
4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.cipher = cipher_number(optarg);
4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (options.cipher == -1) {
4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					fprintf(stderr,
5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    "Unknown cipher type '%s'\n",
5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					    optarg);
5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					exit(255);
5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				}
5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (options.cipher == SSH_CIPHER_3DES)
5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					options.ciphers = "3des-cbc";
5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				else if (options.cipher == SSH_CIPHER_BLOWFISH)
5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					options.ciphers = "blowfish-cbc";
5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				else
5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					options.ciphers = (char *)-1;
5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'm':
5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (mac_valid(optarg))
5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.macs = xstrdup(optarg);
5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else {
5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr, "Unknown mac type '%s'\n",
5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    optarg);
5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'M':
5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.control_master == SSHCTL_MASTER_YES)
5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.control_master = SSHCTL_MASTER_ASK;
5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				options.control_master = SSHCTL_MASTER_YES;
5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'p':
5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.port = a2port(optarg);
5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.port <= 0) {
5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr, "Bad port '%s'\n", optarg);
5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'l':
5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.user = optarg;
5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'L':
5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (parse_forward(&fwd, optarg, 0, 0))
5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				add_local_forward(&options, &fwd);
5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else {
5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr,
5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "Bad local forwarding specification '%s'\n",
5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    optarg);
5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'R':
5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (parse_forward(&fwd, optarg, 0, 1)) {
5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				add_remote_forward(&options, &fwd);
5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr,
5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "Bad remote forwarding specification "
5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "'%s'\n", optarg);
5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'D':
5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (parse_forward(&fwd, optarg, 1, 0)) {
5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				add_local_forward(&options, &fwd);
5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			} else {
5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fprintf(stderr,
5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "Bad dynamic forwarding specification "
5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "'%s'\n", optarg);
5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'C':
5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.compression = 1;
5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'N':
5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			no_shell_flag = 1;
5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.request_tty = REQUEST_TTY_NO;
5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'T':
5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.request_tty = REQUEST_TTY_NO;
5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'o':
5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			dummy = 1;
5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			line = xstrdup(optarg);
5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (process_config_line(&options, host ? host : "",
5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    line, "command-line", 0, &dummy) != 0)
5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				exit(255);
5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(line);
5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 's':
5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			subsystem_flag = 1;
5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'S':
5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.control_path != NULL)
5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				free(options.control_path);
5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.control_path = xstrdup(optarg);
5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'b':
5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.bind_address = optarg;
5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case 'F':
6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			config = optarg;
6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			break;
6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		default:
6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			usage();
6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ac -= optind;
6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	av += optind;
6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (ac > 0 && !host) {
6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (strrchr(*av, '@')) {
6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			p = xstrdup(*av);
6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cp = strrchr(p, '@');
6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (cp == NULL || cp == p)
6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				usage();
6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.user = p;
6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			*cp = '\0';
6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			host = ++cp;
6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else
6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			host = *av;
6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (ac > 1) {
6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			optind = optreset = 1;
6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			goto again;
6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ac--, av++;
6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Check that we got a host name. */
6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!host)
6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		usage();
6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	OpenSSL_add_all_algorithms();
6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ERR_load_crypto_strings();
6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Initialize the command to execute on remote host. */
6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_init(&command);
6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.request_tty == REQUEST_TTY_YES ||
6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.request_tty == REQUEST_TTY_FORCE)
6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = 1;
6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Save the command to execute on the remote host in a buffer. There
6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * is no limit on the length of the command, except by the maximum
6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * packet size.  Also sets the tty flag if there is no command.
6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!ac) {
6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* No command specified - execute shell on a tty. */
6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = options.request_tty != REQUEST_TTY_NO;
6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (subsystem_flag) {
6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fprintf(stderr,
6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "You must specify a subsystem to invoke.\n");
6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			usage();
6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* A command has been specified.  Store it into the buffer. */
6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < ac; i++) {
6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i)
6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				buffer_append(&command, " ", 1);
6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_append(&command, av[i], strlen(av[i]));
6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Cannot fork to background if no command. */
6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    !no_shell_flag)
6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Cannot fork into background without a command "
6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "to execute.");
6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Allocate a tty by default if no command specified. */
6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&command) == 0)
6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = options.request_tty != REQUEST_TTY_NO;
6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Force no tty */
6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = 0;
6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Do not allocate a tty if stdin is not a tty. */
6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.request_tty != REQUEST_TTY_FORCE) {
6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (tty_flag)
6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Pseudo-terminal will not be allocated because "
6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "stdin is not a terminal.");
6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = 0;
6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Initialize "log" output.  Since we are the client all output
6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * actually goes to stderr.
6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	log_init(argv0,
6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    SYSLOG_FACILITY_USER, !use_syslog);
6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Read per-user configuration file.  Ignore the system wide config
6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * file if the user specifies a config file on the command line.
6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (config != NULL) {
7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!read_config_file(config, host, &options, 0))
7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Can't open user config file %.100s: "
7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "%.100s", config, strerror(errno));
7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_SSH_USER_CONFFILE);
7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (r > 0 && (size_t)r < sizeof(buf))
7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			(void)read_config_file(buf, host, &options, 1);
7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Read systemwide configuration file after user config. */
7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &options, 0);
7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Fill configuration defaults. */
7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fill_default_options(&options);
7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	channel_set_af(options.address_family);
7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* reinit */
7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	seed_rng();
7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.user == NULL)
7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.user = xstrdup(pw->pw_name);
7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get default port if port has not been set. */
7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.port == 0) {
7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* preserve host name given on command line for %n expansion */
7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	host_arg = host;
7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.hostname != NULL) {
7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		host = percent_expand(options.hostname,
7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "h", host, (char *)NULL);
7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (gethostname(thishost, sizeof(thishost)) == -1)
7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("gethostname: %s", strerror(errno));
7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	strlcpy(shorthost, thishost, sizeof(shorthost));
7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	shorthost[strcspn(thishost, ".")] = '\0';
7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	snprintf(portstr, sizeof(portstr), "%d", options.port);
7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.local_command != NULL) {
7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("expanding LocalCommand: %s", options.local_command);
7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = options.local_command;
7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.local_command = percent_expand(cp, "d", pw->pw_dir,
7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "h", host, "l", thishost, "n", host_arg, "r", options.user,
7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "p", portstr, "u", pw->pw_name, "L", shorthost,
7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (char *)NULL);
7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("expanded LocalCommand: %s", options.local_command);
7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(cp);
7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* force lowercase for hostkey matching */
7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.host_key_alias != NULL) {
7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (p = options.host_key_alias; *p; p++)
7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (isupper(*p))
7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				*p = (char)tolower(*p);
7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.proxy_command != NULL &&
7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    strcmp(options.proxy_command, "none") == 0) {
7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(options.proxy_command);
7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.proxy_command = NULL;
7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.control_path != NULL &&
7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    strcmp(options.control_path, "none") == 0) {
7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(options.control_path);
7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.control_path = NULL;
7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.control_path != NULL) {
7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = tilde_expand_filename(options.control_path,
7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    original_real_uid);
7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(options.control_path);
7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.control_path = percent_expand(cp, "h", host,
7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "l", thishost, "n", host_arg, "r", options.user,
7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "p", portstr, "u", pw->pw_name, "L", shorthost,
7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (char *)NULL);
7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(cp);
7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (muxclient_command != 0 && options.control_path == NULL)
7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("No ControlPath specified for \"-O\" command");
7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.control_path != NULL)
7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		muxclient(options.control_path);
7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	timeout_ms = options.connection_timeout * 1000;
7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Open a connection to the remote host. */
7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (ssh_connect(host, &hostaddr, options.port,
7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.address_family, options.connection_attempts, &timeout_ms,
7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.tcp_keep_alive,
7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_CYGWIN
7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.use_privileged_port,
7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    original_effective_uid == 0 && options.use_privileged_port,
8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.proxy_command) != 0)
8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		exit(255);
8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (timeout_ms > 0)
8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("timeout: %d ms remain after connect", timeout_ms);
8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If we successfully made the connection, load the host private key
8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * in case we will need it later for combined rsa-rhosts
8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * authentication. This must be done before releasing extra
8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * privileges, because the file is only readable by root.
8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If we cannot access the private keys, load the public keys
8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * instead and try to execute the ssh-keysign helper instead.
8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	sensitive_data.nkeys = 0;
8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	sensitive_data.keys = NULL;
8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	sensitive_data.external_keysign = 0;
8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.rhosts_rsa_authentication ||
8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.hostbased_authentication) {
8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.nkeys = 7;
8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys = xcalloc(sensitive_data.nkeys,
8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    sizeof(Key));
8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < sensitive_data.nkeys; i++)
8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[i] = NULL;
8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		PRIV_START;
8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_KEY_FILE, "", NULL, NULL);
8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_DSA_KEY_FILE, "", NULL);
8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_RSA_KEY_FILE, "", NULL);
8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		PRIV_END;
8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.hostbased_authentication == 1 &&
8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    sensitive_data.keys[0] == NULL &&
8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    sensitive_data.keys[4] == NULL &&
8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    sensitive_data.keys[5] == NULL &&
8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    sensitive_data.keys[6] == NULL) {
8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[1] = key_load_cert(
8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_DSA_KEY_FILE);
8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[2] = key_load_cert(
8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_ECDSA_KEY_FILE);
8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[3] = key_load_cert(
8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_RSA_KEY_FILE);
8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[4] = key_load_public(
8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_DSA_KEY_FILE, NULL);
8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[5] = key_load_public(
8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_ECDSA_KEY_FILE, NULL);
8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.keys[6] = key_load_public(
8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    _PATH_HOST_RSA_KEY_FILE, NULL);
8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			sensitive_data.external_keysign = 1;
8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Get rid of any extra privileges that we may have.  We will no
8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * longer need them.  Also, extra privileges could make it very hard
8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * to read identity files and other non-world-readable files from the
8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * user's home directory if it happens to be on a NFS volume where
8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * root is mapped to nobody.
8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (original_effective_uid == 0) {
8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		PRIV_START;
8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		permanently_set_uid(pw);
8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Now that we are back to our own permissions, create ~/.ssh
8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * directory if it doesn't already exist.
8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX
8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_selinux_setfscreatecon(buf);
8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (mkdir(buf, 0700) < 0)
8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("Could not create directory '%.200s'.", buf);
8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX
8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_selinux_setfscreatecon(NULL);
8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* load options.identity_files */
9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	load_public_identity_files();
9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Expand ~ in known host file names. */
9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	tilde_expand_paths(options.system_hostfiles,
9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.num_system_hostfiles);
9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);
9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	signal(SIGCHLD, main_sigchld_handler);
9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Log into the remote system.  Never returns if the login fails. */
9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.port, pw, timeout_ms);
9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (packet_connection_is_on_socket()) {
9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		verbose("Authenticated to %s ([%s]:%d).", host,
9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    get_remote_ipaddr(), get_remote_port());
9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		verbose("Authenticated to %s (via proxy).", host);
9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* We no longer need the private host keys.  Clear them now. */
9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (sensitive_data.nkeys != 0) {
9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < sensitive_data.nkeys; i++) {
9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (sensitive_data.keys[i] != NULL) {
9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				/* Destroys contents safely */
9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug3("clear hostkey %d", i);
9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				key_free(sensitive_data.keys[i]);
9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				sensitive_data.keys[i] = NULL;
9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(sensitive_data.keys);
9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.num_identity_files; i++) {
9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.identity_files[i]) {
9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(options.identity_files[i]);
9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.identity_files[i] = NULL;
9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.identity_keys[i]) {
9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			key_free(options.identity_keys[i]);
9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.identity_keys[i] = NULL;
9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	exit_status = compat20 ? ssh_session2() : ssh_session();
9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_close();
9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.control_path != NULL && muxserver_sock != -1)
9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		unlink(options.control_path);
9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Kill ProxyCommand if it is running. */
9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_kill_proxy_command();
9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return exit_status;
9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcontrol_persist_detach(void)
9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pid_t pid;
9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int devnull;
9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("%s: backgrounding master process", __func__);
9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	/*
9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	 * master (current process) into the background, and make the
9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	 * foreground process a client of the backgrounded master.
9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	 */
9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	switch ((pid = fork())) {
9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	case -1:
9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("%s: fork: %s", __func__, strerror(errno));
9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	case 0:
9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Child: master process continues mainloop */
9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		break;
9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	default:
9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Parent: set up mux slave to connect to backgrounded master */
9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug2("%s: background process is %ld", __func__, (long)pid);
9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		stdin_null_flag = ostdin_null_flag;
9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.request_tty = orequest_tty;
9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_flag = otty_flag;
9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		close(muxserver_sock);
9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		muxserver_sock = -1;
9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		options.control_master = SSHCTL_MASTER_NO;
9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		muxclient(options.control_path);
9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* muxclient() doesn't return on success. */
9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		fatal("Failed to connect to new control master");
9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	}
9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		error("%s: open(\"/dev/null\"): %s", __func__,
9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    strerror(errno));
9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (dup2(devnull, STDIN_FILENO) == -1 ||
9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    dup2(devnull, STDOUT_FILENO) == -1)
9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("%s: dup2: %s", __func__, strerror(errno));
9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (devnull > STDERR_FILENO)
9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			close(devnull);
9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	setproctitle("%s [mux]", options.control_path);
9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Do fork() after authentication. Used by "ssh -f" */
10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfork_postauth(void)
10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (need_controlpersist_detach)
10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		control_persist_detach();
10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("forking to background");
10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fork_after_authentication_flag = 0;
10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (daemon(1, 1) < 0)
10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("daemon() failed: %.200s", strerror(errno));
10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Callback for remote forward global requests */
10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Forward *rfwd = (Forward *)ctxt;
10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* XXX verbose() on failure? */
10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("remote forward %s for: listen %d, connect %s:%d",
10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rfwd->allocated_port = packet_get_int();
10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("Allocated port %u for remote forward to %s:%d",
10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    rfwd->allocated_port,
10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    rfwd->connect_host, rfwd->connect_port);
10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_REQUEST_FAILURE) {
10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.exit_on_forward_failure)
10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Error: remote port forwarding failed for "
10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "listen port %d", rfwd->listen_port);
10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Warning: remote port forwarding failed for "
10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "listen port %d", rfwd->listen_port);
10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (++remote_forward_confirms_received == options.num_remote_forwards) {
10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("All remote forwarding requests processed");
10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (fork_after_authentication_flag)
10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fork_postauth();
10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_cleanup_stdio_fwd(int id, void *arg)
10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("stdio forwarding: done");
10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cleanup_exit(0);
10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodclient_setup_stdio_fwd(const char *host_to_connect, u_short port_to_connect)
10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Channel *c;
10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int in, out;
10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug3("client_setup_stdio_fwd %s:%d", host_to_connect,
10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    port_to_connect);
10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	in = dup(STDIN_FILENO);
10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	out = dup(STDOUT_FILENO);
10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (in < 0 || out < 0)
10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("channel_connect_stdio_fwd: dup() in/out failed");
10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((c = channel_connect_stdio_fwd(host_to_connect, port_to_connect,
10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    in, out)) == NULL)
10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 1;
10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_init_forwarding(void)
10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int success = 0;
10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i;
10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (stdio_forward_host != NULL) {
10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!compat20) {
10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("stdio forwarding require Protocol 2");
10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!client_setup_stdio_fwd(stdio_forward_host,
10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    stdio_forward_port))
10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Failed to connect in stdio forward mode.");
10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Initiate local TCP/IP port forwardings. */
10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.num_local_forwards; i++) {
10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Local connections to %.200s:%d forwarded to remote "
10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "address %.200s:%d",
10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (options.local_forwards[i].listen_host == NULL) ?
10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (options.gateway_ports ? "*" : "LOCALHOST") :
10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].listen_host,
10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].listen_port,
10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].connect_host,
10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].connect_port);
10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		success += channel_setup_local_fwd_listener(
10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].listen_host,
10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].listen_port,
11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].connect_host,
11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.local_forwards[i].connect_port,
11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.gateway_ports);
11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (i > 0 && success != i && options.exit_on_forward_failure)
11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Could not request local forwarding.");
11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (i > 0 && success == 0)
11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		error("Could not request local forwarding.");
11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Initiate remote TCP/IP port forwardings. */
11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.num_remote_forwards; i++) {
11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Remote connections from %.200s:%d forwarded to "
11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "local address %.200s:%d",
11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (options.remote_forwards[i].listen_host == NULL) ?
11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "LOCALHOST" : options.remote_forwards[i].listen_host,
11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].listen_port,
11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].connect_host,
11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].connect_port);
11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (channel_request_remote_forwarding(
11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].listen_host,
11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].listen_port,
11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].connect_host,
11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.remote_forwards[i].connect_port) < 0) {
11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.exit_on_forward_failure)
11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Could not request remote forwarding.");
11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				logit("Warning: Could not request remote "
11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    "forwarding.");
11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		client_register_global_confirm(ssh_confirm_remote_forward,
11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &options.remote_forwards[i]);
11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Initiate tunnel forwarding. */
11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.tun_open != SSH_TUNMODE_NO) {
11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (client_request_tun_fwd(options.tun_open,
11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.tun_local, options.tun_remote) == -1) {
11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (options.exit_on_forward_failure)
11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("Could not request tunnel forwarding.");
11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				error("Could not request tunnel forwarding.");
11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_agent_present(void)
11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.forward_agent) {
11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Clear agent forwarding if we don't have an agent. */
11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!ssh_agent_present())
11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			options.forward_agent = 0;
11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_session(void)
11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type;
11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int interactive = 0;
11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int have_tty = 0;
11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct winsize ws;
11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *cp;
11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const char *display;
11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Enable compression if requested. */
11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.compression) {
11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting compression at level %d.",
11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.compression_level);
11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.compression_level < 1 ||
11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.compression_level > 9)
11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Compression level must be from 1 (fast) to "
11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "9 (slow, best).");
11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Send the request. */
11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_REQUEST_COMPRESSION);
11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int(options.compression_level);
11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS)
11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_start_compression(options.compression_level);
11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else if (type == SSH_SMSG_FAILURE)
11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Warning: Remote host refused compression.");
11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error waiting for "
11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "compression response.");
11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Allocate a pseudo tty if appropriate. */
11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (tty_flag) {
11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting pty.");
11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Start the packet. */
11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_REQUEST_PTY);
11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Store TERM in the packet.  There is no limit on the
11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		   length of the string. */
11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = getenv("TERM");
11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!cp)
12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cp = "";
12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring(cp);
12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Store window size in the packet. */
12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memset(&ws, 0, sizeof(ws));
12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int((u_int)ws.ws_row);
12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int((u_int)ws.ws_col);
12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int((u_int)ws.ws_xpixel);
12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int((u_int)ws.ws_ypixel);
12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Store tty modes in the packet. */
12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tty_make_modes(fileno(stdin), NULL);
12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Send the packet, and wait for it to leave. */
12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Read response from the server. */
12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS) {
12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			interactive = 1;
12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			have_tty = 1;
12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else if (type == SSH_SMSG_FAILURE)
12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Warning: Remote host failed or refused to "
12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "allocate a pseudo tty.");
12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error waiting for pty "
12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "request response.");
12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Request X11 forwarding if enabled and DISPLAY is set. */
12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	display = getenv("DISPLAY");
12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.forward_x11 && display != NULL) {
12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		char *proto, *data;
12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Get reasonable local authentication information. */
12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		client_x11_get_proto(display, options.xauth_location,
12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.forward_x11_trusted,
12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.forward_x11_timeout,
12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &proto, &data);
12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Request forwarding with authentication spoofing. */
12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting X11 forwarding with authentication "
12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "spoofing.");
12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		x11_request_forwarding_with_spoofing(0, display, proto,
12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    data, 0);
12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Read response from the server. */
12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type == SSH_SMSG_SUCCESS) {
12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			interactive = 1;
12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else if (type == SSH_SMSG_FAILURE) {
12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Warning: Remote host denied X11 forwarding.");
12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else {
12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("Protocol error waiting for X11 "
12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "forwarding");
12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Tell the packet module whether this is an interactive session. */
12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_set_interactive(interactive,
12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.ip_qos_interactive, options.ip_qos_bulk);
12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Request authentication agent forwarding if appropriate. */
12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	check_agent_present();
12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.forward_agent) {
12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting authentication agent forwarding.");
12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		auth_request_forwarding();
12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Read response from the server. */
12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read();
12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_check_eom();
12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_SMSG_SUCCESS)
12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Warning: Remote host denied authentication agent forwarding.");
12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Initiate port forwardings. */
12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_init_forwarding();
12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Execute a local command */
12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.local_command != NULL &&
12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.permit_local_command)
12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_local_cmd(options.local_command);
12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If requested and we are not interested in replies to remote
12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * forwarding requests, then let ssh continue in the background.
12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (fork_after_authentication_flag) {
12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.exit_on_forward_failure &&
12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.num_remote_forwards > 0) {
12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("deferring postauth fork until remote forward "
12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "confirmation received");
12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else
12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fork_postauth();
12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If a command was specified on the command line, execute the
12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * command now. Otherwise request the server to start a shell.
12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&command) > 0) {
12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		int len = buffer_len(&command);
13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len > 900)
13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			len = 900;
13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Sending command: %.*s", len,
13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (u_char *)buffer_ptr(&command));
13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_EXEC_CMD);
13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_string(buffer_ptr(&command), buffer_len(&command));
13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting shell.");
13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_CMSG_EXEC_SHELL);
13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_wait();
13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Enter the interactive session. */
13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return client_loop(have_tty, tty_flag ?
13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.escape_char : SSH_ESCAPECHAR_NONE, 0);
13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* request pty/x11/agent/tcpfwd/shell for channel */
13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_session2_setup(int id, int success, void *arg)
13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	extern char **environ;
13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	const char *display;
13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int interactive = tty_flag;
13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!success)
13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return; /* No need for error message, channels code sens one */
13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	display = getenv("DISPLAY");
13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.forward_x11 && display != NULL) {
13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		char *proto, *data;
13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Get reasonable local authentication information. */
13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		client_x11_get_proto(display, options.xauth_location,
13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.forward_x11_trusted,
13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.forward_x11_timeout, &proto, &data);
13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Request forwarding with authentication spoofing. */
13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting X11 forwarding with authentication "
13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "spoofing.");
13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		x11_request_forwarding_with_spoofing(id, display, proto,
13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    data, 1);
13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* XXX exit_on_forward_failure */
13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		interactive = 1;
13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	check_agent_present();
13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.forward_agent) {
13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting authentication agent forwarding.");
13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		channel_request_start(id, "auth-agent-req@openssh.com", 0);
13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    NULL, fileno(stdin), &command, environ);
13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* open new channel for a session */
13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_session2_open(void)
13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Channel *c;
13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int window, packetmax, in, out, err;
13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (stdin_null_flag) {
13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		in = open(_PATH_DEVNULL, O_RDONLY);
13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		in = dup(STDIN_FILENO);
13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	out = dup(STDOUT_FILENO);
13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	err = dup(STDERR_FILENO);
13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (in < 0 || out < 0 || err < 0)
13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("dup() in/out/err failed");
13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* enable nonblocking unless tty */
13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!isatty(in))
13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_nonblock(in);
13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!isatty(out))
13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_nonblock(out);
13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!isatty(err))
13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_nonblock(err);
13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	window = CHAN_SES_WINDOW_DEFAULT;
13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packetmax = CHAN_SES_PACKET_DEFAULT;
13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (tty_flag) {
13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		window >>= 1;
13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packetmax >>= 1;
13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	c = channel_new(
13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    "session", SSH_CHANNEL_OPENING, in, out, err,
13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    window, packetmax, CHAN_EXTENDED_WRITE,
13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    "client-session", /*nonblock*/0);
13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug3("ssh_session2_open: channel_new: %d", c->self);
13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	channel_send_open(c->self);
13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!no_shell_flag)
14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		channel_register_open_confirm(c->self,
14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    ssh_session2_setup, NULL);
14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return c->self;
14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_session2(void)
14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int id = -1;
14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* XXX should be pre-session */
14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_init_forwarding();
14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Start listening for multiplex clients */
14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	muxserver_listen();
14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	/*
14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If we are in control persist mode, then prepare to background
14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * ourselves and have a foreground client attach as a control
14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * slave. NB. we must save copies of the flags that we override for
14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * the backgrounding, since we defer attachment of the slave until
14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * after the connection is fully established (in particular,
14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * async rfwd replies have been received for ExitOnForwardFailure).
14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	if (options.control_persist && muxserver_sock != -1) {
14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ostdin_null_flag = stdin_null_flag;
14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ono_shell_flag = no_shell_flag;
14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		orequest_tty = options.request_tty;
14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		otty_flag = tty_flag;
14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		stdin_null_flag = 1;
14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		no_shell_flag = 1;
14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 		tty_flag = 0;
14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!fork_after_authentication_flag)
14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			need_controlpersist_detach = 1;
14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fork_after_authentication_flag = 1;
14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 	}
14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		id = ssh_session2_open();
14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* If we don't expect to open a new session, then disallow it */
14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.control_master == SSHCTL_MASTER_NO &&
14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (datafellows & SSH_NEW_OPENSSH)) {
14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("Requesting no-more-sessions@openssh.com");
14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH2_MSG_GLOBAL_REQUEST);
14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring("no-more-sessions@openssh.com");
14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_char(0);
14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send();
14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Execute a local command */
14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.local_command != NULL &&
14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.permit_local_command)
14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		ssh_local_cmd(options.local_command);
14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If requested and we are not interested in replies to remote
14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * forwarding requests, then let ssh continue in the background.
14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (fork_after_authentication_flag) {
14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.exit_on_forward_failure &&
14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    options.num_remote_forwards > 0) {
14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("deferring postauth fork until remote forward "
14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "confirmation received");
14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else
14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fork_postauth();
14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.use_roaming)
14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		request_roaming();
14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return client_loop(tty_flag, tty_flag ?
14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.escape_char : SSH_ESCAPECHAR_NONE, id);
14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodload_public_identity_files(void)
14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *filename, *cp, thishost[NI_MAXHOST];
14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *pwdir = NULL, *pwname = NULL;
14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i = 0;
14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key *public;
14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct passwd *pw;
14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int n_ids;
14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *identity_files[SSH_MAX_IDENTITY_FILES];
14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key *identity_keys[SSH_MAX_IDENTITY_FILES];
14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11
14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Key **keys;
14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int nkeys;
14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* PKCS11 */
14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	n_ids = 0;
14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bzero(identity_files, sizeof(identity_files));
14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bzero(identity_keys, sizeof(identity_keys));
14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef ENABLE_PKCS11
14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.pkcs11_provider != NULL &&
14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
14991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (pkcs11_init(!options.batch_mode) == 0) &&
15001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,
15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &keys)) > 0) {
15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < nkeys; i++) {
15031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (n_ids >= SSH_MAX_IDENTITY_FILES) {
15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				key_free(keys[i]);
15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				continue;
15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			identity_keys[n_ids] = keys[i];
15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			identity_files[n_ids] =
15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    xstrdup(options.pkcs11_provider); /* XXX */
15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			n_ids++;
15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(keys);
15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* ENABLE_PKCS11 */
15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((pw = getpwuid(original_real_uid)) == NULL)
15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("load_public_identity_files: getpwuid failed");
15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pwname = xstrdup(pw->pw_name);
15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pwdir = xstrdup(pw->pw_dir);
15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (gethostname(thishost, sizeof(thishost)) == -1)
15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("load_public_identity_files: gethostname: %s",
15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    strerror(errno));
15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < options.num_identity_files; i++) {
15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (n_ids >= SSH_MAX_IDENTITY_FILES) {
15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(options.identity_files[i]);
15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = tilde_expand_filename(options.identity_files[i],
15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    original_real_uid);
15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		filename = percent_expand(cp, "d", pwdir,
15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "u", pwname, "l", thishost, "h", host,
15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "r", options.user, (char *)NULL);
15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(cp);
15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		public = key_load_public(filename, NULL);
15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("identity file %s type %d", filename,
15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    public ? public->type : -1);
15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(options.identity_files[i]);
15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		identity_files[n_ids] = filename;
15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		identity_keys[n_ids] = public;
15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (++n_ids >= SSH_MAX_IDENTITY_FILES)
15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Try to add the certificate variant too */
15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xasprintf(&cp, "%s-cert", filename);
15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		public = key_load_public(cp, NULL);
15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("identity file %s type %d", cp,
15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    public ? public->type : -1);
15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (public == NULL) {
15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(cp);
15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!key_is_cert(public)) {
15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("%s: key %s type %s is not a certificate",
15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    __func__, cp, key_type(public));
15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			key_free(public);
15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(cp);
15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		identity_keys[n_ids] = public;
15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* point to the original path, most likely the private key */
15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		identity_files[n_ids] = xstrdup(filename);
15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		n_ids++;
15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	options.num_identity_files = n_ids;
15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memcpy(options.identity_files, identity_files, sizeof(identity_files));
15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memcpy(options.identity_keys, identity_keys, sizeof(identity_keys));
15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bzero(pwname, strlen(pwname));
15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(pwname);
15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	bzero(pwdir, strlen(pwdir));
15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(pwdir);
15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmain_sigchld_handler(int sig)
15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int save_errno = errno;
15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	pid_t pid;
15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int status;
15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (pid < 0 && errno == EINTR))
15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		;
15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	signal(sig, main_sigchld_handler);
15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	errno = save_errno;
15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1589