]> andersk Git - gssapi-openssh.git/blob - openssh/readconf.c
Import of OpenSSH 4.0p1
[gssapi-openssh.git] / openssh / 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.137 2005/03/04 08:48:06 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 (!*activep)
779                                 continue;
780                         if (options->num_send_env >= MAX_SEND_ENV)
781                                 fatal("%s line %d: too many send env.",
782                                     filename, linenum);
783                         options->send_env[options->num_send_env++] =
784                             xstrdup(arg);
785                 }
786                 break;
787
788         case oControlPath:
789                 charptr = &options->control_path;
790                 goto parse_string;
791
792         case oControlMaster:
793                 intptr = &options->control_master;
794                 goto parse_yesnoask;
795
796         case oHashKnownHosts:
797                 intptr = &options->hash_known_hosts;
798                 goto parse_flag;
799
800         case oDeprecated:
801                 debug("%s line %d: Deprecated option \"%s\"",
802                     filename, linenum, keyword);
803                 return 0;
804
805         case oUnsupported:
806                 error("%s line %d: Unsupported option \"%s\"",
807                     filename, linenum, keyword);
808                 return 0;
809
810         default:
811                 fatal("process_config_line: Unimplemented opcode %d", opcode);
812         }
813
814         /* Check that there is no garbage at end of line. */
815         if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
816                 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
817                      filename, linenum, arg);
818         }
819         return 0;
820 }
821
822
823 /*
824  * Reads the config file and modifies the options accordingly.  Options
825  * should already be initialized before this call.  This never returns if
826  * there is an error.  If the file does not exist, this returns 0.
827  */
828
829 int
830 read_config_file(const char *filename, const char *host, Options *options,
831     int checkperm)
832 {
833         FILE *f;
834         char line[1024];
835         int active, linenum;
836         int bad_options = 0;
837
838         /* Open the file. */
839         if ((f = fopen(filename, "r")) == NULL)
840                 return 0;
841
842         if (checkperm) {
843                 struct stat sb;
844
845                 if (fstat(fileno(f), &sb) == -1)
846                         fatal("fstat %s: %s", filename, strerror(errno));
847                 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
848                     (sb.st_mode & 022) != 0))
849                         fatal("Bad owner or permissions on %s", filename);
850         }
851
852         debug("Reading configuration data %.200s", filename);
853
854         /*
855          * Mark that we are now processing the options.  This flag is turned
856          * on/off by Host specifications.
857          */
858         active = 1;
859         linenum = 0;
860         while (fgets(line, sizeof(line), f)) {
861                 /* Update line number counter. */
862                 linenum++;
863                 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
864                         bad_options++;
865         }
866         fclose(f);
867         if (bad_options > 0)
868                 fatal("%s: terminating, %d bad configuration options",
869                     filename, bad_options);
870         return 1;
871 }
872
873 /*
874  * Initializes options to special values that indicate that they have not yet
875  * been set.  Read_config_file will only set options with this value. Options
876  * are processed in the following order: command line, user config file,
877  * system config file.  Last, fill_default_options is called.
878  */
879
880 void
881 initialize_options(Options * options)
882 {
883         memset(options, 'X', sizeof(*options));
884         options->forward_agent = -1;
885         options->forward_x11 = -1;
886         options->forward_x11_trusted = -1;
887         options->xauth_location = NULL;
888         options->gateway_ports = -1;
889         options->use_privileged_port = -1;
890         options->rsa_authentication = -1;
891         options->pubkey_authentication = -1;
892         options->challenge_response_authentication = -1;
893         options->gss_authentication = -1;
894         options->gss_deleg_creds = -1;
895         options->password_authentication = -1;
896         options->kbd_interactive_authentication = -1;
897         options->kbd_interactive_devices = NULL;
898         options->rhosts_rsa_authentication = -1;
899         options->hostbased_authentication = -1;
900         options->batch_mode = -1;
901         options->check_host_ip = -1;
902         options->strict_host_key_checking = -1;
903         options->compression = -1;
904         options->tcp_keep_alive = -1;
905         options->compression_level = -1;
906         options->port = -1;
907         options->address_family = -1;
908         options->connection_attempts = -1;
909         options->connection_timeout = -1;
910         options->number_of_password_prompts = -1;
911         options->cipher = -1;
912         options->ciphers = NULL;
913         options->macs = NULL;
914         options->hostkeyalgorithms = NULL;
915         options->protocol = SSH_PROTO_UNKNOWN;
916         options->num_identity_files = 0;
917         options->hostname = NULL;
918         options->host_key_alias = NULL;
919         options->proxy_command = NULL;
920         options->user = NULL;
921         options->escape_char = -1;
922         options->system_hostfile = NULL;
923         options->user_hostfile = NULL;
924         options->system_hostfile2 = NULL;
925         options->user_hostfile2 = NULL;
926         options->num_local_forwards = 0;
927         options->num_remote_forwards = 0;
928         options->clear_forwardings = -1;
929         options->log_level = SYSLOG_LEVEL_NOT_SET;
930         options->preferred_authentications = NULL;
931         options->bind_address = NULL;
932         options->smartcard_device = NULL;
933         options->enable_ssh_keysign = - 1;
934         options->no_host_authentication_for_localhost = - 1;
935         options->identities_only = - 1;
936         options->rekey_limit = - 1;
937         options->verify_host_key_dns = -1;
938         options->server_alive_interval = -1;
939         options->server_alive_count_max = -1;
940         options->num_send_env = 0;
941         options->control_path = NULL;
942         options->control_master = -1;
943         options->hash_known_hosts = -1;
944 }
945
946 /*
947  * Called after processing other sources of option data, this fills those
948  * options for which no value has been specified with their default values.
949  */
950
951 void
952 fill_default_options(Options * options)
953 {
954         int len;
955
956         if (options->forward_agent == -1)
957                 options->forward_agent = 0;
958         if (options->forward_x11 == -1)
959                 options->forward_x11 = 0;
960         if (options->forward_x11_trusted == -1)
961                 options->forward_x11_trusted = 0;
962         if (options->xauth_location == NULL)
963                 options->xauth_location = _PATH_XAUTH;
964         if (options->gateway_ports == -1)
965                 options->gateway_ports = 0;
966         if (options->use_privileged_port == -1)
967                 options->use_privileged_port = 0;
968         if (options->rsa_authentication == -1)
969                 options->rsa_authentication = 1;
970         if (options->pubkey_authentication == -1)
971                 options->pubkey_authentication = 1;
972         if (options->challenge_response_authentication == -1)
973                 options->challenge_response_authentication = 1;
974         if (options->gss_authentication == -1)
975                 options->gss_authentication = 0;
976         if (options->gss_deleg_creds == -1)
977                 options->gss_deleg_creds = 0;
978         if (options->password_authentication == -1)
979                 options->password_authentication = 1;
980         if (options->kbd_interactive_authentication == -1)
981                 options->kbd_interactive_authentication = 1;
982         if (options->rhosts_rsa_authentication == -1)
983                 options->rhosts_rsa_authentication = 0;
984         if (options->hostbased_authentication == -1)
985                 options->hostbased_authentication = 0;
986         if (options->batch_mode == -1)
987                 options->batch_mode = 0;
988         if (options->check_host_ip == -1)
989                 options->check_host_ip = 1;
990         if (options->strict_host_key_checking == -1)
991                 options->strict_host_key_checking = 2;  /* 2 is default */
992         if (options->compression == -1)
993                 options->compression = 0;
994         if (options->tcp_keep_alive == -1)
995                 options->tcp_keep_alive = 1;
996         if (options->compression_level == -1)
997                 options->compression_level = 6;
998         if (options->port == -1)
999                 options->port = 0;      /* Filled in ssh_connect. */
1000         if (options->address_family == -1)
1001                 options->address_family = AF_UNSPEC;
1002         if (options->connection_attempts == -1)
1003                 options->connection_attempts = 1;
1004         if (options->number_of_password_prompts == -1)
1005                 options->number_of_password_prompts = 3;
1006         /* Selected in ssh_login(). */
1007         if (options->cipher == -1)
1008                 options->cipher = SSH_CIPHER_NOT_SET;
1009         /* options->ciphers, default set in myproposals.h */
1010         /* options->macs, default set in myproposals.h */
1011         /* options->hostkeyalgorithms, default set in myproposals.h */
1012         if (options->protocol == SSH_PROTO_UNKNOWN)
1013                 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1014         if (options->num_identity_files == 0) {
1015                 if (options->protocol & SSH_PROTO_1) {
1016                         len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1017                         options->identity_files[options->num_identity_files] =
1018                             xmalloc(len);
1019                         snprintf(options->identity_files[options->num_identity_files++],
1020                             len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1021                 }
1022                 if (options->protocol & SSH_PROTO_2) {
1023                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1024                         options->identity_files[options->num_identity_files] =
1025                             xmalloc(len);
1026                         snprintf(options->identity_files[options->num_identity_files++],
1027                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1028
1029                         len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1030                         options->identity_files[options->num_identity_files] =
1031                             xmalloc(len);
1032                         snprintf(options->identity_files[options->num_identity_files++],
1033                             len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1034                 }
1035         }
1036         if (options->escape_char == -1)
1037                 options->escape_char = '~';
1038         if (options->system_hostfile == NULL)
1039                 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1040         if (options->user_hostfile == NULL)
1041                 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1042         if (options->system_hostfile2 == NULL)
1043                 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1044         if (options->user_hostfile2 == NULL)
1045                 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1046         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1047                 options->log_level = SYSLOG_LEVEL_INFO;
1048         if (options->clear_forwardings == 1)
1049                 clear_forwardings(options);
1050         if (options->no_host_authentication_for_localhost == - 1)
1051                 options->no_host_authentication_for_localhost = 0;
1052         if (options->identities_only == -1)
1053                 options->identities_only = 0;
1054         if (options->enable_ssh_keysign == -1)
1055                 options->enable_ssh_keysign = 0;
1056         if (options->rekey_limit == -1)
1057                 options->rekey_limit = 0;
1058         if (options->verify_host_key_dns == -1)
1059                 options->verify_host_key_dns = 0;
1060         if (options->server_alive_interval == -1)
1061                 options->server_alive_interval = 0;
1062         if (options->server_alive_count_max == -1)
1063                 options->server_alive_count_max = 3;
1064         if (options->control_master == -1)
1065                 options->control_master = 0;
1066         if (options->hash_known_hosts == -1)
1067                 options->hash_known_hosts = 0;
1068         /* options->proxy_command should not be set by default */
1069         /* options->user will be set in the main program if appropriate */
1070         /* options->hostname will be set in the main program if appropriate */
1071         /* options->host_key_alias should not be set by default */
1072         /* options->preferred_authentications will be set in ssh */
1073 }
1074
1075 /*
1076  * parse_forward
1077  * parses a string containing a port forwarding specification of the form:
1078  *      [listenhost:]listenport:connecthost:connectport
1079  * returns number of arguments parsed or zero on error
1080  */
1081 int
1082 parse_forward(Forward *fwd, const char *fwdspec)
1083 {
1084         int i;
1085         char *p, *cp, *fwdarg[4];
1086
1087         memset(fwd, '\0', sizeof(*fwd));
1088
1089         cp = p = xstrdup(fwdspec);
1090
1091         /* skip leading spaces */
1092         while (*cp && isspace(*cp))
1093                 cp++;
1094
1095         for (i = 0; i < 4; ++i)
1096                 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1097                         break;
1098
1099         /* Check for trailing garbage in 4-arg case*/
1100         if (cp != NULL)
1101                 i = 0;  /* failure */
1102
1103         switch (i) {
1104         case 3:
1105                 fwd->listen_host = NULL;
1106                 fwd->listen_port = a2port(fwdarg[0]);
1107                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1108                 fwd->connect_port = a2port(fwdarg[2]);
1109                 break;
1110
1111         case 4:
1112                 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1113                 fwd->listen_port = a2port(fwdarg[1]);
1114                 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1115                 fwd->connect_port = a2port(fwdarg[3]);
1116                 break;
1117         default:
1118                 i = 0; /* failure */
1119         }
1120
1121         xfree(p);
1122
1123         if (fwd->listen_port == 0 && fwd->connect_port == 0)
1124                 goto fail_free;
1125
1126         if (fwd->connect_host != NULL &&
1127             strlen(fwd->connect_host) >= NI_MAXHOST)
1128                 goto fail_free;
1129
1130         return (i);
1131
1132  fail_free:
1133         if (fwd->connect_host != NULL)
1134                 xfree(fwd->connect_host);
1135         if (fwd->listen_host != NULL)
1136                 xfree(fwd->listen_host);
1137         return (0);
1138 }
This page took 0.231885 seconds and 5 git commands to generate.