1 /* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 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 oCertificateFile, oAddKeysToAgent,
143 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
144 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
145 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
146 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
147 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
148 oPubkeyAuthentication,
149 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
150 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
151 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
152 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
153 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
154 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
155 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
156 oSendEnv, oControlPath, oControlMaster, oControlPersist,
158 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
160 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
161 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
162 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
163 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
164 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
165 oPubkeyAcceptedKeyTypes,
166 oIgnoredUnknownOption, oDeprecated, oUnsupported
169 /* Textual representations of the tokens. */
175 { "forwardagent", oForwardAgent },
176 { "forwardx11", oForwardX11 },
177 { "forwardx11trusted", oForwardX11Trusted },
178 { "forwardx11timeout", oForwardX11Timeout },
179 { "exitonforwardfailure", oExitOnForwardFailure },
180 { "xauthlocation", oXAuthLocation },
181 { "gatewayports", oGatewayPorts },
182 { "useprivilegedport", oUsePrivilegedPort },
183 { "rhostsauthentication", oDeprecated },
184 { "passwordauthentication", oPasswordAuthentication },
185 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
186 { "kbdinteractivedevices", oKbdInteractiveDevices },
187 { "rsaauthentication", oRSAAuthentication },
188 { "pubkeyauthentication", oPubkeyAuthentication },
189 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
190 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
191 { "hostbasedauthentication", oHostbasedAuthentication },
192 { "challengeresponseauthentication", oChallengeResponseAuthentication },
193 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
194 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
195 { "kerberosauthentication", oUnsupported },
196 { "kerberostgtpassing", oUnsupported },
197 { "afstokenpassing", oUnsupported },
199 { "gssapiauthentication", oGssAuthentication },
200 { "gssapidelegatecredentials", oGssDelegateCreds },
202 { "gssapiauthentication", oUnsupported },
203 { "gssapidelegatecredentials", oUnsupported },
205 { "fallbacktorsh", oDeprecated },
206 { "usersh", oDeprecated },
207 { "identityfile", oIdentityFile },
208 { "identityfile2", oIdentityFile }, /* obsolete */
209 { "identitiesonly", oIdentitiesOnly },
210 { "certificatefile", oCertificateFile },
211 { "addkeystoagent", oAddKeysToAgent },
212 { "hostname", oHostName },
213 { "hostkeyalias", oHostKeyAlias },
214 { "proxycommand", oProxyCommand },
216 { "cipher", oCipher },
217 { "ciphers", oCiphers },
219 { "protocol", oProtocol },
220 { "remoteforward", oRemoteForward },
221 { "localforward", oLocalForward },
225 { "escapechar", oEscapeChar },
226 { "globalknownhostsfile", oGlobalKnownHostsFile },
227 { "globalknownhostsfile2", oDeprecated },
228 { "userknownhostsfile", oUserKnownHostsFile },
229 { "userknownhostsfile2", oDeprecated },
230 { "connectionattempts", oConnectionAttempts },
231 { "batchmode", oBatchMode },
232 { "checkhostip", oCheckHostIP },
233 { "stricthostkeychecking", oStrictHostKeyChecking },
234 { "compression", oCompression },
235 { "compressionlevel", oCompressionLevel },
236 { "tcpkeepalive", oTCPKeepAlive },
237 { "keepalive", oTCPKeepAlive }, /* obsolete */
238 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
239 { "loglevel", oLogLevel },
240 { "dynamicforward", oDynamicForward },
241 { "preferredauthentications", oPreferredAuthentications },
242 { "hostkeyalgorithms", oHostKeyAlgorithms },
243 { "bindaddress", oBindAddress },
245 { "smartcarddevice", oPKCS11Provider },
246 { "pkcs11provider", oPKCS11Provider },
248 { "smartcarddevice", oUnsupported },
249 { "pkcs11provider", oUnsupported },
251 { "clearallforwardings", oClearAllForwardings },
252 { "enablesshkeysign", oEnableSSHKeysign },
253 { "verifyhostkeydns", oVerifyHostKeyDNS },
254 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
255 { "rekeylimit", oRekeyLimit },
256 { "connecttimeout", oConnectTimeout },
257 { "addressfamily", oAddressFamily },
258 { "serveraliveinterval", oServerAliveInterval },
259 { "serveralivecountmax", oServerAliveCountMax },
260 { "sendenv", oSendEnv },
261 { "controlpath", oControlPath },
262 { "controlmaster", oControlMaster },
263 { "controlpersist", oControlPersist },
264 { "hashknownhosts", oHashKnownHosts },
265 { "tunnel", oTunnel },
266 { "tunneldevice", oTunnelDevice },
267 { "localcommand", oLocalCommand },
268 { "permitlocalcommand", oPermitLocalCommand },
269 { "visualhostkey", oVisualHostKey },
270 { "useroaming", oDeprecated },
271 { "kexalgorithms", oKexAlgorithms },
273 { "requesttty", oRequestTTY },
274 { "proxyusefdpass", oProxyUseFdpass },
275 { "canonicaldomains", oCanonicalDomains },
276 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
277 { "canonicalizehostname", oCanonicalizeHostname },
278 { "canonicalizemaxdots", oCanonicalizeMaxDots },
279 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
280 { "streamlocalbindmask", oStreamLocalBindMask },
281 { "streamlocalbindunlink", oStreamLocalBindUnlink },
282 { "revokedhostkeys", oRevokedHostKeys },
283 { "fingerprinthash", oFingerprintHash },
284 { "updatehostkeys", oUpdateHostkeys },
285 { "hostbasedkeytypes", oHostbasedKeyTypes },
286 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
287 { "ignoreunknown", oIgnoreUnknown },
288 { "hpndisabled", oDeprecated },
289 { "hpnbuffersize", oDeprecated },
290 { "tcprcvbufpoll", oDeprecated },
291 { "tcprcvbuf", oDeprecated },
292 { "noneenabled", oUnsupported },
293 { "noneswitch", oUnsupported },
294 { "versionaddendum", oVersionAddendum },
300 * Adds a local TCP/IP port forward to options. Never returns if there is an
305 add_local_forward(Options *options, const struct Forward *newfwd)
308 #ifndef NO_IPPORT_RESERVED_CONCEPT
309 extern uid_t original_real_uid;
312 size_t len_ipport_reserved = sizeof(ipport_reserved);
314 if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
315 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
316 ipport_reserved = IPPORT_RESERVED;
320 ipport_reserved = IPPORT_RESERVED;
322 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0)
323 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0 &&
324 newfwd->listen_path == NULL)
325 fatal("Privileged ports can only be forwarded by root.");
327 options->local_forwards = xreallocarray(options->local_forwards,
328 options->num_local_forwards + 1,
329 sizeof(*options->local_forwards));
330 fwd = &options->local_forwards[options->num_local_forwards++];
332 fwd->listen_host = newfwd->listen_host;
333 fwd->listen_port = newfwd->listen_port;
334 fwd->listen_path = newfwd->listen_path;
335 fwd->connect_host = newfwd->connect_host;
336 fwd->connect_port = newfwd->connect_port;
337 fwd->connect_path = newfwd->connect_path;
341 * Adds a remote TCP/IP port forward to options. Never returns if there is
346 add_remote_forward(Options *options, const struct Forward *newfwd)
350 options->remote_forwards = xreallocarray(options->remote_forwards,
351 options->num_remote_forwards + 1,
352 sizeof(*options->remote_forwards));
353 fwd = &options->remote_forwards[options->num_remote_forwards++];
355 fwd->listen_host = newfwd->listen_host;
356 fwd->listen_port = newfwd->listen_port;
357 fwd->listen_path = newfwd->listen_path;
358 fwd->connect_host = newfwd->connect_host;
359 fwd->connect_port = newfwd->connect_port;
360 fwd->connect_path = newfwd->connect_path;
361 fwd->handle = newfwd->handle;
362 fwd->allocated_port = 0;
366 clear_forwardings(Options *options)
370 for (i = 0; i < options->num_local_forwards; i++) {
371 free(options->local_forwards[i].listen_host);
372 free(options->local_forwards[i].listen_path);
373 free(options->local_forwards[i].connect_host);
374 free(options->local_forwards[i].connect_path);
376 if (options->num_local_forwards > 0) {
377 free(options->local_forwards);
378 options->local_forwards = NULL;
380 options->num_local_forwards = 0;
381 for (i = 0; i < options->num_remote_forwards; i++) {
382 free(options->remote_forwards[i].listen_host);
383 free(options->remote_forwards[i].listen_path);
384 free(options->remote_forwards[i].connect_host);
385 free(options->remote_forwards[i].connect_path);
387 if (options->num_remote_forwards > 0) {
388 free(options->remote_forwards);
389 options->remote_forwards = NULL;
391 options->num_remote_forwards = 0;
392 options->tun_open = SSH_TUNMODE_NO;
396 add_certificate_file(Options *options, const char *path, int userprovided)
400 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
401 fatal("Too many certificate files specified (max %d)",
402 SSH_MAX_CERTIFICATE_FILES);
404 /* Avoid registering duplicates */
405 for (i = 0; i < options->num_certificate_files; i++) {
406 if (options->certificate_file_userprovided[i] == userprovided &&
407 strcmp(options->certificate_files[i], path) == 0) {
408 debug2("%s: ignoring duplicate key %s", __func__, path);
413 options->certificate_file_userprovided[options->num_certificate_files] =
415 options->certificate_files[options->num_certificate_files++] =
420 add_identity_file(Options *options, const char *dir, const char *filename,
426 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
427 fatal("Too many identity files specified (max %d)",
428 SSH_MAX_IDENTITY_FILES);
430 if (dir == NULL) /* no dir, filename is absolute */
431 path = xstrdup(filename);
433 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
435 /* Avoid registering duplicates */
436 for (i = 0; i < options->num_identity_files; i++) {
437 if (options->identity_file_userprovided[i] == userprovided &&
438 strcmp(options->identity_files[i], path) == 0) {
439 debug2("%s: ignoring duplicate key %s", __func__, path);
445 options->identity_file_userprovided[options->num_identity_files] =
447 options->identity_files[options->num_identity_files++] = path;
451 default_ssh_port(void)
457 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
458 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
464 * Execute a command in a shell.
465 * Return its exit status or -1 on abnormal exit.
468 execute_in_shell(const char *cmd)
473 extern uid_t original_real_uid;
475 if ((shell = getenv("SHELL")) == NULL)
476 shell = _PATH_BSHELL;
478 /* Need this to redirect subprocess stdin/out */
479 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
480 fatal("open(/dev/null): %s", strerror(errno));
482 debug("Executing command: '%.500s'", cmd);
484 /* Fork and execute the command. */
485 if ((pid = fork()) == 0) {
488 /* Child. Permanently give up superuser privileges. */
489 permanently_drop_suid(original_real_uid);
491 /* Redirect child stdin and stdout. Leave stderr */
492 if (dup2(devnull, STDIN_FILENO) == -1)
493 fatal("dup2: %s", strerror(errno));
494 if (dup2(devnull, STDOUT_FILENO) == -1)
495 fatal("dup2: %s", strerror(errno));
496 if (devnull > STDERR_FILENO)
498 closefrom(STDERR_FILENO + 1);
502 argv[2] = xstrdup(cmd);
505 execv(argv[0], argv);
506 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
507 /* Die with signal to make this error apparent to parent. */
508 signal(SIGTERM, SIG_DFL);
509 kill(getpid(), SIGTERM);
514 fatal("%s: fork: %.100s", __func__, strerror(errno));
518 while (waitpid(pid, &status, 0) == -1) {
519 if (errno != EINTR && errno != EAGAIN)
520 fatal("%s: waitpid: %s", __func__, strerror(errno));
522 if (!WIFEXITED(status)) {
523 error("command '%.100s' exited abnormally", cmd);
526 debug3("command returned status %d", WEXITSTATUS(status));
527 return WEXITSTATUS(status);
531 * Parse and execute a Match directive.
534 match_cfg_line(Options *options, char **condition, struct passwd *pw,
535 const char *host_arg, const char *original_host, int post_canon,
536 const char *filename, int linenum)
538 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
540 int r, port, this_result, result = 1, attributes = 0, negate;
541 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
544 * Configuration is likely to be incomplete at this point so we
545 * must be prepared to use default values.
547 port = options->port <= 0 ? default_ssh_port() : options->port;
548 ruser = options->user == NULL ? pw->pw_name : options->user;
550 host = xstrdup(options->hostname);
551 } else if (options->hostname != NULL) {
552 /* NB. Please keep in sync with ssh.c:main() */
553 host = percent_expand(options->hostname,
554 "h", host_arg, (char *)NULL);
556 host = xstrdup(host_arg);
559 debug2("checking match for '%s' host %s originally %s",
560 cp, host, original_host);
561 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
564 if ((negate = attrib[0] == '!'))
566 /* criteria "all" and "canonical" have no argument */
567 if (strcasecmp(attrib, "all") == 0) {
568 if (attributes > 1 ||
569 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
570 error("%.200s line %d: '%s' cannot be combined "
571 "with other Match attributes",
572 filename, linenum, oattrib);
577 result = negate ? 0 : 1;
581 if (strcasecmp(attrib, "canonical") == 0) {
582 r = !!post_canon; /* force bitmask member to boolean */
583 if (r == (negate ? 1 : 0))
584 this_result = result = 0;
585 debug3("%.200s line %d: %smatched '%s'",
587 this_result ? "" : "not ", oattrib);
590 /* All other criteria require an argument */
591 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
592 error("Missing Match criteria for %s", attrib);
596 if (strcasecmp(attrib, "host") == 0) {
597 criteria = xstrdup(host);
598 r = match_hostname(host, arg) == 1;
599 if (r == (negate ? 1 : 0))
600 this_result = result = 0;
601 } else if (strcasecmp(attrib, "originalhost") == 0) {
602 criteria = xstrdup(original_host);
603 r = match_hostname(original_host, arg) == 1;
604 if (r == (negate ? 1 : 0))
605 this_result = result = 0;
606 } else if (strcasecmp(attrib, "user") == 0) {
607 criteria = xstrdup(ruser);
608 r = match_pattern_list(ruser, arg, 0) == 1;
609 if (r == (negate ? 1 : 0))
610 this_result = result = 0;
611 } else if (strcasecmp(attrib, "localuser") == 0) {
612 criteria = xstrdup(pw->pw_name);
613 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
614 if (r == (negate ? 1 : 0))
615 this_result = result = 0;
616 } else if (strcasecmp(attrib, "exec") == 0) {
617 if (gethostname(thishost, sizeof(thishost)) == -1)
618 fatal("gethostname: %s", strerror(errno));
619 strlcpy(shorthost, thishost, sizeof(shorthost));
620 shorthost[strcspn(thishost, ".")] = '\0';
621 snprintf(portstr, sizeof(portstr), "%d", port);
623 cmd = percent_expand(arg,
634 /* skip execution if prior predicate failed */
635 debug3("%.200s line %d: skipped exec "
636 "\"%.100s\"", filename, linenum, cmd);
640 r = execute_in_shell(cmd);
642 fatal("%.200s line %d: match exec "
643 "'%.100s' error", filename,
646 criteria = xstrdup(cmd);
648 /* Force exit status to boolean */
650 if (r == (negate ? 1 : 0))
651 this_result = result = 0;
653 error("Unsupported Match attribute %s", attrib);
657 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
658 filename, linenum, this_result ? "": "not ",
662 if (attributes == 0) {
663 error("One or more attributes required for Match");
669 debug2("match %sfound", result ? "" : "not ");
675 /* Check and prepare a domain name: removes trailing '.' and lowercases */
677 valid_domain(char *name, const char *filename, int linenum)
679 size_t i, l = strlen(name);
680 u_char c, last = '\0';
683 fatal("%s line %d: empty hostname suffix", filename, linenum);
684 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
685 fatal("%s line %d: hostname suffix \"%.100s\" "
686 "starts with invalid character", filename, linenum, name);
687 for (i = 0; i < l; i++) {
688 c = tolower((u_char)name[i]);
690 if (last == '.' && c == '.')
691 fatal("%s line %d: hostname suffix \"%.100s\" contains "
692 "consecutive separators", filename, linenum, name);
693 if (c != '.' && c != '-' && !isalnum(c) &&
694 c != '_') /* technically invalid, but common */
695 fatal("%s line %d: hostname suffix \"%.100s\" contains "
696 "invalid characters", filename, linenum, name);
699 if (name[l - 1] == '.')
704 * Returns the number of the token pointed to by cp or oBadOption.
707 parse_token(const char *cp, const char *filename, int linenum,
708 const char *ignored_unknown)
712 for (i = 0; keywords[i].name; i++)
713 if (strcmp(cp, keywords[i].name) == 0)
714 return keywords[i].opcode;
715 if (ignored_unknown != NULL &&
716 match_pattern_list(cp, ignored_unknown, 1) == 1)
717 return oIgnoredUnknownOption;
718 error("%s: line %d: Bad configuration option: %s",
719 filename, linenum, cp);
723 /* Multistate option parsing */
728 static const struct multistate multistate_flag[] = {
735 static const struct multistate multistate_yesnoask[] = {
743 static const struct multistate multistate_yesnoaskconfirm[] = {
752 static const struct multistate multistate_addressfamily[] = {
754 { "inet6", AF_INET6 },
755 { "any", AF_UNSPEC },
758 static const struct multistate multistate_controlmaster[] = {
759 { "true", SSHCTL_MASTER_YES },
760 { "yes", SSHCTL_MASTER_YES },
761 { "false", SSHCTL_MASTER_NO },
762 { "no", SSHCTL_MASTER_NO },
763 { "auto", SSHCTL_MASTER_AUTO },
764 { "ask", SSHCTL_MASTER_ASK },
765 { "autoask", SSHCTL_MASTER_AUTO_ASK },
768 static const struct multistate multistate_tunnel[] = {
769 { "ethernet", SSH_TUNMODE_ETHERNET },
770 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
771 { "true", SSH_TUNMODE_DEFAULT },
772 { "yes", SSH_TUNMODE_DEFAULT },
773 { "false", SSH_TUNMODE_NO },
774 { "no", SSH_TUNMODE_NO },
777 static const struct multistate multistate_requesttty[] = {
778 { "true", REQUEST_TTY_YES },
779 { "yes", REQUEST_TTY_YES },
780 { "false", REQUEST_TTY_NO },
781 { "no", REQUEST_TTY_NO },
782 { "force", REQUEST_TTY_FORCE },
783 { "auto", REQUEST_TTY_AUTO },
786 static const struct multistate multistate_canonicalizehostname[] = {
787 { "true", SSH_CANONICALISE_YES },
788 { "false", SSH_CANONICALISE_NO },
789 { "yes", SSH_CANONICALISE_YES },
790 { "no", SSH_CANONICALISE_NO },
791 { "always", SSH_CANONICALISE_ALWAYS },
796 * Processes a single option line as used in the configuration files. This
797 * only sets those values that have not already been set.
799 #define WHITESPACE " \t\r\n"
801 process_config_line(Options *options, struct passwd *pw, const char *host,
802 const char *original_host, char *line, const char *filename,
803 int linenum, int *activep, int flags)
805 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
806 char **cpptr, fwdarg[256];
807 u_int i, *uintptr, max_entries = 0;
808 int negated, opcode, *intptr, value, value2, cmdline = 0;
809 LogLevel *log_level_ptr;
813 const struct multistate *multistate_ptr;
814 struct allowed_cname *cname;
816 if (activep == NULL) { /* We are processing a command line directive */
821 /* Strip trailing whitespace */
822 if ((len = strlen(line)) == 0)
824 for (len--; len > 0; len--) {
825 if (strchr(WHITESPACE, line[len]) == NULL)
831 /* Get the keyword. (Each line is supposed to begin with a keyword). */
832 if ((keyword = strdelim(&s)) == NULL)
834 /* Ignore leading whitespace. */
835 if (*keyword == '\0')
836 keyword = strdelim(&s);
837 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
839 /* Match lowercase keyword */
842 opcode = parse_token(keyword, filename, linenum,
843 options->ignored_unknown);
847 /* don't panic, but count bad options */
850 case oIgnoredUnknownOption:
851 debug("%s line %d: Ignored unknown option \"%s\"",
852 filename, linenum, keyword);
854 case oConnectTimeout:
855 intptr = &options->connection_timeout;
858 if (!arg || *arg == '\0')
859 fatal("%s line %d: missing time value.",
861 if (strcmp(arg, "none") == 0)
863 else if ((value = convtime(arg)) == -1)
864 fatal("%s line %d: invalid time value.",
866 if (*activep && *intptr == -1)
871 intptr = &options->forward_agent;
873 multistate_ptr = multistate_flag;
876 if (!arg || *arg == '\0')
877 fatal("%s line %d: missing argument.",
880 for (i = 0; multistate_ptr[i].key != NULL; i++) {
881 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
882 value = multistate_ptr[i].value;
887 fatal("%s line %d: unsupported option \"%s\".",
888 filename, linenum, arg);
889 if (*activep && *intptr == -1)
894 intptr = &options->forward_x11;
897 case oForwardX11Trusted:
898 intptr = &options->forward_x11_trusted;
901 case oForwardX11Timeout:
902 intptr = &options->forward_x11_timeout;
906 intptr = &options->fwd_opts.gateway_ports;
909 case oExitOnForwardFailure:
910 intptr = &options->exit_on_forward_failure;
913 case oUsePrivilegedPort:
914 intptr = &options->use_privileged_port;
917 case oPasswordAuthentication:
918 intptr = &options->password_authentication;
921 case oKbdInteractiveAuthentication:
922 intptr = &options->kbd_interactive_authentication;
925 case oKbdInteractiveDevices:
926 charptr = &options->kbd_interactive_devices;
929 case oPubkeyAuthentication:
930 intptr = &options->pubkey_authentication;
933 case oRSAAuthentication:
934 intptr = &options->rsa_authentication;
937 case oRhostsRSAAuthentication:
938 intptr = &options->rhosts_rsa_authentication;
941 case oHostbasedAuthentication:
942 intptr = &options->hostbased_authentication;
945 case oChallengeResponseAuthentication:
946 intptr = &options->challenge_response_authentication;
949 case oGssAuthentication:
950 intptr = &options->gss_authentication;
953 case oGssDelegateCreds:
954 intptr = &options->gss_deleg_creds;
958 intptr = &options->batch_mode;
962 intptr = &options->check_host_ip;
965 case oVerifyHostKeyDNS:
966 intptr = &options->verify_host_key_dns;
967 multistate_ptr = multistate_yesnoask;
968 goto parse_multistate;
970 case oStrictHostKeyChecking:
971 intptr = &options->strict_host_key_checking;
972 multistate_ptr = multistate_yesnoask;
973 goto parse_multistate;
976 intptr = &options->compression;
980 intptr = &options->tcp_keep_alive;
983 case oNoHostAuthenticationForLocalhost:
984 intptr = &options->no_host_authentication_for_localhost;
987 case oNumberOfPasswordPrompts:
988 intptr = &options->number_of_password_prompts;
991 case oCompressionLevel:
992 intptr = &options->compression_level;
997 if (!arg || *arg == '\0')
998 fatal("%.200s line %d: Missing argument.", filename,
1000 if (strcmp(arg, "default") == 0) {
1003 if (scan_scaled(arg, &val64) == -1)
1004 fatal("%.200s line %d: Bad number '%s': %s",
1005 filename, linenum, arg, strerror(errno));
1006 if (val64 != 0 && val64 < 16)
1007 fatal("%.200s line %d: RekeyLimit too small",
1010 if (*activep && options->rekey_limit == -1)
1011 options->rekey_limit = val64;
1012 if (s != NULL) { /* optional rekey interval present */
1013 if (strcmp(s, "none") == 0) {
1014 (void)strdelim(&s); /* discard */
1017 intptr = &options->rekey_interval;
1024 if (!arg || *arg == '\0')
1025 fatal("%.200s line %d: Missing argument.", filename, linenum);
1027 intptr = &options->num_identity_files;
1028 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1029 fatal("%.200s line %d: Too many identity files specified (max %d).",
1030 filename, linenum, SSH_MAX_IDENTITY_FILES);
1031 add_identity_file(options, NULL,
1032 arg, flags & SSHCONF_USERCONF);
1036 case oCertificateFile:
1038 if (!arg || *arg == '\0')
1039 fatal("%.200s line %d: Missing argument.",
1042 intptr = &options->num_certificate_files;
1043 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1044 fatal("%.200s line %d: Too many certificate "
1045 "files specified (max %d).",
1047 SSH_MAX_CERTIFICATE_FILES);
1049 add_certificate_file(options, arg,
1050 flags & SSHCONF_USERCONF);
1054 case oXAuthLocation:
1055 charptr=&options->xauth_location;
1059 charptr = &options->user;
1062 if (!arg || *arg == '\0')
1063 fatal("%.200s line %d: Missing argument.",
1065 if (*activep && *charptr == NULL)
1066 *charptr = xstrdup(arg);
1069 case oGlobalKnownHostsFile:
1070 cpptr = (char **)&options->system_hostfiles;
1071 uintptr = &options->num_system_hostfiles;
1072 max_entries = SSH_MAX_HOSTS_FILES;
1074 if (*activep && *uintptr == 0) {
1075 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1076 if ((*uintptr) >= max_entries)
1077 fatal("%s line %d: "
1078 "too many authorized keys files.",
1080 cpptr[(*uintptr)++] = xstrdup(arg);
1085 case oUserKnownHostsFile:
1086 cpptr = (char **)&options->user_hostfiles;
1087 uintptr = &options->num_user_hostfiles;
1088 max_entries = SSH_MAX_HOSTS_FILES;
1089 goto parse_char_array;
1092 charptr = &options->hostname;
1096 charptr = &options->host_key_alias;
1099 case oPreferredAuthentications:
1100 charptr = &options->preferred_authentications;
1104 charptr = &options->bind_address;
1107 case oPKCS11Provider:
1108 charptr = &options->pkcs11_provider;
1112 charptr = &options->proxy_command;
1115 fatal("%.200s line %d: Missing argument.", filename, linenum);
1116 len = strspn(s, WHITESPACE "=");
1117 if (*activep && *charptr == NULL)
1118 *charptr = xstrdup(s + len);
1122 intptr = &options->port;
1125 if (!arg || *arg == '\0')
1126 fatal("%.200s line %d: Missing argument.", filename, linenum);
1127 if (arg[0] < '0' || arg[0] > '9')
1128 fatal("%.200s line %d: Bad number.", filename, linenum);
1130 /* Octal, decimal, or hex format? */
1131 value = strtol(arg, &endofnumber, 0);
1132 if (arg == endofnumber)
1133 fatal("%.200s line %d: Bad number.", filename, linenum);
1134 if (*activep && *intptr == -1)
1138 case oConnectionAttempts:
1139 intptr = &options->connection_attempts;
1143 intptr = &options->cipher;
1145 if (!arg || *arg == '\0')
1146 fatal("%.200s line %d: Missing argument.", filename, linenum);
1147 value = cipher_number(arg);
1149 fatal("%.200s line %d: Bad cipher '%s'.",
1150 filename, linenum, arg ? arg : "<NONE>");
1151 if (*activep && *intptr == -1)
1157 if (!arg || *arg == '\0')
1158 fatal("%.200s line %d: Missing argument.", filename, linenum);
1159 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1160 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1161 filename, linenum, arg ? arg : "<NONE>");
1162 if (*activep && options->ciphers == NULL)
1163 options->ciphers = xstrdup(arg);
1168 if (!arg || *arg == '\0')
1169 fatal("%.200s line %d: Missing argument.", filename, linenum);
1170 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1171 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1172 filename, linenum, arg ? arg : "<NONE>");
1173 if (*activep && options->macs == NULL)
1174 options->macs = xstrdup(arg);
1177 case oKexAlgorithms:
1179 if (!arg || *arg == '\0')
1180 fatal("%.200s line %d: Missing argument.",
1182 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1183 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1184 filename, linenum, arg ? arg : "<NONE>");
1185 if (*activep && options->kex_algorithms == NULL)
1186 options->kex_algorithms = xstrdup(arg);
1189 case oHostKeyAlgorithms:
1190 charptr = &options->hostkeyalgorithms;
1193 if (!arg || *arg == '\0')
1194 fatal("%.200s line %d: Missing argument.",
1196 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1197 fatal("%s line %d: Bad key types '%s'.",
1198 filename, linenum, arg ? arg : "<NONE>");
1199 if (*activep && *charptr == NULL)
1200 *charptr = xstrdup(arg);
1204 intptr = &options->protocol;
1206 if (!arg || *arg == '\0')
1207 fatal("%.200s line %d: Missing argument.", filename, linenum);
1208 value = proto_spec(arg);
1209 if (value == SSH_PROTO_UNKNOWN)
1210 fatal("%.200s line %d: Bad protocol spec '%s'.",
1211 filename, linenum, arg ? arg : "<NONE>");
1212 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1217 log_level_ptr = &options->log_level;
1219 value = log_level_number(arg);
1220 if (value == SYSLOG_LEVEL_NOT_SET)
1221 fatal("%.200s line %d: unsupported log level '%s'",
1222 filename, linenum, arg ? arg : "<NONE>");
1223 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1224 *log_level_ptr = (LogLevel) value;
1228 case oRemoteForward:
1229 case oDynamicForward:
1231 if (arg == NULL || *arg == '\0')
1232 fatal("%.200s line %d: Missing port argument.",
1235 if (opcode == oLocalForward ||
1236 opcode == oRemoteForward) {
1237 arg2 = strdelim(&s);
1238 if (arg2 == NULL || *arg2 == '\0')
1239 fatal("%.200s line %d: Missing target argument.",
1242 /* construct a string for parse_forward */
1243 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1244 } else if (opcode == oDynamicForward) {
1245 strlcpy(fwdarg, arg, sizeof(fwdarg));
1248 if (parse_forward(&fwd, fwdarg,
1249 opcode == oDynamicForward ? 1 : 0,
1250 opcode == oRemoteForward ? 1 : 0) == 0)
1251 fatal("%.200s line %d: Bad forwarding specification.",
1255 if (opcode == oLocalForward ||
1256 opcode == oDynamicForward)
1257 add_local_forward(options, &fwd);
1258 else if (opcode == oRemoteForward)
1259 add_remote_forward(options, &fwd);
1263 case oClearAllForwardings:
1264 intptr = &options->clear_forwardings;
1269 fatal("Host directive not supported as a command-line "
1273 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1274 negated = *arg == '!';
1277 if (match_pattern(host, arg)) {
1279 debug("%.200s line %d: Skipping Host "
1280 "block because of negated match "
1281 "for %.100s", filename, linenum,
1287 arg2 = arg; /* logged below */
1292 debug("%.200s line %d: Applying options for %.100s",
1293 filename, linenum, arg2);
1294 /* Avoid garbage check below, as strdelim is done. */
1299 fatal("Host directive not supported as a command-line "
1301 value = match_cfg_line(options, &s, pw, host, original_host,
1302 flags & SSHCONF_POSTCANON, filename, linenum);
1304 fatal("%.200s line %d: Bad Match condition", filename,
1310 intptr = &options->escape_char;
1312 if (!arg || *arg == '\0')
1313 fatal("%.200s line %d: Missing argument.", filename, linenum);
1314 if (strcmp(arg, "none") == 0)
1315 value = SSH_ESCAPECHAR_NONE;
1316 else if (arg[1] == '\0')
1317 value = (u_char) arg[0];
1318 else if (arg[0] == '^' && arg[2] == 0 &&
1319 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1320 value = (u_char) arg[1] & 31;
1322 fatal("%.200s line %d: Bad escape character.",
1325 value = 0; /* Avoid compiler warning. */
1327 if (*activep && *intptr == -1)
1331 case oAddressFamily:
1332 intptr = &options->address_family;
1333 multistate_ptr = multistate_addressfamily;
1334 goto parse_multistate;
1336 case oEnableSSHKeysign:
1337 intptr = &options->enable_ssh_keysign;
1340 case oIdentitiesOnly:
1341 intptr = &options->identities_only;
1344 case oServerAliveInterval:
1345 intptr = &options->server_alive_interval;
1348 case oServerAliveCountMax:
1349 intptr = &options->server_alive_count_max;
1353 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1354 if (strchr(arg, '=') != NULL)
1355 fatal("%s line %d: Invalid environment name.",
1359 if (options->num_send_env >= MAX_SEND_ENV)
1360 fatal("%s line %d: too many send env.",
1362 options->send_env[options->num_send_env++] =
1368 charptr = &options->control_path;
1371 case oControlMaster:
1372 intptr = &options->control_master;
1373 multistate_ptr = multistate_controlmaster;
1374 goto parse_multistate;
1376 case oControlPersist:
1377 /* no/false/yes/true, or a time spec */
1378 intptr = &options->control_persist;
1380 if (!arg || *arg == '\0')
1381 fatal("%.200s line %d: Missing ControlPersist"
1382 " argument.", filename, linenum);
1384 value2 = 0; /* timeout */
1385 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1387 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1389 else if ((value2 = convtime(arg)) >= 0)
1392 fatal("%.200s line %d: Bad ControlPersist argument.",
1394 if (*activep && *intptr == -1) {
1396 options->control_persist_timeout = value2;
1400 case oHashKnownHosts:
1401 intptr = &options->hash_known_hosts;
1405 intptr = &options->tun_open;
1406 multistate_ptr = multistate_tunnel;
1407 goto parse_multistate;
1411 if (!arg || *arg == '\0')
1412 fatal("%.200s line %d: Missing argument.", filename, linenum);
1413 value = a2tun(arg, &value2);
1414 if (value == SSH_TUNID_ERR)
1415 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1417 options->tun_local = value;
1418 options->tun_remote = value2;
1423 charptr = &options->local_command;
1426 case oPermitLocalCommand:
1427 intptr = &options->permit_local_command;
1430 case oVisualHostKey:
1431 intptr = &options->visual_host_key;
1436 if ((value = parse_ipqos(arg)) == -1)
1437 fatal("%s line %d: Bad IPQoS value: %s",
1438 filename, linenum, arg);
1442 else if ((value2 = parse_ipqos(arg)) == -1)
1443 fatal("%s line %d: Bad IPQoS value: %s",
1444 filename, linenum, arg);
1446 options->ip_qos_interactive = value;
1447 options->ip_qos_bulk = value2;
1452 intptr = &options->request_tty;
1453 multistate_ptr = multistate_requesttty;
1454 goto parse_multistate;
1456 case oVersionAddendum:
1458 fatal("%.200s line %d: Missing argument.", filename,
1460 len = strspn(s, WHITESPACE);
1461 if (*activep && options->version_addendum == NULL) {
1462 if (strcasecmp(s + len, "none") == 0)
1463 options->version_addendum = xstrdup("");
1464 else if (strchr(s + len, '\r') != NULL)
1465 fatal("%.200s line %d: Invalid argument",
1468 options->version_addendum = xstrdup(s + len);
1472 case oIgnoreUnknown:
1473 charptr = &options->ignored_unknown;
1476 case oProxyUseFdpass:
1477 intptr = &options->proxy_use_fdpass;
1480 case oCanonicalDomains:
1481 value = options->num_canonical_domains != 0;
1482 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1483 valid_domain(arg, filename, linenum);
1484 if (!*activep || value)
1486 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1487 fatal("%s line %d: too many hostname suffixes.",
1489 options->canonical_domains[
1490 options->num_canonical_domains++] = xstrdup(arg);
1494 case oCanonicalizePermittedCNAMEs:
1495 value = options->num_permitted_cnames != 0;
1496 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1497 /* Either '*' for everything or 'list:list' */
1498 if (strcmp(arg, "*") == 0)
1502 if ((arg2 = strchr(arg, ':')) == NULL ||
1504 fatal("%s line %d: "
1505 "Invalid permitted CNAME \"%s\"",
1506 filename, linenum, arg);
1511 if (!*activep || value)
1513 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1514 fatal("%s line %d: too many permitted CNAMEs.",
1516 cname = options->permitted_cnames +
1517 options->num_permitted_cnames++;
1518 cname->source_list = xstrdup(arg);
1519 cname->target_list = xstrdup(arg2);
1523 case oCanonicalizeHostname:
1524 intptr = &options->canonicalize_hostname;
1525 multistate_ptr = multistate_canonicalizehostname;
1526 goto parse_multistate;
1528 case oCanonicalizeMaxDots:
1529 intptr = &options->canonicalize_max_dots;
1532 case oCanonicalizeFallbackLocal:
1533 intptr = &options->canonicalize_fallback_local;
1536 case oStreamLocalBindMask:
1538 if (!arg || *arg == '\0')
1539 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1540 /* Parse mode in octal format */
1541 value = strtol(arg, &endofnumber, 8);
1542 if (arg == endofnumber || value < 0 || value > 0777)
1543 fatal("%.200s line %d: Bad mask.", filename, linenum);
1544 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1547 case oStreamLocalBindUnlink:
1548 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1551 case oRevokedHostKeys:
1552 charptr = &options->revoked_host_keys;
1555 case oFingerprintHash:
1556 intptr = &options->fingerprint_hash;
1558 if (!arg || *arg == '\0')
1559 fatal("%.200s line %d: Missing argument.",
1561 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1562 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1563 filename, linenum, arg);
1564 if (*activep && *intptr == -1)
1568 case oUpdateHostkeys:
1569 intptr = &options->update_hostkeys;
1570 multistate_ptr = multistate_yesnoask;
1571 goto parse_multistate;
1573 case oHostbasedKeyTypes:
1574 charptr = &options->hostbased_key_types;
1575 goto parse_keytypes;
1577 case oPubkeyAcceptedKeyTypes:
1578 charptr = &options->pubkey_key_types;
1579 goto parse_keytypes;
1581 case oAddKeysToAgent:
1582 intptr = &options->add_keys_to_agent;
1583 multistate_ptr = multistate_yesnoaskconfirm;
1584 goto parse_multistate;
1587 debug("%s line %d: Deprecated option \"%s\"",
1588 filename, linenum, keyword);
1592 error("%s line %d: Unsupported option \"%s\"",
1593 filename, linenum, keyword);
1597 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1600 /* Check that there is no garbage at end of line. */
1601 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1602 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1603 filename, linenum, arg);
1610 * Reads the config file and modifies the options accordingly. Options
1611 * should already be initialized before this call. This never returns if
1612 * there is an error. If the file does not exist, this returns 0.
1616 read_config_file(const char *filename, struct passwd *pw, const char *host,
1617 const char *original_host, Options *options, int flags)
1621 int active, linenum;
1622 int bad_options = 0;
1624 if ((f = fopen(filename, "r")) == NULL)
1627 if (flags & SSHCONF_CHECKPERM) {
1630 if (fstat(fileno(f), &sb) == -1)
1631 fatal("fstat %s: %s", filename, strerror(errno));
1632 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1633 (sb.st_mode & 022) != 0))
1634 fatal("Bad owner or permissions on %s", filename);
1637 debug("Reading configuration data %.200s", filename);
1640 * Mark that we are now processing the options. This flag is turned
1641 * on/off by Host specifications.
1645 while (fgets(line, sizeof(line), f)) {
1646 /* Update line number counter. */
1648 if (process_config_line(options, pw, host, original_host,
1649 line, filename, linenum, &active, flags) != 0)
1653 if (bad_options > 0)
1654 fatal("%s: terminating, %d bad configuration options",
1655 filename, bad_options);
1659 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1661 option_clear_or_none(const char *o)
1663 return o == NULL || strcasecmp(o, "none") == 0;
1667 * Initializes options to special values that indicate that they have not yet
1668 * been set. Read_config_file will only set options with this value. Options
1669 * are processed in the following order: command line, user config file,
1670 * system config file. Last, fill_default_options is called.
1674 initialize_options(Options * options)
1676 memset(options, 'X', sizeof(*options));
1677 options->version_addendum = NULL;
1678 options->forward_agent = -1;
1679 options->forward_x11 = -1;
1680 options->forward_x11_trusted = -1;
1681 options->forward_x11_timeout = -1;
1682 options->exit_on_forward_failure = -1;
1683 options->xauth_location = NULL;
1684 options->fwd_opts.gateway_ports = -1;
1685 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1686 options->fwd_opts.streamlocal_bind_unlink = -1;
1687 options->use_privileged_port = -1;
1688 options->rsa_authentication = -1;
1689 options->pubkey_authentication = -1;
1690 options->challenge_response_authentication = -1;
1691 options->gss_authentication = -1;
1692 options->gss_deleg_creds = -1;
1693 options->password_authentication = -1;
1694 options->kbd_interactive_authentication = -1;
1695 options->kbd_interactive_devices = NULL;
1696 options->rhosts_rsa_authentication = -1;
1697 options->hostbased_authentication = -1;
1698 options->batch_mode = -1;
1699 options->check_host_ip = -1;
1700 options->strict_host_key_checking = -1;
1701 options->compression = -1;
1702 options->tcp_keep_alive = -1;
1703 options->compression_level = -1;
1705 options->address_family = -1;
1706 options->connection_attempts = -1;
1707 options->connection_timeout = -1;
1708 options->number_of_password_prompts = -1;
1709 options->cipher = -1;
1710 options->ciphers = NULL;
1711 options->macs = NULL;
1712 options->kex_algorithms = NULL;
1713 options->hostkeyalgorithms = NULL;
1714 options->protocol = SSH_PROTO_UNKNOWN;
1715 options->num_identity_files = 0;
1716 options->num_certificate_files = 0;
1717 options->hostname = NULL;
1718 options->host_key_alias = NULL;
1719 options->proxy_command = NULL;
1720 options->user = NULL;
1721 options->escape_char = -1;
1722 options->num_system_hostfiles = 0;
1723 options->num_user_hostfiles = 0;
1724 options->local_forwards = NULL;
1725 options->num_local_forwards = 0;
1726 options->remote_forwards = NULL;
1727 options->num_remote_forwards = 0;
1728 options->clear_forwardings = -1;
1729 options->log_level = SYSLOG_LEVEL_NOT_SET;
1730 options->preferred_authentications = NULL;
1731 options->bind_address = NULL;
1732 options->pkcs11_provider = NULL;
1733 options->enable_ssh_keysign = - 1;
1734 options->no_host_authentication_for_localhost = - 1;
1735 options->identities_only = - 1;
1736 options->rekey_limit = - 1;
1737 options->rekey_interval = -1;
1738 options->verify_host_key_dns = -1;
1739 options->server_alive_interval = -1;
1740 options->server_alive_count_max = -1;
1741 options->num_send_env = 0;
1742 options->control_path = NULL;
1743 options->control_master = -1;
1744 options->control_persist = -1;
1745 options->control_persist_timeout = 0;
1746 options->hash_known_hosts = -1;
1747 options->tun_open = -1;
1748 options->tun_local = -1;
1749 options->tun_remote = -1;
1750 options->local_command = NULL;
1751 options->permit_local_command = -1;
1752 options->add_keys_to_agent = -1;
1753 options->visual_host_key = -1;
1754 options->ip_qos_interactive = -1;
1755 options->ip_qos_bulk = -1;
1756 options->request_tty = -1;
1757 options->proxy_use_fdpass = -1;
1758 options->ignored_unknown = NULL;
1759 options->num_canonical_domains = 0;
1760 options->num_permitted_cnames = 0;
1761 options->canonicalize_max_dots = -1;
1762 options->canonicalize_fallback_local = -1;
1763 options->canonicalize_hostname = -1;
1764 options->revoked_host_keys = NULL;
1765 options->fingerprint_hash = -1;
1766 options->update_hostkeys = -1;
1767 options->hostbased_key_types = NULL;
1768 options->pubkey_key_types = NULL;
1772 * A petite version of fill_default_options() that just fills the options
1773 * needed for hostname canonicalization to proceed.
1776 fill_default_options_for_canonicalization(Options *options)
1778 if (options->canonicalize_max_dots == -1)
1779 options->canonicalize_max_dots = 1;
1780 if (options->canonicalize_fallback_local == -1)
1781 options->canonicalize_fallback_local = 1;
1782 if (options->canonicalize_hostname == -1)
1783 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1787 * Called after processing other sources of option data, this fills those
1788 * options for which no value has been specified with their default values.
1791 fill_default_options(Options * options)
1793 if (options->forward_agent == -1)
1794 options->forward_agent = 0;
1795 if (options->forward_x11 == -1)
1796 options->forward_x11 = 0;
1797 if (options->forward_x11_trusted == -1)
1798 options->forward_x11_trusted = 0;
1799 if (options->forward_x11_timeout == -1)
1800 options->forward_x11_timeout = 1200;
1801 if (options->exit_on_forward_failure == -1)
1802 options->exit_on_forward_failure = 0;
1803 if (options->xauth_location == NULL)
1804 options->xauth_location = _PATH_XAUTH;
1805 if (options->fwd_opts.gateway_ports == -1)
1806 options->fwd_opts.gateway_ports = 0;
1807 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1808 options->fwd_opts.streamlocal_bind_mask = 0177;
1809 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1810 options->fwd_opts.streamlocal_bind_unlink = 0;
1811 if (options->use_privileged_port == -1)
1812 options->use_privileged_port = 0;
1813 if (options->rsa_authentication == -1)
1814 options->rsa_authentication = 1;
1815 if (options->pubkey_authentication == -1)
1816 options->pubkey_authentication = 1;
1817 if (options->challenge_response_authentication == -1)
1818 options->challenge_response_authentication = 1;
1819 if (options->gss_authentication == -1)
1820 options->gss_authentication = 0;
1821 if (options->gss_deleg_creds == -1)
1822 options->gss_deleg_creds = 0;
1823 if (options->password_authentication == -1)
1824 options->password_authentication = 1;
1825 if (options->kbd_interactive_authentication == -1)
1826 options->kbd_interactive_authentication = 1;
1827 if (options->rhosts_rsa_authentication == -1)
1828 options->rhosts_rsa_authentication = 0;
1829 if (options->hostbased_authentication == -1)
1830 options->hostbased_authentication = 0;
1831 if (options->batch_mode == -1)
1832 options->batch_mode = 0;
1833 if (options->check_host_ip == -1)
1834 options->check_host_ip = 0;
1835 if (options->strict_host_key_checking == -1)
1836 options->strict_host_key_checking = 2; /* 2 is default */
1837 if (options->compression == -1)
1838 options->compression = 0;
1839 if (options->tcp_keep_alive == -1)
1840 options->tcp_keep_alive = 1;
1841 if (options->compression_level == -1)
1842 options->compression_level = 6;
1843 if (options->port == -1)
1844 options->port = 0; /* Filled in ssh_connect. */
1845 if (options->address_family == -1)
1846 options->address_family = AF_UNSPEC;
1847 if (options->connection_attempts == -1)
1848 options->connection_attempts = 1;
1849 if (options->number_of_password_prompts == -1)
1850 options->number_of_password_prompts = 3;
1851 /* Selected in ssh_login(). */
1852 if (options->cipher == -1)
1853 options->cipher = SSH_CIPHER_NOT_SET;
1854 /* options->hostkeyalgorithms, default set in myproposals.h */
1855 if (options->protocol == SSH_PROTO_UNKNOWN)
1856 options->protocol = SSH_PROTO_2;
1857 if (options->add_keys_to_agent == -1)
1858 options->add_keys_to_agent = 0;
1859 if (options->num_identity_files == 0) {
1860 if (options->protocol & SSH_PROTO_1) {
1861 add_identity_file(options, "~/",
1862 _PATH_SSH_CLIENT_IDENTITY, 0);
1864 if (options->protocol & SSH_PROTO_2) {
1865 add_identity_file(options, "~/",
1866 _PATH_SSH_CLIENT_ID_RSA, 0);
1867 add_identity_file(options, "~/",
1868 _PATH_SSH_CLIENT_ID_DSA, 0);
1869 #ifdef OPENSSL_HAS_ECC
1870 add_identity_file(options, "~/",
1871 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1873 add_identity_file(options, "~/",
1874 _PATH_SSH_CLIENT_ID_ED25519, 0);
1877 if (options->escape_char == -1)
1878 options->escape_char = '~';
1879 if (options->num_system_hostfiles == 0) {
1880 options->system_hostfiles[options->num_system_hostfiles++] =
1881 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1882 options->system_hostfiles[options->num_system_hostfiles++] =
1883 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1885 if (options->num_user_hostfiles == 0) {
1886 options->user_hostfiles[options->num_user_hostfiles++] =
1887 xstrdup(_PATH_SSH_USER_HOSTFILE);
1888 options->user_hostfiles[options->num_user_hostfiles++] =
1889 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1891 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1892 options->log_level = SYSLOG_LEVEL_INFO;
1893 if (options->clear_forwardings == 1)
1894 clear_forwardings(options);
1895 if (options->no_host_authentication_for_localhost == - 1)
1896 options->no_host_authentication_for_localhost = 0;
1897 if (options->identities_only == -1)
1898 options->identities_only = 0;
1899 if (options->enable_ssh_keysign == -1)
1900 options->enable_ssh_keysign = 0;
1901 if (options->rekey_limit == -1)
1902 options->rekey_limit = 0;
1903 if (options->rekey_interval == -1)
1904 options->rekey_interval = 0;
1906 if (options->verify_host_key_dns == -1)
1907 /* automatically trust a verified SSHFP record */
1908 options->verify_host_key_dns = 1;
1910 if (options->verify_host_key_dns == -1)
1911 options->verify_host_key_dns = 0;
1913 if (options->server_alive_interval == -1)
1914 options->server_alive_interval = 0;
1915 if (options->server_alive_count_max == -1)
1916 options->server_alive_count_max = 3;
1917 if (options->control_master == -1)
1918 options->control_master = 0;
1919 if (options->control_persist == -1) {
1920 options->control_persist = 0;
1921 options->control_persist_timeout = 0;
1923 if (options->hash_known_hosts == -1)
1924 options->hash_known_hosts = 0;
1925 if (options->tun_open == -1)
1926 options->tun_open = SSH_TUNMODE_NO;
1927 if (options->tun_local == -1)
1928 options->tun_local = SSH_TUNID_ANY;
1929 if (options->tun_remote == -1)
1930 options->tun_remote = SSH_TUNID_ANY;
1931 if (options->permit_local_command == -1)
1932 options->permit_local_command = 0;
1933 if (options->visual_host_key == -1)
1934 options->visual_host_key = 0;
1935 if (options->ip_qos_interactive == -1)
1936 options->ip_qos_interactive = IPTOS_LOWDELAY;
1937 if (options->ip_qos_bulk == -1)
1938 options->ip_qos_bulk = IPTOS_THROUGHPUT;
1939 if (options->request_tty == -1)
1940 options->request_tty = REQUEST_TTY_AUTO;
1941 if (options->proxy_use_fdpass == -1)
1942 options->proxy_use_fdpass = 0;
1943 if (options->canonicalize_max_dots == -1)
1944 options->canonicalize_max_dots = 1;
1945 if (options->canonicalize_fallback_local == -1)
1946 options->canonicalize_fallback_local = 1;
1947 if (options->canonicalize_hostname == -1)
1948 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1949 if (options->fingerprint_hash == -1)
1950 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
1951 if (options->update_hostkeys == -1)
1952 options->update_hostkeys = 0;
1953 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
1954 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
1955 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
1956 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1957 &options->hostbased_key_types) != 0 ||
1958 kex_assemble_names(KEX_DEFAULT_PK_ALG,
1959 &options->pubkey_key_types) != 0)
1960 fatal("%s: kex_assemble_names failed", __func__);
1962 #define CLEAR_ON_NONE(v) \
1964 if (option_clear_or_none(v)) { \
1969 CLEAR_ON_NONE(options->local_command);
1970 CLEAR_ON_NONE(options->proxy_command);
1971 CLEAR_ON_NONE(options->control_path);
1972 CLEAR_ON_NONE(options->revoked_host_keys);
1973 /* options->user will be set in the main program if appropriate */
1974 /* options->hostname will be set in the main program if appropriate */
1975 /* options->host_key_alias should not be set by default */
1976 /* options->preferred_authentications will be set in ssh */
1977 if (options->version_addendum == NULL)
1978 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
1988 * parses the next field in a port forwarding specification.
1989 * sets fwd to the parsed field and advances p past the colon
1990 * or sets it to NULL at end of string.
1991 * returns 0 on success, else non-zero.
1994 parse_fwd_field(char **p, struct fwdarg *fwd)
2001 return -1; /* end of string */
2005 * A field escaped with square brackets is used literally.
2006 * XXX - allow ']' to be escaped via backslash?
2009 /* find matching ']' */
2010 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2014 /* no matching ']' or not at end of field. */
2015 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2017 /* NUL terminate the field and advance p past the colon */
2022 fwd->ispath = ispath;
2027 for (cp = *p; *cp != '\0'; cp++) {
2030 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2044 fwd->ispath = ispath;
2051 * parses a string containing a port forwarding specification of the form:
2053 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2054 * listenpath:connectpath
2056 * [listenhost:]listenport
2057 * returns number of arguments parsed or zero on error
2060 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2062 struct fwdarg fwdargs[4];
2066 memset(fwd, 0, sizeof(*fwd));
2067 memset(fwdargs, 0, sizeof(fwdargs));
2069 cp = p = xstrdup(fwdspec);
2071 /* skip leading spaces */
2072 while (isspace((u_char)*cp))
2075 for (i = 0; i < 4; ++i) {
2076 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2080 /* Check for trailing garbage */
2081 if (cp != NULL && *cp != '\0') {
2082 i = 0; /* failure */
2087 if (fwdargs[0].ispath) {
2088 fwd->listen_path = xstrdup(fwdargs[0].arg);
2089 fwd->listen_port = PORT_STREAMLOCAL;
2091 fwd->listen_host = NULL;
2092 fwd->listen_port = a2port(fwdargs[0].arg);
2094 fwd->connect_host = xstrdup("socks");
2098 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2099 fwd->listen_path = xstrdup(fwdargs[0].arg);
2100 fwd->listen_port = PORT_STREAMLOCAL;
2101 fwd->connect_path = xstrdup(fwdargs[1].arg);
2102 fwd->connect_port = PORT_STREAMLOCAL;
2103 } else if (fwdargs[1].ispath) {
2104 fwd->listen_host = NULL;
2105 fwd->listen_port = a2port(fwdargs[0].arg);
2106 fwd->connect_path = xstrdup(fwdargs[1].arg);
2107 fwd->connect_port = PORT_STREAMLOCAL;
2109 fwd->listen_host = xstrdup(fwdargs[0].arg);
2110 fwd->listen_port = a2port(fwdargs[1].arg);
2111 fwd->connect_host = xstrdup("socks");
2116 if (fwdargs[0].ispath) {
2117 fwd->listen_path = xstrdup(fwdargs[0].arg);
2118 fwd->listen_port = PORT_STREAMLOCAL;
2119 fwd->connect_host = xstrdup(fwdargs[1].arg);
2120 fwd->connect_port = a2port(fwdargs[2].arg);
2121 } else if (fwdargs[2].ispath) {
2122 fwd->listen_host = xstrdup(fwdargs[0].arg);
2123 fwd->listen_port = a2port(fwdargs[1].arg);
2124 fwd->connect_path = xstrdup(fwdargs[2].arg);
2125 fwd->connect_port = PORT_STREAMLOCAL;
2127 fwd->listen_host = NULL;
2128 fwd->listen_port = a2port(fwdargs[0].arg);
2129 fwd->connect_host = xstrdup(fwdargs[1].arg);
2130 fwd->connect_port = a2port(fwdargs[2].arg);
2135 fwd->listen_host = xstrdup(fwdargs[0].arg);
2136 fwd->listen_port = a2port(fwdargs[1].arg);
2137 fwd->connect_host = xstrdup(fwdargs[2].arg);
2138 fwd->connect_port = a2port(fwdargs[3].arg);
2141 i = 0; /* failure */
2147 if (!(i == 1 || i == 2))
2150 if (!(i == 3 || i == 4)) {
2151 if (fwd->connect_path == NULL &&
2152 fwd->listen_path == NULL)
2155 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2159 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2160 (!remotefwd && fwd->listen_port == 0))
2162 if (fwd->connect_host != NULL &&
2163 strlen(fwd->connect_host) >= NI_MAXHOST)
2165 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2166 if (fwd->connect_path != NULL &&
2167 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2169 if (fwd->listen_host != NULL &&
2170 strlen(fwd->listen_host) >= NI_MAXHOST)
2172 if (fwd->listen_path != NULL &&
2173 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2179 free(fwd->connect_host);
2180 fwd->connect_host = NULL;
2181 free(fwd->connect_path);
2182 fwd->connect_path = NULL;
2183 free(fwd->listen_host);
2184 fwd->listen_host = NULL;
2185 free(fwd->listen_path);
2186 fwd->listen_path = NULL;
2190 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2192 fmt_multistate_int(int val, const struct multistate *m)
2196 for (i = 0; m[i].key != NULL; i++) {
2197 if (m[i].value == val)
2204 fmt_intarg(OpCodes code, int val)
2209 case oAddressFamily:
2210 return fmt_multistate_int(val, multistate_addressfamily);
2211 case oVerifyHostKeyDNS:
2212 case oStrictHostKeyChecking:
2213 case oUpdateHostkeys:
2214 return fmt_multistate_int(val, multistate_yesnoask);
2215 case oControlMaster:
2216 return fmt_multistate_int(val, multistate_controlmaster);
2218 return fmt_multistate_int(val, multistate_tunnel);
2220 return fmt_multistate_int(val, multistate_requesttty);
2221 case oCanonicalizeHostname:
2222 return fmt_multistate_int(val, multistate_canonicalizehostname);
2223 case oFingerprintHash:
2224 return ssh_digest_alg_name(val);
2231 case (SSH_PROTO_1|SSH_PROTO_2):
2249 lookup_opcode_name(OpCodes code)
2253 for (i = 0; keywords[i].name != NULL; i++)
2254 if (keywords[i].opcode == code)
2255 return(keywords[i].name);
2260 dump_cfg_int(OpCodes code, int val)
2262 printf("%s %d\n", lookup_opcode_name(code), val);
2266 dump_cfg_fmtint(OpCodes code, int val)
2268 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2272 dump_cfg_string(OpCodes code, const char *val)
2276 printf("%s %s\n", lookup_opcode_name(code), val);
2280 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2284 for (i = 0; i < count; i++)
2285 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2289 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2293 printf("%s", lookup_opcode_name(code));
2294 for (i = 0; i < count; i++)
2295 printf(" %s", vals[i]);
2300 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2302 const struct Forward *fwd;
2305 /* oDynamicForward */
2306 for (i = 0; i < count; i++) {
2308 if (code == oDynamicForward &&
2309 strcmp(fwd->connect_host, "socks") != 0)
2311 if (code == oLocalForward &&
2312 strcmp(fwd->connect_host, "socks") == 0)
2314 printf("%s", lookup_opcode_name(code));
2315 if (fwd->listen_port == PORT_STREAMLOCAL)
2316 printf(" %s", fwd->listen_path);
2317 else if (fwd->listen_host == NULL)
2318 printf(" %d", fwd->listen_port);
2321 fwd->listen_host, fwd->listen_port);
2323 if (code != oDynamicForward) {
2324 if (fwd->connect_port == PORT_STREAMLOCAL)
2325 printf(" %s", fwd->connect_path);
2326 else if (fwd->connect_host == NULL)
2327 printf(" %d", fwd->connect_port);
2330 fwd->connect_host, fwd->connect_port);
2338 dump_client_config(Options *o, const char *host)
2343 /* This is normally prepared in ssh_kex2 */
2344 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2345 fatal("%s: kex_assemble_names failed", __func__);
2347 /* Most interesting options first: user, host, port */
2348 dump_cfg_string(oUser, o->user);
2349 dump_cfg_string(oHostName, host);
2350 dump_cfg_int(oPort, o->port);
2353 dump_cfg_fmtint(oAddressFamily, o->address_family);
2354 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2355 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2356 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2357 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2358 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2359 dump_cfg_fmtint(oCompression, o->compression);
2360 dump_cfg_fmtint(oControlMaster, o->control_master);
2361 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2362 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2363 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2364 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2365 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2366 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2367 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2369 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2370 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2372 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2373 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2374 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2375 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2376 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2377 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2378 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2379 dump_cfg_fmtint(oProtocol, o->protocol);
2380 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2381 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2382 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2383 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2384 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2385 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2386 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2387 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2388 dump_cfg_fmtint(oTunnel, o->tun_open);
2389 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2390 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2391 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2392 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2394 /* Integer options */
2395 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2396 dump_cfg_int(oCompressionLevel, o->compression_level);
2397 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2398 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2399 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2400 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2401 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2403 /* String options */
2404 dump_cfg_string(oBindAddress, o->bind_address);
2405 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2406 dump_cfg_string(oControlPath, o->control_path);
2407 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2408 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2409 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2410 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2411 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2412 dump_cfg_string(oLocalCommand, o->local_command);
2413 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2414 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2415 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2416 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2417 dump_cfg_string(oProxyCommand, o->proxy_command);
2418 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2419 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2420 dump_cfg_string(oXAuthLocation, o->xauth_location);
2423 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2424 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2425 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2427 /* String array options */
2428 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2429 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2430 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2431 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2432 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2436 /* oConnectTimeout */
2437 if (o->connection_timeout == -1)
2438 printf("connecttimeout none\n");
2440 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2443 printf("tunneldevice");
2444 if (o->tun_local == SSH_TUNID_ANY)
2447 printf(" %d", o->tun_local);
2448 if (o->tun_remote == SSH_TUNID_ANY)
2451 printf(":%d", o->tun_remote);
2454 /* oCanonicalizePermittedCNAMEs */
2455 if ( o->num_permitted_cnames > 0) {
2456 printf("canonicalizePermittedcnames");
2457 for (i = 0; i < o->num_permitted_cnames; i++) {
2458 printf(" %s:%s", o->permitted_cnames[i].source_list,
2459 o->permitted_cnames[i].target_list);
2465 if (o->cipher != SSH_CIPHER_NOT_SET)
2466 printf("Cipher %s\n", cipher_name(o->cipher));
2468 /* oControlPersist */
2469 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2470 dump_cfg_fmtint(oControlPersist, o->control_persist);
2472 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2475 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2476 printf("escapechar none\n");
2478 vis(vbuf, o->escape_char, VIS_WHITE, 0);
2479 printf("escapechar %s\n", vbuf);
2483 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2484 printf("%s\n", iptos2str(o->ip_qos_bulk));
2487 printf("rekeylimit %llu %d\n",
2488 (unsigned long long)o->rekey_limit, o->rekey_interval);
2490 /* oStreamLocalBindMask */
2491 printf("streamlocalbindmask 0%o\n",
2492 o->fwd_opts.streamlocal_bind_mask);