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