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