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