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