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".
18 #include <sys/types.h>
20 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
43 #ifdef USE_SYSTEM_GLOB
46 # include "openbsd-compat/glob.h"
51 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
59 #include "pathnames.h"
68 #include "myproposal.h"
72 /* Format of the configuration file:
74 # Configuration data is parsed as follows:
75 # 1. command line options
76 # 2. user-specific file
78 # Any configuration value is only changed the first time it is set.
79 # Thus, host-specific definitions should be at the beginning of the
80 # configuration file, and defaults at the end.
82 # Host-specific declarations. These may override anything above. A single
83 # host may match multiple declarations; these are processed in the order
84 # that they are given in.
90 HostName another.host.name.real.org
97 RemoteForward 9999 shadows.cs.hut.fi:9999
100 Host fascist.blob.com
103 PasswordAuthentication no
107 ProxyCommand ssh-proxy %h %p
110 PublicKeyAuthentication no
114 PasswordAuthentication no
120 # Defaults for various options
124 PasswordAuthentication yes
125 RSAAuthentication yes
126 RhostsRSAAuthentication yes
127 StrictHostKeyChecking yes
129 IdentityFile ~/.ssh/identity
135 static int read_config_file_depth(const char *filename, struct passwd *pw,
136 const char *host, const char *original_host, Options *options,
137 int flags, int *activep, int depth);
138 static int process_config_line_depth(Options *options, struct passwd *pw,
139 const char *host, const char *original_host, char *line,
140 const char *filename, int linenum, int *activep, int flags, int depth);
142 /* Keyword tokens. */
147 oHost, oMatch, oInclude,
148 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
149 oGatewayPorts, oExitOnForwardFailure,
150 oPasswordAuthentication, oRSAAuthentication,
151 oChallengeResponseAuthentication, oXAuthLocation,
152 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
153 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
154 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
155 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
156 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
157 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
158 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
159 oPubkeyAuthentication,
160 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
161 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
162 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
163 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
164 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
165 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
166 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
167 oSendEnv, oControlPath, oControlMaster, oControlPersist,
169 oTunnel, oTunnelDevice,
170 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
172 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
173 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
174 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
175 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
176 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
177 oPubkeyAcceptedKeyTypes, oProxyJump,
178 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
181 /* Textual representations of the tokens. */
187 /* Deprecated options */
188 { "protocol", oIgnore }, /* NB. silently ignored */
189 { "cipher", oDeprecated },
190 { "fallbacktorsh", oDeprecated },
191 { "globalknownhostsfile2", oDeprecated },
192 { "rhostsauthentication", oDeprecated },
193 { "userknownhostsfile2", oDeprecated },
194 { "useroaming", oDeprecated },
195 { "usersh", oDeprecated },
197 /* Unsupported options */
198 { "afstokenpassing", oUnsupported },
199 { "kerberosauthentication", oUnsupported },
200 { "kerberostgtpassing", oUnsupported },
202 /* Sometimes-unsupported options */
204 { "gssapiauthentication", oGssAuthentication },
205 { "gssapidelegatecredentials", oGssDelegateCreds },
207 { "gssapiauthentication", oUnsupported },
208 { "gssapidelegatecredentials", oUnsupported },
211 { "smartcarddevice", oPKCS11Provider },
212 { "pkcs11provider", oPKCS11Provider },
214 { "smartcarddevice", oUnsupported },
215 { "pkcs11provider", oUnsupported },
217 { "rsaauthentication", oUnsupported },
218 { "rhostsrsaauthentication", oUnsupported },
219 { "compressionlevel", oUnsupported },
221 { "forwardagent", oForwardAgent },
222 { "forwardx11", oForwardX11 },
223 { "forwardx11trusted", oForwardX11Trusted },
224 { "forwardx11timeout", oForwardX11Timeout },
225 { "exitonforwardfailure", oExitOnForwardFailure },
226 { "xauthlocation", oXAuthLocation },
227 { "gatewayports", oGatewayPorts },
228 { "useprivilegedport", oUsePrivilegedPort },
229 { "passwordauthentication", oPasswordAuthentication },
230 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
231 { "kbdinteractivedevices", oKbdInteractiveDevices },
232 { "pubkeyauthentication", oPubkeyAuthentication },
233 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
234 { "hostbasedauthentication", oHostbasedAuthentication },
235 { "challengeresponseauthentication", oChallengeResponseAuthentication },
236 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
237 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
238 { "identityfile", oIdentityFile },
239 { "identityfile2", oIdentityFile }, /* obsolete */
240 { "identitiesonly", oIdentitiesOnly },
241 { "certificatefile", oCertificateFile },
242 { "addkeystoagent", oAddKeysToAgent },
243 { "identityagent", oIdentityAgent },
244 { "hostname", oHostName },
245 { "hostkeyalias", oHostKeyAlias },
246 { "proxycommand", oProxyCommand },
248 { "ciphers", oCiphers },
250 { "remoteforward", oRemoteForward },
251 { "localforward", oLocalForward },
255 { "escapechar", oEscapeChar },
256 { "globalknownhostsfile", oGlobalKnownHostsFile },
257 { "userknownhostsfile", oUserKnownHostsFile },
258 { "connectionattempts", oConnectionAttempts },
259 { "batchmode", oBatchMode },
260 { "checkhostip", oCheckHostIP },
261 { "stricthostkeychecking", oStrictHostKeyChecking },
262 { "compression", oCompression },
263 { "tcpkeepalive", oTCPKeepAlive },
264 { "keepalive", oTCPKeepAlive }, /* obsolete */
265 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
266 { "syslogfacility", oLogFacility },
267 { "loglevel", oLogLevel },
268 { "dynamicforward", oDynamicForward },
269 { "preferredauthentications", oPreferredAuthentications },
270 { "hostkeyalgorithms", oHostKeyAlgorithms },
271 { "bindaddress", oBindAddress },
272 { "bindinterface", oBindInterface },
273 { "clearallforwardings", oClearAllForwardings },
274 { "enablesshkeysign", oEnableSSHKeysign },
275 { "verifyhostkeydns", oVerifyHostKeyDNS },
276 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
277 { "rekeylimit", oRekeyLimit },
278 { "connecttimeout", oConnectTimeout },
279 { "addressfamily", oAddressFamily },
280 { "serveraliveinterval", oServerAliveInterval },
281 { "serveralivecountmax", oServerAliveCountMax },
282 { "sendenv", oSendEnv },
283 { "controlpath", oControlPath },
284 { "controlmaster", oControlMaster },
285 { "controlpersist", oControlPersist },
286 { "hashknownhosts", oHashKnownHosts },
287 { "include", oInclude },
288 { "tunnel", oTunnel },
289 { "tunneldevice", oTunnelDevice },
290 { "localcommand", oLocalCommand },
291 { "permitlocalcommand", oPermitLocalCommand },
292 { "remotecommand", oRemoteCommand },
293 { "visualhostkey", oVisualHostKey },
294 { "kexalgorithms", oKexAlgorithms },
296 { "requesttty", oRequestTTY },
297 { "proxyusefdpass", oProxyUseFdpass },
298 { "canonicaldomains", oCanonicalDomains },
299 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
300 { "canonicalizehostname", oCanonicalizeHostname },
301 { "canonicalizemaxdots", oCanonicalizeMaxDots },
302 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
303 { "streamlocalbindmask", oStreamLocalBindMask },
304 { "streamlocalbindunlink", oStreamLocalBindUnlink },
305 { "revokedhostkeys", oRevokedHostKeys },
306 { "fingerprinthash", oFingerprintHash },
307 { "updatehostkeys", oUpdateHostkeys },
308 { "hostbasedkeytypes", oHostbasedKeyTypes },
309 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
310 { "ignoreunknown", oIgnoreUnknown },
311 { "proxyjump", oProxyJump },
313 { "hpndisabled", oDeprecated },
314 { "hpnbuffersize", oDeprecated },
315 { "tcprcvbufpoll", oDeprecated },
316 { "tcprcvbuf", oDeprecated },
317 { "noneenabled", oUnsupported },
318 { "noneswitch", oUnsupported },
319 { "versionaddendum", oVersionAddendum },
325 * Adds a local TCP/IP port forward to options. Never returns if there is an
330 add_local_forward(Options *options, const struct Forward *newfwd)
333 extern uid_t original_real_uid;
334 int i, ipport_reserved;
336 if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
337 newfwd->listen_path == NULL)
338 fatal("Privileged ports can only be forwarded by root.");
339 /* Don't add duplicates */
340 for (i = 0; i < options->num_local_forwards; i++) {
341 if (forward_equals(newfwd, options->local_forwards + i))
344 options->local_forwards = xreallocarray(options->local_forwards,
345 options->num_local_forwards + 1,
346 sizeof(*options->local_forwards));
347 fwd = &options->local_forwards[options->num_local_forwards++];
349 fwd->listen_host = newfwd->listen_host;
350 fwd->listen_port = newfwd->listen_port;
351 fwd->listen_path = newfwd->listen_path;
352 fwd->connect_host = newfwd->connect_host;
353 fwd->connect_port = newfwd->connect_port;
354 fwd->connect_path = newfwd->connect_path;
358 * Adds a remote TCP/IP port forward to options. Never returns if there is
363 add_remote_forward(Options *options, const struct Forward *newfwd)
368 /* Don't add duplicates */
369 for (i = 0; i < options->num_remote_forwards; i++) {
370 if (forward_equals(newfwd, options->remote_forwards + i))
373 options->remote_forwards = xreallocarray(options->remote_forwards,
374 options->num_remote_forwards + 1,
375 sizeof(*options->remote_forwards));
376 fwd = &options->remote_forwards[options->num_remote_forwards++];
378 fwd->listen_host = newfwd->listen_host;
379 fwd->listen_port = newfwd->listen_port;
380 fwd->listen_path = newfwd->listen_path;
381 fwd->connect_host = newfwd->connect_host;
382 fwd->connect_port = newfwd->connect_port;
383 fwd->connect_path = newfwd->connect_path;
384 fwd->handle = newfwd->handle;
385 fwd->allocated_port = 0;
389 clear_forwardings(Options *options)
393 for (i = 0; i < options->num_local_forwards; i++) {
394 free(options->local_forwards[i].listen_host);
395 free(options->local_forwards[i].listen_path);
396 free(options->local_forwards[i].connect_host);
397 free(options->local_forwards[i].connect_path);
399 if (options->num_local_forwards > 0) {
400 free(options->local_forwards);
401 options->local_forwards = NULL;
403 options->num_local_forwards = 0;
404 for (i = 0; i < options->num_remote_forwards; i++) {
405 free(options->remote_forwards[i].listen_host);
406 free(options->remote_forwards[i].listen_path);
407 free(options->remote_forwards[i].connect_host);
408 free(options->remote_forwards[i].connect_path);
410 if (options->num_remote_forwards > 0) {
411 free(options->remote_forwards);
412 options->remote_forwards = NULL;
414 options->num_remote_forwards = 0;
415 options->tun_open = SSH_TUNMODE_NO;
419 add_certificate_file(Options *options, const char *path, int userprovided)
423 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
424 fatal("Too many certificate files specified (max %d)",
425 SSH_MAX_CERTIFICATE_FILES);
427 /* Avoid registering duplicates */
428 for (i = 0; i < options->num_certificate_files; i++) {
429 if (options->certificate_file_userprovided[i] == userprovided &&
430 strcmp(options->certificate_files[i], path) == 0) {
431 debug2("%s: ignoring duplicate key %s", __func__, path);
436 options->certificate_file_userprovided[options->num_certificate_files] =
438 options->certificate_files[options->num_certificate_files++] =
443 add_identity_file(Options *options, const char *dir, const char *filename,
449 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
450 fatal("Too many identity files specified (max %d)",
451 SSH_MAX_IDENTITY_FILES);
453 if (dir == NULL) /* no dir, filename is absolute */
454 path = xstrdup(filename);
455 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
456 fatal("Identity file path %s too long", path);
458 /* Avoid registering duplicates */
459 for (i = 0; i < options->num_identity_files; i++) {
460 if (options->identity_file_userprovided[i] == userprovided &&
461 strcmp(options->identity_files[i], path) == 0) {
462 debug2("%s: ignoring duplicate key %s", __func__, path);
468 options->identity_file_userprovided[options->num_identity_files] =
470 options->identity_files[options->num_identity_files++] = path;
474 default_ssh_port(void)
480 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
481 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
487 * Execute a command in a shell.
488 * Return its exit status or -1 on abnormal exit.
491 execute_in_shell(const char *cmd)
496 extern uid_t original_real_uid;
498 if ((shell = getenv("SHELL")) == NULL)
499 shell = _PATH_BSHELL;
501 /* Need this to redirect subprocess stdin/out */
502 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
503 fatal("open(/dev/null): %s", strerror(errno));
505 debug("Executing command: '%.500s'", cmd);
507 /* Fork and execute the command. */
508 if ((pid = fork()) == 0) {
511 /* Child. Permanently give up superuser privileges. */
512 permanently_drop_suid(original_real_uid);
514 /* Redirect child stdin and stdout. Leave stderr */
515 if (dup2(devnull, STDIN_FILENO) == -1)
516 fatal("dup2: %s", strerror(errno));
517 if (dup2(devnull, STDOUT_FILENO) == -1)
518 fatal("dup2: %s", strerror(errno));
519 if (devnull > STDERR_FILENO)
521 closefrom(STDERR_FILENO + 1);
525 argv[2] = xstrdup(cmd);
528 execv(argv[0], argv);
529 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
530 /* Die with signal to make this error apparent to parent. */
531 signal(SIGTERM, SIG_DFL);
532 kill(getpid(), SIGTERM);
537 fatal("%s: fork: %.100s", __func__, strerror(errno));
541 while (waitpid(pid, &status, 0) == -1) {
542 if (errno != EINTR && errno != EAGAIN)
543 fatal("%s: waitpid: %s", __func__, strerror(errno));
545 if (!WIFEXITED(status)) {
546 error("command '%.100s' exited abnormally", cmd);
549 debug3("command returned status %d", WEXITSTATUS(status));
550 return WEXITSTATUS(status);
554 * Parse and execute a Match directive.
557 match_cfg_line(Options *options, char **condition, struct passwd *pw,
558 const char *host_arg, const char *original_host, int post_canon,
559 const char *filename, int linenum)
561 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
563 int r, port, this_result, result = 1, attributes = 0, negate;
564 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
567 * Configuration is likely to be incomplete at this point so we
568 * must be prepared to use default values.
570 port = options->port <= 0 ? default_ssh_port() : options->port;
571 ruser = options->user == NULL ? pw->pw_name : options->user;
573 host = xstrdup(options->hostname);
574 } else if (options->hostname != NULL) {
575 /* NB. Please keep in sync with ssh.c:main() */
576 host = percent_expand(options->hostname,
577 "h", host_arg, (char *)NULL);
579 host = xstrdup(host_arg);
582 debug2("checking match for '%s' host %s originally %s",
583 cp, host, original_host);
584 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
587 if ((negate = attrib[0] == '!'))
589 /* criteria "all" and "canonical" have no argument */
590 if (strcasecmp(attrib, "all") == 0) {
591 if (attributes > 1 ||
592 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
593 error("%.200s line %d: '%s' cannot be combined "
594 "with other Match attributes",
595 filename, linenum, oattrib);
600 result = negate ? 0 : 1;
604 if (strcasecmp(attrib, "canonical") == 0) {
605 r = !!post_canon; /* force bitmask member to boolean */
606 if (r == (negate ? 1 : 0))
607 this_result = result = 0;
608 debug3("%.200s line %d: %smatched '%s'",
610 this_result ? "" : "not ", oattrib);
613 /* All other criteria require an argument */
614 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
615 error("Missing Match criteria for %s", attrib);
619 if (strcasecmp(attrib, "host") == 0) {
620 criteria = xstrdup(host);
621 r = match_hostname(host, arg) == 1;
622 if (r == (negate ? 1 : 0))
623 this_result = result = 0;
624 } else if (strcasecmp(attrib, "originalhost") == 0) {
625 criteria = xstrdup(original_host);
626 r = match_hostname(original_host, arg) == 1;
627 if (r == (negate ? 1 : 0))
628 this_result = result = 0;
629 } else if (strcasecmp(attrib, "user") == 0) {
630 criteria = xstrdup(ruser);
631 r = match_pattern_list(ruser, arg, 0) == 1;
632 if (r == (negate ? 1 : 0))
633 this_result = result = 0;
634 } else if (strcasecmp(attrib, "localuser") == 0) {
635 criteria = xstrdup(pw->pw_name);
636 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
637 if (r == (negate ? 1 : 0))
638 this_result = result = 0;
639 } else if (strcasecmp(attrib, "exec") == 0) {
640 if (gethostname(thishost, sizeof(thishost)) == -1)
641 fatal("gethostname: %s", strerror(errno));
642 strlcpy(shorthost, thishost, sizeof(shorthost));
643 shorthost[strcspn(thishost, ".")] = '\0';
644 snprintf(portstr, sizeof(portstr), "%d", port);
646 cmd = percent_expand(arg,
657 /* skip execution if prior predicate failed */
658 debug3("%.200s line %d: skipped exec "
659 "\"%.100s\"", filename, linenum, cmd);
663 r = execute_in_shell(cmd);
665 fatal("%.200s line %d: match exec "
666 "'%.100s' error", filename,
669 criteria = xstrdup(cmd);
671 /* Force exit status to boolean */
673 if (r == (negate ? 1 : 0))
674 this_result = result = 0;
676 error("Unsupported Match attribute %s", attrib);
680 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
681 filename, linenum, this_result ? "": "not ",
685 if (attributes == 0) {
686 error("One or more attributes required for Match");
692 debug2("match %sfound", result ? "" : "not ");
699 * Returns the number of the token pointed to by cp or oBadOption.
702 parse_token(const char *cp, const char *filename, int linenum,
703 const char *ignored_unknown)
707 for (i = 0; keywords[i].name; i++)
708 if (strcmp(cp, keywords[i].name) == 0)
709 return keywords[i].opcode;
710 if (ignored_unknown != NULL &&
711 match_pattern_list(cp, ignored_unknown, 1) == 1)
712 return oIgnoredUnknownOption;
713 error("%s: line %d: Bad configuration option: %s",
714 filename, linenum, cp);
718 /* Multistate option parsing */
723 static const struct multistate multistate_flag[] = {
730 static const struct multistate multistate_yesnoask[] = {
738 static const struct multistate multistate_strict_hostkey[] = {
739 { "true", SSH_STRICT_HOSTKEY_YES },
740 { "false", SSH_STRICT_HOSTKEY_OFF },
741 { "yes", SSH_STRICT_HOSTKEY_YES },
742 { "no", SSH_STRICT_HOSTKEY_OFF },
743 { "ask", SSH_STRICT_HOSTKEY_ASK },
744 { "off", SSH_STRICT_HOSTKEY_OFF },
745 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
748 static const struct multistate multistate_yesnoaskconfirm[] = {
757 static const struct multistate multistate_addressfamily[] = {
759 { "inet6", AF_INET6 },
760 { "any", AF_UNSPEC },
763 static const struct multistate multistate_controlmaster[] = {
764 { "true", SSHCTL_MASTER_YES },
765 { "yes", SSHCTL_MASTER_YES },
766 { "false", SSHCTL_MASTER_NO },
767 { "no", SSHCTL_MASTER_NO },
768 { "auto", SSHCTL_MASTER_AUTO },
769 { "ask", SSHCTL_MASTER_ASK },
770 { "autoask", SSHCTL_MASTER_AUTO_ASK },
773 static const struct multistate multistate_tunnel[] = {
774 { "ethernet", SSH_TUNMODE_ETHERNET },
775 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
776 { "true", SSH_TUNMODE_DEFAULT },
777 { "yes", SSH_TUNMODE_DEFAULT },
778 { "false", SSH_TUNMODE_NO },
779 { "no", SSH_TUNMODE_NO },
782 static const struct multistate multistate_requesttty[] = {
783 { "true", REQUEST_TTY_YES },
784 { "yes", REQUEST_TTY_YES },
785 { "false", REQUEST_TTY_NO },
786 { "no", REQUEST_TTY_NO },
787 { "force", REQUEST_TTY_FORCE },
788 { "auto", REQUEST_TTY_AUTO },
791 static const struct multistate multistate_canonicalizehostname[] = {
792 { "true", SSH_CANONICALISE_YES },
793 { "false", SSH_CANONICALISE_NO },
794 { "yes", SSH_CANONICALISE_YES },
795 { "no", SSH_CANONICALISE_NO },
796 { "always", SSH_CANONICALISE_ALWAYS },
801 * Processes a single option line as used in the configuration files. This
802 * only sets those values that have not already been set.
805 process_config_line(Options *options, struct passwd *pw, const char *host,
806 const char *original_host, char *line, const char *filename,
807 int linenum, int *activep, int flags)
809 return process_config_line_depth(options, pw, host, original_host,
810 line, filename, linenum, activep, flags, 0);
813 #define WHITESPACE " \t\r\n"
815 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
816 const char *original_host, char *line, const char *filename,
817 int linenum, int *activep, int flags, int depth)
819 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
820 char **cpptr, fwdarg[256];
821 u_int i, *uintptr, max_entries = 0;
822 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
823 int remotefwd, dynamicfwd;
824 LogLevel *log_level_ptr;
825 SyslogFacility *log_facility_ptr;
829 const struct multistate *multistate_ptr;
830 struct allowed_cname *cname;
834 if (activep == NULL) { /* We are processing a command line directive */
839 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
840 if ((len = strlen(line)) == 0)
842 for (len--; len > 0; len--) {
843 if (strchr(WHITESPACE "\f", line[len]) == NULL)
849 /* Get the keyword. (Each line is supposed to begin with a keyword). */
850 if ((keyword = strdelim(&s)) == NULL)
852 /* Ignore leading whitespace. */
853 if (*keyword == '\0')
854 keyword = strdelim(&s);
855 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
857 /* Match lowercase keyword */
860 opcode = parse_token(keyword, filename, linenum,
861 options->ignored_unknown);
865 /* don't panic, but count bad options */
869 case oIgnoredUnknownOption:
870 debug("%s line %d: Ignored unknown option \"%s\"",
871 filename, linenum, keyword);
873 case oConnectTimeout:
874 intptr = &options->connection_timeout;
877 if (!arg || *arg == '\0')
878 fatal("%s line %d: missing time value.",
880 if (strcmp(arg, "none") == 0)
882 else if ((value = convtime(arg)) == -1)
883 fatal("%s line %d: invalid time value.",
885 if (*activep && *intptr == -1)
890 intptr = &options->forward_agent;
892 multistate_ptr = multistate_flag;
895 if (!arg || *arg == '\0')
896 fatal("%s line %d: missing argument.",
899 for (i = 0; multistate_ptr[i].key != NULL; i++) {
900 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
901 value = multistate_ptr[i].value;
906 fatal("%s line %d: unsupported option \"%s\".",
907 filename, linenum, arg);
908 if (*activep && *intptr == -1)
913 intptr = &options->forward_x11;
916 case oForwardX11Trusted:
917 intptr = &options->forward_x11_trusted;
920 case oForwardX11Timeout:
921 intptr = &options->forward_x11_timeout;
925 intptr = &options->fwd_opts.gateway_ports;
928 case oExitOnForwardFailure:
929 intptr = &options->exit_on_forward_failure;
932 case oUsePrivilegedPort:
933 intptr = &options->use_privileged_port;
936 case oPasswordAuthentication:
937 intptr = &options->password_authentication;
940 case oKbdInteractiveAuthentication:
941 intptr = &options->kbd_interactive_authentication;
944 case oKbdInteractiveDevices:
945 charptr = &options->kbd_interactive_devices;
948 case oPubkeyAuthentication:
949 intptr = &options->pubkey_authentication;
952 case oHostbasedAuthentication:
953 intptr = &options->hostbased_authentication;
956 case oChallengeResponseAuthentication:
957 intptr = &options->challenge_response_authentication;
960 case oGssAuthentication:
961 intptr = &options->gss_authentication;
964 case oGssDelegateCreds:
965 intptr = &options->gss_deleg_creds;
969 intptr = &options->batch_mode;
973 intptr = &options->check_host_ip;
976 case oVerifyHostKeyDNS:
977 intptr = &options->verify_host_key_dns;
978 multistate_ptr = multistate_yesnoask;
979 goto parse_multistate;
981 case oStrictHostKeyChecking:
982 intptr = &options->strict_host_key_checking;
983 multistate_ptr = multistate_strict_hostkey;
984 goto parse_multistate;
987 intptr = &options->compression;
991 intptr = &options->tcp_keep_alive;
994 case oNoHostAuthenticationForLocalhost:
995 intptr = &options->no_host_authentication_for_localhost;
998 case oNumberOfPasswordPrompts:
999 intptr = &options->number_of_password_prompts;
1004 if (!arg || *arg == '\0')
1005 fatal("%.200s line %d: Missing argument.", filename,
1007 if (strcmp(arg, "default") == 0) {
1010 if (scan_scaled(arg, &val64) == -1)
1011 fatal("%.200s line %d: Bad number '%s': %s",
1012 filename, linenum, arg, strerror(errno));
1013 if (val64 != 0 && val64 < 16)
1014 fatal("%.200s line %d: RekeyLimit too small",
1017 if (*activep && options->rekey_limit == -1)
1018 options->rekey_limit = val64;
1019 if (s != NULL) { /* optional rekey interval present */
1020 if (strcmp(s, "none") == 0) {
1021 (void)strdelim(&s); /* discard */
1024 intptr = &options->rekey_interval;
1031 if (!arg || *arg == '\0')
1032 fatal("%.200s line %d: Missing argument.", filename, linenum);
1034 intptr = &options->num_identity_files;
1035 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1036 fatal("%.200s line %d: Too many identity files specified (max %d).",
1037 filename, linenum, SSH_MAX_IDENTITY_FILES);
1038 add_identity_file(options, NULL,
1039 arg, flags & SSHCONF_USERCONF);
1043 case oCertificateFile:
1045 if (!arg || *arg == '\0')
1046 fatal("%.200s line %d: Missing argument.",
1049 intptr = &options->num_certificate_files;
1050 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1051 fatal("%.200s line %d: Too many certificate "
1052 "files specified (max %d).",
1054 SSH_MAX_CERTIFICATE_FILES);
1056 add_certificate_file(options, arg,
1057 flags & SSHCONF_USERCONF);
1061 case oXAuthLocation:
1062 charptr=&options->xauth_location;
1066 charptr = &options->user;
1069 if (!arg || *arg == '\0')
1070 fatal("%.200s line %d: Missing argument.",
1072 if (*activep && *charptr == NULL)
1073 *charptr = xstrdup(arg);
1076 case oGlobalKnownHostsFile:
1077 cpptr = (char **)&options->system_hostfiles;
1078 uintptr = &options->num_system_hostfiles;
1079 max_entries = SSH_MAX_HOSTS_FILES;
1081 if (*activep && *uintptr == 0) {
1082 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1083 if ((*uintptr) >= max_entries)
1084 fatal("%s line %d: "
1085 "too many authorized keys files.",
1087 cpptr[(*uintptr)++] = xstrdup(arg);
1092 case oUserKnownHostsFile:
1093 cpptr = (char **)&options->user_hostfiles;
1094 uintptr = &options->num_user_hostfiles;
1095 max_entries = SSH_MAX_HOSTS_FILES;
1096 goto parse_char_array;
1099 charptr = &options->hostname;
1103 charptr = &options->host_key_alias;
1106 case oPreferredAuthentications:
1107 charptr = &options->preferred_authentications;
1111 charptr = &options->bind_address;
1114 case oBindInterface:
1115 charptr = &options->bind_interface;
1118 case oPKCS11Provider:
1119 charptr = &options->pkcs11_provider;
1123 charptr = &options->proxy_command;
1124 /* Ignore ProxyCommand if ProxyJump already specified */
1125 if (options->jump_host != NULL)
1126 charptr = &options->jump_host; /* Skip below */
1129 fatal("%.200s line %d: Missing argument.", filename, linenum);
1130 len = strspn(s, WHITESPACE "=");
1131 if (*activep && *charptr == NULL)
1132 *charptr = xstrdup(s + len);
1137 fatal("%.200s line %d: Missing argument.",
1140 len = strspn(s, WHITESPACE "=");
1141 if (parse_jump(s + len, options, *activep) == -1) {
1142 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1143 filename, linenum, s + len);
1148 intptr = &options->port;
1151 if ((errstr = atoi_err(arg, &value)) != NULL)
1152 fatal("%s line %d: integer value %s.",
1153 filename, linenum, errstr);
1154 if (*activep && *intptr == -1)
1158 case oConnectionAttempts:
1159 intptr = &options->connection_attempts;
1164 if (!arg || *arg == '\0')
1165 fatal("%.200s line %d: Missing argument.", filename, linenum);
1166 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1167 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1168 filename, linenum, arg ? arg : "<NONE>");
1169 if (*activep && options->ciphers == NULL)
1170 options->ciphers = xstrdup(arg);
1175 if (!arg || *arg == '\0')
1176 fatal("%.200s line %d: Missing argument.", filename, linenum);
1177 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1178 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1179 filename, linenum, arg ? arg : "<NONE>");
1180 if (*activep && options->macs == NULL)
1181 options->macs = xstrdup(arg);
1184 case oKexAlgorithms:
1186 if (!arg || *arg == '\0')
1187 fatal("%.200s line %d: Missing argument.",
1190 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1191 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1192 filename, linenum, arg ? arg : "<NONE>");
1193 if (*activep && options->kex_algorithms == NULL)
1194 options->kex_algorithms = xstrdup(arg);
1197 case oHostKeyAlgorithms:
1198 charptr = &options->hostkeyalgorithms;
1201 if (!arg || *arg == '\0')
1202 fatal("%.200s line %d: Missing argument.",
1205 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1206 fatal("%s line %d: Bad key types '%s'.",
1207 filename, linenum, arg ? arg : "<NONE>");
1208 if (*activep && *charptr == NULL)
1209 *charptr = xstrdup(arg);
1213 log_level_ptr = &options->log_level;
1215 value = log_level_number(arg);
1216 if (value == SYSLOG_LEVEL_NOT_SET)
1217 fatal("%.200s line %d: unsupported log level '%s'",
1218 filename, linenum, arg ? arg : "<NONE>");
1219 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1220 *log_level_ptr = (LogLevel) value;
1224 log_facility_ptr = &options->log_facility;
1226 value = log_facility_number(arg);
1227 if (value == SYSLOG_FACILITY_NOT_SET)
1228 fatal("%.200s line %d: unsupported log facility '%s'",
1229 filename, linenum, arg ? arg : "<NONE>");
1230 if (*log_facility_ptr == -1)
1231 *log_facility_ptr = (SyslogFacility) value;
1235 case oRemoteForward:
1236 case oDynamicForward:
1238 if (arg == NULL || *arg == '\0')
1239 fatal("%.200s line %d: Missing port argument.",
1242 remotefwd = (opcode == oRemoteForward);
1243 dynamicfwd = (opcode == oDynamicForward);
1246 arg2 = strdelim(&s);
1247 if (arg2 == NULL || *arg2 == '\0') {
1251 fatal("%.200s line %d: Missing target "
1252 "argument.", filename, linenum);
1254 /* construct a string for parse_forward */
1255 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1260 strlcpy(fwdarg, arg, sizeof(fwdarg));
1262 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1263 fatal("%.200s line %d: Bad forwarding specification.",
1268 add_remote_forward(options, &fwd);
1270 add_local_forward(options, &fwd);
1275 case oClearAllForwardings:
1276 intptr = &options->clear_forwardings;
1281 fatal("Host directive not supported as a command-line "
1285 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1286 if ((flags & SSHCONF_NEVERMATCH) != 0)
1288 negated = *arg == '!';
1291 if (match_pattern(host, arg)) {
1293 debug("%.200s line %d: Skipping Host "
1294 "block because of negated match "
1295 "for %.100s", filename, linenum,
1301 arg2 = arg; /* logged below */
1306 debug("%.200s line %d: Applying options for %.100s",
1307 filename, linenum, arg2);
1308 /* Avoid garbage check below, as strdelim is done. */
1313 fatal("Host directive not supported as a command-line "
1315 value = match_cfg_line(options, &s, pw, host, original_host,
1316 flags & SSHCONF_POSTCANON, filename, linenum);
1318 fatal("%.200s line %d: Bad Match condition", filename,
1320 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1324 intptr = &options->escape_char;
1326 if (!arg || *arg == '\0')
1327 fatal("%.200s line %d: Missing argument.", filename, linenum);
1328 if (strcmp(arg, "none") == 0)
1329 value = SSH_ESCAPECHAR_NONE;
1330 else if (arg[1] == '\0')
1331 value = (u_char) arg[0];
1332 else if (arg[0] == '^' && arg[2] == 0 &&
1333 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1334 value = (u_char) arg[1] & 31;
1336 fatal("%.200s line %d: Bad escape character.",
1339 value = 0; /* Avoid compiler warning. */
1341 if (*activep && *intptr == -1)
1345 case oAddressFamily:
1346 intptr = &options->address_family;
1347 multistate_ptr = multistate_addressfamily;
1348 goto parse_multistate;
1350 case oEnableSSHKeysign:
1351 intptr = &options->enable_ssh_keysign;
1354 case oIdentitiesOnly:
1355 intptr = &options->identities_only;
1358 case oServerAliveInterval:
1359 intptr = &options->server_alive_interval;
1362 case oServerAliveCountMax:
1363 intptr = &options->server_alive_count_max;
1367 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1368 if (strchr(arg, '=') != NULL)
1369 fatal("%s line %d: Invalid environment name.",
1373 if (options->num_send_env >= MAX_SEND_ENV)
1374 fatal("%s line %d: too many send env.",
1376 options->send_env[options->num_send_env++] =
1382 charptr = &options->control_path;
1385 case oControlMaster:
1386 intptr = &options->control_master;
1387 multistate_ptr = multistate_controlmaster;
1388 goto parse_multistate;
1390 case oControlPersist:
1391 /* no/false/yes/true, or a time spec */
1392 intptr = &options->control_persist;
1394 if (!arg || *arg == '\0')
1395 fatal("%.200s line %d: Missing ControlPersist"
1396 " argument.", filename, linenum);
1398 value2 = 0; /* timeout */
1399 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1401 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1403 else if ((value2 = convtime(arg)) >= 0)
1406 fatal("%.200s line %d: Bad ControlPersist argument.",
1408 if (*activep && *intptr == -1) {
1410 options->control_persist_timeout = value2;
1414 case oHashKnownHosts:
1415 intptr = &options->hash_known_hosts;
1419 intptr = &options->tun_open;
1420 multistate_ptr = multistate_tunnel;
1421 goto parse_multistate;
1425 if (!arg || *arg == '\0')
1426 fatal("%.200s line %d: Missing argument.", filename, linenum);
1427 value = a2tun(arg, &value2);
1428 if (value == SSH_TUNID_ERR)
1429 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1431 options->tun_local = value;
1432 options->tun_remote = value2;
1437 charptr = &options->local_command;
1440 case oPermitLocalCommand:
1441 intptr = &options->permit_local_command;
1444 case oRemoteCommand:
1445 charptr = &options->remote_command;
1448 case oVisualHostKey:
1449 intptr = &options->visual_host_key;
1454 fatal("Include directive not supported as a "
1455 "command-line option");
1457 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1459 * Ensure all paths are anchored. User configuration
1460 * files may begin with '~/' but system configurations
1461 * must not. If the path is relative, then treat it
1462 * as living in ~/.ssh for user configurations or
1463 * /etc/ssh for system ones.
1465 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1466 fatal("%.200s line %d: bad include path %s.",
1467 filename, linenum, arg);
1468 if (*arg != '/' && *arg != '~') {
1469 xasprintf(&arg2, "%s/%s",
1470 (flags & SSHCONF_USERCONF) ?
1471 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1473 arg2 = xstrdup(arg);
1474 memset(&gl, 0, sizeof(gl));
1475 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1476 if (r == GLOB_NOMATCH) {
1477 debug("%.200s line %d: include %s matched no "
1478 "files",filename, linenum, arg2);
1481 } else if (r != 0 || gl.gl_pathc < 0)
1482 fatal("%.200s line %d: glob failed for %s.",
1483 filename, linenum, arg2);
1486 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1487 debug3("%.200s line %d: Including file %s "
1488 "depth %d%s", filename, linenum,
1489 gl.gl_pathv[i], depth,
1490 oactive ? "" : " (parse only)");
1491 r = read_config_file_depth(gl.gl_pathv[i],
1492 pw, host, original_host, options,
1493 flags | SSHCONF_CHECKPERM |
1494 (oactive ? 0 : SSHCONF_NEVERMATCH),
1495 activep, depth + 1);
1496 if (r != 1 && errno != ENOENT) {
1497 fatal("Can't open user config file "
1498 "%.100s: %.100s", gl.gl_pathv[i],
1502 * don't let Match in includes clobber the
1503 * containing file's Match state.
1517 if ((value = parse_ipqos(arg)) == -1)
1518 fatal("%s line %d: Bad IPQoS value: %s",
1519 filename, linenum, arg);
1523 else if ((value2 = parse_ipqos(arg)) == -1)
1524 fatal("%s line %d: Bad IPQoS value: %s",
1525 filename, linenum, arg);
1527 options->ip_qos_interactive = value;
1528 options->ip_qos_bulk = value2;
1533 intptr = &options->request_tty;
1534 multistate_ptr = multistate_requesttty;
1535 goto parse_multistate;
1537 case oVersionAddendum:
1539 fatal("%.200s line %d: Missing argument.", filename,
1541 len = strspn(s, WHITESPACE);
1542 if (*activep && options->version_addendum == NULL) {
1543 if (strcasecmp(s + len, "none") == 0)
1544 options->version_addendum = xstrdup("");
1545 else if (strchr(s + len, '\r') != NULL)
1546 fatal("%.200s line %d: Invalid argument",
1549 options->version_addendum = xstrdup(s + len);
1553 case oIgnoreUnknown:
1554 charptr = &options->ignored_unknown;
1557 case oProxyUseFdpass:
1558 intptr = &options->proxy_use_fdpass;
1561 case oCanonicalDomains:
1562 value = options->num_canonical_domains != 0;
1563 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1564 if (!valid_domain(arg, 1, &errstr)) {
1565 fatal("%s line %d: %s", filename, linenum,
1568 if (!*activep || value)
1570 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1571 fatal("%s line %d: too many hostname suffixes.",
1573 options->canonical_domains[
1574 options->num_canonical_domains++] = xstrdup(arg);
1578 case oCanonicalizePermittedCNAMEs:
1579 value = options->num_permitted_cnames != 0;
1580 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1581 /* Either '*' for everything or 'list:list' */
1582 if (strcmp(arg, "*") == 0)
1586 if ((arg2 = strchr(arg, ':')) == NULL ||
1588 fatal("%s line %d: "
1589 "Invalid permitted CNAME \"%s\"",
1590 filename, linenum, arg);
1595 if (!*activep || value)
1597 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1598 fatal("%s line %d: too many permitted CNAMEs.",
1600 cname = options->permitted_cnames +
1601 options->num_permitted_cnames++;
1602 cname->source_list = xstrdup(arg);
1603 cname->target_list = xstrdup(arg2);
1607 case oCanonicalizeHostname:
1608 intptr = &options->canonicalize_hostname;
1609 multistate_ptr = multistate_canonicalizehostname;
1610 goto parse_multistate;
1612 case oCanonicalizeMaxDots:
1613 intptr = &options->canonicalize_max_dots;
1616 case oCanonicalizeFallbackLocal:
1617 intptr = &options->canonicalize_fallback_local;
1620 case oStreamLocalBindMask:
1622 if (!arg || *arg == '\0')
1623 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1624 /* Parse mode in octal format */
1625 value = strtol(arg, &endofnumber, 8);
1626 if (arg == endofnumber || value < 0 || value > 0777)
1627 fatal("%.200s line %d: Bad mask.", filename, linenum);
1628 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1631 case oStreamLocalBindUnlink:
1632 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1635 case oRevokedHostKeys:
1636 charptr = &options->revoked_host_keys;
1639 case oFingerprintHash:
1640 intptr = &options->fingerprint_hash;
1642 if (!arg || *arg == '\0')
1643 fatal("%.200s line %d: Missing argument.",
1645 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1646 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1647 filename, linenum, arg);
1648 if (*activep && *intptr == -1)
1652 case oUpdateHostkeys:
1653 intptr = &options->update_hostkeys;
1654 multistate_ptr = multistate_yesnoask;
1655 goto parse_multistate;
1657 case oHostbasedKeyTypes:
1658 charptr = &options->hostbased_key_types;
1659 goto parse_keytypes;
1661 case oPubkeyAcceptedKeyTypes:
1662 charptr = &options->pubkey_key_types;
1663 goto parse_keytypes;
1665 case oAddKeysToAgent:
1666 intptr = &options->add_keys_to_agent;
1667 multistate_ptr = multistate_yesnoaskconfirm;
1668 goto parse_multistate;
1670 case oIdentityAgent:
1671 charptr = &options->identity_agent;
1675 debug("%s line %d: Deprecated option \"%s\"",
1676 filename, linenum, keyword);
1680 error("%s line %d: Unsupported option \"%s\"",
1681 filename, linenum, keyword);
1685 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1688 /* Check that there is no garbage at end of line. */
1689 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1690 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1691 filename, linenum, arg);
1697 * Reads the config file and modifies the options accordingly. Options
1698 * should already be initialized before this call. This never returns if
1699 * there is an error. If the file does not exist, this returns 0.
1702 read_config_file(const char *filename, struct passwd *pw, const char *host,
1703 const char *original_host, Options *options, int flags)
1707 return read_config_file_depth(filename, pw, host, original_host,
1708 options, flags, &active, 0);
1711 #define READCONF_MAX_DEPTH 16
1713 read_config_file_depth(const char *filename, struct passwd *pw,
1714 const char *host, const char *original_host, Options *options,
1715 int flags, int *activep, int depth)
1720 int bad_options = 0;
1722 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1723 fatal("Too many recursive configuration includes");
1725 if ((f = fopen(filename, "r")) == NULL)
1728 if (flags & SSHCONF_CHECKPERM) {
1731 if (fstat(fileno(f), &sb) == -1)
1732 fatal("fstat %s: %s", filename, strerror(errno));
1733 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1734 (sb.st_mode & 022) != 0))
1735 fatal("Bad owner or permissions on %s", filename);
1738 debug("Reading configuration data %.200s", filename);
1741 * Mark that we are now processing the options. This flag is turned
1742 * on/off by Host specifications.
1745 while (fgets(line, sizeof(line), f)) {
1746 /* Update line number counter. */
1748 if (strlen(line) == sizeof(line) - 1)
1749 fatal("%s line %d too long", filename, linenum);
1750 if (process_config_line_depth(options, pw, host, original_host,
1751 line, filename, linenum, activep, flags, depth) != 0)
1755 if (bad_options > 0)
1756 fatal("%s: terminating, %d bad configuration options",
1757 filename, bad_options);
1761 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1763 option_clear_or_none(const char *o)
1765 return o == NULL || strcasecmp(o, "none") == 0;
1769 * Initializes options to special values that indicate that they have not yet
1770 * been set. Read_config_file will only set options with this value. Options
1771 * are processed in the following order: command line, user config file,
1772 * system config file. Last, fill_default_options is called.
1776 initialize_options(Options * options)
1778 memset(options, 'X', sizeof(*options));
1779 options->version_addendum = NULL;
1780 options->forward_agent = -1;
1781 options->forward_x11 = -1;
1782 options->forward_x11_trusted = -1;
1783 options->forward_x11_timeout = -1;
1784 options->stdio_forward_host = NULL;
1785 options->stdio_forward_port = 0;
1786 options->clear_forwardings = -1;
1787 options->exit_on_forward_failure = -1;
1788 options->xauth_location = NULL;
1789 options->fwd_opts.gateway_ports = -1;
1790 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1791 options->fwd_opts.streamlocal_bind_unlink = -1;
1792 options->use_privileged_port = -1;
1793 options->pubkey_authentication = -1;
1794 options->challenge_response_authentication = -1;
1795 options->gss_authentication = -1;
1796 options->gss_deleg_creds = -1;
1797 options->password_authentication = -1;
1798 options->kbd_interactive_authentication = -1;
1799 options->kbd_interactive_devices = NULL;
1800 options->hostbased_authentication = -1;
1801 options->batch_mode = -1;
1802 options->check_host_ip = -1;
1803 options->strict_host_key_checking = -1;
1804 options->compression = -1;
1805 options->tcp_keep_alive = -1;
1807 options->address_family = -1;
1808 options->connection_attempts = -1;
1809 options->connection_timeout = -1;
1810 options->number_of_password_prompts = -1;
1811 options->ciphers = NULL;
1812 options->macs = NULL;
1813 options->kex_algorithms = NULL;
1814 options->hostkeyalgorithms = NULL;
1815 options->num_identity_files = 0;
1816 options->num_certificate_files = 0;
1817 options->hostname = NULL;
1818 options->host_key_alias = NULL;
1819 options->proxy_command = NULL;
1820 options->jump_user = NULL;
1821 options->jump_host = NULL;
1822 options->jump_port = -1;
1823 options->jump_extra = NULL;
1824 options->user = NULL;
1825 options->escape_char = -1;
1826 options->num_system_hostfiles = 0;
1827 options->num_user_hostfiles = 0;
1828 options->local_forwards = NULL;
1829 options->num_local_forwards = 0;
1830 options->remote_forwards = NULL;
1831 options->num_remote_forwards = 0;
1832 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1833 options->log_level = SYSLOG_LEVEL_NOT_SET;
1834 options->preferred_authentications = NULL;
1835 options->bind_address = NULL;
1836 options->bind_interface = NULL;
1837 options->pkcs11_provider = NULL;
1838 options->enable_ssh_keysign = - 1;
1839 options->no_host_authentication_for_localhost = - 1;
1840 options->identities_only = - 1;
1841 options->rekey_limit = - 1;
1842 options->rekey_interval = -1;
1843 options->verify_host_key_dns = -1;
1844 options->server_alive_interval = -1;
1845 options->server_alive_count_max = -1;
1846 options->num_send_env = 0;
1847 options->control_path = NULL;
1848 options->control_master = -1;
1849 options->control_persist = -1;
1850 options->control_persist_timeout = 0;
1851 options->hash_known_hosts = -1;
1852 options->tun_open = -1;
1853 options->tun_local = -1;
1854 options->tun_remote = -1;
1855 options->local_command = NULL;
1856 options->permit_local_command = -1;
1857 options->remote_command = NULL;
1858 options->add_keys_to_agent = -1;
1859 options->identity_agent = NULL;
1860 options->visual_host_key = -1;
1861 options->ip_qos_interactive = -1;
1862 options->ip_qos_bulk = -1;
1863 options->request_tty = -1;
1864 options->proxy_use_fdpass = -1;
1865 options->ignored_unknown = NULL;
1866 options->num_canonical_domains = 0;
1867 options->num_permitted_cnames = 0;
1868 options->canonicalize_max_dots = -1;
1869 options->canonicalize_fallback_local = -1;
1870 options->canonicalize_hostname = -1;
1871 options->revoked_host_keys = NULL;
1872 options->fingerprint_hash = -1;
1873 options->update_hostkeys = -1;
1874 options->hostbased_key_types = NULL;
1875 options->pubkey_key_types = NULL;
1879 * A petite version of fill_default_options() that just fills the options
1880 * needed for hostname canonicalization to proceed.
1883 fill_default_options_for_canonicalization(Options *options)
1885 if (options->canonicalize_max_dots == -1)
1886 options->canonicalize_max_dots = 1;
1887 if (options->canonicalize_fallback_local == -1)
1888 options->canonicalize_fallback_local = 1;
1889 if (options->canonicalize_hostname == -1)
1890 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1894 * Called after processing other sources of option data, this fills those
1895 * options for which no value has been specified with their default values.
1898 fill_default_options(Options * options)
1900 if (options->forward_agent == -1)
1901 options->forward_agent = 0;
1902 if (options->forward_x11 == -1)
1903 options->forward_x11 = 0;
1904 if (options->forward_x11_trusted == -1)
1905 options->forward_x11_trusted = 0;
1906 if (options->forward_x11_timeout == -1)
1907 options->forward_x11_timeout = 1200;
1909 * stdio forwarding (-W) changes the default for these but we defer
1910 * setting the values so they can be overridden.
1912 if (options->exit_on_forward_failure == -1)
1913 options->exit_on_forward_failure =
1914 options->stdio_forward_host != NULL ? 1 : 0;
1915 if (options->clear_forwardings == -1)
1916 options->clear_forwardings =
1917 options->stdio_forward_host != NULL ? 1 : 0;
1918 if (options->clear_forwardings == 1)
1919 clear_forwardings(options);
1921 if (options->xauth_location == NULL)
1922 options->xauth_location = _PATH_XAUTH;
1923 if (options->fwd_opts.gateway_ports == -1)
1924 options->fwd_opts.gateway_ports = 0;
1925 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1926 options->fwd_opts.streamlocal_bind_mask = 0177;
1927 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1928 options->fwd_opts.streamlocal_bind_unlink = 0;
1929 if (options->use_privileged_port == -1)
1930 options->use_privileged_port = 0;
1931 if (options->pubkey_authentication == -1)
1932 options->pubkey_authentication = 1;
1933 if (options->challenge_response_authentication == -1)
1934 options->challenge_response_authentication = 1;
1935 if (options->gss_authentication == -1)
1936 options->gss_authentication = 0;
1937 if (options->gss_deleg_creds == -1)
1938 options->gss_deleg_creds = 0;
1939 if (options->password_authentication == -1)
1940 options->password_authentication = 1;
1941 if (options->kbd_interactive_authentication == -1)
1942 options->kbd_interactive_authentication = 1;
1943 if (options->hostbased_authentication == -1)
1944 options->hostbased_authentication = 0;
1945 if (options->batch_mode == -1)
1946 options->batch_mode = 0;
1947 if (options->check_host_ip == -1)
1948 options->check_host_ip = 0;
1949 if (options->strict_host_key_checking == -1)
1950 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
1951 if (options->compression == -1)
1952 options->compression = 0;
1953 if (options->tcp_keep_alive == -1)
1954 options->tcp_keep_alive = 1;
1955 if (options->port == -1)
1956 options->port = 0; /* Filled in ssh_connect. */
1957 if (options->address_family == -1)
1958 options->address_family = AF_UNSPEC;
1959 if (options->connection_attempts == -1)
1960 options->connection_attempts = 1;
1961 if (options->number_of_password_prompts == -1)
1962 options->number_of_password_prompts = 3;
1963 /* options->hostkeyalgorithms, default set in myproposals.h */
1964 if (options->add_keys_to_agent == -1)
1965 options->add_keys_to_agent = 0;
1966 if (options->num_identity_files == 0) {
1967 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
1968 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
1969 #ifdef OPENSSL_HAS_ECC
1970 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
1972 add_identity_file(options, "~/",
1973 _PATH_SSH_CLIENT_ID_ED25519, 0);
1974 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
1976 if (options->escape_char == -1)
1977 options->escape_char = '~';
1978 if (options->num_system_hostfiles == 0) {
1979 options->system_hostfiles[options->num_system_hostfiles++] =
1980 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1981 options->system_hostfiles[options->num_system_hostfiles++] =
1982 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1984 if (options->num_user_hostfiles == 0) {
1985 options->user_hostfiles[options->num_user_hostfiles++] =
1986 xstrdup(_PATH_SSH_USER_HOSTFILE);
1987 options->user_hostfiles[options->num_user_hostfiles++] =
1988 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1990 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1991 options->log_level = SYSLOG_LEVEL_INFO;
1992 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1993 options->log_facility = SYSLOG_FACILITY_USER;
1994 if (options->no_host_authentication_for_localhost == - 1)
1995 options->no_host_authentication_for_localhost = 0;
1996 if (options->identities_only == -1)
1997 options->identities_only = 0;
1998 if (options->enable_ssh_keysign == -1)
1999 options->enable_ssh_keysign = 0;
2000 if (options->rekey_limit == -1)
2001 options->rekey_limit = 0;
2002 if (options->rekey_interval == -1)
2003 options->rekey_interval = 0;
2005 if (options->verify_host_key_dns == -1)
2006 /* automatically trust a verified SSHFP record */
2007 options->verify_host_key_dns = 1;
2009 if (options->verify_host_key_dns == -1)
2010 options->verify_host_key_dns = 0;
2012 if (options->server_alive_interval == -1)
2013 options->server_alive_interval = 0;
2014 if (options->server_alive_count_max == -1)
2015 options->server_alive_count_max = 3;
2016 if (options->control_master == -1)
2017 options->control_master = 0;
2018 if (options->control_persist == -1) {
2019 options->control_persist = 0;
2020 options->control_persist_timeout = 0;
2022 if (options->hash_known_hosts == -1)
2023 options->hash_known_hosts = 0;
2024 if (options->tun_open == -1)
2025 options->tun_open = SSH_TUNMODE_NO;
2026 if (options->tun_local == -1)
2027 options->tun_local = SSH_TUNID_ANY;
2028 if (options->tun_remote == -1)
2029 options->tun_remote = SSH_TUNID_ANY;
2030 if (options->permit_local_command == -1)
2031 options->permit_local_command = 0;
2032 if (options->visual_host_key == -1)
2033 options->visual_host_key = 0;
2034 if (options->ip_qos_interactive == -1)
2035 options->ip_qos_interactive = IPTOS_LOWDELAY;
2036 if (options->ip_qos_bulk == -1)
2037 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2038 if (options->request_tty == -1)
2039 options->request_tty = REQUEST_TTY_AUTO;
2040 if (options->proxy_use_fdpass == -1)
2041 options->proxy_use_fdpass = 0;
2042 if (options->canonicalize_max_dots == -1)
2043 options->canonicalize_max_dots = 1;
2044 if (options->canonicalize_fallback_local == -1)
2045 options->canonicalize_fallback_local = 1;
2046 if (options->canonicalize_hostname == -1)
2047 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2048 if (options->fingerprint_hash == -1)
2049 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2050 if (options->update_hostkeys == -1)
2051 options->update_hostkeys = 0;
2052 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2053 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2054 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2055 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2056 &options->hostbased_key_types) != 0 ||
2057 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2058 &options->pubkey_key_types) != 0)
2059 fatal("%s: kex_assemble_names failed", __func__);
2061 #define CLEAR_ON_NONE(v) \
2063 if (option_clear_or_none(v)) { \
2068 CLEAR_ON_NONE(options->local_command);
2069 CLEAR_ON_NONE(options->remote_command);
2070 CLEAR_ON_NONE(options->proxy_command);
2071 CLEAR_ON_NONE(options->control_path);
2072 CLEAR_ON_NONE(options->revoked_host_keys);
2073 /* options->identity_agent distinguishes NULL from 'none' */
2074 /* options->user will be set in the main program if appropriate */
2075 /* options->hostname will be set in the main program if appropriate */
2076 /* options->host_key_alias should not be set by default */
2077 /* options->preferred_authentications will be set in ssh */
2078 if (options->version_addendum == NULL)
2079 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2089 * parses the next field in a port forwarding specification.
2090 * sets fwd to the parsed field and advances p past the colon
2091 * or sets it to NULL at end of string.
2092 * returns 0 on success, else non-zero.
2095 parse_fwd_field(char **p, struct fwdarg *fwd)
2102 return -1; /* end of string */
2106 * A field escaped with square brackets is used literally.
2107 * XXX - allow ']' to be escaped via backslash?
2110 /* find matching ']' */
2111 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2115 /* no matching ']' or not at end of field. */
2116 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2118 /* NUL terminate the field and advance p past the colon */
2123 fwd->ispath = ispath;
2128 for (cp = *p; *cp != '\0'; cp++) {
2131 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2145 fwd->ispath = ispath;
2152 * parses a string containing a port forwarding specification of the form:
2154 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2155 * listenpath:connectpath
2157 * [listenhost:]listenport
2158 * returns number of arguments parsed or zero on error
2161 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2163 struct fwdarg fwdargs[4];
2167 memset(fwd, 0, sizeof(*fwd));
2168 memset(fwdargs, 0, sizeof(fwdargs));
2170 cp = p = xstrdup(fwdspec);
2172 /* skip leading spaces */
2173 while (isspace((u_char)*cp))
2176 for (i = 0; i < 4; ++i) {
2177 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2181 /* Check for trailing garbage */
2182 if (cp != NULL && *cp != '\0') {
2183 i = 0; /* failure */
2188 if (fwdargs[0].ispath) {
2189 fwd->listen_path = xstrdup(fwdargs[0].arg);
2190 fwd->listen_port = PORT_STREAMLOCAL;
2192 fwd->listen_host = NULL;
2193 fwd->listen_port = a2port(fwdargs[0].arg);
2195 fwd->connect_host = xstrdup("socks");
2199 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2200 fwd->listen_path = xstrdup(fwdargs[0].arg);
2201 fwd->listen_port = PORT_STREAMLOCAL;
2202 fwd->connect_path = xstrdup(fwdargs[1].arg);
2203 fwd->connect_port = PORT_STREAMLOCAL;
2204 } else if (fwdargs[1].ispath) {
2205 fwd->listen_host = NULL;
2206 fwd->listen_port = a2port(fwdargs[0].arg);
2207 fwd->connect_path = xstrdup(fwdargs[1].arg);
2208 fwd->connect_port = PORT_STREAMLOCAL;
2210 fwd->listen_host = xstrdup(fwdargs[0].arg);
2211 fwd->listen_port = a2port(fwdargs[1].arg);
2212 fwd->connect_host = xstrdup("socks");
2217 if (fwdargs[0].ispath) {
2218 fwd->listen_path = xstrdup(fwdargs[0].arg);
2219 fwd->listen_port = PORT_STREAMLOCAL;
2220 fwd->connect_host = xstrdup(fwdargs[1].arg);
2221 fwd->connect_port = a2port(fwdargs[2].arg);
2222 } else if (fwdargs[2].ispath) {
2223 fwd->listen_host = xstrdup(fwdargs[0].arg);
2224 fwd->listen_port = a2port(fwdargs[1].arg);
2225 fwd->connect_path = xstrdup(fwdargs[2].arg);
2226 fwd->connect_port = PORT_STREAMLOCAL;
2228 fwd->listen_host = NULL;
2229 fwd->listen_port = a2port(fwdargs[0].arg);
2230 fwd->connect_host = xstrdup(fwdargs[1].arg);
2231 fwd->connect_port = a2port(fwdargs[2].arg);
2236 fwd->listen_host = xstrdup(fwdargs[0].arg);
2237 fwd->listen_port = a2port(fwdargs[1].arg);
2238 fwd->connect_host = xstrdup(fwdargs[2].arg);
2239 fwd->connect_port = a2port(fwdargs[3].arg);
2242 i = 0; /* failure */
2248 if (!(i == 1 || i == 2))
2251 if (!(i == 3 || i == 4)) {
2252 if (fwd->connect_path == NULL &&
2253 fwd->listen_path == NULL)
2256 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2260 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2261 (!remotefwd && fwd->listen_port == 0))
2263 if (fwd->connect_host != NULL &&
2264 strlen(fwd->connect_host) >= NI_MAXHOST)
2266 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2267 if (fwd->connect_path != NULL &&
2268 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2270 if (fwd->listen_host != NULL &&
2271 strlen(fwd->listen_host) >= NI_MAXHOST)
2273 if (fwd->listen_path != NULL &&
2274 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2280 free(fwd->connect_host);
2281 fwd->connect_host = NULL;
2282 free(fwd->connect_path);
2283 fwd->connect_path = NULL;
2284 free(fwd->listen_host);
2285 fwd->listen_host = NULL;
2286 free(fwd->listen_path);
2287 fwd->listen_path = NULL;
2292 parse_jump(const char *s, Options *o, int active)
2294 char *orig, *sdup, *cp;
2295 char *host = NULL, *user = NULL;
2296 int ret = -1, port = -1, first;
2298 active &= o->proxy_command == NULL && o->jump_host == NULL;
2300 orig = sdup = xstrdup(s);
2303 if ((cp = strrchr(sdup, ',')) == NULL)
2304 cp = sdup; /* last */
2309 /* First argument and configuration is active */
2310 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2311 parse_user_host_port(cp, &user, &host, &port) != 0)
2314 /* Subsequent argument or inactive configuration */
2315 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2316 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2319 first = 0; /* only check syntax for subsequent hosts */
2320 } while (cp != sdup);
2323 o->jump_user = user;
2324 o->jump_host = host;
2325 o->jump_port = port;
2326 o->proxy_command = xstrdup("none");
2328 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2329 o->jump_extra = xstrdup(s);
2330 o->jump_extra[cp - s] = '\0';
2342 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2347 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2348 if (r == 0 && path != NULL)
2349 r = -1; /* path not allowed */
2353 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2355 fmt_multistate_int(int val, const struct multistate *m)
2359 for (i = 0; m[i].key != NULL; i++) {
2360 if (m[i].value == val)
2367 fmt_intarg(OpCodes code, int val)
2372 case oAddressFamily:
2373 return fmt_multistate_int(val, multistate_addressfamily);
2374 case oVerifyHostKeyDNS:
2375 case oUpdateHostkeys:
2376 return fmt_multistate_int(val, multistate_yesnoask);
2377 case oStrictHostKeyChecking:
2378 return fmt_multistate_int(val, multistate_strict_hostkey);
2379 case oControlMaster:
2380 return fmt_multistate_int(val, multistate_controlmaster);
2382 return fmt_multistate_int(val, multistate_tunnel);
2384 return fmt_multistate_int(val, multistate_requesttty);
2385 case oCanonicalizeHostname:
2386 return fmt_multistate_int(val, multistate_canonicalizehostname);
2387 case oFingerprintHash:
2388 return ssh_digest_alg_name(val);
2402 lookup_opcode_name(OpCodes code)
2406 for (i = 0; keywords[i].name != NULL; i++)
2407 if (keywords[i].opcode == code)
2408 return(keywords[i].name);
2413 dump_cfg_int(OpCodes code, int val)
2415 printf("%s %d\n", lookup_opcode_name(code), val);
2419 dump_cfg_fmtint(OpCodes code, int val)
2421 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2425 dump_cfg_string(OpCodes code, const char *val)
2429 printf("%s %s\n", lookup_opcode_name(code), val);
2433 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2437 for (i = 0; i < count; i++)
2438 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2442 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2446 printf("%s", lookup_opcode_name(code));
2447 for (i = 0; i < count; i++)
2448 printf(" %s", vals[i]);
2453 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2455 const struct Forward *fwd;
2458 /* oDynamicForward */
2459 for (i = 0; i < count; i++) {
2461 if (code == oDynamicForward && fwd->connect_host != NULL &&
2462 strcmp(fwd->connect_host, "socks") != 0)
2464 if (code == oLocalForward && fwd->connect_host != NULL &&
2465 strcmp(fwd->connect_host, "socks") == 0)
2467 printf("%s", lookup_opcode_name(code));
2468 if (fwd->listen_port == PORT_STREAMLOCAL)
2469 printf(" %s", fwd->listen_path);
2470 else if (fwd->listen_host == NULL)
2471 printf(" %d", fwd->listen_port);
2474 fwd->listen_host, fwd->listen_port);
2476 if (code != oDynamicForward) {
2477 if (fwd->connect_port == PORT_STREAMLOCAL)
2478 printf(" %s", fwd->connect_path);
2479 else if (fwd->connect_host == NULL)
2480 printf(" %d", fwd->connect_port);
2483 fwd->connect_host, fwd->connect_port);
2491 dump_client_config(Options *o, const char *host)
2496 /* This is normally prepared in ssh_kex2 */
2497 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2498 fatal("%s: kex_assemble_names failed", __func__);
2500 /* Most interesting options first: user, host, port */
2501 dump_cfg_string(oUser, o->user);
2502 dump_cfg_string(oHostName, host);
2503 dump_cfg_int(oPort, o->port);
2506 dump_cfg_fmtint(oAddressFamily, o->address_family);
2507 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2508 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2509 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2510 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2511 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2512 dump_cfg_fmtint(oCompression, o->compression);
2513 dump_cfg_fmtint(oControlMaster, o->control_master);
2514 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2515 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2516 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2517 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2518 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2519 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2520 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2521 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2523 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2524 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2526 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2527 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2528 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2529 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2530 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2531 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2532 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2533 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2534 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2535 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2536 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2537 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2538 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2539 dump_cfg_fmtint(oTunnel, o->tun_open);
2540 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2541 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2542 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2543 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2545 /* Integer options */
2546 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2547 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2548 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2549 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2550 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2551 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2553 /* String options */
2554 dump_cfg_string(oBindAddress, o->bind_address);
2555 dump_cfg_string(oBindInterface, o->bind_interface);
2556 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2557 dump_cfg_string(oControlPath, o->control_path);
2558 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2559 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2560 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2561 dump_cfg_string(oIdentityAgent, o->identity_agent);
2562 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2563 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2564 dump_cfg_string(oLocalCommand, o->local_command);
2565 dump_cfg_string(oRemoteCommand, o->remote_command);
2566 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2567 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2568 #ifdef ENABLE_PKCS11
2569 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2571 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2572 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2573 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2574 dump_cfg_string(oXAuthLocation, o->xauth_location);
2577 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2578 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2579 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2581 /* String array options */
2582 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2583 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2584 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2585 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2586 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2590 /* oConnectTimeout */
2591 if (o->connection_timeout == -1)
2592 printf("connecttimeout none\n");
2594 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2597 printf("tunneldevice");
2598 if (o->tun_local == SSH_TUNID_ANY)
2601 printf(" %d", o->tun_local);
2602 if (o->tun_remote == SSH_TUNID_ANY)
2605 printf(":%d", o->tun_remote);
2608 /* oCanonicalizePermittedCNAMEs */
2609 if ( o->num_permitted_cnames > 0) {
2610 printf("canonicalizePermittedcnames");
2611 for (i = 0; i < o->num_permitted_cnames; i++) {
2612 printf(" %s:%s", o->permitted_cnames[i].source_list,
2613 o->permitted_cnames[i].target_list);
2618 /* oControlPersist */
2619 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2620 dump_cfg_fmtint(oControlPersist, o->control_persist);
2622 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2625 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2626 printf("escapechar none\n");
2628 vis(buf, o->escape_char, VIS_WHITE, 0);
2629 printf("escapechar %s\n", buf);
2633 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2634 printf("%s\n", iptos2str(o->ip_qos_bulk));
2637 printf("rekeylimit %llu %d\n",
2638 (unsigned long long)o->rekey_limit, o->rekey_interval);
2640 /* oStreamLocalBindMask */
2641 printf("streamlocalbindmask 0%o\n",
2642 o->fwd_opts.streamlocal_bind_mask);
2644 /* oProxyCommand / oProxyJump */
2645 if (o->jump_host == NULL)
2646 dump_cfg_string(oProxyCommand, o->proxy_command);
2648 /* Check for numeric addresses */
2649 i = strchr(o->jump_host, ':') != NULL ||
2650 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2651 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2652 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2653 /* optional additional jump spec */
2654 o->jump_extra == NULL ? "" : o->jump_extra,
2655 o->jump_extra == NULL ? "" : ",",
2657 o->jump_user == NULL ? "" : o->jump_user,
2658 o->jump_user == NULL ? "" : "@",
2659 /* opening [ if hostname is numeric */
2661 /* mandatory hostname */
2663 /* closing ] if hostname is numeric */
2665 /* optional port number */
2666 o->jump_port <= 0 ? "" : ":",
2667 o->jump_port <= 0 ? "" : buf);