- djm@cvs.openbsd.org 2005/05/19 02:39:55
[openssh-git.git] / readconf.c
blobd41220807ad0df0d9d38b969a2d477cb9b36af59
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.
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".
14 #include "includes.h"
15 RCSID("$OpenBSD: readconf.c,v 1.140 2005/05/16 15:30:51 markus Exp $");
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"
29 /* Format of the configuration file:
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.
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.
43 Host *.ngs.fi ngs.fi
44 User foo
46 Host fake.com
47 HostName another.host.name.real.org
48 User blaah
49 Port 34289
50 ForwardX11 no
51 ForwardAgent no
53 Host books.com
54 RemoteForward 9999 shadows.cs.hut.fi:9999
55 Cipher 3des
57 Host fascist.blob.com
58 Port 23123
59 User tylonen
60 PasswordAuthentication no
62 Host puukko.hut.fi
63 User t35124p
64 ProxyCommand ssh-proxy %h %p
66 Host *.fr
67 PublicKeyAuthentication no
69 Host *.su
70 Cipher none
71 PasswordAuthentication no
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 ~
88 /* Keyword tokens. */
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;
113 /* Textual representations of the tokens. */
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 }
205 * Adds a local TCP/IP port forward to options. Never returns if there is an
206 * error.
209 void
210 add_local_forward(Options *options, const Forward *newfwd)
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++];
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;
230 * Adds a remote TCP/IP port forward to options. Never returns if there is
231 * an error.
234 void
235 add_remote_forward(Options *options, const Forward *newfwd)
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++];
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;
250 static void
251 clear_forwardings(Options *options)
253 int i;
255 for (i = 0; i < options->num_local_forwards; i++) {
256 if (options->local_forwards[i].listen_host != NULL)
257 xfree(options->local_forwards[i].listen_host);
258 xfree(options->local_forwards[i].connect_host);
260 options->num_local_forwards = 0;
261 for (i = 0; i < options->num_remote_forwards; i++) {
262 if (options->remote_forwards[i].listen_host != NULL)
263 xfree(options->remote_forwards[i].listen_host);
264 xfree(options->remote_forwards[i].connect_host);
266 options->num_remote_forwards = 0;
270 * Returns the number of the token pointed to by cp or oBadOption.
273 static OpCodes
274 parse_token(const char *cp, const char *filename, int linenum)
276 u_int i;
278 for (i = 0; keywords[i].name; i++)
279 if (strcasecmp(cp, keywords[i].name) == 0)
280 return keywords[i].opcode;
282 error("%s: line %d: Bad configuration option: %s",
283 filename, linenum, cp);
284 return oBadOption;
288 * Processes a single option line as used in the configuration files. This
289 * only sets those values that have not already been set.
291 #define WHITESPACE " \t\r\n"
294 process_config_line(Options *options, const char *host,
295 char *line, const char *filename, int linenum,
296 int *activep)
298 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
299 int opcode, *intptr, value;
300 size_t len;
301 Forward fwd;
303 /* Strip trailing whitespace */
304 for (len = strlen(line) - 1; len > 0; len--) {
305 if (strchr(WHITESPACE, line[len]) == NULL)
306 break;
307 line[len] = '\0';
310 s = line;
311 /* Get the keyword. (Each line is supposed to begin with a keyword). */
312 keyword = strdelim(&s);
313 /* Ignore leading whitespace. */
314 if (*keyword == '\0')
315 keyword = strdelim(&s);
316 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
317 return 0;
319 opcode = parse_token(keyword, filename, linenum);
321 switch (opcode) {
322 case oBadOption:
323 /* don't panic, but count bad options */
324 return -1;
325 /* NOTREACHED */
326 case oConnectTimeout:
327 intptr = &options->connection_timeout;
328 parse_time:
329 arg = strdelim(&s);
330 if (!arg || *arg == '\0')
331 fatal("%s line %d: missing time value.",
332 filename, linenum);
333 if ((value = convtime(arg)) == -1)
334 fatal("%s line %d: invalid time value.",
335 filename, linenum);
336 if (*intptr == -1)
337 *intptr = value;
338 break;
340 case oForwardAgent:
341 intptr = &options->forward_agent;
342 parse_flag:
343 arg = strdelim(&s);
344 if (!arg || *arg == '\0')
345 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
346 value = 0; /* To avoid compiler warning... */
347 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
348 value = 1;
349 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
350 value = 0;
351 else
352 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
353 if (*activep && *intptr == -1)
354 *intptr = value;
355 break;
357 case oForwardX11:
358 intptr = &options->forward_x11;
359 goto parse_flag;
361 case oForwardX11Trusted:
362 intptr = &options->forward_x11_trusted;
363 goto parse_flag;
365 case oGatewayPorts:
366 intptr = &options->gateway_ports;
367 goto parse_flag;
369 case oUsePrivilegedPort:
370 intptr = &options->use_privileged_port;
371 goto parse_flag;
373 case oPasswordAuthentication:
374 intptr = &options->password_authentication;
375 goto parse_flag;
377 case oKbdInteractiveAuthentication:
378 intptr = &options->kbd_interactive_authentication;
379 goto parse_flag;
381 case oKbdInteractiveDevices:
382 charptr = &options->kbd_interactive_devices;
383 goto parse_string;
385 case oPubkeyAuthentication:
386 intptr = &options->pubkey_authentication;
387 goto parse_flag;
389 case oRSAAuthentication:
390 intptr = &options->rsa_authentication;
391 goto parse_flag;
393 case oRhostsRSAAuthentication:
394 intptr = &options->rhosts_rsa_authentication;
395 goto parse_flag;
397 case oHostbasedAuthentication:
398 intptr = &options->hostbased_authentication;
399 goto parse_flag;
401 case oChallengeResponseAuthentication:
402 intptr = &options->challenge_response_authentication;
403 goto parse_flag;
405 case oGssAuthentication:
406 intptr = &options->gss_authentication;
407 goto parse_flag;
409 case oGssDelegateCreds:
410 intptr = &options->gss_deleg_creds;
411 goto parse_flag;
413 case oBatchMode:
414 intptr = &options->batch_mode;
415 goto parse_flag;
417 case oCheckHostIP:
418 intptr = &options->check_host_ip;
419 goto parse_flag;
421 case oVerifyHostKeyDNS:
422 intptr = &options->verify_host_key_dns;
423 goto parse_yesnoask;
425 case oStrictHostKeyChecking:
426 intptr = &options->strict_host_key_checking;
427 parse_yesnoask:
428 arg = strdelim(&s);
429 if (!arg || *arg == '\0')
430 fatal("%.200s line %d: Missing yes/no/ask argument.",
431 filename, linenum);
432 value = 0; /* To avoid compiler warning... */
433 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
434 value = 1;
435 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
436 value = 0;
437 else if (strcmp(arg, "ask") == 0)
438 value = 2;
439 else
440 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
441 if (*activep && *intptr == -1)
442 *intptr = value;
443 break;
445 case oCompression:
446 intptr = &options->compression;
447 goto parse_flag;
449 case oTCPKeepAlive:
450 intptr = &options->tcp_keep_alive;
451 goto parse_flag;
453 case oNoHostAuthenticationForLocalhost:
454 intptr = &options->no_host_authentication_for_localhost;
455 goto parse_flag;
457 case oNumberOfPasswordPrompts:
458 intptr = &options->number_of_password_prompts;
459 goto parse_int;
461 case oCompressionLevel:
462 intptr = &options->compression_level;
463 goto parse_int;
465 case oRekeyLimit:
466 intptr = &options->rekey_limit;
467 arg = strdelim(&s);
468 if (!arg || *arg == '\0')
469 fatal("%.200s line %d: Missing argument.", filename, linenum);
470 if (arg[0] < '0' || arg[0] > '9')
471 fatal("%.200s line %d: Bad number.", filename, linenum);
472 value = strtol(arg, &endofnumber, 10);
473 if (arg == endofnumber)
474 fatal("%.200s line %d: Bad number.", filename, linenum);
475 switch (toupper(*endofnumber)) {
476 case 'K':
477 value *= 1<<10;
478 break;
479 case 'M':
480 value *= 1<<20;
481 break;
482 case 'G':
483 value *= 1<<30;
484 break;
486 if (*activep && *intptr == -1)
487 *intptr = value;
488 break;
490 case oIdentityFile:
491 arg = strdelim(&s);
492 if (!arg || *arg == '\0')
493 fatal("%.200s line %d: Missing argument.", filename, linenum);
494 if (*activep) {
495 intptr = &options->num_identity_files;
496 if (*intptr >= SSH_MAX_IDENTITY_FILES)
497 fatal("%.200s line %d: Too many identity files specified (max %d).",
498 filename, linenum, SSH_MAX_IDENTITY_FILES);
499 charptr = &options->identity_files[*intptr];
500 *charptr = xstrdup(arg);
501 *intptr = *intptr + 1;
503 break;
505 case oXAuthLocation:
506 charptr=&options->xauth_location;
507 goto parse_string;
509 case oUser:
510 charptr = &options->user;
511 parse_string:
512 arg = strdelim(&s);
513 if (!arg || *arg == '\0')
514 fatal("%.200s line %d: Missing argument.", filename, linenum);
515 if (*activep && *charptr == NULL)
516 *charptr = xstrdup(arg);
517 break;
519 case oGlobalKnownHostsFile:
520 charptr = &options->system_hostfile;
521 goto parse_string;
523 case oUserKnownHostsFile:
524 charptr = &options->user_hostfile;
525 goto parse_string;
527 case oGlobalKnownHostsFile2:
528 charptr = &options->system_hostfile2;
529 goto parse_string;
531 case oUserKnownHostsFile2:
532 charptr = &options->user_hostfile2;
533 goto parse_string;
535 case oHostName:
536 charptr = &options->hostname;
537 goto parse_string;
539 case oHostKeyAlias:
540 charptr = &options->host_key_alias;
541 goto parse_string;
543 case oPreferredAuthentications:
544 charptr = &options->preferred_authentications;
545 goto parse_string;
547 case oBindAddress:
548 charptr = &options->bind_address;
549 goto parse_string;
551 case oSmartcardDevice:
552 charptr = &options->smartcard_device;
553 goto parse_string;
555 case oProxyCommand:
556 if (s == NULL)
557 fatal("%.200s line %d: Missing argument.", filename, linenum);
558 charptr = &options->proxy_command;
559 len = strspn(s, WHITESPACE "=");
560 if (*activep && *charptr == NULL)
561 *charptr = xstrdup(s + len);
562 return 0;
564 case oPort:
565 intptr = &options->port;
566 parse_int:
567 arg = strdelim(&s);
568 if (!arg || *arg == '\0')
569 fatal("%.200s line %d: Missing argument.", filename, linenum);
570 if (arg[0] < '0' || arg[0] > '9')
571 fatal("%.200s line %d: Bad number.", filename, linenum);
573 /* Octal, decimal, or hex format? */
574 value = strtol(arg, &endofnumber, 0);
575 if (arg == endofnumber)
576 fatal("%.200s line %d: Bad number.", filename, linenum);
577 if (*activep && *intptr == -1)
578 *intptr = value;
579 break;
581 case oConnectionAttempts:
582 intptr = &options->connection_attempts;
583 goto parse_int;
585 case oCipher:
586 intptr = &options->cipher;
587 arg = strdelim(&s);
588 if (!arg || *arg == '\0')
589 fatal("%.200s line %d: Missing argument.", filename, linenum);
590 value = cipher_number(arg);
591 if (value == -1)
592 fatal("%.200s line %d: Bad cipher '%s'.",
593 filename, linenum, arg ? arg : "<NONE>");
594 if (*activep && *intptr == -1)
595 *intptr = value;
596 break;
598 case oCiphers:
599 arg = strdelim(&s);
600 if (!arg || *arg == '\0')
601 fatal("%.200s line %d: Missing argument.", filename, linenum);
602 if (!ciphers_valid(arg))
603 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
604 filename, linenum, arg ? arg : "<NONE>");
605 if (*activep && options->ciphers == NULL)
606 options->ciphers = xstrdup(arg);
607 break;
609 case oMacs:
610 arg = strdelim(&s);
611 if (!arg || *arg == '\0')
612 fatal("%.200s line %d: Missing argument.", filename, linenum);
613 if (!mac_valid(arg))
614 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
615 filename, linenum, arg ? arg : "<NONE>");
616 if (*activep && options->macs == NULL)
617 options->macs = xstrdup(arg);
618 break;
620 case oHostKeyAlgorithms:
621 arg = strdelim(&s);
622 if (!arg || *arg == '\0')
623 fatal("%.200s line %d: Missing argument.", filename, linenum);
624 if (!key_names_valid2(arg))
625 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
626 filename, linenum, arg ? arg : "<NONE>");
627 if (*activep && options->hostkeyalgorithms == NULL)
628 options->hostkeyalgorithms = xstrdup(arg);
629 break;
631 case oProtocol:
632 intptr = &options->protocol;
633 arg = strdelim(&s);
634 if (!arg || *arg == '\0')
635 fatal("%.200s line %d: Missing argument.", filename, linenum);
636 value = proto_spec(arg);
637 if (value == SSH_PROTO_UNKNOWN)
638 fatal("%.200s line %d: Bad protocol spec '%s'.",
639 filename, linenum, arg ? arg : "<NONE>");
640 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
641 *intptr = value;
642 break;
644 case oLogLevel:
645 intptr = (int *) &options->log_level;
646 arg = strdelim(&s);
647 value = log_level_number(arg);
648 if (value == SYSLOG_LEVEL_NOT_SET)
649 fatal("%.200s line %d: unsupported log level '%s'",
650 filename, linenum, arg ? arg : "<NONE>");
651 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
652 *intptr = (LogLevel) value;
653 break;
655 case oLocalForward:
656 case oRemoteForward:
657 arg = strdelim(&s);
658 if (arg == NULL || *arg == '\0')
659 fatal("%.200s line %d: Missing port argument.",
660 filename, linenum);
661 arg2 = strdelim(&s);
662 if (arg2 == NULL || *arg2 == '\0')
663 fatal("%.200s line %d: Missing target argument.",
664 filename, linenum);
666 /* construct a string for parse_forward */
667 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
669 if (parse_forward(&fwd, fwdarg) == 0)
670 fatal("%.200s line %d: Bad forwarding specification.",
671 filename, linenum);
673 if (*activep) {
674 if (opcode == oLocalForward)
675 add_local_forward(options, &fwd);
676 else if (opcode == oRemoteForward)
677 add_remote_forward(options, &fwd);
679 break;
681 case oDynamicForward:
682 arg = strdelim(&s);
683 if (!arg || *arg == '\0')
684 fatal("%.200s line %d: Missing port argument.",
685 filename, linenum);
686 memset(&fwd, '\0', sizeof(fwd));
687 fwd.connect_host = "socks";
688 fwd.listen_host = hpdelim(&arg);
689 if (fwd.listen_host == NULL ||
690 strlen(fwd.listen_host) >= NI_MAXHOST)
691 fatal("%.200s line %d: Bad forwarding specification.",
692 filename, linenum);
693 if (arg) {
694 fwd.listen_port = a2port(arg);
695 fwd.listen_host = cleanhostname(fwd.listen_host);
696 } else {
697 fwd.listen_port = a2port(fwd.listen_host);
698 fwd.listen_host = "";
700 if (fwd.listen_port == 0)
701 fatal("%.200s line %d: Badly formatted port number.",
702 filename, linenum);
703 if (*activep)
704 add_local_forward(options, &fwd);
705 break;
707 case oClearAllForwardings:
708 intptr = &options->clear_forwardings;
709 goto parse_flag;
711 case oHost:
712 *activep = 0;
713 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
714 if (match_pattern(host, arg)) {
715 debug("Applying options for %.100s", arg);
716 *activep = 1;
717 break;
719 /* Avoid garbage check below, as strdelim is done. */
720 return 0;
722 case oEscapeChar:
723 intptr = &options->escape_char;
724 arg = strdelim(&s);
725 if (!arg || *arg == '\0')
726 fatal("%.200s line %d: Missing argument.", filename, linenum);
727 if (arg[0] == '^' && arg[2] == 0 &&
728 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
729 value = (u_char) arg[1] & 31;
730 else if (strlen(arg) == 1)
731 value = (u_char) arg[0];
732 else if (strcmp(arg, "none") == 0)
733 value = SSH_ESCAPECHAR_NONE;
734 else {
735 fatal("%.200s line %d: Bad escape character.",
736 filename, linenum);
737 /* NOTREACHED */
738 value = 0; /* Avoid compiler warning. */
740 if (*activep && *intptr == -1)
741 *intptr = value;
742 break;
744 case oAddressFamily:
745 arg = strdelim(&s);
746 if (!arg || *arg == '\0')
747 fatal("%s line %d: missing address family.",
748 filename, linenum);
749 intptr = &options->address_family;
750 if (strcasecmp(arg, "inet") == 0)
751 value = AF_INET;
752 else if (strcasecmp(arg, "inet6") == 0)
753 value = AF_INET6;
754 else if (strcasecmp(arg, "any") == 0)
755 value = AF_UNSPEC;
756 else
757 fatal("Unsupported AddressFamily \"%s\"", arg);
758 if (*activep && *intptr == -1)
759 *intptr = value;
760 break;
762 case oEnableSSHKeysign:
763 intptr = &options->enable_ssh_keysign;
764 goto parse_flag;
766 case oIdentitiesOnly:
767 intptr = &options->identities_only;
768 goto parse_flag;
770 case oServerAliveInterval:
771 intptr = &options->server_alive_interval;
772 goto parse_time;
774 case oServerAliveCountMax:
775 intptr = &options->server_alive_count_max;
776 goto parse_int;
778 case oSendEnv:
779 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
780 if (strchr(arg, '=') != NULL)
781 fatal("%s line %d: Invalid environment name.",
782 filename, linenum);
783 if (!*activep)
784 continue;
785 if (options->num_send_env >= MAX_SEND_ENV)
786 fatal("%s line %d: too many send env.",
787 filename, linenum);
788 options->send_env[options->num_send_env++] =
789 xstrdup(arg);
791 break;
793 case oControlPath:
794 charptr = &options->control_path;
795 goto parse_string;
797 case oControlMaster:
798 intptr = &options->control_master;
799 goto parse_yesnoask;
801 case oHashKnownHosts:
802 intptr = &options->hash_known_hosts;
803 goto parse_flag;
805 case oDeprecated:
806 debug("%s line %d: Deprecated option \"%s\"",
807 filename, linenum, keyword);
808 return 0;
810 case oUnsupported:
811 error("%s line %d: Unsupported option \"%s\"",
812 filename, linenum, keyword);
813 return 0;
815 default:
816 fatal("process_config_line: Unimplemented opcode %d", opcode);
819 /* Check that there is no garbage at end of line. */
820 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
821 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
822 filename, linenum, arg);
824 return 0;
829 * Reads the config file and modifies the options accordingly. Options
830 * should already be initialized before this call. This never returns if
831 * there is an error. If the file does not exist, this returns 0.
835 read_config_file(const char *filename, const char *host, Options *options,
836 int checkperm)
838 FILE *f;
839 char line[1024];
840 int active, linenum;
841 int bad_options = 0;
843 /* Open the file. */
844 if ((f = fopen(filename, "r")) == NULL)
845 return 0;
847 if (checkperm) {
848 struct stat sb;
850 if (fstat(fileno(f), &sb) == -1)
851 fatal("fstat %s: %s", filename, strerror(errno));
852 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
853 (sb.st_mode & 022) != 0))
854 fatal("Bad owner or permissions on %s", filename);
857 debug("Reading configuration data %.200s", filename);
860 * Mark that we are now processing the options. This flag is turned
861 * on/off by Host specifications.
863 active = 1;
864 linenum = 0;
865 while (fgets(line, sizeof(line), f)) {
866 /* Update line number counter. */
867 linenum++;
868 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
869 bad_options++;
871 fclose(f);
872 if (bad_options > 0)
873 fatal("%s: terminating, %d bad configuration options",
874 filename, bad_options);
875 return 1;
879 * Initializes options to special values that indicate that they have not yet
880 * been set. Read_config_file will only set options with this value. Options
881 * are processed in the following order: command line, user config file,
882 * system config file. Last, fill_default_options is called.
885 void
886 initialize_options(Options * options)
888 memset(options, 'X', sizeof(*options));
889 options->forward_agent = -1;
890 options->forward_x11 = -1;
891 options->forward_x11_trusted = -1;
892 options->xauth_location = NULL;
893 options->gateway_ports = -1;
894 options->use_privileged_port = -1;
895 options->rsa_authentication = -1;
896 options->pubkey_authentication = -1;
897 options->challenge_response_authentication = -1;
898 options->gss_authentication = -1;
899 options->gss_deleg_creds = -1;
900 options->password_authentication = -1;
901 options->kbd_interactive_authentication = -1;
902 options->kbd_interactive_devices = NULL;
903 options->rhosts_rsa_authentication = -1;
904 options->hostbased_authentication = -1;
905 options->batch_mode = -1;
906 options->check_host_ip = -1;
907 options->strict_host_key_checking = -1;
908 options->compression = -1;
909 options->tcp_keep_alive = -1;
910 options->compression_level = -1;
911 options->port = -1;
912 options->address_family = -1;
913 options->connection_attempts = -1;
914 options->connection_timeout = -1;
915 options->number_of_password_prompts = -1;
916 options->cipher = -1;
917 options->ciphers = NULL;
918 options->macs = NULL;
919 options->hostkeyalgorithms = NULL;
920 options->protocol = SSH_PROTO_UNKNOWN;
921 options->num_identity_files = 0;
922 options->hostname = NULL;
923 options->host_key_alias = NULL;
924 options->proxy_command = NULL;
925 options->user = NULL;
926 options->escape_char = -1;
927 options->system_hostfile = NULL;
928 options->user_hostfile = NULL;
929 options->system_hostfile2 = NULL;
930 options->user_hostfile2 = NULL;
931 options->num_local_forwards = 0;
932 options->num_remote_forwards = 0;
933 options->clear_forwardings = -1;
934 options->log_level = SYSLOG_LEVEL_NOT_SET;
935 options->preferred_authentications = NULL;
936 options->bind_address = NULL;
937 options->smartcard_device = NULL;
938 options->enable_ssh_keysign = - 1;
939 options->no_host_authentication_for_localhost = - 1;
940 options->identities_only = - 1;
941 options->rekey_limit = - 1;
942 options->verify_host_key_dns = -1;
943 options->server_alive_interval = -1;
944 options->server_alive_count_max = -1;
945 options->num_send_env = 0;
946 options->control_path = NULL;
947 options->control_master = -1;
948 options->hash_known_hosts = -1;
952 * Called after processing other sources of option data, this fills those
953 * options for which no value has been specified with their default values.
956 void
957 fill_default_options(Options * options)
959 int len;
961 if (options->forward_agent == -1)
962 options->forward_agent = 0;
963 if (options->forward_x11 == -1)
964 options->forward_x11 = 0;
965 if (options->forward_x11_trusted == -1)
966 options->forward_x11_trusted = 0;
967 if (options->xauth_location == NULL)
968 options->xauth_location = _PATH_XAUTH;
969 if (options->gateway_ports == -1)
970 options->gateway_ports = 0;
971 if (options->use_privileged_port == -1)
972 options->use_privileged_port = 0;
973 if (options->rsa_authentication == -1)
974 options->rsa_authentication = 1;
975 if (options->pubkey_authentication == -1)
976 options->pubkey_authentication = 1;
977 if (options->challenge_response_authentication == -1)
978 options->challenge_response_authentication = 1;
979 if (options->gss_authentication == -1)
980 options->gss_authentication = 0;
981 if (options->gss_deleg_creds == -1)
982 options->gss_deleg_creds = 0;
983 if (options->password_authentication == -1)
984 options->password_authentication = 1;
985 if (options->kbd_interactive_authentication == -1)
986 options->kbd_interactive_authentication = 1;
987 if (options->rhosts_rsa_authentication == -1)
988 options->rhosts_rsa_authentication = 0;
989 if (options->hostbased_authentication == -1)
990 options->hostbased_authentication = 0;
991 if (options->batch_mode == -1)
992 options->batch_mode = 0;
993 if (options->check_host_ip == -1)
994 options->check_host_ip = 1;
995 if (options->strict_host_key_checking == -1)
996 options->strict_host_key_checking = 2; /* 2 is default */
997 if (options->compression == -1)
998 options->compression = 0;
999 if (options->tcp_keep_alive == -1)
1000 options->tcp_keep_alive = 1;
1001 if (options->compression_level == -1)
1002 options->compression_level = 6;
1003 if (options->port == -1)
1004 options->port = 0; /* Filled in ssh_connect. */
1005 if (options->address_family == -1)
1006 options->address_family = AF_UNSPEC;
1007 if (options->connection_attempts == -1)
1008 options->connection_attempts = 1;
1009 if (options->number_of_password_prompts == -1)
1010 options->number_of_password_prompts = 3;
1011 /* Selected in ssh_login(). */
1012 if (options->cipher == -1)
1013 options->cipher = SSH_CIPHER_NOT_SET;
1014 /* options->ciphers, default set in myproposals.h */
1015 /* options->macs, default set in myproposals.h */
1016 /* options->hostkeyalgorithms, default set in myproposals.h */
1017 if (options->protocol == SSH_PROTO_UNKNOWN)
1018 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1019 if (options->num_identity_files == 0) {
1020 if (options->protocol & SSH_PROTO_1) {
1021 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1022 options->identity_files[options->num_identity_files] =
1023 xmalloc(len);
1024 snprintf(options->identity_files[options->num_identity_files++],
1025 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1027 if (options->protocol & SSH_PROTO_2) {
1028 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1029 options->identity_files[options->num_identity_files] =
1030 xmalloc(len);
1031 snprintf(options->identity_files[options->num_identity_files++],
1032 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1034 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 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_DSA);
1041 if (options->escape_char == -1)
1042 options->escape_char = '~';
1043 if (options->system_hostfile == NULL)
1044 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1045 if (options->user_hostfile == NULL)
1046 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1047 if (options->system_hostfile2 == NULL)
1048 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1049 if (options->user_hostfile2 == NULL)
1050 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1051 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1052 options->log_level = SYSLOG_LEVEL_INFO;
1053 if (options->clear_forwardings == 1)
1054 clear_forwardings(options);
1055 if (options->no_host_authentication_for_localhost == - 1)
1056 options->no_host_authentication_for_localhost = 0;
1057 if (options->identities_only == -1)
1058 options->identities_only = 0;
1059 if (options->enable_ssh_keysign == -1)
1060 options->enable_ssh_keysign = 0;
1061 if (options->rekey_limit == -1)
1062 options->rekey_limit = 0;
1063 if (options->verify_host_key_dns == -1)
1064 options->verify_host_key_dns = 0;
1065 if (options->server_alive_interval == -1)
1066 options->server_alive_interval = 0;
1067 if (options->server_alive_count_max == -1)
1068 options->server_alive_count_max = 3;
1069 if (options->control_master == -1)
1070 options->control_master = 0;
1071 if (options->hash_known_hosts == -1)
1072 options->hash_known_hosts = 0;
1073 /* options->proxy_command should not be set by default */
1074 /* options->user will be set in the main program if appropriate */
1075 /* options->hostname will be set in the main program if appropriate */
1076 /* options->host_key_alias should not be set by default */
1077 /* options->preferred_authentications will be set in ssh */
1081 * parse_forward
1082 * parses a string containing a port forwarding specification of the form:
1083 * [listenhost:]listenport:connecthost:connectport
1084 * returns number of arguments parsed or zero on error
1087 parse_forward(Forward *fwd, const char *fwdspec)
1089 int i;
1090 char *p, *cp, *fwdarg[4];
1092 memset(fwd, '\0', sizeof(*fwd));
1094 cp = p = xstrdup(fwdspec);
1096 /* skip leading spaces */
1097 while (*cp && isspace(*cp))
1098 cp++;
1100 for (i = 0; i < 4; ++i)
1101 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1102 break;
1104 /* Check for trailing garbage in 4-arg case*/
1105 if (cp != NULL)
1106 i = 0; /* failure */
1108 switch (i) {
1109 case 3:
1110 fwd->listen_host = NULL;
1111 fwd->listen_port = a2port(fwdarg[0]);
1112 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1113 fwd->connect_port = a2port(fwdarg[2]);
1114 break;
1116 case 4:
1117 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1118 fwd->listen_port = a2port(fwdarg[1]);
1119 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1120 fwd->connect_port = a2port(fwdarg[3]);
1121 break;
1122 default:
1123 i = 0; /* failure */
1126 xfree(p);
1128 if (fwd->listen_port == 0 && fwd->connect_port == 0)
1129 goto fail_free;
1131 if (fwd->connect_host != NULL &&
1132 strlen(fwd->connect_host) >= NI_MAXHOST)
1133 goto fail_free;
1135 return (i);
1137 fail_free:
1138 if (fwd->connect_host != NULL)
1139 xfree(fwd->connect_host);
1140 if (fwd->listen_host != NULL)
1141 xfree(fwd->listen_host);
1142 return (0);