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