readconf.c revision 249016
1/* $OpenBSD: readconf.c,v 1.195 2013/02/17 23:16:57 dtucker Exp $ */
2/* $FreeBSD: head/crypto/openssh/readconf.c 249016 2013-04-02 11:44:55Z des $ */
3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 *                    All rights reserved
7 * Functions for reading the configuration files.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose.  Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 */
15
16#include "includes.h"
17__RCSID("$FreeBSD: head/crypto/openssh/readconf.c 249016 2013-04-02 11:44:55Z des $");
18
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sys/socket.h>
22#include <sys/sysctl.h>
23
24#include <netinet/in.h>
25#include <netinet/in_systm.h>
26#include <netinet/ip.h>
27
28#include <ctype.h>
29#include <errno.h>
30#include <netdb.h>
31#include <signal.h>
32#include <stdarg.h>
33#include <stdio.h>
34#include <string.h>
35#include <unistd.h>
36
37#include "xmalloc.h"
38#include "ssh.h"
39#include "compat.h"
40#include "cipher.h"
41#include "pathnames.h"
42#include "log.h"
43#include "key.h"
44#include "readconf.h"
45#include "match.h"
46#include "misc.h"
47#include "buffer.h"
48#include "kex.h"
49#include "mac.h"
50#include "version.h"
51
52/* Format of the configuration file:
53
54   # Configuration data is parsed as follows:
55   #  1. command line options
56   #  2. user-specific file
57   #  3. system-wide file
58   # Any configuration value is only changed the first time it is set.
59   # Thus, host-specific definitions should be at the beginning of the
60   # configuration file, and defaults at the end.
61
62   # Host-specific declarations.  These may override anything above.  A single
63   # host may match multiple declarations; these are processed in the order
64   # that they are given in.
65
66   Host *.ngs.fi ngs.fi
67     User foo
68
69   Host fake.com
70     HostName another.host.name.real.org
71     User blaah
72     Port 34289
73     ForwardX11 no
74     ForwardAgent no
75
76   Host books.com
77     RemoteForward 9999 shadows.cs.hut.fi:9999
78     Cipher 3des
79
80   Host fascist.blob.com
81     Port 23123
82     User tylonen
83     PasswordAuthentication no
84
85   Host puukko.hut.fi
86     User t35124p
87     ProxyCommand ssh-proxy %h %p
88
89   Host *.fr
90     PublicKeyAuthentication no
91
92   Host *.su
93     Cipher none
94     PasswordAuthentication no
95
96   Host vpn.fake.com
97     Tunnel yes
98     TunnelDevice 3
99
100   # Defaults for various options
101   Host *
102     ForwardAgent no
103     ForwardX11 no
104     PasswordAuthentication yes
105     RSAAuthentication yes
106     RhostsRSAAuthentication yes
107     StrictHostKeyChecking yes
108     TcpKeepAlive no
109     IdentityFile ~/.ssh/identity
110     Port 22
111     EscapeChar ~
112
113*/
114
115/* Keyword tokens. */
116
117typedef enum {
118	oBadOption,
119	oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
120	oGatewayPorts, oExitOnForwardFailure,
121	oPasswordAuthentication, oRSAAuthentication,
122	oChallengeResponseAuthentication, oXAuthLocation,
123	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
124	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
125	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
126	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
127	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
128	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
129	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
130	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
131	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
132	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
133	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
134	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
135	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
136	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
137	oSendEnv, oControlPath, oControlMaster, oControlPersist,
138	oHashKnownHosts,
139	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
140	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
141	oKexAlgorithms, oIPQoS, oRequestTTY,
142	oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf,
143#ifdef NONE_CIPHER_ENABLED
144	oNoneEnabled, oNoneSwitch,
145#endif
146	oVersionAddendum,
147	oDeprecated, oUnsupported
148} OpCodes;
149
150/* Textual representations of the tokens. */
151
152static struct {
153	const char *name;
154	OpCodes opcode;
155} keywords[] = {
156	{ "forwardagent", oForwardAgent },
157	{ "forwardx11", oForwardX11 },
158	{ "forwardx11trusted", oForwardX11Trusted },
159	{ "forwardx11timeout", oForwardX11Timeout },
160	{ "exitonforwardfailure", oExitOnForwardFailure },
161	{ "xauthlocation", oXAuthLocation },
162	{ "gatewayports", oGatewayPorts },
163	{ "useprivilegedport", oUsePrivilegedPort },
164	{ "rhostsauthentication", oDeprecated },
165	{ "passwordauthentication", oPasswordAuthentication },
166	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
167	{ "kbdinteractivedevices", oKbdInteractiveDevices },
168	{ "rsaauthentication", oRSAAuthentication },
169	{ "pubkeyauthentication", oPubkeyAuthentication },
170	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
171	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
172	{ "hostbasedauthentication", oHostbasedAuthentication },
173	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
174	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
175	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
176	{ "kerberosauthentication", oUnsupported },
177	{ "kerberostgtpassing", oUnsupported },
178	{ "afstokenpassing", oUnsupported },
179#if defined(GSSAPI)
180	{ "gssapiauthentication", oGssAuthentication },
181	{ "gssapidelegatecredentials", oGssDelegateCreds },
182#else
183	{ "gssapiauthentication", oUnsupported },
184	{ "gssapidelegatecredentials", oUnsupported },
185#endif
186	{ "fallbacktorsh", oDeprecated },
187	{ "usersh", oDeprecated },
188	{ "identityfile", oIdentityFile },
189	{ "identityfile2", oIdentityFile },			/* obsolete */
190	{ "identitiesonly", oIdentitiesOnly },
191	{ "hostname", oHostName },
192	{ "hostkeyalias", oHostKeyAlias },
193	{ "proxycommand", oProxyCommand },
194	{ "port", oPort },
195	{ "cipher", oCipher },
196	{ "ciphers", oCiphers },
197	{ "macs", oMacs },
198	{ "protocol", oProtocol },
199	{ "remoteforward", oRemoteForward },
200	{ "localforward", oLocalForward },
201	{ "user", oUser },
202	{ "host", oHost },
203	{ "escapechar", oEscapeChar },
204	{ "globalknownhostsfile", oGlobalKnownHostsFile },
205	{ "globalknownhostsfile2", oDeprecated },
206	{ "userknownhostsfile", oUserKnownHostsFile },
207	{ "userknownhostsfile2", oDeprecated },
208	{ "connectionattempts", oConnectionAttempts },
209	{ "batchmode", oBatchMode },
210	{ "checkhostip", oCheckHostIP },
211	{ "stricthostkeychecking", oStrictHostKeyChecking },
212	{ "compression", oCompression },
213	{ "compressionlevel", oCompressionLevel },
214	{ "tcpkeepalive", oTCPKeepAlive },
215	{ "keepalive", oTCPKeepAlive },				/* obsolete */
216	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
217	{ "loglevel", oLogLevel },
218	{ "dynamicforward", oDynamicForward },
219	{ "preferredauthentications", oPreferredAuthentications },
220	{ "hostkeyalgorithms", oHostKeyAlgorithms },
221	{ "bindaddress", oBindAddress },
222#ifdef ENABLE_PKCS11
223	{ "smartcarddevice", oPKCS11Provider },
224	{ "pkcs11provider", oPKCS11Provider },
225#else
226	{ "smartcarddevice", oUnsupported },
227	{ "pkcs11provider", oUnsupported },
228#endif
229	{ "clearallforwardings", oClearAllForwardings },
230	{ "enablesshkeysign", oEnableSSHKeysign },
231	{ "verifyhostkeydns", oVerifyHostKeyDNS },
232	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
233	{ "rekeylimit", oRekeyLimit },
234	{ "connecttimeout", oConnectTimeout },
235	{ "addressfamily", oAddressFamily },
236	{ "serveraliveinterval", oServerAliveInterval },
237	{ "serveralivecountmax", oServerAliveCountMax },
238	{ "sendenv", oSendEnv },
239	{ "controlpath", oControlPath },
240	{ "controlmaster", oControlMaster },
241	{ "controlpersist", oControlPersist },
242	{ "hashknownhosts", oHashKnownHosts },
243	{ "tunnel", oTunnel },
244	{ "tunneldevice", oTunnelDevice },
245	{ "localcommand", oLocalCommand },
246	{ "permitlocalcommand", oPermitLocalCommand },
247	{ "visualhostkey", oVisualHostKey },
248	{ "useroaming", oUseRoaming },
249#ifdef JPAKE
250	{ "zeroknowledgepasswordauthentication",
251	    oZeroKnowledgePasswordAuthentication },
252#else
253	{ "zeroknowledgepasswordauthentication", oUnsupported },
254#endif
255	{ "kexalgorithms", oKexAlgorithms },
256	{ "ipqos", oIPQoS },
257	{ "requesttty", oRequestTTY },
258	{ "hpndisabled", oHPNDisabled },
259	{ "hpnbuffersize", oHPNBufferSize },
260	{ "tcprcvbufpoll", oTcpRcvBufPoll },
261	{ "tcprcvbuf", oTcpRcvBuf },
262#ifdef	NONE_CIPHER_ENABLED
263	{ "noneenabled", oNoneEnabled },
264	{ "noneswitch", oNoneSwitch },
265#endif
266	{ "versionaddendum", oVersionAddendum },
267
268	{ NULL, oBadOption }
269};
270
271/*
272 * Adds a local TCP/IP port forward to options.  Never returns if there is an
273 * error.
274 */
275
276void
277add_local_forward(Options *options, const Forward *newfwd)
278{
279	Forward *fwd;
280#ifndef NO_IPPORT_RESERVED_CONCEPT
281	extern uid_t original_real_uid;
282	int ipport_reserved;
283#ifdef __FreeBSD__
284	size_t len_ipport_reserved = sizeof(ipport_reserved);
285
286	if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
287	    &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
288		ipport_reserved = IPPORT_RESERVED;
289	else
290		ipport_reserved++;
291#else
292	ipport_reserved = IPPORT_RESERVED;
293#endif
294	if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
295		fatal("Privileged ports can only be forwarded by root.");
296#endif
297	options->local_forwards = xrealloc(options->local_forwards,
298	    options->num_local_forwards + 1,
299	    sizeof(*options->local_forwards));
300	fwd = &options->local_forwards[options->num_local_forwards++];
301
302	fwd->listen_host = newfwd->listen_host;
303	fwd->listen_port = newfwd->listen_port;
304	fwd->connect_host = newfwd->connect_host;
305	fwd->connect_port = newfwd->connect_port;
306}
307
308/*
309 * Adds a remote TCP/IP port forward to options.  Never returns if there is
310 * an error.
311 */
312
313void
314add_remote_forward(Options *options, const Forward *newfwd)
315{
316	Forward *fwd;
317
318	options->remote_forwards = xrealloc(options->remote_forwards,
319	    options->num_remote_forwards + 1,
320	    sizeof(*options->remote_forwards));
321	fwd = &options->remote_forwards[options->num_remote_forwards++];
322
323	fwd->listen_host = newfwd->listen_host;
324	fwd->listen_port = newfwd->listen_port;
325	fwd->connect_host = newfwd->connect_host;
326	fwd->connect_port = newfwd->connect_port;
327	fwd->handle = newfwd->handle;
328	fwd->allocated_port = 0;
329}
330
331static void
332clear_forwardings(Options *options)
333{
334	int i;
335
336	for (i = 0; i < options->num_local_forwards; i++) {
337		if (options->local_forwards[i].listen_host != NULL)
338			xfree(options->local_forwards[i].listen_host);
339		xfree(options->local_forwards[i].connect_host);
340	}
341	if (options->num_local_forwards > 0) {
342		xfree(options->local_forwards);
343		options->local_forwards = NULL;
344	}
345	options->num_local_forwards = 0;
346	for (i = 0; i < options->num_remote_forwards; i++) {
347		if (options->remote_forwards[i].listen_host != NULL)
348			xfree(options->remote_forwards[i].listen_host);
349		xfree(options->remote_forwards[i].connect_host);
350	}
351	if (options->num_remote_forwards > 0) {
352		xfree(options->remote_forwards);
353		options->remote_forwards = NULL;
354	}
355	options->num_remote_forwards = 0;
356	options->tun_open = SSH_TUNMODE_NO;
357}
358
359void
360add_identity_file(Options *options, const char *dir, const char *filename,
361    int userprovided)
362{
363	char *path;
364
365	if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
366		fatal("Too many identity files specified (max %d)",
367		    SSH_MAX_IDENTITY_FILES);
368
369	if (dir == NULL) /* no dir, filename is absolute */
370		path = xstrdup(filename);
371	else
372		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
373
374	options->identity_file_userprovided[options->num_identity_files] =
375	    userprovided;
376	options->identity_files[options->num_identity_files++] = path;
377}
378
379/*
380 * Returns the number of the token pointed to by cp or oBadOption.
381 */
382
383static OpCodes
384parse_token(const char *cp, const char *filename, int linenum)
385{
386	u_int i;
387
388	for (i = 0; keywords[i].name; i++)
389		if (strcasecmp(cp, keywords[i].name) == 0)
390			return keywords[i].opcode;
391
392	error("%s: line %d: Bad configuration option: %s",
393	    filename, linenum, cp);
394	return oBadOption;
395}
396
397/*
398 * Processes a single option line as used in the configuration files. This
399 * only sets those values that have not already been set.
400 */
401#define WHITESPACE " \t\r\n"
402
403int
404process_config_line(Options *options, const char *host,
405		    char *line, const char *filename, int linenum,
406		    int *activep)
407{
408	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
409	char **cpptr, fwdarg[256];
410	u_int *uintptr, max_entries = 0;
411	int negated, opcode, *intptr, value, value2, scale;
412	LogLevel *log_level_ptr;
413	long long orig, val64;
414	size_t len;
415	Forward fwd;
416
417	/* Strip trailing whitespace */
418	for (len = strlen(line) - 1; len > 0; len--) {
419		if (strchr(WHITESPACE, line[len]) == NULL)
420			break;
421		line[len] = '\0';
422	}
423
424	s = line;
425	/* Get the keyword. (Each line is supposed to begin with a keyword). */
426	if ((keyword = strdelim(&s)) == NULL)
427		return 0;
428	/* Ignore leading whitespace. */
429	if (*keyword == '\0')
430		keyword = strdelim(&s);
431	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
432		return 0;
433
434	opcode = parse_token(keyword, filename, linenum);
435
436	switch (opcode) {
437	case oBadOption:
438		/* don't panic, but count bad options */
439		return -1;
440		/* NOTREACHED */
441	case oConnectTimeout:
442		intptr = &options->connection_timeout;
443parse_time:
444		arg = strdelim(&s);
445		if (!arg || *arg == '\0')
446			fatal("%s line %d: missing time value.",
447			    filename, linenum);
448		if ((value = convtime(arg)) == -1)
449			fatal("%s line %d: invalid time value.",
450			    filename, linenum);
451		if (*activep && *intptr == -1)
452			*intptr = value;
453		break;
454
455	case oForwardAgent:
456		intptr = &options->forward_agent;
457parse_flag:
458		arg = strdelim(&s);
459		if (!arg || *arg == '\0')
460			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
461		value = 0;	/* To avoid compiler warning... */
462		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
463			value = 1;
464		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
465			value = 0;
466		else
467			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
468		if (*activep && *intptr == -1)
469			*intptr = value;
470		break;
471
472	case oForwardX11:
473		intptr = &options->forward_x11;
474		goto parse_flag;
475
476	case oForwardX11Trusted:
477		intptr = &options->forward_x11_trusted;
478		goto parse_flag;
479
480	case oForwardX11Timeout:
481		intptr = &options->forward_x11_timeout;
482		goto parse_time;
483
484	case oGatewayPorts:
485		intptr = &options->gateway_ports;
486		goto parse_flag;
487
488	case oExitOnForwardFailure:
489		intptr = &options->exit_on_forward_failure;
490		goto parse_flag;
491
492	case oUsePrivilegedPort:
493		intptr = &options->use_privileged_port;
494		goto parse_flag;
495
496	case oPasswordAuthentication:
497		intptr = &options->password_authentication;
498		goto parse_flag;
499
500	case oZeroKnowledgePasswordAuthentication:
501		intptr = &options->zero_knowledge_password_authentication;
502		goto parse_flag;
503
504	case oKbdInteractiveAuthentication:
505		intptr = &options->kbd_interactive_authentication;
506		goto parse_flag;
507
508	case oKbdInteractiveDevices:
509		charptr = &options->kbd_interactive_devices;
510		goto parse_string;
511
512	case oPubkeyAuthentication:
513		intptr = &options->pubkey_authentication;
514		goto parse_flag;
515
516	case oRSAAuthentication:
517		intptr = &options->rsa_authentication;
518		goto parse_flag;
519
520	case oRhostsRSAAuthentication:
521		intptr = &options->rhosts_rsa_authentication;
522		goto parse_flag;
523
524	case oHostbasedAuthentication:
525		intptr = &options->hostbased_authentication;
526		goto parse_flag;
527
528	case oChallengeResponseAuthentication:
529		intptr = &options->challenge_response_authentication;
530		goto parse_flag;
531
532	case oGssAuthentication:
533		intptr = &options->gss_authentication;
534		goto parse_flag;
535
536	case oGssDelegateCreds:
537		intptr = &options->gss_deleg_creds;
538		goto parse_flag;
539
540	case oBatchMode:
541		intptr = &options->batch_mode;
542		goto parse_flag;
543
544	case oCheckHostIP:
545		intptr = &options->check_host_ip;
546		goto parse_flag;
547
548	case oVerifyHostKeyDNS:
549		intptr = &options->verify_host_key_dns;
550		goto parse_yesnoask;
551
552	case oStrictHostKeyChecking:
553		intptr = &options->strict_host_key_checking;
554parse_yesnoask:
555		arg = strdelim(&s);
556		if (!arg || *arg == '\0')
557			fatal("%.200s line %d: Missing yes/no/ask argument.",
558			    filename, linenum);
559		value = 0;	/* To avoid compiler warning... */
560		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
561			value = 1;
562		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
563			value = 0;
564		else if (strcmp(arg, "ask") == 0)
565			value = 2;
566		else
567			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
568		if (*activep && *intptr == -1)
569			*intptr = value;
570		break;
571
572	case oCompression:
573		intptr = &options->compression;
574		goto parse_flag;
575
576	case oTCPKeepAlive:
577		intptr = &options->tcp_keep_alive;
578		goto parse_flag;
579
580	case oNoHostAuthenticationForLocalhost:
581		intptr = &options->no_host_authentication_for_localhost;
582		goto parse_flag;
583
584	case oNumberOfPasswordPrompts:
585		intptr = &options->number_of_password_prompts;
586		goto parse_int;
587
588	case oCompressionLevel:
589		intptr = &options->compression_level;
590		goto parse_int;
591
592	case oRekeyLimit:
593		arg = strdelim(&s);
594		if (!arg || *arg == '\0')
595			fatal("%.200s line %d: Missing argument.", filename, linenum);
596		if (arg[0] < '0' || arg[0] > '9')
597			fatal("%.200s line %d: Bad number.", filename, linenum);
598		orig = val64 = strtoll(arg, &endofnumber, 10);
599		if (arg == endofnumber)
600			fatal("%.200s line %d: Bad number.", filename, linenum);
601		switch (toupper(*endofnumber)) {
602		case '\0':
603			scale = 1;
604			break;
605		case 'K':
606			scale = 1<<10;
607			break;
608		case 'M':
609			scale = 1<<20;
610			break;
611		case 'G':
612			scale = 1<<30;
613			break;
614		default:
615			fatal("%.200s line %d: Invalid RekeyLimit suffix",
616			    filename, linenum);
617		}
618		val64 *= scale;
619		/* detect integer wrap and too-large limits */
620		if ((val64 / scale) != orig || val64 > UINT_MAX)
621			fatal("%.200s line %d: RekeyLimit too large",
622			    filename, linenum);
623		if (val64 < 16)
624			fatal("%.200s line %d: RekeyLimit too small",
625			    filename, linenum);
626		if (*activep && options->rekey_limit == -1)
627			options->rekey_limit = (u_int32_t)val64;
628		break;
629
630	case oIdentityFile:
631		arg = strdelim(&s);
632		if (!arg || *arg == '\0')
633			fatal("%.200s line %d: Missing argument.", filename, linenum);
634		if (*activep) {
635			intptr = &options->num_identity_files;
636			if (*intptr >= SSH_MAX_IDENTITY_FILES)
637				fatal("%.200s line %d: Too many identity files specified (max %d).",
638				    filename, linenum, SSH_MAX_IDENTITY_FILES);
639			add_identity_file(options, NULL, arg, 1);
640		}
641		break;
642
643	case oXAuthLocation:
644		charptr=&options->xauth_location;
645		goto parse_string;
646
647	case oUser:
648		charptr = &options->user;
649parse_string:
650		arg = strdelim(&s);
651		if (!arg || *arg == '\0')
652			fatal("%.200s line %d: Missing argument.",
653			    filename, linenum);
654		if (*activep && *charptr == NULL)
655			*charptr = xstrdup(arg);
656		break;
657
658	case oGlobalKnownHostsFile:
659		cpptr = (char **)&options->system_hostfiles;
660		uintptr = &options->num_system_hostfiles;
661		max_entries = SSH_MAX_HOSTS_FILES;
662parse_char_array:
663		if (*activep && *uintptr == 0) {
664			while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
665				if ((*uintptr) >= max_entries)
666					fatal("%s line %d: "
667					    "too many authorized keys files.",
668					    filename, linenum);
669				cpptr[(*uintptr)++] = xstrdup(arg);
670			}
671		}
672		return 0;
673
674	case oUserKnownHostsFile:
675		cpptr = (char **)&options->user_hostfiles;
676		uintptr = &options->num_user_hostfiles;
677		max_entries = SSH_MAX_HOSTS_FILES;
678		goto parse_char_array;
679
680	case oHostName:
681		charptr = &options->hostname;
682		goto parse_string;
683
684	case oHostKeyAlias:
685		charptr = &options->host_key_alias;
686		goto parse_string;
687
688	case oPreferredAuthentications:
689		charptr = &options->preferred_authentications;
690		goto parse_string;
691
692	case oBindAddress:
693		charptr = &options->bind_address;
694		goto parse_string;
695
696	case oPKCS11Provider:
697		charptr = &options->pkcs11_provider;
698		goto parse_string;
699
700	case oProxyCommand:
701		charptr = &options->proxy_command;
702parse_command:
703		if (s == NULL)
704			fatal("%.200s line %d: Missing argument.", filename, linenum);
705		len = strspn(s, WHITESPACE "=");
706		if (*activep && *charptr == NULL)
707			*charptr = xstrdup(s + len);
708		return 0;
709
710	case oPort:
711		intptr = &options->port;
712parse_int:
713		arg = strdelim(&s);
714		if (!arg || *arg == '\0')
715			fatal("%.200s line %d: Missing argument.", filename, linenum);
716		if (arg[0] < '0' || arg[0] > '9')
717			fatal("%.200s line %d: Bad number.", filename, linenum);
718
719		/* Octal, decimal, or hex format? */
720		value = strtol(arg, &endofnumber, 0);
721		if (arg == endofnumber)
722			fatal("%.200s line %d: Bad number.", filename, linenum);
723		if (*activep && *intptr == -1)
724			*intptr = value;
725		break;
726
727	case oConnectionAttempts:
728		intptr = &options->connection_attempts;
729		goto parse_int;
730
731	case oCipher:
732		intptr = &options->cipher;
733		arg = strdelim(&s);
734		if (!arg || *arg == '\0')
735			fatal("%.200s line %d: Missing argument.", filename, linenum);
736		value = cipher_number(arg);
737		if (value == -1)
738			fatal("%.200s line %d: Bad cipher '%s'.",
739			    filename, linenum, arg ? arg : "<NONE>");
740		if (*activep && *intptr == -1)
741			*intptr = value;
742		break;
743
744	case oCiphers:
745		arg = strdelim(&s);
746		if (!arg || *arg == '\0')
747			fatal("%.200s line %d: Missing argument.", filename, linenum);
748		if (!ciphers_valid(arg))
749			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
750			    filename, linenum, arg ? arg : "<NONE>");
751		if (*activep && options->ciphers == NULL)
752			options->ciphers = xstrdup(arg);
753		break;
754
755	case oMacs:
756		arg = strdelim(&s);
757		if (!arg || *arg == '\0')
758			fatal("%.200s line %d: Missing argument.", filename, linenum);
759		if (!mac_valid(arg))
760			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
761			    filename, linenum, arg ? arg : "<NONE>");
762		if (*activep && options->macs == NULL)
763			options->macs = xstrdup(arg);
764		break;
765
766	case oKexAlgorithms:
767		arg = strdelim(&s);
768		if (!arg || *arg == '\0')
769			fatal("%.200s line %d: Missing argument.",
770			    filename, linenum);
771		if (!kex_names_valid(arg))
772			fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
773			    filename, linenum, arg ? arg : "<NONE>");
774		if (*activep && options->kex_algorithms == NULL)
775			options->kex_algorithms = xstrdup(arg);
776		break;
777
778	case oHostKeyAlgorithms:
779		arg = strdelim(&s);
780		if (!arg || *arg == '\0')
781			fatal("%.200s line %d: Missing argument.", filename, linenum);
782		if (!key_names_valid2(arg))
783			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
784			    filename, linenum, arg ? arg : "<NONE>");
785		if (*activep && options->hostkeyalgorithms == NULL)
786			options->hostkeyalgorithms = xstrdup(arg);
787		break;
788
789	case oProtocol:
790		intptr = &options->protocol;
791		arg = strdelim(&s);
792		if (!arg || *arg == '\0')
793			fatal("%.200s line %d: Missing argument.", filename, linenum);
794		value = proto_spec(arg);
795		if (value == SSH_PROTO_UNKNOWN)
796			fatal("%.200s line %d: Bad protocol spec '%s'.",
797			    filename, linenum, arg ? arg : "<NONE>");
798		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
799			*intptr = value;
800		break;
801
802	case oLogLevel:
803		log_level_ptr = &options->log_level;
804		arg = strdelim(&s);
805		value = log_level_number(arg);
806		if (value == SYSLOG_LEVEL_NOT_SET)
807			fatal("%.200s line %d: unsupported log level '%s'",
808			    filename, linenum, arg ? arg : "<NONE>");
809		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
810			*log_level_ptr = (LogLevel) value;
811		break;
812
813	case oLocalForward:
814	case oRemoteForward:
815	case oDynamicForward:
816		arg = strdelim(&s);
817		if (arg == NULL || *arg == '\0')
818			fatal("%.200s line %d: Missing port argument.",
819			    filename, linenum);
820
821		if (opcode == oLocalForward ||
822		    opcode == oRemoteForward) {
823			arg2 = strdelim(&s);
824			if (arg2 == NULL || *arg2 == '\0')
825				fatal("%.200s line %d: Missing target argument.",
826				    filename, linenum);
827
828			/* construct a string for parse_forward */
829			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
830		} else if (opcode == oDynamicForward) {
831			strlcpy(fwdarg, arg, sizeof(fwdarg));
832		}
833
834		if (parse_forward(&fwd, fwdarg,
835		    opcode == oDynamicForward ? 1 : 0,
836		    opcode == oRemoteForward ? 1 : 0) == 0)
837			fatal("%.200s line %d: Bad forwarding specification.",
838			    filename, linenum);
839
840		if (*activep) {
841			if (opcode == oLocalForward ||
842			    opcode == oDynamicForward)
843				add_local_forward(options, &fwd);
844			else if (opcode == oRemoteForward)
845				add_remote_forward(options, &fwd);
846		}
847		break;
848
849	case oClearAllForwardings:
850		intptr = &options->clear_forwardings;
851		goto parse_flag;
852
853	case oHost:
854		*activep = 0;
855		arg2 = NULL;
856		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
857			negated = *arg == '!';
858			if (negated)
859				arg++;
860			if (match_pattern(host, arg)) {
861				if (negated) {
862					debug("%.200s line %d: Skipping Host "
863					    "block because of negated match "
864					    "for %.100s", filename, linenum,
865					    arg);
866					*activep = 0;
867					break;
868				}
869				if (!*activep)
870					arg2 = arg; /* logged below */
871				*activep = 1;
872			}
873		}
874		if (*activep)
875			debug("%.200s line %d: Applying options for %.100s",
876			    filename, linenum, arg2);
877		/* Avoid garbage check below, as strdelim is done. */
878		return 0;
879
880	case oEscapeChar:
881		intptr = &options->escape_char;
882		arg = strdelim(&s);
883		if (!arg || *arg == '\0')
884			fatal("%.200s line %d: Missing argument.", filename, linenum);
885		if (arg[0] == '^' && arg[2] == 0 &&
886		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
887			value = (u_char) arg[1] & 31;
888		else if (strlen(arg) == 1)
889			value = (u_char) arg[0];
890		else if (strcmp(arg, "none") == 0)
891			value = SSH_ESCAPECHAR_NONE;
892		else {
893			fatal("%.200s line %d: Bad escape character.",
894			    filename, linenum);
895			/* NOTREACHED */
896			value = 0;	/* Avoid compiler warning. */
897		}
898		if (*activep && *intptr == -1)
899			*intptr = value;
900		break;
901
902	case oAddressFamily:
903		arg = strdelim(&s);
904		if (!arg || *arg == '\0')
905			fatal("%s line %d: missing address family.",
906			    filename, linenum);
907		intptr = &options->address_family;
908		if (strcasecmp(arg, "inet") == 0)
909			value = AF_INET;
910		else if (strcasecmp(arg, "inet6") == 0)
911			value = AF_INET6;
912		else if (strcasecmp(arg, "any") == 0)
913			value = AF_UNSPEC;
914		else
915			fatal("Unsupported AddressFamily \"%s\"", arg);
916		if (*activep && *intptr == -1)
917			*intptr = value;
918		break;
919
920	case oEnableSSHKeysign:
921		intptr = &options->enable_ssh_keysign;
922		goto parse_flag;
923
924	case oIdentitiesOnly:
925		intptr = &options->identities_only;
926		goto parse_flag;
927
928	case oServerAliveInterval:
929		intptr = &options->server_alive_interval;
930		goto parse_time;
931
932	case oServerAliveCountMax:
933		intptr = &options->server_alive_count_max;
934		goto parse_int;
935
936	case oSendEnv:
937		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
938			if (strchr(arg, '=') != NULL)
939				fatal("%s line %d: Invalid environment name.",
940				    filename, linenum);
941			if (!*activep)
942				continue;
943			if (options->num_send_env >= MAX_SEND_ENV)
944				fatal("%s line %d: too many send env.",
945				    filename, linenum);
946			options->send_env[options->num_send_env++] =
947			    xstrdup(arg);
948		}
949		break;
950
951	case oControlPath:
952		charptr = &options->control_path;
953		goto parse_string;
954
955	case oControlMaster:
956		intptr = &options->control_master;
957		arg = strdelim(&s);
958		if (!arg || *arg == '\0')
959			fatal("%.200s line %d: Missing ControlMaster argument.",
960			    filename, linenum);
961		value = 0;	/* To avoid compiler warning... */
962		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
963			value = SSHCTL_MASTER_YES;
964		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
965			value = SSHCTL_MASTER_NO;
966		else if (strcmp(arg, "auto") == 0)
967			value = SSHCTL_MASTER_AUTO;
968		else if (strcmp(arg, "ask") == 0)
969			value = SSHCTL_MASTER_ASK;
970		else if (strcmp(arg, "autoask") == 0)
971			value = SSHCTL_MASTER_AUTO_ASK;
972		else
973			fatal("%.200s line %d: Bad ControlMaster argument.",
974			    filename, linenum);
975		if (*activep && *intptr == -1)
976			*intptr = value;
977		break;
978
979	case oControlPersist:
980		/* no/false/yes/true, or a time spec */
981		intptr = &options->control_persist;
982		arg = strdelim(&s);
983		if (!arg || *arg == '\0')
984			fatal("%.200s line %d: Missing ControlPersist"
985			    " argument.", filename, linenum);
986		value = 0;
987		value2 = 0;	/* timeout */
988		if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
989			value = 0;
990		else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
991			value = 1;
992		else if ((value2 = convtime(arg)) >= 0)
993			value = 1;
994		else
995			fatal("%.200s line %d: Bad ControlPersist argument.",
996			    filename, linenum);
997		if (*activep && *intptr == -1) {
998			*intptr = value;
999			options->control_persist_timeout = value2;
1000		}
1001		break;
1002
1003	case oHashKnownHosts:
1004		intptr = &options->hash_known_hosts;
1005		goto parse_flag;
1006
1007	case oTunnel:
1008		intptr = &options->tun_open;
1009		arg = strdelim(&s);
1010		if (!arg || *arg == '\0')
1011			fatal("%s line %d: Missing yes/point-to-point/"
1012			    "ethernet/no argument.", filename, linenum);
1013		value = 0;	/* silence compiler */
1014		if (strcasecmp(arg, "ethernet") == 0)
1015			value = SSH_TUNMODE_ETHERNET;
1016		else if (strcasecmp(arg, "point-to-point") == 0)
1017			value = SSH_TUNMODE_POINTOPOINT;
1018		else if (strcasecmp(arg, "yes") == 0)
1019			value = SSH_TUNMODE_DEFAULT;
1020		else if (strcasecmp(arg, "no") == 0)
1021			value = SSH_TUNMODE_NO;
1022		else
1023			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1024			    "no argument: %s", filename, linenum, arg);
1025		if (*activep)
1026			*intptr = value;
1027		break;
1028
1029	case oTunnelDevice:
1030		arg = strdelim(&s);
1031		if (!arg || *arg == '\0')
1032			fatal("%.200s line %d: Missing argument.", filename, linenum);
1033		value = a2tun(arg, &value2);
1034		if (value == SSH_TUNID_ERR)
1035			fatal("%.200s line %d: Bad tun device.", filename, linenum);
1036		if (*activep) {
1037			options->tun_local = value;
1038			options->tun_remote = value2;
1039		}
1040		break;
1041
1042	case oLocalCommand:
1043		charptr = &options->local_command;
1044		goto parse_command;
1045
1046	case oPermitLocalCommand:
1047		intptr = &options->permit_local_command;
1048		goto parse_flag;
1049
1050	case oVisualHostKey:
1051		intptr = &options->visual_host_key;
1052		goto parse_flag;
1053
1054	case oIPQoS:
1055		arg = strdelim(&s);
1056		if ((value = parse_ipqos(arg)) == -1)
1057			fatal("%s line %d: Bad IPQoS value: %s",
1058			    filename, linenum, arg);
1059		arg = strdelim(&s);
1060		if (arg == NULL)
1061			value2 = value;
1062		else if ((value2 = parse_ipqos(arg)) == -1)
1063			fatal("%s line %d: Bad IPQoS value: %s",
1064			    filename, linenum, arg);
1065		if (*activep) {
1066			options->ip_qos_interactive = value;
1067			options->ip_qos_bulk = value2;
1068		}
1069		break;
1070
1071	case oUseRoaming:
1072		intptr = &options->use_roaming;
1073		goto parse_flag;
1074
1075	case oRequestTTY:
1076		arg = strdelim(&s);
1077		if (!arg || *arg == '\0')
1078			fatal("%s line %d: missing argument.",
1079			    filename, linenum);
1080		intptr = &options->request_tty;
1081		if (strcasecmp(arg, "yes") == 0)
1082			value = REQUEST_TTY_YES;
1083		else if (strcasecmp(arg, "no") == 0)
1084			value = REQUEST_TTY_NO;
1085		else if (strcasecmp(arg, "force") == 0)
1086			value = REQUEST_TTY_FORCE;
1087		else if (strcasecmp(arg, "auto") == 0)
1088			value = REQUEST_TTY_AUTO;
1089		else
1090			fatal("Unsupported RequestTTY \"%s\"", arg);
1091		if (*activep && *intptr == -1)
1092			*intptr = value;
1093		break;
1094
1095	case oHPNDisabled:
1096		intptr = &options->hpn_disabled;
1097		goto parse_flag;
1098
1099	case oHPNBufferSize:
1100		intptr = &options->hpn_buffer_size;
1101		goto parse_int;
1102
1103	case oTcpRcvBufPoll:
1104		intptr = &options->tcp_rcv_buf_poll;
1105		goto parse_flag;
1106
1107	case oTcpRcvBuf:
1108		intptr = &options->tcp_rcv_buf;
1109		goto parse_int;
1110
1111#ifdef	NONE_CIPHER_ENABLED
1112	case oNoneEnabled:
1113		intptr = &options->none_enabled;
1114		goto parse_flag;
1115
1116	/*
1117	 * We check to see if the command comes from the command line or not.
1118	 * If it does then enable it otherwise fail.  NONE must never be a
1119	 * default configuration.
1120	 */
1121	case oNoneSwitch:
1122		if (strcmp(filename,"command-line") == 0) {
1123			intptr = &options->none_switch;
1124			goto parse_flag;
1125		} else {
1126			debug("NoneSwitch directive found in %.200s.",
1127			    filename);
1128			error("NoneSwitch is found in %.200s.\n"
1129			    "You may only use this configuration option "
1130			    "from the command line", filename);
1131			error("Continuing...");
1132			return 0;
1133		}
1134#endif
1135
1136	case oVersionAddendum:
1137		if (s == NULL)
1138			fatal("%.200s line %d: Missing argument.", filename,
1139			    linenum);
1140		len = strspn(s, WHITESPACE);
1141		if (*activep && options->version_addendum == NULL) {
1142			if (strcasecmp(s + len, "none") == 0)
1143				options->version_addendum = xstrdup("");
1144			else if (strchr(s + len, '\r') != NULL)
1145				fatal("%.200s line %d: Invalid argument",
1146				    filename, linenum);
1147			else
1148				options->version_addendum = xstrdup(s + len);
1149		}
1150		return 0;
1151
1152	case oDeprecated:
1153		debug("%s line %d: Deprecated option \"%s\"",
1154		    filename, linenum, keyword);
1155		return 0;
1156
1157	case oUnsupported:
1158		error("%s line %d: Unsupported option \"%s\"",
1159		    filename, linenum, keyword);
1160		return 0;
1161
1162	default:
1163		fatal("process_config_line: Unimplemented opcode %d", opcode);
1164	}
1165
1166	/* Check that there is no garbage at end of line. */
1167	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1168		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1169		    filename, linenum, arg);
1170	}
1171	return 0;
1172}
1173
1174
1175/*
1176 * Reads the config file and modifies the options accordingly.  Options
1177 * should already be initialized before this call.  This never returns if
1178 * there is an error.  If the file does not exist, this returns 0.
1179 */
1180
1181int
1182read_config_file(const char *filename, const char *host, Options *options,
1183    int checkperm)
1184{
1185	FILE *f;
1186	char line[1024];
1187	int active, linenum;
1188	int bad_options = 0;
1189
1190	if ((f = fopen(filename, "r")) == NULL)
1191		return 0;
1192
1193	if (checkperm) {
1194		struct stat sb;
1195
1196		if (fstat(fileno(f), &sb) == -1)
1197			fatal("fstat %s: %s", filename, strerror(errno));
1198		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1199		    (sb.st_mode & 022) != 0))
1200			fatal("Bad owner or permissions on %s", filename);
1201	}
1202
1203	debug("Reading configuration data %.200s", filename);
1204
1205	/*
1206	 * Mark that we are now processing the options.  This flag is turned
1207	 * on/off by Host specifications.
1208	 */
1209	active = 1;
1210	linenum = 0;
1211	while (fgets(line, sizeof(line), f)) {
1212		/* Update line number counter. */
1213		linenum++;
1214		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
1215			bad_options++;
1216	}
1217	fclose(f);
1218	if (bad_options > 0)
1219		fatal("%s: terminating, %d bad configuration options",
1220		    filename, bad_options);
1221	return 1;
1222}
1223
1224/*
1225 * Initializes options to special values that indicate that they have not yet
1226 * been set.  Read_config_file will only set options with this value. Options
1227 * are processed in the following order: command line, user config file,
1228 * system config file.  Last, fill_default_options is called.
1229 */
1230
1231void
1232initialize_options(Options * options)
1233{
1234	memset(options, 'X', sizeof(*options));
1235	options->forward_agent = -1;
1236	options->forward_x11 = -1;
1237	options->forward_x11_trusted = -1;
1238	options->forward_x11_timeout = -1;
1239	options->exit_on_forward_failure = -1;
1240	options->xauth_location = NULL;
1241	options->gateway_ports = -1;
1242	options->use_privileged_port = -1;
1243	options->rsa_authentication = -1;
1244	options->pubkey_authentication = -1;
1245	options->challenge_response_authentication = -1;
1246	options->gss_authentication = -1;
1247	options->gss_deleg_creds = -1;
1248	options->password_authentication = -1;
1249	options->kbd_interactive_authentication = -1;
1250	options->kbd_interactive_devices = NULL;
1251	options->rhosts_rsa_authentication = -1;
1252	options->hostbased_authentication = -1;
1253	options->batch_mode = -1;
1254	options->check_host_ip = -1;
1255	options->strict_host_key_checking = -1;
1256	options->compression = -1;
1257	options->tcp_keep_alive = -1;
1258	options->compression_level = -1;
1259	options->port = -1;
1260	options->address_family = -1;
1261	options->connection_attempts = -1;
1262	options->connection_timeout = -1;
1263	options->number_of_password_prompts = -1;
1264	options->cipher = -1;
1265	options->ciphers = NULL;
1266	options->macs = NULL;
1267	options->kex_algorithms = NULL;
1268	options->hostkeyalgorithms = NULL;
1269	options->protocol = SSH_PROTO_UNKNOWN;
1270	options->num_identity_files = 0;
1271	options->hostname = NULL;
1272	options->host_key_alias = NULL;
1273	options->proxy_command = NULL;
1274	options->user = NULL;
1275	options->escape_char = -1;
1276	options->num_system_hostfiles = 0;
1277	options->num_user_hostfiles = 0;
1278	options->local_forwards = NULL;
1279	options->num_local_forwards = 0;
1280	options->remote_forwards = NULL;
1281	options->num_remote_forwards = 0;
1282	options->clear_forwardings = -1;
1283	options->log_level = SYSLOG_LEVEL_NOT_SET;
1284	options->preferred_authentications = NULL;
1285	options->bind_address = NULL;
1286	options->pkcs11_provider = NULL;
1287	options->enable_ssh_keysign = - 1;
1288	options->no_host_authentication_for_localhost = - 1;
1289	options->identities_only = - 1;
1290	options->rekey_limit = - 1;
1291	options->verify_host_key_dns = -1;
1292	options->server_alive_interval = -1;
1293	options->server_alive_count_max = -1;
1294	options->num_send_env = 0;
1295	options->control_path = NULL;
1296	options->control_master = -1;
1297	options->control_persist = -1;
1298	options->control_persist_timeout = 0;
1299	options->hash_known_hosts = -1;
1300	options->tun_open = -1;
1301	options->tun_local = -1;
1302	options->tun_remote = -1;
1303	options->local_command = NULL;
1304	options->permit_local_command = -1;
1305	options->use_roaming = -1;
1306	options->visual_host_key = -1;
1307	options->zero_knowledge_password_authentication = -1;
1308	options->ip_qos_interactive = -1;
1309	options->ip_qos_bulk = -1;
1310	options->request_tty = -1;
1311	options->version_addendum = NULL;
1312	options->hpn_disabled = -1;
1313	options->hpn_buffer_size = -1;
1314	options->tcp_rcv_buf_poll = -1;
1315	options->tcp_rcv_buf = -1;
1316#ifdef NONE_CIPHER_ENABLED
1317	options->none_enabled = -1;
1318	options->none_switch = -1;
1319#endif
1320}
1321
1322/*
1323 * Called after processing other sources of option data, this fills those
1324 * options for which no value has been specified with their default values.
1325 */
1326
1327void
1328fill_default_options(Options * options)
1329{
1330	int len;
1331
1332	if (options->forward_agent == -1)
1333		options->forward_agent = 0;
1334	if (options->forward_x11 == -1)
1335		options->forward_x11 = 0;
1336	if (options->forward_x11_trusted == -1)
1337		options->forward_x11_trusted = 0;
1338	if (options->forward_x11_timeout == -1)
1339		options->forward_x11_timeout = 1200;
1340	if (options->exit_on_forward_failure == -1)
1341		options->exit_on_forward_failure = 0;
1342	if (options->xauth_location == NULL)
1343		options->xauth_location = _PATH_XAUTH;
1344	if (options->gateway_ports == -1)
1345		options->gateway_ports = 0;
1346	if (options->use_privileged_port == -1)
1347		options->use_privileged_port = 0;
1348	if (options->rsa_authentication == -1)
1349		options->rsa_authentication = 1;
1350	if (options->pubkey_authentication == -1)
1351		options->pubkey_authentication = 1;
1352	if (options->challenge_response_authentication == -1)
1353		options->challenge_response_authentication = 1;
1354	if (options->gss_authentication == -1)
1355		options->gss_authentication = 0;
1356	if (options->gss_deleg_creds == -1)
1357		options->gss_deleg_creds = 0;
1358	if (options->password_authentication == -1)
1359		options->password_authentication = 1;
1360	if (options->kbd_interactive_authentication == -1)
1361		options->kbd_interactive_authentication = 1;
1362	if (options->rhosts_rsa_authentication == -1)
1363		options->rhosts_rsa_authentication = 0;
1364	if (options->hostbased_authentication == -1)
1365		options->hostbased_authentication = 0;
1366	if (options->batch_mode == -1)
1367		options->batch_mode = 0;
1368	if (options->check_host_ip == -1)
1369		options->check_host_ip = 0;
1370	if (options->strict_host_key_checking == -1)
1371		options->strict_host_key_checking = 2;	/* 2 is default */
1372	if (options->compression == -1)
1373		options->compression = 0;
1374	if (options->tcp_keep_alive == -1)
1375		options->tcp_keep_alive = 1;
1376	if (options->compression_level == -1)
1377		options->compression_level = 6;
1378	if (options->port == -1)
1379		options->port = 0;	/* Filled in ssh_connect. */
1380	if (options->address_family == -1)
1381		options->address_family = AF_UNSPEC;
1382	if (options->connection_attempts == -1)
1383		options->connection_attempts = 1;
1384	if (options->number_of_password_prompts == -1)
1385		options->number_of_password_prompts = 3;
1386	/* Selected in ssh_login(). */
1387	if (options->cipher == -1)
1388		options->cipher = SSH_CIPHER_NOT_SET;
1389	/* options->ciphers, default set in myproposals.h */
1390	/* options->macs, default set in myproposals.h */
1391	/* options->kex_algorithms, default set in myproposals.h */
1392	/* options->hostkeyalgorithms, default set in myproposals.h */
1393	if (options->protocol == SSH_PROTO_UNKNOWN)
1394		options->protocol = SSH_PROTO_2;
1395	if (options->num_identity_files == 0) {
1396		if (options->protocol & SSH_PROTO_1) {
1397			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1398			options->identity_files[options->num_identity_files] =
1399			    xmalloc(len);
1400			snprintf(options->identity_files[options->num_identity_files++],
1401			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1402		}
1403		if (options->protocol & SSH_PROTO_2) {
1404			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1405			options->identity_files[options->num_identity_files] =
1406			    xmalloc(len);
1407			snprintf(options->identity_files[options->num_identity_files++],
1408			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1409
1410			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1411			options->identity_files[options->num_identity_files] =
1412			    xmalloc(len);
1413			snprintf(options->identity_files[options->num_identity_files++],
1414			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1415#ifdef OPENSSL_HAS_ECC
1416			len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1;
1417			options->identity_files[options->num_identity_files] =
1418			    xmalloc(len);
1419			snprintf(options->identity_files[options->num_identity_files++],
1420			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA);
1421#endif
1422		}
1423	}
1424	if (options->escape_char == -1)
1425		options->escape_char = '~';
1426	if (options->num_system_hostfiles == 0) {
1427		options->system_hostfiles[options->num_system_hostfiles++] =
1428		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1429		options->system_hostfiles[options->num_system_hostfiles++] =
1430		    xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1431	}
1432	if (options->num_user_hostfiles == 0) {
1433		options->user_hostfiles[options->num_user_hostfiles++] =
1434		    xstrdup(_PATH_SSH_USER_HOSTFILE);
1435		options->user_hostfiles[options->num_user_hostfiles++] =
1436		    xstrdup(_PATH_SSH_USER_HOSTFILE2);
1437	}
1438	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1439		options->log_level = SYSLOG_LEVEL_INFO;
1440	if (options->clear_forwardings == 1)
1441		clear_forwardings(options);
1442	if (options->no_host_authentication_for_localhost == - 1)
1443		options->no_host_authentication_for_localhost = 0;
1444	if (options->identities_only == -1)
1445		options->identities_only = 0;
1446	if (options->enable_ssh_keysign == -1)
1447		options->enable_ssh_keysign = 0;
1448	if (options->rekey_limit == -1)
1449		options->rekey_limit = 0;
1450	if (options->verify_host_key_dns == -1)
1451		options->verify_host_key_dns = 0;
1452	if (options->server_alive_interval == -1)
1453		options->server_alive_interval = 0;
1454	if (options->server_alive_count_max == -1)
1455		options->server_alive_count_max = 3;
1456	if (options->control_master == -1)
1457		options->control_master = 0;
1458	if (options->control_persist == -1) {
1459		options->control_persist = 0;
1460		options->control_persist_timeout = 0;
1461	}
1462	if (options->hash_known_hosts == -1)
1463		options->hash_known_hosts = 0;
1464	if (options->tun_open == -1)
1465		options->tun_open = SSH_TUNMODE_NO;
1466	if (options->tun_local == -1)
1467		options->tun_local = SSH_TUNID_ANY;
1468	if (options->tun_remote == -1)
1469		options->tun_remote = SSH_TUNID_ANY;
1470	if (options->permit_local_command == -1)
1471		options->permit_local_command = 0;
1472	if (options->use_roaming == -1)
1473		options->use_roaming = 1;
1474	if (options->visual_host_key == -1)
1475		options->visual_host_key = 0;
1476	if (options->zero_knowledge_password_authentication == -1)
1477		options->zero_knowledge_password_authentication = 0;
1478	if (options->ip_qos_interactive == -1)
1479		options->ip_qos_interactive = IPTOS_LOWDELAY;
1480	if (options->ip_qos_bulk == -1)
1481		options->ip_qos_bulk = IPTOS_THROUGHPUT;
1482	if (options->request_tty == -1)
1483		options->request_tty = REQUEST_TTY_AUTO;
1484	/* options->local_command should not be set by default */
1485	/* options->proxy_command should not be set by default */
1486	/* options->user will be set in the main program if appropriate */
1487	/* options->hostname will be set in the main program if appropriate */
1488	/* options->host_key_alias should not be set by default */
1489	/* options->preferred_authentications will be set in ssh */
1490	if (options->version_addendum == NULL)
1491		options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1492	if (options->hpn_disabled == -1)
1493		options->hpn_disabled = 0;
1494	if (options->hpn_buffer_size > -1)
1495	{
1496		u_int maxlen;
1497
1498		/* If a user tries to set the size to 0 set it to 1KB. */
1499		if (options->hpn_buffer_size == 0)
1500			options->hpn_buffer_size = 1024;
1501		/* Limit the buffer to BUFFER_MAX_LEN. */
1502		maxlen = buffer_get_max_len();
1503		if (options->hpn_buffer_size > (maxlen / 1024)) {
1504			debug("User requested buffer larger than %ub: %ub. "
1505			    "Request reverted to %ub", maxlen,
1506			    options->hpn_buffer_size * 1024, maxlen);
1507			options->hpn_buffer_size = maxlen;
1508		}
1509		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1510	}
1511	if (options->tcp_rcv_buf == 0)
1512		options->tcp_rcv_buf = 1;
1513	if (options->tcp_rcv_buf > -1)
1514		options->tcp_rcv_buf *= 1024;
1515	if (options->tcp_rcv_buf_poll == -1)
1516		options->tcp_rcv_buf_poll = 1;
1517#ifdef	NONE_CIPHER_ENABLED
1518	/* options->none_enabled must not be set by default */
1519	if (options->none_switch == -1)
1520		options->none_switch = 0;
1521#endif
1522}
1523
1524/*
1525 * parse_forward
1526 * parses a string containing a port forwarding specification of the form:
1527 *   dynamicfwd == 0
1528 *	[listenhost:]listenport:connecthost:connectport
1529 *   dynamicfwd == 1
1530 *	[listenhost:]listenport
1531 * returns number of arguments parsed or zero on error
1532 */
1533int
1534parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1535{
1536	int i;
1537	char *p, *cp, *fwdarg[4];
1538
1539	memset(fwd, '\0', sizeof(*fwd));
1540
1541	cp = p = xstrdup(fwdspec);
1542
1543	/* skip leading spaces */
1544	while (isspace(*cp))
1545		cp++;
1546
1547	for (i = 0; i < 4; ++i)
1548		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1549			break;
1550
1551	/* Check for trailing garbage */
1552	if (cp != NULL)
1553		i = 0;	/* failure */
1554
1555	switch (i) {
1556	case 1:
1557		fwd->listen_host = NULL;
1558		fwd->listen_port = a2port(fwdarg[0]);
1559		fwd->connect_host = xstrdup("socks");
1560		break;
1561
1562	case 2:
1563		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1564		fwd->listen_port = a2port(fwdarg[1]);
1565		fwd->connect_host = xstrdup("socks");
1566		break;
1567
1568	case 3:
1569		fwd->listen_host = NULL;
1570		fwd->listen_port = a2port(fwdarg[0]);
1571		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1572		fwd->connect_port = a2port(fwdarg[2]);
1573		break;
1574
1575	case 4:
1576		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1577		fwd->listen_port = a2port(fwdarg[1]);
1578		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1579		fwd->connect_port = a2port(fwdarg[3]);
1580		break;
1581	default:
1582		i = 0; /* failure */
1583	}
1584
1585	xfree(p);
1586
1587	if (dynamicfwd) {
1588		if (!(i == 1 || i == 2))
1589			goto fail_free;
1590	} else {
1591		if (!(i == 3 || i == 4))
1592			goto fail_free;
1593		if (fwd->connect_port <= 0)
1594			goto fail_free;
1595	}
1596
1597	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
1598		goto fail_free;
1599
1600	if (fwd->connect_host != NULL &&
1601	    strlen(fwd->connect_host) >= NI_MAXHOST)
1602		goto fail_free;
1603	if (fwd->listen_host != NULL &&
1604	    strlen(fwd->listen_host) >= NI_MAXHOST)
1605		goto fail_free;
1606
1607
1608	return (i);
1609
1610 fail_free:
1611	if (fwd->connect_host != NULL) {
1612		xfree(fwd->connect_host);
1613		fwd->connect_host = NULL;
1614	}
1615	if (fwd->listen_host != NULL) {
1616		xfree(fwd->listen_host);
1617		fwd->listen_host = NULL;
1618	}
1619	return (0);
1620}
1621