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