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