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