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