]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
merge OpenSSH 3.8p1 with trunk
[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.127 2003/12/16 15:49:51 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      TcpKeepAlive no
82      IdentityFile ~/.ssh/identity
83      Port 22
84      EscapeChar ~
85
86 */
87
88 /* Keyword tokens. */
89
90 typedef enum {
91         oBadOption,
92         oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
93         oPasswordAuthentication, oRSAAuthentication,
94         oChallengeResponseAuthentication, oXAuthLocation,
95         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
96         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
97         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
98         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
99         oCompressionLevel, oTCPKeepAlive, 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         oServerAliveInterval, oServerAliveCountMax,
109         oDeprecated, oUnsupported
110 } OpCodes;
111
112 /* Textual representations of the tokens. */
113
114 static struct {
115         const char *name;
116         OpCodes opcode;
117 } keywords[] = {
118         { "forwardagent", oForwardAgent },
119         { "forwardx11", oForwardX11 },
120         { "forwardx11trusted", oForwardX11Trusted },
121         { "xauthlocation", oXAuthLocation },
122         { "gatewayports", oGatewayPorts },
123         { "useprivilegedport", oUsePrivilegedPort },
124         { "rhostsauthentication", oDeprecated },
125         { "passwordauthentication", oPasswordAuthentication },
126         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
127         { "kbdinteractivedevices", oKbdInteractiveDevices },
128         { "rsaauthentication", oRSAAuthentication },
129         { "pubkeyauthentication", oPubkeyAuthentication },
130         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
131         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
132         { "hostbasedauthentication", oHostbasedAuthentication },
133         { "challengeresponseauthentication", oChallengeResponseAuthentication },
134         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
135         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
136         { "kerberosauthentication", oUnsupported },
137         { "kerberostgtpassing", oUnsupported },
138         { "afstokenpassing", oUnsupported },
139 #if defined(GSSAPI)
140         { "gssapiauthentication", oGssAuthentication },
141         { "gssapikeyexchange", oGssKeyEx },
142         { "gssapidelegatecredentials", oGssDelegateCreds },
143 #else
144         { "gssapiauthentication", oUnsupported },
145         { "gssapikeyexchange", oUnsupported },
146         { "gssapidelegatecredentials", oUnsupported },
147 #endif
148         { "fallbacktorsh", oDeprecated },
149         { "usersh", oDeprecated },
150         { "identityfile", oIdentityFile },
151         { "identityfile2", oIdentityFile },                     /* alias */
152         { "hostname", oHostName },
153         { "hostkeyalias", oHostKeyAlias },
154         { "proxycommand", oProxyCommand },
155         { "port", oPort },
156         { "cipher", oCipher },
157         { "ciphers", oCiphers },
158         { "macs", oMacs },
159         { "protocol", oProtocol },
160         { "remoteforward", oRemoteForward },
161         { "localforward", oLocalForward },
162         { "user", oUser },
163         { "host", oHost },
164         { "escapechar", oEscapeChar },
165         { "globalknownhostsfile", oGlobalKnownHostsFile },
166         { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
167         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
168         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
169         { "connectionattempts", oConnectionAttempts },
170         { "batchmode", oBatchMode },
171         { "checkhostip", oCheckHostIP },
172         { "stricthostkeychecking", oStrictHostKeyChecking },
173         { "compression", oCompression },
174         { "compressionlevel", oCompressionLevel },
175         { "tcpkeepalive", oTCPKeepAlive },
176         { "keepalive", oTCPKeepAlive },                         /* obsolete */
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         { "verifyhostkeydns", oVerifyHostKeyDNS },
191         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
192         { "rekeylimit", oRekeyLimit },
193         { "connecttimeout", oConnectTimeout },
194         { "addressfamily", oAddressFamily },
195         { "serveraliveinterval", oServerAliveInterval },
196         { "serveralivecountmax", oServerAliveCountMax },
197         { NULL, oBadOption }
198 };
199
200 /*
201  * Adds a local TCP/IP port forward to options.  Never returns if there is an
202  * error.
203  */
204
205 void
206 add_local_forward(Options *options, u_short port, const char *host,
207                   u_short host_port)
208 {
209         Forward *fwd;
210 #ifndef NO_IPPORT_RESERVED_CONCEPT
211         extern uid_t original_real_uid;
212         if (port < IPPORT_RESERVED && original_real_uid != 0)
213                 fatal("Privileged ports can only be forwarded by root.");
214 #endif
215         if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
216                 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
217         fwd = &options->local_forwards[options->num_local_forwards++];
218         fwd->port = port;
219         fwd->host = xstrdup(host);
220         fwd->host_port = host_port;
221 }
222
223 /*
224  * Adds a remote TCP/IP port forward to options.  Never returns if there is
225  * an error.
226  */
227
228 void
229 add_remote_forward(Options *options, u_short port, const char *host,
230                    u_short host_port)
231 {
232         Forward *fwd;
233         if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
234                 fatal("Too many remote forwards (max %d).",
235                     SSH_MAX_FORWARDS_PER_DIRECTION);
236         fwd = &options->remote_forwards[options->num_remote_forwards++];
237         fwd->port = port;
238         fwd->host = xstrdup(host);
239         fwd->host_port = host_port;
240 }
241
242 static void
243 clear_forwardings(Options *options)
244 {
245         int i;
246
247         for (i = 0; i < options->num_local_forwards; i++)
248                 xfree(options->local_forwards[i].host);
249         options->num_local_forwards = 0;
250         for (i = 0; i < options->num_remote_forwards; i++)
251                 xfree(options->remote_forwards[i].host);
252         options->num_remote_forwards = 0;
253 }
254
255 /*
256  * Returns the number of the token pointed to by cp or oBadOption.
257  */
258
259 static OpCodes
260 parse_token(const char *cp, const char *filename, int linenum)
261 {
262         u_int i;
263
264         for (i = 0; keywords[i].name; i++)
265                 if (strcasecmp(cp, keywords[i].name) == 0)
266                         return keywords[i].opcode;
267
268         error("%s: line %d: Bad configuration option: %s",
269             filename, linenum, cp);
270         return oBadOption;
271 }
272
273 /*
274  * Processes a single option line as used in the configuration files. This
275  * only sets those values that have not already been set.
276  */
277 #define WHITESPACE " \t\r\n"
278
279 int
280 process_config_line(Options *options, const char *host,
281                     char *line, const char *filename, int linenum,
282                     int *activep)
283 {
284         char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
285         int opcode, *intptr, value;
286         size_t len;
287         u_short fwd_port, fwd_host_port;
288         char sfwd_host_port[6];
289
290         /* Strip trailing whitespace */
291         for(len = strlen(line) - 1; len > 0; len--) {
292                 if (strchr(WHITESPACE, line[len]) == NULL)
293                         break;
294                 line[len] = '\0';
295         }
296
297         s = line;
298         /* Get the keyword. (Each line is supposed to begin with a keyword). */
299         keyword = strdelim(&s);
300         /* Ignore leading whitespace. */
301         if (*keyword == '\0')
302                 keyword = strdelim(&s);
303         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
304                 return 0;
305
306         opcode = parse_token(keyword, filename, linenum);
307
308         switch (opcode) {
309         case oBadOption:
310                 /* don't panic, but count bad options */
311                 return -1;
312                 /* NOTREACHED */
313         case oConnectTimeout:
314                 intptr = &options->connection_timeout;
315 parse_time:
316                 arg = strdelim(&s);
317                 if (!arg || *arg == '\0')
318                         fatal("%s line %d: missing time value.",
319                             filename, linenum);
320                 if ((value = convtime(arg)) == -1)
321                         fatal("%s line %d: invalid time value.",
322                             filename, linenum);
323                 if (*intptr == -1)
324                         *intptr = value;
325                 break;
326
327         case oForwardAgent:
328                 intptr = &options->forward_agent;
329 parse_flag:
330                 arg = strdelim(&s);
331                 if (!arg || *arg == '\0')
332                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
333                 value = 0;      /* To avoid compiler warning... */
334                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
335                         value = 1;
336                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
337                         value = 0;
338                 else
339                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
340                 if (*activep && *intptr == -1)
341                         *intptr = value;
342                 break;
343
344         case oForwardX11:
345                 intptr = &options->forward_x11;
346                 goto parse_flag;
347
348         case oForwardX11Trusted:
349                 intptr = &options->forward_x11_trusted;
350                 goto parse_flag;
351
352         case oGatewayPorts:
353                 intptr = &options->gateway_ports;
354                 goto parse_flag;
355
356         case oUsePrivilegedPort:
357                 intptr = &options->use_privileged_port;
358                 goto parse_flag;
359
360         case oPasswordAuthentication:
361                 intptr = &options->password_authentication;
362                 goto parse_flag;
363
364         case oKbdInteractiveAuthentication:
365                 intptr = &options->kbd_interactive_authentication;
366                 goto parse_flag;
367
368         case oKbdInteractiveDevices:
369                 charptr = &options->kbd_interactive_devices;
370                 goto parse_string;
371
372         case oPubkeyAuthentication:
373                 intptr = &options->pubkey_authentication;
374                 goto parse_flag;
375
376         case oRSAAuthentication:
377                 intptr = &options->rsa_authentication;
378                 goto parse_flag;
379
380         case oRhostsRSAAuthentication:
381                 intptr = &options->rhosts_rsa_authentication;
382                 goto parse_flag;
383
384         case oHostbasedAuthentication:
385                 intptr = &options->hostbased_authentication;
386                 goto parse_flag;
387
388         case oChallengeResponseAuthentication:
389                 intptr = &options->challenge_response_authentication;
390                 goto parse_flag;
391
392         case oGssAuthentication:
393                 intptr = &options->gss_authentication;
394                 goto parse_flag;
395
396         case oGssKeyEx:
397                 intptr = &options->gss_keyex;
398                 goto parse_flag;
399
400         case oGssDelegateCreds:
401                 intptr = &options->gss_deleg_creds;
402                 goto parse_flag;
403
404         case oBatchMode:
405                 intptr = &options->batch_mode;
406                 goto parse_flag;
407
408         case oCheckHostIP:
409                 intptr = &options->check_host_ip;
410                 goto parse_flag;
411
412         case oVerifyHostKeyDNS:
413                 intptr = &options->verify_host_key_dns;
414                 goto parse_yesnoask;
415
416         case oStrictHostKeyChecking:
417                 intptr = &options->strict_host_key_checking;
418 parse_yesnoask:
419                 arg = strdelim(&s);
420                 if (!arg || *arg == '\0')
421                         fatal("%.200s line %d: Missing yes/no/ask argument.",
422                             filename, linenum);
423                 value = 0;      /* To avoid compiler warning... */
424                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
425                         value = 1;
426                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
427                         value = 0;
428                 else if (strcmp(arg, "ask") == 0)
429                         value = 2;
430                 else
431                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
432                 if (*activep && *intptr == -1)
433                         *intptr = value;
434                 break;
435
436         case oCompression:
437                 intptr = &options->compression;
438                 goto parse_flag;
439
440         case oTCPKeepAlive:
441                 intptr = &options->tcp_keep_alive;
442                 goto parse_flag;
443
444         case oNoHostAuthenticationForLocalhost:
445                 intptr = &options->no_host_authentication_for_localhost;
446                 goto parse_flag;
447
448         case oNumberOfPasswordPrompts:
449                 intptr = &options->number_of_password_prompts;
450                 goto parse_int;
451
452         case oCompressionLevel:
453                 intptr = &options->compression_level;
454                 goto parse_int;
455
456         case oRekeyLimit:
457                 intptr = &options->rekey_limit;
458                 arg = strdelim(&s);
459                 if (!arg || *arg == '\0')
460                         fatal("%.200s line %d: Missing argument.", filename, linenum);
461                 if (arg[0] < '0' || arg[0] > '9')
462                         fatal("%.200s line %d: Bad number.", filename, linenum);
463                 value = strtol(arg, &endofnumber, 10);
464                 if (arg == endofnumber)
465                         fatal("%.200s line %d: Bad number.", filename, linenum);
466                 switch (toupper(*endofnumber)) {
467                 case 'K':
468                         value *= 1<<10;
469                         break;
470                 case 'M':
471                         value *= 1<<20;
472                         break;
473                 case 'G':
474                         value *= 1<<30;
475                         break;
476                 }
477                 if (*activep && *intptr == -1)
478                         *intptr = value;
479                 break;
480
481         case oIdentityFile:
482                 arg = strdelim(&s);
483                 if (!arg || *arg == '\0')
484                         fatal("%.200s line %d: Missing argument.", filename, linenum);
485                 if (*activep) {
486                         intptr = &options->num_identity_files;
487                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
488                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
489                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
490                         charptr =  &options->identity_files[*intptr];
491                         *charptr = xstrdup(arg);
492                         *intptr = *intptr + 1;
493                 }
494                 break;
495
496         case oXAuthLocation:
497                 charptr=&options->xauth_location;
498                 goto parse_string;
499
500         case oUser:
501                 charptr = &options->user;
502 parse_string:
503                 arg = strdelim(&s);
504                 if (!arg || *arg == '\0')
505                         fatal("%.200s line %d: Missing argument.", filename, linenum);
506                 if (*activep && *charptr == NULL)
507                         *charptr = xstrdup(arg);
508                 break;
509
510         case oGlobalKnownHostsFile:
511                 charptr = &options->system_hostfile;
512                 goto parse_string;
513
514         case oUserKnownHostsFile:
515                 charptr = &options->user_hostfile;
516                 goto parse_string;
517
518         case oGlobalKnownHostsFile2:
519                 charptr = &options->system_hostfile2;
520                 goto parse_string;
521
522         case oUserKnownHostsFile2:
523                 charptr = &options->user_hostfile2;
524                 goto parse_string;
525
526         case oHostName:
527                 charptr = &options->hostname;
528                 goto parse_string;
529
530         case oHostKeyAlias:
531                 charptr = &options->host_key_alias;
532                 goto parse_string;
533
534         case oPreferredAuthentications:
535                 charptr = &options->preferred_authentications;
536                 goto parse_string;
537
538         case oBindAddress:
539                 charptr = &options->bind_address;
540                 goto parse_string;
541
542         case oSmartcardDevice:
543                 charptr = &options->smartcard_device;
544                 goto parse_string;
545
546         case oProxyCommand:
547                 if (s == NULL)
548                         fatal("%.200s line %d: Missing argument.", filename, linenum);
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, "socks", 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                 intptr = &options->address_family;
729                 if (strcasecmp(arg, "inet") == 0)
730                         value = AF_INET;
731                 else if (strcasecmp(arg, "inet6") == 0)
732                         value = AF_INET6;
733                 else if (strcasecmp(arg, "any") == 0)
734                         value = AF_UNSPEC;
735                 else
736                         fatal("Unsupported AddressFamily \"%s\"", arg);
737                 if (*activep && *intptr == -1)
738                         *intptr = value;
739                 break;
740
741         case oEnableSSHKeysign:
742                 intptr = &options->enable_ssh_keysign;
743                 goto parse_flag;
744
745         case oServerAliveInterval:
746                 intptr = &options->server_alive_interval;
747                 goto parse_time;
748
749         case oServerAliveCountMax:
750                 intptr = &options->server_alive_count_max;
751                 goto parse_int;
752
753         case oDeprecated:
754                 debug("%s line %d: Deprecated option \"%s\"",
755                     filename, linenum, keyword);
756                 return 0;
757
758         case oUnsupported:
759                 error("%s line %d: Unsupported option \"%s\"",
760                     filename, linenum, keyword);
761                 return 0;
762
763         default:
764                 fatal("process_config_line: Unimplemented opcode %d", opcode);
765         }
766
767         /* Check that there is no garbage at end of line. */
768         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
769                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
770                      filename, linenum, arg);
771         }
772         return 0;
773 }
774
775
776 /*
777  * Reads the config file and modifies the options accordingly.  Options
778  * should already be initialized before this call.  This never returns if
779  * there is an error.  If the file does not exist, this returns 0.
780  */
781
782 int
783 read_config_file(const char *filename, const char *host, Options *options)
784 {
785         FILE *f;
786         char line[1024];
787         int active, linenum;
788         int bad_options = 0;
789
790         /* Open the file. */
791         f = fopen(filename, "r");
792         if (!f)
793                 return 0;
794
795         debug("Reading configuration data %.200s", filename);
796
797         /*
798          * Mark that we are now processing the options.  This flag is turned
799          * on/off by Host specifications.
800          */
801         active = 1;
802         linenum = 0;
803         while (fgets(line, sizeof(line), f)) {
804                 /* Update line number counter. */
805                 linenum++;
806                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
807                         bad_options++;
808         }
809         fclose(f);
810         if (bad_options > 0)
811                 fatal("%s: terminating, %d bad configuration options",
812                     filename, bad_options);
813         return 1;
814 }
815
816 /*
817  * Initializes options to special values that indicate that they have not yet
818  * been set.  Read_config_file will only set options with this value. Options
819  * are processed in the following order: command line, user config file,
820  * system config file.  Last, fill_default_options is called.
821  */
822
823 void
824 initialize_options(Options * options)
825 {
826         memset(options, 'X', sizeof(*options));
827         options->forward_agent = -1;
828         options->forward_x11 = -1;
829         options->forward_x11_trusted = -1;
830         options->xauth_location = NULL;
831         options->gateway_ports = -1;
832         options->use_privileged_port = -1;
833         options->rsa_authentication = -1;
834         options->pubkey_authentication = -1;
835         options->challenge_response_authentication = -1;
836         options->gss_authentication = -1;
837         options->gss_keyex = -1;
838         options->gss_deleg_creds = -1;
839         options->password_authentication = -1;
840         options->kbd_interactive_authentication = -1;
841         options->kbd_interactive_devices = NULL;
842         options->rhosts_rsa_authentication = -1;
843         options->hostbased_authentication = -1;
844         options->batch_mode = -1;
845         options->check_host_ip = -1;
846         options->strict_host_key_checking = -1;
847         options->compression = -1;
848         options->tcp_keep_alive = -1;
849         options->compression_level = -1;
850         options->port = -1;
851         options->address_family = -1;
852         options->connection_attempts = -1;
853         options->connection_timeout = -1;
854         options->number_of_password_prompts = -1;
855         options->cipher = -1;
856         options->ciphers = NULL;
857         options->macs = NULL;
858         options->hostkeyalgorithms = NULL;
859         options->protocol = SSH_PROTO_UNKNOWN;
860         options->num_identity_files = 0;
861         options->hostname = NULL;
862         options->host_key_alias = NULL;
863         options->proxy_command = NULL;
864         options->user = NULL;
865         options->escape_char = -1;
866         options->system_hostfile = NULL;
867         options->user_hostfile = NULL;
868         options->system_hostfile2 = NULL;
869         options->user_hostfile2 = NULL;
870         options->num_local_forwards = 0;
871         options->num_remote_forwards = 0;
872         options->clear_forwardings = -1;
873         options->log_level = SYSLOG_LEVEL_NOT_SET;
874         options->preferred_authentications = NULL;
875         options->bind_address = NULL;
876         options->smartcard_device = NULL;
877         options->enable_ssh_keysign = - 1;
878         options->no_host_authentication_for_localhost = - 1;
879         options->rekey_limit = - 1;
880         options->verify_host_key_dns = -1;
881         options->server_alive_interval = -1;
882         options->server_alive_count_max = -1;
883 }
884
885 /*
886  * Called after processing other sources of option data, this fills those
887  * options for which no value has been specified with their default values.
888  */
889
890 void
891 fill_default_options(Options * options)
892 {
893         int len;
894
895         if (options->forward_agent == -1)
896                 options->forward_agent = 0;
897         if (options->forward_x11 == -1)
898                 options->forward_x11 = 0;
899         if (options->forward_x11_trusted == -1)
900                 options->forward_x11_trusted = 0;
901         if (options->xauth_location == NULL)
902                 options->xauth_location = _PATH_XAUTH;
903         if (options->gateway_ports == -1)
904                 options->gateway_ports = 0;
905         if (options->use_privileged_port == -1)
906                 options->use_privileged_port = 0;
907         if (options->rsa_authentication == -1)
908                 options->rsa_authentication = 1;
909         if (options->pubkey_authentication == -1)
910                 options->pubkey_authentication = 1;
911         if (options->challenge_response_authentication == -1)
912                 options->challenge_response_authentication = 1;
913         if (options->gss_authentication == -1)
914                 options->gss_authentication = 1;
915         if (options->gss_keyex == -1)
916                 options->gss_keyex = 1;
917         if (options->gss_deleg_creds == -1)
918                 options->gss_deleg_creds = 1;
919         if (options->password_authentication == -1)
920                 options->password_authentication = 1;
921         if (options->kbd_interactive_authentication == -1)
922                 options->kbd_interactive_authentication = 1;
923         if (options->rhosts_rsa_authentication == -1)
924                 options->rhosts_rsa_authentication = 0;
925         if (options->hostbased_authentication == -1)
926                 options->hostbased_authentication = 0;
927         if (options->batch_mode == -1)
928                 options->batch_mode = 0;
929         if (options->check_host_ip == -1)
930                 options->check_host_ip = 1;
931         if (options->strict_host_key_checking == -1)
932                 options->strict_host_key_checking = 2;  /* 2 is default */
933         if (options->compression == -1)
934                 options->compression = 0;
935         if (options->tcp_keep_alive == -1)
936                 options->tcp_keep_alive = 1;
937         if (options->compression_level == -1)
938                 options->compression_level = 6;
939         if (options->port == -1)
940                 options->port = 0;      /* Filled in ssh_connect. */
941         if (options->address_family == -1)
942                 options->address_family = AF_UNSPEC;
943         if (options->connection_attempts == -1)
944                 options->connection_attempts = 1;
945         if (options->number_of_password_prompts == -1)
946                 options->number_of_password_prompts = 3;
947         /* Selected in ssh_login(). */
948         if (options->cipher == -1)
949                 options->cipher = SSH_CIPHER_NOT_SET;
950         /* options->ciphers, default set in myproposals.h */
951         /* options->macs, default set in myproposals.h */
952         /* options->hostkeyalgorithms, default set in myproposals.h */
953         if (options->protocol == SSH_PROTO_UNKNOWN)
954                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
955         if (options->num_identity_files == 0) {
956                 if (options->protocol & SSH_PROTO_1) {
957                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
958                         options->identity_files[options->num_identity_files] =
959                             xmalloc(len);
960                         snprintf(options->identity_files[options->num_identity_files++],
961                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
962                 }
963                 if (options->protocol & SSH_PROTO_2) {
964                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
965                         options->identity_files[options->num_identity_files] =
966                             xmalloc(len);
967                         snprintf(options->identity_files[options->num_identity_files++],
968                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
969
970                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
971                         options->identity_files[options->num_identity_files] =
972                             xmalloc(len);
973                         snprintf(options->identity_files[options->num_identity_files++],
974                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
975                 }
976         }
977         if (options->escape_char == -1)
978                 options->escape_char = '~';
979         if (options->system_hostfile == NULL)
980                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
981         if (options->user_hostfile == NULL)
982                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
983         if (options->system_hostfile2 == NULL)
984                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
985         if (options->user_hostfile2 == NULL)
986                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
987         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
988                 options->log_level = SYSLOG_LEVEL_INFO;
989         if (options->clear_forwardings == 1)
990                 clear_forwardings(options);
991         if (options->no_host_authentication_for_localhost == - 1)
992                 options->no_host_authentication_for_localhost = 0;
993         if (options->enable_ssh_keysign == -1)
994                 options->enable_ssh_keysign = 0;
995         if (options->rekey_limit == -1)
996                 options->rekey_limit = 0;
997         if (options->verify_host_key_dns == -1)
998                 options->verify_host_key_dns = 0;
999         if (options->server_alive_interval == -1)
1000                 options->server_alive_interval = 0;
1001         if (options->server_alive_count_max == -1)
1002                 options->server_alive_count_max = 3;
1003         /* options->proxy_command should not be set by default */
1004         /* options->user will be set in the main program if appropriate */
1005         /* options->hostname will be set in the main program if appropriate */
1006         /* options->host_key_alias should not be set by default */
1007         /* options->preferred_authentications will be set in ssh */
1008 }
This page took 0.127189 seconds and 5 git commands to generate.