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