1*e4a9863fSDag-Erling Smørgrav /* $OpenBSD: readconf.c,v 1.204 2013/06/10 19:19:44 dtucker Exp $ */ 289986192SBrooks Davis /* $FreeBSD$ */ 3511b41d2SMark Murray /* 4511b41d2SMark Murray * Author: Tatu Ylonen <ylo@cs.hut.fi> 5511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6511b41d2SMark Murray * All rights reserved 7511b41d2SMark Murray * Functions for reading the configuration files. 8511b41d2SMark Murray * 9c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 10c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 11c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 12c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 13c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 14511b41d2SMark Murray */ 15511b41d2SMark Murray 16511b41d2SMark Murray #include "includes.h" 17333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 18511b41d2SMark Murray 19333ee039SDag-Erling Smørgrav #include <sys/types.h> 20333ee039SDag-Erling Smørgrav #include <sys/stat.h> 21333ee039SDag-Erling Smørgrav #include <sys/socket.h> 2203f6c5cdSDag-Erling Smørgrav #include <sys/sysctl.h> 23333ee039SDag-Erling Smørgrav 24333ee039SDag-Erling Smørgrav #include <netinet/in.h> 254a421b63SDag-Erling Smørgrav #include <netinet/in_systm.h> 264a421b63SDag-Erling Smørgrav #include <netinet/ip.h> 27333ee039SDag-Erling Smørgrav 28333ee039SDag-Erling Smørgrav #include <ctype.h> 29333ee039SDag-Erling Smørgrav #include <errno.h> 30333ee039SDag-Erling Smørgrav #include <netdb.h> 31333ee039SDag-Erling Smørgrav #include <signal.h> 32333ee039SDag-Erling Smørgrav #include <stdarg.h> 33333ee039SDag-Erling Smørgrav #include <stdio.h> 34333ee039SDag-Erling Smørgrav #include <string.h> 35333ee039SDag-Erling Smørgrav #include <unistd.h> 36*e4a9863fSDag-Erling Smørgrav #ifdef HAVE_UTIL_H 37*e4a9863fSDag-Erling Smørgrav #include <util.h> 38*e4a9863fSDag-Erling Smørgrav #endif 39333ee039SDag-Erling Smørgrav 40511b41d2SMark Murray #include "xmalloc.h" 41333ee039SDag-Erling Smørgrav #include "ssh.h" 42e8aafc91SKris Kennaway #include "compat.h" 43ca3176e7SBrian Feldman #include "cipher.h" 44ca3176e7SBrian Feldman #include "pathnames.h" 45ca3176e7SBrian Feldman #include "log.h" 46333ee039SDag-Erling Smørgrav #include "key.h" 47ca3176e7SBrian Feldman #include "readconf.h" 48ca3176e7SBrian Feldman #include "match.h" 49ca3176e7SBrian Feldman #include "misc.h" 50333ee039SDag-Erling Smørgrav #include "buffer.h" 51ca3176e7SBrian Feldman #include "kex.h" 52ca3176e7SBrian Feldman #include "mac.h" 53cce7d346SDag-Erling Smørgrav #include "version.h" 54511b41d2SMark Murray 55511b41d2SMark Murray /* Format of the configuration file: 56511b41d2SMark Murray 57511b41d2SMark Murray # Configuration data is parsed as follows: 58511b41d2SMark Murray # 1. command line options 59511b41d2SMark Murray # 2. user-specific file 60511b41d2SMark Murray # 3. system-wide file 61511b41d2SMark Murray # Any configuration value is only changed the first time it is set. 62511b41d2SMark Murray # Thus, host-specific definitions should be at the beginning of the 63511b41d2SMark Murray # configuration file, and defaults at the end. 64511b41d2SMark Murray 65511b41d2SMark Murray # Host-specific declarations. These may override anything above. A single 66511b41d2SMark Murray # host may match multiple declarations; these are processed in the order 67511b41d2SMark Murray # that they are given in. 68511b41d2SMark Murray 69511b41d2SMark Murray Host *.ngs.fi ngs.fi 7080628bacSDag-Erling Smørgrav User foo 71511b41d2SMark Murray 72511b41d2SMark Murray Host fake.com 73511b41d2SMark Murray HostName another.host.name.real.org 74511b41d2SMark Murray User blaah 75511b41d2SMark Murray Port 34289 76511b41d2SMark Murray ForwardX11 no 77511b41d2SMark Murray ForwardAgent no 78511b41d2SMark Murray 79511b41d2SMark Murray Host books.com 80511b41d2SMark Murray RemoteForward 9999 shadows.cs.hut.fi:9999 81511b41d2SMark Murray Cipher 3des 82511b41d2SMark Murray 83511b41d2SMark Murray Host fascist.blob.com 84511b41d2SMark Murray Port 23123 85511b41d2SMark Murray User tylonen 86511b41d2SMark Murray PasswordAuthentication no 87511b41d2SMark Murray 88511b41d2SMark Murray Host puukko.hut.fi 89511b41d2SMark Murray User t35124p 90511b41d2SMark Murray ProxyCommand ssh-proxy %h %p 91511b41d2SMark Murray 92511b41d2SMark Murray Host *.fr 9380628bacSDag-Erling Smørgrav PublicKeyAuthentication no 94511b41d2SMark Murray 95511b41d2SMark Murray Host *.su 96511b41d2SMark Murray Cipher none 97511b41d2SMark Murray PasswordAuthentication no 98511b41d2SMark Murray 99b74df5b2SDag-Erling Smørgrav Host vpn.fake.com 100b74df5b2SDag-Erling Smørgrav Tunnel yes 101b74df5b2SDag-Erling Smørgrav TunnelDevice 3 102b74df5b2SDag-Erling Smørgrav 103511b41d2SMark Murray # Defaults for various options 104511b41d2SMark Murray Host * 105511b41d2SMark Murray ForwardAgent no 106ca3176e7SBrian Feldman ForwardX11 no 107511b41d2SMark Murray PasswordAuthentication yes 108511b41d2SMark Murray RSAAuthentication yes 109511b41d2SMark Murray RhostsRSAAuthentication yes 110511b41d2SMark Murray StrictHostKeyChecking yes 1111ec0d754SDag-Erling Smørgrav TcpKeepAlive no 112511b41d2SMark Murray IdentityFile ~/.ssh/identity 113511b41d2SMark Murray Port 22 114511b41d2SMark Murray EscapeChar ~ 115511b41d2SMark Murray 116511b41d2SMark Murray */ 117511b41d2SMark Murray 118511b41d2SMark Murray /* Keyword tokens. */ 119511b41d2SMark Murray 120511b41d2SMark Murray typedef enum { 121511b41d2SMark Murray oBadOption, 122e2f6069cSDag-Erling Smørgrav oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, 123e2f6069cSDag-Erling Smørgrav oGatewayPorts, oExitOnForwardFailure, 12480628bacSDag-Erling Smørgrav oPasswordAuthentication, oRSAAuthentication, 125ca3176e7SBrian Feldman oChallengeResponseAuthentication, oXAuthLocation, 126511b41d2SMark Murray oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 127511b41d2SMark Murray oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 128511b41d2SMark Murray oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 129511b41d2SMark Murray oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1301ec0d754SDag-Erling Smørgrav oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 131ca3176e7SBrian Feldman oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 132ca3176e7SBrian Feldman oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 133ca3176e7SBrian Feldman oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 134ca3176e7SBrian Feldman oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 135b15c8340SDag-Erling Smørgrav oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 1369e2cbe04SDag-Erling Smørgrav oClearAllForwardings, oNoHostAuthenticationForLocalhost, 137cf2b5f3bSDag-Erling Smørgrav oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 138cf2b5f3bSDag-Erling Smørgrav oAddressFamily, oGssAuthentication, oGssDelegateCreds, 1395962c0e9SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 140e2f6069cSDag-Erling Smørgrav oSendEnv, oControlPath, oControlMaster, oControlPersist, 141e2f6069cSDag-Erling Smørgrav oHashKnownHosts, 142b74df5b2SDag-Erling Smørgrav oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 1437aee6ffeSDag-Erling Smørgrav oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 144*e4a9863fSDag-Erling Smørgrav oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, 145*e4a9863fSDag-Erling Smørgrav oIgnoredUnknownOption, 14689986192SBrooks Davis oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf, 14789986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 14889986192SBrooks Davis oNoneEnabled, oNoneSwitch, 14989986192SBrooks Davis #endif 150*e4a9863fSDag-Erling Smørgrav oVersionAddendum, oDeprecated, oUnsupported 151511b41d2SMark Murray } OpCodes; 152511b41d2SMark Murray 153511b41d2SMark Murray /* Textual representations of the tokens. */ 154511b41d2SMark Murray 155511b41d2SMark Murray static struct { 156511b41d2SMark Murray const char *name; 157511b41d2SMark Murray OpCodes opcode; 158511b41d2SMark Murray } keywords[] = { 159511b41d2SMark Murray { "forwardagent", oForwardAgent }, 160511b41d2SMark Murray { "forwardx11", oForwardX11 }, 1611ec0d754SDag-Erling Smørgrav { "forwardx11trusted", oForwardX11Trusted }, 162e2f6069cSDag-Erling Smørgrav { "forwardx11timeout", oForwardX11Timeout }, 163333ee039SDag-Erling Smørgrav { "exitonforwardfailure", oExitOnForwardFailure }, 164c2d3a559SKris Kennaway { "xauthlocation", oXAuthLocation }, 165511b41d2SMark Murray { "gatewayports", oGatewayPorts }, 166511b41d2SMark Murray { "useprivilegedport", oUsePrivilegedPort }, 167cf2b5f3bSDag-Erling Smørgrav { "rhostsauthentication", oDeprecated }, 168511b41d2SMark Murray { "passwordauthentication", oPasswordAuthentication }, 16909958426SBrian Feldman { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 17009958426SBrian Feldman { "kbdinteractivedevices", oKbdInteractiveDevices }, 171511b41d2SMark Murray { "rsaauthentication", oRSAAuthentication }, 172ca3176e7SBrian Feldman { "pubkeyauthentication", oPubkeyAuthentication }, 173ca3176e7SBrian Feldman { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 174ca3176e7SBrian Feldman { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 175ca3176e7SBrian Feldman { "hostbasedauthentication", oHostbasedAuthentication }, 176ca3176e7SBrian Feldman { "challengeresponseauthentication", oChallengeResponseAuthentication }, 177ca3176e7SBrian Feldman { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 178ca3176e7SBrian Feldman { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 179cf2b5f3bSDag-Erling Smørgrav { "kerberosauthentication", oUnsupported }, 180cf2b5f3bSDag-Erling Smørgrav { "kerberostgtpassing", oUnsupported }, 181cf2b5f3bSDag-Erling Smørgrav { "afstokenpassing", oUnsupported }, 182cf2b5f3bSDag-Erling Smørgrav #if defined(GSSAPI) 183cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oGssAuthentication }, 184cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oGssDelegateCreds }, 185cf2b5f3bSDag-Erling Smørgrav #else 186cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oUnsupported }, 187cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oUnsupported }, 188511b41d2SMark Murray #endif 18980628bacSDag-Erling Smørgrav { "fallbacktorsh", oDeprecated }, 19080628bacSDag-Erling Smørgrav { "usersh", oDeprecated }, 191511b41d2SMark Murray { "identityfile", oIdentityFile }, 192cce7d346SDag-Erling Smørgrav { "identityfile2", oIdentityFile }, /* obsolete */ 1935962c0e9SDag-Erling Smørgrav { "identitiesonly", oIdentitiesOnly }, 194511b41d2SMark Murray { "hostname", oHostName }, 195ca3176e7SBrian Feldman { "hostkeyalias", oHostKeyAlias }, 196511b41d2SMark Murray { "proxycommand", oProxyCommand }, 197511b41d2SMark Murray { "port", oPort }, 198511b41d2SMark Murray { "cipher", oCipher }, 199e8aafc91SKris Kennaway { "ciphers", oCiphers }, 200ca3176e7SBrian Feldman { "macs", oMacs }, 201e8aafc91SKris Kennaway { "protocol", oProtocol }, 202511b41d2SMark Murray { "remoteforward", oRemoteForward }, 203511b41d2SMark Murray { "localforward", oLocalForward }, 204511b41d2SMark Murray { "user", oUser }, 205511b41d2SMark Murray { "host", oHost }, 206511b41d2SMark Murray { "escapechar", oEscapeChar }, 207511b41d2SMark Murray { "globalknownhostsfile", oGlobalKnownHostsFile }, 208e146993eSDag-Erling Smørgrav { "globalknownhostsfile2", oDeprecated }, 209cce7d346SDag-Erling Smørgrav { "userknownhostsfile", oUserKnownHostsFile }, 210e146993eSDag-Erling Smørgrav { "userknownhostsfile2", oDeprecated }, 211511b41d2SMark Murray { "connectionattempts", oConnectionAttempts }, 212511b41d2SMark Murray { "batchmode", oBatchMode }, 213511b41d2SMark Murray { "checkhostip", oCheckHostIP }, 214511b41d2SMark Murray { "stricthostkeychecking", oStrictHostKeyChecking }, 215511b41d2SMark Murray { "compression", oCompression }, 216511b41d2SMark Murray { "compressionlevel", oCompressionLevel }, 2171ec0d754SDag-Erling Smørgrav { "tcpkeepalive", oTCPKeepAlive }, 2181ec0d754SDag-Erling Smørgrav { "keepalive", oTCPKeepAlive }, /* obsolete */ 219511b41d2SMark Murray { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 220511b41d2SMark Murray { "loglevel", oLogLevel }, 221ca3176e7SBrian Feldman { "dynamicforward", oDynamicForward }, 222ca3176e7SBrian Feldman { "preferredauthentications", oPreferredAuthentications }, 223ca3176e7SBrian Feldman { "hostkeyalgorithms", oHostKeyAlgorithms }, 224af12a3e7SDag-Erling Smørgrav { "bindaddress", oBindAddress }, 225b15c8340SDag-Erling Smørgrav #ifdef ENABLE_PKCS11 226b15c8340SDag-Erling Smørgrav { "smartcarddevice", oPKCS11Provider }, 227b15c8340SDag-Erling Smørgrav { "pkcs11provider", oPKCS11Provider }, 228cf2b5f3bSDag-Erling Smørgrav #else 229cf2b5f3bSDag-Erling Smørgrav { "smartcarddevice", oUnsupported }, 230b15c8340SDag-Erling Smørgrav { "pkcs11provider", oUnsupported }, 231cf2b5f3bSDag-Erling Smørgrav #endif 232af12a3e7SDag-Erling Smørgrav { "clearallforwardings", oClearAllForwardings }, 233e73e9afaSDag-Erling Smørgrav { "enablesshkeysign", oEnableSSHKeysign }, 234cf2b5f3bSDag-Erling Smørgrav { "verifyhostkeydns", oVerifyHostKeyDNS }, 235af12a3e7SDag-Erling Smørgrav { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 236cf2b5f3bSDag-Erling Smørgrav { "rekeylimit", oRekeyLimit }, 237cf2b5f3bSDag-Erling Smørgrav { "connecttimeout", oConnectTimeout }, 238cf2b5f3bSDag-Erling Smørgrav { "addressfamily", oAddressFamily }, 2391ec0d754SDag-Erling Smørgrav { "serveraliveinterval", oServerAliveInterval }, 2401ec0d754SDag-Erling Smørgrav { "serveralivecountmax", oServerAliveCountMax }, 24121e764dfSDag-Erling Smørgrav { "sendenv", oSendEnv }, 24221e764dfSDag-Erling Smørgrav { "controlpath", oControlPath }, 24321e764dfSDag-Erling Smørgrav { "controlmaster", oControlMaster }, 244e2f6069cSDag-Erling Smørgrav { "controlpersist", oControlPersist }, 245aa49c926SDag-Erling Smørgrav { "hashknownhosts", oHashKnownHosts }, 246b74df5b2SDag-Erling Smørgrav { "tunnel", oTunnel }, 247b74df5b2SDag-Erling Smørgrav { "tunneldevice", oTunnelDevice }, 248b74df5b2SDag-Erling Smørgrav { "localcommand", oLocalCommand }, 249b74df5b2SDag-Erling Smørgrav { "permitlocalcommand", oPermitLocalCommand }, 250d4af9e69SDag-Erling Smørgrav { "visualhostkey", oVisualHostKey }, 2517aee6ffeSDag-Erling Smørgrav { "useroaming", oUseRoaming }, 252cce7d346SDag-Erling Smørgrav #ifdef JPAKE 253cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", 254cce7d346SDag-Erling Smørgrav oZeroKnowledgePasswordAuthentication }, 255cce7d346SDag-Erling Smørgrav #else 256cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", oUnsupported }, 257cce7d346SDag-Erling Smørgrav #endif 2584a421b63SDag-Erling Smørgrav { "kexalgorithms", oKexAlgorithms }, 2594a421b63SDag-Erling Smørgrav { "ipqos", oIPQoS }, 260e146993eSDag-Erling Smørgrav { "requesttty", oRequestTTY }, 261*e4a9863fSDag-Erling Smørgrav { "ignoreunknown", oIgnoreUnknown }, 26289986192SBrooks Davis { "hpndisabled", oHPNDisabled }, 26389986192SBrooks Davis { "hpnbuffersize", oHPNBufferSize }, 26489986192SBrooks Davis { "tcprcvbufpoll", oTcpRcvBufPoll }, 26589986192SBrooks Davis { "tcprcvbuf", oTcpRcvBuf }, 26689986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 26789986192SBrooks Davis { "noneenabled", oNoneEnabled }, 26889986192SBrooks Davis { "noneswitch", oNoneSwitch }, 26989986192SBrooks Davis #endif 270975616f0SDag-Erling Smørgrav { "versionaddendum", oVersionAddendum }, 27135762f59SEd Schouten 272af12a3e7SDag-Erling Smørgrav { NULL, oBadOption } 273511b41d2SMark Murray }; 274511b41d2SMark Murray 275511b41d2SMark Murray /* 276511b41d2SMark Murray * Adds a local TCP/IP port forward to options. Never returns if there is an 277511b41d2SMark Murray * error. 278511b41d2SMark Murray */ 279511b41d2SMark Murray 280511b41d2SMark Murray void 281aa49c926SDag-Erling Smørgrav add_local_forward(Options *options, const Forward *newfwd) 282511b41d2SMark Murray { 283511b41d2SMark Murray Forward *fwd; 284f388f5efSDag-Erling Smørgrav #ifndef NO_IPPORT_RESERVED_CONCEPT 285511b41d2SMark Murray extern uid_t original_real_uid; 28603f6c5cdSDag-Erling Smørgrav int ipport_reserved; 28703f6c5cdSDag-Erling Smørgrav #ifdef __FreeBSD__ 28803f6c5cdSDag-Erling Smørgrav size_t len_ipport_reserved = sizeof(ipport_reserved); 28903f6c5cdSDag-Erling Smørgrav 29003f6c5cdSDag-Erling Smørgrav if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 29103f6c5cdSDag-Erling Smørgrav &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 29203f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 29303f6c5cdSDag-Erling Smørgrav else 29403f6c5cdSDag-Erling Smørgrav ipport_reserved++; 29503f6c5cdSDag-Erling Smørgrav #else 29603f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 29703f6c5cdSDag-Erling Smørgrav #endif 29803f6c5cdSDag-Erling Smørgrav if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 299ca3176e7SBrian Feldman fatal("Privileged ports can only be forwarded by root."); 300989dd127SDag-Erling Smørgrav #endif 301e2f6069cSDag-Erling Smørgrav options->local_forwards = xrealloc(options->local_forwards, 302e2f6069cSDag-Erling Smørgrav options->num_local_forwards + 1, 303e2f6069cSDag-Erling Smørgrav sizeof(*options->local_forwards)); 304511b41d2SMark Murray fwd = &options->local_forwards[options->num_local_forwards++]; 305aa49c926SDag-Erling Smørgrav 306cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 307aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 308cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 309aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 310511b41d2SMark Murray } 311511b41d2SMark Murray 312511b41d2SMark Murray /* 313511b41d2SMark Murray * Adds a remote TCP/IP port forward to options. Never returns if there is 314511b41d2SMark Murray * an error. 315511b41d2SMark Murray */ 316511b41d2SMark Murray 317511b41d2SMark Murray void 318aa49c926SDag-Erling Smørgrav add_remote_forward(Options *options, const Forward *newfwd) 319511b41d2SMark Murray { 320511b41d2SMark Murray Forward *fwd; 321e2f6069cSDag-Erling Smørgrav 322e2f6069cSDag-Erling Smørgrav options->remote_forwards = xrealloc(options->remote_forwards, 323e2f6069cSDag-Erling Smørgrav options->num_remote_forwards + 1, 324e2f6069cSDag-Erling Smørgrav sizeof(*options->remote_forwards)); 325511b41d2SMark Murray fwd = &options->remote_forwards[options->num_remote_forwards++]; 326aa49c926SDag-Erling Smørgrav 327cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 328aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 329cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 330aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 331462c32cbSDag-Erling Smørgrav fwd->handle = newfwd->handle; 332e2f6069cSDag-Erling Smørgrav fwd->allocated_port = 0; 333511b41d2SMark Murray } 334511b41d2SMark Murray 335af12a3e7SDag-Erling Smørgrav static void 336af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options) 337af12a3e7SDag-Erling Smørgrav { 338af12a3e7SDag-Erling Smørgrav int i; 339af12a3e7SDag-Erling Smørgrav 340aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_local_forwards; i++) { 341*e4a9863fSDag-Erling Smørgrav free(options->local_forwards[i].listen_host); 342*e4a9863fSDag-Erling Smørgrav free(options->local_forwards[i].connect_host); 343aa49c926SDag-Erling Smørgrav } 344e2f6069cSDag-Erling Smørgrav if (options->num_local_forwards > 0) { 345*e4a9863fSDag-Erling Smørgrav free(options->local_forwards); 346e2f6069cSDag-Erling Smørgrav options->local_forwards = NULL; 347e2f6069cSDag-Erling Smørgrav } 348af12a3e7SDag-Erling Smørgrav options->num_local_forwards = 0; 349aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_remote_forwards; i++) { 350*e4a9863fSDag-Erling Smørgrav free(options->remote_forwards[i].listen_host); 351*e4a9863fSDag-Erling Smørgrav free(options->remote_forwards[i].connect_host); 352aa49c926SDag-Erling Smørgrav } 353e2f6069cSDag-Erling Smørgrav if (options->num_remote_forwards > 0) { 354*e4a9863fSDag-Erling Smørgrav free(options->remote_forwards); 355e2f6069cSDag-Erling Smørgrav options->remote_forwards = NULL; 356e2f6069cSDag-Erling Smørgrav } 357af12a3e7SDag-Erling Smørgrav options->num_remote_forwards = 0; 358b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 359af12a3e7SDag-Erling Smørgrav } 360af12a3e7SDag-Erling Smørgrav 361fa67e83cSDag-Erling Smørgrav void 362fa67e83cSDag-Erling Smørgrav add_identity_file(Options *options, const char *dir, const char *filename, 363fa67e83cSDag-Erling Smørgrav int userprovided) 364fa67e83cSDag-Erling Smørgrav { 365fa67e83cSDag-Erling Smørgrav char *path; 366fa67e83cSDag-Erling Smørgrav 367fa67e83cSDag-Erling Smørgrav if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 368fa67e83cSDag-Erling Smørgrav fatal("Too many identity files specified (max %d)", 369fa67e83cSDag-Erling Smørgrav SSH_MAX_IDENTITY_FILES); 370fa67e83cSDag-Erling Smørgrav 371fa67e83cSDag-Erling Smørgrav if (dir == NULL) /* no dir, filename is absolute */ 372fa67e83cSDag-Erling Smørgrav path = xstrdup(filename); 373fa67e83cSDag-Erling Smørgrav else 374fa67e83cSDag-Erling Smørgrav (void)xasprintf(&path, "%.100s%.100s", dir, filename); 375fa67e83cSDag-Erling Smørgrav 376fa67e83cSDag-Erling Smørgrav options->identity_file_userprovided[options->num_identity_files] = 377fa67e83cSDag-Erling Smørgrav userprovided; 378fa67e83cSDag-Erling Smørgrav options->identity_files[options->num_identity_files++] = path; 379fa67e83cSDag-Erling Smørgrav } 380fa67e83cSDag-Erling Smørgrav 381511b41d2SMark Murray /* 382ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or oBadOption. 383511b41d2SMark Murray */ 384511b41d2SMark Murray 385511b41d2SMark Murray static OpCodes 386*e4a9863fSDag-Erling Smørgrav parse_token(const char *cp, const char *filename, int linenum, 387*e4a9863fSDag-Erling Smørgrav const char *ignored_unknown) 388511b41d2SMark Murray { 389*e4a9863fSDag-Erling Smørgrav int i; 390511b41d2SMark Murray 391511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 392*e4a9863fSDag-Erling Smørgrav if (strcmp(cp, keywords[i].name) == 0) 393511b41d2SMark Murray return keywords[i].opcode; 394*e4a9863fSDag-Erling Smørgrav if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown, 395*e4a9863fSDag-Erling Smørgrav strlen(ignored_unknown), 1) == 1) 396*e4a9863fSDag-Erling Smørgrav return oIgnoredUnknownOption; 397ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 398511b41d2SMark Murray filename, linenum, cp); 399511b41d2SMark Murray return oBadOption; 400511b41d2SMark Murray } 401511b41d2SMark Murray 402511b41d2SMark Murray /* 403511b41d2SMark Murray * Processes a single option line as used in the configuration files. This 404511b41d2SMark Murray * only sets those values that have not already been set. 405511b41d2SMark Murray */ 406e73e9afaSDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 407511b41d2SMark Murray 408511b41d2SMark Murray int 409511b41d2SMark Murray process_config_line(Options *options, const char *host, 410511b41d2SMark Murray char *line, const char *filename, int linenum, 41173370613SDag-Erling Smørgrav int *activep, int userconfig) 412511b41d2SMark Murray { 413e146993eSDag-Erling Smørgrav char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 414e146993eSDag-Erling Smørgrav char **cpptr, fwdarg[256]; 415*e4a9863fSDag-Erling Smørgrav u_int i, *uintptr, max_entries = 0; 416*e4a9863fSDag-Erling Smørgrav int negated, opcode, *intptr, value, value2; 417d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 418*e4a9863fSDag-Erling Smørgrav long long val64; 419e73e9afaSDag-Erling Smørgrav size_t len; 420aa49c926SDag-Erling Smørgrav Forward fwd; 421511b41d2SMark Murray 422cf2b5f3bSDag-Erling Smørgrav /* Strip trailing whitespace */ 423cf2b5f3bSDag-Erling Smørgrav for (len = strlen(line) - 1; len > 0; len--) { 424cf2b5f3bSDag-Erling Smørgrav if (strchr(WHITESPACE, line[len]) == NULL) 425cf2b5f3bSDag-Erling Smørgrav break; 426cf2b5f3bSDag-Erling Smørgrav line[len] = '\0'; 427cf2b5f3bSDag-Erling Smørgrav } 428cf2b5f3bSDag-Erling Smørgrav 429c2d3a559SKris Kennaway s = line; 430c2d3a559SKris Kennaway /* Get the keyword. (Each line is supposed to begin with a keyword). */ 431333ee039SDag-Erling Smørgrav if ((keyword = strdelim(&s)) == NULL) 432333ee039SDag-Erling Smørgrav return 0; 433c2d3a559SKris Kennaway /* Ignore leading whitespace. */ 434c2d3a559SKris Kennaway if (*keyword == '\0') 435c2d3a559SKris Kennaway keyword = strdelim(&s); 436ca3176e7SBrian Feldman if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 437511b41d2SMark Murray return 0; 438*e4a9863fSDag-Erling Smørgrav /* Match lowercase keyword */ 439*e4a9863fSDag-Erling Smørgrav for (i = 0; i < strlen(keyword); i++) 440*e4a9863fSDag-Erling Smørgrav keyword[i] = tolower(keyword[i]); 441511b41d2SMark Murray 442*e4a9863fSDag-Erling Smørgrav opcode = parse_token(keyword, filename, linenum, 443*e4a9863fSDag-Erling Smørgrav options->ignored_unknown); 444511b41d2SMark Murray 445511b41d2SMark Murray switch (opcode) { 446511b41d2SMark Murray case oBadOption: 447511b41d2SMark Murray /* don't panic, but count bad options */ 448511b41d2SMark Murray return -1; 449511b41d2SMark Murray /* NOTREACHED */ 450*e4a9863fSDag-Erling Smørgrav case oIgnoredUnknownOption: 451*e4a9863fSDag-Erling Smørgrav debug("%s line %d: Ignored unknown option \"%s\"", 452*e4a9863fSDag-Erling Smørgrav filename, linenum, keyword); 453*e4a9863fSDag-Erling Smørgrav return 0; 454cf2b5f3bSDag-Erling Smørgrav case oConnectTimeout: 455cf2b5f3bSDag-Erling Smørgrav intptr = &options->connection_timeout; 4561ec0d754SDag-Erling Smørgrav parse_time: 457cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 458cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 459cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: missing time value.", 460cf2b5f3bSDag-Erling Smørgrav filename, linenum); 461cf2b5f3bSDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 462cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 463cf2b5f3bSDag-Erling Smørgrav filename, linenum); 464d4af9e69SDag-Erling Smørgrav if (*activep && *intptr == -1) 465cf2b5f3bSDag-Erling Smørgrav *intptr = value; 466cf2b5f3bSDag-Erling Smørgrav break; 467cf2b5f3bSDag-Erling Smørgrav 468511b41d2SMark Murray case oForwardAgent: 469511b41d2SMark Murray intptr = &options->forward_agent; 470511b41d2SMark Murray parse_flag: 471c2d3a559SKris Kennaway arg = strdelim(&s); 472c2d3a559SKris Kennaway if (!arg || *arg == '\0') 473511b41d2SMark Murray fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 474511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 475c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 476511b41d2SMark Murray value = 1; 477c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 478511b41d2SMark Murray value = 0; 479511b41d2SMark Murray else 480511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 481511b41d2SMark Murray if (*activep && *intptr == -1) 482511b41d2SMark Murray *intptr = value; 483511b41d2SMark Murray break; 484511b41d2SMark Murray 485511b41d2SMark Murray case oForwardX11: 486511b41d2SMark Murray intptr = &options->forward_x11; 487511b41d2SMark Murray goto parse_flag; 488511b41d2SMark Murray 4891ec0d754SDag-Erling Smørgrav case oForwardX11Trusted: 4901ec0d754SDag-Erling Smørgrav intptr = &options->forward_x11_trusted; 4911ec0d754SDag-Erling Smørgrav goto parse_flag; 4921ec0d754SDag-Erling Smørgrav 493e2f6069cSDag-Erling Smørgrav case oForwardX11Timeout: 494e2f6069cSDag-Erling Smørgrav intptr = &options->forward_x11_timeout; 495e2f6069cSDag-Erling Smørgrav goto parse_time; 496e2f6069cSDag-Erling Smørgrav 497511b41d2SMark Murray case oGatewayPorts: 498511b41d2SMark Murray intptr = &options->gateway_ports; 499511b41d2SMark Murray goto parse_flag; 500511b41d2SMark Murray 501333ee039SDag-Erling Smørgrav case oExitOnForwardFailure: 502333ee039SDag-Erling Smørgrav intptr = &options->exit_on_forward_failure; 503333ee039SDag-Erling Smørgrav goto parse_flag; 504333ee039SDag-Erling Smørgrav 505511b41d2SMark Murray case oUsePrivilegedPort: 506511b41d2SMark Murray intptr = &options->use_privileged_port; 507511b41d2SMark Murray goto parse_flag; 508511b41d2SMark Murray 509511b41d2SMark Murray case oPasswordAuthentication: 510511b41d2SMark Murray intptr = &options->password_authentication; 511511b41d2SMark Murray goto parse_flag; 512511b41d2SMark Murray 513cce7d346SDag-Erling Smørgrav case oZeroKnowledgePasswordAuthentication: 514cce7d346SDag-Erling Smørgrav intptr = &options->zero_knowledge_password_authentication; 515cce7d346SDag-Erling Smørgrav goto parse_flag; 516cce7d346SDag-Erling Smørgrav 51709958426SBrian Feldman case oKbdInteractiveAuthentication: 51809958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 51909958426SBrian Feldman goto parse_flag; 52009958426SBrian Feldman 52109958426SBrian Feldman case oKbdInteractiveDevices: 52209958426SBrian Feldman charptr = &options->kbd_interactive_devices; 52309958426SBrian Feldman goto parse_string; 52409958426SBrian Feldman 525ca3176e7SBrian Feldman case oPubkeyAuthentication: 526ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 527e8aafc91SKris Kennaway goto parse_flag; 528e8aafc91SKris Kennaway 529511b41d2SMark Murray case oRSAAuthentication: 530511b41d2SMark Murray intptr = &options->rsa_authentication; 531511b41d2SMark Murray goto parse_flag; 532511b41d2SMark Murray 533511b41d2SMark Murray case oRhostsRSAAuthentication: 534511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 535511b41d2SMark Murray goto parse_flag; 536511b41d2SMark Murray 537ca3176e7SBrian Feldman case oHostbasedAuthentication: 538ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 539511b41d2SMark Murray goto parse_flag; 540511b41d2SMark Murray 541af12a3e7SDag-Erling Smørgrav case oChallengeResponseAuthentication: 542af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 543af12a3e7SDag-Erling Smørgrav goto parse_flag; 544cf2b5f3bSDag-Erling Smørgrav 545cf2b5f3bSDag-Erling Smørgrav case oGssAuthentication: 546cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 547511b41d2SMark Murray goto parse_flag; 548cf2b5f3bSDag-Erling Smørgrav 549cf2b5f3bSDag-Erling Smørgrav case oGssDelegateCreds: 550cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_deleg_creds; 551ca3176e7SBrian Feldman goto parse_flag; 552cf2b5f3bSDag-Erling Smørgrav 553511b41d2SMark Murray case oBatchMode: 554511b41d2SMark Murray intptr = &options->batch_mode; 555511b41d2SMark Murray goto parse_flag; 556511b41d2SMark Murray 557511b41d2SMark Murray case oCheckHostIP: 558511b41d2SMark Murray intptr = &options->check_host_ip; 559511b41d2SMark Murray goto parse_flag; 560511b41d2SMark Murray 561cf2b5f3bSDag-Erling Smørgrav case oVerifyHostKeyDNS: 562cf2b5f3bSDag-Erling Smørgrav intptr = &options->verify_host_key_dns; 5631ec0d754SDag-Erling Smørgrav goto parse_yesnoask; 564cf2b5f3bSDag-Erling Smørgrav 565511b41d2SMark Murray case oStrictHostKeyChecking: 566511b41d2SMark Murray intptr = &options->strict_host_key_checking; 5671ec0d754SDag-Erling Smørgrav parse_yesnoask: 568c2d3a559SKris Kennaway arg = strdelim(&s); 569c2d3a559SKris Kennaway if (!arg || *arg == '\0') 570ca3176e7SBrian Feldman fatal("%.200s line %d: Missing yes/no/ask argument.", 571511b41d2SMark Murray filename, linenum); 572511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 573c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 574511b41d2SMark Murray value = 1; 575c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 576511b41d2SMark Murray value = 0; 577c2d3a559SKris Kennaway else if (strcmp(arg, "ask") == 0) 578511b41d2SMark Murray value = 2; 579511b41d2SMark Murray else 580511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 581511b41d2SMark Murray if (*activep && *intptr == -1) 582511b41d2SMark Murray *intptr = value; 583511b41d2SMark Murray break; 584511b41d2SMark Murray 585511b41d2SMark Murray case oCompression: 586511b41d2SMark Murray intptr = &options->compression; 587511b41d2SMark Murray goto parse_flag; 588511b41d2SMark Murray 5891ec0d754SDag-Erling Smørgrav case oTCPKeepAlive: 5901ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 591511b41d2SMark Murray goto parse_flag; 592511b41d2SMark Murray 593af12a3e7SDag-Erling Smørgrav case oNoHostAuthenticationForLocalhost: 594af12a3e7SDag-Erling Smørgrav intptr = &options->no_host_authentication_for_localhost; 595af12a3e7SDag-Erling Smørgrav goto parse_flag; 596af12a3e7SDag-Erling Smørgrav 597511b41d2SMark Murray case oNumberOfPasswordPrompts: 598511b41d2SMark Murray intptr = &options->number_of_password_prompts; 599511b41d2SMark Murray goto parse_int; 600511b41d2SMark Murray 601511b41d2SMark Murray case oCompressionLevel: 602511b41d2SMark Murray intptr = &options->compression_level; 603511b41d2SMark Murray goto parse_int; 604511b41d2SMark Murray 605cf2b5f3bSDag-Erling Smørgrav case oRekeyLimit: 606cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 607cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 608*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 609*e4a9863fSDag-Erling Smørgrav linenum); 610*e4a9863fSDag-Erling Smørgrav if (strcmp(arg, "default") == 0) { 611*e4a9863fSDag-Erling Smørgrav val64 = 0; 612*e4a9863fSDag-Erling Smørgrav } else { 613*e4a9863fSDag-Erling Smørgrav if (scan_scaled(arg, &val64) == -1) 614*e4a9863fSDag-Erling Smørgrav fatal("%.200s line %d: Bad number '%s': %s", 615*e4a9863fSDag-Erling Smørgrav filename, linenum, arg, strerror(errno)); 616*e4a9863fSDag-Erling Smørgrav /* check for too-large or too-small limits */ 617*e4a9863fSDag-Erling Smørgrav if (val64 > UINT_MAX) 618333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too large", 619333ee039SDag-Erling Smørgrav filename, linenum); 620*e4a9863fSDag-Erling Smørgrav if (val64 != 0 && val64 < 16) 621333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 622333ee039SDag-Erling Smørgrav filename, linenum); 623*e4a9863fSDag-Erling Smørgrav } 624d4af9e69SDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 625d4af9e69SDag-Erling Smørgrav options->rekey_limit = (u_int32_t)val64; 626*e4a9863fSDag-Erling Smørgrav if (s != NULL) { /* optional rekey interval present */ 627*e4a9863fSDag-Erling Smørgrav if (strcmp(s, "none") == 0) { 628*e4a9863fSDag-Erling Smørgrav (void)strdelim(&s); /* discard */ 629*e4a9863fSDag-Erling Smørgrav break; 630*e4a9863fSDag-Erling Smørgrav } 631*e4a9863fSDag-Erling Smørgrav intptr = &options->rekey_interval; 632*e4a9863fSDag-Erling Smørgrav goto parse_time; 633*e4a9863fSDag-Erling Smørgrav } 634cf2b5f3bSDag-Erling Smørgrav break; 635cf2b5f3bSDag-Erling Smørgrav 636511b41d2SMark Murray case oIdentityFile: 637c2d3a559SKris Kennaway arg = strdelim(&s); 638c2d3a559SKris Kennaway if (!arg || *arg == '\0') 639511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 640511b41d2SMark Murray if (*activep) { 641ca3176e7SBrian Feldman intptr = &options->num_identity_files; 642e8aafc91SKris Kennaway if (*intptr >= SSH_MAX_IDENTITY_FILES) 643511b41d2SMark Murray fatal("%.200s line %d: Too many identity files specified (max %d).", 644511b41d2SMark Murray filename, linenum, SSH_MAX_IDENTITY_FILES); 64573370613SDag-Erling Smørgrav add_identity_file(options, NULL, arg, userconfig); 646511b41d2SMark Murray } 647511b41d2SMark Murray break; 648511b41d2SMark Murray 649c2d3a559SKris Kennaway case oXAuthLocation: 650c2d3a559SKris Kennaway charptr=&options->xauth_location; 651c2d3a559SKris Kennaway goto parse_string; 652c2d3a559SKris Kennaway 653511b41d2SMark Murray case oUser: 654511b41d2SMark Murray charptr = &options->user; 655511b41d2SMark Murray parse_string: 656c2d3a559SKris Kennaway arg = strdelim(&s); 657c2d3a559SKris Kennaway if (!arg || *arg == '\0') 658e146993eSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 659e146993eSDag-Erling Smørgrav filename, linenum); 660511b41d2SMark Murray if (*activep && *charptr == NULL) 661c2d3a559SKris Kennaway *charptr = xstrdup(arg); 662511b41d2SMark Murray break; 663511b41d2SMark Murray 664511b41d2SMark Murray case oGlobalKnownHostsFile: 665e146993eSDag-Erling Smørgrav cpptr = (char **)&options->system_hostfiles; 666e146993eSDag-Erling Smørgrav uintptr = &options->num_system_hostfiles; 667e146993eSDag-Erling Smørgrav max_entries = SSH_MAX_HOSTS_FILES; 668e146993eSDag-Erling Smørgrav parse_char_array: 669e146993eSDag-Erling Smørgrav if (*activep && *uintptr == 0) { 670e146993eSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 671e146993eSDag-Erling Smørgrav if ((*uintptr) >= max_entries) 672e146993eSDag-Erling Smørgrav fatal("%s line %d: " 673e146993eSDag-Erling Smørgrav "too many authorized keys files.", 674e146993eSDag-Erling Smørgrav filename, linenum); 675e146993eSDag-Erling Smørgrav cpptr[(*uintptr)++] = xstrdup(arg); 676e146993eSDag-Erling Smørgrav } 677e146993eSDag-Erling Smørgrav } 678e146993eSDag-Erling Smørgrav return 0; 679511b41d2SMark Murray 680511b41d2SMark Murray case oUserKnownHostsFile: 681e146993eSDag-Erling Smørgrav cpptr = (char **)&options->user_hostfiles; 682e146993eSDag-Erling Smørgrav uintptr = &options->num_user_hostfiles; 683e146993eSDag-Erling Smørgrav max_entries = SSH_MAX_HOSTS_FILES; 684e146993eSDag-Erling Smørgrav goto parse_char_array; 685e8aafc91SKris Kennaway 686511b41d2SMark Murray case oHostName: 687511b41d2SMark Murray charptr = &options->hostname; 688511b41d2SMark Murray goto parse_string; 689511b41d2SMark Murray 690ca3176e7SBrian Feldman case oHostKeyAlias: 691ca3176e7SBrian Feldman charptr = &options->host_key_alias; 692ca3176e7SBrian Feldman goto parse_string; 693ca3176e7SBrian Feldman 694ca3176e7SBrian Feldman case oPreferredAuthentications: 695ca3176e7SBrian Feldman charptr = &options->preferred_authentications; 696ca3176e7SBrian Feldman goto parse_string; 697ca3176e7SBrian Feldman 698af12a3e7SDag-Erling Smørgrav case oBindAddress: 699af12a3e7SDag-Erling Smørgrav charptr = &options->bind_address; 700af12a3e7SDag-Erling Smørgrav goto parse_string; 701af12a3e7SDag-Erling Smørgrav 702b15c8340SDag-Erling Smørgrav case oPKCS11Provider: 703b15c8340SDag-Erling Smørgrav charptr = &options->pkcs11_provider; 704af12a3e7SDag-Erling Smørgrav goto parse_string; 705af12a3e7SDag-Erling Smørgrav 706511b41d2SMark Murray case oProxyCommand: 707b74df5b2SDag-Erling Smørgrav charptr = &options->proxy_command; 708b74df5b2SDag-Erling Smørgrav parse_command: 709cf2b5f3bSDag-Erling Smørgrav if (s == NULL) 710cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 711e73e9afaSDag-Erling Smørgrav len = strspn(s, WHITESPACE "="); 712511b41d2SMark Murray if (*activep && *charptr == NULL) 713e73e9afaSDag-Erling Smørgrav *charptr = xstrdup(s + len); 714511b41d2SMark Murray return 0; 715511b41d2SMark Murray 716511b41d2SMark Murray case oPort: 717511b41d2SMark Murray intptr = &options->port; 718511b41d2SMark Murray parse_int: 719c2d3a559SKris Kennaway arg = strdelim(&s); 720c2d3a559SKris Kennaway if (!arg || *arg == '\0') 721511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 722c2d3a559SKris Kennaway if (arg[0] < '0' || arg[0] > '9') 723511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 724511b41d2SMark Murray 725511b41d2SMark Murray /* Octal, decimal, or hex format? */ 726c2d3a559SKris Kennaway value = strtol(arg, &endofnumber, 0); 727c2d3a559SKris Kennaway if (arg == endofnumber) 728511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 729511b41d2SMark Murray if (*activep && *intptr == -1) 730511b41d2SMark Murray *intptr = value; 731511b41d2SMark Murray break; 732511b41d2SMark Murray 733511b41d2SMark Murray case oConnectionAttempts: 734511b41d2SMark Murray intptr = &options->connection_attempts; 735511b41d2SMark Murray goto parse_int; 736511b41d2SMark Murray 737511b41d2SMark Murray case oCipher: 738511b41d2SMark Murray intptr = &options->cipher; 739c2d3a559SKris Kennaway arg = strdelim(&s); 740c2d3a559SKris Kennaway if (!arg || *arg == '\0') 741db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 742c2d3a559SKris Kennaway value = cipher_number(arg); 743511b41d2SMark Murray if (value == -1) 744511b41d2SMark Murray fatal("%.200s line %d: Bad cipher '%s'.", 745c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 746511b41d2SMark Murray if (*activep && *intptr == -1) 747511b41d2SMark Murray *intptr = value; 748511b41d2SMark Murray break; 749511b41d2SMark Murray 750e8aafc91SKris Kennaway case oCiphers: 751c2d3a559SKris Kennaway arg = strdelim(&s); 752c2d3a559SKris Kennaway if (!arg || *arg == '\0') 753db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 754c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 755e8aafc91SKris Kennaway fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 756c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 757e8aafc91SKris Kennaway if (*activep && options->ciphers == NULL) 758c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 759e8aafc91SKris Kennaway break; 760e8aafc91SKris Kennaway 761ca3176e7SBrian Feldman case oMacs: 762ca3176e7SBrian Feldman arg = strdelim(&s); 763ca3176e7SBrian Feldman if (!arg || *arg == '\0') 764ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 765ca3176e7SBrian Feldman if (!mac_valid(arg)) 766ca3176e7SBrian Feldman fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 767ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 768ca3176e7SBrian Feldman if (*activep && options->macs == NULL) 769ca3176e7SBrian Feldman options->macs = xstrdup(arg); 770ca3176e7SBrian Feldman break; 771ca3176e7SBrian Feldman 7724a421b63SDag-Erling Smørgrav case oKexAlgorithms: 7734a421b63SDag-Erling Smørgrav arg = strdelim(&s); 7744a421b63SDag-Erling Smørgrav if (!arg || *arg == '\0') 7754a421b63SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 7764a421b63SDag-Erling Smørgrav filename, linenum); 7774a421b63SDag-Erling Smørgrav if (!kex_names_valid(arg)) 7784a421b63SDag-Erling Smørgrav fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 7794a421b63SDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 7804a421b63SDag-Erling Smørgrav if (*activep && options->kex_algorithms == NULL) 7814a421b63SDag-Erling Smørgrav options->kex_algorithms = xstrdup(arg); 7824a421b63SDag-Erling Smørgrav break; 7834a421b63SDag-Erling Smørgrav 784ca3176e7SBrian Feldman case oHostKeyAlgorithms: 785ca3176e7SBrian Feldman arg = strdelim(&s); 786ca3176e7SBrian Feldman if (!arg || *arg == '\0') 787ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 788ca3176e7SBrian Feldman if (!key_names_valid2(arg)) 789ca3176e7SBrian Feldman fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 790ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 791ca3176e7SBrian Feldman if (*activep && options->hostkeyalgorithms == NULL) 792ca3176e7SBrian Feldman options->hostkeyalgorithms = xstrdup(arg); 793ca3176e7SBrian Feldman break; 794ca3176e7SBrian Feldman 795e8aafc91SKris Kennaway case oProtocol: 796e8aafc91SKris Kennaway intptr = &options->protocol; 797c2d3a559SKris Kennaway arg = strdelim(&s); 798c2d3a559SKris Kennaway if (!arg || *arg == '\0') 799db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 800c2d3a559SKris Kennaway value = proto_spec(arg); 801e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 802e8aafc91SKris Kennaway fatal("%.200s line %d: Bad protocol spec '%s'.", 803c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 804e8aafc91SKris Kennaway if (*activep && *intptr == SSH_PROTO_UNKNOWN) 805e8aafc91SKris Kennaway *intptr = value; 806e8aafc91SKris Kennaway break; 807e8aafc91SKris Kennaway 808511b41d2SMark Murray case oLogLevel: 809d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 810c2d3a559SKris Kennaway arg = strdelim(&s); 811c2d3a559SKris Kennaway value = log_level_number(arg); 812af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 813ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 814c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 815d4af9e69SDag-Erling Smørgrav if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 816d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 817511b41d2SMark Murray break; 818511b41d2SMark Murray 819af12a3e7SDag-Erling Smørgrav case oLocalForward: 820511b41d2SMark Murray case oRemoteForward: 821cce7d346SDag-Erling Smørgrav case oDynamicForward: 822c2d3a559SKris Kennaway arg = strdelim(&s); 823aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 824af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Missing port argument.", 825af12a3e7SDag-Erling Smørgrav filename, linenum); 826cce7d346SDag-Erling Smørgrav 827cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 828cce7d346SDag-Erling Smørgrav opcode == oRemoteForward) { 829aa49c926SDag-Erling Smørgrav arg2 = strdelim(&s); 830aa49c926SDag-Erling Smørgrav if (arg2 == NULL || *arg2 == '\0') 831aa49c926SDag-Erling Smørgrav fatal("%.200s line %d: Missing target argument.", 832511b41d2SMark Murray filename, linenum); 833aa49c926SDag-Erling Smørgrav 834aa49c926SDag-Erling Smørgrav /* construct a string for parse_forward */ 835aa49c926SDag-Erling Smørgrav snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 836cce7d346SDag-Erling Smørgrav } else if (opcode == oDynamicForward) { 837cce7d346SDag-Erling Smørgrav strlcpy(fwdarg, arg, sizeof(fwdarg)); 838cce7d346SDag-Erling Smørgrav } 839aa49c926SDag-Erling Smørgrav 840cce7d346SDag-Erling Smørgrav if (parse_forward(&fwd, fwdarg, 841cce7d346SDag-Erling Smørgrav opcode == oDynamicForward ? 1 : 0, 842cce7d346SDag-Erling Smørgrav opcode == oRemoteForward ? 1 : 0) == 0) 843af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 844511b41d2SMark Murray filename, linenum); 845aa49c926SDag-Erling Smørgrav 846af12a3e7SDag-Erling Smørgrav if (*activep) { 847cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 848cce7d346SDag-Erling Smørgrav opcode == oDynamicForward) 849aa49c926SDag-Erling Smørgrav add_local_forward(options, &fwd); 850af12a3e7SDag-Erling Smørgrav else if (opcode == oRemoteForward) 851aa49c926SDag-Erling Smørgrav add_remote_forward(options, &fwd); 852af12a3e7SDag-Erling Smørgrav } 853511b41d2SMark Murray break; 854511b41d2SMark Murray 855af12a3e7SDag-Erling Smørgrav case oClearAllForwardings: 856af12a3e7SDag-Erling Smørgrav intptr = &options->clear_forwardings; 857af12a3e7SDag-Erling Smørgrav goto parse_flag; 858af12a3e7SDag-Erling Smørgrav 859511b41d2SMark Murray case oHost: 860511b41d2SMark Murray *activep = 0; 861e146993eSDag-Erling Smørgrav arg2 = NULL; 862e146993eSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 863e146993eSDag-Erling Smørgrav negated = *arg == '!'; 864e146993eSDag-Erling Smørgrav if (negated) 865e146993eSDag-Erling Smørgrav arg++; 866c2d3a559SKris Kennaway if (match_pattern(host, arg)) { 867e146993eSDag-Erling Smørgrav if (negated) { 868e146993eSDag-Erling Smørgrav debug("%.200s line %d: Skipping Host " 869e146993eSDag-Erling Smørgrav "block because of negated match " 870e146993eSDag-Erling Smørgrav "for %.100s", filename, linenum, 871e146993eSDag-Erling Smørgrav arg); 872e146993eSDag-Erling Smørgrav *activep = 0; 873511b41d2SMark Murray break; 874511b41d2SMark Murray } 875e146993eSDag-Erling Smørgrav if (!*activep) 876e146993eSDag-Erling Smørgrav arg2 = arg; /* logged below */ 877e146993eSDag-Erling Smørgrav *activep = 1; 878e146993eSDag-Erling Smørgrav } 879e146993eSDag-Erling Smørgrav } 880e146993eSDag-Erling Smørgrav if (*activep) 881e146993eSDag-Erling Smørgrav debug("%.200s line %d: Applying options for %.100s", 882e146993eSDag-Erling Smørgrav filename, linenum, arg2); 883c2d3a559SKris Kennaway /* Avoid garbage check below, as strdelim is done. */ 884511b41d2SMark Murray return 0; 885511b41d2SMark Murray 886511b41d2SMark Murray case oEscapeChar: 887511b41d2SMark Murray intptr = &options->escape_char; 888c2d3a559SKris Kennaway arg = strdelim(&s); 889c2d3a559SKris Kennaway if (!arg || *arg == '\0') 890511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 891c2d3a559SKris Kennaway if (arg[0] == '^' && arg[2] == 0 && 892ca3176e7SBrian Feldman (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 893ca3176e7SBrian Feldman value = (u_char) arg[1] & 31; 894c2d3a559SKris Kennaway else if (strlen(arg) == 1) 895ca3176e7SBrian Feldman value = (u_char) arg[0]; 896c2d3a559SKris Kennaway else if (strcmp(arg, "none") == 0) 897af12a3e7SDag-Erling Smørgrav value = SSH_ESCAPECHAR_NONE; 898511b41d2SMark Murray else { 899511b41d2SMark Murray fatal("%.200s line %d: Bad escape character.", 900511b41d2SMark Murray filename, linenum); 901511b41d2SMark Murray /* NOTREACHED */ 902511b41d2SMark Murray value = 0; /* Avoid compiler warning. */ 903511b41d2SMark Murray } 904511b41d2SMark Murray if (*activep && *intptr == -1) 905511b41d2SMark Murray *intptr = value; 906511b41d2SMark Murray break; 907511b41d2SMark Murray 908cf2b5f3bSDag-Erling Smørgrav case oAddressFamily: 909cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 910d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 911d4ecd108SDag-Erling Smørgrav fatal("%s line %d: missing address family.", 912d4ecd108SDag-Erling Smørgrav filename, linenum); 913cf2b5f3bSDag-Erling Smørgrav intptr = &options->address_family; 914cf2b5f3bSDag-Erling Smørgrav if (strcasecmp(arg, "inet") == 0) 915cf2b5f3bSDag-Erling Smørgrav value = AF_INET; 916cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "inet6") == 0) 917cf2b5f3bSDag-Erling Smørgrav value = AF_INET6; 918cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "any") == 0) 919cf2b5f3bSDag-Erling Smørgrav value = AF_UNSPEC; 920cf2b5f3bSDag-Erling Smørgrav else 921cf2b5f3bSDag-Erling Smørgrav fatal("Unsupported AddressFamily \"%s\"", arg); 922cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 923cf2b5f3bSDag-Erling Smørgrav *intptr = value; 924cf2b5f3bSDag-Erling Smørgrav break; 925cf2b5f3bSDag-Erling Smørgrav 926e73e9afaSDag-Erling Smørgrav case oEnableSSHKeysign: 927e73e9afaSDag-Erling Smørgrav intptr = &options->enable_ssh_keysign; 928e73e9afaSDag-Erling Smørgrav goto parse_flag; 929e73e9afaSDag-Erling Smørgrav 9305962c0e9SDag-Erling Smørgrav case oIdentitiesOnly: 9315962c0e9SDag-Erling Smørgrav intptr = &options->identities_only; 9325962c0e9SDag-Erling Smørgrav goto parse_flag; 9335962c0e9SDag-Erling Smørgrav 9341ec0d754SDag-Erling Smørgrav case oServerAliveInterval: 9351ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_interval; 9361ec0d754SDag-Erling Smørgrav goto parse_time; 9371ec0d754SDag-Erling Smørgrav 9381ec0d754SDag-Erling Smørgrav case oServerAliveCountMax: 9391ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_count_max; 9401ec0d754SDag-Erling Smørgrav goto parse_int; 9411ec0d754SDag-Erling Smørgrav 94221e764dfSDag-Erling Smørgrav case oSendEnv: 94321e764dfSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 94421e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 94521e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 94621e764dfSDag-Erling Smørgrav filename, linenum); 947aa49c926SDag-Erling Smørgrav if (!*activep) 948aa49c926SDag-Erling Smørgrav continue; 94921e764dfSDag-Erling Smørgrav if (options->num_send_env >= MAX_SEND_ENV) 95021e764dfSDag-Erling Smørgrav fatal("%s line %d: too many send env.", 95121e764dfSDag-Erling Smørgrav filename, linenum); 95221e764dfSDag-Erling Smørgrav options->send_env[options->num_send_env++] = 95321e764dfSDag-Erling Smørgrav xstrdup(arg); 95421e764dfSDag-Erling Smørgrav } 95521e764dfSDag-Erling Smørgrav break; 95621e764dfSDag-Erling Smørgrav 95721e764dfSDag-Erling Smørgrav case oControlPath: 95821e764dfSDag-Erling Smørgrav charptr = &options->control_path; 95921e764dfSDag-Erling Smørgrav goto parse_string; 96021e764dfSDag-Erling Smørgrav 96121e764dfSDag-Erling Smørgrav case oControlMaster: 96221e764dfSDag-Erling Smørgrav intptr = &options->control_master; 963d4ecd108SDag-Erling Smørgrav arg = strdelim(&s); 964d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 965d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlMaster argument.", 966d4ecd108SDag-Erling Smørgrav filename, linenum); 967d4ecd108SDag-Erling Smørgrav value = 0; /* To avoid compiler warning... */ 968d4ecd108SDag-Erling Smørgrav if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 969d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_YES; 970d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 971d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_NO; 972d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "auto") == 0) 973d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO; 974d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "ask") == 0) 975d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_ASK; 976d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "autoask") == 0) 977d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO_ASK; 978d4ecd108SDag-Erling Smørgrav else 979d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlMaster argument.", 980d4ecd108SDag-Erling Smørgrav filename, linenum); 981d4ecd108SDag-Erling Smørgrav if (*activep && *intptr == -1) 982d4ecd108SDag-Erling Smørgrav *intptr = value; 983d4ecd108SDag-Erling Smørgrav break; 98421e764dfSDag-Erling Smørgrav 985e2f6069cSDag-Erling Smørgrav case oControlPersist: 986e2f6069cSDag-Erling Smørgrav /* no/false/yes/true, or a time spec */ 987e2f6069cSDag-Erling Smørgrav intptr = &options->control_persist; 988e2f6069cSDag-Erling Smørgrav arg = strdelim(&s); 989e2f6069cSDag-Erling Smørgrav if (!arg || *arg == '\0') 990e2f6069cSDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlPersist" 991e2f6069cSDag-Erling Smørgrav " argument.", filename, linenum); 992e2f6069cSDag-Erling Smørgrav value = 0; 993e2f6069cSDag-Erling Smørgrav value2 = 0; /* timeout */ 994e2f6069cSDag-Erling Smørgrav if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 995e2f6069cSDag-Erling Smørgrav value = 0; 996e2f6069cSDag-Erling Smørgrav else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 997e2f6069cSDag-Erling Smørgrav value = 1; 998e2f6069cSDag-Erling Smørgrav else if ((value2 = convtime(arg)) >= 0) 999e2f6069cSDag-Erling Smørgrav value = 1; 1000e2f6069cSDag-Erling Smørgrav else 1001e2f6069cSDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlPersist argument.", 1002e2f6069cSDag-Erling Smørgrav filename, linenum); 1003e2f6069cSDag-Erling Smørgrav if (*activep && *intptr == -1) { 1004e2f6069cSDag-Erling Smørgrav *intptr = value; 1005e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = value2; 1006e2f6069cSDag-Erling Smørgrav } 1007e2f6069cSDag-Erling Smørgrav break; 1008e2f6069cSDag-Erling Smørgrav 1009aa49c926SDag-Erling Smørgrav case oHashKnownHosts: 1010aa49c926SDag-Erling Smørgrav intptr = &options->hash_known_hosts; 1011aa49c926SDag-Erling Smørgrav goto parse_flag; 1012aa49c926SDag-Erling Smørgrav 1013b74df5b2SDag-Erling Smørgrav case oTunnel: 1014b74df5b2SDag-Erling Smørgrav intptr = &options->tun_open; 1015b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 1016b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1017b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 1018b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 1019b74df5b2SDag-Erling Smørgrav value = 0; /* silence compiler */ 1020b74df5b2SDag-Erling Smørgrav if (strcasecmp(arg, "ethernet") == 0) 1021b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_ETHERNET; 1022b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "point-to-point") == 0) 1023b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_POINTOPOINT; 1024b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "yes") == 0) 1025b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_DEFAULT; 1026b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 1027b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_NO; 1028b74df5b2SDag-Erling Smørgrav else 1029b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1030b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 1031b74df5b2SDag-Erling Smørgrav if (*activep) 1032b74df5b2SDag-Erling Smørgrav *intptr = value; 1033b74df5b2SDag-Erling Smørgrav break; 1034b74df5b2SDag-Erling Smørgrav 1035b74df5b2SDag-Erling Smørgrav case oTunnelDevice: 1036b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 1037b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1038b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 1039b74df5b2SDag-Erling Smørgrav value = a2tun(arg, &value2); 1040b74df5b2SDag-Erling Smørgrav if (value == SSH_TUNID_ERR) 1041b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Bad tun device.", filename, linenum); 1042b74df5b2SDag-Erling Smørgrav if (*activep) { 1043b74df5b2SDag-Erling Smørgrav options->tun_local = value; 1044b74df5b2SDag-Erling Smørgrav options->tun_remote = value2; 1045b74df5b2SDag-Erling Smørgrav } 1046b74df5b2SDag-Erling Smørgrav break; 1047b74df5b2SDag-Erling Smørgrav 1048b74df5b2SDag-Erling Smørgrav case oLocalCommand: 1049b74df5b2SDag-Erling Smørgrav charptr = &options->local_command; 1050b74df5b2SDag-Erling Smørgrav goto parse_command; 1051b74df5b2SDag-Erling Smørgrav 1052b74df5b2SDag-Erling Smørgrav case oPermitLocalCommand: 1053b74df5b2SDag-Erling Smørgrav intptr = &options->permit_local_command; 1054b74df5b2SDag-Erling Smørgrav goto parse_flag; 1055b74df5b2SDag-Erling Smørgrav 1056d4af9e69SDag-Erling Smørgrav case oVisualHostKey: 1057d4af9e69SDag-Erling Smørgrav intptr = &options->visual_host_key; 1058d4af9e69SDag-Erling Smørgrav goto parse_flag; 1059d4af9e69SDag-Erling Smørgrav 10604a421b63SDag-Erling Smørgrav case oIPQoS: 10614a421b63SDag-Erling Smørgrav arg = strdelim(&s); 10624a421b63SDag-Erling Smørgrav if ((value = parse_ipqos(arg)) == -1) 10634a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 10644a421b63SDag-Erling Smørgrav filename, linenum, arg); 10654a421b63SDag-Erling Smørgrav arg = strdelim(&s); 10664a421b63SDag-Erling Smørgrav if (arg == NULL) 10674a421b63SDag-Erling Smørgrav value2 = value; 10684a421b63SDag-Erling Smørgrav else if ((value2 = parse_ipqos(arg)) == -1) 10694a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 10704a421b63SDag-Erling Smørgrav filename, linenum, arg); 10714a421b63SDag-Erling Smørgrav if (*activep) { 10724a421b63SDag-Erling Smørgrav options->ip_qos_interactive = value; 10734a421b63SDag-Erling Smørgrav options->ip_qos_bulk = value2; 10744a421b63SDag-Erling Smørgrav } 10754a421b63SDag-Erling Smørgrav break; 10764a421b63SDag-Erling Smørgrav 10777aee6ffeSDag-Erling Smørgrav case oUseRoaming: 10787aee6ffeSDag-Erling Smørgrav intptr = &options->use_roaming; 10797aee6ffeSDag-Erling Smørgrav goto parse_flag; 10807aee6ffeSDag-Erling Smørgrav 1081e146993eSDag-Erling Smørgrav case oRequestTTY: 1082975616f0SDag-Erling Smørgrav arg = strdelim(&s); 1083e146993eSDag-Erling Smørgrav if (!arg || *arg == '\0') 1084e146993eSDag-Erling Smørgrav fatal("%s line %d: missing argument.", 1085e146993eSDag-Erling Smørgrav filename, linenum); 1086e146993eSDag-Erling Smørgrav intptr = &options->request_tty; 1087e146993eSDag-Erling Smørgrav if (strcasecmp(arg, "yes") == 0) 1088e146993eSDag-Erling Smørgrav value = REQUEST_TTY_YES; 1089e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 1090e146993eSDag-Erling Smørgrav value = REQUEST_TTY_NO; 1091e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "force") == 0) 1092e146993eSDag-Erling Smørgrav value = REQUEST_TTY_FORCE; 1093e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "auto") == 0) 1094e146993eSDag-Erling Smørgrav value = REQUEST_TTY_AUTO; 1095e146993eSDag-Erling Smørgrav else 1096e146993eSDag-Erling Smørgrav fatal("Unsupported RequestTTY \"%s\"", arg); 1097e146993eSDag-Erling Smørgrav if (*activep && *intptr == -1) 1098e146993eSDag-Erling Smørgrav *intptr = value; 1099975616f0SDag-Erling Smørgrav break; 1100975616f0SDag-Erling Smørgrav 110189986192SBrooks Davis case oHPNDisabled: 110289986192SBrooks Davis intptr = &options->hpn_disabled; 110389986192SBrooks Davis goto parse_flag; 110489986192SBrooks Davis 110589986192SBrooks Davis case oHPNBufferSize: 110689986192SBrooks Davis intptr = &options->hpn_buffer_size; 110789986192SBrooks Davis goto parse_int; 110889986192SBrooks Davis 110989986192SBrooks Davis case oTcpRcvBufPoll: 111089986192SBrooks Davis intptr = &options->tcp_rcv_buf_poll; 111189986192SBrooks Davis goto parse_flag; 111289986192SBrooks Davis 111389986192SBrooks Davis case oTcpRcvBuf: 111489986192SBrooks Davis intptr = &options->tcp_rcv_buf; 111589986192SBrooks Davis goto parse_int; 111689986192SBrooks Davis 111789986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 111889986192SBrooks Davis case oNoneEnabled: 111989986192SBrooks Davis intptr = &options->none_enabled; 112089986192SBrooks Davis goto parse_flag; 112189986192SBrooks Davis 112289986192SBrooks Davis /* 112389986192SBrooks Davis * We check to see if the command comes from the command line or not. 112489986192SBrooks Davis * If it does then enable it otherwise fail. NONE must never be a 112589986192SBrooks Davis * default configuration. 112689986192SBrooks Davis */ 112789986192SBrooks Davis case oNoneSwitch: 112889986192SBrooks Davis if (strcmp(filename,"command-line") == 0) { 112989986192SBrooks Davis intptr = &options->none_switch; 113089986192SBrooks Davis goto parse_flag; 113189986192SBrooks Davis } else { 113289986192SBrooks Davis debug("NoneSwitch directive found in %.200s.", 113389986192SBrooks Davis filename); 113489986192SBrooks Davis error("NoneSwitch is found in %.200s.\n" 113589986192SBrooks Davis "You may only use this configuration option " 113689986192SBrooks Davis "from the command line", filename); 113789986192SBrooks Davis error("Continuing..."); 113889986192SBrooks Davis return 0; 113989986192SBrooks Davis } 114089986192SBrooks Davis #endif 114189986192SBrooks Davis 1142e146993eSDag-Erling Smørgrav case oVersionAddendum: 1143462c32cbSDag-Erling Smørgrav if (s == NULL) 1144462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1145462c32cbSDag-Erling Smørgrav linenum); 1146462c32cbSDag-Erling Smørgrav len = strspn(s, WHITESPACE); 1147462c32cbSDag-Erling Smørgrav if (*activep && options->version_addendum == NULL) { 1148462c32cbSDag-Erling Smørgrav if (strcasecmp(s + len, "none") == 0) 1149462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(""); 1150462c32cbSDag-Erling Smørgrav else if (strchr(s + len, '\r') != NULL) 1151462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Invalid argument", 1152462c32cbSDag-Erling Smørgrav filename, linenum); 1153462c32cbSDag-Erling Smørgrav else 1154462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(s + len); 1155462c32cbSDag-Erling Smørgrav } 1156462c32cbSDag-Erling Smørgrav return 0; 1157e146993eSDag-Erling Smørgrav 1158*e4a9863fSDag-Erling Smørgrav case oIgnoreUnknown: 1159*e4a9863fSDag-Erling Smørgrav charptr = &options->ignored_unknown; 1160*e4a9863fSDag-Erling Smørgrav goto parse_string; 1161*e4a9863fSDag-Erling Smørgrav 116280628bacSDag-Erling Smørgrav case oDeprecated: 116380628bacSDag-Erling Smørgrav debug("%s line %d: Deprecated option \"%s\"", 116480628bacSDag-Erling Smørgrav filename, linenum, keyword); 116580628bacSDag-Erling Smørgrav return 0; 116680628bacSDag-Erling Smørgrav 1167cf2b5f3bSDag-Erling Smørgrav case oUnsupported: 1168cf2b5f3bSDag-Erling Smørgrav error("%s line %d: Unsupported option \"%s\"", 1169cf2b5f3bSDag-Erling Smørgrav filename, linenum, keyword); 1170cf2b5f3bSDag-Erling Smørgrav return 0; 1171cf2b5f3bSDag-Erling Smørgrav 1172511b41d2SMark Murray default: 1173511b41d2SMark Murray fatal("process_config_line: Unimplemented opcode %d", opcode); 1174511b41d2SMark Murray } 1175511b41d2SMark Murray 1176511b41d2SMark Murray /* Check that there is no garbage at end of line. */ 1177ca3176e7SBrian Feldman if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1178c2d3a559SKris Kennaway fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1179c2d3a559SKris Kennaway filename, linenum, arg); 1180c2d3a559SKris Kennaway } 1181511b41d2SMark Murray return 0; 1182511b41d2SMark Murray } 1183511b41d2SMark Murray 1184511b41d2SMark Murray 1185511b41d2SMark Murray /* 1186511b41d2SMark Murray * Reads the config file and modifies the options accordingly. Options 1187511b41d2SMark Murray * should already be initialized before this call. This never returns if 1188af12a3e7SDag-Erling Smørgrav * there is an error. If the file does not exist, this returns 0. 1189511b41d2SMark Murray */ 1190511b41d2SMark Murray 1191af12a3e7SDag-Erling Smørgrav int 119221e764dfSDag-Erling Smørgrav read_config_file(const char *filename, const char *host, Options *options, 119373370613SDag-Erling Smørgrav int flags) 1194511b41d2SMark Murray { 1195511b41d2SMark Murray FILE *f; 1196511b41d2SMark Murray char line[1024]; 1197511b41d2SMark Murray int active, linenum; 1198511b41d2SMark Murray int bad_options = 0; 1199511b41d2SMark Murray 120021e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) 1201af12a3e7SDag-Erling Smørgrav return 0; 1202511b41d2SMark Murray 120373370613SDag-Erling Smørgrav if (flags & SSHCONF_CHECKPERM) { 120421e764dfSDag-Erling Smørgrav struct stat sb; 120521e764dfSDag-Erling Smørgrav 120621e764dfSDag-Erling Smørgrav if (fstat(fileno(f), &sb) == -1) 120721e764dfSDag-Erling Smørgrav fatal("fstat %s: %s", filename, strerror(errno)); 120821e764dfSDag-Erling Smørgrav if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 120921e764dfSDag-Erling Smørgrav (sb.st_mode & 022) != 0)) 121021e764dfSDag-Erling Smørgrav fatal("Bad owner or permissions on %s", filename); 121121e764dfSDag-Erling Smørgrav } 121221e764dfSDag-Erling Smørgrav 1213511b41d2SMark Murray debug("Reading configuration data %.200s", filename); 1214511b41d2SMark Murray 1215511b41d2SMark Murray /* 1216511b41d2SMark Murray * Mark that we are now processing the options. This flag is turned 1217511b41d2SMark Murray * on/off by Host specifications. 1218511b41d2SMark Murray */ 1219511b41d2SMark Murray active = 1; 1220511b41d2SMark Murray linenum = 0; 1221511b41d2SMark Murray while (fgets(line, sizeof(line), f)) { 1222511b41d2SMark Murray /* Update line number counter. */ 1223511b41d2SMark Murray linenum++; 122473370613SDag-Erling Smørgrav if (process_config_line(options, host, line, filename, linenum, 122573370613SDag-Erling Smørgrav &active, flags & SSHCONF_USERCONF) != 0) 1226511b41d2SMark Murray bad_options++; 1227511b41d2SMark Murray } 1228511b41d2SMark Murray fclose(f); 1229511b41d2SMark Murray if (bad_options > 0) 1230ca3176e7SBrian Feldman fatal("%s: terminating, %d bad configuration options", 1231511b41d2SMark Murray filename, bad_options); 1232af12a3e7SDag-Erling Smørgrav return 1; 1233511b41d2SMark Murray } 1234511b41d2SMark Murray 1235511b41d2SMark Murray /* 1236511b41d2SMark Murray * Initializes options to special values that indicate that they have not yet 1237511b41d2SMark Murray * been set. Read_config_file will only set options with this value. Options 1238511b41d2SMark Murray * are processed in the following order: command line, user config file, 1239511b41d2SMark Murray * system config file. Last, fill_default_options is called. 1240511b41d2SMark Murray */ 1241511b41d2SMark Murray 1242511b41d2SMark Murray void 1243511b41d2SMark Murray initialize_options(Options * options) 1244511b41d2SMark Murray { 1245511b41d2SMark Murray memset(options, 'X', sizeof(*options)); 1246511b41d2SMark Murray options->forward_agent = -1; 1247511b41d2SMark Murray options->forward_x11 = -1; 12481ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = -1; 1249e2f6069cSDag-Erling Smørgrav options->forward_x11_timeout = -1; 1250333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = -1; 1251c2d3a559SKris Kennaway options->xauth_location = NULL; 1252511b41d2SMark Murray options->gateway_ports = -1; 1253511b41d2SMark Murray options->use_privileged_port = -1; 1254511b41d2SMark Murray options->rsa_authentication = -1; 1255ca3176e7SBrian Feldman options->pubkey_authentication = -1; 1256af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 1257cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = -1; 1258cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = -1; 1259511b41d2SMark Murray options->password_authentication = -1; 126009958426SBrian Feldman options->kbd_interactive_authentication = -1; 126109958426SBrian Feldman options->kbd_interactive_devices = NULL; 1262511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 1263ca3176e7SBrian Feldman options->hostbased_authentication = -1; 1264511b41d2SMark Murray options->batch_mode = -1; 1265511b41d2SMark Murray options->check_host_ip = -1; 1266511b41d2SMark Murray options->strict_host_key_checking = -1; 1267511b41d2SMark Murray options->compression = -1; 12681ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 1269511b41d2SMark Murray options->compression_level = -1; 1270511b41d2SMark Murray options->port = -1; 1271cf2b5f3bSDag-Erling Smørgrav options->address_family = -1; 1272511b41d2SMark Murray options->connection_attempts = -1; 1273cf2b5f3bSDag-Erling Smørgrav options->connection_timeout = -1; 1274511b41d2SMark Murray options->number_of_password_prompts = -1; 1275511b41d2SMark Murray options->cipher = -1; 1276e8aafc91SKris Kennaway options->ciphers = NULL; 1277ca3176e7SBrian Feldman options->macs = NULL; 12784a421b63SDag-Erling Smørgrav options->kex_algorithms = NULL; 1279ca3176e7SBrian Feldman options->hostkeyalgorithms = NULL; 1280e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 1281511b41d2SMark Murray options->num_identity_files = 0; 1282511b41d2SMark Murray options->hostname = NULL; 1283ca3176e7SBrian Feldman options->host_key_alias = NULL; 1284511b41d2SMark Murray options->proxy_command = NULL; 1285511b41d2SMark Murray options->user = NULL; 1286511b41d2SMark Murray options->escape_char = -1; 1287e146993eSDag-Erling Smørgrav options->num_system_hostfiles = 0; 1288e146993eSDag-Erling Smørgrav options->num_user_hostfiles = 0; 1289e2f6069cSDag-Erling Smørgrav options->local_forwards = NULL; 1290511b41d2SMark Murray options->num_local_forwards = 0; 1291e2f6069cSDag-Erling Smørgrav options->remote_forwards = NULL; 1292511b41d2SMark Murray options->num_remote_forwards = 0; 1293af12a3e7SDag-Erling Smørgrav options->clear_forwardings = -1; 1294af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 1295ca3176e7SBrian Feldman options->preferred_authentications = NULL; 1296af12a3e7SDag-Erling Smørgrav options->bind_address = NULL; 1297b15c8340SDag-Erling Smørgrav options->pkcs11_provider = NULL; 1298e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = - 1; 1299af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = - 1; 13005962c0e9SDag-Erling Smørgrav options->identities_only = - 1; 1301cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = - 1; 1302*e4a9863fSDag-Erling Smørgrav options->rekey_interval = -1; 1303cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = -1; 13041ec0d754SDag-Erling Smørgrav options->server_alive_interval = -1; 13051ec0d754SDag-Erling Smørgrav options->server_alive_count_max = -1; 130621e764dfSDag-Erling Smørgrav options->num_send_env = 0; 130721e764dfSDag-Erling Smørgrav options->control_path = NULL; 130821e764dfSDag-Erling Smørgrav options->control_master = -1; 1309e2f6069cSDag-Erling Smørgrav options->control_persist = -1; 1310e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = 0; 1311aa49c926SDag-Erling Smørgrav options->hash_known_hosts = -1; 1312b74df5b2SDag-Erling Smørgrav options->tun_open = -1; 1313b74df5b2SDag-Erling Smørgrav options->tun_local = -1; 1314b74df5b2SDag-Erling Smørgrav options->tun_remote = -1; 1315b74df5b2SDag-Erling Smørgrav options->local_command = NULL; 1316b74df5b2SDag-Erling Smørgrav options->permit_local_command = -1; 13177aee6ffeSDag-Erling Smørgrav options->use_roaming = -1; 1318d4af9e69SDag-Erling Smørgrav options->visual_host_key = -1; 1319cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = -1; 13204a421b63SDag-Erling Smørgrav options->ip_qos_interactive = -1; 13214a421b63SDag-Erling Smørgrav options->ip_qos_bulk = -1; 1322e146993eSDag-Erling Smørgrav options->request_tty = -1; 1323462c32cbSDag-Erling Smørgrav options->version_addendum = NULL; 1324*e4a9863fSDag-Erling Smørgrav options->ignored_unknown = NULL; 132589986192SBrooks Davis options->hpn_disabled = -1; 132689986192SBrooks Davis options->hpn_buffer_size = -1; 132789986192SBrooks Davis options->tcp_rcv_buf_poll = -1; 132889986192SBrooks Davis options->tcp_rcv_buf = -1; 132989986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 133089986192SBrooks Davis options->none_enabled = -1; 133189986192SBrooks Davis options->none_switch = -1; 133289986192SBrooks Davis #endif 1333511b41d2SMark Murray } 1334511b41d2SMark Murray 1335511b41d2SMark Murray /* 1336511b41d2SMark Murray * Called after processing other sources of option data, this fills those 1337511b41d2SMark Murray * options for which no value has been specified with their default values. 1338511b41d2SMark Murray */ 1339511b41d2SMark Murray 1340511b41d2SMark Murray void 1341511b41d2SMark Murray fill_default_options(Options * options) 1342511b41d2SMark Murray { 1343511b41d2SMark Murray if (options->forward_agent == -1) 1344db1cb46cSKris Kennaway options->forward_agent = 0; 1345511b41d2SMark Murray if (options->forward_x11 == -1) 13465dc73ebeSBrian Feldman options->forward_x11 = 0; 13471ec0d754SDag-Erling Smørgrav if (options->forward_x11_trusted == -1) 13481ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = 0; 1349e2f6069cSDag-Erling Smørgrav if (options->forward_x11_timeout == -1) 1350e2f6069cSDag-Erling Smørgrav options->forward_x11_timeout = 1200; 1351333ee039SDag-Erling Smørgrav if (options->exit_on_forward_failure == -1) 1352333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = 0; 1353c2d3a559SKris Kennaway if (options->xauth_location == NULL) 1354af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 1355511b41d2SMark Murray if (options->gateway_ports == -1) 1356511b41d2SMark Murray options->gateway_ports = 0; 1357511b41d2SMark Murray if (options->use_privileged_port == -1) 1358ca3176e7SBrian Feldman options->use_privileged_port = 0; 1359511b41d2SMark Murray if (options->rsa_authentication == -1) 1360511b41d2SMark Murray options->rsa_authentication = 1; 1361ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 1362ca3176e7SBrian Feldman options->pubkey_authentication = 1; 1363af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 1364af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = 1; 1365cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 13661ec0d754SDag-Erling Smørgrav options->gss_authentication = 0; 1367cf2b5f3bSDag-Erling Smørgrav if (options->gss_deleg_creds == -1) 1368cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = 0; 1369511b41d2SMark Murray if (options->password_authentication == -1) 1370511b41d2SMark Murray options->password_authentication = 1; 137109958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 1372ca3176e7SBrian Feldman options->kbd_interactive_authentication = 1; 1373511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 137480628bacSDag-Erling Smørgrav options->rhosts_rsa_authentication = 0; 1375ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 1376ca3176e7SBrian Feldman options->hostbased_authentication = 0; 1377511b41d2SMark Murray if (options->batch_mode == -1) 1378511b41d2SMark Murray options->batch_mode = 0; 1379511b41d2SMark Murray if (options->check_host_ip == -1) 1380975616f0SDag-Erling Smørgrav options->check_host_ip = 0; 1381511b41d2SMark Murray if (options->strict_host_key_checking == -1) 1382511b41d2SMark Murray options->strict_host_key_checking = 2; /* 2 is default */ 1383511b41d2SMark Murray if (options->compression == -1) 1384511b41d2SMark Murray options->compression = 0; 13851ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 13861ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 1387511b41d2SMark Murray if (options->compression_level == -1) 1388511b41d2SMark Murray options->compression_level = 6; 1389511b41d2SMark Murray if (options->port == -1) 1390511b41d2SMark Murray options->port = 0; /* Filled in ssh_connect. */ 1391cf2b5f3bSDag-Erling Smørgrav if (options->address_family == -1) 1392cf2b5f3bSDag-Erling Smørgrav options->address_family = AF_UNSPEC; 1393511b41d2SMark Murray if (options->connection_attempts == -1) 1394af12a3e7SDag-Erling Smørgrav options->connection_attempts = 1; 1395511b41d2SMark Murray if (options->number_of_password_prompts == -1) 1396511b41d2SMark Murray options->number_of_password_prompts = 3; 1397511b41d2SMark Murray /* Selected in ssh_login(). */ 1398511b41d2SMark Murray if (options->cipher == -1) 1399511b41d2SMark Murray options->cipher = SSH_CIPHER_NOT_SET; 1400e8aafc91SKris Kennaway /* options->ciphers, default set in myproposals.h */ 1401ca3176e7SBrian Feldman /* options->macs, default set in myproposals.h */ 14024a421b63SDag-Erling Smørgrav /* options->kex_algorithms, default set in myproposals.h */ 1403ca3176e7SBrian Feldman /* options->hostkeyalgorithms, default set in myproposals.h */ 1404e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 1405b15c8340SDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 1406511b41d2SMark Murray if (options->num_identity_files == 0) { 1407ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) { 140873370613SDag-Erling Smørgrav add_identity_file(options, "~/", 140973370613SDag-Erling Smørgrav _PATH_SSH_CLIENT_IDENTITY, 0); 1410511b41d2SMark Murray } 1411ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_2) { 141273370613SDag-Erling Smørgrav add_identity_file(options, "~/", 141373370613SDag-Erling Smørgrav _PATH_SSH_CLIENT_ID_RSA, 0); 141473370613SDag-Erling Smørgrav add_identity_file(options, "~/", 141573370613SDag-Erling Smørgrav _PATH_SSH_CLIENT_ID_DSA, 0); 14164a421b63SDag-Erling Smørgrav #ifdef OPENSSL_HAS_ECC 141773370613SDag-Erling Smørgrav add_identity_file(options, "~/", 141873370613SDag-Erling Smørgrav _PATH_SSH_CLIENT_ID_ECDSA, 0); 14194a421b63SDag-Erling Smørgrav #endif 1420ca3176e7SBrian Feldman } 1421e8aafc91SKris Kennaway } 1422511b41d2SMark Murray if (options->escape_char == -1) 1423511b41d2SMark Murray options->escape_char = '~'; 1424e146993eSDag-Erling Smørgrav if (options->num_system_hostfiles == 0) { 1425e146993eSDag-Erling Smørgrav options->system_hostfiles[options->num_system_hostfiles++] = 1426e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1427e146993eSDag-Erling Smørgrav options->system_hostfiles[options->num_system_hostfiles++] = 1428e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1429e146993eSDag-Erling Smørgrav } 1430e146993eSDag-Erling Smørgrav if (options->num_user_hostfiles == 0) { 1431e146993eSDag-Erling Smørgrav options->user_hostfiles[options->num_user_hostfiles++] = 1432e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_HOSTFILE); 1433e146993eSDag-Erling Smørgrav options->user_hostfiles[options->num_user_hostfiles++] = 1434e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_HOSTFILE2); 1435e146993eSDag-Erling Smørgrav } 1436af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1437511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 1438af12a3e7SDag-Erling Smørgrav if (options->clear_forwardings == 1) 1439af12a3e7SDag-Erling Smørgrav clear_forwardings(options); 1440af12a3e7SDag-Erling Smørgrav if (options->no_host_authentication_for_localhost == - 1) 1441af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = 0; 14425962c0e9SDag-Erling Smørgrav if (options->identities_only == -1) 14435962c0e9SDag-Erling Smørgrav options->identities_only = 0; 1444e73e9afaSDag-Erling Smørgrav if (options->enable_ssh_keysign == -1) 1445e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = 0; 1446cf2b5f3bSDag-Erling Smørgrav if (options->rekey_limit == -1) 1447cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = 0; 1448*e4a9863fSDag-Erling Smørgrav if (options->rekey_interval == -1) 1449*e4a9863fSDag-Erling Smørgrav options->rekey_interval = 0; 145083c6a524SDag-Erling Smørgrav #if HAVE_LDNS 145183c6a524SDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 145283c6a524SDag-Erling Smørgrav /* automatically trust a verified SSHFP record */ 145383c6a524SDag-Erling Smørgrav options->verify_host_key_dns = 1; 145483c6a524SDag-Erling Smørgrav #else 1455cf2b5f3bSDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 1456cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = 0; 145783c6a524SDag-Erling Smørgrav #endif 14581ec0d754SDag-Erling Smørgrav if (options->server_alive_interval == -1) 14591ec0d754SDag-Erling Smørgrav options->server_alive_interval = 0; 14601ec0d754SDag-Erling Smørgrav if (options->server_alive_count_max == -1) 14611ec0d754SDag-Erling Smørgrav options->server_alive_count_max = 3; 146221e764dfSDag-Erling Smørgrav if (options->control_master == -1) 146321e764dfSDag-Erling Smørgrav options->control_master = 0; 1464e2f6069cSDag-Erling Smørgrav if (options->control_persist == -1) { 1465e2f6069cSDag-Erling Smørgrav options->control_persist = 0; 1466e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = 0; 1467e2f6069cSDag-Erling Smørgrav } 1468aa49c926SDag-Erling Smørgrav if (options->hash_known_hosts == -1) 1469aa49c926SDag-Erling Smørgrav options->hash_known_hosts = 0; 1470b74df5b2SDag-Erling Smørgrav if (options->tun_open == -1) 1471b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 1472b74df5b2SDag-Erling Smørgrav if (options->tun_local == -1) 1473b74df5b2SDag-Erling Smørgrav options->tun_local = SSH_TUNID_ANY; 1474b74df5b2SDag-Erling Smørgrav if (options->tun_remote == -1) 1475b74df5b2SDag-Erling Smørgrav options->tun_remote = SSH_TUNID_ANY; 1476b74df5b2SDag-Erling Smørgrav if (options->permit_local_command == -1) 1477b74df5b2SDag-Erling Smørgrav options->permit_local_command = 0; 14787aee6ffeSDag-Erling Smørgrav if (options->use_roaming == -1) 14797aee6ffeSDag-Erling Smørgrav options->use_roaming = 1; 1480d4af9e69SDag-Erling Smørgrav if (options->visual_host_key == -1) 1481d4af9e69SDag-Erling Smørgrav options->visual_host_key = 0; 1482cce7d346SDag-Erling Smørgrav if (options->zero_knowledge_password_authentication == -1) 1483cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = 0; 14844a421b63SDag-Erling Smørgrav if (options->ip_qos_interactive == -1) 14854a421b63SDag-Erling Smørgrav options->ip_qos_interactive = IPTOS_LOWDELAY; 14864a421b63SDag-Erling Smørgrav if (options->ip_qos_bulk == -1) 14874a421b63SDag-Erling Smørgrav options->ip_qos_bulk = IPTOS_THROUGHPUT; 1488e146993eSDag-Erling Smørgrav if (options->request_tty == -1) 1489e146993eSDag-Erling Smørgrav options->request_tty = REQUEST_TTY_AUTO; 1490b74df5b2SDag-Erling Smørgrav /* options->local_command should not be set by default */ 1491511b41d2SMark Murray /* options->proxy_command should not be set by default */ 1492511b41d2SMark Murray /* options->user will be set in the main program if appropriate */ 1493511b41d2SMark Murray /* options->hostname will be set in the main program if appropriate */ 1494ca3176e7SBrian Feldman /* options->host_key_alias should not be set by default */ 1495ca3176e7SBrian Feldman /* options->preferred_authentications will be set in ssh */ 1496462c32cbSDag-Erling Smørgrav if (options->version_addendum == NULL) 1497462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 149889986192SBrooks Davis if (options->hpn_disabled == -1) 149989986192SBrooks Davis options->hpn_disabled = 0; 150089986192SBrooks Davis if (options->hpn_buffer_size > -1) 150189986192SBrooks Davis { 150289986192SBrooks Davis u_int maxlen; 150389986192SBrooks Davis 150489986192SBrooks Davis /* If a user tries to set the size to 0 set it to 1KB. */ 150589986192SBrooks Davis if (options->hpn_buffer_size == 0) 150689986192SBrooks Davis options->hpn_buffer_size = 1024; 150789986192SBrooks Davis /* Limit the buffer to BUFFER_MAX_LEN. */ 150889986192SBrooks Davis maxlen = buffer_get_max_len(); 150989986192SBrooks Davis if (options->hpn_buffer_size > (maxlen / 1024)) { 151089986192SBrooks Davis debug("User requested buffer larger than %ub: %ub. " 151189986192SBrooks Davis "Request reverted to %ub", maxlen, 151289986192SBrooks Davis options->hpn_buffer_size * 1024, maxlen); 151389986192SBrooks Davis options->hpn_buffer_size = maxlen; 151489986192SBrooks Davis } 151589986192SBrooks Davis debug("hpn_buffer_size set to %d", options->hpn_buffer_size); 151689986192SBrooks Davis } 151789986192SBrooks Davis if (options->tcp_rcv_buf == 0) 151889986192SBrooks Davis options->tcp_rcv_buf = 1; 151989986192SBrooks Davis if (options->tcp_rcv_buf > -1) 152089986192SBrooks Davis options->tcp_rcv_buf *= 1024; 152189986192SBrooks Davis if (options->tcp_rcv_buf_poll == -1) 152289986192SBrooks Davis options->tcp_rcv_buf_poll = 1; 152389986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 152489986192SBrooks Davis /* options->none_enabled must not be set by default */ 152589986192SBrooks Davis if (options->none_switch == -1) 152689986192SBrooks Davis options->none_switch = 0; 152789986192SBrooks Davis #endif 1528511b41d2SMark Murray } 1529aa49c926SDag-Erling Smørgrav 1530aa49c926SDag-Erling Smørgrav /* 1531aa49c926SDag-Erling Smørgrav * parse_forward 1532aa49c926SDag-Erling Smørgrav * parses a string containing a port forwarding specification of the form: 1533cce7d346SDag-Erling Smørgrav * dynamicfwd == 0 1534aa49c926SDag-Erling Smørgrav * [listenhost:]listenport:connecthost:connectport 1535cce7d346SDag-Erling Smørgrav * dynamicfwd == 1 1536cce7d346SDag-Erling Smørgrav * [listenhost:]listenport 1537aa49c926SDag-Erling Smørgrav * returns number of arguments parsed or zero on error 1538aa49c926SDag-Erling Smørgrav */ 1539aa49c926SDag-Erling Smørgrav int 1540cce7d346SDag-Erling Smørgrav parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1541aa49c926SDag-Erling Smørgrav { 1542aa49c926SDag-Erling Smørgrav int i; 1543aa49c926SDag-Erling Smørgrav char *p, *cp, *fwdarg[4]; 1544aa49c926SDag-Erling Smørgrav 1545aa49c926SDag-Erling Smørgrav memset(fwd, '\0', sizeof(*fwd)); 1546aa49c926SDag-Erling Smørgrav 1547aa49c926SDag-Erling Smørgrav cp = p = xstrdup(fwdspec); 1548aa49c926SDag-Erling Smørgrav 1549aa49c926SDag-Erling Smørgrav /* skip leading spaces */ 1550d4af9e69SDag-Erling Smørgrav while (isspace(*cp)) 1551aa49c926SDag-Erling Smørgrav cp++; 1552aa49c926SDag-Erling Smørgrav 1553aa49c926SDag-Erling Smørgrav for (i = 0; i < 4; ++i) 1554aa49c926SDag-Erling Smørgrav if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1555aa49c926SDag-Erling Smørgrav break; 1556aa49c926SDag-Erling Smørgrav 1557cce7d346SDag-Erling Smørgrav /* Check for trailing garbage */ 1558aa49c926SDag-Erling Smørgrav if (cp != NULL) 1559aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1560aa49c926SDag-Erling Smørgrav 1561aa49c926SDag-Erling Smørgrav switch (i) { 1562cce7d346SDag-Erling Smørgrav case 1: 1563cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1564cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1565cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1566cce7d346SDag-Erling Smørgrav break; 1567cce7d346SDag-Erling Smørgrav 1568cce7d346SDag-Erling Smørgrav case 2: 1569cce7d346SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1570cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1571cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1572cce7d346SDag-Erling Smørgrav break; 1573cce7d346SDag-Erling Smørgrav 1574aa49c926SDag-Erling Smørgrav case 3: 1575aa49c926SDag-Erling Smørgrav fwd->listen_host = NULL; 1576aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1577aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1578aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[2]); 1579aa49c926SDag-Erling Smørgrav break; 1580aa49c926SDag-Erling Smørgrav 1581aa49c926SDag-Erling Smørgrav case 4: 1582aa49c926SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1583aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1584aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1585aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[3]); 1586aa49c926SDag-Erling Smørgrav break; 1587aa49c926SDag-Erling Smørgrav default: 1588aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1589aa49c926SDag-Erling Smørgrav } 1590aa49c926SDag-Erling Smørgrav 1591*e4a9863fSDag-Erling Smørgrav free(p); 1592aa49c926SDag-Erling Smørgrav 1593cce7d346SDag-Erling Smørgrav if (dynamicfwd) { 1594cce7d346SDag-Erling Smørgrav if (!(i == 1 || i == 2)) 1595cce7d346SDag-Erling Smørgrav goto fail_free; 1596cce7d346SDag-Erling Smørgrav } else { 1597cce7d346SDag-Erling Smørgrav if (!(i == 3 || i == 4)) 1598cce7d346SDag-Erling Smørgrav goto fail_free; 1599cce7d346SDag-Erling Smørgrav if (fwd->connect_port <= 0) 1600cce7d346SDag-Erling Smørgrav goto fail_free; 1601cce7d346SDag-Erling Smørgrav } 1602cce7d346SDag-Erling Smørgrav 1603cce7d346SDag-Erling Smørgrav if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1604aa49c926SDag-Erling Smørgrav goto fail_free; 1605aa49c926SDag-Erling Smørgrav 1606aa49c926SDag-Erling Smørgrav if (fwd->connect_host != NULL && 1607aa49c926SDag-Erling Smørgrav strlen(fwd->connect_host) >= NI_MAXHOST) 1608aa49c926SDag-Erling Smørgrav goto fail_free; 1609cce7d346SDag-Erling Smørgrav if (fwd->listen_host != NULL && 1610cce7d346SDag-Erling Smørgrav strlen(fwd->listen_host) >= NI_MAXHOST) 1611cce7d346SDag-Erling Smørgrav goto fail_free; 1612cce7d346SDag-Erling Smørgrav 1613aa49c926SDag-Erling Smørgrav 1614aa49c926SDag-Erling Smørgrav return (i); 1615aa49c926SDag-Erling Smørgrav 1616aa49c926SDag-Erling Smørgrav fail_free: 1617*e4a9863fSDag-Erling Smørgrav free(fwd->connect_host); 1618cce7d346SDag-Erling Smørgrav fwd->connect_host = NULL; 1619*e4a9863fSDag-Erling Smørgrav free(fwd->listen_host); 1620cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1621aa49c926SDag-Erling Smørgrav return (0); 1622aa49c926SDag-Erling Smørgrav } 1623