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