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