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