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