1 /* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm 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".
18 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/sysctl.h>
25 #include <netinet/in.h>
26 #include <netinet/in_systm.h>
27 #include <netinet/ip.h>
28 #include <arpa/inet.h>
47 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
55 #include "pathnames.h"
64 #include "myproposal.h"
68 /* Format of the configuration file:
70 # Configuration data is parsed as follows:
71 # 1. command line options
72 # 2. user-specific file
74 # Any configuration value is only changed the first time it is set.
75 # Thus, host-specific definitions should be at the beginning of the
76 # configuration file, and defaults at the end.
78 # Host-specific declarations. These may override anything above. A single
79 # host may match multiple declarations; these are processed in the order
80 # that they are given in.
86 HostName another.host.name.real.org
93 RemoteForward 9999 shadows.cs.hut.fi:9999
99 PasswordAuthentication no
103 ProxyCommand ssh-proxy %h %p
106 PublicKeyAuthentication no
110 PasswordAuthentication no
116 # Defaults for various options
120 PasswordAuthentication yes
121 RSAAuthentication yes
122 RhostsRSAAuthentication yes
123 StrictHostKeyChecking yes
125 IdentityFile ~/.ssh/identity
131 /* Keyword tokens. */
137 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
138 oGatewayPorts, oExitOnForwardFailure,
139 oPasswordAuthentication, oRSAAuthentication,
140 oChallengeResponseAuthentication, oXAuthLocation,
141 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
142 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
143 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
144 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
145 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
146 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
147 oPubkeyAuthentication,
148 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
149 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
150 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
151 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
152 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
153 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
154 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
155 oSendEnv, oControlPath, oControlMaster, oControlPersist,
157 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
158 oVisualHostKey, oUseRoaming,
159 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
160 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
161 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
162 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
163 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
164 oPubkeyAcceptedKeyTypes,
165 oIgnoredUnknownOption, oDeprecated, oUnsupported
168 /* Textual representations of the tokens. */
174 { "forwardagent", oForwardAgent },
175 { "forwardx11", oForwardX11 },
176 { "forwardx11trusted", oForwardX11Trusted },
177 { "forwardx11timeout", oForwardX11Timeout },
178 { "exitonforwardfailure", oExitOnForwardFailure },
179 { "xauthlocation", oXAuthLocation },
180 { "gatewayports", oGatewayPorts },
181 { "useprivilegedport", oUsePrivilegedPort },
182 { "rhostsauthentication", oDeprecated },
183 { "passwordauthentication", oPasswordAuthentication },
184 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
185 { "kbdinteractivedevices", oKbdInteractiveDevices },
186 { "rsaauthentication", oRSAAuthentication },
187 { "pubkeyauthentication", oPubkeyAuthentication },
188 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
189 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
190 { "hostbasedauthentication", oHostbasedAuthentication },
191 { "challengeresponseauthentication", oChallengeResponseAuthentication },
192 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
193 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
194 { "kerberosauthentication", oUnsupported },
195 { "kerberostgtpassing", oUnsupported },
196 { "afstokenpassing", oUnsupported },
198 { "gssapiauthentication", oGssAuthentication },
199 { "gssapidelegatecredentials", oGssDelegateCreds },
201 { "gssapiauthentication", oUnsupported },
202 { "gssapidelegatecredentials", oUnsupported },
204 { "fallbacktorsh", oDeprecated },
205 { "usersh", oDeprecated },
206 { "identityfile", oIdentityFile },
207 { "identityfile2", oIdentityFile }, /* obsolete */
208 { "identitiesonly", oIdentitiesOnly },
209 { "hostname", oHostName },
210 { "hostkeyalias", oHostKeyAlias },
211 { "proxycommand", oProxyCommand },
213 { "cipher", oCipher },
214 { "ciphers", oCiphers },
216 { "protocol", oProtocol },
217 { "remoteforward", oRemoteForward },
218 { "localforward", oLocalForward },
222 { "escapechar", oEscapeChar },
223 { "globalknownhostsfile", oGlobalKnownHostsFile },
224 { "globalknownhostsfile2", oDeprecated },
225 { "userknownhostsfile", oUserKnownHostsFile },
226 { "userknownhostsfile2", oDeprecated },
227 { "connectionattempts", oConnectionAttempts },
228 { "batchmode", oBatchMode },
229 { "checkhostip", oCheckHostIP },
230 { "stricthostkeychecking", oStrictHostKeyChecking },
231 { "compression", oCompression },
232 { "compressionlevel", oCompressionLevel },
233 { "tcpkeepalive", oTCPKeepAlive },
234 { "keepalive", oTCPKeepAlive }, /* obsolete */
235 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
236 { "loglevel", oLogLevel },
237 { "dynamicforward", oDynamicForward },
238 { "preferredauthentications", oPreferredAuthentications },
239 { "hostkeyalgorithms", oHostKeyAlgorithms },
240 { "bindaddress", oBindAddress },
242 { "smartcarddevice", oPKCS11Provider },
243 { "pkcs11provider", oPKCS11Provider },
245 { "smartcarddevice", oUnsupported },
246 { "pkcs11provider", oUnsupported },
248 { "clearallforwardings", oClearAllForwardings },
249 { "enablesshkeysign", oEnableSSHKeysign },
250 { "verifyhostkeydns", oVerifyHostKeyDNS },
251 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
252 { "rekeylimit", oRekeyLimit },
253 { "connecttimeout", oConnectTimeout },
254 { "addressfamily", oAddressFamily },
255 { "serveraliveinterval", oServerAliveInterval },
256 { "serveralivecountmax", oServerAliveCountMax },
257 { "sendenv", oSendEnv },
258 { "controlpath", oControlPath },
259 { "controlmaster", oControlMaster },
260 { "controlpersist", oControlPersist },
261 { "hashknownhosts", oHashKnownHosts },
262 { "tunnel", oTunnel },
263 { "tunneldevice", oTunnelDevice },
264 { "localcommand", oLocalCommand },
265 { "permitlocalcommand", oPermitLocalCommand },
266 { "visualhostkey", oVisualHostKey },
267 { "useroaming", oUseRoaming },
268 { "kexalgorithms", oKexAlgorithms },
270 { "requesttty", oRequestTTY },
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 { "revokedhostkeys", oRevokedHostKeys },
280 { "fingerprinthash", oFingerprintHash },
281 { "updatehostkeys", oUpdateHostkeys },
282 { "hostbasedkeytypes", oHostbasedKeyTypes },
283 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
284 { "ignoreunknown", oIgnoreUnknown },
285 { "hpndisabled", oDeprecated },
286 { "hpnbuffersize", oDeprecated },
287 { "tcprcvbufpoll", oDeprecated },
288 { "tcprcvbuf", oDeprecated },
289 { "noneenabled", oUnsupported },
290 { "noneswitch", oUnsupported },
291 { "versionaddendum", oVersionAddendum },
297 * Adds a local TCP/IP port forward to options. Never returns if there is an
302 add_local_forward(Options *options, const struct Forward *newfwd)
305 #ifndef NO_IPPORT_RESERVED_CONCEPT
306 extern uid_t original_real_uid;
309 size_t len_ipport_reserved = sizeof(ipport_reserved);
311 if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
312 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
313 ipport_reserved = IPPORT_RESERVED;
317 ipport_reserved = IPPORT_RESERVED;
319 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
320 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0 &&
321 newfwd->listen_path == NULL)
322 fatal("Privileged ports can only be forwarded by root.");
324 options->local_forwards = xreallocarray(options->local_forwards,
325 options->num_local_forwards + 1,
326 sizeof(*options->local_forwards));
327 fwd = &options->local_forwards[options->num_local_forwards++];
329 fwd->listen_host = newfwd->listen_host;
330 fwd->listen_port = newfwd->listen_port;
331 fwd->listen_path = newfwd->listen_path;
332 fwd->connect_host = newfwd->connect_host;
333 fwd->connect_port = newfwd->connect_port;
334 fwd->connect_path = newfwd->connect_path;
338 * Adds a remote TCP/IP port forward to options. Never returns if there is
343 add_remote_forward(Options *options, const struct Forward *newfwd)
347 options->remote_forwards = xreallocarray(options->remote_forwards,
348 options->num_remote_forwards + 1,
349 sizeof(*options->remote_forwards));
350 fwd = &options->remote_forwards[options->num_remote_forwards++];
352 fwd->listen_host = newfwd->listen_host;
353 fwd->listen_port = newfwd->listen_port;
354 fwd->listen_path = newfwd->listen_path;
355 fwd->connect_host = newfwd->connect_host;
356 fwd->connect_port = newfwd->connect_port;
357 fwd->connect_path = newfwd->connect_path;
358 fwd->handle = newfwd->handle;
359 fwd->allocated_port = 0;
363 clear_forwardings(Options *options)
367 for (i = 0; i < options->num_local_forwards; i++) {
368 free(options->local_forwards[i].listen_host);
369 free(options->local_forwards[i].listen_path);
370 free(options->local_forwards[i].connect_host);
371 free(options->local_forwards[i].connect_path);
373 if (options->num_local_forwards > 0) {
374 free(options->local_forwards);
375 options->local_forwards = NULL;
377 options->num_local_forwards = 0;
378 for (i = 0; i < options->num_remote_forwards; i++) {
379 free(options->remote_forwards[i].listen_host);
380 free(options->remote_forwards[i].listen_path);
381 free(options->remote_forwards[i].connect_host);
382 free(options->remote_forwards[i].connect_path);
384 if (options->num_remote_forwards > 0) {
385 free(options->remote_forwards);
386 options->remote_forwards = NULL;
388 options->num_remote_forwards = 0;
389 options->tun_open = SSH_TUNMODE_NO;
393 add_identity_file(Options *options, const char *dir, const char *filename,
399 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
400 fatal("Too many identity files specified (max %d)",
401 SSH_MAX_IDENTITY_FILES);
403 if (dir == NULL) /* no dir, filename is absolute */
404 path = xstrdup(filename);
406 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
408 /* Avoid registering duplicates */
409 for (i = 0; i < options->num_identity_files; i++) {
410 if (options->identity_file_userprovided[i] == userprovided &&
411 strcmp(options->identity_files[i], path) == 0) {
412 debug2("%s: ignoring duplicate key %s", __func__, path);
418 options->identity_file_userprovided[options->num_identity_files] =
420 options->identity_files[options->num_identity_files++] = path;
424 default_ssh_port(void)
430 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
431 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
437 * Execute a command in a shell.
438 * Return its exit status or -1 on abnormal exit.
441 execute_in_shell(const char *cmd)
443 char *shell, *command_string;
446 extern uid_t original_real_uid;
448 if ((shell = getenv("SHELL")) == NULL)
449 shell = _PATH_BSHELL;
452 * Use "exec" to avoid "sh -c" processes on some platforms
455 xasprintf(&command_string, "exec %s", cmd);
457 /* Need this to redirect subprocess stdin/out */
458 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
459 fatal("open(/dev/null): %s", strerror(errno));
461 debug("Executing command: '%.500s'", cmd);
463 /* Fork and execute the command. */
464 if ((pid = fork()) == 0) {
467 /* Child. Permanently give up superuser privileges. */
468 permanently_drop_suid(original_real_uid);
470 /* Redirect child stdin and stdout. Leave stderr */
471 if (dup2(devnull, STDIN_FILENO) == -1)
472 fatal("dup2: %s", strerror(errno));
473 if (dup2(devnull, STDOUT_FILENO) == -1)
474 fatal("dup2: %s", strerror(errno));
475 if (devnull > STDERR_FILENO)
477 closefrom(STDERR_FILENO + 1);
481 argv[2] = command_string;
484 execv(argv[0], argv);
485 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
486 /* Die with signal to make this error apparent to parent. */
487 signal(SIGTERM, SIG_DFL);
488 kill(getpid(), SIGTERM);
493 fatal("%s: fork: %.100s", __func__, strerror(errno));
496 free(command_string);
498 while (waitpid(pid, &status, 0) == -1) {
499 if (errno != EINTR && errno != EAGAIN)
500 fatal("%s: waitpid: %s", __func__, strerror(errno));
502 if (!WIFEXITED(status)) {
503 error("command '%.100s' exited abnormally", cmd);
506 debug3("command returned status %d", WEXITSTATUS(status));
507 return WEXITSTATUS(status);
511 * Parse and execute a Match directive.
514 match_cfg_line(Options *options, char **condition, struct passwd *pw,
515 const char *host_arg, const char *original_host, int post_canon,
516 const char *filename, int linenum)
518 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
520 int r, port, this_result, result = 1, attributes = 0, negate;
521 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
524 * Configuration is likely to be incomplete at this point so we
525 * must be prepared to use default values.
527 port = options->port <= 0 ? default_ssh_port() : options->port;
528 ruser = options->user == NULL ? pw->pw_name : options->user;
529 if (options->hostname != NULL) {
530 /* NB. Please keep in sync with ssh.c:main() */
531 host = percent_expand(options->hostname,
532 "h", host_arg, (char *)NULL);
534 host = xstrdup(host_arg);
536 debug2("checking match for '%s' host %s originally %s",
537 cp, host, original_host);
538 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
541 if ((negate = attrib[0] == '!'))
543 /* criteria "all" and "canonical" have no argument */
544 if (strcasecmp(attrib, "all") == 0) {
545 if (attributes > 1 ||
546 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
547 error("%.200s line %d: '%s' cannot be combined "
548 "with other Match attributes",
549 filename, linenum, oattrib);
554 result = negate ? 0 : 1;
558 if (strcasecmp(attrib, "canonical") == 0) {
559 r = !!post_canon; /* force bitmask member to boolean */
560 if (r == (negate ? 1 : 0))
561 this_result = result = 0;
562 debug3("%.200s line %d: %smatched '%s'",
564 this_result ? "" : "not ", oattrib);
567 /* All other criteria require an argument */
568 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
569 error("Missing Match criteria for %s", attrib);
573 if (strcasecmp(attrib, "host") == 0) {
574 criteria = xstrdup(host);
575 r = match_hostname(host, arg) == 1;
576 if (r == (negate ? 1 : 0))
577 this_result = result = 0;
578 } else if (strcasecmp(attrib, "originalhost") == 0) {
579 criteria = xstrdup(original_host);
580 r = match_hostname(original_host, arg) == 1;
581 if (r == (negate ? 1 : 0))
582 this_result = result = 0;
583 } else if (strcasecmp(attrib, "user") == 0) {
584 criteria = xstrdup(ruser);
585 r = match_pattern_list(ruser, arg, 0) == 1;
586 if (r == (negate ? 1 : 0))
587 this_result = result = 0;
588 } else if (strcasecmp(attrib, "localuser") == 0) {
589 criteria = xstrdup(pw->pw_name);
590 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
591 if (r == (negate ? 1 : 0))
592 this_result = result = 0;
593 } else if (strcasecmp(attrib, "exec") == 0) {
594 if (gethostname(thishost, sizeof(thishost)) == -1)
595 fatal("gethostname: %s", strerror(errno));
596 strlcpy(shorthost, thishost, sizeof(shorthost));
597 shorthost[strcspn(thishost, ".")] = '\0';
598 snprintf(portstr, sizeof(portstr), "%d", port);
600 cmd = percent_expand(arg,
611 /* skip execution if prior predicate failed */
612 debug3("%.200s line %d: skipped exec "
613 "\"%.100s\"", filename, linenum, cmd);
617 r = execute_in_shell(cmd);
619 fatal("%.200s line %d: match exec "
620 "'%.100s' error", filename,
623 criteria = xstrdup(cmd);
625 /* Force exit status to boolean */
627 if (r == (negate ? 1 : 0))
628 this_result = result = 0;
630 error("Unsupported Match attribute %s", attrib);
634 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
635 filename, linenum, this_result ? "": "not ",
639 if (attributes == 0) {
640 error("One or more attributes required for Match");
646 debug2("match %sfound", result ? "" : "not ");
652 /* Check and prepare a domain name: removes trailing '.' and lowercases */
654 valid_domain(char *name, const char *filename, int linenum)
656 size_t i, l = strlen(name);
657 u_char c, last = '\0';
660 fatal("%s line %d: empty hostname suffix", filename, linenum);
661 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
662 fatal("%s line %d: hostname suffix \"%.100s\" "
663 "starts with invalid character", filename, linenum, name);
664 for (i = 0; i < l; i++) {
665 c = tolower((u_char)name[i]);
667 if (last == '.' && c == '.')
668 fatal("%s line %d: hostname suffix \"%.100s\" contains "
669 "consecutive separators", filename, linenum, name);
670 if (c != '.' && c != '-' && !isalnum(c) &&
671 c != '_') /* technically invalid, but common */
672 fatal("%s line %d: hostname suffix \"%.100s\" contains "
673 "invalid characters", filename, linenum, name);
676 if (name[l - 1] == '.')
681 * Returns the number of the token pointed to by cp or oBadOption.
684 parse_token(const char *cp, const char *filename, int linenum,
685 const char *ignored_unknown)
689 for (i = 0; keywords[i].name; i++)
690 if (strcmp(cp, keywords[i].name) == 0)
691 return keywords[i].opcode;
692 if (ignored_unknown != NULL &&
693 match_pattern_list(cp, ignored_unknown, 1) == 1)
694 return oIgnoredUnknownOption;
695 error("%s: line %d: Bad configuration option: %s",
696 filename, linenum, cp);
700 /* Multistate option parsing */
705 static const struct multistate multistate_flag[] = {
712 static const struct multistate multistate_yesnoask[] = {
720 static const struct multistate multistate_addressfamily[] = {
722 { "inet6", AF_INET6 },
723 { "any", AF_UNSPEC },
726 static const struct multistate multistate_controlmaster[] = {
727 { "true", SSHCTL_MASTER_YES },
728 { "yes", SSHCTL_MASTER_YES },
729 { "false", SSHCTL_MASTER_NO },
730 { "no", SSHCTL_MASTER_NO },
731 { "auto", SSHCTL_MASTER_AUTO },
732 { "ask", SSHCTL_MASTER_ASK },
733 { "autoask", SSHCTL_MASTER_AUTO_ASK },
736 static const struct multistate multistate_tunnel[] = {
737 { "ethernet", SSH_TUNMODE_ETHERNET },
738 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
739 { "true", SSH_TUNMODE_DEFAULT },
740 { "yes", SSH_TUNMODE_DEFAULT },
741 { "false", SSH_TUNMODE_NO },
742 { "no", SSH_TUNMODE_NO },
745 static const struct multistate multistate_requesttty[] = {
746 { "true", REQUEST_TTY_YES },
747 { "yes", REQUEST_TTY_YES },
748 { "false", REQUEST_TTY_NO },
749 { "no", REQUEST_TTY_NO },
750 { "force", REQUEST_TTY_FORCE },
751 { "auto", REQUEST_TTY_AUTO },
754 static const struct multistate multistate_canonicalizehostname[] = {
755 { "true", SSH_CANONICALISE_YES },
756 { "false", SSH_CANONICALISE_NO },
757 { "yes", SSH_CANONICALISE_YES },
758 { "no", SSH_CANONICALISE_NO },
759 { "always", SSH_CANONICALISE_ALWAYS },
764 * Processes a single option line as used in the configuration files. This
765 * only sets those values that have not already been set.
767 #define WHITESPACE " \t\r\n"
769 process_config_line(Options *options, struct passwd *pw, const char *host,
770 const char *original_host, char *line, const char *filename,
771 int linenum, int *activep, int flags)
773 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
774 char **cpptr, fwdarg[256];
775 u_int i, *uintptr, max_entries = 0;
776 int negated, opcode, *intptr, value, value2, cmdline = 0;
777 LogLevel *log_level_ptr;
781 const struct multistate *multistate_ptr;
782 struct allowed_cname *cname;
784 if (activep == NULL) { /* We are processing a command line directive */
789 /* Strip trailing whitespace */
790 if ((len = strlen(line)) == 0)
792 for (len--; len > 0; len--) {
793 if (strchr(WHITESPACE, line[len]) == NULL)
799 /* Get the keyword. (Each line is supposed to begin with a keyword). */
800 if ((keyword = strdelim(&s)) == NULL)
802 /* Ignore leading whitespace. */
803 if (*keyword == '\0')
804 keyword = strdelim(&s);
805 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
807 /* Match lowercase keyword */
810 opcode = parse_token(keyword, filename, linenum,
811 options->ignored_unknown);
815 /* don't panic, but count bad options */
818 case oIgnoredUnknownOption:
819 debug("%s line %d: Ignored unknown option \"%s\"",
820 filename, linenum, keyword);
822 case oConnectTimeout:
823 intptr = &options->connection_timeout;
826 if (!arg || *arg == '\0')
827 fatal("%s line %d: missing time value.",
829 if (strcmp(arg, "none") == 0)
831 else if ((value = convtime(arg)) == -1)
832 fatal("%s line %d: invalid time value.",
834 if (*activep && *intptr == -1)
839 intptr = &options->forward_agent;
841 multistate_ptr = multistate_flag;
844 if (!arg || *arg == '\0')
845 fatal("%s line %d: missing argument.",
848 for (i = 0; multistate_ptr[i].key != NULL; i++) {
849 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
850 value = multistate_ptr[i].value;
855 fatal("%s line %d: unsupported option \"%s\".",
856 filename, linenum, arg);
857 if (*activep && *intptr == -1)
862 intptr = &options->forward_x11;
865 case oForwardX11Trusted:
866 intptr = &options->forward_x11_trusted;
869 case oForwardX11Timeout:
870 intptr = &options->forward_x11_timeout;
874 intptr = &options->fwd_opts.gateway_ports;
877 case oExitOnForwardFailure:
878 intptr = &options->exit_on_forward_failure;
881 case oUsePrivilegedPort:
882 intptr = &options->use_privileged_port;
885 case oPasswordAuthentication:
886 intptr = &options->password_authentication;
889 case oKbdInteractiveAuthentication:
890 intptr = &options->kbd_interactive_authentication;
893 case oKbdInteractiveDevices:
894 charptr = &options->kbd_interactive_devices;
897 case oPubkeyAuthentication:
898 intptr = &options->pubkey_authentication;
901 case oRSAAuthentication:
902 intptr = &options->rsa_authentication;
905 case oRhostsRSAAuthentication:
906 intptr = &options->rhosts_rsa_authentication;
909 case oHostbasedAuthentication:
910 intptr = &options->hostbased_authentication;
913 case oChallengeResponseAuthentication:
914 intptr = &options->challenge_response_authentication;
917 case oGssAuthentication:
918 intptr = &options->gss_authentication;
921 case oGssDelegateCreds:
922 intptr = &options->gss_deleg_creds;
926 intptr = &options->batch_mode;
930 intptr = &options->check_host_ip;
933 case oVerifyHostKeyDNS:
934 intptr = &options->verify_host_key_dns;
935 multistate_ptr = multistate_yesnoask;
936 goto parse_multistate;
938 case oStrictHostKeyChecking:
939 intptr = &options->strict_host_key_checking;
940 multistate_ptr = multistate_yesnoask;
941 goto parse_multistate;
944 intptr = &options->compression;
948 intptr = &options->tcp_keep_alive;
951 case oNoHostAuthenticationForLocalhost:
952 intptr = &options->no_host_authentication_for_localhost;
955 case oNumberOfPasswordPrompts:
956 intptr = &options->number_of_password_prompts;
959 case oCompressionLevel:
960 intptr = &options->compression_level;
965 if (!arg || *arg == '\0')
966 fatal("%.200s line %d: Missing argument.", filename,
968 if (strcmp(arg, "default") == 0) {
971 if (scan_scaled(arg, &val64) == -1)
972 fatal("%.200s line %d: Bad number '%s': %s",
973 filename, linenum, arg, strerror(errno));
974 /* check for too-large or too-small limits */
975 if (val64 > UINT_MAX)
976 fatal("%.200s line %d: RekeyLimit too large",
978 if (val64 != 0 && val64 < 16)
979 fatal("%.200s line %d: RekeyLimit too small",
982 if (*activep && options->rekey_limit == -1)
983 options->rekey_limit = (u_int32_t)val64;
984 if (s != NULL) { /* optional rekey interval present */
985 if (strcmp(s, "none") == 0) {
986 (void)strdelim(&s); /* discard */
989 intptr = &options->rekey_interval;
996 if (!arg || *arg == '\0')
997 fatal("%.200s line %d: Missing argument.", filename, linenum);
999 intptr = &options->num_identity_files;
1000 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1001 fatal("%.200s line %d: Too many identity files specified (max %d).",
1002 filename, linenum, SSH_MAX_IDENTITY_FILES);
1003 add_identity_file(options, NULL,
1004 arg, flags & SSHCONF_USERCONF);
1008 case oXAuthLocation:
1009 charptr=&options->xauth_location;
1013 charptr = &options->user;
1016 if (!arg || *arg == '\0')
1017 fatal("%.200s line %d: Missing argument.",
1019 if (*activep && *charptr == NULL)
1020 *charptr = xstrdup(arg);
1023 case oGlobalKnownHostsFile:
1024 cpptr = (char **)&options->system_hostfiles;
1025 uintptr = &options->num_system_hostfiles;
1026 max_entries = SSH_MAX_HOSTS_FILES;
1028 if (*activep && *uintptr == 0) {
1029 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1030 if ((*uintptr) >= max_entries)
1031 fatal("%s line %d: "
1032 "too many authorized keys files.",
1034 cpptr[(*uintptr)++] = xstrdup(arg);
1039 case oUserKnownHostsFile:
1040 cpptr = (char **)&options->user_hostfiles;
1041 uintptr = &options->num_user_hostfiles;
1042 max_entries = SSH_MAX_HOSTS_FILES;
1043 goto parse_char_array;
1046 charptr = &options->hostname;
1050 charptr = &options->host_key_alias;
1053 case oPreferredAuthentications:
1054 charptr = &options->preferred_authentications;
1058 charptr = &options->bind_address;
1061 case oPKCS11Provider:
1062 charptr = &options->pkcs11_provider;
1066 charptr = &options->proxy_command;
1069 fatal("%.200s line %d: Missing argument.", filename, linenum);
1070 len = strspn(s, WHITESPACE "=");
1071 if (*activep && *charptr == NULL)
1072 *charptr = xstrdup(s + len);
1076 intptr = &options->port;
1079 if (!arg || *arg == '\0')
1080 fatal("%.200s line %d: Missing argument.", filename, linenum);
1081 if (arg[0] < '0' || arg[0] > '9')
1082 fatal("%.200s line %d: Bad number.", filename, linenum);
1084 /* Octal, decimal, or hex format? */
1085 value = strtol(arg, &endofnumber, 0);
1086 if (arg == endofnumber)
1087 fatal("%.200s line %d: Bad number.", filename, linenum);
1088 if (*activep && *intptr == -1)
1092 case oConnectionAttempts:
1093 intptr = &options->connection_attempts;
1097 intptr = &options->cipher;
1099 if (!arg || *arg == '\0')
1100 fatal("%.200s line %d: Missing argument.", filename, linenum);
1101 value = cipher_number(arg);
1103 fatal("%.200s line %d: Bad cipher '%s'.",
1104 filename, linenum, arg ? arg : "<NONE>");
1105 if (*activep && *intptr == -1)
1111 if (!arg || *arg == '\0')
1112 fatal("%.200s line %d: Missing argument.", filename, linenum);
1113 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1114 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1115 filename, linenum, arg ? arg : "<NONE>");
1116 if (*activep && options->ciphers == NULL)
1117 options->ciphers = xstrdup(arg);
1122 if (!arg || *arg == '\0')
1123 fatal("%.200s line %d: Missing argument.", filename, linenum);
1124 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1125 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1126 filename, linenum, arg ? arg : "<NONE>");
1127 if (*activep && options->macs == NULL)
1128 options->macs = xstrdup(arg);
1131 case oKexAlgorithms:
1133 if (!arg || *arg == '\0')
1134 fatal("%.200s line %d: Missing argument.",
1136 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1137 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1138 filename, linenum, arg ? arg : "<NONE>");
1139 if (*activep && options->kex_algorithms == NULL)
1140 options->kex_algorithms = xstrdup(arg);
1143 case oHostKeyAlgorithms:
1144 charptr = &options->hostkeyalgorithms;
1147 if (!arg || *arg == '\0')
1148 fatal("%.200s line %d: Missing argument.",
1150 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1151 fatal("%s line %d: Bad key types '%s'.",
1152 filename, linenum, arg ? arg : "<NONE>");
1153 if (*activep && *charptr == NULL)
1154 *charptr = xstrdup(arg);
1158 intptr = &options->protocol;
1160 if (!arg || *arg == '\0')
1161 fatal("%.200s line %d: Missing argument.", filename, linenum);
1162 value = proto_spec(arg);
1163 if (value == SSH_PROTO_UNKNOWN)
1164 fatal("%.200s line %d: Bad protocol spec '%s'.",
1165 filename, linenum, arg ? arg : "<NONE>");
1166 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1171 log_level_ptr = &options->log_level;
1173 value = log_level_number(arg);
1174 if (value == SYSLOG_LEVEL_NOT_SET)
1175 fatal("%.200s line %d: unsupported log level '%s'",
1176 filename, linenum, arg ? arg : "<NONE>");
1177 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1178 *log_level_ptr = (LogLevel) value;
1182 case oRemoteForward:
1183 case oDynamicForward:
1185 if (arg == NULL || *arg == '\0')
1186 fatal("%.200s line %d: Missing port argument.",
1189 if (opcode == oLocalForward ||
1190 opcode == oRemoteForward) {
1191 arg2 = strdelim(&s);
1192 if (arg2 == NULL || *arg2 == '\0')
1193 fatal("%.200s line %d: Missing target argument.",
1196 /* construct a string for parse_forward */
1197 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1198 } else if (opcode == oDynamicForward) {
1199 strlcpy(fwdarg, arg, sizeof(fwdarg));
1202 if (parse_forward(&fwd, fwdarg,
1203 opcode == oDynamicForward ? 1 : 0,
1204 opcode == oRemoteForward ? 1 : 0) == 0)
1205 fatal("%.200s line %d: Bad forwarding specification.",
1209 if (opcode == oLocalForward ||
1210 opcode == oDynamicForward)
1211 add_local_forward(options, &fwd);
1212 else if (opcode == oRemoteForward)
1213 add_remote_forward(options, &fwd);
1217 case oClearAllForwardings:
1218 intptr = &options->clear_forwardings;
1223 fatal("Host directive not supported as a command-line "
1227 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1228 negated = *arg == '!';
1231 if (match_pattern(host, arg)) {
1233 debug("%.200s line %d: Skipping Host "
1234 "block because of negated match "
1235 "for %.100s", filename, linenum,
1241 arg2 = arg; /* logged below */
1246 debug("%.200s line %d: Applying options for %.100s",
1247 filename, linenum, arg2);
1248 /* Avoid garbage check below, as strdelim is done. */
1253 fatal("Host directive not supported as a command-line "
1255 value = match_cfg_line(options, &s, pw, host, original_host,
1256 flags & SSHCONF_POSTCANON, filename, linenum);
1258 fatal("%.200s line %d: Bad Match condition", filename,
1264 intptr = &options->escape_char;
1266 if (!arg || *arg == '\0')
1267 fatal("%.200s line %d: Missing argument.", filename, linenum);
1268 if (strcmp(arg, "none") == 0)
1269 value = SSH_ESCAPECHAR_NONE;
1270 else if (arg[1] == '\0')
1271 value = (u_char) arg[0];
1272 else if (arg[0] == '^' && arg[2] == 0 &&
1273 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1274 value = (u_char) arg[1] & 31;
1276 fatal("%.200s line %d: Bad escape character.",
1279 value = 0; /* Avoid compiler warning. */
1281 if (*activep && *intptr == -1)
1285 case oAddressFamily:
1286 intptr = &options->address_family;
1287 multistate_ptr = multistate_addressfamily;
1288 goto parse_multistate;
1290 case oEnableSSHKeysign:
1291 intptr = &options->enable_ssh_keysign;
1294 case oIdentitiesOnly:
1295 intptr = &options->identities_only;
1298 case oServerAliveInterval:
1299 intptr = &options->server_alive_interval;
1302 case oServerAliveCountMax:
1303 intptr = &options->server_alive_count_max;
1307 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1308 if (strchr(arg, '=') != NULL)
1309 fatal("%s line %d: Invalid environment name.",
1313 if (options->num_send_env >= MAX_SEND_ENV)
1314 fatal("%s line %d: too many send env.",
1316 options->send_env[options->num_send_env++] =
1322 charptr = &options->control_path;
1325 case oControlMaster:
1326 intptr = &options->control_master;
1327 multistate_ptr = multistate_controlmaster;
1328 goto parse_multistate;
1330 case oControlPersist:
1331 /* no/false/yes/true, or a time spec */
1332 intptr = &options->control_persist;
1334 if (!arg || *arg == '\0')
1335 fatal("%.200s line %d: Missing ControlPersist"
1336 " argument.", filename, linenum);
1338 value2 = 0; /* timeout */
1339 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1341 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1343 else if ((value2 = convtime(arg)) >= 0)
1346 fatal("%.200s line %d: Bad ControlPersist argument.",
1348 if (*activep && *intptr == -1) {
1350 options->control_persist_timeout = value2;
1354 case oHashKnownHosts:
1355 intptr = &options->hash_known_hosts;
1359 intptr = &options->tun_open;
1360 multistate_ptr = multistate_tunnel;
1361 goto parse_multistate;
1365 if (!arg || *arg == '\0')
1366 fatal("%.200s line %d: Missing argument.", filename, linenum);
1367 value = a2tun(arg, &value2);
1368 if (value == SSH_TUNID_ERR)
1369 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1371 options->tun_local = value;
1372 options->tun_remote = value2;
1377 charptr = &options->local_command;
1380 case oPermitLocalCommand:
1381 intptr = &options->permit_local_command;
1384 case oVisualHostKey:
1385 intptr = &options->visual_host_key;
1390 if ((value = parse_ipqos(arg)) == -1)
1391 fatal("%s line %d: Bad IPQoS value: %s",
1392 filename, linenum, arg);
1396 else if ((value2 = parse_ipqos(arg)) == -1)
1397 fatal("%s line %d: Bad IPQoS value: %s",
1398 filename, linenum, arg);
1400 options->ip_qos_interactive = value;
1401 options->ip_qos_bulk = value2;
1406 intptr = &options->use_roaming;
1410 intptr = &options->request_tty;
1411 multistate_ptr = multistate_requesttty;
1412 goto parse_multistate;
1414 case oVersionAddendum:
1416 fatal("%.200s line %d: Missing argument.", filename,
1418 len = strspn(s, WHITESPACE);
1419 if (*activep && options->version_addendum == NULL) {
1420 if (strcasecmp(s + len, "none") == 0)
1421 options->version_addendum = xstrdup("");
1422 else if (strchr(s + len, '\r') != NULL)
1423 fatal("%.200s line %d: Invalid argument",
1426 options->version_addendum = xstrdup(s + len);
1430 case oIgnoreUnknown:
1431 charptr = &options->ignored_unknown;
1434 case oProxyUseFdpass:
1435 intptr = &options->proxy_use_fdpass;
1438 case oCanonicalDomains:
1439 value = options->num_canonical_domains != 0;
1440 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1441 valid_domain(arg, filename, linenum);
1442 if (!*activep || value)
1444 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1445 fatal("%s line %d: too many hostname suffixes.",
1447 options->canonical_domains[
1448 options->num_canonical_domains++] = xstrdup(arg);
1452 case oCanonicalizePermittedCNAMEs:
1453 value = options->num_permitted_cnames != 0;
1454 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1455 /* Either '*' for everything or 'list:list' */
1456 if (strcmp(arg, "*") == 0)
1460 if ((arg2 = strchr(arg, ':')) == NULL ||
1462 fatal("%s line %d: "
1463 "Invalid permitted CNAME \"%s\"",
1464 filename, linenum, arg);
1469 if (!*activep || value)
1471 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1472 fatal("%s line %d: too many permitted CNAMEs.",
1474 cname = options->permitted_cnames +
1475 options->num_permitted_cnames++;
1476 cname->source_list = xstrdup(arg);
1477 cname->target_list = xstrdup(arg2);
1481 case oCanonicalizeHostname:
1482 intptr = &options->canonicalize_hostname;
1483 multistate_ptr = multistate_canonicalizehostname;
1484 goto parse_multistate;
1486 case oCanonicalizeMaxDots:
1487 intptr = &options->canonicalize_max_dots;
1490 case oCanonicalizeFallbackLocal:
1491 intptr = &options->canonicalize_fallback_local;
1494 case oStreamLocalBindMask:
1496 if (!arg || *arg == '\0')
1497 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1498 /* Parse mode in octal format */
1499 value = strtol(arg, &endofnumber, 8);
1500 if (arg == endofnumber || value < 0 || value > 0777)
1501 fatal("%.200s line %d: Bad mask.", filename, linenum);
1502 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1505 case oStreamLocalBindUnlink:
1506 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1509 case oRevokedHostKeys:
1510 charptr = &options->revoked_host_keys;
1513 case oFingerprintHash:
1514 intptr = &options->fingerprint_hash;
1516 if (!arg || *arg == '\0')
1517 fatal("%.200s line %d: Missing argument.",
1519 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1520 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1521 filename, linenum, arg);
1522 if (*activep && *intptr == -1)
1526 case oUpdateHostkeys:
1527 intptr = &options->update_hostkeys;
1528 multistate_ptr = multistate_yesnoask;
1529 goto parse_multistate;
1531 case oHostbasedKeyTypes:
1532 charptr = &options->hostbased_key_types;
1533 goto parse_keytypes;
1535 case oPubkeyAcceptedKeyTypes:
1536 charptr = &options->pubkey_key_types;
1537 goto parse_keytypes;
1540 debug("%s line %d: Deprecated option \"%s\"",
1541 filename, linenum, keyword);
1545 error("%s line %d: Unsupported option \"%s\"",
1546 filename, linenum, keyword);
1550 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1553 /* Check that there is no garbage at end of line. */
1554 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1555 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1556 filename, linenum, arg);
1563 * Reads the config file and modifies the options accordingly. Options
1564 * should already be initialized before this call. This never returns if
1565 * there is an error. If the file does not exist, this returns 0.
1569 read_config_file(const char *filename, struct passwd *pw, const char *host,
1570 const char *original_host, Options *options, int flags)
1574 int active, linenum;
1575 int bad_options = 0;
1577 if ((f = fopen(filename, "r")) == NULL)
1580 if (flags & SSHCONF_CHECKPERM) {
1583 if (fstat(fileno(f), &sb) == -1)
1584 fatal("fstat %s: %s", filename, strerror(errno));
1585 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1586 (sb.st_mode & 022) != 0))
1587 fatal("Bad owner or permissions on %s", filename);
1590 debug("Reading configuration data %.200s", filename);
1593 * Mark that we are now processing the options. This flag is turned
1594 * on/off by Host specifications.
1598 while (fgets(line, sizeof(line), f)) {
1599 /* Update line number counter. */
1601 if (process_config_line(options, pw, host, original_host,
1602 line, filename, linenum, &active, flags) != 0)
1606 if (bad_options > 0)
1607 fatal("%s: terminating, %d bad configuration options",
1608 filename, bad_options);
1612 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1614 option_clear_or_none(const char *o)
1616 return o == NULL || strcasecmp(o, "none") == 0;
1620 * Initializes options to special values that indicate that they have not yet
1621 * been set. Read_config_file will only set options with this value. Options
1622 * are processed in the following order: command line, user config file,
1623 * system config file. Last, fill_default_options is called.
1627 initialize_options(Options * options)
1629 memset(options, 'X', sizeof(*options));
1630 options->version_addendum = NULL;
1631 options->forward_agent = -1;
1632 options->forward_x11 = -1;
1633 options->forward_x11_trusted = -1;
1634 options->forward_x11_timeout = -1;
1635 options->exit_on_forward_failure = -1;
1636 options->xauth_location = NULL;
1637 options->fwd_opts.gateway_ports = -1;
1638 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1639 options->fwd_opts.streamlocal_bind_unlink = -1;
1640 options->use_privileged_port = -1;
1641 options->rsa_authentication = -1;
1642 options->pubkey_authentication = -1;
1643 options->challenge_response_authentication = -1;
1644 options->gss_authentication = -1;
1645 options->gss_deleg_creds = -1;
1646 options->password_authentication = -1;
1647 options->kbd_interactive_authentication = -1;
1648 options->kbd_interactive_devices = NULL;
1649 options->rhosts_rsa_authentication = -1;
1650 options->hostbased_authentication = -1;
1651 options->batch_mode = -1;
1652 options->check_host_ip = -1;
1653 options->strict_host_key_checking = -1;
1654 options->compression = -1;
1655 options->tcp_keep_alive = -1;
1656 options->compression_level = -1;
1658 options->address_family = -1;
1659 options->connection_attempts = -1;
1660 options->connection_timeout = -1;
1661 options->number_of_password_prompts = -1;
1662 options->cipher = -1;
1663 options->ciphers = NULL;
1664 options->macs = NULL;
1665 options->kex_algorithms = NULL;
1666 options->hostkeyalgorithms = NULL;
1667 options->protocol = SSH_PROTO_UNKNOWN;
1668 options->num_identity_files = 0;
1669 options->hostname = NULL;
1670 options->host_key_alias = NULL;
1671 options->proxy_command = NULL;
1672 options->user = NULL;
1673 options->escape_char = -1;
1674 options->num_system_hostfiles = 0;
1675 options->num_user_hostfiles = 0;
1676 options->local_forwards = NULL;
1677 options->num_local_forwards = 0;
1678 options->remote_forwards = NULL;
1679 options->num_remote_forwards = 0;
1680 options->clear_forwardings = -1;
1681 options->log_level = SYSLOG_LEVEL_NOT_SET;
1682 options->preferred_authentications = NULL;
1683 options->bind_address = NULL;
1684 options->pkcs11_provider = NULL;
1685 options->enable_ssh_keysign = - 1;
1686 options->no_host_authentication_for_localhost = - 1;
1687 options->identities_only = - 1;
1688 options->rekey_limit = - 1;
1689 options->rekey_interval = -1;
1690 options->verify_host_key_dns = -1;
1691 options->server_alive_interval = -1;
1692 options->server_alive_count_max = -1;
1693 options->num_send_env = 0;
1694 options->control_path = NULL;
1695 options->control_master = -1;
1696 options->control_persist = -1;
1697 options->control_persist_timeout = 0;
1698 options->hash_known_hosts = -1;
1699 options->tun_open = -1;
1700 options->tun_local = -1;
1701 options->tun_remote = -1;
1702 options->local_command = NULL;
1703 options->permit_local_command = -1;
1704 options->use_roaming = 0;
1705 options->visual_host_key = -1;
1706 options->ip_qos_interactive = -1;
1707 options->ip_qos_bulk = -1;
1708 options->request_tty = -1;
1709 options->proxy_use_fdpass = -1;
1710 options->ignored_unknown = NULL;
1711 options->num_canonical_domains = 0;
1712 options->num_permitted_cnames = 0;
1713 options->canonicalize_max_dots = -1;
1714 options->canonicalize_fallback_local = -1;
1715 options->canonicalize_hostname = -1;
1716 options->revoked_host_keys = NULL;
1717 options->fingerprint_hash = -1;
1718 options->update_hostkeys = -1;
1719 options->hostbased_key_types = NULL;
1720 options->pubkey_key_types = NULL;
1724 * A petite version of fill_default_options() that just fills the options
1725 * needed for hostname canonicalization to proceed.
1728 fill_default_options_for_canonicalization(Options *options)
1730 if (options->canonicalize_max_dots == -1)
1731 options->canonicalize_max_dots = 1;
1732 if (options->canonicalize_fallback_local == -1)
1733 options->canonicalize_fallback_local = 1;
1734 if (options->canonicalize_hostname == -1)
1735 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1739 * Called after processing other sources of option data, this fills those
1740 * options for which no value has been specified with their default values.
1743 fill_default_options(Options * options)
1745 if (options->forward_agent == -1)
1746 options->forward_agent = 0;
1747 if (options->forward_x11 == -1)
1748 options->forward_x11 = 0;
1749 if (options->forward_x11_trusted == -1)
1750 options->forward_x11_trusted = 0;
1751 if (options->forward_x11_timeout == -1)
1752 options->forward_x11_timeout = 1200;
1753 if (options->exit_on_forward_failure == -1)
1754 options->exit_on_forward_failure = 0;
1755 if (options->xauth_location == NULL)
1756 options->xauth_location = _PATH_XAUTH;
1757 if (options->fwd_opts.gateway_ports == -1)
1758 options->fwd_opts.gateway_ports = 0;
1759 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1760 options->fwd_opts.streamlocal_bind_mask = 0177;
1761 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1762 options->fwd_opts.streamlocal_bind_unlink = 0;
1763 if (options->use_privileged_port == -1)
1764 options->use_privileged_port = 0;
1765 if (options->rsa_authentication == -1)
1766 options->rsa_authentication = 1;
1767 if (options->pubkey_authentication == -1)
1768 options->pubkey_authentication = 1;
1769 if (options->challenge_response_authentication == -1)
1770 options->challenge_response_authentication = 1;
1771 if (options->gss_authentication == -1)
1772 options->gss_authentication = 0;
1773 if (options->gss_deleg_creds == -1)
1774 options->gss_deleg_creds = 0;
1775 if (options->password_authentication == -1)
1776 options->password_authentication = 1;
1777 if (options->kbd_interactive_authentication == -1)
1778 options->kbd_interactive_authentication = 1;
1779 if (options->rhosts_rsa_authentication == -1)
1780 options->rhosts_rsa_authentication = 0;
1781 if (options->hostbased_authentication == -1)
1782 options->hostbased_authentication = 0;
1783 if (options->batch_mode == -1)
1784 options->batch_mode = 0;
1785 if (options->check_host_ip == -1)
1786 options->check_host_ip = 0;
1787 if (options->strict_host_key_checking == -1)
1788 options->strict_host_key_checking = 2; /* 2 is default */
1789 if (options->compression == -1)
1790 options->compression = 0;
1791 if (options->tcp_keep_alive == -1)
1792 options->tcp_keep_alive = 1;
1793 if (options->compression_level == -1)
1794 options->compression_level = 6;
1795 if (options->port == -1)
1796 options->port = 0; /* Filled in ssh_connect. */
1797 if (options->address_family == -1)
1798 options->address_family = AF_UNSPEC;
1799 if (options->connection_attempts == -1)
1800 options->connection_attempts = 1;
1801 if (options->number_of_password_prompts == -1)
1802 options->number_of_password_prompts = 3;
1803 /* Selected in ssh_login(). */
1804 if (options->cipher == -1)
1805 options->cipher = SSH_CIPHER_NOT_SET;
1806 /* options->hostkeyalgorithms, default set in myproposals.h */
1807 if (options->protocol == SSH_PROTO_UNKNOWN)
1808 options->protocol = SSH_PROTO_2;
1809 if (options->num_identity_files == 0) {
1810 if (options->protocol & SSH_PROTO_1) {
1811 add_identity_file(options, "~/",
1812 _PATH_SSH_CLIENT_IDENTITY, 0);
1814 if (options->protocol & SSH_PROTO_2) {
1815 add_identity_file(options, "~/",
1816 _PATH_SSH_CLIENT_ID_RSA, 0);
1817 add_identity_file(options, "~/",
1818 _PATH_SSH_CLIENT_ID_DSA, 0);
1819 #ifdef OPENSSL_HAS_ECC
1820 add_identity_file(options, "~/",
1821 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1823 add_identity_file(options, "~/",
1824 _PATH_SSH_CLIENT_ID_ED25519, 0);
1827 if (options->escape_char == -1)
1828 options->escape_char = '~';
1829 if (options->num_system_hostfiles == 0) {
1830 options->system_hostfiles[options->num_system_hostfiles++] =
1831 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1832 options->system_hostfiles[options->num_system_hostfiles++] =
1833 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1835 if (options->num_user_hostfiles == 0) {
1836 options->user_hostfiles[options->num_user_hostfiles++] =
1837 xstrdup(_PATH_SSH_USER_HOSTFILE);
1838 options->user_hostfiles[options->num_user_hostfiles++] =
1839 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1841 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1842 options->log_level = SYSLOG_LEVEL_INFO;
1843 if (options->clear_forwardings == 1)
1844 clear_forwardings(options);
1845 if (options->no_host_authentication_for_localhost == - 1)
1846 options->no_host_authentication_for_localhost = 0;
1847 if (options->identities_only == -1)
1848 options->identities_only = 0;
1849 if (options->enable_ssh_keysign == -1)
1850 options->enable_ssh_keysign = 0;
1851 if (options->rekey_limit == -1)
1852 options->rekey_limit = 0;
1853 if (options->rekey_interval == -1)
1854 options->rekey_interval = 0;
1856 if (options->verify_host_key_dns == -1)
1857 /* automatically trust a verified SSHFP record */
1858 options->verify_host_key_dns = 1;
1860 if (options->verify_host_key_dns == -1)
1861 options->verify_host_key_dns = 0;
1863 if (options->server_alive_interval == -1)
1864 options->server_alive_interval = 0;
1865 if (options->server_alive_count_max == -1)
1866 options->server_alive_count_max = 3;
1867 if (options->control_master == -1)
1868 options->control_master = 0;
1869 if (options->control_persist == -1) {
1870 options->control_persist = 0;
1871 options->control_persist_timeout = 0;
1873 if (options->hash_known_hosts == -1)
1874 options->hash_known_hosts = 0;
1875 if (options->tun_open == -1)
1876 options->tun_open = SSH_TUNMODE_NO;
1877 if (options->tun_local == -1)
1878 options->tun_local = SSH_TUNID_ANY;
1879 if (options->tun_remote == -1)
1880 options->tun_remote = SSH_TUNID_ANY;
1881 if (options->permit_local_command == -1)
1882 options->permit_local_command = 0;
1883 options->use_roaming = 0;
1884 if (options->visual_host_key == -1)
1885 options->visual_host_key = 0;
1886 if (options->ip_qos_interactive == -1)
1887 options->ip_qos_interactive = IPTOS_LOWDELAY;
1888 if (options->ip_qos_bulk == -1)
1889 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1890 if (options->request_tty == -1)
1891 options->request_tty = REQUEST_TTY_AUTO;
1892 if (options->proxy_use_fdpass == -1)
1893 options->proxy_use_fdpass = 0;
1894 if (options->canonicalize_max_dots == -1)
1895 options->canonicalize_max_dots = 1;
1896 if (options->canonicalize_fallback_local == -1)
1897 options->canonicalize_fallback_local = 1;
1898 if (options->canonicalize_hostname == -1)
1899 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1900 if (options->fingerprint_hash == -1)
1901 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1902 if (options->update_hostkeys == -1)
1903 options->update_hostkeys = 0;
1904 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
1905 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
1906 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
1907 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1908 &options->hostbased_key_types) != 0 ||
1909 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1910 &options->pubkey_key_types) != 0)
1911 fatal("%s: kex_assemble_names failed", __func__);
1913 #define CLEAR_ON_NONE(v) \
1915 if (option_clear_or_none(v)) { \
1920 CLEAR_ON_NONE(options->local_command);
1921 CLEAR_ON_NONE(options->proxy_command);
1922 CLEAR_ON_NONE(options->control_path);
1923 CLEAR_ON_NONE(options->revoked_host_keys);
1924 /* options->user will be set in the main program if appropriate */
1925 /* options->hostname will be set in the main program if appropriate */
1926 /* options->host_key_alias should not be set by default */
1927 /* options->preferred_authentications will be set in ssh */
1928 if (options->version_addendum == NULL)
1929 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1939 * parses the next field in a port forwarding specification.
1940 * sets fwd to the parsed field and advances p past the colon
1941 * or sets it to NULL at end of string.
1942 * returns 0 on success, else non-zero.
1945 parse_fwd_field(char **p, struct fwdarg *fwd)
1952 return -1; /* end of string */
1956 * A field escaped with square brackets is used literally.
1957 * XXX - allow ']' to be escaped via backslash?
1960 /* find matching ']' */
1961 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1965 /* no matching ']' or not at end of field. */
1966 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1968 /* NUL terminate the field and advance p past the colon */
1973 fwd->ispath = ispath;
1978 for (cp = *p; *cp != '\0'; cp++) {
1981 memmove(cp, cp + 1, strlen(cp + 1) + 1);
1995 fwd->ispath = ispath;
2002 * parses a string containing a port forwarding specification of the form:
2004 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2005 * listenpath:connectpath
2007 * [listenhost:]listenport
2008 * returns number of arguments parsed or zero on error
2011 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2013 struct fwdarg fwdargs[4];
2017 memset(fwd, 0, sizeof(*fwd));
2018 memset(fwdargs, 0, sizeof(fwdargs));
2020 cp = p = xstrdup(fwdspec);
2022 /* skip leading spaces */
2023 while (isspace((u_char)*cp))
2026 for (i = 0; i < 4; ++i) {
2027 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2031 /* Check for trailing garbage */
2032 if (cp != NULL && *cp != '\0') {
2033 i = 0; /* failure */
2038 if (fwdargs[0].ispath) {
2039 fwd->listen_path = xstrdup(fwdargs[0].arg);
2040 fwd->listen_port = PORT_STREAMLOCAL;
2042 fwd->listen_host = NULL;
2043 fwd->listen_port = a2port(fwdargs[0].arg);
2045 fwd->connect_host = xstrdup("socks");
2049 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2050 fwd->listen_path = xstrdup(fwdargs[0].arg);
2051 fwd->listen_port = PORT_STREAMLOCAL;
2052 fwd->connect_path = xstrdup(fwdargs[1].arg);
2053 fwd->connect_port = PORT_STREAMLOCAL;
2054 } else if (fwdargs[1].ispath) {
2055 fwd->listen_host = NULL;
2056 fwd->listen_port = a2port(fwdargs[0].arg);
2057 fwd->connect_path = xstrdup(fwdargs[1].arg);
2058 fwd->connect_port = PORT_STREAMLOCAL;
2060 fwd->listen_host = xstrdup(fwdargs[0].arg);
2061 fwd->listen_port = a2port(fwdargs[1].arg);
2062 fwd->connect_host = xstrdup("socks");
2067 if (fwdargs[0].ispath) {
2068 fwd->listen_path = xstrdup(fwdargs[0].arg);
2069 fwd->listen_port = PORT_STREAMLOCAL;
2070 fwd->connect_host = xstrdup(fwdargs[1].arg);
2071 fwd->connect_port = a2port(fwdargs[2].arg);
2072 } else if (fwdargs[2].ispath) {
2073 fwd->listen_host = xstrdup(fwdargs[0].arg);
2074 fwd->listen_port = a2port(fwdargs[1].arg);
2075 fwd->connect_path = xstrdup(fwdargs[2].arg);
2076 fwd->connect_port = PORT_STREAMLOCAL;
2078 fwd->listen_host = NULL;
2079 fwd->listen_port = a2port(fwdargs[0].arg);
2080 fwd->connect_host = xstrdup(fwdargs[1].arg);
2081 fwd->connect_port = a2port(fwdargs[2].arg);
2086 fwd->listen_host = xstrdup(fwdargs[0].arg);
2087 fwd->listen_port = a2port(fwdargs[1].arg);
2088 fwd->connect_host = xstrdup(fwdargs[2].arg);
2089 fwd->connect_port = a2port(fwdargs[3].arg);
2092 i = 0; /* failure */
2098 if (!(i == 1 || i == 2))
2101 if (!(i == 3 || i == 4)) {
2102 if (fwd->connect_path == NULL &&
2103 fwd->listen_path == NULL)
2106 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2110 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2111 (!remotefwd && fwd->listen_port == 0))
2113 if (fwd->connect_host != NULL &&
2114 strlen(fwd->connect_host) >= NI_MAXHOST)
2116 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2117 if (fwd->connect_path != NULL &&
2118 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2120 if (fwd->listen_host != NULL &&
2121 strlen(fwd->listen_host) >= NI_MAXHOST)
2123 if (fwd->listen_path != NULL &&
2124 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2130 free(fwd->connect_host);
2131 fwd->connect_host = NULL;
2132 free(fwd->connect_path);
2133 fwd->connect_path = NULL;
2134 free(fwd->listen_host);
2135 fwd->listen_host = NULL;
2136 free(fwd->listen_path);
2137 fwd->listen_path = NULL;
2141 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2143 fmt_multistate_int(int val, const struct multistate *m)
2147 for (i = 0; m[i].key != NULL; i++) {
2148 if (m[i].value == val)
2155 fmt_intarg(OpCodes code, int val)
2160 case oAddressFamily:
2161 return fmt_multistate_int(val, multistate_addressfamily);
2162 case oVerifyHostKeyDNS:
2163 case oStrictHostKeyChecking:
2164 case oUpdateHostkeys:
2165 return fmt_multistate_int(val, multistate_yesnoask);
2166 case oControlMaster:
2167 return fmt_multistate_int(val, multistate_controlmaster);
2169 return fmt_multistate_int(val, multistate_tunnel);
2171 return fmt_multistate_int(val, multistate_requesttty);
2172 case oCanonicalizeHostname:
2173 return fmt_multistate_int(val, multistate_canonicalizehostname);
2174 case oFingerprintHash:
2175 return ssh_digest_alg_name(val);
2182 case (SSH_PROTO_1|SSH_PROTO_2):
2200 lookup_opcode_name(OpCodes code)
2204 for (i = 0; keywords[i].name != NULL; i++)
2205 if (keywords[i].opcode == code)
2206 return(keywords[i].name);
2211 dump_cfg_int(OpCodes code, int val)
2213 printf("%s %d\n", lookup_opcode_name(code), val);
2217 dump_cfg_fmtint(OpCodes code, int val)
2219 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2223 dump_cfg_string(OpCodes code, const char *val)
2227 printf("%s %s\n", lookup_opcode_name(code), val);
2231 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2235 for (i = 0; i < count; i++)
2236 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2240 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2244 printf("%s", lookup_opcode_name(code));
2245 for (i = 0; i < count; i++)
2246 printf(" %s", vals[i]);
2251 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2253 const struct Forward *fwd;
2256 /* oDynamicForward */
2257 for (i = 0; i < count; i++) {
2259 if (code == oDynamicForward &&
2260 strcmp(fwd->connect_host, "socks") != 0)
2262 if (code == oLocalForward &&
2263 strcmp(fwd->connect_host, "socks") == 0)
2265 printf("%s", lookup_opcode_name(code));
2266 if (fwd->listen_port == PORT_STREAMLOCAL)
2267 printf(" %s", fwd->listen_path);
2268 else if (fwd->listen_host == NULL)
2269 printf(" %d", fwd->listen_port);
2272 fwd->listen_host, fwd->listen_port);
2274 if (code != oDynamicForward) {
2275 if (fwd->connect_port == PORT_STREAMLOCAL)
2276 printf(" %s", fwd->connect_path);
2277 else if (fwd->connect_host == NULL)
2278 printf(" %d", fwd->connect_port);
2281 fwd->connect_host, fwd->connect_port);
2289 dump_client_config(Options *o, const char *host)
2294 /* Most interesting options first: user, host, port */
2295 dump_cfg_string(oUser, o->user);
2296 dump_cfg_string(oHostName, host);
2297 dump_cfg_int(oPort, o->port);
2300 dump_cfg_fmtint(oAddressFamily, o->address_family);
2301 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2302 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2303 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2304 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2305 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2306 dump_cfg_fmtint(oCompression, o->compression);
2307 dump_cfg_fmtint(oControlMaster, o->control_master);
2308 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2309 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2310 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2311 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2312 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2313 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2314 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2316 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2317 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2319 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2320 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2321 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2322 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2323 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2324 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2325 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2326 dump_cfg_fmtint(oProtocol, o->protocol);
2327 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2328 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2329 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2330 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2331 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2332 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2333 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2334 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2335 dump_cfg_fmtint(oTunnel, o->tun_open);
2336 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2337 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2338 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2339 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2341 /* Integer options */
2342 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2343 dump_cfg_int(oCompressionLevel, o->compression_level);
2344 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2345 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2346 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2347 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2348 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2350 /* String options */
2351 dump_cfg_string(oBindAddress, o->bind_address);
2352 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2353 dump_cfg_string(oControlPath, o->control_path);
2354 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
2355 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2356 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2357 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2358 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2359 dump_cfg_string(oLocalCommand, o->local_command);
2360 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2361 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2362 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2363 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2364 dump_cfg_string(oProxyCommand, o->proxy_command);
2365 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2366 dump_cfg_string(oXAuthLocation, o->xauth_location);
2369 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2370 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2371 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2373 /* String array options */
2374 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2375 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2376 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2377 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2378 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2382 /* oConnectTimeout */
2383 if (o->connection_timeout == -1)
2384 printf("connecttimeout none\n");
2386 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2389 printf("tunneldevice");
2390 if (o->tun_local == SSH_TUNID_ANY)
2393 printf(" %d", o->tun_local);
2394 if (o->tun_remote == SSH_TUNID_ANY)
2397 printf(":%d", o->tun_remote);
2400 /* oCanonicalizePermittedCNAMEs */
2401 if ( o->num_permitted_cnames > 0) {
2402 printf("canonicalizePermittedcnames");
2403 for (i = 0; i < o->num_permitted_cnames; i++) {
2404 printf(" %s:%s", o->permitted_cnames[i].source_list,
2405 o->permitted_cnames[i].target_list);
2411 if (o->cipher != SSH_CIPHER_NOT_SET)
2412 printf("Cipher %s\n", cipher_name(o->cipher));
2414 /* oControlPersist */
2415 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2416 dump_cfg_fmtint(oControlPersist, o->control_persist);
2418 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2421 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2422 printf("escapechar none\n");
2424 vis(vbuf, o->escape_char, VIS_WHITE, 0);
2425 printf("escapechar %s\n", vbuf);
2429 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2430 printf("%s\n", iptos2str(o->ip_qos_bulk));
2433 printf("rekeylimit %lld %d\n",
2434 (long long)o->rekey_limit, o->rekey_interval);
2436 /* oStreamLocalBindMask */
2437 printf("streamlocalbindmask 0%o\n",
2438 o->fwd_opts.streamlocal_bind_mask);