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