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