readconf.c revision 126277
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * Functions for reading the configuration files.
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose.  Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 */
13
14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
16RCSID("$FreeBSD: head/crypto/openssh/readconf.c 126277 2004-02-26 10:52:33Z des $");
17
18#include "ssh.h"
19#include "xmalloc.h"
20#include "compat.h"
21#include "cipher.h"
22#include "pathnames.h"
23#include "log.h"
24#include "readconf.h"
25#include "match.h"
26#include "misc.h"
27#include "kex.h"
28#include "mac.h"
29
30/* Format of the configuration file:
31
32   # Configuration data is parsed as follows:
33   #  1. command line options
34   #  2. user-specific file
35   #  3. system-wide file
36   # Any configuration value is only changed the first time it is set.
37   # Thus, host-specific definitions should be at the beginning of the
38   # configuration file, and defaults at the end.
39
40   # Host-specific declarations.  These may override anything above.  A single
41   # host may match multiple declarations; these are processed in the order
42   # that they are given in.
43
44   Host *.ngs.fi ngs.fi
45     User foo
46
47   Host fake.com
48     HostName another.host.name.real.org
49     User blaah
50     Port 34289
51     ForwardX11 no
52     ForwardAgent no
53
54   Host books.com
55     RemoteForward 9999 shadows.cs.hut.fi:9999
56     Cipher 3des
57
58   Host fascist.blob.com
59     Port 23123
60     User tylonen
61     PasswordAuthentication no
62
63   Host puukko.hut.fi
64     User t35124p
65     ProxyCommand ssh-proxy %h %p
66
67   Host *.fr
68     PublicKeyAuthentication no
69
70   Host *.su
71     Cipher none
72     PasswordAuthentication no
73
74   # Defaults for various options
75   Host *
76     ForwardAgent no
77     ForwardX11 no
78     PasswordAuthentication yes
79     RSAAuthentication yes
80     RhostsRSAAuthentication yes
81     StrictHostKeyChecking yes
82     TcpKeepAlive no
83     IdentityFile ~/.ssh/identity
84     Port 22
85     EscapeChar ~
86
87*/
88
89/* Keyword tokens. */
90
91typedef enum {
92	oBadOption,
93	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
94	oPasswordAuthentication, oRSAAuthentication,
95	oChallengeResponseAuthentication, oXAuthLocation,
96	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
97	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
98	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
99	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
100	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
101	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
102	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
103	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
104	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
105	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
106	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
107	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
108	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
109	oServerAliveInterval, oServerAliveCountMax,
110	oVersionAddendum,
111	oDeprecated, oUnsupported
112} OpCodes;
113
114/* Textual representations of the tokens. */
115
116static struct {
117	const char *name;
118	OpCodes opcode;
119} keywords[] = {
120	{ "forwardagent", oForwardAgent },
121	{ "forwardx11", oForwardX11 },
122	{ "forwardx11trusted", oForwardX11Trusted },
123	{ "xauthlocation", oXAuthLocation },
124	{ "gatewayports", oGatewayPorts },
125	{ "useprivilegedport", oUsePrivilegedPort },
126	{ "rhostsauthentication", oDeprecated },
127	{ "passwordauthentication", oPasswordAuthentication },
128	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
129	{ "kbdinteractivedevices", oKbdInteractiveDevices },
130	{ "rsaauthentication", oRSAAuthentication },
131	{ "pubkeyauthentication", oPubkeyAuthentication },
132	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
133	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
134	{ "hostbasedauthentication", oHostbasedAuthentication },
135	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
136	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
137	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
138	{ "kerberosauthentication", oUnsupported },
139	{ "kerberostgtpassing", oUnsupported },
140	{ "afstokenpassing", oUnsupported },
141#if defined(GSSAPI)
142	{ "gssapiauthentication", oGssAuthentication },
143	{ "gssapidelegatecredentials", oGssDelegateCreds },
144#else
145	{ "gssapiauthentication", oUnsupported },
146	{ "gssapidelegatecredentials", oUnsupported },
147#endif
148	{ "fallbacktorsh", oDeprecated },
149	{ "usersh", oDeprecated },
150	{ "identityfile", oIdentityFile },
151	{ "identityfile2", oIdentityFile },			/* alias */
152	{ "hostname", oHostName },
153	{ "hostkeyalias", oHostKeyAlias },
154	{ "proxycommand", oProxyCommand },
155	{ "port", oPort },
156	{ "cipher", oCipher },
157	{ "ciphers", oCiphers },
158	{ "macs", oMacs },
159	{ "protocol", oProtocol },
160	{ "remoteforward", oRemoteForward },
161	{ "localforward", oLocalForward },
162	{ "user", oUser },
163	{ "host", oHost },
164	{ "escapechar", oEscapeChar },
165	{ "globalknownhostsfile", oGlobalKnownHostsFile },
166	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
167	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
168	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
169	{ "connectionattempts", oConnectionAttempts },
170	{ "batchmode", oBatchMode },
171	{ "checkhostip", oCheckHostIP },
172	{ "stricthostkeychecking", oStrictHostKeyChecking },
173	{ "compression", oCompression },
174	{ "compressionlevel", oCompressionLevel },
175	{ "tcpkeepalive", oTCPKeepAlive },
176	{ "keepalive", oTCPKeepAlive },				/* obsolete */
177	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
178	{ "loglevel", oLogLevel },
179	{ "dynamicforward", oDynamicForward },
180	{ "preferredauthentications", oPreferredAuthentications },
181	{ "hostkeyalgorithms", oHostKeyAlgorithms },
182	{ "bindaddress", oBindAddress },
183#ifdef SMARTCARD
184	{ "smartcarddevice", oSmartcardDevice },
185#else
186	{ "smartcarddevice", oUnsupported },
187#endif
188	{ "clearallforwardings", oClearAllForwardings },
189	{ "enablesshkeysign", oEnableSSHKeysign },
190	{ "verifyhostkeydns", oVerifyHostKeyDNS },
191	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
192	{ "rekeylimit", oRekeyLimit },
193	{ "connecttimeout", oConnectTimeout },
194	{ "addressfamily", oAddressFamily },
195	{ "serveraliveinterval", oServerAliveInterval },
196	{ "serveralivecountmax", oServerAliveCountMax },
197	{ "versionaddendum", oVersionAddendum },
198	{ NULL, oBadOption }
199};
200
201/*
202 * Adds a local TCP/IP port forward to options.  Never returns if there is an
203 * error.
204 */
205
206void
207add_local_forward(Options *options, u_short port, const char *host,
208		  u_short host_port)
209{
210	Forward *fwd;
211#ifndef NO_IPPORT_RESERVED_CONCEPT
212	extern uid_t original_real_uid;
213	if (port < IPPORT_RESERVED && original_real_uid != 0)
214		fatal("Privileged ports can only be forwarded by root.");
215#endif
216	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
217		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
218	fwd = &options->local_forwards[options->num_local_forwards++];
219	fwd->port = port;
220	fwd->host = xstrdup(host);
221	fwd->host_port = host_port;
222}
223
224/*
225 * Adds a remote TCP/IP port forward to options.  Never returns if there is
226 * an error.
227 */
228
229void
230add_remote_forward(Options *options, u_short port, const char *host,
231		   u_short host_port)
232{
233	Forward *fwd;
234	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
235		fatal("Too many remote forwards (max %d).",
236		    SSH_MAX_FORWARDS_PER_DIRECTION);
237	fwd = &options->remote_forwards[options->num_remote_forwards++];
238	fwd->port = port;
239	fwd->host = xstrdup(host);
240	fwd->host_port = host_port;
241}
242
243static void
244clear_forwardings(Options *options)
245{
246	int i;
247
248	for (i = 0; i < options->num_local_forwards; i++)
249		xfree(options->local_forwards[i].host);
250	options->num_local_forwards = 0;
251	for (i = 0; i < options->num_remote_forwards; i++)
252		xfree(options->remote_forwards[i].host);
253	options->num_remote_forwards = 0;
254}
255
256/*
257 * Returns the number of the token pointed to by cp or oBadOption.
258 */
259
260static OpCodes
261parse_token(const char *cp, const char *filename, int linenum)
262{
263	u_int i;
264
265	for (i = 0; keywords[i].name; i++)
266		if (strcasecmp(cp, keywords[i].name) == 0)
267			return keywords[i].opcode;
268
269	error("%s: line %d: Bad configuration option: %s",
270	    filename, linenum, cp);
271	return oBadOption;
272}
273
274/*
275 * Processes a single option line as used in the configuration files. This
276 * only sets those values that have not already been set.
277 */
278#define WHITESPACE " \t\r\n"
279
280int
281process_config_line(Options *options, const char *host,
282		    char *line, const char *filename, int linenum,
283		    int *activep)
284{
285	char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
286	int opcode, *intptr, value;
287	size_t len;
288	u_short fwd_port, fwd_host_port;
289	char sfwd_host_port[6];
290
291	/* Strip trailing whitespace */
292	for(len = strlen(line) - 1; len > 0; len--) {
293		if (strchr(WHITESPACE, line[len]) == NULL)
294			break;
295		line[len] = '\0';
296	}
297
298	s = line;
299	/* Get the keyword. (Each line is supposed to begin with a keyword). */
300	keyword = strdelim(&s);
301	/* Ignore leading whitespace. */
302	if (*keyword == '\0')
303		keyword = strdelim(&s);
304	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
305		return 0;
306
307	opcode = parse_token(keyword, filename, linenum);
308
309	switch (opcode) {
310	case oBadOption:
311		/* don't panic, but count bad options */
312		return -1;
313		/* NOTREACHED */
314	case oConnectTimeout:
315		intptr = &options->connection_timeout;
316parse_time:
317		arg = strdelim(&s);
318		if (!arg || *arg == '\0')
319			fatal("%s line %d: missing time value.",
320			    filename, linenum);
321		if ((value = convtime(arg)) == -1)
322			fatal("%s line %d: invalid time value.",
323			    filename, linenum);
324		if (*intptr == -1)
325			*intptr = value;
326		break;
327
328	case oForwardAgent:
329		intptr = &options->forward_agent;
330parse_flag:
331		arg = strdelim(&s);
332		if (!arg || *arg == '\0')
333			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
334		value = 0;	/* To avoid compiler warning... */
335		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
336			value = 1;
337		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
338			value = 0;
339		else
340			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
341		if (*activep && *intptr == -1)
342			*intptr = value;
343		break;
344
345	case oForwardX11:
346		intptr = &options->forward_x11;
347		goto parse_flag;
348
349	case oForwardX11Trusted:
350		intptr = &options->forward_x11_trusted;
351		goto parse_flag;
352
353	case oGatewayPorts:
354		intptr = &options->gateway_ports;
355		goto parse_flag;
356
357	case oUsePrivilegedPort:
358		intptr = &options->use_privileged_port;
359		goto parse_flag;
360
361	case oPasswordAuthentication:
362		intptr = &options->password_authentication;
363		goto parse_flag;
364
365	case oKbdInteractiveAuthentication:
366		intptr = &options->kbd_interactive_authentication;
367		goto parse_flag;
368
369	case oKbdInteractiveDevices:
370		charptr = &options->kbd_interactive_devices;
371		goto parse_string;
372
373	case oPubkeyAuthentication:
374		intptr = &options->pubkey_authentication;
375		goto parse_flag;
376
377	case oRSAAuthentication:
378		intptr = &options->rsa_authentication;
379		goto parse_flag;
380
381	case oRhostsRSAAuthentication:
382		intptr = &options->rhosts_rsa_authentication;
383		goto parse_flag;
384
385	case oHostbasedAuthentication:
386		intptr = &options->hostbased_authentication;
387		goto parse_flag;
388
389	case oChallengeResponseAuthentication:
390		intptr = &options->challenge_response_authentication;
391		goto parse_flag;
392
393	case oGssAuthentication:
394		intptr = &options->gss_authentication;
395		goto parse_flag;
396
397	case oGssDelegateCreds:
398		intptr = &options->gss_deleg_creds;
399		goto parse_flag;
400
401	case oBatchMode:
402		intptr = &options->batch_mode;
403		goto parse_flag;
404
405	case oCheckHostIP:
406		intptr = &options->check_host_ip;
407		goto parse_flag;
408
409	case oVerifyHostKeyDNS:
410		intptr = &options->verify_host_key_dns;
411		goto parse_yesnoask;
412
413	case oStrictHostKeyChecking:
414		intptr = &options->strict_host_key_checking;
415parse_yesnoask:
416		arg = strdelim(&s);
417		if (!arg || *arg == '\0')
418			fatal("%.200s line %d: Missing yes/no/ask argument.",
419			    filename, linenum);
420		value = 0;	/* To avoid compiler warning... */
421		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
422			value = 1;
423		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
424			value = 0;
425		else if (strcmp(arg, "ask") == 0)
426			value = 2;
427		else
428			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
429		if (*activep && *intptr == -1)
430			*intptr = value;
431		break;
432
433	case oCompression:
434		intptr = &options->compression;
435		goto parse_flag;
436
437	case oTCPKeepAlive:
438		intptr = &options->tcp_keep_alive;
439		goto parse_flag;
440
441	case oNoHostAuthenticationForLocalhost:
442		intptr = &options->no_host_authentication_for_localhost;
443		goto parse_flag;
444
445	case oNumberOfPasswordPrompts:
446		intptr = &options->number_of_password_prompts;
447		goto parse_int;
448
449	case oCompressionLevel:
450		intptr = &options->compression_level;
451		goto parse_int;
452
453	case oRekeyLimit:
454		intptr = &options->rekey_limit;
455		arg = strdelim(&s);
456		if (!arg || *arg == '\0')
457			fatal("%.200s line %d: Missing argument.", filename, linenum);
458		if (arg[0] < '0' || arg[0] > '9')
459			fatal("%.200s line %d: Bad number.", filename, linenum);
460		value = strtol(arg, &endofnumber, 10);
461		if (arg == endofnumber)
462			fatal("%.200s line %d: Bad number.", filename, linenum);
463		switch (toupper(*endofnumber)) {
464		case 'K':
465			value *= 1<<10;
466			break;
467		case 'M':
468			value *= 1<<20;
469			break;
470		case 'G':
471			value *= 1<<30;
472			break;
473		}
474		if (*activep && *intptr == -1)
475			*intptr = value;
476		break;
477
478	case oIdentityFile:
479		arg = strdelim(&s);
480		if (!arg || *arg == '\0')
481			fatal("%.200s line %d: Missing argument.", filename, linenum);
482		if (*activep) {
483			intptr = &options->num_identity_files;
484			if (*intptr >= SSH_MAX_IDENTITY_FILES)
485				fatal("%.200s line %d: Too many identity files specified (max %d).",
486				    filename, linenum, SSH_MAX_IDENTITY_FILES);
487			charptr =  &options->identity_files[*intptr];
488			*charptr = xstrdup(arg);
489			*intptr = *intptr + 1;
490		}
491		break;
492
493	case oXAuthLocation:
494		charptr=&options->xauth_location;
495		goto parse_string;
496
497	case oUser:
498		charptr = &options->user;
499parse_string:
500		arg = strdelim(&s);
501		if (!arg || *arg == '\0')
502			fatal("%.200s line %d: Missing argument.", filename, linenum);
503		if (*activep && *charptr == NULL)
504			*charptr = xstrdup(arg);
505		break;
506
507	case oGlobalKnownHostsFile:
508		charptr = &options->system_hostfile;
509		goto parse_string;
510
511	case oUserKnownHostsFile:
512		charptr = &options->user_hostfile;
513		goto parse_string;
514
515	case oGlobalKnownHostsFile2:
516		charptr = &options->system_hostfile2;
517		goto parse_string;
518
519	case oUserKnownHostsFile2:
520		charptr = &options->user_hostfile2;
521		goto parse_string;
522
523	case oHostName:
524		charptr = &options->hostname;
525		goto parse_string;
526
527	case oHostKeyAlias:
528		charptr = &options->host_key_alias;
529		goto parse_string;
530
531	case oPreferredAuthentications:
532		charptr = &options->preferred_authentications;
533		goto parse_string;
534
535	case oBindAddress:
536		charptr = &options->bind_address;
537		goto parse_string;
538
539	case oSmartcardDevice:
540		charptr = &options->smartcard_device;
541		goto parse_string;
542
543	case oProxyCommand:
544		if (s == NULL)
545			fatal("%.200s line %d: Missing argument.", filename, linenum);
546		charptr = &options->proxy_command;
547		len = strspn(s, WHITESPACE "=");
548		if (*activep && *charptr == NULL)
549			*charptr = xstrdup(s + len);
550		return 0;
551
552	case oPort:
553		intptr = &options->port;
554parse_int:
555		arg = strdelim(&s);
556		if (!arg || *arg == '\0')
557			fatal("%.200s line %d: Missing argument.", filename, linenum);
558		if (arg[0] < '0' || arg[0] > '9')
559			fatal("%.200s line %d: Bad number.", filename, linenum);
560
561		/* Octal, decimal, or hex format? */
562		value = strtol(arg, &endofnumber, 0);
563		if (arg == endofnumber)
564			fatal("%.200s line %d: Bad number.", filename, linenum);
565		if (*activep && *intptr == -1)
566			*intptr = value;
567		break;
568
569	case oConnectionAttempts:
570		intptr = &options->connection_attempts;
571		goto parse_int;
572
573	case oCipher:
574		intptr = &options->cipher;
575		arg = strdelim(&s);
576		if (!arg || *arg == '\0')
577			fatal("%.200s line %d: Missing argument.", filename, linenum);
578		value = cipher_number(arg);
579		if (value == -1)
580			fatal("%.200s line %d: Bad cipher '%s'.",
581			    filename, linenum, arg ? arg : "<NONE>");
582		if (*activep && *intptr == -1)
583			*intptr = value;
584		break;
585
586	case oCiphers:
587		arg = strdelim(&s);
588		if (!arg || *arg == '\0')
589			fatal("%.200s line %d: Missing argument.", filename, linenum);
590		if (!ciphers_valid(arg))
591			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
592			    filename, linenum, arg ? arg : "<NONE>");
593		if (*activep && options->ciphers == NULL)
594			options->ciphers = xstrdup(arg);
595		break;
596
597	case oMacs:
598		arg = strdelim(&s);
599		if (!arg || *arg == '\0')
600			fatal("%.200s line %d: Missing argument.", filename, linenum);
601		if (!mac_valid(arg))
602			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
603			    filename, linenum, arg ? arg : "<NONE>");
604		if (*activep && options->macs == NULL)
605			options->macs = xstrdup(arg);
606		break;
607
608	case oHostKeyAlgorithms:
609		arg = strdelim(&s);
610		if (!arg || *arg == '\0')
611			fatal("%.200s line %d: Missing argument.", filename, linenum);
612		if (!key_names_valid2(arg))
613			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
614			    filename, linenum, arg ? arg : "<NONE>");
615		if (*activep && options->hostkeyalgorithms == NULL)
616			options->hostkeyalgorithms = xstrdup(arg);
617		break;
618
619	case oProtocol:
620		intptr = &options->protocol;
621		arg = strdelim(&s);
622		if (!arg || *arg == '\0')
623			fatal("%.200s line %d: Missing argument.", filename, linenum);
624		value = proto_spec(arg);
625		if (value == SSH_PROTO_UNKNOWN)
626			fatal("%.200s line %d: Bad protocol spec '%s'.",
627			    filename, linenum, arg ? arg : "<NONE>");
628		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
629			*intptr = value;
630		break;
631
632	case oLogLevel:
633		intptr = (int *) &options->log_level;
634		arg = strdelim(&s);
635		value = log_level_number(arg);
636		if (value == SYSLOG_LEVEL_NOT_SET)
637			fatal("%.200s line %d: unsupported log level '%s'",
638			    filename, linenum, arg ? arg : "<NONE>");
639		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
640			*intptr = (LogLevel) value;
641		break;
642
643	case oLocalForward:
644	case oRemoteForward:
645		arg = strdelim(&s);
646		if (!arg || *arg == '\0')
647			fatal("%.200s line %d: Missing port argument.",
648			    filename, linenum);
649		if ((fwd_port = a2port(arg)) == 0)
650			fatal("%.200s line %d: Bad listen port.",
651			    filename, linenum);
652		arg = strdelim(&s);
653		if (!arg || *arg == '\0')
654			fatal("%.200s line %d: Missing second argument.",
655			    filename, linenum);
656		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
657		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
658			fatal("%.200s line %d: Bad forwarding specification.",
659			    filename, linenum);
660		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
661			fatal("%.200s line %d: Bad forwarding port.",
662			    filename, linenum);
663		if (*activep) {
664			if (opcode == oLocalForward)
665				add_local_forward(options, fwd_port, buf,
666				    fwd_host_port);
667			else if (opcode == oRemoteForward)
668				add_remote_forward(options, fwd_port, buf,
669				    fwd_host_port);
670		}
671		break;
672
673	case oDynamicForward:
674		arg = strdelim(&s);
675		if (!arg || *arg == '\0')
676			fatal("%.200s line %d: Missing port argument.",
677			    filename, linenum);
678		fwd_port = a2port(arg);
679		if (fwd_port == 0)
680			fatal("%.200s line %d: Badly formatted port number.",
681			    filename, linenum);
682		if (*activep)
683			add_local_forward(options, fwd_port, "socks", 0);
684		break;
685
686	case oClearAllForwardings:
687		intptr = &options->clear_forwardings;
688		goto parse_flag;
689
690	case oHost:
691		*activep = 0;
692		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
693			if (match_pattern(host, arg)) {
694				debug("Applying options for %.100s", arg);
695				*activep = 1;
696				break;
697			}
698		/* Avoid garbage check below, as strdelim is done. */
699		return 0;
700
701	case oEscapeChar:
702		intptr = &options->escape_char;
703		arg = strdelim(&s);
704		if (!arg || *arg == '\0')
705			fatal("%.200s line %d: Missing argument.", filename, linenum);
706		if (arg[0] == '^' && arg[2] == 0 &&
707		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
708			value = (u_char) arg[1] & 31;
709		else if (strlen(arg) == 1)
710			value = (u_char) arg[0];
711		else if (strcmp(arg, "none") == 0)
712			value = SSH_ESCAPECHAR_NONE;
713		else {
714			fatal("%.200s line %d: Bad escape character.",
715			    filename, linenum);
716			/* NOTREACHED */
717			value = 0;	/* Avoid compiler warning. */
718		}
719		if (*activep && *intptr == -1)
720			*intptr = value;
721		break;
722
723	case oAddressFamily:
724		arg = strdelim(&s);
725		intptr = &options->address_family;
726		if (strcasecmp(arg, "inet") == 0)
727			value = AF_INET;
728		else if (strcasecmp(arg, "inet6") == 0)
729			value = AF_INET6;
730		else if (strcasecmp(arg, "any") == 0)
731			value = AF_UNSPEC;
732		else
733			fatal("Unsupported AddressFamily \"%s\"", arg);
734		if (*activep && *intptr == -1)
735			*intptr = value;
736		break;
737
738	case oEnableSSHKeysign:
739		intptr = &options->enable_ssh_keysign;
740		goto parse_flag;
741
742	case oServerAliveInterval:
743		intptr = &options->server_alive_interval;
744		goto parse_time;
745
746	case oServerAliveCountMax:
747		intptr = &options->server_alive_count_max;
748		goto parse_int;
749
750	case oVersionAddendum:
751		ssh_version_set_addendum(strtok(s, "\n"));
752		do {
753			arg = strdelim(&s);
754		} while (arg != NULL && *arg != '\0');
755		break;
756
757	case oDeprecated:
758		debug("%s line %d: Deprecated option \"%s\"",
759		    filename, linenum, keyword);
760		return 0;
761
762	case oUnsupported:
763		error("%s line %d: Unsupported option \"%s\"",
764		    filename, linenum, keyword);
765		return 0;
766
767	default:
768		fatal("process_config_line: Unimplemented opcode %d", opcode);
769	}
770
771	/* Check that there is no garbage at end of line. */
772	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
773		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
774		     filename, linenum, arg);
775	}
776	return 0;
777}
778
779
780/*
781 * Reads the config file and modifies the options accordingly.  Options
782 * should already be initialized before this call.  This never returns if
783 * there is an error.  If the file does not exist, this returns 0.
784 */
785
786int
787read_config_file(const char *filename, const char *host, Options *options)
788{
789	FILE *f;
790	char line[1024];
791	int active, linenum;
792	int bad_options = 0;
793
794	/* Open the file. */
795	f = fopen(filename, "r");
796	if (!f)
797		return 0;
798
799	debug("Reading configuration data %.200s", filename);
800
801	/*
802	 * Mark that we are now processing the options.  This flag is turned
803	 * on/off by Host specifications.
804	 */
805	active = 1;
806	linenum = 0;
807	while (fgets(line, sizeof(line), f)) {
808		/* Update line number counter. */
809		linenum++;
810		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
811			bad_options++;
812	}
813	fclose(f);
814	if (bad_options > 0)
815		fatal("%s: terminating, %d bad configuration options",
816		    filename, bad_options);
817	return 1;
818}
819
820/*
821 * Initializes options to special values that indicate that they have not yet
822 * been set.  Read_config_file will only set options with this value. Options
823 * are processed in the following order: command line, user config file,
824 * system config file.  Last, fill_default_options is called.
825 */
826
827void
828initialize_options(Options * options)
829{
830	memset(options, 'X', sizeof(*options));
831	options->forward_agent = -1;
832	options->forward_x11 = -1;
833	options->forward_x11_trusted = -1;
834	options->xauth_location = NULL;
835	options->gateway_ports = -1;
836	options->use_privileged_port = -1;
837	options->rsa_authentication = -1;
838	options->pubkey_authentication = -1;
839	options->challenge_response_authentication = -1;
840	options->gss_authentication = -1;
841	options->gss_deleg_creds = -1;
842	options->password_authentication = -1;
843	options->kbd_interactive_authentication = -1;
844	options->kbd_interactive_devices = NULL;
845	options->rhosts_rsa_authentication = -1;
846	options->hostbased_authentication = -1;
847	options->batch_mode = -1;
848	options->check_host_ip = -1;
849	options->strict_host_key_checking = -1;
850	options->compression = -1;
851	options->tcp_keep_alive = -1;
852	options->compression_level = -1;
853	options->port = -1;
854	options->address_family = -1;
855	options->connection_attempts = -1;
856	options->connection_timeout = -1;
857	options->number_of_password_prompts = -1;
858	options->cipher = -1;
859	options->ciphers = NULL;
860	options->macs = NULL;
861	options->hostkeyalgorithms = NULL;
862	options->protocol = SSH_PROTO_UNKNOWN;
863	options->num_identity_files = 0;
864	options->hostname = NULL;
865	options->host_key_alias = NULL;
866	options->proxy_command = NULL;
867	options->user = NULL;
868	options->escape_char = -1;
869	options->system_hostfile = NULL;
870	options->user_hostfile = NULL;
871	options->system_hostfile2 = NULL;
872	options->user_hostfile2 = NULL;
873	options->num_local_forwards = 0;
874	options->num_remote_forwards = 0;
875	options->clear_forwardings = -1;
876	options->log_level = SYSLOG_LEVEL_NOT_SET;
877	options->preferred_authentications = NULL;
878	options->bind_address = NULL;
879	options->smartcard_device = NULL;
880	options->enable_ssh_keysign = - 1;
881	options->no_host_authentication_for_localhost = - 1;
882	options->rekey_limit = - 1;
883	options->verify_host_key_dns = -1;
884	options->server_alive_interval = -1;
885	options->server_alive_count_max = -1;
886}
887
888/*
889 * Called after processing other sources of option data, this fills those
890 * options for which no value has been specified with their default values.
891 */
892
893void
894fill_default_options(Options * options)
895{
896	int len;
897
898	if (options->forward_agent == -1)
899		options->forward_agent = 0;
900	if (options->forward_x11 == -1)
901		options->forward_x11 = 0;
902	if (options->forward_x11_trusted == -1)
903		options->forward_x11_trusted = 0;
904	if (options->xauth_location == NULL)
905		options->xauth_location = _PATH_XAUTH;
906	if (options->gateway_ports == -1)
907		options->gateway_ports = 0;
908	if (options->use_privileged_port == -1)
909		options->use_privileged_port = 0;
910	if (options->rsa_authentication == -1)
911		options->rsa_authentication = 1;
912	if (options->pubkey_authentication == -1)
913		options->pubkey_authentication = 1;
914	if (options->challenge_response_authentication == -1)
915		options->challenge_response_authentication = 1;
916	if (options->gss_authentication == -1)
917		options->gss_authentication = 0;
918	if (options->gss_deleg_creds == -1)
919		options->gss_deleg_creds = 0;
920	if (options->password_authentication == -1)
921		options->password_authentication = 1;
922	if (options->kbd_interactive_authentication == -1)
923		options->kbd_interactive_authentication = 1;
924	if (options->rhosts_rsa_authentication == -1)
925		options->rhosts_rsa_authentication = 0;
926	if (options->hostbased_authentication == -1)
927		options->hostbased_authentication = 0;
928	if (options->batch_mode == -1)
929		options->batch_mode = 0;
930	if (options->check_host_ip == -1)
931		options->check_host_ip = 0;
932	if (options->strict_host_key_checking == -1)
933		options->strict_host_key_checking = 2;	/* 2 is default */
934	if (options->compression == -1)
935		options->compression = 0;
936	if (options->tcp_keep_alive == -1)
937		options->tcp_keep_alive = 1;
938	if (options->compression_level == -1)
939		options->compression_level = 6;
940	if (options->port == -1)
941		options->port = 0;	/* Filled in ssh_connect. */
942	if (options->address_family == -1)
943		options->address_family = AF_UNSPEC;
944	if (options->connection_attempts == -1)
945		options->connection_attempts = 1;
946	if (options->number_of_password_prompts == -1)
947		options->number_of_password_prompts = 3;
948	/* Selected in ssh_login(). */
949	if (options->cipher == -1)
950		options->cipher = SSH_CIPHER_NOT_SET;
951	/* options->ciphers, default set in myproposals.h */
952	/* options->macs, default set in myproposals.h */
953	/* options->hostkeyalgorithms, default set in myproposals.h */
954	if (options->protocol == SSH_PROTO_UNKNOWN)
955		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
956	if (options->num_identity_files == 0) {
957		if (options->protocol & SSH_PROTO_1) {
958			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
959			options->identity_files[options->num_identity_files] =
960			    xmalloc(len);
961			snprintf(options->identity_files[options->num_identity_files++],
962			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
963		}
964		if (options->protocol & SSH_PROTO_2) {
965			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
966			options->identity_files[options->num_identity_files] =
967			    xmalloc(len);
968			snprintf(options->identity_files[options->num_identity_files++],
969			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
970
971			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
972			options->identity_files[options->num_identity_files] =
973			    xmalloc(len);
974			snprintf(options->identity_files[options->num_identity_files++],
975			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
976		}
977	}
978	if (options->escape_char == -1)
979		options->escape_char = '~';
980	if (options->system_hostfile == NULL)
981		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
982	if (options->user_hostfile == NULL)
983		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
984	if (options->system_hostfile2 == NULL)
985		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
986	if (options->user_hostfile2 == NULL)
987		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
988	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
989		options->log_level = SYSLOG_LEVEL_INFO;
990	if (options->clear_forwardings == 1)
991		clear_forwardings(options);
992	if (options->no_host_authentication_for_localhost == - 1)
993		options->no_host_authentication_for_localhost = 0;
994	if (options->enable_ssh_keysign == -1)
995		options->enable_ssh_keysign = 0;
996	if (options->rekey_limit == -1)
997		options->rekey_limit = 0;
998	if (options->verify_host_key_dns == -1)
999		options->verify_host_key_dns = 0;
1000	if (options->server_alive_interval == -1)
1001		options->server_alive_interval = 0;
1002	if (options->server_alive_count_max == -1)
1003		options->server_alive_count_max = 3;
1004	/* options->proxy_command should not be set by default */
1005	/* options->user will be set in the main program if appropriate */
1006	/* options->hostname will be set in the main program if appropriate */
1007	/* options->host_key_alias should not be set by default */
1008	/* options->preferred_authentications will be set in ssh */
1009}
1010