1511b41d2SMark Murray /* 2511b41d2SMark Murray * Author: Tatu Ylonen <ylo@cs.hut.fi> 3511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4511b41d2SMark Murray * All rights reserved 5511b41d2SMark Murray * Functions for reading the configuration files. 6511b41d2SMark Murray * 7c2d3a559SKris Kennaway * As far as I am concerned, the code I have written for this software 8c2d3a559SKris Kennaway * can be used freely for any purpose. Any derived versions of this 9c2d3a559SKris Kennaway * software must be clearly marked as such, and if the derived work is 10c2d3a559SKris Kennaway * incompatible with the protocol description in the RFC file, it must be 11c2d3a559SKris Kennaway * called by a name other than "ssh" or "Secure Shell". 12511b41d2SMark Murray */ 13511b41d2SMark Murray 14511b41d2SMark Murray #include "includes.h" 15975616f0SDag-Erling Smørgrav RCSID("$FreeBSD$"); 165962c0e9SDag-Erling Smørgrav RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $"); 17511b41d2SMark Murray 18511b41d2SMark Murray #include "ssh.h" 19511b41d2SMark Murray #include "xmalloc.h" 20e8aafc91SKris Kennaway #include "compat.h" 21ca3176e7SBrian Feldman #include "cipher.h" 22ca3176e7SBrian Feldman #include "pathnames.h" 23ca3176e7SBrian Feldman #include "log.h" 24ca3176e7SBrian Feldman #include "readconf.h" 25ca3176e7SBrian Feldman #include "match.h" 26ca3176e7SBrian Feldman #include "misc.h" 27ca3176e7SBrian Feldman #include "kex.h" 28ca3176e7SBrian Feldman #include "mac.h" 29511b41d2SMark Murray 30511b41d2SMark Murray /* Format of the configuration file: 31511b41d2SMark Murray 32511b41d2SMark Murray # Configuration data is parsed as follows: 33511b41d2SMark Murray # 1. command line options 34511b41d2SMark Murray # 2. user-specific file 35511b41d2SMark Murray # 3. system-wide file 36511b41d2SMark Murray # Any configuration value is only changed the first time it is set. 37511b41d2SMark Murray # Thus, host-specific definitions should be at the beginning of the 38511b41d2SMark Murray # configuration file, and defaults at the end. 39511b41d2SMark Murray 40511b41d2SMark Murray # Host-specific declarations. These may override anything above. A single 41511b41d2SMark Murray # host may match multiple declarations; these are processed in the order 42511b41d2SMark Murray # that they are given in. 43511b41d2SMark Murray 44511b41d2SMark Murray Host *.ngs.fi ngs.fi 4580628bacSDag-Erling Smørgrav User foo 46511b41d2SMark Murray 47511b41d2SMark Murray Host fake.com 48511b41d2SMark Murray HostName another.host.name.real.org 49511b41d2SMark Murray User blaah 50511b41d2SMark Murray Port 34289 51511b41d2SMark Murray ForwardX11 no 52511b41d2SMark Murray ForwardAgent no 53511b41d2SMark Murray 54511b41d2SMark Murray Host books.com 55511b41d2SMark Murray RemoteForward 9999 shadows.cs.hut.fi:9999 56511b41d2SMark Murray Cipher 3des 57511b41d2SMark Murray 58511b41d2SMark Murray Host fascist.blob.com 59511b41d2SMark Murray Port 23123 60511b41d2SMark Murray User tylonen 61511b41d2SMark Murray PasswordAuthentication no 62511b41d2SMark Murray 63511b41d2SMark Murray Host puukko.hut.fi 64511b41d2SMark Murray User t35124p 65511b41d2SMark Murray ProxyCommand ssh-proxy %h %p 66511b41d2SMark Murray 67511b41d2SMark Murray Host *.fr 6880628bacSDag-Erling Smørgrav PublicKeyAuthentication no 69511b41d2SMark Murray 70511b41d2SMark Murray Host *.su 71511b41d2SMark Murray Cipher none 72511b41d2SMark Murray PasswordAuthentication no 73511b41d2SMark Murray 74511b41d2SMark Murray # Defaults for various options 75511b41d2SMark Murray Host * 76511b41d2SMark Murray ForwardAgent no 77ca3176e7SBrian Feldman ForwardX11 no 78511b41d2SMark Murray PasswordAuthentication yes 79511b41d2SMark Murray RSAAuthentication yes 80511b41d2SMark Murray RhostsRSAAuthentication yes 81511b41d2SMark Murray StrictHostKeyChecking yes 821ec0d754SDag-Erling Smørgrav TcpKeepAlive no 83511b41d2SMark Murray IdentityFile ~/.ssh/identity 84511b41d2SMark Murray Port 22 85511b41d2SMark Murray EscapeChar ~ 86511b41d2SMark Murray 87511b41d2SMark Murray */ 88511b41d2SMark Murray 89511b41d2SMark Murray /* Keyword tokens. */ 90511b41d2SMark Murray 91511b41d2SMark Murray typedef enum { 92511b41d2SMark Murray oBadOption, 931ec0d754SDag-Erling Smørgrav oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts, 9480628bacSDag-Erling Smørgrav oPasswordAuthentication, oRSAAuthentication, 95ca3176e7SBrian Feldman oChallengeResponseAuthentication, oXAuthLocation, 96511b41d2SMark Murray oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 97511b41d2SMark Murray oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 98511b41d2SMark Murray oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 99511b41d2SMark Murray oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 1001ec0d754SDag-Erling Smørgrav oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 101ca3176e7SBrian Feldman oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 102ca3176e7SBrian Feldman oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 103ca3176e7SBrian Feldman oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 104ca3176e7SBrian Feldman oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 105af12a3e7SDag-Erling Smørgrav oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 1069e2cbe04SDag-Erling Smørgrav oClearAllForwardings, oNoHostAuthenticationForLocalhost, 107cf2b5f3bSDag-Erling Smørgrav oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 108cf2b5f3bSDag-Erling Smørgrav oAddressFamily, oGssAuthentication, oGssDelegateCreds, 1095962c0e9SDag-Erling Smørgrav <<<<<<< readconf.c 1101ec0d754SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, 111975616f0SDag-Erling Smørgrav oVersionAddendum, 1125962c0e9SDag-Erling Smørgrav ======= 1135962c0e9SDag-Erling Smørgrav oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 1145962c0e9SDag-Erling Smørgrav >>>>>>> 1.1.1.15 115cf2b5f3bSDag-Erling Smørgrav oDeprecated, oUnsupported 116511b41d2SMark Murray } OpCodes; 117511b41d2SMark Murray 118511b41d2SMark Murray /* Textual representations of the tokens. */ 119511b41d2SMark Murray 120511b41d2SMark Murray static struct { 121511b41d2SMark Murray const char *name; 122511b41d2SMark Murray OpCodes opcode; 123511b41d2SMark Murray } keywords[] = { 124511b41d2SMark Murray { "forwardagent", oForwardAgent }, 125511b41d2SMark Murray { "forwardx11", oForwardX11 }, 1261ec0d754SDag-Erling Smørgrav { "forwardx11trusted", oForwardX11Trusted }, 127c2d3a559SKris Kennaway { "xauthlocation", oXAuthLocation }, 128511b41d2SMark Murray { "gatewayports", oGatewayPorts }, 129511b41d2SMark Murray { "useprivilegedport", oUsePrivilegedPort }, 130cf2b5f3bSDag-Erling Smørgrav { "rhostsauthentication", oDeprecated }, 131511b41d2SMark Murray { "passwordauthentication", oPasswordAuthentication }, 13209958426SBrian Feldman { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 13309958426SBrian Feldman { "kbdinteractivedevices", oKbdInteractiveDevices }, 134511b41d2SMark Murray { "rsaauthentication", oRSAAuthentication }, 135ca3176e7SBrian Feldman { "pubkeyauthentication", oPubkeyAuthentication }, 136ca3176e7SBrian Feldman { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 137ca3176e7SBrian Feldman { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 138ca3176e7SBrian Feldman { "hostbasedauthentication", oHostbasedAuthentication }, 139ca3176e7SBrian Feldman { "challengeresponseauthentication", oChallengeResponseAuthentication }, 140ca3176e7SBrian Feldman { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 141ca3176e7SBrian Feldman { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 142cf2b5f3bSDag-Erling Smørgrav { "kerberosauthentication", oUnsupported }, 143cf2b5f3bSDag-Erling Smørgrav { "kerberostgtpassing", oUnsupported }, 144cf2b5f3bSDag-Erling Smørgrav { "afstokenpassing", oUnsupported }, 145cf2b5f3bSDag-Erling Smørgrav #if defined(GSSAPI) 146cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oGssAuthentication }, 147cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oGssDelegateCreds }, 148cf2b5f3bSDag-Erling Smørgrav #else 149cf2b5f3bSDag-Erling Smørgrav { "gssapiauthentication", oUnsupported }, 150cf2b5f3bSDag-Erling Smørgrav { "gssapidelegatecredentials", oUnsupported }, 151511b41d2SMark Murray #endif 15280628bacSDag-Erling Smørgrav { "fallbacktorsh", oDeprecated }, 15380628bacSDag-Erling Smørgrav { "usersh", oDeprecated }, 154511b41d2SMark Murray { "identityfile", oIdentityFile }, 155ca3176e7SBrian Feldman { "identityfile2", oIdentityFile }, /* alias */ 1565962c0e9SDag-Erling Smørgrav { "identitiesonly", oIdentitiesOnly }, 157511b41d2SMark Murray { "hostname", oHostName }, 158ca3176e7SBrian Feldman { "hostkeyalias", oHostKeyAlias }, 159511b41d2SMark Murray { "proxycommand", oProxyCommand }, 160511b41d2SMark Murray { "port", oPort }, 161511b41d2SMark Murray { "cipher", oCipher }, 162e8aafc91SKris Kennaway { "ciphers", oCiphers }, 163ca3176e7SBrian Feldman { "macs", oMacs }, 164e8aafc91SKris Kennaway { "protocol", oProtocol }, 165511b41d2SMark Murray { "remoteforward", oRemoteForward }, 166511b41d2SMark Murray { "localforward", oLocalForward }, 167511b41d2SMark Murray { "user", oUser }, 168511b41d2SMark Murray { "host", oHost }, 169511b41d2SMark Murray { "escapechar", oEscapeChar }, 170511b41d2SMark Murray { "globalknownhostsfile", oGlobalKnownHostsFile }, 171af12a3e7SDag-Erling Smørgrav { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ 172e8aafc91SKris Kennaway { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 173af12a3e7SDag-Erling Smørgrav { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ 174511b41d2SMark Murray { "connectionattempts", oConnectionAttempts }, 175511b41d2SMark Murray { "batchmode", oBatchMode }, 176511b41d2SMark Murray { "checkhostip", oCheckHostIP }, 177511b41d2SMark Murray { "stricthostkeychecking", oStrictHostKeyChecking }, 178511b41d2SMark Murray { "compression", oCompression }, 179511b41d2SMark Murray { "compressionlevel", oCompressionLevel }, 1801ec0d754SDag-Erling Smørgrav { "tcpkeepalive", oTCPKeepAlive }, 1811ec0d754SDag-Erling Smørgrav { "keepalive", oTCPKeepAlive }, /* obsolete */ 182511b41d2SMark Murray { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 183511b41d2SMark Murray { "loglevel", oLogLevel }, 184ca3176e7SBrian Feldman { "dynamicforward", oDynamicForward }, 185ca3176e7SBrian Feldman { "preferredauthentications", oPreferredAuthentications }, 186ca3176e7SBrian Feldman { "hostkeyalgorithms", oHostKeyAlgorithms }, 187af12a3e7SDag-Erling Smørgrav { "bindaddress", oBindAddress }, 188cf2b5f3bSDag-Erling Smørgrav #ifdef SMARTCARD 189af12a3e7SDag-Erling Smørgrav { "smartcarddevice", oSmartcardDevice }, 190cf2b5f3bSDag-Erling Smørgrav #else 191cf2b5f3bSDag-Erling Smørgrav { "smartcarddevice", oUnsupported }, 192cf2b5f3bSDag-Erling Smørgrav #endif 193af12a3e7SDag-Erling Smørgrav { "clearallforwardings", oClearAllForwardings }, 194e73e9afaSDag-Erling Smørgrav { "enablesshkeysign", oEnableSSHKeysign }, 195cf2b5f3bSDag-Erling Smørgrav { "verifyhostkeydns", oVerifyHostKeyDNS }, 196af12a3e7SDag-Erling Smørgrav { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 197cf2b5f3bSDag-Erling Smørgrav { "rekeylimit", oRekeyLimit }, 198cf2b5f3bSDag-Erling Smørgrav { "connecttimeout", oConnectTimeout }, 199cf2b5f3bSDag-Erling Smørgrav { "addressfamily", oAddressFamily }, 2001ec0d754SDag-Erling Smørgrav { "serveraliveinterval", oServerAliveInterval }, 2011ec0d754SDag-Erling Smørgrav { "serveralivecountmax", oServerAliveCountMax }, 202975616f0SDag-Erling Smørgrav { "versionaddendum", oVersionAddendum }, 203af12a3e7SDag-Erling Smørgrav { NULL, oBadOption } 204511b41d2SMark Murray }; 205511b41d2SMark Murray 206511b41d2SMark Murray /* 207511b41d2SMark Murray * Adds a local TCP/IP port forward to options. Never returns if there is an 208511b41d2SMark Murray * error. 209511b41d2SMark Murray */ 210511b41d2SMark Murray 211511b41d2SMark Murray void 212511b41d2SMark Murray add_local_forward(Options *options, u_short port, const char *host, 213511b41d2SMark Murray u_short host_port) 214511b41d2SMark Murray { 215511b41d2SMark Murray Forward *fwd; 216f388f5efSDag-Erling Smørgrav #ifndef NO_IPPORT_RESERVED_CONCEPT 217511b41d2SMark Murray extern uid_t original_real_uid; 218511b41d2SMark Murray if (port < IPPORT_RESERVED && original_real_uid != 0) 219ca3176e7SBrian Feldman fatal("Privileged ports can only be forwarded by root."); 220989dd127SDag-Erling Smørgrav #endif 221511b41d2SMark Murray if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 222511b41d2SMark Murray fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 223511b41d2SMark Murray fwd = &options->local_forwards[options->num_local_forwards++]; 224511b41d2SMark Murray fwd->port = port; 225511b41d2SMark Murray fwd->host = xstrdup(host); 226511b41d2SMark Murray fwd->host_port = host_port; 227511b41d2SMark Murray } 228511b41d2SMark Murray 229511b41d2SMark Murray /* 230511b41d2SMark Murray * Adds a remote TCP/IP port forward to options. Never returns if there is 231511b41d2SMark Murray * an error. 232511b41d2SMark Murray */ 233511b41d2SMark Murray 234511b41d2SMark Murray void 235511b41d2SMark Murray add_remote_forward(Options *options, u_short port, const char *host, 236511b41d2SMark Murray u_short host_port) 237511b41d2SMark Murray { 238511b41d2SMark Murray Forward *fwd; 239511b41d2SMark Murray if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 240511b41d2SMark Murray fatal("Too many remote forwards (max %d).", 241511b41d2SMark Murray SSH_MAX_FORWARDS_PER_DIRECTION); 242511b41d2SMark Murray fwd = &options->remote_forwards[options->num_remote_forwards++]; 243511b41d2SMark Murray fwd->port = port; 244511b41d2SMark Murray fwd->host = xstrdup(host); 245511b41d2SMark Murray fwd->host_port = host_port; 246511b41d2SMark Murray } 247511b41d2SMark Murray 248af12a3e7SDag-Erling Smørgrav static void 249af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options) 250af12a3e7SDag-Erling Smørgrav { 251af12a3e7SDag-Erling Smørgrav int i; 252af12a3e7SDag-Erling Smørgrav 253af12a3e7SDag-Erling Smørgrav for (i = 0; i < options->num_local_forwards; i++) 254af12a3e7SDag-Erling Smørgrav xfree(options->local_forwards[i].host); 255af12a3e7SDag-Erling Smørgrav options->num_local_forwards = 0; 256af12a3e7SDag-Erling Smørgrav for (i = 0; i < options->num_remote_forwards; i++) 257af12a3e7SDag-Erling Smørgrav xfree(options->remote_forwards[i].host); 258af12a3e7SDag-Erling Smørgrav options->num_remote_forwards = 0; 259af12a3e7SDag-Erling Smørgrav } 260af12a3e7SDag-Erling Smørgrav 261511b41d2SMark Murray /* 262ca3176e7SBrian Feldman * Returns the number of the token pointed to by cp or oBadOption. 263511b41d2SMark Murray */ 264511b41d2SMark Murray 265511b41d2SMark Murray static OpCodes 266511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum) 267511b41d2SMark Murray { 268ca3176e7SBrian Feldman u_int i; 269511b41d2SMark Murray 270511b41d2SMark Murray for (i = 0; keywords[i].name; i++) 271511b41d2SMark Murray if (strcasecmp(cp, keywords[i].name) == 0) 272511b41d2SMark Murray return keywords[i].opcode; 273511b41d2SMark Murray 274ca3176e7SBrian Feldman error("%s: line %d: Bad configuration option: %s", 275511b41d2SMark Murray filename, linenum, cp); 276511b41d2SMark Murray return oBadOption; 277511b41d2SMark Murray } 278511b41d2SMark Murray 279511b41d2SMark Murray /* 280511b41d2SMark Murray * Processes a single option line as used in the configuration files. This 281511b41d2SMark Murray * only sets those values that have not already been set. 282511b41d2SMark Murray */ 283e73e9afaSDag-Erling Smørgrav #define WHITESPACE " \t\r\n" 284511b41d2SMark Murray 285511b41d2SMark Murray int 286511b41d2SMark Murray process_config_line(Options *options, const char *host, 287511b41d2SMark Murray char *line, const char *filename, int linenum, 288511b41d2SMark Murray int *activep) 289511b41d2SMark Murray { 290e73e9afaSDag-Erling Smørgrav char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; 291511b41d2SMark Murray int opcode, *intptr, value; 292e73e9afaSDag-Erling Smørgrav size_t len; 293511b41d2SMark Murray u_short fwd_port, fwd_host_port; 294af12a3e7SDag-Erling Smørgrav char sfwd_host_port[6]; 295511b41d2SMark Murray 296cf2b5f3bSDag-Erling Smørgrav /* Strip trailing whitespace */ 297cf2b5f3bSDag-Erling Smørgrav for(len = strlen(line) - 1; len > 0; len--) { 298cf2b5f3bSDag-Erling Smørgrav if (strchr(WHITESPACE, line[len]) == NULL) 299cf2b5f3bSDag-Erling Smørgrav break; 300cf2b5f3bSDag-Erling Smørgrav line[len] = '\0'; 301cf2b5f3bSDag-Erling Smørgrav } 302cf2b5f3bSDag-Erling Smørgrav 303c2d3a559SKris Kennaway s = line; 304c2d3a559SKris Kennaway /* Get the keyword. (Each line is supposed to begin with a keyword). */ 305c2d3a559SKris Kennaway keyword = strdelim(&s); 306c2d3a559SKris Kennaway /* Ignore leading whitespace. */ 307c2d3a559SKris Kennaway if (*keyword == '\0') 308c2d3a559SKris Kennaway keyword = strdelim(&s); 309ca3176e7SBrian Feldman if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#') 310511b41d2SMark Murray return 0; 311511b41d2SMark Murray 312c2d3a559SKris Kennaway opcode = parse_token(keyword, filename, linenum); 313511b41d2SMark Murray 314511b41d2SMark Murray switch (opcode) { 315511b41d2SMark Murray case oBadOption: 316511b41d2SMark Murray /* don't panic, but count bad options */ 317511b41d2SMark Murray return -1; 318511b41d2SMark Murray /* NOTREACHED */ 319cf2b5f3bSDag-Erling Smørgrav case oConnectTimeout: 320cf2b5f3bSDag-Erling Smørgrav intptr = &options->connection_timeout; 3211ec0d754SDag-Erling Smørgrav parse_time: 322cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 323cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 324cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: missing time value.", 325cf2b5f3bSDag-Erling Smørgrav filename, linenum); 326cf2b5f3bSDag-Erling Smørgrav if ((value = convtime(arg)) == -1) 327cf2b5f3bSDag-Erling Smørgrav fatal("%s line %d: invalid time value.", 328cf2b5f3bSDag-Erling Smørgrav filename, linenum); 329cf2b5f3bSDag-Erling Smørgrav if (*intptr == -1) 330cf2b5f3bSDag-Erling Smørgrav *intptr = value; 331cf2b5f3bSDag-Erling Smørgrav break; 332cf2b5f3bSDag-Erling Smørgrav 333511b41d2SMark Murray case oForwardAgent: 334511b41d2SMark Murray intptr = &options->forward_agent; 335511b41d2SMark Murray parse_flag: 336c2d3a559SKris Kennaway arg = strdelim(&s); 337c2d3a559SKris Kennaway if (!arg || *arg == '\0') 338511b41d2SMark Murray fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 339511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 340c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 341511b41d2SMark Murray value = 1; 342c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 343511b41d2SMark Murray value = 0; 344511b41d2SMark Murray else 345511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 346511b41d2SMark Murray if (*activep && *intptr == -1) 347511b41d2SMark Murray *intptr = value; 348511b41d2SMark Murray break; 349511b41d2SMark Murray 350511b41d2SMark Murray case oForwardX11: 351511b41d2SMark Murray intptr = &options->forward_x11; 352511b41d2SMark Murray goto parse_flag; 353511b41d2SMark Murray 3541ec0d754SDag-Erling Smørgrav case oForwardX11Trusted: 3551ec0d754SDag-Erling Smørgrav intptr = &options->forward_x11_trusted; 3561ec0d754SDag-Erling Smørgrav goto parse_flag; 3571ec0d754SDag-Erling Smørgrav 358511b41d2SMark Murray case oGatewayPorts: 359511b41d2SMark Murray intptr = &options->gateway_ports; 360511b41d2SMark Murray goto parse_flag; 361511b41d2SMark Murray 362511b41d2SMark Murray case oUsePrivilegedPort: 363511b41d2SMark Murray intptr = &options->use_privileged_port; 364511b41d2SMark Murray goto parse_flag; 365511b41d2SMark Murray 366511b41d2SMark Murray case oPasswordAuthentication: 367511b41d2SMark Murray intptr = &options->password_authentication; 368511b41d2SMark Murray goto parse_flag; 369511b41d2SMark Murray 37009958426SBrian Feldman case oKbdInteractiveAuthentication: 37109958426SBrian Feldman intptr = &options->kbd_interactive_authentication; 37209958426SBrian Feldman goto parse_flag; 37309958426SBrian Feldman 37409958426SBrian Feldman case oKbdInteractiveDevices: 37509958426SBrian Feldman charptr = &options->kbd_interactive_devices; 37609958426SBrian Feldman goto parse_string; 37709958426SBrian Feldman 378ca3176e7SBrian Feldman case oPubkeyAuthentication: 379ca3176e7SBrian Feldman intptr = &options->pubkey_authentication; 380e8aafc91SKris Kennaway goto parse_flag; 381e8aafc91SKris Kennaway 382511b41d2SMark Murray case oRSAAuthentication: 383511b41d2SMark Murray intptr = &options->rsa_authentication; 384511b41d2SMark Murray goto parse_flag; 385511b41d2SMark Murray 386511b41d2SMark Murray case oRhostsRSAAuthentication: 387511b41d2SMark Murray intptr = &options->rhosts_rsa_authentication; 388511b41d2SMark Murray goto parse_flag; 389511b41d2SMark Murray 390ca3176e7SBrian Feldman case oHostbasedAuthentication: 391ca3176e7SBrian Feldman intptr = &options->hostbased_authentication; 392511b41d2SMark Murray goto parse_flag; 393511b41d2SMark Murray 394af12a3e7SDag-Erling Smørgrav case oChallengeResponseAuthentication: 395af12a3e7SDag-Erling Smørgrav intptr = &options->challenge_response_authentication; 396af12a3e7SDag-Erling Smørgrav goto parse_flag; 397cf2b5f3bSDag-Erling Smørgrav 398cf2b5f3bSDag-Erling Smørgrav case oGssAuthentication: 399cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_authentication; 400511b41d2SMark Murray goto parse_flag; 401cf2b5f3bSDag-Erling Smørgrav 402cf2b5f3bSDag-Erling Smørgrav case oGssDelegateCreds: 403cf2b5f3bSDag-Erling Smørgrav intptr = &options->gss_deleg_creds; 404ca3176e7SBrian Feldman goto parse_flag; 405cf2b5f3bSDag-Erling Smørgrav 406511b41d2SMark Murray case oBatchMode: 407511b41d2SMark Murray intptr = &options->batch_mode; 408511b41d2SMark Murray goto parse_flag; 409511b41d2SMark Murray 410511b41d2SMark Murray case oCheckHostIP: 411511b41d2SMark Murray intptr = &options->check_host_ip; 412511b41d2SMark Murray goto parse_flag; 413511b41d2SMark Murray 414cf2b5f3bSDag-Erling Smørgrav case oVerifyHostKeyDNS: 415cf2b5f3bSDag-Erling Smørgrav intptr = &options->verify_host_key_dns; 4161ec0d754SDag-Erling Smørgrav goto parse_yesnoask; 417cf2b5f3bSDag-Erling Smørgrav 418511b41d2SMark Murray case oStrictHostKeyChecking: 419511b41d2SMark Murray intptr = &options->strict_host_key_checking; 4201ec0d754SDag-Erling Smørgrav parse_yesnoask: 421c2d3a559SKris Kennaway arg = strdelim(&s); 422c2d3a559SKris Kennaway if (!arg || *arg == '\0') 423ca3176e7SBrian Feldman fatal("%.200s line %d: Missing yes/no/ask argument.", 424511b41d2SMark Murray filename, linenum); 425511b41d2SMark Murray value = 0; /* To avoid compiler warning... */ 426c2d3a559SKris Kennaway if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0) 427511b41d2SMark Murray value = 1; 428c2d3a559SKris Kennaway else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0) 429511b41d2SMark Murray value = 0; 430c2d3a559SKris Kennaway else if (strcmp(arg, "ask") == 0) 431511b41d2SMark Murray value = 2; 432511b41d2SMark Murray else 433511b41d2SMark Murray fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 434511b41d2SMark Murray if (*activep && *intptr == -1) 435511b41d2SMark Murray *intptr = value; 436511b41d2SMark Murray break; 437511b41d2SMark Murray 438511b41d2SMark Murray case oCompression: 439511b41d2SMark Murray intptr = &options->compression; 440511b41d2SMark Murray goto parse_flag; 441511b41d2SMark Murray 4421ec0d754SDag-Erling Smørgrav case oTCPKeepAlive: 4431ec0d754SDag-Erling Smørgrav intptr = &options->tcp_keep_alive; 444511b41d2SMark Murray goto parse_flag; 445511b41d2SMark Murray 446af12a3e7SDag-Erling Smørgrav case oNoHostAuthenticationForLocalhost: 447af12a3e7SDag-Erling Smørgrav intptr = &options->no_host_authentication_for_localhost; 448af12a3e7SDag-Erling Smørgrav goto parse_flag; 449af12a3e7SDag-Erling Smørgrav 450511b41d2SMark Murray case oNumberOfPasswordPrompts: 451511b41d2SMark Murray intptr = &options->number_of_password_prompts; 452511b41d2SMark Murray goto parse_int; 453511b41d2SMark Murray 454511b41d2SMark Murray case oCompressionLevel: 455511b41d2SMark Murray intptr = &options->compression_level; 456511b41d2SMark Murray goto parse_int; 457511b41d2SMark Murray 458cf2b5f3bSDag-Erling Smørgrav case oRekeyLimit: 459cf2b5f3bSDag-Erling Smørgrav intptr = &options->rekey_limit; 460cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 461cf2b5f3bSDag-Erling Smørgrav if (!arg || *arg == '\0') 462cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 463cf2b5f3bSDag-Erling Smørgrav if (arg[0] < '0' || arg[0] > '9') 464cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 465cf2b5f3bSDag-Erling Smørgrav value = strtol(arg, &endofnumber, 10); 466cf2b5f3bSDag-Erling Smørgrav if (arg == endofnumber) 467cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Bad number.", filename, linenum); 468cf2b5f3bSDag-Erling Smørgrav switch (toupper(*endofnumber)) { 469cf2b5f3bSDag-Erling Smørgrav case 'K': 470cf2b5f3bSDag-Erling Smørgrav value *= 1<<10; 471cf2b5f3bSDag-Erling Smørgrav break; 472cf2b5f3bSDag-Erling Smørgrav case 'M': 473cf2b5f3bSDag-Erling Smørgrav value *= 1<<20; 474cf2b5f3bSDag-Erling Smørgrav break; 475cf2b5f3bSDag-Erling Smørgrav case 'G': 476cf2b5f3bSDag-Erling Smørgrav value *= 1<<30; 477cf2b5f3bSDag-Erling Smørgrav break; 478cf2b5f3bSDag-Erling Smørgrav } 479cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 480cf2b5f3bSDag-Erling Smørgrav *intptr = value; 481cf2b5f3bSDag-Erling Smørgrav break; 482cf2b5f3bSDag-Erling Smørgrav 483511b41d2SMark Murray case oIdentityFile: 484c2d3a559SKris Kennaway arg = strdelim(&s); 485c2d3a559SKris Kennaway if (!arg || *arg == '\0') 486511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 487511b41d2SMark Murray if (*activep) { 488ca3176e7SBrian Feldman intptr = &options->num_identity_files; 489e8aafc91SKris Kennaway if (*intptr >= SSH_MAX_IDENTITY_FILES) 490511b41d2SMark Murray fatal("%.200s line %d: Too many identity files specified (max %d).", 491511b41d2SMark Murray filename, linenum, SSH_MAX_IDENTITY_FILES); 492ca3176e7SBrian Feldman charptr = &options->identity_files[*intptr]; 493c2d3a559SKris Kennaway *charptr = xstrdup(arg); 494e8aafc91SKris Kennaway *intptr = *intptr + 1; 495511b41d2SMark Murray } 496511b41d2SMark Murray break; 497511b41d2SMark Murray 498c2d3a559SKris Kennaway case oXAuthLocation: 499c2d3a559SKris Kennaway charptr=&options->xauth_location; 500c2d3a559SKris Kennaway goto parse_string; 501c2d3a559SKris Kennaway 502511b41d2SMark Murray case oUser: 503511b41d2SMark Murray charptr = &options->user; 504511b41d2SMark Murray parse_string: 505c2d3a559SKris Kennaway arg = strdelim(&s); 506c2d3a559SKris Kennaway if (!arg || *arg == '\0') 507511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 508511b41d2SMark Murray if (*activep && *charptr == NULL) 509c2d3a559SKris Kennaway *charptr = xstrdup(arg); 510511b41d2SMark Murray break; 511511b41d2SMark Murray 512511b41d2SMark Murray case oGlobalKnownHostsFile: 513511b41d2SMark Murray charptr = &options->system_hostfile; 514511b41d2SMark Murray goto parse_string; 515511b41d2SMark Murray 516511b41d2SMark Murray case oUserKnownHostsFile: 517511b41d2SMark Murray charptr = &options->user_hostfile; 518511b41d2SMark Murray goto parse_string; 519511b41d2SMark Murray 520e8aafc91SKris Kennaway case oGlobalKnownHostsFile2: 521e8aafc91SKris Kennaway charptr = &options->system_hostfile2; 522e8aafc91SKris Kennaway goto parse_string; 523e8aafc91SKris Kennaway 524e8aafc91SKris Kennaway case oUserKnownHostsFile2: 525e8aafc91SKris Kennaway charptr = &options->user_hostfile2; 526e8aafc91SKris Kennaway goto parse_string; 527e8aafc91SKris Kennaway 528511b41d2SMark Murray case oHostName: 529511b41d2SMark Murray charptr = &options->hostname; 530511b41d2SMark Murray goto parse_string; 531511b41d2SMark Murray 532ca3176e7SBrian Feldman case oHostKeyAlias: 533ca3176e7SBrian Feldman charptr = &options->host_key_alias; 534ca3176e7SBrian Feldman goto parse_string; 535ca3176e7SBrian Feldman 536ca3176e7SBrian Feldman case oPreferredAuthentications: 537ca3176e7SBrian Feldman charptr = &options->preferred_authentications; 538ca3176e7SBrian Feldman goto parse_string; 539ca3176e7SBrian Feldman 540af12a3e7SDag-Erling Smørgrav case oBindAddress: 541af12a3e7SDag-Erling Smørgrav charptr = &options->bind_address; 542af12a3e7SDag-Erling Smørgrav goto parse_string; 543af12a3e7SDag-Erling Smørgrav 544af12a3e7SDag-Erling Smørgrav case oSmartcardDevice: 545af12a3e7SDag-Erling Smørgrav charptr = &options->smartcard_device; 546af12a3e7SDag-Erling Smørgrav goto parse_string; 547af12a3e7SDag-Erling Smørgrav 548511b41d2SMark Murray case oProxyCommand: 549cf2b5f3bSDag-Erling Smørgrav if (s == NULL) 550cf2b5f3bSDag-Erling Smørgrav fatal("%.200s line %d: Missing argument.", filename, linenum); 551511b41d2SMark Murray charptr = &options->proxy_command; 552e73e9afaSDag-Erling Smørgrav len = strspn(s, WHITESPACE "="); 553511b41d2SMark Murray if (*activep && *charptr == NULL) 554e73e9afaSDag-Erling Smørgrav *charptr = xstrdup(s + len); 555511b41d2SMark Murray return 0; 556511b41d2SMark Murray 557511b41d2SMark Murray case oPort: 558511b41d2SMark Murray intptr = &options->port; 559511b41d2SMark Murray parse_int: 560c2d3a559SKris Kennaway arg = strdelim(&s); 561c2d3a559SKris Kennaway if (!arg || *arg == '\0') 562511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 563c2d3a559SKris Kennaway if (arg[0] < '0' || arg[0] > '9') 564511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 565511b41d2SMark Murray 566511b41d2SMark Murray /* Octal, decimal, or hex format? */ 567c2d3a559SKris Kennaway value = strtol(arg, &endofnumber, 0); 568c2d3a559SKris Kennaway if (arg == endofnumber) 569511b41d2SMark Murray fatal("%.200s line %d: Bad number.", filename, linenum); 570511b41d2SMark Murray if (*activep && *intptr == -1) 571511b41d2SMark Murray *intptr = value; 572511b41d2SMark Murray break; 573511b41d2SMark Murray 574511b41d2SMark Murray case oConnectionAttempts: 575511b41d2SMark Murray intptr = &options->connection_attempts; 576511b41d2SMark Murray goto parse_int; 577511b41d2SMark Murray 578511b41d2SMark Murray case oCipher: 579511b41d2SMark Murray intptr = &options->cipher; 580c2d3a559SKris Kennaway arg = strdelim(&s); 581c2d3a559SKris Kennaway if (!arg || *arg == '\0') 582db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 583c2d3a559SKris Kennaway value = cipher_number(arg); 584511b41d2SMark Murray if (value == -1) 585511b41d2SMark Murray fatal("%.200s line %d: Bad cipher '%s'.", 586c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 587511b41d2SMark Murray if (*activep && *intptr == -1) 588511b41d2SMark Murray *intptr = value; 589511b41d2SMark Murray break; 590511b41d2SMark Murray 591e8aafc91SKris Kennaway case oCiphers: 592c2d3a559SKris Kennaway arg = strdelim(&s); 593c2d3a559SKris Kennaway if (!arg || *arg == '\0') 594db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 595c2d3a559SKris Kennaway if (!ciphers_valid(arg)) 596e8aafc91SKris Kennaway fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", 597c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 598e8aafc91SKris Kennaway if (*activep && options->ciphers == NULL) 599c2d3a559SKris Kennaway options->ciphers = xstrdup(arg); 600e8aafc91SKris Kennaway break; 601e8aafc91SKris Kennaway 602ca3176e7SBrian Feldman case oMacs: 603ca3176e7SBrian Feldman arg = strdelim(&s); 604ca3176e7SBrian Feldman if (!arg || *arg == '\0') 605ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 606ca3176e7SBrian Feldman if (!mac_valid(arg)) 607ca3176e7SBrian Feldman fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.", 608ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 609ca3176e7SBrian Feldman if (*activep && options->macs == NULL) 610ca3176e7SBrian Feldman options->macs = xstrdup(arg); 611ca3176e7SBrian Feldman break; 612ca3176e7SBrian Feldman 613ca3176e7SBrian Feldman case oHostKeyAlgorithms: 614ca3176e7SBrian Feldman arg = strdelim(&s); 615ca3176e7SBrian Feldman if (!arg || *arg == '\0') 616ca3176e7SBrian Feldman fatal("%.200s line %d: Missing argument.", filename, linenum); 617ca3176e7SBrian Feldman if (!key_names_valid2(arg)) 618ca3176e7SBrian Feldman fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", 619ca3176e7SBrian Feldman filename, linenum, arg ? arg : "<NONE>"); 620ca3176e7SBrian Feldman if (*activep && options->hostkeyalgorithms == NULL) 621ca3176e7SBrian Feldman options->hostkeyalgorithms = xstrdup(arg); 622ca3176e7SBrian Feldman break; 623ca3176e7SBrian Feldman 624e8aafc91SKris Kennaway case oProtocol: 625e8aafc91SKris Kennaway intptr = &options->protocol; 626c2d3a559SKris Kennaway arg = strdelim(&s); 627c2d3a559SKris Kennaway if (!arg || *arg == '\0') 628db1cb46cSKris Kennaway fatal("%.200s line %d: Missing argument.", filename, linenum); 629c2d3a559SKris Kennaway value = proto_spec(arg); 630e8aafc91SKris Kennaway if (value == SSH_PROTO_UNKNOWN) 631e8aafc91SKris Kennaway fatal("%.200s line %d: Bad protocol spec '%s'.", 632c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 633e8aafc91SKris Kennaway if (*activep && *intptr == SSH_PROTO_UNKNOWN) 634e8aafc91SKris Kennaway *intptr = value; 635e8aafc91SKris Kennaway break; 636e8aafc91SKris Kennaway 637511b41d2SMark Murray case oLogLevel: 638511b41d2SMark Murray intptr = (int *) &options->log_level; 639c2d3a559SKris Kennaway arg = strdelim(&s); 640c2d3a559SKris Kennaway value = log_level_number(arg); 641af12a3e7SDag-Erling Smørgrav if (value == SYSLOG_LEVEL_NOT_SET) 642ca3176e7SBrian Feldman fatal("%.200s line %d: unsupported log level '%s'", 643c2d3a559SKris Kennaway filename, linenum, arg ? arg : "<NONE>"); 644af12a3e7SDag-Erling Smørgrav if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET) 645511b41d2SMark Murray *intptr = (LogLevel) value; 646511b41d2SMark Murray break; 647511b41d2SMark Murray 648af12a3e7SDag-Erling Smørgrav case oLocalForward: 649511b41d2SMark Murray case oRemoteForward: 650c2d3a559SKris Kennaway arg = strdelim(&s); 651c2d3a559SKris Kennaway if (!arg || *arg == '\0') 652af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Missing port argument.", 653af12a3e7SDag-Erling Smørgrav filename, linenum); 654af12a3e7SDag-Erling Smørgrav if ((fwd_port = a2port(arg)) == 0) 655af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad listen port.", 656511b41d2SMark Murray filename, linenum); 657c2d3a559SKris Kennaway arg = strdelim(&s); 658c2d3a559SKris Kennaway if (!arg || *arg == '\0') 659511b41d2SMark Murray fatal("%.200s line %d: Missing second argument.", 660511b41d2SMark Murray filename, linenum); 661af12a3e7SDag-Erling Smørgrav if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && 662af12a3e7SDag-Erling Smørgrav sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) 663af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding specification.", 664511b41d2SMark Murray filename, linenum); 665af12a3e7SDag-Erling Smørgrav if ((fwd_host_port = a2port(sfwd_host_port)) == 0) 666af12a3e7SDag-Erling Smørgrav fatal("%.200s line %d: Bad forwarding port.", 667511b41d2SMark Murray filename, linenum); 668af12a3e7SDag-Erling Smørgrav if (*activep) { 669af12a3e7SDag-Erling Smørgrav if (opcode == oLocalForward) 670af12a3e7SDag-Erling Smørgrav add_local_forward(options, fwd_port, buf, 671af12a3e7SDag-Erling Smørgrav fwd_host_port); 672af12a3e7SDag-Erling Smørgrav else if (opcode == oRemoteForward) 673af12a3e7SDag-Erling Smørgrav add_remote_forward(options, fwd_port, buf, 674af12a3e7SDag-Erling Smørgrav fwd_host_port); 675af12a3e7SDag-Erling Smørgrav } 676511b41d2SMark Murray break; 677511b41d2SMark Murray 678ca3176e7SBrian Feldman case oDynamicForward: 679ca3176e7SBrian Feldman arg = strdelim(&s); 680ca3176e7SBrian Feldman if (!arg || *arg == '\0') 681ca3176e7SBrian Feldman fatal("%.200s line %d: Missing port argument.", 682ca3176e7SBrian Feldman filename, linenum); 683ca3176e7SBrian Feldman fwd_port = a2port(arg); 684ca3176e7SBrian Feldman if (fwd_port == 0) 685ca3176e7SBrian Feldman fatal("%.200s line %d: Badly formatted port number.", 686ca3176e7SBrian Feldman filename, linenum); 687af12a3e7SDag-Erling Smørgrav if (*activep) 688cf2b5f3bSDag-Erling Smørgrav add_local_forward(options, fwd_port, "socks", 0); 689ca3176e7SBrian Feldman break; 690ca3176e7SBrian Feldman 691af12a3e7SDag-Erling Smørgrav case oClearAllForwardings: 692af12a3e7SDag-Erling Smørgrav intptr = &options->clear_forwardings; 693af12a3e7SDag-Erling Smørgrav goto parse_flag; 694af12a3e7SDag-Erling Smørgrav 695511b41d2SMark Murray case oHost: 696511b41d2SMark Murray *activep = 0; 697c2d3a559SKris Kennaway while ((arg = strdelim(&s)) != NULL && *arg != '\0') 698c2d3a559SKris Kennaway if (match_pattern(host, arg)) { 699c2d3a559SKris Kennaway debug("Applying options for %.100s", arg); 700511b41d2SMark Murray *activep = 1; 701511b41d2SMark Murray break; 702511b41d2SMark Murray } 703c2d3a559SKris Kennaway /* Avoid garbage check below, as strdelim is done. */ 704511b41d2SMark Murray return 0; 705511b41d2SMark Murray 706511b41d2SMark Murray case oEscapeChar: 707511b41d2SMark Murray intptr = &options->escape_char; 708c2d3a559SKris Kennaway arg = strdelim(&s); 709c2d3a559SKris Kennaway if (!arg || *arg == '\0') 710511b41d2SMark Murray fatal("%.200s line %d: Missing argument.", filename, linenum); 711c2d3a559SKris Kennaway if (arg[0] == '^' && arg[2] == 0 && 712ca3176e7SBrian Feldman (u_char) arg[1] >= 64 && (u_char) arg[1] < 128) 713ca3176e7SBrian Feldman value = (u_char) arg[1] & 31; 714c2d3a559SKris Kennaway else if (strlen(arg) == 1) 715ca3176e7SBrian Feldman value = (u_char) arg[0]; 716c2d3a559SKris Kennaway else if (strcmp(arg, "none") == 0) 717af12a3e7SDag-Erling Smørgrav value = SSH_ESCAPECHAR_NONE; 718511b41d2SMark Murray else { 719511b41d2SMark Murray fatal("%.200s line %d: Bad escape character.", 720511b41d2SMark Murray filename, linenum); 721511b41d2SMark Murray /* NOTREACHED */ 722511b41d2SMark Murray value = 0; /* Avoid compiler warning. */ 723511b41d2SMark Murray } 724511b41d2SMark Murray if (*activep && *intptr == -1) 725511b41d2SMark Murray *intptr = value; 726511b41d2SMark Murray break; 727511b41d2SMark Murray 728cf2b5f3bSDag-Erling Smørgrav case oAddressFamily: 729cf2b5f3bSDag-Erling Smørgrav arg = strdelim(&s); 730cf2b5f3bSDag-Erling Smørgrav intptr = &options->address_family; 731cf2b5f3bSDag-Erling Smørgrav if (strcasecmp(arg, "inet") == 0) 732cf2b5f3bSDag-Erling Smørgrav value = AF_INET; 733cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "inet6") == 0) 734cf2b5f3bSDag-Erling Smørgrav value = AF_INET6; 735cf2b5f3bSDag-Erling Smørgrav else if (strcasecmp(arg, "any") == 0) 736cf2b5f3bSDag-Erling Smørgrav value = AF_UNSPEC; 737cf2b5f3bSDag-Erling Smørgrav else 738cf2b5f3bSDag-Erling Smørgrav fatal("Unsupported AddressFamily \"%s\"", arg); 739cf2b5f3bSDag-Erling Smørgrav if (*activep && *intptr == -1) 740cf2b5f3bSDag-Erling Smørgrav *intptr = value; 741cf2b5f3bSDag-Erling Smørgrav break; 742cf2b5f3bSDag-Erling Smørgrav 743e73e9afaSDag-Erling Smørgrav case oEnableSSHKeysign: 744e73e9afaSDag-Erling Smørgrav intptr = &options->enable_ssh_keysign; 745e73e9afaSDag-Erling Smørgrav goto parse_flag; 746e73e9afaSDag-Erling Smørgrav 7475962c0e9SDag-Erling Smørgrav case oIdentitiesOnly: 7485962c0e9SDag-Erling Smørgrav intptr = &options->identities_only; 7495962c0e9SDag-Erling Smørgrav goto parse_flag; 7505962c0e9SDag-Erling Smørgrav 7511ec0d754SDag-Erling Smørgrav case oServerAliveInterval: 7521ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_interval; 7531ec0d754SDag-Erling Smørgrav goto parse_time; 7541ec0d754SDag-Erling Smørgrav 7551ec0d754SDag-Erling Smørgrav case oServerAliveCountMax: 7561ec0d754SDag-Erling Smørgrav intptr = &options->server_alive_count_max; 7571ec0d754SDag-Erling Smørgrav goto parse_int; 7581ec0d754SDag-Erling Smørgrav 759975616f0SDag-Erling Smørgrav case oVersionAddendum: 760975616f0SDag-Erling Smørgrav ssh_version_set_addendum(strtok(s, "\n")); 761975616f0SDag-Erling Smørgrav do { 762975616f0SDag-Erling Smørgrav arg = strdelim(&s); 763975616f0SDag-Erling Smørgrav } while (arg != NULL && *arg != '\0'); 764975616f0SDag-Erling Smørgrav break; 765975616f0SDag-Erling Smørgrav 76680628bacSDag-Erling Smørgrav case oDeprecated: 76780628bacSDag-Erling Smørgrav debug("%s line %d: Deprecated option \"%s\"", 76880628bacSDag-Erling Smørgrav filename, linenum, keyword); 76980628bacSDag-Erling Smørgrav return 0; 77080628bacSDag-Erling Smørgrav 771cf2b5f3bSDag-Erling Smørgrav case oUnsupported: 772cf2b5f3bSDag-Erling Smørgrav error("%s line %d: Unsupported option \"%s\"", 773cf2b5f3bSDag-Erling Smørgrav filename, linenum, keyword); 774cf2b5f3bSDag-Erling Smørgrav return 0; 775cf2b5f3bSDag-Erling Smørgrav 776511b41d2SMark Murray default: 777511b41d2SMark Murray fatal("process_config_line: Unimplemented opcode %d", opcode); 778511b41d2SMark Murray } 779511b41d2SMark Murray 780511b41d2SMark Murray /* Check that there is no garbage at end of line. */ 781ca3176e7SBrian Feldman if ((arg = strdelim(&s)) != NULL && *arg != '\0') { 782c2d3a559SKris Kennaway fatal("%.200s line %d: garbage at end of line; \"%.200s\".", 783c2d3a559SKris Kennaway filename, linenum, arg); 784c2d3a559SKris Kennaway } 785511b41d2SMark Murray return 0; 786511b41d2SMark Murray } 787511b41d2SMark Murray 788511b41d2SMark Murray 789511b41d2SMark Murray /* 790511b41d2SMark Murray * Reads the config file and modifies the options accordingly. Options 791511b41d2SMark Murray * should already be initialized before this call. This never returns if 792af12a3e7SDag-Erling Smørgrav * there is an error. If the file does not exist, this returns 0. 793511b41d2SMark Murray */ 794511b41d2SMark Murray 795af12a3e7SDag-Erling Smørgrav int 796511b41d2SMark Murray read_config_file(const char *filename, const char *host, Options *options) 797511b41d2SMark Murray { 798511b41d2SMark Murray FILE *f; 799511b41d2SMark Murray char line[1024]; 800511b41d2SMark Murray int active, linenum; 801511b41d2SMark Murray int bad_options = 0; 802511b41d2SMark Murray 803511b41d2SMark Murray /* Open the file. */ 804511b41d2SMark Murray f = fopen(filename, "r"); 805511b41d2SMark Murray if (!f) 806af12a3e7SDag-Erling Smørgrav return 0; 807511b41d2SMark Murray 808511b41d2SMark Murray debug("Reading configuration data %.200s", filename); 809511b41d2SMark Murray 810511b41d2SMark Murray /* 811511b41d2SMark Murray * Mark that we are now processing the options. This flag is turned 812511b41d2SMark Murray * on/off by Host specifications. 813511b41d2SMark Murray */ 814511b41d2SMark Murray active = 1; 815511b41d2SMark Murray linenum = 0; 816511b41d2SMark Murray while (fgets(line, sizeof(line), f)) { 817511b41d2SMark Murray /* Update line number counter. */ 818511b41d2SMark Murray linenum++; 819511b41d2SMark Murray if (process_config_line(options, host, line, filename, linenum, &active) != 0) 820511b41d2SMark Murray bad_options++; 821511b41d2SMark Murray } 822511b41d2SMark Murray fclose(f); 823511b41d2SMark Murray if (bad_options > 0) 824ca3176e7SBrian Feldman fatal("%s: terminating, %d bad configuration options", 825511b41d2SMark Murray filename, bad_options); 826af12a3e7SDag-Erling Smørgrav return 1; 827511b41d2SMark Murray } 828511b41d2SMark Murray 829511b41d2SMark Murray /* 830511b41d2SMark Murray * Initializes options to special values that indicate that they have not yet 831511b41d2SMark Murray * been set. Read_config_file will only set options with this value. Options 832511b41d2SMark Murray * are processed in the following order: command line, user config file, 833511b41d2SMark Murray * system config file. Last, fill_default_options is called. 834511b41d2SMark Murray */ 835511b41d2SMark Murray 836511b41d2SMark Murray void 837511b41d2SMark Murray initialize_options(Options * options) 838511b41d2SMark Murray { 839511b41d2SMark Murray memset(options, 'X', sizeof(*options)); 840511b41d2SMark Murray options->forward_agent = -1; 841511b41d2SMark Murray options->forward_x11 = -1; 8421ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = -1; 843c2d3a559SKris Kennaway options->xauth_location = NULL; 844511b41d2SMark Murray options->gateway_ports = -1; 845511b41d2SMark Murray options->use_privileged_port = -1; 846511b41d2SMark Murray options->rsa_authentication = -1; 847ca3176e7SBrian Feldman options->pubkey_authentication = -1; 848af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = -1; 849cf2b5f3bSDag-Erling Smørgrav options->gss_authentication = -1; 850cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = -1; 851511b41d2SMark Murray options->password_authentication = -1; 85209958426SBrian Feldman options->kbd_interactive_authentication = -1; 85309958426SBrian Feldman options->kbd_interactive_devices = NULL; 854511b41d2SMark Murray options->rhosts_rsa_authentication = -1; 855ca3176e7SBrian Feldman options->hostbased_authentication = -1; 856511b41d2SMark Murray options->batch_mode = -1; 857511b41d2SMark Murray options->check_host_ip = -1; 858511b41d2SMark Murray options->strict_host_key_checking = -1; 859511b41d2SMark Murray options->compression = -1; 8601ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = -1; 861511b41d2SMark Murray options->compression_level = -1; 862511b41d2SMark Murray options->port = -1; 863cf2b5f3bSDag-Erling Smørgrav options->address_family = -1; 864511b41d2SMark Murray options->connection_attempts = -1; 865cf2b5f3bSDag-Erling Smørgrav options->connection_timeout = -1; 866511b41d2SMark Murray options->number_of_password_prompts = -1; 867511b41d2SMark Murray options->cipher = -1; 868e8aafc91SKris Kennaway options->ciphers = NULL; 869ca3176e7SBrian Feldman options->macs = NULL; 870ca3176e7SBrian Feldman options->hostkeyalgorithms = NULL; 871e8aafc91SKris Kennaway options->protocol = SSH_PROTO_UNKNOWN; 872511b41d2SMark Murray options->num_identity_files = 0; 873511b41d2SMark Murray options->hostname = NULL; 874ca3176e7SBrian Feldman options->host_key_alias = NULL; 875511b41d2SMark Murray options->proxy_command = NULL; 876511b41d2SMark Murray options->user = NULL; 877511b41d2SMark Murray options->escape_char = -1; 878511b41d2SMark Murray options->system_hostfile = NULL; 879511b41d2SMark Murray options->user_hostfile = NULL; 880e8aafc91SKris Kennaway options->system_hostfile2 = NULL; 881e8aafc91SKris Kennaway options->user_hostfile2 = NULL; 882511b41d2SMark Murray options->num_local_forwards = 0; 883511b41d2SMark Murray options->num_remote_forwards = 0; 884af12a3e7SDag-Erling Smørgrav options->clear_forwardings = -1; 885af12a3e7SDag-Erling Smørgrav options->log_level = SYSLOG_LEVEL_NOT_SET; 886ca3176e7SBrian Feldman options->preferred_authentications = NULL; 887af12a3e7SDag-Erling Smørgrav options->bind_address = NULL; 888af12a3e7SDag-Erling Smørgrav options->smartcard_device = NULL; 889e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = - 1; 890af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = - 1; 8915962c0e9SDag-Erling Smørgrav options->identities_only = - 1; 892cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = - 1; 893cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = -1; 8941ec0d754SDag-Erling Smørgrav options->server_alive_interval = -1; 8951ec0d754SDag-Erling Smørgrav options->server_alive_count_max = -1; 896511b41d2SMark Murray } 897511b41d2SMark Murray 898511b41d2SMark Murray /* 899511b41d2SMark Murray * Called after processing other sources of option data, this fills those 900511b41d2SMark Murray * options for which no value has been specified with their default values. 901511b41d2SMark Murray */ 902511b41d2SMark Murray 903511b41d2SMark Murray void 904511b41d2SMark Murray fill_default_options(Options * options) 905511b41d2SMark Murray { 906ca3176e7SBrian Feldman int len; 907ca3176e7SBrian Feldman 908511b41d2SMark Murray if (options->forward_agent == -1) 909db1cb46cSKris Kennaway options->forward_agent = 0; 910511b41d2SMark Murray if (options->forward_x11 == -1) 9115dc73ebeSBrian Feldman options->forward_x11 = 0; 9121ec0d754SDag-Erling Smørgrav if (options->forward_x11_trusted == -1) 9131ec0d754SDag-Erling Smørgrav options->forward_x11_trusted = 0; 914c2d3a559SKris Kennaway if (options->xauth_location == NULL) 915af12a3e7SDag-Erling Smørgrav options->xauth_location = _PATH_XAUTH; 916511b41d2SMark Murray if (options->gateway_ports == -1) 917511b41d2SMark Murray options->gateway_ports = 0; 918511b41d2SMark Murray if (options->use_privileged_port == -1) 919ca3176e7SBrian Feldman options->use_privileged_port = 0; 920511b41d2SMark Murray if (options->rsa_authentication == -1) 921511b41d2SMark Murray options->rsa_authentication = 1; 922ca3176e7SBrian Feldman if (options->pubkey_authentication == -1) 923ca3176e7SBrian Feldman options->pubkey_authentication = 1; 924af12a3e7SDag-Erling Smørgrav if (options->challenge_response_authentication == -1) 925af12a3e7SDag-Erling Smørgrav options->challenge_response_authentication = 1; 926cf2b5f3bSDag-Erling Smørgrav if (options->gss_authentication == -1) 9271ec0d754SDag-Erling Smørgrav options->gss_authentication = 0; 928cf2b5f3bSDag-Erling Smørgrav if (options->gss_deleg_creds == -1) 929cf2b5f3bSDag-Erling Smørgrav options->gss_deleg_creds = 0; 930511b41d2SMark Murray if (options->password_authentication == -1) 931511b41d2SMark Murray options->password_authentication = 1; 93209958426SBrian Feldman if (options->kbd_interactive_authentication == -1) 933ca3176e7SBrian Feldman options->kbd_interactive_authentication = 1; 934511b41d2SMark Murray if (options->rhosts_rsa_authentication == -1) 93580628bacSDag-Erling Smørgrav options->rhosts_rsa_authentication = 0; 936ca3176e7SBrian Feldman if (options->hostbased_authentication == -1) 937ca3176e7SBrian Feldman options->hostbased_authentication = 0; 938511b41d2SMark Murray if (options->batch_mode == -1) 939511b41d2SMark Murray options->batch_mode = 0; 940511b41d2SMark Murray if (options->check_host_ip == -1) 941975616f0SDag-Erling Smørgrav options->check_host_ip = 0; 942511b41d2SMark Murray if (options->strict_host_key_checking == -1) 943511b41d2SMark Murray options->strict_host_key_checking = 2; /* 2 is default */ 944511b41d2SMark Murray if (options->compression == -1) 945511b41d2SMark Murray options->compression = 0; 9461ec0d754SDag-Erling Smørgrav if (options->tcp_keep_alive == -1) 9471ec0d754SDag-Erling Smørgrav options->tcp_keep_alive = 1; 948511b41d2SMark Murray if (options->compression_level == -1) 949511b41d2SMark Murray options->compression_level = 6; 950511b41d2SMark Murray if (options->port == -1) 951511b41d2SMark Murray options->port = 0; /* Filled in ssh_connect. */ 952cf2b5f3bSDag-Erling Smørgrav if (options->address_family == -1) 953cf2b5f3bSDag-Erling Smørgrav options->address_family = AF_UNSPEC; 954511b41d2SMark Murray if (options->connection_attempts == -1) 955af12a3e7SDag-Erling Smørgrav options->connection_attempts = 1; 956511b41d2SMark Murray if (options->number_of_password_prompts == -1) 957511b41d2SMark Murray options->number_of_password_prompts = 3; 958511b41d2SMark Murray /* Selected in ssh_login(). */ 959511b41d2SMark Murray if (options->cipher == -1) 960511b41d2SMark Murray options->cipher = SSH_CIPHER_NOT_SET; 961e8aafc91SKris Kennaway /* options->ciphers, default set in myproposals.h */ 962ca3176e7SBrian Feldman /* options->macs, default set in myproposals.h */ 963ca3176e7SBrian Feldman /* options->hostkeyalgorithms, default set in myproposals.h */ 964e8aafc91SKris Kennaway if (options->protocol == SSH_PROTO_UNKNOWN) 965ca3176e7SBrian Feldman options->protocol = SSH_PROTO_1|SSH_PROTO_2; 966511b41d2SMark Murray if (options->num_identity_files == 0) { 967ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_1) { 968ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1; 969ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 970ca3176e7SBrian Feldman xmalloc(len); 971ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 972ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY); 973511b41d2SMark Murray } 974ca3176e7SBrian Feldman if (options->protocol & SSH_PROTO_2) { 975ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1; 976ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 977ca3176e7SBrian Feldman xmalloc(len); 978ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 979ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA); 980ca3176e7SBrian Feldman 981ca3176e7SBrian Feldman len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1; 982ca3176e7SBrian Feldman options->identity_files[options->num_identity_files] = 983ca3176e7SBrian Feldman xmalloc(len); 984ca3176e7SBrian Feldman snprintf(options->identity_files[options->num_identity_files++], 985ca3176e7SBrian Feldman len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); 986ca3176e7SBrian Feldman } 987e8aafc91SKris Kennaway } 988511b41d2SMark Murray if (options->escape_char == -1) 989511b41d2SMark Murray options->escape_char = '~'; 990511b41d2SMark Murray if (options->system_hostfile == NULL) 991ca3176e7SBrian Feldman options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE; 992511b41d2SMark Murray if (options->user_hostfile == NULL) 993ca3176e7SBrian Feldman options->user_hostfile = _PATH_SSH_USER_HOSTFILE; 994e8aafc91SKris Kennaway if (options->system_hostfile2 == NULL) 995ca3176e7SBrian Feldman options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2; 996e8aafc91SKris Kennaway if (options->user_hostfile2 == NULL) 997ca3176e7SBrian Feldman options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2; 998af12a3e7SDag-Erling Smørgrav if (options->log_level == SYSLOG_LEVEL_NOT_SET) 999511b41d2SMark Murray options->log_level = SYSLOG_LEVEL_INFO; 1000af12a3e7SDag-Erling Smørgrav if (options->clear_forwardings == 1) 1001af12a3e7SDag-Erling Smørgrav clear_forwardings(options); 1002af12a3e7SDag-Erling Smørgrav if (options->no_host_authentication_for_localhost == - 1) 1003af12a3e7SDag-Erling Smørgrav options->no_host_authentication_for_localhost = 0; 10045962c0e9SDag-Erling Smørgrav if (options->identities_only == -1) 10055962c0e9SDag-Erling Smørgrav options->identities_only = 0; 1006e73e9afaSDag-Erling Smørgrav if (options->enable_ssh_keysign == -1) 1007e73e9afaSDag-Erling Smørgrav options->enable_ssh_keysign = 0; 1008cf2b5f3bSDag-Erling Smørgrav if (options->rekey_limit == -1) 1009cf2b5f3bSDag-Erling Smørgrav options->rekey_limit = 0; 1010cf2b5f3bSDag-Erling Smørgrav if (options->verify_host_key_dns == -1) 1011cf2b5f3bSDag-Erling Smørgrav options->verify_host_key_dns = 0; 10121ec0d754SDag-Erling Smørgrav if (options->server_alive_interval == -1) 10131ec0d754SDag-Erling Smørgrav options->server_alive_interval = 0; 10141ec0d754SDag-Erling Smørgrav if (options->server_alive_count_max == -1) 10151ec0d754SDag-Erling Smørgrav options->server_alive_count_max = 3; 1016511b41d2SMark Murray /* options->proxy_command should not be set by default */ 1017511b41d2SMark Murray /* options->user will be set in the main program if appropriate */ 1018511b41d2SMark Murray /* options->hostname will be set in the main program if appropriate */ 1019ca3176e7SBrian Feldman /* options->host_key_alias should not be set by default */ 1020ca3176e7SBrian Feldman /* options->preferred_authentications will be set in ssh */ 1021511b41d2SMark Murray } 1022