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