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