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