Home | History | Annotate | Line # | Download | only in dist
readconf.c revision 1.12
      1 /*	$NetBSD: readconf.c,v 1.12 2014/10/19 16:30:58 christos Exp $	*/
      2 /* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert 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 "includes.h"
     17 __RCSID("$NetBSD: readconf.c,v 1.12 2014/10/19 16:30:58 christos Exp $");
     18 #include <sys/types.h>
     19 #include <sys/stat.h>
     20 #include <sys/socket.h>
     21 #include <sys/wait.h>
     22 #include <sys/un.h>
     23 
     24 #include <netinet/in.h>
     25 #include <netinet/in_systm.h>
     26 #include <netinet/ip.h>
     27 
     28 #include <ctype.h>
     29 #include <errno.h>
     30 #include <fcntl.h>
     31 #include <netdb.h>
     32 #include <paths.h>
     33 #include <pwd.h>
     34 #include <signal.h>
     35 #include <stdio.h>
     36 #include <string.h>
     37 #include <unistd.h>
     38 #include <limits.h>
     39 #include <util.h>
     40 
     41 #include "xmalloc.h"
     42 #include "ssh.h"
     43 #include "compat.h"
     44 #include "cipher.h"
     45 #include "pathnames.h"
     46 #include "log.h"
     47 #include "key.h"
     48 #include "misc.h"
     49 #include "readconf.h"
     50 #include "match.h"
     51 #include "buffer.h"
     52 #include "kex.h"
     53 #include "mac.h"
     54 #include "fmt_scaled.h"
     55 #include "uidswap.h"
     56 
     57 /* Format of the configuration file:
     58 
     59    # Configuration data is parsed as follows:
     60    #  1. command line options
     61    #  2. user-specific file
     62    #  3. system-wide file
     63    # Any configuration value is only changed the first time it is set.
     64    # Thus, host-specific definitions should be at the beginning of the
     65    # configuration file, and defaults at the end.
     66 
     67    # Host-specific declarations.  These may override anything above.  A single
     68    # host may match multiple declarations; these are processed in the order
     69    # that they are given in.
     70 
     71    Host *.ngs.fi ngs.fi
     72      User foo
     73 
     74    Host fake.com
     75      HostName another.host.name.real.org
     76      User blaah
     77      Port 34289
     78      ForwardX11 no
     79      ForwardAgent no
     80 
     81    Host books.com
     82      RemoteForward 9999 shadows.cs.hut.fi:9999
     83      Cipher 3des
     84 
     85    Host fascist.blob.com
     86      Port 23123
     87      User tylonen
     88      PasswordAuthentication no
     89 
     90    Host puukko.hut.fi
     91      User t35124p
     92      ProxyCommand ssh-proxy %h %p
     93 
     94    Host *.fr
     95      PublicKeyAuthentication no
     96 
     97    Host *.su
     98      Cipher none
     99      PasswordAuthentication no
    100 
    101    Host vpn.fake.com
    102      Tunnel yes
    103      TunnelDevice 3
    104 
    105    # Defaults for various options
    106    Host *
    107      ForwardAgent no
    108      ForwardX11 no
    109      PasswordAuthentication yes
    110      RSAAuthentication yes
    111      RhostsRSAAuthentication yes
    112      StrictHostKeyChecking yes
    113      TcpKeepAlive no
    114      IdentityFile ~/.ssh/identity
    115      Port 22
    116      EscapeChar ~
    117 
    118 */
    119 
    120 /* Keyword tokens. */
    121 
    122 typedef enum {
    123 	oBadOption,
    124 	oHost, oMatch,
    125 	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
    126 	oGatewayPorts, oExitOnForwardFailure,
    127 	oPasswordAuthentication, oRSAAuthentication,
    128 	oChallengeResponseAuthentication, oXAuthLocation,
    129 #if defined(KRB4) || defined(KRB5)
    130 	oKerberosAuthentication,
    131 #endif
    132 #if defined(AFS) || defined(KRB5)
    133 	oKerberosTgtPassing,
    134 #endif
    135 #ifdef AFS
    136 	oAFSTokenPassing,
    137 #endif
    138 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
    139 	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
    140 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
    141 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
    142 	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
    143 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
    144 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
    145 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
    146 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
    147 	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
    148 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
    149 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
    150 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
    151 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
    152 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
    153 	oHashKnownHosts,
    154 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
    155 	oVisualHostKey, oUseRoaming,
    156 	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
    157 	oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
    158 	oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
    159 	oStreamLocalBindMask, oStreamLocalBindUnlink,
    160 	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
    161 	oHPNBufferSize,
    162 	oSendVersionFirst,
    163 	oIgnoredUnknownOption, oDeprecated, oUnsupported
    164 } OpCodes;
    165 
    166 /* Textual representations of the tokens. */
    167 
    168 static struct {
    169 	const char *name;
    170 	OpCodes opcode;
    171 } keywords[] = {
    172 	{ "forwardagent", oForwardAgent },
    173 	{ "forwardx11", oForwardX11 },
    174 	{ "forwardx11trusted", oForwardX11Trusted },
    175 	{ "forwardx11timeout", oForwardX11Timeout },
    176 	{ "exitonforwardfailure", oExitOnForwardFailure },
    177 	{ "xauthlocation", oXAuthLocation },
    178 	{ "gatewayports", oGatewayPorts },
    179 	{ "useprivilegedport", oUsePrivilegedPort },
    180 	{ "rhostsauthentication", oDeprecated },
    181 	{ "passwordauthentication", oPasswordAuthentication },
    182 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
    183 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
    184 	{ "rsaauthentication", oRSAAuthentication },
    185 	{ "pubkeyauthentication", oPubkeyAuthentication },
    186 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
    187 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
    188 	{ "hostbasedauthentication", oHostbasedAuthentication },
    189 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
    190 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
    191 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
    192 #if defined(KRB4) || defined(KRB5)
    193 	{ "kerberosauthentication", oKerberosAuthentication },
    194 #endif
    195 #if defined(AFS) || defined(KRB5)
    196 	{ "kerberostgtpassing", oKerberosTgtPassing },
    197 	{ "kerberos5tgtpassing", oKerberosTgtPassing },		/* alias */
    198 	{ "kerberos4tgtpassing", oKerberosTgtPassing },		/* alias */
    199 #endif
    200 #ifdef AFS
    201 	{ "afstokenpassing", oAFSTokenPassing },
    202 #endif
    203 #if defined(GSSAPI)
    204 	{ "gssapiauthentication", oGssAuthentication },
    205 	{ "gssapidelegatecredentials", oGssDelegateCreds },
    206 #else
    207 	{ "gssapiauthentication", oUnsupported },
    208 	{ "gssapidelegatecredentials", oUnsupported },
    209 #endif
    210 	{ "fallbacktorsh", oDeprecated },
    211 	{ "usersh", oDeprecated },
    212 	{ "identityfile", oIdentityFile },
    213 	{ "identityfile2", oIdentityFile },			/* obsolete */
    214 	{ "identitiesonly", oIdentitiesOnly },
    215 	{ "hostname", oHostName },
    216 	{ "hostkeyalias", oHostKeyAlias },
    217 	{ "proxycommand", oProxyCommand },
    218 	{ "port", oPort },
    219 	{ "cipher", oCipher },
    220 	{ "ciphers", oCiphers },
    221 	{ "macs", oMacs },
    222 	{ "protocol", oProtocol },
    223 	{ "remoteforward", oRemoteForward },
    224 	{ "localforward", oLocalForward },
    225 	{ "user", oUser },
    226 	{ "host", oHost },
    227 	{ "match", oMatch },
    228 	{ "escapechar", oEscapeChar },
    229 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
    230 	{ "globalknownhostsfile2", oDeprecated },
    231 	{ "userknownhostsfile", oUserKnownHostsFile },
    232 	{ "userknownhostsfile2", oDeprecated },
    233 	{ "connectionattempts", oConnectionAttempts },
    234 	{ "batchmode", oBatchMode },
    235 	{ "checkhostip", oCheckHostIP },
    236 	{ "stricthostkeychecking", oStrictHostKeyChecking },
    237 	{ "compression", oCompression },
    238 	{ "compressionlevel", oCompressionLevel },
    239 	{ "tcpkeepalive", oTCPKeepAlive },
    240 	{ "keepalive", oTCPKeepAlive },				/* obsolete */
    241 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
    242 	{ "loglevel", oLogLevel },
    243 	{ "dynamicforward", oDynamicForward },
    244 	{ "preferredauthentications", oPreferredAuthentications },
    245 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
    246 	{ "bindaddress", oBindAddress },
    247 #ifdef ENABLE_PKCS11
    248 	{ "smartcarddevice", oPKCS11Provider },
    249 	{ "pkcs11provider", oPKCS11Provider },
    250 #else
    251 	{ "smartcarddevice", oUnsupported },
    252 	{ "pkcs11provider", oUnsupported },
    253 #endif
    254 	{ "clearallforwardings", oClearAllForwardings },
    255 	{ "enablesshkeysign", oEnableSSHKeysign },
    256 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
    257 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
    258 	{ "rekeylimit", oRekeyLimit },
    259 	{ "connecttimeout", oConnectTimeout },
    260 	{ "addressfamily", oAddressFamily },
    261 	{ "serveraliveinterval", oServerAliveInterval },
    262 	{ "serveralivecountmax", oServerAliveCountMax },
    263 	{ "sendenv", oSendEnv },
    264 	{ "controlpath", oControlPath },
    265 	{ "controlmaster", oControlMaster },
    266 	{ "controlpersist", oControlPersist },
    267 	{ "hashknownhosts", oHashKnownHosts },
    268 	{ "tunnel", oTunnel },
    269 	{ "tunneldevice", oTunnelDevice },
    270 	{ "localcommand", oLocalCommand },
    271 	{ "permitlocalcommand", oPermitLocalCommand },
    272 	{ "visualhostkey", oVisualHostKey },
    273 	{ "useroaming", oUseRoaming },
    274 	{ "kexalgorithms", oKexAlgorithms },
    275 	{ "ipqos", oIPQoS },
    276 	{ "requesttty", oRequestTTY },
    277 	{ "proxyusefdpass", oProxyUseFdpass },
    278 	{ "canonicaldomains", oCanonicalDomains },
    279 	{ "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
    280 	{ "canonicalizehostname", oCanonicalizeHostname },
    281 	{ "canonicalizemaxdots", oCanonicalizeMaxDots },
    282 	{ "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
    283 	{ "streamlocalbindmask", oStreamLocalBindMask },
    284 	{ "streamlocalbindunlink", oStreamLocalBindUnlink },
    285 	{ "noneenabled", oNoneEnabled },
    286 	{ "tcprcvbufpoll", oTcpRcvBufPoll },
    287 	{ "tcprcvbuf", oTcpRcvBuf },
    288 	{ "noneswitch", oNoneSwitch },
    289 	{ "hpndisabled", oHPNDisabled },
    290 	{ "hpnbuffersize", oHPNBufferSize },
    291 	{ "sendversionfirst", oSendVersionFirst },
    292 	{ "ignoreunknown", oIgnoreUnknown },
    293 	{ NULL, oBadOption }
    294 };
    295 
    296 /*
    297  * Adds a local TCP/IP port forward to options.  Never returns if there is an
    298  * error.
    299  */
    300 
    301 void
    302 add_local_forward(Options *options, const struct Forward *newfwd)
    303 {
    304 	struct Forward *fwd;
    305 	extern uid_t original_real_uid;
    306 
    307 	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
    308 	    newfwd->listen_path == NULL)
    309 		fatal("Privileged ports can only be forwarded by root.");
    310 	options->local_forwards = xrealloc(options->local_forwards,
    311 	    options->num_local_forwards + 1,
    312 	    sizeof(*options->local_forwards));
    313 	fwd = &options->local_forwards[options->num_local_forwards++];
    314 
    315 	fwd->listen_host = newfwd->listen_host;
    316 	fwd->listen_port = newfwd->listen_port;
    317 	fwd->listen_path = newfwd->listen_path;
    318 	fwd->connect_host = newfwd->connect_host;
    319 	fwd->connect_port = newfwd->connect_port;
    320 	fwd->connect_path = newfwd->connect_path;
    321 }
    322 
    323 /*
    324  * Adds a remote TCP/IP port forward to options.  Never returns if there is
    325  * an error.
    326  */
    327 
    328 void
    329 add_remote_forward(Options *options, const struct Forward *newfwd)
    330 {
    331 	struct Forward *fwd;
    332 
    333 	options->remote_forwards = xrealloc(options->remote_forwards,
    334 	    options->num_remote_forwards + 1,
    335 	    sizeof(*options->remote_forwards));
    336 	fwd = &options->remote_forwards[options->num_remote_forwards++];
    337 
    338 	fwd->listen_host = newfwd->listen_host;
    339 	fwd->listen_port = newfwd->listen_port;
    340 	fwd->listen_path = newfwd->listen_path;
    341 	fwd->connect_host = newfwd->connect_host;
    342 	fwd->connect_port = newfwd->connect_port;
    343 	fwd->connect_path = newfwd->connect_path;
    344 	fwd->handle = newfwd->handle;
    345 	fwd->allocated_port = 0;
    346 }
    347 
    348 static void
    349 clear_forwardings(Options *options)
    350 {
    351 	int i;
    352 
    353 	for (i = 0; i < options->num_local_forwards; i++) {
    354 		free(options->local_forwards[i].listen_host);
    355 		free(options->local_forwards[i].listen_path);
    356 		free(options->local_forwards[i].connect_host);
    357 		free(options->local_forwards[i].connect_path);
    358 	}
    359 	if (options->num_local_forwards > 0) {
    360 		free(options->local_forwards);
    361 		options->local_forwards = NULL;
    362 	}
    363 	options->num_local_forwards = 0;
    364 	for (i = 0; i < options->num_remote_forwards; i++) {
    365 		free(options->remote_forwards[i].listen_host);
    366 		free(options->remote_forwards[i].listen_path);
    367 		free(options->remote_forwards[i].connect_host);
    368 		free(options->remote_forwards[i].connect_path);
    369 	}
    370 	if (options->num_remote_forwards > 0) {
    371 		free(options->remote_forwards);
    372 		options->remote_forwards = NULL;
    373 	}
    374 	options->num_remote_forwards = 0;
    375 	options->tun_open = SSH_TUNMODE_NO;
    376 }
    377 
    378 void
    379 add_identity_file(Options *options, const char *dir, const char *filename,
    380     int userprovided)
    381 {
    382 	char *path;
    383 	int i;
    384 
    385 	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
    386 		fatal("Too many identity files specified (max %d)",
    387 		    SSH_MAX_IDENTITY_FILES);
    388 
    389 	if (dir == NULL) /* no dir, filename is absolute */
    390 		path = xstrdup(filename);
    391 	else
    392 		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
    393 
    394 	/* Avoid registering duplicates */
    395 	for (i = 0; i < options->num_identity_files; i++) {
    396 		if (options->identity_file_userprovided[i] == userprovided &&
    397 		    strcmp(options->identity_files[i], path) == 0) {
    398 			debug2("%s: ignoring duplicate key %s", __func__, path);
    399 			free(path);
    400 			return;
    401 		}
    402 	}
    403 
    404 	options->identity_file_userprovided[options->num_identity_files] =
    405 	    userprovided;
    406 	options->identity_files[options->num_identity_files++] = path;
    407 }
    408 
    409 int
    410 default_ssh_port(void)
    411 {
    412 	static int port;
    413 	struct servent *sp;
    414 
    415 	if (port == 0) {
    416 		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
    417 		port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
    418 	}
    419 	return port;
    420 }
    421 
    422 /*
    423  * Execute a command in a shell.
    424  * Return its exit status or -1 on abnormal exit.
    425  */
    426 static int
    427 execute_in_shell(const char *cmd)
    428 {
    429 	const char *shell;
    430 	char *command_string;
    431 	pid_t pid;
    432 	int devnull, status;
    433 	extern uid_t original_real_uid;
    434 
    435 	if ((shell = getenv("SHELL")) == NULL)
    436 		shell = _PATH_BSHELL;
    437 
    438 	/*
    439 	 * Use "exec" to avoid "sh -c" processes on some platforms
    440 	 * (e.g. Solaris)
    441 	 */
    442 	xasprintf(&command_string, "exec %s", cmd);
    443 
    444 	/* Need this to redirect subprocess stdin/out */
    445 	if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
    446 		fatal("open(/dev/null): %s", strerror(errno));
    447 
    448 	debug("Executing command: '%.500s'", cmd);
    449 
    450 	/* Fork and execute the command. */
    451 	if ((pid = fork()) == 0) {
    452 		char *argv[4];
    453 
    454 		/* Child.  Permanently give up superuser privileges. */
    455 		permanently_drop_suid(original_real_uid);
    456 
    457 		/* Redirect child stdin and stdout. Leave stderr */
    458 		if (dup2(devnull, STDIN_FILENO) == -1)
    459 			fatal("dup2: %s", strerror(errno));
    460 		if (dup2(devnull, STDOUT_FILENO) == -1)
    461 			fatal("dup2: %s", strerror(errno));
    462 		if (devnull > STDERR_FILENO)
    463 			close(devnull);
    464 		closefrom(STDERR_FILENO + 1);
    465 
    466 		argv[0] = __UNCONST(shell);
    467 		argv[1] = __UNCONST("-c");
    468 		argv[2] = command_string;
    469 		argv[3] = NULL;
    470 
    471 		execv(argv[0], argv);
    472 		error("Unable to execute '%.100s': %s", cmd, strerror(errno));
    473 		/* Die with signal to make this error apparent to parent. */
    474 		signal(SIGTERM, SIG_DFL);
    475 		kill(getpid(), SIGTERM);
    476 		_exit(1);
    477 	}
    478 	/* Parent. */
    479 	if (pid < 0)
    480 		fatal("%s: fork: %.100s", __func__, strerror(errno));
    481 
    482 	close(devnull);
    483 	free(command_string);
    484 
    485 	while (waitpid(pid, &status, 0) == -1) {
    486 		if (errno != EINTR && errno != EAGAIN)
    487 			fatal("%s: waitpid: %s", __func__, strerror(errno));
    488 	}
    489 	if (!WIFEXITED(status)) {
    490 		error("command '%.100s' exited abnormally", cmd);
    491 		return -1;
    492 	}
    493 	debug3("command returned status %d", WEXITSTATUS(status));
    494 	return WEXITSTATUS(status);
    495 }
    496 
    497 /*
    498  * Parse and execute a Match directive.
    499  */
    500 static int
    501 match_cfg_line(Options *options, char **condition, struct passwd *pw,
    502     const char *host_arg, const char *filename, int linenum)
    503 {
    504 	char *arg, *attrib, *cmd, *cp = *condition, *host;
    505 	const char *ruser;
    506 	int r, port, result = 1, attributes = 0;
    507 	size_t len;
    508 	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
    509 
    510 	/*
    511 	 * Configuration is likely to be incomplete at this point so we
    512 	 * must be prepared to use default values.
    513 	 */
    514 	port = options->port <= 0 ? default_ssh_port() : options->port;
    515 	ruser = options->user == NULL ? pw->pw_name : options->user;
    516 	if (options->hostname != NULL) {
    517 		/* NB. Please keep in sync with ssh.c:main() */
    518 		host = percent_expand(options->hostname,
    519 		    "h", host_arg, (char *)NULL);
    520 	} else
    521 		host = xstrdup(host_arg);
    522 
    523 	debug3("checking match for '%s' host %s", cp, host);
    524 	while ((attrib = strdelim(&cp)) && *attrib != '\0') {
    525 		attributes++;
    526 		if (strcasecmp(attrib, "all") == 0) {
    527 			if (attributes != 1 ||
    528 			    ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
    529 				error("'all' cannot be combined with other "
    530 				    "Match attributes");
    531 				result = -1;
    532 				goto out;
    533 			}
    534 			*condition = cp;
    535 			result = 1;
    536 			goto out;
    537 		}
    538 		if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
    539 			error("Missing Match criteria for %s", attrib);
    540 			result = -1;
    541 			goto out;
    542 		}
    543 		len = strlen(arg);
    544 		if (strcasecmp(attrib, "host") == 0) {
    545 			if (match_hostname(host, arg, len) != 1)
    546 				result = 0;
    547 			else
    548 				debug("%.200s line %d: matched 'Host %.100s' ",
    549 				    filename, linenum, host);
    550 		} else if (strcasecmp(attrib, "originalhost") == 0) {
    551 			if (match_hostname(host_arg, arg, len) != 1)
    552 				result = 0;
    553 			else
    554 				debug("%.200s line %d: matched "
    555 				    "'OriginalHost %.100s' ",
    556 				    filename, linenum, host_arg);
    557 		} else if (strcasecmp(attrib, "user") == 0) {
    558 			if (match_pattern_list(ruser, arg, len, 0) != 1)
    559 				result = 0;
    560 			else
    561 				debug("%.200s line %d: matched 'User %.100s' ",
    562 				    filename, linenum, ruser);
    563 		} else if (strcasecmp(attrib, "localuser") == 0) {
    564 			if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
    565 				result = 0;
    566 			else
    567 				debug("%.200s line %d: matched "
    568 				    "'LocalUser %.100s' ",
    569 				    filename, linenum, pw->pw_name);
    570 		} else if (strcasecmp(attrib, "exec") == 0) {
    571 			if (gethostname(thishost, sizeof(thishost)) == -1)
    572 				fatal("gethostname: %s", strerror(errno));
    573 			strlcpy(shorthost, thishost, sizeof(shorthost));
    574 			shorthost[strcspn(thishost, ".")] = '\0';
    575 			snprintf(portstr, sizeof(portstr), "%d", port);
    576 
    577 			cmd = percent_expand(arg,
    578 			    "L", shorthost,
    579 			    "d", pw->pw_dir,
    580 			    "h", host,
    581 			    "l", thishost,
    582 			    "n", host_arg,
    583 			    "p", portstr,
    584 			    "r", ruser,
    585 			    "u", pw->pw_name,
    586 			    (char *)NULL);
    587 			if (result != 1) {
    588 				/* skip execution if prior predicate failed */
    589 				debug("%.200s line %d: skipped exec \"%.100s\"",
    590 				    filename, linenum, cmd);
    591 			} else {
    592 				r = execute_in_shell(cmd);
    593 				if (r == -1) {
    594 					fatal("%.200s line %d: match exec "
    595 					    "'%.100s' error", filename,
    596 					    linenum, cmd);
    597 				} else if (r == 0) {
    598 					debug("%.200s line %d: matched "
    599 					    "'exec \"%.100s\"'", filename,
    600 					    linenum, cmd);
    601 				} else {
    602 					debug("%.200s line %d: no match "
    603 					    "'exec \"%.100s\"'", filename,
    604 					    linenum, cmd);
    605 					result = 0;
    606 				}
    607 			}
    608 			free(cmd);
    609 		} else {
    610 			error("Unsupported Match attribute %s", attrib);
    611 			result = -1;
    612 			goto out;
    613 		}
    614 	}
    615 	if (attributes == 0) {
    616 		error("One or more attributes required for Match");
    617 		result = -1;
    618 		goto out;
    619 	}
    620 	debug3("match %sfound", result ? "" : "not ");
    621 	*condition = cp;
    622  out:
    623 	free(host);
    624 	return result;
    625 }
    626 
    627 /* Check and prepare a domain name: removes trailing '.' and lowercases */
    628 static void
    629 valid_domain(char *name, const char *filename, int linenum)
    630 {
    631 	size_t i, l = strlen(name);
    632 	u_char c, last = '\0';
    633 
    634 	if (l == 0)
    635 		fatal("%s line %d: empty hostname suffix", filename, linenum);
    636 	if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
    637 		fatal("%s line %d: hostname suffix \"%.100s\" "
    638 		    "starts with invalid character", filename, linenum, name);
    639 	for (i = 0; i < l; i++) {
    640 		c = tolower((u_char)name[i]);
    641 		name[i] = (char)c;
    642 		if (last == '.' && c == '.')
    643 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
    644 			    "consecutive separators", filename, linenum, name);
    645 		if (c != '.' && c != '-' && !isalnum(c) &&
    646 		    c != '_') /* technically invalid, but common */
    647 			fatal("%s line %d: hostname suffix \"%.100s\" contains "
    648 			    "invalid characters", filename, linenum, name);
    649 		last = c;
    650 	}
    651 	if (name[l - 1] == '.')
    652 		name[l - 1] = '\0';
    653 }
    654 
    655 /*
    656  * Returns the number of the token pointed to by cp or oBadOption.
    657  */
    658 static OpCodes
    659 parse_token(const char *cp, const char *filename, int linenum,
    660     const char *ignored_unknown)
    661 {
    662 	int i;
    663 
    664 	for (i = 0; keywords[i].name; i++)
    665 		if (strcmp(cp, keywords[i].name) == 0)
    666 			return keywords[i].opcode;
    667 	if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
    668 	    strlen(ignored_unknown), 1) == 1)
    669 		return oIgnoredUnknownOption;
    670 	error("%s: line %d: Bad configuration option: %s",
    671 	    filename, linenum, cp);
    672 	return oBadOption;
    673 }
    674 
    675 /* Multistate option parsing */
    676 struct multistate {
    677 	const char *key;
    678 	int value;
    679 };
    680 static const struct multistate multistate_flag[] = {
    681 	{ "true",			1 },
    682 	{ "false",			0 },
    683 	{ "yes",			1 },
    684 	{ "no",				0 },
    685 	{ NULL, -1 }
    686 };
    687 static const struct multistate multistate_yesnoask[] = {
    688 	{ "true",			1 },
    689 	{ "false",			0 },
    690 	{ "yes",			1 },
    691 	{ "no",				0 },
    692 	{ "ask",			2 },
    693 	{ NULL, -1 }
    694 };
    695 static const struct multistate multistate_addressfamily[] = {
    696 	{ "inet",			AF_INET },
    697 	{ "inet6",			AF_INET6 },
    698 	{ "any",			AF_UNSPEC },
    699 	{ NULL, -1 }
    700 };
    701 static const struct multistate multistate_controlmaster[] = {
    702 	{ "true",			SSHCTL_MASTER_YES },
    703 	{ "yes",			SSHCTL_MASTER_YES },
    704 	{ "false",			SSHCTL_MASTER_NO },
    705 	{ "no",				SSHCTL_MASTER_NO },
    706 	{ "auto",			SSHCTL_MASTER_AUTO },
    707 	{ "ask",			SSHCTL_MASTER_ASK },
    708 	{ "autoask",			SSHCTL_MASTER_AUTO_ASK },
    709 	{ NULL, -1 }
    710 };
    711 static const struct multistate multistate_tunnel[] = {
    712 	{ "ethernet",			SSH_TUNMODE_ETHERNET },
    713 	{ "point-to-point",		SSH_TUNMODE_POINTOPOINT },
    714 	{ "true",			SSH_TUNMODE_DEFAULT },
    715 	{ "yes",			SSH_TUNMODE_DEFAULT },
    716 	{ "false",			SSH_TUNMODE_NO },
    717 	{ "no",				SSH_TUNMODE_NO },
    718 	{ NULL, -1 }
    719 };
    720 static const struct multistate multistate_requesttty[] = {
    721 	{ "true",			REQUEST_TTY_YES },
    722 	{ "yes",			REQUEST_TTY_YES },
    723 	{ "false",			REQUEST_TTY_NO },
    724 	{ "no",				REQUEST_TTY_NO },
    725 	{ "force",			REQUEST_TTY_FORCE },
    726 	{ "auto",			REQUEST_TTY_AUTO },
    727 	{ NULL, -1 }
    728 };
    729 static const struct multistate multistate_canonicalizehostname[] = {
    730 	{ "true",			SSH_CANONICALISE_YES },
    731 	{ "false",			SSH_CANONICALISE_NO },
    732 	{ "yes",			SSH_CANONICALISE_YES },
    733 	{ "no",				SSH_CANONICALISE_NO },
    734 	{ "always",			SSH_CANONICALISE_ALWAYS },
    735 	{ NULL, -1 }
    736 };
    737 
    738 /*
    739  * Processes a single option line as used in the configuration files. This
    740  * only sets those values that have not already been set.
    741  */
    742 #define WHITESPACE " \t\r\n"
    743 int
    744 process_config_line(Options *options, struct passwd *pw, const char *host,
    745     char *line, const char *filename, int linenum, int *activep, int userconfig)
    746 {
    747 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
    748 	char **cpptr, fwdarg[256];
    749 	u_int i, *uintptr, max_entries = 0;
    750 	int negated, opcode, *intptr, value, value2, cmdline = 0;
    751 	LogLevel *log_level_ptr;
    752 	long long val64;
    753 	size_t len;
    754 	struct Forward fwd;
    755 	const struct multistate *multistate_ptr;
    756 	struct allowed_cname *cname;
    757 
    758 	if (activep == NULL) { /* We are processing a command line directive */
    759 		cmdline = 1;
    760 		activep = &cmdline;
    761 	}
    762 
    763 	/* Strip trailing whitespace */
    764 	for (len = strlen(line) - 1; len > 0; len--) {
    765 		if (strchr(WHITESPACE, line[len]) == NULL)
    766 			break;
    767 		line[len] = '\0';
    768 	}
    769 
    770 	s = line;
    771 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
    772 	if ((keyword = strdelim(&s)) == NULL)
    773 		return 0;
    774 	/* Ignore leading whitespace. */
    775 	if (*keyword == '\0')
    776 		keyword = strdelim(&s);
    777 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
    778 		return 0;
    779 	/* Match lowercase keyword */
    780 	lowercase(keyword);
    781 
    782 	opcode = parse_token(keyword, filename, linenum,
    783 	    options->ignored_unknown);
    784 
    785 	switch (opcode) {
    786 	case oBadOption:
    787 		/* don't panic, but count bad options */
    788 		return -1;
    789 		/* NOTREACHED */
    790 	case oIgnoredUnknownOption:
    791 		debug("%s line %d: Ignored unknown option \"%s\"",
    792 		    filename, linenum, keyword);
    793 		return 0;
    794 	case oConnectTimeout:
    795 		intptr = &options->connection_timeout;
    796 parse_time:
    797 		arg = strdelim(&s);
    798 		if (!arg || *arg == '\0')
    799 			fatal("%s line %d: missing time value.",
    800 			    filename, linenum);
    801 		if ((value = convtime(arg)) == -1)
    802 			fatal("%s line %d: invalid time value.",
    803 			    filename, linenum);
    804 		if (*activep && *intptr == -1)
    805 			*intptr = value;
    806 		break;
    807 
    808 	case oForwardAgent:
    809 		intptr = &options->forward_agent;
    810  parse_flag:
    811 		multistate_ptr = multistate_flag;
    812  parse_multistate:
    813 		arg = strdelim(&s);
    814 		if (!arg || *arg == '\0')
    815 			fatal("%s line %d: missing argument.",
    816 			    filename, linenum);
    817 		value = -1;
    818 		for (i = 0; multistate_ptr[i].key != NULL; i++) {
    819 			if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
    820 				value = multistate_ptr[i].value;
    821 				break;
    822 			}
    823 		}
    824 		if (value == -1)
    825 			fatal("%s line %d: unsupported option \"%s\".",
    826 			    filename, linenum, arg);
    827 		if (*activep && *intptr == -1)
    828 			*intptr = value;
    829 		break;
    830 
    831 	case oForwardX11:
    832 		intptr = &options->forward_x11;
    833 		goto parse_flag;
    834 
    835 	case oForwardX11Trusted:
    836 		intptr = &options->forward_x11_trusted;
    837 		goto parse_flag;
    838 
    839 	case oForwardX11Timeout:
    840 		intptr = &options->forward_x11_timeout;
    841 		goto parse_time;
    842 
    843 	case oGatewayPorts:
    844 		intptr = &options->fwd_opts.gateway_ports;
    845 		goto parse_flag;
    846 
    847 	case oExitOnForwardFailure:
    848 		intptr = &options->exit_on_forward_failure;
    849 		goto parse_flag;
    850 
    851 	case oUsePrivilegedPort:
    852 		intptr = &options->use_privileged_port;
    853 		goto parse_flag;
    854 
    855 	case oPasswordAuthentication:
    856 		intptr = &options->password_authentication;
    857 		goto parse_flag;
    858 
    859 	case oKbdInteractiveAuthentication:
    860 		intptr = &options->kbd_interactive_authentication;
    861 		goto parse_flag;
    862 
    863 	case oKbdInteractiveDevices:
    864 		charptr = &options->kbd_interactive_devices;
    865 		goto parse_string;
    866 
    867 	case oPubkeyAuthentication:
    868 		intptr = &options->pubkey_authentication;
    869 		goto parse_flag;
    870 
    871 	case oRSAAuthentication:
    872 		intptr = &options->rsa_authentication;
    873 		goto parse_flag;
    874 
    875 	case oRhostsRSAAuthentication:
    876 		intptr = &options->rhosts_rsa_authentication;
    877 		goto parse_flag;
    878 
    879 	case oHostbasedAuthentication:
    880 		intptr = &options->hostbased_authentication;
    881 		goto parse_flag;
    882 
    883 	case oChallengeResponseAuthentication:
    884 		intptr = &options->challenge_response_authentication;
    885 		goto parse_flag;
    886 
    887 #if defined(KRB4) || defined(KRB5)
    888 	case oKerberosAuthentication:
    889 		intptr = &options->kerberos_authentication;
    890 		goto parse_flag;
    891 #endif
    892 #if defined(AFS) || defined(KRB5)
    893 	case oKerberosTgtPassing:
    894 		intptr = &options->kerberos_tgt_passing;
    895 		goto parse_flag;
    896 #endif
    897 
    898 	case oGssAuthentication:
    899 		intptr = &options->gss_authentication;
    900 		goto parse_flag;
    901 
    902 #ifdef AFS
    903 	case oAFSTokenPassing:
    904 		intptr = &options->afs_token_passing;
    905  		goto parse_flag;
    906 #endif
    907 
    908 	case oGssDelegateCreds:
    909 		intptr = &options->gss_deleg_creds;
    910 		goto parse_flag;
    911 
    912 	case oBatchMode:
    913 		intptr = &options->batch_mode;
    914 		goto parse_flag;
    915 
    916 	case oCheckHostIP:
    917 		intptr = &options->check_host_ip;
    918 		goto parse_flag;
    919 
    920 	case oNoneEnabled:
    921 		intptr = &options->none_enabled;
    922 		goto parse_flag;
    923 
    924 	/* we check to see if the command comes from the */
    925 	/* command line or not. If it does then enable it */
    926 	/* otherwise fail. NONE should never be a default configuration */
    927 	case oNoneSwitch:
    928 		if(strcmp(filename,"command-line")==0)
    929 		{
    930 		    intptr = &options->none_switch;
    931 		    goto parse_flag;
    932 		} else {
    933 		    error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
    934 		    error("Continuing...");
    935 		    debug("NoneSwitch directive found in %.200s.", filename);
    936 		    return 0;
    937 	        }
    938 
    939 	case oHPNDisabled:
    940 		intptr = &options->hpn_disabled;
    941 		goto parse_flag;
    942 
    943 	case oHPNBufferSize:
    944 		intptr = &options->hpn_buffer_size;
    945 		goto parse_int;
    946 
    947 	case oTcpRcvBufPoll:
    948 		intptr = &options->tcp_rcv_buf_poll;
    949 		goto parse_flag;
    950 
    951 	case oVerifyHostKeyDNS:
    952 		intptr = &options->verify_host_key_dns;
    953 		multistate_ptr = multistate_yesnoask;
    954 		goto parse_multistate;
    955 
    956 	case oStrictHostKeyChecking:
    957 		intptr = &options->strict_host_key_checking;
    958 		multistate_ptr = multistate_yesnoask;
    959 		goto parse_multistate;
    960 
    961 	case oCompression:
    962 		intptr = &options->compression;
    963 		goto parse_flag;
    964 
    965 	case oTCPKeepAlive:
    966 		intptr = &options->tcp_keep_alive;
    967 		goto parse_flag;
    968 
    969 	case oNoHostAuthenticationForLocalhost:
    970 		intptr = &options->no_host_authentication_for_localhost;
    971 		goto parse_flag;
    972 
    973 	case oNumberOfPasswordPrompts:
    974 		intptr = &options->number_of_password_prompts;
    975 		goto parse_int;
    976 
    977 	case oCompressionLevel:
    978 		intptr = &options->compression_level;
    979 		goto parse_int;
    980 
    981 	case oRekeyLimit:
    982 		arg = strdelim(&s);
    983 		if (!arg || *arg == '\0')
    984 			fatal("%.200s line %d: Missing argument.", filename,
    985 			    linenum);
    986 		if (strcmp(arg, "default") == 0) {
    987 			val64 = 0;
    988 		} else {
    989 			if (scan_scaled(arg, &val64) == -1)
    990 				fatal("%.200s line %d: Bad number '%s': %s",
    991 				    filename, linenum, arg, strerror(errno));
    992 			/* check for too-large or too-small limits */
    993 			if (val64 > UINT_MAX)
    994 				fatal("%.200s line %d: RekeyLimit too large",
    995 				    filename, linenum);
    996 			if (val64 != 0 && val64 < 16)
    997 				fatal("%.200s line %d: RekeyLimit too small",
    998 				    filename, linenum);
    999 		}
   1000 		if (*activep && options->rekey_limit == -1)
   1001 			options->rekey_limit = (u_int32_t)val64;
   1002 		if (s != NULL) { /* optional rekey interval present */
   1003 			if (strcmp(s, "none") == 0) {
   1004 				(void)strdelim(&s);	/* discard */
   1005 				break;
   1006 			}
   1007 			intptr = &options->rekey_interval;
   1008 			goto parse_time;
   1009 		}
   1010 		break;
   1011 
   1012 	case oIdentityFile:
   1013 		arg = strdelim(&s);
   1014 		if (!arg || *arg == '\0')
   1015 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1016 		if (*activep) {
   1017 			intptr = &options->num_identity_files;
   1018 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
   1019 				fatal("%.200s line %d: Too many identity files specified (max %d).",
   1020 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
   1021 			add_identity_file(options, NULL, arg, userconfig);
   1022 		}
   1023 		break;
   1024 
   1025 	case oXAuthLocation:
   1026 		charptr=&options->xauth_location;
   1027 		goto parse_string;
   1028 
   1029 	case oUser:
   1030 		charptr = &options->user;
   1031 parse_string:
   1032 		arg = strdelim(&s);
   1033 		if (!arg || *arg == '\0')
   1034 			fatal("%.200s line %d: Missing argument.",
   1035 			    filename, linenum);
   1036 		if (*activep && *charptr == NULL)
   1037 			*charptr = xstrdup(arg);
   1038 		break;
   1039 
   1040 	case oGlobalKnownHostsFile:
   1041 		cpptr = (char **)&options->system_hostfiles;
   1042 		uintptr = &options->num_system_hostfiles;
   1043 		max_entries = SSH_MAX_HOSTS_FILES;
   1044 parse_char_array:
   1045 		if (*activep && *uintptr == 0) {
   1046 			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1047 				if ((*uintptr) >= max_entries)
   1048 					fatal("%s line %d: "
   1049 					    "too many authorized keys files.",
   1050 					    filename, linenum);
   1051 				cpptr[(*uintptr)++] = xstrdup(arg);
   1052 			}
   1053 		}
   1054 		return 0;
   1055 
   1056 	case oUserKnownHostsFile:
   1057 		cpptr = (char **)&options->user_hostfiles;
   1058 		uintptr = &options->num_user_hostfiles;
   1059 		max_entries = SSH_MAX_HOSTS_FILES;
   1060 		goto parse_char_array;
   1061 
   1062 	case oHostName:
   1063 		charptr = &options->hostname;
   1064 		goto parse_string;
   1065 
   1066 	case oHostKeyAlias:
   1067 		charptr = &options->host_key_alias;
   1068 		goto parse_string;
   1069 
   1070 	case oPreferredAuthentications:
   1071 		charptr = &options->preferred_authentications;
   1072 		goto parse_string;
   1073 
   1074 	case oBindAddress:
   1075 		charptr = &options->bind_address;
   1076 		goto parse_string;
   1077 
   1078 	case oPKCS11Provider:
   1079 		charptr = &options->pkcs11_provider;
   1080 		goto parse_string;
   1081 
   1082 	case oProxyCommand:
   1083 		charptr = &options->proxy_command;
   1084 parse_command:
   1085 		if (s == NULL)
   1086 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1087 		len = strspn(s, WHITESPACE "=");
   1088 		if (*activep && *charptr == NULL)
   1089 			*charptr = xstrdup(s + len);
   1090 		return 0;
   1091 
   1092 	case oPort:
   1093 		intptr = &options->port;
   1094 parse_int:
   1095 		arg = strdelim(&s);
   1096 		if (!arg || *arg == '\0')
   1097 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1098 		if (arg[0] < '0' || arg[0] > '9')
   1099 			fatal("%.200s line %d: Bad number.", filename, linenum);
   1100 
   1101 		/* Octal, decimal, or hex format? */
   1102 		value = strtol(arg, &endofnumber, 0);
   1103 		if (arg == endofnumber)
   1104 			fatal("%.200s line %d: Bad number.", filename, linenum);
   1105 		if (*activep && *intptr == -1)
   1106 			*intptr = value;
   1107 		break;
   1108 
   1109 	case oConnectionAttempts:
   1110 		intptr = &options->connection_attempts;
   1111 		goto parse_int;
   1112 
   1113 	case oTcpRcvBuf:
   1114 		intptr = &options->tcp_rcv_buf;
   1115 		goto parse_int;
   1116 
   1117 	case oCipher:
   1118 		intptr = &options->cipher;
   1119 		arg = strdelim(&s);
   1120 		if (!arg || *arg == '\0')
   1121 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1122 		value = cipher_number(arg);
   1123 		if (value == -1)
   1124 			fatal("%.200s line %d: Bad cipher '%s'.",
   1125 			    filename, linenum, arg ? arg : "<NONE>");
   1126 		if (*activep && *intptr == -1)
   1127 			*intptr = value;
   1128 		break;
   1129 
   1130 	case oCiphers:
   1131 		arg = strdelim(&s);
   1132 		if (!arg || *arg == '\0')
   1133 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1134 		if (!ciphers_valid(arg))
   1135 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
   1136 			    filename, linenum, arg ? arg : "<NONE>");
   1137 		if (*activep && options->ciphers == NULL)
   1138 			options->ciphers = xstrdup(arg);
   1139 		break;
   1140 
   1141 	case oMacs:
   1142 		arg = strdelim(&s);
   1143 		if (!arg || *arg == '\0')
   1144 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1145 		if (!mac_valid(arg))
   1146 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
   1147 			    filename, linenum, arg ? arg : "<NONE>");
   1148 		if (*activep && options->macs == NULL)
   1149 			options->macs = xstrdup(arg);
   1150 		break;
   1151 
   1152 	case oKexAlgorithms:
   1153 		arg = strdelim(&s);
   1154 		if (!arg || *arg == '\0')
   1155 			fatal("%.200s line %d: Missing argument.",
   1156 			    filename, linenum);
   1157 		if (!kex_names_valid(arg))
   1158 			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
   1159 			    filename, linenum, arg ? arg : "<NONE>");
   1160 		if (*activep && options->kex_algorithms == NULL)
   1161 			options->kex_algorithms = xstrdup(arg);
   1162 		break;
   1163 
   1164 	case oHostKeyAlgorithms:
   1165 		arg = strdelim(&s);
   1166 		if (!arg || *arg == '\0')
   1167 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1168 		if (!key_names_valid2(arg))
   1169 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
   1170 			    filename, linenum, arg ? arg : "<NONE>");
   1171 		if (*activep && options->hostkeyalgorithms == NULL)
   1172 			options->hostkeyalgorithms = xstrdup(arg);
   1173 		break;
   1174 
   1175 	case oProtocol:
   1176 		intptr = &options->protocol;
   1177 		arg = strdelim(&s);
   1178 		if (!arg || *arg == '\0')
   1179 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1180 		value = proto_spec(arg);
   1181 		if (value == SSH_PROTO_UNKNOWN)
   1182 			fatal("%.200s line %d: Bad protocol spec '%s'.",
   1183 			    filename, linenum, arg ? arg : "<NONE>");
   1184 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
   1185 			*intptr = value;
   1186 		break;
   1187 
   1188 	case oLogLevel:
   1189 		log_level_ptr = &options->log_level;
   1190 		arg = strdelim(&s);
   1191 		value = log_level_number(arg);
   1192 		if (value == SYSLOG_LEVEL_NOT_SET)
   1193 			fatal("%.200s line %d: unsupported log level '%s'",
   1194 			    filename, linenum, arg ? arg : "<NONE>");
   1195 		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
   1196 			*log_level_ptr = (LogLevel) value;
   1197 		break;
   1198 
   1199 	case oLocalForward:
   1200 	case oRemoteForward:
   1201 	case oDynamicForward:
   1202 		arg = strdelim(&s);
   1203 		if (arg == NULL || *arg == '\0')
   1204 			fatal("%.200s line %d: Missing port argument.",
   1205 			    filename, linenum);
   1206 
   1207 		if (opcode == oLocalForward ||
   1208 		    opcode == oRemoteForward) {
   1209 			arg2 = strdelim(&s);
   1210 			if (arg2 == NULL || *arg2 == '\0')
   1211 				fatal("%.200s line %d: Missing target argument.",
   1212 				    filename, linenum);
   1213 
   1214 			/* construct a string for parse_forward */
   1215 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
   1216 		} else if (opcode == oDynamicForward) {
   1217 			strlcpy(fwdarg, arg, sizeof(fwdarg));
   1218 		}
   1219 
   1220 		if (parse_forward(&fwd, fwdarg,
   1221 		    opcode == oDynamicForward ? 1 : 0,
   1222 		    opcode == oRemoteForward ? 1 : 0) == 0)
   1223 			fatal("%.200s line %d: Bad forwarding specification.",
   1224 			    filename, linenum);
   1225 
   1226 		if (*activep) {
   1227 			if (opcode == oLocalForward ||
   1228 			    opcode == oDynamicForward)
   1229 				add_local_forward(options, &fwd);
   1230 			else if (opcode == oRemoteForward)
   1231 				add_remote_forward(options, &fwd);
   1232 		}
   1233 		break;
   1234 
   1235 	case oClearAllForwardings:
   1236 		intptr = &options->clear_forwardings;
   1237 		goto parse_flag;
   1238 
   1239 	case oHost:
   1240 		if (cmdline)
   1241 			fatal("Host directive not supported as a command-line "
   1242 			    "option");
   1243 		*activep = 0;
   1244 		arg2 = NULL;
   1245 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1246 			negated = *arg == '!';
   1247 			if (negated)
   1248 				arg++;
   1249 			if (match_pattern(host, arg)) {
   1250 				if (negated) {
   1251 					debug("%.200s line %d: Skipping Host "
   1252 					    "block because of negated match "
   1253 					    "for %.100s", filename, linenum,
   1254 					    arg);
   1255 					*activep = 0;
   1256 					break;
   1257 				}
   1258 				if (!*activep)
   1259 					arg2 = arg; /* logged below */
   1260 				*activep = 1;
   1261 			}
   1262 		}
   1263 		if (*activep)
   1264 			debug("%.200s line %d: Applying options for %.100s",
   1265 			    filename, linenum, arg2);
   1266 		/* Avoid garbage check below, as strdelim is done. */
   1267 		return 0;
   1268 
   1269 	case oMatch:
   1270 		if (cmdline)
   1271 			fatal("Host directive not supported as a command-line "
   1272 			    "option");
   1273 		value = match_cfg_line(options, &s, pw, host,
   1274 		    filename, linenum);
   1275 		if (value < 0)
   1276 			fatal("%.200s line %d: Bad Match condition", filename,
   1277 			    linenum);
   1278 		*activep = value;
   1279 		break;
   1280 
   1281 	case oEscapeChar:
   1282 		intptr = &options->escape_char;
   1283 		arg = strdelim(&s);
   1284 		if (!arg || *arg == '\0')
   1285 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1286 		value = 0;	/* To avoid compiler warning... */
   1287 		if (arg[0] == '^' && arg[2] == 0 &&
   1288 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
   1289 			value = (u_char) arg[1] & 31;
   1290 		else if (strlen(arg) == 1)
   1291 			value = (u_char) arg[0];
   1292 		else if (strcmp(arg, "none") == 0)
   1293 			value = SSH_ESCAPECHAR_NONE;
   1294 		else {
   1295 			fatal("%.200s line %d: Bad escape character.",
   1296 			    filename, linenum);
   1297 			/* NOTREACHED */
   1298 			value = 0;	/* Avoid compiler warning. */
   1299 		}
   1300 		if (*activep && *intptr == -1)
   1301 			*intptr = value;
   1302 		break;
   1303 
   1304 	case oAddressFamily:
   1305 		intptr = &options->address_family;
   1306 		multistate_ptr = multistate_addressfamily;
   1307 		goto parse_multistate;
   1308 
   1309 	case oEnableSSHKeysign:
   1310 		intptr = &options->enable_ssh_keysign;
   1311 		goto parse_flag;
   1312 
   1313 	case oIdentitiesOnly:
   1314 		intptr = &options->identities_only;
   1315 		goto parse_flag;
   1316 
   1317 	case oServerAliveInterval:
   1318 		intptr = &options->server_alive_interval;
   1319 		goto parse_time;
   1320 
   1321 	case oServerAliveCountMax:
   1322 		intptr = &options->server_alive_count_max;
   1323 		goto parse_int;
   1324 
   1325 	case oSendEnv:
   1326 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1327 			if (strchr(arg, '=') != NULL)
   1328 				fatal("%s line %d: Invalid environment name.",
   1329 				    filename, linenum);
   1330 			if (!*activep)
   1331 				continue;
   1332 			if (options->num_send_env >= MAX_SEND_ENV)
   1333 				fatal("%s line %d: too many send env.",
   1334 				    filename, linenum);
   1335 			options->send_env[options->num_send_env++] =
   1336 			    xstrdup(arg);
   1337 		}
   1338 		break;
   1339 
   1340 	case oControlPath:
   1341 		charptr = &options->control_path;
   1342 		goto parse_string;
   1343 
   1344 	case oControlMaster:
   1345 		intptr = &options->control_master;
   1346 		multistate_ptr = multistate_controlmaster;
   1347 		goto parse_multistate;
   1348 
   1349 	case oControlPersist:
   1350 		/* no/false/yes/true, or a time spec */
   1351 		intptr = &options->control_persist;
   1352 		arg = strdelim(&s);
   1353 		if (!arg || *arg == '\0')
   1354 			fatal("%.200s line %d: Missing ControlPersist"
   1355 			    " argument.", filename, linenum);
   1356 		value = 0;
   1357 		value2 = 0;	/* timeout */
   1358 		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
   1359 			value = 0;
   1360 		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
   1361 			value = 1;
   1362 		else if ((value2 = convtime(arg)) >= 0)
   1363 			value = 1;
   1364 		else
   1365 			fatal("%.200s line %d: Bad ControlPersist argument.",
   1366 			    filename, linenum);
   1367 		if (*activep && *intptr == -1) {
   1368 			*intptr = value;
   1369 			options->control_persist_timeout = value2;
   1370 		}
   1371 		break;
   1372 
   1373 	case oHashKnownHosts:
   1374 		intptr = &options->hash_known_hosts;
   1375 		goto parse_flag;
   1376 
   1377 	case oTunnel:
   1378 		intptr = &options->tun_open;
   1379 		multistate_ptr = multistate_tunnel;
   1380 		goto parse_multistate;
   1381 
   1382 	case oTunnelDevice:
   1383 		arg = strdelim(&s);
   1384 		if (!arg || *arg == '\0')
   1385 			fatal("%.200s line %d: Missing argument.", filename, linenum);
   1386 		value = a2tun(arg, &value2);
   1387 		if (value == SSH_TUNID_ERR)
   1388 			fatal("%.200s line %d: Bad tun device.", filename, linenum);
   1389 		if (*activep) {
   1390 			options->tun_local = value;
   1391 			options->tun_remote = value2;
   1392 		}
   1393 		break;
   1394 
   1395 	case oLocalCommand:
   1396 		charptr = &options->local_command;
   1397 		goto parse_command;
   1398 
   1399 	case oPermitLocalCommand:
   1400 		intptr = &options->permit_local_command;
   1401 		goto parse_flag;
   1402 
   1403 	case oVisualHostKey:
   1404 		intptr = &options->visual_host_key;
   1405 		goto parse_flag;
   1406 
   1407 	case oIPQoS:
   1408 		arg = strdelim(&s);
   1409 		if ((value = parse_ipqos(arg)) == -1)
   1410 			fatal("%s line %d: Bad IPQoS value: %s",
   1411 			    filename, linenum, arg);
   1412 		arg = strdelim(&s);
   1413 		if (arg == NULL)
   1414 			value2 = value;
   1415 		else if ((value2 = parse_ipqos(arg)) == -1)
   1416 			fatal("%s line %d: Bad IPQoS value: %s",
   1417 			    filename, linenum, arg);
   1418 		if (*activep) {
   1419 			options->ip_qos_interactive = value;
   1420 			options->ip_qos_bulk = value2;
   1421 		}
   1422 		break;
   1423 
   1424 	case oUseRoaming:
   1425 		intptr = &options->use_roaming;
   1426 		goto parse_flag;
   1427 
   1428 	case oRequestTTY:
   1429 		intptr = &options->request_tty;
   1430 		multistate_ptr = multistate_requesttty;
   1431 		goto parse_multistate;
   1432 
   1433 	case oSendVersionFirst:
   1434 		intptr = &options->send_version_first;
   1435 		goto parse_flag;
   1436 
   1437 	case oIgnoreUnknown:
   1438 		charptr = &options->ignored_unknown;
   1439 		goto parse_string;
   1440 
   1441 	case oProxyUseFdpass:
   1442 		intptr = &options->proxy_use_fdpass;
   1443 		goto parse_flag;
   1444 
   1445 	case oCanonicalDomains:
   1446 		value = options->num_canonical_domains != 0;
   1447 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1448 			valid_domain(arg, filename, linenum);
   1449 			if (!*activep || value)
   1450 				continue;
   1451 			if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
   1452 				fatal("%s line %d: too many hostname suffixes.",
   1453 				    filename, linenum);
   1454 			options->canonical_domains[
   1455 			    options->num_canonical_domains++] = xstrdup(arg);
   1456 		}
   1457 		break;
   1458 
   1459 	case oCanonicalizePermittedCNAMEs:
   1460 		value = options->num_permitted_cnames != 0;
   1461 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1462 			/* Either '*' for everything or 'list:list' */
   1463 			if (strcmp(arg, "*") == 0)
   1464 				arg2 = arg;
   1465 			else {
   1466 				lowercase(arg);
   1467 				if ((arg2 = strchr(arg, ':')) == NULL ||
   1468 				    arg2[1] == '\0') {
   1469 					fatal("%s line %d: "
   1470 					    "Invalid permitted CNAME \"%s\"",
   1471 					    filename, linenum, arg);
   1472 				}
   1473 				*arg2 = '\0';
   1474 				arg2++;
   1475 			}
   1476 			if (!*activep || value)
   1477 				continue;
   1478 			if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
   1479 				fatal("%s line %d: too many permitted CNAMEs.",
   1480 				    filename, linenum);
   1481 			cname = options->permitted_cnames +
   1482 			    options->num_permitted_cnames++;
   1483 			cname->source_list = xstrdup(arg);
   1484 			cname->target_list = xstrdup(arg2);
   1485 		}
   1486 		break;
   1487 
   1488 	case oCanonicalizeHostname:
   1489 		intptr = &options->canonicalize_hostname;
   1490 		multistate_ptr = multistate_canonicalizehostname;
   1491 		goto parse_multistate;
   1492 
   1493 	case oCanonicalizeMaxDots:
   1494 		intptr = &options->canonicalize_max_dots;
   1495 		goto parse_int;
   1496 
   1497 	case oCanonicalizeFallbackLocal:
   1498 		intptr = &options->canonicalize_fallback_local;
   1499 		goto parse_flag;
   1500 
   1501 	case oStreamLocalBindMask:
   1502 		arg = strdelim(&s);
   1503 		if (!arg || *arg == '\0')
   1504 			fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
   1505 		/* Parse mode in octal format */
   1506 		value = strtol(arg, &endofnumber, 8);
   1507 		if (arg == endofnumber || value < 0 || value > 0777)
   1508 			fatal("%.200s line %d: Bad mask.", filename, linenum);
   1509 		options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
   1510 		break;
   1511 
   1512 	case oStreamLocalBindUnlink:
   1513 		intptr = &options->fwd_opts.streamlocal_bind_unlink;
   1514 		goto parse_flag;
   1515 
   1516 	case oDeprecated:
   1517 		debug("%s line %d: Deprecated option \"%s\"",
   1518 		    filename, linenum, keyword);
   1519 		return 0;
   1520 
   1521 	case oUnsupported:
   1522 		error("%s line %d: Unsupported option \"%s\"",
   1523 		    filename, linenum, keyword);
   1524 		return 0;
   1525 
   1526 	default:
   1527 		fatal("process_config_line: Unimplemented opcode %d", opcode);
   1528 	}
   1529 
   1530 	/* Check that there is no garbage at end of line. */
   1531 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
   1532 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
   1533 		    filename, linenum, arg);
   1534 	}
   1535 	return 0;
   1536 }
   1537 
   1538 
   1539 /*
   1540  * Reads the config file and modifies the options accordingly.  Options
   1541  * should already be initialized before this call.  This never returns if
   1542  * there is an error.  If the file does not exist, this returns 0.
   1543  */
   1544 
   1545 int
   1546 read_config_file(const char *filename, struct passwd *pw, const char *host,
   1547     Options *options, int flags)
   1548 {
   1549 	FILE *f;
   1550 	char line[1024];
   1551 	int active, linenum;
   1552 	int bad_options = 0;
   1553 
   1554 	if ((f = fopen(filename, "r")) == NULL)
   1555 		return 0;
   1556 
   1557 	if (flags & SSHCONF_CHECKPERM) {
   1558 		struct stat sb;
   1559 
   1560 		if (fstat(fileno(f), &sb) == -1)
   1561 			fatal("fstat %s: %s", filename, strerror(errno));
   1562 		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
   1563 		    (sb.st_mode & 022) != 0))
   1564 			fatal("Bad owner or permissions on %s", filename);
   1565 	}
   1566 
   1567 	debug("Reading configuration data %.200s", filename);
   1568 
   1569 	/*
   1570 	 * Mark that we are now processing the options.  This flag is turned
   1571 	 * on/off by Host specifications.
   1572 	 */
   1573 	active = 1;
   1574 	linenum = 0;
   1575 	while (fgets(line, sizeof(line), f)) {
   1576 		/* Update line number counter. */
   1577 		linenum++;
   1578 		if (process_config_line(options, pw, host, line, filename,
   1579 		    linenum, &active, flags & SSHCONF_USERCONF) != 0)
   1580 			bad_options++;
   1581 	}
   1582 	fclose(f);
   1583 	if (bad_options > 0)
   1584 		fatal("%s: terminating, %d bad configuration options",
   1585 		    filename, bad_options);
   1586 	return 1;
   1587 }
   1588 
   1589 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
   1590 int
   1591 option_clear_or_none(const char *o)
   1592 {
   1593 	return o == NULL || strcasecmp(o, "none") == 0;
   1594 }
   1595 
   1596 /*
   1597  * Initializes options to special values that indicate that they have not yet
   1598  * been set.  Read_config_file will only set options with this value. Options
   1599  * are processed in the following order: command line, user config file,
   1600  * system config file.  Last, fill_default_options is called.
   1601  */
   1602 
   1603 void
   1604 initialize_options(Options * options)
   1605 {
   1606 	memset(options, 'X', sizeof(*options));
   1607 	options->forward_agent = -1;
   1608 	options->forward_x11 = -1;
   1609 	options->forward_x11_trusted = -1;
   1610 	options->forward_x11_timeout = -1;
   1611 	options->exit_on_forward_failure = -1;
   1612 	options->xauth_location = NULL;
   1613 	options->fwd_opts.gateway_ports = -1;
   1614 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
   1615 	options->fwd_opts.streamlocal_bind_unlink = -1;
   1616 	options->use_privileged_port = -1;
   1617 	options->rsa_authentication = -1;
   1618 	options->pubkey_authentication = -1;
   1619 	options->challenge_response_authentication = -1;
   1620 #if defined(KRB4) || defined(KRB5)
   1621 	options->kerberos_authentication = -1;
   1622 #endif
   1623 #if defined(AFS) || defined(KRB5)
   1624 	options->kerberos_tgt_passing = -1;
   1625 #endif
   1626 #ifdef AFS
   1627 	options->afs_token_passing = -1;
   1628 #endif
   1629 	options->gss_authentication = -1;
   1630 	options->gss_deleg_creds = -1;
   1631 	options->password_authentication = -1;
   1632 	options->kbd_interactive_authentication = -1;
   1633 	options->kbd_interactive_devices = NULL;
   1634 	options->rhosts_rsa_authentication = -1;
   1635 	options->hostbased_authentication = -1;
   1636 	options->batch_mode = -1;
   1637 	options->check_host_ip = -1;
   1638 	options->strict_host_key_checking = -1;
   1639 	options->compression = -1;
   1640 	options->tcp_keep_alive = -1;
   1641 	options->compression_level = -1;
   1642 	options->port = -1;
   1643 	options->address_family = -1;
   1644 	options->connection_attempts = -1;
   1645 	options->connection_timeout = -1;
   1646 	options->number_of_password_prompts = -1;
   1647 	options->cipher = -1;
   1648 	options->ciphers = NULL;
   1649 	options->macs = NULL;
   1650 	options->kex_algorithms = NULL;
   1651 	options->hostkeyalgorithms = NULL;
   1652 	options->protocol = SSH_PROTO_UNKNOWN;
   1653 	options->num_identity_files = 0;
   1654 	options->hostname = NULL;
   1655 	options->host_key_alias = NULL;
   1656 	options->proxy_command = NULL;
   1657 	options->user = NULL;
   1658 	options->escape_char = -1;
   1659 	options->num_system_hostfiles = 0;
   1660 	options->num_user_hostfiles = 0;
   1661 	options->local_forwards = NULL;
   1662 	options->num_local_forwards = 0;
   1663 	options->remote_forwards = NULL;
   1664 	options->num_remote_forwards = 0;
   1665 	options->clear_forwardings = -1;
   1666 	options->log_level = SYSLOG_LEVEL_NOT_SET;
   1667 	options->preferred_authentications = NULL;
   1668 	options->bind_address = NULL;
   1669 	options->pkcs11_provider = NULL;
   1670 	options->enable_ssh_keysign = - 1;
   1671 	options->no_host_authentication_for_localhost = - 1;
   1672 	options->identities_only = - 1;
   1673 	options->rekey_limit = - 1;
   1674 	options->rekey_interval = -1;
   1675 	options->verify_host_key_dns = -1;
   1676 	options->server_alive_interval = -1;
   1677 	options->server_alive_count_max = -1;
   1678 	options->num_send_env = 0;
   1679 	options->control_path = NULL;
   1680 	options->control_master = -1;
   1681 	options->control_persist = -1;
   1682 	options->control_persist_timeout = 0;
   1683 	options->hash_known_hosts = -1;
   1684 	options->tun_open = -1;
   1685 	options->tun_local = -1;
   1686 	options->tun_remote = -1;
   1687 	options->local_command = NULL;
   1688 	options->permit_local_command = -1;
   1689 	options->use_roaming = -1;
   1690 	options->visual_host_key = -1;
   1691 	options->ip_qos_interactive = -1;
   1692 	options->ip_qos_bulk = -1;
   1693 	options->request_tty = -1;
   1694 	options->proxy_use_fdpass = -1;
   1695 	options->ignored_unknown = NULL;
   1696 	options->num_canonical_domains = 0;
   1697 	options->num_permitted_cnames = 0;
   1698 	options->canonicalize_max_dots = -1;
   1699 	options->canonicalize_fallback_local = -1;
   1700 	options->canonicalize_hostname = -1;
   1701 	options->none_switch = -1;
   1702 	options->none_enabled = -1;
   1703 	options->hpn_disabled = -1;
   1704 	options->hpn_buffer_size = -1;
   1705 	options->tcp_rcv_buf_poll = -1;
   1706 	options->tcp_rcv_buf = -1;
   1707 	options->send_version_first = -1;
   1708 }
   1709 
   1710 /*
   1711  * A petite version of fill_default_options() that just fills the options
   1712  * needed for hostname canonicalization to proceed.
   1713  */
   1714 void
   1715 fill_default_options_for_canonicalization(Options *options)
   1716 {
   1717 	if (options->canonicalize_max_dots == -1)
   1718 		options->canonicalize_max_dots = 1;
   1719 	if (options->canonicalize_fallback_local == -1)
   1720 		options->canonicalize_fallback_local = 1;
   1721 	if (options->canonicalize_hostname == -1)
   1722 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
   1723 }
   1724 
   1725 /*
   1726  * Called after processing other sources of option data, this fills those
   1727  * options for which no value has been specified with their default values.
   1728  */
   1729 void
   1730 fill_default_options(Options * options)
   1731 {
   1732 	if (options->forward_agent == -1)
   1733 		options->forward_agent = 0;
   1734 	if (options->forward_x11 == -1)
   1735 		options->forward_x11 = 0;
   1736 	if (options->forward_x11_trusted == -1)
   1737 		options->forward_x11_trusted = 0;
   1738 	if (options->forward_x11_timeout == -1)
   1739 		options->forward_x11_timeout = 1200;
   1740 	if (options->exit_on_forward_failure == -1)
   1741 		options->exit_on_forward_failure = 0;
   1742 	if (options->xauth_location == NULL)
   1743 		options->xauth_location = __UNCONST(_PATH_XAUTH);
   1744 	if (options->fwd_opts.gateway_ports == -1)
   1745 		options->fwd_opts.gateway_ports = 0;
   1746 	if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
   1747 		options->fwd_opts.streamlocal_bind_mask = 0177;
   1748 	if (options->fwd_opts.streamlocal_bind_unlink == -1)
   1749 		options->fwd_opts.streamlocal_bind_unlink = 0;
   1750 	if (options->use_privileged_port == -1)
   1751 		options->use_privileged_port = 0;
   1752 	if (options->rsa_authentication == -1)
   1753 		options->rsa_authentication = 1;
   1754 	if (options->pubkey_authentication == -1)
   1755 		options->pubkey_authentication = 1;
   1756 	if (options->challenge_response_authentication == -1)
   1757 		options->challenge_response_authentication = 1;
   1758 #if defined(KRB4) || defined(KRB5)
   1759 	if (options->kerberos_authentication == -1)
   1760 		options->kerberos_authentication = 1;
   1761 #endif
   1762 #if defined(AFS) || defined(KRB5)
   1763 	if (options->kerberos_tgt_passing == -1)
   1764 		options->kerberos_tgt_passing = 1;
   1765 #endif
   1766 #ifdef AFS
   1767 	if (options->afs_token_passing == -1)
   1768 		options->afs_token_passing = 1;
   1769 #endif
   1770 	if (options->gss_authentication == -1)
   1771 		options->gss_authentication = 0;
   1772 	if (options->gss_deleg_creds == -1)
   1773 		options->gss_deleg_creds = 0;
   1774 	if (options->password_authentication == -1)
   1775 		options->password_authentication = 1;
   1776 	if (options->kbd_interactive_authentication == -1)
   1777 		options->kbd_interactive_authentication = 1;
   1778 	if (options->rhosts_rsa_authentication == -1)
   1779 		options->rhosts_rsa_authentication = 0;
   1780 	if (options->hostbased_authentication == -1)
   1781 		options->hostbased_authentication = 0;
   1782 	if (options->batch_mode == -1)
   1783 		options->batch_mode = 0;
   1784 	if (options->check_host_ip == -1)
   1785 		options->check_host_ip = 1;
   1786 	if (options->strict_host_key_checking == -1)
   1787 		options->strict_host_key_checking = 2;	/* 2 is default */
   1788 	if (options->compression == -1)
   1789 		options->compression = 0;
   1790 	if (options->tcp_keep_alive == -1)
   1791 		options->tcp_keep_alive = 1;
   1792 	if (options->compression_level == -1)
   1793 		options->compression_level = 6;
   1794 	if (options->port == -1)
   1795 		options->port = 0;	/* Filled in ssh_connect. */
   1796 	if (options->address_family == -1)
   1797 		options->address_family = AF_UNSPEC;
   1798 	if (options->connection_attempts == -1)
   1799 		options->connection_attempts = 1;
   1800 	if (options->number_of_password_prompts == -1)
   1801 		options->number_of_password_prompts = 3;
   1802 	/* Selected in ssh_login(). */
   1803 	if (options->cipher == -1)
   1804 		options->cipher = SSH_CIPHER_NOT_SET;
   1805 	/* options->ciphers, default set in myproposals.h */
   1806 	/* options->macs, default set in myproposals.h */
   1807 	/* options->kex_algorithms, default set in myproposals.h */
   1808 	/* options->hostkeyalgorithms, default set in myproposals.h */
   1809 	if (options->protocol == SSH_PROTO_UNKNOWN)
   1810 		options->protocol = SSH_PROTO_2;
   1811 	if (options->num_identity_files == 0) {
   1812 		if (options->protocol & SSH_PROTO_1) {
   1813 			add_identity_file(options, "~/",
   1814 			    _PATH_SSH_CLIENT_IDENTITY, 0);
   1815 		}
   1816 		if (options->protocol & SSH_PROTO_2) {
   1817 			add_identity_file(options, "~/",
   1818 			    _PATH_SSH_CLIENT_ID_RSA, 0);
   1819 			add_identity_file(options, "~/",
   1820 			    _PATH_SSH_CLIENT_ID_DSA, 0);
   1821 			add_identity_file(options, "~/",
   1822 			    _PATH_SSH_CLIENT_ID_ECDSA, 0);
   1823 			add_identity_file(options, "~/",
   1824 			    _PATH_SSH_CLIENT_ID_ED25519, 0);
   1825 		}
   1826 	}
   1827 	if (options->escape_char == -1)
   1828 		options->escape_char = '~';
   1829 	if (options->num_system_hostfiles == 0) {
   1830 		options->system_hostfiles[options->num_system_hostfiles++] =
   1831 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
   1832 		options->system_hostfiles[options->num_system_hostfiles++] =
   1833 		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
   1834 	}
   1835 	if (options->num_user_hostfiles == 0) {
   1836 		options->user_hostfiles[options->num_user_hostfiles++] =
   1837 		    xstrdup(_PATH_SSH_USER_HOSTFILE);
   1838 		options->user_hostfiles[options->num_user_hostfiles++] =
   1839 		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
   1840 	}
   1841 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
   1842 		options->log_level = SYSLOG_LEVEL_INFO;
   1843 	if (options->clear_forwardings == 1)
   1844 		clear_forwardings(options);
   1845 	if (options->no_host_authentication_for_localhost == - 1)
   1846 		options->no_host_authentication_for_localhost = 0;
   1847 	if (options->identities_only == -1)
   1848 		options->identities_only = 0;
   1849 	if (options->enable_ssh_keysign == -1)
   1850 		options->enable_ssh_keysign = 0;
   1851 	if (options->rekey_limit == -1)
   1852 		options->rekey_limit = 0;
   1853 	if (options->rekey_interval == -1)
   1854 		options->rekey_interval = 0;
   1855 	if (options->verify_host_key_dns == -1)
   1856 		options->verify_host_key_dns = 0;
   1857 	if (options->server_alive_interval == -1)
   1858 		options->server_alive_interval = 0;
   1859 	if (options->server_alive_count_max == -1)
   1860 		options->server_alive_count_max = 3;
   1861 	if (options->none_switch == -1)
   1862 	        options->none_switch = 0;
   1863 	if (options->hpn_disabled == -1)
   1864 	        options->hpn_disabled = 0;
   1865 	if (options->hpn_buffer_size > -1)
   1866 	{
   1867 	  /* if a user tries to set the size to 0 set it to 1KB */
   1868 		if (options->hpn_buffer_size == 0)
   1869 		options->hpn_buffer_size = 1024;
   1870 		/*limit the buffer to 64MB*/
   1871 		if (options->hpn_buffer_size > 65536)
   1872 		{
   1873 			options->hpn_buffer_size = 65536*1024;
   1874 			debug("User requested buffer larger than 64MB. Request reverted to 64MB");
   1875 		}
   1876 		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
   1877 	}
   1878 	if (options->tcp_rcv_buf == 0)
   1879 		options->tcp_rcv_buf = 1;
   1880 	if (options->tcp_rcv_buf > -1)
   1881 		options->tcp_rcv_buf *=1024;
   1882 	if (options->tcp_rcv_buf_poll == -1)
   1883 		options->tcp_rcv_buf_poll = 1;
   1884 	if (options->control_master == -1)
   1885 		options->control_master = 0;
   1886 	if (options->control_persist == -1) {
   1887 		options->control_persist = 0;
   1888 		options->control_persist_timeout = 0;
   1889 	}
   1890 	if (options->hash_known_hosts == -1)
   1891 		options->hash_known_hosts = 0;
   1892 	if (options->tun_open == -1)
   1893 		options->tun_open = SSH_TUNMODE_NO;
   1894 	if (options->tun_local == -1)
   1895 		options->tun_local = SSH_TUNID_ANY;
   1896 	if (options->tun_remote == -1)
   1897 		options->tun_remote = SSH_TUNID_ANY;
   1898 	if (options->permit_local_command == -1)
   1899 		options->permit_local_command = 0;
   1900 	if (options->use_roaming == -1)
   1901 		options->use_roaming = 1;
   1902 	if (options->visual_host_key == -1)
   1903 		options->visual_host_key = 0;
   1904 	if (options->ip_qos_interactive == -1)
   1905 		options->ip_qos_interactive = IPTOS_LOWDELAY;
   1906 	if (options->ip_qos_bulk == -1)
   1907 		options->ip_qos_bulk = IPTOS_THROUGHPUT;
   1908 	if (options->request_tty == -1)
   1909 		options->request_tty = REQUEST_TTY_AUTO;
   1910 	if (options->proxy_use_fdpass == -1)
   1911 		options->proxy_use_fdpass = 0;
   1912 	if (options->canonicalize_max_dots == -1)
   1913 		options->canonicalize_max_dots = 1;
   1914 	if (options->canonicalize_fallback_local == -1)
   1915 		options->canonicalize_fallback_local = 1;
   1916 	if (options->canonicalize_hostname == -1)
   1917 		options->canonicalize_hostname = SSH_CANONICALISE_NO;
   1918 	if (options->send_version_first == -1)
   1919 		options->send_version_first = 1;
   1920 #define CLEAR_ON_NONE(v) \
   1921 	do { \
   1922 		if (option_clear_or_none(v)) { \
   1923 			free(v); \
   1924 			v = NULL; \
   1925 		} \
   1926 	} while(0)
   1927 	CLEAR_ON_NONE(options->local_command);
   1928 	CLEAR_ON_NONE(options->proxy_command);
   1929 	CLEAR_ON_NONE(options->control_path);
   1930 	/* options->user will be set in the main program if appropriate */
   1931 	/* options->hostname will be set in the main program if appropriate */
   1932 	/* options->host_key_alias should not be set by default */
   1933 	/* options->preferred_authentications will be set in ssh */
   1934 }
   1935 
   1936 struct fwdarg {
   1937 	char *arg;
   1938 	int ispath;
   1939 };
   1940 
   1941 /*
   1942  * parse_fwd_field
   1943  * parses the next field in a port forwarding specification.
   1944  * sets fwd to the parsed field and advances p past the colon
   1945  * or sets it to NULL at end of string.
   1946  * returns 0 on success, else non-zero.
   1947  */
   1948 static int
   1949 parse_fwd_field(char **p, struct fwdarg *fwd)
   1950 {
   1951 	char *ep, *cp = *p;
   1952 	int ispath = 0;
   1953 
   1954 	if (*cp == '\0') {
   1955 		*p = NULL;
   1956 		return -1;	/* end of string */
   1957 	}
   1958 
   1959 	/*
   1960 	 * A field escaped with square brackets is used literally.
   1961 	 * XXX - allow ']' to be escaped via backslash?
   1962 	 */
   1963 	if (*cp == '[') {
   1964 		/* find matching ']' */
   1965 		for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
   1966 			if (*ep == '/')
   1967 				ispath = 1;
   1968 		}
   1969 		/* no matching ']' or not at end of field. */
   1970 		if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
   1971 			return -1;
   1972 		/* NUL terminate the field and advance p past the colon */
   1973 		*ep++ = '\0';
   1974 		if (*ep != '\0')
   1975 			*ep++ = '\0';
   1976 		fwd->arg = cp + 1;
   1977 		fwd->ispath = ispath;
   1978 		*p = ep;
   1979 		return 0;
   1980 	}
   1981 
   1982 	for (cp = *p; *cp != '\0'; cp++) {
   1983 		switch (*cp) {
   1984 		case '\\':
   1985 			memmove(cp, cp + 1, strlen(cp + 1) + 1);
   1986 			cp++;
   1987 			break;
   1988 		case '/':
   1989 			ispath = 1;
   1990 			break;
   1991 		case ':':
   1992 			*cp++ = '\0';
   1993 			goto done;
   1994 		}
   1995 	}
   1996 done:
   1997 	fwd->arg = *p;
   1998 	fwd->ispath = ispath;
   1999 	*p = cp;
   2000 	return 0;
   2001 }
   2002 
   2003 /*
   2004  * parse_forward
   2005  * parses a string containing a port forwarding specification of the form:
   2006  *   dynamicfwd == 0
   2007  *	[listenhost:]listenport|listenpath:connecthost:connectport|connectpath
   2008  *	listenpath:connectpath
   2009  *   dynamicfwd == 1
   2010  *	[listenhost:]listenport
   2011  * returns number of arguments parsed or zero on error
   2012  */
   2013 int
   2014 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
   2015 {
   2016 	struct fwdarg fwdargs[4];
   2017 	char *p, *cp;
   2018 	int i;
   2019 
   2020 	memset(fwd, 0, sizeof(*fwd));
   2021 	memset(fwdargs, 0, sizeof(fwdargs));
   2022 
   2023 	cp = p = xstrdup(fwdspec);
   2024 
   2025 	/* skip leading spaces */
   2026 	while (isspace((u_char)*cp))
   2027 		cp++;
   2028 
   2029 	for (i = 0; i < 4; ++i) {
   2030 		if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
   2031 			break;
   2032 	}
   2033 
   2034 	/* Check for trailing garbage */
   2035 	if (cp != NULL && *cp != '\0') {
   2036 		i = 0;	/* failure */
   2037 	}
   2038 
   2039 	switch (i) {
   2040 	case 1:
   2041 		if (fwdargs[0].ispath) {
   2042 			fwd->listen_path = xstrdup(fwdargs[0].arg);
   2043 			fwd->listen_port = PORT_STREAMLOCAL;
   2044 		} else {
   2045 			fwd->listen_host = NULL;
   2046 			fwd->listen_port = a2port(fwdargs[0].arg);
   2047 		}
   2048 		fwd->connect_host = xstrdup("socks");
   2049 		break;
   2050 
   2051 	case 2:
   2052 		if (fwdargs[0].ispath && fwdargs[1].ispath) {
   2053 			fwd->listen_path = xstrdup(fwdargs[0].arg);
   2054 			fwd->listen_port = PORT_STREAMLOCAL;
   2055 			fwd->connect_path = xstrdup(fwdargs[1].arg);
   2056 			fwd->connect_port = PORT_STREAMLOCAL;
   2057 		} else if (fwdargs[1].ispath) {
   2058 			fwd->listen_host = NULL;
   2059 			fwd->listen_port = a2port(fwdargs[0].arg);
   2060 			fwd->connect_path = xstrdup(fwdargs[1].arg);
   2061 			fwd->connect_port = PORT_STREAMLOCAL;
   2062 		} else {
   2063 			fwd->listen_host = xstrdup(fwdargs[0].arg);
   2064 			fwd->listen_port = a2port(fwdargs[1].arg);
   2065 			fwd->connect_host = xstrdup("socks");
   2066 		}
   2067 		break;
   2068 
   2069 	case 3:
   2070 		if (fwdargs[0].ispath) {
   2071 			fwd->listen_path = xstrdup(fwdargs[0].arg);
   2072 			fwd->listen_port = PORT_STREAMLOCAL;
   2073 			fwd->connect_host = xstrdup(fwdargs[1].arg);
   2074 			fwd->connect_port = a2port(fwdargs[2].arg);
   2075 		} else if (fwdargs[2].ispath) {
   2076 			fwd->listen_host = xstrdup(fwdargs[0].arg);
   2077 			fwd->listen_port = a2port(fwdargs[1].arg);
   2078 			fwd->connect_path = xstrdup(fwdargs[2].arg);
   2079 			fwd->connect_port = PORT_STREAMLOCAL;
   2080 		} else {
   2081 			fwd->listen_host = NULL;
   2082 			fwd->listen_port = a2port(fwdargs[0].arg);
   2083 			fwd->connect_host = xstrdup(fwdargs[1].arg);
   2084 			fwd->connect_port = a2port(fwdargs[2].arg);
   2085 		}
   2086 		break;
   2087 
   2088 	case 4:
   2089 		fwd->listen_host = xstrdup(fwdargs[0].arg);
   2090 		fwd->listen_port = a2port(fwdargs[1].arg);
   2091 		fwd->connect_host = xstrdup(fwdargs[2].arg);
   2092 		fwd->connect_port = a2port(fwdargs[3].arg);
   2093 		break;
   2094 	default:
   2095 		i = 0; /* failure */
   2096 	}
   2097 
   2098 	free(p);
   2099 
   2100 	if (dynamicfwd) {
   2101 		if (!(i == 1 || i == 2))
   2102 			goto fail_free;
   2103 	} else {
   2104 		if (!(i == 3 || i == 4)) {
   2105 			if (fwd->connect_path == NULL &&
   2106 			    fwd->listen_path == NULL)
   2107 				goto fail_free;
   2108 		}
   2109 		if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
   2110 			goto fail_free;
   2111 	}
   2112 
   2113 	if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
   2114 	    (!remotefwd && fwd->listen_port == 0))
   2115 		goto fail_free;
   2116 	if (fwd->connect_host != NULL &&
   2117 	    strlen(fwd->connect_host) >= NI_MAXHOST)
   2118 		goto fail_free;
   2119 	/* XXX - if connecting to a remote socket, max sun len may not match this host */
   2120 	if (fwd->connect_path != NULL &&
   2121 	    strlen(fwd->connect_path) >= PATH_MAX_SUN)
   2122 		goto fail_free;
   2123 	if (fwd->listen_host != NULL &&
   2124 	    strlen(fwd->listen_host) >= NI_MAXHOST)
   2125 		goto fail_free;
   2126 	if (fwd->listen_path != NULL &&
   2127 	    strlen(fwd->listen_path) >= PATH_MAX_SUN)
   2128 		goto fail_free;
   2129 
   2130 	return (i);
   2131 
   2132  fail_free:
   2133 	free(fwd->connect_host);
   2134 	fwd->connect_host = NULL;
   2135 	free(fwd->connect_path);
   2136 	fwd->connect_path = NULL;
   2137 	free(fwd->listen_host);
   2138 	fwd->listen_host = NULL;
   2139 	free(fwd->listen_path);
   2140 	fwd->listen_path = NULL;
   2141 	return (0);
   2142 }
   2143