]> andersk Git - openssh.git/blob - readconf.c
- stevesk@cvs.openbsd.org 2006/07/12 22:28:52
[openssh.git] / readconf.c
1 /* $OpenBSD: readconf.c,v 1.155 2006/07/12 22:28:52 stevesk Exp $ */
2 /*
3  * Author: Tatu Ylonen <ylo@cs.hut.fi>
4  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5  *                    All rights reserved
6  * Functions for reading the configuration files.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14
15 #include "includes.h"
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <sys/socket.h>
20
21 #include <netinet/in.h>
22
23 #include <ctype.h>
24 #include <errno.h>
25 #if defined(HAVE_NETDB_H)
26 # include <netdb.h>
27 #endif
28
29 #include "ssh.h"
30 #include "xmalloc.h"
31 #include "compat.h"
32 #include "cipher.h"
33 #include "pathnames.h"
34 #include "log.h"
35 #include "readconf.h"
36 #include "match.h"
37 #include "misc.h"
38 #include "kex.h"
39 #include "mac.h"
40
41 /* Format of the configuration file:
42
43    # Configuration data is parsed as follows:
44    #  1. command line options
45    #  2. user-specific file
46    #  3. system-wide file
47    # Any configuration value is only changed the first time it is set.
48    # Thus, host-specific definitions should be at the beginning of the
49    # configuration file, and defaults at the end.
50
51    # Host-specific declarations.  These may override anything above.  A single
52    # host may match multiple declarations; these are processed in the order
53    # that they are given in.
54
55    Host *.ngs.fi ngs.fi
56      User foo
57
58    Host fake.com
59      HostName another.host.name.real.org
60      User blaah
61      Port 34289
62      ForwardX11 no
63      ForwardAgent no
64
65    Host books.com
66      RemoteForward 9999 shadows.cs.hut.fi:9999
67      Cipher 3des
68
69    Host fascist.blob.com
70      Port 23123
71      User tylonen
72      PasswordAuthentication no
73
74    Host puukko.hut.fi
75      User t35124p
76      ProxyCommand ssh-proxy %h %p
77
78    Host *.fr
79      PublicKeyAuthentication no
80
81    Host *.su
82      Cipher none
83      PasswordAuthentication no
84
85    Host vpn.fake.com
86      Tunnel yes
87      TunnelDevice 3
88
89    # Defaults for various options
90    Host *
91      ForwardAgent no
92      ForwardX11 no
93      PasswordAuthentication yes
94      RSAAuthentication yes
95      RhostsRSAAuthentication yes
96      StrictHostKeyChecking yes
97      TcpKeepAlive no
98      IdentityFile ~/.ssh/identity
99      Port 22
100      EscapeChar ~
101
102 */
103
104 /* Keyword tokens. */
105
106 typedef enum {
107         oBadOption,
108         oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
109         oExitOnForwardFailure,
110         oPasswordAuthentication, oRSAAuthentication,
111         oChallengeResponseAuthentication, oXAuthLocation,
112         oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
113         oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
114         oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
115         oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
116         oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
117         oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
118         oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
119         oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
120         oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
121         oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
122         oClearAllForwardings, oNoHostAuthenticationForLocalhost,
123         oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
124         oAddressFamily, oGssAuthentication, oGssDelegateCreds,
125         oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
126         oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
127         oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
128         oDeprecated, oUnsupported
129 } OpCodes;
130
131 /* Textual representations of the tokens. */
132
133 static struct {
134         const char *name;
135         OpCodes opcode;
136 } keywords[] = {
137         { "forwardagent", oForwardAgent },
138         { "forwardx11", oForwardX11 },
139         { "forwardx11trusted", oForwardX11Trusted },
140         { "exitonforwardfailure", oExitOnForwardFailure },
141         { "xauthlocation", oXAuthLocation },
142         { "gatewayports", oGatewayPorts },
143         { "useprivilegedport", oUsePrivilegedPort },
144         { "rhostsauthentication", oDeprecated },
145         { "passwordauthentication", oPasswordAuthentication },
146         { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
147         { "kbdinteractivedevices", oKbdInteractiveDevices },
148         { "rsaauthentication", oRSAAuthentication },
149         { "pubkeyauthentication", oPubkeyAuthentication },
150         { "dsaauthentication", oPubkeyAuthentication },             /* alias */
151         { "rhostsrsaauthentication", oRhostsRSAAuthentication },
152         { "hostbasedauthentication", oHostbasedAuthentication },
153         { "challengeresponseauthentication", oChallengeResponseAuthentication },
154         { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
155         { "tisauthentication", oChallengeResponseAuthentication },  /* alias */
156         { "kerberosauthentication", oUnsupported },
157         { "kerberostgtpassing", oUnsupported },
158         { "afstokenpassing", oUnsupported },
159 #if defined(GSSAPI)
160         { "gssapiauthentication", oGssAuthentication },
161         { "gssapidelegatecredentials", oGssDelegateCreds },
162 #else
163         { "gssapiauthentication", oUnsupported },
164         { "gssapidelegatecredentials", oUnsupported },
165 #endif
166         { "fallbacktorsh", oDeprecated },
167         { "usersh", oDeprecated },
168         { "identityfile", oIdentityFile },
169         { "identityfile2", oIdentityFile },                     /* alias */
170         { "identitiesonly", oIdentitiesOnly },
171         { "hostname", oHostName },
172         { "hostkeyalias", oHostKeyAlias },
173         { "proxycommand", oProxyCommand },
174         { "port", oPort },
175         { "cipher", oCipher },
176         { "ciphers", oCiphers },
177         { "macs", oMacs },
178         { "protocol", oProtocol },
179         { "remoteforward", oRemoteForward },
180         { "localforward", oLocalForward },
181         { "user", oUser },
182         { "host", oHost },
183         { "escapechar", oEscapeChar },
184         { "globalknownhostsfile", oGlobalKnownHostsFile },
185         { "userknownhostsfile", oUserKnownHostsFile },          /* obsolete */
186         { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
187         { "userknownhostsfile2", oUserKnownHostsFile2 },        /* obsolete */
188         { "connectionattempts", oConnectionAttempts },
189         { "batchmode", oBatchMode },
190         { "checkhostip", oCheckHostIP },
191         { "stricthostkeychecking", oStrictHostKeyChecking },
192         { "compression", oCompression },
193         { "compressionlevel", oCompressionLevel },
194         { "tcpkeepalive", oTCPKeepAlive },
195         { "keepalive", oTCPKeepAlive },                         /* obsolete */
196         { "numberofpasswordprompts", oNumberOfPasswordPrompts },
197         { "loglevel", oLogLevel },
198         { "dynamicforward", oDynamicForward },
199         { "preferredauthentications", oPreferredAuthentications },
200         { "hostkeyalgorithms", oHostKeyAlgorithms },
201         { "bindaddress", oBindAddress },
202 #ifdef SMARTCARD
203         { "smartcarddevice", oSmartcardDevice },
204 #else
205         { "smartcarddevice", oUnsupported },
206 #endif
207         { "clearallforwardings", oClearAllForwardings },
208         { "enablesshkeysign", oEnableSSHKeysign },
209         { "verifyhostkeydns", oVerifyHostKeyDNS },
210         { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
211         { "rekeylimit", oRekeyLimit },
212         { "connecttimeout", oConnectTimeout },
213         { "addressfamily", oAddressFamily },
214         { "serveraliveinterval", oServerAliveInterval },
215         { "serveralivecountmax", oServerAliveCountMax },
216         { "sendenv", oSendEnv },
217         { "controlpath", oControlPath },
218         { "controlmaster", oControlMaster },
219         { "hashknownhosts", oHashKnownHosts },
220         { "tunnel", oTunnel },
221         { "tunneldevice", oTunnelDevice },
222         { "localcommand", oLocalCommand },
223         { "permitlocalcommand", oPermitLocalCommand },
224         { NULL, oBadOption }
225 };
226
227 /*
228  * Adds a local TCP/IP port forward to options.  Never returns if there is an
229  * error.
230  */
231
232 void
233 add_local_forward(Options *options, const Forward *newfwd)
234 {
235         Forward *fwd;
236 #ifndef NO_IPPORT_RESERVED_CONCEPT
237         extern uid_t original_real_uid;
238         if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
239                 fatal("Privileged ports can only be forwarded by root.");
240 #endif
241         if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
242                 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
243         fwd = &options->local_forwards[options->num_local_forwards++];
244
245         fwd->listen_host = (newfwd->listen_host == NULL) ?
246             NULL : xstrdup(newfwd->listen_host);
247         fwd->listen_port = newfwd->listen_port;
248         fwd->connect_host = xstrdup(newfwd->connect_host);
249         fwd->connect_port = newfwd->connect_port;
250 }
251
252 /*
253  * Adds a remote TCP/IP port forward to options.  Never returns if there is
254  * an error.
255  */
256
257 void
258 add_remote_forward(Options *options, const Forward *newfwd)
259 {
260         Forward *fwd;
261         if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
262                 fatal("Too many remote forwards (max %d).",
263                     SSH_MAX_FORWARDS_PER_DIRECTION);
264         fwd = &options->remote_forwards[options->num_remote_forwards++];
265
266         fwd->listen_host = (newfwd->listen_host == NULL) ?
267             NULL : xstrdup(newfwd->listen_host);
268         fwd->listen_port = newfwd->listen_port;
269         fwd->connect_host = xstrdup(newfwd->connect_host);
270         fwd->connect_port = newfwd->connect_port;
271 }
272
273 static void
274 clear_forwardings(Options *options)
275 {
276         int i;
277
278         for (i = 0; i < options->num_local_forwards; i++) {
279                 if (options->local_forwards[i].listen_host != NULL)
280                         xfree(options->local_forwards[i].listen_host);
281                 xfree(options->local_forwards[i].connect_host);
282         }
283         options->num_local_forwards = 0;
284         for (i = 0; i < options->num_remote_forwards; i++) {
285                 if (options->remote_forwards[i].listen_host != NULL)
286                         xfree(options->remote_forwards[i].listen_host);
287                 xfree(options->remote_forwards[i].connect_host);
288         }
289         options->num_remote_forwards = 0;
290         options->tun_open = SSH_TUNMODE_NO;
291 }
292
293 /*
294  * Returns the number of the token pointed to by cp or oBadOption.
295  */
296
297 static OpCodes
298 parse_token(const char *cp, const char *filename, int linenum)
299 {
300         u_int i;
301
302         for (i = 0; keywords[i].name; i++)
303                 if (strcasecmp(cp, keywords[i].name) == 0)
304                         return keywords[i].opcode;
305
306         error("%s: line %d: Bad configuration option: %s",
307             filename, linenum, cp);
308         return oBadOption;
309 }
310
311 /*
312  * Processes a single option line as used in the configuration files. This
313  * only sets those values that have not already been set.
314  */
315 #define WHITESPACE " \t\r\n"
316
317 int
318 process_config_line(Options *options, const char *host,
319                     char *line, const char *filename, int linenum,
320                     int *activep)
321 {
322         char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
323         int opcode, *intptr, value, value2, scale;
324         long long orig, val64;
325         size_t len;
326         Forward fwd;
327
328         /* Strip trailing whitespace */
329         for (len = strlen(line) - 1; len > 0; len--) {
330                 if (strchr(WHITESPACE, line[len]) == NULL)
331                         break;
332                 line[len] = '\0';
333         }
334
335         s = line;
336         /* Get the keyword. (Each line is supposed to begin with a keyword). */
337         if ((keyword = strdelim(&s)) == NULL)
338                 return 0;
339         /* Ignore leading whitespace. */
340         if (*keyword == '\0')
341                 keyword = strdelim(&s);
342         if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
343                 return 0;
344
345         opcode = parse_token(keyword, filename, linenum);
346
347         switch (opcode) {
348         case oBadOption:
349                 /* don't panic, but count bad options */
350                 return -1;
351                 /* NOTREACHED */
352         case oConnectTimeout:
353                 intptr = &options->connection_timeout;
354 parse_time:
355                 arg = strdelim(&s);
356                 if (!arg || *arg == '\0')
357                         fatal("%s line %d: missing time value.",
358                             filename, linenum);
359                 if ((value = convtime(arg)) == -1)
360                         fatal("%s line %d: invalid time value.",
361                             filename, linenum);
362                 if (*intptr == -1)
363                         *intptr = value;
364                 break;
365
366         case oForwardAgent:
367                 intptr = &options->forward_agent;
368 parse_flag:
369                 arg = strdelim(&s);
370                 if (!arg || *arg == '\0')
371                         fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
372                 value = 0;      /* To avoid compiler warning... */
373                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
374                         value = 1;
375                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
376                         value = 0;
377                 else
378                         fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
379                 if (*activep && *intptr == -1)
380                         *intptr = value;
381                 break;
382
383         case oForwardX11:
384                 intptr = &options->forward_x11;
385                 goto parse_flag;
386
387         case oForwardX11Trusted:
388                 intptr = &options->forward_x11_trusted;
389                 goto parse_flag;
390
391         case oGatewayPorts:
392                 intptr = &options->gateway_ports;
393                 goto parse_flag;
394
395         case oExitOnForwardFailure:
396                 intptr = &options->exit_on_forward_failure;
397                 goto parse_flag;
398
399         case oUsePrivilegedPort:
400                 intptr = &options->use_privileged_port;
401                 goto parse_flag;
402
403         case oPasswordAuthentication:
404                 intptr = &options->password_authentication;
405                 goto parse_flag;
406
407         case oKbdInteractiveAuthentication:
408                 intptr = &options->kbd_interactive_authentication;
409                 goto parse_flag;
410
411         case oKbdInteractiveDevices:
412                 charptr = &options->kbd_interactive_devices;
413                 goto parse_string;
414
415         case oPubkeyAuthentication:
416                 intptr = &options->pubkey_authentication;
417                 goto parse_flag;
418
419         case oRSAAuthentication:
420                 intptr = &options->rsa_authentication;
421                 goto parse_flag;
422
423         case oRhostsRSAAuthentication:
424                 intptr = &options->rhosts_rsa_authentication;
425                 goto parse_flag;
426
427         case oHostbasedAuthentication:
428                 intptr = &options->hostbased_authentication;
429                 goto parse_flag;
430
431         case oChallengeResponseAuthentication:
432                 intptr = &options->challenge_response_authentication;
433                 goto parse_flag;
434
435         case oGssAuthentication:
436                 intptr = &options->gss_authentication;
437                 goto parse_flag;
438
439         case oGssDelegateCreds:
440                 intptr = &options->gss_deleg_creds;
441                 goto parse_flag;
442
443         case oBatchMode:
444                 intptr = &options->batch_mode;
445                 goto parse_flag;
446
447         case oCheckHostIP:
448                 intptr = &options->check_host_ip;
449                 goto parse_flag;
450
451         case oVerifyHostKeyDNS:
452                 intptr = &options->verify_host_key_dns;
453                 goto parse_yesnoask;
454
455         case oStrictHostKeyChecking:
456                 intptr = &options->strict_host_key_checking;
457 parse_yesnoask:
458                 arg = strdelim(&s);
459                 if (!arg || *arg == '\0')
460                         fatal("%.200s line %d: Missing yes/no/ask argument.",
461                             filename, linenum);
462                 value = 0;      /* To avoid compiler warning... */
463                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
464                         value = 1;
465                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
466                         value = 0;
467                 else if (strcmp(arg, "ask") == 0)
468                         value = 2;
469                 else
470                         fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
471                 if (*activep && *intptr == -1)
472                         *intptr = value;
473                 break;
474
475         case oCompression:
476                 intptr = &options->compression;
477                 goto parse_flag;
478
479         case oTCPKeepAlive:
480                 intptr = &options->tcp_keep_alive;
481                 goto parse_flag;
482
483         case oNoHostAuthenticationForLocalhost:
484                 intptr = &options->no_host_authentication_for_localhost;
485                 goto parse_flag;
486
487         case oNumberOfPasswordPrompts:
488                 intptr = &options->number_of_password_prompts;
489                 goto parse_int;
490
491         case oCompressionLevel:
492                 intptr = &options->compression_level;
493                 goto parse_int;
494
495         case oRekeyLimit:
496                 intptr = &options->rekey_limit;
497                 arg = strdelim(&s);
498                 if (!arg || *arg == '\0')
499                         fatal("%.200s line %d: Missing argument.", filename, linenum);
500                 if (arg[0] < '0' || arg[0] > '9')
501                         fatal("%.200s line %d: Bad number.", filename, linenum);
502                 orig = val64 = strtoll(arg, &endofnumber, 10);
503                 if (arg == endofnumber)
504                         fatal("%.200s line %d: Bad number.", filename, linenum);
505                 switch (toupper(*endofnumber)) {
506                 case '\0':
507                         scale = 1;
508                         break;
509                 case 'K':
510                         scale = 1<<10;
511                         break;
512                 case 'M':
513                         scale = 1<<20;
514                         break;
515                 case 'G':
516                         scale = 1<<30;
517                         break;
518                 default:
519                         fatal("%.200s line %d: Invalid RekeyLimit suffix",
520                             filename, linenum);
521                 }
522                 val64 *= scale;
523                 /* detect integer wrap and too-large limits */
524                 if ((val64 / scale) != orig || val64 > INT_MAX)
525                         fatal("%.200s line %d: RekeyLimit too large",
526                             filename, linenum);
527                 if (val64 < 16)
528                         fatal("%.200s line %d: RekeyLimit too small",
529                             filename, linenum);
530                 if (*activep && *intptr == -1)
531                         *intptr = (int)val64;
532                 break;
533
534         case oIdentityFile:
535                 arg = strdelim(&s);
536                 if (!arg || *arg == '\0')
537                         fatal("%.200s line %d: Missing argument.", filename, linenum);
538                 if (*activep) {
539                         intptr = &options->num_identity_files;
540                         if (*intptr >= SSH_MAX_IDENTITY_FILES)
541                                 fatal("%.200s line %d: Too many identity files specified (max %d).",
542                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
543                         charptr =  &options->identity_files[*intptr];
544                         *charptr = xstrdup(arg);
545                         *intptr = *intptr + 1;
546                 }
547                 break;
548
549         case oXAuthLocation:
550                 charptr=&options->xauth_location;
551                 goto parse_string;
552
553         case oUser:
554                 charptr = &options->user;
555 parse_string:
556                 arg = strdelim(&s);
557                 if (!arg || *arg == '\0')
558                         fatal("%.200s line %d: Missing argument.", filename, linenum);
559                 if (*activep && *charptr == NULL)
560                         *charptr = xstrdup(arg);
561                 break;
562
563         case oGlobalKnownHostsFile:
564                 charptr = &options->system_hostfile;
565                 goto parse_string;
566
567         case oUserKnownHostsFile:
568                 charptr = &options->user_hostfile;
569                 goto parse_string;
570
571         case oGlobalKnownHostsFile2:
572                 charptr = &options->system_hostfile2;
573                 goto parse_string;
574
575         case oUserKnownHostsFile2:
576                 charptr = &options->user_hostfile2;
577                 goto parse_string;
578
579         case oHostName:
580                 charptr = &options->hostname;
581                 goto parse_string;
582
583         case oHostKeyAlias:
584                 charptr = &options->host_key_alias;
585                 goto parse_string;
586
587         case oPreferredAuthentications:
588                 charptr = &options->preferred_authentications;
589                 goto parse_string;
590
591         case oBindAddress:
592                 charptr = &options->bind_address;
593                 goto parse_string;
594
595         case oSmartcardDevice:
596                 charptr = &options->smartcard_device;
597                 goto parse_string;
598
599         case oProxyCommand:
600                 charptr = &options->proxy_command;
601 parse_command:
602                 if (s == NULL)
603                         fatal("%.200s line %d: Missing argument.", filename, linenum);
604                 len = strspn(s, WHITESPACE "=");
605                 if (*activep && *charptr == NULL)
606                         *charptr = xstrdup(s + len);
607                 return 0;
608
609         case oPort:
610                 intptr = &options->port;
611 parse_int:
612                 arg = strdelim(&s);
613                 if (!arg || *arg == '\0')
614                         fatal("%.200s line %d: Missing argument.", filename, linenum);
615                 if (arg[0] < '0' || arg[0] > '9')
616                         fatal("%.200s line %d: Bad number.", filename, linenum);
617
618                 /* Octal, decimal, or hex format? */
619                 value = strtol(arg, &endofnumber, 0);
620                 if (arg == endofnumber)
621                         fatal("%.200s line %d: Bad number.", filename, linenum);
622                 if (*activep && *intptr == -1)
623                         *intptr = value;
624                 break;
625
626         case oConnectionAttempts:
627                 intptr = &options->connection_attempts;
628                 goto parse_int;
629
630         case oCipher:
631                 intptr = &options->cipher;
632                 arg = strdelim(&s);
633                 if (!arg || *arg == '\0')
634                         fatal("%.200s line %d: Missing argument.", filename, linenum);
635                 value = cipher_number(arg);
636                 if (value == -1)
637                         fatal("%.200s line %d: Bad cipher '%s'.",
638                             filename, linenum, arg ? arg : "<NONE>");
639                 if (*activep && *intptr == -1)
640                         *intptr = value;
641                 break;
642
643         case oCiphers:
644                 arg = strdelim(&s);
645                 if (!arg || *arg == '\0')
646                         fatal("%.200s line %d: Missing argument.", filename, linenum);
647                 if (!ciphers_valid(arg))
648                         fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
649                             filename, linenum, arg ? arg : "<NONE>");
650                 if (*activep && options->ciphers == NULL)
651                         options->ciphers = xstrdup(arg);
652                 break;
653
654         case oMacs:
655                 arg = strdelim(&s);
656                 if (!arg || *arg == '\0')
657                         fatal("%.200s line %d: Missing argument.", filename, linenum);
658                 if (!mac_valid(arg))
659                         fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
660                             filename, linenum, arg ? arg : "<NONE>");
661                 if (*activep && options->macs == NULL)
662                         options->macs = xstrdup(arg);
663                 break;
664
665         case oHostKeyAlgorithms:
666                 arg = strdelim(&s);
667                 if (!arg || *arg == '\0')
668                         fatal("%.200s line %d: Missing argument.", filename, linenum);
669                 if (!key_names_valid2(arg))
670                         fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
671                             filename, linenum, arg ? arg : "<NONE>");
672                 if (*activep && options->hostkeyalgorithms == NULL)
673                         options->hostkeyalgorithms = xstrdup(arg);
674                 break;
675
676         case oProtocol:
677                 intptr = &options->protocol;
678                 arg = strdelim(&s);
679                 if (!arg || *arg == '\0')
680                         fatal("%.200s line %d: Missing argument.", filename, linenum);
681                 value = proto_spec(arg);
682                 if (value == SSH_PROTO_UNKNOWN)
683                         fatal("%.200s line %d: Bad protocol spec '%s'.",
684                             filename, linenum, arg ? arg : "<NONE>");
685                 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
686                         *intptr = value;
687                 break;
688
689         case oLogLevel:
690                 intptr = (int *) &options->log_level;
691                 arg = strdelim(&s);
692                 value = log_level_number(arg);
693                 if (value == SYSLOG_LEVEL_NOT_SET)
694                         fatal("%.200s line %d: unsupported log level '%s'",
695                             filename, linenum, arg ? arg : "<NONE>");
696                 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
697                         *intptr = (LogLevel) value;
698                 break;
699
700         case oLocalForward:
701         case oRemoteForward:
702                 arg = strdelim(&s);
703                 if (arg == NULL || *arg == '\0')
704                         fatal("%.200s line %d: Missing port argument.",
705                             filename, linenum);
706                 arg2 = strdelim(&s);
707                 if (arg2 == NULL || *arg2 == '\0')
708                         fatal("%.200s line %d: Missing target argument.",
709                             filename, linenum);
710
711                 /* construct a string for parse_forward */
712                 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
713
714                 if (parse_forward(&fwd, fwdarg) == 0)
715                         fatal("%.200s line %d: Bad forwarding specification.",
716                             filename, linenum);
717
718                 if (*activep) {
719                         if (opcode == oLocalForward)
720                                 add_local_forward(options, &fwd);
721                         else if (opcode == oRemoteForward)
722                                 add_remote_forward(options, &fwd);
723                 }
724                 break;
725
726         case oDynamicForward:
727                 arg = strdelim(&s);
728                 if (!arg || *arg == '\0')
729                         fatal("%.200s line %d: Missing port argument.",
730                             filename, linenum);
731                 memset(&fwd, '\0', sizeof(fwd));
732                 fwd.connect_host = "socks";
733                 fwd.listen_host = hpdelim(&arg);
734                 if (fwd.listen_host == NULL ||
735                     strlen(fwd.listen_host) >= NI_MAXHOST)
736                         fatal("%.200s line %d: Bad forwarding specification.",
737                             filename, linenum);
738                 if (arg) {
739                         fwd.listen_port = a2port(arg);
740                         fwd.listen_host = cleanhostname(fwd.listen_host);
741                 } else {
742                         fwd.listen_port = a2port(fwd.listen_host);
743                         fwd.listen_host = NULL;
744                 }
745                 if (fwd.listen_port == 0)
746                         fatal("%.200s line %d: Badly formatted port number.",
747                             filename, linenum);
748                 if (*activep)
749                         add_local_forward(options, &fwd);
750                 break;
751
752         case oClearAllForwardings:
753                 intptr = &options->clear_forwardings;
754                 goto parse_flag;
755
756         case oHost:
757                 *activep = 0;
758                 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
759                         if (match_pattern(host, arg)) {
760                                 debug("Applying options for %.100s", arg);
761                                 *activep = 1;
762                                 break;
763                         }
764                 /* Avoid garbage check below, as strdelim is done. */
765                 return 0;
766
767         case oEscapeChar:
768                 intptr = &options->escape_char;
769                 arg = strdelim(&s);
770                 if (!arg || *arg == '\0')
771                         fatal("%.200s line %d: Missing argument.", filename, linenum);
772                 if (arg[0] == '^' && arg[2] == 0 &&
773                     (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
774                         value = (u_char) arg[1] & 31;
775                 else if (strlen(arg) == 1)
776                         value = (u_char) arg[0];
777                 else if (strcmp(arg, "none") == 0)
778                         value = SSH_ESCAPECHAR_NONE;
779                 else {
780                         fatal("%.200s line %d: Bad escape character.",
781                             filename, linenum);
782                         /* NOTREACHED */
783                         value = 0;      /* Avoid compiler warning. */
784                 }
785                 if (*activep && *intptr == -1)
786                         *intptr = value;
787                 break;
788
789         case oAddressFamily:
790                 arg = strdelim(&s);
791                 if (!arg || *arg == '\0')
792                         fatal("%s line %d: missing address family.",
793                             filename, linenum);
794                 intptr = &options->address_family;
795                 if (strcasecmp(arg, "inet") == 0)
796                         value = AF_INET;
797                 else if (strcasecmp(arg, "inet6") == 0)
798                         value = AF_INET6;
799                 else if (strcasecmp(arg, "any") == 0)
800                         value = AF_UNSPEC;
801                 else
802                         fatal("Unsupported AddressFamily \"%s\"", arg);
803                 if (*activep && *intptr == -1)
804                         *intptr = value;
805                 break;
806
807         case oEnableSSHKeysign:
808                 intptr = &options->enable_ssh_keysign;
809                 goto parse_flag;
810
811         case oIdentitiesOnly:
812                 intptr = &options->identities_only;
813                 goto parse_flag;
814
815         case oServerAliveInterval:
816                 intptr = &options->server_alive_interval;
817                 goto parse_time;
818
819         case oServerAliveCountMax:
820                 intptr = &options->server_alive_count_max;
821                 goto parse_int;
822
823         case oSendEnv:
824                 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
825                         if (strchr(arg, '=') != NULL)
826                                 fatal("%s line %d: Invalid environment name.",
827                                     filename, linenum);
828                         if (!*activep)
829                                 continue;
830                         if (options->num_send_env >= MAX_SEND_ENV)
831                                 fatal("%s line %d: too many send env.",
832                                     filename, linenum);
833                         options->send_env[options->num_send_env++] =
834                             xstrdup(arg);
835                 }
836                 break;
837
838         case oControlPath:
839                 charptr = &options->control_path;
840                 goto parse_string;
841
842         case oControlMaster:
843                 intptr = &options->control_master;
844                 arg = strdelim(&s);
845                 if (!arg || *arg == '\0')
846                         fatal("%.200s line %d: Missing ControlMaster argument.",
847                             filename, linenum);
848                 value = 0;      /* To avoid compiler warning... */
849                 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
850                         value = SSHCTL_MASTER_YES;
851                 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
852                         value = SSHCTL_MASTER_NO;
853                 else if (strcmp(arg, "auto") == 0)
854                         value = SSHCTL_MASTER_AUTO;
855                 else if (strcmp(arg, "ask") == 0)
856                         value = SSHCTL_MASTER_ASK;
857                 else if (strcmp(arg, "autoask") == 0)
858                         value = SSHCTL_MASTER_AUTO_ASK;
859                 else
860                         fatal("%.200s line %d: Bad ControlMaster argument.",
861                             filename, linenum);
862                 if (*activep && *intptr == -1)
863                         *intptr = value;
864                 break;
865
866         case oHashKnownHosts:
867                 intptr = &options->hash_known_hosts;
868                 goto parse_flag;
869
870         case oTunnel:
871                 intptr = &options->tun_open;
872                 arg = strdelim(&s);
873                 if (!arg || *arg == '\0')
874                         fatal("%s line %d: Missing yes/point-to-point/"
875                             "ethernet/no argument.", filename, linenum);
876                 value = 0;      /* silence compiler */
877                 if (strcasecmp(arg, "ethernet") == 0)
878                         value = SSH_TUNMODE_ETHERNET;
879                 else if (strcasecmp(arg, "point-to-point") == 0)
880                         value = SSH_TUNMODE_POINTOPOINT;
881                 else if (strcasecmp(arg, "yes") == 0)
882                         value = SSH_TUNMODE_DEFAULT;
883                 else if (strcasecmp(arg, "no") == 0)
884                         value = SSH_TUNMODE_NO;
885                 else
886                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
887                             "no argument: %s", filename, linenum, arg);
888                 if (*activep)
889                         *intptr = value;
890                 break;
891
892         case oTunnelDevice:
893                 arg = strdelim(&s);
894                 if (!arg || *arg == '\0')
895                         fatal("%.200s line %d: Missing argument.", filename, linenum);
896                 value = a2tun(arg, &value2);
897                 if (value == SSH_TUNID_ERR)
898                         fatal("%.200s line %d: Bad tun device.", filename, linenum);
899                 if (*activep) {
900                         options->tun_local = value;
901                         options->tun_remote = value2;
902                 }
903                 break;
904
905         case oLocalCommand:
906                 charptr = &options->local_command;
907                 goto parse_command;
908
909         case oPermitLocalCommand:
910                 intptr = &options->permit_local_command;
911                 goto parse_flag;
912
913         case oDeprecated:
914                 debug("%s line %d: Deprecated option \"%s\"",
915                     filename, linenum, keyword);
916                 return 0;
917
918         case oUnsupported:
919                 error("%s line %d: Unsupported option \"%s\"",
920                     filename, linenum, keyword);
921                 return 0;
922
923         default:
924                 fatal("process_config_line: Unimplemented opcode %d", opcode);
925         }
926
927         /* Check that there is no garbage at end of line. */
928         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
929                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
930                     filename, linenum, arg);
931         }
932         return 0;
933 }
934
935
936 /*
937  * Reads the config file and modifies the options accordingly.  Options
938  * should already be initialized before this call.  This never returns if
939  * there is an error.  If the file does not exist, this returns 0.
940  */
941
942 int
943 read_config_file(const char *filename, const char *host, Options *options,
944     int checkperm)
945 {
946         FILE *f;
947         char line[1024];
948         int active, linenum;
949         int bad_options = 0;
950
951         /* Open the file. */
952         if ((f = fopen(filename, "r")) == NULL)
953                 return 0;
954
955         if (checkperm) {
956                 struct stat sb;
957
958                 if (fstat(fileno(f), &sb) == -1)
959                         fatal("fstat %s: %s", filename, strerror(errno));
960                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
961                     (sb.st_mode & 022) != 0))
962                         fatal("Bad owner or permissions on %s", filename);
963         }
964
965         debug("Reading configuration data %.200s", filename);
966
967         /*
968          * Mark that we are now processing the options.  This flag is turned
969          * on/off by Host specifications.
970          */
971         active = 1;
972         linenum = 0;
973         while (fgets(line, sizeof(line), f)) {
974                 /* Update line number counter. */
975                 linenum++;
976                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
977                         bad_options++;
978         }
979         fclose(f);
980         if (bad_options > 0)
981                 fatal("%s: terminating, %d bad configuration options",
982                     filename, bad_options);
983         return 1;
984 }
985
986 /*
987  * Initializes options to special values that indicate that they have not yet
988  * been set.  Read_config_file will only set options with this value. Options
989  * are processed in the following order: command line, user config file,
990  * system config file.  Last, fill_default_options is called.
991  */
992
993 void
994 initialize_options(Options * options)
995 {
996         memset(options, 'X', sizeof(*options));
997         options->forward_agent = -1;
998         options->forward_x11 = -1;
999         options->forward_x11_trusted = -1;
1000         options->exit_on_forward_failure = -1;
1001         options->xauth_location = NULL;
1002         options->gateway_ports = -1;
1003         options->use_privileged_port = -1;
1004         options->rsa_authentication = -1;
1005         options->pubkey_authentication = -1;
1006         options->challenge_response_authentication = -1;
1007         options->gss_authentication = -1;
1008         options->gss_deleg_creds = -1;
1009         options->password_authentication = -1;
1010         options->kbd_interactive_authentication = -1;
1011         options->kbd_interactive_devices = NULL;
1012         options->rhosts_rsa_authentication = -1;
1013         options->hostbased_authentication = -1;
1014         options->batch_mode = -1;
1015         options->check_host_ip = -1;
1016         options->strict_host_key_checking = -1;
1017         options->compression = -1;
1018         options->tcp_keep_alive = -1;
1019         options->compression_level = -1;
1020         options->port = -1;
1021         options->address_family = -1;
1022         options->connection_attempts = -1;
1023         options->connection_timeout = -1;
1024         options->number_of_password_prompts = -1;
1025         options->cipher = -1;
1026         options->ciphers = NULL;
1027         options->macs = NULL;
1028         options->hostkeyalgorithms = NULL;
1029         options->protocol = SSH_PROTO_UNKNOWN;
1030         options->num_identity_files = 0;
1031         options->hostname = NULL;
1032         options->host_key_alias = NULL;
1033         options->proxy_command = NULL;
1034         options->user = NULL;
1035         options->escape_char = -1;
1036         options->system_hostfile = NULL;
1037         options->user_hostfile = NULL;
1038         options->system_hostfile2 = NULL;
1039         options->user_hostfile2 = NULL;
1040         options->num_local_forwards = 0;
1041         options->num_remote_forwards = 0;
1042         options->clear_forwardings = -1;
1043         options->log_level = SYSLOG_LEVEL_NOT_SET;
1044         options->preferred_authentications = NULL;
1045         options->bind_address = NULL;
1046         options->smartcard_device = NULL;
1047         options->enable_ssh_keysign = - 1;
1048         options->no_host_authentication_for_localhost = - 1;
1049         options->identities_only = - 1;
1050         options->rekey_limit = - 1;
1051         options->verify_host_key_dns = -1;
1052         options->server_alive_interval = -1;
1053         options->server_alive_count_max = -1;
1054         options->num_send_env = 0;
1055         options->control_path = NULL;
1056         options->control_master = -1;
1057         options->hash_known_hosts = -1;
1058         options->tun_open = -1;
1059         options->tun_local = -1;
1060         options->tun_remote = -1;
1061         options->local_command = NULL;
1062         options->permit_local_command = -1;
1063 }
1064
1065 /*
1066  * Called after processing other sources of option data, this fills those
1067  * options for which no value has been specified with their default values.
1068  */
1069
1070 void
1071 fill_default_options(Options * options)
1072 {
1073         int len;
1074
1075         if (options->forward_agent == -1)
1076                 options->forward_agent = 0;
1077         if (options->forward_x11 == -1)
1078                 options->forward_x11 = 0;
1079         if (options->forward_x11_trusted == -1)
1080                 options->forward_x11_trusted = 0;
1081         if (options->exit_on_forward_failure == -1)
1082                 options->exit_on_forward_failure = 0;
1083         if (options->xauth_location == NULL)
1084                 options->xauth_location = _PATH_XAUTH;
1085         if (options->gateway_ports == -1)
1086                 options->gateway_ports = 0;
1087         if (options->use_privileged_port == -1)
1088                 options->use_privileged_port = 0;
1089         if (options->rsa_authentication == -1)
1090                 options->rsa_authentication = 1;
1091         if (options->pubkey_authentication == -1)
1092                 options->pubkey_authentication = 1;
1093         if (options->challenge_response_authentication == -1)
1094                 options->challenge_response_authentication = 1;
1095         if (options->gss_authentication == -1)
1096                 options->gss_authentication = 0;
1097         if (options->gss_deleg_creds == -1)
1098                 options->gss_deleg_creds = 0;
1099         if (options->password_authentication == -1)
1100                 options->password_authentication = 1;
1101         if (options->kbd_interactive_authentication == -1)
1102                 options->kbd_interactive_authentication = 1;
1103         if (options->rhosts_rsa_authentication == -1)
1104                 options->rhosts_rsa_authentication = 0;
1105         if (options->hostbased_authentication == -1)
1106                 options->hostbased_authentication = 0;
1107         if (options->batch_mode == -1)
1108                 options->batch_mode = 0;
1109         if (options->check_host_ip == -1)
1110                 options->check_host_ip = 1;
1111         if (options->strict_host_key_checking == -1)
1112                 options->strict_host_key_checking = 2;  /* 2 is default */
1113         if (options->compression == -1)
1114                 options->compression = 0;
1115         if (options->tcp_keep_alive == -1)
1116                 options->tcp_keep_alive = 1;
1117         if (options->compression_level == -1)
1118                 options->compression_level = 6;
1119         if (options->port == -1)
1120                 options->port = 0;      /* Filled in ssh_connect. */
1121         if (options->address_family == -1)
1122                 options->address_family = AF_UNSPEC;
1123         if (options->connection_attempts == -1)
1124                 options->connection_attempts = 1;
1125         if (options->number_of_password_prompts == -1)
1126                 options->number_of_password_prompts = 3;
1127         /* Selected in ssh_login(). */
1128         if (options->cipher == -1)
1129                 options->cipher = SSH_CIPHER_NOT_SET;
1130         /* options->ciphers, default set in myproposals.h */
1131         /* options->macs, default set in myproposals.h */
1132         /* options->hostkeyalgorithms, default set in myproposals.h */
1133         if (options->protocol == SSH_PROTO_UNKNOWN)
1134                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1135         if (options->num_identity_files == 0) {
1136                 if (options->protocol & SSH_PROTO_1) {
1137                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1138                         options->identity_files[options->num_identity_files] =
1139                             xmalloc(len);
1140                         snprintf(options->identity_files[options->num_identity_files++],
1141                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1142                 }
1143                 if (options->protocol & SSH_PROTO_2) {
1144                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1145                         options->identity_files[options->num_identity_files] =
1146                             xmalloc(len);
1147                         snprintf(options->identity_files[options->num_identity_files++],
1148                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1149
1150                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1151                         options->identity_files[options->num_identity_files] =
1152                             xmalloc(len);
1153                         snprintf(options->identity_files[options->num_identity_files++],
1154                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1155                 }
1156         }
1157         if (options->escape_char == -1)
1158                 options->escape_char = '~';
1159         if (options->system_hostfile == NULL)
1160                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1161         if (options->user_hostfile == NULL)
1162                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1163         if (options->system_hostfile2 == NULL)
1164                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1165         if (options->user_hostfile2 == NULL)
1166                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1167         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1168                 options->log_level = SYSLOG_LEVEL_INFO;
1169         if (options->clear_forwardings == 1)
1170                 clear_forwardings(options);
1171         if (options->no_host_authentication_for_localhost == - 1)
1172                 options->no_host_authentication_for_localhost = 0;
1173         if (options->identities_only == -1)
1174                 options->identities_only = 0;
1175         if (options->enable_ssh_keysign == -1)
1176                 options->enable_ssh_keysign = 0;
1177         if (options->rekey_limit == -1)
1178                 options->rekey_limit = 0;
1179         if (options->verify_host_key_dns == -1)
1180                 options->verify_host_key_dns = 0;
1181         if (options->server_alive_interval == -1)
1182                 options->server_alive_interval = 0;
1183         if (options->server_alive_count_max == -1)
1184                 options->server_alive_count_max = 3;
1185         if (options->control_master == -1)
1186                 options->control_master = 0;
1187         if (options->hash_known_hosts == -1)
1188                 options->hash_known_hosts = 0;
1189         if (options->tun_open == -1)
1190                 options->tun_open = SSH_TUNMODE_NO;
1191         if (options->tun_local == -1)
1192                 options->tun_local = SSH_TUNID_ANY;
1193         if (options->tun_remote == -1)
1194                 options->tun_remote = SSH_TUNID_ANY;
1195         if (options->permit_local_command == -1)
1196                 options->permit_local_command = 0;
1197         /* options->local_command should not be set by default */
1198         /* options->proxy_command should not be set by default */
1199         /* options->user will be set in the main program if appropriate */
1200         /* options->hostname will be set in the main program if appropriate */
1201         /* options->host_key_alias should not be set by default */
1202         /* options->preferred_authentications will be set in ssh */
1203 }
1204
1205 /*
1206  * parse_forward
1207  * parses a string containing a port forwarding specification of the form:
1208  *      [listenhost:]listenport:connecthost:connectport
1209  * returns number of arguments parsed or zero on error
1210  */
1211 int
1212 parse_forward(Forward *fwd, const char *fwdspec)
1213 {
1214         int i;
1215         char *p, *cp, *fwdarg[4];
1216
1217         memset(fwd, '\0', sizeof(*fwd));
1218
1219         cp = p = xstrdup(fwdspec);
1220
1221         /* skip leading spaces */
1222         while (*cp && isspace(*cp))
1223                 cp++;
1224
1225         for (i = 0; i < 4; ++i)
1226                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1227                         break;
1228
1229         /* Check for trailing garbage in 4-arg case*/
1230         if (cp != NULL)
1231                 i = 0;  /* failure */
1232
1233         switch (i) {
1234         case 3:
1235                 fwd->listen_host = NULL;
1236                 fwd->listen_port = a2port(fwdarg[0]);
1237                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1238                 fwd->connect_port = a2port(fwdarg[2]);
1239                 break;
1240
1241         case 4:
1242                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1243                 fwd->listen_port = a2port(fwdarg[1]);
1244                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1245                 fwd->connect_port = a2port(fwdarg[3]);
1246                 break;
1247         default:
1248                 i = 0; /* failure */
1249         }
1250
1251         xfree(p);
1252
1253         if (fwd->listen_port == 0 && fwd->connect_port == 0)
1254                 goto fail_free;
1255
1256         if (fwd->connect_host != NULL &&
1257             strlen(fwd->connect_host) >= NI_MAXHOST)
1258                 goto fail_free;
1259
1260         return (i);
1261
1262  fail_free:
1263         if (fwd->connect_host != NULL)
1264                 xfree(fwd->connect_host);
1265         if (fwd->listen_host != NULL)
1266                 xfree(fwd->listen_host);
1267         return (0);
1268 }
This page took 0.141526 seconds and 5 git commands to generate.