1 /* $OpenBSD: readconf.c,v 1.259 2016/07/22 03:35:11 djm Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Functions for reading the configuration files.
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
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, oLogLevel, oCiphers, oProtocol, 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, oLocalCommand, oPermitLocalCommand,
168 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
169 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
170 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
171 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
172 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
173 oPubkeyAcceptedKeyTypes, oProxyJump,
174 oIgnoredUnknownOption, oDeprecated, oUnsupported
177 /* Textual representations of the tokens. */
183 { "forwardagent", oForwardAgent },
184 { "forwardx11", oForwardX11 },
185 { "forwardx11trusted", oForwardX11Trusted },
186 { "forwardx11timeout", oForwardX11Timeout },
187 { "exitonforwardfailure", oExitOnForwardFailure },
188 { "xauthlocation", oXAuthLocation },
189 { "gatewayports", oGatewayPorts },
190 { "useprivilegedport", oUsePrivilegedPort },
191 { "rhostsauthentication", oDeprecated },
192 { "passwordauthentication", oPasswordAuthentication },
193 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
194 { "kbdinteractivedevices", oKbdInteractiveDevices },
195 { "rsaauthentication", oRSAAuthentication },
196 { "pubkeyauthentication", oPubkeyAuthentication },
197 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
198 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
199 { "hostbasedauthentication", oHostbasedAuthentication },
200 { "challengeresponseauthentication", oChallengeResponseAuthentication },
201 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
202 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
203 { "kerberosauthentication", oUnsupported },
204 { "kerberostgtpassing", oUnsupported },
205 { "afstokenpassing", oUnsupported },
207 { "gssapiauthentication", oGssAuthentication },
208 { "gssapidelegatecredentials", oGssDelegateCreds },
210 { "gssapiauthentication", oUnsupported },
211 { "gssapidelegatecredentials", oUnsupported },
213 { "fallbacktorsh", oDeprecated },
214 { "usersh", oDeprecated },
215 { "identityfile", oIdentityFile },
216 { "identityfile2", oIdentityFile }, /* obsolete */
217 { "identitiesonly", oIdentitiesOnly },
218 { "certificatefile", oCertificateFile },
219 { "addkeystoagent", oAddKeysToAgent },
220 { "identityagent", oIdentityAgent },
221 { "hostname", oHostName },
222 { "hostkeyalias", oHostKeyAlias },
223 { "proxycommand", oProxyCommand },
225 { "cipher", oCipher },
226 { "ciphers", oCiphers },
228 { "protocol", oProtocol },
229 { "remoteforward", oRemoteForward },
230 { "localforward", oLocalForward },
234 { "escapechar", oEscapeChar },
235 { "globalknownhostsfile", oGlobalKnownHostsFile },
236 { "globalknownhostsfile2", oDeprecated },
237 { "userknownhostsfile", oUserKnownHostsFile },
238 { "userknownhostsfile2", oDeprecated },
239 { "connectionattempts", oConnectionAttempts },
240 { "batchmode", oBatchMode },
241 { "checkhostip", oCheckHostIP },
242 { "stricthostkeychecking", oStrictHostKeyChecking },
243 { "compression", oCompression },
244 { "compressionlevel", oCompressionLevel },
245 { "tcpkeepalive", oTCPKeepAlive },
246 { "keepalive", oTCPKeepAlive }, /* obsolete */
247 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
248 { "loglevel", oLogLevel },
249 { "dynamicforward", oDynamicForward },
250 { "preferredauthentications", oPreferredAuthentications },
251 { "hostkeyalgorithms", oHostKeyAlgorithms },
252 { "bindaddress", oBindAddress },
254 { "smartcarddevice", oPKCS11Provider },
255 { "pkcs11provider", oPKCS11Provider },
257 { "smartcarddevice", oUnsupported },
258 { "pkcs11provider", oUnsupported },
260 { "clearallforwardings", oClearAllForwardings },
261 { "enablesshkeysign", oEnableSSHKeysign },
262 { "verifyhostkeydns", oVerifyHostKeyDNS },
263 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
264 { "rekeylimit", oRekeyLimit },
265 { "connecttimeout", oConnectTimeout },
266 { "addressfamily", oAddressFamily },
267 { "serveraliveinterval", oServerAliveInterval },
268 { "serveralivecountmax", oServerAliveCountMax },
269 { "sendenv", oSendEnv },
270 { "controlpath", oControlPath },
271 { "controlmaster", oControlMaster },
272 { "controlpersist", oControlPersist },
273 { "hashknownhosts", oHashKnownHosts },
274 { "include", oInclude },
275 { "tunnel", oTunnel },
276 { "tunneldevice", oTunnelDevice },
277 { "localcommand", oLocalCommand },
278 { "permitlocalcommand", oPermitLocalCommand },
279 { "visualhostkey", oVisualHostKey },
280 { "useroaming", oDeprecated },
281 { "kexalgorithms", oKexAlgorithms },
283 { "requesttty", oRequestTTY },
284 { "proxyusefdpass", oProxyUseFdpass },
285 { "canonicaldomains", oCanonicalDomains },
286 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
287 { "canonicalizehostname", oCanonicalizeHostname },
288 { "canonicalizemaxdots", oCanonicalizeMaxDots },
289 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
290 { "streamlocalbindmask", oStreamLocalBindMask },
291 { "streamlocalbindunlink", oStreamLocalBindUnlink },
292 { "revokedhostkeys", oRevokedHostKeys },
293 { "fingerprinthash", oFingerprintHash },
294 { "updatehostkeys", oUpdateHostkeys },
295 { "hostbasedkeytypes", oHostbasedKeyTypes },
296 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
297 { "ignoreunknown", oIgnoreUnknown },
298 { "proxyjump", oProxyJump },
304 * Adds a local TCP/IP port forward to options. Never returns if there is an
309 add_local_forward(Options *options, const struct Forward *newfwd)
312 extern uid_t original_real_uid;
315 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
316 newfwd->listen_path == NULL)
317 fatal("Privileged ports can only be forwarded by root.");
318 /* Don't add duplicates */
319 for (i = 0; i < options->num_local_forwards; i++) {
320 if (forward_equals(newfwd, options->local_forwards + i))
323 options->local_forwards = xreallocarray(options->local_forwards,
324 options->num_local_forwards + 1,
325 sizeof(*options->local_forwards));
326 fwd = &options->local_forwards[options->num_local_forwards++];
328 fwd->listen_host = newfwd->listen_host;
329 fwd->listen_port = newfwd->listen_port;
330 fwd->listen_path = newfwd->listen_path;
331 fwd->connect_host = newfwd->connect_host;
332 fwd->connect_port = newfwd->connect_port;
333 fwd->connect_path = newfwd->connect_path;
337 * Adds a remote TCP/IP port forward to options. Never returns if there is
342 add_remote_forward(Options *options, const struct Forward *newfwd)
347 /* Don't add duplicates */
348 for (i = 0; i < options->num_remote_forwards; i++) {
349 if (forward_equals(newfwd, options->remote_forwards + i))
352 options->remote_forwards = xreallocarray(options->remote_forwards,
353 options->num_remote_forwards + 1,
354 sizeof(*options->remote_forwards));
355 fwd = &options->remote_forwards[options->num_remote_forwards++];
357 fwd->listen_host = newfwd->listen_host;
358 fwd->listen_port = newfwd->listen_port;
359 fwd->listen_path = newfwd->listen_path;
360 fwd->connect_host = newfwd->connect_host;
361 fwd->connect_port = newfwd->connect_port;
362 fwd->connect_path = newfwd->connect_path;
363 fwd->handle = newfwd->handle;
364 fwd->allocated_port = 0;
368 clear_forwardings(Options *options)
372 for (i = 0; i < options->num_local_forwards; i++) {
373 free(options->local_forwards[i].listen_host);
374 free(options->local_forwards[i].listen_path);
375 free(options->local_forwards[i].connect_host);
376 free(options->local_forwards[i].connect_path);
378 if (options->num_local_forwards > 0) {
379 free(options->local_forwards);
380 options->local_forwards = NULL;
382 options->num_local_forwards = 0;
383 for (i = 0; i < options->num_remote_forwards; i++) {
384 free(options->remote_forwards[i].listen_host);
385 free(options->remote_forwards[i].listen_path);
386 free(options->remote_forwards[i].connect_host);
387 free(options->remote_forwards[i].connect_path);
389 if (options->num_remote_forwards > 0) {
390 free(options->remote_forwards);
391 options->remote_forwards = NULL;
393 options->num_remote_forwards = 0;
394 options->tun_open = SSH_TUNMODE_NO;
398 add_certificate_file(Options *options, const char *path, int userprovided)
402 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
403 fatal("Too many certificate files specified (max %d)",
404 SSH_MAX_CERTIFICATE_FILES);
406 /* Avoid registering duplicates */
407 for (i = 0; i < options->num_certificate_files; i++) {
408 if (options->certificate_file_userprovided[i] == userprovided &&
409 strcmp(options->certificate_files[i], path) == 0) {
410 debug2("%s: ignoring duplicate key %s", __func__, path);
415 options->certificate_file_userprovided[options->num_certificate_files] =
417 options->certificate_files[options->num_certificate_files++] =
422 add_identity_file(Options *options, const char *dir, const char *filename,
428 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
429 fatal("Too many identity files specified (max %d)",
430 SSH_MAX_IDENTITY_FILES);
432 if (dir == NULL) /* no dir, filename is absolute */
433 path = xstrdup(filename);
435 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
437 /* Avoid registering duplicates */
438 for (i = 0; i < options->num_identity_files; i++) {
439 if (options->identity_file_userprovided[i] == userprovided &&
440 strcmp(options->identity_files[i], path) == 0) {
441 debug2("%s: ignoring duplicate key %s", __func__, path);
447 options->identity_file_userprovided[options->num_identity_files] =
449 options->identity_files[options->num_identity_files++] = path;
453 default_ssh_port(void)
459 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
460 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
466 * Execute a command in a shell.
467 * Return its exit status or -1 on abnormal exit.
470 execute_in_shell(const char *cmd)
475 extern uid_t original_real_uid;
477 if ((shell = getenv("SHELL")) == NULL)
478 shell = _PATH_BSHELL;
480 /* Need this to redirect subprocess stdin/out */
481 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
482 fatal("open(/dev/null): %s", strerror(errno));
484 debug("Executing command: '%.500s'", cmd);
486 /* Fork and execute the command. */
487 if ((pid = fork()) == 0) {
490 /* Child. Permanently give up superuser privileges. */
491 permanently_drop_suid(original_real_uid);
493 /* Redirect child stdin and stdout. Leave stderr */
494 if (dup2(devnull, STDIN_FILENO) == -1)
495 fatal("dup2: %s", strerror(errno));
496 if (dup2(devnull, STDOUT_FILENO) == -1)
497 fatal("dup2: %s", strerror(errno));
498 if (devnull > STDERR_FILENO)
500 closefrom(STDERR_FILENO + 1);
504 argv[2] = xstrdup(cmd);
507 execv(argv[0], argv);
508 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
509 /* Die with signal to make this error apparent to parent. */
510 signal(SIGTERM, SIG_DFL);
511 kill(getpid(), SIGTERM);
516 fatal("%s: fork: %.100s", __func__, strerror(errno));
520 while (waitpid(pid, &status, 0) == -1) {
521 if (errno != EINTR && errno != EAGAIN)
522 fatal("%s: waitpid: %s", __func__, strerror(errno));
524 if (!WIFEXITED(status)) {
525 error("command '%.100s' exited abnormally", cmd);
528 debug3("command returned status %d", WEXITSTATUS(status));
529 return WEXITSTATUS(status);
533 * Parse and execute a Match directive.
536 match_cfg_line(Options *options, char **condition, struct passwd *pw,
537 const char *host_arg, const char *original_host, int post_canon,
538 const char *filename, int linenum)
540 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
542 int r, port, this_result, result = 1, attributes = 0, negate;
543 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
546 * Configuration is likely to be incomplete at this point so we
547 * must be prepared to use default values.
549 port = options->port <= 0 ? default_ssh_port() : options->port;
550 ruser = options->user == NULL ? pw->pw_name : options->user;
552 host = xstrdup(options->hostname);
553 } else if (options->hostname != NULL) {
554 /* NB. Please keep in sync with ssh.c:main() */
555 host = percent_expand(options->hostname,
556 "h", host_arg, (char *)NULL);
558 host = xstrdup(host_arg);
561 debug2("checking match for '%s' host %s originally %s",
562 cp, host, original_host);
563 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
566 if ((negate = attrib[0] == '!'))
568 /* criteria "all" and "canonical" have no argument */
569 if (strcasecmp(attrib, "all") == 0) {
570 if (attributes > 1 ||
571 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
572 error("%.200s line %d: '%s' cannot be combined "
573 "with other Match attributes",
574 filename, linenum, oattrib);
579 result = negate ? 0 : 1;
583 if (strcasecmp(attrib, "canonical") == 0) {
584 r = !!post_canon; /* force bitmask member to boolean */
585 if (r == (negate ? 1 : 0))
586 this_result = result = 0;
587 debug3("%.200s line %d: %smatched '%s'",
589 this_result ? "" : "not ", oattrib);
592 /* All other criteria require an argument */
593 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
594 error("Missing Match criteria for %s", attrib);
598 if (strcasecmp(attrib, "host") == 0) {
599 criteria = xstrdup(host);
600 r = match_hostname(host, arg) == 1;
601 if (r == (negate ? 1 : 0))
602 this_result = result = 0;
603 } else if (strcasecmp(attrib, "originalhost") == 0) {
604 criteria = xstrdup(original_host);
605 r = match_hostname(original_host, arg) == 1;
606 if (r == (negate ? 1 : 0))
607 this_result = result = 0;
608 } else if (strcasecmp(attrib, "user") == 0) {
609 criteria = xstrdup(ruser);
610 r = match_pattern_list(ruser, arg, 0) == 1;
611 if (r == (negate ? 1 : 0))
612 this_result = result = 0;
613 } else if (strcasecmp(attrib, "localuser") == 0) {
614 criteria = xstrdup(pw->pw_name);
615 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
616 if (r == (negate ? 1 : 0))
617 this_result = result = 0;
618 } else if (strcasecmp(attrib, "exec") == 0) {
619 if (gethostname(thishost, sizeof(thishost)) == -1)
620 fatal("gethostname: %s", strerror(errno));
621 strlcpy(shorthost, thishost, sizeof(shorthost));
622 shorthost[strcspn(thishost, ".")] = '\0';
623 snprintf(portstr, sizeof(portstr), "%d", port);
625 cmd = percent_expand(arg,
636 /* skip execution if prior predicate failed */
637 debug3("%.200s line %d: skipped exec "
638 "\"%.100s\"", filename, linenum, cmd);
642 r = execute_in_shell(cmd);
644 fatal("%.200s line %d: match exec "
645 "'%.100s' error", filename,
648 criteria = xstrdup(cmd);
650 /* Force exit status to boolean */
652 if (r == (negate ? 1 : 0))
653 this_result = result = 0;
655 error("Unsupported Match attribute %s", attrib);
659 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
660 filename, linenum, this_result ? "": "not ",
664 if (attributes == 0) {
665 error("One or more attributes required for Match");
671 debug2("match %sfound", result ? "" : "not ");
677 /* Check and prepare a domain name: removes trailing '.' and lowercases */
679 valid_domain(char *name, const char *filename, int linenum)
681 size_t i, l = strlen(name);
682 u_char c, last = '\0';
685 fatal("%s line %d: empty hostname suffix", filename, linenum);
686 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
687 fatal("%s line %d: hostname suffix \"%.100s\" "
688 "starts with invalid character", filename, linenum, name);
689 for (i = 0; i < l; i++) {
690 c = tolower((u_char)name[i]);
692 if (last == '.' && c == '.')
693 fatal("%s line %d: hostname suffix \"%.100s\" contains "
694 "consecutive separators", filename, linenum, name);
695 if (c != '.' && c != '-' && !isalnum(c) &&
696 c != '_') /* technically invalid, but common */
697 fatal("%s line %d: hostname suffix \"%.100s\" contains "
698 "invalid characters", filename, linenum, name);
701 if (name[l - 1] == '.')
706 * Returns the number of the token pointed to by cp or oBadOption.
709 parse_token(const char *cp, const char *filename, int linenum,
710 const char *ignored_unknown)
714 for (i = 0; keywords[i].name; i++)
715 if (strcmp(cp, keywords[i].name) == 0)
716 return keywords[i].opcode;
717 if (ignored_unknown != NULL &&
718 match_pattern_list(cp, ignored_unknown, 1) == 1)
719 return oIgnoredUnknownOption;
720 error("%s: line %d: Bad configuration option: %s",
721 filename, linenum, cp);
725 /* Multistate option parsing */
730 static const struct multistate multistate_flag[] = {
737 static const struct multistate multistate_yesnoask[] = {
745 static const struct multistate multistate_yesnoaskconfirm[] = {
754 static const struct multistate multistate_addressfamily[] = {
756 { "inet6", AF_INET6 },
757 { "any", AF_UNSPEC },
760 static const struct multistate multistate_controlmaster[] = {
761 { "true", SSHCTL_MASTER_YES },
762 { "yes", SSHCTL_MASTER_YES },
763 { "false", SSHCTL_MASTER_NO },
764 { "no", SSHCTL_MASTER_NO },
765 { "auto", SSHCTL_MASTER_AUTO },
766 { "ask", SSHCTL_MASTER_ASK },
767 { "autoask", SSHCTL_MASTER_AUTO_ASK },
770 static const struct multistate multistate_tunnel[] = {
771 { "ethernet", SSH_TUNMODE_ETHERNET },
772 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
773 { "true", SSH_TUNMODE_DEFAULT },
774 { "yes", SSH_TUNMODE_DEFAULT },
775 { "false", SSH_TUNMODE_NO },
776 { "no", SSH_TUNMODE_NO },
779 static const struct multistate multistate_requesttty[] = {
780 { "true", REQUEST_TTY_YES },
781 { "yes", REQUEST_TTY_YES },
782 { "false", REQUEST_TTY_NO },
783 { "no", REQUEST_TTY_NO },
784 { "force", REQUEST_TTY_FORCE },
785 { "auto", REQUEST_TTY_AUTO },
788 static const struct multistate multistate_canonicalizehostname[] = {
789 { "true", SSH_CANONICALISE_YES },
790 { "false", SSH_CANONICALISE_NO },
791 { "yes", SSH_CANONICALISE_YES },
792 { "no", SSH_CANONICALISE_NO },
793 { "always", SSH_CANONICALISE_ALWAYS },
798 * Processes a single option line as used in the configuration files. This
799 * only sets those values that have not already been set.
802 process_config_line(Options *options, struct passwd *pw, const char *host,
803 const char *original_host, char *line, const char *filename,
804 int linenum, int *activep, int flags)
806 return process_config_line_depth(options, pw, host, original_host,
807 line, filename, linenum, activep, flags, 0);
810 #define WHITESPACE " \t\r\n"
812 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
813 const char *original_host, char *line, const char *filename,
814 int linenum, int *activep, int flags, int depth)
816 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
817 char **cpptr, fwdarg[256];
818 u_int i, *uintptr, max_entries = 0;
819 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
820 LogLevel *log_level_ptr;
824 const struct multistate *multistate_ptr;
825 struct allowed_cname *cname;
828 if (activep == NULL) { /* We are processing a command line directive */
833 /* Strip trailing whitespace */
834 if ((len = strlen(line)) == 0)
836 for (len--; len > 0; len--) {
837 if (strchr(WHITESPACE, line[len]) == NULL)
843 /* Get the keyword. (Each line is supposed to begin with a keyword). */
844 if ((keyword = strdelim(&s)) == NULL)
846 /* Ignore leading whitespace. */
847 if (*keyword == '\0')
848 keyword = strdelim(&s);
849 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
851 /* Match lowercase keyword */
854 opcode = parse_token(keyword, filename, linenum,
855 options->ignored_unknown);
859 /* don't panic, but count bad options */
862 case oIgnoredUnknownOption:
863 debug("%s line %d: Ignored unknown option \"%s\"",
864 filename, linenum, keyword);
866 case oConnectTimeout:
867 intptr = &options->connection_timeout;
870 if (!arg || *arg == '\0')
871 fatal("%s line %d: missing time value.",
873 if (strcmp(arg, "none") == 0)
875 else if ((value = convtime(arg)) == -1)
876 fatal("%s line %d: invalid time value.",
878 if (*activep && *intptr == -1)
883 intptr = &options->forward_agent;
885 multistate_ptr = multistate_flag;
888 if (!arg || *arg == '\0')
889 fatal("%s line %d: missing argument.",
892 for (i = 0; multistate_ptr[i].key != NULL; i++) {
893 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
894 value = multistate_ptr[i].value;
899 fatal("%s line %d: unsupported option \"%s\".",
900 filename, linenum, arg);
901 if (*activep && *intptr == -1)
906 intptr = &options->forward_x11;
909 case oForwardX11Trusted:
910 intptr = &options->forward_x11_trusted;
913 case oForwardX11Timeout:
914 intptr = &options->forward_x11_timeout;
918 intptr = &options->fwd_opts.gateway_ports;
921 case oExitOnForwardFailure:
922 intptr = &options->exit_on_forward_failure;
925 case oUsePrivilegedPort:
926 intptr = &options->use_privileged_port;
929 case oPasswordAuthentication:
930 intptr = &options->password_authentication;
933 case oKbdInteractiveAuthentication:
934 intptr = &options->kbd_interactive_authentication;
937 case oKbdInteractiveDevices:
938 charptr = &options->kbd_interactive_devices;
941 case oPubkeyAuthentication:
942 intptr = &options->pubkey_authentication;
945 case oRSAAuthentication:
946 intptr = &options->rsa_authentication;
949 case oRhostsRSAAuthentication:
950 intptr = &options->rhosts_rsa_authentication;
953 case oHostbasedAuthentication:
954 intptr = &options->hostbased_authentication;
957 case oChallengeResponseAuthentication:
958 intptr = &options->challenge_response_authentication;
961 case oGssAuthentication:
962 intptr = &options->gss_authentication;
965 case oGssDelegateCreds:
966 intptr = &options->gss_deleg_creds;
970 intptr = &options->batch_mode;
974 intptr = &options->check_host_ip;
977 case oVerifyHostKeyDNS:
978 intptr = &options->verify_host_key_dns;
979 multistate_ptr = multistate_yesnoask;
980 goto parse_multistate;
982 case oStrictHostKeyChecking:
983 intptr = &options->strict_host_key_checking;
984 multistate_ptr = multistate_yesnoask;
985 goto parse_multistate;
988 intptr = &options->compression;
992 intptr = &options->tcp_keep_alive;
995 case oNoHostAuthenticationForLocalhost:
996 intptr = &options->no_host_authentication_for_localhost;
999 case oNumberOfPasswordPrompts:
1000 intptr = &options->number_of_password_prompts;
1003 case oCompressionLevel:
1004 intptr = &options->compression_level;
1009 if (!arg || *arg == '\0')
1010 fatal("%.200s line %d: Missing argument.", filename,
1012 if (strcmp(arg, "default") == 0) {
1015 if (scan_scaled(arg, &val64) == -1)
1016 fatal("%.200s line %d: Bad number '%s': %s",
1017 filename, linenum, arg, strerror(errno));
1018 if (val64 != 0 && val64 < 16)
1019 fatal("%.200s line %d: RekeyLimit too small",
1022 if (*activep && options->rekey_limit == -1)
1023 options->rekey_limit = val64;
1024 if (s != NULL) { /* optional rekey interval present */
1025 if (strcmp(s, "none") == 0) {
1026 (void)strdelim(&s); /* discard */
1029 intptr = &options->rekey_interval;
1036 if (!arg || *arg == '\0')
1037 fatal("%.200s line %d: Missing argument.", filename, linenum);
1039 intptr = &options->num_identity_files;
1040 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1041 fatal("%.200s line %d: Too many identity files specified (max %d).",
1042 filename, linenum, SSH_MAX_IDENTITY_FILES);
1043 add_identity_file(options, NULL,
1044 arg, flags & SSHCONF_USERCONF);
1048 case oCertificateFile:
1050 if (!arg || *arg == '\0')
1051 fatal("%.200s line %d: Missing argument.",
1054 intptr = &options->num_certificate_files;
1055 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1056 fatal("%.200s line %d: Too many certificate "
1057 "files specified (max %d).",
1059 SSH_MAX_CERTIFICATE_FILES);
1061 add_certificate_file(options, arg,
1062 flags & SSHCONF_USERCONF);
1066 case oXAuthLocation:
1067 charptr=&options->xauth_location;
1071 charptr = &options->user;
1074 if (!arg || *arg == '\0')
1075 fatal("%.200s line %d: Missing argument.",
1077 if (*activep && *charptr == NULL)
1078 *charptr = xstrdup(arg);
1081 case oGlobalKnownHostsFile:
1082 cpptr = (char **)&options->system_hostfiles;
1083 uintptr = &options->num_system_hostfiles;
1084 max_entries = SSH_MAX_HOSTS_FILES;
1086 if (*activep && *uintptr == 0) {
1087 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1088 if ((*uintptr) >= max_entries)
1089 fatal("%s line %d: "
1090 "too many authorized keys files.",
1092 cpptr[(*uintptr)++] = xstrdup(arg);
1097 case oUserKnownHostsFile:
1098 cpptr = (char **)&options->user_hostfiles;
1099 uintptr = &options->num_user_hostfiles;
1100 max_entries = SSH_MAX_HOSTS_FILES;
1101 goto parse_char_array;
1104 charptr = &options->hostname;
1108 charptr = &options->host_key_alias;
1111 case oPreferredAuthentications:
1112 charptr = &options->preferred_authentications;
1116 charptr = &options->bind_address;
1119 case oPKCS11Provider:
1120 charptr = &options->pkcs11_provider;
1124 charptr = &options->proxy_command;
1125 /* Ignore ProxyCommand if ProxyJump already specified */
1126 if (options->jump_host != NULL)
1127 charptr = &options->jump_host; /* Skip below */
1130 fatal("%.200s line %d: Missing argument.", filename, linenum);
1131 len = strspn(s, WHITESPACE "=");
1132 if (*activep && *charptr == NULL)
1133 *charptr = xstrdup(s + len);
1138 fatal("%.200s line %d: Missing argument.",
1141 len = strspn(s, WHITESPACE "=");
1142 if (parse_jump(s + len, options, *activep) == -1) {
1143 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1144 filename, linenum, s + len);
1149 intptr = &options->port;
1152 if (!arg || *arg == '\0')
1153 fatal("%.200s line %d: Missing argument.", filename, linenum);
1154 if (arg[0] < '0' || arg[0] > '9')
1155 fatal("%.200s line %d: Bad number.", filename, linenum);
1157 /* Octal, decimal, or hex format? */
1158 value = strtol(arg, &endofnumber, 0);
1159 if (arg == endofnumber)
1160 fatal("%.200s line %d: Bad number.", filename, linenum);
1161 if (*activep && *intptr == -1)
1165 case oConnectionAttempts:
1166 intptr = &options->connection_attempts;
1170 intptr = &options->cipher;
1172 if (!arg || *arg == '\0')
1173 fatal("%.200s line %d: Missing argument.", filename, linenum);
1174 value = cipher_number(arg);
1176 fatal("%.200s line %d: Bad cipher '%s'.",
1177 filename, linenum, arg ? arg : "<NONE>");
1178 if (*activep && *intptr == -1)
1184 if (!arg || *arg == '\0')
1185 fatal("%.200s line %d: Missing argument.", filename, linenum);
1186 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1187 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1188 filename, linenum, arg ? arg : "<NONE>");
1189 if (*activep && options->ciphers == NULL)
1190 options->ciphers = xstrdup(arg);
1195 if (!arg || *arg == '\0')
1196 fatal("%.200s line %d: Missing argument.", filename, linenum);
1197 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1198 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1199 filename, linenum, arg ? arg : "<NONE>");
1200 if (*activep && options->macs == NULL)
1201 options->macs = xstrdup(arg);
1204 case oKexAlgorithms:
1206 if (!arg || *arg == '\0')
1207 fatal("%.200s line %d: Missing argument.",
1209 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1210 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1211 filename, linenum, arg ? arg : "<NONE>");
1212 if (*activep && options->kex_algorithms == NULL)
1213 options->kex_algorithms = xstrdup(arg);
1216 case oHostKeyAlgorithms:
1217 charptr = &options->hostkeyalgorithms;
1220 if (!arg || *arg == '\0')
1221 fatal("%.200s line %d: Missing argument.",
1223 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1224 fatal("%s line %d: Bad key types '%s'.",
1225 filename, linenum, arg ? arg : "<NONE>");
1226 if (*activep && *charptr == NULL)
1227 *charptr = xstrdup(arg);
1231 intptr = &options->protocol;
1233 if (!arg || *arg == '\0')
1234 fatal("%.200s line %d: Missing argument.", filename, linenum);
1235 value = proto_spec(arg);
1236 if (value == SSH_PROTO_UNKNOWN)
1237 fatal("%.200s line %d: Bad protocol spec '%s'.",
1238 filename, linenum, arg ? arg : "<NONE>");
1239 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1244 log_level_ptr = &options->log_level;
1246 value = log_level_number(arg);
1247 if (value == SYSLOG_LEVEL_NOT_SET)
1248 fatal("%.200s line %d: unsupported log level '%s'",
1249 filename, linenum, arg ? arg : "<NONE>");
1250 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1251 *log_level_ptr = (LogLevel) value;
1255 case oRemoteForward:
1256 case oDynamicForward:
1258 if (arg == NULL || *arg == '\0')
1259 fatal("%.200s line %d: Missing port argument.",
1262 if (opcode == oLocalForward ||
1263 opcode == oRemoteForward) {
1264 arg2 = strdelim(&s);
1265 if (arg2 == NULL || *arg2 == '\0')
1266 fatal("%.200s line %d: Missing target argument.",
1269 /* construct a string for parse_forward */
1270 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1271 } else if (opcode == oDynamicForward) {
1272 strlcpy(fwdarg, arg, sizeof(fwdarg));
1275 if (parse_forward(&fwd, fwdarg,
1276 opcode == oDynamicForward ? 1 : 0,
1277 opcode == oRemoteForward ? 1 : 0) == 0)
1278 fatal("%.200s line %d: Bad forwarding specification.",
1282 if (opcode == oLocalForward ||
1283 opcode == oDynamicForward)
1284 add_local_forward(options, &fwd);
1285 else if (opcode == oRemoteForward)
1286 add_remote_forward(options, &fwd);
1290 case oClearAllForwardings:
1291 intptr = &options->clear_forwardings;
1296 fatal("Host directive not supported as a command-line "
1300 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1301 if ((flags & SSHCONF_NEVERMATCH) != 0)
1303 negated = *arg == '!';
1306 if (match_pattern(host, arg)) {
1308 debug("%.200s line %d: Skipping Host "
1309 "block because of negated match "
1310 "for %.100s", filename, linenum,
1316 arg2 = arg; /* logged below */
1321 debug("%.200s line %d: Applying options for %.100s",
1322 filename, linenum, arg2);
1323 /* Avoid garbage check below, as strdelim is done. */
1328 fatal("Host directive not supported as a command-line "
1330 value = match_cfg_line(options, &s, pw, host, original_host,
1331 flags & SSHCONF_POSTCANON, filename, linenum);
1333 fatal("%.200s line %d: Bad Match condition", filename,
1335 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1339 intptr = &options->escape_char;
1341 if (!arg || *arg == '\0')
1342 fatal("%.200s line %d: Missing argument.", filename, linenum);
1343 if (strcmp(arg, "none") == 0)
1344 value = SSH_ESCAPECHAR_NONE;
1345 else if (arg[1] == '\0')
1346 value = (u_char) arg[0];
1347 else if (arg[0] == '^' && arg[2] == 0 &&
1348 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1349 value = (u_char) arg[1] & 31;
1351 fatal("%.200s line %d: Bad escape character.",
1354 value = 0; /* Avoid compiler warning. */
1356 if (*activep && *intptr == -1)
1360 case oAddressFamily:
1361 intptr = &options->address_family;
1362 multistate_ptr = multistate_addressfamily;
1363 goto parse_multistate;
1365 case oEnableSSHKeysign:
1366 intptr = &options->enable_ssh_keysign;
1369 case oIdentitiesOnly:
1370 intptr = &options->identities_only;
1373 case oServerAliveInterval:
1374 intptr = &options->server_alive_interval;
1377 case oServerAliveCountMax:
1378 intptr = &options->server_alive_count_max;
1382 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1383 if (strchr(arg, '=') != NULL)
1384 fatal("%s line %d: Invalid environment name.",
1388 if (options->num_send_env >= MAX_SEND_ENV)
1389 fatal("%s line %d: too many send env.",
1391 options->send_env[options->num_send_env++] =
1397 charptr = &options->control_path;
1400 case oControlMaster:
1401 intptr = &options->control_master;
1402 multistate_ptr = multistate_controlmaster;
1403 goto parse_multistate;
1405 case oControlPersist:
1406 /* no/false/yes/true, or a time spec */
1407 intptr = &options->control_persist;
1409 if (!arg || *arg == '\0')
1410 fatal("%.200s line %d: Missing ControlPersist"
1411 " argument.", filename, linenum);
1413 value2 = 0; /* timeout */
1414 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1416 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1418 else if ((value2 = convtime(arg)) >= 0)
1421 fatal("%.200s line %d: Bad ControlPersist argument.",
1423 if (*activep && *intptr == -1) {
1425 options->control_persist_timeout = value2;
1429 case oHashKnownHosts:
1430 intptr = &options->hash_known_hosts;
1434 intptr = &options->tun_open;
1435 multistate_ptr = multistate_tunnel;
1436 goto parse_multistate;
1440 if (!arg || *arg == '\0')
1441 fatal("%.200s line %d: Missing argument.", filename, linenum);
1442 value = a2tun(arg, &value2);
1443 if (value == SSH_TUNID_ERR)
1444 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1446 options->tun_local = value;
1447 options->tun_remote = value2;
1452 charptr = &options->local_command;
1455 case oPermitLocalCommand:
1456 intptr = &options->permit_local_command;
1459 case oVisualHostKey:
1460 intptr = &options->visual_host_key;
1465 fatal("Include directive not supported as a "
1466 "command-line option");
1468 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1470 * Ensure all paths are anchored. User configuration
1471 * files may begin with '~/' but system configurations
1472 * must not. If the path is relative, then treat it
1473 * as living in ~/.ssh for user configurations or
1474 * /etc/ssh for system ones.
1476 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1477 fatal("%.200s line %d: bad include path %s.",
1478 filename, linenum, arg);
1479 if (*arg != '/' && *arg != '~') {
1480 xasprintf(&arg2, "%s/%s",
1481 (flags & SSHCONF_USERCONF) ?
1482 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1484 arg2 = xstrdup(arg);
1485 memset(&gl, 0, sizeof(gl));
1486 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1487 if (r == GLOB_NOMATCH) {
1488 debug("%.200s line %d: include %s matched no "
1489 "files",filename, linenum, arg2);
1491 } else if (r != 0 || gl.gl_pathc < 0)
1492 fatal("%.200s line %d: glob failed for %s.",
1493 filename, linenum, arg2);
1496 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1497 debug3("%.200s line %d: Including file %s "
1498 "depth %d%s", filename, linenum,
1499 gl.gl_pathv[i], depth,
1500 oactive ? "" : " (parse only)");
1501 r = read_config_file_depth(gl.gl_pathv[i],
1502 pw, host, original_host, options,
1503 flags | SSHCONF_CHECKPERM |
1504 (oactive ? 0 : SSHCONF_NEVERMATCH),
1505 activep, depth + 1);
1507 * don't let Match in includes clobber the
1508 * containing file's Match state.
1522 if ((value = parse_ipqos(arg)) == -1)
1523 fatal("%s line %d: Bad IPQoS value: %s",
1524 filename, linenum, arg);
1528 else if ((value2 = parse_ipqos(arg)) == -1)
1529 fatal("%s line %d: Bad IPQoS value: %s",
1530 filename, linenum, arg);
1532 options->ip_qos_interactive = value;
1533 options->ip_qos_bulk = value2;
1538 intptr = &options->request_tty;
1539 multistate_ptr = multistate_requesttty;
1540 goto parse_multistate;
1542 case oIgnoreUnknown:
1543 charptr = &options->ignored_unknown;
1546 case oProxyUseFdpass:
1547 intptr = &options->proxy_use_fdpass;
1550 case oCanonicalDomains:
1551 value = options->num_canonical_domains != 0;
1552 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1553 valid_domain(arg, filename, linenum);
1554 if (!*activep || value)
1556 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1557 fatal("%s line %d: too many hostname suffixes.",
1559 options->canonical_domains[
1560 options->num_canonical_domains++] = xstrdup(arg);
1564 case oCanonicalizePermittedCNAMEs:
1565 value = options->num_permitted_cnames != 0;
1566 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1567 /* Either '*' for everything or 'list:list' */
1568 if (strcmp(arg, "*") == 0)
1572 if ((arg2 = strchr(arg, ':')) == NULL ||
1574 fatal("%s line %d: "
1575 "Invalid permitted CNAME \"%s\"",
1576 filename, linenum, arg);
1581 if (!*activep || value)
1583 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1584 fatal("%s line %d: too many permitted CNAMEs.",
1586 cname = options->permitted_cnames +
1587 options->num_permitted_cnames++;
1588 cname->source_list = xstrdup(arg);
1589 cname->target_list = xstrdup(arg2);
1593 case oCanonicalizeHostname:
1594 intptr = &options->canonicalize_hostname;
1595 multistate_ptr = multistate_canonicalizehostname;
1596 goto parse_multistate;
1598 case oCanonicalizeMaxDots:
1599 intptr = &options->canonicalize_max_dots;
1602 case oCanonicalizeFallbackLocal:
1603 intptr = &options->canonicalize_fallback_local;
1606 case oStreamLocalBindMask:
1608 if (!arg || *arg == '\0')
1609 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1610 /* Parse mode in octal format */
1611 value = strtol(arg, &endofnumber, 8);
1612 if (arg == endofnumber || value < 0 || value > 0777)
1613 fatal("%.200s line %d: Bad mask.", filename, linenum);
1614 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1617 case oStreamLocalBindUnlink:
1618 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1621 case oRevokedHostKeys:
1622 charptr = &options->revoked_host_keys;
1625 case oFingerprintHash:
1626 intptr = &options->fingerprint_hash;
1628 if (!arg || *arg == '\0')
1629 fatal("%.200s line %d: Missing argument.",
1631 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1632 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1633 filename, linenum, arg);
1634 if (*activep && *intptr == -1)
1638 case oUpdateHostkeys:
1639 intptr = &options->update_hostkeys;
1640 multistate_ptr = multistate_yesnoask;
1641 goto parse_multistate;
1643 case oHostbasedKeyTypes:
1644 charptr = &options->hostbased_key_types;
1645 goto parse_keytypes;
1647 case oPubkeyAcceptedKeyTypes:
1648 charptr = &options->pubkey_key_types;
1649 goto parse_keytypes;
1651 case oAddKeysToAgent:
1652 intptr = &options->add_keys_to_agent;
1653 multistate_ptr = multistate_yesnoaskconfirm;
1654 goto parse_multistate;
1656 case oIdentityAgent:
1657 charptr = &options->identity_agent;
1661 debug("%s line %d: Deprecated option \"%s\"",
1662 filename, linenum, keyword);
1666 error("%s line %d: Unsupported option \"%s\"",
1667 filename, linenum, keyword);
1671 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1674 /* Check that there is no garbage at end of line. */
1675 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1676 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1677 filename, linenum, arg);
1683 * Reads the config file and modifies the options accordingly. Options
1684 * should already be initialized before this call. This never returns if
1685 * there is an error. If the file does not exist, this returns 0.
1688 read_config_file(const char *filename, struct passwd *pw, const char *host,
1689 const char *original_host, Options *options, int flags)
1693 return read_config_file_depth(filename, pw, host, original_host,
1694 options, flags, &active, 0);
1697 #define READCONF_MAX_DEPTH 16
1699 read_config_file_depth(const char *filename, struct passwd *pw,
1700 const char *host, const char *original_host, Options *options,
1701 int flags, int *activep, int depth)
1706 int bad_options = 0;
1708 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1709 fatal("Too many recursive configuration includes");
1711 if ((f = fopen(filename, "r")) == NULL)
1714 if (flags & SSHCONF_CHECKPERM) {
1717 if (fstat(fileno(f), &sb) == -1)
1718 fatal("fstat %s: %s", filename, strerror(errno));
1719 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1720 (sb.st_mode & 022) != 0))
1721 fatal("Bad owner or permissions on %s", filename);
1724 debug("Reading configuration data %.200s", filename);
1727 * Mark that we are now processing the options. This flag is turned
1728 * on/off by Host specifications.
1731 while (fgets(line, sizeof(line), f)) {
1732 /* Update line number counter. */
1734 if (process_config_line_depth(options, pw, host, original_host,
1735 line, filename, linenum, activep, flags, depth) != 0)
1739 if (bad_options > 0)
1740 fatal("%s: terminating, %d bad configuration options",
1741 filename, bad_options);
1745 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1747 option_clear_or_none(const char *o)
1749 return o == NULL || strcasecmp(o, "none") == 0;
1753 * Initializes options to special values that indicate that they have not yet
1754 * been set. Read_config_file will only set options with this value. Options
1755 * are processed in the following order: command line, user config file,
1756 * system config file. Last, fill_default_options is called.
1760 initialize_options(Options * options)
1762 memset(options, 'X', sizeof(*options));
1763 options->forward_agent = -1;
1764 options->forward_x11 = -1;
1765 options->forward_x11_trusted = -1;
1766 options->forward_x11_timeout = -1;
1767 options->stdio_forward_host = NULL;
1768 options->stdio_forward_port = 0;
1769 options->clear_forwardings = -1;
1770 options->exit_on_forward_failure = -1;
1771 options->xauth_location = NULL;
1772 options->fwd_opts.gateway_ports = -1;
1773 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1774 options->fwd_opts.streamlocal_bind_unlink = -1;
1775 options->use_privileged_port = -1;
1776 options->rsa_authentication = -1;
1777 options->pubkey_authentication = -1;
1778 options->challenge_response_authentication = -1;
1779 options->gss_authentication = -1;
1780 options->gss_deleg_creds = -1;
1781 options->password_authentication = -1;
1782 options->kbd_interactive_authentication = -1;
1783 options->kbd_interactive_devices = NULL;
1784 options->rhosts_rsa_authentication = -1;
1785 options->hostbased_authentication = -1;
1786 options->batch_mode = -1;
1787 options->check_host_ip = -1;
1788 options->strict_host_key_checking = -1;
1789 options->compression = -1;
1790 options->tcp_keep_alive = -1;
1791 options->compression_level = -1;
1793 options->address_family = -1;
1794 options->connection_attempts = -1;
1795 options->connection_timeout = -1;
1796 options->number_of_password_prompts = -1;
1797 options->cipher = -1;
1798 options->ciphers = NULL;
1799 options->macs = NULL;
1800 options->kex_algorithms = NULL;
1801 options->hostkeyalgorithms = NULL;
1802 options->protocol = SSH_PROTO_UNKNOWN;
1803 options->num_identity_files = 0;
1804 options->num_certificate_files = 0;
1805 options->hostname = NULL;
1806 options->host_key_alias = NULL;
1807 options->proxy_command = NULL;
1808 options->jump_user = NULL;
1809 options->jump_host = NULL;
1810 options->jump_port = -1;
1811 options->jump_extra = NULL;
1812 options->user = NULL;
1813 options->escape_char = -1;
1814 options->num_system_hostfiles = 0;
1815 options->num_user_hostfiles = 0;
1816 options->local_forwards = NULL;
1817 options->num_local_forwards = 0;
1818 options->remote_forwards = NULL;
1819 options->num_remote_forwards = 0;
1820 options->log_level = SYSLOG_LEVEL_NOT_SET;
1821 options->preferred_authentications = NULL;
1822 options->bind_address = NULL;
1823 options->pkcs11_provider = NULL;
1824 options->enable_ssh_keysign = - 1;
1825 options->no_host_authentication_for_localhost = - 1;
1826 options->identities_only = - 1;
1827 options->rekey_limit = - 1;
1828 options->rekey_interval = -1;
1829 options->verify_host_key_dns = -1;
1830 options->server_alive_interval = -1;
1831 options->server_alive_count_max = -1;
1832 options->num_send_env = 0;
1833 options->control_path = NULL;
1834 options->control_master = -1;
1835 options->control_persist = -1;
1836 options->control_persist_timeout = 0;
1837 options->hash_known_hosts = -1;
1838 options->tun_open = -1;
1839 options->tun_local = -1;
1840 options->tun_remote = -1;
1841 options->local_command = NULL;
1842 options->permit_local_command = -1;
1843 options->add_keys_to_agent = -1;
1844 options->identity_agent = NULL;
1845 options->visual_host_key = -1;
1846 options->ip_qos_interactive = -1;
1847 options->ip_qos_bulk = -1;
1848 options->request_tty = -1;
1849 options->proxy_use_fdpass = -1;
1850 options->ignored_unknown = NULL;
1851 options->num_canonical_domains = 0;
1852 options->num_permitted_cnames = 0;
1853 options->canonicalize_max_dots = -1;
1854 options->canonicalize_fallback_local = -1;
1855 options->canonicalize_hostname = -1;
1856 options->revoked_host_keys = NULL;
1857 options->fingerprint_hash = -1;
1858 options->update_hostkeys = -1;
1859 options->hostbased_key_types = NULL;
1860 options->pubkey_key_types = NULL;
1864 * A petite version of fill_default_options() that just fills the options
1865 * needed for hostname canonicalization to proceed.
1868 fill_default_options_for_canonicalization(Options *options)
1870 if (options->canonicalize_max_dots == -1)
1871 options->canonicalize_max_dots = 1;
1872 if (options->canonicalize_fallback_local == -1)
1873 options->canonicalize_fallback_local = 1;
1874 if (options->canonicalize_hostname == -1)
1875 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1879 * Called after processing other sources of option data, this fills those
1880 * options for which no value has been specified with their default values.
1883 fill_default_options(Options * options)
1885 if (options->forward_agent == -1)
1886 options->forward_agent = 0;
1887 if (options->forward_x11 == -1)
1888 options->forward_x11 = 0;
1889 if (options->forward_x11_trusted == -1)
1890 options->forward_x11_trusted = 0;
1891 if (options->forward_x11_timeout == -1)
1892 options->forward_x11_timeout = 1200;
1894 * stdio forwarding (-W) changes the default for these but we defer
1895 * setting the values so they can be overridden.
1897 if (options->exit_on_forward_failure == -1)
1898 options->exit_on_forward_failure =
1899 options->stdio_forward_host != NULL ? 1 : 0;
1900 if (options->clear_forwardings == -1)
1901 options->clear_forwardings =
1902 options->stdio_forward_host != NULL ? 1 : 0;
1903 if (options->clear_forwardings == 1)
1904 clear_forwardings(options);
1906 if (options->xauth_location == NULL)
1907 options->xauth_location = _PATH_XAUTH;
1908 if (options->fwd_opts.gateway_ports == -1)
1909 options->fwd_opts.gateway_ports = 0;
1910 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1911 options->fwd_opts.streamlocal_bind_mask = 0177;
1912 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1913 options->fwd_opts.streamlocal_bind_unlink = 0;
1914 if (options->use_privileged_port == -1)
1915 options->use_privileged_port = 0;
1916 if (options->rsa_authentication == -1)
1917 options->rsa_authentication = 1;
1918 if (options->pubkey_authentication == -1)
1919 options->pubkey_authentication = 1;
1920 if (options->challenge_response_authentication == -1)
1921 options->challenge_response_authentication = 1;
1922 if (options->gss_authentication == -1)
1923 options->gss_authentication = 0;
1924 if (options->gss_deleg_creds == -1)
1925 options->gss_deleg_creds = 0;
1926 if (options->password_authentication == -1)
1927 options->password_authentication = 1;
1928 if (options->kbd_interactive_authentication == -1)
1929 options->kbd_interactive_authentication = 1;
1930 if (options->rhosts_rsa_authentication == -1)
1931 options->rhosts_rsa_authentication = 0;
1932 if (options->hostbased_authentication == -1)
1933 options->hostbased_authentication = 0;
1934 if (options->batch_mode == -1)
1935 options->batch_mode = 0;
1936 if (options->check_host_ip == -1)
1937 options->check_host_ip = 1;
1938 if (options->strict_host_key_checking == -1)
1939 options->strict_host_key_checking = 2; /* 2 is default */
1940 if (options->compression == -1)
1941 options->compression = 0;
1942 if (options->tcp_keep_alive == -1)
1943 options->tcp_keep_alive = 1;
1944 if (options->compression_level == -1)
1945 options->compression_level = 6;
1946 if (options->port == -1)
1947 options->port = 0; /* Filled in ssh_connect. */
1948 if (options->address_family == -1)
1949 options->address_family = AF_UNSPEC;
1950 if (options->connection_attempts == -1)
1951 options->connection_attempts = 1;
1952 if (options->number_of_password_prompts == -1)
1953 options->number_of_password_prompts = 3;
1954 /* Selected in ssh_login(). */
1955 if (options->cipher == -1)
1956 options->cipher = SSH_CIPHER_NOT_SET;
1957 /* options->hostkeyalgorithms, default set in myproposals.h */
1958 if (options->protocol == SSH_PROTO_UNKNOWN)
1959 options->protocol = SSH_PROTO_2;
1960 if (options->add_keys_to_agent == -1)
1961 options->add_keys_to_agent = 0;
1962 if (options->num_identity_files == 0) {
1963 if (options->protocol & SSH_PROTO_1) {
1964 add_identity_file(options, "~/",
1965 _PATH_SSH_CLIENT_IDENTITY, 0);
1967 if (options->protocol & SSH_PROTO_2) {
1968 add_identity_file(options, "~/",
1969 _PATH_SSH_CLIENT_ID_RSA, 0);
1970 add_identity_file(options, "~/",
1971 _PATH_SSH_CLIENT_ID_DSA, 0);
1972 #ifdef OPENSSL_HAS_ECC
1973 add_identity_file(options, "~/",
1974 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1976 add_identity_file(options, "~/",
1977 _PATH_SSH_CLIENT_ID_ED25519, 0);
1980 if (options->escape_char == -1)
1981 options->escape_char = '~';
1982 if (options->num_system_hostfiles == 0) {
1983 options->system_hostfiles[options->num_system_hostfiles++] =
1984 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
1985 options->system_hostfiles[options->num_system_hostfiles++] =
1986 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
1988 if (options->num_user_hostfiles == 0) {
1989 options->user_hostfiles[options->num_user_hostfiles++] =
1990 xstrdup(_PATH_SSH_USER_HOSTFILE);
1991 options->user_hostfiles[options->num_user_hostfiles++] =
1992 xstrdup(_PATH_SSH_USER_HOSTFILE2);
1994 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
1995 options->log_level = SYSLOG_LEVEL_INFO;
1996 if (options->no_host_authentication_for_localhost == - 1)
1997 options->no_host_authentication_for_localhost = 0;
1998 if (options->identities_only == -1)
1999 options->identities_only = 0;
2000 if (options->enable_ssh_keysign == -1)
2001 options->enable_ssh_keysign = 0;
2002 if (options->rekey_limit == -1)
2003 options->rekey_limit = 0;
2004 if (options->rekey_interval == -1)
2005 options->rekey_interval = 0;
2006 if (options->verify_host_key_dns == -1)
2007 options->verify_host_key_dns = 0;
2008 if (options->server_alive_interval == -1)
2009 options->server_alive_interval = 0;
2010 if (options->server_alive_count_max == -1)
2011 options->server_alive_count_max = 3;
2012 if (options->control_master == -1)
2013 options->control_master = 0;
2014 if (options->control_persist == -1) {
2015 options->control_persist = 0;
2016 options->control_persist_timeout = 0;
2018 if (options->hash_known_hosts == -1)
2019 options->hash_known_hosts = 0;
2020 if (options->tun_open == -1)
2021 options->tun_open = SSH_TUNMODE_NO;
2022 if (options->tun_local == -1)
2023 options->tun_local = SSH_TUNID_ANY;
2024 if (options->tun_remote == -1)
2025 options->tun_remote = SSH_TUNID_ANY;
2026 if (options->permit_local_command == -1)
2027 options->permit_local_command = 0;
2028 if (options->visual_host_key == -1)
2029 options->visual_host_key = 0;
2030 if (options->ip_qos_interactive == -1)
2031 options->ip_qos_interactive = IPTOS_LOWDELAY;
2032 if (options->ip_qos_bulk == -1)
2033 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2034 if (options->request_tty == -1)
2035 options->request_tty = REQUEST_TTY_AUTO;
2036 if (options->proxy_use_fdpass == -1)
2037 options->proxy_use_fdpass = 0;
2038 if (options->canonicalize_max_dots == -1)
2039 options->canonicalize_max_dots = 1;
2040 if (options->canonicalize_fallback_local == -1)
2041 options->canonicalize_fallback_local = 1;
2042 if (options->canonicalize_hostname == -1)
2043 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2044 if (options->fingerprint_hash == -1)
2045 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2046 if (options->update_hostkeys == -1)
2047 options->update_hostkeys = 0;
2048 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2049 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2050 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2051 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2052 &options->hostbased_key_types) != 0 ||
2053 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2054 &options->pubkey_key_types) != 0)
2055 fatal("%s: kex_assemble_names failed", __func__);
2057 #define CLEAR_ON_NONE(v) \
2059 if (option_clear_or_none(v)) { \
2064 CLEAR_ON_NONE(options->local_command);
2065 CLEAR_ON_NONE(options->proxy_command);
2066 CLEAR_ON_NONE(options->control_path);
2067 CLEAR_ON_NONE(options->revoked_host_keys);
2068 /* options->identity_agent distinguishes NULL from 'none' */
2069 /* options->user will be set in the main program if appropriate */
2070 /* options->hostname will be set in the main program if appropriate */
2071 /* options->host_key_alias should not be set by default */
2072 /* options->preferred_authentications will be set in ssh */
2082 * parses the next field in a port forwarding specification.
2083 * sets fwd to the parsed field and advances p past the colon
2084 * or sets it to NULL at end of string.
2085 * returns 0 on success, else non-zero.
2088 parse_fwd_field(char **p, struct fwdarg *fwd)
2095 return -1; /* end of string */
2099 * A field escaped with square brackets is used literally.
2100 * XXX - allow ']' to be escaped via backslash?
2103 /* find matching ']' */
2104 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2108 /* no matching ']' or not at end of field. */
2109 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2111 /* NUL terminate the field and advance p past the colon */
2116 fwd->ispath = ispath;
2121 for (cp = *p; *cp != '\0'; cp++) {
2124 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2138 fwd->ispath = ispath;
2145 * parses a string containing a port forwarding specification of the form:
2147 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2148 * listenpath:connectpath
2150 * [listenhost:]listenport
2151 * returns number of arguments parsed or zero on error
2154 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2156 struct fwdarg fwdargs[4];
2160 memset(fwd, 0, sizeof(*fwd));
2161 memset(fwdargs, 0, sizeof(fwdargs));
2163 cp = p = xstrdup(fwdspec);
2165 /* skip leading spaces */
2166 while (isspace((u_char)*cp))
2169 for (i = 0; i < 4; ++i) {
2170 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2174 /* Check for trailing garbage */
2175 if (cp != NULL && *cp != '\0') {
2176 i = 0; /* failure */
2181 if (fwdargs[0].ispath) {
2182 fwd->listen_path = xstrdup(fwdargs[0].arg);
2183 fwd->listen_port = PORT_STREAMLOCAL;
2185 fwd->listen_host = NULL;
2186 fwd->listen_port = a2port(fwdargs[0].arg);
2188 fwd->connect_host = xstrdup("socks");
2192 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2193 fwd->listen_path = xstrdup(fwdargs[0].arg);
2194 fwd->listen_port = PORT_STREAMLOCAL;
2195 fwd->connect_path = xstrdup(fwdargs[1].arg);
2196 fwd->connect_port = PORT_STREAMLOCAL;
2197 } else if (fwdargs[1].ispath) {
2198 fwd->listen_host = NULL;
2199 fwd->listen_port = a2port(fwdargs[0].arg);
2200 fwd->connect_path = xstrdup(fwdargs[1].arg);
2201 fwd->connect_port = PORT_STREAMLOCAL;
2203 fwd->listen_host = xstrdup(fwdargs[0].arg);
2204 fwd->listen_port = a2port(fwdargs[1].arg);
2205 fwd->connect_host = xstrdup("socks");
2210 if (fwdargs[0].ispath) {
2211 fwd->listen_path = xstrdup(fwdargs[0].arg);
2212 fwd->listen_port = PORT_STREAMLOCAL;
2213 fwd->connect_host = xstrdup(fwdargs[1].arg);
2214 fwd->connect_port = a2port(fwdargs[2].arg);
2215 } else if (fwdargs[2].ispath) {
2216 fwd->listen_host = xstrdup(fwdargs[0].arg);
2217 fwd->listen_port = a2port(fwdargs[1].arg);
2218 fwd->connect_path = xstrdup(fwdargs[2].arg);
2219 fwd->connect_port = PORT_STREAMLOCAL;
2221 fwd->listen_host = NULL;
2222 fwd->listen_port = a2port(fwdargs[0].arg);
2223 fwd->connect_host = xstrdup(fwdargs[1].arg);
2224 fwd->connect_port = a2port(fwdargs[2].arg);
2229 fwd->listen_host = xstrdup(fwdargs[0].arg);
2230 fwd->listen_port = a2port(fwdargs[1].arg);
2231 fwd->connect_host = xstrdup(fwdargs[2].arg);
2232 fwd->connect_port = a2port(fwdargs[3].arg);
2235 i = 0; /* failure */
2241 if (!(i == 1 || i == 2))
2244 if (!(i == 3 || i == 4)) {
2245 if (fwd->connect_path == NULL &&
2246 fwd->listen_path == NULL)
2249 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2253 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2254 (!remotefwd && fwd->listen_port == 0))
2256 if (fwd->connect_host != NULL &&
2257 strlen(fwd->connect_host) >= NI_MAXHOST)
2259 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2260 if (fwd->connect_path != NULL &&
2261 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2263 if (fwd->listen_host != NULL &&
2264 strlen(fwd->listen_host) >= NI_MAXHOST)
2266 if (fwd->listen_path != NULL &&
2267 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2273 free(fwd->connect_host);
2274 fwd->connect_host = NULL;
2275 free(fwd->connect_path);
2276 fwd->connect_path = NULL;
2277 free(fwd->listen_host);
2278 fwd->listen_host = NULL;
2279 free(fwd->listen_path);
2280 fwd->listen_path = NULL;
2285 parse_jump(const char *s, Options *o, int active)
2287 char *orig, *sdup, *cp;
2288 char *host = NULL, *user = NULL;
2289 int ret = -1, port = -1, first;
2291 active &= o->proxy_command == NULL && o->jump_host == NULL;
2293 orig = sdup = xstrdup(s);
2296 if ((cp = strrchr(sdup, ',')) == NULL)
2297 cp = sdup; /* last */
2302 /* First argument and configuration is active */
2303 if (parse_user_host_port(cp, &user, &host, &port) != 0)
2306 /* Subsequent argument or inactive configuration */
2307 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2310 first = 0; /* only check syntax for subsequent hosts */
2311 } while (cp != sdup);
2314 o->jump_user = user;
2315 o->jump_host = host;
2316 o->jump_port = port;
2317 o->proxy_command = xstrdup("none");
2319 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2320 o->jump_extra = xstrdup(s);
2321 o->jump_extra[cp - s] = '\0';
2332 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2334 fmt_multistate_int(int val, const struct multistate *m)
2338 for (i = 0; m[i].key != NULL; i++) {
2339 if (m[i].value == val)
2346 fmt_intarg(OpCodes code, int val)
2351 case oAddressFamily:
2352 return fmt_multistate_int(val, multistate_addressfamily);
2353 case oVerifyHostKeyDNS:
2354 case oStrictHostKeyChecking:
2355 case oUpdateHostkeys:
2356 return fmt_multistate_int(val, multistate_yesnoask);
2357 case oControlMaster:
2358 return fmt_multistate_int(val, multistate_controlmaster);
2360 return fmt_multistate_int(val, multistate_tunnel);
2362 return fmt_multistate_int(val, multistate_requesttty);
2363 case oCanonicalizeHostname:
2364 return fmt_multistate_int(val, multistate_canonicalizehostname);
2365 case oFingerprintHash:
2366 return ssh_digest_alg_name(val);
2373 case (SSH_PROTO_1|SSH_PROTO_2):
2391 lookup_opcode_name(OpCodes code)
2395 for (i = 0; keywords[i].name != NULL; i++)
2396 if (keywords[i].opcode == code)
2397 return(keywords[i].name);
2402 dump_cfg_int(OpCodes code, int val)
2404 printf("%s %d\n", lookup_opcode_name(code), val);
2408 dump_cfg_fmtint(OpCodes code, int val)
2410 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2414 dump_cfg_string(OpCodes code, const char *val)
2418 printf("%s %s\n", lookup_opcode_name(code), val);
2422 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2426 for (i = 0; i < count; i++)
2427 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2431 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2435 printf("%s", lookup_opcode_name(code));
2436 for (i = 0; i < count; i++)
2437 printf(" %s", vals[i]);
2442 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2444 const struct Forward *fwd;
2447 /* oDynamicForward */
2448 for (i = 0; i < count; i++) {
2450 if (code == oDynamicForward &&
2451 strcmp(fwd->connect_host, "socks") != 0)
2453 if (code == oLocalForward &&
2454 strcmp(fwd->connect_host, "socks") == 0)
2456 printf("%s", lookup_opcode_name(code));
2457 if (fwd->listen_port == PORT_STREAMLOCAL)
2458 printf(" %s", fwd->listen_path);
2459 else if (fwd->listen_host == NULL)
2460 printf(" %d", fwd->listen_port);
2463 fwd->listen_host, fwd->listen_port);
2465 if (code != oDynamicForward) {
2466 if (fwd->connect_port == PORT_STREAMLOCAL)
2467 printf(" %s", fwd->connect_path);
2468 else if (fwd->connect_host == NULL)
2469 printf(" %d", fwd->connect_port);
2472 fwd->connect_host, fwd->connect_port);
2480 dump_client_config(Options *o, const char *host)
2485 /* This is normally prepared in ssh_kex2 */
2486 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2487 fatal("%s: kex_assemble_names failed", __func__);
2489 /* Most interesting options first: user, host, port */
2490 dump_cfg_string(oUser, o->user);
2491 dump_cfg_string(oHostName, host);
2492 dump_cfg_int(oPort, o->port);
2495 dump_cfg_fmtint(oAddressFamily, o->address_family);
2496 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2497 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2498 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2499 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2500 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2501 dump_cfg_fmtint(oCompression, o->compression);
2502 dump_cfg_fmtint(oControlMaster, o->control_master);
2503 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2504 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2505 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2506 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2507 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2508 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2509 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2510 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2512 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2513 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2515 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2516 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2517 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2518 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2519 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2520 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2521 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2522 dump_cfg_fmtint(oProtocol, o->protocol);
2523 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2524 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2525 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2526 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2527 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2528 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2529 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2530 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2531 dump_cfg_fmtint(oTunnel, o->tun_open);
2532 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2533 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2534 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2535 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2537 /* Integer options */
2538 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2539 dump_cfg_int(oCompressionLevel, o->compression_level);
2540 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2541 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2542 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2543 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2544 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2546 /* String options */
2547 dump_cfg_string(oBindAddress, o->bind_address);
2548 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2549 dump_cfg_string(oControlPath, o->control_path);
2550 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2551 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2552 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2553 dump_cfg_string(oIdentityAgent, o->identity_agent);
2554 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2555 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2556 dump_cfg_string(oLocalCommand, o->local_command);
2557 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2558 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2559 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2560 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2561 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2562 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2563 dump_cfg_string(oXAuthLocation, o->xauth_location);
2566 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2567 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2568 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2570 /* String array options */
2571 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2572 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2573 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2574 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2575 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2579 /* oConnectTimeout */
2580 if (o->connection_timeout == -1)
2581 printf("connecttimeout none\n");
2583 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2586 printf("tunneldevice");
2587 if (o->tun_local == SSH_TUNID_ANY)
2590 printf(" %d", o->tun_local);
2591 if (o->tun_remote == SSH_TUNID_ANY)
2594 printf(":%d", o->tun_remote);
2597 /* oCanonicalizePermittedCNAMEs */
2598 if ( o->num_permitted_cnames > 0) {
2599 printf("canonicalizePermittedcnames");
2600 for (i = 0; i < o->num_permitted_cnames; i++) {
2601 printf(" %s:%s", o->permitted_cnames[i].source_list,
2602 o->permitted_cnames[i].target_list);
2608 if (o->cipher != SSH_CIPHER_NOT_SET)
2609 printf("Cipher %s\n", cipher_name(o->cipher));
2611 /* oControlPersist */
2612 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2613 dump_cfg_fmtint(oControlPersist, o->control_persist);
2615 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2618 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2619 printf("escapechar none\n");
2621 vis(buf, o->escape_char, VIS_WHITE, 0);
2622 printf("escapechar %s\n", buf);
2626 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2627 printf("%s\n", iptos2str(o->ip_qos_bulk));
2630 printf("rekeylimit %llu %d\n",
2631 (unsigned long long)o->rekey_limit, o->rekey_interval);
2633 /* oStreamLocalBindMask */
2634 printf("streamlocalbindmask 0%o\n",
2635 o->fwd_opts.streamlocal_bind_mask);
2637 /* oProxyCommand / oProxyJump */
2638 if (o->jump_host == NULL)
2639 dump_cfg_string(oProxyCommand, o->proxy_command);
2641 /* Check for numeric addresses */
2642 i = strchr(o->jump_host, ':') != NULL ||
2643 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2644 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2645 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2646 /* optional additional jump spec */
2647 o->jump_extra == NULL ? "" : o->jump_extra,
2648 o->jump_extra == NULL ? "" : ",",
2650 o->jump_user == NULL ? "" : o->jump_user,
2651 o->jump_user == NULL ? "" : "@",
2652 /* opening [ if hostname is numeric */
2654 /* mandatory hostname */
2656 /* closing ] if hostname is numeric */
2658 /* optional port number */
2659 o->jump_port <= 0 ? "" : ":",
2660 o->jump_port <= 0 ? "" : buf);