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