Home | History | Annotate | Download | only in common
      1 /*
      2  * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
      3  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      4  *                    All rights reserved
      5  * Functions for reading the configuration files.
      6  *
      7  * As far as I am concerned, the code I have written for this software
      8  * can be used freely for any purpose.  Any derived versions of this
      9  * software must be clearly marked as such, and if the derived work is
     10  * incompatible with the protocol description in the RFC file, it must be
     11  * called by a name other than "ssh" or "Secure Shell".
     12  */
     13 /*
     14  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     15  * Use is subject to license terms.
     16  */
     17 
     18 #include "includes.h"
     19 RCSID("$OpenBSD: readconf.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
     20 
     21 #include "ssh.h"
     22 #include "xmalloc.h"
     23 #include "compat.h"
     24 #include "cipher.h"
     25 #include "pathnames.h"
     26 #include "log.h"
     27 #include "readconf.h"
     28 #include "match.h"
     29 #include "misc.h"
     30 #include "kex.h"
     31 #include "mac.h"
     32 
     33 /* Format of the configuration file:
     34 
     35    # Configuration data is parsed as follows:
     36    #  1. command line options
     37    #  2. user-specific file
     38    #  3. system-wide file
     39    # Any configuration value is only changed the first time it is set.
     40    # Thus, host-specific definitions should be at the beginning of the
     41    # configuration file, and defaults at the end.
     42 
     43    # Host-specific declarations.  These may override anything above.  A single
     44    # host may match multiple declarations; these are processed in the order
     45    # that they are given in.
     46 
     47    Host *.ngs.fi ngs.fi
     48      User foo
     49 
     50    Host fake.com
     51      HostName another.host.name.real.org
     52      User blaah
     53      Port 34289
     54      ForwardX11 no
     55      ForwardAgent no
     56 
     57    Host books.com
     58      RemoteForward 9999 shadows.cs.hut.fi:9999
     59      Cipher 3des
     60 
     61    Host fascist.blob.com
     62      Port 23123
     63      User tylonen
     64      RhostsAuthentication no
     65      PasswordAuthentication no
     66 
     67    Host puukko.hut.fi
     68      User t35124p
     69      ProxyCommand ssh-proxy %h %p
     70 
     71    Host *.fr
     72      PublicKeyAuthentication no
     73 
     74    Host *.su
     75      Cipher none
     76      PasswordAuthentication no
     77 
     78    # Defaults for various options
     79    Host *
     80      ForwardAgent no
     81      ForwardX11 no
     82      RhostsAuthentication yes
     83      PasswordAuthentication yes
     84      RSAAuthentication yes
     85      RhostsRSAAuthentication yes
     86      StrictHostKeyChecking yes
     87      KeepAlives no
     88      IdentityFile ~/.ssh/identity
     89      Port 22
     90      EscapeChar ~
     91 
     92 */
     93 
     94 /* Keyword tokens. */
     95 
     96 typedef enum {
     97 	oBadOption,
     98 	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
     99 	oRhostsAuthentication,
    100 	oPasswordAuthentication, oRSAAuthentication,
    101 	oChallengeResponseAuthentication, oXAuthLocation,
    102 #if defined(KRB4) || defined(KRB5)
    103 	oKerberosAuthentication,
    104 #endif
    105 #ifdef GSSAPI
    106 	oGssKeyEx, oGssAuthentication, oGssDelegateCreds,
    107 #ifdef GSI
    108 	oGssGlobusDelegateLimitedCreds,
    109 #endif /* GSI */
    110 #endif /* GSSAPI */
    111 #if defined(AFS) || defined(KRB5)
    112 	oKerberosTgtPassing,
    113 #endif
    114 #ifdef AFS
    115 	oAFSTokenPassing,
    116 #endif
    117 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
    118 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
    119 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
    120 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
    121 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
    122 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
    123 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
    124 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
    125 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
    126 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
    127 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
    128 	oFallBackToRsh, oUseRsh, oConnectTimeout, oHashKnownHosts,
    129 	oServerAliveInterval, oServerAliveCountMax, oDisableBanner,
    130 	oIgnoreIfUnknown, oRekeyLimit, oUseOpenSSLEngine,
    131 	oDeprecated
    132 } OpCodes;
    133 
    134 /* Textual representations of the tokens. */
    135 
    136 static struct {
    137 	const char *name;
    138 	OpCodes opcode;
    139 } keywords[] = {
    140 	{ "forwardagent", oForwardAgent },
    141 	{ "forwardx11", oForwardX11 },
    142 	{ "forwardx11trusted", oForwardX11Trusted },
    143 	{ "xauthlocation", oXAuthLocation },
    144 	{ "gatewayports", oGatewayPorts },
    145 	{ "useprivilegedport", oUsePrivilegedPort },
    146 	{ "rhostsauthentication", oRhostsAuthentication },
    147 	{ "passwordauthentication", oPasswordAuthentication },
    148 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
    149 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
    150 	{ "rsaauthentication", oRSAAuthentication },
    151 	{ "pubkeyauthentication", oPubkeyAuthentication },
    152 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
    153 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
    154 	{ "hostbasedauthentication", oHostbasedAuthentication },
    155 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
    156 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
    157 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
    158 #if defined(KRB4) || defined(KRB5)
    159 	{ "kerberosauthentication", oKerberosAuthentication },
    160 #endif
    161 #ifdef GSSAPI
    162 	{ "gssapikeyexchange", oGssKeyEx },
    163 	{ "gssapiauthentication", oGssAuthentication },
    164 	{ "gssapidelegatecredentials", oGssDelegateCreds },
    165 	{ "gsskeyex", oGssKeyEx },				/* alias */
    166 	{ "gssauthentication", oGssAuthentication },		/* alias */
    167 	{ "gssdelegatecreds", oGssDelegateCreds },		/* alias */
    168 #ifdef GSI
    169 	/* For backwards compatability with old 1.2.27 client code */
    170 	{ "forwardgssapiglobusproxy", oGssDelegateCreds }, /* alias */
    171 	{ "forwardgssapiglobuslimitedproxy", oGssGlobusDelegateLimitedCreds },
    172 #endif /* GSI */
    173 #endif /* GSSAPI */
    174 #if defined(AFS) || defined(KRB5)
    175 	{ "kerberostgtpassing", oKerberosTgtPassing },
    176 #endif
    177 #ifdef AFS
    178 	{ "afstokenpassing", oAFSTokenPassing },
    179 #endif
    180 	{ "fallbacktorsh", oFallBackToRsh },
    181 	{ "usersh", oUseRsh },
    182 	{ "identityfile", oIdentityFile },
    183 	{ "identityfile2", oIdentityFile },			/* alias */
    184 	{ "hostname", oHostName },
    185 	{ "hostkeyalias", oHostKeyAlias },
    186 	{ "proxycommand", oProxyCommand },
    187 	{ "port", oPort },
    188 	{ "cipher", oCipher },
    189 	{ "ciphers", oCiphers },
    190 	{ "macs", oMacs },
    191 	{ "protocol", oProtocol },
    192 	{ "remoteforward", oRemoteForward },
    193 	{ "localforward", oLocalForward },
    194 	{ "user", oUser },
    195 	{ "host", oHost },
    196 	{ "escapechar", oEscapeChar },
    197 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
    198 	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
    199 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
    200 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
    201 	{ "connectionattempts", oConnectionAttempts },
    202 	{ "batchmode", oBatchMode },
    203 	{ "checkhostip", oCheckHostIP },
    204 	{ "stricthostkeychecking", oStrictHostKeyChecking },
    205 	{ "compression", oCompression },
    206 	{ "compressionlevel", oCompressionLevel },
    207 	{ "keepalive", oKeepAlives },
    208 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
    209 	{ "loglevel", oLogLevel },
    210 	{ "dynamicforward", oDynamicForward },
    211 	{ "preferredauthentications", oPreferredAuthentications },
    212 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
    213 	{ "bindaddress", oBindAddress },
    214 	{ "smartcarddevice", oSmartcardDevice },
    215 	{ "clearallforwardings", oClearAllForwardings },
    216 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
    217 	{ "rekeylimit", oRekeyLimit },
    218 	{ "connecttimeout", oConnectTimeout },
    219 	{ "serveraliveinterval", oServerAliveInterval },
    220 	{ "serveralivecountmax", oServerAliveCountMax },
    221 	{ "disablebanner", oDisableBanner },
    222 	{ "hashknownhosts", oHashKnownHosts },
    223 	{ "ignoreifunknown", oIgnoreIfUnknown },
    224 	{ "useopensslengine", oUseOpenSSLEngine },
    225 	{ NULL, oBadOption }
    226 };
    227 
    228 /*
    229  * Adds a local TCP/IP port forward to options.  Never returns if there is an
    230  * error.
    231  */
    232 
    233 void
    234 add_local_forward(Options *options, const Forward *newfwd)
    235 {
    236 	Forward *fwd;
    237 #ifndef NO_IPPORT_RESERVED_CONCEPT
    238 	extern uid_t original_real_uid;
    239 	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
    240 		fatal("Privileged ports can only be forwarded by root.");
    241 #endif
    242 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
    243 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
    244 	fwd = &options->local_forwards[options->num_local_forwards++];
    245 
    246 	fwd->listen_host = (newfwd->listen_host == NULL) ?
    247 	    NULL : xstrdup(newfwd->listen_host);
    248 	fwd->listen_port = newfwd->listen_port;
    249 	fwd->connect_host = xstrdup(newfwd->connect_host);
    250 	fwd->connect_port = newfwd->connect_port;
    251 }
    252 
    253 /*
    254  * Adds a remote TCP/IP port forward to options.  Never returns if there is
    255  * an error.
    256  */
    257 
    258 void
    259 add_remote_forward(Options *options, const Forward *newfwd)
    260 {
    261 	Forward *fwd;
    262 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
    263 		fatal("Too many remote forwards (max %d).",
    264 		    SSH_MAX_FORWARDS_PER_DIRECTION);
    265 	fwd = &options->remote_forwards[options->num_remote_forwards++];
    266 
    267 	fwd->listen_host = (newfwd->listen_host == NULL) ?
    268 	    NULL : xstrdup(newfwd->listen_host);
    269 	fwd->listen_port = newfwd->listen_port;
    270 	fwd->connect_host = xstrdup(newfwd->connect_host);
    271 	fwd->connect_port = newfwd->connect_port;
    272 }
    273 
    274 static void
    275 clear_forwardings(Options *options)
    276 {
    277 	int i;
    278 
    279 	for (i = 0; i < options->num_local_forwards; i++) {
    280 		if (options->local_forwards[i].listen_host != NULL)
    281 			xfree(options->local_forwards[i].listen_host);
    282 		xfree(options->local_forwards[i].connect_host);
    283 	}
    284 	options->num_local_forwards = 0;
    285 	for (i = 0; i < options->num_remote_forwards; i++) {
    286 		if (options->remote_forwards[i].listen_host != NULL)
    287 			xfree(options->remote_forwards[i].listen_host);
    288 		xfree(options->remote_forwards[i].connect_host);
    289 	}
    290 	options->num_remote_forwards = 0;
    291 }
    292 
    293 /*
    294  * Returns the number of the token pointed to by cp or oBadOption.
    295  */
    296 
    297 static OpCodes
    298 parse_token(const char *cp, const char *filename, int linenum)
    299 {
    300 	u_int i;
    301 
    302 	for (i = 0; keywords[i].name; i++)
    303 		if (strcasecmp(cp, keywords[i].name) == 0)
    304 			return keywords[i].opcode;
    305 
    306 	debug("%s: line %d: unknown configuration option: %s",
    307 	    filename, linenum, cp);
    308 	return oBadOption;
    309 }
    310 
    311 /*
    312  * Processes a single option line as used in the configuration files. This
    313  * only sets those values that have not already been set.
    314  */
    315 
    316 int
    317 process_config_line(Options *options, const char *host,
    318 		    char *line, const char *filename, int linenum,
    319 		    int *activep)
    320 {
    321 	char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
    322 	int opcode, *intptr, value, scale, i;
    323 	long long orig, val64;
    324 	StoredOption *so;
    325 	Forward fwd;
    326 
    327 	s = line;
    328 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
    329 	keyword = strdelim(&s);
    330 	/* Ignore leading whitespace. */
    331 	if (*keyword == '\0')
    332 		keyword = strdelim(&s);
    333 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
    334 		return 0;
    335 
    336 	opcode = parse_token(keyword, filename, linenum);
    337 
    338 	switch (opcode) {
    339 	case oBadOption:
    340 		if (options->unknown_opts_num == MAX_UNKNOWN_OPTIONS) {
    341 			error("we can't have more than %d unknown options:",
    342 			    MAX_UNKNOWN_OPTIONS);
    343 			for (i = 0; i < MAX_UNKNOWN_OPTIONS; ++i) {
    344 				so = &options->unknown_opts[i];
    345 				error("%s:%d:%s",
    346 				    so->filename, so->linenum, so->keyword);
    347 				xfree(so->keyword);
    348 				xfree(so->filename);
    349 			}
    350 			fatal("too many unknown options found, can't continue");
    351 		}
    352 
    353 		/* unknown options will be processed later */
    354 		so = &options->unknown_opts[options->unknown_opts_num];
    355 		so->keyword = xstrdup(keyword);
    356 		so->filename = xstrdup(filename);
    357 		so->linenum = linenum;
    358 		options->unknown_opts_num++;
    359 		return (0);
    360 
    361 		/* NOTREACHED */
    362 	case oConnectTimeout:
    363 		intptr = &options->connection_timeout;
    364 parse_time:
    365 		arg = strdelim(&s);
    366 		if (!arg || *arg == '\0')
    367 			fatal("%s line %d: missing time value.",
    368 			    filename, linenum);
    369 		if ((value = convtime(arg)) == -1)
    370 			fatal("%s line %d: invalid time value.",
    371 			    filename, linenum);
    372 		if (*activep && *intptr == -1)
    373 			*intptr = value;
    374 		break;
    375 
    376 	case oForwardAgent:
    377 		intptr = &options->forward_agent;
    378 parse_flag:
    379 		arg = strdelim(&s);
    380 		if (!arg || *arg == '\0')
    381 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
    382 		value = 0;	/* To avoid compiler warning... */
    383 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    384 			value = 1;
    385 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    386 			value = 0;
    387 		else
    388 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
    389 		if (*activep && *intptr == -1)
    390 			*intptr = value;
    391 		break;
    392 
    393 	case oForwardX11:
    394 		intptr = &options->forward_x11;
    395 		goto parse_flag;
    396 
    397 	case oForwardX11Trusted:
    398 		intptr = &options->forward_x11_trusted;
    399 		goto parse_flag;
    400 
    401 	case oGatewayPorts:
    402 		intptr = &options->gateway_ports;
    403 		goto parse_flag;
    404 
    405 	case oUsePrivilegedPort:
    406 		intptr = &options->use_privileged_port;
    407 		goto parse_flag;
    408 
    409 	case oRhostsAuthentication:
    410 		intptr = &options->rhosts_authentication;
    411 		goto parse_flag;
    412 
    413 	case oPasswordAuthentication:
    414 		intptr = &options->password_authentication;
    415 		goto parse_flag;
    416 
    417 	case oKbdInteractiveAuthentication:
    418 		intptr = &options->kbd_interactive_authentication;
    419 		goto parse_flag;
    420 
    421 	case oKbdInteractiveDevices:
    422 		charptr = &options->kbd_interactive_devices;
    423 		goto parse_string;
    424 
    425 	case oPubkeyAuthentication:
    426 		intptr = &options->pubkey_authentication;
    427 		goto parse_flag;
    428 
    429 	case oRSAAuthentication:
    430 		intptr = &options->rsa_authentication;
    431 		goto parse_flag;
    432 
    433 	case oRhostsRSAAuthentication:
    434 		intptr = &options->rhosts_rsa_authentication;
    435 		goto parse_flag;
    436 
    437 	case oHostbasedAuthentication:
    438 		intptr = &options->hostbased_authentication;
    439 		goto parse_flag;
    440 
    441 	case oChallengeResponseAuthentication:
    442 		intptr = &options->challenge_response_authentication;
    443 		goto parse_flag;
    444 #if defined(KRB4) || defined(KRB5)
    445 	case oKerberosAuthentication:
    446 		intptr = &options->kerberos_authentication;
    447 		goto parse_flag;
    448 #endif
    449 #ifdef GSSAPI
    450 	case oGssKeyEx:
    451 		intptr = &options->gss_keyex;
    452 		goto parse_flag;
    453 
    454 	case oGssAuthentication:
    455 		intptr = &options->gss_authentication;
    456 		goto parse_flag;
    457 
    458 	case oGssDelegateCreds:
    459 		intptr = &options->gss_deleg_creds;
    460 		goto parse_flag;
    461 
    462 #ifdef GSI
    463 	case oGssGlobusDelegateLimitedCreds:
    464 		intptr = &options->gss_globus_deleg_limited_proxy;
    465 		goto parse_flag;
    466 #endif /* GSI */
    467 
    468 #endif /* GSSAPI */
    469 
    470 #if defined(AFS) || defined(KRB5)
    471 	case oKerberosTgtPassing:
    472 		intptr = &options->kerberos_tgt_passing;
    473 		goto parse_flag;
    474 #endif
    475 #ifdef AFS
    476 	case oAFSTokenPassing:
    477 		intptr = &options->afs_token_passing;
    478 		goto parse_flag;
    479 #endif
    480 	case oFallBackToRsh:
    481 		intptr = &options->fallback_to_rsh;
    482 		goto parse_flag;
    483 
    484 	case oUseRsh:
    485 		intptr = &options->use_rsh;
    486 		goto parse_flag;
    487 
    488 	case oBatchMode:
    489 		intptr = &options->batch_mode;
    490 		goto parse_flag;
    491 
    492 	case oCheckHostIP:
    493 		intptr = &options->check_host_ip;
    494 		goto parse_flag;
    495 
    496 	case oStrictHostKeyChecking:
    497 		intptr = &options->strict_host_key_checking;
    498 		arg = strdelim(&s);
    499 		if (!arg || *arg == '\0')
    500 			fatal("%.200s line %d: Missing yes/no/ask argument.",
    501 			    filename, linenum);
    502 		value = 0;	/* To avoid compiler warning... */
    503 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    504 			value = 1;
    505 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    506 			value = 0;
    507 		else if (strcmp(arg, "ask") == 0)
    508 			value = 2;
    509 		else
    510 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
    511 		if (*activep && *intptr == -1)
    512 			*intptr = value;
    513 		break;
    514 
    515 	case oCompression:
    516 		intptr = &options->compression;
    517 		goto parse_flag;
    518 
    519 	case oKeepAlives:
    520 		intptr = &options->keepalives;
    521 		goto parse_flag;
    522 
    523 	case oNoHostAuthenticationForLocalhost:
    524 		intptr = &options->no_host_authentication_for_localhost;
    525 		goto parse_flag;
    526 
    527 	case oNumberOfPasswordPrompts:
    528 		intptr = &options->number_of_password_prompts;
    529 		goto parse_int;
    530 
    531 	case oCompressionLevel:
    532 		intptr = &options->compression_level;
    533 		goto parse_int;
    534 
    535 	case oRekeyLimit:
    536 		arg = strdelim(&s);
    537 		if (!arg || *arg == '\0')
    538 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    539 		if (arg[0] < '0' || arg[0] > '9')
    540 			fatal("%.200s line %d: Bad number.", filename, linenum);
    541 		orig = val64 = strtoll(arg, &endofnumber, 10);
    542 		if (arg == endofnumber)
    543 			fatal("%.200s line %d: Bad number.", filename, linenum);
    544 		switch (toupper(*endofnumber)) {
    545 		case '\0':
    546 			scale = 1;
    547 			break;
    548 		case 'K':
    549 			scale = 1<<10;
    550 			break;
    551 		case 'M':
    552 			scale = 1<<20;
    553 			break;
    554 		case 'G':
    555 			scale = 1<<30;
    556 			break;
    557 		default:
    558 			fatal("%.200s line %d: Invalid RekeyLimit suffix",
    559 			    filename, linenum);
    560 		}
    561 		val64 *= scale;
    562 		/* detect integer wrap and too-large limits */
    563 		if ((val64 / scale) != orig || val64 > UINT_MAX)
    564 			fatal("%.200s line %d: RekeyLimit too large",
    565 			    filename, linenum);
    566 		if (val64 < 16)
    567 			fatal("%.200s line %d: RekeyLimit too small",
    568 			    filename, linenum);
    569 		if (*activep && options->rekey_limit == -1)
    570 			options->rekey_limit = (u_int32_t)val64;
    571 		break;
    572 
    573 	case oIdentityFile:
    574 		arg = strdelim(&s);
    575 		if (!arg || *arg == '\0')
    576 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    577 		if (*activep) {
    578 			intptr = &options->num_identity_files;
    579 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
    580 				fatal("%.200s line %d: Too many identity files specified (max %d).",
    581 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
    582 			charptr =  &options->identity_files[*intptr];
    583 			*charptr = xstrdup(arg);
    584 			*intptr = *intptr + 1;
    585 		}
    586 		break;
    587 
    588 	case oXAuthLocation:
    589 		charptr=&options->xauth_location;
    590 		goto parse_string;
    591 
    592 	case oUser:
    593 		charptr = &options->user;
    594 parse_string:
    595 		arg = strdelim(&s);
    596 		if (!arg || *arg == '\0')
    597 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    598 		if (*activep && *charptr == NULL)
    599 			*charptr = xstrdup(arg);
    600 		break;
    601 
    602 	case oGlobalKnownHostsFile:
    603 		charptr = &options->system_hostfile;
    604 		goto parse_string;
    605 
    606 	case oUserKnownHostsFile:
    607 		charptr = &options->user_hostfile;
    608 		goto parse_string;
    609 
    610 	case oGlobalKnownHostsFile2:
    611 		charptr = &options->system_hostfile2;
    612 		goto parse_string;
    613 
    614 	case oUserKnownHostsFile2:
    615 		charptr = &options->user_hostfile2;
    616 		goto parse_string;
    617 
    618 	case oHostName:
    619 		charptr = &options->hostname;
    620 		goto parse_string;
    621 
    622 	case oHostKeyAlias:
    623 		charptr = &options->host_key_alias;
    624 		goto parse_string;
    625 
    626 	case oPreferredAuthentications:
    627 		charptr = &options->preferred_authentications;
    628 		goto parse_string;
    629 
    630 	case oBindAddress:
    631 		charptr = &options->bind_address;
    632 		goto parse_string;
    633 
    634 	case oSmartcardDevice:
    635 		charptr = &options->smartcard_device;
    636 		goto parse_string;
    637 
    638 	case oProxyCommand:
    639 		charptr = &options->proxy_command;
    640 		string = xstrdup("");
    641 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    642 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
    643 			strcat(string, " ");
    644 			strcat(string, arg);
    645 		}
    646 		if (*activep && *charptr == NULL)
    647 			*charptr = string;
    648 		else
    649 			xfree(string);
    650 		return 0;
    651 
    652 	case oPort:
    653 		intptr = &options->port;
    654 parse_int:
    655 		arg = strdelim(&s);
    656 		if (!arg || *arg == '\0')
    657 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    658 		if (arg[0] < '0' || arg[0] > '9')
    659 			fatal("%.200s line %d: Bad number.", filename, linenum);
    660 
    661 		/* Octal, decimal, or hex format? */
    662 		value = strtol(arg, &endofnumber, 0);
    663 		if (arg == endofnumber)
    664 			fatal("%.200s line %d: Bad number.", filename, linenum);
    665 		if (*activep && *intptr == -1)
    666 			*intptr = value;
    667 		break;
    668 
    669 	case oConnectionAttempts:
    670 		intptr = &options->connection_attempts;
    671 		goto parse_int;
    672 
    673 	case oCipher:
    674 		intptr = &options->cipher;
    675 		arg = strdelim(&s);
    676 		if (!arg || *arg == '\0')
    677 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    678 		value = cipher_number(arg);
    679 		if (value == -1)
    680 			fatal("%.200s line %d: Bad cipher '%s'.",
    681 			    filename, linenum, arg ? arg : "<NONE>");
    682 		if (*activep && *intptr == -1)
    683 			*intptr = value;
    684 		break;
    685 
    686 	case oCiphers:
    687 		arg = strdelim(&s);
    688 		if (!arg || *arg == '\0')
    689 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    690 		if (!ciphers_valid(arg))
    691 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
    692 			    filename, linenum, arg ? arg : "<NONE>");
    693 		if (*activep && options->ciphers == NULL)
    694 			options->ciphers = xstrdup(arg);
    695 		break;
    696 
    697 	case oMacs:
    698 		arg = strdelim(&s);
    699 		if (!arg || *arg == '\0')
    700 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    701 		if (!mac_valid(arg))
    702 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
    703 			    filename, linenum, arg ? arg : "<NONE>");
    704 		if (*activep && options->macs == NULL)
    705 			options->macs = xstrdup(arg);
    706 		break;
    707 
    708 	case oHostKeyAlgorithms:
    709 		arg = strdelim(&s);
    710 		if (!arg || *arg == '\0')
    711 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    712 		if (!key_names_valid2(arg))
    713 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
    714 			    filename, linenum, arg ? arg : "<NONE>");
    715 		if (*activep && options->hostkeyalgorithms == NULL)
    716 			options->hostkeyalgorithms = xstrdup(arg);
    717 		break;
    718 
    719 	case oProtocol:
    720 		intptr = &options->protocol;
    721 		arg = strdelim(&s);
    722 		if (!arg || *arg == '\0')
    723 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    724 		value = proto_spec(arg);
    725 		if (value == SSH_PROTO_UNKNOWN)
    726 			fatal("%.200s line %d: Bad protocol spec '%s'.",
    727 			    filename, linenum, arg ? arg : "<NONE>");
    728 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
    729 			*intptr = value;
    730 		break;
    731 
    732 	case oLogLevel:
    733 		intptr = (int *) &options->log_level;
    734 		arg = strdelim(&s);
    735 		value = log_level_number(arg);
    736 		if (value == SYSLOG_LEVEL_NOT_SET)
    737 			fatal("%.200s line %d: unsupported log level '%s'",
    738 			    filename, linenum, arg ? arg : "<NONE>");
    739 		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
    740 			*intptr = (LogLevel) value;
    741 		break;
    742 
    743 	case oLocalForward:
    744 	case oRemoteForward:
    745 		arg = strdelim(&s);
    746 		if (arg == NULL || *arg == '\0')
    747 			fatal("%.200s line %d: Missing port argument.",
    748 			    filename, linenum);
    749 		arg2 = strdelim(&s);
    750 		if (arg2 == NULL || *arg2 == '\0')
    751 			fatal("%.200s line %d: Missing target argument.",
    752 			    filename, linenum);
    753 
    754 		/* construct a string for parse_forward */
    755 		snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
    756 
    757 		if (parse_forward(1, &fwd, fwdarg) == 0)
    758 			fatal("%.200s line %d: Bad forwarding specification.",
    759 			    filename, linenum);
    760 
    761 		if (*activep) {
    762 			if (opcode == oLocalForward)
    763 				add_local_forward(options, &fwd);
    764 			else if (opcode == oRemoteForward)
    765 				add_remote_forward(options, &fwd);
    766 		}
    767 		break;
    768 
    769 	case oDynamicForward:
    770 		arg = strdelim(&s);
    771 		if (!arg || *arg == '\0')
    772 			fatal("%.200s line %d: Missing port argument.",
    773 			    filename, linenum);
    774 
    775 		if (parse_forward(0, &fwd, arg) == 0) {
    776 			fatal("%.200s line %d: Bad dynamic forwarding specification.",
    777 			    filename, linenum);
    778 		}
    779 
    780 		if (*activep) {
    781 			fwd.connect_host = "socks";
    782 			add_local_forward(options, &fwd);
    783 		}
    784 		break;
    785 
    786 	case oClearAllForwardings:
    787 		intptr = &options->clear_forwardings;
    788 		goto parse_flag;
    789 
    790 	case oHost:
    791 		*activep = 0;
    792 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
    793 			if (match_pattern(host, arg)) {
    794 				debug("Applying options for %.100s", arg);
    795 				*activep = 1;
    796 				break;
    797 			}
    798 		/* Avoid garbage check below, as strdelim is done. */
    799 		return 0;
    800 
    801 	case oEscapeChar:
    802 		intptr = &options->escape_char;
    803 		arg = strdelim(&s);
    804 		if (!arg || *arg == '\0')
    805 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    806 		if (arg[0] == '^' && arg[2] == 0 &&
    807 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
    808 			value = (u_char) arg[1] & 31;
    809 		else if (strlen(arg) == 1)
    810 			value = (u_char) arg[0];
    811 		else if (strcmp(arg, "none") == 0)
    812 			value = SSH_ESCAPECHAR_NONE;
    813 		else {
    814 			fatal("%.200s line %d: Bad escape character.",
    815 			    filename, linenum);
    816 			/* NOTREACHED */
    817 			value = 0;	/* Avoid compiler warning. */
    818 		}
    819 		if (*activep && *intptr == -1)
    820 			*intptr = value;
    821 		break;
    822 
    823 	case oServerAliveInterval:
    824 		intptr = &options->server_alive_interval;
    825 		goto parse_time;
    826 
    827 	case oServerAliveCountMax:
    828 		intptr = &options->server_alive_count_max;
    829 		goto parse_int;
    830 
    831 	case oHashKnownHosts:
    832 		intptr = &options->hash_known_hosts;
    833 		goto parse_flag;
    834 
    835 	case oDisableBanner:
    836 		arg = strdelim(&s);
    837 		if (get_yes_no_flag(&options->disable_banner, arg, filename,
    838 		    linenum, *activep) == 1)
    839 			break;
    840 
    841 		if (strcmp(arg, "in-exec-mode") == 0)
    842 			options->disable_banner = SSH_NO_BANNER_IN_EXEC_MODE;
    843 		else
    844 			fatal("%.200s line %d: Bad yes/no/in-exec-mode "
    845 			    "argument.", filename, linenum);
    846 		break;
    847 
    848 	case oIgnoreIfUnknown:
    849 		charptr = &options->ignore_if_unknown;
    850 		goto parse_string;
    851 
    852 	case oUseOpenSSLEngine:
    853 		intptr = &options->use_openssl_engine;
    854 		goto parse_flag;
    855 
    856 	case oDeprecated:
    857 		debug("%s line %d: Deprecated option \"%s\"",
    858 		    filename, linenum, keyword);
    859 		return 0;
    860 
    861 	default:
    862 		fatal("process_config_line: Unimplemented opcode %d", opcode);
    863 	}
    864 
    865 	/* Check that there is no garbage at end of line. */
    866 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    867 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
    868 		     filename, linenum, arg);
    869 	}
    870 	return 0;
    871 }
    872 
    873 
    874 /*
    875  * Reads the config file and modifies the options accordingly.  Options
    876  * should already be initialized before this call.  This never returns if
    877  * there is an error.  If the file does not exist, this returns 0.
    878  */
    879 
    880 int
    881 read_config_file(const char *filename, const char *host, Options *options)
    882 {
    883 	FILE *f;
    884 	char line[1024];
    885 	int active, linenum;
    886 
    887 	/* Open the file. */
    888 	f = fopen(filename, "r");
    889 	if (!f)
    890 		return 0;
    891 
    892 	debug("Reading configuration data %.200s", filename);
    893 
    894 	/*
    895 	 * Mark that we are now processing the options.  This flag is turned
    896 	 * on/off by Host specifications.
    897 	 */
    898 	active = 1;
    899 	linenum = 0;
    900 	while (fgets(line, sizeof(line), f)) {
    901 		/* Update line number counter. */
    902 		linenum++;
    903 		process_config_line(options, host, line, filename, linenum, &active);
    904 	}
    905 	fclose(f);
    906 	return 1;
    907 }
    908 
    909 /*
    910  * Initializes options to special values that indicate that they have not yet
    911  * been set.  Read_config_file will only set options with this value. Options
    912  * are processed in the following order: command line, user config file,
    913  * system config file.  Last, fill_default_options is called.
    914  */
    915 
    916 void
    917 initialize_options(Options * options)
    918 {
    919 	memset(options, 'X', sizeof(*options));
    920 	options->forward_agent = -1;
    921 	options->forward_x11 = -1;
    922 	options->forward_x11_trusted = -1;
    923 	options->xauth_location = NULL;
    924 	options->gateway_ports = -1;
    925 	options->use_privileged_port = -1;
    926 	options->rhosts_authentication = -1;
    927 	options->rsa_authentication = -1;
    928 	options->pubkey_authentication = -1;
    929 	options->challenge_response_authentication = -1;
    930 #ifdef GSSAPI
    931         options->gss_keyex = -1;
    932         options->gss_authentication = -1;
    933         options->gss_deleg_creds = -1;
    934 #ifdef GSI
    935         options->gss_globus_deleg_limited_proxy = -1;
    936 #endif /* GSI */
    937 #endif /* GSSAPI */
    938 
    939 #if defined(KRB4) || defined(KRB5)
    940 	options->kerberos_authentication = -1;
    941 #endif
    942 #if defined(AFS) || defined(KRB5)
    943 	options->kerberos_tgt_passing = -1;
    944 #endif
    945 #ifdef AFS
    946 	options->afs_token_passing = -1;
    947 #endif
    948 	options->password_authentication = -1;
    949 	options->kbd_interactive_authentication = -1;
    950 	options->kbd_interactive_devices = NULL;
    951 	options->rhosts_rsa_authentication = -1;
    952 	options->hostbased_authentication = -1;
    953 	options->batch_mode = -1;
    954 	options->check_host_ip = -1;
    955 	options->strict_host_key_checking = -1;
    956 	options->compression = -1;
    957 	options->keepalives = -1;
    958 	options->compression_level = -1;
    959 	options->port = -1;
    960 	options->connection_attempts = -1;
    961 	options->connection_timeout = -1;
    962 	options->number_of_password_prompts = -1;
    963 	options->cipher = -1;
    964 	options->ciphers = NULL;
    965 	options->macs = NULL;
    966 	options->hostkeyalgorithms =