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