Home | History | Annotate | Line # | Download | only in dist
readconf.c revision 1.1.1.2
      1 /*	$NetBSD: readconf.c,v 1.1.1.2 2009/12/27 01:07:02 christos Exp $	*/
      2 /* $OpenBSD: readconf.c,v 1.177 2009/06/27 09:35:06 andreas Exp $ */
      3 /*
      4  * Author: Tatu Ylonen <ylo (at) cs.hut.fi>
      5  * Copyright (c) 1995 Tatu Ylonen <ylo (at) cs.hut.fi>, Espoo, Finland
      6  *                    All rights reserved
      7  * Functions for reading the configuration files.
      8  *
      9  * As far as I am concerned, the code I have written for this software
     10  * can be used freely for any purpose.  Any derived versions of this
     11  * software must be clearly marked as such, and if the derived work is
     12  * incompatible with the protocol description in the RFC file, it must be
     13  * called by a name other than "ssh" or "Secure Shell".
     14  */
     15 
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 #include <sys/socket.h>
     19 
     20 #include <netinet/in.h>
     21 
     22 #include <ctype.h>
     23 #include <errno.h>
     24 #include <netdb.h>
     25 #include <signal.h>
     26 #include <stdio.h>
     27 #include <string.h>
     28 #include <unistd.h>
     29 
     30 #include "xmalloc.h"
     31 #include "ssh.h"
     32 #include "compat.h"
     33 #include "cipher.h"
     34 #include "pathnames.h"
     35 #include "log.h"
     36 #include "key.h"
     37 #include "readconf.h"
     38 #include "match.h"
     39 #include "misc.h"
     40 #include "buffer.h"
     41 #include "kex.h"
     42 #include "mac.h"
     43 
     44 /* Format of the configuration file:
     45 
     46    # Configuration data is parsed as follows:
     47    #  1. command line options
     48    #  2. user-specific file
     49    #  3. system-wide file
     50    # Any configuration value is only changed the first time it is set.
     51    # Thus, host-specific definitions should be at the beginning of the
     52    # configuration file, and defaults at the end.
     53 
     54    # Host-specific declarations.  These may override anything above.  A single
     55    # host may match multiple declarations; these are processed in the order
     56    # that they are given in.
     57 
     58    Host *.ngs.fi ngs.fi
     59      User foo
     60 
     61    Host fake.com
     62      HostName another.host.name.real.org
     63      User blaah
     64      Port 34289
     65      ForwardX11 no
     66      ForwardAgent no
     67 
     68    Host books.com
     69      RemoteForward 9999 shadows.cs.hut.fi:9999
     70      Cipher 3des
     71 
     72    Host fascist.blob.com
     73      Port 23123
     74      User tylonen
     75      PasswordAuthentication no
     76 
     77    Host puukko.hut.fi
     78      User t35124p
     79      ProxyCommand ssh-proxy %h %p
     80 
     81    Host *.fr
     82      PublicKeyAuthentication no
     83 
     84    Host *.su
     85      Cipher none
     86      PasswordAuthentication no
     87 
     88    Host vpn.fake.com
     89      Tunnel yes
     90      TunnelDevice 3
     91 
     92    # Defaults for various options
     93    Host *
     94      ForwardAgent no
     95      ForwardX11 no
     96      PasswordAuthentication yes
     97      RSAAuthentication yes
     98      RhostsRSAAuthentication yes
     99      StrictHostKeyChecking yes
    100      TcpKeepAlive no
    101      IdentityFile ~/.ssh/identity
    102      Port 22
    103      EscapeChar ~
    104 
    105 */
    106 
    107 /* Keyword tokens. */
    108 
    109 typedef enum {
    110 	oBadOption,
    111 	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
    112 	oExitOnForwardFailure,
    113 	oPasswordAuthentication, oRSAAuthentication,
    114 	oChallengeResponseAuthentication, oXAuthLocation,
    115 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
    116 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
    117 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
    118 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
    119 	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
    120 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
    121 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
    122 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
    123 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
    124 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
    125 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
    126 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
    127 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
    128 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
    129 	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
    130 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
    131 	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
    132 	oDeprecated, oUnsupported
    133 } OpCodes;
    134 
    135 /* Textual representations of the tokens. */
    136 
    137 static struct {
    138 	const char *name;
    139 	OpCodes opcode;
    140 } keywords[] = {
    141 	{ "forwardagent", oForwardAgent },
    142 	{ "forwardx11", oForwardX11 },
    143 	{ "forwardx11trusted", oForwardX11Trusted },
    144 	{ "exitonforwardfailure", oExitOnForwardFailure },
    145 	{ "xauthlocation", oXAuthLocation },
    146 	{ "gatewayports", oGatewayPorts },
    147 	{ "useprivilegedport", oUsePrivilegedPort },
    148 	{ "rhostsauthentication", oDeprecated },
    149 	{ "passwordauthentication", oPasswordAuthentication },
    150 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
    151 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
    152 	{ "rsaauthentication", oRSAAuthentication },
    153 	{ "pubkeyauthentication", oPubkeyAuthentication },
    154 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
    155 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
    156 	{ "hostbasedauthentication", oHostbasedAuthentication },
    157 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
    158 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
    159 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
    160 	{ "kerberosauthentication", oUnsupported },
    161 	{ "kerberostgtpassing", oUnsupported },
    162 	{ "afstokenpassing", oUnsupported },
    163 #if defined(GSSAPI)
    164 	{ "gssapiauthentication", oGssAuthentication },
    165 	{ "gssapidelegatecredentials", oGssDelegateCreds },
    166 #else
    167 	{ "gssapiauthentication", oUnsupported },
    168 	{ "gssapidelegatecredentials", oUnsupported },
    169 #endif
    170 	{ "fallbacktorsh", oDeprecated },
    171 	{ "usersh", oDeprecated },
    172 	{ "identityfile", oIdentityFile },
    173 	{ "identityfile2", oIdentityFile },			/* obsolete */
    174 	{ "identitiesonly", oIdentitiesOnly },
    175 	{ "hostname", oHostName },
    176 	{ "hostkeyalias", oHostKeyAlias },
    177 	{ "proxycommand", oProxyCommand },
    178 	{ "port", oPort },
    179 	{ "cipher", oCipher },
    180 	{ "ciphers", oCiphers },
    181 	{ "macs", oMacs },
    182 	{ "protocol", oProtocol },
    183 	{ "remoteforward", oRemoteForward },
    184 	{ "localforward", oLocalForward },
    185 	{ "user", oUser },
    186 	{ "host", oHost },
    187 	{ "escapechar", oEscapeChar },
    188 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
    189 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },	/* obsolete */
    190 	{ "userknownhostsfile", oUserKnownHostsFile },
    191 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
    192 	{ "connectionattempts", oConnectionAttempts },
    193 	{ "batchmode", oBatchMode },
    194 	{ "checkhostip", oCheckHostIP },
    195 	{ "stricthostkeychecking", oStrictHostKeyChecking },
    196 	{ "compression", oCompression },
    197 	{ "compressionlevel", oCompressionLevel },
    198 	{ "tcpkeepalive", oTCPKeepAlive },
    199 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
    200 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
    201 	{ "loglevel", oLogLevel },
    202 	{ "dynamicforward", oDynamicForward },
    203 	{ "preferredauthentications", oPreferredAuthentications },
    204 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
    205 	{ "bindaddress", oBindAddress },
    206 #ifdef SMARTCARD
    207 	{ "smartcarddevice", oSmartcardDevice },
    208 #else
    209 	{ "smartcarddevice", oUnsupported },
    210 #endif
    211 	{ "clearallforwardings", oClearAllForwardings },
    212 	{ "enablesshkeysign", oEnableSSHKeysign },
    213 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
    214 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
    215 	{ "rekeylimit", oRekeyLimit },
    216 	{ "connecttimeout", oConnectTimeout },
    217 	{ "addressfamily", oAddressFamily },
    218 	{ "serveraliveinterval", oServerAliveInterval },
    219 	{ "serveralivecountmax", oServerAliveCountMax },
    220 	{ "sendenv", oSendEnv },
    221 	{ "controlpath", oControlPath },
    222 	{ "controlmaster", oControlMaster },
    223 	{ "hashknownhosts", oHashKnownHosts },
    224 	{ "tunnel", oTunnel },
    225 	{ "tunneldevice", oTunnelDevice },
    226 	{ "localcommand", oLocalCommand },
    227 	{ "permitlocalcommand", oPermitLocalCommand },
    228 	{ "visualhostkey", oVisualHostKey },
    229 	{ "useroaming", oUseRoaming },
    230 #ifdef JPAKE
    231 	{ "zeroknowledgepasswordauthentication",
    232 	    oZeroKnowledgePasswordAuthentication },
    233 #else
    234 	{ "zeroknowledgepasswordauthentication", oUnsupported },
    235 #endif
    236 
    237 	{ NULL, oBadOption }
    238 };
    239 
    240 /*
    241  * Adds a local TCP/IP port forward to options.  Never returns if there is an
    242  * error.
    243  */
    244 
    245 void
    246 add_local_forward(Options *options, const Forward *newfwd)
    247 {
    248 	Forward *fwd;
    249 	extern uid_t original_real_uid;
    250 	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
    251 		fatal("Privileged ports can only be forwarded by root.");
    252 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
    253 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
    254 	fwd = &options->local_forwards[options->num_local_forwards++];
    255 
    256 	fwd->listen_host = newfwd->listen_host;
    257 	fwd->listen_port = newfwd->listen_port;
    258 	fwd->connect_host = newfwd->connect_host;
    259 	fwd->connect_port = newfwd->connect_port;
    260 }
    261 
    262 /*
    263  * Adds a remote TCP/IP port forward to options.  Never returns if there is
    264  * an error.
    265  */
    266 
    267 void
    268 add_remote_forward(Options *options, const Forward *newfwd)
    269 {
    270 	Forward *fwd;
    271 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
    272 		fatal("Too many remote forwards (max %d).",
    273 		    SSH_MAX_FORWARDS_PER_DIRECTION);
    274 	fwd = &options->remote_forwards[options->num_remote_forwards++];
    275 
    276 	fwd->listen_host = newfwd->listen_host;
    277 	fwd->listen_port = newfwd->listen_port;
    278 	fwd->connect_host = newfwd->connect_host;
    279 	fwd->connect_port = newfwd->connect_port;
    280 }
    281 
    282 static void
    283 clear_forwardings(Options *options)
    284 {
    285 	int i;
    286 
    287 	for (i = 0; i < options->num_local_forwards; i++) {
    288 		if (options->local_forwards[i].listen_host != NULL)
    289 			xfree(options->local_forwards[i].listen_host);
    290 		xfree(options->local_forwards[i].connect_host);
    291 	}
    292 	options->num_local_forwards = 0;
    293 	for (i = 0; i < options->num_remote_forwards; i++) {
    294 		if (options->remote_forwards[i].listen_host != NULL)
    295 			xfree(options->remote_forwards[i].listen_host);
    296 		xfree(options->remote_forwards[i].connect_host);
    297 	}
    298 	options->num_remote_forwards = 0;
    299 	options->tun_open = SSH_TUNMODE_NO;
    300 }
    301 
    302 /*
    303  * Returns the number of the token pointed to by cp or oBadOption.
    304  */
    305 
    306 static OpCodes
    307 parse_token(const char *cp, const char *filename, int linenum)
    308 {
    309 	u_int i;
    310 
    311 	for (i = 0; keywords[i].name; i++)
    312 		if (strcasecmp(cp, keywords[i].name) == 0)
    313 			return keywords[i].opcode;
    314 
    315 	error("%s: line %d: Bad configuration option: %s",
    316 	    filename, linenum, cp);
    317 	return oBadOption;
    318 }
    319 
    320 /*
    321  * Processes a single option line as used in the configuration files. This
    322  * only sets those values that have not already been set.
    323  */
    324 #define WHITESPACE " \t\r\n"
    325 
    326 int
    327 process_config_line(Options *options, const char *host,
    328 		    char *line, const char *filename, int linenum,
    329 		    int *activep)
    330 {
    331 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
    332 	int opcode, *intptr, value, value2, scale;
    333 	LogLevel *log_level_ptr;
    334 	long long orig, val64;
    335 	size_t len;
    336 	Forward fwd;
    337 
    338 	/* Strip trailing whitespace */
    339 	for (len = strlen(line) - 1; len > 0; len--) {
    340 		if (strchr(WHITESPACE, line[len]) == NULL)
    341 			break;
    342 		line[len] = '\0';
    343 	}
    344 
    345 	s = line;
    346 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
    347 	if ((keyword = strdelim(&s)) == NULL)
    348 		return 0;
    349 	/* Ignore leading whitespace. */
    350 	if (*keyword == '\0')
    351 		keyword = strdelim(&s);
    352 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
    353 		return 0;
    354 
    355 	opcode = parse_token(keyword, filename, linenum);
    356 
    357 	switch (opcode) {
    358 	case oBadOption:
    359 		/* don't panic, but count bad options */
    360 		return -1;
    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 oExitOnForwardFailure:
    406 		intptr = &options->exit_on_forward_failure;
    407 		goto parse_flag;
    408 
    409 	case oUsePrivilegedPort:
    410 		intptr = &options->use_privileged_port;
    411 		goto parse_flag;
    412 
    413 	case oPasswordAuthentication:
    414 		intptr = &options->password_authentication;
    415 		goto parse_flag;
    416 
    417 	case oZeroKnowledgePasswordAuthentication:
    418 		intptr = &options->zero_knowledge_password_authentication;
    419 		goto parse_flag;
    420 
    421 	case oKbdInteractiveAuthentication:
    422 		intptr = &options->kbd_interactive_authentication;
    423 		goto parse_flag;
    424 
    425 	case oKbdInteractiveDevices:
    426 		charptr = &options->kbd_interactive_devices;
    427 		goto parse_string;
    428 
    429 	case oPubkeyAuthentication:
    430 		intptr = &options->pubkey_authentication;
    431 		goto parse_flag;
    432 
    433 	case oRSAAuthentication:
    434 		intptr = &options->rsa_authentication;
    435 		goto parse_flag;
    436 
    437 	case oRhostsRSAAuthentication:
    438 		intptr = &options->rhosts_rsa_authentication;
    439 		goto parse_flag;
    440 
    441 	case oHostbasedAuthentication:
    442 		intptr = &options->hostbased_authentication;
    443 		goto parse_flag;
    444 
    445 	case oChallengeResponseAuthentication:
    446 		intptr = &options->challenge_response_authentication;
    447 		goto parse_flag;
    448 
    449 	case oGssAuthentication:
    450 		intptr = &options->gss_authentication;
    451 		goto parse_flag;
    452 
    453 	case oGssDelegateCreds:
    454 		intptr = &options->gss_deleg_creds;
    455 		goto parse_flag;
    456 
    457 	case oBatchMode:
    458 		intptr = &options->batch_mode;
    459 		goto parse_flag;
    460 
    461 	case oCheckHostIP:
    462 		intptr = &options->check_host_ip;
    463 		goto parse_flag;
    464 
    465 	case oVerifyHostKeyDNS:
    466 		intptr = &options->verify_host_key_dns;
    467 		goto parse_yesnoask;
    468 
    469 	case oStrictHostKeyChecking:
    470 		intptr = &options->strict_host_key_checking;
    471 parse_yesnoask:
    472 		arg = strdelim(&s);
    473 		if (!arg || *arg == '\0')
    474 			fatal("%.200s line %d: Missing yes/no/ask argument.",
    475 			    filename, linenum);
    476 		value = 0;	/* To avoid compiler warning... */
    477 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    478 			value = 1;
    479 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    480 			value = 0;
    481 		else if (strcmp(arg, "ask") == 0)
    482 			value = 2;
    483 		else
    484 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
    485 		if (*activep && *intptr == -1)
    486 			*intptr = value;
    487 		break;
    488 
    489 	case oCompression:
    490 		intptr = &options->compression;
    491 		goto parse_flag;
    492 
    493 	case oTCPKeepAlive:
    494 		intptr = &options->tcp_keep_alive;
    495 		goto parse_flag;
    496 
    497 	case oNoHostAuthenticationForLocalhost:
    498 		intptr = &options->no_host_authentication_for_localhost;
    499 		goto parse_flag;
    500 
    501 	case oNumberOfPasswordPrompts:
    502 		intptr = &options->number_of_password_prompts;
    503 		goto parse_int;
    504 
    505 	case oCompressionLevel:
    506 		intptr = &options->compression_level;
    507 		goto parse_int;
    508 
    509 	case oRekeyLimit:
    510 		arg = strdelim(&s);
    511 		if (!arg || *arg == '\0')
    512 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    513 		if (arg[0] < '0' || arg[0] > '9')
    514 			fatal("%.200s line %d: Bad number.", filename, linenum);
    515 		orig = val64 = strtoll(arg, &endofnumber, 10);
    516 		if (arg == endofnumber)
    517 			fatal("%.200s line %d: Bad number.", filename, linenum);
    518 		switch (toupper(*endofnumber)) {
    519 		case '\0':
    520 			scale = 1;
    521 			break;
    522 		case 'K':
    523 			scale = 1<<10;
    524 			break;
    525 		case 'M':
    526 			scale = 1<<20;
    527 			break;
    528 		case 'G':
    529 			scale = 1<<30;
    530 			break;
    531 		default:
    532 			fatal("%.200s line %d: Invalid RekeyLimit suffix",
    533 			    filename, linenum);
    534 		}
    535 		val64 *= scale;
    536 		/* detect integer wrap and too-large limits */
    537 		if ((val64 / scale) != orig || val64 > UINT_MAX)
    538 			fatal("%.200s line %d: RekeyLimit too large",
    539 			    filename, linenum);
    540 		if (val64 < 16)
    541 			fatal("%.200s line %d: RekeyLimit too small",
    542 			    filename, linenum);
    543 		if (*activep && options->rekey_limit == -1)
    544 			options->rekey_limit = (u_int32_t)val64;
    545 		break;
    546 
    547 	case oIdentityFile:
    548 		arg = strdelim(&s);
    549 		if (!arg || *arg == '\0')
    550 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    551 		if (*activep) {
    552 			intptr = &options->num_identity_files;
    553 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
    554 				fatal("%.200s line %d: Too many identity files specified (max %d).",
    555 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
    556 			charptr = &options->identity_files[*intptr];
    557 			*charptr = xstrdup(arg);
    558 			*intptr = *intptr + 1;
    559 		}
    560 		break;
    561 
    562 	case oXAuthLocation:
    563 		charptr=&options->xauth_location;
    564 		goto parse_string;
    565 
    566 	case oUser:
    567 		charptr = &options->user;
    568 parse_string:
    569 		arg = strdelim(&s);
    570 		if (!arg || *arg == '\0')
    571 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    572 		if (*activep && *charptr == NULL)
    573 			*charptr = xstrdup(arg);
    574 		break;
    575 
    576 	case oGlobalKnownHostsFile:
    577 		charptr = &options->system_hostfile;
    578 		goto parse_string;
    579 
    580 	case oUserKnownHostsFile:
    581 		charptr = &options->user_hostfile;
    582 		goto parse_string;
    583 
    584 	case oGlobalKnownHostsFile2:
    585 		charptr = &options->system_hostfile2;
    586 		goto parse_string;
    587 
    588 	case oUserKnownHostsFile2:
    589 		charptr = &options->user_hostfile2;
    590 		goto parse_string;
    591 
    592 	case oHostName:
    593 		charptr = &options->hostname;
    594 		goto parse_string;
    595 
    596 	case oHostKeyAlias:
    597 		charptr = &options->host_key_alias;
    598 		goto parse_string;
    599 
    600 	case oPreferredAuthentications:
    601 		charptr = &options->preferred_authentications;
    602 		goto parse_string;
    603 
    604 	case oBindAddress:
    605 		charptr = &options->bind_address;
    606 		goto parse_string;
    607 
    608 	case oSmartcardDevice:
    609 		charptr = &options->smartcard_device;
    610 		goto parse_string;
    611 
    612 	case oProxyCommand:
    613 		charptr = &options->proxy_command;
    614 parse_command:
    615 		if (s == NULL)
    616 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    617 		len = strspn(s, WHITESPACE "=");
    618 		if (*activep && *charptr == NULL)
    619 			*charptr = xstrdup(s + len);
    620 		return 0;
    621 
    622 	case oPort:
    623 		intptr = &options->port;
    624 parse_int:
    625 		arg = strdelim(&s);
    626 		if (!arg || *arg == '\0')
    627 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    628 		if (arg[0] < '0' || arg[0] > '9')
    629 			fatal("%.200s line %d: Bad number.", filename, linenum);
    630 
    631 		/* Octal, decimal, or hex format? */
    632 		value = strtol(arg, &endofnumber, 0);
    633 		if (arg == endofnumber)
    634 			fatal("%.200s line %d: Bad number.", filename, linenum);
    635 		if (*activep && *intptr == -1)
    636 			*intptr = value;
    637 		break;
    638 
    639 	case oConnectionAttempts:
    640 		intptr = &options->connection_attempts;
    641 		goto parse_int;
    642 
    643 	case oCipher:
    644 		intptr = &options->cipher;
    645 		arg = strdelim(&s);
    646 		if (!arg || *arg == '\0')
    647 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    648 		value = cipher_number(arg);
    649 		if (value == -1)
    650 			fatal("%.200s line %d: Bad cipher '%s'.",
    651 			    filename, linenum, arg ? arg : "<NONE>");
    652 		if (*activep && *intptr == -1)
    653 			*intptr = value;
    654 		break;
    655 
    656 	case oCiphers:
    657 		arg = strdelim(&s);
    658 		if (!arg || *arg == '\0')
    659 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    660 		if (!ciphers_valid(arg))
    661 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
    662 			    filename, linenum, arg ? arg : "<NONE>");
    663 		if (*activep && options->ciphers == NULL)
    664 			options->ciphers = xstrdup(arg);
    665 		break;
    666 
    667 	case oMacs:
    668 		arg = strdelim(&s);
    669 		if (!arg || *arg == '\0')
    670 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    671 		if (!mac_valid(arg))
    672 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
    673 			    filename, linenum, arg ? arg : "<NONE>");
    674 		if (*activep && options->macs == NULL)
    675 			options->macs = xstrdup(arg);
    676 		break;
    677 
    678 	case oHostKeyAlgorithms:
    679 		arg = strdelim(&s);
    680 		if (!arg || *arg == '\0')
    681 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    682 		if (!key_names_valid2(arg))
    683 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
    684 			    filename, linenum, arg ? arg : "<NONE>");
    685 		if (*activep && options->hostkeyalgorithms == NULL)
    686 			options->hostkeyalgorithms = xstrdup(arg);
    687 		break;
    688 
    689 	case oProtocol:
    690 		intptr = &options->protocol;
    691 		arg = strdelim(&s);
    692 		if (!arg || *arg == '\0')
    693 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    694 		value = proto_spec(arg);
    695 		if (value == SSH_PROTO_UNKNOWN)
    696 			fatal("%.200s line %d: Bad protocol spec '%s'.",
    697 			    filename, linenum, arg ? arg : "<NONE>");
    698 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
    699 			*intptr = value;
    700 		break;
    701 
    702 	case oLogLevel:
    703 		log_level_ptr = &options->log_level;
    704 		arg = strdelim(&s);
    705 		value = log_level_number(arg);
    706 		if (value == SYSLOG_LEVEL_NOT_SET)
    707 			fatal("%.200s line %d: unsupported log level '%s'",
    708 			    filename, linenum, arg ? arg : "<NONE>");
    709 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
    710 			*log_level_ptr = (LogLevel) value;
    711 		break;
    712 
    713 	case oLocalForward:
    714 	case oRemoteForward:
    715 	case oDynamicForward:
    716 		arg = strdelim(&s);
    717 		if (arg == NULL || *arg == '\0')
    718 			fatal("%.200s line %d: Missing port argument.",
    719 			    filename, linenum);
    720 
    721 		if (opcode == oLocalForward ||
    722 		    opcode == oRemoteForward) {
    723 			arg2 = strdelim(&s);
    724 			if (arg2 == NULL || *arg2 == '\0')
    725 				fatal("%.200s line %d: Missing target argument.",
    726 				    filename, linenum);
    727 
    728 			/* construct a string for parse_forward */
    729 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
    730 		} else if (opcode == oDynamicForward) {
    731 			strlcpy(fwdarg, arg, sizeof(fwdarg));
    732 		}
    733 
    734 		if (parse_forward(&fwd, fwdarg,
    735 		    opcode == oDynamicForward ? 1 : 0,
    736 		    opcode == oRemoteForward ? 1 : 0) == 0)
    737 			fatal("%.200s line %d: Bad forwarding specification.",
    738 			    filename, linenum);
    739 
    740 		if (*activep) {
    741 			if (opcode == oLocalForward ||
    742 			    opcode == oDynamicForward)
    743 				add_local_forward(options, &fwd);
    744 			else if (opcode == oRemoteForward)
    745 				add_remote_forward(options, &fwd);
    746 		}
    747 		break;
    748 
    749 	case oClearAllForwardings:
    750 		intptr = &options->clear_forwardings;
    751 		goto parse_flag;
    752 
    753 	case oHost:
    754 		*activep = 0;
    755 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
    756 			if (match_pattern(host, arg)) {
    757 				debug("Applying options for %.100s", arg);
    758 				*activep = 1;
    759 				break;
    760 			}
    761 		/* Avoid garbage check below, as strdelim is done. */
    762 		return 0;
    763 
    764 	case oEscapeChar:
    765 		intptr = &options->escape_char;
    766 		arg = strdelim(&s);
    767 		if (!arg || *arg == '\0')
    768 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    769 		if (arg[0] == '^' && arg[2] == 0 &&
    770 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
    771 			value = (u_char) arg[1] & 31;
    772 		else if (strlen(arg) == 1)
    773 			value = (u_char) arg[0];
    774 		else if (strcmp(arg, "none") == 0)
    775 			value = SSH_ESCAPECHAR_NONE;
    776 		else {
    777 			fatal("%.200s line %d: Bad escape character.",
    778 			    filename, linenum);
    779 			/* NOTREACHED */
    780 			value = 0;	/* Avoid compiler warning. */
    781 		}
    782 		if (*activep && *intptr == -1)
    783 			*intptr = value;
    784 		break;
    785 
    786 	case oAddressFamily:
    787 		arg = strdelim(&s);
    788 		if (!arg || *arg == '\0')
    789 			fatal("%s line %d: missing address family.",
    790 			    filename, linenum);
    791 		intptr = &options->address_family;
    792 		if (strcasecmp(arg, "inet") == 0)
    793 			value = AF_INET;
    794 		else if (strcasecmp(arg, "inet6") == 0)
    795 			value = AF_INET6;
    796 		else if (strcasecmp(arg, "any") == 0)
    797 			value = AF_UNSPEC;
    798 		else
    799 			fatal("Unsupported AddressFamily \"%s\"", arg);
    800 		if (*activep && *intptr == -1)
    801 			*intptr = value;
    802 		break;
    803 
    804 	case oEnableSSHKeysign:
    805 		intptr = &options->enable_ssh_keysign;
    806 		goto parse_flag;
    807 
    808 	case oIdentitiesOnly:
    809 		intptr = &options->identities_only;
    810 		goto parse_flag;
    811 
    812 	case oServerAliveInterval:
    813 		intptr = &options->server_alive_interval;
    814 		goto parse_time;
    815 
    816 	case oServerAliveCountMax:
    817 		intptr = &options->server_alive_count_max;
    818 		goto parse_int;
    819 
    820 	case oSendEnv:
    821 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    822 			if (strchr(arg, '=') != NULL)
    823 				fatal("%s line %d: Invalid environment name.",
    824 				    filename, linenum);
    825 			if (!*activep)
    826 				continue;
    827 			if (options->num_send_env >= MAX_SEND_ENV)
    828 				fatal("%s line %d: too many send env.",
    829 				    filename, linenum);
    830 			options->send_env[options->num_send_env++] =
    831 			    xstrdup(arg);
    832 		}
    833 		break;
    834 
    835 	case oControlPath:
    836 		charptr = &options->control_path;
    837 		goto parse_string;
    838 
    839 	case oControlMaster:
    840 		intptr = &options->control_master;
    841 		arg = strdelim(&s);
    842 		if (!arg || *arg == '\0')
    843 			fatal("%.200s line %d: Missing ControlMaster argument.",
    844 			    filename, linenum);
    845 		value = 0;	/* To avoid compiler warning... */
    846 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
    847 			value = SSHCTL_MASTER_YES;
    848 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
    849 			value = SSHCTL_MASTER_NO;
    850 		else if (strcmp(arg, "auto") == 0)
    851 			value = SSHCTL_MASTER_AUTO;
    852 		else if (strcmp(arg, "ask") == 0)
    853 			value = SSHCTL_MASTER_ASK;
    854 		else if (strcmp(arg, "autoask") == 0)
    855 			value = SSHCTL_MASTER_AUTO_ASK;
    856 		else
    857 			fatal("%.200s line %d: Bad ControlMaster argument.",
    858 			    filename, linenum);
    859 		if (*activep && *intptr == -1)
    860 			*intptr = value;
    861 		break;
    862 
    863 	case oHashKnownHosts:
    864 		intptr = &options->hash_known_hosts;
    865 		goto parse_flag;
    866 
    867 	case oTunnel:
    868 		intptr = &options->tun_open;
    869 		arg = strdelim(&s);
    870 		if (!arg || *arg == '\0')
    871 			fatal("%s line %d: Missing yes/point-to-point/"
    872 			    "ethernet/no argument.", filename, linenum);
    873 		value = 0;	/* silence compiler */
    874 		if (strcasecmp(arg, "ethernet") == 0)
    875 			value = SSH_TUNMODE_ETHERNET;
    876 		else if (strcasecmp(arg, "point-to-point") == 0)
    877 			value = SSH_TUNMODE_POINTOPOINT;
    878 		else if (strcasecmp(arg, "yes") == 0)
    879 			value = SSH_TUNMODE_DEFAULT;
    880 		else if (strcasecmp(arg, "no") == 0)
    881 			value = SSH_TUNMODE_NO;
    882 		else
    883 			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
    884 			    "no argument: %s", filename, linenum, arg);
    885 		if (*activep)
    886 			*intptr = value;
    887 		break;
    888 
    889 	case oTunnelDevice:
    890 		arg = strdelim(&s);
    891 		if (!arg || *arg == '\0')
    892 			fatal("%.200s line %d: Missing argument.", filename, linenum);
    893 		value = a2tun(arg, &value2);
    894 		if (value == SSH_TUNID_ERR)
    895 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
    896 		if (*activep) {
    897 			options->tun_local = value;
    898 			options->tun_remote = value2;
    899 		}
    900 		break;
    901 
    902 	case oLocalCommand:
    903 		charptr = &options->local_command;
    904 		goto parse_command;
    905 
    906 	case oPermitLocalCommand:
    907 		intptr = &options->permit_local_command;
    908 		goto parse_flag;
    909 
    910 	case oVisualHostKey:
    911 		intptr = &options->visual_host_key;
    912 		goto parse_flag;
    913 
    914 	case oUseRoaming:
    915 		intptr = &options->use_roaming;
    916 		goto parse_flag;
    917 
    918 	case oDeprecated:
    919 		debug("%s line %d: Deprecated option \"%s\"",
    920 		    filename, linenum, keyword);
    921 		return 0;
    922 
    923 	case oUnsupported:
    924 		error("%s line %d: Unsupported option \"%s\"",
    925 		    filename, linenum, keyword);
    926 		return 0;
    927 
    928 	default:
    929 		fatal("process_config_line: Unimplemented opcode %d", opcode);
    930 	}
    931 
    932 	/* Check that there is no garbage at end of line. */
    933 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
    934 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
    935 		    filename, linenum, arg);
    936 	}
    937 	return 0;
    938 }
    939 
    940 
    941 /*
    942  * Reads the config file and modifies the options accordingly.  Options
    943  * should already be initialized before this call.  This never returns if
    944  * there is an error.  If the file does not exist, this returns 0.
    945  */
    946 
    947 int
    948 read_config_file(const char *filename, const char *host, Options *options,
    949     int checkperm)
    950 {
    951 	FILE *f;
    952 	char line[1024];
    953 	int active, linenum;
    954 	int bad_options = 0;
    955 
    956 	if ((f = fopen(filename, "r")) == NULL)
    957 		return 0;
    958 
    959 	if (checkperm) {
    960 		struct stat sb;
    961 
    962 		if (fstat(fileno(f), &sb) == -1)
    963 			fatal("fstat %s: %s", filename, strerror(errno));
    964 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
    965 		    (sb.st_mode & 022) != 0))
    966 			fatal("Bad owner or permissions on %s", filename);
    967 	}
    968 
    969 	debug("Reading configuration data %.200s", filename);
    970 
    971 	/*
    972 	 * Mark that we are now processing the options.  This flag is turned
    973 	 * on/off by Host specifications.
    974 	 */
    975 	active = 1;
    976 	linenum = 0;
    977 	while (fgets(line, sizeof(line), f)) {
    978 		/* Update line number counter. */
    979 		linenum++;
    980 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
    981 			bad_options++;
    982 	}
    983 	fclose(f);
    984 	if (bad_options > 0)
    985 		fatal("%s: terminating, %d bad configuration options",
    986 		    filename, bad_options);
    987 	return 1;
    988 }
    989 
    990 /*
    991  * Initializes options to special values that indicate that they have not yet
    992  * been set.  Read_config_file will only set options with this value. Options
    993  * are processed in the following order: command line, user config file,
    994  * system config file.  Last, fill_default_options is called.
    995  */
    996 
    997 void
    998 initialize_options(Options * options)
    999 {
   1000 	memset(options, 'X', sizeof(*options));
   1001 	options->forward_agent = -1;
   1002 	options->forward_x11 = -1;
   1003 	options->forward_x11_trusted = -1;
   1004 	options->exit_on_forward_failure = -1;
   1005 	options->xauth_location = NULL;
   1006 	options->gateway_ports = -1;
   1007 	options->use_privileged_port = -1;
   1008 	options->rsa_authentication = -1;
   1009 	options->pubkey_authentication = -1;
   1010 	options->challenge_response_authentication = -1;
   1011 	options->gss_authentication = -1;
   1012 	options->gss_deleg_creds = -1;
   1013 	options->password_authentication = -1;
   1014 	options->kbd_interactive_authentication = -1;
   1015 	options->kbd_interactive_devices = NULL;
   1016 	options->rhosts_rsa_authentication = -1;
   1017 	options->hostbased_authentication = -1;
   1018 	options->batch_mode = -1;
   1019 	options->check_host_ip = -1;
   1020 	options->strict_host_key_checking = -1;
   1021 	options->compression = -1;
   1022 	options->tcp_keep_alive = -1;
   1023 	options->compression_level = -1;
   1024 	options->port = -1;
   1025 	options->address_family = -1;
   1026 	options->connection_attempts = -1;
   1027 	options->connection_timeout = -1;
   1028 	options->number_of_password_prompts = -1;
   1029 	options->cipher = -1;
   1030 	options->ciphers = NULL;
   1031 	options->macs = NULL;
   1032 	options->hostkeyalgorithms = NULL;
   1033 	options->protocol = SSH_PROTO_UNKNOWN;
   1034 	options->num_identity_files = 0;
   1035 	options->hostname = NULL;
   1036 	options->host_key_alias = NULL;
   1037 	options->proxy_command = NULL;
   1038 	options->user = NULL;
   1039 	options->escape_char = -1;
   1040 	options->system_hostfile = NULL;
   1041 	options->user_hostfile = NULL;
   1042 	options->system_hostfile2 = NULL;
   1043 	options->user_hostfile2 = NULL;
   1044 	options->num_local_forwards = 0;
   1045 	options->num_remote_forwards = 0;
   1046 	options->clear_forwardings = -1;
   1047 	options->log_level = SYSLOG_LEVEL_NOT_SET;
   1048 	options->preferred_authentications = NULL;
   1049 	options->bind_address = NULL;
   1050 	options->smartcard_device = NULL;
   1051 	options->enable_ssh_keysign = - 1;
   1052 	options->no_host_authentication_for_localhost = - 1;
   1053 	options->identities_only = - 1;
   1054 	options->rekey_limit = - 1;
   1055 	options->verify_host_key_dns = -1;
   1056 	options->server_alive_interval = -1;
   1057 	options->server_alive_count_max = -1;
   1058 	options->num_send_env = 0;
   1059 	options->control_path = NULL;
   1060 	options->control_master = -1;
   1061 	options->hash_known_hosts = -1;
   1062 	options->tun_open = -1;
   1063 	options->tun_local = -1;
   1064 	options->tun_remote = -1;
   1065 	options->local_command = NULL;
   1066 	options->permit_local_command = -1;
   1067 	options->use_roaming = -1;
   1068 	options->visual_host_key = -1;
   1069 	options->zero_knowledge_password_authentication = -1;
   1070 }
   1071 
   1072 /*
   1073  * Called after processing other sources of option data, this fills those
   1074  * options for which no value has been specified with their default values.
   1075  */
   1076 
   1077 void
   1078 fill_default_options(Options * options)
   1079 {
   1080 	int len;
   1081 
   1082 	if (options->forward_agent == -1)
   1083 		options->forward_agent = 0;
   1084 	if (options->forward_x11 == -1)
   1085 		options->forward_x11 = 0;
   1086 	if (options->forward_x11_trusted == -1)
   1087 		options->forward_x11_trusted = 0;
   1088 	if (options->exit_on_forward_failure == -1)
   1089 		options->exit_on_forward_failure = 0;
   1090 	if (options->xauth_location == NULL)
   1091 		options->xauth_location = _PATH_XAUTH;
   1092 	if (options->gateway_ports == -1)
   1093 		options->gateway_ports = 0;
   1094 	if (options->use_privileged_port == -1)
   1095 		options->use_privileged_port = 0;
   1096 	if (options->rsa_authentication == -1)
   1097 		options->rsa_authentication = 1;
   1098 	if (options->pubkey_authentication == -1)
   1099 		options->pubkey_authentication = 1;
   1100 	if (options->challenge_response_authentication == -1)
   1101 		options->challenge_response_authentication = 1;
   1102 	if (options->gss_authentication == -1)
   1103 		options->gss_authentication = 0;
   1104 	if (options->gss_deleg_creds == -1)
   1105 		options->gss_deleg_creds = 0;
   1106 	if (options->password_authentication == -1)
   1107 		options->password_authentication = 1;
   1108 	if (options->kbd_interactive_authentication == -1)
   1109 		options->kbd_interactive_authentication = 1;
   1110 	if (options->rhosts_rsa_authentication == -1)
   1111 		options->rhosts_rsa_authentication = 0;
   1112 	if (options->hostbased_authentication == -1)
   1113 		options->hostbased_authentication = 0;
   1114 	if (options->batch_mode == -1)
   1115 		options->batch_mode = 0;
   1116 	if (options->check_host_ip == -1)
   1117 		options->check_host_ip = 1;
   1118 	if (options->strict_host_key_checking == -1)
   1119 		options->strict_host_key_checking = 2;	/* 2 is default */
   1120 	if (options->compression == -1)
   1121 		options->compression = 0;
   1122 	if (options->tcp_keep_alive == -1)
   1123 		options->tcp_keep_alive = 1;
   1124 	if (options->compression_level == -1)
   1125 		options->compression_level = 6;
   1126 	if (options->port == -1)
   1127 		options->port = 0;	/* Filled in ssh_connect. */
   1128 	if (options->address_family == -1)
   1129 		options->address_family = AF_UNSPEC;
   1130 	if (options->connection_attempts == -1)
   1131 		options->connection_attempts = 1;
   1132 	if (options->number_of_password_prompts == -1)
   1133 		options->number_of_password_prompts = 3;
   1134 	/* Selected in ssh_login(). */
   1135 	if (options->cipher == -1)
   1136 		options->cipher = SSH_CIPHER_NOT_SET;
   1137 	/* options->ciphers, default set in myproposals.h */
   1138 	/* options->macs, default set in myproposals.h */
   1139 	/* options->hostkeyalgorithms, default set in myproposals.h */
   1140 	if (options->protocol == SSH_PROTO_UNKNOWN)
   1141 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
   1142 	if (options->num_identity_files == 0) {
   1143 		if (options->protocol & SSH_PROTO_1) {
   1144 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
   1145 			options->identity_files[options->num_identity_files] =
   1146 			    xmalloc(len);
   1147 			snprintf(options->identity_files[options->num_identity_files++],
   1148 			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
   1149 		}
   1150 		if (options->protocol & SSH_PROTO_2) {
   1151 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
   1152 			options->identity_files[options->num_identity_files] =
   1153 			    xmalloc(len);
   1154 			snprintf(options->identity_files[options->num_identity_files++],
   1155 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
   1156 
   1157 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
   1158 			options->identity_files[options->num_identity_files] =
   1159 			    xmalloc(len);
   1160 			snprintf(options->identity_files[options->num_identity_files++],
   1161 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
   1162 		}
   1163 	}
   1164 	if (options->escape_char == -1)
   1165 		options->escape_char = '~';
   1166 	if (options->system_hostfile == NULL)
   1167 		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
   1168 	if (options->user_hostfile == NULL)
   1169 		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
   1170 	if (options->system_hostfile2 == NULL)
   1171 		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
   1172 	if (options->user_hostfile2 == NULL)
   1173 		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
   1174 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
   1175 		options->log_level = SYSLOG_LEVEL_INFO;
   1176 	if (options->clear_forwardings == 1)
   1177 		clear_forwardings(options);
   1178 	if (options->no_host_authentication_for_localhost == - 1)
   1179 		options->no_host_authentication_for_localhost = 0;
   1180 	if (options->identities_only == -1)
   1181 		options->identities_only = 0;
   1182 	if (options->enable_ssh_keysign == -1)
   1183 		options->enable_ssh_keysign = 0;
   1184 	if (options->rekey_limit == -1)
   1185 		options->rekey_limit = 0;
   1186 	if (options->verify_host_key_dns == -1)
   1187 		options->verify_host_key_dns = 0;
   1188 	if (options->server_alive_interval == -1)
   1189 		options->server_alive_interval = 0;
   1190 	if (options->server_alive_count_max == -1)
   1191 		options->server_alive_count_max = 3;
   1192 	if (options->control_master == -1)
   1193 		options->control_master = 0;
   1194 	if (options->hash_known_hosts == -1)
   1195 		options->hash_known_hosts = 0;
   1196 	if (options->tun_open == -1)
   1197 		options->tun_open = SSH_TUNMODE_NO;
   1198 	if (options->tun_local == -1)
   1199 		options->tun_local = SSH_TUNID_ANY;
   1200 	if (options->tun_remote == -1)
   1201 		options->tun_remote = SSH_TUNID_ANY;
   1202 	if (options->permit_local_command == -1)
   1203 		options->permit_local_command = 0;
   1204 	if (options->use_roaming == -1)
   1205 		options->use_roaming = 1;
   1206 	if (options->visual_host_key == -1)
   1207 		options->visual_host_key = 0;
   1208 	if (options->zero_knowledge_password_authentication == -1)
   1209 		options->zero_knowledge_password_authentication = 0;
   1210 	/* options->local_command should not be set by default */
   1211 	/* options->proxy_command should not be set by default */
   1212 	/* options->user will be set in the main program if appropriate */
   1213 	/* options->hostname will be set in the main program if appropriate */
   1214 	/* options->host_key_alias should not be set by default */
   1215 	/* options->preferred_authentications will be set in ssh */
   1216 }
   1217 
   1218 /*
   1219  * parse_forward
   1220  * parses a string containing a port forwarding specification of the form:
   1221  *   dynamicfwd == 0
   1222  *	[listenhost:]listenport:connecthost:connectport
   1223  *   dynamicfwd == 1
   1224  *	[listenhost:]listenport
   1225  * returns number of arguments parsed or zero on error
   1226  */
   1227 int
   1228 parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
   1229 {
   1230 	int i;
   1231 	char *p, *cp, *fwdarg[4];
   1232 
   1233 	memset(fwd, '\0', sizeof(*fwd));
   1234 
   1235 	cp = p = xstrdup(fwdspec);
   1236 
   1237 	/* skip leading spaces */
   1238 	while (isspace(*cp))
   1239 		cp++;
   1240 
   1241 	for (i = 0; i < 4; ++i)
   1242 		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
   1243 			break;
   1244 
   1245 	/* Check for trailing garbage */
   1246 	if (cp != NULL)
   1247 		i = 0;	/* failure */
   1248 
   1249 	switch (i) {
   1250 	case 1:
   1251 		fwd->listen_host = NULL;
   1252 		fwd->listen_port = a2port(fwdarg[0]);
   1253 		fwd->connect_host = xstrdup("socks");
   1254 		break;
   1255 
   1256 	case 2:
   1257 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
   1258 		fwd->listen_port = a2port(fwdarg[1]);
   1259 		fwd->connect_host = xstrdup("socks");
   1260 		break;
   1261 
   1262 	case 3:
   1263 		fwd->listen_host = NULL;
   1264 		fwd->listen_port = a2port(fwdarg[0]);
   1265 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
   1266 		fwd->connect_port = a2port(fwdarg[2]);
   1267 		break;
   1268 
   1269 	case 4:
   1270 		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
   1271 		fwd->listen_port = a2port(fwdarg[1]);
   1272 		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
   1273 		fwd->connect_port = a2port(fwdarg[3]);
   1274 		break;
   1275 	default:
   1276 		i = 0; /* failure */
   1277 	}
   1278 
   1279 	xfree(p);
   1280 
   1281 	if (dynamicfwd) {
   1282 		if (!(i == 1 || i == 2))
   1283 			goto fail_free;
   1284 	} else {
   1285 		if (!(i == 3 || i == 4))
   1286 			goto fail_free;
   1287 		if (fwd->connect_port <= 0)
   1288 			goto fail_free;
   1289 	}
   1290 
   1291 	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
   1292 		goto fail_free;
   1293 
   1294 	if (fwd->connect_host != NULL &&
   1295 	    strlen(fwd->connect_host) >= NI_MAXHOST)
   1296 		goto fail_free;
   1297 	if (fwd->listen_host != NULL &&
   1298 	    strlen(fwd->listen_host) >= NI_MAXHOST)
   1299 		goto fail_free;
   1300 
   1301 
   1302 	return (i);
   1303 
   1304  fail_free:
   1305 	if (fwd->connect_host != NULL) {
   1306 		xfree(fwd->connect_host);
   1307 		fwd->connect_host = NULL;
   1308 	}
   1309 	if (fwd->listen_host != NULL) {
   1310 		xfree(fwd->listen_host);
   1311 		fwd->listen_host = NULL;
   1312 	}
   1313 	return (0);
   1314 }
   1315