1*fa67e83cSDag-Erling Smørgrav /* $OpenBSD: readconf.c,v 1.195 2013/02/17 23:16:57 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> 36333ee039SDag-Erling Smørgrav 37511b41d2SMark Murray #include "xmalloc.h" 38333ee039SDag-Erling Smørgrav #include "ssh.h" 39e8aafc91SKris Kennaway #include "compat.h" 40ca3176e7SBrian Feldman #include "cipher.h" 41ca3176e7SBrian Feldman #include "pathnames.h" 42ca3176e7SBrian Feldman #include "log.h" 43333ee039SDag-Erling Smørgrav #include "key.h" 44ca3176e7SBrian Feldman #include "readconf.h" 45ca3176e7SBrian Feldman #include "match.h" 46ca3176e7SBrian Feldman #include "misc.h" 47333ee039SDag-Erling Smørgrav #include "buffer.h" 48ca3176e7SBrian Feldman #include "kex.h" 49ca3176e7SBrian Feldman #include "mac.h" 50cce7d346SDag-Erling Smørgrav #include "version.h" 51511b41d2SMark Murray 52511b41d2SMark Murray /* Format of the configuration file: 53511b41d2SMark Murray 54511b41d2SMark Murray # Configuration data is parsed as follows: 55511b41d2SMark Murray # 1. command line options 56511b41d2SMark Murray # 2. user-specific file 57511b41d2SMark Murray # 3. system-wide file 58511b41d2SMark Murray # Any configuration value is only changed the first time it is set. 59511b41d2SMark Murray # Thus, host-specific definitions should be at the beginning of the 60511b41d2SMark Murray # configuration file, and defaults at the end. 61511b41d2SMark Murray 62511b41d2SMark Murray # Host-specific declarations. These may override anything above. A single 63511b41d2SMark Murray # host may match multiple declarations; these are processed in the order 64511b41d2SMark Murray # that they are given in. 65511b41d2SMark Murray 66511b41d2SMark Murray Host *.ngs.fi ngs.fi 6780628bacSDag-Erling Smørgrav User foo 68511b41d2SMark Murray 69511b41d2SMark Murray Host fake.com 70511b41d2SMark Murray HostName another.host.name.real.org 71511b41d2SMark Murray User blaah 72511b41d2SMark Murray Port 34289 73511b41d2SMark Murray ForwardX11 no 74511b41d2SMark Murray ForwardAgent no 75511b41d2SMark Murray 76511b41d2SMark Murray Host books.com 77511b41d2SMark Murray RemoteForward 9999 shadows.cs.hut.fi:9999 78511b41d2SMark Murray Cipher 3des 79511b41d2SMark Murray 80511b41d2SMark Murray Host fascist.blob.com 81511b41d2SMark Murray Port 23123 82511b41d2SMark Murray User tylonen 83511b41d2SMark Murray PasswordAuthentication no 84511b41d2SMark Murray 85511b41d2SMark Murray Host puukko.hut.fi 86511b41d2SMark Murray User t35124p 87511b41d2SMark Murray ProxyCommand ssh-proxy %h %p 88511b41d2SMark Murray 89511b41d2SMark Murray Host *.fr 9080628bacSDag-Erling Smørgrav PublicKeyAuthentication no 91511b41d2SMark Murray 92511b41d2SMark Murray Host *.su 93511b41d2SMark Murray Cipher none 94511b41d2SMark Murray PasswordAuthentication no 95511b41d2SMark Murray 96b74df5b2SDag-Erling Smørgrav Host vpn.fake.com 97b74df5b2SDag-Erling Smørgrav Tunnel yes 98b74df5b2SDag-Erling Smørgrav TunnelDevice 3 99b74df5b2SDag-Erling Smørgrav 100511b41d2SMark Murray # Defaults for various options 101511b41d2SMark Murray Host * 102511b41d2SMark Murray ForwardAgent no 103ca3176e7SBrian Feldman ForwardX11 no 104511b41d2SMark Murray PasswordAuthentication yes 105511b41d2SMark Murray RSAAuthentication yes 106511b41d2SMark Murray RhostsRSAAuthentication yes 107511b41d2SMark Murray StrictHostKeyChecking yes 1081ec0d754SDag-Erling Smørgrav TcpKeepAlive no 109511b41d2SMark Murray IdentityFile ~/.ssh/identity 110511b41d2SMark Murray Port 22 111511b41d2SMark Murray EscapeChar ~ 112511b41d2SMark Murray 113511b41d2SMark Murray */ 114511b41d2SMark Murray 115511b41d2SMark Murray /* Keyword tokens. */ 116511b41d2SMark Murray 117511b41d2SMark Murray typedef enum { 118511b41d2SMark Murray oBadOption, 119e2f6069cSDag-Erling Smørgrav oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, 120e2f6069cSDag-Erling Smørgrav oGatewayPorts, oExitOnForwardFailure, 12180628bacSDag-Erling Smørgrav oPasswordAuthentication, oRSAAuthentication, 122ca3176e7SBrian Feldman oChallengeResponseAuthentication, oXAuthLocation, 123511b41d2SMark Murray oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 124511b41d2SMark Murray oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 125511b41d2SMark Murray oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 126511b41d2SMark Murray oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1271ec0d754SDag-Erling Smørgrav oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 128ca3176e7SBrian Feldman oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 129ca3176e7SBrian Feldman oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 130ca3176e7SBrian Feldman oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 131ca3176e7SBrian Feldman oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 132b15c8340SDag-Erling Smørgrav oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 1339e2cbe04SDag-Erling Smørgrav oClearAllForwardings, oNoHostAuthenticationForLocalhost, 134cf2b5f3bSDag-Erling Smørgrav oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 135cf2b5f3bSDag-Erling Smørgrav oAddressFamily, oGssAuthentication, oGssDelegateCreds, 1365962c0e9SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 137e2f6069cSDag-Erling Smørgrav oSendEnv, oControlPath, oControlMaster, oControlPersist, 138e2f6069cSDag-Erling Smørgrav oHashKnownHosts, 139b74df5b2SDag-Erling Smørgrav oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 1407aee6ffeSDag-Erling Smørgrav oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 141e146993eSDag-Erling Smørgrav oKexAlgorithms, oIPQoS, oRequestTTY, 14289986192SBrooks Davis oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf, 14389986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 14489986192SBrooks Davis oNoneEnabled, oNoneSwitch, 14589986192SBrooks Davis #endif 146cfa59440SDag-Erling Smørgrav oVersionAddendum, 147cf2b5f3bSDag-Erling Smørgrav oDeprecated, oUnsupported 148511b41d2SMark Murray } OpCodes; 149511b41d2SMark Murray 150511b41d2SMark Murray /* Textual representations of the tokens. */ 151511b41d2SMark Murray 152511b41d2SMark Murray static struct { 153511b41d2SMark Murray const char *name; 154511b41d2SMark Murray OpCodes opcode; 155511b41d2SMark Murray } keywords[] = { 156511b41d2SMark Murray { "forwardagent", oForwardAgent }, 157511b41d2SMark Murray { "forwardx11", oForwardX11 }, 1581ec0d754SDag-Erling Smørgrav { "forwardx11trusted", oForwardX11Trusted }, 159e2f6069cSDag-Erling Smørgrav { "forwardx11timeout", oForwardX11Timeout }, 160333ee039SDag-Erling Smørgrav { "exitonforwardfailure", oExitOnForwardFailure }, 161c2d3a559SKris Kennaway { "xauthlocation", oXAuthLocation }, 162511b41d2SMark Murray { "gatewayports", oGatewayPorts }, 163511b41d2SMark Murray { "useprivilegedport", oUsePrivilegedPort }, 164cf2b5f3bSDag-Erling Smørgrav { "rhostsauthentication", oDeprecated }, 165511b41d2SMark Murray { "passwordauthentication", oPasswordAuthentication }, 16609958426SBrian Feldman { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 16709958426SBrian Feldman { "kbdinteractivedevices", oKbdInteractiveDevices }, 168511b41d2SMark Murray { "rsaauthentication", oRSAAuthentication }, 169ca3176e7SBrian Feldman { "pubkeyauthentication", oPubkeyAuthentication }, 170ca3176e7SBrian Feldman { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 171ca3176e7SBrian Feldman { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 172ca3176e7SBrian Feldman { "hostbasedauthentication", oHostbasedAuthentication }, 173ca3176e7SBrian Feldman { "challengeresponseauthentication", oChallengeResponseAuthentication }, 174ca3176e7SBrian Feldman { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 175ca3176e7SBrian Feldman { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 176cf2b5f3bSDag-Erling Smørgrav { "kerberosauthentication", oUnsupported }, 177cf2b5f3bSDag-Erling Smørgrav { "kerberostgtpassing", oUnsupported }, 178cf2b5f3bSDag-Erling Smørgrav { "afstokenpassing", oUnsupported }, 179cf2b5f3bSDag-Erling Smørgrav #if defined(GSSAPI) 180cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oGssAuthentication }, 181cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oGssDelegateCreds }, 182cf2b5f3bSDag-Erling Smørgrav #else 183cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oUnsupported }, 184cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oUnsupported }, 185511b41d2SMark Murray #endif 18680628bacSDag-Erling Smørgrav { "fallbacktorsh", oDeprecated }, 18780628bacSDag-Erling Smørgrav { "usersh", oDeprecated }, 188511b41d2SMark Murray { "identityfile", oIdentityFile }, 189cce7d346SDag-Erling Smørgrav { "identityfile2", oIdentityFile }, /* obsolete */ 1905962c0e9SDag-Erling Smørgrav { "identitiesonly", oIdentitiesOnly }, 191511b41d2SMark Murray { "hostname", oHostName }, 192ca3176e7SBrian Feldman { "hostkeyalias", oHostKeyAlias }, 193511b41d2SMark Murray { "proxycommand", oProxyCommand }, 194511b41d2SMark Murray { "port", oPort }, 195511b41d2SMark Murray { "cipher", oCipher }, 196e8aafc91SKris Kennaway { "ciphers", oCiphers }, 197ca3176e7SBrian Feldman { "macs", oMacs }, 198e8aafc91SKris Kennaway { "protocol", oProtocol }, 199511b41d2SMark Murray { "remoteforward", oRemoteForward }, 200511b41d2SMark Murray { "localforward", oLocalForward }, 201511b41d2SMark Murray { "user", oUser }, 202511b41d2SMark Murray { "host", oHost }, 203511b41d2SMark Murray { "escapechar", oEscapeChar }, 204511b41d2SMark Murray { "globalknownhostsfile", oGlobalKnownHostsFile }, 205e146993eSDag-Erling Smørgrav { "globalknownhostsfile2", oDeprecated }, 206cce7d346SDag-Erling Smørgrav { "userknownhostsfile", oUserKnownHostsFile }, 207e146993eSDag-Erling Smørgrav { "userknownhostsfile2", oDeprecated }, 208511b41d2SMark Murray { "connectionattempts", oConnectionAttempts }, 209511b41d2SMark Murray { "batchmode", oBatchMode }, 210511b41d2SMark Murray { "checkhostip", oCheckHostIP }, 211511b41d2SMark Murray { "stricthostkeychecking", oStrictHostKeyChecking }, 212511b41d2SMark Murray { "compression", oCompression }, 213511b41d2SMark Murray { "compressionlevel", oCompressionLevel }, 2141ec0d754SDag-Erling Smørgrav { "tcpkeepalive", oTCPKeepAlive }, 2151ec0d754SDag-Erling Smørgrav { "keepalive", oTCPKeepAlive }, /* obsolete */ 216511b41d2SMark Murray { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 217511b41d2SMark Murray { "loglevel", oLogLevel }, 218ca3176e7SBrian Feldman { "dynamicforward", oDynamicForward }, 219ca3176e7SBrian Feldman { "preferredauthentications", oPreferredAuthentications }, 220ca3176e7SBrian Feldman { "hostkeyalgorithms", oHostKeyAlgorithms }, 221af12a3e7SDag-Erling Smørgrav { "bindaddress", oBindAddress }, 222b15c8340SDag-Erling Smørgrav #ifdef ENABLE_PKCS11 223b15c8340SDag-Erling Smørgrav { "smartcarddevice", oPKCS11Provider }, 224b15c8340SDag-Erling Smørgrav { "pkcs11provider", oPKCS11Provider }, 225cf2b5f3bSDag-Erling Smørgrav #else 226cf2b5f3bSDag-Erling Smørgrav { "smartcarddevice", oUnsupported }, 227b15c8340SDag-Erling Smørgrav { "pkcs11provider", oUnsupported }, 228cf2b5f3bSDag-Erling Smørgrav #endif 229af12a3e7SDag-Erling Smørgrav { "clearallforwardings", oClearAllForwardings }, 230e73e9afaSDag-Erling Smørgrav { "enablesshkeysign", oEnableSSHKeysign }, 231cf2b5f3bSDag-Erling Smørgrav { "verifyhostkeydns", oVerifyHostKeyDNS }, 232af12a3e7SDag-Erling Smørgrav { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 233cf2b5f3bSDag-Erling Smørgrav { "rekeylimit", oRekeyLimit }, 234cf2b5f3bSDag-Erling Smørgrav { "connecttimeout", oConnectTimeout }, 235cf2b5f3bSDag-Erling Smørgrav { "addressfamily", oAddressFamily }, 2361ec0d754SDag-Erling Smørgrav { "serveraliveinterval", oServerAliveInterval }, 2371ec0d754SDag-Erling Smørgrav { "serveralivecountmax", oServerAliveCountMax }, 23821e764dfSDag-Erling Smørgrav { "sendenv", oSendEnv }, 23921e764dfSDag-Erling Smørgrav { "controlpath", oControlPath }, 24021e764dfSDag-Erling Smørgrav { "controlmaster", oControlMaster }, 241e2f6069cSDag-Erling Smørgrav { "controlpersist", oControlPersist }, 242aa49c926SDag-Erling Smørgrav { "hashknownhosts", oHashKnownHosts }, 243b74df5b2SDag-Erling Smørgrav { "tunnel", oTunnel }, 244b74df5b2SDag-Erling Smørgrav { "tunneldevice", oTunnelDevice }, 245b74df5b2SDag-Erling Smørgrav { "localcommand", oLocalCommand }, 246b74df5b2SDag-Erling Smørgrav { "permitlocalcommand", oPermitLocalCommand }, 247d4af9e69SDag-Erling Smørgrav { "visualhostkey", oVisualHostKey }, 2487aee6ffeSDag-Erling Smørgrav { "useroaming", oUseRoaming }, 249cce7d346SDag-Erling Smørgrav #ifdef JPAKE 250cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", 251cce7d346SDag-Erling Smørgrav oZeroKnowledgePasswordAuthentication }, 252cce7d346SDag-Erling Smørgrav #else 253cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", oUnsupported }, 254cce7d346SDag-Erling Smørgrav #endif 2554a421b63SDag-Erling Smørgrav { "kexalgorithms", oKexAlgorithms }, 2564a421b63SDag-Erling Smørgrav { "ipqos", oIPQoS }, 257e146993eSDag-Erling Smørgrav { "requesttty", oRequestTTY }, 25889986192SBrooks Davis { "hpndisabled", oHPNDisabled }, 25989986192SBrooks Davis { "hpnbuffersize", oHPNBufferSize }, 26089986192SBrooks Davis { "tcprcvbufpoll", oTcpRcvBufPoll }, 26189986192SBrooks Davis { "tcprcvbuf", oTcpRcvBuf }, 26289986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 26389986192SBrooks Davis { "noneenabled", oNoneEnabled }, 26489986192SBrooks Davis { "noneswitch", oNoneSwitch }, 26589986192SBrooks Davis #endif 266975616f0SDag-Erling Smørgrav { "versionaddendum", oVersionAddendum }, 26735762f59SEd Schouten 268af12a3e7SDag-Erling Smørgrav { NULL, oBadOption } 269511b41d2SMark Murray }; 270511b41d2SMark Murray 271511b41d2SMark Murray /* 272511b41d2SMark Murray * Adds a local TCP/IP port forward to options. Never returns if there is an 273511b41d2SMark Murray * error. 274511b41d2SMark Murray */ 275511b41d2SMark Murray 276511b41d2SMark Murray void 277aa49c926SDag-Erling Smørgrav add_local_forward(Options *options, const Forward *newfwd) 278511b41d2SMark Murray { 279511b41d2SMark Murray Forward *fwd; 280f388f5efSDag-Erling Smørgrav #ifndef NO_IPPORT_RESERVED_CONCEPT 281511b41d2SMark Murray extern uid_t original_real_uid; 28203f6c5cdSDag-Erling Smørgrav int ipport_reserved; 28303f6c5cdSDag-Erling Smørgrav #ifdef __FreeBSD__ 28403f6c5cdSDag-Erling Smørgrav size_t len_ipport_reserved = sizeof(ipport_reserved); 28503f6c5cdSDag-Erling Smørgrav 28603f6c5cdSDag-Erling Smørgrav if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 28703f6c5cdSDag-Erling Smørgrav &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 28803f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 28903f6c5cdSDag-Erling Smørgrav else 29003f6c5cdSDag-Erling Smørgrav ipport_reserved++; 29103f6c5cdSDag-Erling Smørgrav #else 29203f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 29303f6c5cdSDag-Erling Smørgrav #endif 29403f6c5cdSDag-Erling Smørgrav if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 295ca3176e7SBrian Feldman fatal("Privileged ports can only be forwarded by root."); 296989dd127SDag-Erling Smørgrav #endif 297e2f6069cSDag-Erling Smørgrav options->local_forwards = xrealloc(options->local_forwards, 298e2f6069cSDag-Erling Smørgrav options->num_local_forwards + 1, 299e2f6069cSDag-Erling Smørgrav sizeof(*options->local_forwards)); 300511b41d2SMark Murray fwd = &options->local_forwards[options->num_local_forwards++]; 301aa49c926SDag-Erling Smørgrav 302cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 303aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 304cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 305aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 306511b41d2SMark Murray } 307511b41d2SMark Murray 308511b41d2SMark Murray /* 309511b41d2SMark Murray * Adds a remote TCP/IP port forward to options. Never returns if there is 310511b41d2SMark Murray * an error. 311511b41d2SMark Murray */ 312511b41d2SMark Murray 313511b41d2SMark Murray void 314aa49c926SDag-Erling Smørgrav add_remote_forward(Options *options, const Forward *newfwd) 315511b41d2SMark Murray { 316511b41d2SMark Murray Forward *fwd; 317e2f6069cSDag-Erling Smørgrav 318e2f6069cSDag-Erling Smørgrav options->remote_forwards = xrealloc(options->remote_forwards, 319e2f6069cSDag-Erling Smørgrav options->num_remote_forwards + 1, 320e2f6069cSDag-Erling Smørgrav sizeof(*options->remote_forwards)); 321511b41d2SMark Murray fwd = &options->remote_forwards[options->num_remote_forwards++]; 322aa49c926SDag-Erling Smørgrav 323cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 324aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 325cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 326aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 327462c32cbSDag-Erling Smørgrav fwd->handle = newfwd->handle; 328e2f6069cSDag-Erling Smørgrav fwd->allocated_port = 0; 329511b41d2SMark Murray } 330511b41d2SMark Murray 331af12a3e7SDag-Erling Smørgrav static void 332af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options) 333af12a3e7SDag-Erling Smørgrav { 334af12a3e7SDag-Erling Smørgrav int i; 335af12a3e7SDag-Erling Smørgrav 336aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_local_forwards; i++) { 337aa49c926SDag-Erling Smørgrav if (options->local_forwards[i].listen_host != NULL) 338aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].listen_host); 339aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].connect_host); 340aa49c926SDag-Erling Smørgrav } 341e2f6069cSDag-Erling Smørgrav if (options->num_local_forwards > 0) { 342e2f6069cSDag-Erling Smørgrav xfree(options->local_forwards); 343e2f6069cSDag-Erling Smørgrav options->local_forwards = NULL; 344e2f6069cSDag-Erling Smørgrav } 345af12a3e7SDag-Erling Smørgrav options->num_local_forwards = 0; 346aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_remote_forwards; i++) { 347aa49c926SDag-Erling Smørgrav if (options->remote_forwards[i].listen_host != NULL) 348aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].listen_host); 349aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].connect_host); 350aa49c926SDag-Erling Smørgrav } 351e2f6069cSDag-Erling Smørgrav if (options->num_remote_forwards > 0) { 352e2f6069cSDag-Erling Smørgrav xfree(options->remote_forwards); 353e2f6069cSDag-Erling Smørgrav options->remote_forwards = NULL; 354e2f6069cSDag-Erling Smørgrav } 355af12a3e7SDag-Erling Smørgrav options->num_remote_forwards = 0; 356b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 357af12a3e7SDag-Erling Smørgrav } 358af12a3e7SDag-Erling Smørgrav 359*fa67e83cSDag-Erling Smørgrav void 360*fa67e83cSDag-Erling Smørgrav add_identity_file(Options *options, const char *dir, const char *filename, 361*fa67e83cSDag-Erling Smørgrav int userprovided) 362*fa67e83cSDag-Erling Smørgrav { 363*fa67e83cSDag-Erling Smørgrav char *path; 364*fa67e83cSDag-Erling Smørgrav 365*fa67e83cSDag-Erling Smørgrav if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 366*fa67e83cSDag-Erling Smørgrav fatal("Too many identity files specified (max %d)", 367*fa67e83cSDag-Erling Smørgrav SSH_MAX_IDENTITY_FILES); 368*fa67e83cSDag-Erling Smørgrav 369*fa67e83cSDag-Erling Smørgrav if (dir == NULL) /* no dir, filename is absolute */ 370*fa67e83cSDag-Erling Smørgrav path = xstrdup(filename); 371*fa67e83cSDag-Erling Smørgrav else 372*fa67e83cSDag-Erling Smørgrav (void)xasprintf(&path, "%.100s%.100s", dir, filename); 373*fa67e83cSDag-Erling Smørgrav 374*fa67e83cSDag-Erling Smørgrav options->identity_file_userprovided[options->num_identity_files] = 375*fa67e83cSDag-Erling Smørgrav userprovided; 376*fa67e83cSDag-Erling Smørgrav options->identity_files[options->num_identity_files++] = path; 377*fa67e83cSDag-Erling Smørgrav } 378*fa67e83cSDag-Erling Smørgrav 379511b41d2SMark Murray /* 380ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or oBadOption. 381511b41d2SMark Murray */ 382511b41d2SMark Murray 383511b41d2SMark Murray static OpCodes 384511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum) 385511b41d2SMark Murray { 386ca3176e7SBrian Feldman u_int i; 387511b41d2SMark Murray 388511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 389511b41d2SMark Murray if (strcasecmp(cp, keywords[i].name) == 0) 390511b41d2SMark Murray return keywords[i].opcode; 391511b41d2SMark Murray 392ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 393511b41d2SMark Murray filename, linenum, cp); 394511b41d2SMark Murray return oBadOption; 395511b41d2SMark Murray } 396511b41d2SMark Murray 397511b41d2SMark Murray /* 398511b41d2SMark Murray * Processes a single option line as used in the configuration files. This 399511b41d2SMark Murray * only sets those values that have not already been set. 400511b41d2SMark Murray */ 401e73e9afaSDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 402511b41d2SMark Murray 403511b41d2SMark Murray int 404511b41d2SMark Murray process_config_line(Options *options, const char *host, 405511b41d2SMark Murray char *line, const char *filename, int linenum, 406511b41d2SMark Murray int *activep) 407511b41d2SMark Murray { 408e146993eSDag-Erling Smørgrav char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 409e146993eSDag-Erling Smørgrav char **cpptr, fwdarg[256]; 410e146993eSDag-Erling Smørgrav u_int *uintptr, max_entries = 0; 411e146993eSDag-Erling Smørgrav int negated, opcode, *intptr, value, value2, scale; 412d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 413333ee039SDag-Erling Smørgrav long long orig, val64; 414e73e9afaSDag-Erling Smørgrav size_t len; 415aa49c926SDag-Erling Smørgrav Forward fwd; 416511b41d2SMark Murray 417cf2b5f3bSDag-Erling Smørgrav /* Strip trailing whitespace */ 418cf2b5f3bSDag-Erling Smørgrav for (len = strlen(line) - 1; len > 0; len--) { 419cf2b5f3bSDag-Erling Smørgrav if (strchr(WHITESPACE, line[len]) == NULL) 420cf2b5f3bSDag-Erling Smørgrav break; 421cf2b5f3bSDag-Erling Smørgrav line[len] = '\0'; 422cf2b5f3bSDag-Erling Smørgrav } 423cf2b5f3bSDag-Erling Smørgrav 424c2d3a559SKris Kennaway s = line; 425c2d3a559SKris Kennaway /* Get the keyword. (Each line is supposed to begin with a keyword). */ 426333ee039SDag-Erling Smørgrav if ((keyword = strdelim(&s)) == NULL) 427333ee039SDag-Erling Smørgrav return 0; 428c2d3a559SKris Kennaway /* Ignore leading whitespace. */ 429c2d3a559SKris Kennaway if (*keyword == '\0') 430c2d3a559SKris Kennaway keyword = strdelim(&s); 431ca3176e7SBrian Feldman if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 432511b41d2SMark Murray return 0; 433511b41d2SMark Murray 434c2d3a559SKris Kennaway opcode = parse_token(keyword, filename, linenum); 435511b41d2SMark Murray 436511b41d2SMark Murray switch (opcode) { 437511b41d2SMark Murray case oBadOption: 438511b41d2SMark Murray /* don't panic, but count bad options */ 439511b41d2SMark Murray return -1; 440511b41d2SMark Murray /* NOTREACHED */ 441cf2b5f3bSDag-Erling Smørgrav case oConnectTimeout: 442cf2b5f3bSDag-Erling Smørgrav intptr = &options->connection_timeout; 4431ec0d754SDag-Erling Smørgrav parse_time: 444cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 445cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 446cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: missing time value.", 447cf2b5f3bSDag-Erling Smørgrav filename, linenum); 448cf2b5f3bSDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 449cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 450cf2b5f3bSDag-Erling Smørgrav filename, linenum); 451d4af9e69SDag-Erling Smørgrav if (*activep && *intptr == -1) 452cf2b5f3bSDag-Erling Smørgrav *intptr = value; 453cf2b5f3bSDag-Erling Smørgrav break; 454cf2b5f3bSDag-Erling Smørgrav 455511b41d2SMark Murray case oForwardAgent: 456511b41d2SMark Murray intptr = &options->forward_agent; 457511b41d2SMark Murray parse_flag: 458c2d3a559SKris Kennaway arg = strdelim(&s); 459c2d3a559SKris Kennaway if (!arg || *arg == '\0') 460511b41d2SMark Murray fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 461511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 462c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 463511b41d2SMark Murray value = 1; 464c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 465511b41d2SMark Murray value = 0; 466511b41d2SMark Murray else 467511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 468511b41d2SMark Murray if (*activep && *intptr == -1) 469511b41d2SMark Murray *intptr = value; 470511b41d2SMark Murray break; 471511b41d2SMark Murray 472511b41d2SMark Murray case oForwardX11: 473511b41d2SMark Murray intptr = &options->forward_x11; 474511b41d2SMark Murray goto parse_flag; 475511b41d2SMark Murray 4761ec0d754SDag-Erling Smørgrav case oForwardX11Trusted: 4771ec0d754SDag-Erling Smørgrav intptr = &options->forward_x11_trusted; 4781ec0d754SDag-Erling Smørgrav goto parse_flag; 4791ec0d754SDag-Erling Smørgrav 480e2f6069cSDag-Erling Smørgrav case oForwardX11Timeout: 481e2f6069cSDag-Erling Smørgrav intptr = &options->forward_x11_timeout; 482e2f6069cSDag-Erling Smørgrav goto parse_time; 483e2f6069cSDag-Erling Smørgrav 484511b41d2SMark Murray case oGatewayPorts: 485511b41d2SMark Murray intptr = &options->gateway_ports; 486511b41d2SMark Murray goto parse_flag; 487511b41d2SMark Murray 488333ee039SDag-Erling Smørgrav case oExitOnForwardFailure: 489333ee039SDag-Erling Smørgrav intptr = &options->exit_on_forward_failure; 490333ee039SDag-Erling Smørgrav goto parse_flag; 491333ee039SDag-Erling Smørgrav 492511b41d2SMark Murray case oUsePrivilegedPort: 493511b41d2SMark Murray intptr = &options->use_privileged_port; 494511b41d2SMark Murray goto parse_flag; 495511b41d2SMark Murray 496511b41d2SMark Murray case oPasswordAuthentication: 497511b41d2SMark Murray intptr = &options->password_authentication; 498511b41d2SMark Murray goto parse_flag; 499511b41d2SMark Murray 500cce7d346SDag-Erling Smørgrav case oZeroKnowledgePasswordAuthentication: 501cce7d346SDag-Erling Smørgrav intptr = &options->zero_knowledge_password_authentication; 502cce7d346SDag-Erling Smørgrav goto parse_flag; 503cce7d346SDag-Erling Smørgrav 50409958426SBrian Feldman case oKbdInteractiveAuthentication: 50509958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 50609958426SBrian Feldman goto parse_flag; 50709958426SBrian Feldman 50809958426SBrian Feldman case oKbdInteractiveDevices: 50909958426SBrian Feldman charptr = &options->kbd_interactive_devices; 51009958426SBrian Feldman goto parse_string; 51109958426SBrian Feldman 512ca3176e7SBrian Feldman case oPubkeyAuthentication: 513ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 514e8aafc91SKris Kennaway goto parse_flag; 515e8aafc91SKris Kennaway 516511b41d2SMark Murray case oRSAAuthentication: 517511b41d2SMark Murray intptr = &options->rsa_authentication; 518511b41d2SMark Murray goto parse_flag; 519511b41d2SMark Murray 520511b41d2SMark Murray case oRhostsRSAAuthentication: 521511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 522511b41d2SMark Murray goto parse_flag; 523511b41d2SMark Murray 524ca3176e7SBrian Feldman case oHostbasedAuthentication: 525ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 526511b41d2SMark Murray goto parse_flag; 527511b41d2SMark Murray 528af12a3e7SDag-Erling Smørgrav case oChallengeResponseAuthentication: 529af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 530af12a3e7SDag-Erling Smørgrav goto parse_flag; 531cf2b5f3bSDag-Erling Smørgrav 532cf2b5f3bSDag-Erling Smørgrav case oGssAuthentication: 533cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 534511b41d2SMark Murray goto parse_flag; 535cf2b5f3bSDag-Erling Smørgrav 536cf2b5f3bSDag-Erling Smørgrav case oGssDelegateCreds: 537cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_deleg_creds; 538ca3176e7SBrian Feldman goto parse_flag; 539cf2b5f3bSDag-Erling Smørgrav 540511b41d2SMark Murray case oBatchMode: 541511b41d2SMark Murray intptr = &options->batch_mode; 542511b41d2SMark Murray goto parse_flag; 543511b41d2SMark Murray 544511b41d2SMark Murray case oCheckHostIP: 545511b41d2SMark Murray intptr = &options->check_host_ip; 546511b41d2SMark Murray goto parse_flag; 547511b41d2SMark Murray 548cf2b5f3bSDag-Erling Smørgrav case oVerifyHostKeyDNS: 549cf2b5f3bSDag-Erling Smørgrav intptr = &options->verify_host_key_dns; 5501ec0d754SDag-Erling Smørgrav goto parse_yesnoask; 551cf2b5f3bSDag-Erling Smørgrav 552511b41d2SMark Murray case oStrictHostKeyChecking: 553511b41d2SMark Murray intptr = &options->strict_host_key_checking; 5541ec0d754SDag-Erling Smørgrav parse_yesnoask: 555c2d3a559SKris Kennaway arg = strdelim(&s); 556c2d3a559SKris Kennaway if (!arg || *arg == '\0') 557ca3176e7SBrian Feldman fatal("%.200s line %d: Missing yes/no/ask argument.", 558511b41d2SMark Murray filename, linenum); 559511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 560c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 561511b41d2SMark Murray value = 1; 562c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 563511b41d2SMark Murray value = 0; 564c2d3a559SKris Kennaway else if (strcmp(arg, "ask") == 0) 565511b41d2SMark Murray value = 2; 566511b41d2SMark Murray else 567511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 568511b41d2SMark Murray if (*activep && *intptr == -1) 569511b41d2SMark Murray *intptr = value; 570511b41d2SMark Murray break; 571511b41d2SMark Murray 572511b41d2SMark Murray case oCompression: 573511b41d2SMark Murray intptr = &options->compression; 574511b41d2SMark Murray goto parse_flag; 575511b41d2SMark Murray 5761ec0d754SDag-Erling Smørgrav case oTCPKeepAlive: 5771ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 578511b41d2SMark Murray goto parse_flag; 579511b41d2SMark Murray 580af12a3e7SDag-Erling Smørgrav case oNoHostAuthenticationForLocalhost: 581af12a3e7SDag-Erling Smørgrav intptr = &options->no_host_authentication_for_localhost; 582af12a3e7SDag-Erling Smørgrav goto parse_flag; 583af12a3e7SDag-Erling Smørgrav 584511b41d2SMark Murray case oNumberOfPasswordPrompts: 585511b41d2SMark Murray intptr = &options->number_of_password_prompts; 586511b41d2SMark Murray goto parse_int; 587511b41d2SMark Murray 588511b41d2SMark Murray case oCompressionLevel: 589511b41d2SMark Murray intptr = &options->compression_level; 590511b41d2SMark Murray goto parse_int; 591511b41d2SMark Murray 592cf2b5f3bSDag-Erling Smørgrav case oRekeyLimit: 593cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 594cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 595cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 596cf2b5f3bSDag-Erling Smørgrav if (arg[0] < '0' || arg[0] > '9') 597cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 598333ee039SDag-Erling Smørgrav orig = val64 = strtoll(arg, &endofnumber, 10); 599cf2b5f3bSDag-Erling Smørgrav if (arg == endofnumber) 600cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 601cf2b5f3bSDag-Erling Smørgrav switch (toupper(*endofnumber)) { 602333ee039SDag-Erling Smørgrav case '\0': 603333ee039SDag-Erling Smørgrav scale = 1; 604333ee039SDag-Erling Smørgrav break; 605cf2b5f3bSDag-Erling Smørgrav case 'K': 606333ee039SDag-Erling Smørgrav scale = 1<<10; 607cf2b5f3bSDag-Erling Smørgrav break; 608cf2b5f3bSDag-Erling Smørgrav case 'M': 609333ee039SDag-Erling Smørgrav scale = 1<<20; 610cf2b5f3bSDag-Erling Smørgrav break; 611cf2b5f3bSDag-Erling Smørgrav case 'G': 612333ee039SDag-Erling Smørgrav scale = 1<<30; 613cf2b5f3bSDag-Erling Smørgrav break; 614333ee039SDag-Erling Smørgrav default: 615333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Invalid RekeyLimit suffix", 616333ee039SDag-Erling Smørgrav filename, linenum); 617cf2b5f3bSDag-Erling Smørgrav } 618333ee039SDag-Erling Smørgrav val64 *= scale; 619333ee039SDag-Erling Smørgrav /* detect integer wrap and too-large limits */ 620d4af9e69SDag-Erling Smørgrav if ((val64 / scale) != orig || val64 > UINT_MAX) 621333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too large", 622333ee039SDag-Erling Smørgrav filename, linenum); 623333ee039SDag-Erling Smørgrav if (val64 < 16) 624333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 625333ee039SDag-Erling Smørgrav filename, linenum); 626d4af9e69SDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 627d4af9e69SDag-Erling Smørgrav options->rekey_limit = (u_int32_t)val64; 628cf2b5f3bSDag-Erling Smørgrav break; 629cf2b5f3bSDag-Erling Smørgrav 630511b41d2SMark Murray case oIdentityFile: 631c2d3a559SKris Kennaway arg = strdelim(&s); 632c2d3a559SKris Kennaway if (!arg || *arg == '\0') 633511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 634511b41d2SMark Murray if (*activep) { 635ca3176e7SBrian Feldman intptr = &options->num_identity_files; 636e8aafc91SKris Kennaway if (*intptr >= SSH_MAX_IDENTITY_FILES) 637511b41d2SMark Murray fatal("%.200s line %d: Too many identity files specified (max %d).", 638511b41d2SMark Murray filename, linenum, SSH_MAX_IDENTITY_FILES); 639*fa67e83cSDag-Erling Smørgrav add_identity_file(options, NULL, arg, 1); 640511b41d2SMark Murray } 641511b41d2SMark Murray break; 642511b41d2SMark Murray 643c2d3a559SKris Kennaway case oXAuthLocation: 644c2d3a559SKris Kennaway charptr=&options->xauth_location; 645c2d3a559SKris Kennaway goto parse_string; 646c2d3a559SKris Kennaway 647511b41d2SMark Murray case oUser: 648511b41d2SMark Murray charptr = &options->user; 649511b41d2SMark Murray parse_string: 650c2d3a559SKris Kennaway arg = strdelim(&s); 651c2d3a559SKris Kennaway if (!arg || *arg == '\0') 652e146993eSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 653e146993eSDag-Erling Smørgrav filename, linenum); 654511b41d2SMark Murray if (*activep && *charptr == NULL) 655c2d3a559SKris Kennaway *charptr = xstrdup(arg); 656511b41d2SMark Murray break; 657511b41d2SMark Murray 658511b41d2SMark Murray case oGlobalKnownHostsFile: 659e146993eSDag-Erling Smørgrav cpptr = (char **)&options->system_hostfiles; 660e146993eSDag-Erling Smørgrav uintptr = &options->num_system_hostfiles; 661e146993eSDag-Erling Smørgrav max_entries = SSH_MAX_HOSTS_FILES; 662e146993eSDag-Erling Smørgrav parse_char_array: 663e146993eSDag-Erling Smørgrav if (*activep && *uintptr == 0) { 664e146993eSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 665e146993eSDag-Erling Smørgrav if ((*uintptr) >= max_entries) 666e146993eSDag-Erling Smørgrav fatal("%s line %d: " 667e146993eSDag-Erling Smørgrav "too many authorized keys files.", 668e146993eSDag-Erling Smørgrav filename, linenum); 669e146993eSDag-Erling Smørgrav cpptr[(*uintptr)++] = xstrdup(arg); 670e146993eSDag-Erling Smørgrav } 671e146993eSDag-Erling Smørgrav } 672e146993eSDag-Erling Smørgrav return 0; 673511b41d2SMark Murray 674511b41d2SMark Murray case oUserKnownHostsFile: 675e146993eSDag-Erling Smørgrav cpptr = (char **)&options->user_hostfiles; 676e146993eSDag-Erling Smørgrav uintptr = &options->num_user_hostfiles; 677e146993eSDag-Erling Smørgrav max_entries = SSH_MAX_HOSTS_FILES; 678e146993eSDag-Erling Smørgrav goto parse_char_array; 679e8aafc91SKris Kennaway 680511b41d2SMark Murray case oHostName: 681511b41d2SMark Murray charptr = &options->hostname; 682511b41d2SMark Murray goto parse_string; 683511b41d2SMark Murray 684ca3176e7SBrian Feldman case oHostKeyAlias: 685ca3176e7SBrian Feldman charptr = &options->host_key_alias; 686ca3176e7SBrian Feldman goto parse_string; 687ca3176e7SBrian Feldman 688ca3176e7SBrian Feldman case oPreferredAuthentications: 689ca3176e7SBrian Feldman charptr = &options->preferred_authentications; 690ca3176e7SBrian Feldman goto parse_string; 691ca3176e7SBrian Feldman 692af12a3e7SDag-Erling Smørgrav case oBindAddress: 693af12a3e7SDag-Erling Smørgrav charptr = &options->bind_address; 694af12a3e7SDag-Erling Smørgrav goto parse_string; 695af12a3e7SDag-Erling Smørgrav 696b15c8340SDag-Erling Smørgrav case oPKCS11Provider: 697b15c8340SDag-Erling Smørgrav charptr = &options->pkcs11_provider; 698af12a3e7SDag-Erling Smørgrav goto parse_string; 699af12a3e7SDag-Erling Smørgrav 700511b41d2SMark Murray case oProxyCommand: 701b74df5b2SDag-Erling Smørgrav charptr = &options->proxy_command; 702b74df5b2SDag-Erling Smørgrav parse_command: 703cf2b5f3bSDag-Erling Smørgrav if (s == NULL) 704cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 705e73e9afaSDag-Erling Smørgrav len = strspn(s, WHITESPACE "="); 706511b41d2SMark Murray if (*activep && *charptr == NULL) 707e73e9afaSDag-Erling Smørgrav *charptr = xstrdup(s + len); 708511b41d2SMark Murray return 0; 709511b41d2SMark Murray 710511b41d2SMark Murray case oPort: 711511b41d2SMark Murray intptr = &options->port; 712511b41d2SMark Murray parse_int: 713c2d3a559SKris Kennaway arg = strdelim(&s); 714c2d3a559SKris Kennaway if (!arg || *arg == '\0') 715511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 716c2d3a559SKris Kennaway if (arg[0] < '0' || arg[0] > '9') 717511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 718511b41d2SMark Murray 719511b41d2SMark Murray /* Octal, decimal, or hex format? */ 720c2d3a559SKris Kennaway value = strtol(arg, &endofnumber, 0); 721c2d3a559SKris Kennaway if (arg == endofnumber) 722511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 723511b41d2SMark Murray if (*activep && *intptr == -1) 724511b41d2SMark Murray *intptr = value; 725511b41d2SMark Murray break; 726511b41d2SMark Murray 727511b41d2SMark Murray case oConnectionAttempts: 728511b41d2SMark Murray intptr = &options->connection_attempts; 729511b41d2SMark Murray goto parse_int; 730511b41d2SMark Murray 731511b41d2SMark Murray case oCipher: 732511b41d2SMark Murray intptr = &options->cipher; 733c2d3a559SKris Kennaway arg = strdelim(&s); 734c2d3a559SKris Kennaway if (!arg || *arg == '\0') 735db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 736c2d3a559SKris Kennaway value = cipher_number(arg); 737511b41d2SMark Murray if (value == -1) 738511b41d2SMark Murray fatal("%.200s line %d: Bad cipher '%s'.", 739c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 740511b41d2SMark Murray if (*activep && *intptr == -1) 741511b41d2SMark Murray *intptr = value; 742511b41d2SMark Murray break; 743511b41d2SMark Murray 744e8aafc91SKris Kennaway case oCiphers: 745c2d3a559SKris Kennaway arg = strdelim(&s); 746c2d3a559SKris Kennaway if (!arg || *arg == '\0') 747db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 748c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 749e8aafc91SKris Kennaway fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 750c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 751e8aafc91SKris Kennaway if (*activep && options->ciphers == NULL) 752c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 753e8aafc91SKris Kennaway break; 754e8aafc91SKris Kennaway 755ca3176e7SBrian Feldman case oMacs: 756ca3176e7SBrian Feldman arg = strdelim(&s); 757ca3176e7SBrian Feldman if (!arg || *arg == '\0') 758ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 759ca3176e7SBrian Feldman if (!mac_valid(arg)) 760ca3176e7SBrian Feldman fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 761ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 762ca3176e7SBrian Feldman if (*activep && options->macs == NULL) 763ca3176e7SBrian Feldman options->macs = xstrdup(arg); 764ca3176e7SBrian Feldman break; 765ca3176e7SBrian Feldman 7664a421b63SDag-Erling Smørgrav case oKexAlgorithms: 7674a421b63SDag-Erling Smørgrav arg = strdelim(&s); 7684a421b63SDag-Erling Smørgrav if (!arg || *arg == '\0') 7694a421b63SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", 7704a421b63SDag-Erling Smørgrav filename, linenum); 7714a421b63SDag-Erling Smørgrav if (!kex_names_valid(arg)) 7724a421b63SDag-Erling Smørgrav fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", 7734a421b63SDag-Erling Smørgrav filename, linenum, arg ? arg : "<NONE>"); 7744a421b63SDag-Erling Smørgrav if (*activep && options->kex_algorithms == NULL) 7754a421b63SDag-Erling Smørgrav options->kex_algorithms = xstrdup(arg); 7764a421b63SDag-Erling Smørgrav break; 7774a421b63SDag-Erling Smørgrav 778ca3176e7SBrian Feldman case oHostKeyAlgorithms: 779ca3176e7SBrian Feldman arg = strdelim(&s); 780ca3176e7SBrian Feldman if (!arg || *arg == '\0') 781ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 782ca3176e7SBrian Feldman if (!key_names_valid2(arg)) 783ca3176e7SBrian Feldman fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 784ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 785ca3176e7SBrian Feldman if (*activep && options->hostkeyalgorithms == NULL) 786ca3176e7SBrian Feldman options->hostkeyalgorithms = xstrdup(arg); 787ca3176e7SBrian Feldman break; 788ca3176e7SBrian Feldman 789e8aafc91SKris Kennaway case oProtocol: 790e8aafc91SKris Kennaway intptr = &options->protocol; 791c2d3a559SKris Kennaway arg = strdelim(&s); 792c2d3a559SKris Kennaway if (!arg || *arg == '\0') 793db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 794c2d3a559SKris Kennaway value = proto_spec(arg); 795e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 796e8aafc91SKris Kennaway fatal("%.200s line %d: Bad protocol spec '%s'.", 797c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 798e8aafc91SKris Kennaway if (*activep && *intptr == SSH_PROTO_UNKNOWN) 799e8aafc91SKris Kennaway *intptr = value; 800e8aafc91SKris Kennaway break; 801e8aafc91SKris Kennaway 802511b41d2SMark Murray case oLogLevel: 803d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 804c2d3a559SKris Kennaway arg = strdelim(&s); 805c2d3a559SKris Kennaway value = log_level_number(arg); 806af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 807ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 808c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 809d4af9e69SDag-Erling Smørgrav if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 810d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 811511b41d2SMark Murray break; 812511b41d2SMark Murray 813af12a3e7SDag-Erling Smørgrav case oLocalForward: 814511b41d2SMark Murray case oRemoteForward: 815cce7d346SDag-Erling Smørgrav case oDynamicForward: 816c2d3a559SKris Kennaway arg = strdelim(&s); 817aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 818af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Missing port argument.", 819af12a3e7SDag-Erling Smørgrav filename, linenum); 820cce7d346SDag-Erling Smørgrav 821cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 822cce7d346SDag-Erling Smørgrav opcode == oRemoteForward) { 823aa49c926SDag-Erling Smørgrav arg2 = strdelim(&s); 824aa49c926SDag-Erling Smørgrav if (arg2 == NULL || *arg2 == '\0') 825aa49c926SDag-Erling Smørgrav fatal("%.200s line %d: Missing target argument.", 826511b41d2SMark Murray filename, linenum); 827aa49c926SDag-Erling Smørgrav 828aa49c926SDag-Erling Smørgrav /* construct a string for parse_forward */ 829aa49c926SDag-Erling Smørgrav snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 830cce7d346SDag-Erling Smørgrav } else if (opcode == oDynamicForward) { 831cce7d346SDag-Erling Smørgrav strlcpy(fwdarg, arg, sizeof(fwdarg)); 832cce7d346SDag-Erling Smørgrav } 833aa49c926SDag-Erling Smørgrav 834cce7d346SDag-Erling Smørgrav if (parse_forward(&fwd, fwdarg, 835cce7d346SDag-Erling Smørgrav opcode == oDynamicForward ? 1 : 0, 836cce7d346SDag-Erling Smørgrav opcode == oRemoteForward ? 1 : 0) == 0) 837af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 838511b41d2SMark Murray filename, linenum); 839aa49c926SDag-Erling Smørgrav 840af12a3e7SDag-Erling Smørgrav if (*activep) { 841cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 842cce7d346SDag-Erling Smørgrav opcode == oDynamicForward) 843aa49c926SDag-Erling Smørgrav add_local_forward(options, &fwd); 844af12a3e7SDag-Erling Smørgrav else if (opcode == oRemoteForward) 845aa49c926SDag-Erling Smørgrav add_remote_forward(options, &fwd); 846af12a3e7SDag-Erling Smørgrav } 847511b41d2SMark Murray break; 848511b41d2SMark Murray 849af12a3e7SDag-Erling Smørgrav case oClearAllForwardings: 850af12a3e7SDag-Erling Smørgrav intptr = &options->clear_forwardings; 851af12a3e7SDag-Erling Smørgrav goto parse_flag; 852af12a3e7SDag-Erling Smørgrav 853511b41d2SMark Murray case oHost: 854511b41d2SMark Murray *activep = 0; 855e146993eSDag-Erling Smørgrav arg2 = NULL; 856e146993eSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 857e146993eSDag-Erling Smørgrav negated = *arg == '!'; 858e146993eSDag-Erling Smørgrav if (negated) 859e146993eSDag-Erling Smørgrav arg++; 860c2d3a559SKris Kennaway if (match_pattern(host, arg)) { 861e146993eSDag-Erling Smørgrav if (negated) { 862e146993eSDag-Erling Smørgrav debug("%.200s line %d: Skipping Host " 863e146993eSDag-Erling Smørgrav "block because of negated match " 864e146993eSDag-Erling Smørgrav "for %.100s", filename, linenum, 865e146993eSDag-Erling Smørgrav arg); 866e146993eSDag-Erling Smørgrav *activep = 0; 867511b41d2SMark Murray break; 868511b41d2SMark Murray } 869e146993eSDag-Erling Smørgrav if (!*activep) 870e146993eSDag-Erling Smørgrav arg2 = arg; /* logged below */ 871e146993eSDag-Erling Smørgrav *activep = 1; 872e146993eSDag-Erling Smørgrav } 873e146993eSDag-Erling Smørgrav } 874e146993eSDag-Erling Smørgrav if (*activep) 875e146993eSDag-Erling Smørgrav debug("%.200s line %d: Applying options for %.100s", 876e146993eSDag-Erling Smørgrav filename, linenum, arg2); 877c2d3a559SKris Kennaway /* Avoid garbage check below, as strdelim is done. */ 878511b41d2SMark Murray return 0; 879511b41d2SMark Murray 880511b41d2SMark Murray case oEscapeChar: 881511b41d2SMark Murray intptr = &options->escape_char; 882c2d3a559SKris Kennaway arg = strdelim(&s); 883c2d3a559SKris Kennaway if (!arg || *arg == '\0') 884511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 885c2d3a559SKris Kennaway if (arg[0] == '^' && arg[2] == 0 && 886ca3176e7SBrian Feldman (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 887ca3176e7SBrian Feldman value = (u_char) arg[1] & 31; 888c2d3a559SKris Kennaway else if (strlen(arg) == 1) 889ca3176e7SBrian Feldman value = (u_char) arg[0]; 890c2d3a559SKris Kennaway else if (strcmp(arg, "none") == 0) 891af12a3e7SDag-Erling Smørgrav value = SSH_ESCAPECHAR_NONE; 892511b41d2SMark Murray else { 893511b41d2SMark Murray fatal("%.200s line %d: Bad escape character.", 894511b41d2SMark Murray filename, linenum); 895511b41d2SMark Murray /* NOTREACHED */ 896511b41d2SMark Murray value = 0; /* Avoid compiler warning. */ 897511b41d2SMark Murray } 898511b41d2SMark Murray if (*activep && *intptr == -1) 899511b41d2SMark Murray *intptr = value; 900511b41d2SMark Murray break; 901511b41d2SMark Murray 902cf2b5f3bSDag-Erling Smørgrav case oAddressFamily: 903cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 904d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 905d4ecd108SDag-Erling Smørgrav fatal("%s line %d: missing address family.", 906d4ecd108SDag-Erling Smørgrav filename, linenum); 907cf2b5f3bSDag-Erling Smørgrav intptr = &options->address_family; 908cf2b5f3bSDag-Erling Smørgrav if (strcasecmp(arg, "inet") == 0) 909cf2b5f3bSDag-Erling Smørgrav value = AF_INET; 910cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "inet6") == 0) 911cf2b5f3bSDag-Erling Smørgrav value = AF_INET6; 912cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "any") == 0) 913cf2b5f3bSDag-Erling Smørgrav value = AF_UNSPEC; 914cf2b5f3bSDag-Erling Smørgrav else 915cf2b5f3bSDag-Erling Smørgrav fatal("Unsupported AddressFamily \"%s\"", arg); 916cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 917cf2b5f3bSDag-Erling Smørgrav *intptr = value; 918cf2b5f3bSDag-Erling Smørgrav break; 919cf2b5f3bSDag-Erling Smørgrav 920e73e9afaSDag-Erling Smørgrav case oEnableSSHKeysign: 921e73e9afaSDag-Erling Smørgrav intptr = &options->enable_ssh_keysign; 922e73e9afaSDag-Erling Smørgrav goto parse_flag; 923e73e9afaSDag-Erling Smørgrav 9245962c0e9SDag-Erling Smørgrav case oIdentitiesOnly: 9255962c0e9SDag-Erling Smørgrav intptr = &options->identities_only; 9265962c0e9SDag-Erling Smørgrav goto parse_flag; 9275962c0e9SDag-Erling Smørgrav 9281ec0d754SDag-Erling Smørgrav case oServerAliveInterval: 9291ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_interval; 9301ec0d754SDag-Erling Smørgrav goto parse_time; 9311ec0d754SDag-Erling Smørgrav 9321ec0d754SDag-Erling Smørgrav case oServerAliveCountMax: 9331ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_count_max; 9341ec0d754SDag-Erling Smørgrav goto parse_int; 9351ec0d754SDag-Erling Smørgrav 93621e764dfSDag-Erling Smørgrav case oSendEnv: 93721e764dfSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 93821e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 93921e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 94021e764dfSDag-Erling Smørgrav filename, linenum); 941aa49c926SDag-Erling Smørgrav if (!*activep) 942aa49c926SDag-Erling Smørgrav continue; 94321e764dfSDag-Erling Smørgrav if (options->num_send_env >= MAX_SEND_ENV) 94421e764dfSDag-Erling Smørgrav fatal("%s line %d: too many send env.", 94521e764dfSDag-Erling Smørgrav filename, linenum); 94621e764dfSDag-Erling Smørgrav options->send_env[options->num_send_env++] = 94721e764dfSDag-Erling Smørgrav xstrdup(arg); 94821e764dfSDag-Erling Smørgrav } 94921e764dfSDag-Erling Smørgrav break; 95021e764dfSDag-Erling Smørgrav 95121e764dfSDag-Erling Smørgrav case oControlPath: 95221e764dfSDag-Erling Smørgrav charptr = &options->control_path; 95321e764dfSDag-Erling Smørgrav goto parse_string; 95421e764dfSDag-Erling Smørgrav 95521e764dfSDag-Erling Smørgrav case oControlMaster: 95621e764dfSDag-Erling Smørgrav intptr = &options->control_master; 957d4ecd108SDag-Erling Smørgrav arg = strdelim(&s); 958d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 959d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlMaster argument.", 960d4ecd108SDag-Erling Smørgrav filename, linenum); 961d4ecd108SDag-Erling Smørgrav value = 0; /* To avoid compiler warning... */ 962d4ecd108SDag-Erling Smørgrav if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 963d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_YES; 964d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 965d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_NO; 966d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "auto") == 0) 967d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO; 968d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "ask") == 0) 969d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_ASK; 970d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "autoask") == 0) 971d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO_ASK; 972d4ecd108SDag-Erling Smørgrav else 973d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlMaster argument.", 974d4ecd108SDag-Erling Smørgrav filename, linenum); 975d4ecd108SDag-Erling Smørgrav if (*activep && *intptr == -1) 976d4ecd108SDag-Erling Smørgrav *intptr = value; 977d4ecd108SDag-Erling Smørgrav break; 97821e764dfSDag-Erling Smørgrav 979e2f6069cSDag-Erling Smørgrav case oControlPersist: 980e2f6069cSDag-Erling Smørgrav /* no/false/yes/true, or a time spec */ 981e2f6069cSDag-Erling Smørgrav intptr = &options->control_persist; 982e2f6069cSDag-Erling Smørgrav arg = strdelim(&s); 983e2f6069cSDag-Erling Smørgrav if (!arg || *arg == '\0') 984e2f6069cSDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlPersist" 985e2f6069cSDag-Erling Smørgrav " argument.", filename, linenum); 986e2f6069cSDag-Erling Smørgrav value = 0; 987e2f6069cSDag-Erling Smørgrav value2 = 0; /* timeout */ 988e2f6069cSDag-Erling Smørgrav if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 989e2f6069cSDag-Erling Smørgrav value = 0; 990e2f6069cSDag-Erling Smørgrav else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 991e2f6069cSDag-Erling Smørgrav value = 1; 992e2f6069cSDag-Erling Smørgrav else if ((value2 = convtime(arg)) >= 0) 993e2f6069cSDag-Erling Smørgrav value = 1; 994e2f6069cSDag-Erling Smørgrav else 995e2f6069cSDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlPersist argument.", 996e2f6069cSDag-Erling Smørgrav filename, linenum); 997e2f6069cSDag-Erling Smørgrav if (*activep && *intptr == -1) { 998e2f6069cSDag-Erling Smørgrav *intptr = value; 999e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = value2; 1000e2f6069cSDag-Erling Smørgrav } 1001e2f6069cSDag-Erling Smørgrav break; 1002e2f6069cSDag-Erling Smørgrav 1003aa49c926SDag-Erling Smørgrav case oHashKnownHosts: 1004aa49c926SDag-Erling Smørgrav intptr = &options->hash_known_hosts; 1005aa49c926SDag-Erling Smørgrav goto parse_flag; 1006aa49c926SDag-Erling Smørgrav 1007b74df5b2SDag-Erling Smørgrav case oTunnel: 1008b74df5b2SDag-Erling Smørgrav intptr = &options->tun_open; 1009b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 1010b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1011b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 1012b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 1013b74df5b2SDag-Erling Smørgrav value = 0; /* silence compiler */ 1014b74df5b2SDag-Erling Smørgrav if (strcasecmp(arg, "ethernet") == 0) 1015b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_ETHERNET; 1016b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "point-to-point") == 0) 1017b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_POINTOPOINT; 1018b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "yes") == 0) 1019b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_DEFAULT; 1020b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 1021b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_NO; 1022b74df5b2SDag-Erling Smørgrav else 1023b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 1024b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 1025b74df5b2SDag-Erling Smørgrav if (*activep) 1026b74df5b2SDag-Erling Smørgrav *intptr = value; 1027b74df5b2SDag-Erling Smørgrav break; 1028b74df5b2SDag-Erling Smørgrav 1029b74df5b2SDag-Erling Smørgrav case oTunnelDevice: 1030b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 1031b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 1032b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 1033b74df5b2SDag-Erling Smørgrav value = a2tun(arg, &value2); 1034b74df5b2SDag-Erling Smørgrav if (value == SSH_TUNID_ERR) 1035b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Bad tun device.", filename, linenum); 1036b74df5b2SDag-Erling Smørgrav if (*activep) { 1037b74df5b2SDag-Erling Smørgrav options->tun_local = value; 1038b74df5b2SDag-Erling Smørgrav options->tun_remote = value2; 1039b74df5b2SDag-Erling Smørgrav } 1040b74df5b2SDag-Erling Smørgrav break; 1041b74df5b2SDag-Erling Smørgrav 1042b74df5b2SDag-Erling Smørgrav case oLocalCommand: 1043b74df5b2SDag-Erling Smørgrav charptr = &options->local_command; 1044b74df5b2SDag-Erling Smørgrav goto parse_command; 1045b74df5b2SDag-Erling Smørgrav 1046b74df5b2SDag-Erling Smørgrav case oPermitLocalCommand: 1047b74df5b2SDag-Erling Smørgrav intptr = &options->permit_local_command; 1048b74df5b2SDag-Erling Smørgrav goto parse_flag; 1049b74df5b2SDag-Erling Smørgrav 1050d4af9e69SDag-Erling Smørgrav case oVisualHostKey: 1051d4af9e69SDag-Erling Smørgrav intptr = &options->visual_host_key; 1052d4af9e69SDag-Erling Smørgrav goto parse_flag; 1053d4af9e69SDag-Erling Smørgrav 10544a421b63SDag-Erling Smørgrav case oIPQoS: 10554a421b63SDag-Erling Smørgrav arg = strdelim(&s); 10564a421b63SDag-Erling Smørgrav if ((value = parse_ipqos(arg)) == -1) 10574a421b63SDag-Erling Smørgrav fatal("%s line %d: Bad IPQoS value: %s", 10584a421b63SDag-Erling Smørgrav filename, linenum, arg); 10594a421b63SDag-Erling Smørgrav arg = strdelim(&s); 10604a421b63SDag-Erling Smørgrav if (arg == NULL) 10614a421b63SDag-Erling Smørgrav value2 = value; 10624a421b63SDag-Erling Smørgrav else if ((value2 = 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 if (*activep) { 10664a421b63SDag-Erling Smørgrav options->ip_qos_interactive = value; 10674a421b63SDag-Erling Smørgrav options->ip_qos_bulk = value2; 10684a421b63SDag-Erling Smørgrav } 10694a421b63SDag-Erling Smørgrav break; 10704a421b63SDag-Erling Smørgrav 10717aee6ffeSDag-Erling Smørgrav case oUseRoaming: 10727aee6ffeSDag-Erling Smørgrav intptr = &options->use_roaming; 10737aee6ffeSDag-Erling Smørgrav goto parse_flag; 10747aee6ffeSDag-Erling Smørgrav 1075e146993eSDag-Erling Smørgrav case oRequestTTY: 1076975616f0SDag-Erling Smørgrav arg = strdelim(&s); 1077e146993eSDag-Erling Smørgrav if (!arg || *arg == '\0') 1078e146993eSDag-Erling Smørgrav fatal("%s line %d: missing argument.", 1079e146993eSDag-Erling Smørgrav filename, linenum); 1080e146993eSDag-Erling Smørgrav intptr = &options->request_tty; 1081e146993eSDag-Erling Smørgrav if (strcasecmp(arg, "yes") == 0) 1082e146993eSDag-Erling Smørgrav value = REQUEST_TTY_YES; 1083e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 1084e146993eSDag-Erling Smørgrav value = REQUEST_TTY_NO; 1085e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "force") == 0) 1086e146993eSDag-Erling Smørgrav value = REQUEST_TTY_FORCE; 1087e146993eSDag-Erling Smørgrav else if (strcasecmp(arg, "auto") == 0) 1088e146993eSDag-Erling Smørgrav value = REQUEST_TTY_AUTO; 1089e146993eSDag-Erling Smørgrav else 1090e146993eSDag-Erling Smørgrav fatal("Unsupported RequestTTY \"%s\"", arg); 1091e146993eSDag-Erling Smørgrav if (*activep && *intptr == -1) 1092e146993eSDag-Erling Smørgrav *intptr = value; 1093975616f0SDag-Erling Smørgrav break; 1094975616f0SDag-Erling Smørgrav 109589986192SBrooks Davis case oHPNDisabled: 109689986192SBrooks Davis intptr = &options->hpn_disabled; 109789986192SBrooks Davis goto parse_flag; 109889986192SBrooks Davis 109989986192SBrooks Davis case oHPNBufferSize: 110089986192SBrooks Davis intptr = &options->hpn_buffer_size; 110189986192SBrooks Davis goto parse_int; 110289986192SBrooks Davis 110389986192SBrooks Davis case oTcpRcvBufPoll: 110489986192SBrooks Davis intptr = &options->tcp_rcv_buf_poll; 110589986192SBrooks Davis goto parse_flag; 110689986192SBrooks Davis 110789986192SBrooks Davis case oTcpRcvBuf: 110889986192SBrooks Davis intptr = &options->tcp_rcv_buf; 110989986192SBrooks Davis goto parse_int; 111089986192SBrooks Davis 111189986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 111289986192SBrooks Davis case oNoneEnabled: 111389986192SBrooks Davis intptr = &options->none_enabled; 111489986192SBrooks Davis goto parse_flag; 111589986192SBrooks Davis 111689986192SBrooks Davis /* 111789986192SBrooks Davis * We check to see if the command comes from the command line or not. 111889986192SBrooks Davis * If it does then enable it otherwise fail. NONE must never be a 111989986192SBrooks Davis * default configuration. 112089986192SBrooks Davis */ 112189986192SBrooks Davis case oNoneSwitch: 112289986192SBrooks Davis if (strcmp(filename,"command-line") == 0) { 112389986192SBrooks Davis intptr = &options->none_switch; 112489986192SBrooks Davis goto parse_flag; 112589986192SBrooks Davis } else { 112689986192SBrooks Davis debug("NoneSwitch directive found in %.200s.", 112789986192SBrooks Davis filename); 112889986192SBrooks Davis error("NoneSwitch is found in %.200s.\n" 112989986192SBrooks Davis "You may only use this configuration option " 113089986192SBrooks Davis "from the command line", filename); 113189986192SBrooks Davis error("Continuing..."); 113289986192SBrooks Davis return 0; 113389986192SBrooks Davis } 113489986192SBrooks Davis #endif 113589986192SBrooks Davis 1136e146993eSDag-Erling Smørgrav case oVersionAddendum: 1137462c32cbSDag-Erling Smørgrav if (s == NULL) 1138462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, 1139462c32cbSDag-Erling Smørgrav linenum); 1140462c32cbSDag-Erling Smørgrav len = strspn(s, WHITESPACE); 1141462c32cbSDag-Erling Smørgrav if (*activep && options->version_addendum == NULL) { 1142462c32cbSDag-Erling Smørgrav if (strcasecmp(s + len, "none") == 0) 1143462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(""); 1144462c32cbSDag-Erling Smørgrav else if (strchr(s + len, '\r') != NULL) 1145462c32cbSDag-Erling Smørgrav fatal("%.200s line %d: Invalid argument", 1146462c32cbSDag-Erling Smørgrav filename, linenum); 1147462c32cbSDag-Erling Smørgrav else 1148462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(s + len); 1149462c32cbSDag-Erling Smørgrav } 1150462c32cbSDag-Erling Smørgrav return 0; 1151e146993eSDag-Erling Smørgrav 115280628bacSDag-Erling Smørgrav case oDeprecated: 115380628bacSDag-Erling Smørgrav debug("%s line %d: Deprecated option \"%s\"", 115480628bacSDag-Erling Smørgrav filename, linenum, keyword); 115580628bacSDag-Erling Smørgrav return 0; 115680628bacSDag-Erling Smørgrav 1157cf2b5f3bSDag-Erling Smørgrav case oUnsupported: 1158cf2b5f3bSDag-Erling Smørgrav error("%s line %d: Unsupported option \"%s\"", 1159cf2b5f3bSDag-Erling Smørgrav filename, linenum, keyword); 1160cf2b5f3bSDag-Erling Smørgrav return 0; 1161cf2b5f3bSDag-Erling Smørgrav 1162511b41d2SMark Murray default: 1163511b41d2SMark Murray fatal("process_config_line: Unimplemented opcode %d", opcode); 1164511b41d2SMark Murray } 1165511b41d2SMark Murray 1166511b41d2SMark Murray /* Check that there is no garbage at end of line. */ 1167ca3176e7SBrian Feldman if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 1168c2d3a559SKris Kennaway fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 1169c2d3a559SKris Kennaway filename, linenum, arg); 1170c2d3a559SKris Kennaway } 1171511b41d2SMark Murray return 0; 1172511b41d2SMark Murray } 1173511b41d2SMark Murray 1174511b41d2SMark Murray 1175511b41d2SMark Murray /* 1176511b41d2SMark Murray * Reads the config file and modifies the options accordingly. Options 1177511b41d2SMark Murray * should already be initialized before this call. This never returns if 1178af12a3e7SDag-Erling Smørgrav * there is an error. If the file does not exist, this returns 0. 1179511b41d2SMark Murray */ 1180511b41d2SMark Murray 1181af12a3e7SDag-Erling Smørgrav int 118221e764dfSDag-Erling Smørgrav read_config_file(const char *filename, const char *host, Options *options, 118321e764dfSDag-Erling Smørgrav int checkperm) 1184511b41d2SMark Murray { 1185511b41d2SMark Murray FILE *f; 1186511b41d2SMark Murray char line[1024]; 1187511b41d2SMark Murray int active, linenum; 1188511b41d2SMark Murray int bad_options = 0; 1189511b41d2SMark Murray 119021e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) 1191af12a3e7SDag-Erling Smørgrav return 0; 1192511b41d2SMark Murray 119321e764dfSDag-Erling Smørgrav if (checkperm) { 119421e764dfSDag-Erling Smørgrav struct stat sb; 119521e764dfSDag-Erling Smørgrav 119621e764dfSDag-Erling Smørgrav if (fstat(fileno(f), &sb) == -1) 119721e764dfSDag-Erling Smørgrav fatal("fstat %s: %s", filename, strerror(errno)); 119821e764dfSDag-Erling Smørgrav if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 119921e764dfSDag-Erling Smørgrav (sb.st_mode & 022) != 0)) 120021e764dfSDag-Erling Smørgrav fatal("Bad owner or permissions on %s", filename); 120121e764dfSDag-Erling Smørgrav } 120221e764dfSDag-Erling Smørgrav 1203511b41d2SMark Murray debug("Reading configuration data %.200s", filename); 1204511b41d2SMark Murray 1205511b41d2SMark Murray /* 1206511b41d2SMark Murray * Mark that we are now processing the options. This flag is turned 1207511b41d2SMark Murray * on/off by Host specifications. 1208511b41d2SMark Murray */ 1209511b41d2SMark Murray active = 1; 1210511b41d2SMark Murray linenum = 0; 1211511b41d2SMark Murray while (fgets(line, sizeof(line), f)) { 1212511b41d2SMark Murray /* Update line number counter. */ 1213511b41d2SMark Murray linenum++; 1214511b41d2SMark Murray if (process_config_line(options, host, line, filename, linenum, &active) != 0) 1215511b41d2SMark Murray bad_options++; 1216511b41d2SMark Murray } 1217511b41d2SMark Murray fclose(f); 1218511b41d2SMark Murray if (bad_options > 0) 1219ca3176e7SBrian Feldman fatal("%s: terminating, %d bad configuration options", 1220511b41d2SMark Murray filename, bad_options); 1221af12a3e7SDag-Erling Smørgrav return 1; 1222511b41d2SMark Murray } 1223511b41d2SMark Murray 1224511b41d2SMark Murray /* 1225511b41d2SMark Murray * Initializes options to special values that indicate that they have not yet 1226511b41d2SMark Murray * been set. Read_config_file will only set options with this value. Options 1227511b41d2SMark Murray * are processed in the following order: command line, user config file, 1228511b41d2SMark Murray * system config file. Last, fill_default_options is called. 1229511b41d2SMark Murray */ 1230511b41d2SMark Murray 1231511b41d2SMark Murray void 1232511b41d2SMark Murray initialize_options(Options * options) 1233511b41d2SMark Murray { 1234511b41d2SMark Murray memset(options, 'X', sizeof(*options)); 1235511b41d2SMark Murray options->forward_agent = -1; 1236511b41d2SMark Murray options->forward_x11 = -1; 12371ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = -1; 1238e2f6069cSDag-Erling Smørgrav options->forward_x11_timeout = -1; 1239333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = -1; 1240c2d3a559SKris Kennaway options->xauth_location = NULL; 1241511b41d2SMark Murray options->gateway_ports = -1; 1242511b41d2SMark Murray options->use_privileged_port = -1; 1243511b41d2SMark Murray options->rsa_authentication = -1; 1244ca3176e7SBrian Feldman options->pubkey_authentication = -1; 1245af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 1246cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = -1; 1247cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = -1; 1248511b41d2SMark Murray options->password_authentication = -1; 124909958426SBrian Feldman options->kbd_interactive_authentication = -1; 125009958426SBrian Feldman options->kbd_interactive_devices = NULL; 1251511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 1252ca3176e7SBrian Feldman options->hostbased_authentication = -1; 1253511b41d2SMark Murray options->batch_mode = -1; 1254511b41d2SMark Murray options->check_host_ip = -1; 1255511b41d2SMark Murray options->strict_host_key_checking = -1; 1256511b41d2SMark Murray options->compression = -1; 12571ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 1258511b41d2SMark Murray options->compression_level = -1; 1259511b41d2SMark Murray options->port = -1; 1260cf2b5f3bSDag-Erling Smørgrav options->address_family = -1; 1261511b41d2SMark Murray options->connection_attempts = -1; 1262cf2b5f3bSDag-Erling Smørgrav options->connection_timeout = -1; 1263511b41d2SMark Murray options->number_of_password_prompts = -1; 1264511b41d2SMark Murray options->cipher = -1; 1265e8aafc91SKris Kennaway options->ciphers = NULL; 1266ca3176e7SBrian Feldman options->macs = NULL; 12674a421b63SDag-Erling Smørgrav options->kex_algorithms = NULL; 1268ca3176e7SBrian Feldman options->hostkeyalgorithms = NULL; 1269e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 1270511b41d2SMark Murray options->num_identity_files = 0; 1271511b41d2SMark Murray options->hostname = NULL; 1272ca3176e7SBrian Feldman options->host_key_alias = NULL; 1273511b41d2SMark Murray options->proxy_command = NULL; 1274511b41d2SMark Murray options->user = NULL; 1275511b41d2SMark Murray options->escape_char = -1; 1276e146993eSDag-Erling Smørgrav options->num_system_hostfiles = 0; 1277e146993eSDag-Erling Smørgrav options->num_user_hostfiles = 0; 1278e2f6069cSDag-Erling Smørgrav options->local_forwards = NULL; 1279511b41d2SMark Murray options->num_local_forwards = 0; 1280e2f6069cSDag-Erling Smørgrav options->remote_forwards = NULL; 1281511b41d2SMark Murray options->num_remote_forwards = 0; 1282af12a3e7SDag-Erling Smørgrav options->clear_forwardings = -1; 1283af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 1284ca3176e7SBrian Feldman options->preferred_authentications = NULL; 1285af12a3e7SDag-Erling Smørgrav options->bind_address = NULL; 1286b15c8340SDag-Erling Smørgrav options->pkcs11_provider = NULL; 1287e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = - 1; 1288af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = - 1; 12895962c0e9SDag-Erling Smørgrav options->identities_only = - 1; 1290cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = - 1; 1291cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = -1; 12921ec0d754SDag-Erling Smørgrav options->server_alive_interval = -1; 12931ec0d754SDag-Erling Smørgrav options->server_alive_count_max = -1; 129421e764dfSDag-Erling Smørgrav options->num_send_env = 0; 129521e764dfSDag-Erling Smørgrav options->control_path = NULL; 129621e764dfSDag-Erling Smørgrav options->control_master = -1; 1297e2f6069cSDag-Erling Smørgrav options->control_persist = -1; 1298e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = 0; 1299aa49c926SDag-Erling Smørgrav options->hash_known_hosts = -1; 1300b74df5b2SDag-Erling Smørgrav options->tun_open = -1; 1301b74df5b2SDag-Erling Smørgrav options->tun_local = -1; 1302b74df5b2SDag-Erling Smørgrav options->tun_remote = -1; 1303b74df5b2SDag-Erling Smørgrav options->local_command = NULL; 1304b74df5b2SDag-Erling Smørgrav options->permit_local_command = -1; 13057aee6ffeSDag-Erling Smørgrav options->use_roaming = -1; 1306d4af9e69SDag-Erling Smørgrav options->visual_host_key = -1; 1307cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = -1; 13084a421b63SDag-Erling Smørgrav options->ip_qos_interactive = -1; 13094a421b63SDag-Erling Smørgrav options->ip_qos_bulk = -1; 1310e146993eSDag-Erling Smørgrav options->request_tty = -1; 1311462c32cbSDag-Erling Smørgrav options->version_addendum = NULL; 131289986192SBrooks Davis options->hpn_disabled = -1; 131389986192SBrooks Davis options->hpn_buffer_size = -1; 131489986192SBrooks Davis options->tcp_rcv_buf_poll = -1; 131589986192SBrooks Davis options->tcp_rcv_buf = -1; 131689986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 131789986192SBrooks Davis options->none_enabled = -1; 131889986192SBrooks Davis options->none_switch = -1; 131989986192SBrooks Davis #endif 1320511b41d2SMark Murray } 1321511b41d2SMark Murray 1322511b41d2SMark Murray /* 1323511b41d2SMark Murray * Called after processing other sources of option data, this fills those 1324511b41d2SMark Murray * options for which no value has been specified with their default values. 1325511b41d2SMark Murray */ 1326511b41d2SMark Murray 1327511b41d2SMark Murray void 1328511b41d2SMark Murray fill_default_options(Options * options) 1329511b41d2SMark Murray { 1330ca3176e7SBrian Feldman int len; 1331ca3176e7SBrian Feldman 1332511b41d2SMark Murray if (options->forward_agent == -1) 1333db1cb46cSKris Kennaway options->forward_agent = 0; 1334511b41d2SMark Murray if (options->forward_x11 == -1) 13355dc73ebeSBrian Feldman options->forward_x11 = 0; 13361ec0d754SDag-Erling Smørgrav if (options->forward_x11_trusted == -1) 13371ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = 0; 1338e2f6069cSDag-Erling Smørgrav if (options->forward_x11_timeout == -1) 1339e2f6069cSDag-Erling Smørgrav options->forward_x11_timeout = 1200; 1340333ee039SDag-Erling Smørgrav if (options->exit_on_forward_failure == -1) 1341333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = 0; 1342c2d3a559SKris Kennaway if (options->xauth_location == NULL) 1343af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 1344511b41d2SMark Murray if (options->gateway_ports == -1) 1345511b41d2SMark Murray options->gateway_ports = 0; 1346511b41d2SMark Murray if (options->use_privileged_port == -1) 1347ca3176e7SBrian Feldman options->use_privileged_port = 0; 1348511b41d2SMark Murray if (options->rsa_authentication == -1) 1349511b41d2SMark Murray options->rsa_authentication = 1; 1350ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 1351ca3176e7SBrian Feldman options->pubkey_authentication = 1; 1352af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 1353af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = 1; 1354cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 13551ec0d754SDag-Erling Smørgrav options->gss_authentication = 0; 1356cf2b5f3bSDag-Erling Smørgrav if (options->gss_deleg_creds == -1) 1357cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = 0; 1358511b41d2SMark Murray if (options->password_authentication == -1) 1359511b41d2SMark Murray options->password_authentication = 1; 136009958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 1361ca3176e7SBrian Feldman options->kbd_interactive_authentication = 1; 1362511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 136380628bacSDag-Erling Smørgrav options->rhosts_rsa_authentication = 0; 1364ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 1365ca3176e7SBrian Feldman options->hostbased_authentication = 0; 1366511b41d2SMark Murray if (options->batch_mode == -1) 1367511b41d2SMark Murray options->batch_mode = 0; 1368511b41d2SMark Murray if (options->check_host_ip == -1) 1369975616f0SDag-Erling Smørgrav options->check_host_ip = 0; 1370511b41d2SMark Murray if (options->strict_host_key_checking == -1) 1371511b41d2SMark Murray options->strict_host_key_checking = 2; /* 2 is default */ 1372511b41d2SMark Murray if (options->compression == -1) 1373511b41d2SMark Murray options->compression = 0; 13741ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 13751ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 1376511b41d2SMark Murray if (options->compression_level == -1) 1377511b41d2SMark Murray options->compression_level = 6; 1378511b41d2SMark Murray if (options->port == -1) 1379511b41d2SMark Murray options->port = 0; /* Filled in ssh_connect. */ 1380cf2b5f3bSDag-Erling Smørgrav if (options->address_family == -1) 1381cf2b5f3bSDag-Erling Smørgrav options->address_family = AF_UNSPEC; 1382511b41d2SMark Murray if (options->connection_attempts == -1) 1383af12a3e7SDag-Erling Smørgrav options->connection_attempts = 1; 1384511b41d2SMark Murray if (options->number_of_password_prompts == -1) 1385511b41d2SMark Murray options->number_of_password_prompts = 3; 1386511b41d2SMark Murray /* Selected in ssh_login(). */ 1387511b41d2SMark Murray if (options->cipher == -1) 1388511b41d2SMark Murray options->cipher = SSH_CIPHER_NOT_SET; 1389e8aafc91SKris Kennaway /* options->ciphers, default set in myproposals.h */ 1390ca3176e7SBrian Feldman /* options->macs, default set in myproposals.h */ 13914a421b63SDag-Erling Smørgrav /* options->kex_algorithms, default set in myproposals.h */ 1392ca3176e7SBrian Feldman /* options->hostkeyalgorithms, default set in myproposals.h */ 1393e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 1394b15c8340SDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 1395511b41d2SMark Murray if (options->num_identity_files == 0) { 1396ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) { 1397ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 1398ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1399ca3176e7SBrian Feldman xmalloc(len); 1400ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1401ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 1402511b41d2SMark Murray } 1403ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_2) { 1404ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 1405ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1406ca3176e7SBrian Feldman xmalloc(len); 1407ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1408ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 1409ca3176e7SBrian Feldman 1410ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 1411ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1412ca3176e7SBrian Feldman xmalloc(len); 1413ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1414ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 14154a421b63SDag-Erling Smørgrav #ifdef OPENSSL_HAS_ECC 14164a421b63SDag-Erling Smørgrav len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1; 14174a421b63SDag-Erling Smørgrav options->identity_files[options->num_identity_files] = 14184a421b63SDag-Erling Smørgrav xmalloc(len); 14194a421b63SDag-Erling Smørgrav snprintf(options->identity_files[options->num_identity_files++], 14204a421b63SDag-Erling Smørgrav len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA); 14214a421b63SDag-Erling Smørgrav #endif 1422ca3176e7SBrian Feldman } 1423e8aafc91SKris Kennaway } 1424511b41d2SMark Murray if (options->escape_char == -1) 1425511b41d2SMark Murray options->escape_char = '~'; 1426e146993eSDag-Erling Smørgrav if (options->num_system_hostfiles == 0) { 1427e146993eSDag-Erling Smørgrav options->system_hostfiles[options->num_system_hostfiles++] = 1428e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_SYSTEM_HOSTFILE); 1429e146993eSDag-Erling Smørgrav options->system_hostfiles[options->num_system_hostfiles++] = 1430e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2); 1431e146993eSDag-Erling Smørgrav } 1432e146993eSDag-Erling Smørgrav if (options->num_user_hostfiles == 0) { 1433e146993eSDag-Erling Smørgrav options->user_hostfiles[options->num_user_hostfiles++] = 1434e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_HOSTFILE); 1435e146993eSDag-Erling Smørgrav options->user_hostfiles[options->num_user_hostfiles++] = 1436e146993eSDag-Erling Smørgrav xstrdup(_PATH_SSH_USER_HOSTFILE2); 1437e146993eSDag-Erling Smørgrav } 1438af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1439511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 1440af12a3e7SDag-Erling Smørgrav if (options->clear_forwardings == 1) 1441af12a3e7SDag-Erling Smørgrav clear_forwardings(options); 1442af12a3e7SDag-Erling Smørgrav if (options->no_host_authentication_for_localhost == - 1) 1443af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = 0; 14445962c0e9SDag-Erling Smørgrav if (options->identities_only == -1) 14455962c0e9SDag-Erling Smørgrav options->identities_only = 0; 1446e73e9afaSDag-Erling Smørgrav if (options->enable_ssh_keysign == -1) 1447e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = 0; 1448cf2b5f3bSDag-Erling Smørgrav if (options->rekey_limit == -1) 1449cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = 0; 1450cf2b5f3bSDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 1451cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = 0; 14521ec0d754SDag-Erling Smørgrav if (options->server_alive_interval == -1) 14531ec0d754SDag-Erling Smørgrav options->server_alive_interval = 0; 14541ec0d754SDag-Erling Smørgrav if (options->server_alive_count_max == -1) 14551ec0d754SDag-Erling Smørgrav options->server_alive_count_max = 3; 145621e764dfSDag-Erling Smørgrav if (options->control_master == -1) 145721e764dfSDag-Erling Smørgrav options->control_master = 0; 1458e2f6069cSDag-Erling Smørgrav if (options->control_persist == -1) { 1459e2f6069cSDag-Erling Smørgrav options->control_persist = 0; 1460e2f6069cSDag-Erling Smørgrav options->control_persist_timeout = 0; 1461e2f6069cSDag-Erling Smørgrav } 1462aa49c926SDag-Erling Smørgrav if (options->hash_known_hosts == -1) 1463aa49c926SDag-Erling Smørgrav options->hash_known_hosts = 0; 1464b74df5b2SDag-Erling Smørgrav if (options->tun_open == -1) 1465b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 1466b74df5b2SDag-Erling Smørgrav if (options->tun_local == -1) 1467b74df5b2SDag-Erling Smørgrav options->tun_local = SSH_TUNID_ANY; 1468b74df5b2SDag-Erling Smørgrav if (options->tun_remote == -1) 1469b74df5b2SDag-Erling Smørgrav options->tun_remote = SSH_TUNID_ANY; 1470b74df5b2SDag-Erling Smørgrav if (options->permit_local_command == -1) 1471b74df5b2SDag-Erling Smørgrav options->permit_local_command = 0; 14727aee6ffeSDag-Erling Smørgrav if (options->use_roaming == -1) 14737aee6ffeSDag-Erling Smørgrav options->use_roaming = 1; 1474d4af9e69SDag-Erling Smørgrav if (options->visual_host_key == -1) 1475d4af9e69SDag-Erling Smørgrav options->visual_host_key = 0; 1476cce7d346SDag-Erling Smørgrav if (options->zero_knowledge_password_authentication == -1) 1477cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = 0; 14784a421b63SDag-Erling Smørgrav if (options->ip_qos_interactive == -1) 14794a421b63SDag-Erling Smørgrav options->ip_qos_interactive = IPTOS_LOWDELAY; 14804a421b63SDag-Erling Smørgrav if (options->ip_qos_bulk == -1) 14814a421b63SDag-Erling Smørgrav options->ip_qos_bulk = IPTOS_THROUGHPUT; 1482e146993eSDag-Erling Smørgrav if (options->request_tty == -1) 1483e146993eSDag-Erling Smørgrav options->request_tty = REQUEST_TTY_AUTO; 1484b74df5b2SDag-Erling Smørgrav /* options->local_command should not be set by default */ 1485511b41d2SMark Murray /* options->proxy_command should not be set by default */ 1486511b41d2SMark Murray /* options->user will be set in the main program if appropriate */ 1487511b41d2SMark Murray /* options->hostname will be set in the main program if appropriate */ 1488ca3176e7SBrian Feldman /* options->host_key_alias should not be set by default */ 1489ca3176e7SBrian Feldman /* options->preferred_authentications will be set in ssh */ 1490462c32cbSDag-Erling Smørgrav if (options->version_addendum == NULL) 1491462c32cbSDag-Erling Smørgrav options->version_addendum = xstrdup(SSH_VERSION_FREEBSD); 149289986192SBrooks Davis if (options->hpn_disabled == -1) 149389986192SBrooks Davis options->hpn_disabled = 0; 149489986192SBrooks Davis if (options->hpn_buffer_size > -1) 149589986192SBrooks Davis { 149689986192SBrooks Davis u_int maxlen; 149789986192SBrooks Davis 149889986192SBrooks Davis /* If a user tries to set the size to 0 set it to 1KB. */ 149989986192SBrooks Davis if (options->hpn_buffer_size == 0) 150089986192SBrooks Davis options->hpn_buffer_size = 1024; 150189986192SBrooks Davis /* Limit the buffer to BUFFER_MAX_LEN. */ 150289986192SBrooks Davis maxlen = buffer_get_max_len(); 150389986192SBrooks Davis if (options->hpn_buffer_size > (maxlen / 1024)) { 150489986192SBrooks Davis debug("User requested buffer larger than %ub: %ub. " 150589986192SBrooks Davis "Request reverted to %ub", maxlen, 150689986192SBrooks Davis options->hpn_buffer_size * 1024, maxlen); 150789986192SBrooks Davis options->hpn_buffer_size = maxlen; 150889986192SBrooks Davis } 150989986192SBrooks Davis debug("hpn_buffer_size set to %d", options->hpn_buffer_size); 151089986192SBrooks Davis } 151189986192SBrooks Davis if (options->tcp_rcv_buf == 0) 151289986192SBrooks Davis options->tcp_rcv_buf = 1; 151389986192SBrooks Davis if (options->tcp_rcv_buf > -1) 151489986192SBrooks Davis options->tcp_rcv_buf *= 1024; 151589986192SBrooks Davis if (options->tcp_rcv_buf_poll == -1) 151689986192SBrooks Davis options->tcp_rcv_buf_poll = 1; 151789986192SBrooks Davis #ifdef NONE_CIPHER_ENABLED 151889986192SBrooks Davis /* options->none_enabled must not be set by default */ 151989986192SBrooks Davis if (options->none_switch == -1) 152089986192SBrooks Davis options->none_switch = 0; 152189986192SBrooks Davis #endif 1522511b41d2SMark Murray } 1523aa49c926SDag-Erling Smørgrav 1524aa49c926SDag-Erling Smørgrav /* 1525aa49c926SDag-Erling Smørgrav * parse_forward 1526aa49c926SDag-Erling Smørgrav * parses a string containing a port forwarding specification of the form: 1527cce7d346SDag-Erling Smørgrav * dynamicfwd == 0 1528aa49c926SDag-Erling Smørgrav * [listenhost:]listenport:connecthost:connectport 1529cce7d346SDag-Erling Smørgrav * dynamicfwd == 1 1530cce7d346SDag-Erling Smørgrav * [listenhost:]listenport 1531aa49c926SDag-Erling Smørgrav * returns number of arguments parsed or zero on error 1532aa49c926SDag-Erling Smørgrav */ 1533aa49c926SDag-Erling Smørgrav int 1534cce7d346SDag-Erling Smørgrav parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1535aa49c926SDag-Erling Smørgrav { 1536aa49c926SDag-Erling Smørgrav int i; 1537aa49c926SDag-Erling Smørgrav char *p, *cp, *fwdarg[4]; 1538aa49c926SDag-Erling Smørgrav 1539aa49c926SDag-Erling Smørgrav memset(fwd, '\0', sizeof(*fwd)); 1540aa49c926SDag-Erling Smørgrav 1541aa49c926SDag-Erling Smørgrav cp = p = xstrdup(fwdspec); 1542aa49c926SDag-Erling Smørgrav 1543aa49c926SDag-Erling Smørgrav /* skip leading spaces */ 1544d4af9e69SDag-Erling Smørgrav while (isspace(*cp)) 1545aa49c926SDag-Erling Smørgrav cp++; 1546aa49c926SDag-Erling Smørgrav 1547aa49c926SDag-Erling Smørgrav for (i = 0; i < 4; ++i) 1548aa49c926SDag-Erling Smørgrav if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1549aa49c926SDag-Erling Smørgrav break; 1550aa49c926SDag-Erling Smørgrav 1551cce7d346SDag-Erling Smørgrav /* Check for trailing garbage */ 1552aa49c926SDag-Erling Smørgrav if (cp != NULL) 1553aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1554aa49c926SDag-Erling Smørgrav 1555aa49c926SDag-Erling Smørgrav switch (i) { 1556cce7d346SDag-Erling Smørgrav case 1: 1557cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1558cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1559cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1560cce7d346SDag-Erling Smørgrav break; 1561cce7d346SDag-Erling Smørgrav 1562cce7d346SDag-Erling Smørgrav case 2: 1563cce7d346SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1564cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1565cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1566cce7d346SDag-Erling Smørgrav break; 1567cce7d346SDag-Erling Smørgrav 1568aa49c926SDag-Erling Smørgrav case 3: 1569aa49c926SDag-Erling Smørgrav fwd->listen_host = NULL; 1570aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1571aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1572aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[2]); 1573aa49c926SDag-Erling Smørgrav break; 1574aa49c926SDag-Erling Smørgrav 1575aa49c926SDag-Erling Smørgrav case 4: 1576aa49c926SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1577aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1578aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1579aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[3]); 1580aa49c926SDag-Erling Smørgrav break; 1581aa49c926SDag-Erling Smørgrav default: 1582aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1583aa49c926SDag-Erling Smørgrav } 1584aa49c926SDag-Erling Smørgrav 1585aa49c926SDag-Erling Smørgrav xfree(p); 1586aa49c926SDag-Erling Smørgrav 1587cce7d346SDag-Erling Smørgrav if (dynamicfwd) { 1588cce7d346SDag-Erling Smørgrav if (!(i == 1 || i == 2)) 1589cce7d346SDag-Erling Smørgrav goto fail_free; 1590cce7d346SDag-Erling Smørgrav } else { 1591cce7d346SDag-Erling Smørgrav if (!(i == 3 || i == 4)) 1592cce7d346SDag-Erling Smørgrav goto fail_free; 1593cce7d346SDag-Erling Smørgrav if (fwd->connect_port <= 0) 1594cce7d346SDag-Erling Smørgrav goto fail_free; 1595cce7d346SDag-Erling Smørgrav } 1596cce7d346SDag-Erling Smørgrav 1597cce7d346SDag-Erling Smørgrav if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1598aa49c926SDag-Erling Smørgrav goto fail_free; 1599aa49c926SDag-Erling Smørgrav 1600aa49c926SDag-Erling Smørgrav if (fwd->connect_host != NULL && 1601aa49c926SDag-Erling Smørgrav strlen(fwd->connect_host) >= NI_MAXHOST) 1602aa49c926SDag-Erling Smørgrav goto fail_free; 1603cce7d346SDag-Erling Smørgrav if (fwd->listen_host != NULL && 1604cce7d346SDag-Erling Smørgrav strlen(fwd->listen_host) >= NI_MAXHOST) 1605cce7d346SDag-Erling Smørgrav goto fail_free; 1606cce7d346SDag-Erling Smørgrav 1607aa49c926SDag-Erling Smørgrav 1608aa49c926SDag-Erling Smørgrav return (i); 1609aa49c926SDag-Erling Smørgrav 1610aa49c926SDag-Erling Smørgrav fail_free: 1611cce7d346SDag-Erling Smørgrav if (fwd->connect_host != NULL) { 1612aa49c926SDag-Erling Smørgrav xfree(fwd->connect_host); 1613cce7d346SDag-Erling Smørgrav fwd->connect_host = NULL; 1614cce7d346SDag-Erling Smørgrav } 1615cce7d346SDag-Erling Smørgrav if (fwd->listen_host != NULL) { 1616aa49c926SDag-Erling Smørgrav xfree(fwd->listen_host); 1617cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1618cce7d346SDag-Erling Smørgrav } 1619aa49c926SDag-Erling Smørgrav return (0); 1620aa49c926SDag-Erling Smørgrav } 1621