1d4af9e69SDag-Erling Smørgrav /* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk 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" 47511b41d2SMark Murray 48511b41d2SMark Murray /* Format of the configuration file: 49511b41d2SMark Murray 50511b41d2SMark Murray # Configuration data is parsed as follows: 51511b41d2SMark Murray # 1. command line options 52511b41d2SMark Murray # 2. user-specific file 53511b41d2SMark Murray # 3. system-wide file 54511b41d2SMark Murray # Any configuration value is only changed the first time it is set. 55511b41d2SMark Murray # Thus, host-specific definitions should be at the beginning of the 56511b41d2SMark Murray # configuration file, and defaults at the end. 57511b41d2SMark Murray 58511b41d2SMark Murray # Host-specific declarations. These may override anything above. A single 59511b41d2SMark Murray # host may match multiple declarations; these are processed in the order 60511b41d2SMark Murray # that they are given in. 61511b41d2SMark Murray 62511b41d2SMark Murray Host *.ngs.fi ngs.fi 6380628bacSDag-Erling Smørgrav User foo 64511b41d2SMark Murray 65511b41d2SMark Murray Host fake.com 66511b41d2SMark Murray HostName another.host.name.real.org 67511b41d2SMark Murray User blaah 68511b41d2SMark Murray Port 34289 69511b41d2SMark Murray ForwardX11 no 70511b41d2SMark Murray ForwardAgent no 71511b41d2SMark Murray 72511b41d2SMark Murray Host books.com 73511b41d2SMark Murray RemoteForward 9999 shadows.cs.hut.fi:9999 74511b41d2SMark Murray Cipher 3des 75511b41d2SMark Murray 76511b41d2SMark Murray Host fascist.blob.com 77511b41d2SMark Murray Port 23123 78511b41d2SMark Murray User tylonen 79511b41d2SMark Murray PasswordAuthentication no 80511b41d2SMark Murray 81511b41d2SMark Murray Host puukko.hut.fi 82511b41d2SMark Murray User t35124p 83511b41d2SMark Murray ProxyCommand ssh-proxy %h %p 84511b41d2SMark Murray 85511b41d2SMark Murray Host *.fr 8680628bacSDag-Erling Smørgrav PublicKeyAuthentication no 87511b41d2SMark Murray 88511b41d2SMark Murray Host *.su 89511b41d2SMark Murray Cipher none 90511b41d2SMark Murray PasswordAuthentication no 91511b41d2SMark Murray 92b74df5b2SDag-Erling Smørgrav Host vpn.fake.com 93b74df5b2SDag-Erling Smørgrav Tunnel yes 94b74df5b2SDag-Erling Smørgrav TunnelDevice 3 95b74df5b2SDag-Erling Smørgrav 96511b41d2SMark Murray # Defaults for various options 97511b41d2SMark Murray Host * 98511b41d2SMark Murray ForwardAgent no 99ca3176e7SBrian Feldman ForwardX11 no 100511b41d2SMark Murray PasswordAuthentication yes 101511b41d2SMark Murray RSAAuthentication yes 102511b41d2SMark Murray RhostsRSAAuthentication yes 103511b41d2SMark Murray StrictHostKeyChecking yes 1041ec0d754SDag-Erling Smørgrav TcpKeepAlive no 105511b41d2SMark Murray IdentityFile ~/.ssh/identity 106511b41d2SMark Murray Port 22 107511b41d2SMark Murray EscapeChar ~ 108511b41d2SMark Murray 109511b41d2SMark Murray */ 110511b41d2SMark Murray 111511b41d2SMark Murray /* Keyword tokens. */ 112511b41d2SMark Murray 113511b41d2SMark Murray typedef enum { 114511b41d2SMark Murray oBadOption, 1151ec0d754SDag-Erling Smørgrav oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, 116333ee039SDag-Erling Smørgrav oExitOnForwardFailure, 11780628bacSDag-Erling Smørgrav oPasswordAuthentication, oRSAAuthentication, 118ca3176e7SBrian Feldman oChallengeResponseAuthentication, oXAuthLocation, 119511b41d2SMark Murray oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 120511b41d2SMark Murray oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 121511b41d2SMark Murray oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 122511b41d2SMark Murray oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1231ec0d754SDag-Erling Smørgrav oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 124ca3176e7SBrian Feldman oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 125ca3176e7SBrian Feldman oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 126ca3176e7SBrian Feldman oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 127ca3176e7SBrian Feldman oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 128af12a3e7SDag-Erling Smørgrav oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 1299e2cbe04SDag-Erling Smørgrav oClearAllForwardings, oNoHostAuthenticationForLocalhost, 130cf2b5f3bSDag-Erling Smørgrav oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 131cf2b5f3bSDag-Erling Smørgrav oAddressFamily, oGssAuthentication, oGssDelegateCreds, 1325962c0e9SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 133aa49c926SDag-Erling Smørgrav oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, 134b74df5b2SDag-Erling Smørgrav oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 135d4af9e69SDag-Erling Smørgrav oVisualHostKey, 136cfa59440SDag-Erling Smørgrav oVersionAddendum, 137cf2b5f3bSDag-Erling Smørgrav oDeprecated, oUnsupported 138511b41d2SMark Murray } OpCodes; 139511b41d2SMark Murray 140511b41d2SMark Murray /* Textual representations of the tokens. */ 141511b41d2SMark Murray 142511b41d2SMark Murray static struct { 143511b41d2SMark Murray const char *name; 144511b41d2SMark Murray OpCodes opcode; 145511b41d2SMark Murray } keywords[] = { 146511b41d2SMark Murray { "forwardagent", oForwardAgent }, 147511b41d2SMark Murray { "forwardx11", oForwardX11 }, 1481ec0d754SDag-Erling Smørgrav { "forwardx11trusted", oForwardX11Trusted }, 149333ee039SDag-Erling Smørgrav { "exitonforwardfailure", oExitOnForwardFailure }, 150c2d3a559SKris Kennaway { "xauthlocation", oXAuthLocation }, 151511b41d2SMark Murray { "gatewayports", oGatewayPorts }, 152511b41d2SMark Murray { "useprivilegedport", oUsePrivilegedPort }, 153cf2b5f3bSDag-Erling Smørgrav { "rhostsauthentication", oDeprecated }, 154511b41d2SMark Murray { "passwordauthentication", oPasswordAuthentication }, 15509958426SBrian Feldman { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 15609958426SBrian Feldman { "kbdinteractivedevices", oKbdInteractiveDevices }, 157511b41d2SMark Murray { "rsaauthentication", oRSAAuthentication }, 158ca3176e7SBrian Feldman { "pubkeyauthentication", oPubkeyAuthentication }, 159ca3176e7SBrian Feldman { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 160ca3176e7SBrian Feldman { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 161ca3176e7SBrian Feldman { "hostbasedauthentication", oHostbasedAuthentication }, 162ca3176e7SBrian Feldman { "challengeresponseauthentication", oChallengeResponseAuthentication }, 163ca3176e7SBrian Feldman { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 164ca3176e7SBrian Feldman { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 165cf2b5f3bSDag-Erling Smørgrav { "kerberosauthentication", oUnsupported }, 166cf2b5f3bSDag-Erling Smørgrav { "kerberostgtpassing", oUnsupported }, 167cf2b5f3bSDag-Erling Smørgrav { "afstokenpassing", oUnsupported }, 168cf2b5f3bSDag-Erling Smørgrav #if defined(GSSAPI) 169cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oGssAuthentication }, 170cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oGssDelegateCreds }, 171cf2b5f3bSDag-Erling Smørgrav #else 172cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oUnsupported }, 173cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oUnsupported }, 174511b41d2SMark Murray #endif 17580628bacSDag-Erling Smørgrav { "fallbacktorsh", oDeprecated }, 17680628bacSDag-Erling Smørgrav { "usersh", oDeprecated }, 177511b41d2SMark Murray { "identityfile", oIdentityFile }, 178ca3176e7SBrian Feldman { "identityfile2", oIdentityFile }, /* alias */ 1795962c0e9SDag-Erling Smørgrav { "identitiesonly", oIdentitiesOnly }, 180511b41d2SMark Murray { "hostname", oHostName }, 181ca3176e7SBrian Feldman { "hostkeyalias", oHostKeyAlias }, 182511b41d2SMark Murray { "proxycommand", oProxyCommand }, 183511b41d2SMark Murray { "port", oPort }, 184511b41d2SMark Murray { "cipher", oCipher }, 185e8aafc91SKris Kennaway { "ciphers", oCiphers }, 186ca3176e7SBrian Feldman { "macs", oMacs }, 187e8aafc91SKris Kennaway { "protocol", oProtocol }, 188511b41d2SMark Murray { "remoteforward", oRemoteForward }, 189511b41d2SMark Murray { "localforward", oLocalForward }, 190511b41d2SMark Murray { "user", oUser }, 191511b41d2SMark Murray { "host", oHost }, 192511b41d2SMark Murray { "escapechar", oEscapeChar }, 193511b41d2SMark Murray { "globalknownhostsfile", oGlobalKnownHostsFile }, 194af12a3e7SDag-Erling Smørgrav { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ 195e8aafc91SKris Kennaway { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 196af12a3e7SDag-Erling Smørgrav { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 197511b41d2SMark Murray { "connectionattempts", oConnectionAttempts }, 198511b41d2SMark Murray { "batchmode", oBatchMode }, 199511b41d2SMark Murray { "checkhostip", oCheckHostIP }, 200511b41d2SMark Murray { "stricthostkeychecking", oStrictHostKeyChecking }, 201511b41d2SMark Murray { "compression", oCompression }, 202511b41d2SMark Murray { "compressionlevel", oCompressionLevel }, 2031ec0d754SDag-Erling Smørgrav { "tcpkeepalive", oTCPKeepAlive }, 2041ec0d754SDag-Erling Smørgrav { "keepalive", oTCPKeepAlive }, /* obsolete */ 205511b41d2SMark Murray { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 206511b41d2SMark Murray { "loglevel", oLogLevel }, 207ca3176e7SBrian Feldman { "dynamicforward", oDynamicForward }, 208ca3176e7SBrian Feldman { "preferredauthentications", oPreferredAuthentications }, 209ca3176e7SBrian Feldman { "hostkeyalgorithms", oHostKeyAlgorithms }, 210af12a3e7SDag-Erling Smørgrav { "bindaddress", oBindAddress }, 211cf2b5f3bSDag-Erling Smørgrav #ifdef SMARTCARD 212af12a3e7SDag-Erling Smørgrav { "smartcarddevice", oSmartcardDevice }, 213cf2b5f3bSDag-Erling Smørgrav #else 214cf2b5f3bSDag-Erling Smørgrav { "smartcarddevice", oUnsupported }, 215cf2b5f3bSDag-Erling Smørgrav #endif 216af12a3e7SDag-Erling Smørgrav { "clearallforwardings", oClearAllForwardings }, 217e73e9afaSDag-Erling Smørgrav { "enablesshkeysign", oEnableSSHKeysign }, 218cf2b5f3bSDag-Erling Smørgrav { "verifyhostkeydns", oVerifyHostKeyDNS }, 219af12a3e7SDag-Erling Smørgrav { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 220cf2b5f3bSDag-Erling Smørgrav { "rekeylimit", oRekeyLimit }, 221cf2b5f3bSDag-Erling Smørgrav { "connecttimeout", oConnectTimeout }, 222cf2b5f3bSDag-Erling Smørgrav { "addressfamily", oAddressFamily }, 2231ec0d754SDag-Erling Smørgrav { "serveraliveinterval", oServerAliveInterval }, 2241ec0d754SDag-Erling Smørgrav { "serveralivecountmax", oServerAliveCountMax }, 22521e764dfSDag-Erling Smørgrav { "sendenv", oSendEnv }, 22621e764dfSDag-Erling Smørgrav { "controlpath", oControlPath }, 22721e764dfSDag-Erling Smørgrav { "controlmaster", oControlMaster }, 228aa49c926SDag-Erling Smørgrav { "hashknownhosts", oHashKnownHosts }, 229b74df5b2SDag-Erling Smørgrav { "tunnel", oTunnel }, 230b74df5b2SDag-Erling Smørgrav { "tunneldevice", oTunnelDevice }, 231b74df5b2SDag-Erling Smørgrav { "localcommand", oLocalCommand }, 232b74df5b2SDag-Erling Smørgrav { "permitlocalcommand", oPermitLocalCommand }, 233d4af9e69SDag-Erling Smørgrav { "visualhostkey", oVisualHostKey }, 234975616f0SDag-Erling Smørgrav { "versionaddendum", oVersionAddendum }, 235af12a3e7SDag-Erling Smørgrav { NULL, oBadOption } 236511b41d2SMark Murray }; 237511b41d2SMark Murray 238511b41d2SMark Murray /* 239511b41d2SMark Murray * Adds a local TCP/IP port forward to options. Never returns if there is an 240511b41d2SMark Murray * error. 241511b41d2SMark Murray */ 242511b41d2SMark Murray 243511b41d2SMark Murray void 244aa49c926SDag-Erling Smørgrav add_local_forward(Options *options, const Forward *newfwd) 245511b41d2SMark Murray { 246511b41d2SMark Murray Forward *fwd; 247f388f5efSDag-Erling Smørgrav #ifndef NO_IPPORT_RESERVED_CONCEPT 248511b41d2SMark Murray extern uid_t original_real_uid; 24903f6c5cdSDag-Erling Smørgrav int ipport_reserved; 25003f6c5cdSDag-Erling Smørgrav #ifdef __FreeBSD__ 25103f6c5cdSDag-Erling Smørgrav size_t len_ipport_reserved = sizeof(ipport_reserved); 25203f6c5cdSDag-Erling Smørgrav 25303f6c5cdSDag-Erling Smørgrav if (sysctlbyname("net.inet.ip.portrange.reservedhigh", 25403f6c5cdSDag-Erling Smørgrav &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) 25503f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 25603f6c5cdSDag-Erling Smørgrav else 25703f6c5cdSDag-Erling Smørgrav ipport_reserved++; 25803f6c5cdSDag-Erling Smørgrav #else 25903f6c5cdSDag-Erling Smørgrav ipport_reserved = IPPORT_RESERVED; 26003f6c5cdSDag-Erling Smørgrav #endif 26103f6c5cdSDag-Erling Smørgrav if (newfwd->listen_port < ipport_reserved && original_real_uid != 0) 262ca3176e7SBrian Feldman fatal("Privileged ports can only be forwarded by root."); 263989dd127SDag-Erling Smørgrav #endif 264511b41d2SMark Murray if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 265511b41d2SMark Murray fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 266511b41d2SMark Murray fwd = &options->local_forwards[options->num_local_forwards++]; 267aa49c926SDag-Erling Smørgrav 268aa49c926SDag-Erling Smørgrav fwd->listen_host = (newfwd->listen_host == NULL) ? 269aa49c926SDag-Erling Smørgrav NULL : xstrdup(newfwd->listen_host); 270aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 271aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(newfwd->connect_host); 272aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 273511b41d2SMark Murray } 274511b41d2SMark Murray 275511b41d2SMark Murray /* 276511b41d2SMark Murray * Adds a remote TCP/IP port forward to options. Never returns if there is 277511b41d2SMark Murray * an error. 278511b41d2SMark Murray */ 279511b41d2SMark Murray 280511b41d2SMark Murray void 281aa49c926SDag-Erling Smørgrav add_remote_forward(Options *options, const Forward *newfwd) 282511b41d2SMark Murray { 283511b41d2SMark Murray Forward *fwd; 284511b41d2SMark Murray if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 285511b41d2SMark Murray fatal("Too many remote forwards (max %d).", 286511b41d2SMark Murray SSH_MAX_FORWARDS_PER_DIRECTION); 287511b41d2SMark Murray fwd = &options->remote_forwards[options->num_remote_forwards++]; 288aa49c926SDag-Erling Smørgrav 289aa49c926SDag-Erling Smørgrav fwd->listen_host = (newfwd->listen_host == NULL) ? 290aa49c926SDag-Erling Smørgrav NULL : xstrdup(newfwd->listen_host); 291aa49c926SDag-Erling Smørgrav fwd->listen_port = newfwd->listen_port; 292aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(newfwd->connect_host); 293aa49c926SDag-Erling Smørgrav fwd->connect_port = newfwd->connect_port; 294511b41d2SMark Murray } 295511b41d2SMark Murray 296af12a3e7SDag-Erling Smørgrav static void 297af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options) 298af12a3e7SDag-Erling Smørgrav { 299af12a3e7SDag-Erling Smørgrav int i; 300af12a3e7SDag-Erling Smørgrav 301aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_local_forwards; i++) { 302aa49c926SDag-Erling Smørgrav if (options->local_forwards[i].listen_host != NULL) 303aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].listen_host); 304aa49c926SDag-Erling Smørgrav xfree(options->local_forwards[i].connect_host); 305aa49c926SDag-Erling Smørgrav } 306af12a3e7SDag-Erling Smørgrav options->num_local_forwards = 0; 307aa49c926SDag-Erling Smørgrav for (i = 0; i < options->num_remote_forwards; i++) { 308aa49c926SDag-Erling Smørgrav if (options->remote_forwards[i].listen_host != NULL) 309aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].listen_host); 310aa49c926SDag-Erling Smørgrav xfree(options->remote_forwards[i].connect_host); 311aa49c926SDag-Erling Smørgrav } 312af12a3e7SDag-Erling Smørgrav options->num_remote_forwards = 0; 313b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 314af12a3e7SDag-Erling Smørgrav } 315af12a3e7SDag-Erling Smørgrav 316511b41d2SMark Murray /* 317ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or oBadOption. 318511b41d2SMark Murray */ 319511b41d2SMark Murray 320511b41d2SMark Murray static OpCodes 321511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum) 322511b41d2SMark Murray { 323ca3176e7SBrian Feldman u_int i; 324511b41d2SMark Murray 325511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 326511b41d2SMark Murray if (strcasecmp(cp, keywords[i].name) == 0) 327511b41d2SMark Murray return keywords[i].opcode; 328511b41d2SMark Murray 329ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 330511b41d2SMark Murray filename, linenum, cp); 331511b41d2SMark Murray return oBadOption; 332511b41d2SMark Murray } 333511b41d2SMark Murray 334511b41d2SMark Murray /* 335511b41d2SMark Murray * Processes a single option line as used in the configuration files. This 336511b41d2SMark Murray * only sets those values that have not already been set. 337511b41d2SMark Murray */ 338e73e9afaSDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 339511b41d2SMark Murray 340511b41d2SMark Murray int 341511b41d2SMark Murray process_config_line(Options *options, const char *host, 342511b41d2SMark Murray char *line, const char *filename, int linenum, 343511b41d2SMark Murray int *activep) 344511b41d2SMark Murray { 345aa49c926SDag-Erling Smørgrav char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; 346333ee039SDag-Erling Smørgrav int opcode, *intptr, value, value2, scale; 347d4af9e69SDag-Erling Smørgrav LogLevel *log_level_ptr; 348333ee039SDag-Erling Smørgrav long long orig, val64; 349e73e9afaSDag-Erling Smørgrav size_t len; 350aa49c926SDag-Erling Smørgrav Forward fwd; 351511b41d2SMark Murray 352cf2b5f3bSDag-Erling Smørgrav /* Strip trailing whitespace */ 353cf2b5f3bSDag-Erling Smørgrav for (len = strlen(line) - 1; len > 0; len--) { 354cf2b5f3bSDag-Erling Smørgrav if (strchr(WHITESPACE, line[len]) == NULL) 355cf2b5f3bSDag-Erling Smørgrav break; 356cf2b5f3bSDag-Erling Smørgrav line[len] = '\0'; 357cf2b5f3bSDag-Erling Smørgrav } 358cf2b5f3bSDag-Erling Smørgrav 359c2d3a559SKris Kennaway s = line; 360c2d3a559SKris Kennaway /* Get the keyword. (Each line is supposed to begin with a keyword). */ 361333ee039SDag-Erling Smørgrav if ((keyword = strdelim(&s)) == NULL) 362333ee039SDag-Erling Smørgrav return 0; 363c2d3a559SKris Kennaway /* Ignore leading whitespace. */ 364c2d3a559SKris Kennaway if (*keyword == '\0') 365c2d3a559SKris Kennaway keyword = strdelim(&s); 366ca3176e7SBrian Feldman if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 367511b41d2SMark Murray return 0; 368511b41d2SMark Murray 369c2d3a559SKris Kennaway opcode = parse_token(keyword, filename, linenum); 370511b41d2SMark Murray 371511b41d2SMark Murray switch (opcode) { 372511b41d2SMark Murray case oBadOption: 373511b41d2SMark Murray /* don't panic, but count bad options */ 374511b41d2SMark Murray return -1; 375511b41d2SMark Murray /* NOTREACHED */ 376cf2b5f3bSDag-Erling Smørgrav case oConnectTimeout: 377cf2b5f3bSDag-Erling Smørgrav intptr = &options->connection_timeout; 3781ec0d754SDag-Erling Smørgrav parse_time: 379cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 380cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 381cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: missing time value.", 382cf2b5f3bSDag-Erling Smørgrav filename, linenum); 383cf2b5f3bSDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 384cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 385cf2b5f3bSDag-Erling Smørgrav filename, linenum); 386d4af9e69SDag-Erling Smørgrav if (*activep && *intptr == -1) 387cf2b5f3bSDag-Erling Smørgrav *intptr = value; 388cf2b5f3bSDag-Erling Smørgrav break; 389cf2b5f3bSDag-Erling Smørgrav 390511b41d2SMark Murray case oForwardAgent: 391511b41d2SMark Murray intptr = &options->forward_agent; 392511b41d2SMark Murray parse_flag: 393c2d3a559SKris Kennaway arg = strdelim(&s); 394c2d3a559SKris Kennaway if (!arg || *arg == '\0') 395511b41d2SMark Murray fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 396511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 397c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 398511b41d2SMark Murray value = 1; 399c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 400511b41d2SMark Murray value = 0; 401511b41d2SMark Murray else 402511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 403511b41d2SMark Murray if (*activep && *intptr == -1) 404511b41d2SMark Murray *intptr = value; 405511b41d2SMark Murray break; 406511b41d2SMark Murray 407511b41d2SMark Murray case oForwardX11: 408511b41d2SMark Murray intptr = &options->forward_x11; 409511b41d2SMark Murray goto parse_flag; 410511b41d2SMark Murray 4111ec0d754SDag-Erling Smørgrav case oForwardX11Trusted: 4121ec0d754SDag-Erling Smørgrav intptr = &options->forward_x11_trusted; 4131ec0d754SDag-Erling Smørgrav goto parse_flag; 4141ec0d754SDag-Erling Smørgrav 415511b41d2SMark Murray case oGatewayPorts: 416511b41d2SMark Murray intptr = &options->gateway_ports; 417511b41d2SMark Murray goto parse_flag; 418511b41d2SMark Murray 419333ee039SDag-Erling Smørgrav case oExitOnForwardFailure: 420333ee039SDag-Erling Smørgrav intptr = &options->exit_on_forward_failure; 421333ee039SDag-Erling Smørgrav goto parse_flag; 422333ee039SDag-Erling Smørgrav 423511b41d2SMark Murray case oUsePrivilegedPort: 424511b41d2SMark Murray intptr = &options->use_privileged_port; 425511b41d2SMark Murray goto parse_flag; 426511b41d2SMark Murray 427511b41d2SMark Murray case oPasswordAuthentication: 428511b41d2SMark Murray intptr = &options->password_authentication; 429511b41d2SMark Murray goto parse_flag; 430511b41d2SMark Murray 43109958426SBrian Feldman case oKbdInteractiveAuthentication: 43209958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 43309958426SBrian Feldman goto parse_flag; 43409958426SBrian Feldman 43509958426SBrian Feldman case oKbdInteractiveDevices: 43609958426SBrian Feldman charptr = &options->kbd_interactive_devices; 43709958426SBrian Feldman goto parse_string; 43809958426SBrian Feldman 439ca3176e7SBrian Feldman case oPubkeyAuthentication: 440ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 441e8aafc91SKris Kennaway goto parse_flag; 442e8aafc91SKris Kennaway 443511b41d2SMark Murray case oRSAAuthentication: 444511b41d2SMark Murray intptr = &options->rsa_authentication; 445511b41d2SMark Murray goto parse_flag; 446511b41d2SMark Murray 447511b41d2SMark Murray case oRhostsRSAAuthentication: 448511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 449511b41d2SMark Murray goto parse_flag; 450511b41d2SMark Murray 451ca3176e7SBrian Feldman case oHostbasedAuthentication: 452ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 453511b41d2SMark Murray goto parse_flag; 454511b41d2SMark Murray 455af12a3e7SDag-Erling Smørgrav case oChallengeResponseAuthentication: 456af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 457af12a3e7SDag-Erling Smørgrav goto parse_flag; 458cf2b5f3bSDag-Erling Smørgrav 459cf2b5f3bSDag-Erling Smørgrav case oGssAuthentication: 460cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 461511b41d2SMark Murray goto parse_flag; 462cf2b5f3bSDag-Erling Smørgrav 463cf2b5f3bSDag-Erling Smørgrav case oGssDelegateCreds: 464cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_deleg_creds; 465ca3176e7SBrian Feldman goto parse_flag; 466cf2b5f3bSDag-Erling Smørgrav 467511b41d2SMark Murray case oBatchMode: 468511b41d2SMark Murray intptr = &options->batch_mode; 469511b41d2SMark Murray goto parse_flag; 470511b41d2SMark Murray 471511b41d2SMark Murray case oCheckHostIP: 472511b41d2SMark Murray intptr = &options->check_host_ip; 473511b41d2SMark Murray goto parse_flag; 474511b41d2SMark Murray 475cf2b5f3bSDag-Erling Smørgrav case oVerifyHostKeyDNS: 476cf2b5f3bSDag-Erling Smørgrav intptr = &options->verify_host_key_dns; 4771ec0d754SDag-Erling Smørgrav goto parse_yesnoask; 478cf2b5f3bSDag-Erling Smørgrav 479511b41d2SMark Murray case oStrictHostKeyChecking: 480511b41d2SMark Murray intptr = &options->strict_host_key_checking; 4811ec0d754SDag-Erling Smørgrav parse_yesnoask: 482c2d3a559SKris Kennaway arg = strdelim(&s); 483c2d3a559SKris Kennaway if (!arg || *arg == '\0') 484ca3176e7SBrian Feldman fatal("%.200s line %d: Missing yes/no/ask argument.", 485511b41d2SMark Murray filename, linenum); 486511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 487c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 488511b41d2SMark Murray value = 1; 489c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 490511b41d2SMark Murray value = 0; 491c2d3a559SKris Kennaway else if (strcmp(arg, "ask") == 0) 492511b41d2SMark Murray value = 2; 493511b41d2SMark Murray else 494511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 495511b41d2SMark Murray if (*activep && *intptr == -1) 496511b41d2SMark Murray *intptr = value; 497511b41d2SMark Murray break; 498511b41d2SMark Murray 499511b41d2SMark Murray case oCompression: 500511b41d2SMark Murray intptr = &options->compression; 501511b41d2SMark Murray goto parse_flag; 502511b41d2SMark Murray 5031ec0d754SDag-Erling Smørgrav case oTCPKeepAlive: 5041ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 505511b41d2SMark Murray goto parse_flag; 506511b41d2SMark Murray 507af12a3e7SDag-Erling Smørgrav case oNoHostAuthenticationForLocalhost: 508af12a3e7SDag-Erling Smørgrav intptr = &options->no_host_authentication_for_localhost; 509af12a3e7SDag-Erling Smørgrav goto parse_flag; 510af12a3e7SDag-Erling Smørgrav 511511b41d2SMark Murray case oNumberOfPasswordPrompts: 512511b41d2SMark Murray intptr = &options->number_of_password_prompts; 513511b41d2SMark Murray goto parse_int; 514511b41d2SMark Murray 515511b41d2SMark Murray case oCompressionLevel: 516511b41d2SMark Murray intptr = &options->compression_level; 517511b41d2SMark Murray goto parse_int; 518511b41d2SMark Murray 519cf2b5f3bSDag-Erling Smørgrav case oRekeyLimit: 520cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 521cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 522cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 523cf2b5f3bSDag-Erling Smørgrav if (arg[0] < '0' || arg[0] > '9') 524cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 525333ee039SDag-Erling Smørgrav orig = val64 = strtoll(arg, &endofnumber, 10); 526cf2b5f3bSDag-Erling Smørgrav if (arg == endofnumber) 527cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 528cf2b5f3bSDag-Erling Smørgrav switch (toupper(*endofnumber)) { 529333ee039SDag-Erling Smørgrav case '\0': 530333ee039SDag-Erling Smørgrav scale = 1; 531333ee039SDag-Erling Smørgrav break; 532cf2b5f3bSDag-Erling Smørgrav case 'K': 533333ee039SDag-Erling Smørgrav scale = 1<<10; 534cf2b5f3bSDag-Erling Smørgrav break; 535cf2b5f3bSDag-Erling Smørgrav case 'M': 536333ee039SDag-Erling Smørgrav scale = 1<<20; 537cf2b5f3bSDag-Erling Smørgrav break; 538cf2b5f3bSDag-Erling Smørgrav case 'G': 539333ee039SDag-Erling Smørgrav scale = 1<<30; 540cf2b5f3bSDag-Erling Smørgrav break; 541333ee039SDag-Erling Smørgrav default: 542333ee039SDag-Erling Smørgrav fatal("%.200s line %d: Invalid RekeyLimit suffix", 543333ee039SDag-Erling Smørgrav filename, linenum); 544cf2b5f3bSDag-Erling Smørgrav } 545333ee039SDag-Erling Smørgrav val64 *= scale; 546333ee039SDag-Erling Smørgrav /* detect integer wrap and too-large limits */ 547d4af9e69SDag-Erling Smørgrav if ((val64 / scale) != orig || val64 > UINT_MAX) 548333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too large", 549333ee039SDag-Erling Smørgrav filename, linenum); 550333ee039SDag-Erling Smørgrav if (val64 < 16) 551333ee039SDag-Erling Smørgrav fatal("%.200s line %d: RekeyLimit too small", 552333ee039SDag-Erling Smørgrav filename, linenum); 553d4af9e69SDag-Erling Smørgrav if (*activep && options->rekey_limit == -1) 554d4af9e69SDag-Erling Smørgrav options->rekey_limit = (u_int32_t)val64; 555cf2b5f3bSDag-Erling Smørgrav break; 556cf2b5f3bSDag-Erling Smørgrav 557511b41d2SMark Murray case oIdentityFile: 558c2d3a559SKris Kennaway arg = strdelim(&s); 559c2d3a559SKris Kennaway if (!arg || *arg == '\0') 560511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 561511b41d2SMark Murray if (*activep) { 562ca3176e7SBrian Feldman intptr = &options->num_identity_files; 563e8aafc91SKris Kennaway if (*intptr >= SSH_MAX_IDENTITY_FILES) 564511b41d2SMark Murray fatal("%.200s line %d: Too many identity files specified (max %d).", 565511b41d2SMark Murray filename, linenum, SSH_MAX_IDENTITY_FILES); 566ca3176e7SBrian Feldman charptr = &options->identity_files[*intptr]; 567c2d3a559SKris Kennaway *charptr = xstrdup(arg); 568e8aafc91SKris Kennaway *intptr = *intptr + 1; 569511b41d2SMark Murray } 570511b41d2SMark Murray break; 571511b41d2SMark Murray 572c2d3a559SKris Kennaway case oXAuthLocation: 573c2d3a559SKris Kennaway charptr=&options->xauth_location; 574c2d3a559SKris Kennaway goto parse_string; 575c2d3a559SKris Kennaway 576511b41d2SMark Murray case oUser: 577511b41d2SMark Murray charptr = &options->user; 578511b41d2SMark Murray parse_string: 579c2d3a559SKris Kennaway arg = strdelim(&s); 580c2d3a559SKris Kennaway if (!arg || *arg == '\0') 581511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 582511b41d2SMark Murray if (*activep && *charptr == NULL) 583c2d3a559SKris Kennaway *charptr = xstrdup(arg); 584511b41d2SMark Murray break; 585511b41d2SMark Murray 586511b41d2SMark Murray case oGlobalKnownHostsFile: 587511b41d2SMark Murray charptr = &options->system_hostfile; 588511b41d2SMark Murray goto parse_string; 589511b41d2SMark Murray 590511b41d2SMark Murray case oUserKnownHostsFile: 591511b41d2SMark Murray charptr = &options->user_hostfile; 592511b41d2SMark Murray goto parse_string; 593511b41d2SMark Murray 594e8aafc91SKris Kennaway case oGlobalKnownHostsFile2: 595e8aafc91SKris Kennaway charptr = &options->system_hostfile2; 596e8aafc91SKris Kennaway goto parse_string; 597e8aafc91SKris Kennaway 598e8aafc91SKris Kennaway case oUserKnownHostsFile2: 599e8aafc91SKris Kennaway charptr = &options->user_hostfile2; 600e8aafc91SKris Kennaway goto parse_string; 601e8aafc91SKris Kennaway 602511b41d2SMark Murray case oHostName: 603511b41d2SMark Murray charptr = &options->hostname; 604511b41d2SMark Murray goto parse_string; 605511b41d2SMark Murray 606ca3176e7SBrian Feldman case oHostKeyAlias: 607ca3176e7SBrian Feldman charptr = &options->host_key_alias; 608ca3176e7SBrian Feldman goto parse_string; 609ca3176e7SBrian Feldman 610ca3176e7SBrian Feldman case oPreferredAuthentications: 611ca3176e7SBrian Feldman charptr = &options->preferred_authentications; 612ca3176e7SBrian Feldman goto parse_string; 613ca3176e7SBrian Feldman 614af12a3e7SDag-Erling Smørgrav case oBindAddress: 615af12a3e7SDag-Erling Smørgrav charptr = &options->bind_address; 616af12a3e7SDag-Erling Smørgrav goto parse_string; 617af12a3e7SDag-Erling Smørgrav 618af12a3e7SDag-Erling Smørgrav case oSmartcardDevice: 619af12a3e7SDag-Erling Smørgrav charptr = &options->smartcard_device; 620af12a3e7SDag-Erling Smørgrav goto parse_string; 621af12a3e7SDag-Erling Smørgrav 622511b41d2SMark Murray case oProxyCommand: 623b74df5b2SDag-Erling Smørgrav charptr = &options->proxy_command; 624b74df5b2SDag-Erling Smørgrav parse_command: 625cf2b5f3bSDag-Erling Smørgrav if (s == NULL) 626cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 627e73e9afaSDag-Erling Smørgrav len = strspn(s, WHITESPACE "="); 628511b41d2SMark Murray if (*activep && *charptr == NULL) 629e73e9afaSDag-Erling Smørgrav *charptr = xstrdup(s + len); 630511b41d2SMark Murray return 0; 631511b41d2SMark Murray 632511b41d2SMark Murray case oPort: 633511b41d2SMark Murray intptr = &options->port; 634511b41d2SMark Murray parse_int: 635c2d3a559SKris Kennaway arg = strdelim(&s); 636c2d3a559SKris Kennaway if (!arg || *arg == '\0') 637511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 638c2d3a559SKris Kennaway if (arg[0] < '0' || arg[0] > '9') 639511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 640511b41d2SMark Murray 641511b41d2SMark Murray /* Octal, decimal, or hex format? */ 642c2d3a559SKris Kennaway value = strtol(arg, &endofnumber, 0); 643c2d3a559SKris Kennaway if (arg == endofnumber) 644511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 645511b41d2SMark Murray if (*activep && *intptr == -1) 646511b41d2SMark Murray *intptr = value; 647511b41d2SMark Murray break; 648511b41d2SMark Murray 649511b41d2SMark Murray case oConnectionAttempts: 650511b41d2SMark Murray intptr = &options->connection_attempts; 651511b41d2SMark Murray goto parse_int; 652511b41d2SMark Murray 653511b41d2SMark Murray case oCipher: 654511b41d2SMark Murray intptr = &options->cipher; 655c2d3a559SKris Kennaway arg = strdelim(&s); 656c2d3a559SKris Kennaway if (!arg || *arg == '\0') 657db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 658c2d3a559SKris Kennaway value = cipher_number(arg); 659511b41d2SMark Murray if (value == -1) 660511b41d2SMark Murray fatal("%.200s line %d: Bad cipher '%s'.", 661c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 662511b41d2SMark Murray if (*activep && *intptr == -1) 663511b41d2SMark Murray *intptr = value; 664511b41d2SMark Murray break; 665511b41d2SMark Murray 666e8aafc91SKris Kennaway case oCiphers: 667c2d3a559SKris Kennaway arg = strdelim(&s); 668c2d3a559SKris Kennaway if (!arg || *arg == '\0') 669db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 670c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 671e8aafc91SKris Kennaway fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 672c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 673e8aafc91SKris Kennaway if (*activep && options->ciphers == NULL) 674c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 675e8aafc91SKris Kennaway break; 676e8aafc91SKris Kennaway 677ca3176e7SBrian Feldman case oMacs: 678ca3176e7SBrian Feldman arg = strdelim(&s); 679ca3176e7SBrian Feldman if (!arg || *arg == '\0') 680ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 681ca3176e7SBrian Feldman if (!mac_valid(arg)) 682ca3176e7SBrian Feldman fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 683ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 684ca3176e7SBrian Feldman if (*activep && options->macs == NULL) 685ca3176e7SBrian Feldman options->macs = xstrdup(arg); 686ca3176e7SBrian Feldman break; 687ca3176e7SBrian Feldman 688ca3176e7SBrian Feldman case oHostKeyAlgorithms: 689ca3176e7SBrian Feldman arg = strdelim(&s); 690ca3176e7SBrian Feldman if (!arg || *arg == '\0') 691ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 692ca3176e7SBrian Feldman if (!key_names_valid2(arg)) 693ca3176e7SBrian Feldman fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 694ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 695ca3176e7SBrian Feldman if (*activep && options->hostkeyalgorithms == NULL) 696ca3176e7SBrian Feldman options->hostkeyalgorithms = xstrdup(arg); 697ca3176e7SBrian Feldman break; 698ca3176e7SBrian Feldman 699e8aafc91SKris Kennaway case oProtocol: 700e8aafc91SKris Kennaway intptr = &options->protocol; 701c2d3a559SKris Kennaway arg = strdelim(&s); 702c2d3a559SKris Kennaway if (!arg || *arg == '\0') 703db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 704c2d3a559SKris Kennaway value = proto_spec(arg); 705e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 706e8aafc91SKris Kennaway fatal("%.200s line %d: Bad protocol spec '%s'.", 707c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 708e8aafc91SKris Kennaway if (*activep && *intptr == SSH_PROTO_UNKNOWN) 709e8aafc91SKris Kennaway *intptr = value; 710e8aafc91SKris Kennaway break; 711e8aafc91SKris Kennaway 712511b41d2SMark Murray case oLogLevel: 713d4af9e69SDag-Erling Smørgrav log_level_ptr = &options->log_level; 714c2d3a559SKris Kennaway arg = strdelim(&s); 715c2d3a559SKris Kennaway value = log_level_number(arg); 716af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 717ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 718c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 719d4af9e69SDag-Erling Smørgrav if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) 720d4af9e69SDag-Erling Smørgrav *log_level_ptr = (LogLevel) value; 721511b41d2SMark Murray break; 722511b41d2SMark Murray 723af12a3e7SDag-Erling Smørgrav case oLocalForward: 724511b41d2SMark Murray case oRemoteForward: 725c2d3a559SKris Kennaway arg = strdelim(&s); 726aa49c926SDag-Erling Smørgrav if (arg == NULL || *arg == '\0') 727af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Missing port argument.", 728af12a3e7SDag-Erling Smørgrav filename, linenum); 729aa49c926SDag-Erling Smørgrav arg2 = strdelim(&s); 730aa49c926SDag-Erling Smørgrav if (arg2 == NULL || *arg2 == '\0') 731aa49c926SDag-Erling Smørgrav fatal("%.200s line %d: Missing target argument.", 732511b41d2SMark Murray filename, linenum); 733aa49c926SDag-Erling Smørgrav 734aa49c926SDag-Erling Smørgrav /* construct a string for parse_forward */ 735aa49c926SDag-Erling Smørgrav snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 736aa49c926SDag-Erling Smørgrav 737aa49c926SDag-Erling Smørgrav if (parse_forward(&fwd, fwdarg) == 0) 738af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 739511b41d2SMark Murray filename, linenum); 740aa49c926SDag-Erling Smørgrav 741af12a3e7SDag-Erling Smørgrav if (*activep) { 742af12a3e7SDag-Erling Smørgrav if (opcode == oLocalForward) 743aa49c926SDag-Erling Smørgrav add_local_forward(options, &fwd); 744af12a3e7SDag-Erling Smørgrav else if (opcode == oRemoteForward) 745aa49c926SDag-Erling Smørgrav add_remote_forward(options, &fwd); 746af12a3e7SDag-Erling Smørgrav } 747511b41d2SMark Murray break; 748511b41d2SMark Murray 749ca3176e7SBrian Feldman case oDynamicForward: 750ca3176e7SBrian Feldman arg = strdelim(&s); 751ca3176e7SBrian Feldman if (!arg || *arg == '\0') 752ca3176e7SBrian Feldman fatal("%.200s line %d: Missing port argument.", 753ca3176e7SBrian Feldman filename, linenum); 754aa49c926SDag-Erling Smørgrav memset(&fwd, '\0', sizeof(fwd)); 755aa49c926SDag-Erling Smørgrav fwd.connect_host = "socks"; 756aa49c926SDag-Erling Smørgrav fwd.listen_host = hpdelim(&arg); 757aa49c926SDag-Erling Smørgrav if (fwd.listen_host == NULL || 758aa49c926SDag-Erling Smørgrav strlen(fwd.listen_host) >= NI_MAXHOST) 759aa49c926SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 760aa49c926SDag-Erling Smørgrav filename, linenum); 761aa49c926SDag-Erling Smørgrav if (arg) { 762aa49c926SDag-Erling Smørgrav fwd.listen_port = a2port(arg); 763aa49c926SDag-Erling Smørgrav fwd.listen_host = cleanhostname(fwd.listen_host); 764aa49c926SDag-Erling Smørgrav } else { 765aa49c926SDag-Erling Smørgrav fwd.listen_port = a2port(fwd.listen_host); 766d4ecd108SDag-Erling Smørgrav fwd.listen_host = NULL; 767aa49c926SDag-Erling Smørgrav } 768aa49c926SDag-Erling Smørgrav if (fwd.listen_port == 0) 769ca3176e7SBrian Feldman fatal("%.200s line %d: Badly formatted port number.", 770ca3176e7SBrian Feldman filename, linenum); 771af12a3e7SDag-Erling Smørgrav if (*activep) 772aa49c926SDag-Erling Smørgrav add_local_forward(options, &fwd); 773ca3176e7SBrian Feldman break; 774ca3176e7SBrian Feldman 775af12a3e7SDag-Erling Smørgrav case oClearAllForwardings: 776af12a3e7SDag-Erling Smørgrav intptr = &options->clear_forwardings; 777af12a3e7SDag-Erling Smørgrav goto parse_flag; 778af12a3e7SDag-Erling Smørgrav 779511b41d2SMark Murray case oHost: 780511b41d2SMark Murray *activep = 0; 781c2d3a559SKris Kennaway while ((arg = strdelim(&s)) != NULL && *arg != '\0') 782c2d3a559SKris Kennaway if (match_pattern(host, arg)) { 783c2d3a559SKris Kennaway debug("Applying options for %.100s", arg); 784511b41d2SMark Murray *activep = 1; 785511b41d2SMark Murray break; 786511b41d2SMark Murray } 787c2d3a559SKris Kennaway /* Avoid garbage check below, as strdelim is done. */ 788511b41d2SMark Murray return 0; 789511b41d2SMark Murray 790511b41d2SMark Murray case oEscapeChar: 791511b41d2SMark Murray intptr = &options->escape_char; 792c2d3a559SKris Kennaway arg = strdelim(&s); 793c2d3a559SKris Kennaway if (!arg || *arg == '\0') 794511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 795c2d3a559SKris Kennaway if (arg[0] == '^' && arg[2] == 0 && 796ca3176e7SBrian Feldman (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 797ca3176e7SBrian Feldman value = (u_char) arg[1] & 31; 798c2d3a559SKris Kennaway else if (strlen(arg) == 1) 799ca3176e7SBrian Feldman value = (u_char) arg[0]; 800c2d3a559SKris Kennaway else if (strcmp(arg, "none") == 0) 801af12a3e7SDag-Erling Smørgrav value = SSH_ESCAPECHAR_NONE; 802511b41d2SMark Murray else { 803511b41d2SMark Murray fatal("%.200s line %d: Bad escape character.", 804511b41d2SMark Murray filename, linenum); 805511b41d2SMark Murray /* NOTREACHED */ 806511b41d2SMark Murray value = 0; /* Avoid compiler warning. */ 807511b41d2SMark Murray } 808511b41d2SMark Murray if (*activep && *intptr == -1) 809511b41d2SMark Murray *intptr = value; 810511b41d2SMark Murray break; 811511b41d2SMark Murray 812cf2b5f3bSDag-Erling Smørgrav case oAddressFamily: 813cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 814d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 815d4ecd108SDag-Erling Smørgrav fatal("%s line %d: missing address family.", 816d4ecd108SDag-Erling Smørgrav filename, linenum); 817cf2b5f3bSDag-Erling Smørgrav intptr = &options->address_family; 818cf2b5f3bSDag-Erling Smørgrav if (strcasecmp(arg, "inet") == 0) 819cf2b5f3bSDag-Erling Smørgrav value = AF_INET; 820cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "inet6") == 0) 821cf2b5f3bSDag-Erling Smørgrav value = AF_INET6; 822cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "any") == 0) 823cf2b5f3bSDag-Erling Smørgrav value = AF_UNSPEC; 824cf2b5f3bSDag-Erling Smørgrav else 825cf2b5f3bSDag-Erling Smørgrav fatal("Unsupported AddressFamily \"%s\"", arg); 826cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 827cf2b5f3bSDag-Erling Smørgrav *intptr = value; 828cf2b5f3bSDag-Erling Smørgrav break; 829cf2b5f3bSDag-Erling Smørgrav 830e73e9afaSDag-Erling Smørgrav case oEnableSSHKeysign: 831e73e9afaSDag-Erling Smørgrav intptr = &options->enable_ssh_keysign; 832e73e9afaSDag-Erling Smørgrav goto parse_flag; 833e73e9afaSDag-Erling Smørgrav 8345962c0e9SDag-Erling Smørgrav case oIdentitiesOnly: 8355962c0e9SDag-Erling Smørgrav intptr = &options->identities_only; 8365962c0e9SDag-Erling Smørgrav goto parse_flag; 8375962c0e9SDag-Erling Smørgrav 8381ec0d754SDag-Erling Smørgrav case oServerAliveInterval: 8391ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_interval; 8401ec0d754SDag-Erling Smørgrav goto parse_time; 8411ec0d754SDag-Erling Smørgrav 8421ec0d754SDag-Erling Smørgrav case oServerAliveCountMax: 8431ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_count_max; 8441ec0d754SDag-Erling Smørgrav goto parse_int; 8451ec0d754SDag-Erling Smørgrav 84621e764dfSDag-Erling Smørgrav case oSendEnv: 84721e764dfSDag-Erling Smørgrav while ((arg = strdelim(&s)) != NULL && *arg != '\0') { 84821e764dfSDag-Erling Smørgrav if (strchr(arg, '=') != NULL) 84921e764dfSDag-Erling Smørgrav fatal("%s line %d: Invalid environment name.", 85021e764dfSDag-Erling Smørgrav filename, linenum); 851aa49c926SDag-Erling Smørgrav if (!*activep) 852aa49c926SDag-Erling Smørgrav continue; 85321e764dfSDag-Erling Smørgrav if (options->num_send_env >= MAX_SEND_ENV) 85421e764dfSDag-Erling Smørgrav fatal("%s line %d: too many send env.", 85521e764dfSDag-Erling Smørgrav filename, linenum); 85621e764dfSDag-Erling Smørgrav options->send_env[options->num_send_env++] = 85721e764dfSDag-Erling Smørgrav xstrdup(arg); 85821e764dfSDag-Erling Smørgrav } 85921e764dfSDag-Erling Smørgrav break; 86021e764dfSDag-Erling Smørgrav 86121e764dfSDag-Erling Smørgrav case oControlPath: 86221e764dfSDag-Erling Smørgrav charptr = &options->control_path; 86321e764dfSDag-Erling Smørgrav goto parse_string; 86421e764dfSDag-Erling Smørgrav 86521e764dfSDag-Erling Smørgrav case oControlMaster: 86621e764dfSDag-Erling Smørgrav intptr = &options->control_master; 867d4ecd108SDag-Erling Smørgrav arg = strdelim(&s); 868d4ecd108SDag-Erling Smørgrav if (!arg || *arg == '\0') 869d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Missing ControlMaster argument.", 870d4ecd108SDag-Erling Smørgrav filename, linenum); 871d4ecd108SDag-Erling Smørgrav value = 0; /* To avoid compiler warning... */ 872d4ecd108SDag-Erling Smørgrav if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 873d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_YES; 874d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 875d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_NO; 876d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "auto") == 0) 877d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO; 878d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "ask") == 0) 879d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_ASK; 880d4ecd108SDag-Erling Smørgrav else if (strcmp(arg, "autoask") == 0) 881d4ecd108SDag-Erling Smørgrav value = SSHCTL_MASTER_AUTO_ASK; 882d4ecd108SDag-Erling Smørgrav else 883d4ecd108SDag-Erling Smørgrav fatal("%.200s line %d: Bad ControlMaster argument.", 884d4ecd108SDag-Erling Smørgrav filename, linenum); 885d4ecd108SDag-Erling Smørgrav if (*activep && *intptr == -1) 886d4ecd108SDag-Erling Smørgrav *intptr = value; 887d4ecd108SDag-Erling Smørgrav break; 88821e764dfSDag-Erling Smørgrav 889aa49c926SDag-Erling Smørgrav case oHashKnownHosts: 890aa49c926SDag-Erling Smørgrav intptr = &options->hash_known_hosts; 891aa49c926SDag-Erling Smørgrav goto parse_flag; 892aa49c926SDag-Erling Smørgrav 893b74df5b2SDag-Erling Smørgrav case oTunnel: 894b74df5b2SDag-Erling Smørgrav intptr = &options->tun_open; 895b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 896b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 897b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Missing yes/point-to-point/" 898b74df5b2SDag-Erling Smørgrav "ethernet/no argument.", filename, linenum); 899b74df5b2SDag-Erling Smørgrav value = 0; /* silence compiler */ 900b74df5b2SDag-Erling Smørgrav if (strcasecmp(arg, "ethernet") == 0) 901b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_ETHERNET; 902b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "point-to-point") == 0) 903b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_POINTOPOINT; 904b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "yes") == 0) 905b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_DEFAULT; 906b74df5b2SDag-Erling Smørgrav else if (strcasecmp(arg, "no") == 0) 907b74df5b2SDag-Erling Smørgrav value = SSH_TUNMODE_NO; 908b74df5b2SDag-Erling Smørgrav else 909b74df5b2SDag-Erling Smørgrav fatal("%s line %d: Bad yes/point-to-point/ethernet/" 910b74df5b2SDag-Erling Smørgrav "no argument: %s", filename, linenum, arg); 911b74df5b2SDag-Erling Smørgrav if (*activep) 912b74df5b2SDag-Erling Smørgrav *intptr = value; 913b74df5b2SDag-Erling Smørgrav break; 914b74df5b2SDag-Erling Smørgrav 915b74df5b2SDag-Erling Smørgrav case oTunnelDevice: 916b74df5b2SDag-Erling Smørgrav arg = strdelim(&s); 917b74df5b2SDag-Erling Smørgrav if (!arg || *arg == '\0') 918b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 919b74df5b2SDag-Erling Smørgrav value = a2tun(arg, &value2); 920b74df5b2SDag-Erling Smørgrav if (value == SSH_TUNID_ERR) 921b74df5b2SDag-Erling Smørgrav fatal("%.200s line %d: Bad tun device.", filename, linenum); 922b74df5b2SDag-Erling Smørgrav if (*activep) { 923b74df5b2SDag-Erling Smørgrav options->tun_local = value; 924b74df5b2SDag-Erling Smørgrav options->tun_remote = value2; 925b74df5b2SDag-Erling Smørgrav } 926b74df5b2SDag-Erling Smørgrav break; 927b74df5b2SDag-Erling Smørgrav 928b74df5b2SDag-Erling Smørgrav case oLocalCommand: 929b74df5b2SDag-Erling Smørgrav charptr = &options->local_command; 930b74df5b2SDag-Erling Smørgrav goto parse_command; 931b74df5b2SDag-Erling Smørgrav 932b74df5b2SDag-Erling Smørgrav case oPermitLocalCommand: 933b74df5b2SDag-Erling Smørgrav intptr = &options->permit_local_command; 934b74df5b2SDag-Erling Smørgrav goto parse_flag; 935b74df5b2SDag-Erling Smørgrav 936d4af9e69SDag-Erling Smørgrav case oVisualHostKey: 937d4af9e69SDag-Erling Smørgrav intptr = &options->visual_host_key; 938d4af9e69SDag-Erling Smørgrav goto parse_flag; 939d4af9e69SDag-Erling Smørgrav 940975616f0SDag-Erling Smørgrav case oVersionAddendum: 941975616f0SDag-Erling Smørgrav ssh_version_set_addendum(strtok(s, "\n")); 942975616f0SDag-Erling Smørgrav do { 943975616f0SDag-Erling Smørgrav arg = strdelim(&s); 944975616f0SDag-Erling Smørgrav } while (arg != NULL && *arg != '\0'); 945975616f0SDag-Erling Smørgrav break; 946975616f0SDag-Erling Smørgrav 94780628bacSDag-Erling Smørgrav case oDeprecated: 94880628bacSDag-Erling Smørgrav debug("%s line %d: Deprecated option \"%s\"", 94980628bacSDag-Erling Smørgrav filename, linenum, keyword); 95080628bacSDag-Erling Smørgrav return 0; 95180628bacSDag-Erling Smørgrav 952cf2b5f3bSDag-Erling Smørgrav case oUnsupported: 953cf2b5f3bSDag-Erling Smørgrav error("%s line %d: Unsupported option \"%s\"", 954cf2b5f3bSDag-Erling Smørgrav filename, linenum, keyword); 955cf2b5f3bSDag-Erling Smørgrav return 0; 956cf2b5f3bSDag-Erling Smørgrav 957511b41d2SMark Murray default: 958511b41d2SMark Murray fatal("process_config_line: Unimplemented opcode %d", opcode); 959511b41d2SMark Murray } 960511b41d2SMark Murray 961511b41d2SMark Murray /* Check that there is no garbage at end of line. */ 962ca3176e7SBrian Feldman if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 963c2d3a559SKris Kennaway fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 964c2d3a559SKris Kennaway filename, linenum, arg); 965c2d3a559SKris Kennaway } 966511b41d2SMark Murray return 0; 967511b41d2SMark Murray } 968511b41d2SMark Murray 969511b41d2SMark Murray 970511b41d2SMark Murray /* 971511b41d2SMark Murray * Reads the config file and modifies the options accordingly. Options 972511b41d2SMark Murray * should already be initialized before this call. This never returns if 973af12a3e7SDag-Erling Smørgrav * there is an error. If the file does not exist, this returns 0. 974511b41d2SMark Murray */ 975511b41d2SMark Murray 976af12a3e7SDag-Erling Smørgrav int 97721e764dfSDag-Erling Smørgrav read_config_file(const char *filename, const char *host, Options *options, 97821e764dfSDag-Erling Smørgrav int checkperm) 979511b41d2SMark Murray { 980511b41d2SMark Murray FILE *f; 981511b41d2SMark Murray char line[1024]; 982511b41d2SMark Murray int active, linenum; 983511b41d2SMark Murray int bad_options = 0; 984511b41d2SMark Murray 985511b41d2SMark Murray /* Open the file. */ 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; 1080af12a3e7SDag-Erling Smørgrav options->smartcard_device = 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; 1097d4af9e69SDag-Erling Smørgrav options->visual_host_key = -1; 1098511b41d2SMark Murray } 1099511b41d2SMark Murray 1100511b41d2SMark Murray /* 1101511b41d2SMark Murray * Called after processing other sources of option data, this fills those 1102511b41d2SMark Murray * options for which no value has been specified with their default values. 1103511b41d2SMark Murray */ 1104511b41d2SMark Murray 1105511b41d2SMark Murray void 1106511b41d2SMark Murray fill_default_options(Options * options) 1107511b41d2SMark Murray { 1108ca3176e7SBrian Feldman int len; 1109ca3176e7SBrian Feldman 1110511b41d2SMark Murray if (options->forward_agent == -1) 1111db1cb46cSKris Kennaway options->forward_agent = 0; 1112511b41d2SMark Murray if (options->forward_x11 == -1) 11135dc73ebeSBrian Feldman options->forward_x11 = 0; 11141ec0d754SDag-Erling Smørgrav if (options->forward_x11_trusted == -1) 11151ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = 0; 1116333ee039SDag-Erling Smørgrav if (options->exit_on_forward_failure == -1) 1117333ee039SDag-Erling Smørgrav options->exit_on_forward_failure = 0; 1118c2d3a559SKris Kennaway if (options->xauth_location == NULL) 1119af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 1120511b41d2SMark Murray if (options->gateway_ports == -1) 1121511b41d2SMark Murray options->gateway_ports = 0; 1122511b41d2SMark Murray if (options->use_privileged_port == -1) 1123ca3176e7SBrian Feldman options->use_privileged_port = 0; 1124511b41d2SMark Murray if (options->rsa_authentication == -1) 1125511b41d2SMark Murray options->rsa_authentication = 1; 1126ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 1127ca3176e7SBrian Feldman options->pubkey_authentication = 1; 1128af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 1129af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = 1; 1130cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 11311ec0d754SDag-Erling Smørgrav options->gss_authentication = 0; 1132cf2b5f3bSDag-Erling Smørgrav if (options->gss_deleg_creds == -1) 1133cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = 0; 1134511b41d2SMark Murray if (options->password_authentication == -1) 1135511b41d2SMark Murray options->password_authentication = 1; 113609958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 1137ca3176e7SBrian Feldman options->kbd_interactive_authentication = 1; 1138511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 113980628bacSDag-Erling Smørgrav options->rhosts_rsa_authentication = 0; 1140ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 1141ca3176e7SBrian Feldman options->hostbased_authentication = 0; 1142511b41d2SMark Murray if (options->batch_mode == -1) 1143511b41d2SMark Murray options->batch_mode = 0; 1144511b41d2SMark Murray if (options->check_host_ip == -1) 1145975616f0SDag-Erling Smørgrav options->check_host_ip = 0; 1146511b41d2SMark Murray if (options->strict_host_key_checking == -1) 1147511b41d2SMark Murray options->strict_host_key_checking = 2; /* 2 is default */ 1148511b41d2SMark Murray if (options->compression == -1) 1149511b41d2SMark Murray options->compression = 0; 11501ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 11511ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 1152511b41d2SMark Murray if (options->compression_level == -1) 1153511b41d2SMark Murray options->compression_level = 6; 1154511b41d2SMark Murray if (options->port == -1) 1155511b41d2SMark Murray options->port = 0; /* Filled in ssh_connect. */ 1156cf2b5f3bSDag-Erling Smørgrav if (options->address_family == -1) 1157cf2b5f3bSDag-Erling Smørgrav options->address_family = AF_UNSPEC; 1158511b41d2SMark Murray if (options->connection_attempts == -1) 1159af12a3e7SDag-Erling Smørgrav options->connection_attempts = 1; 1160511b41d2SMark Murray if (options->number_of_password_prompts == -1) 1161511b41d2SMark Murray options->number_of_password_prompts = 3; 1162511b41d2SMark Murray /* Selected in ssh_login(). */ 1163511b41d2SMark Murray if (options->cipher == -1) 1164511b41d2SMark Murray options->cipher = SSH_CIPHER_NOT_SET; 1165e8aafc91SKris Kennaway /* options->ciphers, default set in myproposals.h */ 1166ca3176e7SBrian Feldman /* options->macs, default set in myproposals.h */ 1167ca3176e7SBrian Feldman /* options->hostkeyalgorithms, default set in myproposals.h */ 1168e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 1169ca3176e7SBrian Feldman options->protocol = SSH_PROTO_1|SSH_PROTO_2; 1170511b41d2SMark Murray if (options->num_identity_files == 0) { 1171ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) { 1172ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 1173ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1174ca3176e7SBrian Feldman xmalloc(len); 1175ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1176ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 1177511b41d2SMark Murray } 1178ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_2) { 1179ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 1180ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1181ca3176e7SBrian Feldman xmalloc(len); 1182ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1183ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 1184ca3176e7SBrian Feldman 1185ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 1186ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 1187ca3176e7SBrian Feldman xmalloc(len); 1188ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 1189ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 1190ca3176e7SBrian Feldman } 1191e8aafc91SKris Kennaway } 1192511b41d2SMark Murray if (options->escape_char == -1) 1193511b41d2SMark Murray options->escape_char = '~'; 1194511b41d2SMark Murray if (options->system_hostfile == NULL) 1195ca3176e7SBrian Feldman options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 1196511b41d2SMark Murray if (options->user_hostfile == NULL) 1197ca3176e7SBrian Feldman options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 1198e8aafc91SKris Kennaway if (options->system_hostfile2 == NULL) 1199ca3176e7SBrian Feldman options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 1200e8aafc91SKris Kennaway if (options->user_hostfile2 == NULL) 1201ca3176e7SBrian Feldman options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 1202af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1203511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 1204af12a3e7SDag-Erling Smørgrav if (options->clear_forwardings == 1) 1205af12a3e7SDag-Erling Smørgrav clear_forwardings(options); 1206af12a3e7SDag-Erling Smørgrav if (options->no_host_authentication_for_localhost == - 1) 1207af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = 0; 12085962c0e9SDag-Erling Smørgrav if (options->identities_only == -1) 12095962c0e9SDag-Erling Smørgrav options->identities_only = 0; 1210e73e9afaSDag-Erling Smørgrav if (options->enable_ssh_keysign == -1) 1211e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = 0; 1212cf2b5f3bSDag-Erling Smørgrav if (options->rekey_limit == -1) 1213cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = 0; 1214cf2b5f3bSDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 1215cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = 0; 12161ec0d754SDag-Erling Smørgrav if (options->server_alive_interval == -1) 12171ec0d754SDag-Erling Smørgrav options->server_alive_interval = 0; 12181ec0d754SDag-Erling Smørgrav if (options->server_alive_count_max == -1) 12191ec0d754SDag-Erling Smørgrav options->server_alive_count_max = 3; 122021e764dfSDag-Erling Smørgrav if (options->control_master == -1) 122121e764dfSDag-Erling Smørgrav options->control_master = 0; 1222aa49c926SDag-Erling Smørgrav if (options->hash_known_hosts == -1) 1223aa49c926SDag-Erling Smørgrav options->hash_known_hosts = 0; 1224b74df5b2SDag-Erling Smørgrav if (options->tun_open == -1) 1225b74df5b2SDag-Erling Smørgrav options->tun_open = SSH_TUNMODE_NO; 1226b74df5b2SDag-Erling Smørgrav if (options->tun_local == -1) 1227b74df5b2SDag-Erling Smørgrav options->tun_local = SSH_TUNID_ANY; 1228b74df5b2SDag-Erling Smørgrav if (options->tun_remote == -1) 1229b74df5b2SDag-Erling Smørgrav options->tun_remote = SSH_TUNID_ANY; 1230b74df5b2SDag-Erling Smørgrav if (options->permit_local_command == -1) 1231b74df5b2SDag-Erling Smørgrav options->permit_local_command = 0; 1232d4af9e69SDag-Erling Smørgrav if (options->visual_host_key == -1) 1233d4af9e69SDag-Erling Smørgrav options->visual_host_key = 0; 1234b74df5b2SDag-Erling Smørgrav /* options->local_command should not be set by default */ 1235511b41d2SMark Murray /* options->proxy_command should not be set by default */ 1236511b41d2SMark Murray /* options->user will be set in the main program if appropriate */ 1237511b41d2SMark Murray /* options->hostname will be set in the main program if appropriate */ 1238ca3176e7SBrian Feldman /* options->host_key_alias should not be set by default */ 1239ca3176e7SBrian Feldman /* options->preferred_authentications will be set in ssh */ 1240511b41d2SMark Murray } 1241aa49c926SDag-Erling Smørgrav 1242aa49c926SDag-Erling Smørgrav /* 1243aa49c926SDag-Erling Smørgrav * parse_forward 1244aa49c926SDag-Erling Smørgrav * parses a string containing a port forwarding specification of the form: 1245aa49c926SDag-Erling Smørgrav * [listenhost:]listenport:connecthost:connectport 1246aa49c926SDag-Erling Smørgrav * returns number of arguments parsed or zero on error 1247aa49c926SDag-Erling Smørgrav */ 1248aa49c926SDag-Erling Smørgrav int 1249aa49c926SDag-Erling Smørgrav parse_forward(Forward *fwd, const char *fwdspec) 1250aa49c926SDag-Erling Smørgrav { 1251aa49c926SDag-Erling Smørgrav int i; 1252aa49c926SDag-Erling Smørgrav char *p, *cp, *fwdarg[4]; 1253aa49c926SDag-Erling Smørgrav 1254aa49c926SDag-Erling Smørgrav memset(fwd, '\0', sizeof(*fwd)); 1255aa49c926SDag-Erling Smørgrav 1256aa49c926SDag-Erling Smørgrav cp = p = xstrdup(fwdspec); 1257aa49c926SDag-Erling Smørgrav 1258aa49c926SDag-Erling Smørgrav /* skip leading spaces */ 1259d4af9e69SDag-Erling Smørgrav while (isspace(*cp)) 1260aa49c926SDag-Erling Smørgrav cp++; 1261aa49c926SDag-Erling Smørgrav 1262aa49c926SDag-Erling Smørgrav for (i = 0; i < 4; ++i) 1263aa49c926SDag-Erling Smørgrav if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1264aa49c926SDag-Erling Smørgrav break; 1265aa49c926SDag-Erling Smørgrav 1266aa49c926SDag-Erling Smørgrav /* Check for trailing garbage in 4-arg case*/ 1267aa49c926SDag-Erling Smørgrav if (cp != NULL) 1268aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1269aa49c926SDag-Erling Smørgrav 1270aa49c926SDag-Erling Smørgrav switch (i) { 1271aa49c926SDag-Erling Smørgrav case 3: 1272aa49c926SDag-Erling Smørgrav fwd->listen_host = NULL; 1273aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[0]); 1274aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1275aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[2]); 1276aa49c926SDag-Erling Smørgrav break; 1277aa49c926SDag-Erling Smørgrav 1278aa49c926SDag-Erling Smørgrav case 4: 1279aa49c926SDag-Erling Smørgrav fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1280aa49c926SDag-Erling Smørgrav fwd->listen_port = a2port(fwdarg[1]); 1281aa49c926SDag-Erling Smørgrav fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1282aa49c926SDag-Erling Smørgrav fwd->connect_port = a2port(fwdarg[3]); 1283aa49c926SDag-Erling Smørgrav break; 1284aa49c926SDag-Erling Smørgrav default: 1285aa49c926SDag-Erling Smørgrav i = 0; /* failure */ 1286aa49c926SDag-Erling Smørgrav } 1287aa49c926SDag-Erling Smørgrav 1288aa49c926SDag-Erling Smørgrav xfree(p); 1289aa49c926SDag-Erling Smørgrav 1290d4af9e69SDag-Erling Smørgrav if (fwd->listen_port == 0 || fwd->connect_port == 0) 1291aa49c926SDag-Erling Smørgrav goto fail_free; 1292aa49c926SDag-Erling Smørgrav 1293aa49c926SDag-Erling Smørgrav if (fwd->connect_host != NULL && 1294aa49c926SDag-Erling Smørgrav strlen(fwd->connect_host) >= NI_MAXHOST) 1295aa49c926SDag-Erling Smørgrav goto fail_free; 1296aa49c926SDag-Erling Smørgrav 1297aa49c926SDag-Erling Smørgrav return (i); 1298aa49c926SDag-Erling Smørgrav 1299aa49c926SDag-Erling Smørgrav fail_free: 1300aa49c926SDag-Erling Smørgrav if (fwd->connect_host != NULL) 1301aa49c926SDag-Erling Smørgrav xfree(fwd->connect_host); 1302aa49c926SDag-Erling Smørgrav if (fwd->listen_host != NULL) 1303aa49c926SDag-Erling Smørgrav xfree(fwd->listen_host); 1304aa49c926SDag-Erling Smørgrav return (0); 1305aa49c926SDag-Erling Smørgrav } 1306