1 /* $OpenBSD: readconf.c,v 1.279 2017/09/21 19:16:53 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, 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 { "clearallforwardings", oClearAllForwardings },
270 { "enablesshkeysign", oEnableSSHKeysign },
271 { "verifyhostkeydns", oVerifyHostKeyDNS },
272 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
273 { "rekeylimit", oRekeyLimit },
274 { "connecttimeout", oConnectTimeout },
275 { "addressfamily", oAddressFamily },
276 { "serveraliveinterval", oServerAliveInterval },
277 { "serveralivecountmax", oServerAliveCountMax },
278 { "sendenv", oSendEnv },
279 { "controlpath", oControlPath },
280 { "controlmaster", oControlMaster },
281 { "controlpersist", oControlPersist },
282 { "hashknownhosts", oHashKnownHosts },
283 { "include", oInclude },
284 { "tunnel", oTunnel },
285 { "tunneldevice", oTunnelDevice },
286 { "localcommand", oLocalCommand },
287 { "permitlocalcommand", oPermitLocalCommand },
288 { "remotecommand", oRemoteCommand },
289 { "visualhostkey", oVisualHostKey },
290 { "kexalgorithms", oKexAlgorithms },
292 { "requesttty", oRequestTTY },
293 { "proxyusefdpass", oProxyUseFdpass },
294 { "canonicaldomains", oCanonicalDomains },
295 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
296 { "canonicalizehostname", oCanonicalizeHostname },
297 { "canonicalizemaxdots", oCanonicalizeMaxDots },
298 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
299 { "streamlocalbindmask", oStreamLocalBindMask },
300 { "streamlocalbindunlink", oStreamLocalBindUnlink },
301 { "revokedhostkeys", oRevokedHostKeys },
302 { "fingerprinthash", oFingerprintHash },
303 { "updatehostkeys", oUpdateHostkeys },
304 { "hostbasedkeytypes", oHostbasedKeyTypes },
305 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
306 { "ignoreunknown", oIgnoreUnknown },
307 { "proxyjump", oProxyJump },
313 * Adds a local TCP/IP port forward to options. Never returns if there is an
318 add_local_forward(Options *options, const struct Forward *newfwd)
321 extern uid_t original_real_uid;
324 if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
325 newfwd->listen_path == NULL)
326 fatal("Privileged ports can only be forwarded by root.");
327 /* Don't add duplicates */
328 for (i = 0; i < options->num_local_forwards; i++) {
329 if (forward_equals(newfwd, options->local_forwards + i))
332 options->local_forwards = xreallocarray(options->local_forwards,
333 options->num_local_forwards + 1,
334 sizeof(*options->local_forwards));
335 fwd = &options->local_forwards[options->num_local_forwards++];
337 fwd->listen_host = newfwd->listen_host;
338 fwd->listen_port = newfwd->listen_port;
339 fwd->listen_path = newfwd->listen_path;
340 fwd->connect_host = newfwd->connect_host;
341 fwd->connect_port = newfwd->connect_port;
342 fwd->connect_path = newfwd->connect_path;
346 * Adds a remote TCP/IP port forward to options. Never returns if there is
351 add_remote_forward(Options *options, const struct Forward *newfwd)
356 /* Don't add duplicates */
357 for (i = 0; i < options->num_remote_forwards; i++) {
358 if (forward_equals(newfwd, options->remote_forwards + i))
361 options->remote_forwards = xreallocarray(options->remote_forwards,
362 options->num_remote_forwards + 1,
363 sizeof(*options->remote_forwards));
364 fwd = &options->remote_forwards[options->num_remote_forwards++];
366 fwd->listen_host = newfwd->listen_host;
367 fwd->listen_port = newfwd->listen_port;
368 fwd->listen_path = newfwd->listen_path;
369 fwd->connect_host = newfwd->connect_host;
370 fwd->connect_port = newfwd->connect_port;
371 fwd->connect_path = newfwd->connect_path;
372 fwd->handle = newfwd->handle;
373 fwd->allocated_port = 0;
377 clear_forwardings(Options *options)
381 for (i = 0; i < options->num_local_forwards; i++) {
382 free(options->local_forwards[i].listen_host);
383 free(options->local_forwards[i].listen_path);
384 free(options->local_forwards[i].connect_host);
385 free(options->local_forwards[i].connect_path);
387 if (options->num_local_forwards > 0) {
388 free(options->local_forwards);
389 options->local_forwards = NULL;
391 options->num_local_forwards = 0;
392 for (i = 0; i < options->num_remote_forwards; i++) {
393 free(options->remote_forwards[i].listen_host);
394 free(options->remote_forwards[i].listen_path);
395 free(options->remote_forwards[i].connect_host);
396 free(options->remote_forwards[i].connect_path);
398 if (options->num_remote_forwards > 0) {
399 free(options->remote_forwards);
400 options->remote_forwards = NULL;
402 options->num_remote_forwards = 0;
403 options->tun_open = SSH_TUNMODE_NO;
407 add_certificate_file(Options *options, const char *path, int userprovided)
411 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
412 fatal("Too many certificate files specified (max %d)",
413 SSH_MAX_CERTIFICATE_FILES);
415 /* Avoid registering duplicates */
416 for (i = 0; i < options->num_certificate_files; i++) {
417 if (options->certificate_file_userprovided[i] == userprovided &&
418 strcmp(options->certificate_files[i], path) == 0) {
419 debug2("%s: ignoring duplicate key %s", __func__, path);
424 options->certificate_file_userprovided[options->num_certificate_files] =
426 options->certificate_files[options->num_certificate_files++] =
431 add_identity_file(Options *options, const char *dir, const char *filename,
437 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
438 fatal("Too many identity files specified (max %d)",
439 SSH_MAX_IDENTITY_FILES);
441 if (dir == NULL) /* no dir, filename is absolute */
442 path = xstrdup(filename);
443 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
444 fatal("Identity file path %s too long", path);
446 /* Avoid registering duplicates */
447 for (i = 0; i < options->num_identity_files; i++) {
448 if (options->identity_file_userprovided[i] == userprovided &&
449 strcmp(options->identity_files[i], path) == 0) {
450 debug2("%s: ignoring duplicate key %s", __func__, path);
456 options->identity_file_userprovided[options->num_identity_files] =
458 options->identity_files[options->num_identity_files++] = path;
462 default_ssh_port(void)
468 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
469 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
475 * Execute a command in a shell.
476 * Return its exit status or -1 on abnormal exit.
479 execute_in_shell(const char *cmd)
484 extern uid_t original_real_uid;
486 if ((shell = getenv("SHELL")) == NULL)
487 shell = _PATH_BSHELL;
489 /* Need this to redirect subprocess stdin/out */
490 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
491 fatal("open(/dev/null): %s", strerror(errno));
493 debug("Executing command: '%.500s'", cmd);
495 /* Fork and execute the command. */
496 if ((pid = fork()) == 0) {
499 /* Child. Permanently give up superuser privileges. */
500 permanently_drop_suid(original_real_uid);
502 /* Redirect child stdin and stdout. Leave stderr */
503 if (dup2(devnull, STDIN_FILENO) == -1)
504 fatal("dup2: %s", strerror(errno));
505 if (dup2(devnull, STDOUT_FILENO) == -1)
506 fatal("dup2: %s", strerror(errno));
507 if (devnull > STDERR_FILENO)
509 closefrom(STDERR_FILENO + 1);
513 argv[2] = xstrdup(cmd);
516 execv(argv[0], argv);
517 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
518 /* Die with signal to make this error apparent to parent. */
519 signal(SIGTERM, SIG_DFL);
520 kill(getpid(), SIGTERM);
525 fatal("%s: fork: %.100s", __func__, strerror(errno));
529 while (waitpid(pid, &status, 0) == -1) {
530 if (errno != EINTR && errno != EAGAIN)
531 fatal("%s: waitpid: %s", __func__, strerror(errno));
533 if (!WIFEXITED(status)) {
534 error("command '%.100s' exited abnormally", cmd);
537 debug3("command returned status %d", WEXITSTATUS(status));
538 return WEXITSTATUS(status);
542 * Parse and execute a Match directive.
545 match_cfg_line(Options *options, char **condition, struct passwd *pw,
546 const char *host_arg, const char *original_host, int post_canon,
547 const char *filename, int linenum)
549 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
551 int r, port, this_result, result = 1, attributes = 0, negate;
552 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
555 * Configuration is likely to be incomplete at this point so we
556 * must be prepared to use default values.
558 port = options->port <= 0 ? default_ssh_port() : options->port;
559 ruser = options->user == NULL ? pw->pw_name : options->user;
561 host = xstrdup(options->hostname);
562 } else if (options->hostname != NULL) {
563 /* NB. Please keep in sync with ssh.c:main() */
564 host = percent_expand(options->hostname,
565 "h", host_arg, (char *)NULL);
567 host = xstrdup(host_arg);
570 debug2("checking match for '%s' host %s originally %s",
571 cp, host, original_host);
572 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
575 if ((negate = attrib[0] == '!'))
577 /* criteria "all" and "canonical" have no argument */
578 if (strcasecmp(attrib, "all") == 0) {
579 if (attributes > 1 ||
580 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
581 error("%.200s line %d: '%s' cannot be combined "
582 "with other Match attributes",
583 filename, linenum, oattrib);
588 result = negate ? 0 : 1;
592 if (strcasecmp(attrib, "canonical") == 0) {
593 r = !!post_canon; /* force bitmask member to boolean */
594 if (r == (negate ? 1 : 0))
595 this_result = result = 0;
596 debug3("%.200s line %d: %smatched '%s'",
598 this_result ? "" : "not ", oattrib);
601 /* All other criteria require an argument */
602 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
603 error("Missing Match criteria for %s", attrib);
607 if (strcasecmp(attrib, "host") == 0) {
608 criteria = xstrdup(host);
609 r = match_hostname(host, arg) == 1;
610 if (r == (negate ? 1 : 0))
611 this_result = result = 0;
612 } else if (strcasecmp(attrib, "originalhost") == 0) {
613 criteria = xstrdup(original_host);
614 r = match_hostname(original_host, arg) == 1;
615 if (r == (negate ? 1 : 0))
616 this_result = result = 0;
617 } else if (strcasecmp(attrib, "user") == 0) {
618 criteria = xstrdup(ruser);
619 r = match_pattern_list(ruser, arg, 0) == 1;
620 if (r == (negate ? 1 : 0))
621 this_result = result = 0;
622 } else if (strcasecmp(attrib, "localuser") == 0) {
623 criteria = xstrdup(pw->pw_name);
624 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
625 if (r == (negate ? 1 : 0))
626 this_result = result = 0;
627 } else if (strcasecmp(attrib, "exec") == 0) {
628 if (gethostname(thishost, sizeof(thishost)) == -1)
629 fatal("gethostname: %s", strerror(errno));
630 strlcpy(shorthost, thishost, sizeof(shorthost));
631 shorthost[strcspn(thishost, ".")] = '\0';
632 snprintf(portstr, sizeof(portstr), "%d", port);
634 cmd = percent_expand(arg,
645 /* skip execution if prior predicate failed */
646 debug3("%.200s line %d: skipped exec "
647 "\"%.100s\"", filename, linenum, cmd);
651 r = execute_in_shell(cmd);
653 fatal("%.200s line %d: match exec "
654 "'%.100s' error", filename,
657 criteria = xstrdup(cmd);
659 /* Force exit status to boolean */
661 if (r == (negate ? 1 : 0))
662 this_result = result = 0;
664 error("Unsupported Match attribute %s", attrib);
668 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
669 filename, linenum, this_result ? "": "not ",
673 if (attributes == 0) {
674 error("One or more attributes required for Match");
680 debug2("match %sfound", result ? "" : "not ");
686 /* Check and prepare a domain name: removes trailing '.' and lowercases */
688 valid_domain(char *name, const char *filename, int linenum)
690 size_t i, l = strlen(name);
691 u_char c, last = '\0';
694 fatal("%s line %d: empty hostname suffix", filename, linenum);
695 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
696 fatal("%s line %d: hostname suffix \"%.100s\" "
697 "starts with invalid character", filename, linenum, name);
698 for (i = 0; i < l; i++) {
699 c = tolower((u_char)name[i]);
701 if (last == '.' && c == '.')
702 fatal("%s line %d: hostname suffix \"%.100s\" contains "
703 "consecutive separators", filename, linenum, name);
704 if (c != '.' && c != '-' && !isalnum(c) &&
705 c != '_') /* technically invalid, but common */
706 fatal("%s line %d: hostname suffix \"%.100s\" contains "
707 "invalid characters", filename, linenum, name);
710 if (name[l - 1] == '.')
715 * Returns the number of the token pointed to by cp or oBadOption.
718 parse_token(const char *cp, const char *filename, int linenum,
719 const char *ignored_unknown)
723 for (i = 0; keywords[i].name; i++)
724 if (strcmp(cp, keywords[i].name) == 0)
725 return keywords[i].opcode;
726 if (ignored_unknown != NULL &&
727 match_pattern_list(cp, ignored_unknown, 1) == 1)
728 return oIgnoredUnknownOption;
729 error("%s: line %d: Bad configuration option: %s",
730 filename, linenum, cp);
734 /* Multistate option parsing */
739 static const struct multistate multistate_flag[] = {
746 static const struct multistate multistate_yesnoask[] = {
754 static const struct multistate multistate_strict_hostkey[] = {
755 { "true", SSH_STRICT_HOSTKEY_YES },
756 { "false", SSH_STRICT_HOSTKEY_OFF },
757 { "yes", SSH_STRICT_HOSTKEY_YES },
758 { "no", SSH_STRICT_HOSTKEY_OFF },
759 { "ask", SSH_STRICT_HOSTKEY_ASK },
760 { "off", SSH_STRICT_HOSTKEY_OFF },
761 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
764 static const struct multistate multistate_yesnoaskconfirm[] = {
773 static const struct multistate multistate_addressfamily[] = {
775 { "inet6", AF_INET6 },
776 { "any", AF_UNSPEC },
779 static const struct multistate multistate_controlmaster[] = {
780 { "true", SSHCTL_MASTER_YES },
781 { "yes", SSHCTL_MASTER_YES },
782 { "false", SSHCTL_MASTER_NO },
783 { "no", SSHCTL_MASTER_NO },
784 { "auto", SSHCTL_MASTER_AUTO },
785 { "ask", SSHCTL_MASTER_ASK },
786 { "autoask", SSHCTL_MASTER_AUTO_ASK },
789 static const struct multistate multistate_tunnel[] = {
790 { "ethernet", SSH_TUNMODE_ETHERNET },
791 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
792 { "true", SSH_TUNMODE_DEFAULT },
793 { "yes", SSH_TUNMODE_DEFAULT },
794 { "false", SSH_TUNMODE_NO },
795 { "no", SSH_TUNMODE_NO },
798 static const struct multistate multistate_requesttty[] = {
799 { "true", REQUEST_TTY_YES },
800 { "yes", REQUEST_TTY_YES },
801 { "false", REQUEST_TTY_NO },
802 { "no", REQUEST_TTY_NO },
803 { "force", REQUEST_TTY_FORCE },
804 { "auto", REQUEST_TTY_AUTO },
807 static const struct multistate multistate_canonicalizehostname[] = {
808 { "true", SSH_CANONICALISE_YES },
809 { "false", SSH_CANONICALISE_NO },
810 { "yes", SSH_CANONICALISE_YES },
811 { "no", SSH_CANONICALISE_NO },
812 { "always", SSH_CANONICALISE_ALWAYS },
817 * Processes a single option line as used in the configuration files. This
818 * only sets those values that have not already been set.
821 process_config_line(Options *options, struct passwd *pw, const char *host,
822 const char *original_host, char *line, const char *filename,
823 int linenum, int *activep, int flags)
825 return process_config_line_depth(options, pw, host, original_host,
826 line, filename, linenum, activep, flags, 0);
829 #define WHITESPACE " \t\r\n"
831 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
832 const char *original_host, char *line, const char *filename,
833 int linenum, int *activep, int flags, int depth)
835 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
836 char **cpptr, fwdarg[256];
837 u_int i, *uintptr, max_entries = 0;
838 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
839 int remotefwd, dynamicfwd;
840 LogLevel *log_level_ptr;
841 SyslogFacility *log_facility_ptr;
845 const struct multistate *multistate_ptr;
846 struct allowed_cname *cname;
849 if (activep == NULL) { /* We are processing a command line directive */
854 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
855 if ((len = strlen(line)) == 0)
857 for (len--; len > 0; len--) {
858 if (strchr(WHITESPACE "\f", line[len]) == NULL)
864 /* Get the keyword. (Each line is supposed to begin with a keyword). */
865 if ((keyword = strdelim(&s)) == NULL)
867 /* Ignore leading whitespace. */
868 if (*keyword == '\0')
869 keyword = strdelim(&s);
870 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
872 /* Match lowercase keyword */
875 opcode = parse_token(keyword, filename, linenum,
876 options->ignored_unknown);
880 /* don't panic, but count bad options */
884 case oIgnoredUnknownOption:
885 debug("%s line %d: Ignored unknown option \"%s\"",
886 filename, linenum, keyword);
888 case oConnectTimeout:
889 intptr = &options->connection_timeout;
892 if (!arg || *arg == '\0')
893 fatal("%s line %d: missing time value.",
895 if (strcmp(arg, "none") == 0)
897 else if ((value = convtime(arg)) == -1)
898 fatal("%s line %d: invalid time value.",
900 if (*activep && *intptr == -1)
905 intptr = &options->forward_agent;
907 multistate_ptr = multistate_flag;
910 if (!arg || *arg == '\0')
911 fatal("%s line %d: missing argument.",
914 for (i = 0; multistate_ptr[i].key != NULL; i++) {
915 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
916 value = multistate_ptr[i].value;
921 fatal("%s line %d: unsupported option \"%s\".",
922 filename, linenum, arg);
923 if (*activep && *intptr == -1)
928 intptr = &options->forward_x11;
931 case oForwardX11Trusted:
932 intptr = &options->forward_x11_trusted;
935 case oForwardX11Timeout:
936 intptr = &options->forward_x11_timeout;
940 intptr = &options->fwd_opts.gateway_ports;
943 case oExitOnForwardFailure:
944 intptr = &options->exit_on_forward_failure;
947 case oUsePrivilegedPort:
948 intptr = &options->use_privileged_port;
951 case oPasswordAuthentication:
952 intptr = &options->password_authentication;
955 case oKbdInteractiveAuthentication:
956 intptr = &options->kbd_interactive_authentication;
959 case oKbdInteractiveDevices:
960 charptr = &options->kbd_interactive_devices;
963 case oPubkeyAuthentication:
964 intptr = &options->pubkey_authentication;
967 case oHostbasedAuthentication:
968 intptr = &options->hostbased_authentication;
971 case oChallengeResponseAuthentication:
972 intptr = &options->challenge_response_authentication;
975 case oGssAuthentication:
976 intptr = &options->gss_authentication;
979 case oGssDelegateCreds:
980 intptr = &options->gss_deleg_creds;
984 intptr = &options->batch_mode;
988 intptr = &options->check_host_ip;
991 case oVerifyHostKeyDNS:
992 intptr = &options->verify_host_key_dns;
993 multistate_ptr = multistate_yesnoask;
994 goto parse_multistate;
996 case oStrictHostKeyChecking:
997 intptr = &options->strict_host_key_checking;
998 multistate_ptr = multistate_strict_hostkey;
999 goto parse_multistate;
1002 intptr = &options->compression;
1006 intptr = &options->tcp_keep_alive;
1009 case oNoHostAuthenticationForLocalhost:
1010 intptr = &options->no_host_authentication_for_localhost;
1013 case oNumberOfPasswordPrompts:
1014 intptr = &options->number_of_password_prompts;
1019 if (!arg || *arg == '\0')
1020 fatal("%.200s line %d: Missing argument.", filename,
1022 if (strcmp(arg, "default") == 0) {
1025 if (scan_scaled(arg, &val64) == -1)
1026 fatal("%.200s line %d: Bad number '%s': %s",
1027 filename, linenum, arg, strerror(errno));
1028 if (val64 != 0 && val64 < 16)
1029 fatal("%.200s line %d: RekeyLimit too small",
1032 if (*activep && options->rekey_limit == -1)
1033 options->rekey_limit = val64;
1034 if (s != NULL) { /* optional rekey interval present */
1035 if (strcmp(s, "none") == 0) {
1036 (void)strdelim(&s); /* discard */
1039 intptr = &options->rekey_interval;
1046 if (!arg || *arg == '\0')
1047 fatal("%.200s line %d: Missing argument.", filename, linenum);
1049 intptr = &options->num_identity_files;
1050 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1051 fatal("%.200s line %d: Too many identity files specified (max %d).",
1052 filename, linenum, SSH_MAX_IDENTITY_FILES);
1053 add_identity_file(options, NULL,
1054 arg, flags & SSHCONF_USERCONF);
1058 case oCertificateFile:
1060 if (!arg || *arg == '\0')
1061 fatal("%.200s line %d: Missing argument.",
1064 intptr = &options->num_certificate_files;
1065 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1066 fatal("%.200s line %d: Too many certificate "
1067 "files specified (max %d).",
1069 SSH_MAX_CERTIFICATE_FILES);
1071 add_certificate_file(options, arg,
1072 flags & SSHCONF_USERCONF);
1076 case oXAuthLocation:
1077 charptr=&options->xauth_location;
1081 charptr = &options->user;
1084 if (!arg || *arg == '\0')
1085 fatal("%.200s line %d: Missing argument.",
1087 if (*activep && *charptr == NULL)
1088 *charptr = xstrdup(arg);
1091 case oGlobalKnownHostsFile:
1092 cpptr = (char **)&options->system_hostfiles;
1093 uintptr = &options->num_system_hostfiles;
1094 max_entries = SSH_MAX_HOSTS_FILES;
1096 if (*activep && *uintptr == 0) {
1097 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1098 if ((*uintptr) >= max_entries)
1099 fatal("%s line %d: "
1100 "too many authorized keys files.",
1102 cpptr[(*uintptr)++] = xstrdup(arg);
1107 case oUserKnownHostsFile:
1108 cpptr = (char **)&options->user_hostfiles;
1109 uintptr = &options->num_user_hostfiles;
1110 max_entries = SSH_MAX_HOSTS_FILES;
1111 goto parse_char_array;
1114 charptr = &options->hostname;
1118 charptr = &options->host_key_alias;
1121 case oPreferredAuthentications:
1122 charptr = &options->preferred_authentications;
1126 charptr = &options->bind_address;
1129 case oPKCS11Provider:
1130 charptr = &options->pkcs11_provider;
1134 charptr = &options->proxy_command;
1135 /* Ignore ProxyCommand if ProxyJump already specified */
1136 if (options->jump_host != NULL)
1137 charptr = &options->jump_host; /* Skip below */
1140 fatal("%.200s line %d: Missing argument.", filename, linenum);
1141 len = strspn(s, WHITESPACE "=");
1142 if (*activep && *charptr == NULL)
1143 *charptr = xstrdup(s + len);
1148 fatal("%.200s line %d: Missing argument.",
1151 len = strspn(s, WHITESPACE "=");
1152 if (parse_jump(s + len, options, *activep) == -1) {
1153 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1154 filename, linenum, s + len);
1159 intptr = &options->port;
1162 if (!arg || *arg == '\0')
1163 fatal("%.200s line %d: Missing argument.", filename, linenum);
1164 if (arg[0] < '0' || arg[0] > '9')
1165 fatal("%.200s line %d: Bad number.", filename, linenum);
1167 /* Octal, decimal, or hex format? */
1168 value = strtol(arg, &endofnumber, 0);
1169 if (arg == endofnumber)
1170 fatal("%.200s line %d: Bad number.", filename, linenum);
1171 if (*activep && *intptr == -1)
1175 case oConnectionAttempts:
1176 intptr = &options->connection_attempts;
1181 if (!arg || *arg == '\0')
1182 fatal("%.200s line %d: Missing argument.", filename, linenum);
1183 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1184 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1185 filename, linenum, arg ? arg : "<NONE>");
1186 if (*activep && options->ciphers == NULL)
1187 options->ciphers = xstrdup(arg);
1192 if (!arg || *arg == '\0')
1193 fatal("%.200s line %d: Missing argument.", filename, linenum);
1194 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1195 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1196 filename, linenum, arg ? arg : "<NONE>");
1197 if (*activep && options->macs == NULL)
1198 options->macs = xstrdup(arg);
1201 case oKexAlgorithms:
1203 if (!arg || *arg == '\0')
1204 fatal("%.200s line %d: Missing argument.",
1207 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1208 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1209 filename, linenum, arg ? arg : "<NONE>");
1210 if (*activep && options->kex_algorithms == NULL)
1211 options->kex_algorithms = xstrdup(arg);
1214 case oHostKeyAlgorithms:
1215 charptr = &options->hostkeyalgorithms;
1218 if (!arg || *arg == '\0')
1219 fatal("%.200s line %d: Missing argument.",
1222 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1223 fatal("%s line %d: Bad key types '%s'.",
1224 filename, linenum, arg ? arg : "<NONE>");
1225 if (*activep && *charptr == NULL)
1226 *charptr = xstrdup(arg);
1230 log_level_ptr = &options->log_level;
1232 value = log_level_number(arg);
1233 if (value == SYSLOG_LEVEL_NOT_SET)
1234 fatal("%.200s line %d: unsupported log level '%s'",
1235 filename, linenum, arg ? arg : "<NONE>");
1236 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1237 *log_level_ptr = (LogLevel) value;
1241 log_facility_ptr = &options->log_facility;
1243 value = log_facility_number(arg);
1244 if (value == SYSLOG_FACILITY_NOT_SET)
1245 fatal("%.200s line %d: unsupported log facility '%s'",
1246 filename, linenum, arg ? arg : "<NONE>");
1247 if (*log_facility_ptr == -1)
1248 *log_facility_ptr = (SyslogFacility) value;
1252 case oRemoteForward:
1253 case oDynamicForward:
1255 if (arg == NULL || *arg == '\0')
1256 fatal("%.200s line %d: Missing port argument.",
1259 remotefwd = (opcode == oRemoteForward);
1260 dynamicfwd = (opcode == oDynamicForward);
1263 arg2 = strdelim(&s);
1264 if (arg2 == NULL || *arg2 == '\0') {
1268 fatal("%.200s line %d: Missing target "
1269 "argument.", filename, linenum);
1271 /* construct a string for parse_forward */
1272 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1277 strlcpy(fwdarg, arg, sizeof(fwdarg));
1279 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1280 fatal("%.200s line %d: Bad forwarding specification.",
1285 add_remote_forward(options, &fwd);
1287 add_local_forward(options, &fwd);
1292 case oClearAllForwardings:
1293 intptr = &options->clear_forwardings;
1298 fatal("Host directive not supported as a command-line "
1302 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1303 if ((flags & SSHCONF_NEVERMATCH) != 0)
1305 negated = *arg == '!';
1308 if (match_pattern(host, arg)) {
1310 debug("%.200s line %d: Skipping Host "
1311 "block because of negated match "
1312 "for %.100s", filename, linenum,
1318 arg2 = arg; /* logged below */
1323 debug("%.200s line %d: Applying options for %.100s",
1324 filename, linenum, arg2);
1325 /* Avoid garbage check below, as strdelim is done. */
1330 fatal("Host directive not supported as a command-line "
1332 value = match_cfg_line(options, &s, pw, host, original_host,
1333 flags & SSHCONF_POSTCANON, filename, linenum);
1335 fatal("%.200s line %d: Bad Match condition", filename,
1337 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1341 intptr = &options->escape_char;
1343 if (!arg || *arg == '\0')
1344 fatal("%.200s line %d: Missing argument.", filename, linenum);
1345 if (strcmp(arg, "none") == 0)
1346 value = SSH_ESCAPECHAR_NONE;
1347 else if (arg[1] == '\0')
1348 value = (u_char) arg[0];
1349 else if (arg[0] == '^' && arg[2] == 0 &&
1350 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1351 value = (u_char) arg[1] & 31;
1353 fatal("%.200s line %d: Bad escape character.",
1356 value = 0; /* Avoid compiler warning. */
1358 if (*activep && *intptr == -1)
1362 case oAddressFamily:
1363 intptr = &options->address_family;
1364 multistate_ptr = multistate_addressfamily;
1365 goto parse_multistate;
1367 case oEnableSSHKeysign:
1368 intptr = &options->enable_ssh_keysign;
1371 case oIdentitiesOnly:
1372 intptr = &options->identities_only;
1375 case oServerAliveInterval:
1376 intptr = &options->server_alive_interval;
1379 case oServerAliveCountMax:
1380 intptr = &options->server_alive_count_max;
1384 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1385 if (strchr(arg, '=') != NULL)
1386 fatal("%s line %d: Invalid environment name.",
1390 if (options->num_send_env >= MAX_SEND_ENV)
1391 fatal("%s line %d: too many send env.",
1393 options->send_env[options->num_send_env++] =
1399 charptr = &options->control_path;
1402 case oControlMaster:
1403 intptr = &options->control_master;
1404 multistate_ptr = multistate_controlmaster;
1405 goto parse_multistate;
1407 case oControlPersist:
1408 /* no/false/yes/true, or a time spec */
1409 intptr = &options->control_persist;
1411 if (!arg || *arg == '\0')
1412 fatal("%.200s line %d: Missing ControlPersist"
1413 " argument.", filename, linenum);
1415 value2 = 0; /* timeout */
1416 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1418 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1420 else if ((value2 = convtime(arg)) >= 0)
1423 fatal("%.200s line %d: Bad ControlPersist argument.",
1425 if (*activep && *intptr == -1) {
1427 options->control_persist_timeout = value2;
1431 case oHashKnownHosts:
1432 intptr = &options->hash_known_hosts;
1436 intptr = &options->tun_open;
1437 multistate_ptr = multistate_tunnel;
1438 goto parse_multistate;
1442 if (!arg || *arg == '\0')
1443 fatal("%.200s line %d: Missing argument.", filename, linenum);
1444 value = a2tun(arg, &value2);
1445 if (value == SSH_TUNID_ERR)
1446 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1448 options->tun_local = value;
1449 options->tun_remote = value2;
1454 charptr = &options->local_command;
1457 case oPermitLocalCommand:
1458 intptr = &options->permit_local_command;
1461 case oRemoteCommand:
1462 charptr = &options->remote_command;
1465 case oVisualHostKey:
1466 intptr = &options->visual_host_key;
1471 fatal("Include directive not supported as a "
1472 "command-line option");
1474 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1476 * Ensure all paths are anchored. User configuration
1477 * files may begin with '~/' but system configurations
1478 * must not. If the path is relative, then treat it
1479 * as living in ~/.ssh for user configurations or
1480 * /etc/ssh for system ones.
1482 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1483 fatal("%.200s line %d: bad include path %s.",
1484 filename, linenum, arg);
1485 if (*arg != '/' && *arg != '~') {
1486 xasprintf(&arg2, "%s/%s",
1487 (flags & SSHCONF_USERCONF) ?
1488 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1490 arg2 = xstrdup(arg);
1491 memset(&gl, 0, sizeof(gl));
1492 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1493 if (r == GLOB_NOMATCH) {
1494 debug("%.200s line %d: include %s matched no "
1495 "files",filename, linenum, arg2);
1498 } else if (r != 0 || gl.gl_pathc < 0)
1499 fatal("%.200s line %d: glob failed for %s.",
1500 filename, linenum, arg2);
1503 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1504 debug3("%.200s line %d: Including file %s "
1505 "depth %d%s", filename, linenum,
1506 gl.gl_pathv[i], depth,
1507 oactive ? "" : " (parse only)");
1508 r = read_config_file_depth(gl.gl_pathv[i],
1509 pw, host, original_host, options,
1510 flags | SSHCONF_CHECKPERM |
1511 (oactive ? 0 : SSHCONF_NEVERMATCH),
1512 activep, depth + 1);
1513 if (r != 1 && errno != ENOENT) {
1514 fatal("Can't open user config file "
1515 "%.100s: %.100s", gl.gl_pathv[i],
1519 * don't let Match in includes clobber the
1520 * containing file's Match state.
1534 if ((value = parse_ipqos(arg)) == -1)
1535 fatal("%s line %d: Bad IPQoS value: %s",
1536 filename, linenum, arg);
1540 else if ((value2 = parse_ipqos(arg)) == -1)
1541 fatal("%s line %d: Bad IPQoS value: %s",
1542 filename, linenum, arg);
1544 options->ip_qos_interactive = value;
1545 options->ip_qos_bulk = value2;
1550 intptr = &options->request_tty;
1551 multistate_ptr = multistate_requesttty;
1552 goto parse_multistate;
1554 case oIgnoreUnknown:
1555 charptr = &options->ignored_unknown;
1558 case oProxyUseFdpass:
1559 intptr = &options->proxy_use_fdpass;
1562 case oCanonicalDomains:
1563 value = options->num_canonical_domains != 0;
1564 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1565 valid_domain(arg, filename, linenum);
1566 if (!*activep || value)
1568 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1569 fatal("%s line %d: too many hostname suffixes.",
1571 options->canonical_domains[
1572 options->num_canonical_domains++] = xstrdup(arg);
1576 case oCanonicalizePermittedCNAMEs:
1577 value = options->num_permitted_cnames != 0;
1578 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1579 /* Either '*' for everything or 'list:list' */
1580 if (strcmp(arg, "*") == 0)
1584 if ((arg2 = strchr(arg, ':')) == NULL ||
1586 fatal("%s line %d: "
1587 "Invalid permitted CNAME \"%s\"",
1588 filename, linenum, arg);
1593 if (!*activep || value)
1595 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1596 fatal("%s line %d: too many permitted CNAMEs.",
1598 cname = options->permitted_cnames +
1599 options->num_permitted_cnames++;
1600 cname->source_list = xstrdup(arg);
1601 cname->target_list = xstrdup(arg2);
1605 case oCanonicalizeHostname:
1606 intptr = &options->canonicalize_hostname;
1607 multistate_ptr = multistate_canonicalizehostname;
1608 goto parse_multistate;
1610 case oCanonicalizeMaxDots:
1611 intptr = &options->canonicalize_max_dots;
1614 case oCanonicalizeFallbackLocal:
1615 intptr = &options->canonicalize_fallback_local;
1618 case oStreamLocalBindMask:
1620 if (!arg || *arg == '\0')
1621 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1622 /* Parse mode in octal format */
1623 value = strtol(arg, &endofnumber, 8);
1624 if (arg == endofnumber || value < 0 || value > 0777)
1625 fatal("%.200s line %d: Bad mask.", filename, linenum);
1626 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1629 case oStreamLocalBindUnlink:
1630 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1633 case oRevokedHostKeys:
1634 charptr = &options->revoked_host_keys;
1637 case oFingerprintHash:
1638 intptr = &options->fingerprint_hash;
1640 if (!arg || *arg == '\0')
1641 fatal("%.200s line %d: Missing argument.",
1643 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1644 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1645 filename, linenum, arg);
1646 if (*activep && *intptr == -1)
1650 case oUpdateHostkeys:
1651 intptr = &options->update_hostkeys;
1652 multistate_ptr = multistate_yesnoask;
1653 goto parse_multistate;
1655 case oHostbasedKeyTypes:
1656 charptr = &options->hostbased_key_types;
1657 goto parse_keytypes;
1659 case oPubkeyAcceptedKeyTypes:
1660 charptr = &options->pubkey_key_types;
1661 goto parse_keytypes;
1663 case oAddKeysToAgent:
1664 intptr = &options->add_keys_to_agent;
1665 multistate_ptr = multistate_yesnoaskconfirm;
1666 goto parse_multistate;
1668 case oIdentityAgent:
1669 charptr = &options->identity_agent;
1673 debug("%s line %d: Deprecated option \"%s\"",
1674 filename, linenum, keyword);
1678 error("%s line %d: Unsupported option \"%s\"",
1679 filename, linenum, keyword);
1683 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1686 /* Check that there is no garbage at end of line. */
1687 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1688 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1689 filename, linenum, arg);
1695 * Reads the config file and modifies the options accordingly. Options
1696 * should already be initialized before this call. This never returns if
1697 * there is an error. If the file does not exist, this returns 0.
1700 read_config_file(const char *filename, struct passwd *pw, const char *host,
1701 const char *original_host, Options *options, int flags)
1705 return read_config_file_depth(filename, pw, host, original_host,
1706 options, flags, &active, 0);
1709 #define READCONF_MAX_DEPTH 16
1711 read_config_file_depth(const char *filename, struct passwd *pw,
1712 const char *host, const char *original_host, Options *options,
1713 int flags, int *activep, int depth)
1718 int bad_options = 0;
1720 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1721 fatal("Too many recursive configuration includes");
1723 if ((f = fopen(filename, "r")) == NULL)
1726 if (flags & SSHCONF_CHECKPERM) {
1729 if (fstat(fileno(f), &sb) == -1)
1730 fatal("fstat %s: %s", filename, strerror(errno));
1731 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1732 (sb.st_mode & 022) != 0))
1733 fatal("Bad owner or permissions on %s", filename);
1736 debug("Reading configuration data %.200s", filename);
1739 * Mark that we are now processing the options. This flag is turned
1740 * on/off by Host specifications.
1743 while (fgets(line, sizeof(line), f)) {
1744 /* Update line number counter. */
1746 if (strlen(line) == sizeof(line) - 1)
1747 fatal("%s line %d too long", filename, linenum);
1748 if (process_config_line_depth(options, pw, host, original_host,
1749 line, filename, linenum, activep, flags, depth) != 0)
1753 if (bad_options > 0)
1754 fatal("%s: terminating, %d bad configuration options",
1755 filename, bad_options);
1759 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1761 option_clear_or_none(const char *o)
1763 return o == NULL || strcasecmp(o, "none") == 0;
1767 * Initializes options to special values that indicate that they have not yet
1768 * been set. Read_config_file will only set options with this value. Options
1769 * are processed in the following order: command line, user config file,
1770 * system config file. Last, fill_default_options is called.
1774 initialize_options(Options * options)
1776 memset(options, 'X', sizeof(*options));
1777 options->forward_agent = -1;
1778 options->forward_x11 = -1;
1779 options->forward_x11_trusted = -1;
1780 options->forward_x11_timeout = -1;
1781 options->stdio_forward_host = NULL;
1782 options->stdio_forward_port = 0;
1783 options->clear_forwardings = -1;
1784 options->exit_on_forward_failure = -1;
1785 options->xauth_location = NULL;
1786 options->fwd_opts.gateway_ports = -1;
1787 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1788 options->fwd_opts.streamlocal_bind_unlink = -1;
1789 options->use_privileged_port = -1;
1790 options->pubkey_authentication = -1;
1791 options->challenge_response_authentication = -1;
1792 options->gss_authentication = -1;
1793 options->gss_deleg_creds = -1;
1794 options->password_authentication = -1;
1795 options->kbd_interactive_authentication = -1;
1796 options->kbd_interactive_devices = NULL;
1797 options->hostbased_authentication = -1;
1798 options->batch_mode = -1;
1799 options->check_host_ip = -1;
1800 options->strict_host_key_checking = -1;
1801 options->compression = -1;
1802 options->tcp_keep_alive = -1;
1804 options->address_family = -1;
1805 options->connection_attempts = -1;
1806 options->connection_timeout = -1;
1807 options->number_of_password_prompts = -1;
1808 options->ciphers = NULL;
1809 options->macs = NULL;
1810 options->kex_algorithms = NULL;
1811 options->hostkeyalgorithms = NULL;
1812 options->num_identity_files = 0;
1813 options->num_certificate_files = 0;
1814 options->hostname = NULL;
1815 options->host_key_alias = NULL;
1816 options->proxy_command = NULL;
1817 options->jump_user = NULL;
1818 options->jump_host = NULL;
1819 options->jump_port = -1;
1820 options->jump_extra = NULL;
1821 options->user = NULL;
1822 options->escape_char = -1;
1823 options->num_system_hostfiles = 0;
1824 options->num_user_hostfiles = 0;
1825 options->local_forwards = NULL;
1826 options->num_local_forwards = 0;
1827 options->remote_forwards = NULL;
1828 options->num_remote_forwards = 0;
1829 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1830 options->log_level = SYSLOG_LEVEL_NOT_SET;
1831 options->preferred_authentications = NULL;
1832 options->bind_address = NULL;
1833 options->pkcs11_provider = NULL;
1834 options->enable_ssh_keysign = - 1;
1835 options->no_host_authentication_for_localhost = - 1;
1836 options->identities_only = - 1;
1837 options->rekey_limit = - 1;
1838 options->rekey_interval = -1;
1839 options->verify_host_key_dns = -1;
1840 options->server_alive_interval = -1;
1841 options->server_alive_count_max = -1;
1842 options->num_send_env = 0;
1843 options->control_path = NULL;
1844 options->control_master = -1;
1845 options->control_persist = -1;
1846 options->control_persist_timeout = 0;
1847 options->hash_known_hosts = -1;
1848 options->tun_open = -1;
1849 options->tun_local = -1;
1850 options->tun_remote = -1;
1851 options->local_command = NULL;
1852 options->permit_local_command = -1;
1853 options->remote_command = NULL;
1854 options->add_keys_to_agent = -1;
1855 options->identity_agent = NULL;
1856 options->visual_host_key = -1;
1857 options->ip_qos_interactive = -1;
1858 options->ip_qos_bulk = -1;
1859 options->request_tty = -1;
1860 options->proxy_use_fdpass = -1;
1861 options->ignored_unknown = NULL;
1862 options->num_canonical_domains = 0;
1863 options->num_permitted_cnames = 0;
1864 options->canonicalize_max_dots = -1;
1865 options->canonicalize_fallback_local = -1;
1866 options->canonicalize_hostname = -1;
1867 options->revoked_host_keys = NULL;
1868 options->fingerprint_hash = -1;
1869 options->update_hostkeys = -1;
1870 options->hostbased_key_types = NULL;
1871 options->pubkey_key_types = NULL;
1875 * A petite version of fill_default_options() that just fills the options
1876 * needed for hostname canonicalization to proceed.
1879 fill_default_options_for_canonicalization(Options *options)
1881 if (options->canonicalize_max_dots == -1)
1882 options->canonicalize_max_dots = 1;
1883 if (options->canonicalize_fallback_local == -1)
1884 options->canonicalize_fallback_local = 1;
1885 if (options->canonicalize_hostname == -1)
1886 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1890 * Called after processing other sources of option data, this fills those
1891 * options for which no value has been specified with their default values.
1894 fill_default_options(Options * options)
1896 if (options->forward_agent == -1)
1897 options->forward_agent = 0;
1898 if (options->forward_x11 == -1)
1899 options->forward_x11 = 0;
1900 if (options->forward_x11_trusted == -1)
1901 options->forward_x11_trusted = 0;
1902 if (options->forward_x11_timeout == -1)
1903 options->forward_x11_timeout = 1200;
1905 * stdio forwarding (-W) changes the default for these but we defer
1906 * setting the values so they can be overridden.
1908 if (options->exit_on_forward_failure == -1)
1909 options->exit_on_forward_failure =
1910 options->stdio_forward_host != NULL ? 1 : 0;
1911 if (options->clear_forwardings == -1)
1912 options->clear_forwardings =
1913 options->stdio_forward_host != NULL ? 1 : 0;
1914 if (options->clear_forwardings == 1)
1915 clear_forwardings(options);
1917 if (options->xauth_location == NULL)
1918 options->xauth_location = _PATH_XAUTH;
1919 if (options->fwd_opts.gateway_ports == -1)
1920 options->fwd_opts.gateway_ports = 0;
1921 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1922 options->fwd_opts.streamlocal_bind_mask = 0177;
1923 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1924 options->fwd_opts.streamlocal_bind_unlink = 0;
1925 if (options->use_privileged_port == -1)
1926 options->use_privileged_port = 0;
1927 if (options->pubkey_authentication == -1)
1928 options->pubkey_authentication = 1;
1929 if (options->challenge_response_authentication == -1)
1930 options->challenge_response_authentication = 1;
1931 if (options->gss_authentication == -1)
1932 options->gss_authentication = 0;
1933 if (options->gss_deleg_creds == -1)
1934 options->gss_deleg_creds = 0;
1935 if (options->password_authentication == -1)
1936 options->password_authentication = 0;
1937 if (options->kbd_interactive_authentication == -1)
1938 options->kbd_interactive_authentication = 1;
1939 if (options->hostbased_authentication == -1)
1940 options->hostbased_authentication = 0;
1941 if (options->batch_mode == -1)
1942 options->batch_mode = 0;
1943 if (options->check_host_ip == -1)
1944 options->check_host_ip = 1;
1945 if (options->strict_host_key_checking == -1)
1946 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
1947 if (options->compression == -1)
1948 options->compression = 0;
1949 if (options->tcp_keep_alive == -1)
1950 options->tcp_keep_alive = 1;
1951 if (options->port == -1)
1952 options->port = 0; /* Filled in ssh_connect. */
1953 if (options->address_family == -1)
1954 options->address_family = AF_UNSPEC;
1955 if (options->connection_attempts == -1)
1956 options->connection_attempts = 1;
1957 if (options->number_of_password_prompts == -1)
1958 options->number_of_password_prompts = 3;
1959 /* options->hostkeyalgorithms, default set in myproposals.h */
1960 if (options->add_keys_to_agent == -1)
1961 options->add_keys_to_agent = 0;
1962 if (options->num_identity_files == 0) {
1963 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
1964 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
1965 #ifdef OPENSSL_HAS_ECC
1966 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
1968 add_identity_file(options, "~/",
1969 _PATH_SSH_CLIENT_ID_ED25519, 0);
1971 if (options->escape_char == -1)
1972 options->escape_char = '~';
1973 if (options->num_system_hostfiles == 0) {
1974 options->system_hostfiles[options->num_system_hostfiles++] =
1975 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1976 options->system_hostfiles[options->num_system_hostfiles++] =
1977 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1979 if (options->num_user_hostfiles == 0) {
1980 options->user_hostfiles[options->num_user_hostfiles++] =
1981 xstrdup(_PATH_SSH_USER_HOSTFILE);
1982 options->user_hostfiles[options->num_user_hostfiles++] =
1983 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1985 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1986 options->log_level = SYSLOG_LEVEL_INFO;
1987 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1988 options->log_facility = SYSLOG_FACILITY_USER;
1989 if (options->no_host_authentication_for_localhost == - 1)
1990 options->no_host_authentication_for_localhost = 0;
1991 if (options->identities_only == -1)
1992 options->identities_only = 0;
1993 if (options->enable_ssh_keysign == -1)
1994 options->enable_ssh_keysign = 0;
1995 if (options->rekey_limit == -1)
1996 options->rekey_limit = 0;
1997 if (options->rekey_interval == -1)
1998 options->rekey_interval = 0;
1999 if (options->verify_host_key_dns == -1)
2000 options->verify_host_key_dns = 0;
2001 if (options->server_alive_interval == -1)
2002 options->server_alive_interval = 0;
2003 if (options->server_alive_count_max == -1)
2004 options->server_alive_count_max = 3;
2005 if (options->control_master == -1)
2006 options->control_master = 0;
2007 if (options->control_persist == -1) {
2008 options->control_persist = 0;
2009 options->control_persist_timeout = 0;
2011 if (options->hash_known_hosts == -1)
2012 options->hash_known_hosts = 0;
2013 if (options->tun_open == -1)
2014 options->tun_open = SSH_TUNMODE_NO;
2015 if (options->tun_local == -1)
2016 options->tun_local = SSH_TUNID_ANY;
2017 if (options->tun_remote == -1)
2018 options->tun_remote = SSH_TUNID_ANY;
2019 if (options->permit_local_command == -1)
2020 options->permit_local_command = 0;
2021 if (options->visual_host_key == -1)
2022 options->visual_host_key = 0;
2023 if (options->ip_qos_interactive == -1)
2024 options->ip_qos_interactive = IPTOS_LOWDELAY;
2025 if (options->ip_qos_bulk == -1)
2026 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2027 if (options->request_tty == -1)
2028 options->request_tty = REQUEST_TTY_AUTO;
2029 if (options->proxy_use_fdpass == -1)
2030 options->proxy_use_fdpass = 0;
2031 if (options->canonicalize_max_dots == -1)
2032 options->canonicalize_max_dots = 1;
2033 if (options->canonicalize_fallback_local == -1)
2034 options->canonicalize_fallback_local = 1;
2035 if (options->canonicalize_hostname == -1)
2036 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2037 if (options->fingerprint_hash == -1)
2038 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2039 if (options->update_hostkeys == -1)
2040 options->update_hostkeys = 0;
2041 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2042 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2043 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2044 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2045 &options->hostbased_key_types) != 0 ||
2046 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2047 &options->pubkey_key_types) != 0)
2048 fatal("%s: kex_assemble_names failed", __func__);
2050 #define CLEAR_ON_NONE(v) \
2052 if (option_clear_or_none(v)) { \
2057 CLEAR_ON_NONE(options->local_command);
2058 CLEAR_ON_NONE(options->remote_command);
2059 CLEAR_ON_NONE(options->proxy_command);
2060 CLEAR_ON_NONE(options->control_path);
2061 CLEAR_ON_NONE(options->revoked_host_keys);
2062 /* options->identity_agent distinguishes NULL from 'none' */
2063 /* options->user will be set in the main program if appropriate */
2064 /* options->hostname will be set in the main program if appropriate */
2065 /* options->host_key_alias should not be set by default */
2066 /* options->preferred_authentications will be set in ssh */
2076 * parses the next field in a port forwarding specification.
2077 * sets fwd to the parsed field and advances p past the colon
2078 * or sets it to NULL at end of string.
2079 * returns 0 on success, else non-zero.
2082 parse_fwd_field(char **p, struct fwdarg *fwd)
2089 return -1; /* end of string */
2093 * A field escaped with square brackets is used literally.
2094 * XXX - allow ']' to be escaped via backslash?
2097 /* find matching ']' */
2098 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2102 /* no matching ']' or not at end of field. */
2103 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2105 /* NUL terminate the field and advance p past the colon */
2110 fwd->ispath = ispath;
2115 for (cp = *p; *cp != '\0'; cp++) {
2118 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2132 fwd->ispath = ispath;
2139 * parses a string containing a port forwarding specification of the form:
2141 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2142 * listenpath:connectpath
2144 * [listenhost:]listenport
2145 * returns number of arguments parsed or zero on error
2148 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2150 struct fwdarg fwdargs[4];
2154 memset(fwd, 0, sizeof(*fwd));
2155 memset(fwdargs, 0, sizeof(fwdargs));
2157 cp = p = xstrdup(fwdspec);
2159 /* skip leading spaces */
2160 while (isspace((u_char)*cp))
2163 for (i = 0; i < 4; ++i) {
2164 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2168 /* Check for trailing garbage */
2169 if (cp != NULL && *cp != '\0') {
2170 i = 0; /* failure */
2175 if (fwdargs[0].ispath) {
2176 fwd->listen_path = xstrdup(fwdargs[0].arg);
2177 fwd->listen_port = PORT_STREAMLOCAL;
2179 fwd->listen_host = NULL;
2180 fwd->listen_port = a2port(fwdargs[0].arg);
2182 fwd->connect_host = xstrdup("socks");
2186 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2187 fwd->listen_path = xstrdup(fwdargs[0].arg);
2188 fwd->listen_port = PORT_STREAMLOCAL;
2189 fwd->connect_path = xstrdup(fwdargs[1].arg);
2190 fwd->connect_port = PORT_STREAMLOCAL;
2191 } else if (fwdargs[1].ispath) {
2192 fwd->listen_host = NULL;
2193 fwd->listen_port = a2port(fwdargs[0].arg);
2194 fwd->connect_path = xstrdup(fwdargs[1].arg);
2195 fwd->connect_port = PORT_STREAMLOCAL;
2197 fwd->listen_host = xstrdup(fwdargs[0].arg);
2198 fwd->listen_port = a2port(fwdargs[1].arg);
2199 fwd->connect_host = xstrdup("socks");
2204 if (fwdargs[0].ispath) {
2205 fwd->listen_path = xstrdup(fwdargs[0].arg);
2206 fwd->listen_port = PORT_STREAMLOCAL;
2207 fwd->connect_host = xstrdup(fwdargs[1].arg);
2208 fwd->connect_port = a2port(fwdargs[2].arg);
2209 } else if (fwdargs[2].ispath) {
2210 fwd->listen_host = xstrdup(fwdargs[0].arg);
2211 fwd->listen_port = a2port(fwdargs[1].arg);
2212 fwd->connect_path = xstrdup(fwdargs[2].arg);
2213 fwd->connect_port = PORT_STREAMLOCAL;
2215 fwd->listen_host = NULL;
2216 fwd->listen_port = a2port(fwdargs[0].arg);
2217 fwd->connect_host = xstrdup(fwdargs[1].arg);
2218 fwd->connect_port = a2port(fwdargs[2].arg);
2223 fwd->listen_host = xstrdup(fwdargs[0].arg);
2224 fwd->listen_port = a2port(fwdargs[1].arg);
2225 fwd->connect_host = xstrdup(fwdargs[2].arg);
2226 fwd->connect_port = a2port(fwdargs[3].arg);
2229 i = 0; /* failure */
2235 if (!(i == 1 || i == 2))
2238 if (!(i == 3 || i == 4)) {
2239 if (fwd->connect_path == NULL &&
2240 fwd->listen_path == NULL)
2243 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2247 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2248 (!remotefwd && fwd->listen_port == 0))
2250 if (fwd->connect_host != NULL &&
2251 strlen(fwd->connect_host) >= NI_MAXHOST)
2253 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2254 if (fwd->connect_path != NULL &&
2255 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2257 if (fwd->listen_host != NULL &&
2258 strlen(fwd->listen_host) >= NI_MAXHOST)
2260 if (fwd->listen_path != NULL &&
2261 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2267 free(fwd->connect_host);
2268 fwd->connect_host = NULL;
2269 free(fwd->connect_path);
2270 fwd->connect_path = NULL;
2271 free(fwd->listen_host);
2272 fwd->listen_host = NULL;
2273 free(fwd->listen_path);
2274 fwd->listen_path = NULL;
2279 parse_jump(const char *s, Options *o, int active)
2281 char *orig, *sdup, *cp;
2282 char *host = NULL, *user = NULL;
2283 int ret = -1, port = -1, first;
2285 active &= o->proxy_command == NULL && o->jump_host == NULL;
2287 orig = sdup = xstrdup(s);
2290 if ((cp = strrchr(sdup, ',')) == NULL)
2291 cp = sdup; /* last */
2296 /* First argument and configuration is active */
2297 if (parse_user_host_port(cp, &user, &host, &port) != 0)
2300 /* Subsequent argument or inactive configuration */
2301 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2304 first = 0; /* only check syntax for subsequent hosts */
2305 } while (cp != sdup);
2308 o->jump_user = user;
2309 o->jump_host = host;
2310 o->jump_port = port;
2311 o->proxy_command = xstrdup("none");
2313 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2314 o->jump_extra = xstrdup(s);
2315 o->jump_extra[cp - s] = '\0';
2326 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2328 fmt_multistate_int(int val, const struct multistate *m)
2332 for (i = 0; m[i].key != NULL; i++) {
2333 if (m[i].value == val)
2340 fmt_intarg(OpCodes code, int val)
2345 case oAddressFamily:
2346 return fmt_multistate_int(val, multistate_addressfamily);
2347 case oVerifyHostKeyDNS:
2348 case oUpdateHostkeys:
2349 return fmt_multistate_int(val, multistate_yesnoask);
2350 case oStrictHostKeyChecking:
2351 return fmt_multistate_int(val, multistate_strict_hostkey);
2352 case oControlMaster:
2353 return fmt_multistate_int(val, multistate_controlmaster);
2355 return fmt_multistate_int(val, multistate_tunnel);
2357 return fmt_multistate_int(val, multistate_requesttty);
2358 case oCanonicalizeHostname:
2359 return fmt_multistate_int(val, multistate_canonicalizehostname);
2360 case oFingerprintHash:
2361 return ssh_digest_alg_name(val);
2375 lookup_opcode_name(OpCodes code)
2379 for (i = 0; keywords[i].name != NULL; i++)
2380 if (keywords[i].opcode == code)
2381 return(keywords[i].name);
2386 dump_cfg_int(OpCodes code, int val)
2388 printf("%s %d\n", lookup_opcode_name(code), val);
2392 dump_cfg_fmtint(OpCodes code, int val)
2394 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2398 dump_cfg_string(OpCodes code, const char *val)
2402 printf("%s %s\n", lookup_opcode_name(code), val);
2406 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2410 for (i = 0; i < count; i++)
2411 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2415 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2419 printf("%s", lookup_opcode_name(code));
2420 for (i = 0; i < count; i++)
2421 printf(" %s", vals[i]);
2426 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2428 const struct Forward *fwd;
2431 /* oDynamicForward */
2432 for (i = 0; i < count; i++) {
2434 if (code == oDynamicForward && fwd->connect_host != NULL &&
2435 strcmp(fwd->connect_host, "socks") != 0)
2437 if (code == oLocalForward && fwd->connect_host != NULL &&
2438 strcmp(fwd->connect_host, "socks") == 0)
2440 printf("%s", lookup_opcode_name(code));
2441 if (fwd->listen_port == PORT_STREAMLOCAL)
2442 printf(" %s", fwd->listen_path);
2443 else if (fwd->listen_host == NULL)
2444 printf(" %d", fwd->listen_port);
2447 fwd->listen_host, fwd->listen_port);
2449 if (code != oDynamicForward) {
2450 if (fwd->connect_port == PORT_STREAMLOCAL)
2451 printf(" %s", fwd->connect_path);
2452 else if (fwd->connect_host == NULL)
2453 printf(" %d", fwd->connect_port);
2456 fwd->connect_host, fwd->connect_port);
2464 dump_client_config(Options *o, const char *host)
2469 /* This is normally prepared in ssh_kex2 */
2470 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2471 fatal("%s: kex_assemble_names failed", __func__);
2473 /* Most interesting options first: user, host, port */
2474 dump_cfg_string(oUser, o->user);
2475 dump_cfg_string(oHostName, host);
2476 dump_cfg_int(oPort, o->port);
2479 dump_cfg_fmtint(oAddressFamily, o->address_family);
2480 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2481 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2482 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2483 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2484 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2485 dump_cfg_fmtint(oCompression, o->compression);
2486 dump_cfg_fmtint(oControlMaster, o->control_master);
2487 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2488 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2489 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2490 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2491 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2492 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2493 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2494 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2496 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2497 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2499 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2500 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2501 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2502 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2503 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2504 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2505 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2506 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2507 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2508 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2509 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2510 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2511 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2512 dump_cfg_fmtint(oTunnel, o->tun_open);
2513 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2514 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2515 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2516 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2518 /* Integer options */
2519 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2520 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2521 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2522 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2523 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2524 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2526 /* String options */
2527 dump_cfg_string(oBindAddress, o->bind_address);
2528 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2529 dump_cfg_string(oControlPath, o->control_path);
2530 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2531 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2532 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2533 dump_cfg_string(oIdentityAgent, o->identity_agent);
2534 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2535 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2536 dump_cfg_string(oLocalCommand, o->local_command);
2537 dump_cfg_string(oRemoteCommand, o->remote_command);
2538 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2539 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2540 #ifdef ENABLE_PKCS11
2541 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2543 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2544 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2545 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2546 dump_cfg_string(oXAuthLocation, o->xauth_location);
2549 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2550 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2551 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2553 /* String array options */
2554 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2555 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2556 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2557 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2558 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2562 /* oConnectTimeout */
2563 if (o->connection_timeout == -1)
2564 printf("connecttimeout none\n");
2566 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2569 printf("tunneldevice");
2570 if (o->tun_local == SSH_TUNID_ANY)
2573 printf(" %d", o->tun_local);
2574 if (o->tun_remote == SSH_TUNID_ANY)
2577 printf(":%d", o->tun_remote);
2580 /* oCanonicalizePermittedCNAMEs */
2581 if ( o->num_permitted_cnames > 0) {
2582 printf("canonicalizePermittedcnames");
2583 for (i = 0; i < o->num_permitted_cnames; i++) {
2584 printf(" %s:%s", o->permitted_cnames[i].source_list,
2585 o->permitted_cnames[i].target_list);
2590 /* oControlPersist */
2591 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2592 dump_cfg_fmtint(oControlPersist, o->control_persist);
2594 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2597 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2598 printf("escapechar none\n");
2600 vis(buf, o->escape_char, VIS_WHITE, 0);
2601 printf("escapechar %s\n", buf);
2605 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2606 printf("%s\n", iptos2str(o->ip_qos_bulk));
2609 printf("rekeylimit %llu %d\n",
2610 (unsigned long long)o->rekey_limit, o->rekey_interval);
2612 /* oStreamLocalBindMask */
2613 printf("streamlocalbindmask 0%o\n",
2614 o->fwd_opts.streamlocal_bind_mask);
2616 /* oProxyCommand / oProxyJump */
2617 if (o->jump_host == NULL)
2618 dump_cfg_string(oProxyCommand, o->proxy_command);
2620 /* Check for numeric addresses */
2621 i = strchr(o->jump_host, ':') != NULL ||
2622 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2623 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2624 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2625 /* optional additional jump spec */
2626 o->jump_extra == NULL ? "" : o->jump_extra,
2627 o->jump_extra == NULL ? "" : ",",
2629 o->jump_user == NULL ? "" : o->jump_user,
2630 o->jump_user == NULL ? "" : "@",
2631 /* opening [ if hostname is numeric */
2633 /* mandatory hostname */
2635 /* closing ] if hostname is numeric */
2637 /* optional port number */
2638 o->jump_port <= 0 ? "" : ":",
2639 o->jump_port <= 0 ? "" : buf);