readconf.c revision 92559
12061Sjkh/*
250479Speter * Author: Tatu Ylonen <ylo@cs.hut.fi>
32061Sjkh * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
438666Sjb *                    All rights reserved
532427Sjb * Functions for reading the configuration files.
638666Sjb *
738666Sjb * As far as I am concerned, the code I have written for this software
838666Sjb * can be used freely for any purpose.  Any derived versions of this
938666Sjb * software must be clearly marked as such, and if the derived work is
1064049Salex * incompatible with the protocol description in the RFC file, it must be
1164049Salex * called by a name other than "ssh" or "Secure Shell".
1266071Smarkm */
1373504Sobrien
1438666Sjb#include "includes.h"
1544918SjkhRCSID("$OpenBSD: readconf.c,v 1.95 2002/02/04 12:15:25 markus Exp $");
1638666SjbRCSID("$FreeBSD: head/crypto/openssh/readconf.c 92559 2002-03-18 10:09:43Z des $");
1738666Sjb
1838666Sjb#include "ssh.h"
1938666Sjb#include "xmalloc.h"
2038666Sjb#include "compat.h"
2138666Sjb#include "cipher.h"
2238666Sjb#include "pathnames.h"
2338978Sjb#include "log.h"
2438978Sjb#include "readconf.h"
2532427Sjb#include "match.h"
2638666Sjb#include "misc.h"
2738666Sjb#include "kex.h"
2838666Sjb#include "mac.h"
2938666Sjb
3038666Sjb/* Format of the configuration file:
3138666Sjb
3217308Speter   # Configuration data is parsed as follows:
3391606Skeramida   #  1. command line options
3419175Sbde   #  2. user-specific file
3538666Sjb   #  3. system-wide file
3638666Sjb   # Any configuration value is only changed the first time it is set.
3738042Sbde   # Thus, host-specific definitions should be at the beginning of the
3839726Sjb   # configuration file, and defaults at the end.
3938666Sjb
4038666Sjb   # Host-specific declarations.  These may override anything above.  A single
4138042Sbde   # host may match multiple declarations; these are processed in the order
4238666Sjb   # that they are given in.
4349315Shoek
4417308Speter   Host *.ngs.fi ngs.fi
4538666Sjb     FallBackToRsh no
4638666Sjb
4738666Sjb   Host fake.com
4838666Sjb     HostName another.host.name.real.org
4917308Speter     User blaah
5045108Sobrien     Port 34289
5142128Speter     ForwardX11 no
5242128Speter     ForwardAgent no
5338666Sjb
5451361Sjb   Host books.com
5538666Sjb     RemoteForward 9999 shadows.cs.hut.fi:9999
5617308Speter     Cipher 3des
5738666Sjb
5817308Speter   Host fascist.blob.com
5938666Sjb     Port 23123
6017308Speter     User tylonen
6127910Sasami     RhostsAuthentication no
6243226Sjkh     PasswordAuthentication no
6343226Sjkh
6443226Sjkh   Host puukko.hut.fi
6538666Sjb     User t35124p
6627910Sasami     ProxyCommand ssh-proxy %h %p
6738666Sjb
6838666Sjb   Host *.fr
6938666Sjb     UseRsh yes
7027910Sasami
7138666Sjb   Host *.su
7238666Sjb     Cipher none
7343226Sjkh     PasswordAuthentication no
7443226Sjkh
7527910Sasami   # Defaults for various options
7638666Sjb   Host *
7738666Sjb     ForwardAgent no
7827910Sasami     ForwardX11 no
7938666Sjb     RhostsAuthentication yes
8027910Sasami     PasswordAuthentication yes
8117308Speter     RSAAuthentication yes
8238666Sjb     RhostsRSAAuthentication yes
8338666Sjb     FallBackToRsh no
8417308Speter     UseRsh no
8595509Sru     StrictHostKeyChecking yes
8668987Smarcel     KeepAlives no
8795730Sru     IdentityFile ~/.ssh/identity
8895306Sru     Port 22
8995146Sgshapiro     EscapeChar ~
902061Sjkh
9195730Sru*/
9295730Sru
9395730Sru/* Keyword tokens. */
9495730Sru
9595730Srutypedef enum {
9655026Smarcel	oBadOption,
9755026Smarcel	oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
9854324Smarcel	oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
9917308Speter	oChallengeResponseAuthentication, oXAuthLocation,
10038666Sjb#if defined(KRB4) || defined(KRB5)
10117308Speter	oKerberosAuthentication,
10255678Smarcel#endif
10338666Sjb#if defined(AFS) || defined(KRB5)
10454324Smarcel	oKerberosTgtPassing,
1052302Spaul#endif
10639206Sjkh#ifdef AFS
10739206Sjkh	oAFSTokenPassing,
10839206Sjkh#endif
10973349Sru	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
11017308Speter	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
11154324Smarcel	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
11254324Smarcel	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
11354324Smarcel	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
11454324Smarcel	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
11554324Smarcel	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
11654324Smarcel	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
11754324Smarcel	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
11869659Sobrien	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
11954324Smarcel	oClearAllForwardings, oNoHostAuthenticationForLocalhost
12054324Smarcel} OpCodes;
12154324Smarcel
12254324Smarcel/* Textual representations of the tokens. */
12354324Smarcel
12454324Smarcelstatic struct {
12554324Smarcel	const char *name;
12654324Smarcel	OpCodes opcode;
12754324Smarcel} keywords[] = {
12854324Smarcel	{ "forwardagent", oForwardAgent },
12954324Smarcel	{ "forwardx11", oForwardX11 },
13054324Smarcel	{ "xauthlocation", oXAuthLocation },
13154324Smarcel	{ "gatewayports", oGatewayPorts },
13254324Smarcel	{ "useprivilegedport", oUsePrivilegedPort },
13354324Smarcel	{ "rhostsauthentication", oRhostsAuthentication },
13454324Smarcel	{ "passwordauthentication", oPasswordAuthentication },
13554324Smarcel	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
13654324Smarcel	{ "kbdinteractivedevices", oKbdInteractiveDevices },
13754324Smarcel	{ "rsaauthentication", oRSAAuthentication },
13873504Sobrien	{ "pubkeyauthentication", oPubkeyAuthentication },
13954324Smarcel	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
14054324Smarcel	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
14154324Smarcel	{ "hostbasedauthentication", oHostbasedAuthentication },
14295730Sru	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
14395730Sru	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
14495730Sru	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
14595730Sru#if defined(KRB4) || defined(KRB5)
14695730Sru	{ "kerberosauthentication", oKerberosAuthentication },
14795730Sru#endif
14895730Sru#if defined(AFS) || defined(KRB5)
14938666Sjb	{ "kerberostgtpassing", oKerberosTgtPassing },
15038666Sjb#endif
15117308Speter#ifdef AFS
15238666Sjb	{ "afstokenpassing", oAFSTokenPassing },
15338666Sjb#endif
15438666Sjb	{ "fallbacktorsh", oFallBackToRsh },
15517308Speter	{ "usersh", oUseRsh },
15655678Smarcel	{ "identityfile", oIdentityFile },
15755678Smarcel	{ "identityfile2", oIdentityFile },			/* alias */
15855678Smarcel	{ "hostname", oHostName },
15955678Smarcel	{ "hostkeyalias", oHostKeyAlias },
16055678Smarcel	{ "proxycommand", oProxyCommand },
16190395Sru	{ "port", oPort },
16290395Sru	{ "cipher", oCipher },
16390395Sru	{ "ciphers", oCiphers },
16490395Sru	{ "macs", oMacs },
16590395Sru	{ "protocol", oProtocol },
1662061Sjkh	{ "remoteforward", oRemoteForward },
16717308Speter	{ "localforward", oLocalForward },
16838666Sjb	{ "user", oUser },
16938666Sjb	{ "host", oHost },
17017308Speter	{ "escapechar", oEscapeChar },
17155678Smarcel	{ "globalknownhostsfile", oGlobalKnownHostsFile },
1723626Swollman	{ "userknownhostsfile", oUserKnownHostsFile },		/* obsolete */
17317308Speter	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
17455678Smarcel	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
17555678Smarcel	{ "connectionattempts", oConnectionAttempts },
17655678Smarcel	{ "batchmode", oBatchMode },
17755678Smarcel	{ "checkhostip", oCheckHostIP },
17855678Smarcel	{ "stricthostkeychecking", oStrictHostKeyChecking },
17955678Smarcel	{ "compression", oCompression },
18055678Smarcel	{ "compressionlevel", oCompressionLevel },
18155678Smarcel	{ "keepalive", oKeepAlives },
18255678Smarcel	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
18355678Smarcel	{ "loglevel", oLogLevel },
18455678Smarcel	{ "dynamicforward", oDynamicForward },
18555678Smarcel	{ "preferredauthentications", oPreferredAuthentications },
18655678Smarcel	{ "hostkeyalgorithms", oHostKeyAlgorithms },
18738666Sjb	{ "bindaddress", oBindAddress },
18838666Sjb	{ "smartcarddevice", oSmartcardDevice },
18917308Speter	{ "clearallforwardings", oClearAllForwardings },
19055678Smarcel	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
19138978Sjb	{ NULL, oBadOption }
1923626Swollman};
19317308Speter
19438666Sjb/*
19517308Speter * Adds a local TCP/IP port forward to options.  Never returns if there is an
19643226Sjkh * error.
19743226Sjkh */
19843226Sjkh
19938666Sjbvoid
20038666Sjbadd_local_forward(Options *options, u_short port, const char *host,
20144103Smsmith		  u_short host_port)
202{
203	Forward *fwd;
204	extern uid_t original_real_uid;
205	if (port < IPPORT_RESERVED && original_real_uid != 0)
206		fatal("Privileged ports can only be forwarded by root.");
207	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
208		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
209	fwd = &options->local_forwards[options->num_local_forwards++];
210	fwd->port = port;
211	fwd->host = xstrdup(host);
212	fwd->host_port = host_port;
213}
214
215/*
216 * Adds a remote TCP/IP port forward to options.  Never returns if there is
217 * an error.
218 */
219
220void
221add_remote_forward(Options *options, u_short port, const char *host,
222		   u_short host_port)
223{
224	Forward *fwd;
225	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
226		fatal("Too many remote forwards (max %d).",
227		    SSH_MAX_FORWARDS_PER_DIRECTION);
228	fwd = &options->remote_forwards[options->num_remote_forwards++];
229	fwd->port = port;
230	fwd->host = xstrdup(host);
231	fwd->host_port = host_port;
232}
233
234static void
235clear_forwardings(Options *options)
236{
237	int i;
238
239	for (i = 0; i < options->num_local_forwards; i++)
240		xfree(options->local_forwards[i].host);
241	options->num_local_forwards = 0;
242	for (i = 0; i < options->num_remote_forwards; i++)
243		xfree(options->remote_forwards[i].host);
244	options->num_remote_forwards = 0;
245}
246
247/*
248 * Returns the number of the token pointed to by cp or oBadOption.
249 */
250
251static OpCodes
252parse_token(const char *cp, const char *filename, int linenum)
253{
254	u_int i;
255
256	for (i = 0; keywords[i].name; i++)
257		if (strcasecmp(cp, keywords[i].name) == 0)
258			return keywords[i].opcode;
259
260	error("%s: line %d: Bad configuration option: %s",
261	    filename, linenum, cp);
262	return oBadOption;
263}
264
265/*
266 * Processes a single option line as used in the configuration files. This
267 * only sets those values that have not already been set.
268 */
269
270int
271process_config_line(Options *options, const char *host,
272		    char *line, const char *filename, int linenum,
273		    int *activep)
274{
275	char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
276	int opcode, *intptr, value;
277	u_short fwd_port, fwd_host_port;
278	char sfwd_host_port[6];
279
280	s = line;
281	/* Get the keyword. (Each line is supposed to begin with a keyword). */
282	keyword = strdelim(&s);
283	/* Ignore leading whitespace. */
284	if (*keyword == '\0')
285		keyword = strdelim(&s);
286	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
287		return 0;
288
289	opcode = parse_token(keyword, filename, linenum);
290
291	switch (opcode) {
292	case oBadOption:
293		/* don't panic, but count bad options */
294		return -1;
295		/* NOTREACHED */
296	case oForwardAgent:
297		intptr = &options->forward_agent;
298parse_flag:
299		arg = strdelim(&s);
300		if (!arg || *arg == '\0')
301			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
302		value = 0;	/* To avoid compiler warning... */
303		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
304			value = 1;
305		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
306			value = 0;
307		else
308			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
309		if (*activep && *intptr == -1)
310			*intptr = value;
311		break;
312
313	case oForwardX11:
314		intptr = &options->forward_x11;
315		goto parse_flag;
316
317	case oGatewayPorts:
318		intptr = &options->gateway_ports;
319		goto parse_flag;
320
321	case oUsePrivilegedPort:
322		intptr = &options->use_privileged_port;
323		goto parse_flag;
324
325	case oRhostsAuthentication:
326		intptr = &options->rhosts_authentication;
327		goto parse_flag;
328
329	case oPasswordAuthentication:
330		intptr = &options->password_authentication;
331		goto parse_flag;
332
333	case oKbdInteractiveAuthentication:
334		intptr = &options->kbd_interactive_authentication;
335		goto parse_flag;
336
337	case oKbdInteractiveDevices:
338		charptr = &options->kbd_interactive_devices;
339		goto parse_string;
340
341	case oPubkeyAuthentication:
342		intptr = &options->pubkey_authentication;
343		goto parse_flag;
344
345	case oRSAAuthentication:
346		intptr = &options->rsa_authentication;
347		goto parse_flag;
348
349	case oRhostsRSAAuthentication:
350		intptr = &options->rhosts_rsa_authentication;
351		goto parse_flag;
352
353	case oHostbasedAuthentication:
354		intptr = &options->hostbased_authentication;
355		goto parse_flag;
356
357	case oChallengeResponseAuthentication:
358		intptr = &options->challenge_response_authentication;
359		goto parse_flag;
360#if defined(KRB4) || defined(KRB5)
361	case oKerberosAuthentication:
362		intptr = &options->kerberos_authentication;
363		goto parse_flag;
364#endif
365#if defined(AFS) || defined(KRB5)
366	case oKerberosTgtPassing:
367		intptr = &options->kerberos_tgt_passing;
368		goto parse_flag;
369#endif
370#ifdef AFS
371	case oAFSTokenPassing:
372		intptr = &options->afs_token_passing;
373		goto parse_flag;
374#endif
375	case oFallBackToRsh:
376		intptr = &options->fallback_to_rsh;
377		goto parse_flag;
378
379	case oUseRsh:
380		intptr = &options->use_rsh;
381		goto parse_flag;
382
383	case oBatchMode:
384		intptr = &options->batch_mode;
385		goto parse_flag;
386
387	case oCheckHostIP:
388		intptr = &options->check_host_ip;
389		goto parse_flag;
390
391	case oStrictHostKeyChecking:
392		intptr = &options->strict_host_key_checking;
393		arg = strdelim(&s);
394		if (!arg || *arg == '\0')
395			fatal("%.200s line %d: Missing yes/no/ask argument.",
396			    filename, linenum);
397		value = 0;	/* To avoid compiler warning... */
398		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
399			value = 1;
400		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
401			value = 0;
402		else if (strcmp(arg, "ask") == 0)
403			value = 2;
404		else
405			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
406		if (*activep && *intptr == -1)
407			*intptr = value;
408		break;
409
410	case oCompression:
411		intptr = &options->compression;
412		goto parse_flag;
413
414	case oKeepAlives:
415		intptr = &options->keepalives;
416		goto parse_flag;
417
418	case oNoHostAuthenticationForLocalhost:
419		intptr = &options->no_host_authentication_for_localhost;
420		goto parse_flag;
421
422	case oNumberOfPasswordPrompts:
423		intptr = &options->number_of_password_prompts;
424		goto parse_int;
425
426	case oCompressionLevel:
427		intptr = &options->compression_level;
428		goto parse_int;
429
430	case oIdentityFile:
431		arg = strdelim(&s);
432		if (!arg || *arg == '\0')
433			fatal("%.200s line %d: Missing argument.", filename, linenum);
434		if (*activep) {
435			intptr = &options->num_identity_files;
436			if (*intptr >= SSH_MAX_IDENTITY_FILES)
437				fatal("%.200s line %d: Too many identity files specified (max %d).",
438				    filename, linenum, SSH_MAX_IDENTITY_FILES);
439			charptr =  &options->identity_files[*intptr];
440			*charptr = xstrdup(arg);
441			*intptr = *intptr + 1;
442		}
443		break;
444
445	case oXAuthLocation:
446		charptr=&options->xauth_location;
447		goto parse_string;
448
449	case oUser:
450		charptr = &options->user;
451parse_string:
452		arg = strdelim(&s);
453		if (!arg || *arg == '\0')
454			fatal("%.200s line %d: Missing argument.", filename, linenum);
455		if (*activep && *charptr == NULL)
456			*charptr = xstrdup(arg);
457		break;
458
459	case oGlobalKnownHostsFile:
460		charptr = &options->system_hostfile;
461		goto parse_string;
462
463	case oUserKnownHostsFile:
464		charptr = &options->user_hostfile;
465		goto parse_string;
466
467	case oGlobalKnownHostsFile2:
468		charptr = &options->system_hostfile2;
469		goto parse_string;
470
471	case oUserKnownHostsFile2:
472		charptr = &options->user_hostfile2;
473		goto parse_string;
474
475	case oHostName:
476		charptr = &options->hostname;
477		goto parse_string;
478
479	case oHostKeyAlias:
480		charptr = &options->host_key_alias;
481		goto parse_string;
482
483	case oPreferredAuthentications:
484		charptr = &options->preferred_authentications;
485		goto parse_string;
486
487	case oBindAddress:
488		charptr = &options->bind_address;
489		goto parse_string;
490
491	case oSmartcardDevice:
492		charptr = &options->smartcard_device;
493		goto parse_string;
494
495	case oProxyCommand:
496		charptr = &options->proxy_command;
497		string = xstrdup("");
498		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
499			string = xrealloc(string, strlen(string) + strlen(arg) + 2);
500			strcat(string, " ");
501			strcat(string, arg);
502		}
503		if (*activep && *charptr == NULL)
504			*charptr = string;
505		else
506			xfree(string);
507		return 0;
508
509	case oPort:
510		intptr = &options->port;
511parse_int:
512		arg = strdelim(&s);
513		if (!arg || *arg == '\0')
514			fatal("%.200s line %d: Missing argument.", filename, linenum);
515		if (arg[0] < '0' || arg[0] > '9')
516			fatal("%.200s line %d: Bad number.", filename, linenum);
517
518		/* Octal, decimal, or hex format? */
519		value = strtol(arg, &endofnumber, 0);
520		if (arg == endofnumber)
521			fatal("%.200s line %d: Bad number.", filename, linenum);
522		if (*activep && *intptr == -1)
523			*intptr = value;
524		break;
525
526	case oConnectionAttempts:
527		intptr = &options->connection_attempts;
528		goto parse_int;
529
530	case oCipher:
531		intptr = &options->cipher;
532		arg = strdelim(&s);
533		if (!arg || *arg == '\0')
534			fatal("%.200s line %d: Missing argument.", filename, linenum);
535		value = cipher_number(arg);
536		if (value == -1)
537			fatal("%.200s line %d: Bad cipher '%s'.",
538			    filename, linenum, arg ? arg : "<NONE>");
539		if (*activep && *intptr == -1)
540			*intptr = value;
541		break;
542
543	case oCiphers:
544		arg = strdelim(&s);
545		if (!arg || *arg == '\0')
546			fatal("%.200s line %d: Missing argument.", filename, linenum);
547		if (!ciphers_valid(arg))
548			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
549			    filename, linenum, arg ? arg : "<NONE>");
550		if (*activep && options->ciphers == NULL)
551			options->ciphers = xstrdup(arg);
552		break;
553
554	case oMacs:
555		arg = strdelim(&s);
556		if (!arg || *arg == '\0')
557			fatal("%.200s line %d: Missing argument.", filename, linenum);
558		if (!mac_valid(arg))
559			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
560			    filename, linenum, arg ? arg : "<NONE>");
561		if (*activep && options->macs == NULL)
562			options->macs = xstrdup(arg);
563		break;
564
565	case oHostKeyAlgorithms:
566		arg = strdelim(&s);
567		if (!arg || *arg == '\0')
568			fatal("%.200s line %d: Missing argument.", filename, linenum);
569		if (!key_names_valid2(arg))
570			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
571			    filename, linenum, arg ? arg : "<NONE>");
572		if (*activep && options->hostkeyalgorithms == NULL)
573			options->hostkeyalgorithms = xstrdup(arg);
574		break;
575
576	case oProtocol:
577		intptr = &options->protocol;
578		arg = strdelim(&s);
579		if (!arg || *arg == '\0')
580			fatal("%.200s line %d: Missing argument.", filename, linenum);
581		value = proto_spec(arg);
582		if (value == SSH_PROTO_UNKNOWN)
583			fatal("%.200s line %d: Bad protocol spec '%s'.",
584			    filename, linenum, arg ? arg : "<NONE>");
585		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
586			*intptr = value;
587		break;
588
589	case oLogLevel:
590		intptr = (int *) &options->log_level;
591		arg = strdelim(&s);
592		value = log_level_number(arg);
593		if (value == SYSLOG_LEVEL_NOT_SET)
594			fatal("%.200s line %d: unsupported log level '%s'",
595			    filename, linenum, arg ? arg : "<NONE>");
596		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
597			*intptr = (LogLevel) value;
598		break;
599
600	case oLocalForward:
601	case oRemoteForward:
602		arg = strdelim(&s);
603		if (!arg || *arg == '\0')
604			fatal("%.200s line %d: Missing port argument.",
605			    filename, linenum);
606		if ((fwd_port = a2port(arg)) == 0)
607			fatal("%.200s line %d: Bad listen port.",
608			    filename, linenum);
609		arg = strdelim(&s);
610		if (!arg || *arg == '\0')
611			fatal("%.200s line %d: Missing second argument.",
612			    filename, linenum);
613		if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
614		    sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
615			fatal("%.200s line %d: Bad forwarding specification.",
616			    filename, linenum);
617		if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
618			fatal("%.200s line %d: Bad forwarding port.",
619			    filename, linenum);
620		if (*activep) {
621			if (opcode == oLocalForward)
622				add_local_forward(options, fwd_port, buf,
623				    fwd_host_port);
624			else if (opcode == oRemoteForward)
625				add_remote_forward(options, fwd_port, buf,
626				    fwd_host_port);
627		}
628		break;
629
630	case oDynamicForward:
631		arg = strdelim(&s);
632		if (!arg || *arg == '\0')
633			fatal("%.200s line %d: Missing port argument.",
634			    filename, linenum);
635		fwd_port = a2port(arg);
636		if (fwd_port == 0)
637			fatal("%.200s line %d: Badly formatted port number.",
638			    filename, linenum);
639		if (*activep)
640			add_local_forward(options, fwd_port, "socks4", 0);
641		break;
642
643	case oClearAllForwardings:
644		intptr = &options->clear_forwardings;
645		goto parse_flag;
646
647	case oHost:
648		*activep = 0;
649		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
650			if (match_pattern(host, arg)) {
651				debug("Applying options for %.100s", arg);
652				*activep = 1;
653				break;
654			}
655		/* Avoid garbage check below, as strdelim is done. */
656		return 0;
657
658	case oEscapeChar:
659		intptr = &options->escape_char;
660		arg = strdelim(&s);
661		if (!arg || *arg == '\0')
662			fatal("%.200s line %d: Missing argument.", filename, linenum);
663		if (arg[0] == '^' && arg[2] == 0 &&
664		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
665			value = (u_char) arg[1] & 31;
666		else if (strlen(arg) == 1)
667			value = (u_char) arg[0];
668		else if (strcmp(arg, "none") == 0)
669			value = SSH_ESCAPECHAR_NONE;
670		else {
671			fatal("%.200s line %d: Bad escape character.",
672			    filename, linenum);
673			/* NOTREACHED */
674			value = 0;	/* Avoid compiler warning. */
675		}
676		if (*activep && *intptr == -1)
677			*intptr = value;
678		break;
679
680	default:
681		fatal("process_config_line: Unimplemented opcode %d", opcode);
682	}
683
684	/* Check that there is no garbage at end of line. */
685	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
686		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
687		     filename, linenum, arg);
688	}
689	return 0;
690}
691
692
693/*
694 * Reads the config file and modifies the options accordingly.  Options
695 * should already be initialized before this call.  This never returns if
696 * there is an error.  If the file does not exist, this returns 0.
697 */
698
699int
700read_config_file(const char *filename, const char *host, Options *options)
701{
702	FILE *f;
703	char line[1024];
704	int active, linenum;
705	int bad_options = 0;
706
707	/* Open the file. */
708	f = fopen(filename, "r");
709	if (!f)
710		return 0;
711
712	debug("Reading configuration data %.200s", filename);
713
714	/*
715	 * Mark that we are now processing the options.  This flag is turned
716	 * on/off by Host specifications.
717	 */
718	active = 1;
719	linenum = 0;
720	while (fgets(line, sizeof(line), f)) {
721		/* Update line number counter. */
722		linenum++;
723		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
724			bad_options++;
725	}
726	fclose(f);
727	if (bad_options > 0)
728		fatal("%s: terminating, %d bad configuration options",
729		    filename, bad_options);
730	return 1;
731}
732
733/*
734 * Initializes options to special values that indicate that they have not yet
735 * been set.  Read_config_file will only set options with this value. Options
736 * are processed in the following order: command line, user config file,
737 * system config file.  Last, fill_default_options is called.
738 */
739
740void
741initialize_options(Options * options)
742{
743	memset(options, 'X', sizeof(*options));
744	options->forward_agent = -1;
745	options->forward_x11 = -1;
746	options->xauth_location = NULL;
747	options->gateway_ports = -1;
748	options->use_privileged_port = -1;
749	options->rhosts_authentication = -1;
750	options->rsa_authentication = -1;
751	options->pubkey_authentication = -1;
752	options->challenge_response_authentication = -1;
753#if defined(KRB4) || defined(KRB5)
754	options->kerberos_authentication = -1;
755#endif
756#if defined(AFS) || defined(KRB5)
757	options->kerberos_tgt_passing = -1;
758#endif
759#ifdef AFS
760	options->afs_token_passing = -1;
761#endif
762	options->password_authentication = -1;
763	options->kbd_interactive_authentication = -1;
764	options->kbd_interactive_devices = NULL;
765	options->rhosts_rsa_authentication = -1;
766	options->hostbased_authentication = -1;
767	options->fallback_to_rsh = -1;
768	options->use_rsh = -1;
769	options->batch_mode = -1;
770	options->check_host_ip = -1;
771	options->strict_host_key_checking = -1;
772	options->compression = -1;
773	options->keepalives = -1;
774	options->compression_level = -1;
775	options->port = -1;
776	options->connection_attempts = -1;
777	options->number_of_password_prompts = -1;
778	options->cipher = -1;
779	options->ciphers = NULL;
780	options->macs = NULL;
781	options->hostkeyalgorithms = NULL;
782	options->protocol = SSH_PROTO_UNKNOWN;
783	options->num_identity_files = 0;
784	options->hostname = NULL;
785	options->host_key_alias = NULL;
786	options->proxy_command = NULL;
787	options->user = NULL;
788	options->escape_char = -1;
789	options->system_hostfile = NULL;
790	options->user_hostfile = NULL;
791	options->system_hostfile2 = NULL;
792	options->user_hostfile2 = NULL;
793	options->num_local_forwards = 0;
794	options->num_remote_forwards = 0;
795	options->clear_forwardings = -1;
796	options->log_level = SYSLOG_LEVEL_NOT_SET;
797	options->preferred_authentications = NULL;
798	options->bind_address = NULL;
799	options->smartcard_device = NULL;
800	options->no_host_authentication_for_localhost = - 1;
801}
802
803/*
804 * Called after processing other sources of option data, this fills those
805 * options for which no value has been specified with their default values.
806 */
807
808void
809fill_default_options(Options * options)
810{
811	int len;
812
813	if (options->forward_agent == -1)
814		options->forward_agent = 0;
815	if (options->forward_x11 == -1)
816		options->forward_x11 = 0;
817	if (options->xauth_location == NULL)
818		options->xauth_location = _PATH_XAUTH;
819	if (options->gateway_ports == -1)
820		options->gateway_ports = 0;
821	if (options->use_privileged_port == -1)
822		options->use_privileged_port = 0;
823	if (options->rhosts_authentication == -1)
824		options->rhosts_authentication = 1;
825	if (options->rsa_authentication == -1)
826		options->rsa_authentication = 1;
827	if (options->pubkey_authentication == -1)
828		options->pubkey_authentication = 1;
829	if (options->challenge_response_authentication == -1)
830		options->challenge_response_authentication = 1;
831#if defined(KRB4) || defined(KRB5)
832	if (options->kerberos_authentication == -1)
833		options->kerberos_authentication = 1;
834#endif
835#if defined(AFS) || defined(KRB5)
836	if (options->kerberos_tgt_passing == -1)
837		options->kerberos_tgt_passing = 1;
838#endif
839#ifdef AFS
840	if (options->afs_token_passing == -1)
841		options->afs_token_passing = 1;
842#endif
843	if (options->password_authentication == -1)
844		options->password_authentication = 1;
845	if (options->kbd_interactive_authentication == -1)
846		options->kbd_interactive_authentication = 1;
847	if (options->rhosts_rsa_authentication == -1)
848		options->rhosts_rsa_authentication = 1;
849	if (options->hostbased_authentication == -1)
850		options->hostbased_authentication = 0;
851	if (options->fallback_to_rsh == -1)
852		options->fallback_to_rsh = 0;
853	if (options->use_rsh == -1)
854		options->use_rsh = 0;
855	if (options->batch_mode == -1)
856		options->batch_mode = 0;
857	if (options->check_host_ip == -1)
858		options->check_host_ip = 0;
859	if (options->strict_host_key_checking == -1)
860		options->strict_host_key_checking = 2;	/* 2 is default */
861	if (options->compression == -1)
862		options->compression = 0;
863	if (options->keepalives == -1)
864		options->keepalives = 1;
865	if (options->compression_level == -1)
866		options->compression_level = 6;
867	if (options->port == -1)
868		options->port = 0;	/* Filled in ssh_connect. */
869	if (options->connection_attempts == -1)
870		options->connection_attempts = 1;
871	if (options->number_of_password_prompts == -1)
872		options->number_of_password_prompts = 3;
873	/* Selected in ssh_login(). */
874	if (options->cipher == -1)
875		options->cipher = SSH_CIPHER_NOT_SET;
876	/* options->ciphers, default set in myproposals.h */
877	/* options->macs, default set in myproposals.h */
878	/* options->hostkeyalgorithms, default set in myproposals.h */
879	if (options->protocol == SSH_PROTO_UNKNOWN)
880		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
881	if (options->num_identity_files == 0) {
882		if (options->protocol & SSH_PROTO_1) {
883			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
884			options->identity_files[options->num_identity_files] =
885			    xmalloc(len);
886			snprintf(options->identity_files[options->num_identity_files++],
887			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
888		}
889		if (options->protocol & SSH_PROTO_2) {
890			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
891			options->identity_files[options->num_identity_files] =
892			    xmalloc(len);
893			snprintf(options->identity_files[options->num_identity_files++],
894			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
895
896			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
897			options->identity_files[options->num_identity_files] =
898			    xmalloc(len);
899			snprintf(options->identity_files[options->num_identity_files++],
900			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
901		}
902	}
903	if (options->escape_char == -1)
904		options->escape_char = '~';
905	if (options->system_hostfile == NULL)
906		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
907	if (options->user_hostfile == NULL)
908		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
909	if (options->system_hostfile2 == NULL)
910		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
911	if (options->user_hostfile2 == NULL)
912		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
913	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
914		options->log_level = SYSLOG_LEVEL_INFO;
915	if (options->clear_forwardings == 1)
916		clear_forwardings(options);
917	if (options->no_host_authentication_for_localhost == - 1)
918		options->no_host_authentication_for_localhost = 0;
919	/* options->proxy_command should not be set by default */
920	/* options->user will be set in the main program if appropriate */
921	/* options->hostname will be set in the main program if appropriate */
922	/* options->host_key_alias should not be set by default */
923	/* options->preferred_authentications will be set in ssh */
924}
925