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