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