1 /* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
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".
17 #include <sys/types.h>
19 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #include <arpa/inet.h>
49 #include "pathnames.h"
61 /* Format of the configuration file:
63 # Configuration data is parsed as follows:
64 # 1. command line options
65 # 2. user-specific file
67 # Any configuration value is only changed the first time it is set.
68 # Thus, host-specific definitions should be at the beginning of the
69 # configuration file, and defaults at the end.
71 # Host-specific declarations. These may override anything above. A single
72 # host may match multiple declarations; these are processed in the order
73 # that they are given in.
79 HostName another.host.name.real.org
86 RemoteForward 9999 shadows.cs.hut.fi:9999
92 PasswordAuthentication no
96 ProxyCommand ssh-proxy %h %p
99 PublicKeyAuthentication no
103 PasswordAuthentication no
109 # Defaults for various options
113 PasswordAuthentication yes
114 RSAAuthentication yes
115 RhostsRSAAuthentication yes
116 StrictHostKeyChecking yes
118 IdentityFile ~/.ssh/identity
124 /* Keyword tokens. */
129 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
130 oGatewayPorts, oExitOnForwardFailure,
131 oPasswordAuthentication, oRSAAuthentication,
132 oChallengeResponseAuthentication, oXAuthLocation,
133 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
134 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
135 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
136 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
137 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
138 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
139 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
140 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
141 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
142 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
143 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
144 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
145 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
146 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
148 oSendEnv, oControlPath, oControlMaster, oControlPersist,
150 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
151 oTcpRcvBufPoll, oTcpRcvBuf, oHPNDisabled, oHPNBufferSize,
152 oNoneEnabled, oNoneSwitch,
153 oVisualHostKey, oUseRoaming,
154 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
155 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
156 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
157 oStreamLocalBindMask, oStreamLocalBindUnlink,
158 oIgnoredUnknownOption, oDeprecated, oUnsupported
161 /* Textual representations of the tokens. */
167 { "forwardagent", oForwardAgent },
168 { "forwardx11", oForwardX11 },
169 { "forwardx11trusted", oForwardX11Trusted },
170 { "forwardx11timeout", oForwardX11Timeout },
171 { "exitonforwardfailure", oExitOnForwardFailure },
172 { "xauthlocation", oXAuthLocation },
173 { "gatewayports", oGatewayPorts },
174 { "useprivilegedport", oUsePrivilegedPort },
175 { "rhostsauthentication", oDeprecated },
176 { "passwordauthentication", oPasswordAuthentication },
177 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
178 { "kbdinteractivedevices", oKbdInteractiveDevices },
179 { "rsaauthentication", oRSAAuthentication },
180 { "pubkeyauthentication", oPubkeyAuthentication },
181 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
182 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
183 { "hostbasedauthentication", oHostbasedAuthentication },
184 { "challengeresponseauthentication", oChallengeResponseAuthentication },
185 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
186 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
187 { "kerberosauthentication", oUnsupported },
188 { "kerberostgtpassing", oUnsupported },
189 { "afstokenpassing", oUnsupported },
191 { "gssapiauthentication", oGssAuthentication },
192 { "gssapidelegatecredentials", oGssDelegateCreds },
194 { "gssapiauthentication", oUnsupported },
195 { "gssapidelegatecredentials", oUnsupported },
197 { "fallbacktorsh", oDeprecated },
198 { "usersh", oDeprecated },
199 { "identityfile", oIdentityFile },
200 { "identityfile2", oIdentityFile }, /* obsolete */
201 { "identitiesonly", oIdentitiesOnly },
202 { "hostname", oHostName },
203 { "hostkeyalias", oHostKeyAlias },
204 { "proxycommand", oProxyCommand },
206 { "cipher", oCipher },
207 { "ciphers", oCiphers },
209 { "protocol", oProtocol },
210 { "remoteforward", oRemoteForward },
211 { "localforward", oLocalForward },
215 { "escapechar", oEscapeChar },
216 { "globalknownhostsfile", oGlobalKnownHostsFile },
217 { "globalknownhostsfile2", oDeprecated },
218 { "userknownhostsfile", oUserKnownHostsFile },
219 { "userknownhostsfile2", oDeprecated },
220 { "connectionattempts", oConnectionAttempts },
221 { "batchmode", oBatchMode },
222 { "checkhostip", oCheckHostIP },
223 { "stricthostkeychecking", oStrictHostKeyChecking },
224 { "compression", oCompression },
225 { "compressionlevel", oCompressionLevel },
226 { "tcpkeepalive", oTCPKeepAlive },
227 { "keepalive", oTCPKeepAlive }, /* obsolete */
228 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
229 { "loglevel", oLogLevel },
230 { "dynamicforward", oDynamicForward },
231 { "preferredauthentications", oPreferredAuthentications },
232 { "hostkeyalgorithms", oHostKeyAlgorithms },
233 { "bindaddress", oBindAddress },
235 { "smartcarddevice", oPKCS11Provider },
236 { "pkcs11provider", oPKCS11Provider },
238 { "smartcarddevice", oUnsupported },
239 { "pkcs11provider", oUnsupported },
241 { "clearallforwardings", oClearAllForwardings },
242 { "enablesshkeysign", oEnableSSHKeysign },
243 { "verifyhostkeydns", oVerifyHostKeyDNS },
244 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
245 { "rekeylimit", oRekeyLimit },
246 { "connecttimeout", oConnectTimeout },
247 { "addressfamily", oAddressFamily },
248 { "serveraliveinterval", oServerAliveInterval },
249 { "serveralivecountmax", oServerAliveCountMax },
250 { "versionaddendum", oVersionAddendum },
251 { "sendenv", oSendEnv },
252 { "controlpath", oControlPath },
253 { "controlmaster", oControlMaster },
254 { "controlpersist", oControlPersist },
255 { "hashknownhosts", oHashKnownHosts },
256 { "tunnel", oTunnel },
257 { "tunneldevice", oTunnelDevice },
258 { "localcommand", oLocalCommand },
259 { "permitlocalcommand", oPermitLocalCommand },
260 { "visualhostkey", oVisualHostKey },
261 { "useroaming", oUseRoaming },
262 { "kexalgorithms", oKexAlgorithms },
264 { "requesttty", oRequestTTY },
265 { "noneenabled", oNoneEnabled },
266 { "noneswitch", oNoneSwitch },
267 { "tcprcvbufpoll", oTcpRcvBufPoll },
268 { "tcprcvbuf", oTcpRcvBuf },
269 { "hpndisabled", oHPNDisabled },
270 { "hpnbuffersize", oHPNBufferSize },
271 { "proxyusefdpass", oProxyUseFdpass },
272 { "canonicaldomains", oCanonicalDomains },
273 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
274 { "canonicalizehostname", oCanonicalizeHostname },
275 { "canonicalizemaxdots", oCanonicalizeMaxDots },
276 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
277 { "streamlocalbindmask", oStreamLocalBindMask },
278 { "streamlocalbindunlink", oStreamLocalBindUnlink },
279 { "ignoreunknown", oIgnoreUnknown },
285 * Adds a local TCP/IP port forward to options. Never returns if there is an
290 add_local_forward(Options *options, const struct Forward *newfwd)
293 #ifndef NO_IPPORT_RESERVED_CONCEPT
294 extern uid_t original_real_uid;
295 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
296 newfwd->listen_path == NULL)
297 fatal("Privileged ports can only be forwarded by root.");
299 options->local_forwards = xrealloc(options->local_forwards,
300 options->num_local_forwards + 1,
301 sizeof(*options->local_forwards));
302 fwd = &options->local_forwards[options->num_local_forwards++];
304 fwd->listen_host = newfwd->listen_host;
305 fwd->listen_port = newfwd->listen_port;
306 fwd->listen_path = newfwd->listen_path;
307 fwd->connect_host = newfwd->connect_host;
308 fwd->connect_port = newfwd->connect_port;
309 fwd->connect_path = newfwd->connect_path;
313 * Adds a remote TCP/IP port forward to options. Never returns if there is
318 add_remote_forward(Options *options, const struct Forward *newfwd)
322 options->remote_forwards = xrealloc(options->remote_forwards,
323 options->num_remote_forwards + 1,
324 sizeof(*options->remote_forwards));
325 fwd = &options->remote_forwards[options->num_remote_forwards++];
327 fwd->listen_host = newfwd->listen_host;
328 fwd->listen_port = newfwd->listen_port;
329 fwd->listen_path = newfwd->listen_path;
330 fwd->connect_host = newfwd->connect_host;
331 fwd->connect_port = newfwd->connect_port;
332 fwd->connect_path = newfwd->connect_path;
333 fwd->handle = newfwd->handle;
334 fwd->allocated_port = 0;
338 clear_forwardings(Options *options)
342 for (i = 0; i < options->num_local_forwards; i++) {
343 free(options->local_forwards[i].listen_host);
344 free(options->local_forwards[i].listen_path);
345 free(options->local_forwards[i].connect_host);
346 free(options->local_forwards[i].connect_path);
348 if (options->num_local_forwards > 0) {
349 free(options->local_forwards);
350 options->local_forwards = NULL;
352 options->num_local_forwards = 0;
353 for (i = 0; i < options->num_remote_forwards; i++) {
354 free(options->remote_forwards[i].listen_host);
355 free(options->remote_forwards[i].listen_path);
356 free(options->remote_forwards[i].connect_host);
357 free(options->remote_forwards[i].connect_path);
359 if (options->num_remote_forwards > 0) {
360 free(options->remote_forwards);
361 options->remote_forwards = NULL;
363 options->num_remote_forwards = 0;
364 options->tun_open = SSH_TUNMODE_NO;
368 add_identity_file(Options *options, const char *dir, const char *filename,
374 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
375 fatal("Too many identity files specified (max %d)",
376 SSH_MAX_IDENTITY_FILES);
378 if (dir == NULL) /* no dir, filename is absolute */
379 path = xstrdup(filename);
381 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
383 /* Avoid registering duplicates */
384 for (i = 0; i < options->num_identity_files; i++) {
385 if (options->identity_file_userprovided[i] == userprovided &&
386 strcmp(options->identity_files[i], path) == 0) {
387 debug2("%s: ignoring duplicate key %s", __func__, path);
393 options->identity_file_userprovided[options->num_identity_files] =
395 options->identity_files[options->num_identity_files++] = path;
399 default_ssh_port(void)
405 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
406 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
412 * Execute a command in a shell.
413 * Return its exit status or -1 on abnormal exit.
416 execute_in_shell(const char *cmd)
418 char *shell, *command_string;
421 extern uid_t original_real_uid;
423 if ((shell = getenv("SHELL")) == NULL)
424 shell = _PATH_BSHELL;
427 * Use "exec" to avoid "sh -c" processes on some platforms
430 xasprintf(&command_string, "exec %s", cmd);
432 /* Need this to redirect subprocess stdin/out */
433 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
434 fatal("open(/dev/null): %s", strerror(errno));
436 debug("Executing command: '%.500s'", cmd);
438 /* Fork and execute the command. */
439 if ((pid = fork()) == 0) {
442 /* Child. Permanently give up superuser privileges. */
443 permanently_drop_suid(original_real_uid);
445 /* Redirect child stdin and stdout. Leave stderr */
446 if (dup2(devnull, STDIN_FILENO) == -1)
447 fatal("dup2: %s", strerror(errno));
448 if (dup2(devnull, STDOUT_FILENO) == -1)
449 fatal("dup2: %s", strerror(errno));
450 if (devnull > STDERR_FILENO)
452 closefrom(STDERR_FILENO + 1);
456 argv[2] = command_string;
459 execv(argv[0], argv);
460 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
461 /* Die with signal to make this error apparent to parent. */
462 signal(SIGTERM, SIG_DFL);
463 kill(getpid(), SIGTERM);
468 fatal("%s: fork: %.100s", __func__, strerror(errno));
471 free(command_string);
473 while (waitpid(pid, &status, 0) == -1) {
474 if (errno != EINTR && errno != EAGAIN)
475 fatal("%s: waitpid: %s", __func__, strerror(errno));
477 if (!WIFEXITED(status)) {
478 error("command '%.100s' exited abnormally", cmd);
481 debug3("command returned status %d", WEXITSTATUS(status));
482 return WEXITSTATUS(status);
486 * Parse and execute a Match directive.
489 match_cfg_line(Options *options, char **condition, struct passwd *pw,
490 const char *host_arg, const char *filename, int linenum)
492 char *arg, *attrib, *cmd, *cp = *condition, *host;
494 int r, port, result = 1, attributes = 0;
496 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
499 * Configuration is likely to be incomplete at this point so we
500 * must be prepared to use default values.
502 port = options->port <= 0 ? default_ssh_port() : options->port;
503 ruser = options->user == NULL ? pw->pw_name : options->user;
504 if (options->hostname != NULL) {
505 /* NB. Please keep in sync with ssh.c:main() */
506 host = percent_expand(options->hostname,
507 "h", host_arg, (char *)NULL);
509 host = xstrdup(host_arg);
511 debug3("checking match for '%s' host %s", cp, host);
512 while ((attrib = strdelim(&cp)) && *attrib != '\0') {
514 if (strcasecmp(attrib, "all") == 0) {
515 if (attributes != 1 ||
516 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
517 error("'all' cannot be combined with other "
526 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
527 error("Missing Match criteria for %s", attrib);
532 if (strcasecmp(attrib, "host") == 0) {
533 if (match_hostname(host, arg, len) != 1)
536 debug("%.200s line %d: matched 'Host %.100s' ",
537 filename, linenum, host);
538 } else if (strcasecmp(attrib, "originalhost") == 0) {
539 if (match_hostname(host_arg, arg, len) != 1)
542 debug("%.200s line %d: matched "
543 "'OriginalHost %.100s' ",
544 filename, linenum, host_arg);
545 } else if (strcasecmp(attrib, "user") == 0) {
546 if (match_pattern_list(ruser, arg, len, 0) != 1)
549 debug("%.200s line %d: matched 'User %.100s' ",
550 filename, linenum, ruser);
551 } else if (strcasecmp(attrib, "localuser") == 0) {
552 if (match_pattern_list(pw->pw_name, arg, len, 0) != 1)
555 debug("%.200s line %d: matched "
556 "'LocalUser %.100s' ",
557 filename, linenum, pw->pw_name);
558 } else if (strcasecmp(attrib, "exec") == 0) {
559 if (gethostname(thishost, sizeof(thishost)) == -1)
560 fatal("gethostname: %s", strerror(errno));
561 strlcpy(shorthost, thishost, sizeof(shorthost));
562 shorthost[strcspn(thishost, ".")] = '\0';
563 snprintf(portstr, sizeof(portstr), "%d", port);
565 cmd = percent_expand(arg,
576 /* skip execution if prior predicate failed */
577 debug("%.200s line %d: skipped exec \"%.100s\"",
578 filename, linenum, cmd);
580 r = execute_in_shell(cmd);
582 fatal("%.200s line %d: match exec "
583 "'%.100s' error", filename,
586 debug("%.200s line %d: matched "
587 "'exec \"%.100s\"'", filename,
590 debug("%.200s line %d: no match "
591 "'exec \"%.100s\"'", filename,
598 error("Unsupported Match attribute %s", attrib);
603 if (attributes == 0) {
604 error("One or more attributes required for Match");
608 debug3("match %sfound", result ? "" : "not ");
615 /* Check and prepare a domain name: removes trailing '.' and lowercases */
617 valid_domain(char *name, const char *filename, int linenum)
619 size_t i, l = strlen(name);
620 u_char c, last = '\0';
623 fatal("%s line %d: empty hostname suffix", filename, linenum);
624 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
625 fatal("%s line %d: hostname suffix \"%.100s\" "
626 "starts with invalid character", filename, linenum, name);
627 for (i = 0; i < l; i++) {
628 c = tolower((u_char)name[i]);
630 if (last == '.' && c == '.')
631 fatal("%s line %d: hostname suffix \"%.100s\" contains "
632 "consecutive separators", filename, linenum, name);
633 if (c != '.' && c != '-' && !isalnum(c) &&
634 c != '_') /* technically invalid, but common */
635 fatal("%s line %d: hostname suffix \"%.100s\" contains "
636 "invalid characters", filename, linenum, name);
639 if (name[l - 1] == '.')
644 * Returns the number of the token pointed to by cp or oBadOption.
647 parse_token(const char *cp, const char *filename, int linenum,
648 const char *ignored_unknown)
652 for (i = 0; keywords[i].name; i++)
653 if (strcmp(cp, keywords[i].name) == 0)
654 return keywords[i].opcode;
655 if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
656 strlen(ignored_unknown), 1) == 1)
657 return oIgnoredUnknownOption;
658 error("%s: line %d: Bad configuration option: %s",
659 filename, linenum, cp);
663 /* Multistate option parsing */
668 static const struct multistate multistate_flag[] = {
675 static const struct multistate multistate_yesnoask[] = {
683 static const struct multistate multistate_addressfamily[] = {
685 { "inet6", AF_INET6 },
686 { "any", AF_UNSPEC },
689 static const struct multistate multistate_controlmaster[] = {
690 { "true", SSHCTL_MASTER_YES },
691 { "yes", SSHCTL_MASTER_YES },
692 { "false", SSHCTL_MASTER_NO },
693 { "no", SSHCTL_MASTER_NO },
694 { "auto", SSHCTL_MASTER_AUTO },
695 { "ask", SSHCTL_MASTER_ASK },
696 { "autoask", SSHCTL_MASTER_AUTO_ASK },
699 static const struct multistate multistate_tunnel[] = {
700 { "ethernet", SSH_TUNMODE_ETHERNET },
701 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
702 { "true", SSH_TUNMODE_DEFAULT },
703 { "yes", SSH_TUNMODE_DEFAULT },
704 { "false", SSH_TUNMODE_NO },
705 { "no", SSH_TUNMODE_NO },
708 static const struct multistate multistate_requesttty[] = {
709 { "true", REQUEST_TTY_YES },
710 { "yes", REQUEST_TTY_YES },
711 { "false", REQUEST_TTY_NO },
712 { "no", REQUEST_TTY_NO },
713 { "force", REQUEST_TTY_FORCE },
714 { "auto", REQUEST_TTY_AUTO },
717 static const struct multistate multistate_canonicalizehostname[] = {
718 { "true", SSH_CANONICALISE_YES },
719 { "false", SSH_CANONICALISE_NO },
720 { "yes", SSH_CANONICALISE_YES },
721 { "no", SSH_CANONICALISE_NO },
722 { "always", SSH_CANONICALISE_ALWAYS },
727 * Processes a single option line as used in the configuration files. This
728 * only sets those values that have not already been set.
730 #define WHITESPACE " \t\r\n"
732 process_config_line(Options *options, struct passwd *pw, const char *host,
733 char *line, const char *filename, int linenum, int *activep, int userconfig)
735 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
736 char **cpptr, fwdarg[256];
737 u_int i, *uintptr, max_entries = 0;
738 int negated, opcode, *intptr, value, value2, cmdline = 0;
739 LogLevel *log_level_ptr;
743 const struct multistate *multistate_ptr;
744 struct allowed_cname *cname;
746 if (activep == NULL) { /* We are processing a command line directive */
751 /* Strip trailing whitespace */
752 for (len = strlen(line) - 1; len > 0; len--) {
753 if (strchr(WHITESPACE, line[len]) == NULL)
759 /* Get the keyword. (Each line is supposed to begin with a keyword). */
760 if ((keyword = strdelim(&s)) == NULL)
762 /* Ignore leading whitespace. */
763 if (*keyword == '\0')
764 keyword = strdelim(&s);
765 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
767 /* Match lowercase keyword */
770 opcode = parse_token(keyword, filename, linenum,
771 options->ignored_unknown);
775 /* don't panic, but count bad options */
778 case oIgnoredUnknownOption:
779 debug("%s line %d: Ignored unknown option \"%s\"",
780 filename, linenum, keyword);
782 case oConnectTimeout:
783 intptr = &options->connection_timeout;
786 if (!arg || *arg == '\0')
787 fatal("%s line %d: missing time value.",
789 if ((value = convtime(arg)) == -1)
790 fatal("%s line %d: invalid time value.",
792 if (*activep && *intptr == -1)
797 intptr = &options->forward_agent;
799 multistate_ptr = multistate_flag;
802 if (!arg || *arg == '\0')
803 fatal("%s line %d: missing argument.",
806 for (i = 0; multistate_ptr[i].key != NULL; i++) {
807 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
808 value = multistate_ptr[i].value;
813 fatal("%s line %d: unsupported option \"%s\".",
814 filename, linenum, arg);
815 if (*activep && *intptr == -1)
820 intptr = &options->forward_x11;
823 case oForwardX11Trusted:
824 intptr = &options->forward_x11_trusted;
827 case oForwardX11Timeout:
828 intptr = &options->forward_x11_timeout;
832 intptr = &options->fwd_opts.gateway_ports;
835 case oExitOnForwardFailure:
836 intptr = &options->exit_on_forward_failure;
839 case oUsePrivilegedPort:
840 intptr = &options->use_privileged_port;
843 case oPasswordAuthentication:
844 intptr = &options->password_authentication;
847 case oKbdInteractiveAuthentication:
848 intptr = &options->kbd_interactive_authentication;
851 case oKbdInteractiveDevices:
852 charptr = &options->kbd_interactive_devices;
855 case oPubkeyAuthentication:
856 intptr = &options->pubkey_authentication;
859 case oRSAAuthentication:
860 intptr = &options->rsa_authentication;
863 case oRhostsRSAAuthentication:
864 intptr = &options->rhosts_rsa_authentication;
867 case oHostbasedAuthentication:
868 intptr = &options->hostbased_authentication;
871 case oChallengeResponseAuthentication:
872 intptr = &options->challenge_response_authentication;
875 case oGssAuthentication:
876 intptr = &options->gss_authentication;
879 case oGssDelegateCreds:
880 intptr = &options->gss_deleg_creds;
884 intptr = &options->batch_mode;
888 intptr = &options->check_host_ip;
892 intptr = &options->hpn_disabled;
896 intptr = &options->hpn_buffer_size;
900 intptr = &options->tcp_rcv_buf_poll;
904 intptr = &options->none_enabled;
907 /* we check to see if the command comes from the */
908 /* command line or not. If it does then enable it */
909 /* otherwise fail. NONE should never be a default configuration */
911 if(strcmp(filename,"command-line") == 0) {
912 intptr = &options->none_switch;
915 error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
916 error("Continuing...");
917 debug("NoneSwitch directive found in %.200s.", filename);
921 case oVerifyHostKeyDNS:
922 intptr = &options->verify_host_key_dns;
923 multistate_ptr = multistate_yesnoask;
924 goto parse_multistate;
926 case oStrictHostKeyChecking:
927 intptr = &options->strict_host_key_checking;
928 multistate_ptr = multistate_yesnoask;
929 goto parse_multistate;
932 intptr = &options->compression;
936 intptr = &options->tcp_keep_alive;
939 case oNoHostAuthenticationForLocalhost:
940 intptr = &options->no_host_authentication_for_localhost;
943 case oNumberOfPasswordPrompts:
944 intptr = &options->number_of_password_prompts;
947 case oCompressionLevel:
948 intptr = &options->compression_level;
953 if (!arg || *arg == '\0')
954 fatal("%.200s line %d: Missing argument.", filename,
956 if (strcmp(arg, "default") == 0) {
959 if (scan_scaled(arg, &val64) == -1)
960 fatal("%.200s line %d: Bad number '%s': %s",
961 filename, linenum, arg, strerror(errno));
962 /* check for too-large or too-small limits */
963 if (val64 > UINT_MAX)
964 fatal("%.200s line %d: RekeyLimit too large",
966 if (val64 != 0 && val64 < 16)
967 fatal("%.200s line %d: RekeyLimit too small",
970 if (*activep && options->rekey_limit == -1)
971 options->rekey_limit = (u_int32_t)val64;
972 if (s != NULL) { /* optional rekey interval present */
973 if (strcmp(s, "none") == 0) {
974 (void)strdelim(&s); /* discard */
977 intptr = &options->rekey_interval;
984 if (!arg || *arg == '\0')
985 fatal("%.200s line %d: Missing argument.", filename, linenum);
987 intptr = &options->num_identity_files;
988 if (*intptr >= SSH_MAX_IDENTITY_FILES)
989 fatal("%.200s line %d: Too many identity files specified (max %d).",
990 filename, linenum, SSH_MAX_IDENTITY_FILES);
991 add_identity_file(options, NULL, arg, userconfig);
996 charptr=&options->xauth_location;
1000 charptr = &options->user;
1003 if (!arg || *arg == '\0')
1004 fatal("%.200s line %d: Missing argument.",
1006 if (*activep && *charptr == NULL)
1007 *charptr = xstrdup(arg);
1010 case oGlobalKnownHostsFile:
1011 cpptr = (char **)&options->system_hostfiles;
1012 uintptr = &options->num_system_hostfiles;
1013 max_entries = SSH_MAX_HOSTS_FILES;
1015 if (*activep && *uintptr == 0) {
1016 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1017 if ((*uintptr) >= max_entries)
1018 fatal("%s line %d: "
1019 "too many authorized keys files.",
1021 cpptr[(*uintptr)++] = xstrdup(arg);
1026 case oUserKnownHostsFile:
1027 cpptr = (char **)&options->user_hostfiles;
1028 uintptr = &options->num_user_hostfiles;
1029 max_entries = SSH_MAX_HOSTS_FILES;
1030 goto parse_char_array;
1033 charptr = &options->hostname;
1037 charptr = &options->host_key_alias;
1040 case oPreferredAuthentications:
1041 charptr = &options->preferred_authentications;
1045 charptr = &options->bind_address;
1048 case oPKCS11Provider:
1049 charptr = &options->pkcs11_provider;
1053 charptr = &options->proxy_command;
1056 fatal("%.200s line %d: Missing argument.", filename, linenum);
1057 len = strspn(s, WHITESPACE "=");
1058 if (*activep && *charptr == NULL)
1059 *charptr = xstrdup(s + len);
1063 intptr = &options->port;
1066 if (!arg || *arg == '\0')
1067 fatal("%.200s line %d: Missing argument.", filename, linenum);
1068 if (arg[0] < '0' || arg[0] > '9')
1069 fatal("%.200s line %d: Bad number.", filename, linenum);
1071 /* Octal, decimal, or hex format? */
1072 value = strtol(arg, &endofnumber, 0);
1073 if (arg == endofnumber)
1074 fatal("%.200s line %d: Bad number.", filename, linenum);
1075 if (*activep && *intptr == -1)
1079 case oConnectionAttempts:
1080 intptr = &options->connection_attempts;
1084 intptr = &options->tcp_rcv_buf;
1088 intptr = &options->cipher;
1090 if (!arg || *arg == '\0')
1091 fatal("%.200s line %d: Missing argument.", filename, linenum);
1092 value = cipher_number(arg);
1094 fatal("%.200s line %d: Bad cipher '%s'.",
1095 filename, linenum, arg ? arg : "<NONE>");
1096 if (*activep && *intptr == -1)
1102 if (!arg || *arg == '\0')
1103 fatal("%.200s line %d: Missing argument.", filename, linenum);
1104 if (!ciphers_valid(arg))
1105 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1106 filename, linenum, arg ? arg : "<NONE>");
1107 if (*activep && options->ciphers == NULL)
1108 options->ciphers = xstrdup(arg);
1113 if (!arg || *arg == '\0')
1114 fatal("%.200s line %d: Missing argument.", filename, linenum);
1115 if (!mac_valid(arg))
1116 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1117 filename, linenum, arg ? arg : "<NONE>");
1118 if (*activep && options->macs == NULL)
1119 options->macs = xstrdup(arg);
1122 case oKexAlgorithms:
1124 if (!arg || *arg == '\0')
1125 fatal("%.200s line %d: Missing argument.",
1127 if (!kex_names_valid(arg))
1128 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1129 filename, linenum, arg ? arg : "<NONE>");
1130 if (*activep && options->kex_algorithms == NULL)
1131 options->kex_algorithms = xstrdup(arg);
1134 case oHostKeyAlgorithms:
1136 if (!arg || *arg == '\0')
1137 fatal("%.200s line %d: Missing argument.", filename, linenum);
1138 if (!key_names_valid2(arg))
1139 fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
1140 filename, linenum, arg ? arg : "<NONE>");
1141 if (*activep && options->hostkeyalgorithms == NULL)
1142 options->hostkeyalgorithms = xstrdup(arg);
1146 intptr = &options->protocol;
1148 if (!arg || *arg == '\0')
1149 fatal("%.200s line %d: Missing argument.", filename, linenum);
1150 value = proto_spec(arg);
1151 if (value == SSH_PROTO_UNKNOWN)
1152 fatal("%.200s line %d: Bad protocol spec '%s'.",
1153 filename, linenum, arg ? arg : "<NONE>");
1154 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1159 log_level_ptr = &options->log_level;
1161 value = log_level_number(arg);
1162 if (value == SYSLOG_LEVEL_NOT_SET)
1163 fatal("%.200s line %d: unsupported log level '%s'",
1164 filename, linenum, arg ? arg : "<NONE>");
1165 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1166 *log_level_ptr = (LogLevel) value;
1170 case oRemoteForward:
1171 case oDynamicForward:
1173 if (arg == NULL || *arg == '\0')
1174 fatal("%.200s line %d: Missing port argument.",
1177 if (opcode == oLocalForward ||
1178 opcode == oRemoteForward) {
1179 arg2 = strdelim(&s);
1180 if (arg2 == NULL || *arg2 == '\0')
1181 fatal("%.200s line %d: Missing target argument.",
1184 /* construct a string for parse_forward */
1185 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1186 } else if (opcode == oDynamicForward) {
1187 strlcpy(fwdarg, arg, sizeof(fwdarg));
1190 if (parse_forward(&fwd, fwdarg,
1191 opcode == oDynamicForward ? 1 : 0,
1192 opcode == oRemoteForward ? 1 : 0) == 0)
1193 fatal("%.200s line %d: Bad forwarding specification.",
1197 if (opcode == oLocalForward ||
1198 opcode == oDynamicForward)
1199 add_local_forward(options, &fwd);
1200 else if (opcode == oRemoteForward)
1201 add_remote_forward(options, &fwd);
1205 case oClearAllForwardings:
1206 intptr = &options->clear_forwardings;
1211 fatal("Host directive not supported as a command-line "
1215 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1216 negated = *arg == '!';
1219 if (match_pattern(host, arg)) {
1221 debug("%.200s line %d: Skipping Host "
1222 "block because of negated match "
1223 "for %.100s", filename, linenum,
1229 arg2 = arg; /* logged below */
1234 debug("%.200s line %d: Applying options for %.100s",
1235 filename, linenum, arg2);
1236 /* Avoid garbage check below, as strdelim is done. */
1241 fatal("Host directive not supported as a command-line "
1243 value = match_cfg_line(options, &s, pw, host,
1246 fatal("%.200s line %d: Bad Match condition", filename,
1252 intptr = &options->escape_char;
1254 if (!arg || *arg == '\0')
1255 fatal("%.200s line %d: Missing argument.", filename, linenum);
1256 if (arg[0] == '^' && arg[2] == 0 &&
1257 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1258 value = (u_char) arg[1] & 31;
1259 else if (strlen(arg) == 1)
1260 value = (u_char) arg[0];
1261 else if (strcmp(arg, "none") == 0)
1262 value = SSH_ESCAPECHAR_NONE;
1264 fatal("%.200s line %d: Bad escape character.",
1267 value = 0; /* Avoid compiler warning. */
1269 if (*activep && *intptr == -1)
1273 case oAddressFamily:
1274 intptr = &options->address_family;
1275 multistate_ptr = multistate_addressfamily;
1276 goto parse_multistate;
1278 case oEnableSSHKeysign:
1279 intptr = &options->enable_ssh_keysign;
1282 case oIdentitiesOnly:
1283 intptr = &options->identities_only;
1286 case oServerAliveInterval:
1287 intptr = &options->server_alive_interval;
1290 case oServerAliveCountMax:
1291 intptr = &options->server_alive_count_max;
1294 case oVersionAddendum:
1296 fatal("%.200s line %d: Missing argument.", filename,
1298 len = strspn(s, WHITESPACE);
1299 if (*activep && options->version_addendum == NULL) {
1300 if (strcasecmp(s + len, "none") == 0)
1301 options->version_addendum = xstrdup("");
1302 else if (strchr(s + len, '\r') != NULL)
1303 fatal("%.200s line %d: Invalid argument",
1306 options->version_addendum = xstrdup(s + len);
1311 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1312 if (strchr(arg, '=') != NULL)
1313 fatal("%s line %d: Invalid environment name.",
1317 if (options->num_send_env >= MAX_SEND_ENV)
1318 fatal("%s line %d: too many send env.",
1320 options->send_env[options->num_send_env++] =
1326 charptr = &options->control_path;
1329 case oControlMaster:
1330 intptr = &options->control_master;
1331 multistate_ptr = multistate_controlmaster;
1332 goto parse_multistate;
1334 case oControlPersist:
1335 /* no/false/yes/true, or a time spec */
1336 intptr = &options->control_persist;
1338 if (!arg || *arg == '\0')
1339 fatal("%.200s line %d: Missing ControlPersist"
1340 " argument.", filename, linenum);
1342 value2 = 0; /* timeout */
1343 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1345 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1347 else if ((value2 = convtime(arg)) >= 0)
1350 fatal("%.200s line %d: Bad ControlPersist argument.",
1352 if (*activep && *intptr == -1) {
1354 options->control_persist_timeout = value2;
1358 case oHashKnownHosts:
1359 intptr = &options->hash_known_hosts;
1363 intptr = &options->tun_open;
1364 multistate_ptr = multistate_tunnel;
1365 goto parse_multistate;
1369 if (!arg || *arg == '\0')
1370 fatal("%.200s line %d: Missing argument.", filename, linenum);
1371 value = a2tun(arg, &value2);
1372 if (value == SSH_TUNID_ERR)
1373 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1375 options->tun_local = value;
1376 options->tun_remote = value2;
1381 charptr = &options->local_command;
1384 case oPermitLocalCommand:
1385 intptr = &options->permit_local_command;
1388 case oVisualHostKey:
1389 intptr = &options->visual_host_key;
1394 if ((value = parse_ipqos(arg)) == -1)
1395 fatal("%s line %d: Bad IPQoS value: %s",
1396 filename, linenum, arg);
1400 else if ((value2 = parse_ipqos(arg)) == -1)
1401 fatal("%s line %d: Bad IPQoS value: %s",
1402 filename, linenum, arg);
1404 options->ip_qos_interactive = value;
1405 options->ip_qos_bulk = value2;
1410 intptr = &options->use_roaming;
1414 intptr = &options->request_tty;
1415 multistate_ptr = multistate_requesttty;
1416 goto parse_multistate;
1418 case oIgnoreUnknown:
1419 charptr = &options->ignored_unknown;
1422 case oProxyUseFdpass:
1423 intptr = &options->proxy_use_fdpass;
1426 case oCanonicalDomains:
1427 value = options->num_canonical_domains != 0;
1428 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1429 valid_domain(arg, filename, linenum);
1430 if (!*activep || value)
1432 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1433 fatal("%s line %d: too many hostname suffixes.",
1435 options->canonical_domains[
1436 options->num_canonical_domains++] = xstrdup(arg);
1440 case oCanonicalizePermittedCNAMEs:
1441 value = options->num_permitted_cnames != 0;
1442 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1443 /* Either '*' for everything or 'list:list' */
1444 if (strcmp(arg, "*") == 0)
1448 if ((arg2 = strchr(arg, ':')) == NULL ||
1450 fatal("%s line %d: "
1451 "Invalid permitted CNAME \"%s\"",
1452 filename, linenum, arg);
1457 if (!*activep || value)
1459 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1460 fatal("%s line %d: too many permitted CNAMEs.",
1462 cname = options->permitted_cnames +
1463 options->num_permitted_cnames++;
1464 cname->source_list = xstrdup(arg);
1465 cname->target_list = xstrdup(arg2);
1469 case oCanonicalizeHostname:
1470 intptr = &options->canonicalize_hostname;
1471 multistate_ptr = multistate_canonicalizehostname;
1472 goto parse_multistate;
1474 case oCanonicalizeMaxDots:
1475 intptr = &options->canonicalize_max_dots;
1478 case oCanonicalizeFallbackLocal:
1479 intptr = &options->canonicalize_fallback_local;
1482 case oStreamLocalBindMask:
1484 if (!arg || *arg == '\0')
1485 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1486 /* Parse mode in octal format */
1487 value = strtol(arg, &endofnumber, 8);
1488 if (arg == endofnumber || value < 0 || value > 0777)
1489 fatal("%.200s line %d: Bad mask.", filename, linenum);
1490 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1493 case oStreamLocalBindUnlink:
1494 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1498 debug("%s line %d: Deprecated option \"%s\"",
1499 filename, linenum, keyword);
1503 error("%s line %d: Unsupported option \"%s\"",
1504 filename, linenum, keyword);
1508 fatal("process_config_line: Unimplemented opcode %d", opcode);
1511 /* Check that there is no garbage at end of line. */
1512 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1513 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1514 filename, linenum, arg);
1521 * Reads the config file and modifies the options accordingly. Options
1522 * should already be initialized before this call. This never returns if
1523 * there is an error. If the file does not exist, this returns 0.
1527 read_config_file(const char *filename, struct passwd *pw, const char *host,
1528 Options *options, int flags)
1532 int active, linenum;
1533 int bad_options = 0;
1535 if ((f = fopen(filename, "r")) == NULL)
1538 if (flags & SSHCONF_CHECKPERM) {
1541 if (fstat(fileno(f), &sb) == -1)
1542 fatal("fstat %s: %s", filename, strerror(errno));
1543 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1544 (sb.st_mode & 022) != 0))
1545 fatal("Bad owner or permissions on %s", filename);
1548 debug("Reading configuration data %.200s", filename);
1551 * Mark that we are now processing the options. This flag is turned
1552 * on/off by Host specifications.
1556 while (fgets(line, sizeof(line), f)) {
1557 /* Update line number counter. */
1559 if (process_config_line(options, pw, host, line, filename,
1560 linenum, &active, flags & SSHCONF_USERCONF) != 0)
1564 if (bad_options > 0)
1565 fatal("%s: terminating, %d bad configuration options",
1566 filename, bad_options);
1570 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1572 option_clear_or_none(const char *o)
1574 return o == NULL || strcasecmp(o, "none") == 0;
1578 * Initializes options to special values that indicate that they have not yet
1579 * been set. Read_config_file will only set options with this value. Options
1580 * are processed in the following order: command line, user config file,
1581 * system config file. Last, fill_default_options is called.
1585 initialize_options(Options * options)
1587 memset(options, 'X', sizeof(*options));
1588 options->forward_agent = -1;
1589 options->forward_x11 = -1;
1590 options->forward_x11_trusted = -1;
1591 options->forward_x11_timeout = -1;
1592 options->exit_on_forward_failure = -1;
1593 options->xauth_location = NULL;
1594 options->fwd_opts.gateway_ports = -1;
1595 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1596 options->fwd_opts.streamlocal_bind_unlink = -1;
1597 options->use_privileged_port = -1;
1598 options->rsa_authentication = -1;
1599 options->pubkey_authentication = -1;
1600 options->challenge_response_authentication = -1;
1601 options->gss_authentication = -1;
1602 options->gss_deleg_creds = -1;
1603 options->password_authentication = -1;
1604 options->kbd_interactive_authentication = -1;
1605 options->kbd_interactive_devices = NULL;
1606 options->rhosts_rsa_authentication = -1;
1607 options->hostbased_authentication = -1;
1608 options->batch_mode = -1;
1609 options->check_host_ip = -1;
1610 options->strict_host_key_checking = -1;
1611 options->compression = -1;
1612 options->tcp_keep_alive = -1;
1613 options->compression_level = -1;
1615 options->address_family = -1;
1616 options->connection_attempts = -1;
1617 options->connection_timeout = -1;
1618 options->number_of_password_prompts = -1;
1619 options->cipher = -1;
1620 options->ciphers = NULL;
1621 options->macs = NULL;
1622 options->kex_algorithms = NULL;
1623 options->hostkeyalgorithms = NULL;
1624 options->protocol = SSH_PROTO_UNKNOWN;
1625 options->num_identity_files = 0;
1626 options->hostname = NULL;
1627 options->host_key_alias = NULL;
1628 options->proxy_command = NULL;
1629 options->user = NULL;
1630 options->escape_char = -1;
1631 options->num_system_hostfiles = 0;
1632 options->num_user_hostfiles = 0;
1633 options->local_forwards = NULL;
1634 options->num_local_forwards = 0;
1635 options->remote_forwards = NULL;
1636 options->num_remote_forwards = 0;
1637 options->clear_forwardings = -1;
1638 options->log_level = SYSLOG_LEVEL_NOT_SET;
1639 options->preferred_authentications = NULL;
1640 options->bind_address = NULL;
1641 options->pkcs11_provider = NULL;
1642 options->enable_ssh_keysign = - 1;
1643 options->no_host_authentication_for_localhost = - 1;
1644 options->identities_only = - 1;
1645 options->rekey_limit = - 1;
1646 options->rekey_interval = -1;
1647 options->verify_host_key_dns = -1;
1648 options->server_alive_interval = -1;
1649 options->server_alive_count_max = -1;
1650 options->num_send_env = 0;
1651 options->control_path = NULL;
1652 options->control_master = -1;
1653 options->control_persist = -1;
1654 options->control_persist_timeout = 0;
1655 options->hash_known_hosts = -1;
1656 options->tun_open = -1;
1657 options->tun_local = -1;
1658 options->tun_remote = -1;
1659 options->local_command = NULL;
1660 options->permit_local_command = -1;
1661 options->use_roaming = -1;
1662 options->visual_host_key = -1;
1663 options->ip_qos_interactive = -1;
1664 options->ip_qos_bulk = -1;
1665 options->request_tty = -1;
1666 options->version_addendum = NULL;
1667 options->none_switch = -1;
1668 options->none_enabled = -1;
1669 options->hpn_disabled = -1;
1670 options->hpn_buffer_size = -1;
1671 options->tcp_rcv_buf_poll = -1;
1672 options->tcp_rcv_buf = -1;
1673 options->proxy_use_fdpass = -1;
1674 options->ignored_unknown = NULL;
1675 options->num_canonical_domains = 0;
1676 options->num_permitted_cnames = 0;
1677 options->canonicalize_max_dots = -1;
1678 options->canonicalize_fallback_local = -1;
1679 options->canonicalize_hostname = -1;
1683 * A petite version of fill_default_options() that just fills the options
1684 * needed for hostname canonicalization to proceed.
1687 fill_default_options_for_canonicalization(Options *options)
1689 if (options->canonicalize_max_dots == -1)
1690 options->canonicalize_max_dots = 1;
1691 if (options->canonicalize_fallback_local == -1)
1692 options->canonicalize_fallback_local = 1;
1693 if (options->canonicalize_hostname == -1)
1694 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1698 * Called after processing other sources of option data, this fills those
1699 * options for which no value has been specified with their default values.
1702 fill_default_options(Options * options)
1704 if (options->forward_agent == -1)
1705 options->forward_agent = 0;
1706 if (options->forward_x11 == -1)
1707 options->forward_x11 = 0;
1708 if (options->forward_x11_trusted == -1)
1709 options->forward_x11_trusted = 0;
1710 if (options->forward_x11_timeout == -1)
1711 options->forward_x11_timeout = 1200;
1712 if (options->exit_on_forward_failure == -1)
1713 options->exit_on_forward_failure = 0;
1714 if (options->xauth_location == NULL)
1715 options->xauth_location = _PATH_XAUTH;
1716 if (options->fwd_opts.gateway_ports == -1)
1717 options->fwd_opts.gateway_ports = 0;
1718 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1719 options->fwd_opts.streamlocal_bind_mask = 0177;
1720 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1721 options->fwd_opts.streamlocal_bind_unlink = 0;
1722 if (options->use_privileged_port == -1)
1723 options->use_privileged_port = 0;
1724 if (options->rsa_authentication == -1)
1725 options->rsa_authentication = 1;
1726 if (options->pubkey_authentication == -1)
1727 options->pubkey_authentication = 1;
1728 if (options->challenge_response_authentication == -1)
1729 options->challenge_response_authentication = 1;
1730 if (options->gss_authentication == -1)
1731 options->gss_authentication = 0;
1732 if (options->gss_deleg_creds == -1)
1733 options->gss_deleg_creds = 0;
1734 if (options->password_authentication == -1)
1735 options->password_authentication = 1;
1736 if (options->kbd_interactive_authentication == -1)
1737 options->kbd_interactive_authentication = 1;
1738 if (options->rhosts_rsa_authentication == -1)
1739 options->rhosts_rsa_authentication = 0;
1740 if (options->hostbased_authentication == -1)
1741 options->hostbased_authentication = 0;
1742 if (options->batch_mode == -1)
1743 options->batch_mode = 0;
1744 if (options->check_host_ip == -1)
1745 options->check_host_ip = 0;
1746 if (options->strict_host_key_checking == -1)
1747 options->strict_host_key_checking = 2; /* 2 is default */
1748 if (options->compression == -1)
1749 options->compression = 0;
1750 if (options->tcp_keep_alive == -1)
1751 options->tcp_keep_alive = 1;
1752 if (options->compression_level == -1)
1753 options->compression_level = 6;
1754 if (options->port == -1)
1755 options->port = 0; /* Filled in ssh_connect. */
1756 if (options->address_family == -1)
1757 options->address_family = AF_UNSPEC;
1758 if (options->connection_attempts == -1)
1759 options->connection_attempts = 1;
1760 if (options->number_of_password_prompts == -1)
1761 options->number_of_password_prompts = 3;
1762 /* Selected in ssh_login(). */
1763 if (options->cipher == -1)
1764 options->cipher = SSH_CIPHER_NOT_SET;
1765 /* options->ciphers, default set in myproposals.h */
1766 /* options->macs, default set in myproposals.h */
1767 /* options->kex_algorithms, default set in myproposals.h */
1768 /* options->hostkeyalgorithms, default set in myproposals.h */
1769 if (options->protocol == SSH_PROTO_UNKNOWN)
1770 options->protocol = SSH_PROTO_2;
1771 if (options->num_identity_files == 0) {
1772 if (options->protocol & SSH_PROTO_1) {
1773 add_identity_file(options, "~/",
1774 _PATH_SSH_CLIENT_IDENTITY, 0);
1776 if (options->protocol & SSH_PROTO_2) {
1777 add_identity_file(options, "~/",
1778 _PATH_SSH_CLIENT_ID_RSA, 0);
1779 add_identity_file(options, "~/",
1780 _PATH_SSH_CLIENT_ID_DSA, 0);
1781 #ifdef OPENSSL_HAS_ECC
1782 add_identity_file(options, "~/",
1783 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1785 add_identity_file(options, "~/",
1786 _PATH_SSH_CLIENT_ID_ED25519, 0);
1789 if (options->escape_char == -1)
1790 options->escape_char = '~';
1791 if (options->num_system_hostfiles == 0) {
1792 options->system_hostfiles[options->num_system_hostfiles++] =
1793 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1794 options->system_hostfiles[options->num_system_hostfiles++] =
1795 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1797 if (options->num_user_hostfiles == 0) {
1798 options->user_hostfiles[options->num_user_hostfiles++] =
1799 xstrdup(_PATH_SSH_USER_HOSTFILE);
1800 options->user_hostfiles[options->num_user_hostfiles++] =
1801 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1803 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1804 options->log_level = SYSLOG_LEVEL_INFO;
1805 if (options->clear_forwardings == 1)
1806 clear_forwardings(options);
1807 if (options->no_host_authentication_for_localhost == - 1)
1808 options->no_host_authentication_for_localhost = 0;
1809 if (options->identities_only == -1)
1810 options->identities_only = 0;
1811 if (options->enable_ssh_keysign == -1)
1812 options->enable_ssh_keysign = 0;
1813 if (options->rekey_limit == -1)
1814 options->rekey_limit = 0;
1815 if (options->rekey_interval == -1)
1816 options->rekey_interval = 0;
1817 if (options->verify_host_key_dns == -1)
1818 options->verify_host_key_dns = 0;
1819 if (options->server_alive_interval == -1)
1820 options->server_alive_interval = 0;
1821 if (options->server_alive_count_max == -1)
1822 options->server_alive_count_max = 3;
1823 if (options->version_addendum == NULL)
1824 options->version_addendum = xstrdup(SSH_VERSION_DRAGONFLY);
1825 if (options->none_switch == -1)
1826 options->none_switch = 0;
1827 if (options->none_enabled == -1)
1828 options->none_enabled = 0;
1829 if (options->hpn_disabled == -1)
1830 options->hpn_disabled = 0;
1831 if (options->hpn_buffer_size > -1)
1833 /* if a user tries to set the size to 0 set it to 1KB */
1834 if (options->hpn_buffer_size == 0)
1835 options->hpn_buffer_size = 1;
1836 /*limit the buffer to 64MB*/
1837 if (options->hpn_buffer_size > 64*1024)
1839 options->hpn_buffer_size = 64*1024*1024;
1840 debug("User requested buffer larger than 64MB. Request reverted to 64MB");
1842 else options->hpn_buffer_size *= 1024;
1843 debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
1845 if (options->tcp_rcv_buf == 0)
1846 options->tcp_rcv_buf = 1;
1847 if (options->tcp_rcv_buf > -1)
1848 options->tcp_rcv_buf *=1024;
1849 if (options->tcp_rcv_buf_poll == -1)
1850 options->tcp_rcv_buf_poll = 1;
1851 if (options->control_master == -1)
1852 options->control_master = 0;
1853 if (options->control_persist == -1) {
1854 options->control_persist = 0;
1855 options->control_persist_timeout = 0;
1857 if (options->hash_known_hosts == -1)
1858 options->hash_known_hosts = 0;
1859 if (options->tun_open == -1)
1860 options->tun_open = SSH_TUNMODE_NO;
1861 if (options->tun_local == -1)
1862 options->tun_local = SSH_TUNID_ANY;
1863 if (options->tun_remote == -1)
1864 options->tun_remote = SSH_TUNID_ANY;
1865 if (options->permit_local_command == -1)
1866 options->permit_local_command = 0;
1867 if (options->use_roaming == -1)
1868 options->use_roaming = 1;
1869 if (options->visual_host_key == -1)
1870 options->visual_host_key = 0;
1871 if (options->ip_qos_interactive == -1)
1872 options->ip_qos_interactive = IPTOS_LOWDELAY;
1873 if (options->ip_qos_bulk == -1)
1874 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1875 if (options->request_tty == -1)
1876 options->request_tty = REQUEST_TTY_AUTO;
1877 if (options->proxy_use_fdpass == -1)
1878 options->proxy_use_fdpass = 0;
1879 if (options->canonicalize_max_dots == -1)
1880 options->canonicalize_max_dots = 1;
1881 if (options->canonicalize_fallback_local == -1)
1882 options->canonicalize_fallback_local = 1;
1883 if (options->canonicalize_hostname == -1)
1884 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1885 #define CLEAR_ON_NONE(v) \
1887 if (option_clear_or_none(v)) { \
1892 CLEAR_ON_NONE(options->local_command);
1893 CLEAR_ON_NONE(options->proxy_command);
1894 CLEAR_ON_NONE(options->control_path);
1895 /* options->user will be set in the main program if appropriate */
1896 /* options->hostname will be set in the main program if appropriate */
1897 /* options->host_key_alias should not be set by default */
1898 /* options->preferred_authentications will be set in ssh */
1908 * parses the next field in a port forwarding specification.
1909 * sets fwd to the parsed field and advances p past the colon
1910 * or sets it to NULL at end of string.
1911 * returns 0 on success, else non-zero.
1914 parse_fwd_field(char **p, struct fwdarg *fwd)
1921 return -1; /* end of string */
1925 * A field escaped with square brackets is used literally.
1926 * XXX - allow ']' to be escaped via backslash?
1929 /* find matching ']' */
1930 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1934 /* no matching ']' or not at end of field. */
1935 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1937 /* NUL terminate the field and advance p past the colon */
1942 fwd->ispath = ispath;
1947 for (cp = *p; *cp != '\0'; cp++) {
1950 memmove(cp, cp + 1, strlen(cp + 1) + 1);
1963 fwd->ispath = ispath;
1970 * parses a string containing a port forwarding specification of the form:
1972 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
1973 * listenpath:connectpath
1975 * [listenhost:]listenport
1976 * returns number of arguments parsed or zero on error
1979 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1981 struct fwdarg fwdargs[4];
1985 memset(fwd, 0, sizeof(*fwd));
1986 memset(fwdargs, 0, sizeof(fwdargs));
1988 cp = p = xstrdup(fwdspec);
1990 /* skip leading spaces */
1991 while (isspace((u_char)*cp))
1994 for (i = 0; i < 4; ++i) {
1995 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
1999 /* Check for trailing garbage */
2000 if (cp != NULL && *cp != '\0') {
2001 i = 0; /* failure */
2006 if (fwdargs[0].ispath) {
2007 fwd->listen_path = xstrdup(fwdargs[0].arg);
2008 fwd->listen_port = PORT_STREAMLOCAL;
2010 fwd->listen_host = NULL;
2011 fwd->listen_port = a2port(fwdargs[0].arg);
2013 fwd->connect_host = xstrdup("socks");
2017 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2018 fwd->listen_path = xstrdup(fwdargs[0].arg);
2019 fwd->listen_port = PORT_STREAMLOCAL;
2020 fwd->connect_path = xstrdup(fwdargs[1].arg);
2021 fwd->connect_port = PORT_STREAMLOCAL;
2022 } else if (fwdargs[1].ispath) {
2023 fwd->listen_host = NULL;
2024 fwd->listen_port = a2port(fwdargs[0].arg);
2025 fwd->connect_path = xstrdup(fwdargs[1].arg);
2026 fwd->connect_port = PORT_STREAMLOCAL;
2028 fwd->listen_host = xstrdup(fwdargs[0].arg);
2029 fwd->listen_port = a2port(fwdargs[1].arg);
2030 fwd->connect_host = xstrdup("socks");
2035 if (fwdargs[0].ispath) {
2036 fwd->listen_path = xstrdup(fwdargs[0].arg);
2037 fwd->listen_port = PORT_STREAMLOCAL;
2038 fwd->connect_host = xstrdup(fwdargs[1].arg);
2039 fwd->connect_port = a2port(fwdargs[2].arg);
2040 } else if (fwdargs[2].ispath) {
2041 fwd->listen_host = xstrdup(fwdargs[0].arg);
2042 fwd->listen_port = a2port(fwdargs[1].arg);
2043 fwd->connect_path = xstrdup(fwdargs[2].arg);
2044 fwd->connect_port = PORT_STREAMLOCAL;
2046 fwd->listen_host = NULL;
2047 fwd->listen_port = a2port(fwdargs[0].arg);
2048 fwd->connect_host = xstrdup(fwdargs[1].arg);
2049 fwd->connect_port = a2port(fwdargs[2].arg);
2054 fwd->listen_host = xstrdup(fwdargs[0].arg);
2055 fwd->listen_port = a2port(fwdargs[1].arg);
2056 fwd->connect_host = xstrdup(fwdargs[2].arg);
2057 fwd->connect_port = a2port(fwdargs[3].arg);
2060 i = 0; /* failure */
2066 if (!(i == 1 || i == 2))
2069 if (!(i == 3 || i == 4)) {
2070 if (fwd->connect_path == NULL &&
2071 fwd->listen_path == NULL)
2074 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2078 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2079 (!remotefwd && fwd->listen_port == 0))
2081 if (fwd->connect_host != NULL &&
2082 strlen(fwd->connect_host) >= NI_MAXHOST)
2084 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2085 if (fwd->connect_path != NULL &&
2086 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2088 if (fwd->listen_host != NULL &&
2089 strlen(fwd->listen_host) >= NI_MAXHOST)
2091 if (fwd->listen_path != NULL &&
2092 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2098 free(fwd->connect_host);
2099 fwd->connect_host = NULL;
2100 free(fwd->connect_path);
2101 fwd->connect_path = NULL;
2102 free(fwd->listen_host);
2103 fwd->listen_host = NULL;
2104 free(fwd->listen_path);
2105 fwd->listen_path = NULL;