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