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