1b15c8340SDag-Erling Smørgrav /* $OpenBSD: readconf.c,v 1.183 2010/02/08 10:50:20 markus Exp $ */ 2511b41d2SMark Murray /* 3511b41d2SMark Murray * Author: Tatu Ylonen <ylo@cs.hut.fi> 4511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5511b41d2SMark Murray * All rights reserved 6511b41d2SMark Murray * Functions for reading the configuration files. 7511b41d2SMark Murray * 8c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 9c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 10c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 11c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 12c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 13511b41d2SMark Murray */ 14511b41d2SMark Murray 15511b41d2SMark Murray #include "includes.h" 16333ee039SDag-Erling Smørgrav __RCSID("$FreeBSD$"); 17511b41d2SMark Murray 18333ee039SDag-Erling Smørgrav #include <sys/types.h> 19333ee039SDag-Erling Smørgrav #include <sys/stat.h> 20333ee039SDag-Erling Smørgrav #include <sys/socket.h> 2103f6c5cdSDag-Erling Smørgrav #include <sys/sysctl.h> 22333ee039SDag-Erling Smørgrav 23333ee039SDag-Erling Smørgrav #include <netinet/in.h> 24333ee039SDag-Erling Smørgrav 25333ee039SDag-Erling Smørgrav #include <ctype.h> 26333ee039SDag-Erling Smørgrav #include <errno.h> 27333ee039SDag-Erling Smørgrav #include <netdb.h> 28333ee039SDag-Erling Smørgrav #include <signal.h> 29333ee039SDag-Erling Smørgrav #include <stdarg.h> 30333ee039SDag-Erling Smørgrav #include <stdio.h> 31333ee039SDag-Erling Smørgrav #include <string.h> 32333ee039SDag-Erling Smørgrav #include <unistd.h> 33333ee039SDag-Erling Smørgrav 34511b41d2SMark Murray #include "xmalloc.h" 35333ee039SDag-Erling Smørgrav #include "ssh.h" 36e8aafc91SKris Kennaway #include "compat.h" 37ca3176e7SBrian Feldman #include "cipher.h" 38ca3176e7SBrian Feldman #include "pathnames.h" 39ca3176e7SBrian Feldman #include "log.h" 40333ee039SDag-Erling Smørgrav #include "key.h" 41ca3176e7SBrian Feldman #include "readconf.h" 42ca3176e7SBrian Feldman #include "match.h" 43ca3176e7SBrian Feldman #include "misc.h" 44333ee039SDag-Erling Smørgrav #include "buffer.h" 45ca3176e7SBrian Feldman #include "kex.h" 46ca3176e7SBrian Feldman #include "mac.h" 47cce7d346SDag-Erling Smørgrav #include "version.h" 48511b41d2SMark Murray 49511b41d2SMark Murray /* Format of the configuration file: 50511b41d2SMark Murray 51511b41d2SMark Murray # Configuration data is parsed as follows: 52511b41d2SMark Murray # 1. command line options 53511b41d2SMark Murray # 2. user-specific file 54511b41d2SMark Murray # 3. system-wide file 55511b41d2SMark Murray # Any configuration value is only changed the first time it is set. 56511b41d2SMark Murray # Thus, host-specific definitions should be at the beginning of the 57511b41d2SMark Murray # configuration file, and defaults at the end. 58511b41d2SMark Murray 59511b41d2SMark Murray # Host-specific declarations. These may override anything above. A single 60511b41d2SMark Murray # host may match multiple declarations; these are processed in the order 61511b41d2SMark Murray # that they are given in. 62511b41d2SMark Murray 63511b41d2SMark Murray Host *.ngs.fi ngs.fi 6480628bacSDag-Erling Smørgrav User foo 65511b41d2SMark Murray 66511b41d2SMark Murray Host fake.com 67511b41d2SMark Murray HostName another.host.name.real.org 68511b41d2SMark Murray User blaah 69511b41d2SMark Murray Port 34289 70511b41d2SMark Murray ForwardX11 no 71511b41d2SMark Murray ForwardAgent no 72511b41d2SMark Murray 73511b41d2SMark Murray Host books.com 74511b41d2SMark Murray RemoteForward 9999 shadows.cs.hut.fi:9999 75511b41d2SMark Murray Cipher 3des 76511b41d2SMark Murray 77511b41d2SMark Murray Host fascist.blob.com 78511b41d2SMark Murray Port 23123 79511b41d2SMark Murray User tylonen 80511b41d2SMark Murray PasswordAuthentication no 81511b41d2SMark Murray 82511b41d2SMark Murray Host puukko.hut.fi 83511b41d2SMark Murray User t35124p 84511b41d2SMark Murray ProxyCommand ssh-proxy %h %p 85511b41d2SMark Murray 86511b41d2SMark Murray Host *.fr 8780628bacSDag-Erling Smørgrav PublicKeyAuthentication no 88511b41d2SMark Murray 89511b41d2SMark Murray Host *.su 90511b41d2SMark Murray Cipher none 91511b41d2SMark Murray PasswordAuthentication no 92511b41d2SMark Murray 93b74df5b2SDag-Erling Smørgrav Host vpn.fake.com 94b74df5b2SDag-Erling Smørgrav Tunnel yes 95b74df5b2SDag-Erling Smørgrav TunnelDevice 3 96b74df5b2SDag-Erling Smørgrav 97511b41d2SMark Murray # Defaults for various options 98511b41d2SMark Murray Host * 99511b41d2SMark Murray ForwardAgent no 100ca3176e7SBrian Feldman ForwardX11 no 101511b41d2SMark Murray PasswordAuthentication yes 102511b41d2SMark Murray RSAAuthentication yes 103511b41d2SMark Murray RhostsRSAAuthentication yes 104511b41d2SMark Murray StrictHostKeyChecking yes 1051ec0d754SDag-Erling Smørgrav TcpKeepAlive no 106511b41d2SMark Murray IdentityFile ~/.ssh/identity 107511b41d2SMark Murray Port 22 108511b41d2SMark Murray EscapeChar ~ 109511b41d2SMark Murray 110511b41d2SMark Murray */ 111511b41d2SMark Murray 112511b41d2SMark Murray /* Keyword tokens. */ 113511b41d2SMark Murray 114511b41d2SMark Murray typedef enum { 115511b41d2SMark Murray oBadOption, 1161ec0d754SDag-Erling Smørgrav oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, 117333ee039SDag-Erling Smørgrav oExitOnForwardFailure, 11880628bacSDag-Erling Smørgrav oPasswordAuthentication, oRSAAuthentication, 119ca3176e7SBrian Feldman oChallengeResponseAuthentication, oXAuthLocation, 120511b41d2SMark Murray oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 121511b41d2SMark Murray oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 122511b41d2SMark Murray oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 123511b41d2SMark Murray oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1241ec0d754SDag-Erling Smørgrav oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 125ca3176e7SBrian Feldman oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 126ca3176e7SBrian Feldman oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 127ca3176e7SBrian Feldman oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 128ca3176e7SBrian Feldman oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 129b15c8340SDag-Erling Smørgrav oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 1309e2cbe04SDag-Erling Smørgrav oClearAllForwardings, oNoHostAuthenticationForLocalhost, 131cf2b5f3bSDag-Erling Smørgrav oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 132cf2b5f3bSDag-Erling Smørgrav oAddressFamily, oGssAuthentication, oGssDelegateCreds, 1335962c0e9SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 134aa49c926SDag-Erling Smørgrav oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 135b74df5b2SDag-Erling Smørgrav oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 1367aee6ffeSDag-Erling Smørgrav oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 137cfa59440SDag-Erling Smørgrav oVersionAddendum, 138cf2b5f3bSDag-Erling Smørgrav oDeprecated, oUnsupported 139511b41d2SMark Murray } OpCodes; 140511b41d2SMark Murray 141511b41d2SMark Murray /* Textual representations of the tokens. */ 142511b41d2SMark Murray 143511b41d2SMark Murray static struct { 144511b41d2SMark Murray const char *name; 145511b41d2SMark Murray OpCodes opcode; 146511b41d2SMark Murray } keywords[] = { 147511b41d2SMark Murray { "forwardagent", oForwardAgent }, 148511b41d2SMark Murray { "forwardx11", oForwardX11 }, 1491ec0d754SDag-Erling Smørgrav { "forwardx11trusted", oForwardX11Trusted }, 150333ee039SDag-Erling Smørgrav { "exitonforwardfailure", oExitOnForwardFailure }, 151c2d3a559SKris Kennaway { "xauthlocation", oXAuthLocation }, 152511b41d2SMark Murray { "gatewayports", oGatewayPorts }, 153511b41d2SMark Murray { "useprivilegedport", oUsePrivilegedPort }, 154cf2b5f3bSDag-Erling Smørgrav { "rhostsauthentication", oDeprecated }, 155511b41d2SMark Murray { "passwordauthentication", oPasswordAuthentication }, 15609958426SBrian Feldman { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 15709958426SBrian Feldman { "kbdinteractivedevices", oKbdInteractiveDevices }, 158511b41d2SMark Murray { "rsaauthentication", oRSAAuthentication }, 159ca3176e7SBrian Feldman { "pubkeyauthentication", oPubkeyAuthentication }, 160ca3176e7SBrian Feldman { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 161ca3176e7SBrian Feldman { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 162ca3176e7SBrian Feldman { "hostbasedauthentication", oHostbasedAuthentication }, 163ca3176e7SBrian Feldman { "challengeresponseauthentication", oChallengeResponseAuthentication }, 164ca3176e7SBrian Feldman { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 165ca3176e7SBrian Feldman { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 166cf2b5f3bSDag-Erling Smørgrav { "kerberosauthentication", oUnsupported }, 167cf2b5f3bSDag-Erling Smørgrav { "kerberostgtpassing", oUnsupported }, 168cf2b5f3bSDag-Erling Smørgrav { "afstokenpassing", oUnsupported }, 169cf2b5f3bSDag-Erling Smørgrav #if defined(GSSAPI) 170cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oGssAuthentication }, 171cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oGssDelegateCreds }, 172cf2b5f3bSDag-Erling Smørgrav #else 173cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oUnsupported }, 174cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oUnsupported }, 175511b41d2SMark Murray #endif 17680628bacSDag-Erling Smørgrav { "fallbacktorsh", oDeprecated }, 17780628bacSDag-Erling Smørgrav { "usersh", oDeprecated }, 178511b41d2SMark Murray { "identityfile", oIdentityFile }, 179cce7d346SDag-Erling Smørgrav { "identityfile2", oIdentityFile }, /* obsolete */ 1805962c0e9SDag-Erling Smørgrav { "identitiesonly", oIdentitiesOnly }, 181511b41d2SMark Murray { "hostname", oHostName }, 182ca3176e7SBrian Feldman { "hostkeyalias", oHostKeyAlias }, 183511b41d2SMark Murray { "proxycommand", oProxyCommand }, 184511b41d2SMark Murray { "port", oPort }, 185511b41d2SMark Murray { "cipher", oCipher }, 186e8aafc91SKris Kennaway { "ciphers", oCiphers }, 187ca3176e7SBrian Feldman { "macs", oMacs }, 188e8aafc91SKris Kennaway { "protocol", oProtocol }, 189511b41d2SMark Murray { "remoteforward", oRemoteForward }, 190511b41d2SMark Murray { "localforward", oLocalForward }, 191511b41d2SMark Murray { "user", oUser }, 192511b41d2SMark Murray { "host", oHost }, 193511b41d2SMark Murray { "escapechar", oEscapeChar }, 194511b41d2SMark Murray { "globalknownhostsfile", oGlobalKnownHostsFile }, 195cce7d346SDag-Erling Smørgrav { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */ 196cce7d346SDag-Erling Smørgrav { "userknownhostsfile", oUserKnownHostsFile }, 197af12a3e7SDag-Erling Smørgrav { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 198511b41d2SMark Murray { "connectionattempts", oConnectionAttempts }, 199511b41d2SMark Murray { "batchmode", oBatchMode }, 200511b41d2SMark Murray { "checkhostip", oCheckHostIP }, 201511b41d2SMark Murray { "stricthostkeychecking", oStrictHostKeyChecking }, 202511b41d2SMark Murray { "compression", oCompression }, 203511b41d2SMark Murray { "compressionlevel", oCompressionLevel }, 2041ec0d754SDag-Erling Smørgrav { "tcpkeepalive", oTCPKeepAlive }, 2051ec0d754SDag-Erling Smørgrav { "keepalive", oTCPKeepAlive }, /* obsolete */ 206511b41d2SMark Murray { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 207511b41d2SMark Murray { "loglevel", oLogLevel }, 208ca3176e7SBrian Feldman { "dynamicforward", oDynamicForward }, 209ca3176e7SBrian Feldman { "preferredauthentications", oPreferredAuthentications }, 210ca3176e7SBrian Feldman { "hostkeyalgorithms", oHostKeyAlgorithms }, 211af12a3e7SDag-Erling Smørgrav { "bindaddress", oBindAddress }, 212b15c8340SDag-Erling Smørgrav #ifdef ENABLE_PKCS11 213b15c8340SDag-Erling Smørgrav { "smartcarddevice", oPKCS11Provider }, 214b15c8340SDag-Erling Smørgrav { "pkcs11provider", oPKCS11Provider }, 215cf2b5f3bSDag-Erling Smørgrav #else 216cf2b5f3bSDag-Erling Smørgrav { "smartcarddevice", oUnsupported }, 217b15c8340SDag-Erling Smørgrav { "pkcs11provider", oUnsupported }, 218cf2b5f3bSDag-Erling Smørgrav #endif 219af12a3e7SDag-Erling Smørgrav { "clearallforwardings", oClearAllForwardings }, 220e73e9afaSDag-Erling Smørgrav { "enablesshkeysign", oEnableSSHKeysign }, 221cf2b5f3bSDag-Erling Smørgrav { "verifyhostkeydns", oVerifyHostKeyDNS }, 222af12a3e7SDag-Erling Smørgrav { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 223cf2b5f3bSDag-Erling Smørgrav { "rekeylimit", oRekeyLimit }, 224cf2b5f3bSDag-Erling Smørgrav { "connecttimeout", oConnectTimeout }, 225cf2b5f3bSDag-Erling Smørgrav { "addressfamily", oAddressFamily }, 2261ec0d754SDag-Erling Smørgrav { "serveraliveinterval", oServerAliveInterval }, 2271ec0d754SDag-Erling Smørgrav { "serveralivecountmax", oServerAliveCountMax }, 22821e764dfSDag-Erling Smørgrav { "sendenv", oSendEnv }, 22921e764dfSDag-Erling Smørgrav { "controlpath", oControlPath }, 23021e764dfSDag-Erling Smørgrav { "controlmaster", oControlMaster }, 231aa49c926SDag-Erling Smørgrav { "hashknownhosts", oHashKnownHosts }, 232b74df5b2SDag-Erling Smørgrav { "tunnel", oTunnel }, 233b74df5b2SDag-Erling Smørgrav { "tunneldevice", oTunnelDevice }, 234b74df5b2SDag-Erling Smørgrav { "localcommand", oLocalCommand }, 235b74df5b2SDag-Erling Smørgrav { "permitlocalcommand", oPermitLocalCommand }, 236d4af9e69SDag-Erling Smørgrav { "visualhostkey", oVisualHostKey }, 2377aee6ffeSDag-Erling Smørgrav { "useroaming", oUseRoaming }, 238cce7d346SDag-Erling Smørgrav #ifdef JPAKE 239cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", 240cce7d346SDag-Erling Smørgrav oZeroKnowledgePasswordAuthentication }, 241cce7d346SDag-Erling Smørgrav #else 242cce7d346SDag-Erling Smørgrav { "zeroknowledgepasswordauthentication", oUnsupported }, 243cce7d346SDag-Erling Smørgrav #endif 244cce7d346SDag-Erling Smørgrav 245975616f0SDag-Erling Smørgrav { "versionaddendum", oVersionAddendum }, 246af12a3e7SDag-Erling Smørgrav { NULL, oBadOption } 247511b41d2SMark Murray }; 248511b41d2SMark Murray 249511b41d2SMark Murray /* 250511b41d2SMark Murray * Adds a local TCP/IP port forward to options. Never returns if there is an 251511b41d2SMark Murray * error. 252511b41d2SMark Murray */ 253511b41d2SMark Murray 254511b41d2SMark Murray void 255aa49c926SDag-Erling Smørgrav add_local_forward(Options *options, const Forward *newfwd) 256511b41d2SMark Murray { 257511b41d2SMark Murray Forward *fwd; 258f388f5efSDag-Erling Smørgrav #ifndef NO_IPPORT_RESERVED_CONCEPT 259511b41d2SMark Murray extern uid_t original_real_uid; 26003f6c5cdSDag-Erling Smørgrav int ipport_reserved; 26103f6c5cdSDag-Erling Smørgrav #ifdef __FreeBSD__ 26203f6c5cdSDag-Erling Smørgrav size_t len_ipport_reserved = sizeof(ipport_reserved); 26303f6c5cdSDag-Erling Smørgrav 26403f6c5cdSDag-Erling Smørgrav if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 26503f6c5cdSDag-Erling Smørgrav &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 26603f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 26703f6c5cdSDag-Erling Smørgrav else 26803f6c5cdSDag-Erling Smørgrav ipport_reserved++; 26903f6c5cdSDag-Erling Smørgrav #else 27003f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 27103f6c5cdSDag-Erling Smørgrav #endif 27203f6c5cdSDag-Erling Smørgrav if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 273ca3176e7SBrian Feldman fatal("Privileged ports can only be forwarded by root."); 274989dd127SDag-Erling Smørgrav #endif 275511b41d2SMark Murray if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 276511b41d2SMark Murray fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 277511b41d2SMark Murray fwd = &options->local_forwards[options->num_local_forwards++]; 278aa49c926SDag-Erling Smørgrav 279cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 280aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 281cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 282aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 283511b41d2SMark Murray } 284511b41d2SMark Murray 285511b41d2SMark Murray /* 286511b41d2SMark Murray * Adds a remote TCP/IP port forward to options. Never returns if there is 287511b41d2SMark Murray * an error. 288511b41d2SMark Murray */ 289511b41d2SMark Murray 290511b41d2SMark Murray void 291aa49c926SDag-Erling Smørgrav add_remote_forward(Options *options, const Forward *newfwd) 292511b41d2SMark Murray { 293511b41d2SMark Murray Forward *fwd; 294511b41d2SMark Murray if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 295511b41d2SMark Murray fatal("Too many remote forwards (max %d).", 296511b41d2SMark Murray SSH_MAX_FORWARDS_PER_DIRECTION); 297511b41d2SMark Murray fwd = &options->remote_forwards[options->num_remote_forwards++]; 298aa49c926SDag-Erling Smørgrav 299cce7d346SDag-Erling Smørgrav fwd->listen_host = newfwd->listen_host; 300aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 301cce7d346SDag-Erling Smørgrav fwd->connect_host = newfwd->connect_host; 302aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 303511b41d2SMark Murray } 304511b41d2SMark Murray 305af12a3e7SDag-Erling Smørgrav static void 306af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options) 307af12a3e7SDag-Erling Smørgrav { 308af12a3e7SDag-Erling Smørgrav int i; 309af12a3e7SDag-Erling Smørgrav 310aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_local_forwards; i++) { 311aa49c926SDag-Erling Smørgrav if (options->local_forwards[i].listen_host != NULL) 312aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].listen_host); 313aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].connect_host); 314aa49c926SDag-Erling Smørgrav } 315af12a3e7SDag-Erling Smørgrav options->num_local_forwards = 0; 316aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_remote_forwards; i++) { 317aa49c926SDag-Erling Smørgrav if (options->remote_forwards[i].listen_host != NULL) 318aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].listen_host); 319aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].connect_host); 320aa49c926SDag-Erling Smørgrav } 321af12a3e7SDag-Erling Smørgrav options->num_remote_forwards = 0; 322b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 323af12a3e7SDag-Erling Smørgrav } 324af12a3e7SDag-Erling Smørgrav 325511b41d2SMark Murray /* 326ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or oBadOption. 327511b41d2SMark Murray */ 328511b41d2SMark Murray 329511b41d2SMark Murray static OpCodes 330511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum) 331511b41d2SMark Murray { 332ca3176e7SBrian Feldman u_int i; 333511b41d2SMark Murray 334511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 335511b41d2SMark Murray if (strcasecmp(cp, keywords[i].name) == 0) 336511b41d2SMark Murray return keywords[i].opcode; 337511b41d2SMark Murray 338ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 339511b41d2SMark Murray filename, linenum, cp); 340511b41d2SMark Murray return oBadOption; 341511b41d2SMark Murray } 342511b41d2SMark Murray 343511b41d2SMark Murray /* 344511b41d2SMark Murray * Processes a single option line as used in the configuration files. This 345511b41d2SMark Murray * only sets those values that have not already been set. 346511b41d2SMark Murray */ 347e73e9afaSDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 348511b41d2SMark Murray 349511b41d2SMark Murray int 350511b41d2SMark Murray process_config_line(Options *options, const char *host, 351511b41d2SMark Murray char *line, const char *filename, int linenum, 352511b41d2SMark Murray int *activep) 353511b41d2SMark Murray { 354aa49c926SDag-Erling Smørgrav char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 355333ee039SDag-Erling Smørgrav int opcode, *intptr, value, value2, scale; 356d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 357333ee039SDag-Erling Smørgrav long long orig, val64; 358e73e9afaSDag-Erling Smørgrav size_t len; 359aa49c926SDag-Erling Smørgrav Forward fwd; 360511b41d2SMark Murray 361cf2b5f3bSDag-Erling Smørgrav /* Strip trailing whitespace */ 362cf2b5f3bSDag-Erling Smørgrav for (len = strlen(line) - 1; len > 0; len--) { 363cf2b5f3bSDag-Erling Smørgrav if (strchr(WHITESPACE, line[len]) == NULL) 364cf2b5f3bSDag-Erling Smørgrav break; 365cf2b5f3bSDag-Erling Smørgrav line[len] = '\0'; 366cf2b5f3bSDag-Erling Smørgrav } 367cf2b5f3bSDag-Erling Smørgrav 368c2d3a559SKris Kennaway s = line; 369c2d3a559SKris Kennaway /* Get the keyword. (Each line is supposed to begin with a keyword). */ 370333ee039SDag-Erling Smørgrav if ((keyword = strdelim(&s)) == NULL) 371333ee039SDag-Erling Smørgrav return 0; 372c2d3a559SKris Kennaway /* Ignore leading whitespace. */ 373c2d3a559SKris Kennaway if (*keyword == '\0') 374c2d3a559SKris Kennaway keyword = strdelim(&s); 375ca3176e7SBrian Feldman if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 376511b41d2SMark Murray return 0; 377511b41d2SMark Murray 378c2d3a559SKris Kennaway opcode = parse_token(keyword, filename, linenum); 379511b41d2SMark Murray 380511b41d2SMark Murray switch (opcode) { 381511b41d2SMark Murray case oBadOption: 382511b41d2SMark Murray /* don't panic, but count bad options */ 383511b41d2SMark Murray return -1; 384511b41d2SMark Murray /* NOTREACHED */ 385cf2b5f3bSDag-Erling Smørgrav case oConnectTimeout: 386cf2b5f3bSDag-Erling Smørgrav intptr = &options->connection_timeout; 3871ec0d754SDag-Erling Smørgrav parse_time: 388cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 389cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 390cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: missing time value.", 391cf2b5f3bSDag-Erling Smørgrav filename, linenum); 392cf2b5f3bSDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 393cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 394cf2b5f3bSDag-Erling Smørgrav filename, linenum); 395d4af9e69SDag-Erling Smørgrav if (*activep && *intptr == -1) 396cf2b5f3bSDag-Erling Smørgrav *intptr = value; 397cf2b5f3bSDag-Erling Smørgrav break; 398cf2b5f3bSDag-Erling Smørgrav 399511b41d2SMark Murray case oForwardAgent: 400511b41d2SMark Murray intptr = &options->forward_agent; 401511b41d2SMark Murray parse_flag: 402c2d3a559SKris Kennaway arg = strdelim(&s); 403c2d3a559SKris Kennaway if (!arg || *arg == '\0') 404511b41d2SMark Murray fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 405511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 406c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 407511b41d2SMark Murray value = 1; 408c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 409511b41d2SMark Murray value = 0; 410511b41d2SMark Murray else 411511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 412511b41d2SMark Murray if (*activep && *intptr == -1) 413511b41d2SMark Murray *intptr = value; 414511b41d2SMark Murray break; 415511b41d2SMark Murray 416511b41d2SMark Murray case oForwardX11: 417511b41d2SMark Murray intptr = &options->forward_x11; 418511b41d2SMark Murray goto parse_flag; 419511b41d2SMark Murray 4201ec0d754SDag-Erling Smørgrav case oForwardX11Trusted: 4211ec0d754SDag-Erling Smørgrav intptr = &options->forward_x11_trusted; 4221ec0d754SDag-Erling Smørgrav goto parse_flag; 4231ec0d754SDag-Erling Smørgrav 424511b41d2SMark Murray case oGatewayPorts: 425511b41d2SMark Murray intptr = &options->gateway_ports; 426511b41d2SMark Murray goto parse_flag; 427511b41d2SMark Murray 428333ee039SDag-Erling Smørgrav case oExitOnForwardFailure: 429333ee039SDag-Erling Smørgrav intptr = &options->exit_on_forward_failure; 430333ee039SDag-Erling Smørgrav goto parse_flag; 431333ee039SDag-Erling Smørgrav 432511b41d2SMark Murray case oUsePrivilegedPort: 433511b41d2SMark Murray intptr = &options->use_privileged_port; 434511b41d2SMark Murray goto parse_flag; 435511b41d2SMark Murray 436511b41d2SMark Murray case oPasswordAuthentication: 437511b41d2SMark Murray intptr = &options->password_authentication; 438511b41d2SMark Murray goto parse_flag; 439511b41d2SMark Murray 440cce7d346SDag-Erling Smørgrav case oZeroKnowledgePasswordAuthentication: 441cce7d346SDag-Erling Smørgrav intptr = &options->zero_knowledge_password_authentication; 442cce7d346SDag-Erling Smørgrav goto parse_flag; 443cce7d346SDag-Erling Smørgrav 44409958426SBrian Feldman case oKbdInteractiveAuthentication: 44509958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 44609958426SBrian Feldman goto parse_flag; 44709958426SBrian Feldman 44809958426SBrian Feldman case oKbdInteractiveDevices: 44909958426SBrian Feldman charptr = &options->kbd_interactive_devices; 45009958426SBrian Feldman goto parse_string; 45109958426SBrian Feldman 452ca3176e7SBrian Feldman case oPubkeyAuthentication: 453ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 454e8aafc91SKris Kennaway goto parse_flag; 455e8aafc91SKris Kennaway 456511b41d2SMark Murray case oRSAAuthentication: 457511b41d2SMark Murray intptr = &options->rsa_authentication; 458511b41d2SMark Murray goto parse_flag; 459511b41d2SMark Murray 460511b41d2SMark Murray case oRhostsRSAAuthentication: 461511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 462511b41d2SMark Murray goto parse_flag; 463511b41d2SMark Murray 464ca3176e7SBrian Feldman case oHostbasedAuthentication: 465ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 466511b41d2SMark Murray goto parse_flag; 467511b41d2SMark Murray 468af12a3e7SDag-Erling Smørgrav case oChallengeResponseAuthentication: 469af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 470af12a3e7SDag-Erling Smørgrav goto parse_flag; 471cf2b5f3bSDag-Erling Smørgrav 472cf2b5f3bSDag-Erling Smørgrav case oGssAuthentication: 473cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 474511b41d2SMark Murray goto parse_flag; 475cf2b5f3bSDag-Erling Smørgrav 476cf2b5f3bSDag-Erling Smørgrav case oGssDelegateCreds: 477cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_deleg_creds; 478ca3176e7SBrian Feldman goto parse_flag; 479cf2b5f3bSDag-Erling Smørgrav 480511b41d2SMark Murray case oBatchMode: 481511b41d2SMark Murray intptr = &options->batch_mode; 482511b41d2SMark Murray goto parse_flag; 483511b41d2SMark Murray 484511b41d2SMark Murray case oCheckHostIP: 485511b41d2SMark Murray intptr = &options->check_host_ip; 486511b41d2SMark Murray goto parse_flag; 487511b41d2SMark Murray 488cf2b5f3bSDag-Erling Smørgrav case oVerifyHostKeyDNS: 489cf2b5f3bSDag-Erling Smørgrav intptr = &options->verify_host_key_dns; 4901ec0d754SDag-Erling Smørgrav goto parse_yesnoask; 491cf2b5f3bSDag-Erling Smørgrav 492511b41d2SMark Murray case oStrictHostKeyChecking: 493511b41d2SMark Murray intptr = &options->strict_host_key_checking; 4941ec0d754SDag-Erling Smørgrav parse_yesnoask: 495c2d3a559SKris Kennaway arg = strdelim(&s); 496c2d3a559SKris Kennaway if (!arg || *arg == '\0') 497ca3176e7SBrian Feldman fatal("%.200s line %d: Missing yes/no/ask argument.", 498511b41d2SMark Murray filename, linenum); 499511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 500c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 501511b41d2SMark Murray value = 1; 502c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 503511b41d2SMark Murray value = 0; 504c2d3a559SKris Kennaway else if (strcmp(arg, "ask") == 0) 505511b41d2SMark Murray value = 2; 506511b41d2SMark Murray else 507511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 508511b41d2SMark Murray if (*activep && *intptr == -1) 509511b41d2SMark Murray *intptr = value; 510511b41d2SMark Murray break; 511511b41d2SMark Murray 512511b41d2SMark Murray case oCompression: 513511b41d2SMark Murray intptr = &options->compression; 514511b41d2SMark Murray goto parse_flag; 515511b41d2SMark Murray 5161ec0d754SDag-Erling Smørgrav case oTCPKeepAlive: 5171ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 518511b41d2SMark Murray goto parse_flag; 519511b41d2SMark Murray 520af12a3e7SDag-Erling Smørgrav case oNoHostAuthenticationForLocalhost: 521af12a3e7SDag-Erling Smørgrav intptr = &options->no_host_authentication_for_localhost; 522af12a3e7SDag-Erling Smørgrav goto parse_flag; 523af12a3e7SDag-Erling Smørgrav 524511b41d2SMark Murray case oNumberOfPasswordPrompts: 525511b41d2SMark Murray intptr = &options->number_of_password_prompts; 526511b41d2SMark Murray goto parse_int; 527511b41d2SMark Murray 528511b41d2SMark Murray case oCompressionLevel: 529511b41d2SMark Murray intptr = &options->compression_level; 530511b41d2SMark Murray goto parse_int; 531511b41d2SMark Murray 532cf2b5f3bSDag-Erling Smørgrav case oRekeyLimit: 533cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 534cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 535cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 536cf2b5f3bSDag-Erling Smørgrav if (arg[0] < '0' || arg[0] > '9') 537cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 538333ee039SDag-Erling Smørgrav orig = val64 = strtoll(arg, &endofnumber, 10); 539cf2b5f3bSDag-Erling Smørgrav if (arg == endofnumber) 540cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 541cf2b5f3bSDag-Erling Smørgrav switch (toupper(*endofnumber)) { 542333ee039SDag-Erling Smørgrav case '\0': 543333ee039SDag-Erling Smørgrav scale = 1; 544333ee039SDag-Erling Smørgrav break; 545cf2b5f3bSDag-Erling Smørgrav case 'K': 546333ee039SDag-Erling Smørgrav scale = 1<<10; 547cf2b5f3bSDag-Erling Smørgrav break; 548cf2b5f3bSDag-Erling Smørgrav case 'M': 549333ee039SDag-Erling Smørgrav scale = 1<<20; 550cf2b5f3bSDag-Erling Smørgrav break; 551cf2b5f3bSDag-Erling Smørgrav case 'G': 552333ee039SDag-Erling Smørgrav scale = 1<<30; 553cf2b5f3bSDag-Erling Smørgrav break; 554333ee039SDag-Erling Smørgrav default: 555333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Invalid RekeyLimit suffix", 556333ee039SDag-Erling Smørgrav filename, linenum); 557cf2b5f3bSDag-Erling Smørgrav } 558333ee039SDag-Erling Smørgrav val64 *= scale; 559333ee039SDag-Erling Smørgrav /* detect integer wrap and too-large limits */ 560d4af9e69SDag-Erling Smørgrav if ((val64 / scale) != orig || val64 > UINT_MAX) 561333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too large", 562333ee039SDag-Erling Smørgrav filename, linenum); 563333ee039SDag-Erling Smørgrav if (val64 < 16) 564333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 565333ee039SDag-Erling Smørgrav filename, linenum); 566d4af9e69SDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 567d4af9e69SDag-Erling Smørgrav options->rekey_limit = (u_int32_t)val64; 568cf2b5f3bSDag-Erling Smørgrav break; 569cf2b5f3bSDag-Erling Smørgrav 570511b41d2SMark Murray case oIdentityFile: 571c2d3a559SKris Kennaway arg = strdelim(&s); 572c2d3a559SKris Kennaway if (!arg || *arg == '\0') 573511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 574511b41d2SMark Murray if (*activep) { 575ca3176e7SBrian Feldman intptr = &options->num_identity_files; 576e8aafc91SKris Kennaway if (*intptr >= SSH_MAX_IDENTITY_FILES) 577511b41d2SMark Murray fatal("%.200s line %d: Too many identity files specified (max %d).", 578511b41d2SMark Murray filename, linenum, SSH_MAX_IDENTITY_FILES); 579ca3176e7SBrian Feldman charptr = &options->identity_files[*intptr]; 580c2d3a559SKris Kennaway *charptr = xstrdup(arg); 581e8aafc91SKris Kennaway *intptr = *intptr + 1; 582511b41d2SMark Murray } 583511b41d2SMark Murray break; 584511b41d2SMark Murray 585c2d3a559SKris Kennaway case oXAuthLocation: 586c2d3a559SKris Kennaway charptr=&options->xauth_location; 587c2d3a559SKris Kennaway goto parse_string; 588c2d3a559SKris Kennaway 589511b41d2SMark Murray case oUser: 590511b41d2SMark Murray charptr = &options->user; 591511b41d2SMark Murray parse_string: 592c2d3a559SKris Kennaway arg = strdelim(&s); 593c2d3a559SKris Kennaway if (!arg || *arg == '\0') 594511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 595511b41d2SMark Murray if (*activep && *charptr == NULL) 596c2d3a559SKris Kennaway *charptr = xstrdup(arg); 597511b41d2SMark Murray break; 598511b41d2SMark Murray 599511b41d2SMark Murray case oGlobalKnownHostsFile: 600511b41d2SMark Murray charptr = &options->system_hostfile; 601511b41d2SMark Murray goto parse_string; 602511b41d2SMark Murray 603511b41d2SMark Murray case oUserKnownHostsFile: 604511b41d2SMark Murray charptr = &options->user_hostfile; 605511b41d2SMark Murray goto parse_string; 606511b41d2SMark Murray 607e8aafc91SKris Kennaway case oGlobalKnownHostsFile2: 608e8aafc91SKris Kennaway charptr = &options->system_hostfile2; 609e8aafc91SKris Kennaway goto parse_string; 610e8aafc91SKris Kennaway 611e8aafc91SKris Kennaway case oUserKnownHostsFile2: 612e8aafc91SKris Kennaway charptr = &options->user_hostfile2; 613e8aafc91SKris Kennaway goto parse_string; 614e8aafc91SKris Kennaway 615511b41d2SMark Murray case oHostName: 616511b41d2SMark Murray charptr = &options->hostname; 617511b41d2SMark Murray goto parse_string; 618511b41d2SMark Murray 619ca3176e7SBrian Feldman case oHostKeyAlias: 620ca3176e7SBrian Feldman charptr = &options->host_key_alias; 621ca3176e7SBrian Feldman goto parse_string; 622ca3176e7SBrian Feldman 623ca3176e7SBrian Feldman case oPreferredAuthentications: 624ca3176e7SBrian Feldman charptr = &options->preferred_authentications; 625ca3176e7SBrian Feldman goto parse_string; 626ca3176e7SBrian Feldman 627af12a3e7SDag-Erling Smørgrav case oBindAddress: 628af12a3e7SDag-Erling Smørgrav charptr = &options->bind_address; 629af12a3e7SDag-Erling Smørgrav goto parse_string; 630af12a3e7SDag-Erling Smørgrav 631b15c8340SDag-Erling Smørgrav case oPKCS11Provider: 632b15c8340SDag-Erling Smørgrav charptr = &options->pkcs11_provider; 633af12a3e7SDag-Erling Smørgrav goto parse_string; 634af12a3e7SDag-Erling Smørgrav 635511b41d2SMark Murray case oProxyCommand: 636b74df5b2SDag-Erling Smørgrav charptr = &options->proxy_command; 637b74df5b2SDag-Erling Smørgrav parse_command: 638cf2b5f3bSDag-Erling Smørgrav if (s == NULL) 639cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 640e73e9afaSDag-Erling Smørgrav len = strspn(s, WHITESPACE "="); 641511b41d2SMark Murray if (*activep && *charptr == NULL) 642e73e9afaSDag-Erling Smørgrav *charptr = xstrdup(s + len); 643511b41d2SMark Murray return 0; 644511b41d2SMark Murray 645511b41d2SMark Murray case oPort: 646511b41d2SMark Murray intptr = &options->port; 647511b41d2SMark Murray parse_int: 648c2d3a559SKris Kennaway arg = strdelim(&s); 649c2d3a559SKris Kennaway if (!arg || *arg == '\0') 650511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 651c2d3a559SKris Kennaway if (arg[0] < '0' || arg[0] > '9') 652511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 653511b41d2SMark Murray 654511b41d2SMark Murray /* Octal, decimal, or hex format? */ 655c2d3a559SKris Kennaway value = strtol(arg, &endofnumber, 0); 656c2d3a559SKris Kennaway if (arg == endofnumber) 657511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 658511b41d2SMark Murray if (*activep && *intptr == -1) 659511b41d2SMark Murray *intptr = value; 660511b41d2SMark Murray break; 661511b41d2SMark Murray 662511b41d2SMark Murray case oConnectionAttempts: 663511b41d2SMark Murray intptr = &options->connection_attempts; 664511b41d2SMark Murray goto parse_int; 665511b41d2SMark Murray 666511b41d2SMark Murray case oCipher: 667511b41d2SMark Murray intptr = &options->cipher; 668c2d3a559SKris Kennaway arg = strdelim(&s); 669c2d3a559SKris Kennaway if (!arg || *arg == '\0') 670db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 671c2d3a559SKris Kennaway value = cipher_number(arg); 672511b41d2SMark Murray if (value == -1) 673511b41d2SMark Murray fatal("%.200s line %d: Bad cipher '%s'.", 674c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 675511b41d2SMark Murray if (*activep && *intptr == -1) 676511b41d2SMark Murray *intptr = value; 677511b41d2SMark Murray break; 678511b41d2SMark Murray 679e8aafc91SKris Kennaway case oCiphers: 680c2d3a559SKris Kennaway arg = strdelim(&s); 681c2d3a559SKris Kennaway if (!arg || *arg == '\0') 682db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 683c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 684e8aafc91SKris Kennaway fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 685c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 686e8aafc91SKris Kennaway if (*activep && options->ciphers == NULL) 687c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 688e8aafc91SKris Kennaway break; 689e8aafc91SKris Kennaway 690ca3176e7SBrian Feldman case oMacs: 691ca3176e7SBrian Feldman arg = strdelim(&s); 692ca3176e7SBrian Feldman if (!arg || *arg == '\0') 693ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 694ca3176e7SBrian Feldman if (!mac_valid(arg)) 695ca3176e7SBrian Feldman fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 696ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 697ca3176e7SBrian Feldman if (*activep && options->macs == NULL) 698ca3176e7SBrian Feldman options->macs = xstrdup(arg); 699ca3176e7SBrian Feldman break; 700ca3176e7SBrian Feldman 701ca3176e7SBrian Feldman case oHostKeyAlgorithms: 702ca3176e7SBrian Feldman arg = strdelim(&s); 703ca3176e7SBrian Feldman if (!arg || *arg == '\0') 704ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 705ca3176e7SBrian Feldman if (!key_names_valid2(arg)) 706ca3176e7SBrian Feldman fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 707ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 708ca3176e7SBrian Feldman if (*activep && options->hostkeyalgorithms == NULL) 709ca3176e7SBrian Feldman options->hostkeyalgorithms = xstrdup(arg); 710ca3176e7SBrian Feldman break; 711ca3176e7SBrian Feldman 712e8aafc91SKris Kennaway case oProtocol: 713e8aafc91SKris Kennaway intptr = &options->protocol; 714c2d3a559SKris Kennaway arg = strdelim(&s); 715c2d3a559SKris Kennaway if (!arg || *arg == '\0') 716db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 717c2d3a559SKris Kennaway value = proto_spec(arg); 718e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 719e8aafc91SKris Kennaway fatal("%.200s line %d: Bad protocol spec '%s'.", 720c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 721e8aafc91SKris Kennaway if (*activep && *intptr == SSH_PROTO_UNKNOWN) 722e8aafc91SKris Kennaway *intptr = value; 723e8aafc91SKris Kennaway break; 724e8aafc91SKris Kennaway 725511b41d2SMark Murray case oLogLevel: 726d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 727c2d3a559SKris Kennaway arg = strdelim(&s); 728c2d3a559SKris Kennaway value = log_level_number(arg); 729af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 730ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 731c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 732d4af9e69SDag-Erling Smørgrav if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 733d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 734511b41d2SMark Murray break; 735511b41d2SMark Murray 736af12a3e7SDag-Erling Smørgrav case oLocalForward: 737511b41d2SMark Murray case oRemoteForward: 738cce7d346SDag-Erling Smørgrav case oDynamicForward: 739c2d3a559SKris Kennaway arg = strdelim(&s); 740aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 741af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Missing port argument.", 742af12a3e7SDag-Erling Smørgrav filename, linenum); 743cce7d346SDag-Erling Smørgrav 744cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 745cce7d346SDag-Erling Smørgrav opcode == oRemoteForward) { 746aa49c926SDag-Erling Smørgrav arg2 = strdelim(&s); 747aa49c926SDag-Erling Smørgrav if (arg2 == NULL || *arg2 == '\0') 748aa49c926SDag-Erling Smørgrav fatal("%.200s line %d: Missing target argument.", 749511b41d2SMark Murray filename, linenum); 750aa49c926SDag-Erling Smørgrav 751aa49c926SDag-Erling Smørgrav /* construct a string for parse_forward */ 752aa49c926SDag-Erling Smørgrav snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 753cce7d346SDag-Erling Smørgrav } else if (opcode == oDynamicForward) { 754cce7d346SDag-Erling Smørgrav strlcpy(fwdarg, arg, sizeof(fwdarg)); 755cce7d346SDag-Erling Smørgrav } 756aa49c926SDag-Erling Smørgrav 757cce7d346SDag-Erling Smørgrav if (parse_forward(&fwd, fwdarg, 758cce7d346SDag-Erling Smørgrav opcode == oDynamicForward ? 1 : 0, 759cce7d346SDag-Erling Smørgrav opcode == oRemoteForward ? 1 : 0) == 0) 760af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 761511b41d2SMark Murray filename, linenum); 762aa49c926SDag-Erling Smørgrav 763af12a3e7SDag-Erling Smørgrav if (*activep) { 764cce7d346SDag-Erling Smørgrav if (opcode == oLocalForward || 765cce7d346SDag-Erling Smørgrav opcode == oDynamicForward) 766aa49c926SDag-Erling Smørgrav add_local_forward(options, &fwd); 767af12a3e7SDag-Erling Smørgrav else if (opcode == oRemoteForward) 768aa49c926SDag-Erling Smørgrav add_remote_forward(options, &fwd); 769af12a3e7SDag-Erling Smørgrav } 770511b41d2SMark Murray break; 771511b41d2SMark Murray 772af12a3e7SDag-Erling Smørgrav case oClearAllForwardings: 773af12a3e7SDag-Erling Smørgrav intptr = &options->clear_forwardings; 774af12a3e7SDag-Erling Smørgrav goto parse_flag; 775af12a3e7SDag-Erling Smørgrav 776511b41d2SMark Murray case oHost: 777511b41d2SMark Murray *activep = 0; 778c2d3a559SKris Kennaway while ((arg = strdelim(&s)) != NULL && *arg != '\0') 779c2d3a559SKris Kennaway if (match_pattern(host, arg)) { 780c2d3a559SKris Kennaway debug("Applying options for %.100s", arg); 781511b41d2SMark Murray *activep = 1; 782511b41d2SMark Murray break; 783511b41d2SMark Murray } 784c2d3a559SKris Kennaway /* Avoid garbage check below, as strdelim is done. */ 785511b41d2SMark Murray return 0; 786511b41d2SMark Murray 787511b41d2SMark Murray case oEscapeChar: 788511b41d2SMark Murray intptr = &options->escape_char; 789c2d3a559SKris Kennaway arg = strdelim(&s); 790c2d3a559SKris Kennaway if (!arg || *arg == '\0') 791511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 792c2d3a559SKris Kennaway if (arg[0] == '^' && arg[2] == 0 && 793ca3176e7SBrian Feldman (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 794ca3176e7SBrian Feldman value = (u_char) arg[1] & 31; 795c2d3a559SKris Kennaway else if (strlen(arg) == 1) 796ca3176e7SBrian Feldman value = (u_char) arg[0]; 797c2d3a559SKris Kennaway else if (strcmp(arg, "none") == 0) 798af12a3e7SDag-Erling Smørgrav value = SSH_ESCAPECHAR_NONE; 799511b41d2SMark Murray else { 800511b41d2SMark Murray fatal("%.200s line %d: Bad escape character.", 801511b41d2SMark Murray filename, linenum); 802511b41d2SMark Murray /* NOTREACHED */ 803511b41d2SMark Murray value = 0; /* Avoid compiler warning. */ 804511b41d2SMark Murray } 805511b41d2SMark Murray if (*activep && *intptr == -1) 806511b41d2SMark Murray *intptr = value; 807511b41d2SMark Murray break; 808511b41d2SMark Murray 809cf2b5f3bSDag-Erling Smørgrav case oAddressFamily: 810cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 811d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 812d4ecd108SDag-Erling Smørgrav fatal("%s line %d: missing address family.", 813d4ecd108SDag-Erling Smørgrav filename, linenum); 814cf2b5f3bSDag-Erling Smørgrav intptr = &options->address_family; 815cf2b5f3bSDag-Erling Smørgrav if (strcasecmp(arg, "inet") == 0) 816cf2b5f3bSDag-Erling Smørgrav value = AF_INET; 817cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "inet6") == 0) 818cf2b5f3bSDag-Erling Smørgrav value = AF_INET6; 819cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "any") == 0) 820cf2b5f3bSDag-Erling Smørgrav value = AF_UNSPEC; 821cf2b5f3bSDag-Erling Smørgrav else 822cf2b5f3bSDag-Erling Smørgrav fatal("Unsupported AddressFamily \"%s\"", arg); 823cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 824cf2b5f3bSDag-Erling Smørgrav *intptr = value; 825cf2b5f3bSDag-Erling Smørgrav break; 826cf2b5f3bSDag-Erling Smørgrav 827e73e9afaSDag-Erling Smørgrav case oEnableSSHKeysign: 828e73e9afaSDag-Erling Smørgrav intptr = &options->enable_ssh_keysign; 829e73e9afaSDag-Erling Smørgrav goto parse_flag; 830e73e9afaSDag-Erling Smørgrav 8315962c0e9SDag-Erling Smørgrav case oIdentitiesOnly: 8325962c0e9SDag-Erling Smørgrav intptr = &options->identities_only; 8335962c0e9SDag-Erling Smørgrav goto parse_flag; 8345962c0e9SDag-Erling Smørgrav 8351ec0d754SDag-Erling Smørgrav case oServerAliveInterval: 8361ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_interval; 8371ec0d754SDag-Erling Smørgrav goto parse_time; 8381ec0d754SDag-Erling Smørgrav 8391ec0d754SDag-Erling Smørgrav case oServerAliveCountMax: 8401ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_count_max; 8411ec0d754SDag-Erling Smørgrav goto parse_int; 8421ec0d754SDag-Erling Smørgrav 84321e764dfSDag-Erling Smørgrav case oSendEnv: 84421e764dfSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 84521e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 84621e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 84721e764dfSDag-Erling Smørgrav filename, linenum); 848aa49c926SDag-Erling Smørgrav if (!*activep) 849aa49c926SDag-Erling Smørgrav continue; 85021e764dfSDag-Erling Smørgrav if (options->num_send_env >= MAX_SEND_ENV) 85121e764dfSDag-Erling Smørgrav fatal("%s line %d: too many send env.", 85221e764dfSDag-Erling Smørgrav filename, linenum); 85321e764dfSDag-Erling Smørgrav options->send_env[options->num_send_env++] = 85421e764dfSDag-Erling Smørgrav xstrdup(arg); 85521e764dfSDag-Erling Smørgrav } 85621e764dfSDag-Erling Smørgrav break; 85721e764dfSDag-Erling Smørgrav 85821e764dfSDag-Erling Smørgrav case oControlPath: 85921e764dfSDag-Erling Smørgrav charptr = &options->control_path; 86021e764dfSDag-Erling Smørgrav goto parse_string; 86121e764dfSDag-Erling Smørgrav 86221e764dfSDag-Erling Smørgrav case oControlMaster: 86321e764dfSDag-Erling Smørgrav intptr = &options->control_master; 864d4ecd108SDag-Erling Smørgrav arg = strdelim(&s); 865d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 866d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlMaster argument.", 867d4ecd108SDag-Erling Smørgrav filename, linenum); 868d4ecd108SDag-Erling Smørgrav value = 0; /* To avoid compiler warning... */ 869d4ecd108SDag-Erling Smørgrav if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 870d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_YES; 871d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 872d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_NO; 873d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "auto") == 0) 874d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO; 875d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "ask") == 0) 876d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_ASK; 877d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "autoask") == 0) 878d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO_ASK; 879d4ecd108SDag-Erling Smørgrav else 880d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlMaster argument.", 881d4ecd108SDag-Erling Smørgrav filename, linenum); 882d4ecd108SDag-Erling Smørgrav if (*activep && *intptr == -1) 883d4ecd108SDag-Erling Smørgrav *intptr = value; 884d4ecd108SDag-Erling Smørgrav break; 88521e764dfSDag-Erling Smørgrav 886aa49c926SDag-Erling Smørgrav case oHashKnownHosts: 887aa49c926SDag-Erling Smørgrav intptr = &options->hash_known_hosts; 888aa49c926SDag-Erling Smørgrav goto parse_flag; 889aa49c926SDag-Erling Smørgrav 890b74df5b2SDag-Erling Smørgrav case oTunnel: 891b74df5b2SDag-Erling Smørgrav intptr = &options->tun_open; 892b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 893b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 894b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 895b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 896b74df5b2SDag-Erling Smørgrav value = 0; /* silence compiler */ 897b74df5b2SDag-Erling Smørgrav if (strcasecmp(arg, "ethernet") == 0) 898b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_ETHERNET; 899b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "point-to-point") == 0) 900b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_POINTOPOINT; 901b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "yes") == 0) 902b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_DEFAULT; 903b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 904b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_NO; 905b74df5b2SDag-Erling Smørgrav else 906b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 907b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 908b74df5b2SDag-Erling Smørgrav if (*activep) 909b74df5b2SDag-Erling Smørgrav *intptr = value; 910b74df5b2SDag-Erling Smørgrav break; 911b74df5b2SDag-Erling Smørgrav 912b74df5b2SDag-Erling Smørgrav case oTunnelDevice: 913b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 914b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 915b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 916b74df5b2SDag-Erling Smørgrav value = a2tun(arg, &value2); 917b74df5b2SDag-Erling Smørgrav if (value == SSH_TUNID_ERR) 918b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Bad tun device.", filename, linenum); 919b74df5b2SDag-Erling Smørgrav if (*activep) { 920b74df5b2SDag-Erling Smørgrav options->tun_local = value; 921b74df5b2SDag-Erling Smørgrav options->tun_remote = value2; 922b74df5b2SDag-Erling Smørgrav } 923b74df5b2SDag-Erling Smørgrav break; 924b74df5b2SDag-Erling Smørgrav 925b74df5b2SDag-Erling Smørgrav case oLocalCommand: 926b74df5b2SDag-Erling Smørgrav charptr = &options->local_command; 927b74df5b2SDag-Erling Smørgrav goto parse_command; 928b74df5b2SDag-Erling Smørgrav 929b74df5b2SDag-Erling Smørgrav case oPermitLocalCommand: 930b74df5b2SDag-Erling Smørgrav intptr = &options->permit_local_command; 931b74df5b2SDag-Erling Smørgrav goto parse_flag; 932b74df5b2SDag-Erling Smørgrav 933d4af9e69SDag-Erling Smørgrav case oVisualHostKey: 934d4af9e69SDag-Erling Smørgrav intptr = &options->visual_host_key; 935d4af9e69SDag-Erling Smørgrav goto parse_flag; 936d4af9e69SDag-Erling Smørgrav 9377aee6ffeSDag-Erling Smørgrav case oUseRoaming: 9387aee6ffeSDag-Erling Smørgrav intptr = &options->use_roaming; 9397aee6ffeSDag-Erling Smørgrav goto parse_flag; 9407aee6ffeSDag-Erling Smørgrav 941975616f0SDag-Erling Smørgrav case oVersionAddendum: 942975616f0SDag-Erling Smørgrav ssh_version_set_addendum(strtok(s, "\n")); 943975616f0SDag-Erling Smørgrav do { 944975616f0SDag-Erling Smørgrav arg = strdelim(&s); 945975616f0SDag-Erling Smørgrav } while (arg != NULL && *arg != '\0'); 946975616f0SDag-Erling Smørgrav break; 947975616f0SDag-Erling Smørgrav 94880628bacSDag-Erling Smørgrav case oDeprecated: 94980628bacSDag-Erling Smørgrav debug("%s line %d: Deprecated option \"%s\"", 95080628bacSDag-Erling Smørgrav filename, linenum, keyword); 95180628bacSDag-Erling Smørgrav return 0; 95280628bacSDag-Erling Smørgrav 953cf2b5f3bSDag-Erling Smørgrav case oUnsupported: 954cf2b5f3bSDag-Erling Smørgrav error("%s line %d: Unsupported option \"%s\"", 955cf2b5f3bSDag-Erling Smørgrav filename, linenum, keyword); 956cf2b5f3bSDag-Erling Smørgrav return 0; 957cf2b5f3bSDag-Erling Smørgrav 958511b41d2SMark Murray default: 959511b41d2SMark Murray fatal("process_config_line: Unimplemented opcode %d", opcode); 960511b41d2SMark Murray } 961511b41d2SMark Murray 962511b41d2SMark Murray /* Check that there is no garbage at end of line. */ 963ca3176e7SBrian Feldman if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 964c2d3a559SKris Kennaway fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 965c2d3a559SKris Kennaway filename, linenum, arg); 966c2d3a559SKris Kennaway } 967511b41d2SMark Murray return 0; 968511b41d2SMark Murray } 969511b41d2SMark Murray 970511b41d2SMark Murray 971511b41d2SMark Murray /* 972511b41d2SMark Murray * Reads the config file and modifies the options accordingly. Options 973511b41d2SMark Murray * should already be initialized before this call. This never returns if 974af12a3e7SDag-Erling Smørgrav * there is an error. If the file does not exist, this returns 0. 975511b41d2SMark Murray */ 976511b41d2SMark Murray 977af12a3e7SDag-Erling Smørgrav int 97821e764dfSDag-Erling Smørgrav read_config_file(const char *filename, const char *host, Options *options, 97921e764dfSDag-Erling Smørgrav int checkperm) 980511b41d2SMark Murray { 981511b41d2SMark Murray FILE *f; 982511b41d2SMark Murray char line[1024]; 983511b41d2SMark Murray int active, linenum; 984511b41d2SMark Murray int bad_options = 0; 985511b41d2SMark Murray 98621e764dfSDag-Erling Smørgrav if ((f = fopen(filename, "r")) == NULL) 987af12a3e7SDag-Erling Smørgrav return 0; 988511b41d2SMark Murray 98921e764dfSDag-Erling Smørgrav if (checkperm) { 99021e764dfSDag-Erling Smørgrav struct stat sb; 99121e764dfSDag-Erling Smørgrav 99221e764dfSDag-Erling Smørgrav if (fstat(fileno(f), &sb) == -1) 99321e764dfSDag-Erling Smørgrav fatal("fstat %s: %s", filename, strerror(errno)); 99421e764dfSDag-Erling Smørgrav if (((sb.st_uid != 0 && sb.st_uid != getuid()) || 99521e764dfSDag-Erling Smørgrav (sb.st_mode & 022) != 0)) 99621e764dfSDag-Erling Smørgrav fatal("Bad owner or permissions on %s", filename); 99721e764dfSDag-Erling Smørgrav } 99821e764dfSDag-Erling Smørgrav 999511b41d2SMark Murray debug("Reading configuration data %.200s", filename); 1000511b41d2SMark Murray 1001511b41d2SMark Murray /* 1002511b41d2SMark Murray * Mark that we are now processing the options. This flag is turned 1003511b41d2SMark Murray * on/off by Host specifications. 1004511b41d2SMark Murray */ 1005511b41d2SMark Murray active = 1; 1006511b41d2SMark Murray linenum = 0; 1007511b41d2SMark Murray while (fgets(line, sizeof(line), f)) { 1008511b41d2SMark Murray /* Update line number counter. */ 1009511b41d2SMark Murray linenum++; 1010511b41d2SMark Murray if (process_config_line(options, host, line, filename, linenum, &active) != 0) 1011511b41d2SMark Murray bad_options++; 1012511b41d2SMark Murray } 1013511b41d2SMark Murray fclose(f); 1014511b41d2SMark Murray if (bad_options > 0) 1015ca3176e7SBrian Feldman fatal("%s: terminating, %d bad configuration options", 1016511b41d2SMark Murray filename, bad_options); 1017af12a3e7SDag-Erling Smørgrav return 1; 1018511b41d2SMark Murray } 1019511b41d2SMark Murray 1020511b41d2SMark Murray /* 1021511b41d2SMark Murray * Initializes options to special values that indicate that they have not yet 1022511b41d2SMark Murray * been set. Read_config_file will only set options with this value. Options 1023511b41d2SMark Murray * are processed in the following order: command line, user config file, 1024511b41d2SMark Murray * system config file. Last, fill_default_options is called. 1025511b41d2SMark Murray */ 1026511b41d2SMark Murray 1027511b41d2SMark Murray void 1028511b41d2SMark Murray initialize_options(Options * options) 1029511b41d2SMark Murray { 1030511b41d2SMark Murray memset(options, 'X', sizeof(*options)); 1031511b41d2SMark Murray options->forward_agent = -1; 1032511b41d2SMark Murray options->forward_x11 = -1; 10331ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = -1; 1034333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = -1; 1035c2d3a559SKris Kennaway options->xauth_location = NULL; 1036511b41d2SMark Murray options->gateway_ports = -1; 1037511b41d2SMark Murray options->use_privileged_port = -1; 1038511b41d2SMark Murray options->rsa_authentication = -1; 1039ca3176e7SBrian Feldman options->pubkey_authentication = -1; 1040af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 1041cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = -1; 1042cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = -1; 1043511b41d2SMark Murray options->password_authentication = -1; 104409958426SBrian Feldman options->kbd_interactive_authentication = -1; 104509958426SBrian Feldman options->kbd_interactive_devices = NULL; 1046511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 1047ca3176e7SBrian Feldman options->hostbased_authentication = -1; 1048511b41d2SMark Murray options->batch_mode = -1; 1049511b41d2SMark Murray options->check_host_ip = -1; 1050511b41d2SMark Murray options->strict_host_key_checking = -1; 1051511b41d2SMark Murray options->compression = -1; 10521ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 1053511b41d2SMark Murray options->compression_level = -1; 1054511b41d2SMark Murray options->port = -1; 1055cf2b5f3bSDag-Erling Smørgrav options->address_family = -1; 1056511b41d2SMark Murray options->connection_attempts = -1; 1057cf2b5f3bSDag-Erling Smørgrav options->connection_timeout = -1; 1058511b41d2SMark Murray options->number_of_password_prompts = -1; 1059511b41d2SMark Murray options->cipher = -1; 1060e8aafc91SKris Kennaway options->ciphers = NULL; 1061ca3176e7SBrian Feldman options->macs = NULL; 1062ca3176e7SBrian Feldman options->hostkeyalgorithms = NULL; 1063e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 1064511b41d2SMark Murray options->num_identity_files = 0; 1065511b41d2SMark Murray options->hostname = NULL; 1066ca3176e7SBrian Feldman options->host_key_alias = NULL; 1067511b41d2SMark Murray options->proxy_command = NULL; 1068511b41d2SMark Murray options->user = NULL; 1069511b41d2SMark Murray options->escape_char = -1; 1070511b41d2SMark Murray options->system_hostfile = NULL; 1071511b41d2SMark Murray options->user_hostfile = NULL; 1072e8aafc91SKris Kennaway options->system_hostfile2 = NULL; 1073e8aafc91SKris Kennaway options->user_hostfile2 = NULL; 1074511b41d2SMark Murray options->num_local_forwards = 0; 1075511b41d2SMark Murray options->num_remote_forwards = 0; 1076af12a3e7SDag-Erling Smørgrav options->clear_forwardings = -1; 1077af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 1078ca3176e7SBrian Feldman options->preferred_authentications = NULL; 1079af12a3e7SDag-Erling Smørgrav options->bind_address = NULL; 1080b15c8340SDag-Erling Smørgrav options->pkcs11_provider = NULL; 1081e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = - 1; 1082af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = - 1; 10835962c0e9SDag-Erling Smørgrav options->identities_only = - 1; 1084cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = - 1; 1085cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = -1; 10861ec0d754SDag-Erling Smørgrav options->server_alive_interval = -1; 10871ec0d754SDag-Erling Smørgrav options->server_alive_count_max = -1; 108821e764dfSDag-Erling Smørgrav options->num_send_env = 0; 108921e764dfSDag-Erling Smørgrav options->control_path = NULL; 109021e764dfSDag-Erling Smørgrav options->control_master = -1; 1091aa49c926SDag-Erling Smørgrav options->hash_known_hosts = -1; 1092b74df5b2SDag-Erling Smørgrav options->tun_open = -1; 1093b74df5b2SDag-Erling Smørgrav options->tun_local = -1; 1094b74df5b2SDag-Erling Smørgrav options->tun_remote = -1; 1095b74df5b2SDag-Erling Smørgrav options->local_command = NULL; 1096b74df5b2SDag-Erling Smørgrav options->permit_local_command = -1; 10977aee6ffeSDag-Erling Smørgrav options->use_roaming = -1; 1098d4af9e69SDag-Erling Smørgrav options->visual_host_key = -1; 1099cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = -1; 1100511b41d2SMark Murray } 1101511b41d2SMark Murray 1102511b41d2SMark Murray /* 1103511b41d2SMark Murray * Called after processing other sources of option data, this fills those 1104511b41d2SMark Murray * options for which no value has been specified with their default values. 1105511b41d2SMark Murray */ 1106511b41d2SMark Murray 1107511b41d2SMark Murray void 1108511b41d2SMark Murray fill_default_options(Options * options) 1109511b41d2SMark Murray { 1110ca3176e7SBrian Feldman int len; 1111ca3176e7SBrian Feldman 1112511b41d2SMark Murray if (options->forward_agent == -1) 1113db1cb46cSKris Kennaway options->forward_agent = 0; 1114511b41d2SMark Murray if (options->forward_x11 == -1) 11155dc73ebeSBrian Feldman options->forward_x11 = 0; 11161ec0d754SDag-Erling Smørgrav if (options->forward_x11_trusted == -1) 11171ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = 0; 1118333ee039SDag-Erling Smørgrav if (options->exit_on_forward_failure == -1) 1119333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = 0; 1120c2d3a559SKris Kennaway if (options->xauth_location == NULL) 1121af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 1122511b41d2SMark Murray if (options->gateway_ports == -1) 1123511b41d2SMark Murray options->gateway_ports = 0; 1124511b41d2SMark Murray if (options->use_privileged_port == -1) 1125ca3176e7SBrian Feldman options->use_privileged_port = 0; 1126511b41d2SMark Murray if (options->rsa_authentication == -1) 1127511b41d2SMark Murray options->rsa_authentication = 1; 1128ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 1129ca3176e7SBrian Feldman options->pubkey_authentication = 1; 1130af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 1131af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = 1; 1132cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 11331ec0d754SDag-Erling Smørgrav options->gss_authentication = 0; 1134cf2b5f3bSDag-Erling Smørgrav if (options->gss_deleg_creds == -1) 1135cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = 0; 1136511b41d2SMark Murray if (options->password_authentication == -1) 1137511b41d2SMark Murray options->password_authentication = 1; 113809958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 1139ca3176e7SBrian Feldman options->kbd_interactive_authentication = 1; 1140511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 114180628bacSDag-Erling Smørgrav options->rhosts_rsa_authentication = 0; 1142ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 1143ca3176e7SBrian Feldman options->hostbased_authentication = 0; 1144511b41d2SMark Murray if (options->batch_mode == -1) 1145511b41d2SMark Murray options->batch_mode = 0; 1146511b41d2SMark Murray if (options->check_host_ip == -1) 1147975616f0SDag-Erling Smørgrav options->check_host_ip = 0; 1148511b41d2SMark Murray if (options->strict_host_key_checking == -1) 1149511b41d2SMark Murray options->strict_host_key_checking = 2; /* 2 is default */ 1150511b41d2SMark Murray if (options->compression == -1) 1151511b41d2SMark Murray options->compression = 0; 11521ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 11531ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 1154511b41d2SMark Murray if (options->compression_level == -1) 1155511b41d2SMark Murray options->compression_level = 6; 1156511b41d2SMark Murray if (options->port == -1) 1157511b41d2SMark Murray options->port = 0; /* Filled in ssh_connect. */ 1158cf2b5f3bSDag-Erling Smørgrav if (options->address_family == -1) 1159cf2b5f3bSDag-Erling Smørgrav options->address_family = AF_UNSPEC; 1160511b41d2SMark Murray if (options->connection_attempts == -1) 1161af12a3e7SDag-Erling Smørgrav options->connection_attempts = 1; 1162511b41d2SMark Murray if (options->number_of_password_prompts == -1) 1163511b41d2SMark Murray options->number_of_password_prompts = 3; 1164511b41d2SMark Murray /* Selected in ssh_login(). */ 1165511b41d2SMark Murray if (options->cipher == -1) 1166511b41d2SMark Murray options->cipher = SSH_CIPHER_NOT_SET; 1167e8aafc91SKris Kennaway /* options->ciphers, default set in myproposals.h */ 1168ca3176e7SBrian Feldman /* options->macs, default set in myproposals.h */ 1169ca3176e7SBrian Feldman /* options->hostkeyalgorithms, default set in myproposals.h */ 1170e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 1171b15c8340SDag-Erling Smørgrav options->protocol = SSH_PROTO_2; 1172511b41d2SMark Murray if (options->num_identity_files == 0) { 1173ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) { 1174ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 1175ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1176ca3176e7SBrian Feldman xmalloc(len); 1177ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1178ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 1179511b41d2SMark Murray } 1180ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_2) { 1181ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 1182ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1183ca3176e7SBrian Feldman xmalloc(len); 1184ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1185ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 1186ca3176e7SBrian Feldman 1187ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 1188ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1189ca3176e7SBrian Feldman xmalloc(len); 1190ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1191ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 1192ca3176e7SBrian Feldman } 1193e8aafc91SKris Kennaway } 1194511b41d2SMark Murray if (options->escape_char == -1) 1195511b41d2SMark Murray options->escape_char = '~'; 1196511b41d2SMark Murray if (options->system_hostfile == NULL) 1197ca3176e7SBrian Feldman options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 1198511b41d2SMark Murray if (options->user_hostfile == NULL) 1199ca3176e7SBrian Feldman options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 1200e8aafc91SKris Kennaway if (options->system_hostfile2 == NULL) 1201ca3176e7SBrian Feldman options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 1202e8aafc91SKris Kennaway if (options->user_hostfile2 == NULL) 1203ca3176e7SBrian Feldman options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 1204af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1205511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 1206af12a3e7SDag-Erling Smørgrav if (options->clear_forwardings == 1) 1207af12a3e7SDag-Erling Smørgrav clear_forwardings(options); 1208af12a3e7SDag-Erling Smørgrav if (options->no_host_authentication_for_localhost == - 1) 1209af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = 0; 12105962c0e9SDag-Erling Smørgrav if (options->identities_only == -1) 12115962c0e9SDag-Erling Smørgrav options->identities_only = 0; 1212e73e9afaSDag-Erling Smørgrav if (options->enable_ssh_keysign == -1) 1213e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = 0; 1214cf2b5f3bSDag-Erling Smørgrav if (options->rekey_limit == -1) 1215cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = 0; 1216cf2b5f3bSDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 1217cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = 0; 12181ec0d754SDag-Erling Smørgrav if (options->server_alive_interval == -1) 12191ec0d754SDag-Erling Smørgrav options->server_alive_interval = 0; 12201ec0d754SDag-Erling Smørgrav if (options->server_alive_count_max == -1) 12211ec0d754SDag-Erling Smørgrav options->server_alive_count_max = 3; 122221e764dfSDag-Erling Smørgrav if (options->control_master == -1) 122321e764dfSDag-Erling Smørgrav options->control_master = 0; 1224aa49c926SDag-Erling Smørgrav if (options->hash_known_hosts == -1) 1225aa49c926SDag-Erling Smørgrav options->hash_known_hosts = 0; 1226b74df5b2SDag-Erling Smørgrav if (options->tun_open == -1) 1227b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 1228b74df5b2SDag-Erling Smørgrav if (options->tun_local == -1) 1229b74df5b2SDag-Erling Smørgrav options->tun_local = SSH_TUNID_ANY; 1230b74df5b2SDag-Erling Smørgrav if (options->tun_remote == -1) 1231b74df5b2SDag-Erling Smørgrav options->tun_remote = SSH_TUNID_ANY; 1232b74df5b2SDag-Erling Smørgrav if (options->permit_local_command == -1) 1233b74df5b2SDag-Erling Smørgrav options->permit_local_command = 0; 12347aee6ffeSDag-Erling Smørgrav if (options->use_roaming == -1) 12357aee6ffeSDag-Erling Smørgrav options->use_roaming = 1; 1236d4af9e69SDag-Erling Smørgrav if (options->visual_host_key == -1) 1237d4af9e69SDag-Erling Smørgrav options->visual_host_key = 0; 1238cce7d346SDag-Erling Smørgrav if (options->zero_knowledge_password_authentication == -1) 1239cce7d346SDag-Erling Smørgrav options->zero_knowledge_password_authentication = 0; 1240b74df5b2SDag-Erling Smørgrav /* options->local_command should not be set by default */ 1241511b41d2SMark Murray /* options->proxy_command should not be set by default */ 1242511b41d2SMark Murray /* options->user will be set in the main program if appropriate */ 1243511b41d2SMark Murray /* options->hostname will be set in the main program if appropriate */ 1244ca3176e7SBrian Feldman /* options->host_key_alias should not be set by default */ 1245ca3176e7SBrian Feldman /* options->preferred_authentications will be set in ssh */ 1246511b41d2SMark Murray } 1247aa49c926SDag-Erling Smørgrav 1248aa49c926SDag-Erling Smørgrav /* 1249aa49c926SDag-Erling Smørgrav * parse_forward 1250aa49c926SDag-Erling Smørgrav * parses a string containing a port forwarding specification of the form: 1251cce7d346SDag-Erling Smørgrav * dynamicfwd == 0 1252aa49c926SDag-Erling Smørgrav * [listenhost:]listenport:connecthost:connectport 1253cce7d346SDag-Erling Smørgrav * dynamicfwd == 1 1254cce7d346SDag-Erling Smørgrav * [listenhost:]listenport 1255aa49c926SDag-Erling Smørgrav * returns number of arguments parsed or zero on error 1256aa49c926SDag-Erling Smørgrav */ 1257aa49c926SDag-Erling Smørgrav int 1258cce7d346SDag-Erling Smørgrav parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1259aa49c926SDag-Erling Smørgrav { 1260aa49c926SDag-Erling Smørgrav int i; 1261aa49c926SDag-Erling Smørgrav char *p, *cp, *fwdarg[4]; 1262aa49c926SDag-Erling Smørgrav 1263aa49c926SDag-Erling Smørgrav memset(fwd, '\0', sizeof(*fwd)); 1264aa49c926SDag-Erling Smørgrav 1265aa49c926SDag-Erling Smørgrav cp = p = xstrdup(fwdspec); 1266aa49c926SDag-Erling Smørgrav 1267aa49c926SDag-Erling Smørgrav /* skip leading spaces */ 1268d4af9e69SDag-Erling Smørgrav while (isspace(*cp)) 1269aa49c926SDag-Erling Smørgrav cp++; 1270aa49c926SDag-Erling Smørgrav 1271aa49c926SDag-Erling Smørgrav for (i = 0; i < 4; ++i) 1272aa49c926SDag-Erling Smørgrav if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1273aa49c926SDag-Erling Smørgrav break; 1274aa49c926SDag-Erling Smørgrav 1275cce7d346SDag-Erling Smørgrav /* Check for trailing garbage */ 1276aa49c926SDag-Erling Smørgrav if (cp != NULL) 1277aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1278aa49c926SDag-Erling Smørgrav 1279aa49c926SDag-Erling Smørgrav switch (i) { 1280cce7d346SDag-Erling Smørgrav case 1: 1281cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1282cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1283cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1284cce7d346SDag-Erling Smørgrav break; 1285cce7d346SDag-Erling Smørgrav 1286cce7d346SDag-Erling Smørgrav case 2: 1287cce7d346SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1288cce7d346SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1289cce7d346SDag-Erling Smørgrav fwd->connect_host = xstrdup("socks"); 1290cce7d346SDag-Erling Smørgrav break; 1291cce7d346SDag-Erling Smørgrav 1292aa49c926SDag-Erling Smørgrav case 3: 1293aa49c926SDag-Erling Smørgrav fwd->listen_host = NULL; 1294aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1295aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1296aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[2]); 1297aa49c926SDag-Erling Smørgrav break; 1298aa49c926SDag-Erling Smørgrav 1299aa49c926SDag-Erling Smørgrav case 4: 1300aa49c926SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1301aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1302aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1303aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[3]); 1304aa49c926SDag-Erling Smørgrav break; 1305aa49c926SDag-Erling Smørgrav default: 1306aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1307aa49c926SDag-Erling Smørgrav } 1308aa49c926SDag-Erling Smørgrav 1309aa49c926SDag-Erling Smørgrav xfree(p); 1310aa49c926SDag-Erling Smørgrav 1311cce7d346SDag-Erling Smørgrav if (dynamicfwd) { 1312cce7d346SDag-Erling Smørgrav if (!(i == 1 || i == 2)) 1313cce7d346SDag-Erling Smørgrav goto fail_free; 1314cce7d346SDag-Erling Smørgrav } else { 1315cce7d346SDag-Erling Smørgrav if (!(i == 3 || i == 4)) 1316cce7d346SDag-Erling Smørgrav goto fail_free; 1317cce7d346SDag-Erling Smørgrav if (fwd->connect_port <= 0) 1318cce7d346SDag-Erling Smørgrav goto fail_free; 1319cce7d346SDag-Erling Smørgrav } 1320cce7d346SDag-Erling Smørgrav 1321cce7d346SDag-Erling Smørgrav if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1322aa49c926SDag-Erling Smørgrav goto fail_free; 1323aa49c926SDag-Erling Smørgrav 1324aa49c926SDag-Erling Smørgrav if (fwd->connect_host != NULL && 1325aa49c926SDag-Erling Smørgrav strlen(fwd->connect_host) >= NI_MAXHOST) 1326aa49c926SDag-Erling Smørgrav goto fail_free; 1327cce7d346SDag-Erling Smørgrav if (fwd->listen_host != NULL && 1328cce7d346SDag-Erling Smørgrav strlen(fwd->listen_host) >= NI_MAXHOST) 1329cce7d346SDag-Erling Smørgrav goto fail_free; 1330cce7d346SDag-Erling Smørgrav 1331aa49c926SDag-Erling Smørgrav 1332aa49c926SDag-Erling Smørgrav return (i); 1333aa49c926SDag-Erling Smørgrav 1334aa49c926SDag-Erling Smørgrav fail_free: 1335cce7d346SDag-Erling Smørgrav if (fwd->connect_host != NULL) { 1336aa49c926SDag-Erling Smørgrav xfree(fwd->connect_host); 1337cce7d346SDag-Erling Smørgrav fwd->connect_host = NULL; 1338cce7d346SDag-Erling Smørgrav } 1339cce7d346SDag-Erling Smørgrav if (fwd->listen_host != NULL) { 1340aa49c926SDag-Erling Smørgrav xfree(fwd->listen_host); 1341cce7d346SDag-Erling Smørgrav fwd->listen_host = NULL; 1342cce7d346SDag-Erling Smørgrav } 1343aa49c926SDag-Erling Smørgrav return (0); 1344aa49c926SDag-Erling Smørgrav } 1345