1 /* $OpenBSD: readconf.c,v 1.283 2018/02/23 15:58:37 markus Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Functions for reading the configuration files.
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
17 #include <sys/types.h>
19 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #include <arpa/inet.h>
42 #ifdef USE_SYSTEM_GLOB
45 # include "openbsd-compat/glob.h"
50 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
58 #include "pathnames.h"
67 #include "myproposal.h"
70 /* Format of the configuration file:
72 # Configuration data is parsed as follows:
73 # 1. command line options
74 # 2. user-specific file
76 # Any configuration value is only changed the first time it is set.
77 # Thus, host-specific definitions should be at the beginning of the
78 # configuration file, and defaults at the end.
80 # Host-specific declarations. These may override anything above. A single
81 # host may match multiple declarations; these are processed in the order
82 # that they are given in.
88 HostName another.host.name.real.org
95 RemoteForward 9999 shadows.cs.hut.fi:9999
101 PasswordAuthentication no
105 ProxyCommand ssh-proxy %h %p
108 PublicKeyAuthentication no
112 PasswordAuthentication no
118 # Defaults for various options
122 PasswordAuthentication yes
123 RSAAuthentication yes
124 RhostsRSAAuthentication yes
125 StrictHostKeyChecking yes
127 IdentityFile ~/.ssh/identity
133 static int read_config_file_depth(const char *filename, struct passwd *pw,
134 const char *host, const char *original_host, Options *options,
135 int flags, int *activep, int depth);
136 static int process_config_line_depth(Options *options, struct passwd *pw,
137 const char *host, const char *original_host, char *line,
138 const char *filename, int linenum, int *activep, int flags, int depth);
140 /* Keyword tokens. */
144 oHost, oMatch, oInclude,
145 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
146 oGatewayPorts, oExitOnForwardFailure,
147 oPasswordAuthentication, oRSAAuthentication,
148 oChallengeResponseAuthentication, oXAuthLocation,
149 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
150 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
151 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
152 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
153 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
154 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
155 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
156 oPubkeyAuthentication,
157 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
158 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
159 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
160 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
161 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
162 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
163 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
164 oSendEnv, oControlPath, oControlMaster, oControlPersist,
166 oTunnel, oTunnelDevice,
167 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
169 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
170 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
171 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
172 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
173 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
174 oPubkeyAcceptedKeyTypes, oProxyJump,
175 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
178 /* Textual representations of the tokens. */
184 /* Deprecated options */
185 { "protocol", oIgnore }, /* NB. silently ignored */
186 { "cipher", oDeprecated },
187 { "fallbacktorsh", oDeprecated },
188 { "globalknownhostsfile2", oDeprecated },
189 { "rhostsauthentication", oDeprecated },
190 { "userknownhostsfile2", oDeprecated },
191 { "useroaming", oDeprecated },
192 { "usersh", oDeprecated },
194 /* Unsupported options */
195 { "afstokenpassing", oUnsupported },
196 { "kerberosauthentication", oUnsupported },
197 { "kerberostgtpassing", oUnsupported },
199 /* Sometimes-unsupported options */
201 { "gssapiauthentication", oGssAuthentication },
202 { "gssapidelegatecredentials", oGssDelegateCreds },
204 { "gssapiauthentication", oUnsupported },
205 { "gssapidelegatecredentials", oUnsupported },
208 { "smartcarddevice", oPKCS11Provider },
209 { "pkcs11provider", oPKCS11Provider },
211 { "smartcarddevice", oUnsupported },
212 { "pkcs11provider", oUnsupported },
214 { "rsaauthentication", oUnsupported },
215 { "rhostsrsaauthentication", oUnsupported },
216 { "compressionlevel", oUnsupported },
218 { "forwardagent", oForwardAgent },
219 { "forwardx11", oForwardX11 },
220 { "forwardx11trusted", oForwardX11Trusted },
221 { "forwardx11timeout", oForwardX11Timeout },
222 { "exitonforwardfailure", oExitOnForwardFailure },
223 { "xauthlocation", oXAuthLocation },
224 { "gatewayports", oGatewayPorts },
225 { "useprivilegedport", oUsePrivilegedPort },
226 { "passwordauthentication", oPasswordAuthentication },
227 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
228 { "kbdinteractivedevices", oKbdInteractiveDevices },
229 { "pubkeyauthentication", oPubkeyAuthentication },
230 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
231 { "hostbasedauthentication", oHostbasedAuthentication },
232 { "challengeresponseauthentication", oChallengeResponseAuthentication },
233 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
234 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
235 { "identityfile", oIdentityFile },
236 { "identityfile2", oIdentityFile }, /* obsolete */
237 { "identitiesonly", oIdentitiesOnly },
238 { "certificatefile", oCertificateFile },
239 { "addkeystoagent", oAddKeysToAgent },
240 { "identityagent", oIdentityAgent },
241 { "hostname", oHostName },
242 { "hostkeyalias", oHostKeyAlias },
243 { "proxycommand", oProxyCommand },
245 { "ciphers", oCiphers },
247 { "remoteforward", oRemoteForward },
248 { "localforward", oLocalForward },
252 { "escapechar", oEscapeChar },
253 { "globalknownhostsfile", oGlobalKnownHostsFile },
254 { "userknownhostsfile", oUserKnownHostsFile },
255 { "connectionattempts", oConnectionAttempts },
256 { "batchmode", oBatchMode },
257 { "checkhostip", oCheckHostIP },
258 { "stricthostkeychecking", oStrictHostKeyChecking },
259 { "compression", oCompression },
260 { "tcpkeepalive", oTCPKeepAlive },
261 { "keepalive", oTCPKeepAlive }, /* obsolete */
262 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
263 { "syslogfacility", oLogFacility },
264 { "loglevel", oLogLevel },
265 { "dynamicforward", oDynamicForward },
266 { "preferredauthentications", oPreferredAuthentications },
267 { "hostkeyalgorithms", oHostKeyAlgorithms },
268 { "bindaddress", oBindAddress },
269 { "bindinterface", oBindInterface },
270 { "clearallforwardings", oClearAllForwardings },
271 { "enablesshkeysign", oEnableSSHKeysign },
272 { "verifyhostkeydns", oVerifyHostKeyDNS },
273 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
274 { "rekeylimit", oRekeyLimit },
275 { "connecttimeout", oConnectTimeout },
276 { "addressfamily", oAddressFamily },
277 { "serveraliveinterval", oServerAliveInterval },
278 { "serveralivecountmax", oServerAliveCountMax },
279 { "sendenv", oSendEnv },
280 { "controlpath", oControlPath },
281 { "controlmaster", oControlMaster },
282 { "controlpersist", oControlPersist },
283 { "hashknownhosts", oHashKnownHosts },
284 { "include", oInclude },
285 { "tunnel", oTunnel },
286 { "tunneldevice", oTunnelDevice },
287 { "localcommand", oLocalCommand },
288 { "permitlocalcommand", oPermitLocalCommand },
289 { "remotecommand", oRemoteCommand },
290 { "visualhostkey", oVisualHostKey },
291 { "kexalgorithms", oKexAlgorithms },
293 { "requesttty", oRequestTTY },
294 { "proxyusefdpass", oProxyUseFdpass },
295 { "canonicaldomains", oCanonicalDomains },
296 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
297 { "canonicalizehostname", oCanonicalizeHostname },
298 { "canonicalizemaxdots", oCanonicalizeMaxDots },
299 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
300 { "streamlocalbindmask", oStreamLocalBindMask },
301 { "streamlocalbindunlink", oStreamLocalBindUnlink },
302 { "revokedhostkeys", oRevokedHostKeys },
303 { "fingerprinthash", oFingerprintHash },
304 { "updatehostkeys", oUpdateHostkeys },
305 { "hostbasedkeytypes", oHostbasedKeyTypes },
306 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
307 { "ignoreunknown", oIgnoreUnknown },
308 { "proxyjump", oProxyJump },
314 * Adds a local TCP/IP port forward to options. Never returns if there is an
319 add_local_forward(Options *options, const struct Forward *newfwd)
322 extern uid_t original_real_uid;
325 if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
326 newfwd->listen_path == NULL)
327 fatal("Privileged ports can only be forwarded by root.");
328 /* Don't add duplicates */
329 for (i = 0; i < options->num_local_forwards; i++) {
330 if (forward_equals(newfwd, options->local_forwards + i))
333 options->local_forwards = xreallocarray(options->local_forwards,
334 options->num_local_forwards + 1,
335 sizeof(*options->local_forwards));
336 fwd = &options->local_forwards[options->num_local_forwards++];
338 fwd->listen_host = newfwd->listen_host;
339 fwd->listen_port = newfwd->listen_port;
340 fwd->listen_path = newfwd->listen_path;
341 fwd->connect_host = newfwd->connect_host;
342 fwd->connect_port = newfwd->connect_port;
343 fwd->connect_path = newfwd->connect_path;
347 * Adds a remote TCP/IP port forward to options. Never returns if there is
352 add_remote_forward(Options *options, const struct Forward *newfwd)
357 /* Don't add duplicates */
358 for (i = 0; i < options->num_remote_forwards; i++) {
359 if (forward_equals(newfwd, options->remote_forwards + i))
362 options->remote_forwards = xreallocarray(options->remote_forwards,
363 options->num_remote_forwards + 1,
364 sizeof(*options->remote_forwards));
365 fwd = &options->remote_forwards[options->num_remote_forwards++];
367 fwd->listen_host = newfwd->listen_host;
368 fwd->listen_port = newfwd->listen_port;
369 fwd->listen_path = newfwd->listen_path;
370 fwd->connect_host = newfwd->connect_host;
371 fwd->connect_port = newfwd->connect_port;
372 fwd->connect_path = newfwd->connect_path;
373 fwd->handle = newfwd->handle;
374 fwd->allocated_port = 0;
378 clear_forwardings(Options *options)
382 for (i = 0; i < options->num_local_forwards; i++) {
383 free(options->local_forwards[i].listen_host);
384 free(options->local_forwards[i].listen_path);
385 free(options->local_forwards[i].connect_host);
386 free(options->local_forwards[i].connect_path);
388 if (options->num_local_forwards > 0) {
389 free(options->local_forwards);
390 options->local_forwards = NULL;
392 options->num_local_forwards = 0;
393 for (i = 0; i < options->num_remote_forwards; i++) {
394 free(options->remote_forwards[i].listen_host);
395 free(options->remote_forwards[i].listen_path);
396 free(options->remote_forwards[i].connect_host);
397 free(options->remote_forwards[i].connect_path);
399 if (options->num_remote_forwards > 0) {
400 free(options->remote_forwards);
401 options->remote_forwards = NULL;
403 options->num_remote_forwards = 0;
404 options->tun_open = SSH_TUNMODE_NO;
408 add_certificate_file(Options *options, const char *path, int userprovided)
412 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
413 fatal("Too many certificate files specified (max %d)",
414 SSH_MAX_CERTIFICATE_FILES);
416 /* Avoid registering duplicates */
417 for (i = 0; i < options->num_certificate_files; i++) {
418 if (options->certificate_file_userprovided[i] == userprovided &&
419 strcmp(options->certificate_files[i], path) == 0) {
420 debug2("%s: ignoring duplicate key %s", __func__, path);
425 options->certificate_file_userprovided[options->num_certificate_files] =
427 options->certificate_files[options->num_certificate_files++] =
432 add_identity_file(Options *options, const char *dir, const char *filename,
438 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
439 fatal("Too many identity files specified (max %d)",
440 SSH_MAX_IDENTITY_FILES);
442 if (dir == NULL) /* no dir, filename is absolute */
443 path = xstrdup(filename);
444 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
445 fatal("Identity file path %s too long", path);
447 /* Avoid registering duplicates */
448 for (i = 0; i < options->num_identity_files; i++) {
449 if (options->identity_file_userprovided[i] == userprovided &&
450 strcmp(options->identity_files[i], path) == 0) {
451 debug2("%s: ignoring duplicate key %s", __func__, path);
457 options->identity_file_userprovided[options->num_identity_files] =
459 options->identity_files[options->num_identity_files++] = path;
463 default_ssh_port(void)
469 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
470 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
476 * Execute a command in a shell.
477 * Return its exit status or -1 on abnormal exit.
480 execute_in_shell(const char *cmd)
485 extern uid_t original_real_uid;
487 if ((shell = getenv("SHELL")) == NULL)
488 shell = _PATH_BSHELL;
490 /* Need this to redirect subprocess stdin/out */
491 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
492 fatal("open(/dev/null): %s", strerror(errno));
494 debug("Executing command: '%.500s'", cmd);
496 /* Fork and execute the command. */
497 if ((pid = fork()) == 0) {
500 /* Child. Permanently give up superuser privileges. */
501 permanently_drop_suid(original_real_uid);
503 /* Redirect child stdin and stdout. Leave stderr */
504 if (dup2(devnull, STDIN_FILENO) == -1)
505 fatal("dup2: %s", strerror(errno));
506 if (dup2(devnull, STDOUT_FILENO) == -1)
507 fatal("dup2: %s", strerror(errno));
508 if (devnull > STDERR_FILENO)
510 closefrom(STDERR_FILENO + 1);
514 argv[2] = xstrdup(cmd);
517 execv(argv[0], argv);
518 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
519 /* Die with signal to make this error apparent to parent. */
520 signal(SIGTERM, SIG_DFL);
521 kill(getpid(), SIGTERM);
526 fatal("%s: fork: %.100s", __func__, strerror(errno));
530 while (waitpid(pid, &status, 0) == -1) {
531 if (errno != EINTR && errno != EAGAIN)
532 fatal("%s: waitpid: %s", __func__, strerror(errno));
534 if (!WIFEXITED(status)) {
535 error("command '%.100s' exited abnormally", cmd);
538 debug3("command returned status %d", WEXITSTATUS(status));
539 return WEXITSTATUS(status);
543 * Parse and execute a Match directive.
546 match_cfg_line(Options *options, char **condition, struct passwd *pw,
547 const char *host_arg, const char *original_host, int post_canon,
548 const char *filename, int linenum)
550 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
552 int r, port, this_result, result = 1, attributes = 0, negate;
553 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
556 * Configuration is likely to be incomplete at this point so we
557 * must be prepared to use default values.
559 port = options->port <= 0 ? default_ssh_port() : options->port;
560 ruser = options->user == NULL ? pw->pw_name : options->user;
562 host = xstrdup(options->hostname);
563 } else if (options->hostname != NULL) {
564 /* NB. Please keep in sync with ssh.c:main() */
565 host = percent_expand(options->hostname,
566 "h", host_arg, (char *)NULL);
568 host = xstrdup(host_arg);
571 debug2("checking match for '%s' host %s originally %s",
572 cp, host, original_host);
573 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
576 if ((negate = attrib[0] == '!'))
578 /* criteria "all" and "canonical" have no argument */
579 if (strcasecmp(attrib, "all") == 0) {
580 if (attributes > 1 ||
581 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
582 error("%.200s line %d: '%s' cannot be combined "
583 "with other Match attributes",
584 filename, linenum, oattrib);
589 result = negate ? 0 : 1;
593 if (strcasecmp(attrib, "canonical") == 0) {
594 r = !!post_canon; /* force bitmask member to boolean */
595 if (r == (negate ? 1 : 0))
596 this_result = result = 0;
597 debug3("%.200s line %d: %smatched '%s'",
599 this_result ? "" : "not ", oattrib);
602 /* All other criteria require an argument */
603 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
604 error("Missing Match criteria for %s", attrib);
608 if (strcasecmp(attrib, "host") == 0) {
609 criteria = xstrdup(host);
610 r = match_hostname(host, arg) == 1;
611 if (r == (negate ? 1 : 0))
612 this_result = result = 0;
613 } else if (strcasecmp(attrib, "originalhost") == 0) {
614 criteria = xstrdup(original_host);
615 r = match_hostname(original_host, arg) == 1;
616 if (r == (negate ? 1 : 0))
617 this_result = result = 0;
618 } else if (strcasecmp(attrib, "user") == 0) {
619 criteria = xstrdup(ruser);
620 r = match_pattern_list(ruser, arg, 0) == 1;
621 if (r == (negate ? 1 : 0))
622 this_result = result = 0;
623 } else if (strcasecmp(attrib, "localuser") == 0) {
624 criteria = xstrdup(pw->pw_name);
625 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
626 if (r == (negate ? 1 : 0))
627 this_result = result = 0;
628 } else if (strcasecmp(attrib, "exec") == 0) {
629 if (gethostname(thishost, sizeof(thishost)) == -1)
630 fatal("gethostname: %s", strerror(errno));
631 strlcpy(shorthost, thishost, sizeof(shorthost));
632 shorthost[strcspn(thishost, ".")] = '\0';
633 snprintf(portstr, sizeof(portstr), "%d", port);
635 cmd = percent_expand(arg,
646 /* skip execution if prior predicate failed */
647 debug3("%.200s line %d: skipped exec "
648 "\"%.100s\"", filename, linenum, cmd);
652 r = execute_in_shell(cmd);
654 fatal("%.200s line %d: match exec "
655 "'%.100s' error", filename,
658 criteria = xstrdup(cmd);
660 /* Force exit status to boolean */
662 if (r == (negate ? 1 : 0))
663 this_result = result = 0;
665 error("Unsupported Match attribute %s", attrib);
669 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
670 filename, linenum, this_result ? "": "not ",
674 if (attributes == 0) {
675 error("One or more attributes required for Match");
681 debug2("match %sfound", result ? "" : "not ");
688 * Returns the number of the token pointed to by cp or oBadOption.
691 parse_token(const char *cp, const char *filename, int linenum,
692 const char *ignored_unknown)
696 for (i = 0; keywords[i].name; i++)
697 if (strcmp(cp, keywords[i].name) == 0)
698 return keywords[i].opcode;
699 if (ignored_unknown != NULL &&
700 match_pattern_list(cp, ignored_unknown, 1) == 1)
701 return oIgnoredUnknownOption;
702 error("%s: line %d: Bad configuration option: %s",
703 filename, linenum, cp);
707 /* Multistate option parsing */
712 static const struct multistate multistate_flag[] = {
719 static const struct multistate multistate_yesnoask[] = {
727 static const struct multistate multistate_strict_hostkey[] = {
728 { "true", SSH_STRICT_HOSTKEY_YES },
729 { "false", SSH_STRICT_HOSTKEY_OFF },
730 { "yes", SSH_STRICT_HOSTKEY_YES },
731 { "no", SSH_STRICT_HOSTKEY_OFF },
732 { "ask", SSH_STRICT_HOSTKEY_ASK },
733 { "off", SSH_STRICT_HOSTKEY_OFF },
734 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
737 static const struct multistate multistate_yesnoaskconfirm[] = {
746 static const struct multistate multistate_addressfamily[] = {
748 { "inet6", AF_INET6 },
749 { "any", AF_UNSPEC },
752 static const struct multistate multistate_controlmaster[] = {
753 { "true", SSHCTL_MASTER_YES },
754 { "yes", SSHCTL_MASTER_YES },
755 { "false", SSHCTL_MASTER_NO },
756 { "no", SSHCTL_MASTER_NO },
757 { "auto", SSHCTL_MASTER_AUTO },
758 { "ask", SSHCTL_MASTER_ASK },
759 { "autoask", SSHCTL_MASTER_AUTO_ASK },
762 static const struct multistate multistate_tunnel[] = {
763 { "ethernet", SSH_TUNMODE_ETHERNET },
764 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
765 { "true", SSH_TUNMODE_DEFAULT },
766 { "yes", SSH_TUNMODE_DEFAULT },
767 { "false", SSH_TUNMODE_NO },
768 { "no", SSH_TUNMODE_NO },
771 static const struct multistate multistate_requesttty[] = {
772 { "true", REQUEST_TTY_YES },
773 { "yes", REQUEST_TTY_YES },
774 { "false", REQUEST_TTY_NO },
775 { "no", REQUEST_TTY_NO },
776 { "force", REQUEST_TTY_FORCE },
777 { "auto", REQUEST_TTY_AUTO },
780 static const struct multistate multistate_canonicalizehostname[] = {
781 { "true", SSH_CANONICALISE_YES },
782 { "false", SSH_CANONICALISE_NO },
783 { "yes", SSH_CANONICALISE_YES },
784 { "no", SSH_CANONICALISE_NO },
785 { "always", SSH_CANONICALISE_ALWAYS },
790 * Processes a single option line as used in the configuration files. This
791 * only sets those values that have not already been set.
794 process_config_line(Options *options, struct passwd *pw, const char *host,
795 const char *original_host, char *line, const char *filename,
796 int linenum, int *activep, int flags)
798 return process_config_line_depth(options, pw, host, original_host,
799 line, filename, linenum, activep, flags, 0);
802 #define WHITESPACE " \t\r\n"
804 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
805 const char *original_host, char *line, const char *filename,
806 int linenum, int *activep, int flags, int depth)
808 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
809 char **cpptr, fwdarg[256];
810 u_int i, *uintptr, max_entries = 0;
811 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
812 int remotefwd, dynamicfwd;
813 LogLevel *log_level_ptr;
814 SyslogFacility *log_facility_ptr;
818 const struct multistate *multistate_ptr;
819 struct allowed_cname *cname;
823 if (activep == NULL) { /* We are processing a command line directive */
828 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
829 if ((len = strlen(line)) == 0)
831 for (len--; len > 0; len--) {
832 if (strchr(WHITESPACE "\f", line[len]) == NULL)
838 /* Get the keyword. (Each line is supposed to begin with a keyword). */
839 if ((keyword = strdelim(&s)) == NULL)
841 /* Ignore leading whitespace. */
842 if (*keyword == '\0')
843 keyword = strdelim(&s);
844 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
846 /* Match lowercase keyword */
849 opcode = parse_token(keyword, filename, linenum,
850 options->ignored_unknown);
854 /* don't panic, but count bad options */
858 case oIgnoredUnknownOption:
859 debug("%s line %d: Ignored unknown option \"%s\"",
860 filename, linenum, keyword);
862 case oConnectTimeout:
863 intptr = &options->connection_timeout;
866 if (!arg || *arg == '\0')
867 fatal("%s line %d: missing time value.",
869 if (strcmp(arg, "none") == 0)
871 else if ((value = convtime(arg)) == -1)
872 fatal("%s line %d: invalid time value.",
874 if (*activep && *intptr == -1)
879 intptr = &options->forward_agent;
881 multistate_ptr = multistate_flag;
884 if (!arg || *arg == '\0')
885 fatal("%s line %d: missing argument.",
888 for (i = 0; multistate_ptr[i].key != NULL; i++) {
889 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
890 value = multistate_ptr[i].value;
895 fatal("%s line %d: unsupported option \"%s\".",
896 filename, linenum, arg);
897 if (*activep && *intptr == -1)
902 intptr = &options->forward_x11;
905 case oForwardX11Trusted:
906 intptr = &options->forward_x11_trusted;
909 case oForwardX11Timeout:
910 intptr = &options->forward_x11_timeout;
914 intptr = &options->fwd_opts.gateway_ports;
917 case oExitOnForwardFailure:
918 intptr = &options->exit_on_forward_failure;
921 case oUsePrivilegedPort:
922 intptr = &options->use_privileged_port;
925 case oPasswordAuthentication:
926 intptr = &options->password_authentication;
929 case oKbdInteractiveAuthentication:
930 intptr = &options->kbd_interactive_authentication;
933 case oKbdInteractiveDevices:
934 charptr = &options->kbd_interactive_devices;
937 case oPubkeyAuthentication:
938 intptr = &options->pubkey_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_strict_hostkey;
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;
993 if (!arg || *arg == '\0')
994 fatal("%.200s line %d: Missing argument.", filename,
996 if (strcmp(arg, "default") == 0) {
999 if (scan_scaled(arg, &val64) == -1)
1000 fatal("%.200s line %d: Bad number '%s': %s",
1001 filename, linenum, arg, strerror(errno));
1002 if (val64 != 0 && val64 < 16)
1003 fatal("%.200s line %d: RekeyLimit too small",
1006 if (*activep && options->rekey_limit == -1)
1007 options->rekey_limit = val64;
1008 if (s != NULL) { /* optional rekey interval present */
1009 if (strcmp(s, "none") == 0) {
1010 (void)strdelim(&s); /* discard */
1013 intptr = &options->rekey_interval;
1020 if (!arg || *arg == '\0')
1021 fatal("%.200s line %d: Missing argument.", filename, linenum);
1023 intptr = &options->num_identity_files;
1024 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1025 fatal("%.200s line %d: Too many identity files specified (max %d).",
1026 filename, linenum, SSH_MAX_IDENTITY_FILES);
1027 add_identity_file(options, NULL,
1028 arg, flags & SSHCONF_USERCONF);
1032 case oCertificateFile:
1034 if (!arg || *arg == '\0')
1035 fatal("%.200s line %d: Missing argument.",
1038 intptr = &options->num_certificate_files;
1039 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1040 fatal("%.200s line %d: Too many certificate "
1041 "files specified (max %d).",
1043 SSH_MAX_CERTIFICATE_FILES);
1045 add_certificate_file(options, arg,
1046 flags & SSHCONF_USERCONF);
1050 case oXAuthLocation:
1051 charptr=&options->xauth_location;
1055 charptr = &options->user;
1058 if (!arg || *arg == '\0')
1059 fatal("%.200s line %d: Missing argument.",
1061 if (*activep && *charptr == NULL)
1062 *charptr = xstrdup(arg);
1065 case oGlobalKnownHostsFile:
1066 cpptr = (char **)&options->system_hostfiles;
1067 uintptr = &options->num_system_hostfiles;
1068 max_entries = SSH_MAX_HOSTS_FILES;
1070 if (*activep && *uintptr == 0) {
1071 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1072 if ((*uintptr) >= max_entries)
1073 fatal("%s line %d: "
1074 "too many authorized keys files.",
1076 cpptr[(*uintptr)++] = xstrdup(arg);
1081 case oUserKnownHostsFile:
1082 cpptr = (char **)&options->user_hostfiles;
1083 uintptr = &options->num_user_hostfiles;
1084 max_entries = SSH_MAX_HOSTS_FILES;
1085 goto parse_char_array;
1088 charptr = &options->hostname;
1092 charptr = &options->host_key_alias;
1095 case oPreferredAuthentications:
1096 charptr = &options->preferred_authentications;
1100 charptr = &options->bind_address;
1103 case oBindInterface:
1104 charptr = &options->bind_interface;
1107 case oPKCS11Provider:
1108 charptr = &options->pkcs11_provider;
1112 charptr = &options->proxy_command;
1113 /* Ignore ProxyCommand if ProxyJump already specified */
1114 if (options->jump_host != NULL)
1115 charptr = &options->jump_host; /* Skip below */
1118 fatal("%.200s line %d: Missing argument.", filename, linenum);
1119 len = strspn(s, WHITESPACE "=");
1120 if (*activep && *charptr == NULL)
1121 *charptr = xstrdup(s + len);
1126 fatal("%.200s line %d: Missing argument.",
1129 len = strspn(s, WHITESPACE "=");
1130 if (parse_jump(s + len, options, *activep) == -1) {
1131 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1132 filename, linenum, s + len);
1137 intptr = &options->port;
1140 if ((errstr = atoi_err(arg, &value)) != NULL)
1141 fatal("%s line %d: integer value %s.",
1142 filename, linenum, errstr);
1143 if (*activep && *intptr == -1)
1147 case oConnectionAttempts:
1148 intptr = &options->connection_attempts;
1153 if (!arg || *arg == '\0')
1154 fatal("%.200s line %d: Missing argument.", filename, linenum);
1155 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1156 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1157 filename, linenum, arg ? arg : "<NONE>");
1158 if (*activep && options->ciphers == NULL)
1159 options->ciphers = xstrdup(arg);
1164 if (!arg || *arg == '\0')
1165 fatal("%.200s line %d: Missing argument.", filename, linenum);
1166 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1167 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1168 filename, linenum, arg ? arg : "<NONE>");
1169 if (*activep && options->macs == NULL)
1170 options->macs = xstrdup(arg);
1173 case oKexAlgorithms:
1175 if (!arg || *arg == '\0')
1176 fatal("%.200s line %d: Missing argument.",
1179 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1180 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1181 filename, linenum, arg ? arg : "<NONE>");
1182 if (*activep && options->kex_algorithms == NULL)
1183 options->kex_algorithms = xstrdup(arg);
1186 case oHostKeyAlgorithms:
1187 charptr = &options->hostkeyalgorithms;
1190 if (!arg || *arg == '\0')
1191 fatal("%.200s line %d: Missing argument.",
1194 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1195 fatal("%s line %d: Bad key types '%s'.",
1196 filename, linenum, arg ? arg : "<NONE>");
1197 if (*activep && *charptr == NULL)
1198 *charptr = xstrdup(arg);
1202 log_level_ptr = &options->log_level;
1204 value = log_level_number(arg);
1205 if (value == SYSLOG_LEVEL_NOT_SET)
1206 fatal("%.200s line %d: unsupported log level '%s'",
1207 filename, linenum, arg ? arg : "<NONE>");
1208 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1209 *log_level_ptr = (LogLevel) value;
1213 log_facility_ptr = &options->log_facility;
1215 value = log_facility_number(arg);
1216 if (value == SYSLOG_FACILITY_NOT_SET)
1217 fatal("%.200s line %d: unsupported log facility '%s'",
1218 filename, linenum, arg ? arg : "<NONE>");
1219 if (*log_facility_ptr == -1)
1220 *log_facility_ptr = (SyslogFacility) value;
1224 case oRemoteForward:
1225 case oDynamicForward:
1227 if (arg == NULL || *arg == '\0')
1228 fatal("%.200s line %d: Missing port argument.",
1231 remotefwd = (opcode == oRemoteForward);
1232 dynamicfwd = (opcode == oDynamicForward);
1235 arg2 = strdelim(&s);
1236 if (arg2 == NULL || *arg2 == '\0') {
1240 fatal("%.200s line %d: Missing target "
1241 "argument.", filename, linenum);
1243 /* construct a string for parse_forward */
1244 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1249 strlcpy(fwdarg, arg, sizeof(fwdarg));
1251 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1252 fatal("%.200s line %d: Bad forwarding specification.",
1257 add_remote_forward(options, &fwd);
1259 add_local_forward(options, &fwd);
1264 case oClearAllForwardings:
1265 intptr = &options->clear_forwardings;
1270 fatal("Host directive not supported as a command-line "
1274 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1275 if ((flags & SSHCONF_NEVERMATCH) != 0)
1277 negated = *arg == '!';
1280 if (match_pattern(host, arg)) {
1282 debug("%.200s line %d: Skipping Host "
1283 "block because of negated match "
1284 "for %.100s", filename, linenum,
1290 arg2 = arg; /* logged below */
1295 debug("%.200s line %d: Applying options for %.100s",
1296 filename, linenum, arg2);
1297 /* Avoid garbage check below, as strdelim is done. */
1302 fatal("Host directive not supported as a command-line "
1304 value = match_cfg_line(options, &s, pw, host, original_host,
1305 flags & SSHCONF_POSTCANON, filename, linenum);
1307 fatal("%.200s line %d: Bad Match condition", filename,
1309 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1313 intptr = &options->escape_char;
1315 if (!arg || *arg == '\0')
1316 fatal("%.200s line %d: Missing argument.", filename, linenum);
1317 if (strcmp(arg, "none") == 0)
1318 value = SSH_ESCAPECHAR_NONE;
1319 else if (arg[1] == '\0')
1320 value = (u_char) arg[0];
1321 else if (arg[0] == '^' && arg[2] == 0 &&
1322 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1323 value = (u_char) arg[1] & 31;
1325 fatal("%.200s line %d: Bad escape character.",
1328 value = 0; /* Avoid compiler warning. */
1330 if (*activep && *intptr == -1)
1334 case oAddressFamily:
1335 intptr = &options->address_family;
1336 multistate_ptr = multistate_addressfamily;
1337 goto parse_multistate;
1339 case oEnableSSHKeysign:
1340 intptr = &options->enable_ssh_keysign;
1343 case oIdentitiesOnly:
1344 intptr = &options->identities_only;
1347 case oServerAliveInterval:
1348 intptr = &options->server_alive_interval;
1351 case oServerAliveCountMax:
1352 intptr = &options->server_alive_count_max;
1356 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1357 if (strchr(arg, '=') != NULL)
1358 fatal("%s line %d: Invalid environment name.",
1362 if (options->num_send_env >= MAX_SEND_ENV)
1363 fatal("%s line %d: too many send env.",
1365 options->send_env[options->num_send_env++] =
1371 charptr = &options->control_path;
1374 case oControlMaster:
1375 intptr = &options->control_master;
1376 multistate_ptr = multistate_controlmaster;
1377 goto parse_multistate;
1379 case oControlPersist:
1380 /* no/false/yes/true, or a time spec */
1381 intptr = &options->control_persist;
1383 if (!arg || *arg == '\0')
1384 fatal("%.200s line %d: Missing ControlPersist"
1385 " argument.", filename, linenum);
1387 value2 = 0; /* timeout */
1388 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1390 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1392 else if ((value2 = convtime(arg)) >= 0)
1395 fatal("%.200s line %d: Bad ControlPersist argument.",
1397 if (*activep && *intptr == -1) {
1399 options->control_persist_timeout = value2;
1403 case oHashKnownHosts:
1404 intptr = &options->hash_known_hosts;
1408 intptr = &options->tun_open;
1409 multistate_ptr = multistate_tunnel;
1410 goto parse_multistate;
1414 if (!arg || *arg == '\0')
1415 fatal("%.200s line %d: Missing argument.", filename, linenum);
1416 value = a2tun(arg, &value2);
1417 if (value == SSH_TUNID_ERR)
1418 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1420 options->tun_local = value;
1421 options->tun_remote = value2;
1426 charptr = &options->local_command;
1429 case oPermitLocalCommand:
1430 intptr = &options->permit_local_command;
1433 case oRemoteCommand:
1434 charptr = &options->remote_command;
1437 case oVisualHostKey:
1438 intptr = &options->visual_host_key;
1443 fatal("Include directive not supported as a "
1444 "command-line option");
1446 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1448 * Ensure all paths are anchored. User configuration
1449 * files may begin with '~/' but system configurations
1450 * must not. If the path is relative, then treat it
1451 * as living in ~/.ssh for user configurations or
1452 * /etc/ssh for system ones.
1454 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1455 fatal("%.200s line %d: bad include path %s.",
1456 filename, linenum, arg);
1457 if (*arg != '/' && *arg != '~') {
1458 xasprintf(&arg2, "%s/%s",
1459 (flags & SSHCONF_USERCONF) ?
1460 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1462 arg2 = xstrdup(arg);
1463 memset(&gl, 0, sizeof(gl));
1464 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1465 if (r == GLOB_NOMATCH) {
1466 debug("%.200s line %d: include %s matched no "
1467 "files",filename, linenum, arg2);
1470 } else if (r != 0 || gl.gl_pathc < 0)
1471 fatal("%.200s line %d: glob failed for %s.",
1472 filename, linenum, arg2);
1475 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1476 debug3("%.200s line %d: Including file %s "
1477 "depth %d%s", filename, linenum,
1478 gl.gl_pathv[i], depth,
1479 oactive ? "" : " (parse only)");
1480 r = read_config_file_depth(gl.gl_pathv[i],
1481 pw, host, original_host, options,
1482 flags | SSHCONF_CHECKPERM |
1483 (oactive ? 0 : SSHCONF_NEVERMATCH),
1484 activep, depth + 1);
1485 if (r != 1 && errno != ENOENT) {
1486 fatal("Can't open user config file "
1487 "%.100s: %.100s", gl.gl_pathv[i],
1491 * don't let Match in includes clobber the
1492 * containing file's Match state.
1506 if ((value = parse_ipqos(arg)) == -1)
1507 fatal("%s line %d: Bad IPQoS value: %s",
1508 filename, linenum, arg);
1512 else if ((value2 = parse_ipqos(arg)) == -1)
1513 fatal("%s line %d: Bad IPQoS value: %s",
1514 filename, linenum, arg);
1516 options->ip_qos_interactive = value;
1517 options->ip_qos_bulk = value2;
1522 intptr = &options->request_tty;
1523 multistate_ptr = multistate_requesttty;
1524 goto parse_multistate;
1526 case oIgnoreUnknown:
1527 charptr = &options->ignored_unknown;
1530 case oProxyUseFdpass:
1531 intptr = &options->proxy_use_fdpass;
1534 case oCanonicalDomains:
1535 value = options->num_canonical_domains != 0;
1536 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1537 if (!valid_domain(arg, 1, &errstr)) {
1538 fatal("%s line %d: %s", filename, linenum,
1541 if (!*activep || value)
1543 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1544 fatal("%s line %d: too many hostname suffixes.",
1546 options->canonical_domains[
1547 options->num_canonical_domains++] = xstrdup(arg);
1551 case oCanonicalizePermittedCNAMEs:
1552 value = options->num_permitted_cnames != 0;
1553 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1554 /* Either '*' for everything or 'list:list' */
1555 if (strcmp(arg, "*") == 0)
1559 if ((arg2 = strchr(arg, ':')) == NULL ||
1561 fatal("%s line %d: "
1562 "Invalid permitted CNAME \"%s\"",
1563 filename, linenum, arg);
1568 if (!*activep || value)
1570 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1571 fatal("%s line %d: too many permitted CNAMEs.",
1573 cname = options->permitted_cnames +
1574 options->num_permitted_cnames++;
1575 cname->source_list = xstrdup(arg);
1576 cname->target_list = xstrdup(arg2);
1580 case oCanonicalizeHostname:
1581 intptr = &options->canonicalize_hostname;
1582 multistate_ptr = multistate_canonicalizehostname;
1583 goto parse_multistate;
1585 case oCanonicalizeMaxDots:
1586 intptr = &options->canonicalize_max_dots;
1589 case oCanonicalizeFallbackLocal:
1590 intptr = &options->canonicalize_fallback_local;
1593 case oStreamLocalBindMask:
1595 if (!arg || *arg == '\0')
1596 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1597 /* Parse mode in octal format */
1598 value = strtol(arg, &endofnumber, 8);
1599 if (arg == endofnumber || value < 0 || value > 0777)
1600 fatal("%.200s line %d: Bad mask.", filename, linenum);
1601 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1604 case oStreamLocalBindUnlink:
1605 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1608 case oRevokedHostKeys:
1609 charptr = &options->revoked_host_keys;
1612 case oFingerprintHash:
1613 intptr = &options->fingerprint_hash;
1615 if (!arg || *arg == '\0')
1616 fatal("%.200s line %d: Missing argument.",
1618 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1619 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1620 filename, linenum, arg);
1621 if (*activep && *intptr == -1)
1625 case oUpdateHostkeys:
1626 intptr = &options->update_hostkeys;
1627 multistate_ptr = multistate_yesnoask;
1628 goto parse_multistate;
1630 case oHostbasedKeyTypes:
1631 charptr = &options->hostbased_key_types;
1632 goto parse_keytypes;
1634 case oPubkeyAcceptedKeyTypes:
1635 charptr = &options->pubkey_key_types;
1636 goto parse_keytypes;
1638 case oAddKeysToAgent:
1639 intptr = &options->add_keys_to_agent;
1640 multistate_ptr = multistate_yesnoaskconfirm;
1641 goto parse_multistate;
1643 case oIdentityAgent:
1644 charptr = &options->identity_agent;
1648 debug("%s line %d: Deprecated option \"%s\"",
1649 filename, linenum, keyword);
1653 error("%s line %d: Unsupported option \"%s\"",
1654 filename, linenum, keyword);
1658 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1661 /* Check that there is no garbage at end of line. */
1662 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1663 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1664 filename, linenum, arg);
1670 * Reads the config file and modifies the options accordingly. Options
1671 * should already be initialized before this call. This never returns if
1672 * there is an error. If the file does not exist, this returns 0.
1675 read_config_file(const char *filename, struct passwd *pw, const char *host,
1676 const char *original_host, Options *options, int flags)
1680 return read_config_file_depth(filename, pw, host, original_host,
1681 options, flags, &active, 0);
1684 #define READCONF_MAX_DEPTH 16
1686 read_config_file_depth(const char *filename, struct passwd *pw,
1687 const char *host, const char *original_host, Options *options,
1688 int flags, int *activep, int depth)
1693 int bad_options = 0;
1695 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1696 fatal("Too many recursive configuration includes");
1698 if ((f = fopen(filename, "r")) == NULL)
1701 if (flags & SSHCONF_CHECKPERM) {
1704 if (fstat(fileno(f), &sb) == -1)
1705 fatal("fstat %s: %s", filename, strerror(errno));
1706 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1707 (sb.st_mode & 022) != 0))
1708 fatal("Bad owner or permissions on %s", filename);
1711 debug("Reading configuration data %.200s", filename);
1714 * Mark that we are now processing the options. This flag is turned
1715 * on/off by Host specifications.
1718 while (fgets(line, sizeof(line), f)) {
1719 /* Update line number counter. */
1721 if (strlen(line) == sizeof(line) - 1)
1722 fatal("%s line %d too long", filename, linenum);
1723 if (process_config_line_depth(options, pw, host, original_host,
1724 line, filename, linenum, activep, flags, depth) != 0)
1728 if (bad_options > 0)
1729 fatal("%s: terminating, %d bad configuration options",
1730 filename, bad_options);
1734 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1736 option_clear_or_none(const char *o)
1738 return o == NULL || strcasecmp(o, "none") == 0;
1742 * Initializes options to special values that indicate that they have not yet
1743 * been set. Read_config_file will only set options with this value. Options
1744 * are processed in the following order: command line, user config file,
1745 * system config file. Last, fill_default_options is called.
1749 initialize_options(Options * options)
1751 memset(options, 'X', sizeof(*options));
1752 options->forward_agent = -1;
1753 options->forward_x11 = -1;
1754 options->forward_x11_trusted = -1;
1755 options->forward_x11_timeout = -1;
1756 options->stdio_forward_host = NULL;
1757 options->stdio_forward_port = 0;
1758 options->clear_forwardings = -1;
1759 options->exit_on_forward_failure = -1;
1760 options->xauth_location = NULL;
1761 options->fwd_opts.gateway_ports = -1;
1762 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1763 options->fwd_opts.streamlocal_bind_unlink = -1;
1764 options->use_privileged_port = -1;
1765 options->pubkey_authentication = -1;
1766 options->challenge_response_authentication = -1;
1767 options->gss_authentication = -1;
1768 options->gss_deleg_creds = -1;
1769 options->password_authentication = -1;
1770 options->kbd_interactive_authentication = -1;
1771 options->kbd_interactive_devices = NULL;
1772 options->hostbased_authentication = -1;
1773 options->batch_mode = -1;
1774 options->check_host_ip = -1;
1775 options->strict_host_key_checking = -1;
1776 options->compression = -1;
1777 options->tcp_keep_alive = -1;
1779 options->address_family = -1;
1780 options->connection_attempts = -1;
1781 options->connection_timeout = -1;
1782 options->number_of_password_prompts = -1;
1783 options->ciphers = NULL;
1784 options->macs = NULL;
1785 options->kex_algorithms = NULL;
1786 options->hostkeyalgorithms = NULL;
1787 options->num_identity_files = 0;
1788 options->num_certificate_files = 0;
1789 options->hostname = NULL;
1790 options->host_key_alias = NULL;
1791 options->proxy_command = NULL;
1792 options->jump_user = NULL;
1793 options->jump_host = NULL;
1794 options->jump_port = -1;
1795 options->jump_extra = NULL;
1796 options->user = NULL;
1797 options->escape_char = -1;
1798 options->num_system_hostfiles = 0;
1799 options->num_user_hostfiles = 0;
1800 options->local_forwards = NULL;
1801 options->num_local_forwards = 0;
1802 options->remote_forwards = NULL;
1803 options->num_remote_forwards = 0;
1804 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1805 options->log_level = SYSLOG_LEVEL_NOT_SET;
1806 options->preferred_authentications = NULL;
1807 options->bind_address = NULL;
1808 options->bind_interface = NULL;
1809 options->pkcs11_provider = NULL;
1810 options->enable_ssh_keysign = - 1;
1811 options->no_host_authentication_for_localhost = - 1;
1812 options->identities_only = - 1;
1813 options->rekey_limit = - 1;
1814 options->rekey_interval = -1;
1815 options->verify_host_key_dns = -1;
1816 options->server_alive_interval = -1;
1817 options->server_alive_count_max = -1;
1818 options->num_send_env = 0;
1819 options->control_path = NULL;
1820 options->control_master = -1;
1821 options->control_persist = -1;
1822 options->control_persist_timeout = 0;
1823 options->hash_known_hosts = -1;
1824 options->tun_open = -1;
1825 options->tun_local = -1;
1826 options->tun_remote = -1;
1827 options->local_command = NULL;
1828 options->permit_local_command = -1;
1829 options->remote_command = NULL;
1830 options->add_keys_to_agent = -1;
1831 options->identity_agent = NULL;
1832 options->visual_host_key = -1;
1833 options->ip_qos_interactive = -1;
1834 options->ip_qos_bulk = -1;
1835 options->request_tty = -1;
1836 options->proxy_use_fdpass = -1;
1837 options->ignored_unknown = NULL;
1838 options->num_canonical_domains = 0;
1839 options->num_permitted_cnames = 0;
1840 options->canonicalize_max_dots = -1;
1841 options->canonicalize_fallback_local = -1;
1842 options->canonicalize_hostname = -1;
1843 options->revoked_host_keys = NULL;
1844 options->fingerprint_hash = -1;
1845 options->update_hostkeys = -1;
1846 options->hostbased_key_types = NULL;
1847 options->pubkey_key_types = NULL;
1851 * A petite version of fill_default_options() that just fills the options
1852 * needed for hostname canonicalization to proceed.
1855 fill_default_options_for_canonicalization(Options *options)
1857 if (options->canonicalize_max_dots == -1)
1858 options->canonicalize_max_dots = 1;
1859 if (options->canonicalize_fallback_local == -1)
1860 options->canonicalize_fallback_local = 1;
1861 if (options->canonicalize_hostname == -1)
1862 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1866 * Called after processing other sources of option data, this fills those
1867 * options for which no value has been specified with their default values.
1870 fill_default_options(Options * options)
1872 if (options->forward_agent == -1)
1873 options->forward_agent = 0;
1874 if (options->forward_x11 == -1)
1875 options->forward_x11 = 0;
1876 if (options->forward_x11_trusted == -1)
1877 options->forward_x11_trusted = 0;
1878 if (options->forward_x11_timeout == -1)
1879 options->forward_x11_timeout = 1200;
1881 * stdio forwarding (-W) changes the default for these but we defer
1882 * setting the values so they can be overridden.
1884 if (options->exit_on_forward_failure == -1)
1885 options->exit_on_forward_failure =
1886 options->stdio_forward_host != NULL ? 1 : 0;
1887 if (options->clear_forwardings == -1)
1888 options->clear_forwardings =
1889 options->stdio_forward_host != NULL ? 1 : 0;
1890 if (options->clear_forwardings == 1)
1891 clear_forwardings(options);
1893 if (options->xauth_location == NULL)
1894 options->xauth_location = _PATH_XAUTH;
1895 if (options->fwd_opts.gateway_ports == -1)
1896 options->fwd_opts.gateway_ports = 0;
1897 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1898 options->fwd_opts.streamlocal_bind_mask = 0177;
1899 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1900 options->fwd_opts.streamlocal_bind_unlink = 0;
1901 if (options->use_privileged_port == -1)
1902 options->use_privileged_port = 0;
1903 if (options->pubkey_authentication == -1)
1904 options->pubkey_authentication = 1;
1905 if (options->challenge_response_authentication == -1)
1906 options->challenge_response_authentication = 1;
1907 if (options->gss_authentication == -1)
1908 options->gss_authentication = 0;
1909 if (options->gss_deleg_creds == -1)
1910 options->gss_deleg_creds = 0;
1911 if (options->password_authentication == -1)
1912 options->password_authentication = 1;
1913 if (options->kbd_interactive_authentication == -1)
1914 options->kbd_interactive_authentication = 1;
1915 if (options->hostbased_authentication == -1)
1916 options->hostbased_authentication = 0;
1917 if (options->batch_mode == -1)
1918 options->batch_mode = 0;
1919 if (options->check_host_ip == -1)
1920 options->check_host_ip = 1;
1921 if (options->strict_host_key_checking == -1)
1922 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
1923 if (options->compression == -1)
1924 options->compression = 0;
1925 if (options->tcp_keep_alive == -1)
1926 options->tcp_keep_alive = 1;
1927 if (options->port == -1)
1928 options->port = 0; /* Filled in ssh_connect. */
1929 if (options->address_family == -1)
1930 options->address_family = AF_UNSPEC;
1931 if (options->connection_attempts == -1)
1932 options->connection_attempts = 1;
1933 if (options->number_of_password_prompts == -1)
1934 options->number_of_password_prompts = 3;
1935 /* options->hostkeyalgorithms, default set in myproposals.h */
1936 if (options->add_keys_to_agent == -1)
1937 options->add_keys_to_agent = 0;
1938 if (options->num_identity_files == 0) {
1939 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
1940 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
1941 #ifdef OPENSSL_HAS_ECC
1942 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
1944 add_identity_file(options, "~/",
1945 _PATH_SSH_CLIENT_ID_ED25519, 0);
1946 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
1948 if (options->escape_char == -1)
1949 options->escape_char = '~';
1950 if (options->num_system_hostfiles == 0) {
1951 options->system_hostfiles[options->num_system_hostfiles++] =
1952 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1953 options->system_hostfiles[options->num_system_hostfiles++] =
1954 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1956 if (options->num_user_hostfiles == 0) {
1957 options->user_hostfiles[options->num_user_hostfiles++] =
1958 xstrdup(_PATH_SSH_USER_HOSTFILE);
1959 options->user_hostfiles[options->num_user_hostfiles++] =
1960 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1962 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1963 options->log_level = SYSLOG_LEVEL_INFO;
1964 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1965 options->log_facility = SYSLOG_FACILITY_USER;
1966 if (options->no_host_authentication_for_localhost == - 1)
1967 options->no_host_authentication_for_localhost = 0;
1968 if (options->identities_only == -1)
1969 options->identities_only = 0;
1970 if (options->enable_ssh_keysign == -1)
1971 options->enable_ssh_keysign = 0;
1972 if (options->rekey_limit == -1)
1973 options->rekey_limit = 0;
1974 if (options->rekey_interval == -1)
1975 options->rekey_interval = 0;
1976 if (options->verify_host_key_dns == -1)
1977 options->verify_host_key_dns = 0;
1978 if (options->server_alive_interval == -1)
1979 options->server_alive_interval = 0;
1980 if (options->server_alive_count_max == -1)
1981 options->server_alive_count_max = 3;
1982 if (options->control_master == -1)
1983 options->control_master = 0;
1984 if (options->control_persist == -1) {
1985 options->control_persist = 0;
1986 options->control_persist_timeout = 0;
1988 if (options->hash_known_hosts == -1)
1989 options->hash_known_hosts = 0;
1990 if (options->tun_open == -1)
1991 options->tun_open = SSH_TUNMODE_NO;
1992 if (options->tun_local == -1)
1993 options->tun_local = SSH_TUNID_ANY;
1994 if (options->tun_remote == -1)
1995 options->tun_remote = SSH_TUNID_ANY;
1996 if (options->permit_local_command == -1)
1997 options->permit_local_command = 0;
1998 if (options->visual_host_key == -1)
1999 options->visual_host_key = 0;
2000 if (options->ip_qos_interactive == -1)
2001 options->ip_qos_interactive = IPTOS_LOWDELAY;
2002 if (options->ip_qos_bulk == -1)
2003 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2004 if (options->request_tty == -1)
2005 options->request_tty = REQUEST_TTY_AUTO;
2006 if (options->proxy_use_fdpass == -1)
2007 options->proxy_use_fdpass = 0;
2008 if (options->canonicalize_max_dots == -1)
2009 options->canonicalize_max_dots = 1;
2010 if (options->canonicalize_fallback_local == -1)
2011 options->canonicalize_fallback_local = 1;
2012 if (options->canonicalize_hostname == -1)
2013 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2014 if (options->fingerprint_hash == -1)
2015 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2016 if (options->update_hostkeys == -1)
2017 options->update_hostkeys = 0;
2018 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2019 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2020 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2021 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2022 &options->hostbased_key_types) != 0 ||
2023 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2024 &options->pubkey_key_types) != 0)
2025 fatal("%s: kex_assemble_names failed", __func__);
2027 #define CLEAR_ON_NONE(v) \
2029 if (option_clear_or_none(v)) { \
2034 CLEAR_ON_NONE(options->local_command);
2035 CLEAR_ON_NONE(options->remote_command);
2036 CLEAR_ON_NONE(options->proxy_command);
2037 CLEAR_ON_NONE(options->control_path);
2038 CLEAR_ON_NONE(options->revoked_host_keys);
2039 /* options->identity_agent distinguishes NULL from 'none' */
2040 /* options->user will be set in the main program if appropriate */
2041 /* options->hostname will be set in the main program if appropriate */
2042 /* options->host_key_alias should not be set by default */
2043 /* options->preferred_authentications will be set in ssh */
2053 * parses the next field in a port forwarding specification.
2054 * sets fwd to the parsed field and advances p past the colon
2055 * or sets it to NULL at end of string.
2056 * returns 0 on success, else non-zero.
2059 parse_fwd_field(char **p, struct fwdarg *fwd)
2066 return -1; /* end of string */
2070 * A field escaped with square brackets is used literally.
2071 * XXX - allow ']' to be escaped via backslash?
2074 /* find matching ']' */
2075 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2079 /* no matching ']' or not at end of field. */
2080 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2082 /* NUL terminate the field and advance p past the colon */
2087 fwd->ispath = ispath;
2092 for (cp = *p; *cp != '\0'; cp++) {
2095 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2109 fwd->ispath = ispath;
2116 * parses a string containing a port forwarding specification of the form:
2118 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2119 * listenpath:connectpath
2121 * [listenhost:]listenport
2122 * returns number of arguments parsed or zero on error
2125 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2127 struct fwdarg fwdargs[4];
2131 memset(fwd, 0, sizeof(*fwd));
2132 memset(fwdargs, 0, sizeof(fwdargs));
2134 cp = p = xstrdup(fwdspec);
2136 /* skip leading spaces */
2137 while (isspace((u_char)*cp))
2140 for (i = 0; i < 4; ++i) {
2141 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2145 /* Check for trailing garbage */
2146 if (cp != NULL && *cp != '\0') {
2147 i = 0; /* failure */
2152 if (fwdargs[0].ispath) {
2153 fwd->listen_path = xstrdup(fwdargs[0].arg);
2154 fwd->listen_port = PORT_STREAMLOCAL;
2156 fwd->listen_host = NULL;
2157 fwd->listen_port = a2port(fwdargs[0].arg);
2159 fwd->connect_host = xstrdup("socks");
2163 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2164 fwd->listen_path = xstrdup(fwdargs[0].arg);
2165 fwd->listen_port = PORT_STREAMLOCAL;
2166 fwd->connect_path = xstrdup(fwdargs[1].arg);
2167 fwd->connect_port = PORT_STREAMLOCAL;
2168 } else if (fwdargs[1].ispath) {
2169 fwd->listen_host = NULL;
2170 fwd->listen_port = a2port(fwdargs[0].arg);
2171 fwd->connect_path = xstrdup(fwdargs[1].arg);
2172 fwd->connect_port = PORT_STREAMLOCAL;
2174 fwd->listen_host = xstrdup(fwdargs[0].arg);
2175 fwd->listen_port = a2port(fwdargs[1].arg);
2176 fwd->connect_host = xstrdup("socks");
2181 if (fwdargs[0].ispath) {
2182 fwd->listen_path = xstrdup(fwdargs[0].arg);
2183 fwd->listen_port = PORT_STREAMLOCAL;
2184 fwd->connect_host = xstrdup(fwdargs[1].arg);
2185 fwd->connect_port = a2port(fwdargs[2].arg);
2186 } else if (fwdargs[2].ispath) {
2187 fwd->listen_host = xstrdup(fwdargs[0].arg);
2188 fwd->listen_port = a2port(fwdargs[1].arg);
2189 fwd->connect_path = xstrdup(fwdargs[2].arg);
2190 fwd->connect_port = PORT_STREAMLOCAL;
2192 fwd->listen_host = NULL;
2193 fwd->listen_port = a2port(fwdargs[0].arg);
2194 fwd->connect_host = xstrdup(fwdargs[1].arg);
2195 fwd->connect_port = a2port(fwdargs[2].arg);
2200 fwd->listen_host = xstrdup(fwdargs[0].arg);
2201 fwd->listen_port = a2port(fwdargs[1].arg);
2202 fwd->connect_host = xstrdup(fwdargs[2].arg);
2203 fwd->connect_port = a2port(fwdargs[3].arg);
2206 i = 0; /* failure */
2212 if (!(i == 1 || i == 2))
2215 if (!(i == 3 || i == 4)) {
2216 if (fwd->connect_path == NULL &&
2217 fwd->listen_path == NULL)
2220 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2224 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2225 (!remotefwd && fwd->listen_port == 0))
2227 if (fwd->connect_host != NULL &&
2228 strlen(fwd->connect_host) >= NI_MAXHOST)
2230 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2231 if (fwd->connect_path != NULL &&
2232 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2234 if (fwd->listen_host != NULL &&
2235 strlen(fwd->listen_host) >= NI_MAXHOST)
2237 if (fwd->listen_path != NULL &&
2238 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2244 free(fwd->connect_host);
2245 fwd->connect_host = NULL;
2246 free(fwd->connect_path);
2247 fwd->connect_path = NULL;
2248 free(fwd->listen_host);
2249 fwd->listen_host = NULL;
2250 free(fwd->listen_path);
2251 fwd->listen_path = NULL;
2256 parse_jump(const char *s, Options *o, int active)
2258 char *orig, *sdup, *cp;
2259 char *host = NULL, *user = NULL;
2260 int ret = -1, port = -1, first;
2262 active &= o->proxy_command == NULL && o->jump_host == NULL;
2264 orig = sdup = xstrdup(s);
2267 if ((cp = strrchr(sdup, ',')) == NULL)
2268 cp = sdup; /* last */
2273 /* First argument and configuration is active */
2274 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2275 parse_user_host_port(cp, &user, &host, &port) != 0)
2278 /* Subsequent argument or inactive configuration */
2279 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2280 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2283 first = 0; /* only check syntax for subsequent hosts */
2284 } while (cp != sdup);
2287 o->jump_user = user;
2288 o->jump_host = host;
2289 o->jump_port = port;
2290 o->proxy_command = xstrdup("none");
2292 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2293 o->jump_extra = xstrdup(s);
2294 o->jump_extra[cp - s] = '\0';
2306 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2311 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2312 if (r == 0 && path != NULL)
2313 r = -1; /* path not allowed */
2317 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2319 fmt_multistate_int(int val, const struct multistate *m)
2323 for (i = 0; m[i].key != NULL; i++) {
2324 if (m[i].value == val)
2331 fmt_intarg(OpCodes code, int val)
2336 case oAddressFamily:
2337 return fmt_multistate_int(val, multistate_addressfamily);
2338 case oVerifyHostKeyDNS:
2339 case oUpdateHostkeys:
2340 return fmt_multistate_int(val, multistate_yesnoask);
2341 case oStrictHostKeyChecking:
2342 return fmt_multistate_int(val, multistate_strict_hostkey);
2343 case oControlMaster:
2344 return fmt_multistate_int(val, multistate_controlmaster);
2346 return fmt_multistate_int(val, multistate_tunnel);
2348 return fmt_multistate_int(val, multistate_requesttty);
2349 case oCanonicalizeHostname:
2350 return fmt_multistate_int(val, multistate_canonicalizehostname);
2351 case oFingerprintHash:
2352 return ssh_digest_alg_name(val);
2366 lookup_opcode_name(OpCodes code)
2370 for (i = 0; keywords[i].name != NULL; i++)
2371 if (keywords[i].opcode == code)
2372 return(keywords[i].name);
2377 dump_cfg_int(OpCodes code, int val)
2379 printf("%s %d\n", lookup_opcode_name(code), val);
2383 dump_cfg_fmtint(OpCodes code, int val)
2385 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2389 dump_cfg_string(OpCodes code, const char *val)
2393 printf("%s %s\n", lookup_opcode_name(code), val);
2397 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2401 for (i = 0; i < count; i++)
2402 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2406 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2410 printf("%s", lookup_opcode_name(code));
2411 for (i = 0; i < count; i++)
2412 printf(" %s", vals[i]);
2417 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2419 const struct Forward *fwd;
2422 /* oDynamicForward */
2423 for (i = 0; i < count; i++) {
2425 if (code == oDynamicForward && fwd->connect_host != NULL &&
2426 strcmp(fwd->connect_host, "socks") != 0)
2428 if (code == oLocalForward && fwd->connect_host != NULL &&
2429 strcmp(fwd->connect_host, "socks") == 0)
2431 printf("%s", lookup_opcode_name(code));
2432 if (fwd->listen_port == PORT_STREAMLOCAL)
2433 printf(" %s", fwd->listen_path);
2434 else if (fwd->listen_host == NULL)
2435 printf(" %d", fwd->listen_port);
2438 fwd->listen_host, fwd->listen_port);
2440 if (code != oDynamicForward) {
2441 if (fwd->connect_port == PORT_STREAMLOCAL)
2442 printf(" %s", fwd->connect_path);
2443 else if (fwd->connect_host == NULL)
2444 printf(" %d", fwd->connect_port);
2447 fwd->connect_host, fwd->connect_port);
2455 dump_client_config(Options *o, const char *host)
2460 /* This is normally prepared in ssh_kex2 */
2461 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2462 fatal("%s: kex_assemble_names failed", __func__);
2464 /* Most interesting options first: user, host, port */
2465 dump_cfg_string(oUser, o->user);
2466 dump_cfg_string(oHostName, host);
2467 dump_cfg_int(oPort, o->port);
2470 dump_cfg_fmtint(oAddressFamily, o->address_family);
2471 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2472 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2473 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2474 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2475 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2476 dump_cfg_fmtint(oCompression, o->compression);
2477 dump_cfg_fmtint(oControlMaster, o->control_master);
2478 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2479 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2480 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2481 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2482 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2483 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2484 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2485 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2487 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2488 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2490 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2491 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2492 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2493 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2494 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2495 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2496 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2497 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2498 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2499 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2500 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2501 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2502 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2503 dump_cfg_fmtint(oTunnel, o->tun_open);
2504 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2505 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2506 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2507 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2509 /* Integer options */
2510 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2511 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2512 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2513 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2514 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2515 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2517 /* String options */
2518 dump_cfg_string(oBindAddress, o->bind_address);
2519 dump_cfg_string(oBindInterface, o->bind_interface);
2520 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2521 dump_cfg_string(oControlPath, o->control_path);
2522 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2523 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2524 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2525 dump_cfg_string(oIdentityAgent, o->identity_agent);
2526 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2527 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2528 dump_cfg_string(oLocalCommand, o->local_command);
2529 dump_cfg_string(oRemoteCommand, o->remote_command);
2530 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2531 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2532 #ifdef ENABLE_PKCS11
2533 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2535 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2536 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2537 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2538 dump_cfg_string(oXAuthLocation, o->xauth_location);
2541 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2542 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2543 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2545 /* String array options */
2546 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2547 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2548 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2549 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2550 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2554 /* oConnectTimeout */
2555 if (o->connection_timeout == -1)
2556 printf("connecttimeout none\n");
2558 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2561 printf("tunneldevice");
2562 if (o->tun_local == SSH_TUNID_ANY)
2565 printf(" %d", o->tun_local);
2566 if (o->tun_remote == SSH_TUNID_ANY)
2569 printf(":%d", o->tun_remote);
2572 /* oCanonicalizePermittedCNAMEs */
2573 if ( o->num_permitted_cnames > 0) {
2574 printf("canonicalizePermittedcnames");
2575 for (i = 0; i < o->num_permitted_cnames; i++) {
2576 printf(" %s:%s", o->permitted_cnames[i].source_list,
2577 o->permitted_cnames[i].target_list);
2582 /* oControlPersist */
2583 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2584 dump_cfg_fmtint(oControlPersist, o->control_persist);
2586 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2589 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2590 printf("escapechar none\n");
2592 vis(buf, o->escape_char, VIS_WHITE, 0);
2593 printf("escapechar %s\n", buf);
2597 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2598 printf("%s\n", iptos2str(o->ip_qos_bulk));
2601 printf("rekeylimit %llu %d\n",
2602 (unsigned long long)o->rekey_limit, o->rekey_interval);
2604 /* oStreamLocalBindMask */
2605 printf("streamlocalbindmask 0%o\n",
2606 o->fwd_opts.streamlocal_bind_mask);
2608 /* oProxyCommand / oProxyJump */
2609 if (o->jump_host == NULL)
2610 dump_cfg_string(oProxyCommand, o->proxy_command);
2612 /* Check for numeric addresses */
2613 i = strchr(o->jump_host, ':') != NULL ||
2614 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2615 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2616 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2617 /* optional additional jump spec */
2618 o->jump_extra == NULL ? "" : o->jump_extra,
2619 o->jump_extra == NULL ? "" : ",",
2621 o->jump_user == NULL ? "" : o->jump_user,
2622 o->jump_user == NULL ? "" : "@",
2623 /* opening [ if hostname is numeric */
2625 /* mandatory hostname */
2627 /* closing ] if hostname is numeric */
2629 /* optional port number */
2630 o->jump_port <= 0 ? "" : ":",
2631 o->jump_port <= 0 ? "" : buf);