1  | 
     | 
     | 
    /* $OpenBSD: readconf.c,v 1.280 2017/10/21 23:06:24 millert Exp $ */  | 
    
    
    2  | 
     | 
     | 
    /*  | 
    
    
    3  | 
     | 
     | 
     * Author: Tatu Ylonen <ylo@cs.hut.fi>  | 
    
    
    4  | 
     | 
     | 
     * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland  | 
    
    
    5  | 
     | 
     | 
     *                    All rights reserved  | 
    
    
    6  | 
     | 
     | 
     * Functions for reading the configuration files.  | 
    
    
    7  | 
     | 
     | 
     *  | 
    
    
    8  | 
     | 
     | 
     * As far as I am concerned, the code I have written for this software  | 
    
    
    9  | 
     | 
     | 
     * can be used freely for any purpose.  Any derived versions of this  | 
    
    
    10  | 
     | 
     | 
     * software must be clearly marked as such, and if the derived work is  | 
    
    
    11  | 
     | 
     | 
     * incompatible with the protocol description in the RFC file, it must be  | 
    
    
    12  | 
     | 
     | 
     * called by a name other than "ssh" or "Secure Shell".  | 
    
    
    13  | 
     | 
     | 
     */  | 
    
    
    14  | 
     | 
     | 
     | 
    
    
    15  | 
     | 
     | 
    #include <sys/types.h>  | 
    
    
    16  | 
     | 
     | 
    #include <sys/stat.h>  | 
    
    
    17  | 
     | 
     | 
    #include <sys/socket.h>  | 
    
    
    18  | 
     | 
     | 
    #include <sys/wait.h>  | 
    
    
    19  | 
     | 
     | 
    #include <sys/un.h>  | 
    
    
    20  | 
     | 
     | 
     | 
    
    
    21  | 
     | 
     | 
    #include <netinet/in.h>  | 
    
    
    22  | 
     | 
     | 
    #include <netinet/ip.h>  | 
    
    
    23  | 
     | 
     | 
     | 
    
    
    24  | 
     | 
     | 
    #include <ctype.h>  | 
    
    
    25  | 
     | 
     | 
    #include <errno.h>  | 
    
    
    26  | 
     | 
     | 
    #include <fcntl.h>  | 
    
    
    27  | 
     | 
     | 
    #include <glob.h>  | 
    
    
    28  | 
     | 
     | 
    #include <netdb.h>  | 
    
    
    29  | 
     | 
     | 
    #include <paths.h>  | 
    
    
    30  | 
     | 
     | 
    #include <pwd.h>  | 
    
    
    31  | 
     | 
     | 
    #include <signal.h>  | 
    
    
    32  | 
     | 
     | 
    #include <stdio.h>  | 
    
    
    33  | 
     | 
     | 
    #include <string.h>  | 
    
    
    34  | 
     | 
     | 
    #include <unistd.h>  | 
    
    
    35  | 
     | 
     | 
    #include <limits.h>  | 
    
    
    36  | 
     | 
     | 
    #include <util.h>  | 
    
    
    37  | 
     | 
     | 
    #include <vis.h>  | 
    
    
    38  | 
     | 
     | 
     | 
    
    
    39  | 
     | 
     | 
    #include "xmalloc.h"  | 
    
    
    40  | 
     | 
     | 
    #include "ssh.h"  | 
    
    
    41  | 
     | 
     | 
    #include "compat.h"  | 
    
    
    42  | 
     | 
     | 
    #include "cipher.h"  | 
    
    
    43  | 
     | 
     | 
    #include "pathnames.h"  | 
    
    
    44  | 
     | 
     | 
    #include "log.h"  | 
    
    
    45  | 
     | 
     | 
    #include "sshkey.h"  | 
    
    
    46  | 
     | 
     | 
    #include "misc.h"  | 
    
    
    47  | 
     | 
     | 
    #include "readconf.h"  | 
    
    
    48  | 
     | 
     | 
    #include "match.h"  | 
    
    
    49  | 
     | 
     | 
    #include "kex.h"  | 
    
    
    50  | 
     | 
     | 
    #include "mac.h"  | 
    
    
    51  | 
     | 
     | 
    #include "uidswap.h"  | 
    
    
    52  | 
     | 
     | 
    #include "myproposal.h"  | 
    
    
    53  | 
     | 
     | 
    #include "digest.h"  | 
    
    
    54  | 
     | 
     | 
     | 
    
    
    55  | 
     | 
     | 
    /* Format of the configuration file:  | 
    
    
    56  | 
     | 
     | 
     | 
    
    
    57  | 
     | 
     | 
       # Configuration data is parsed as follows:  | 
    
    
    58  | 
     | 
     | 
       #  1. command line options  | 
    
    
    59  | 
     | 
     | 
       #  2. user-specific file  | 
    
    
    60  | 
     | 
     | 
       #  3. system-wide file  | 
    
    
    61  | 
     | 
     | 
       # Any configuration value is only changed the first time it is set.  | 
    
    
    62  | 
     | 
     | 
       # Thus, host-specific definitions should be at the beginning of the  | 
    
    
    63  | 
     | 
     | 
       # configuration file, and defaults at the end.  | 
    
    
    64  | 
     | 
     | 
     | 
    
    
    65  | 
     | 
     | 
       # Host-specific declarations.  These may override anything above.  A single  | 
    
    
    66  | 
     | 
     | 
       # host may match multiple declarations; these are processed in the order  | 
    
    
    67  | 
     | 
     | 
       # that they are given in.  | 
    
    
    68  | 
     | 
     | 
     | 
    
    
    69  | 
     | 
     | 
       Host *.ngs.fi ngs.fi  | 
    
    
    70  | 
     | 
     | 
         User foo  | 
    
    
    71  | 
     | 
     | 
     | 
    
    
    72  | 
     | 
     | 
       Host fake.com  | 
    
    
    73  | 
     | 
     | 
         HostName another.host.name.real.org  | 
    
    
    74  | 
     | 
     | 
         User blaah  | 
    
    
    75  | 
     | 
     | 
         Port 34289  | 
    
    
    76  | 
     | 
     | 
         ForwardX11 no  | 
    
    
    77  | 
     | 
     | 
         ForwardAgent no  | 
    
    
    78  | 
     | 
     | 
     | 
    
    
    79  | 
     | 
     | 
       Host books.com  | 
    
    
    80  | 
     | 
     | 
         RemoteForward 9999 shadows.cs.hut.fi:9999  | 
    
    
    81  | 
     | 
     | 
         Ciphers 3des-cbc  | 
    
    
    82  | 
     | 
     | 
     | 
    
    
    83  | 
     | 
     | 
       Host fascist.blob.com  | 
    
    
    84  | 
     | 
     | 
         Port 23123  | 
    
    
    85  | 
     | 
     | 
         User tylonen  | 
    
    
    86  | 
     | 
     | 
         PasswordAuthentication no  | 
    
    
    87  | 
     | 
     | 
     | 
    
    
    88  | 
     | 
     | 
       Host puukko.hut.fi  | 
    
    
    89  | 
     | 
     | 
         User t35124p  | 
    
    
    90  | 
     | 
     | 
         ProxyCommand ssh-proxy %h %p  | 
    
    
    91  | 
     | 
     | 
     | 
    
    
    92  | 
     | 
     | 
       Host *.fr  | 
    
    
    93  | 
     | 
     | 
         PublicKeyAuthentication no  | 
    
    
    94  | 
     | 
     | 
     | 
    
    
    95  | 
     | 
     | 
       Host *.su  | 
    
    
    96  | 
     | 
     | 
         Ciphers aes128-ctr  | 
    
    
    97  | 
     | 
     | 
         PasswordAuthentication no  | 
    
    
    98  | 
     | 
     | 
     | 
    
    
    99  | 
     | 
     | 
       Host vpn.fake.com  | 
    
    
    100  | 
     | 
     | 
         Tunnel yes  | 
    
    
    101  | 
     | 
     | 
         TunnelDevice 3  | 
    
    
    102  | 
     | 
     | 
     | 
    
    
    103  | 
     | 
     | 
       # Defaults for various options  | 
    
    
    104  | 
     | 
     | 
       Host *  | 
    
    
    105  | 
     | 
     | 
         ForwardAgent no  | 
    
    
    106  | 
     | 
     | 
         ForwardX11 no  | 
    
    
    107  | 
     | 
     | 
         PasswordAuthentication yes  | 
    
    
    108  | 
     | 
     | 
         RSAAuthentication yes  | 
    
    
    109  | 
     | 
     | 
         RhostsRSAAuthentication yes  | 
    
    
    110  | 
     | 
     | 
         StrictHostKeyChecking yes  | 
    
    
    111  | 
     | 
     | 
         TcpKeepAlive no  | 
    
    
    112  | 
     | 
     | 
         IdentityFile ~/.ssh/identity  | 
    
    
    113  | 
     | 
     | 
         Port 22  | 
    
    
    114  | 
     | 
     | 
         EscapeChar ~  | 
    
    
    115  | 
     | 
     | 
     | 
    
    
    116  | 
     | 
     | 
    */  | 
    
    
    117  | 
     | 
     | 
     | 
    
    
    118  | 
     | 
     | 
    static int read_config_file_depth(const char *filename, struct passwd *pw,  | 
    
    
    119  | 
     | 
     | 
        const char *host, const char *original_host, Options *options,  | 
    
    
    120  | 
     | 
     | 
        int flags, int *activep, int depth);  | 
    
    
    121  | 
     | 
     | 
    static int process_config_line_depth(Options *options, struct passwd *pw,  | 
    
    
    122  | 
     | 
     | 
        const char *host, const char *original_host, char *line,  | 
    
    
    123  | 
     | 
     | 
        const char *filename, int linenum, int *activep, int flags, int depth);  | 
    
    
    124  | 
     | 
     | 
     | 
    
    
    125  | 
     | 
     | 
    /* Keyword tokens. */  | 
    
    
    126  | 
     | 
     | 
     | 
    
    
    127  | 
     | 
     | 
    typedef enum { | 
    
    
    128  | 
     | 
     | 
    	oBadOption,  | 
    
    
    129  | 
     | 
     | 
    	oHost, oMatch, oInclude,  | 
    
    
    130  | 
     | 
     | 
    	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,  | 
    
    
    131  | 
     | 
     | 
    	oGatewayPorts, oExitOnForwardFailure,  | 
    
    
    132  | 
     | 
     | 
    	oPasswordAuthentication, oRSAAuthentication,  | 
    
    
    133  | 
     | 
     | 
    	oChallengeResponseAuthentication, oXAuthLocation,  | 
    
    
    134  | 
     | 
     | 
    	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,  | 
    
    
    135  | 
     | 
     | 
    	oCertificateFile, oAddKeysToAgent, oIdentityAgent,  | 
    
    
    136  | 
     | 
     | 
    	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,  | 
    
    
    137  | 
     | 
     | 
    	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,  | 
    
    
    138  | 
     | 
     | 
    	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,  | 
    
    
    139  | 
     | 
     | 
    	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,  | 
    
    
    140  | 
     | 
     | 
    	oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,  | 
    
    
    141  | 
     | 
     | 
    	oPubkeyAuthentication,  | 
    
    
    142  | 
     | 
     | 
    	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,  | 
    
    
    143  | 
     | 
     | 
    	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,  | 
    
    
    144  | 
     | 
     | 
    	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,  | 
    
    
    145  | 
     | 
     | 
    	oClearAllForwardings, oNoHostAuthenticationForLocalhost,  | 
    
    
    146  | 
     | 
     | 
    	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,  | 
    
    
    147  | 
     | 
     | 
    	oAddressFamily, oGssAuthentication, oGssDelegateCreds,  | 
    
    
    148  | 
     | 
     | 
    	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,  | 
    
    
    149  | 
     | 
     | 
    	oSendEnv, oControlPath, oControlMaster, oControlPersist,  | 
    
    
    150  | 
     | 
     | 
    	oHashKnownHosts,  | 
    
    
    151  | 
     | 
     | 
    	oTunnel, oTunnelDevice,  | 
    
    
    152  | 
     | 
     | 
    	oLocalCommand, oPermitLocalCommand, oRemoteCommand,  | 
    
    
    153  | 
     | 
     | 
    	oVisualHostKey,  | 
    
    
    154  | 
     | 
     | 
    	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,  | 
    
    
    155  | 
     | 
     | 
    	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,  | 
    
    
    156  | 
     | 
     | 
    	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,  | 
    
    
    157  | 
     | 
     | 
    	oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,  | 
    
    
    158  | 
     | 
     | 
    	oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,  | 
    
    
    159  | 
     | 
     | 
    	oPubkeyAcceptedKeyTypes, oProxyJump,  | 
    
    
    160  | 
     | 
     | 
    	oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported  | 
    
    
    161  | 
     | 
     | 
    } OpCodes;  | 
    
    
    162  | 
     | 
     | 
     | 
    
    
    163  | 
     | 
     | 
    /* Textual representations of the tokens. */  | 
    
    
    164  | 
     | 
     | 
     | 
    
    
    165  | 
     | 
     | 
    static struct { | 
    
    
    166  | 
     | 
     | 
    	const char *name;  | 
    
    
    167  | 
     | 
     | 
    	OpCodes opcode;  | 
    
    
    168  | 
     | 
     | 
    } keywords[] = { | 
    
    
    169  | 
     | 
     | 
    	/* Deprecated options */  | 
    
    
    170  | 
     | 
     | 
    	{ "protocol", oIgnore }, /* NB. silently ignored */ | 
    
    
    171  | 
     | 
     | 
    	{ "cipher", oDeprecated }, | 
    
    
    172  | 
     | 
     | 
    	{ "fallbacktorsh", oDeprecated }, | 
    
    
    173  | 
     | 
     | 
    	{ "globalknownhostsfile2", oDeprecated }, | 
    
    
    174  | 
     | 
     | 
    	{ "rhostsauthentication", oDeprecated }, | 
    
    
    175  | 
     | 
     | 
    	{ "userknownhostsfile2", oDeprecated }, | 
    
    
    176  | 
     | 
     | 
    	{ "useroaming", oDeprecated }, | 
    
    
    177  | 
     | 
     | 
    	{ "usersh", oDeprecated }, | 
    
    
    178  | 
     | 
     | 
     | 
    
    
    179  | 
     | 
     | 
    	/* Unsupported options */  | 
    
    
    180  | 
     | 
     | 
    	{ "afstokenpassing", oUnsupported }, | 
    
    
    181  | 
     | 
     | 
    	{ "kerberosauthentication", oUnsupported }, | 
    
    
    182  | 
     | 
     | 
    	{ "kerberostgtpassing", oUnsupported }, | 
    
    
    183  | 
     | 
     | 
     | 
    
    
    184  | 
     | 
     | 
    	/* Sometimes-unsupported options */  | 
    
    
    185  | 
     | 
     | 
    #if defined(GSSAPI)  | 
    
    
    186  | 
     | 
     | 
    	{ "gssapiauthentication", oGssAuthentication }, | 
    
    
    187  | 
     | 
     | 
    	{ "gssapidelegatecredentials", oGssDelegateCreds }, | 
    
    
    188  | 
     | 
     | 
    # else  | 
    
    
    189  | 
     | 
     | 
    	{ "gssapiauthentication", oUnsupported }, | 
    
    
    190  | 
     | 
     | 
    	{ "gssapidelegatecredentials", oUnsupported }, | 
    
    
    191  | 
     | 
     | 
    #endif  | 
    
    
    192  | 
     | 
     | 
    #ifdef ENABLE_PKCS11  | 
    
    
    193  | 
     | 
     | 
    	{ "smartcarddevice", oPKCS11Provider }, | 
    
    
    194  | 
     | 
     | 
    	{ "pkcs11provider", oPKCS11Provider }, | 
    
    
    195  | 
     | 
     | 
    # else  | 
    
    
    196  | 
     | 
     | 
    	{ "smartcarddevice", oUnsupported }, | 
    
    
    197  | 
     | 
     | 
    	{ "pkcs11provider", oUnsupported }, | 
    
    
    198  | 
     | 
     | 
    #endif  | 
    
    
    199  | 
     | 
     | 
    	{ "rsaauthentication", oUnsupported }, | 
    
    
    200  | 
     | 
     | 
    	{ "rhostsrsaauthentication", oUnsupported }, | 
    
    
    201  | 
     | 
     | 
    	{ "compressionlevel", oUnsupported }, | 
    
    
    202  | 
     | 
     | 
     | 
    
    
    203  | 
     | 
     | 
    	{ "forwardagent", oForwardAgent }, | 
    
    
    204  | 
     | 
     | 
    	{ "forwardx11", oForwardX11 }, | 
    
    
    205  | 
     | 
     | 
    	{ "forwardx11trusted", oForwardX11Trusted }, | 
    
    
    206  | 
     | 
     | 
    	{ "forwardx11timeout", oForwardX11Timeout }, | 
    
    
    207  | 
     | 
     | 
    	{ "exitonforwardfailure", oExitOnForwardFailure }, | 
    
    
    208  | 
     | 
     | 
    	{ "xauthlocation", oXAuthLocation }, | 
    
    
    209  | 
     | 
     | 
    	{ "gatewayports", oGatewayPorts }, | 
    
    
    210  | 
     | 
     | 
    	{ "useprivilegedport", oUsePrivilegedPort }, | 
    
    
    211  | 
     | 
     | 
    	{ "passwordauthentication", oPasswordAuthentication }, | 
    
    
    212  | 
     | 
     | 
    	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, | 
    
    
    213  | 
     | 
     | 
    	{ "kbdinteractivedevices", oKbdInteractiveDevices }, | 
    
    
    214  | 
     | 
     | 
    	{ "pubkeyauthentication", oPubkeyAuthentication }, | 
    
    
    215  | 
     | 
     | 
    	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */ | 
    
    
    216  | 
     | 
     | 
    	{ "hostbasedauthentication", oHostbasedAuthentication }, | 
    
    
    217  | 
     | 
     | 
    	{ "challengeresponseauthentication", oChallengeResponseAuthentication }, | 
    
    
    218  | 
     | 
     | 
    	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ | 
    
    
    219  | 
     | 
     | 
    	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */ | 
    
    
    220  | 
     | 
     | 
    	{ "identityfile", oIdentityFile }, | 
    
    
    221  | 
     | 
     | 
    	{ "identityfile2", oIdentityFile },			/* obsolete */ | 
    
    
    222  | 
     | 
     | 
    	{ "identitiesonly", oIdentitiesOnly }, | 
    
    
    223  | 
     | 
     | 
    	{ "certificatefile", oCertificateFile }, | 
    
    
    224  | 
     | 
     | 
    	{ "addkeystoagent", oAddKeysToAgent }, | 
    
    
    225  | 
     | 
     | 
    	{ "identityagent", oIdentityAgent }, | 
    
    
    226  | 
     | 
     | 
    	{ "hostname", oHostName }, | 
    
    
    227  | 
     | 
     | 
    	{ "hostkeyalias", oHostKeyAlias }, | 
    
    
    228  | 
     | 
     | 
    	{ "proxycommand", oProxyCommand }, | 
    
    
    229  | 
     | 
     | 
    	{ "port", oPort }, | 
    
    
    230  | 
     | 
     | 
    	{ "ciphers", oCiphers }, | 
    
    
    231  | 
     | 
     | 
    	{ "macs", oMacs }, | 
    
    
    232  | 
     | 
     | 
    	{ "remoteforward", oRemoteForward }, | 
    
    
    233  | 
     | 
     | 
    	{ "localforward", oLocalForward }, | 
    
    
    234  | 
     | 
     | 
    	{ "user", oUser }, | 
    
    
    235  | 
     | 
     | 
    	{ "host", oHost }, | 
    
    
    236  | 
     | 
     | 
    	{ "match", oMatch }, | 
    
    
    237  | 
     | 
     | 
    	{ "escapechar", oEscapeChar }, | 
    
    
    238  | 
     | 
     | 
    	{ "globalknownhostsfile", oGlobalKnownHostsFile }, | 
    
    
    239  | 
     | 
     | 
    	{ "userknownhostsfile", oUserKnownHostsFile }, | 
    
    
    240  | 
     | 
     | 
    	{ "connectionattempts", oConnectionAttempts }, | 
    
    
    241  | 
     | 
     | 
    	{ "batchmode", oBatchMode }, | 
    
    
    242  | 
     | 
     | 
    	{ "checkhostip", oCheckHostIP }, | 
    
    
    243  | 
     | 
     | 
    	{ "stricthostkeychecking", oStrictHostKeyChecking }, | 
    
    
    244  | 
     | 
     | 
    	{ "compression", oCompression }, | 
    
    
    245  | 
     | 
     | 
    	{ "tcpkeepalive", oTCPKeepAlive }, | 
    
    
    246  | 
     | 
     | 
    	{ "keepalive", oTCPKeepAlive },				/* obsolete */ | 
    
    
    247  | 
     | 
     | 
    	{ "numberofpasswordprompts", oNumberOfPasswordPrompts }, | 
    
    
    248  | 
     | 
     | 
    	{ "syslogfacility", oLogFacility }, | 
    
    
    249  | 
     | 
     | 
    	{ "loglevel", oLogLevel }, | 
    
    
    250  | 
     | 
     | 
    	{ "dynamicforward", oDynamicForward }, | 
    
    
    251  | 
     | 
     | 
    	{ "preferredauthentications", oPreferredAuthentications }, | 
    
    
    252  | 
     | 
     | 
    	{ "hostkeyalgorithms", oHostKeyAlgorithms }, | 
    
    
    253  | 
     | 
     | 
    	{ "bindaddress", oBindAddress }, | 
    
    
    254  | 
     | 
     | 
    	{ "clearallforwardings", oClearAllForwardings }, | 
    
    
    255  | 
     | 
     | 
    	{ "enablesshkeysign", oEnableSSHKeysign }, | 
    
    
    256  | 
     | 
     | 
    	{ "verifyhostkeydns", oVerifyHostKeyDNS }, | 
    
    
    257  | 
     | 
     | 
    	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, | 
    
    
    258  | 
     | 
     | 
    	{ "rekeylimit", oRekeyLimit }, | 
    
    
    259  | 
     | 
     | 
    	{ "connecttimeout", oConnectTimeout }, | 
    
    
    260  | 
     | 
     | 
    	{ "addressfamily", oAddressFamily }, | 
    
    
    261  | 
     | 
     | 
    	{ "serveraliveinterval", oServerAliveInterval }, | 
    
    
    262  | 
     | 
     | 
    	{ "serveralivecountmax", oServerAliveCountMax }, | 
    
    
    263  | 
     | 
     | 
    	{ "sendenv", oSendEnv }, | 
    
    
    264  | 
     | 
     | 
    	{ "controlpath", oControlPath }, | 
    
    
    265  | 
     | 
     | 
    	{ "controlmaster", oControlMaster }, | 
    
    
    266  | 
     | 
     | 
    	{ "controlpersist", oControlPersist }, | 
    
    
    267  | 
     | 
     | 
    	{ "hashknownhosts", oHashKnownHosts }, | 
    
    
    268  | 
     | 
     | 
    	{ "include", oInclude }, | 
    
    
    269  | 
     | 
     | 
    	{ "tunnel", oTunnel }, | 
    
    
    270  | 
     | 
     | 
    	{ "tunneldevice", oTunnelDevice }, | 
    
    
    271  | 
     | 
     | 
    	{ "localcommand", oLocalCommand }, | 
    
    
    272  | 
     | 
     | 
    	{ "permitlocalcommand", oPermitLocalCommand }, | 
    
    
    273  | 
     | 
     | 
    	{ "remotecommand", oRemoteCommand }, | 
    
    
    274  | 
     | 
     | 
    	{ "visualhostkey", oVisualHostKey }, | 
    
    
    275  | 
     | 
     | 
    	{ "kexalgorithms", oKexAlgorithms }, | 
    
    
    276  | 
     | 
     | 
    	{ "ipqos", oIPQoS }, | 
    
    
    277  | 
     | 
     | 
    	{ "requesttty", oRequestTTY }, | 
    
    
    278  | 
     | 
     | 
    	{ "proxyusefdpass", oProxyUseFdpass }, | 
    
    
    279  | 
     | 
     | 
    	{ "canonicaldomains", oCanonicalDomains }, | 
    
    
    280  | 
     | 
     | 
    	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal }, | 
    
    
    281  | 
     | 
     | 
    	{ "canonicalizehostname", oCanonicalizeHostname }, | 
    
    
    282  | 
     | 
     | 
    	{ "canonicalizemaxdots", oCanonicalizeMaxDots }, | 
    
    
    283  | 
     | 
     | 
    	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, | 
    
    
    284  | 
     | 
     | 
    	{ "streamlocalbindmask", oStreamLocalBindMask }, | 
    
    
    285  | 
     | 
     | 
    	{ "streamlocalbindunlink", oStreamLocalBindUnlink }, | 
    
    
    286  | 
     | 
     | 
    	{ "revokedhostkeys", oRevokedHostKeys }, | 
    
    
    287  | 
     | 
     | 
    	{ "fingerprinthash", oFingerprintHash }, | 
    
    
    288  | 
     | 
     | 
    	{ "updatehostkeys", oUpdateHostkeys }, | 
    
    
    289  | 
     | 
     | 
    	{ "hostbasedkeytypes", oHostbasedKeyTypes }, | 
    
    
    290  | 
     | 
     | 
    	{ "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, | 
    
    
    291  | 
     | 
     | 
    	{ "ignoreunknown", oIgnoreUnknown }, | 
    
    
    292  | 
     | 
     | 
    	{ "proxyjump", oProxyJump }, | 
    
    
    293  | 
     | 
     | 
     | 
    
    
    294  | 
     | 
     | 
    	{ NULL, oBadOption } | 
    
    
    295  | 
     | 
     | 
    };  | 
    
    
    296  | 
     | 
     | 
     | 
    
    
    297  | 
     | 
     | 
    /*  | 
    
    
    298  | 
     | 
     | 
     * Adds a local TCP/IP port forward to options.  Never returns if there is an  | 
    
    
    299  | 
     | 
     | 
     * error.  | 
    
    
    300  | 
     | 
     | 
     */  | 
    
    
    301  | 
     | 
     | 
     | 
    
    
    302  | 
     | 
     | 
    void  | 
    
    
    303  | 
     | 
     | 
    add_local_forward(Options *options, const struct Forward *newfwd)  | 
    
    
    304  | 
     | 
     | 
    { | 
    
    
    305  | 
     | 
     | 
    	struct Forward *fwd;  | 
    
    
    306  | 
     | 
     | 
    	extern uid_t original_real_uid;  | 
    
    
    307  | 
     | 
     | 
    	int i;  | 
    
    
    308  | 
     | 
     | 
     | 
    
    
    309  | 
     | 
     | 
    	if (!bind_permitted(newfwd->listen_port, original_real_uid) &&  | 
    
    
    310  | 
     | 
     | 
    	    newfwd->listen_path == NULL)  | 
    
    
    311  | 
     | 
     | 
    		fatal("Privileged ports can only be forwarded by root."); | 
    
    
    312  | 
     | 
     | 
    	/* Don't add duplicates */  | 
    
    
    313  | 
     | 
     | 
    	for (i = 0; i < options->num_local_forwards; i++) { | 
    
    
    314  | 
     | 
     | 
    		if (forward_equals(newfwd, options->local_forwards + i))  | 
    
    
    315  | 
     | 
     | 
    			return;  | 
    
    
    316  | 
     | 
     | 
    	}  | 
    
    
    317  | 
     | 
     | 
    	options->local_forwards = xreallocarray(options->local_forwards,  | 
    
    
    318  | 
     | 
     | 
    	    options->num_local_forwards + 1,  | 
    
    
    319  | 
     | 
     | 
    	    sizeof(*options->local_forwards));  | 
    
    
    320  | 
     | 
     | 
    	fwd = &options->local_forwards[options->num_local_forwards++];  | 
    
    
    321  | 
     | 
     | 
     | 
    
    
    322  | 
     | 
     | 
    	fwd->listen_host = newfwd->listen_host;  | 
    
    
    323  | 
     | 
     | 
    	fwd->listen_port = newfwd->listen_port;  | 
    
    
    324  | 
     | 
     | 
    	fwd->listen_path = newfwd->listen_path;  | 
    
    
    325  | 
     | 
     | 
    	fwd->connect_host = newfwd->connect_host;  | 
    
    
    326  | 
     | 
     | 
    	fwd->connect_port = newfwd->connect_port;  | 
    
    
    327  | 
     | 
     | 
    	fwd->connect_path = newfwd->connect_path;  | 
    
    
    328  | 
     | 
     | 
    }  | 
    
    
    329  | 
     | 
     | 
     | 
    
    
    330  | 
     | 
     | 
    /*  | 
    
    
    331  | 
     | 
     | 
     * Adds a remote TCP/IP port forward to options.  Never returns if there is  | 
    
    
    332  | 
     | 
     | 
     * an error.  | 
    
    
    333  | 
     | 
     | 
     */  | 
    
    
    334  | 
     | 
     | 
     | 
    
    
    335  | 
     | 
     | 
    void  | 
    
    
    336  | 
     | 
     | 
    add_remote_forward(Options *options, const struct Forward *newfwd)  | 
    
    
    337  | 
     | 
     | 
    { | 
    
    
    338  | 
     | 
     | 
    	struct Forward *fwd;  | 
    
    
    339  | 
     | 
     | 
    	int i;  | 
    
    
    340  | 
     | 
     | 
     | 
    
    
    341  | 
     | 
     | 
    	/* Don't add duplicates */  | 
    
    
    342  | 
     | 
     | 
    	for (i = 0; i < options->num_remote_forwards; i++) { | 
    
    
    343  | 
     | 
     | 
    		if (forward_equals(newfwd, options->remote_forwards + i))  | 
    
    
    344  | 
     | 
     | 
    			return;  | 
    
    
    345  | 
     | 
     | 
    	}  | 
    
    
    346  | 
     | 
     | 
    	options->remote_forwards = xreallocarray(options->remote_forwards,  | 
    
    
    347  | 
     | 
     | 
    	    options->num_remote_forwards + 1,  | 
    
    
    348  | 
     | 
     | 
    	    sizeof(*options->remote_forwards));  | 
    
    
    349  | 
     | 
     | 
    	fwd = &options->remote_forwards[options->num_remote_forwards++];  | 
    
    
    350  | 
     | 
     | 
     | 
    
    
    351  | 
     | 
     | 
    	fwd->listen_host = newfwd->listen_host;  | 
    
    
    352  | 
     | 
     | 
    	fwd->listen_port = newfwd->listen_port;  | 
    
    
    353  | 
     | 
     | 
    	fwd->listen_path = newfwd->listen_path;  | 
    
    
    354  | 
     | 
     | 
    	fwd->connect_host = newfwd->connect_host;  | 
    
    
    355  | 
     | 
     | 
    	fwd->connect_port = newfwd->connect_port;  | 
    
    
    356  | 
     | 
     | 
    	fwd->connect_path = newfwd->connect_path;  | 
    
    
    357  | 
     | 
     | 
    	fwd->handle = newfwd->handle;  | 
    
    
    358  | 
     | 
     | 
    	fwd->allocated_port = 0;  | 
    
    
    359  | 
     | 
     | 
    }  | 
    
    
    360  | 
     | 
     | 
     | 
    
    
    361  | 
     | 
     | 
    static void  | 
    
    
    362  | 
     | 
     | 
    clear_forwardings(Options *options)  | 
    
    
    363  | 
     | 
     | 
    { | 
    
    
    364  | 
     | 
     | 
    	int i;  | 
    
    
    365  | 
     | 
     | 
     | 
    
    
    366  | 
     | 
     | 
    	for (i = 0; i < options->num_local_forwards; i++) { | 
    
    
    367  | 
     | 
     | 
    		free(options->local_forwards[i].listen_host);  | 
    
    
    368  | 
     | 
     | 
    		free(options->local_forwards[i].listen_path);  | 
    
    
    369  | 
     | 
     | 
    		free(options->local_forwards[i].connect_host);  | 
    
    
    370  | 
     | 
     | 
    		free(options->local_forwards[i].connect_path);  | 
    
    
    371  | 
     | 
     | 
    	}  | 
    
    
    372  | 
     | 
     | 
    	if (options->num_local_forwards > 0) { | 
    
    
    373  | 
     | 
     | 
    		free(options->local_forwards);  | 
    
    
    374  | 
     | 
     | 
    		options->local_forwards = NULL;  | 
    
    
    375  | 
     | 
     | 
    	}  | 
    
    
    376  | 
     | 
     | 
    	options->num_local_forwards = 0;  | 
    
    
    377  | 
     | 
     | 
    	for (i = 0; i < options->num_remote_forwards; i++) { | 
    
    
    378  | 
     | 
     | 
    		free(options->remote_forwards[i].listen_host);  | 
    
    
    379  | 
     | 
     | 
    		free(options->remote_forwards[i].listen_path);  | 
    
    
    380  | 
     | 
     | 
    		free(options->remote_forwards[i].connect_host);  | 
    
    
    381  | 
     | 
     | 
    		free(options->remote_forwards[i].connect_path);  | 
    
    
    382  | 
     | 
     | 
    	}  | 
    
    
    383  | 
     | 
     | 
    	if (options->num_remote_forwards > 0) { | 
    
    
    384  | 
     | 
     | 
    		free(options->remote_forwards);  | 
    
    
    385  | 
     | 
     | 
    		options->remote_forwards = NULL;  | 
    
    
    386  | 
     | 
     | 
    	}  | 
    
    
    387  | 
     | 
     | 
    	options->num_remote_forwards = 0;  | 
    
    
    388  | 
     | 
     | 
    	options->tun_open = SSH_TUNMODE_NO;  | 
    
    
    389  | 
     | 
     | 
    }  | 
    
    
    390  | 
     | 
     | 
     | 
    
    
    391  | 
     | 
     | 
    void  | 
    
    
    392  | 
     | 
     | 
    add_certificate_file(Options *options, const char *path, int userprovided)  | 
    
    
    393  | 
     | 
     | 
    { | 
    
    
    394  | 
     | 
     | 
    	int i;  | 
    
    
    395  | 
     | 
     | 
     | 
    
    
    396  | 
     | 
     | 
    	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)  | 
    
    
    397  | 
     | 
     | 
    		fatal("Too many certificate files specified (max %d)", | 
    
    
    398  | 
     | 
     | 
    		    SSH_MAX_CERTIFICATE_FILES);  | 
    
    
    399  | 
     | 
     | 
     | 
    
    
    400  | 
     | 
     | 
    	/* Avoid registering duplicates */  | 
    
    
    401  | 
     | 
     | 
    	for (i = 0; i < options->num_certificate_files; i++) { | 
    
    
    402  | 
     | 
     | 
    		if (options->certificate_file_userprovided[i] == userprovided &&  | 
    
    
    403  | 
     | 
     | 
    		    strcmp(options->certificate_files[i], path) == 0) { | 
    
    
    404  | 
     | 
     | 
    			debug2("%s: ignoring duplicate key %s", __func__, path); | 
    
    
    405  | 
     | 
     | 
    			return;  | 
    
    
    406  | 
     | 
     | 
    		}  | 
    
    
    407  | 
     | 
     | 
    	}  | 
    
    
    408  | 
     | 
     | 
     | 
    
    
    409  | 
     | 
     | 
    	options->certificate_file_userprovided[options->num_certificate_files] =  | 
    
    
    410  | 
     | 
     | 
    	    userprovided;  | 
    
    
    411  | 
     | 
     | 
    	options->certificate_files[options->num_certificate_files++] =  | 
    
    
    412  | 
     | 
     | 
    	    xstrdup(path);  | 
    
    
    413  | 
     | 
     | 
    }  | 
    
    
    414  | 
     | 
     | 
     | 
    
    
    415  | 
     | 
     | 
    void  | 
    
    
    416  | 
     | 
     | 
    add_identity_file(Options *options, const char *dir, const char *filename,  | 
    
    
    417  | 
     | 
     | 
        int userprovided)  | 
    
    
    418  | 
     | 
     | 
    { | 
    
    
    419  | 
     | 
     | 
    	char *path;  | 
    
    
    420  | 
     | 
     | 
    	int i;  | 
    
    
    421  | 
     | 
     | 
     | 
    
    
    422  | 
     | 
     | 
    	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)  | 
    
    
    423  | 
     | 
     | 
    		fatal("Too many identity files specified (max %d)", | 
    
    
    424  | 
     | 
     | 
    		    SSH_MAX_IDENTITY_FILES);  | 
    
    
    425  | 
     | 
     | 
     | 
    
    
    426  | 
     | 
     | 
    	if (dir == NULL) /* no dir, filename is absolute */  | 
    
    
    427  | 
     | 
     | 
    		path = xstrdup(filename);  | 
    
    
    428  | 
     | 
     | 
    	else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)  | 
    
    
    429  | 
     | 
     | 
    		fatal("Identity file path %s too long", path); | 
    
    
    430  | 
     | 
     | 
     | 
    
    
    431  | 
     | 
     | 
    	/* Avoid registering duplicates */  | 
    
    
    432  | 
     | 
     | 
    	for (i = 0; i < options->num_identity_files; i++) { | 
    
    
    433  | 
     | 
     | 
    		if (options->identity_file_userprovided[i] == userprovided &&  | 
    
    
    434  | 
     | 
     | 
    		    strcmp(options->identity_files[i], path) == 0) { | 
    
    
    435  | 
     | 
     | 
    			debug2("%s: ignoring duplicate key %s", __func__, path); | 
    
    
    436  | 
     | 
     | 
    			free(path);  | 
    
    
    437  | 
     | 
     | 
    			return;  | 
    
    
    438  | 
     | 
     | 
    		}  | 
    
    
    439  | 
     | 
     | 
    	}  | 
    
    
    440  | 
     | 
     | 
     | 
    
    
    441  | 
     | 
     | 
    	options->identity_file_userprovided[options->num_identity_files] =  | 
    
    
    442  | 
     | 
     | 
    	    userprovided;  | 
    
    
    443  | 
     | 
     | 
    	options->identity_files[options->num_identity_files++] = path;  | 
    
    
    444  | 
     | 
     | 
    }  | 
    
    
    445  | 
     | 
     | 
     | 
    
    
    446  | 
     | 
     | 
    int  | 
    
    
    447  | 
     | 
     | 
    default_ssh_port(void)  | 
    
    
    448  | 
     | 
     | 
    { | 
    
    
    449  | 
     | 
     | 
    	static int port;  | 
    
    
    450  | 
     | 
     | 
    	struct servent *sp;  | 
    
    
    451  | 
     | 
     | 
     | 
    
    
    452  | 
     | 
     | 
    	if (port == 0) { | 
    
    
    453  | 
     | 
     | 
    		sp = getservbyname(SSH_SERVICE_NAME, "tcp");  | 
    
    
    454  | 
     | 
     | 
    		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;  | 
    
    
    455  | 
     | 
     | 
    	}  | 
    
    
    456  | 
     | 
     | 
    	return port;  | 
    
    
    457  | 
     | 
     | 
    }  | 
    
    
    458  | 
     | 
     | 
     | 
    
    
    459  | 
     | 
     | 
    /*  | 
    
    
    460  | 
     | 
     | 
     * Execute a command in a shell.  | 
    
    
    461  | 
     | 
     | 
     * Return its exit status or -1 on abnormal exit.  | 
    
    
    462  | 
     | 
     | 
     */  | 
    
    
    463  | 
     | 
     | 
    static int  | 
    
    
    464  | 
     | 
     | 
    execute_in_shell(const char *cmd)  | 
    
    
    465  | 
     | 
     | 
    { | 
    
    
    466  | 
     | 
     | 
    	char *shell;  | 
    
    
    467  | 
     | 
     | 
    	pid_t pid;  | 
    
    
    468  | 
     | 
     | 
    	int devnull, status;  | 
    
    
    469  | 
     | 
     | 
    	extern uid_t original_real_uid;  | 
    
    
    470  | 
     | 
     | 
     | 
    
    
    471  | 
     | 
     | 
    	if ((shell = getenv("SHELL")) == NULL) | 
    
    
    472  | 
     | 
     | 
    		shell = _PATH_BSHELL;  | 
    
    
    473  | 
     | 
     | 
     | 
    
    
    474  | 
     | 
     | 
    	/* Need this to redirect subprocess stdin/out */  | 
    
    
    475  | 
     | 
     | 
    	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)  | 
    
    
    476  | 
     | 
     | 
    		fatal("open(/dev/null): %s", strerror(errno)); | 
    
    
    477  | 
     | 
     | 
     | 
    
    
    478  | 
     | 
     | 
    	debug("Executing command: '%.500s'", cmd); | 
    
    
    479  | 
     | 
     | 
     | 
    
    
    480  | 
     | 
     | 
    	/* Fork and execute the command. */  | 
    
    
    481  | 
     | 
     | 
    	if ((pid = fork()) == 0) { | 
    
    
    482  | 
     | 
     | 
    		char *argv[4];  | 
    
    
    483  | 
     | 
     | 
     | 
    
    
    484  | 
     | 
     | 
    		/* Child.  Permanently give up superuser privileges. */  | 
    
    
    485  | 
     | 
     | 
    		permanently_drop_suid(original_real_uid);  | 
    
    
    486  | 
     | 
     | 
     | 
    
    
    487  | 
     | 
     | 
    		/* Redirect child stdin and stdout. Leave stderr */  | 
    
    
    488  | 
     | 
     | 
    		if (dup2(devnull, STDIN_FILENO) == -1)  | 
    
    
    489  | 
     | 
     | 
    			fatal("dup2: %s", strerror(errno)); | 
    
    
    490  | 
     | 
     | 
    		if (dup2(devnull, STDOUT_FILENO) == -1)  | 
    
    
    491  | 
     | 
     | 
    			fatal("dup2: %s", strerror(errno)); | 
    
    
    492  | 
     | 
     | 
    		if (devnull > STDERR_FILENO)  | 
    
    
    493  | 
     | 
     | 
    			close(devnull);  | 
    
    
    494  | 
     | 
     | 
    		closefrom(STDERR_FILENO + 1);  | 
    
    
    495  | 
     | 
     | 
     | 
    
    
    496  | 
     | 
     | 
    		argv[0] = shell;  | 
    
    
    497  | 
     | 
     | 
    		argv[1] = "-c";  | 
    
    
    498  | 
     | 
     | 
    		argv[2] = xstrdup(cmd);  | 
    
    
    499  | 
     | 
     | 
    		argv[3] = NULL;  | 
    
    
    500  | 
     | 
     | 
     | 
    
    
    501  | 
     | 
     | 
    		execv(argv[0], argv);  | 
    
    
    502  | 
     | 
     | 
    		error("Unable to execute '%.100s': %s", cmd, strerror(errno)); | 
    
    
    503  | 
     | 
     | 
    		/* Die with signal to make this error apparent to parent. */  | 
    
    
    504  | 
     | 
     | 
    		signal(SIGTERM, SIG_DFL);  | 
    
    
    505  | 
     | 
     | 
    		kill(getpid(), SIGTERM);  | 
    
    
    506  | 
     | 
     | 
    		_exit(1);  | 
    
    
    507  | 
     | 
     | 
    	}  | 
    
    
    508  | 
     | 
     | 
    	/* Parent. */  | 
    
    
    509  | 
     | 
     | 
    	if (pid < 0)  | 
    
    
    510  | 
     | 
     | 
    		fatal("%s: fork: %.100s", __func__, strerror(errno)); | 
    
    
    511  | 
     | 
     | 
     | 
    
    
    512  | 
     | 
     | 
    	close(devnull);  | 
    
    
    513  | 
     | 
     | 
     | 
    
    
    514  | 
     | 
     | 
    	while (waitpid(pid, &status, 0) == -1) { | 
    
    
    515  | 
     | 
     | 
    		if (errno != EINTR && errno != EAGAIN)  | 
    
    
    516  | 
     | 
     | 
    			fatal("%s: waitpid: %s", __func__, strerror(errno)); | 
    
    
    517  | 
     | 
     | 
    	}  | 
    
    
    518  | 
     | 
     | 
    	if (!WIFEXITED(status)) { | 
    
    
    519  | 
     | 
     | 
    		error("command '%.100s' exited abnormally", cmd); | 
    
    
    520  | 
     | 
     | 
    		return -1;  | 
    
    
    521  | 
     | 
     | 
    	}  | 
    
    
    522  | 
     | 
     | 
    	debug3("command returned status %d", WEXITSTATUS(status)); | 
    
    
    523  | 
     | 
     | 
    	return WEXITSTATUS(status);  | 
    
    
    524  | 
     | 
     | 
    }  | 
    
    
    525  | 
     | 
     | 
     | 
    
    
    526  | 
     | 
     | 
    /*  | 
    
    
    527  | 
     | 
     | 
     * Parse and execute a Match directive.  | 
    
    
    528  | 
     | 
     | 
     */  | 
    
    
    529  | 
     | 
     | 
    static int  | 
    
    
    530  | 
     | 
     | 
    match_cfg_line(Options *options, char **condition, struct passwd *pw,  | 
    
    
    531  | 
     | 
     | 
        const char *host_arg, const char *original_host, int post_canon,  | 
    
    
    532  | 
     | 
     | 
        const char *filename, int linenum)  | 
    
    
    533  | 
     | 
     | 
    { | 
    
    
    534  | 
     | 
     | 
    	char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;  | 
    
    
    535  | 
     | 
     | 
    	const char *ruser;  | 
    
    
    536  | 
     | 
     | 
    	int r, port, this_result, result = 1, attributes = 0, negate;  | 
    
    
    537  | 
     | 
     | 
    	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];  | 
    
    
    538  | 
     | 
     | 
     | 
    
    
    539  | 
     | 
     | 
    	/*  | 
    
    
    540  | 
     | 
     | 
    	 * Configuration is likely to be incomplete at this point so we  | 
    
    
    541  | 
     | 
     | 
    	 * must be prepared to use default values.  | 
    
    
    542  | 
     | 
     | 
    	 */  | 
    
    
    543  | 
     | 
     | 
    	port = options->port <= 0 ? default_ssh_port() : options->port;  | 
    
    
    544  | 
     | 
     | 
    	ruser = options->user == NULL ? pw->pw_name : options->user;  | 
    
    
    545  | 
     | 
     | 
    	if (post_canon) { | 
    
    
    546  | 
     | 
     | 
    		host = xstrdup(options->hostname);  | 
    
    
    547  | 
     | 
     | 
    	} else if (options->hostname != NULL) { | 
    
    
    548  | 
     | 
     | 
    		/* NB. Please keep in sync with ssh.c:main() */  | 
    
    
    549  | 
     | 
     | 
    		host = percent_expand(options->hostname,  | 
    
    
    550  | 
     | 
     | 
    		    "h", host_arg, (char *)NULL);  | 
    
    
    551  | 
     | 
     | 
    	} else { | 
    
    
    552  | 
     | 
     | 
    		host = xstrdup(host_arg);  | 
    
    
    553  | 
     | 
     | 
    	}  | 
    
    
    554  | 
     | 
     | 
     | 
    
    
    555  | 
     | 
     | 
    	debug2("checking match for '%s' host %s originally %s", | 
    
    
    556  | 
     | 
     | 
    	    cp, host, original_host);  | 
    
    
    557  | 
     | 
     | 
    	while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { | 
    
    
    558  | 
     | 
     | 
    		criteria = NULL;  | 
    
    
    559  | 
     | 
     | 
    		this_result = 1;  | 
    
    
    560  | 
     | 
     | 
    		if ((negate = attrib[0] == '!'))  | 
    
    
    561  | 
     | 
     | 
    			attrib++;  | 
    
    
    562  | 
     | 
     | 
    		/* criteria "all" and "canonical" have no argument */  | 
    
    
    563  | 
     | 
     | 
    		if (strcasecmp(attrib, "all") == 0) { | 
    
    
    564  | 
     | 
     | 
    			if (attributes > 1 ||  | 
    
    
    565  | 
     | 
     | 
    			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { | 
    
    
    566  | 
     | 
     | 
    				error("%.200s line %d: '%s' cannot be combined " | 
    
    
    567  | 
     | 
     | 
    				    "with other Match attributes",  | 
    
    
    568  | 
     | 
     | 
    				    filename, linenum, oattrib);  | 
    
    
    569  | 
     | 
     | 
    				result = -1;  | 
    
    
    570  | 
     | 
     | 
    				goto out;  | 
    
    
    571  | 
     | 
     | 
    			}  | 
    
    
    572  | 
     | 
     | 
    			if (result)  | 
    
    
    573  | 
     | 
     | 
    				result = negate ? 0 : 1;  | 
    
    
    574  | 
     | 
     | 
    			goto out;  | 
    
    
    575  | 
     | 
     | 
    		}  | 
    
    
    576  | 
     | 
     | 
    		attributes++;  | 
    
    
    577  | 
     | 
     | 
    		if (strcasecmp(attrib, "canonical") == 0) { | 
    
    
    578  | 
     | 
     | 
    			r = !!post_canon;  /* force bitmask member to boolean */  | 
    
    
    579  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    580  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    581  | 
     | 
     | 
    			debug3("%.200s line %d: %smatched '%s'", | 
    
    
    582  | 
     | 
     | 
    			    filename, linenum,  | 
    
    
    583  | 
     | 
     | 
    			    this_result ? "" : "not ", oattrib);  | 
    
    
    584  | 
     | 
     | 
    			continue;  | 
    
    
    585  | 
     | 
     | 
    		}  | 
    
    
    586  | 
     | 
     | 
    		/* All other criteria require an argument */  | 
    
    
    587  | 
     | 
     | 
    		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { | 
    
    
    588  | 
     | 
     | 
    			error("Missing Match criteria for %s", attrib); | 
    
    
    589  | 
     | 
     | 
    			result = -1;  | 
    
    
    590  | 
     | 
     | 
    			goto out;  | 
    
    
    591  | 
     | 
     | 
    		}  | 
    
    
    592  | 
     | 
     | 
    		if (strcasecmp(attrib, "host") == 0) { | 
    
    
    593  | 
     | 
     | 
    			criteria = xstrdup(host);  | 
    
    
    594  | 
     | 
     | 
    			r = match_hostname(host, arg) == 1;  | 
    
    
    595  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    596  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    597  | 
     | 
     | 
    		} else if (strcasecmp(attrib, "originalhost") == 0) { | 
    
    
    598  | 
     | 
     | 
    			criteria = xstrdup(original_host);  | 
    
    
    599  | 
     | 
     | 
    			r = match_hostname(original_host, arg) == 1;  | 
    
    
    600  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    601  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    602  | 
     | 
     | 
    		} else if (strcasecmp(attrib, "user") == 0) { | 
    
    
    603  | 
     | 
     | 
    			criteria = xstrdup(ruser);  | 
    
    
    604  | 
     | 
     | 
    			r = match_pattern_list(ruser, arg, 0) == 1;  | 
    
    
    605  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    606  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    607  | 
     | 
     | 
    		} else if (strcasecmp(attrib, "localuser") == 0) { | 
    
    
    608  | 
     | 
     | 
    			criteria = xstrdup(pw->pw_name);  | 
    
    
    609  | 
     | 
     | 
    			r = match_pattern_list(pw->pw_name, arg, 0) == 1;  | 
    
    
    610  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    611  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    612  | 
     | 
     | 
    		} else if (strcasecmp(attrib, "exec") == 0) { | 
    
    
    613  | 
     | 
     | 
    			if (gethostname(thishost, sizeof(thishost)) == -1)  | 
    
    
    614  | 
     | 
     | 
    				fatal("gethostname: %s", strerror(errno)); | 
    
    
    615  | 
     | 
     | 
    			strlcpy(shorthost, thishost, sizeof(shorthost));  | 
    
    
    616  | 
     | 
     | 
    			shorthost[strcspn(thishost, ".")] = '\0';  | 
    
    
    617  | 
     | 
     | 
    			snprintf(portstr, sizeof(portstr), "%d", port);  | 
    
    
    618  | 
     | 
     | 
     | 
    
    
    619  | 
     | 
     | 
    			cmd = percent_expand(arg,  | 
    
    
    620  | 
     | 
     | 
    			    "L", shorthost,  | 
    
    
    621  | 
     | 
     | 
    			    "d", pw->pw_dir,  | 
    
    
    622  | 
     | 
     | 
    			    "h", host,  | 
    
    
    623  | 
     | 
     | 
    			    "l", thishost,  | 
    
    
    624  | 
     | 
     | 
    			    "n", original_host,  | 
    
    
    625  | 
     | 
     | 
    			    "p", portstr,  | 
    
    
    626  | 
     | 
     | 
    			    "r", ruser,  | 
    
    
    627  | 
     | 
     | 
    			    "u", pw->pw_name,  | 
    
    
    628  | 
     | 
     | 
    			    (char *)NULL);  | 
    
    
    629  | 
     | 
     | 
    			if (result != 1) { | 
    
    
    630  | 
     | 
     | 
    				/* skip execution if prior predicate failed */  | 
    
    
    631  | 
     | 
     | 
    				debug3("%.200s line %d: skipped exec " | 
    
    
    632  | 
     | 
     | 
    				    "\"%.100s\"", filename, linenum, cmd);  | 
    
    
    633  | 
     | 
     | 
    				free(cmd);  | 
    
    
    634  | 
     | 
     | 
    				continue;  | 
    
    
    635  | 
     | 
     | 
    			}  | 
    
    
    636  | 
     | 
     | 
    			r = execute_in_shell(cmd);  | 
    
    
    637  | 
     | 
     | 
    			if (r == -1) { | 
    
    
    638  | 
     | 
     | 
    				fatal("%.200s line %d: match exec " | 
    
    
    639  | 
     | 
     | 
    				    "'%.100s' error", filename,  | 
    
    
    640  | 
     | 
     | 
    				    linenum, cmd);  | 
    
    
    641  | 
     | 
     | 
    			}  | 
    
    
    642  | 
     | 
     | 
    			criteria = xstrdup(cmd);  | 
    
    
    643  | 
     | 
     | 
    			free(cmd);  | 
    
    
    644  | 
     | 
     | 
    			/* Force exit status to boolean */  | 
    
    
    645  | 
     | 
     | 
    			r = r == 0;  | 
    
    
    646  | 
     | 
     | 
    			if (r == (negate ? 1 : 0))  | 
    
    
    647  | 
     | 
     | 
    				this_result = result = 0;  | 
    
    
    648  | 
     | 
     | 
    		} else { | 
    
    
    649  | 
     | 
     | 
    			error("Unsupported Match attribute %s", attrib); | 
    
    
    650  | 
     | 
     | 
    			result = -1;  | 
    
    
    651  | 
     | 
     | 
    			goto out;  | 
    
    
    652  | 
     | 
     | 
    		}  | 
    
    
    653  | 
     | 
     | 
    		debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", | 
    
    
    654  | 
     | 
     | 
    		    filename, linenum, this_result ? "": "not ",  | 
    
    
    655  | 
     | 
     | 
    		    oattrib, criteria);  | 
    
    
    656  | 
     | 
     | 
    		free(criteria);  | 
    
    
    657  | 
     | 
     | 
    	}  | 
    
    
    658  | 
     | 
     | 
    	if (attributes == 0) { | 
    
    
    659  | 
     | 
     | 
    		error("One or more attributes required for Match"); | 
    
    
    660  | 
     | 
     | 
    		result = -1;  | 
    
    
    661  | 
     | 
     | 
    		goto out;  | 
    
    
    662  | 
     | 
     | 
    	}  | 
    
    
    663  | 
     | 
     | 
     out:  | 
    
    
    664  | 
     | 
     | 
    	if (result != -1)  | 
    
    
    665  | 
     | 
     | 
    		debug2("match %sfound", result ? "" : "not "); | 
    
    
    666  | 
     | 
     | 
    	*condition = cp;  | 
    
    
    667  | 
     | 
     | 
    	free(host);  | 
    
    
    668  | 
     | 
     | 
    	return result;  | 
    
    
    669  | 
     | 
     | 
    }  | 
    
    
    670  | 
     | 
     | 
     | 
    
    
    671  | 
     | 
     | 
    /*  | 
    
    
    672  | 
     | 
     | 
     * Returns the number of the token pointed to by cp or oBadOption.  | 
    
    
    673  | 
     | 
     | 
     */  | 
    
    
    674  | 
     | 
     | 
    static OpCodes  | 
    
    
    675  | 
     | 
     | 
    parse_token(const char *cp, const char *filename, int linenum,  | 
    
    
    676  | 
     | 
     | 
        const char *ignored_unknown)  | 
    
    
    677  | 
     | 
     | 
    { | 
    
    
    678  | 
     | 
     | 
    	int i;  | 
    
    
    679  | 
     | 
     | 
     | 
    
    
    680  | 
     | 
     | 
    	for (i = 0; keywords[i].name; i++)  | 
    
    
    681  | 
     | 
     | 
    		if (strcmp(cp, keywords[i].name) == 0)  | 
    
    
    682  | 
     | 
     | 
    			return keywords[i].opcode;  | 
    
    
    683  | 
     | 
     | 
    	if (ignored_unknown != NULL &&  | 
    
    
    684  | 
     | 
     | 
    	    match_pattern_list(cp, ignored_unknown, 1) == 1)  | 
    
    
    685  | 
     | 
     | 
    		return oIgnoredUnknownOption;  | 
    
    
    686  | 
     | 
     | 
    	error("%s: line %d: Bad configuration option: %s", | 
    
    
    687  | 
     | 
     | 
    	    filename, linenum, cp);  | 
    
    
    688  | 
     | 
     | 
    	return oBadOption;  | 
    
    
    689  | 
     | 
     | 
    }  | 
    
    
    690  | 
     | 
     | 
     | 
    
    
    691  | 
     | 
     | 
    /* Multistate option parsing */  | 
    
    
    692  | 
     | 
     | 
    struct multistate { | 
    
    
    693  | 
     | 
     | 
    	char *key;  | 
    
    
    694  | 
     | 
     | 
    	int value;  | 
    
    
    695  | 
     | 
     | 
    };  | 
    
    
    696  | 
     | 
     | 
    static const struct multistate multistate_flag[] = { | 
    
    
    697  | 
     | 
     | 
    	{ "true",			1 }, | 
    
    
    698  | 
     | 
     | 
    	{ "false",			0 }, | 
    
    
    699  | 
     | 
     | 
    	{ "yes",			1 }, | 
    
    
    700  | 
     | 
     | 
    	{ "no",				0 }, | 
    
    
    701  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    702  | 
     | 
     | 
    };  | 
    
    
    703  | 
     | 
     | 
    static const struct multistate multistate_yesnoask[] = { | 
    
    
    704  | 
     | 
     | 
    	{ "true",			1 }, | 
    
    
    705  | 
     | 
     | 
    	{ "false",			0 }, | 
    
    
    706  | 
     | 
     | 
    	{ "yes",			1 }, | 
    
    
    707  | 
     | 
     | 
    	{ "no",				0 }, | 
    
    
    708  | 
     | 
     | 
    	{ "ask",			2 }, | 
    
    
    709  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    710  | 
     | 
     | 
    };  | 
    
    
    711  | 
     | 
     | 
    static const struct multistate multistate_strict_hostkey[] = { | 
    
    
    712  | 
     | 
     | 
    	{ "true",			SSH_STRICT_HOSTKEY_YES }, | 
    
    
    713  | 
     | 
     | 
    	{ "false",			SSH_STRICT_HOSTKEY_OFF }, | 
    
    
    714  | 
     | 
     | 
    	{ "yes",			SSH_STRICT_HOSTKEY_YES }, | 
    
    
    715  | 
     | 
     | 
    	{ "no",				SSH_STRICT_HOSTKEY_OFF }, | 
    
    
    716  | 
     | 
     | 
    	{ "ask",			SSH_STRICT_HOSTKEY_ASK }, | 
    
    
    717  | 
     | 
     | 
    	{ "off",			SSH_STRICT_HOSTKEY_OFF }, | 
    
    
    718  | 
     | 
     | 
    	{ "accept-new",			SSH_STRICT_HOSTKEY_NEW }, | 
    
    
    719  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    720  | 
     | 
     | 
    };  | 
    
    
    721  | 
     | 
     | 
    static const struct multistate multistate_yesnoaskconfirm[] = { | 
    
    
    722  | 
     | 
     | 
    	{ "true",			1 }, | 
    
    
    723  | 
     | 
     | 
    	{ "false",			0 }, | 
    
    
    724  | 
     | 
     | 
    	{ "yes",			1 }, | 
    
    
    725  | 
     | 
     | 
    	{ "no",				0 }, | 
    
    
    726  | 
     | 
     | 
    	{ "ask",			2 }, | 
    
    
    727  | 
     | 
     | 
    	{ "confirm",			3 }, | 
    
    
    728  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    729  | 
     | 
     | 
    };  | 
    
    
    730  | 
     | 
     | 
    static const struct multistate multistate_addressfamily[] = { | 
    
    
    731  | 
     | 
     | 
    	{ "inet",			AF_INET }, | 
    
    
    732  | 
     | 
     | 
    	{ "inet6",			AF_INET6 }, | 
    
    
    733  | 
     | 
     | 
    	{ "any",			AF_UNSPEC }, | 
    
    
    734  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    735  | 
     | 
     | 
    };  | 
    
    
    736  | 
     | 
     | 
    static const struct multistate multistate_controlmaster[] = { | 
    
    
    737  | 
     | 
     | 
    	{ "true",			SSHCTL_MASTER_YES }, | 
    
    
    738  | 
     | 
     | 
    	{ "yes",			SSHCTL_MASTER_YES }, | 
    
    
    739  | 
     | 
     | 
    	{ "false",			SSHCTL_MASTER_NO }, | 
    
    
    740  | 
     | 
     | 
    	{ "no",				SSHCTL_MASTER_NO }, | 
    
    
    741  | 
     | 
     | 
    	{ "auto",			SSHCTL_MASTER_AUTO }, | 
    
    
    742  | 
     | 
     | 
    	{ "ask",			SSHCTL_MASTER_ASK }, | 
    
    
    743  | 
     | 
     | 
    	{ "autoask",			SSHCTL_MASTER_AUTO_ASK }, | 
    
    
    744  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    745  | 
     | 
     | 
    };  | 
    
    
    746  | 
     | 
     | 
    static const struct multistate multistate_tunnel[] = { | 
    
    
    747  | 
     | 
     | 
    	{ "ethernet",			SSH_TUNMODE_ETHERNET }, | 
    
    
    748  | 
     | 
     | 
    	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT }, | 
    
    
    749  | 
     | 
     | 
    	{ "true",			SSH_TUNMODE_DEFAULT }, | 
    
    
    750  | 
     | 
     | 
    	{ "yes",			SSH_TUNMODE_DEFAULT }, | 
    
    
    751  | 
     | 
     | 
    	{ "false",			SSH_TUNMODE_NO }, | 
    
    
    752  | 
     | 
     | 
    	{ "no",				SSH_TUNMODE_NO }, | 
    
    
    753  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    754  | 
     | 
     | 
    };  | 
    
    
    755  | 
     | 
     | 
    static const struct multistate multistate_requesttty[] = { | 
    
    
    756  | 
     | 
     | 
    	{ "true",			REQUEST_TTY_YES }, | 
    
    
    757  | 
     | 
     | 
    	{ "yes",			REQUEST_TTY_YES }, | 
    
    
    758  | 
     | 
     | 
    	{ "false",			REQUEST_TTY_NO }, | 
    
    
    759  | 
     | 
     | 
    	{ "no",				REQUEST_TTY_NO }, | 
    
    
    760  | 
     | 
     | 
    	{ "force",			REQUEST_TTY_FORCE }, | 
    
    
    761  | 
     | 
     | 
    	{ "auto",			REQUEST_TTY_AUTO }, | 
    
    
    762  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    763  | 
     | 
     | 
    };  | 
    
    
    764  | 
     | 
     | 
    static const struct multistate multistate_canonicalizehostname[] = { | 
    
    
    765  | 
     | 
     | 
    	{ "true",			SSH_CANONICALISE_YES }, | 
    
    
    766  | 
     | 
     | 
    	{ "false",			SSH_CANONICALISE_NO }, | 
    
    
    767  | 
     | 
     | 
    	{ "yes",			SSH_CANONICALISE_YES }, | 
    
    
    768  | 
     | 
     | 
    	{ "no",				SSH_CANONICALISE_NO }, | 
    
    
    769  | 
     | 
     | 
    	{ "always",			SSH_CANONICALISE_ALWAYS }, | 
    
    
    770  | 
     | 
     | 
    	{ NULL, -1 } | 
    
    
    771  | 
     | 
     | 
    };  | 
    
    
    772  | 
     | 
     | 
     | 
    
    
    773  | 
     | 
     | 
    /*  | 
    
    
    774  | 
     | 
     | 
     * Processes a single option line as used in the configuration files. This  | 
    
    
    775  | 
     | 
     | 
     * only sets those values that have not already been set.  | 
    
    
    776  | 
     | 
     | 
     */  | 
    
    
    777  | 
     | 
     | 
    int  | 
    
    
    778  | 
     | 
     | 
    process_config_line(Options *options, struct passwd *pw, const char *host,  | 
    
    
    779  | 
     | 
     | 
        const char *original_host, char *line, const char *filename,  | 
    
    
    780  | 
     | 
     | 
        int linenum, int *activep, int flags)  | 
    
    
    781  | 
     | 
     | 
    { | 
    
    
    782  | 
     | 
     | 
    	return process_config_line_depth(options, pw, host, original_host,  | 
    
    
    783  | 
     | 
     | 
    	    line, filename, linenum, activep, flags, 0);  | 
    
    
    784  | 
     | 
     | 
    }  | 
    
    
    785  | 
     | 
     | 
     | 
    
    
    786  | 
     | 
     | 
    #define WHITESPACE " \t\r\n"  | 
    
    
    787  | 
     | 
     | 
    static int  | 
    
    
    788  | 
     | 
     | 
    process_config_line_depth(Options *options, struct passwd *pw, const char *host,  | 
    
    
    789  | 
     | 
     | 
        const char *original_host, char *line, const char *filename,  | 
    
    
    790  | 
     | 
     | 
        int linenum, int *activep, int flags, int depth)  | 
    
    
    791  | 
     | 
     | 
    { | 
    
    
    792  | 
     | 
     | 
    	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;  | 
    
    
    793  | 
     | 
     | 
    	char **cpptr, fwdarg[256];  | 
    
    
    794  | 
     | 
     | 
    	u_int i, *uintptr, max_entries = 0;  | 
    
    
    795  | 
     | 
     | 
    	int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;  | 
    
    
    796  | 
     | 
     | 
    	int remotefwd, dynamicfwd;  | 
    
    
    797  | 
     | 
     | 
    	LogLevel *log_level_ptr;  | 
    
    
    798  | 
     | 
     | 
    	SyslogFacility *log_facility_ptr;  | 
    
    
    799  | 
     | 
     | 
    	long long val64;  | 
    
    
    800  | 
     | 
     | 
    	size_t len;  | 
    
    
    801  | 
     | 
     | 
    	struct Forward fwd;  | 
    
    
    802  | 
     | 
     | 
    	const struct multistate *multistate_ptr;  | 
    
    
    803  | 
     | 
     | 
    	struct allowed_cname *cname;  | 
    
    
    804  | 
     | 
     | 
    	glob_t gl;  | 
    
    
    805  | 
     | 
     | 
     | 
    
    
    806  | 
     | 
     | 
    	if (activep == NULL) { /* We are processing a command line directive */ | 
    
    
    807  | 
     | 
     | 
    		cmdline = 1;  | 
    
    
    808  | 
     | 
     | 
    		activep = &cmdline;  | 
    
    
    809  | 
     | 
     | 
    	}  | 
    
    
    810  | 
     | 
     | 
     | 
    
    
    811  | 
     | 
     | 
    	/* Strip trailing whitespace. Allow \f (form feed) at EOL only */  | 
    
    
    812  | 
     | 
     | 
    	if ((len = strlen(line)) == 0)  | 
    
    
    813  | 
     | 
     | 
    		return 0;  | 
    
    
    814  | 
     | 
     | 
    	for (len--; len > 0; len--) { | 
    
    
    815  | 
     | 
     | 
    		if (strchr(WHITESPACE "\f", line[len]) == NULL)  | 
    
    
    816  | 
     | 
     | 
    			break;  | 
    
    
    817  | 
     | 
     | 
    		line[len] = '\0';  | 
    
    
    818  | 
     | 
     | 
    	}  | 
    
    
    819  | 
     | 
     | 
     | 
    
    
    820  | 
     | 
     | 
    	s = line;  | 
    
    
    821  | 
     | 
     | 
    	/* Get the keyword. (Each line is supposed to begin with a keyword). */  | 
    
    
    822  | 
     | 
     | 
    	if ((keyword = strdelim(&s)) == NULL)  | 
    
    
    823  | 
     | 
     | 
    		return 0;  | 
    
    
    824  | 
     | 
     | 
    	/* Ignore leading whitespace. */  | 
    
    
    825  | 
     | 
     | 
    	if (*keyword == '\0')  | 
    
    
    826  | 
     | 
     | 
    		keyword = strdelim(&s);  | 
    
    
    827  | 
     | 
     | 
    	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')  | 
    
    
    828  | 
     | 
     | 
    		return 0;  | 
    
    
    829  | 
     | 
     | 
    	/* Match lowercase keyword */  | 
    
    
    830  | 
     | 
     | 
    	lowercase(keyword);  | 
    
    
    831  | 
     | 
     | 
     | 
    
    
    832  | 
     | 
     | 
    	opcode = parse_token(keyword, filename, linenum,  | 
    
    
    833  | 
     | 
     | 
    	    options->ignored_unknown);  | 
    
    
    834  | 
     | 
     | 
     | 
    
    
    835  | 
     | 
     | 
    	switch (opcode) { | 
    
    
    836  | 
     | 
     | 
    	case oBadOption:  | 
    
    
    837  | 
     | 
     | 
    		/* don't panic, but count bad options */  | 
    
    
    838  | 
     | 
     | 
    		return -1;  | 
    
    
    839  | 
     | 
     | 
    	case oIgnore:  | 
    
    
    840  | 
     | 
     | 
    		return 0;  | 
    
    
    841  | 
     | 
     | 
    	case oIgnoredUnknownOption:  | 
    
    
    842  | 
     | 
     | 
    		debug("%s line %d: Ignored unknown option \"%s\"", | 
    
    
    843  | 
     | 
     | 
    		    filename, linenum, keyword);  | 
    
    
    844  | 
     | 
     | 
    		return 0;  | 
    
    
    845  | 
     | 
     | 
    	case oConnectTimeout:  | 
    
    
    846  | 
     | 
     | 
    		intptr = &options->connection_timeout;  | 
    
    
    847  | 
     | 
     | 
    parse_time:  | 
    
    
    848  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    849  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    850  | 
     | 
     | 
    			fatal("%s line %d: missing time value.", | 
    
    
    851  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    852  | 
     | 
     | 
    		if (strcmp(arg, "none") == 0)  | 
    
    
    853  | 
     | 
     | 
    			value = -1;  | 
    
    
    854  | 
     | 
     | 
    		else if ((value = convtime(arg)) == -1)  | 
    
    
    855  | 
     | 
     | 
    			fatal("%s line %d: invalid time value.", | 
    
    
    856  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    857  | 
     | 
     | 
    		if (*activep && *intptr == -1)  | 
    
    
    858  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    859  | 
     | 
     | 
    		break;  | 
    
    
    860  | 
     | 
     | 
     | 
    
    
    861  | 
     | 
     | 
    	case oForwardAgent:  | 
    
    
    862  | 
     | 
     | 
    		intptr = &options->forward_agent;  | 
    
    
    863  | 
     | 
     | 
     parse_flag:  | 
    
    
    864  | 
     | 
     | 
    		multistate_ptr = multistate_flag;  | 
    
    
    865  | 
     | 
     | 
     parse_multistate:  | 
    
    
    866  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    867  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    868  | 
     | 
     | 
    			fatal("%s line %d: missing argument.", | 
    
    
    869  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    870  | 
     | 
     | 
    		value = -1;  | 
    
    
    871  | 
     | 
     | 
    		for (i = 0; multistate_ptr[i].key != NULL; i++) { | 
    
    
    872  | 
     | 
     | 
    			if (strcasecmp(arg, multistate_ptr[i].key) == 0) { | 
    
    
    873  | 
     | 
     | 
    				value = multistate_ptr[i].value;  | 
    
    
    874  | 
     | 
     | 
    				break;  | 
    
    
    875  | 
     | 
     | 
    			}  | 
    
    
    876  | 
     | 
     | 
    		}  | 
    
    
    877  | 
     | 
     | 
    		if (value == -1)  | 
    
    
    878  | 
     | 
     | 
    			fatal("%s line %d: unsupported option \"%s\".", | 
    
    
    879  | 
     | 
     | 
    			    filename, linenum, arg);  | 
    
    
    880  | 
     | 
     | 
    		if (*activep && *intptr == -1)  | 
    
    
    881  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    882  | 
     | 
     | 
    		break;  | 
    
    
    883  | 
     | 
     | 
     | 
    
    
    884  | 
     | 
     | 
    	case oForwardX11:  | 
    
    
    885  | 
     | 
     | 
    		intptr = &options->forward_x11;  | 
    
    
    886  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    887  | 
     | 
     | 
     | 
    
    
    888  | 
     | 
     | 
    	case oForwardX11Trusted:  | 
    
    
    889  | 
     | 
     | 
    		intptr = &options->forward_x11_trusted;  | 
    
    
    890  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    891  | 
     | 
     | 
     | 
    
    
    892  | 
     | 
     | 
    	case oForwardX11Timeout:  | 
    
    
    893  | 
     | 
     | 
    		intptr = &options->forward_x11_timeout;  | 
    
    
    894  | 
     | 
     | 
    		goto parse_time;  | 
    
    
    895  | 
     | 
     | 
     | 
    
    
    896  | 
     | 
     | 
    	case oGatewayPorts:  | 
    
    
    897  | 
     | 
     | 
    		intptr = &options->fwd_opts.gateway_ports;  | 
    
    
    898  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    899  | 
     | 
     | 
     | 
    
    
    900  | 
     | 
     | 
    	case oExitOnForwardFailure:  | 
    
    
    901  | 
     | 
     | 
    		intptr = &options->exit_on_forward_failure;  | 
    
    
    902  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    903  | 
     | 
     | 
     | 
    
    
    904  | 
     | 
     | 
    	case oUsePrivilegedPort:  | 
    
    
    905  | 
     | 
     | 
    		intptr = &options->use_privileged_port;  | 
    
    
    906  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    907  | 
     | 
     | 
     | 
    
    
    908  | 
     | 
     | 
    	case oPasswordAuthentication:  | 
    
    
    909  | 
     | 
     | 
    		intptr = &options->password_authentication;  | 
    
    
    910  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    911  | 
     | 
     | 
     | 
    
    
    912  | 
     | 
     | 
    	case oKbdInteractiveAuthentication:  | 
    
    
    913  | 
     | 
     | 
    		intptr = &options->kbd_interactive_authentication;  | 
    
    
    914  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    915  | 
     | 
     | 
     | 
    
    
    916  | 
     | 
     | 
    	case oKbdInteractiveDevices:  | 
    
    
    917  | 
     | 
     | 
    		charptr = &options->kbd_interactive_devices;  | 
    
    
    918  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    919  | 
     | 
     | 
     | 
    
    
    920  | 
     | 
     | 
    	case oPubkeyAuthentication:  | 
    
    
    921  | 
     | 
     | 
    		intptr = &options->pubkey_authentication;  | 
    
    
    922  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    923  | 
     | 
     | 
     | 
    
    
    924  | 
     | 
     | 
    	case oHostbasedAuthentication:  | 
    
    
    925  | 
     | 
     | 
    		intptr = &options->hostbased_authentication;  | 
    
    
    926  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    927  | 
     | 
     | 
     | 
    
    
    928  | 
     | 
     | 
    	case oChallengeResponseAuthentication:  | 
    
    
    929  | 
     | 
     | 
    		intptr = &options->challenge_response_authentication;  | 
    
    
    930  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    931  | 
     | 
     | 
     | 
    
    
    932  | 
     | 
     | 
    	case oGssAuthentication:  | 
    
    
    933  | 
     | 
     | 
    		intptr = &options->gss_authentication;  | 
    
    
    934  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    935  | 
     | 
     | 
     | 
    
    
    936  | 
     | 
     | 
    	case oGssDelegateCreds:  | 
    
    
    937  | 
     | 
     | 
    		intptr = &options->gss_deleg_creds;  | 
    
    
    938  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    939  | 
     | 
     | 
     | 
    
    
    940  | 
     | 
     | 
    	case oBatchMode:  | 
    
    
    941  | 
     | 
     | 
    		intptr = &options->batch_mode;  | 
    
    
    942  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    943  | 
     | 
     | 
     | 
    
    
    944  | 
     | 
     | 
    	case oCheckHostIP:  | 
    
    
    945  | 
     | 
     | 
    		intptr = &options->check_host_ip;  | 
    
    
    946  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    947  | 
     | 
     | 
     | 
    
    
    948  | 
     | 
     | 
    	case oVerifyHostKeyDNS:  | 
    
    
    949  | 
     | 
     | 
    		intptr = &options->verify_host_key_dns;  | 
    
    
    950  | 
     | 
     | 
    		multistate_ptr = multistate_yesnoask;  | 
    
    
    951  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    952  | 
     | 
     | 
     | 
    
    
    953  | 
     | 
     | 
    	case oStrictHostKeyChecking:  | 
    
    
    954  | 
     | 
     | 
    		intptr = &options->strict_host_key_checking;  | 
    
    
    955  | 
     | 
     | 
    		multistate_ptr = multistate_strict_hostkey;  | 
    
    
    956  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    957  | 
     | 
     | 
     | 
    
    
    958  | 
     | 
     | 
    	case oCompression:  | 
    
    
    959  | 
     | 
     | 
    		intptr = &options->compression;  | 
    
    
    960  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    961  | 
     | 
     | 
     | 
    
    
    962  | 
     | 
     | 
    	case oTCPKeepAlive:  | 
    
    
    963  | 
     | 
     | 
    		intptr = &options->tcp_keep_alive;  | 
    
    
    964  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    965  | 
     | 
     | 
     | 
    
    
    966  | 
     | 
     | 
    	case oNoHostAuthenticationForLocalhost:  | 
    
    
    967  | 
     | 
     | 
    		intptr = &options->no_host_authentication_for_localhost;  | 
    
    
    968  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    969  | 
     | 
     | 
     | 
    
    
    970  | 
     | 
     | 
    	case oNumberOfPasswordPrompts:  | 
    
    
    971  | 
     | 
     | 
    		intptr = &options->number_of_password_prompts;  | 
    
    
    972  | 
     | 
     | 
    		goto parse_int;  | 
    
    
    973  | 
     | 
     | 
     | 
    
    
    974  | 
     | 
     | 
    	case oRekeyLimit:  | 
    
    
    975  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    976  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    977  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, | 
    
    
    978  | 
     | 
     | 
    			    linenum);  | 
    
    
    979  | 
     | 
     | 
    		if (strcmp(arg, "default") == 0) { | 
    
    
    980  | 
     | 
     | 
    			val64 = 0;  | 
    
    
    981  | 
     | 
     | 
    		} else { | 
    
    
    982  | 
     | 
     | 
    			if (scan_scaled(arg, &val64) == -1)  | 
    
    
    983  | 
     | 
     | 
    				fatal("%.200s line %d: Bad number '%s': %s", | 
    
    
    984  | 
     | 
     | 
    				    filename, linenum, arg, strerror(errno));  | 
    
    
    985  | 
     | 
     | 
    			if (val64 != 0 && val64 < 16)  | 
    
    
    986  | 
     | 
     | 
    				fatal("%.200s line %d: RekeyLimit too small", | 
    
    
    987  | 
     | 
     | 
    				    filename, linenum);  | 
    
    
    988  | 
     | 
     | 
    		}  | 
    
    
    989  | 
     | 
     | 
    		if (*activep && options->rekey_limit == -1)  | 
    
    
    990  | 
     | 
     | 
    			options->rekey_limit = val64;  | 
    
    
    991  | 
     | 
     | 
    		if (s != NULL) { /* optional rekey interval present */ | 
    
    
    992  | 
     | 
     | 
    			if (strcmp(s, "none") == 0) { | 
    
    
    993  | 
     | 
     | 
    				(void)strdelim(&s);	/* discard */  | 
    
    
    994  | 
     | 
     | 
    				break;  | 
    
    
    995  | 
     | 
     | 
    			}  | 
    
    
    996  | 
     | 
     | 
    			intptr = &options->rekey_interval;  | 
    
    
    997  | 
     | 
     | 
    			goto parse_time;  | 
    
    
    998  | 
     | 
     | 
    		}  | 
    
    
    999  | 
     | 
     | 
    		break;  | 
    
    
    1000  | 
     | 
     | 
     | 
    
    
    1001  | 
     | 
     | 
    	case oIdentityFile:  | 
    
    
    1002  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1003  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1004  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1005  | 
     | 
     | 
    		if (*activep) { | 
    
    
    1006  | 
     | 
     | 
    			intptr = &options->num_identity_files;  | 
    
    
    1007  | 
     | 
     | 
    			if (*intptr >= SSH_MAX_IDENTITY_FILES)  | 
    
    
    1008  | 
     | 
     | 
    				fatal("%.200s line %d: Too many identity files specified (max %d).", | 
    
    
    1009  | 
     | 
     | 
    				    filename, linenum, SSH_MAX_IDENTITY_FILES);  | 
    
    
    1010  | 
     | 
     | 
    			add_identity_file(options, NULL,  | 
    
    
    1011  | 
     | 
     | 
    			    arg, flags & SSHCONF_USERCONF);  | 
    
    
    1012  | 
     | 
     | 
    		}  | 
    
    
    1013  | 
     | 
     | 
    		break;  | 
    
    
    1014  | 
     | 
     | 
     | 
    
    
    1015  | 
     | 
     | 
    	case oCertificateFile:  | 
    
    
    1016  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1017  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1018  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1019  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1020  | 
     | 
     | 
    		if (*activep) { | 
    
    
    1021  | 
     | 
     | 
    			intptr = &options->num_certificate_files;  | 
    
    
    1022  | 
     | 
     | 
    			if (*intptr >= SSH_MAX_CERTIFICATE_FILES) { | 
    
    
    1023  | 
     | 
     | 
    				fatal("%.200s line %d: Too many certificate " | 
    
    
    1024  | 
     | 
     | 
    				    "files specified (max %d).",  | 
    
    
    1025  | 
     | 
     | 
    				    filename, linenum,  | 
    
    
    1026  | 
     | 
     | 
    				    SSH_MAX_CERTIFICATE_FILES);  | 
    
    
    1027  | 
     | 
     | 
    			}  | 
    
    
    1028  | 
     | 
     | 
    			add_certificate_file(options, arg,  | 
    
    
    1029  | 
     | 
     | 
    			    flags & SSHCONF_USERCONF);  | 
    
    
    1030  | 
     | 
     | 
    		}  | 
    
    
    1031  | 
     | 
     | 
    		break;  | 
    
    
    1032  | 
     | 
     | 
     | 
    
    
    1033  | 
     | 
     | 
    	case oXAuthLocation:  | 
    
    
    1034  | 
     | 
     | 
    		charptr=&options->xauth_location;  | 
    
    
    1035  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1036  | 
     | 
     | 
     | 
    
    
    1037  | 
     | 
     | 
    	case oUser:  | 
    
    
    1038  | 
     | 
     | 
    		charptr = &options->user;  | 
    
    
    1039  | 
     | 
     | 
    parse_string:  | 
    
    
    1040  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1041  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1042  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1043  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1044  | 
     | 
     | 
    		if (*activep && *charptr == NULL)  | 
    
    
    1045  | 
     | 
     | 
    			*charptr = xstrdup(arg);  | 
    
    
    1046  | 
     | 
     | 
    		break;  | 
    
    
    1047  | 
     | 
     | 
     | 
    
    
    1048  | 
     | 
     | 
    	case oGlobalKnownHostsFile:  | 
    
    
    1049  | 
     | 
     | 
    		cpptr = (char **)&options->system_hostfiles;  | 
    
    
    1050  | 
     | 
     | 
    		uintptr = &options->num_system_hostfiles;  | 
    
    
    1051  | 
     | 
     | 
    		max_entries = SSH_MAX_HOSTS_FILES;  | 
    
    
    1052  | 
     | 
     | 
    parse_char_array:  | 
    
    
    1053  | 
     | 
     | 
    		if (*activep && *uintptr == 0) { | 
    
    
    1054  | 
     | 
     | 
    			while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1055  | 
     | 
     | 
    				if ((*uintptr) >= max_entries)  | 
    
    
    1056  | 
     | 
     | 
    					fatal("%s line %d: " | 
    
    
    1057  | 
     | 
     | 
    					    "too many authorized keys files.",  | 
    
    
    1058  | 
     | 
     | 
    					    filename, linenum);  | 
    
    
    1059  | 
     | 
     | 
    				cpptr[(*uintptr)++] = xstrdup(arg);  | 
    
    
    1060  | 
     | 
     | 
    			}  | 
    
    
    1061  | 
     | 
     | 
    		}  | 
    
    
    1062  | 
     | 
     | 
    		return 0;  | 
    
    
    1063  | 
     | 
     | 
     | 
    
    
    1064  | 
     | 
     | 
    	case oUserKnownHostsFile:  | 
    
    
    1065  | 
     | 
     | 
    		cpptr = (char **)&options->user_hostfiles;  | 
    
    
    1066  | 
     | 
     | 
    		uintptr = &options->num_user_hostfiles;  | 
    
    
    1067  | 
     | 
     | 
    		max_entries = SSH_MAX_HOSTS_FILES;  | 
    
    
    1068  | 
     | 
     | 
    		goto parse_char_array;  | 
    
    
    1069  | 
     | 
     | 
     | 
    
    
    1070  | 
     | 
     | 
    	case oHostName:  | 
    
    
    1071  | 
     | 
     | 
    		charptr = &options->hostname;  | 
    
    
    1072  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1073  | 
     | 
     | 
     | 
    
    
    1074  | 
     | 
     | 
    	case oHostKeyAlias:  | 
    
    
    1075  | 
     | 
     | 
    		charptr = &options->host_key_alias;  | 
    
    
    1076  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1077  | 
     | 
     | 
     | 
    
    
    1078  | 
     | 
     | 
    	case oPreferredAuthentications:  | 
    
    
    1079  | 
     | 
     | 
    		charptr = &options->preferred_authentications;  | 
    
    
    1080  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1081  | 
     | 
     | 
     | 
    
    
    1082  | 
     | 
     | 
    	case oBindAddress:  | 
    
    
    1083  | 
     | 
     | 
    		charptr = &options->bind_address;  | 
    
    
    1084  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1085  | 
     | 
     | 
     | 
    
    
    1086  | 
     | 
     | 
    	case oPKCS11Provider:  | 
    
    
    1087  | 
     | 
     | 
    		charptr = &options->pkcs11_provider;  | 
    
    
    1088  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1089  | 
     | 
     | 
     | 
    
    
    1090  | 
     | 
     | 
    	case oProxyCommand:  | 
    
    
    1091  | 
     | 
     | 
    		charptr = &options->proxy_command;  | 
    
    
    1092  | 
     | 
     | 
    		/* Ignore ProxyCommand if ProxyJump already specified */  | 
    
    
    1093  | 
     | 
     | 
    		if (options->jump_host != NULL)  | 
    
    
    1094  | 
     | 
     | 
    			charptr = &options->jump_host; /* Skip below */  | 
    
    
    1095  | 
     | 
     | 
    parse_command:  | 
    
    
    1096  | 
     | 
     | 
    		if (s == NULL)  | 
    
    
    1097  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1098  | 
     | 
     | 
    		len = strspn(s, WHITESPACE "=");  | 
    
    
    1099  | 
     | 
     | 
    		if (*activep && *charptr == NULL)  | 
    
    
    1100  | 
     | 
     | 
    			*charptr = xstrdup(s + len);  | 
    
    
    1101  | 
     | 
     | 
    		return 0;  | 
    
    
    1102  | 
     | 
     | 
     | 
    
    
    1103  | 
     | 
     | 
    	case oProxyJump:  | 
    
    
    1104  | 
     | 
     | 
    		if (s == NULL) { | 
    
    
    1105  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1106  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1107  | 
     | 
     | 
    		}  | 
    
    
    1108  | 
     | 
     | 
    		len = strspn(s, WHITESPACE "=");  | 
    
    
    1109  | 
     | 
     | 
    		if (parse_jump(s + len, options, *activep) == -1) { | 
    
    
    1110  | 
     | 
     | 
    			fatal("%.200s line %d: Invalid ProxyJump \"%s\"", | 
    
    
    1111  | 
     | 
     | 
    			    filename, linenum, s + len);  | 
    
    
    1112  | 
     | 
     | 
    		}  | 
    
    
    1113  | 
     | 
     | 
    		return 0;  | 
    
    
    1114  | 
     | 
     | 
     | 
    
    
    1115  | 
     | 
     | 
    	case oPort:  | 
    
    
    1116  | 
     | 
     | 
    		intptr = &options->port;  | 
    
    
    1117  | 
     | 
     | 
    parse_int:  | 
    
    
    1118  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1119  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1120  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1121  | 
     | 
     | 
    		if (arg[0] < '0' || arg[0] > '9')  | 
    
    
    1122  | 
     | 
     | 
    			fatal("%.200s line %d: Bad number.", filename, linenum); | 
    
    
    1123  | 
     | 
     | 
     | 
    
    
    1124  | 
     | 
     | 
    		/* Octal, decimal, or hex format? */  | 
    
    
    1125  | 
     | 
     | 
    		value = strtol(arg, &endofnumber, 0);  | 
    
    
    1126  | 
     | 
     | 
    		if (arg == endofnumber)  | 
    
    
    1127  | 
     | 
     | 
    			fatal("%.200s line %d: Bad number.", filename, linenum); | 
    
    
    1128  | 
     | 
     | 
    		if (*activep && *intptr == -1)  | 
    
    
    1129  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    1130  | 
     | 
     | 
    		break;  | 
    
    
    1131  | 
     | 
     | 
     | 
    
    
    1132  | 
     | 
     | 
    	case oConnectionAttempts:  | 
    
    
    1133  | 
     | 
     | 
    		intptr = &options->connection_attempts;  | 
    
    
    1134  | 
     | 
     | 
    		goto parse_int;  | 
    
    
    1135  | 
     | 
     | 
     | 
    
    
    1136  | 
     | 
     | 
    	case oCiphers:  | 
    
    
    1137  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1138  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1139  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1140  | 
     | 
     | 
    		if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))  | 
    
    
    1141  | 
     | 
     | 
    			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", | 
    
    
    1142  | 
     | 
     | 
    			    filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1143  | 
     | 
     | 
    		if (*activep && options->ciphers == NULL)  | 
    
    
    1144  | 
     | 
     | 
    			options->ciphers = xstrdup(arg);  | 
    
    
    1145  | 
     | 
     | 
    		break;  | 
    
    
    1146  | 
     | 
     | 
     | 
    
    
    1147  | 
     | 
     | 
    	case oMacs:  | 
    
    
    1148  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1149  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1150  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1151  | 
     | 
     | 
    		if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))  | 
    
    
    1152  | 
     | 
     | 
    			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", | 
    
    
    1153  | 
     | 
     | 
    			    filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1154  | 
     | 
     | 
    		if (*activep && options->macs == NULL)  | 
    
    
    1155  | 
     | 
     | 
    			options->macs = xstrdup(arg);  | 
    
    
    1156  | 
     | 
     | 
    		break;  | 
    
    
    1157  | 
     | 
     | 
     | 
    
    
    1158  | 
     | 
     | 
    	case oKexAlgorithms:  | 
    
    
    1159  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1160  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1161  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1162  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1163  | 
     | 
     | 
    		if (*arg != '-' &&  | 
    
    
    1164  | 
     | 
     | 
    		    !kex_names_valid(*arg == '+' ? arg + 1 : arg))  | 
    
    
    1165  | 
     | 
     | 
    			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", | 
    
    
    1166  | 
     | 
     | 
    			    filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1167  | 
     | 
     | 
    		if (*activep && options->kex_algorithms == NULL)  | 
    
    
    1168  | 
     | 
     | 
    			options->kex_algorithms = xstrdup(arg);  | 
    
    
    1169  | 
     | 
     | 
    		break;  | 
    
    
    1170  | 
     | 
     | 
     | 
    
    
    1171  | 
     | 
     | 
    	case oHostKeyAlgorithms:  | 
    
    
    1172  | 
     | 
     | 
    		charptr = &options->hostkeyalgorithms;  | 
    
    
    1173  | 
     | 
     | 
    parse_keytypes:  | 
    
    
    1174  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1175  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1176  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1177  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1178  | 
     | 
     | 
    		if (*arg != '-' &&  | 
    
    
    1179  | 
     | 
     | 
    		    !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))  | 
    
    
    1180  | 
     | 
     | 
    			fatal("%s line %d: Bad key types '%s'.", | 
    
    
    1181  | 
     | 
     | 
    				filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1182  | 
     | 
     | 
    		if (*activep && *charptr == NULL)  | 
    
    
    1183  | 
     | 
     | 
    			*charptr = xstrdup(arg);  | 
    
    
    1184  | 
     | 
     | 
    		break;  | 
    
    
    1185  | 
     | 
     | 
     | 
    
    
    1186  | 
     | 
     | 
    	case oLogLevel:  | 
    
    
    1187  | 
     | 
     | 
    		log_level_ptr = &options->log_level;  | 
    
    
    1188  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1189  | 
     | 
     | 
    		value = log_level_number(arg);  | 
    
    
    1190  | 
     | 
     | 
    		if (value == SYSLOG_LEVEL_NOT_SET)  | 
    
    
    1191  | 
     | 
     | 
    			fatal("%.200s line %d: unsupported log level '%s'", | 
    
    
    1192  | 
     | 
     | 
    			    filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1193  | 
     | 
     | 
    		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)  | 
    
    
    1194  | 
     | 
     | 
    			*log_level_ptr = (LogLevel) value;  | 
    
    
    1195  | 
     | 
     | 
    		break;  | 
    
    
    1196  | 
     | 
     | 
     | 
    
    
    1197  | 
     | 
     | 
    	case oLogFacility:  | 
    
    
    1198  | 
     | 
     | 
    		log_facility_ptr = &options->log_facility;  | 
    
    
    1199  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1200  | 
     | 
     | 
    		value = log_facility_number(arg);  | 
    
    
    1201  | 
     | 
     | 
    		if (value == SYSLOG_FACILITY_NOT_SET)  | 
    
    
    1202  | 
     | 
     | 
    			fatal("%.200s line %d: unsupported log facility '%s'", | 
    
    
    1203  | 
     | 
     | 
    			    filename, linenum, arg ? arg : "<NONE>");  | 
    
    
    1204  | 
     | 
     | 
    		if (*log_facility_ptr == -1)  | 
    
    
    1205  | 
     | 
     | 
    			*log_facility_ptr = (SyslogFacility) value;  | 
    
    
    1206  | 
     | 
     | 
    		break;  | 
    
    
    1207  | 
     | 
     | 
     | 
    
    
    1208  | 
     | 
     | 
    	case oLocalForward:  | 
    
    
    1209  | 
     | 
     | 
    	case oRemoteForward:  | 
    
    
    1210  | 
     | 
     | 
    	case oDynamicForward:  | 
    
    
    1211  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1212  | 
     | 
     | 
    		if (arg == NULL || *arg == '\0')  | 
    
    
    1213  | 
     | 
     | 
    			fatal("%.200s line %d: Missing port argument.", | 
    
    
    1214  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1215  | 
     | 
     | 
     | 
    
    
    1216  | 
     | 
     | 
    		remotefwd = (opcode == oRemoteForward);  | 
    
    
    1217  | 
     | 
     | 
    		dynamicfwd = (opcode == oDynamicForward);  | 
    
    
    1218  | 
     | 
     | 
     | 
    
    
    1219  | 
     | 
     | 
    		if (!dynamicfwd) { | 
    
    
    1220  | 
     | 
     | 
    			arg2 = strdelim(&s);  | 
    
    
    1221  | 
     | 
     | 
    			if (arg2 == NULL || *arg2 == '\0') { | 
    
    
    1222  | 
     | 
     | 
    				if (remotefwd)  | 
    
    
    1223  | 
     | 
     | 
    					dynamicfwd = 1;  | 
    
    
    1224  | 
     | 
     | 
    				else  | 
    
    
    1225  | 
     | 
     | 
    					fatal("%.200s line %d: Missing target " | 
    
    
    1226  | 
     | 
     | 
    					    "argument.", filename, linenum);  | 
    
    
    1227  | 
     | 
     | 
    			} else { | 
    
    
    1228  | 
     | 
     | 
    				/* construct a string for parse_forward */  | 
    
    
    1229  | 
     | 
     | 
    				snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,  | 
    
    
    1230  | 
     | 
     | 
    				    arg2);  | 
    
    
    1231  | 
     | 
     | 
    			}  | 
    
    
    1232  | 
     | 
     | 
    		}  | 
    
    
    1233  | 
     | 
     | 
    		if (dynamicfwd)  | 
    
    
    1234  | 
     | 
     | 
    			strlcpy(fwdarg, arg, sizeof(fwdarg));  | 
    
    
    1235  | 
     | 
     | 
     | 
    
    
    1236  | 
     | 
     | 
    		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)  | 
    
    
    1237  | 
     | 
     | 
    			fatal("%.200s line %d: Bad forwarding specification.", | 
    
    
    1238  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1239  | 
     | 
     | 
     | 
    
    
    1240  | 
     | 
     | 
    		if (*activep) { | 
    
    
    1241  | 
     | 
     | 
    			if (remotefwd) { | 
    
    
    1242  | 
     | 
     | 
    				add_remote_forward(options, &fwd);  | 
    
    
    1243  | 
     | 
     | 
    			} else { | 
    
    
    1244  | 
     | 
     | 
    				add_local_forward(options, &fwd);  | 
    
    
    1245  | 
     | 
     | 
    			}  | 
    
    
    1246  | 
     | 
     | 
    		}  | 
    
    
    1247  | 
     | 
     | 
    		break;  | 
    
    
    1248  | 
     | 
     | 
     | 
    
    
    1249  | 
     | 
     | 
    	case oClearAllForwardings:  | 
    
    
    1250  | 
     | 
     | 
    		intptr = &options->clear_forwardings;  | 
    
    
    1251  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1252  | 
     | 
     | 
     | 
    
    
    1253  | 
     | 
     | 
    	case oHost:  | 
    
    
    1254  | 
     | 
     | 
    		if (cmdline)  | 
    
    
    1255  | 
     | 
     | 
    			fatal("Host directive not supported as a command-line " | 
    
    
    1256  | 
     | 
     | 
    			    "option");  | 
    
    
    1257  | 
     | 
     | 
    		*activep = 0;  | 
    
    
    1258  | 
     | 
     | 
    		arg2 = NULL;  | 
    
    
    1259  | 
     | 
     | 
    		while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1260  | 
     | 
     | 
    			if ((flags & SSHCONF_NEVERMATCH) != 0)  | 
    
    
    1261  | 
     | 
     | 
    				break;  | 
    
    
    1262  | 
     | 
     | 
    			negated = *arg == '!';  | 
    
    
    1263  | 
     | 
     | 
    			if (negated)  | 
    
    
    1264  | 
     | 
     | 
    				arg++;  | 
    
    
    1265  | 
     | 
     | 
    			if (match_pattern(host, arg)) { | 
    
    
    1266  | 
     | 
     | 
    				if (negated) { | 
    
    
    1267  | 
     | 
     | 
    					debug("%.200s line %d: Skipping Host " | 
    
    
    1268  | 
     | 
     | 
    					    "block because of negated match "  | 
    
    
    1269  | 
     | 
     | 
    					    "for %.100s", filename, linenum,  | 
    
    
    1270  | 
     | 
     | 
    					    arg);  | 
    
    
    1271  | 
     | 
     | 
    					*activep = 0;  | 
    
    
    1272  | 
     | 
     | 
    					break;  | 
    
    
    1273  | 
     | 
     | 
    				}  | 
    
    
    1274  | 
     | 
     | 
    				if (!*activep)  | 
    
    
    1275  | 
     | 
     | 
    					arg2 = arg; /* logged below */  | 
    
    
    1276  | 
     | 
     | 
    				*activep = 1;  | 
    
    
    1277  | 
     | 
     | 
    			}  | 
    
    
    1278  | 
     | 
     | 
    		}  | 
    
    
    1279  | 
     | 
     | 
    		if (*activep)  | 
    
    
    1280  | 
     | 
     | 
    			debug("%.200s line %d: Applying options for %.100s", | 
    
    
    1281  | 
     | 
     | 
    			    filename, linenum, arg2);  | 
    
    
    1282  | 
     | 
     | 
    		/* Avoid garbage check below, as strdelim is done. */  | 
    
    
    1283  | 
     | 
     | 
    		return 0;  | 
    
    
    1284  | 
     | 
     | 
     | 
    
    
    1285  | 
     | 
     | 
    	case oMatch:  | 
    
    
    1286  | 
     | 
     | 
    		if (cmdline)  | 
    
    
    1287  | 
     | 
     | 
    			fatal("Host directive not supported as a command-line " | 
    
    
    1288  | 
     | 
     | 
    			    "option");  | 
    
    
    1289  | 
     | 
     | 
    		value = match_cfg_line(options, &s, pw, host, original_host,  | 
    
    
    1290  | 
     | 
     | 
    		    flags & SSHCONF_POSTCANON, filename, linenum);  | 
    
    
    1291  | 
     | 
     | 
    		if (value < 0)  | 
    
    
    1292  | 
     | 
     | 
    			fatal("%.200s line %d: Bad Match condition", filename, | 
    
    
    1293  | 
     | 
     | 
    			    linenum);  | 
    
    
    1294  | 
     | 
     | 
    		*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;  | 
    
    
    1295  | 
     | 
     | 
    		break;  | 
    
    
    1296  | 
     | 
     | 
     | 
    
    
    1297  | 
     | 
     | 
    	case oEscapeChar:  | 
    
    
    1298  | 
     | 
     | 
    		intptr = &options->escape_char;  | 
    
    
    1299  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1300  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1301  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1302  | 
     | 
     | 
    		if (strcmp(arg, "none") == 0)  | 
    
    
    1303  | 
     | 
     | 
    			value = SSH_ESCAPECHAR_NONE;  | 
    
    
    1304  | 
     | 
     | 
    		else if (arg[1] == '\0')  | 
    
    
    1305  | 
     | 
     | 
    			value = (u_char) arg[0];  | 
    
    
    1306  | 
     | 
     | 
    		else if (arg[0] == '^' && arg[2] == 0 &&  | 
    
    
    1307  | 
     | 
     | 
    		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)  | 
    
    
    1308  | 
     | 
     | 
    			value = (u_char) arg[1] & 31;  | 
    
    
    1309  | 
     | 
     | 
    		else { | 
    
    
    1310  | 
     | 
     | 
    			fatal("%.200s line %d: Bad escape character.", | 
    
    
    1311  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1312  | 
     | 
     | 
    			/* NOTREACHED */  | 
    
    
    1313  | 
     | 
     | 
    			value = 0;	/* Avoid compiler warning. */  | 
    
    
    1314  | 
     | 
     | 
    		}  | 
    
    
    1315  | 
     | 
     | 
    		if (*activep && *intptr == -1)  | 
    
    
    1316  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    1317  | 
     | 
     | 
    		break;  | 
    
    
    1318  | 
     | 
     | 
     | 
    
    
    1319  | 
     | 
     | 
    	case oAddressFamily:  | 
    
    
    1320  | 
     | 
     | 
    		intptr = &options->address_family;  | 
    
    
    1321  | 
     | 
     | 
    		multistate_ptr = multistate_addressfamily;  | 
    
    
    1322  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1323  | 
     | 
     | 
     | 
    
    
    1324  | 
     | 
     | 
    	case oEnableSSHKeysign:  | 
    
    
    1325  | 
     | 
     | 
    		intptr = &options->enable_ssh_keysign;  | 
    
    
    1326  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1327  | 
     | 
     | 
     | 
    
    
    1328  | 
     | 
     | 
    	case oIdentitiesOnly:  | 
    
    
    1329  | 
     | 
     | 
    		intptr = &options->identities_only;  | 
    
    
    1330  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1331  | 
     | 
     | 
     | 
    
    
    1332  | 
     | 
     | 
    	case oServerAliveInterval:  | 
    
    
    1333  | 
     | 
     | 
    		intptr = &options->server_alive_interval;  | 
    
    
    1334  | 
     | 
     | 
    		goto parse_time;  | 
    
    
    1335  | 
     | 
     | 
     | 
    
    
    1336  | 
     | 
     | 
    	case oServerAliveCountMax:  | 
    
    
    1337  | 
     | 
     | 
    		intptr = &options->server_alive_count_max;  | 
    
    
    1338  | 
     | 
     | 
    		goto parse_int;  | 
    
    
    1339  | 
     | 
     | 
     | 
    
    
    1340  | 
     | 
     | 
    	case oSendEnv:  | 
    
    
    1341  | 
     | 
     | 
    		while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1342  | 
     | 
     | 
    			if (strchr(arg, '=') != NULL)  | 
    
    
    1343  | 
     | 
     | 
    				fatal("%s line %d: Invalid environment name.", | 
    
    
    1344  | 
     | 
     | 
    				    filename, linenum);  | 
    
    
    1345  | 
     | 
     | 
    			if (!*activep)  | 
    
    
    1346  | 
     | 
     | 
    				continue;  | 
    
    
    1347  | 
     | 
     | 
    			if (options->num_send_env >= MAX_SEND_ENV)  | 
    
    
    1348  | 
     | 
     | 
    				fatal("%s line %d: too many send env.", | 
    
    
    1349  | 
     | 
     | 
    				    filename, linenum);  | 
    
    
    1350  | 
     | 
     | 
    			options->send_env[options->num_send_env++] =  | 
    
    
    1351  | 
     | 
     | 
    			    xstrdup(arg);  | 
    
    
    1352  | 
     | 
     | 
    		}  | 
    
    
    1353  | 
     | 
     | 
    		break;  | 
    
    
    1354  | 
     | 
     | 
     | 
    
    
    1355  | 
     | 
     | 
    	case oControlPath:  | 
    
    
    1356  | 
     | 
     | 
    		charptr = &options->control_path;  | 
    
    
    1357  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1358  | 
     | 
     | 
     | 
    
    
    1359  | 
     | 
     | 
    	case oControlMaster:  | 
    
    
    1360  | 
     | 
     | 
    		intptr = &options->control_master;  | 
    
    
    1361  | 
     | 
     | 
    		multistate_ptr = multistate_controlmaster;  | 
    
    
    1362  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1363  | 
     | 
     | 
     | 
    
    
    1364  | 
     | 
     | 
    	case oControlPersist:  | 
    
    
    1365  | 
     | 
     | 
    		/* no/false/yes/true, or a time spec */  | 
    
    
    1366  | 
     | 
     | 
    		intptr = &options->control_persist;  | 
    
    
    1367  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1368  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1369  | 
     | 
     | 
    			fatal("%.200s line %d: Missing ControlPersist" | 
    
    
    1370  | 
     | 
     | 
    			    " argument.", filename, linenum);  | 
    
    
    1371  | 
     | 
     | 
    		value = 0;  | 
    
    
    1372  | 
     | 
     | 
    		value2 = 0;	/* timeout */  | 
    
    
    1373  | 
     | 
     | 
    		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)  | 
    
    
    1374  | 
     | 
     | 
    			value = 0;  | 
    
    
    1375  | 
     | 
     | 
    		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)  | 
    
    
    1376  | 
     | 
     | 
    			value = 1;  | 
    
    
    1377  | 
     | 
     | 
    		else if ((value2 = convtime(arg)) >= 0)  | 
    
    
    1378  | 
     | 
     | 
    			value = 1;  | 
    
    
    1379  | 
     | 
     | 
    		else  | 
    
    
    1380  | 
     | 
     | 
    			fatal("%.200s line %d: Bad ControlPersist argument.", | 
    
    
    1381  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1382  | 
     | 
     | 
    		if (*activep && *intptr == -1) { | 
    
    
    1383  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    1384  | 
     | 
     | 
    			options->control_persist_timeout = value2;  | 
    
    
    1385  | 
     | 
     | 
    		}  | 
    
    
    1386  | 
     | 
     | 
    		break;  | 
    
    
    1387  | 
     | 
     | 
     | 
    
    
    1388  | 
     | 
     | 
    	case oHashKnownHosts:  | 
    
    
    1389  | 
     | 
     | 
    		intptr = &options->hash_known_hosts;  | 
    
    
    1390  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1391  | 
     | 
     | 
     | 
    
    
    1392  | 
     | 
     | 
    	case oTunnel:  | 
    
    
    1393  | 
     | 
     | 
    		intptr = &options->tun_open;  | 
    
    
    1394  | 
     | 
     | 
    		multistate_ptr = multistate_tunnel;  | 
    
    
    1395  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1396  | 
     | 
     | 
     | 
    
    
    1397  | 
     | 
     | 
    	case oTunnelDevice:  | 
    
    
    1398  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1399  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1400  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", filename, linenum); | 
    
    
    1401  | 
     | 
     | 
    		value = a2tun(arg, &value2);  | 
    
    
    1402  | 
     | 
     | 
    		if (value == SSH_TUNID_ERR)  | 
    
    
    1403  | 
     | 
     | 
    			fatal("%.200s line %d: Bad tun device.", filename, linenum); | 
    
    
    1404  | 
     | 
     | 
    		if (*activep) { | 
    
    
    1405  | 
     | 
     | 
    			options->tun_local = value;  | 
    
    
    1406  | 
     | 
     | 
    			options->tun_remote = value2;  | 
    
    
    1407  | 
     | 
     | 
    		}  | 
    
    
    1408  | 
     | 
     | 
    		break;  | 
    
    
    1409  | 
     | 
     | 
     | 
    
    
    1410  | 
     | 
     | 
    	case oLocalCommand:  | 
    
    
    1411  | 
     | 
     | 
    		charptr = &options->local_command;  | 
    
    
    1412  | 
     | 
     | 
    		goto parse_command;  | 
    
    
    1413  | 
     | 
     | 
     | 
    
    
    1414  | 
     | 
     | 
    	case oPermitLocalCommand:  | 
    
    
    1415  | 
     | 
     | 
    		intptr = &options->permit_local_command;  | 
    
    
    1416  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1417  | 
     | 
     | 
     | 
    
    
    1418  | 
     | 
     | 
    	case oRemoteCommand:  | 
    
    
    1419  | 
     | 
     | 
    		charptr = &options->remote_command;  | 
    
    
    1420  | 
     | 
     | 
    		goto parse_command;  | 
    
    
    1421  | 
     | 
     | 
     | 
    
    
    1422  | 
     | 
     | 
    	case oVisualHostKey:  | 
    
    
    1423  | 
     | 
     | 
    		intptr = &options->visual_host_key;  | 
    
    
    1424  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1425  | 
     | 
     | 
     | 
    
    
    1426  | 
     | 
     | 
    	case oInclude:  | 
    
    
    1427  | 
     | 
     | 
    		if (cmdline)  | 
    
    
    1428  | 
     | 
     | 
    			fatal("Include directive not supported as a " | 
    
    
    1429  | 
     | 
     | 
    			    "command-line option");  | 
    
    
    1430  | 
     | 
     | 
    		value = 0;  | 
    
    
    1431  | 
     | 
     | 
    		while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1432  | 
     | 
     | 
    			/*  | 
    
    
    1433  | 
     | 
     | 
    			 * Ensure all paths are anchored. User configuration  | 
    
    
    1434  | 
     | 
     | 
    			 * files may begin with '~/' but system configurations  | 
    
    
    1435  | 
     | 
     | 
    			 * must not. If the path is relative, then treat it  | 
    
    
    1436  | 
     | 
     | 
    			 * as living in ~/.ssh for user configurations or  | 
    
    
    1437  | 
     | 
     | 
    			 * /etc/ssh for system ones.  | 
    
    
    1438  | 
     | 
     | 
    			 */  | 
    
    
    1439  | 
     | 
     | 
    			if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)  | 
    
    
    1440  | 
     | 
     | 
    				fatal("%.200s line %d: bad include path %s.", | 
    
    
    1441  | 
     | 
     | 
    				    filename, linenum, arg);  | 
    
    
    1442  | 
     | 
     | 
    			if (*arg != '/' && *arg != '~') { | 
    
    
    1443  | 
     | 
     | 
    				xasprintf(&arg2, "%s/%s",  | 
    
    
    1444  | 
     | 
     | 
    				    (flags & SSHCONF_USERCONF) ?  | 
    
    
    1445  | 
     | 
     | 
    				    "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);  | 
    
    
    1446  | 
     | 
     | 
    			} else  | 
    
    
    1447  | 
     | 
     | 
    				arg2 = xstrdup(arg);  | 
    
    
    1448  | 
     | 
     | 
    			memset(&gl, 0, sizeof(gl));  | 
    
    
    1449  | 
     | 
     | 
    			r = glob(arg2, GLOB_TILDE, NULL, &gl);  | 
    
    
    1450  | 
     | 
     | 
    			if (r == GLOB_NOMATCH) { | 
    
    
    1451  | 
     | 
     | 
    				debug("%.200s line %d: include %s matched no " | 
    
    
    1452  | 
     | 
     | 
    				    "files",filename, linenum, arg2);  | 
    
    
    1453  | 
     | 
     | 
    				free(arg2);  | 
    
    
    1454  | 
     | 
     | 
    				continue;  | 
    
    
    1455  | 
     | 
     | 
    			} else if (r != 0 || gl.gl_pathc < 0)  | 
    
    
    1456  | 
     | 
     | 
    				fatal("%.200s line %d: glob failed for %s.", | 
    
    
    1457  | 
     | 
     | 
    				    filename, linenum, arg2);  | 
    
    
    1458  | 
     | 
     | 
    			free(arg2);  | 
    
    
    1459  | 
     | 
     | 
    			oactive = *activep;  | 
    
    
    1460  | 
     | 
     | 
    			for (i = 0; i < (u_int)gl.gl_pathc; i++) { | 
    
    
    1461  | 
     | 
     | 
    				debug3("%.200s line %d: Including file %s " | 
    
    
    1462  | 
     | 
     | 
    				    "depth %d%s", filename, linenum,  | 
    
    
    1463  | 
     | 
     | 
    				    gl.gl_pathv[i], depth,  | 
    
    
    1464  | 
     | 
     | 
    				    oactive ? "" : " (parse only)");  | 
    
    
    1465  | 
     | 
     | 
    				r = read_config_file_depth(gl.gl_pathv[i],  | 
    
    
    1466  | 
     | 
     | 
    				    pw, host, original_host, options,  | 
    
    
    1467  | 
     | 
     | 
    				    flags | SSHCONF_CHECKPERM |  | 
    
    
    1468  | 
     | 
     | 
    				    (oactive ? 0 : SSHCONF_NEVERMATCH),  | 
    
    
    1469  | 
     | 
     | 
    				    activep, depth + 1);  | 
    
    
    1470  | 
     | 
     | 
    				if (r != 1 && errno != ENOENT) { | 
    
    
    1471  | 
     | 
     | 
    					fatal("Can't open user config file " | 
    
    
    1472  | 
     | 
     | 
    					    "%.100s: %.100s", gl.gl_pathv[i],  | 
    
    
    1473  | 
     | 
     | 
    					    strerror(errno));  | 
    
    
    1474  | 
     | 
     | 
    				}  | 
    
    
    1475  | 
     | 
     | 
    				/*  | 
    
    
    1476  | 
     | 
     | 
    				 * don't let Match in includes clobber the  | 
    
    
    1477  | 
     | 
     | 
    				 * containing file's Match state.  | 
    
    
    1478  | 
     | 
     | 
    				 */  | 
    
    
    1479  | 
     | 
     | 
    				*activep = oactive;  | 
    
    
    1480  | 
     | 
     | 
    				if (r != 1)  | 
    
    
    1481  | 
     | 
     | 
    					value = -1;  | 
    
    
    1482  | 
     | 
     | 
    			}  | 
    
    
    1483  | 
     | 
     | 
    			globfree(&gl);  | 
    
    
    1484  | 
     | 
     | 
    		}  | 
    
    
    1485  | 
     | 
     | 
    		if (value != 0)  | 
    
    
    1486  | 
     | 
     | 
    			return value;  | 
    
    
    1487  | 
     | 
     | 
    		break;  | 
    
    
    1488  | 
     | 
     | 
     | 
    
    
    1489  | 
     | 
     | 
    	case oIPQoS:  | 
    
    
    1490  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1491  | 
     | 
     | 
    		if ((value = parse_ipqos(arg)) == -1)  | 
    
    
    1492  | 
     | 
     | 
    			fatal("%s line %d: Bad IPQoS value: %s", | 
    
    
    1493  | 
     | 
     | 
    			    filename, linenum, arg);  | 
    
    
    1494  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1495  | 
     | 
     | 
    		if (arg == NULL)  | 
    
    
    1496  | 
     | 
     | 
    			value2 = value;  | 
    
    
    1497  | 
     | 
     | 
    		else if ((value2 = parse_ipqos(arg)) == -1)  | 
    
    
    1498  | 
     | 
     | 
    			fatal("%s line %d: Bad IPQoS value: %s", | 
    
    
    1499  | 
     | 
     | 
    			    filename, linenum, arg);  | 
    
    
    1500  | 
     | 
     | 
    		if (*activep) { | 
    
    
    1501  | 
     | 
     | 
    			options->ip_qos_interactive = value;  | 
    
    
    1502  | 
     | 
     | 
    			options->ip_qos_bulk = value2;  | 
    
    
    1503  | 
     | 
     | 
    		}  | 
    
    
    1504  | 
     | 
     | 
    		break;  | 
    
    
    1505  | 
     | 
     | 
     | 
    
    
    1506  | 
     | 
     | 
    	case oRequestTTY:  | 
    
    
    1507  | 
     | 
     | 
    		intptr = &options->request_tty;  | 
    
    
    1508  | 
     | 
     | 
    		multistate_ptr = multistate_requesttty;  | 
    
    
    1509  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1510  | 
     | 
     | 
     | 
    
    
    1511  | 
     | 
     | 
    	case oIgnoreUnknown:  | 
    
    
    1512  | 
     | 
     | 
    		charptr = &options->ignored_unknown;  | 
    
    
    1513  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1514  | 
     | 
     | 
     | 
    
    
    1515  | 
     | 
     | 
    	case oProxyUseFdpass:  | 
    
    
    1516  | 
     | 
     | 
    		intptr = &options->proxy_use_fdpass;  | 
    
    
    1517  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1518  | 
     | 
     | 
     | 
    
    
    1519  | 
     | 
     | 
    	case oCanonicalDomains:  | 
    
    
    1520  | 
     | 
     | 
    		value = options->num_canonical_domains != 0;  | 
    
    
    1521  | 
     | 
     | 
    		while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1522  | 
     | 
     | 
    			const char *errstr;  | 
    
    
    1523  | 
     | 
     | 
    			if (!valid_domain(arg, 1, &errstr)) { | 
    
    
    1524  | 
     | 
     | 
    				fatal("%s line %d: %s", filename, linenum, | 
    
    
    1525  | 
     | 
     | 
    				    errstr);  | 
    
    
    1526  | 
     | 
     | 
    			}  | 
    
    
    1527  | 
     | 
     | 
    			if (!*activep || value)  | 
    
    
    1528  | 
     | 
     | 
    				continue;  | 
    
    
    1529  | 
     | 
     | 
    			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)  | 
    
    
    1530  | 
     | 
     | 
    				fatal("%s line %d: too many hostname suffixes.", | 
    
    
    1531  | 
     | 
     | 
    				    filename, linenum);  | 
    
    
    1532  | 
     | 
     | 
    			options->canonical_domains[  | 
    
    
    1533  | 
     | 
     | 
    			    options->num_canonical_domains++] = xstrdup(arg);  | 
    
    
    1534  | 
     | 
     | 
    		}  | 
    
    
    1535  | 
     | 
     | 
    		break;  | 
    
    
    1536  | 
     | 
     | 
     | 
    
    
    1537  | 
     | 
     | 
    	case oCanonicalizePermittedCNAMEs:  | 
    
    
    1538  | 
     | 
     | 
    		value = options->num_permitted_cnames != 0;  | 
    
    
    1539  | 
     | 
     | 
    		while ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1540  | 
     | 
     | 
    			/* Either '*' for everything or 'list:list' */  | 
    
    
    1541  | 
     | 
     | 
    			if (strcmp(arg, "*") == 0)  | 
    
    
    1542  | 
     | 
     | 
    				arg2 = arg;  | 
    
    
    1543  | 
     | 
     | 
    			else { | 
    
    
    1544  | 
     | 
     | 
    				lowercase(arg);  | 
    
    
    1545  | 
     | 
     | 
    				if ((arg2 = strchr(arg, ':')) == NULL ||  | 
    
    
    1546  | 
     | 
     | 
    				    arg2[1] == '\0') { | 
    
    
    1547  | 
     | 
     | 
    					fatal("%s line %d: " | 
    
    
    1548  | 
     | 
     | 
    					    "Invalid permitted CNAME \"%s\"",  | 
    
    
    1549  | 
     | 
     | 
    					    filename, linenum, arg);  | 
    
    
    1550  | 
     | 
     | 
    				}  | 
    
    
    1551  | 
     | 
     | 
    				*arg2 = '\0';  | 
    
    
    1552  | 
     | 
     | 
    				arg2++;  | 
    
    
    1553  | 
     | 
     | 
    			}  | 
    
    
    1554  | 
     | 
     | 
    			if (!*activep || value)  | 
    
    
    1555  | 
     | 
     | 
    				continue;  | 
    
    
    1556  | 
     | 
     | 
    			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)  | 
    
    
    1557  | 
     | 
     | 
    				fatal("%s line %d: too many permitted CNAMEs.", | 
    
    
    1558  | 
     | 
     | 
    				    filename, linenum);  | 
    
    
    1559  | 
     | 
     | 
    			cname = options->permitted_cnames +  | 
    
    
    1560  | 
     | 
     | 
    			    options->num_permitted_cnames++;  | 
    
    
    1561  | 
     | 
     | 
    			cname->source_list = xstrdup(arg);  | 
    
    
    1562  | 
     | 
     | 
    			cname->target_list = xstrdup(arg2);  | 
    
    
    1563  | 
     | 
     | 
    		}  | 
    
    
    1564  | 
     | 
     | 
    		break;  | 
    
    
    1565  | 
     | 
     | 
     | 
    
    
    1566  | 
     | 
     | 
    	case oCanonicalizeHostname:  | 
    
    
    1567  | 
     | 
     | 
    		intptr = &options->canonicalize_hostname;  | 
    
    
    1568  | 
     | 
     | 
    		multistate_ptr = multistate_canonicalizehostname;  | 
    
    
    1569  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1570  | 
     | 
     | 
     | 
    
    
    1571  | 
     | 
     | 
    	case oCanonicalizeMaxDots:  | 
    
    
    1572  | 
     | 
     | 
    		intptr = &options->canonicalize_max_dots;  | 
    
    
    1573  | 
     | 
     | 
    		goto parse_int;  | 
    
    
    1574  | 
     | 
     | 
     | 
    
    
    1575  | 
     | 
     | 
    	case oCanonicalizeFallbackLocal:  | 
    
    
    1576  | 
     | 
     | 
    		intptr = &options->canonicalize_fallback_local;  | 
    
    
    1577  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1578  | 
     | 
     | 
     | 
    
    
    1579  | 
     | 
     | 
    	case oStreamLocalBindMask:  | 
    
    
    1580  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1581  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1582  | 
     | 
     | 
    			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum); | 
    
    
    1583  | 
     | 
     | 
    		/* Parse mode in octal format */  | 
    
    
    1584  | 
     | 
     | 
    		value = strtol(arg, &endofnumber, 8);  | 
    
    
    1585  | 
     | 
     | 
    		if (arg == endofnumber || value < 0 || value > 0777)  | 
    
    
    1586  | 
     | 
     | 
    			fatal("%.200s line %d: Bad mask.", filename, linenum); | 
    
    
    1587  | 
     | 
     | 
    		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;  | 
    
    
    1588  | 
     | 
     | 
    		break;  | 
    
    
    1589  | 
     | 
     | 
     | 
    
    
    1590  | 
     | 
     | 
    	case oStreamLocalBindUnlink:  | 
    
    
    1591  | 
     | 
     | 
    		intptr = &options->fwd_opts.streamlocal_bind_unlink;  | 
    
    
    1592  | 
     | 
     | 
    		goto parse_flag;  | 
    
    
    1593  | 
     | 
     | 
     | 
    
    
    1594  | 
     | 
     | 
    	case oRevokedHostKeys:  | 
    
    
    1595  | 
     | 
     | 
    		charptr = &options->revoked_host_keys;  | 
    
    
    1596  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1597  | 
     | 
     | 
     | 
    
    
    1598  | 
     | 
     | 
    	case oFingerprintHash:  | 
    
    
    1599  | 
     | 
     | 
    		intptr = &options->fingerprint_hash;  | 
    
    
    1600  | 
     | 
     | 
    		arg = strdelim(&s);  | 
    
    
    1601  | 
     | 
     | 
    		if (!arg || *arg == '\0')  | 
    
    
    1602  | 
     | 
     | 
    			fatal("%.200s line %d: Missing argument.", | 
    
    
    1603  | 
     | 
     | 
    			    filename, linenum);  | 
    
    
    1604  | 
     | 
     | 
    		if ((value = ssh_digest_alg_by_name(arg)) == -1)  | 
    
    
    1605  | 
     | 
     | 
    			fatal("%.200s line %d: Invalid hash algorithm \"%s\".", | 
    
    
    1606  | 
     | 
     | 
    			    filename, linenum, arg);  | 
    
    
    1607  | 
     | 
     | 
    		if (*activep && *intptr == -1)  | 
    
    
    1608  | 
     | 
     | 
    			*intptr = value;  | 
    
    
    1609  | 
     | 
     | 
    		break;  | 
    
    
    1610  | 
     | 
     | 
     | 
    
    
    1611  | 
     | 
     | 
    	case oUpdateHostkeys:  | 
    
    
    1612  | 
     | 
     | 
    		intptr = &options->update_hostkeys;  | 
    
    
    1613  | 
     | 
     | 
    		multistate_ptr = multistate_yesnoask;  | 
    
    
    1614  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1615  | 
     | 
     | 
     | 
    
    
    1616  | 
     | 
     | 
    	case oHostbasedKeyTypes:  | 
    
    
    1617  | 
     | 
     | 
    		charptr = &options->hostbased_key_types;  | 
    
    
    1618  | 
     | 
     | 
    		goto parse_keytypes;  | 
    
    
    1619  | 
     | 
     | 
     | 
    
    
    1620  | 
     | 
     | 
    	case oPubkeyAcceptedKeyTypes:  | 
    
    
    1621  | 
     | 
     | 
    		charptr = &options->pubkey_key_types;  | 
    
    
    1622  | 
     | 
     | 
    		goto parse_keytypes;  | 
    
    
    1623  | 
     | 
     | 
     | 
    
    
    1624  | 
     | 
     | 
    	case oAddKeysToAgent:  | 
    
    
    1625  | 
     | 
     | 
    		intptr = &options->add_keys_to_agent;  | 
    
    
    1626  | 
     | 
     | 
    		multistate_ptr = multistate_yesnoaskconfirm;  | 
    
    
    1627  | 
     | 
     | 
    		goto parse_multistate;  | 
    
    
    1628  | 
     | 
     | 
     | 
    
    
    1629  | 
     | 
     | 
    	case oIdentityAgent:  | 
    
    
    1630  | 
     | 
     | 
    		charptr = &options->identity_agent;  | 
    
    
    1631  | 
     | 
     | 
    		goto parse_string;  | 
    
    
    1632  | 
     | 
     | 
     | 
    
    
    1633  | 
     | 
     | 
    	case oDeprecated:  | 
    
    
    1634  | 
     | 
     | 
    		debug("%s line %d: Deprecated option \"%s\"", | 
    
    
    1635  | 
     | 
     | 
    		    filename, linenum, keyword);  | 
    
    
    1636  | 
     | 
     | 
    		return 0;  | 
    
    
    1637  | 
     | 
     | 
     | 
    
    
    1638  | 
     | 
     | 
    	case oUnsupported:  | 
    
    
    1639  | 
     | 
     | 
    		error("%s line %d: Unsupported option \"%s\"", | 
    
    
    1640  | 
     | 
     | 
    		    filename, linenum, keyword);  | 
    
    
    1641  | 
     | 
     | 
    		return 0;  | 
    
    
    1642  | 
     | 
     | 
     | 
    
    
    1643  | 
     | 
     | 
    	default:  | 
    
    
    1644  | 
     | 
     | 
    		fatal("%s: Unimplemented opcode %d", __func__, opcode); | 
    
    
    1645  | 
     | 
     | 
    	}  | 
    
    
    1646  | 
     | 
     | 
     | 
    
    
    1647  | 
     | 
     | 
    	/* Check that there is no garbage at end of line. */  | 
    
    
    1648  | 
     | 
     | 
    	if ((arg = strdelim(&s)) != NULL && *arg != '\0') { | 
    
    
    1649  | 
     | 
     | 
    		fatal("%.200s line %d: garbage at end of line; \"%.200s\".", | 
    
    
    1650  | 
     | 
     | 
    		    filename, linenum, arg);  | 
    
    
    1651  | 
     | 
     | 
    	}  | 
    
    
    1652  | 
     | 
     | 
    	return 0;  | 
    
    
    1653  | 
     | 
     | 
    }  | 
    
    
    1654  | 
     | 
     | 
     | 
    
    
    1655  | 
     | 
     | 
    /*  | 
    
    
    1656  | 
     | 
     | 
     * Reads the config file and modifies the options accordingly.  Options  | 
    
    
    1657  | 
     | 
     | 
     * should already be initialized before this call.  This never returns if  | 
    
    
    1658  | 
     | 
     | 
     * there is an error.  If the file does not exist, this returns 0.  | 
    
    
    1659  | 
     | 
     | 
     */  | 
    
    
    1660  | 
     | 
     | 
    int  | 
    
    
    1661  | 
     | 
     | 
    read_config_file(const char *filename, struct passwd *pw, const char *host,  | 
    
    
    1662  | 
     | 
     | 
        const char *original_host, Options *options, int flags)  | 
    
    
    1663  | 
     | 
     | 
    { | 
    
    
    1664  | 
     | 
     | 
    	int active = 1;  | 
    
    
    1665  | 
     | 
     | 
     | 
    
    
    1666  | 
     | 
     | 
    	return read_config_file_depth(filename, pw, host, original_host,  | 
    
    
    1667  | 
     | 
     | 
    	    options, flags, &active, 0);  | 
    
    
    1668  | 
     | 
     | 
    }  | 
    
    
    1669  | 
     | 
     | 
     | 
    
    
    1670  | 
     | 
     | 
    #define READCONF_MAX_DEPTH	16  | 
    
    
    1671  | 
     | 
     | 
    static int  | 
    
    
    1672  | 
     | 
     | 
    read_config_file_depth(const char *filename, struct passwd *pw,  | 
    
    
    1673  | 
     | 
     | 
        const char *host, const char *original_host, Options *options,  | 
    
    
    1674  | 
     | 
     | 
        int flags, int *activep, int depth)  | 
    
    
    1675  | 
     | 
     | 
    { | 
    
    
    1676  | 
     | 
     | 
    	FILE *f;  | 
    
    
    1677  | 
     | 
     | 
    	char line[4096];  | 
    
    
    1678  | 
     | 
     | 
    	int linenum;  | 
    
    
    1679  | 
     | 
     | 
    	int bad_options = 0;  | 
    
    
    1680  | 
     | 
     | 
     | 
    
    
    1681  | 
     | 
     | 
    	if (depth < 0 || depth > READCONF_MAX_DEPTH)  | 
    
    
    1682  | 
     | 
     | 
    		fatal("Too many recursive configuration includes"); | 
    
    
    1683  | 
     | 
     | 
     | 
    
    
    1684  | 
     | 
     | 
    	if ((f = fopen(filename, "r")) == NULL)  | 
    
    
    1685  | 
     | 
     | 
    		return 0;  | 
    
    
    1686  | 
     | 
     | 
     | 
    
    
    1687  | 
     | 
     | 
    	if (flags & SSHCONF_CHECKPERM) { | 
    
    
    1688  | 
     | 
     | 
    		struct stat sb;  | 
    
    
    1689  | 
     | 
     | 
     | 
    
    
    1690  | 
     | 
     | 
    		if (fstat(fileno(f), &sb) == -1)  | 
    
    
    1691  | 
     | 
     | 
    			fatal("fstat %s: %s", filename, strerror(errno)); | 
    
    
    1692  | 
     | 
     | 
    		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||  | 
    
    
    1693  | 
     | 
     | 
    		    (sb.st_mode & 022) != 0))  | 
    
    
    1694  | 
     | 
     | 
    			fatal("Bad owner or permissions on %s", filename); | 
    
    
    1695  | 
     | 
     | 
    	}  | 
    
    
    1696  | 
     | 
     | 
     | 
    
    
    1697  | 
     | 
     | 
    	debug("Reading configuration data %.200s", filename); | 
    
    
    1698  | 
     | 
     | 
     | 
    
    
    1699  | 
     | 
     | 
    	/*  | 
    
    
    1700  | 
     | 
     | 
    	 * Mark that we are now processing the options.  This flag is turned  | 
    
    
    1701  | 
     | 
     | 
    	 * on/off by Host specifications.  | 
    
    
    1702  | 
     | 
     | 
    	 */  | 
    
    
    1703  | 
     | 
     | 
    	linenum = 0;  | 
    
    
    1704  | 
     | 
     | 
    	while (fgets(line, sizeof(line), f)) { | 
    
    
    1705  | 
     | 
     | 
    		/* Update line number counter. */  | 
    
    
    1706  | 
     | 
     | 
    		linenum++;  | 
    
    
    1707  | 
     | 
     | 
    		if (strlen(line) == sizeof(line) - 1)  | 
    
    
    1708  | 
     | 
     | 
    			fatal("%s line %d too long", filename, linenum); | 
    
    
    1709  | 
     | 
     | 
    		if (process_config_line_depth(options, pw, host, original_host,  | 
    
    
    1710  | 
     | 
     | 
    		    line, filename, linenum, activep, flags, depth) != 0)  | 
    
    
    1711  | 
     | 
     | 
    			bad_options++;  | 
    
    
    1712  | 
     | 
     | 
    	}  | 
    
    
    1713  | 
     | 
     | 
    	fclose(f);  | 
    
    
    1714  | 
     | 
     | 
    	if (bad_options > 0)  | 
    
    
    1715  | 
     | 
     | 
    		fatal("%s: terminating, %d bad configuration options", | 
    
    
    1716  | 
     | 
     | 
    		    filename, bad_options);  | 
    
    
    1717  | 
     | 
     | 
    	return 1;  | 
    
    
    1718  | 
     | 
     | 
    }  | 
    
    
    1719  | 
     | 
     | 
     | 
    
    
    1720  | 
     | 
     | 
    /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */  | 
    
    
    1721  | 
     | 
     | 
    int  | 
    
    
    1722  | 
     | 
     | 
    option_clear_or_none(const char *o)  | 
    
    
    1723  | 
     | 
     | 
    { | 
    
    
    1724  | 
     | 
     | 
    	return o == NULL || strcasecmp(o, "none") == 0;  | 
    
    
    1725  | 
     | 
     | 
    }  | 
    
    
    1726  | 
     | 
     | 
     | 
    
    
    1727  | 
     | 
     | 
    /*  | 
    
    
    1728  | 
     | 
     | 
     * Initializes options to special values that indicate that they have not yet  | 
    
    
    1729  | 
     | 
     | 
     * been set.  Read_config_file will only set options with this value. Options  | 
    
    
    1730  | 
     | 
     | 
     * are processed in the following order: command line, user config file,  | 
    
    
    1731  | 
     | 
     | 
     * system config file.  Last, fill_default_options is called.  | 
    
    
    1732  | 
     | 
     | 
     */  | 
    
    
    1733  | 
     | 
     | 
     | 
    
    
    1734  | 
     | 
     | 
    void  | 
    
    
    1735  | 
     | 
     | 
    initialize_options(Options * options)  | 
    
    
    1736  | 
     | 
     | 
    { | 
    
    
    1737  | 
     | 
     | 
    	memset(options, 'X', sizeof(*options));  | 
    
    
    1738  | 
     | 
     | 
    	options->forward_agent = -1;  | 
    
    
    1739  | 
     | 
     | 
    	options->forward_x11 = -1;  | 
    
    
    1740  | 
     | 
     | 
    	options->forward_x11_trusted = -1;  | 
    
    
    1741  | 
     | 
     | 
    	options->forward_x11_timeout = -1;  | 
    
    
    1742  | 
     | 
     | 
    	options->stdio_forward_host = NULL;  | 
    
    
    1743  | 
     | 
     | 
    	options->stdio_forward_port = 0;  | 
    
    
    1744  | 
     | 
     | 
    	options->clear_forwardings = -1;  | 
    
    
    1745  | 
     | 
     | 
    	options->exit_on_forward_failure = -1;  | 
    
    
    1746  | 
     | 
     | 
    	options->xauth_location = NULL;  | 
    
    
    1747  | 
     | 
     | 
    	options->fwd_opts.gateway_ports = -1;  | 
    
    
    1748  | 
     | 
     | 
    	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;  | 
    
    
    1749  | 
     | 
     | 
    	options->fwd_opts.streamlocal_bind_unlink = -1;  | 
    
    
    1750  | 
     | 
     | 
    	options->use_privileged_port = -1;  | 
    
    
    1751  | 
     | 
     | 
    	options->pubkey_authentication = -1;  | 
    
    
    1752  | 
     | 
     | 
    	options->challenge_response_authentication = -1;  | 
    
    
    1753  | 
     | 
     | 
    	options->gss_authentication = -1;  | 
    
    
    1754  | 
     | 
     | 
    	options->gss_deleg_creds = -1;  | 
    
    
    1755  | 
     | 
     | 
    	options->password_authentication = -1;  | 
    
    
    1756  | 
     | 
     | 
    	options->kbd_interactive_authentication = -1;  | 
    
    
    1757  | 
     | 
     | 
    	options->kbd_interactive_devices = NULL;  | 
    
    
    1758  | 
     | 
     | 
    	options->hostbased_authentication = -1;  | 
    
    
    1759  | 
     | 
     | 
    	options->batch_mode = -1;  | 
    
    
    1760  | 
     | 
     | 
    	options->check_host_ip = -1;  | 
    
    
    1761  | 
     | 
     | 
    	options->strict_host_key_checking = -1;  | 
    
    
    1762  | 
     | 
     | 
    	options->compression = -1;  | 
    
    
    1763  | 
     | 
     | 
    	options->tcp_keep_alive = -1;  | 
    
    
    1764  | 
     | 
     | 
    	options->port = -1;  | 
    
    
    1765  | 
     | 
     | 
    	options->address_family = -1;  | 
    
    
    1766  | 
     | 
     | 
    	options->connection_attempts = -1;  | 
    
    
    1767  | 
     | 
     | 
    	options->connection_timeout = -1;  | 
    
    
    1768  | 
     | 
     | 
    	options->number_of_password_prompts = -1;  | 
    
    
    1769  | 
     | 
     | 
    	options->ciphers = NULL;  | 
    
    
    1770  | 
     | 
     | 
    	options->macs = NULL;  | 
    
    
    1771  | 
     | 
     | 
    	options->kex_algorithms = NULL;  | 
    
    
    1772  | 
     | 
     | 
    	options->hostkeyalgorithms = NULL;  | 
    
    
    1773  | 
     | 
     | 
    	options->num_identity_files = 0;  | 
    
    
    1774  | 
     | 
     | 
    	options->num_certificate_files = 0;  | 
    
    
    1775  | 
     | 
     | 
    	options->hostname = NULL;  | 
    
    
    1776  | 
     | 
     | 
    	options->host_key_alias = NULL;  | 
    
    
    1777  | 
     | 
     | 
    	options->proxy_command = NULL;  | 
    
    
    1778  | 
     | 
     | 
    	options->jump_user = NULL;  | 
    
    
    1779  | 
     | 
     | 
    	options->jump_host = NULL;  | 
    
    
    1780  | 
     | 
     | 
    	options->jump_port = -1;  | 
    
    
    1781  | 
     | 
     | 
    	options->jump_extra = NULL;  | 
    
    
    1782  | 
     | 
     | 
    	options->user = NULL;  | 
    
    
    1783  | 
     | 
     | 
    	options->escape_char = -1;  | 
    
    
    1784  | 
     | 
     | 
    	options->num_system_hostfiles = 0;  | 
    
    
    1785  | 
     | 
     | 
    	options->num_user_hostfiles = 0;  | 
    
    
    1786  | 
     | 
     | 
    	options->local_forwards = NULL;  | 
    
    
    1787  | 
     | 
     | 
    	options->num_local_forwards = 0;  | 
    
    
    1788  | 
     | 
     | 
    	options->remote_forwards = NULL;  | 
    
    
    1789  | 
     | 
     | 
    	options->num_remote_forwards = 0;  | 
    
    
    1790  | 
     | 
     | 
    	options->log_facility = SYSLOG_FACILITY_NOT_SET;  | 
    
    
    1791  | 
     | 
     | 
    	options->log_level = SYSLOG_LEVEL_NOT_SET;  | 
    
    
    1792  | 
     | 
     | 
    	options->preferred_authentications = NULL;  | 
    
    
    1793  | 
     | 
     | 
    	options->bind_address = NULL;  | 
    
    
    1794  | 
     | 
     | 
    	options->pkcs11_provider = NULL;  | 
    
    
    1795  | 
     | 
     | 
    	options->enable_ssh_keysign = - 1;  | 
    
    
    1796  | 
     | 
     | 
    	options->no_host_authentication_for_localhost = - 1;  | 
    
    
    1797  | 
     | 
     | 
    	options->identities_only = - 1;  | 
    
    
    1798  | 
     | 
     | 
    	options->rekey_limit = - 1;  | 
    
    
    1799  | 
     | 
     | 
    	options->rekey_interval = -1;  | 
    
    
    1800  | 
     | 
     | 
    	options->verify_host_key_dns = -1;  | 
    
    
    1801  | 
     | 
     | 
    	options->server_alive_interval = -1;  | 
    
    
    1802  | 
     | 
     | 
    	options->server_alive_count_max = -1;  | 
    
    
    1803  | 
     | 
     | 
    	options->num_send_env = 0;  | 
    
    
    1804  | 
     | 
     | 
    	options->control_path = NULL;  | 
    
    
    1805  | 
     | 
     | 
    	options->control_master = -1;  | 
    
    
    1806  | 
     | 
     | 
    	options->control_persist = -1;  | 
    
    
    1807  | 
     | 
     | 
    	options->control_persist_timeout = 0;  | 
    
    
    1808  | 
     | 
     | 
    	options->hash_known_hosts = -1;  | 
    
    
    1809  | 
     | 
     | 
    	options->tun_open = -1;  | 
    
    
    1810  | 
     | 
     | 
    	options->tun_local = -1;  | 
    
    
    1811  | 
     | 
     | 
    	options->tun_remote = -1;  | 
    
    
    1812  | 
     | 
     | 
    	options->local_command = NULL;  | 
    
    
    1813  | 
     | 
     | 
    	options->permit_local_command = -1;  | 
    
    
    1814  | 
     | 
     | 
    	options->remote_command = NULL;  | 
    
    
    1815  | 
     | 
     | 
    	options->add_keys_to_agent = -1;  | 
    
    
    1816  | 
     | 
     | 
    	options->identity_agent = NULL;  | 
    
    
    1817  | 
     | 
     | 
    	options->visual_host_key = -1;  | 
    
    
    1818  | 
     | 
     | 
    	options->ip_qos_interactive = -1;  | 
    
    
    1819  | 
     | 
     | 
    	options->ip_qos_bulk = -1;  | 
    
    
    1820  | 
     | 
     | 
    	options->request_tty = -1;  | 
    
    
    1821  | 
     | 
     | 
    	options->proxy_use_fdpass = -1;  | 
    
    
    1822  | 
     | 
     | 
    	options->ignored_unknown = NULL;  | 
    
    
    1823  | 
     | 
     | 
    	options->num_canonical_domains = 0;  | 
    
    
    1824  | 
     | 
     | 
    	options->num_permitted_cnames = 0;  | 
    
    
    1825  | 
     | 
     | 
    	options->canonicalize_max_dots = -1;  | 
    
    
    1826  | 
     | 
     | 
    	options->canonicalize_fallback_local = -1;  | 
    
    
    1827  | 
     | 
     | 
    	options->canonicalize_hostname = -1;  | 
    
    
    1828  | 
     | 
     | 
    	options->revoked_host_keys = NULL;  | 
    
    
    1829  | 
     | 
     | 
    	options->fingerprint_hash = -1;  | 
    
    
    1830  | 
     | 
     | 
    	options->update_hostkeys = -1;  | 
    
    
    1831  | 
     | 
     | 
    	options->hostbased_key_types = NULL;  | 
    
    
    1832  | 
     | 
     | 
    	options->pubkey_key_types = NULL;  | 
    
    
    1833  | 
     | 
     | 
    }  | 
    
    
    1834  | 
     | 
     | 
     | 
    
    
    1835  | 
     | 
     | 
    /*  | 
    
    
    1836  | 
     | 
     | 
     * A petite version of fill_default_options() that just fills the options  | 
    
    
    1837  | 
     | 
     | 
     * needed for hostname canonicalization to proceed.  | 
    
    
    1838  | 
     | 
     | 
     */  | 
    
    
    1839  | 
     | 
     | 
    void  | 
    
    
    1840  | 
     | 
     | 
    fill_default_options_for_canonicalization(Options *options)  | 
    
    
    1841  | 
     | 
     | 
    { | 
    
    
    1842  | 
     | 
     | 
    	if (options->canonicalize_max_dots == -1)  | 
    
    
    1843  | 
     | 
     | 
    		options->canonicalize_max_dots = 1;  | 
    
    
    1844  | 
     | 
     | 
    	if (options->canonicalize_fallback_local == -1)  | 
    
    
    1845  | 
     | 
     | 
    		options->canonicalize_fallback_local = 1;  | 
    
    
    1846  | 
     | 
     | 
    	if (options->canonicalize_hostname == -1)  | 
    
    
    1847  | 
     | 
     | 
    		options->canonicalize_hostname = SSH_CANONICALISE_NO;  | 
    
    
    1848  | 
     | 
     | 
    }  | 
    
    
    1849  | 
     | 
     | 
     | 
    
    
    1850  | 
     | 
     | 
    /*  | 
    
    
    1851  | 
     | 
     | 
     * Called after processing other sources of option data, this fills those  | 
    
    
    1852  | 
     | 
     | 
     * options for which no value has been specified with their default values.  | 
    
    
    1853  | 
     | 
     | 
     */  | 
    
    
    1854  | 
     | 
     | 
    void  | 
    
    
    1855  | 
     | 
     | 
    fill_default_options(Options * options)  | 
    
    
    1856  | 
     | 
     | 
    { | 
    
    
    1857  | 
     | 
     | 
    	if (options->forward_agent == -1)  | 
    
    
    1858  | 
     | 
     | 
    		options->forward_agent = 0;  | 
    
    
    1859  | 
     | 
     | 
    	if (options->forward_x11 == -1)  | 
    
    
    1860  | 
     | 
     | 
    		options->forward_x11 = 0;  | 
    
    
    1861  | 
     | 
     | 
    	if (options->forward_x11_trusted == -1)  | 
    
    
    1862  | 
     | 
     | 
    		options->forward_x11_trusted = 0;  | 
    
    
    1863  | 
     | 
     | 
    	if (options->forward_x11_timeout == -1)  | 
    
    
    1864  | 
     | 
     | 
    		options->forward_x11_timeout = 1200;  | 
    
    
    1865  | 
     | 
     | 
    	/*  | 
    
    
    1866  | 
     | 
     | 
    	 * stdio forwarding (-W) changes the default for these but we defer  | 
    
    
    1867  | 
     | 
     | 
    	 * setting the values so they can be overridden.  | 
    
    
    1868  | 
     | 
     | 
    	 */  | 
    
    
    1869  | 
     | 
     | 
    	if (options->exit_on_forward_failure == -1)  | 
    
    
    1870  | 
     | 
     | 
    		options->exit_on_forward_failure =  | 
    
    
    1871  | 
     | 
     | 
    		    options->stdio_forward_host != NULL ? 1 : 0;  | 
    
    
    1872  | 
     | 
     | 
    	if (options->clear_forwardings == -1)  | 
    
    
    1873  | 
     | 
     | 
    		options->clear_forwardings =  | 
    
    
    1874  | 
     | 
     | 
    		    options->stdio_forward_host != NULL ? 1 : 0;  | 
    
    
    1875  | 
     | 
     | 
    	if (options->clear_forwardings == 1)  | 
    
    
    1876  | 
     | 
     | 
    		clear_forwardings(options);  | 
    
    
    1877  | 
     | 
     | 
     | 
    
    
    1878  | 
     | 
     | 
    	if (options->xauth_location == NULL)  | 
    
    
    1879  | 
     | 
     | 
    		options->xauth_location = _PATH_XAUTH;  | 
    
    
    1880  | 
     | 
     | 
    	if (options->fwd_opts.gateway_ports == -1)  | 
    
    
    1881  | 
     | 
     | 
    		options->fwd_opts.gateway_ports = 0;  | 
    
    
    1882  | 
     | 
     | 
    	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)  | 
    
    
    1883  | 
     | 
     | 
    		options->fwd_opts.streamlocal_bind_mask = 0177;  | 
    
    
    1884  | 
     | 
     | 
    	if (options->fwd_opts.streamlocal_bind_unlink == -1)  | 
    
    
    1885  | 
     | 
     | 
    		options->fwd_opts.streamlocal_bind_unlink = 0;  | 
    
    
    1886  | 
     | 
     | 
    	if (options->use_privileged_port == -1)  | 
    
    
    1887  | 
     | 
     | 
    		options->use_privileged_port = 0;  | 
    
    
    1888  | 
     | 
     | 
    	if (options->pubkey_authentication == -1)  | 
    
    
    1889  | 
     | 
     | 
    		options->pubkey_authentication = 1;  | 
    
    
    1890  | 
     | 
     | 
    	if (options->challenge_response_authentication == -1)  | 
    
    
    1891  | 
     | 
     | 
    		options->challenge_response_authentication = 1;  | 
    
    
    1892  | 
     | 
     | 
    	if (options->gss_authentication == -1)  | 
    
    
    1893  | 
     | 
     | 
    		options->gss_authentication = 0;  | 
    
    
    1894  | 
     | 
     | 
    	if (options->gss_deleg_creds == -1)  | 
    
    
    1895  | 
     | 
     | 
    		options->gss_deleg_creds = 0;  | 
    
    
    1896  | 
     | 
     | 
    	if (options->password_authentication == -1)  | 
    
    
    1897  | 
     | 
     | 
    		options->password_authentication = 1;  | 
    
    
    1898  | 
     | 
     | 
    	if (options->kbd_interactive_authentication == -1)  | 
    
    
    1899  | 
     | 
     | 
    		options->kbd_interactive_authentication = 1;  | 
    
    
    1900  | 
     | 
     | 
    	if (options->hostbased_authentication == -1)  | 
    
    
    1901  | 
     | 
     | 
    		options->hostbased_authentication = 0;  | 
    
    
    1902  | 
     | 
     | 
    	if (options->batch_mode == -1)  | 
    
    
    1903  | 
     | 
     | 
    		options->batch_mode = 0;  | 
    
    
    1904  | 
     | 
     | 
    	if (options->check_host_ip == -1)  | 
    
    
    1905  | 
     | 
     | 
    		options->check_host_ip = 1;  | 
    
    
    1906  | 
     | 
     | 
    	if (options->strict_host_key_checking == -1)  | 
    
    
    1907  | 
     | 
     | 
    		options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;  | 
    
    
    1908  | 
     | 
     | 
    	if (options->compression == -1)  | 
    
    
    1909  | 
     | 
     | 
    		options->compression = 0;  | 
    
    
    1910  | 
     | 
     | 
    	if (options->tcp_keep_alive == -1)  | 
    
    
    1911  | 
     | 
     | 
    		options->tcp_keep_alive = 1;  | 
    
    
    1912  | 
     | 
     | 
    	if (options->port == -1)  | 
    
    
    1913  | 
     | 
     | 
    		options->port = 0;	/* Filled in ssh_connect. */  | 
    
    
    1914  | 
     | 
     | 
    	if (options->address_family == -1)  | 
    
    
    1915  | 
     | 
     | 
    		options->address_family = AF_UNSPEC;  | 
    
    
    1916  | 
     | 
     | 
    	if (options->connection_attempts == -1)  | 
    
    
    1917  | 
     | 
     | 
    		options->connection_attempts = 1;  | 
    
    
    1918  | 
     | 
     | 
    	if (options->number_of_password_prompts == -1)  | 
    
    
    1919  | 
     | 
     | 
    		options->number_of_password_prompts = 3;  | 
    
    
    1920  | 
     | 
     | 
    	/* options->hostkeyalgorithms, default set in myproposals.h */  | 
    
    
    1921  | 
     | 
     | 
    	if (options->add_keys_to_agent == -1)  | 
    
    
    1922  | 
     | 
     | 
    		options->add_keys_to_agent = 0;  | 
    
    
    1923  | 
     | 
     | 
    	if (options->num_identity_files == 0) { | 
    
    
    1924  | 
     | 
     | 
    		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);  | 
    
    
    1925  | 
     | 
     | 
    		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);  | 
    
    
    1926  | 
     | 
     | 
    		add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);  | 
    
    
    1927  | 
     | 
     | 
    		add_identity_file(options, "~/",  | 
    
    
    1928  | 
     | 
     | 
    		    _PATH_SSH_CLIENT_ID_ED25519, 0);  | 
    
    
    1929  | 
     | 
     | 
    	}  | 
    
    
    1930  | 
     | 
     | 
    	if (options->escape_char == -1)  | 
    
    
    1931  | 
     | 
     | 
    		options->escape_char = '~';  | 
    
    
    1932  | 
     | 
     | 
    	if (options->num_system_hostfiles == 0) { | 
    
    
    1933  | 
     | 
     | 
    		options->system_hostfiles[options->num_system_hostfiles++] =  | 
    
    
    1934  | 
     | 
     | 
    		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);  | 
    
    
    1935  | 
     | 
     | 
    		options->system_hostfiles[options->num_system_hostfiles++] =  | 
    
    
    1936  | 
     | 
     | 
    		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);  | 
    
    
    1937  | 
     | 
     | 
    	}  | 
    
    
    1938  | 
     | 
     | 
    	if (options->num_user_hostfiles == 0) { | 
    
    
    1939  | 
     | 
     | 
    		options->user_hostfiles[options->num_user_hostfiles++] =  | 
    
    
    1940  | 
     | 
     | 
    		    xstrdup(_PATH_SSH_USER_HOSTFILE);  | 
    
    
    1941  | 
     | 
     | 
    		options->user_hostfiles[options->num_user_hostfiles++] =  | 
    
    
    1942  | 
     | 
     | 
    		    xstrdup(_PATH_SSH_USER_HOSTFILE2);  | 
    
    
    1943  | 
     | 
     | 
    	}  | 
    
    
    1944  | 
     | 
     | 
    	if (options->log_level == SYSLOG_LEVEL_NOT_SET)  | 
    
    
    1945  | 
     | 
     | 
    		options->log_level = SYSLOG_LEVEL_INFO;  | 
    
    
    1946  | 
     | 
     | 
    	if (options->log_facility == SYSLOG_FACILITY_NOT_SET)  | 
    
    
    1947  | 
     | 
     | 
    		options->log_facility = SYSLOG_FACILITY_USER;  | 
    
    
    1948  | 
     | 
     | 
    	if (options->no_host_authentication_for_localhost == - 1)  | 
    
    
    1949  | 
     | 
     | 
    		options->no_host_authentication_for_localhost = 0;  | 
    
    
    1950  | 
     | 
     | 
    	if (options->identities_only == -1)  | 
    
    
    1951  | 
     | 
     | 
    		options->identities_only = 0;  | 
    
    
    1952  | 
     | 
     | 
    	if (options->enable_ssh_keysign == -1)  | 
    
    
    1953  | 
     | 
     | 
    		options->enable_ssh_keysign = 0;  | 
    
    
    1954  | 
     | 
     | 
    	if (options->rekey_limit == -1)  | 
    
    
    1955  | 
     | 
     | 
    		options->rekey_limit = 0;  | 
    
    
    1956  | 
     | 
     | 
    	if (options->rekey_interval == -1)  | 
    
    
    1957  | 
     | 
     | 
    		options->rekey_interval = 0;  | 
    
    
    1958  | 
     | 
     | 
    	if (options->verify_host_key_dns == -1)  | 
    
    
    1959  | 
     | 
     | 
    		options->verify_host_key_dns = 0;  | 
    
    
    1960  | 
     | 
     | 
    	if (options->server_alive_interval == -1)  | 
    
    
    1961  | 
     | 
     | 
    		options->server_alive_interval = 0;  | 
    
    
    1962  | 
     | 
     | 
    	if (options->server_alive_count_max == -1)  | 
    
    
    1963  | 
     | 
     | 
    		options->server_alive_count_max = 3;  | 
    
    
    1964  | 
     | 
     | 
    	if (options->control_master == -1)  | 
    
    
    1965  | 
     | 
     | 
    		options->control_master = 0;  | 
    
    
    1966  | 
     | 
     | 
    	if (options->control_persist == -1) { | 
    
    
    1967  | 
     | 
     | 
    		options->control_persist = 0;  | 
    
    
    1968  | 
     | 
     | 
    		options->control_persist_timeout = 0;  | 
    
    
    1969  | 
     | 
     | 
    	}  | 
    
    
    1970  | 
     | 
     | 
    	if (options->hash_known_hosts == -1)  | 
    
    
    1971  | 
     | 
     | 
    		options->hash_known_hosts = 0;  | 
    
    
    1972  | 
     | 
     | 
    	if (options->tun_open == -1)  | 
    
    
    1973  | 
     | 
     | 
    		options->tun_open = SSH_TUNMODE_NO;  | 
    
    
    1974  | 
     | 
     | 
    	if (options->tun_local == -1)  | 
    
    
    1975  | 
     | 
     | 
    		options->tun_local = SSH_TUNID_ANY;  | 
    
    
    1976  | 
     | 
     | 
    	if (options->tun_remote == -1)  | 
    
    
    1977  | 
     | 
     | 
    		options->tun_remote = SSH_TUNID_ANY;  | 
    
    
    1978  | 
     | 
     | 
    	if (options->permit_local_command == -1)  | 
    
    
    1979  | 
     | 
     | 
    		options->permit_local_command = 0;  | 
    
    
    1980  | 
     | 
     | 
    	if (options->visual_host_key == -1)  | 
    
    
    1981  | 
     | 
     | 
    		options->visual_host_key = 0;  | 
    
    
    1982  | 
     | 
     | 
    	if (options->ip_qos_interactive == -1)  | 
    
    
    1983  | 
     | 
     | 
    		options->ip_qos_interactive = IPTOS_LOWDELAY;  | 
    
    
    1984  | 
     | 
     | 
    	if (options->ip_qos_bulk == -1)  | 
    
    
    1985  | 
     | 
     | 
    		options->ip_qos_bulk = IPTOS_THROUGHPUT;  | 
    
    
    1986  | 
     | 
     | 
    	if (options->request_tty == -1)  | 
    
    
    1987  | 
     | 
     | 
    		options->request_tty = REQUEST_TTY_AUTO;  | 
    
    
    1988  | 
     | 
     | 
    	if (options->proxy_use_fdpass == -1)  | 
    
    
    1989  | 
     | 
     | 
    		options->proxy_use_fdpass = 0;  | 
    
    
    1990  | 
     | 
     | 
    	if (options->canonicalize_max_dots == -1)  | 
    
    
    1991  | 
     | 
     | 
    		options->canonicalize_max_dots = 1;  | 
    
    
    1992  | 
     | 
     | 
    	if (options->canonicalize_fallback_local == -1)  | 
    
    
    1993  | 
     | 
     | 
    		options->canonicalize_fallback_local = 1;  | 
    
    
    1994  | 
     | 
     | 
    	if (options->canonicalize_hostname == -1)  | 
    
    
    1995  | 
     | 
     | 
    		options->canonicalize_hostname = SSH_CANONICALISE_NO;  | 
    
    
    1996  | 
     | 
     | 
    	if (options->fingerprint_hash == -1)  | 
    
    
    1997  | 
     | 
     | 
    		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;  | 
    
    
    1998  | 
     | 
     | 
    	if (options->update_hostkeys == -1)  | 
    
    
    1999  | 
     | 
     | 
    		options->update_hostkeys = 0;  | 
    
    
    2000  | 
     | 
     | 
    	if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||  | 
    
    
    2001  | 
     | 
     | 
    	    kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||  | 
    
    
    2002  | 
     | 
     | 
    	    kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||  | 
    
    
    2003  | 
     | 
     | 
    	    kex_assemble_names(KEX_DEFAULT_PK_ALG,  | 
    
    
    2004  | 
     | 
     | 
    	    &options->hostbased_key_types) != 0 ||  | 
    
    
    2005  | 
     | 
     | 
    	    kex_assemble_names(KEX_DEFAULT_PK_ALG,  | 
    
    
    2006  | 
     | 
     | 
    	    &options->pubkey_key_types) != 0)  | 
    
    
    2007  | 
     | 
     | 
    		fatal("%s: kex_assemble_names failed", __func__); | 
    
    
    2008  | 
     | 
     | 
     | 
    
    
    2009  | 
     | 
     | 
    #define CLEAR_ON_NONE(v) \  | 
    
    
    2010  | 
     | 
     | 
    	do { \ | 
    
    
    2011  | 
     | 
     | 
    		if (option_clear_or_none(v)) { \ | 
    
    
    2012  | 
     | 
     | 
    			free(v); \  | 
    
    
    2013  | 
     | 
     | 
    			v = NULL; \  | 
    
    
    2014  | 
     | 
     | 
    		} \  | 
    
    
    2015  | 
     | 
     | 
    	} while(0)  | 
    
    
    2016  | 
     | 
     | 
    	CLEAR_ON_NONE(options->local_command);  | 
    
    
    2017  | 
     | 
     | 
    	CLEAR_ON_NONE(options->remote_command);  | 
    
    
    2018  | 
     | 
     | 
    	CLEAR_ON_NONE(options->proxy_command);  | 
    
    
    2019  | 
     | 
     | 
    	CLEAR_ON_NONE(options->control_path);  | 
    
    
    2020  | 
     | 
     | 
    	CLEAR_ON_NONE(options->revoked_host_keys);  | 
    
    
    2021  | 
     | 
     | 
    	/* options->identity_agent distinguishes NULL from 'none' */  | 
    
    
    2022  | 
     | 
     | 
    	/* options->user will be set in the main program if appropriate */  | 
    
    
    2023  | 
     | 
     | 
    	/* options->hostname will be set in the main program if appropriate */  | 
    
    
    2024  | 
     | 
     | 
    	/* options->host_key_alias should not be set by default */  | 
    
    
    2025  | 
     | 
     | 
    	/* options->preferred_authentications will be set in ssh */  | 
    
    
    2026  | 
     | 
     | 
    }  | 
    
    
    2027  | 
     | 
     | 
     | 
    
    
    2028  | 
     | 
     | 
    struct fwdarg { | 
    
    
    2029  | 
     | 
     | 
    	char *arg;  | 
    
    
    2030  | 
     | 
     | 
    	int ispath;  | 
    
    
    2031  | 
     | 
     | 
    };  | 
    
    
    2032  | 
     | 
     | 
     | 
    
    
    2033  | 
     | 
     | 
    /*  | 
    
    
    2034  | 
     | 
     | 
     * parse_fwd_field  | 
    
    
    2035  | 
     | 
     | 
     * parses the next field in a port forwarding specification.  | 
    
    
    2036  | 
     | 
     | 
     * sets fwd to the parsed field and advances p past the colon  | 
    
    
    2037  | 
     | 
     | 
     * or sets it to NULL at end of string.  | 
    
    
    2038  | 
     | 
     | 
     * returns 0 on success, else non-zero.  | 
    
    
    2039  | 
     | 
     | 
     */  | 
    
    
    2040  | 
     | 
     | 
    static int  | 
    
    
    2041  | 
     | 
     | 
    parse_fwd_field(char **p, struct fwdarg *fwd)  | 
    
    
    2042  | 
     | 
     | 
    { | 
    
    
    2043  | 
     | 
     | 
    	char *ep, *cp = *p;  | 
    
    
    2044  | 
     | 
     | 
    	int ispath = 0;  | 
    
    
    2045  | 
     | 
     | 
     | 
    
    
    2046  | 
     | 
     | 
    	if (*cp == '\0') { | 
    
    
    2047  | 
     | 
     | 
    		*p = NULL;  | 
    
    
    2048  | 
     | 
     | 
    		return -1;	/* end of string */  | 
    
    
    2049  | 
     | 
     | 
    	}  | 
    
    
    2050  | 
     | 
     | 
     | 
    
    
    2051  | 
     | 
     | 
    	/*  | 
    
    
    2052  | 
     | 
     | 
    	 * A field escaped with square brackets is used literally.  | 
    
    
    2053  | 
     | 
     | 
    	 * XXX - allow ']' to be escaped via backslash?  | 
    
    
    2054  | 
     | 
     | 
    	 */  | 
    
    
    2055  | 
     | 
     | 
    	if (*cp == '[') { | 
    
    
    2056  | 
     | 
     | 
    		/* find matching ']' */  | 
    
    
    2057  | 
     | 
     | 
    		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) { | 
    
    
    2058  | 
     | 
     | 
    			if (*ep == '/')  | 
    
    
    2059  | 
     | 
     | 
    				ispath = 1;  | 
    
    
    2060  | 
     | 
     | 
    		}  | 
    
    
    2061  | 
     | 
     | 
    		/* no matching ']' or not at end of field. */  | 
    
    
    2062  | 
     | 
     | 
    		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))  | 
    
    
    2063  | 
     | 
     | 
    			return -1;  | 
    
    
    2064  | 
     | 
     | 
    		/* NUL terminate the field and advance p past the colon */  | 
    
    
    2065  | 
     | 
     | 
    		*ep++ = '\0';  | 
    
    
    2066  | 
     | 
     | 
    		if (*ep != '\0')  | 
    
    
    2067  | 
     | 
     | 
    			*ep++ = '\0';  | 
    
    
    2068  | 
     | 
     | 
    		fwd->arg = cp + 1;  | 
    
    
    2069  | 
     | 
     | 
    		fwd->ispath = ispath;  | 
    
    
    2070  | 
     | 
     | 
    		*p = ep;  | 
    
    
    2071  | 
     | 
     | 
    		return 0;  | 
    
    
    2072  | 
     | 
     | 
    	}  | 
    
    
    2073  | 
     | 
     | 
     | 
    
    
    2074  | 
     | 
     | 
    	for (cp = *p; *cp != '\0'; cp++) { | 
    
    
    2075  | 
     | 
     | 
    		switch (*cp) { | 
    
    
    2076  | 
     | 
     | 
    		case '\\':  | 
    
    
    2077  | 
     | 
     | 
    			memmove(cp, cp + 1, strlen(cp + 1) + 1);  | 
    
    
    2078  | 
     | 
     | 
    			if (*cp == '\0')  | 
    
    
    2079  | 
     | 
     | 
    				return -1;  | 
    
    
    2080  | 
     | 
     | 
    			break;  | 
    
    
    2081  | 
     | 
     | 
    		case '/':  | 
    
    
    2082  | 
     | 
     | 
    			ispath = 1;  | 
    
    
    2083  | 
     | 
     | 
    			break;  | 
    
    
    2084  | 
     | 
     | 
    		case ':':  | 
    
    
    2085  | 
     | 
     | 
    			*cp++ = '\0';  | 
    
    
    2086  | 
     | 
     | 
    			goto done;  | 
    
    
    2087  | 
     | 
     | 
    		}  | 
    
    
    2088  | 
     | 
     | 
    	}  | 
    
    
    2089  | 
     | 
     | 
    done:  | 
    
    
    2090  | 
     | 
     | 
    	fwd->arg = *p;  | 
    
    
    2091  | 
     | 
     | 
    	fwd->ispath = ispath;  | 
    
    
    2092  | 
     | 
     | 
    	*p = cp;  | 
    
    
    2093  | 
     | 
     | 
    	return 0;  | 
    
    
    2094  | 
     | 
     | 
    }  | 
    
    
    2095  | 
     | 
     | 
     | 
    
    
    2096  | 
     | 
     | 
    /*  | 
    
    
    2097  | 
     | 
     | 
     * parse_forward  | 
    
    
    2098  | 
     | 
     | 
     * parses a string containing a port forwarding specification of the form:  | 
    
    
    2099  | 
     | 
     | 
     *   dynamicfwd == 0  | 
    
    
    2100  | 
     | 
     | 
     *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath  | 
    
    
    2101  | 
     | 
     | 
     *	listenpath:connectpath  | 
    
    
    2102  | 
     | 
     | 
     *   dynamicfwd == 1  | 
    
    
    2103  | 
     | 
     | 
     *	[listenhost:]listenport  | 
    
    
    2104  | 
     | 
     | 
     * returns number of arguments parsed or zero on error  | 
    
    
    2105  | 
     | 
     | 
     */  | 
    
    
    2106  | 
     | 
     | 
    int  | 
    
    
    2107  | 
     | 
     | 
    parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)  | 
    
    
    2108  | 
     | 
     | 
    { | 
    
    
    2109  | 
     | 
     | 
    	struct fwdarg fwdargs[4];  | 
    
    
    2110  | 
     | 
     | 
    	char *p, *cp;  | 
    
    
    2111  | 
     | 
     | 
    	int i;  | 
    
    
    2112  | 
     | 
     | 
     | 
    
    
    2113  | 
     | 
     | 
    	memset(fwd, 0, sizeof(*fwd));  | 
    
    
    2114  | 
     | 
     | 
    	memset(fwdargs, 0, sizeof(fwdargs));  | 
    
    
    2115  | 
     | 
     | 
     | 
    
    
    2116  | 
     | 
     | 
    	cp = p = xstrdup(fwdspec);  | 
    
    
    2117  | 
     | 
     | 
     | 
    
    
    2118  | 
     | 
     | 
    	/* skip leading spaces */  | 
    
    
    2119  | 
     | 
     | 
    	while (isspace((u_char)*cp))  | 
    
    
    2120  | 
     | 
     | 
    		cp++;  | 
    
    
    2121  | 
     | 
     | 
     | 
    
    
    2122  | 
     | 
     | 
    	for (i = 0; i < 4; ++i) { | 
    
    
    2123  | 
     | 
     | 
    		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)  | 
    
    
    2124  | 
     | 
     | 
    			break;  | 
    
    
    2125  | 
     | 
     | 
    	}  | 
    
    
    2126  | 
     | 
     | 
     | 
    
    
    2127  | 
     | 
     | 
    	/* Check for trailing garbage */  | 
    
    
    2128  | 
     | 
     | 
    	if (cp != NULL && *cp != '\0') { | 
    
    
    2129  | 
     | 
     | 
    		i = 0;	/* failure */  | 
    
    
    2130  | 
     | 
     | 
    	}  | 
    
    
    2131  | 
     | 
     | 
     | 
    
    
    2132  | 
     | 
     | 
    	switch (i) { | 
    
    
    2133  | 
     | 
     | 
    	case 1:  | 
    
    
    2134  | 
     | 
     | 
    		if (fwdargs[0].ispath) { | 
    
    
    2135  | 
     | 
     | 
    			fwd->listen_path = xstrdup(fwdargs[0].arg);  | 
    
    
    2136  | 
     | 
     | 
    			fwd->listen_port = PORT_STREAMLOCAL;  | 
    
    
    2137  | 
     | 
     | 
    		} else { | 
    
    
    2138  | 
     | 
     | 
    			fwd->listen_host = NULL;  | 
    
    
    2139  | 
     | 
     | 
    			fwd->listen_port = a2port(fwdargs[0].arg);  | 
    
    
    2140  | 
     | 
     | 
    		}  | 
    
    
    2141  | 
     | 
     | 
    		fwd->connect_host = xstrdup("socks"); | 
    
    
    2142  | 
     | 
     | 
    		break;  | 
    
    
    2143  | 
     | 
     | 
     | 
    
    
    2144  | 
     | 
     | 
    	case 2:  | 
    
    
    2145  | 
     | 
     | 
    		if (fwdargs[0].ispath && fwdargs[1].ispath) { | 
    
    
    2146  | 
     | 
     | 
    			fwd->listen_path = xstrdup(fwdargs[0].arg);  | 
    
    
    2147  | 
     | 
     | 
    			fwd->listen_port = PORT_STREAMLOCAL;  | 
    
    
    2148  | 
     | 
     | 
    			fwd->connect_path = xstrdup(fwdargs[1].arg);  | 
    
    
    2149  | 
     | 
     | 
    			fwd->connect_port = PORT_STREAMLOCAL;  | 
    
    
    2150  | 
     | 
     | 
    		} else if (fwdargs[1].ispath) { | 
    
    
    2151  | 
     | 
     | 
    			fwd->listen_host = NULL;  | 
    
    
    2152  | 
     | 
     | 
    			fwd->listen_port = a2port(fwdargs[0].arg);  | 
    
    
    2153  | 
     | 
     | 
    			fwd->connect_path = xstrdup(fwdargs[1].arg);  | 
    
    
    2154  | 
     | 
     | 
    			fwd->connect_port = PORT_STREAMLOCAL;  | 
    
    
    2155  | 
     | 
     | 
    		} else { | 
    
    
    2156  | 
     | 
     | 
    			fwd->listen_host = xstrdup(fwdargs[0].arg);  | 
    
    
    2157  | 
     | 
     | 
    			fwd->listen_port = a2port(fwdargs[1].arg);  | 
    
    
    2158  | 
     | 
     | 
    			fwd->connect_host = xstrdup("socks"); | 
    
    
    2159  | 
     | 
     | 
    		}  | 
    
    
    2160  | 
     | 
     | 
    		break;  | 
    
    
    2161  | 
     | 
     | 
     | 
    
    
    2162  | 
     | 
     | 
    	case 3:  | 
    
    
    2163  | 
     | 
     | 
    		if (fwdargs[0].ispath) { | 
    
    
    2164  | 
     | 
     | 
    			fwd->listen_path = xstrdup(fwdargs[0].arg);  | 
    
    
    2165  | 
     | 
     | 
    			fwd->listen_port = PORT_STREAMLOCAL;  | 
    
    
    2166  | 
     | 
     | 
    			fwd->connect_host = xstrdup(fwdargs[1].arg);  | 
    
    
    2167  | 
     | 
     | 
    			fwd->connect_port = a2port(fwdargs[2].arg);  | 
    
    
    2168  | 
     | 
     | 
    		} else if (fwdargs[2].ispath) { | 
    
    
    2169  | 
     | 
     | 
    			fwd->listen_host = xstrdup(fwdargs[0].arg);  | 
    
    
    2170  | 
     | 
     | 
    			fwd->listen_port = a2port(fwdargs[1].arg);  | 
    
    
    2171  | 
     | 
     | 
    			fwd->connect_path = xstrdup(fwdargs[2].arg);  | 
    
    
    2172  | 
     | 
     | 
    			fwd->connect_port = PORT_STREAMLOCAL;  | 
    
    
    2173  | 
     | 
     | 
    		} else { | 
    
    
    2174  | 
     | 
     | 
    			fwd->listen_host = NULL;  | 
    
    
    2175  | 
     | 
     | 
    			fwd->listen_port = a2port(fwdargs[0].arg);  | 
    
    
    2176  | 
     | 
     | 
    			fwd->connect_host = xstrdup(fwdargs[1].arg);  | 
    
    
    2177  | 
     | 
     | 
    			fwd->connect_port = a2port(fwdargs[2].arg);  | 
    
    
    2178  | 
     | 
     | 
    		}  | 
    
    
    2179  | 
     | 
     | 
    		break;  | 
    
    
    2180  | 
     | 
     | 
     | 
    
    
    2181  | 
     | 
     | 
    	case 4:  | 
    
    
    2182  | 
     | 
     | 
    		fwd->listen_host = xstrdup(fwdargs[0].arg);  | 
    
    
    2183  | 
     | 
     | 
    		fwd->listen_port = a2port(fwdargs[1].arg);  | 
    
    
    2184  | 
     | 
     | 
    		fwd->connect_host = xstrdup(fwdargs[2].arg);  | 
    
    
    2185  | 
     | 
     | 
    		fwd->connect_port = a2port(fwdargs[3].arg);  | 
    
    
    2186  | 
     | 
     | 
    		break;  | 
    
    
    2187  | 
     | 
     | 
    	default:  | 
    
    
    2188  | 
     | 
     | 
    		i = 0; /* failure */  | 
    
    
    2189  | 
     | 
     | 
    	}  | 
    
    
    2190  | 
     | 
     | 
     | 
    
    
    2191  | 
     | 
     | 
    	free(p);  | 
    
    
    2192  | 
     | 
     | 
     | 
    
    
    2193  | 
     | 
     | 
    	if (dynamicfwd) { | 
    
    
    2194  | 
     | 
     | 
    		if (!(i == 1 || i == 2))  | 
    
    
    2195  | 
     | 
     | 
    			goto fail_free;  | 
    
    
    2196  | 
     | 
     | 
    	} else { | 
    
    
    2197  | 
     | 
     | 
    		if (!(i == 3 || i == 4)) { | 
    
    
    2198  | 
     | 
     | 
    			if (fwd->connect_path == NULL &&  | 
    
    
    2199  | 
     | 
     | 
    			    fwd->listen_path == NULL)  | 
    
    
    2200  | 
     | 
     | 
    				goto fail_free;  | 
    
    
    2201  | 
     | 
     | 
    		}  | 
    
    
    2202  | 
     | 
     | 
    		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)  | 
    
    
    2203  | 
     | 
     | 
    			goto fail_free;  | 
    
    
    2204  | 
     | 
     | 
    	}  | 
    
    
    2205  | 
     | 
     | 
     | 
    
    
    2206  | 
     | 
     | 
    	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||  | 
    
    
    2207  | 
     | 
     | 
    	    (!remotefwd && fwd->listen_port == 0))  | 
    
    
    2208  | 
     | 
     | 
    		goto fail_free;  | 
    
    
    2209  | 
     | 
     | 
    	if (fwd->connect_host != NULL &&  | 
    
    
    2210  | 
     | 
     | 
    	    strlen(fwd->connect_host) >= NI_MAXHOST)  | 
    
    
    2211  | 
     | 
     | 
    		goto fail_free;  | 
    
    
    2212  | 
     | 
     | 
    	/* XXX - if connecting to a remote socket, max sun len may not match this host */  | 
    
    
    2213  | 
     | 
     | 
    	if (fwd->connect_path != NULL &&  | 
    
    
    2214  | 
     | 
     | 
    	    strlen(fwd->connect_path) >= PATH_MAX_SUN)  | 
    
    
    2215  | 
     | 
     | 
    		goto fail_free;  | 
    
    
    2216  | 
     | 
     | 
    	if (fwd->listen_host != NULL &&  | 
    
    
    2217  | 
     | 
     | 
    	    strlen(fwd->listen_host) >= NI_MAXHOST)  | 
    
    
    2218  | 
     | 
     | 
    		goto fail_free;  | 
    
    
    2219  | 
     | 
     | 
    	if (fwd->listen_path != NULL &&  | 
    
    
    2220  | 
     | 
     | 
    	    strlen(fwd->listen_path) >= PATH_MAX_SUN)  | 
    
    
    2221  | 
     | 
     | 
    		goto fail_free;  | 
    
    
    2222  | 
     | 
     | 
     | 
    
    
    2223  | 
     | 
     | 
    	return (i);  | 
    
    
    2224  | 
     | 
     | 
     | 
    
    
    2225  | 
     | 
     | 
     fail_free:  | 
    
    
    2226  | 
     | 
     | 
    	free(fwd->connect_host);  | 
    
    
    2227  | 
     | 
     | 
    	fwd->connect_host = NULL;  | 
    
    
    2228  | 
     | 
     | 
    	free(fwd->connect_path);  | 
    
    
    2229  | 
     | 
     | 
    	fwd->connect_path = NULL;  | 
    
    
    2230  | 
     | 
     | 
    	free(fwd->listen_host);  | 
    
    
    2231  | 
     | 
     | 
    	fwd->listen_host = NULL;  | 
    
    
    2232  | 
     | 
     | 
    	free(fwd->listen_path);  | 
    
    
    2233  | 
     | 
     | 
    	fwd->listen_path = NULL;  | 
    
    
    2234  | 
     | 
     | 
    	return (0);  | 
    
    
    2235  | 
     | 
     | 
    }  | 
    
    
    2236  | 
     | 
     | 
     | 
    
    
    2237  | 
     | 
     | 
    int  | 
    
    
    2238  | 
     | 
     | 
    parse_jump(const char *s, Options *o, int active)  | 
    
    
    2239  | 
     | 
     | 
    { | 
    
    
    2240  | 
     | 
     | 
    	char *orig, *sdup, *cp;  | 
    
    
    2241  | 
     | 
     | 
    	char *host = NULL, *user = NULL;  | 
    
    
    2242  | 
     | 
     | 
    	int ret = -1, port = -1, first;  | 
    
    
    2243  | 
     | 
     | 
     | 
    
    
    2244  | 
     | 
     | 
    	active &= o->proxy_command == NULL && o->jump_host == NULL;  | 
    
    
    2245  | 
     | 
     | 
     | 
    
    
    2246  | 
     | 
     | 
    	orig = sdup = xstrdup(s);  | 
    
    
    2247  | 
     | 
     | 
    	first = active;  | 
    
    
    2248  | 
     | 
     | 
    	do { | 
    
    
    2249  | 
     | 
     | 
    		if ((cp = strrchr(sdup, ',')) == NULL)  | 
    
    
    2250  | 
     | 
     | 
    			cp = sdup; /* last */  | 
    
    
    2251  | 
     | 
     | 
    		else  | 
    
    
    2252  | 
     | 
     | 
    			*cp++ = '\0';  | 
    
    
    2253  | 
     | 
     | 
     | 
    
    
    2254  | 
     | 
     | 
    		if (first) { | 
    
    
    2255  | 
     | 
     | 
    			/* First argument and configuration is active */  | 
    
    
    2256  | 
     | 
     | 
    			if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||  | 
    
    
    2257  | 
     | 
     | 
    			    parse_user_host_port(cp, &user, &host, &port) != 0)  | 
    
    
    2258  | 
     | 
     | 
    				goto out;  | 
    
    
    2259  | 
     | 
     | 
    		} else { | 
    
    
    2260  | 
     | 
     | 
    			/* Subsequent argument or inactive configuration */  | 
    
    
    2261  | 
     | 
     | 
    			if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||  | 
    
    
    2262  | 
     | 
     | 
    			    parse_user_host_port(cp, NULL, NULL, NULL) != 0)  | 
    
    
    2263  | 
     | 
     | 
    				goto out;  | 
    
    
    2264  | 
     | 
     | 
    		}  | 
    
    
    2265  | 
     | 
     | 
    		first = 0; /* only check syntax for subsequent hosts */  | 
    
    
    2266  | 
     | 
     | 
    	} while (cp != sdup);  | 
    
    
    2267  | 
     | 
     | 
    	/* success */  | 
    
    
    2268  | 
     | 
     | 
    	if (active) { | 
    
    
    2269  | 
     | 
     | 
    		o->jump_user = user;  | 
    
    
    2270  | 
     | 
     | 
    		o->jump_host = host;  | 
    
    
    2271  | 
     | 
     | 
    		o->jump_port = port;  | 
    
    
    2272  | 
     | 
     | 
    		o->proxy_command = xstrdup("none"); | 
    
    
    2273  | 
     | 
     | 
    		user = host = NULL;  | 
    
    
    2274  | 
     | 
     | 
    		if ((cp = strrchr(s, ',')) != NULL && cp != s) { | 
    
    
    2275  | 
     | 
     | 
    			o->jump_extra = xstrdup(s);  | 
    
    
    2276  | 
     | 
     | 
    			o->jump_extra[cp - s] = '\0';  | 
    
    
    2277  | 
     | 
     | 
    		}  | 
    
    
    2278  | 
     | 
     | 
    	}  | 
    
    
    2279  | 
     | 
     | 
    	ret = 0;  | 
    
    
    2280  | 
     | 
     | 
     out:  | 
    
    
    2281  | 
     | 
     | 
    	free(orig);  | 
    
    
    2282  | 
     | 
     | 
    	free(user);  | 
    
    
    2283  | 
     | 
     | 
    	free(host);  | 
    
    
    2284  | 
     | 
     | 
    	return ret;  | 
    
    
    2285  | 
     | 
     | 
    }  | 
    
    
    2286  | 
     | 
     | 
     | 
    
    
    2287  | 
     | 
     | 
    int  | 
    
    
    2288  | 
     | 
     | 
    parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)  | 
    
    
    2289  | 
     | 
     | 
    { | 
    
    
    2290  | 
     | 
     | 
    	char *path;  | 
    
    
    2291  | 
     | 
     | 
    	int r;  | 
    
    
    2292  | 
     | 
     | 
     | 
    
    
    2293  | 
     | 
     | 
    	r = parse_uri("ssh", uri, userp, hostp, portp, &path); | 
    
    
    2294  | 
     | 
     | 
    	if (r == 0 && path != NULL)  | 
    
    
    2295  | 
     | 
     | 
    		r = -1;		/* path not allowed */  | 
    
    
    2296  | 
     | 
     | 
    	return r;  | 
    
    
    2297  | 
     | 
     | 
    }  | 
    
    
    2298  | 
     | 
     | 
     | 
    
    
    2299  | 
     | 
     | 
    /* XXX the following is a near-vebatim copy from servconf.c; refactor */  | 
    
    
    2300  | 
     | 
     | 
    static const char *  | 
    
    
    2301  | 
     | 
     | 
    fmt_multistate_int(int val, const struct multistate *m)  | 
    
    
    2302  | 
     | 
     | 
    { | 
    
    
    2303  | 
     | 
     | 
    	u_int i;  | 
    
    
    2304  | 
     | 
     | 
     | 
    
    
    2305  | 
     | 
     | 
    	for (i = 0; m[i].key != NULL; i++) { | 
    
    
    2306  | 
     | 
     | 
    		if (m[i].value == val)  | 
    
    
    2307  | 
     | 
     | 
    			return m[i].key;  | 
    
    
    2308  | 
     | 
     | 
    	}  | 
    
    
    2309  | 
     | 
     | 
    	return "UNKNOWN";  | 
    
    
    2310  | 
     | 
     | 
    }  | 
    
    
    2311  | 
     | 
     | 
     | 
    
    
    2312  | 
     | 
     | 
    static const char *  | 
    
    
    2313  | 
     | 
     | 
    fmt_intarg(OpCodes code, int val)  | 
    
    
    2314  | 
     | 
     | 
    { | 
    
    
    2315  | 
     | 
     | 
    	if (val == -1)  | 
    
    
    2316  | 
     | 
     | 
    		return "unset";  | 
    
    
    2317  | 
     | 
     | 
    	switch (code) { | 
    
    
    2318  | 
     | 
     | 
    	case oAddressFamily:  | 
    
    
    2319  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_addressfamily);  | 
    
    
    2320  | 
     | 
     | 
    	case oVerifyHostKeyDNS:  | 
    
    
    2321  | 
     | 
     | 
    	case oUpdateHostkeys:  | 
    
    
    2322  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_yesnoask);  | 
    
    
    2323  | 
     | 
     | 
    	case oStrictHostKeyChecking:  | 
    
    
    2324  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_strict_hostkey);  | 
    
    
    2325  | 
     | 
     | 
    	case oControlMaster:  | 
    
    
    2326  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_controlmaster);  | 
    
    
    2327  | 
     | 
     | 
    	case oTunnel:  | 
    
    
    2328  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_tunnel);  | 
    
    
    2329  | 
     | 
     | 
    	case oRequestTTY:  | 
    
    
    2330  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_requesttty);  | 
    
    
    2331  | 
     | 
     | 
    	case oCanonicalizeHostname:  | 
    
    
    2332  | 
     | 
     | 
    		return fmt_multistate_int(val, multistate_canonicalizehostname);  | 
    
    
    2333  | 
     | 
     | 
    	case oFingerprintHash:  | 
    
    
    2334  | 
     | 
     | 
    		return ssh_digest_alg_name(val);  | 
    
    
    2335  | 
     | 
     | 
    	default:  | 
    
    
    2336  | 
     | 
     | 
    		switch (val) { | 
    
    
    2337  | 
     | 
     | 
    		case 0:  | 
    
    
    2338  | 
     | 
     | 
    			return "no";  | 
    
    
    2339  | 
     | 
     | 
    		case 1:  | 
    
    
    2340  | 
     | 
     | 
    			return "yes";  | 
    
    
    2341  | 
     | 
     | 
    		default:  | 
    
    
    2342  | 
     | 
     | 
    			return "UNKNOWN";  | 
    
    
    2343  | 
     | 
     | 
    		}  | 
    
    
    2344  | 
     | 
     | 
    	}  | 
    
    
    2345  | 
     | 
     | 
    }  | 
    
    
    2346  | 
     | 
     | 
     | 
    
    
    2347  | 
     | 
     | 
    static const char *  | 
    
    
    2348  | 
     | 
     | 
    lookup_opcode_name(OpCodes code)  | 
    
    
    2349  | 
     | 
     | 
    { | 
    
    
    2350  | 
     | 
     | 
    	u_int i;  | 
    
    
    2351  | 
     | 
     | 
     | 
    
    
    2352  | 
     | 
     | 
    	for (i = 0; keywords[i].name != NULL; i++)  | 
    
    
    2353  | 
     | 
     | 
    		if (keywords[i].opcode == code)  | 
    
    
    2354  | 
     | 
     | 
    			return(keywords[i].name);  | 
    
    
    2355  | 
     | 
     | 
    	return "UNKNOWN";  | 
    
    
    2356  | 
     | 
     | 
    }  | 
    
    
    2357  | 
     | 
     | 
     | 
    
    
    2358  | 
     | 
     | 
    static void  | 
    
    
    2359  | 
     | 
     | 
    dump_cfg_int(OpCodes code, int val)  | 
    
    
    2360  | 
     | 
     | 
    { | 
    
    
    2361  | 
     | 
     | 
    	printf("%s %d\n", lookup_opcode_name(code), val); | 
    
    
    2362  | 
     | 
     | 
    }  | 
    
    
    2363  | 
     | 
     | 
     | 
    
    
    2364  | 
     | 
     | 
    static void  | 
    
    
    2365  | 
     | 
     | 
    dump_cfg_fmtint(OpCodes code, int val)  | 
    
    
    2366  | 
     | 
     | 
    { | 
    
    
    2367  | 
     | 
     | 
    	printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); | 
    
    
    2368  | 
     | 
     | 
    }  | 
    
    
    2369  | 
     | 
     | 
     | 
    
    
    2370  | 
     | 
     | 
    static void  | 
    
    
    2371  | 
     | 
     | 
    dump_cfg_string(OpCodes code, const char *val)  | 
    
    
    2372  | 
     | 
     | 
    { | 
    
    
    2373  | 
     | 
     | 
    	if (val == NULL)  | 
    
    
    2374  | 
     | 
     | 
    		return;  | 
    
    
    2375  | 
     | 
     | 
    	printf("%s %s\n", lookup_opcode_name(code), val); | 
    
    
    2376  | 
     | 
     | 
    }  | 
    
    
    2377  | 
     | 
     | 
     | 
    
    
    2378  | 
     | 
     | 
    static void  | 
    
    
    2379  | 
     | 
     | 
    dump_cfg_strarray(OpCodes code, u_int count, char **vals)  | 
    
    
    2380  | 
     | 
     | 
    { | 
    
    
    2381  | 
     | 
     | 
    	u_int i;  | 
    
    
    2382  | 
     | 
     | 
     | 
    
    
    2383  | 
     | 
     | 
    	for (i = 0; i < count; i++)  | 
    
    
    2384  | 
     | 
     | 
    		printf("%s %s\n", lookup_opcode_name(code), vals[i]); | 
    
    
    2385  | 
     | 
     | 
    }  | 
    
    
    2386  | 
     | 
     | 
     | 
    
    
    2387  | 
     | 
     | 
    static void  | 
    
    
    2388  | 
     | 
     | 
    dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)  | 
    
    
    2389  | 
     | 
     | 
    { | 
    
    
    2390  | 
     | 
     | 
    	u_int i;  | 
    
    
    2391  | 
     | 
     | 
     | 
    
    
    2392  | 
     | 
     | 
    	printf("%s", lookup_opcode_name(code)); | 
    
    
    2393  | 
     | 
     | 
    	for (i = 0; i < count; i++)  | 
    
    
    2394  | 
     | 
     | 
    		printf(" %s",  vals[i]); | 
    
    
    2395  | 
     | 
     | 
    	printf("\n"); | 
    
    
    2396  | 
     | 
     | 
    }  | 
    
    
    2397  | 
     | 
     | 
     | 
    
    
    2398  | 
     | 
     | 
    static void  | 
    
    
    2399  | 
     | 
     | 
    dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)  | 
    
    
    2400  | 
     | 
     | 
    { | 
    
    
    2401  | 
     | 
     | 
    	const struct Forward *fwd;  | 
    
    
    2402  | 
     | 
     | 
    	u_int i;  | 
    
    
    2403  | 
     | 
     | 
     | 
    
    
    2404  | 
     | 
     | 
    	/* oDynamicForward */  | 
    
    
    2405  | 
     | 
     | 
    	for (i = 0; i < count; i++) { | 
    
    
    2406  | 
     | 
     | 
    		fwd = &fwds[i];  | 
    
    
    2407  | 
     | 
     | 
    		if (code == oDynamicForward && fwd->connect_host != NULL &&  | 
    
    
    2408  | 
     | 
     | 
    		    strcmp(fwd->connect_host, "socks") != 0)  | 
    
    
    2409  | 
     | 
     | 
    			continue;  | 
    
    
    2410  | 
     | 
     | 
    		if (code == oLocalForward && fwd->connect_host != NULL &&  | 
    
    
    2411  | 
     | 
     | 
    		    strcmp(fwd->connect_host, "socks") == 0)  | 
    
    
    2412  | 
     | 
     | 
    			continue;  | 
    
    
    2413  | 
     | 
     | 
    		printf("%s", lookup_opcode_name(code)); | 
    
    
    2414  | 
     | 
     | 
    		if (fwd->listen_port == PORT_STREAMLOCAL)  | 
    
    
    2415  | 
     | 
     | 
    			printf(" %s", fwd->listen_path); | 
    
    
    2416  | 
     | 
     | 
    		else if (fwd->listen_host == NULL)  | 
    
    
    2417  | 
     | 
     | 
    			printf(" %d", fwd->listen_port); | 
    
    
    2418  | 
     | 
     | 
    		else { | 
    
    
    2419  | 
     | 
     | 
    			printf(" [%s]:%d", | 
    
    
    2420  | 
     | 
     | 
    			    fwd->listen_host, fwd->listen_port);  | 
    
    
    2421  | 
     | 
     | 
    		}  | 
    
    
    2422  | 
     | 
     | 
    		if (code != oDynamicForward) { | 
    
    
    2423  | 
     | 
     | 
    			if (fwd->connect_port == PORT_STREAMLOCAL)  | 
    
    
    2424  | 
     | 
     | 
    				printf(" %s", fwd->connect_path); | 
    
    
    2425  | 
     | 
     | 
    			else if (fwd->connect_host == NULL)  | 
    
    
    2426  | 
     | 
     | 
    				printf(" %d", fwd->connect_port); | 
    
    
    2427  | 
     | 
     | 
    			else { | 
    
    
    2428  | 
     | 
     | 
    				printf(" [%s]:%d", | 
    
    
    2429  | 
     | 
     | 
    				    fwd->connect_host, fwd->connect_port);  | 
    
    
    2430  | 
     | 
     | 
    			}  | 
    
    
    2431  | 
     | 
     | 
    		}  | 
    
    
    2432  | 
     | 
     | 
    		printf("\n"); | 
    
    
    2433  | 
     | 
     | 
    	}  | 
    
    
    2434  | 
     | 
     | 
    }  | 
    
    
    2435  | 
     | 
     | 
     | 
    
    
    2436  | 
     | 
     | 
    void  | 
    
    
    2437  | 
     | 
     | 
    dump_client_config(Options *o, const char *host)  | 
    
    
    2438  | 
     | 
     | 
    { | 
    
    
    2439  | 
     | 
     | 
    	int i;  | 
    
    
    2440  | 
     | 
     | 
    	char buf[8];  | 
    
    
    2441  | 
     | 
     | 
     | 
    
    
    2442  | 
     | 
     | 
    	/* This is normally prepared in ssh_kex2 */  | 
    
    
    2443  | 
     | 
     | 
    	if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)  | 
    
    
    2444  | 
     | 
     | 
    		fatal("%s: kex_assemble_names failed", __func__); | 
    
    
    2445  | 
     | 
     | 
     | 
    
    
    2446  | 
     | 
     | 
    	/* Most interesting options first: user, host, port */  | 
    
    
    2447  | 
     | 
     | 
    	dump_cfg_string(oUser, o->user);  | 
    
    
    2448  | 
     | 
     | 
    	dump_cfg_string(oHostName, host);  | 
    
    
    2449  | 
     | 
     | 
    	dump_cfg_int(oPort, o->port);  | 
    
    
    2450  | 
     | 
     | 
     | 
    
    
    2451  | 
     | 
     | 
    	/* Flag options */  | 
    
    
    2452  | 
     | 
     | 
    	dump_cfg_fmtint(oAddressFamily, o->address_family);  | 
    
    
    2453  | 
     | 
     | 
    	dump_cfg_fmtint(oBatchMode, o->batch_mode);  | 
    
    
    2454  | 
     | 
     | 
    	dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);  | 
    
    
    2455  | 
     | 
     | 
    	dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);  | 
    
    
    2456  | 
     | 
     | 
    	dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);  | 
    
    
    2457  | 
     | 
     | 
    	dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);  | 
    
    
    2458  | 
     | 
     | 
    	dump_cfg_fmtint(oCompression, o->compression);  | 
    
    
    2459  | 
     | 
     | 
    	dump_cfg_fmtint(oControlMaster, o->control_master);  | 
    
    
    2460  | 
     | 
     | 
    	dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);  | 
    
    
    2461  | 
     | 
     | 
    	dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);  | 
    
    
    2462  | 
     | 
     | 
    	dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);  | 
    
    
    2463  | 
     | 
     | 
    	dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);  | 
    
    
    2464  | 
     | 
     | 
    	dump_cfg_fmtint(oForwardAgent, o->forward_agent);  | 
    
    
    2465  | 
     | 
     | 
    	dump_cfg_fmtint(oForwardX11, o->forward_x11);  | 
    
    
    2466  | 
     | 
     | 
    	dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);  | 
    
    
    2467  | 
     | 
     | 
    	dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);  | 
    
    
    2468  | 
     | 
     | 
    #ifdef GSSAPI  | 
    
    
    2469  | 
     | 
     | 
    	dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);  | 
    
    
    2470  | 
     | 
     | 
    	dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);  | 
    
    
    2471  | 
     | 
     | 
    #endif /* GSSAPI */  | 
    
    
    2472  | 
     | 
     | 
    	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);  | 
    
    
    2473  | 
     | 
     | 
    	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);  | 
    
    
    2474  | 
     | 
     | 
    	dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);  | 
    
    
    2475  | 
     | 
     | 
    	dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);  | 
    
    
    2476  | 
     | 
     | 
    	dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);  | 
    
    
    2477  | 
     | 
     | 
    	dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);  | 
    
    
    2478  | 
     | 
     | 
    	dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);  | 
    
    
    2479  | 
     | 
     | 
    	dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);  | 
    
    
    2480  | 
     | 
     | 
    	dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);  | 
    
    
    2481  | 
     | 
     | 
    	dump_cfg_fmtint(oRequestTTY, o->request_tty);  | 
    
    
    2482  | 
     | 
     | 
    	dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);  | 
    
    
    2483  | 
     | 
     | 
    	dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);  | 
    
    
    2484  | 
     | 
     | 
    	dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);  | 
    
    
    2485  | 
     | 
     | 
    	dump_cfg_fmtint(oTunnel, o->tun_open);  | 
    
    
    2486  | 
     | 
     | 
    	dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);  | 
    
    
    2487  | 
     | 
     | 
    	dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);  | 
    
    
    2488  | 
     | 
     | 
    	dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);  | 
    
    
    2489  | 
     | 
     | 
    	dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);  | 
    
    
    2490  | 
     | 
     | 
     | 
    
    
    2491  | 
     | 
     | 
    	/* Integer options */  | 
    
    
    2492  | 
     | 
     | 
    	dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);  | 
    
    
    2493  | 
     | 
     | 
    	dump_cfg_int(oConnectionAttempts, o->connection_attempts);  | 
    
    
    2494  | 
     | 
     | 
    	dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);  | 
    
    
    2495  | 
     | 
     | 
    	dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);  | 
    
    
    2496  | 
     | 
     | 
    	dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);  | 
    
    
    2497  | 
     | 
     | 
    	dump_cfg_int(oServerAliveInterval, o->server_alive_interval);  | 
    
    
    2498  | 
     | 
     | 
     | 
    
    
    2499  | 
     | 
     | 
    	/* String options */  | 
    
    
    2500  | 
     | 
     | 
    	dump_cfg_string(oBindAddress, o->bind_address);  | 
    
    
    2501  | 
     | 
     | 
    	dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);  | 
    
    
    2502  | 
     | 
     | 
    	dump_cfg_string(oControlPath, o->control_path);  | 
    
    
    2503  | 
     | 
     | 
    	dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);  | 
    
    
    2504  | 
     | 
     | 
    	dump_cfg_string(oHostKeyAlias, o->host_key_alias);  | 
    
    
    2505  | 
     | 
     | 
    	dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);  | 
    
    
    2506  | 
     | 
     | 
    	dump_cfg_string(oIdentityAgent, o->identity_agent);  | 
    
    
    2507  | 
     | 
     | 
    	dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);  | 
    
    
    2508  | 
     | 
     | 
    	dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);  | 
    
    
    2509  | 
     | 
     | 
    	dump_cfg_string(oLocalCommand, o->local_command);  | 
    
    
    2510  | 
     | 
     | 
    	dump_cfg_string(oRemoteCommand, o->remote_command);  | 
    
    
    2511  | 
     | 
     | 
    	dump_cfg_string(oLogLevel, log_level_name(o->log_level));  | 
    
    
    2512  | 
     | 
     | 
    	dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);  | 
    
    
    2513  | 
     | 
     | 
    #ifdef ENABLE_PKCS11  | 
    
    
    2514  | 
     | 
     | 
    	dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);  | 
    
    
    2515  | 
     | 
     | 
    #endif  | 
    
    
    2516  | 
     | 
     | 
    	dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);  | 
    
    
    2517  | 
     | 
     | 
    	dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);  | 
    
    
    2518  | 
     | 
     | 
    	dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);  | 
    
    
    2519  | 
     | 
     | 
    	dump_cfg_string(oXAuthLocation, o->xauth_location);  | 
    
    
    2520  | 
     | 
     | 
     | 
    
    
    2521  | 
     | 
     | 
    	/* Forwards */  | 
    
    
    2522  | 
     | 
     | 
    	dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);  | 
    
    
    2523  | 
     | 
     | 
    	dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);  | 
    
    
    2524  | 
     | 
     | 
    	dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);  | 
    
    
    2525  | 
     | 
     | 
     | 
    
    
    2526  | 
     | 
     | 
    	/* String array options */  | 
    
    
    2527  | 
     | 
     | 
    	dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);  | 
    
    
    2528  | 
     | 
     | 
    	dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);  | 
    
    
    2529  | 
     | 
     | 
    	dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);  | 
    
    
    2530  | 
     | 
     | 
    	dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);  | 
    
    
    2531  | 
     | 
     | 
    	dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);  | 
    
    
    2532  | 
     | 
     | 
     | 
    
    
    2533  | 
     | 
     | 
    	/* Special cases */  | 
    
    
    2534  | 
     | 
     | 
     | 
    
    
    2535  | 
     | 
     | 
    	/* oConnectTimeout */  | 
    
    
    2536  | 
     | 
     | 
    	if (o->connection_timeout == -1)  | 
    
    
    2537  | 
     | 
     | 
    		printf("connecttimeout none\n"); | 
    
    
    2538  | 
     | 
     | 
    	else  | 
    
    
    2539  | 
     | 
     | 
    		dump_cfg_int(oConnectTimeout, o->connection_timeout);  | 
    
    
    2540  | 
     | 
     | 
     | 
    
    
    2541  | 
     | 
     | 
    	/* oTunnelDevice */  | 
    
    
    2542  | 
     | 
     | 
    	printf("tunneldevice"); | 
    
    
    2543  | 
     | 
     | 
    	if (o->tun_local == SSH_TUNID_ANY)  | 
    
    
    2544  | 
     | 
     | 
    		printf(" any"); | 
    
    
    2545  | 
     | 
     | 
    	else  | 
    
    
    2546  | 
     | 
     | 
    		printf(" %d", o->tun_local); | 
    
    
    2547  | 
     | 
     | 
    	if (o->tun_remote == SSH_TUNID_ANY)  | 
    
    
    2548  | 
     | 
     | 
    		printf(":any"); | 
    
    
    2549  | 
     | 
     | 
    	else  | 
    
    
    2550  | 
     | 
     | 
    		printf(":%d", o->tun_remote); | 
    
    
    2551  | 
     | 
     | 
    	printf("\n"); | 
    
    
    2552  | 
     | 
     | 
     | 
    
    
    2553  | 
     | 
     | 
    	/* oCanonicalizePermittedCNAMEs */  | 
    
    
    2554  | 
     | 
     | 
    	if ( o->num_permitted_cnames > 0) { | 
    
    
    2555  | 
     | 
     | 
    		printf("canonicalizePermittedcnames"); | 
    
    
    2556  | 
     | 
     | 
    		for (i = 0; i < o->num_permitted_cnames; i++) { | 
    
    
    2557  | 
     | 
     | 
    			printf(" %s:%s", o->permitted_cnames[i].source_list, | 
    
    
    2558  | 
     | 
     | 
    			    o->permitted_cnames[i].target_list);  | 
    
    
    2559  | 
     | 
     | 
    		}  | 
    
    
    2560  | 
     | 
     | 
    		printf("\n"); | 
    
    
    2561  | 
     | 
     | 
    	}  | 
    
    
    2562  | 
     | 
     | 
     | 
    
    
    2563  | 
     | 
     | 
    	/* oControlPersist */  | 
    
    
    2564  | 
     | 
     | 
    	if (o->control_persist == 0 || o->control_persist_timeout == 0)  | 
    
    
    2565  | 
     | 
     | 
    		dump_cfg_fmtint(oControlPersist, o->control_persist);  | 
    
    
    2566  | 
     | 
     | 
    	else  | 
    
    
    2567  | 
     | 
     | 
    		dump_cfg_int(oControlPersist, o->control_persist_timeout);  | 
    
    
    2568  | 
     | 
     | 
     | 
    
    
    2569  | 
     | 
     | 
    	/* oEscapeChar */  | 
    
    
    2570  | 
     | 
     | 
    	if (o->escape_char == SSH_ESCAPECHAR_NONE)  | 
    
    
    2571  | 
     | 
     | 
    		printf("escapechar none\n"); | 
    
    
    2572  | 
     | 
     | 
    	else { | 
    
    
    2573  | 
     | 
     | 
    		vis(buf, o->escape_char, VIS_WHITE, 0);  | 
    
    
    2574  | 
     | 
     | 
    		printf("escapechar %s\n", buf); | 
    
    
    2575  | 
     | 
     | 
    	}  | 
    
    
    2576  | 
     | 
     | 
     | 
    
    
    2577  | 
     | 
     | 
    	/* oIPQoS */  | 
    
    
    2578  | 
     | 
     | 
    	printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); | 
    
    
    2579  | 
     | 
     | 
    	printf("%s\n", iptos2str(o->ip_qos_bulk)); | 
    
    
    2580  | 
     | 
     | 
     | 
    
    
    2581  | 
     | 
     | 
    	/* oRekeyLimit */  | 
    
    
    2582  | 
     | 
     | 
    	printf("rekeylimit %llu %d\n", | 
    
    
    2583  | 
     | 
     | 
    	    (unsigned long long)o->rekey_limit, o->rekey_interval);  | 
    
    
    2584  | 
     | 
     | 
     | 
    
    
    2585  | 
     | 
     | 
    	/* oStreamLocalBindMask */  | 
    
    
    2586  | 
     | 
     | 
    	printf("streamlocalbindmask 0%o\n", | 
    
    
    2587  | 
     | 
     | 
    	    o->fwd_opts.streamlocal_bind_mask);  | 
    
    
    2588  | 
     | 
     | 
     | 
    
    
    2589  | 
     | 
     | 
    	/* oProxyCommand / oProxyJump */  | 
    
    
    2590  | 
     | 
     | 
    	if (o->jump_host == NULL)  | 
    
    
    2591  | 
     | 
     | 
    		dump_cfg_string(oProxyCommand, o->proxy_command);  | 
    
    
    2592  | 
     | 
     | 
    	else { | 
    
    
    2593  | 
     | 
     | 
    		/* Check for numeric addresses */  | 
    
    
    2594  | 
     | 
     | 
    		i = strchr(o->jump_host, ':') != NULL ||  | 
    
    
    2595  | 
     | 
     | 
    		    strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);  | 
    
    
    2596  | 
     | 
     | 
    		snprintf(buf, sizeof(buf), "%d", o->jump_port);  | 
    
    
    2597  | 
     | 
     | 
    		printf("proxyjump %s%s%s%s%s%s%s%s%s\n", | 
    
    
    2598  | 
     | 
     | 
    		    /* optional additional jump spec */  | 
    
    
    2599  | 
     | 
     | 
    		    o->jump_extra == NULL ? "" : o->jump_extra,  | 
    
    
    2600  | 
     | 
     | 
    		    o->jump_extra == NULL ? "" : ",",  | 
    
    
    2601  | 
     | 
     | 
    		    /* optional user */  | 
    
    
    2602  | 
     | 
     | 
    		    o->jump_user == NULL ? "" : o->jump_user,  | 
    
    
    2603  | 
     | 
     | 
    		    o->jump_user == NULL ? "" : "@",  | 
    
    
    2604  | 
     | 
     | 
    		    /* opening [ if hostname is numeric */  | 
    
    
    2605  | 
     | 
     | 
    		    i ? "[" : "",  | 
    
    
    2606  | 
     | 
     | 
    		    /* mandatory hostname */  | 
    
    
    2607  | 
     | 
     | 
    		    o->jump_host,  | 
    
    
    2608  | 
     | 
     | 
    		    /* closing ] if hostname is numeric */  | 
    
    
    2609  | 
     | 
     | 
    		    i ? "]" : "",  | 
    
    
    2610  | 
     | 
     | 
    		    /* optional port number */  | 
    
    
    2611  | 
     | 
     | 
    		    o->jump_port <= 0 ? "" : ":",  | 
    
    
    2612  | 
     | 
     | 
    		    o->jump_port <= 0 ? "" : buf);  | 
    
    
    2613  | 
     | 
     | 
    	}  | 
    
    
    2614  | 
     | 
     | 
    }  |