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