- (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
[openssh-git.git] / readconf.c
blob7173a8c2328860287eb951be34dcfd7ced76f988
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.137 2005/03/04 08:48:06 djm 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 xfree(options->local_forwards[i].listen_host);
257 xfree(options->local_forwards[i].connect_host);
259 options->num_local_forwards = 0;
260 for (i = 0; i < options->num_remote_forwards; i++) {
261 xfree(options->remote_forwards[i].listen_host);
262 xfree(options->remote_forwards[i].connect_host);
264 options->num_remote_forwards = 0;
268 * Returns the number of the token pointed to by cp or oBadOption.
271 static OpCodes
272 parse_token(const char *cp, const char *filename, int linenum)
274 u_int i;
276 for (i = 0; keywords[i].name; i++)
277 if (strcasecmp(cp, keywords[i].name) == 0)
278 return keywords[i].opcode;
280 error("%s: line %d: Bad configuration option: %s",
281 filename, linenum, cp);
282 return oBadOption;
286 * Processes a single option line as used in the configuration files. This
287 * only sets those values that have not already been set.
289 #define WHITESPACE " \t\r\n"
292 process_config_line(Options *options, const char *host,
293 char *line, const char *filename, int linenum,
294 int *activep)
296 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
297 int opcode, *intptr, value;
298 size_t len;
299 Forward fwd;
301 /* Strip trailing whitespace */
302 for(len = strlen(line) - 1; len > 0; len--) {
303 if (strchr(WHITESPACE, line[len]) == NULL)
304 break;
305 line[len] = '\0';
308 s = line;
309 /* Get the keyword. (Each line is supposed to begin with a keyword). */
310 keyword = strdelim(&s);
311 /* Ignore leading whitespace. */
312 if (*keyword == '\0')
313 keyword = strdelim(&s);
314 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
315 return 0;
317 opcode = parse_token(keyword, filename, linenum);
319 switch (opcode) {
320 case oBadOption:
321 /* don't panic, but count bad options */
322 return -1;
323 /* NOTREACHED */
324 case oConnectTimeout:
325 intptr = &options->connection_timeout;
326 parse_time:
327 arg = strdelim(&s);
328 if (!arg || *arg == '\0')
329 fatal("%s line %d: missing time value.",
330 filename, linenum);
331 if ((value = convtime(arg)) == -1)
332 fatal("%s line %d: invalid time value.",
333 filename, linenum);
334 if (*intptr == -1)
335 *intptr = value;
336 break;
338 case oForwardAgent:
339 intptr = &options->forward_agent;
340 parse_flag:
341 arg = strdelim(&s);
342 if (!arg || *arg == '\0')
343 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
344 value = 0; /* To avoid compiler warning... */
345 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
346 value = 1;
347 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
348 value = 0;
349 else
350 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
351 if (*activep && *intptr == -1)
352 *intptr = value;
353 break;
355 case oForwardX11:
356 intptr = &options->forward_x11;
357 goto parse_flag;
359 case oForwardX11Trusted:
360 intptr = &options->forward_x11_trusted;
361 goto parse_flag;
363 case oGatewayPorts:
364 intptr = &options->gateway_ports;
365 goto parse_flag;
367 case oUsePrivilegedPort:
368 intptr = &options->use_privileged_port;
369 goto parse_flag;
371 case oPasswordAuthentication:
372 intptr = &options->password_authentication;
373 goto parse_flag;
375 case oKbdInteractiveAuthentication:
376 intptr = &options->kbd_interactive_authentication;
377 goto parse_flag;
379 case oKbdInteractiveDevices:
380 charptr = &options->kbd_interactive_devices;
381 goto parse_string;
383 case oPubkeyAuthentication:
384 intptr = &options->pubkey_authentication;
385 goto parse_flag;
387 case oRSAAuthentication:
388 intptr = &options->rsa_authentication;
389 goto parse_flag;
391 case oRhostsRSAAuthentication:
392 intptr = &options->rhosts_rsa_authentication;
393 goto parse_flag;
395 case oHostbasedAuthentication:
396 intptr = &options->hostbased_authentication;
397 goto parse_flag;
399 case oChallengeResponseAuthentication:
400 intptr = &options->challenge_response_authentication;
401 goto parse_flag;
403 case oGssAuthentication:
404 intptr = &options->gss_authentication;
405 goto parse_flag;
407 case oGssDelegateCreds:
408 intptr = &options->gss_deleg_creds;
409 goto parse_flag;
411 case oBatchMode:
412 intptr = &options->batch_mode;
413 goto parse_flag;
415 case oCheckHostIP:
416 intptr = &options->check_host_ip;
417 goto parse_flag;
419 case oVerifyHostKeyDNS:
420 intptr = &options->verify_host_key_dns;
421 goto parse_yesnoask;
423 case oStrictHostKeyChecking:
424 intptr = &options->strict_host_key_checking;
425 parse_yesnoask:
426 arg = strdelim(&s);
427 if (!arg || *arg == '\0')
428 fatal("%.200s line %d: Missing yes/no/ask argument.",
429 filename, linenum);
430 value = 0; /* To avoid compiler warning... */
431 if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
432 value = 1;
433 else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
434 value = 0;
435 else if (strcmp(arg, "ask") == 0)
436 value = 2;
437 else
438 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
439 if (*activep && *intptr == -1)
440 *intptr = value;
441 break;
443 case oCompression:
444 intptr = &options->compression;
445 goto parse_flag;
447 case oTCPKeepAlive:
448 intptr = &options->tcp_keep_alive;
449 goto parse_flag;
451 case oNoHostAuthenticationForLocalhost:
452 intptr = &options->no_host_authentication_for_localhost;
453 goto parse_flag;
455 case oNumberOfPasswordPrompts:
456 intptr = &options->number_of_password_prompts;
457 goto parse_int;
459 case oCompressionLevel:
460 intptr = &options->compression_level;
461 goto parse_int;
463 case oRekeyLimit:
464 intptr = &options->rekey_limit;
465 arg = strdelim(&s);
466 if (!arg || *arg == '\0')
467 fatal("%.200s line %d: Missing argument.", filename, linenum);
468 if (arg[0] < '0' || arg[0] > '9')
469 fatal("%.200s line %d: Bad number.", filename, linenum);
470 value = strtol(arg, &endofnumber, 10);
471 if (arg == endofnumber)
472 fatal("%.200s line %d: Bad number.", filename, linenum);
473 switch (toupper(*endofnumber)) {
474 case 'K':
475 value *= 1<<10;
476 break;
477 case 'M':
478 value *= 1<<20;
479 break;
480 case 'G':
481 value *= 1<<30;
482 break;
484 if (*activep && *intptr == -1)
485 *intptr = value;
486 break;
488 case oIdentityFile:
489 arg = strdelim(&s);
490 if (!arg || *arg == '\0')
491 fatal("%.200s line %d: Missing argument.", filename, linenum);
492 if (*activep) {
493 intptr = &options->num_identity_files;
494 if (*intptr >= SSH_MAX_IDENTITY_FILES)
495 fatal("%.200s line %d: Too many identity files specified (max %d).",
496 filename, linenum, SSH_MAX_IDENTITY_FILES);
497 charptr = &options->identity_files[*intptr];
498 *charptr = xstrdup(arg);
499 *intptr = *intptr + 1;
501 break;
503 case oXAuthLocation:
504 charptr=&options->xauth_location;
505 goto parse_string;
507 case oUser:
508 charptr = &options->user;
509 parse_string:
510 arg = strdelim(&s);
511 if (!arg || *arg == '\0')
512 fatal("%.200s line %d: Missing argument.", filename, linenum);
513 if (*activep && *charptr == NULL)
514 *charptr = xstrdup(arg);
515 break;
517 case oGlobalKnownHostsFile:
518 charptr = &options->system_hostfile;
519 goto parse_string;
521 case oUserKnownHostsFile:
522 charptr = &options->user_hostfile;
523 goto parse_string;
525 case oGlobalKnownHostsFile2:
526 charptr = &options->system_hostfile2;
527 goto parse_string;
529 case oUserKnownHostsFile2:
530 charptr = &options->user_hostfile2;
531 goto parse_string;
533 case oHostName:
534 charptr = &options->hostname;
535 goto parse_string;
537 case oHostKeyAlias:
538 charptr = &options->host_key_alias;
539 goto parse_string;
541 case oPreferredAuthentications:
542 charptr = &options->preferred_authentications;
543 goto parse_string;
545 case oBindAddress:
546 charptr = &options->bind_address;
547 goto parse_string;
549 case oSmartcardDevice:
550 charptr = &options->smartcard_device;
551 goto parse_string;
553 case oProxyCommand:
554 if (s == NULL)
555 fatal("%.200s line %d: Missing argument.", filename, linenum);
556 charptr = &options->proxy_command;
557 len = strspn(s, WHITESPACE "=");
558 if (*activep && *charptr == NULL)
559 *charptr = xstrdup(s + len);
560 return 0;
562 case oPort:
563 intptr = &options->port;
564 parse_int:
565 arg = strdelim(&s);
566 if (!arg || *arg == '\0')
567 fatal("%.200s line %d: Missing argument.", filename, linenum);
568 if (arg[0] < '0' || arg[0] > '9')
569 fatal("%.200s line %d: Bad number.", filename, linenum);
571 /* Octal, decimal, or hex format? */
572 value = strtol(arg, &endofnumber, 0);
573 if (arg == endofnumber)
574 fatal("%.200s line %d: Bad number.", filename, linenum);
575 if (*activep && *intptr == -1)
576 *intptr = value;
577 break;
579 case oConnectionAttempts:
580 intptr = &options->connection_attempts;
581 goto parse_int;
583 case oCipher:
584 intptr = &options->cipher;
585 arg = strdelim(&s);
586 if (!arg || *arg == '\0')
587 fatal("%.200s line %d: Missing argument.", filename, linenum);
588 value = cipher_number(arg);
589 if (value == -1)
590 fatal("%.200s line %d: Bad cipher '%s'.",
591 filename, linenum, arg ? arg : "<NONE>");
592 if (*activep && *intptr == -1)
593 *intptr = value;
594 break;
596 case oCiphers:
597 arg = strdelim(&s);
598 if (!arg || *arg == '\0')
599 fatal("%.200s line %d: Missing argument.", filename, linenum);
600 if (!ciphers_valid(arg))
601 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
602 filename, linenum, arg ? arg : "<NONE>");
603 if (*activep && options->ciphers == NULL)
604 options->ciphers = xstrdup(arg);
605 break;
607 case oMacs:
608 arg = strdelim(&s);
609 if (!arg || *arg == '\0')
610 fatal("%.200s line %d: Missing argument.", filename, linenum);
611 if (!mac_valid(arg))
612 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
613 filename, linenum, arg ? arg : "<NONE>");
614 if (*activep && options->macs == NULL)
615 options->macs = xstrdup(arg);
616 break;
618 case oHostKeyAlgorithms:
619 arg = strdelim(&s);
620 if (!arg || *arg == '\0')
621 fatal("%.200s line %d: Missing argument.", filename, linenum);
622 if (!key_names_valid2(arg))
623 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
624 filename, linenum, arg ? arg : "<NONE>");
625 if (*activep && options->hostkeyalgorithms == NULL)
626 options->hostkeyalgorithms = xstrdup(arg);
627 break;
629 case oProtocol:
630 intptr = &options->protocol;
631 arg = strdelim(&s);
632 if (!arg || *arg == '\0')
633 fatal("%.200s line %d: Missing argument.", filename, linenum);
634 value = proto_spec(arg);
635 if (value == SSH_PROTO_UNKNOWN)
636 fatal("%.200s line %d: Bad protocol spec '%s'.",
637 filename, linenum, arg ? arg : "<NONE>");
638 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
639 *intptr = value;
640 break;
642 case oLogLevel:
643 intptr = (int *) &options->log_level;
644 arg = strdelim(&s);
645 value = log_level_number(arg);
646 if (value == SYSLOG_LEVEL_NOT_SET)
647 fatal("%.200s line %d: unsupported log level '%s'",
648 filename, linenum, arg ? arg : "<NONE>");
649 if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
650 *intptr = (LogLevel) value;
651 break;
653 case oLocalForward:
654 case oRemoteForward:
655 arg = strdelim(&s);
656 if (arg == NULL || *arg == '\0')
657 fatal("%.200s line %d: Missing port argument.",
658 filename, linenum);
659 arg2 = strdelim(&s);
660 if (arg2 == NULL || *arg2 == '\0')
661 fatal("%.200s line %d: Missing target argument.",
662 filename, linenum);
664 /* construct a string for parse_forward */
665 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
667 if (parse_forward(&fwd, fwdarg) == 0)
668 fatal("%.200s line %d: Bad forwarding specification.",
669 filename, linenum);
671 if (*activep) {
672 if (opcode == oLocalForward)
673 add_local_forward(options, &fwd);
674 else if (opcode == oRemoteForward)
675 add_remote_forward(options, &fwd);
677 break;
679 case oDynamicForward:
680 arg = strdelim(&s);
681 if (!arg || *arg == '\0')
682 fatal("%.200s line %d: Missing port argument.",
683 filename, linenum);
684 memset(&fwd, '\0', sizeof(fwd));
685 fwd.connect_host = "socks";
686 fwd.listen_host = hpdelim(&arg);
687 if (fwd.listen_host == NULL ||
688 strlen(fwd.listen_host) >= NI_MAXHOST)
689 fatal("%.200s line %d: Bad forwarding specification.",
690 filename, linenum);
691 if (arg) {
692 fwd.listen_port = a2port(arg);
693 fwd.listen_host = cleanhostname(fwd.listen_host);
694 } else {
695 fwd.listen_port = a2port(fwd.listen_host);
696 fwd.listen_host = "";
698 if (fwd.listen_port == 0)
699 fatal("%.200s line %d: Badly formatted port number.",
700 filename, linenum);
701 if (*activep)
702 add_local_forward(options, &fwd);
703 break;
705 case oClearAllForwardings:
706 intptr = &options->clear_forwardings;
707 goto parse_flag;
709 case oHost:
710 *activep = 0;
711 while ((arg = strdelim(&s)) != NULL && *arg != '\0')
712 if (match_pattern(host, arg)) {
713 debug("Applying options for %.100s", arg);
714 *activep = 1;
715 break;
717 /* Avoid garbage check below, as strdelim is done. */
718 return 0;
720 case oEscapeChar:
721 intptr = &options->escape_char;
722 arg = strdelim(&s);
723 if (!arg || *arg == '\0')
724 fatal("%.200s line %d: Missing argument.", filename, linenum);
725 if (arg[0] == '^' && arg[2] == 0 &&
726 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
727 value = (u_char) arg[1] & 31;
728 else if (strlen(arg) == 1)
729 value = (u_char) arg[0];
730 else if (strcmp(arg, "none") == 0)
731 value = SSH_ESCAPECHAR_NONE;
732 else {
733 fatal("%.200s line %d: Bad escape character.",
734 filename, linenum);
735 /* NOTREACHED */
736 value = 0; /* Avoid compiler warning. */
738 if (*activep && *intptr == -1)
739 *intptr = value;
740 break;
742 case oAddressFamily:
743 arg = strdelim(&s);
744 intptr = &options->address_family;
745 if (strcasecmp(arg, "inet") == 0)
746 value = AF_INET;
747 else if (strcasecmp(arg, "inet6") == 0)
748 value = AF_INET6;
749 else if (strcasecmp(arg, "any") == 0)
750 value = AF_UNSPEC;
751 else
752 fatal("Unsupported AddressFamily \"%s\"", arg);
753 if (*activep && *intptr == -1)
754 *intptr = value;
755 break;
757 case oEnableSSHKeysign:
758 intptr = &options->enable_ssh_keysign;
759 goto parse_flag;
761 case oIdentitiesOnly:
762 intptr = &options->identities_only;
763 goto parse_flag;
765 case oServerAliveInterval:
766 intptr = &options->server_alive_interval;
767 goto parse_time;
769 case oServerAliveCountMax:
770 intptr = &options->server_alive_count_max;
771 goto parse_int;
773 case oSendEnv:
774 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
775 if (strchr(arg, '=') != NULL)
776 fatal("%s line %d: Invalid environment name.",
777 filename, linenum);
778 if (!*activep)
779 continue;
780 if (options->num_send_env >= MAX_SEND_ENV)
781 fatal("%s line %d: too many send env.",
782 filename, linenum);
783 options->send_env[options->num_send_env++] =
784 xstrdup(arg);
786 break;
788 case oControlPath:
789 charptr = &options->control_path;
790 goto parse_string;
792 case oControlMaster:
793 intptr = &options->control_master;
794 goto parse_yesnoask;
796 case oHashKnownHosts:
797 intptr = &options->hash_known_hosts;
798 goto parse_flag;
800 case oDeprecated:
801 debug("%s line %d: Deprecated option \"%s\"",
802 filename, linenum, keyword);
803 return 0;
805 case oUnsupported:
806 error("%s line %d: Unsupported option \"%s\"",
807 filename, linenum, keyword);
808 return 0;
810 default:
811 fatal("process_config_line: Unimplemented opcode %d", opcode);
814 /* Check that there is no garbage at end of line. */
815 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
816 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
817 filename, linenum, arg);
819 return 0;
824 * Reads the config file and modifies the options accordingly. Options
825 * should already be initialized before this call. This never returns if
826 * there is an error. If the file does not exist, this returns 0.
830 read_config_file(const char *filename, const char *host, Options *options,
831 int checkperm)
833 FILE *f;
834 char line[1024];
835 int active, linenum;
836 int bad_options = 0;
838 /* Open the file. */
839 if ((f = fopen(filename, "r")) == NULL)
840 return 0;
842 if (checkperm) {
843 struct stat sb;
845 if (fstat(fileno(f), &sb) == -1)
846 fatal("fstat %s: %s", filename, strerror(errno));
847 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
848 (sb.st_mode & 022) != 0))
849 fatal("Bad owner or permissions on %s", filename);
852 debug("Reading configuration data %.200s", filename);
855 * Mark that we are now processing the options. This flag is turned
856 * on/off by Host specifications.
858 active = 1;
859 linenum = 0;
860 while (fgets(line, sizeof(line), f)) {
861 /* Update line number counter. */
862 linenum++;
863 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
864 bad_options++;
866 fclose(f);
867 if (bad_options > 0)
868 fatal("%s: terminating, %d bad configuration options",
869 filename, bad_options);
870 return 1;
874 * Initializes options to special values that indicate that they have not yet
875 * been set. Read_config_file will only set options with this value. Options
876 * are processed in the following order: command line, user config file,
877 * system config file. Last, fill_default_options is called.
880 void
881 initialize_options(Options * options)
883 memset(options, 'X', sizeof(*options));
884 options->forward_agent = -1;
885 options->forward_x11 = -1;
886 options->forward_x11_trusted = -1;
887 options->xauth_location = NULL;
888 options->gateway_ports = -1;
889 options->use_privileged_port = -1;
890 options->rsa_authentication = -1;
891 options->pubkey_authentication = -1;
892 options->challenge_response_authentication = -1;
893 options->gss_authentication = -1;
894 options->gss_deleg_creds = -1;
895 options->password_authentication = -1;
896 options->kbd_interactive_authentication = -1;
897 options->kbd_interactive_devices = NULL;
898 options->rhosts_rsa_authentication = -1;
899 options->hostbased_authentication = -1;
900 options->batch_mode = -1;
901 options->check_host_ip = -1;
902 options->strict_host_key_checking = -1;
903 options->compression = -1;
904 options->tcp_keep_alive = -1;
905 options->compression_level = -1;
906 options->port = -1;
907 options->address_family = -1;
908 options->connection_attempts = -1;
909 options->connection_timeout = -1;
910 options->number_of_password_prompts = -1;
911 options->cipher = -1;
912 options->ciphers = NULL;
913 options->macs = NULL;
914 options->hostkeyalgorithms = NULL;
915 options->protocol = SSH_PROTO_UNKNOWN;
916 options->num_identity_files = 0;
917 options->hostname = NULL;
918 options->host_key_alias = NULL;
919 options->proxy_command = NULL;
920 options->user = NULL;
921 options->escape_char = -1;
922 options->system_hostfile = NULL;
923 options->user_hostfile = NULL;
924 options->system_hostfile2 = NULL;
925 options->user_hostfile2 = NULL;
926 options->num_local_forwards = 0;
927 options->num_remote_forwards = 0;
928 options->clear_forwardings = -1;
929 options->log_level = SYSLOG_LEVEL_NOT_SET;
930 options->preferred_authentications = NULL;
931 options->bind_address = NULL;
932 options->smartcard_device = NULL;
933 options->enable_ssh_keysign = - 1;
934 options->no_host_authentication_for_localhost = - 1;
935 options->identities_only = - 1;
936 options->rekey_limit = - 1;
937 options->verify_host_key_dns = -1;
938 options->server_alive_interval = -1;
939 options->server_alive_count_max = -1;
940 options->num_send_env = 0;
941 options->control_path = NULL;
942 options->control_master = -1;
943 options->hash_known_hosts = -1;
947 * Called after processing other sources of option data, this fills those
948 * options for which no value has been specified with their default values.
951 void
952 fill_default_options(Options * options)
954 int len;
956 if (options->forward_agent == -1)
957 options->forward_agent = 0;
958 if (options->forward_x11 == -1)
959 options->forward_x11 = 0;
960 if (options->forward_x11_trusted == -1)
961 options->forward_x11_trusted = 0;
962 if (options->xauth_location == NULL)
963 options->xauth_location = _PATH_XAUTH;
964 if (options->gateway_ports == -1)
965 options->gateway_ports = 0;
966 if (options->use_privileged_port == -1)
967 options->use_privileged_port = 0;
968 if (options->rsa_authentication == -1)
969 options->rsa_authentication = 1;
970 if (options->pubkey_authentication == -1)
971 options->pubkey_authentication = 1;
972 if (options->challenge_response_authentication == -1)
973 options->challenge_response_authentication = 1;
974 if (options->gss_authentication == -1)
975 options->gss_authentication = 0;
976 if (options->gss_deleg_creds == -1)
977 options->gss_deleg_creds = 0;
978 if (options->password_authentication == -1)
979 options->password_authentication = 1;
980 if (options->kbd_interactive_authentication == -1)
981 options->kbd_interactive_authentication = 1;
982 if (options->rhosts_rsa_authentication == -1)
983 options->rhosts_rsa_authentication = 0;
984 if (options->hostbased_authentication == -1)
985 options->hostbased_authentication = 0;
986 if (options->batch_mode == -1)
987 options->batch_mode = 0;
988 if (options->check_host_ip == -1)
989 options->check_host_ip = 1;
990 if (options->strict_host_key_checking == -1)
991 options->strict_host_key_checking = 2; /* 2 is default */
992 if (options->compression == -1)
993 options->compression = 0;
994 if (options->tcp_keep_alive == -1)
995 options->tcp_keep_alive = 1;
996 if (options->compression_level == -1)
997 options->compression_level = 6;
998 if (options->port == -1)
999 options->port = 0; /* Filled in ssh_connect. */
1000 if (options->address_family == -1)
1001 options->address_family = AF_UNSPEC;
1002 if (options->connection_attempts == -1)
1003 options->connection_attempts = 1;
1004 if (options->number_of_password_prompts == -1)
1005 options->number_of_password_prompts = 3;
1006 /* Selected in ssh_login(). */
1007 if (options->cipher == -1)
1008 options->cipher = SSH_CIPHER_NOT_SET;
1009 /* options->ciphers, default set in myproposals.h */
1010 /* options->macs, default set in myproposals.h */
1011 /* options->hostkeyalgorithms, default set in myproposals.h */
1012 if (options->protocol == SSH_PROTO_UNKNOWN)
1013 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
1014 if (options->num_identity_files == 0) {
1015 if (options->protocol & SSH_PROTO_1) {
1016 len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1017 options->identity_files[options->num_identity_files] =
1018 xmalloc(len);
1019 snprintf(options->identity_files[options->num_identity_files++],
1020 len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1022 if (options->protocol & SSH_PROTO_2) {
1023 len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1024 options->identity_files[options->num_identity_files] =
1025 xmalloc(len);
1026 snprintf(options->identity_files[options->num_identity_files++],
1027 len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
1029 len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
1030 options->identity_files[options->num_identity_files] =
1031 xmalloc(len);
1032 snprintf(options->identity_files[options->num_identity_files++],
1033 len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
1036 if (options->escape_char == -1)
1037 options->escape_char = '~';
1038 if (options->system_hostfile == NULL)
1039 options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
1040 if (options->user_hostfile == NULL)
1041 options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
1042 if (options->system_hostfile2 == NULL)
1043 options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
1044 if (options->user_hostfile2 == NULL)
1045 options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
1046 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1047 options->log_level = SYSLOG_LEVEL_INFO;
1048 if (options->clear_forwardings == 1)
1049 clear_forwardings(options);
1050 if (options->no_host_authentication_for_localhost == - 1)
1051 options->no_host_authentication_for_localhost = 0;
1052 if (options->identities_only == -1)
1053 options->identities_only = 0;
1054 if (options->enable_ssh_keysign == -1)
1055 options->enable_ssh_keysign = 0;
1056 if (options->rekey_limit == -1)
1057 options->rekey_limit = 0;
1058 if (options->verify_host_key_dns == -1)
1059 options->verify_host_key_dns = 0;
1060 if (options->server_alive_interval == -1)
1061 options->server_alive_interval = 0;
1062 if (options->server_alive_count_max == -1)
1063 options->server_alive_count_max = 3;
1064 if (options->control_master == -1)
1065 options->control_master = 0;
1066 if (options->hash_known_hosts == -1)
1067 options->hash_known_hosts = 0;
1068 /* options->proxy_command should not be set by default */
1069 /* options->user will be set in the main program if appropriate */
1070 /* options->hostname will be set in the main program if appropriate */
1071 /* options->host_key_alias should not be set by default */
1072 /* options->preferred_authentications will be set in ssh */
1076 * parse_forward
1077 * parses a string containing a port forwarding specification of the form:
1078 * [listenhost:]listenport:connecthost:connectport
1079 * returns number of arguments parsed or zero on error
1082 parse_forward(Forward *fwd, const char *fwdspec)
1084 int i;
1085 char *p, *cp, *fwdarg[4];
1087 memset(fwd, '\0', sizeof(*fwd));
1089 cp = p = xstrdup(fwdspec);
1091 /* skip leading spaces */
1092 while (*cp && isspace(*cp))
1093 cp++;
1095 for (i = 0; i < 4; ++i)
1096 if ((fwdarg[i] = hpdelim(&cp)) == NULL)
1097 break;
1099 /* Check for trailing garbage in 4-arg case*/
1100 if (cp != NULL)
1101 i = 0; /* failure */
1103 switch (i) {
1104 case 3:
1105 fwd->listen_host = NULL;
1106 fwd->listen_port = a2port(fwdarg[0]);
1107 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
1108 fwd->connect_port = a2port(fwdarg[2]);
1109 break;
1111 case 4:
1112 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
1113 fwd->listen_port = a2port(fwdarg[1]);
1114 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
1115 fwd->connect_port = a2port(fwdarg[3]);
1116 break;
1117 default:
1118 i = 0; /* failure */
1121 xfree(p);
1123 if (fwd->listen_port == 0 && fwd->connect_port == 0)
1124 goto fail_free;
1126 if (fwd->connect_host != NULL &&
1127 strlen(fwd->connect_host) >= NI_MAXHOST)
1128 goto fail_free;
1130 return (i);
1132 fail_free:
1133 if (fwd->connect_host != NULL)
1134 xfree(fwd->connect_host);
1135 if (fwd->listen_host != NULL)
1136 xfree(fwd->listen_host);
1137 return (0);