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