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