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