xref: /freebsd/crypto/openssh/readconf.c (revision 9e2cbe04ff4fa7b48a5deb3469b95314b12040cb)
1511b41d2SMark Murray /*
2511b41d2SMark Murray  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3511b41d2SMark Murray  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4511b41d2SMark Murray  *                    All rights reserved
5511b41d2SMark Murray  * Functions for reading the configuration files.
6511b41d2SMark Murray  *
7c2d3a559SKris Kennaway  * As far as I am concerned, the code I have written for this software
8c2d3a559SKris Kennaway  * can be used freely for any purpose.  Any derived versions of this
9c2d3a559SKris Kennaway  * software must be clearly marked as such, and if the derived work is
10c2d3a559SKris Kennaway  * incompatible with the protocol description in the RFC file, it must be
11c2d3a559SKris Kennaway  * called by a name other than "ssh" or "Secure Shell".
12511b41d2SMark Murray  */
13511b41d2SMark Murray 
14511b41d2SMark Murray #include "includes.h"
15af12a3e7SDag-Erling Smørgrav RCSID("$OpenBSD: readconf.c,v 1.95 2002/02/04 12:15:25 markus Exp $");
16c2d3a559SKris Kennaway RCSID("$FreeBSD$");
17511b41d2SMark Murray 
18511b41d2SMark Murray #include "ssh.h"
19511b41d2SMark Murray #include "xmalloc.h"
20e8aafc91SKris Kennaway #include "compat.h"
21ca3176e7SBrian Feldman #include "cipher.h"
22ca3176e7SBrian Feldman #include "pathnames.h"
23ca3176e7SBrian Feldman #include "log.h"
24ca3176e7SBrian Feldman #include "readconf.h"
25ca3176e7SBrian Feldman #include "match.h"
26ca3176e7SBrian Feldman #include "misc.h"
27ca3176e7SBrian Feldman #include "kex.h"
28ca3176e7SBrian Feldman #include "mac.h"
29511b41d2SMark Murray 
30511b41d2SMark Murray /* Format of the configuration file:
31511b41d2SMark Murray 
32511b41d2SMark Murray    # Configuration data is parsed as follows:
33511b41d2SMark Murray    #  1. command line options
34511b41d2SMark Murray    #  2. user-specific file
35511b41d2SMark Murray    #  3. system-wide file
36511b41d2SMark Murray    # Any configuration value is only changed the first time it is set.
37511b41d2SMark Murray    # Thus, host-specific definitions should be at the beginning of the
38511b41d2SMark Murray    # configuration file, and defaults at the end.
39511b41d2SMark Murray 
40511b41d2SMark Murray    # Host-specific declarations.  These may override anything above.  A single
41511b41d2SMark Murray    # host may match multiple declarations; these are processed in the order
42511b41d2SMark Murray    # that they are given in.
43511b41d2SMark Murray 
44511b41d2SMark Murray    Host *.ngs.fi ngs.fi
45511b41d2SMark Murray      FallBackToRsh no
46511b41d2SMark Murray 
47511b41d2SMark Murray    Host fake.com
48511b41d2SMark Murray      HostName another.host.name.real.org
49511b41d2SMark Murray      User blaah
50511b41d2SMark Murray      Port 34289
51511b41d2SMark Murray      ForwardX11 no
52511b41d2SMark Murray      ForwardAgent no
53511b41d2SMark Murray 
54511b41d2SMark Murray    Host books.com
55511b41d2SMark Murray      RemoteForward 9999 shadows.cs.hut.fi:9999
56511b41d2SMark Murray      Cipher 3des
57511b41d2SMark Murray 
58511b41d2SMark Murray    Host fascist.blob.com
59511b41d2SMark Murray      Port 23123
60511b41d2SMark Murray      User tylonen
61511b41d2SMark Murray      RhostsAuthentication no
62511b41d2SMark Murray      PasswordAuthentication no
63511b41d2SMark Murray 
64511b41d2SMark Murray    Host puukko.hut.fi
65511b41d2SMark Murray      User t35124p
66511b41d2SMark Murray      ProxyCommand ssh-proxy %h %p
67511b41d2SMark Murray 
68511b41d2SMark Murray    Host *.fr
69511b41d2SMark Murray      UseRsh yes
70511b41d2SMark Murray 
71511b41d2SMark Murray    Host *.su
72511b41d2SMark Murray      Cipher none
73511b41d2SMark Murray      PasswordAuthentication no
74511b41d2SMark Murray 
75511b41d2SMark Murray    # Defaults for various options
76511b41d2SMark Murray    Host *
77511b41d2SMark Murray      ForwardAgent no
78ca3176e7SBrian Feldman      ForwardX11 no
79511b41d2SMark Murray      RhostsAuthentication yes
80511b41d2SMark Murray      PasswordAuthentication yes
81511b41d2SMark Murray      RSAAuthentication yes
82511b41d2SMark Murray      RhostsRSAAuthentication yes
83511b41d2SMark Murray      FallBackToRsh no
84511b41d2SMark Murray      UseRsh no
85511b41d2SMark Murray      StrictHostKeyChecking yes
86511b41d2SMark Murray      KeepAlives no
87511b41d2SMark Murray      IdentityFile ~/.ssh/identity
88511b41d2SMark Murray      Port 22
89511b41d2SMark Murray      EscapeChar ~
90511b41d2SMark Murray 
91511b41d2SMark Murray */
92511b41d2SMark Murray 
93511b41d2SMark Murray /* Keyword tokens. */
94511b41d2SMark Murray 
95511b41d2SMark Murray typedef enum {
96511b41d2SMark Murray 	oBadOption,
97511b41d2SMark Murray 	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
98511b41d2SMark Murray 	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
99ca3176e7SBrian Feldman 	oChallengeResponseAuthentication, oXAuthLocation,
100cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
101cb96ab36SAssar Westerlund 	oKerberosAuthentication,
102af12a3e7SDag-Erling Smørgrav #endif
103af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
104af12a3e7SDag-Erling Smørgrav 	oKerberosTgtPassing,
105af12a3e7SDag-Erling Smørgrav #endif
106511b41d2SMark Murray #ifdef AFS
107af12a3e7SDag-Erling Smørgrav 	oAFSTokenPassing,
108511b41d2SMark Murray #endif
109511b41d2SMark Murray 	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
110511b41d2SMark Murray 	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
111511b41d2SMark Murray 	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
112511b41d2SMark Murray 	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
113ca3176e7SBrian Feldman 	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
114ca3176e7SBrian Feldman 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
115ca3176e7SBrian Feldman 	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
116ca3176e7SBrian Feldman 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
117ca3176e7SBrian Feldman 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
118af12a3e7SDag-Erling Smørgrav 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
1199e2cbe04SDag-Erling Smørgrav 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
1209e2cbe04SDag-Erling Smørgrav 	oVersionAddendum
121511b41d2SMark Murray } OpCodes;
122511b41d2SMark Murray 
123511b41d2SMark Murray /* Textual representations of the tokens. */
124511b41d2SMark Murray 
125511b41d2SMark Murray static struct {
126511b41d2SMark Murray 	const char *name;
127511b41d2SMark Murray 	OpCodes opcode;
128511b41d2SMark Murray } keywords[] = {
129511b41d2SMark Murray 	{ "forwardagent", oForwardAgent },
130511b41d2SMark Murray 	{ "forwardx11", oForwardX11 },
131c2d3a559SKris Kennaway 	{ "xauthlocation", oXAuthLocation },
132511b41d2SMark Murray 	{ "gatewayports", oGatewayPorts },
133511b41d2SMark Murray 	{ "useprivilegedport", oUsePrivilegedPort },
134511b41d2SMark Murray 	{ "rhostsauthentication", oRhostsAuthentication },
135511b41d2SMark Murray 	{ "passwordauthentication", oPasswordAuthentication },
13609958426SBrian Feldman 	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
13709958426SBrian Feldman 	{ "kbdinteractivedevices", oKbdInteractiveDevices },
138511b41d2SMark Murray 	{ "rsaauthentication", oRSAAuthentication },
139ca3176e7SBrian Feldman 	{ "pubkeyauthentication", oPubkeyAuthentication },
140ca3176e7SBrian Feldman 	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
141ca3176e7SBrian Feldman 	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
142ca3176e7SBrian Feldman 	{ "hostbasedauthentication", oHostbasedAuthentication },
143ca3176e7SBrian Feldman 	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
144ca3176e7SBrian Feldman 	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
145ca3176e7SBrian Feldman 	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
146cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
147cb96ab36SAssar Westerlund 	{ "kerberosauthentication", oKerberosAuthentication },
148af12a3e7SDag-Erling Smørgrav #endif
149af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
150af12a3e7SDag-Erling Smørgrav 	{ "kerberostgtpassing", oKerberosTgtPassing },
151af12a3e7SDag-Erling Smørgrav #endif
152511b41d2SMark Murray #ifdef AFS
153511b41d2SMark Murray 	{ "afstokenpassing", oAFSTokenPassing },
154511b41d2SMark Murray #endif
155511b41d2SMark Murray 	{ "fallbacktorsh", oFallBackToRsh },
156511b41d2SMark Murray 	{ "usersh", oUseRsh },
157511b41d2SMark Murray 	{ "identityfile", oIdentityFile },
158ca3176e7SBrian Feldman 	{ "identityfile2", oIdentityFile },			/* alias */
159511b41d2SMark Murray 	{ "hostname", oHostName },
160ca3176e7SBrian Feldman 	{ "hostkeyalias", oHostKeyAlias },
161511b41d2SMark Murray 	{ "proxycommand", oProxyCommand },
162511b41d2SMark Murray 	{ "port", oPort },
163511b41d2SMark Murray 	{ "cipher", oCipher },
164e8aafc91SKris Kennaway 	{ "ciphers", oCiphers },
165ca3176e7SBrian Feldman 	{ "macs", oMacs },
166e8aafc91SKris Kennaway 	{ "protocol", oProtocol },
167511b41d2SMark Murray 	{ "remoteforward", oRemoteForward },
168511b41d2SMark Murray 	{ "localforward", oLocalForward },
169511b41d2SMark Murray 	{ "user", oUser },
170511b41d2SMark Murray 	{ "host", oHost },
171511b41d2SMark Murray 	{ "escapechar", oEscapeChar },
172511b41d2SMark Murray 	{ "globalknownhostsfile", oGlobalKnownHostsFile },
173af12a3e7SDag-Erling Smørgrav 	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
174e8aafc91SKris Kennaway 	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
175af12a3e7SDag-Erling Smørgrav 	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
176511b41d2SMark Murray 	{ "connectionattempts", oConnectionAttempts },
177511b41d2SMark Murray 	{ "batchmode", oBatchMode },
178511b41d2SMark Murray 	{ "checkhostip", oCheckHostIP },
179511b41d2SMark Murray 	{ "stricthostkeychecking", oStrictHostKeyChecking },
180511b41d2SMark Murray 	{ "compression", oCompression },
181511b41d2SMark Murray 	{ "compressionlevel", oCompressionLevel },
182511b41d2SMark Murray 	{ "keepalive", oKeepAlives },
183511b41d2SMark Murray 	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
184511b41d2SMark Murray 	{ "loglevel", oLogLevel },
185ca3176e7SBrian Feldman 	{ "dynamicforward", oDynamicForward },
186ca3176e7SBrian Feldman 	{ "preferredauthentications", oPreferredAuthentications },
187ca3176e7SBrian Feldman 	{ "hostkeyalgorithms", oHostKeyAlgorithms },
188af12a3e7SDag-Erling Smørgrav 	{ "bindaddress", oBindAddress },
189af12a3e7SDag-Erling Smørgrav 	{ "smartcarddevice", oSmartcardDevice },
190af12a3e7SDag-Erling Smørgrav 	{ "clearallforwardings", oClearAllForwardings },
191af12a3e7SDag-Erling Smørgrav 	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
1929e2cbe04SDag-Erling Smørgrav 	{ "versionaddendum", oVersionAddendum },
193af12a3e7SDag-Erling Smørgrav 	{ NULL, oBadOption }
194511b41d2SMark Murray };
195511b41d2SMark Murray 
196511b41d2SMark Murray /*
197511b41d2SMark Murray  * Adds a local TCP/IP port forward to options.  Never returns if there is an
198511b41d2SMark Murray  * error.
199511b41d2SMark Murray  */
200511b41d2SMark Murray 
201511b41d2SMark Murray void
202511b41d2SMark Murray add_local_forward(Options *options, u_short port, const char *host,
203511b41d2SMark Murray 		  u_short host_port)
204511b41d2SMark Murray {
205511b41d2SMark Murray 	Forward *fwd;
206511b41d2SMark Murray 	extern uid_t original_real_uid;
207511b41d2SMark Murray 	if (port < IPPORT_RESERVED && original_real_uid != 0)
208ca3176e7SBrian Feldman 		fatal("Privileged ports can only be forwarded by root.");
209511b41d2SMark Murray 	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
210511b41d2SMark Murray 		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
211511b41d2SMark Murray 	fwd = &options->local_forwards[options->num_local_forwards++];
212511b41d2SMark Murray 	fwd->port = port;
213511b41d2SMark Murray 	fwd->host = xstrdup(host);
214511b41d2SMark Murray 	fwd->host_port = host_port;
215511b41d2SMark Murray }
216511b41d2SMark Murray 
217511b41d2SMark Murray /*
218511b41d2SMark Murray  * Adds a remote TCP/IP port forward to options.  Never returns if there is
219511b41d2SMark Murray  * an error.
220511b41d2SMark Murray  */
221511b41d2SMark Murray 
222511b41d2SMark Murray void
223511b41d2SMark Murray add_remote_forward(Options *options, u_short port, const char *host,
224511b41d2SMark Murray 		   u_short host_port)
225511b41d2SMark Murray {
226511b41d2SMark Murray 	Forward *fwd;
227511b41d2SMark Murray 	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
228511b41d2SMark Murray 		fatal("Too many remote forwards (max %d).",
229511b41d2SMark Murray 		    SSH_MAX_FORWARDS_PER_DIRECTION);
230511b41d2SMark Murray 	fwd = &options->remote_forwards[options->num_remote_forwards++];
231511b41d2SMark Murray 	fwd->port = port;
232511b41d2SMark Murray 	fwd->host = xstrdup(host);
233511b41d2SMark Murray 	fwd->host_port = host_port;
234511b41d2SMark Murray }
235511b41d2SMark Murray 
236af12a3e7SDag-Erling Smørgrav static void
237af12a3e7SDag-Erling Smørgrav clear_forwardings(Options *options)
238af12a3e7SDag-Erling Smørgrav {
239af12a3e7SDag-Erling Smørgrav 	int i;
240af12a3e7SDag-Erling Smørgrav 
241af12a3e7SDag-Erling Smørgrav 	for (i = 0; i < options->num_local_forwards; i++)
242af12a3e7SDag-Erling Smørgrav 		xfree(options->local_forwards[i].host);
243af12a3e7SDag-Erling Smørgrav 	options->num_local_forwards = 0;
244af12a3e7SDag-Erling Smørgrav 	for (i = 0; i < options->num_remote_forwards; i++)
245af12a3e7SDag-Erling Smørgrav 		xfree(options->remote_forwards[i].host);
246af12a3e7SDag-Erling Smørgrav 	options->num_remote_forwards = 0;
247af12a3e7SDag-Erling Smørgrav }
248af12a3e7SDag-Erling Smørgrav 
249511b41d2SMark Murray /*
250ca3176e7SBrian Feldman  * Returns the number of the token pointed to by cp or oBadOption.
251511b41d2SMark Murray  */
252511b41d2SMark Murray 
253511b41d2SMark Murray static OpCodes
254511b41d2SMark Murray parse_token(const char *cp, const char *filename, int linenum)
255511b41d2SMark Murray {
256ca3176e7SBrian Feldman 	u_int i;
257511b41d2SMark Murray 
258511b41d2SMark Murray 	for (i = 0; keywords[i].name; i++)
259511b41d2SMark Murray 		if (strcasecmp(cp, keywords[i].name) == 0)
260511b41d2SMark Murray 			return keywords[i].opcode;
261511b41d2SMark Murray 
262ca3176e7SBrian Feldman 	error("%s: line %d: Bad configuration option: %s",
263511b41d2SMark Murray 	    filename, linenum, cp);
264511b41d2SMark Murray 	return oBadOption;
265511b41d2SMark Murray }
266511b41d2SMark Murray 
267511b41d2SMark Murray /*
268511b41d2SMark Murray  * Processes a single option line as used in the configuration files. This
269511b41d2SMark Murray  * only sets those values that have not already been set.
270511b41d2SMark Murray  */
271511b41d2SMark Murray 
272511b41d2SMark Murray int
273511b41d2SMark Murray process_config_line(Options *options, const char *host,
274511b41d2SMark Murray 		    char *line, const char *filename, int linenum,
275511b41d2SMark Murray 		    int *activep)
276511b41d2SMark Murray {
277c2d3a559SKris Kennaway 	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
278511b41d2SMark Murray 	int opcode, *intptr, value;
279511b41d2SMark Murray 	u_short fwd_port, fwd_host_port;
280af12a3e7SDag-Erling Smørgrav 	char sfwd_host_port[6];
281511b41d2SMark Murray 
282c2d3a559SKris Kennaway 	s = line;
283c2d3a559SKris Kennaway 	/* Get the keyword. (Each line is supposed to begin with a keyword). */
284c2d3a559SKris Kennaway 	keyword = strdelim(&s);
285c2d3a559SKris Kennaway 	/* Ignore leading whitespace. */
286c2d3a559SKris Kennaway 	if (*keyword == '\0')
287c2d3a559SKris Kennaway 		keyword = strdelim(&s);
288ca3176e7SBrian Feldman 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
289511b41d2SMark Murray 		return 0;
290511b41d2SMark Murray 
291c2d3a559SKris Kennaway 	opcode = parse_token(keyword, filename, linenum);
292511b41d2SMark Murray 
293511b41d2SMark Murray 	switch (opcode) {
294511b41d2SMark Murray 	case oBadOption:
295511b41d2SMark Murray 		/* don't panic, but count bad options */
296511b41d2SMark Murray 		return -1;
297511b41d2SMark Murray 		/* NOTREACHED */
298511b41d2SMark Murray 	case oForwardAgent:
299511b41d2SMark Murray 		intptr = &options->forward_agent;
300511b41d2SMark Murray parse_flag:
301c2d3a559SKris Kennaway 		arg = strdelim(&s);
302c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
303511b41d2SMark Murray 			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
304511b41d2SMark Murray 		value = 0;	/* To avoid compiler warning... */
305c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
306511b41d2SMark Murray 			value = 1;
307c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
308511b41d2SMark Murray 			value = 0;
309511b41d2SMark Murray 		else
310511b41d2SMark Murray 			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
311511b41d2SMark Murray 		if (*activep && *intptr == -1)
312511b41d2SMark Murray 			*intptr = value;
313511b41d2SMark Murray 		break;
314511b41d2SMark Murray 
315511b41d2SMark Murray 	case oForwardX11:
316511b41d2SMark Murray 		intptr = &options->forward_x11;
317511b41d2SMark Murray 		goto parse_flag;
318511b41d2SMark Murray 
319511b41d2SMark Murray 	case oGatewayPorts:
320511b41d2SMark Murray 		intptr = &options->gateway_ports;
321511b41d2SMark Murray 		goto parse_flag;
322511b41d2SMark Murray 
323511b41d2SMark Murray 	case oUsePrivilegedPort:
324511b41d2SMark Murray 		intptr = &options->use_privileged_port;
325511b41d2SMark Murray 		goto parse_flag;
326511b41d2SMark Murray 
327511b41d2SMark Murray 	case oRhostsAuthentication:
328511b41d2SMark Murray 		intptr = &options->rhosts_authentication;
329511b41d2SMark Murray 		goto parse_flag;
330511b41d2SMark Murray 
331511b41d2SMark Murray 	case oPasswordAuthentication:
332511b41d2SMark Murray 		intptr = &options->password_authentication;
333511b41d2SMark Murray 		goto parse_flag;
334511b41d2SMark Murray 
33509958426SBrian Feldman 	case oKbdInteractiveAuthentication:
33609958426SBrian Feldman 		intptr = &options->kbd_interactive_authentication;
33709958426SBrian Feldman 		goto parse_flag;
33809958426SBrian Feldman 
33909958426SBrian Feldman 	case oKbdInteractiveDevices:
34009958426SBrian Feldman 		charptr = &options->kbd_interactive_devices;
34109958426SBrian Feldman 		goto parse_string;
34209958426SBrian Feldman 
343ca3176e7SBrian Feldman 	case oPubkeyAuthentication:
344ca3176e7SBrian Feldman 		intptr = &options->pubkey_authentication;
345e8aafc91SKris Kennaway 		goto parse_flag;
346e8aafc91SKris Kennaway 
347511b41d2SMark Murray 	case oRSAAuthentication:
348511b41d2SMark Murray 		intptr = &options->rsa_authentication;
349511b41d2SMark Murray 		goto parse_flag;
350511b41d2SMark Murray 
351511b41d2SMark Murray 	case oRhostsRSAAuthentication:
352511b41d2SMark Murray 		intptr = &options->rhosts_rsa_authentication;
353511b41d2SMark Murray 		goto parse_flag;
354511b41d2SMark Murray 
355ca3176e7SBrian Feldman 	case oHostbasedAuthentication:
356ca3176e7SBrian Feldman 		intptr = &options->hostbased_authentication;
357511b41d2SMark Murray 		goto parse_flag;
358511b41d2SMark Murray 
359af12a3e7SDag-Erling Smørgrav 	case oChallengeResponseAuthentication:
360af12a3e7SDag-Erling Smørgrav 		intptr = &options->challenge_response_authentication;
361af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
362cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
363cb96ab36SAssar Westerlund 	case oKerberosAuthentication:
364cb96ab36SAssar Westerlund 		intptr = &options->kerberos_authentication;
365511b41d2SMark Murray 		goto parse_flag;
366af12a3e7SDag-Erling Smørgrav #endif
367af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
368af12a3e7SDag-Erling Smørgrav 	case oKerberosTgtPassing:
369af12a3e7SDag-Erling Smørgrav 		intptr = &options->kerberos_tgt_passing;
370ca3176e7SBrian Feldman 		goto parse_flag;
371af12a3e7SDag-Erling Smørgrav #endif
372511b41d2SMark Murray #ifdef AFS
373511b41d2SMark Murray 	case oAFSTokenPassing:
374511b41d2SMark Murray 		intptr = &options->afs_token_passing;
375511b41d2SMark Murray 		goto parse_flag;
376511b41d2SMark Murray #endif
377511b41d2SMark Murray 	case oFallBackToRsh:
378511b41d2SMark Murray 		intptr = &options->fallback_to_rsh;
379511b41d2SMark Murray 		goto parse_flag;
380511b41d2SMark Murray 
381511b41d2SMark Murray 	case oUseRsh:
382511b41d2SMark Murray 		intptr = &options->use_rsh;
383511b41d2SMark Murray 		goto parse_flag;
384511b41d2SMark Murray 
385511b41d2SMark Murray 	case oBatchMode:
386511b41d2SMark Murray 		intptr = &options->batch_mode;
387511b41d2SMark Murray 		goto parse_flag;
388511b41d2SMark Murray 
389511b41d2SMark Murray 	case oCheckHostIP:
390511b41d2SMark Murray 		intptr = &options->check_host_ip;
391511b41d2SMark Murray 		goto parse_flag;
392511b41d2SMark Murray 
393511b41d2SMark Murray 	case oStrictHostKeyChecking:
394511b41d2SMark Murray 		intptr = &options->strict_host_key_checking;
395c2d3a559SKris Kennaway 		arg = strdelim(&s);
396c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
397ca3176e7SBrian Feldman 			fatal("%.200s line %d: Missing yes/no/ask argument.",
398511b41d2SMark Murray 			    filename, linenum);
399511b41d2SMark Murray 		value = 0;	/* To avoid compiler warning... */
400c2d3a559SKris Kennaway 		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
401511b41d2SMark Murray 			value = 1;
402c2d3a559SKris Kennaway 		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
403511b41d2SMark Murray 			value = 0;
404c2d3a559SKris Kennaway 		else if (strcmp(arg, "ask") == 0)
405511b41d2SMark Murray 			value = 2;
406511b41d2SMark Murray 		else
407511b41d2SMark Murray 			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
408511b41d2SMark Murray 		if (*activep && *intptr == -1)
409511b41d2SMark Murray 			*intptr = value;
410511b41d2SMark Murray 		break;
411511b41d2SMark Murray 
412511b41d2SMark Murray 	case oCompression:
413511b41d2SMark Murray 		intptr = &options->compression;
414511b41d2SMark Murray 		goto parse_flag;
415511b41d2SMark Murray 
416511b41d2SMark Murray 	case oKeepAlives:
417511b41d2SMark Murray 		intptr = &options->keepalives;
418511b41d2SMark Murray 		goto parse_flag;
419511b41d2SMark Murray 
420af12a3e7SDag-Erling Smørgrav 	case oNoHostAuthenticationForLocalhost:
421af12a3e7SDag-Erling Smørgrav 		intptr = &options->no_host_authentication_for_localhost;
422af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
423af12a3e7SDag-Erling Smørgrav 
424511b41d2SMark Murray 	case oNumberOfPasswordPrompts:
425511b41d2SMark Murray 		intptr = &options->number_of_password_prompts;
426511b41d2SMark Murray 		goto parse_int;
427511b41d2SMark Murray 
428511b41d2SMark Murray 	case oCompressionLevel:
429511b41d2SMark Murray 		intptr = &options->compression_level;
430511b41d2SMark Murray 		goto parse_int;
431511b41d2SMark Murray 
432511b41d2SMark Murray 	case oIdentityFile:
433c2d3a559SKris Kennaway 		arg = strdelim(&s);
434c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
435511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
436511b41d2SMark Murray 		if (*activep) {
437ca3176e7SBrian Feldman 			intptr = &options->num_identity_files;
438e8aafc91SKris Kennaway 			if (*intptr >= SSH_MAX_IDENTITY_FILES)
439511b41d2SMark Murray 				fatal("%.200s line %d: Too many identity files specified (max %d).",
440511b41d2SMark Murray 				    filename, linenum, SSH_MAX_IDENTITY_FILES);
441ca3176e7SBrian Feldman 			charptr =  &options->identity_files[*intptr];
442c2d3a559SKris Kennaway 			*charptr = xstrdup(arg);
443e8aafc91SKris Kennaway 			*intptr = *intptr + 1;
444511b41d2SMark Murray 		}
445511b41d2SMark Murray 		break;
446511b41d2SMark Murray 
447c2d3a559SKris Kennaway 	case oXAuthLocation:
448c2d3a559SKris Kennaway 		charptr=&options->xauth_location;
449c2d3a559SKris Kennaway 		goto parse_string;
450c2d3a559SKris Kennaway 
451511b41d2SMark Murray 	case oUser:
452511b41d2SMark Murray 		charptr = &options->user;
453511b41d2SMark Murray parse_string:
454c2d3a559SKris Kennaway 		arg = strdelim(&s);
455c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
456511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
457511b41d2SMark Murray 		if (*activep && *charptr == NULL)
458c2d3a559SKris Kennaway 			*charptr = xstrdup(arg);
459511b41d2SMark Murray 		break;
460511b41d2SMark Murray 
461511b41d2SMark Murray 	case oGlobalKnownHostsFile:
462511b41d2SMark Murray 		charptr = &options->system_hostfile;
463511b41d2SMark Murray 		goto parse_string;
464511b41d2SMark Murray 
465511b41d2SMark Murray 	case oUserKnownHostsFile:
466511b41d2SMark Murray 		charptr = &options->user_hostfile;
467511b41d2SMark Murray 		goto parse_string;
468511b41d2SMark Murray 
469e8aafc91SKris Kennaway 	case oGlobalKnownHostsFile2:
470e8aafc91SKris Kennaway 		charptr = &options->system_hostfile2;
471e8aafc91SKris Kennaway 		goto parse_string;
472e8aafc91SKris Kennaway 
473e8aafc91SKris Kennaway 	case oUserKnownHostsFile2:
474e8aafc91SKris Kennaway 		charptr = &options->user_hostfile2;
475e8aafc91SKris Kennaway 		goto parse_string;
476e8aafc91SKris Kennaway 
477511b41d2SMark Murray 	case oHostName:
478511b41d2SMark Murray 		charptr = &options->hostname;
479511b41d2SMark Murray 		goto parse_string;
480511b41d2SMark Murray 
481ca3176e7SBrian Feldman 	case oHostKeyAlias:
482ca3176e7SBrian Feldman 		charptr = &options->host_key_alias;
483ca3176e7SBrian Feldman 		goto parse_string;
484ca3176e7SBrian Feldman 
485ca3176e7SBrian Feldman 	case oPreferredAuthentications:
486ca3176e7SBrian Feldman 		charptr = &options->preferred_authentications;
487ca3176e7SBrian Feldman 		goto parse_string;
488ca3176e7SBrian Feldman 
489af12a3e7SDag-Erling Smørgrav 	case oBindAddress:
490af12a3e7SDag-Erling Smørgrav 		charptr = &options->bind_address;
491af12a3e7SDag-Erling Smørgrav 		goto parse_string;
492af12a3e7SDag-Erling Smørgrav 
493af12a3e7SDag-Erling Smørgrav 	case oSmartcardDevice:
494af12a3e7SDag-Erling Smørgrav 		charptr = &options->smartcard_device;
495af12a3e7SDag-Erling Smørgrav 		goto parse_string;
496af12a3e7SDag-Erling Smørgrav 
497511b41d2SMark Murray 	case oProxyCommand:
498511b41d2SMark Murray 		charptr = &options->proxy_command;
499511b41d2SMark Murray 		string = xstrdup("");
500c2d3a559SKris Kennaway 		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
501c2d3a559SKris Kennaway 			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
502511b41d2SMark Murray 			strcat(string, " ");
503c2d3a559SKris Kennaway 			strcat(string, arg);
504511b41d2SMark Murray 		}
505511b41d2SMark Murray 		if (*activep && *charptr == NULL)
506511b41d2SMark Murray 			*charptr = string;
507511b41d2SMark Murray 		else
508511b41d2SMark Murray 			xfree(string);
509511b41d2SMark Murray 		return 0;
510511b41d2SMark Murray 
511511b41d2SMark Murray 	case oPort:
512511b41d2SMark Murray 		intptr = &options->port;
513511b41d2SMark Murray parse_int:
514c2d3a559SKris Kennaway 		arg = strdelim(&s);
515c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
516511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
517c2d3a559SKris Kennaway 		if (arg[0] < '0' || arg[0] > '9')
518511b41d2SMark Murray 			fatal("%.200s line %d: Bad number.", filename, linenum);
519511b41d2SMark Murray 
520511b41d2SMark Murray 		/* Octal, decimal, or hex format? */
521c2d3a559SKris Kennaway 		value = strtol(arg, &endofnumber, 0);
522c2d3a559SKris Kennaway 		if (arg == endofnumber)
523511b41d2SMark Murray 			fatal("%.200s line %d: Bad number.", filename, linenum);
524511b41d2SMark Murray 		if (*activep && *intptr == -1)
525511b41d2SMark Murray 			*intptr = value;
526511b41d2SMark Murray 		break;
527511b41d2SMark Murray 
528511b41d2SMark Murray 	case oConnectionAttempts:
529511b41d2SMark Murray 		intptr = &options->connection_attempts;
530511b41d2SMark Murray 		goto parse_int;
531511b41d2SMark Murray 
532511b41d2SMark Murray 	case oCipher:
533511b41d2SMark Murray 		intptr = &options->cipher;
534c2d3a559SKris Kennaway 		arg = strdelim(&s);
535c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
536db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
537c2d3a559SKris Kennaway 		value = cipher_number(arg);
538511b41d2SMark Murray 		if (value == -1)
539511b41d2SMark Murray 			fatal("%.200s line %d: Bad cipher '%s'.",
540c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
541511b41d2SMark Murray 		if (*activep && *intptr == -1)
542511b41d2SMark Murray 			*intptr = value;
543511b41d2SMark Murray 		break;
544511b41d2SMark Murray 
545e8aafc91SKris Kennaway 	case oCiphers:
546c2d3a559SKris Kennaway 		arg = strdelim(&s);
547c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
548db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
549c2d3a559SKris Kennaway 		if (!ciphers_valid(arg))
550e8aafc91SKris Kennaway 			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
551c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
552e8aafc91SKris Kennaway 		if (*activep && options->ciphers == NULL)
553c2d3a559SKris Kennaway 			options->ciphers = xstrdup(arg);
554e8aafc91SKris Kennaway 		break;
555e8aafc91SKris Kennaway 
556ca3176e7SBrian Feldman 	case oMacs:
557ca3176e7SBrian Feldman 		arg = strdelim(&s);
558ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
559ca3176e7SBrian Feldman 			fatal("%.200s line %d: Missing argument.", filename, linenum);
560ca3176e7SBrian Feldman 		if (!mac_valid(arg))
561ca3176e7SBrian Feldman 			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
562ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
563ca3176e7SBrian Feldman 		if (*activep && options->macs == NULL)
564ca3176e7SBrian Feldman 			options->macs = xstrdup(arg);
565ca3176e7SBrian Feldman 		break;
566ca3176e7SBrian Feldman 
567ca3176e7SBrian Feldman 	case oHostKeyAlgorithms:
568ca3176e7SBrian Feldman 		arg = strdelim(&s);
569ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
570ca3176e7SBrian Feldman 			fatal("%.200s line %d: Missing argument.", filename, linenum);
571ca3176e7SBrian Feldman 		if (!key_names_valid2(arg))
572ca3176e7SBrian Feldman 			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
573ca3176e7SBrian Feldman 			    filename, linenum, arg ? arg : "<NONE>");
574ca3176e7SBrian Feldman 		if (*activep && options->hostkeyalgorithms == NULL)
575ca3176e7SBrian Feldman 			options->hostkeyalgorithms = xstrdup(arg);
576ca3176e7SBrian Feldman 		break;
577ca3176e7SBrian Feldman 
578e8aafc91SKris Kennaway 	case oProtocol:
579e8aafc91SKris Kennaway 		intptr = &options->protocol;
580c2d3a559SKris Kennaway 		arg = strdelim(&s);
581c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
582db1cb46cSKris Kennaway 			fatal("%.200s line %d: Missing argument.", filename, linenum);
583c2d3a559SKris Kennaway 		value = proto_spec(arg);
584e8aafc91SKris Kennaway 		if (value == SSH_PROTO_UNKNOWN)
585e8aafc91SKris Kennaway 			fatal("%.200s line %d: Bad protocol spec '%s'.",
586c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
587e8aafc91SKris Kennaway 		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
588e8aafc91SKris Kennaway 			*intptr = value;
589e8aafc91SKris Kennaway 		break;
590e8aafc91SKris Kennaway 
591511b41d2SMark Murray 	case oLogLevel:
592511b41d2SMark Murray 		intptr = (int *) &options->log_level;
593c2d3a559SKris Kennaway 		arg = strdelim(&s);
594c2d3a559SKris Kennaway 		value = log_level_number(arg);
595af12a3e7SDag-Erling Smørgrav 		if (value == SYSLOG_LEVEL_NOT_SET)
596ca3176e7SBrian Feldman 			fatal("%.200s line %d: unsupported log level '%s'",
597c2d3a559SKris Kennaway 			    filename, linenum, arg ? arg : "<NONE>");
598af12a3e7SDag-Erling Smørgrav 		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
599511b41d2SMark Murray 			*intptr = (LogLevel) value;
600511b41d2SMark Murray 		break;
601511b41d2SMark Murray 
602af12a3e7SDag-Erling Smørgrav 	case oLocalForward:
603511b41d2SMark Murray 	case oRemoteForward:
604c2d3a559SKris Kennaway 		arg = strdelim(&s);
605c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
606af12a3e7SDag-Erling Smørgrav 			fatal("%.200s line %d: Missing port argument.",
607af12a3e7SDag-Erling Smørgrav 			    filename, linenum);
608af12a3e7SDag-Erling Smørgrav 		if ((fwd_port = a2port(arg)) == 0)
609af12a3e7SDag-Erling Smørgrav 			fatal("%.200s line %d: Bad listen port.",
610511b41d2SMark Murray 			    filename, linenum);
611c2d3a559SKris Kennaway 		arg = strdelim(&s);
612c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
613511b41d2SMark Murray 			fatal("%.200s line %d: Missing second argument.",
614511b41d2SMark Murray 			    filename, linenum);
615af12a3e7SDag-Erling Smørgrav 		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
616af12a3e7SDag-Erling Smørgrav 		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
617af12a3e7SDag-Erling Smørgrav 			fatal("%.200s line %d: Bad forwarding specification.",
618511b41d2SMark Murray 			    filename, linenum);
619af12a3e7SDag-Erling Smørgrav 		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
620af12a3e7SDag-Erling Smørgrav 			fatal("%.200s line %d: Bad forwarding port.",
621511b41d2SMark Murray 			    filename, linenum);
622af12a3e7SDag-Erling Smørgrav 		if (*activep) {
623af12a3e7SDag-Erling Smørgrav 			if (opcode == oLocalForward)
624af12a3e7SDag-Erling Smørgrav 				add_local_forward(options, fwd_port, buf,
625af12a3e7SDag-Erling Smørgrav 				    fwd_host_port);
626af12a3e7SDag-Erling Smørgrav 			else if (opcode == oRemoteForward)
627af12a3e7SDag-Erling Smørgrav 				add_remote_forward(options, fwd_port, buf,
628af12a3e7SDag-Erling Smørgrav 				    fwd_host_port);
629af12a3e7SDag-Erling Smørgrav 		}
630511b41d2SMark Murray 		break;
631511b41d2SMark Murray 
632ca3176e7SBrian Feldman 	case oDynamicForward:
633ca3176e7SBrian Feldman 		arg = strdelim(&s);
634ca3176e7SBrian Feldman 		if (!arg || *arg == '\0')
635ca3176e7SBrian Feldman 			fatal("%.200s line %d: Missing port argument.",
636ca3176e7SBrian Feldman 			    filename, linenum);
637ca3176e7SBrian Feldman 		fwd_port = a2port(arg);
638ca3176e7SBrian Feldman 		if (fwd_port == 0)
639ca3176e7SBrian Feldman 			fatal("%.200s line %d: Badly formatted port number.",
640ca3176e7SBrian Feldman 			    filename, linenum);
641af12a3e7SDag-Erling Smørgrav 		if (*activep)
642ca3176e7SBrian Feldman 			add_local_forward(options, fwd_port, "socks4", 0);
643ca3176e7SBrian Feldman 		break;
644ca3176e7SBrian Feldman 
645af12a3e7SDag-Erling Smørgrav 	case oClearAllForwardings:
646af12a3e7SDag-Erling Smørgrav 		intptr = &options->clear_forwardings;
647af12a3e7SDag-Erling Smørgrav 		goto parse_flag;
648af12a3e7SDag-Erling Smørgrav 
649511b41d2SMark Murray 	case oHost:
650511b41d2SMark Murray 		*activep = 0;
651c2d3a559SKris Kennaway 		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
652c2d3a559SKris Kennaway 			if (match_pattern(host, arg)) {
653c2d3a559SKris Kennaway 				debug("Applying options for %.100s", arg);
654511b41d2SMark Murray 				*activep = 1;
655511b41d2SMark Murray 				break;
656511b41d2SMark Murray 			}
657c2d3a559SKris Kennaway 		/* Avoid garbage check below, as strdelim is done. */
658511b41d2SMark Murray 		return 0;
659511b41d2SMark Murray 
660511b41d2SMark Murray 	case oEscapeChar:
661511b41d2SMark Murray 		intptr = &options->escape_char;
662c2d3a559SKris Kennaway 		arg = strdelim(&s);
663c2d3a559SKris Kennaway 		if (!arg || *arg == '\0')
664511b41d2SMark Murray 			fatal("%.200s line %d: Missing argument.", filename, linenum);
665c2d3a559SKris Kennaway 		if (arg[0] == '^' && arg[2] == 0 &&
666ca3176e7SBrian Feldman 		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
667ca3176e7SBrian Feldman 			value = (u_char) arg[1] & 31;
668c2d3a559SKris Kennaway 		else if (strlen(arg) == 1)
669ca3176e7SBrian Feldman 			value = (u_char) arg[0];
670c2d3a559SKris Kennaway 		else if (strcmp(arg, "none") == 0)
671af12a3e7SDag-Erling Smørgrav 			value = SSH_ESCAPECHAR_NONE;
672511b41d2SMark Murray 		else {
673511b41d2SMark Murray 			fatal("%.200s line %d: Bad escape character.",
674511b41d2SMark Murray 			    filename, linenum);
675511b41d2SMark Murray 			/* NOTREACHED */
676511b41d2SMark Murray 			value = 0;	/* Avoid compiler warning. */
677511b41d2SMark Murray 		}
678511b41d2SMark Murray 		if (*activep && *intptr == -1)
679511b41d2SMark Murray 			*intptr = value;
680511b41d2SMark Murray 		break;
681511b41d2SMark Murray 
6829e2cbe04SDag-Erling Smørgrav 	case oVersionAddendum:
6839e2cbe04SDag-Erling Smørgrav 		ssh_version_set_addendum(strtok(s, "\n"));
6849e2cbe04SDag-Erling Smørgrav 		do {
6859e2cbe04SDag-Erling Smørgrav 			arg = strdelim(&s);
6869e2cbe04SDag-Erling Smørgrav 		} while (arg != NULL && *arg != '\0');
6879e2cbe04SDag-Erling Smørgrav 		break;
6889e2cbe04SDag-Erling Smørgrav 
689511b41d2SMark Murray 	default:
690511b41d2SMark Murray 		fatal("process_config_line: Unimplemented opcode %d", opcode);
691511b41d2SMark Murray 	}
692511b41d2SMark Murray 
693511b41d2SMark Murray 	/* Check that there is no garbage at end of line. */
694ca3176e7SBrian Feldman 	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
695c2d3a559SKris Kennaway 		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
696c2d3a559SKris Kennaway 		     filename, linenum, arg);
697c2d3a559SKris Kennaway 	}
698511b41d2SMark Murray 	return 0;
699511b41d2SMark Murray }
700511b41d2SMark Murray 
701511b41d2SMark Murray 
702511b41d2SMark Murray /*
703511b41d2SMark Murray  * Reads the config file and modifies the options accordingly.  Options
704511b41d2SMark Murray  * should already be initialized before this call.  This never returns if
705af12a3e7SDag-Erling Smørgrav  * there is an error.  If the file does not exist, this returns 0.
706511b41d2SMark Murray  */
707511b41d2SMark Murray 
708af12a3e7SDag-Erling Smørgrav int
709511b41d2SMark Murray read_config_file(const char *filename, const char *host, Options *options)
710511b41d2SMark Murray {
711511b41d2SMark Murray 	FILE *f;
712511b41d2SMark Murray 	char line[1024];
713511b41d2SMark Murray 	int active, linenum;
714511b41d2SMark Murray 	int bad_options = 0;
715511b41d2SMark Murray 
716511b41d2SMark Murray 	/* Open the file. */
717511b41d2SMark Murray 	f = fopen(filename, "r");
718511b41d2SMark Murray 	if (!f)
719af12a3e7SDag-Erling Smørgrav 		return 0;
720511b41d2SMark Murray 
721511b41d2SMark Murray 	debug("Reading configuration data %.200s", filename);
722511b41d2SMark Murray 
723511b41d2SMark Murray 	/*
724511b41d2SMark Murray 	 * Mark that we are now processing the options.  This flag is turned
725511b41d2SMark Murray 	 * on/off by Host specifications.
726511b41d2SMark Murray 	 */
727511b41d2SMark Murray 	active = 1;
728511b41d2SMark Murray 	linenum = 0;
729511b41d2SMark Murray 	while (fgets(line, sizeof(line), f)) {
730511b41d2SMark Murray 		/* Update line number counter. */
731511b41d2SMark Murray 		linenum++;
732511b41d2SMark Murray 		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
733511b41d2SMark Murray 			bad_options++;
734511b41d2SMark Murray 	}
735511b41d2SMark Murray 	fclose(f);
736511b41d2SMark Murray 	if (bad_options > 0)
737ca3176e7SBrian Feldman 		fatal("%s: terminating, %d bad configuration options",
738511b41d2SMark Murray 		    filename, bad_options);
739af12a3e7SDag-Erling Smørgrav 	return 1;
740511b41d2SMark Murray }
741511b41d2SMark Murray 
742511b41d2SMark Murray /*
743511b41d2SMark Murray  * Initializes options to special values that indicate that they have not yet
744511b41d2SMark Murray  * been set.  Read_config_file will only set options with this value. Options
745511b41d2SMark Murray  * are processed in the following order: command line, user config file,
746511b41d2SMark Murray  * system config file.  Last, fill_default_options is called.
747511b41d2SMark Murray  */
748511b41d2SMark Murray 
749511b41d2SMark Murray void
750511b41d2SMark Murray initialize_options(Options * options)
751511b41d2SMark Murray {
752511b41d2SMark Murray 	memset(options, 'X', sizeof(*options));
753511b41d2SMark Murray 	options->forward_agent = -1;
754511b41d2SMark Murray 	options->forward_x11 = -1;
755c2d3a559SKris Kennaway 	options->xauth_location = NULL;
756511b41d2SMark Murray 	options->gateway_ports = -1;
757511b41d2SMark Murray 	options->use_privileged_port = -1;
758511b41d2SMark Murray 	options->rhosts_authentication = -1;
759511b41d2SMark Murray 	options->rsa_authentication = -1;
760ca3176e7SBrian Feldman 	options->pubkey_authentication = -1;
761af12a3e7SDag-Erling Smørgrav 	options->challenge_response_authentication = -1;
762cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
763cb96ab36SAssar Westerlund 	options->kerberos_authentication = -1;
764511b41d2SMark Murray #endif
765af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
766af12a3e7SDag-Erling Smørgrav 	options->kerberos_tgt_passing = -1;
767af12a3e7SDag-Erling Smørgrav #endif
768511b41d2SMark Murray #ifdef AFS
769511b41d2SMark Murray 	options->afs_token_passing = -1;
770511b41d2SMark Murray #endif
771511b41d2SMark Murray 	options->password_authentication = -1;
77209958426SBrian Feldman 	options->kbd_interactive_authentication = -1;
77309958426SBrian Feldman 	options->kbd_interactive_devices = NULL;
774511b41d2SMark Murray 	options->rhosts_rsa_authentication = -1;
775ca3176e7SBrian Feldman 	options->hostbased_authentication = -1;
776511b41d2SMark Murray 	options->fallback_to_rsh = -1;
777511b41d2SMark Murray 	options->use_rsh = -1;
778511b41d2SMark Murray 	options->batch_mode = -1;
779511b41d2SMark Murray 	options->check_host_ip = -1;
780511b41d2SMark Murray 	options->strict_host_key_checking = -1;
781511b41d2SMark Murray 	options->compression = -1;
782511b41d2SMark Murray 	options->keepalives = -1;
783511b41d2SMark Murray 	options->compression_level = -1;
784511b41d2SMark Murray 	options->port = -1;
785511b41d2SMark Murray 	options->connection_attempts = -1;
786511b41d2SMark Murray 	options->number_of_password_prompts = -1;
787511b41d2SMark Murray 	options->cipher = -1;
788e8aafc91SKris Kennaway 	options->ciphers = NULL;
789ca3176e7SBrian Feldman 	options->macs = NULL;
790ca3176e7SBrian Feldman 	options->hostkeyalgorithms = NULL;
791e8aafc91SKris Kennaway 	options->protocol = SSH_PROTO_UNKNOWN;
792511b41d2SMark Murray 	options->num_identity_files = 0;
793511b41d2SMark Murray 	options->hostname = NULL;
794ca3176e7SBrian Feldman 	options->host_key_alias = NULL;
795511b41d2SMark Murray 	options->proxy_command = NULL;
796511b41d2SMark Murray 	options->user = NULL;
797511b41d2SMark Murray 	options->escape_char = -1;
798511b41d2SMark Murray 	options->system_hostfile = NULL;
799511b41d2SMark Murray 	options->user_hostfile = NULL;
800e8aafc91SKris Kennaway 	options->system_hostfile2 = NULL;
801e8aafc91SKris Kennaway 	options->user_hostfile2 = NULL;
802511b41d2SMark Murray 	options->num_local_forwards = 0;
803511b41d2SMark Murray 	options->num_remote_forwards = 0;
804af12a3e7SDag-Erling Smørgrav 	options->clear_forwardings = -1;
805af12a3e7SDag-Erling Smørgrav 	options->log_level = SYSLOG_LEVEL_NOT_SET;
806ca3176e7SBrian Feldman 	options->preferred_authentications = NULL;
807af12a3e7SDag-Erling Smørgrav 	options->bind_address = NULL;
808af12a3e7SDag-Erling Smørgrav 	options->smartcard_device = NULL;
809af12a3e7SDag-Erling Smørgrav 	options->no_host_authentication_for_localhost = - 1;
810511b41d2SMark Murray }
811511b41d2SMark Murray 
812511b41d2SMark Murray /*
813511b41d2SMark Murray  * Called after processing other sources of option data, this fills those
814511b41d2SMark Murray  * options for which no value has been specified with their default values.
815511b41d2SMark Murray  */
816511b41d2SMark Murray 
817511b41d2SMark Murray void
818511b41d2SMark Murray fill_default_options(Options * options)
819511b41d2SMark Murray {
820ca3176e7SBrian Feldman 	int len;
821ca3176e7SBrian Feldman 
822511b41d2SMark Murray 	if (options->forward_agent == -1)
823db1cb46cSKris Kennaway 		options->forward_agent = 0;
824511b41d2SMark Murray 	if (options->forward_x11 == -1)
8255dc73ebeSBrian Feldman 		options->forward_x11 = 0;
826c2d3a559SKris Kennaway 	if (options->xauth_location == NULL)
827af12a3e7SDag-Erling Smørgrav 		options->xauth_location = _PATH_XAUTH;
828511b41d2SMark Murray 	if (options->gateway_ports == -1)
829511b41d2SMark Murray 		options->gateway_ports = 0;
830511b41d2SMark Murray 	if (options->use_privileged_port == -1)
831ca3176e7SBrian Feldman 		options->use_privileged_port = 0;
832511b41d2SMark Murray 	if (options->rhosts_authentication == -1)
833511b41d2SMark Murray 		options->rhosts_authentication = 1;
834511b41d2SMark Murray 	if (options->rsa_authentication == -1)
835511b41d2SMark Murray 		options->rsa_authentication = 1;
836ca3176e7SBrian Feldman 	if (options->pubkey_authentication == -1)
837ca3176e7SBrian Feldman 		options->pubkey_authentication = 1;
838af12a3e7SDag-Erling Smørgrav 	if (options->challenge_response_authentication == -1)
839af12a3e7SDag-Erling Smørgrav 		options->challenge_response_authentication = 1;
840cb96ab36SAssar Westerlund #if defined(KRB4) || defined(KRB5)
841cb96ab36SAssar Westerlund 	if (options->kerberos_authentication == -1)
842cb96ab36SAssar Westerlund 		options->kerberos_authentication = 1;
843af12a3e7SDag-Erling Smørgrav #endif
844af12a3e7SDag-Erling Smørgrav #if defined(AFS) || defined(KRB5)
845af12a3e7SDag-Erling Smørgrav 	if (options->kerberos_tgt_passing == -1)
846af12a3e7SDag-Erling Smørgrav 		options->kerberos_tgt_passing = 1;
847af12a3e7SDag-Erling Smørgrav #endif
848511b41d2SMark Murray #ifdef AFS
849511b41d2SMark Murray 	if (options->afs_token_passing == -1)
850511b41d2SMark Murray 		options->afs_token_passing = 1;
851af12a3e7SDag-Erling Smørgrav #endif
852511b41d2SMark Murray 	if (options->password_authentication == -1)
853511b41d2SMark Murray 		options->password_authentication = 1;
85409958426SBrian Feldman 	if (options->kbd_interactive_authentication == -1)
855ca3176e7SBrian Feldman 		options->kbd_interactive_authentication = 1;
856511b41d2SMark Murray 	if (options->rhosts_rsa_authentication == -1)
857511b41d2SMark Murray 		options->rhosts_rsa_authentication = 1;
858ca3176e7SBrian Feldman 	if (options->hostbased_authentication == -1)
859ca3176e7SBrian Feldman 		options->hostbased_authentication = 0;
860511b41d2SMark Murray 	if (options->fallback_to_rsh == -1)
861a3d67969SPeter Wemm 		options->fallback_to_rsh = 0;
862511b41d2SMark Murray 	if (options->use_rsh == -1)
863511b41d2SMark Murray 		options->use_rsh = 0;
864511b41d2SMark Murray 	if (options->batch_mode == -1)
865511b41d2SMark Murray 		options->batch_mode = 0;
866511b41d2SMark Murray 	if (options->check_host_ip == -1)
867a95c1225SBrian Feldman 		options->check_host_ip = 0;
868511b41d2SMark Murray 	if (options->strict_host_key_checking == -1)
869511b41d2SMark Murray 		options->strict_host_key_checking = 2;	/* 2 is default */
870511b41d2SMark Murray 	if (options->compression == -1)
871511b41d2SMark Murray 		options->compression = 0;
872511b41d2SMark Murray 	if (options->keepalives == -1)
873511b41d2SMark Murray 		options->keepalives = 1;
874511b41d2SMark Murray 	if (options->compression_level == -1)
875511b41d2SMark Murray 		options->compression_level = 6;
876511b41d2SMark Murray 	if (options->port == -1)
877511b41d2SMark Murray 		options->port = 0;	/* Filled in ssh_connect. */
878511b41d2SMark Murray 	if (options->connection_attempts == -1)
879af12a3e7SDag-Erling Smørgrav 		options->connection_attempts = 1;
880511b41d2SMark Murray 	if (options->number_of_password_prompts == -1)
881511b41d2SMark Murray 		options->number_of_password_prompts = 3;
882511b41d2SMark Murray 	/* Selected in ssh_login(). */
883511b41d2SMark Murray 	if (options->cipher == -1)
884511b41d2SMark Murray 		options->cipher = SSH_CIPHER_NOT_SET;
885e8aafc91SKris Kennaway 	/* options->ciphers, default set in myproposals.h */
886ca3176e7SBrian Feldman 	/* options->macs, default set in myproposals.h */
887ca3176e7SBrian Feldman 	/* options->hostkeyalgorithms, default set in myproposals.h */
888e8aafc91SKris Kennaway 	if (options->protocol == SSH_PROTO_UNKNOWN)
889ca3176e7SBrian Feldman 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
890511b41d2SMark Murray 	if (options->num_identity_files == 0) {
891ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_1) {
892ca3176e7SBrian Feldman 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
893ca3176e7SBrian Feldman 			options->identity_files[options->num_identity_files] =
894ca3176e7SBrian Feldman 			    xmalloc(len);
895ca3176e7SBrian Feldman 			snprintf(options->identity_files[options->num_identity_files++],
896ca3176e7SBrian Feldman 			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
897511b41d2SMark Murray 		}
898ca3176e7SBrian Feldman 		if (options->protocol & SSH_PROTO_2) {
899ca3176e7SBrian Feldman 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
900ca3176e7SBrian Feldman 			options->identity_files[options->num_identity_files] =
901ca3176e7SBrian Feldman 			    xmalloc(len);
902ca3176e7SBrian Feldman 			snprintf(options->identity_files[options->num_identity_files++],
903ca3176e7SBrian Feldman 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
904ca3176e7SBrian Feldman 
905ca3176e7SBrian Feldman 			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
906ca3176e7SBrian Feldman 			options->identity_files[options->num_identity_files] =
907ca3176e7SBrian Feldman 			    xmalloc(len);
908ca3176e7SBrian Feldman 			snprintf(options->identity_files[options->num_identity_files++],
909ca3176e7SBrian Feldman 			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
910ca3176e7SBrian Feldman 		}
911e8aafc91SKris Kennaway 	}
912511b41d2SMark Murray 	if (options->escape_char == -1)
913511b41d2SMark Murray 		options->escape_char = '~';
914511b41d2SMark Murray 	if (options->system_hostfile == NULL)
915ca3176e7SBrian Feldman 		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
916511b41d2SMark Murray 	if (options->user_hostfile == NULL)
917ca3176e7SBrian Feldman 		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
918e8aafc91SKris Kennaway 	if (options->system_hostfile2 == NULL)
919ca3176e7SBrian Feldman 		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
920e8aafc91SKris Kennaway 	if (options->user_hostfile2 == NULL)
921ca3176e7SBrian Feldman 		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
922af12a3e7SDag-Erling Smørgrav 	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
923511b41d2SMark Murray 		options->log_level = SYSLOG_LEVEL_INFO;
924af12a3e7SDag-Erling Smørgrav 	if (options->clear_forwardings == 1)
925af12a3e7SDag-Erling Smørgrav 		clear_forwardings(options);
926af12a3e7SDag-Erling Smørgrav 	if (options->no_host_authentication_for_localhost == - 1)
927af12a3e7SDag-Erling Smørgrav 		options->no_host_authentication_for_localhost = 0;
928511b41d2SMark Murray 	/* options->proxy_command should not be set by default */
929511b41d2SMark Murray 	/* options->user will be set in the main program if appropriate */
930511b41d2SMark Murray 	/* options->hostname will be set in the main program if appropriate */
931ca3176e7SBrian Feldman 	/* options->host_key_alias should not be set by default */
932ca3176e7SBrian Feldman 	/* options->preferred_authentications will be set in ssh */
933511b41d2SMark Murray }
934