1 /* $OpenBSD: readconf.c,v 1.297 2018/08/12 20:19:13 djm Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Functions for reading the configuration files.
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
18 #include <sys/types.h>
20 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
43 #ifdef USE_SYSTEM_GLOB
46 # include "openbsd-compat/glob.h"
51 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
60 #include "pathnames.h"
69 #include "myproposal.h"
73 /* Format of the configuration file:
75 # Configuration data is parsed as follows:
76 # 1. command line options
77 # 2. user-specific file
79 # Any configuration value is only changed the first time it is set.
80 # Thus, host-specific definitions should be at the beginning of the
81 # configuration file, and defaults at the end.
83 # Host-specific declarations. These may override anything above. A single
84 # host may match multiple declarations; these are processed in the order
85 # that they are given in.
91 HostName another.host.name.real.org
98 RemoteForward 9999 shadows.cs.hut.fi:9999
101 Host fascist.blob.com
104 PasswordAuthentication no
108 ProxyCommand ssh-proxy %h %p
111 PublicKeyAuthentication no
115 PasswordAuthentication no
121 # Defaults for various options
125 PasswordAuthentication yes
126 RSAAuthentication yes
127 RhostsRSAAuthentication yes
128 StrictHostKeyChecking yes
130 IdentityFile ~/.ssh/identity
136 static int read_config_file_depth(const char *filename, struct passwd *pw,
137 const char *host, const char *original_host, Options *options,
138 int flags, int *activep, int depth);
139 static int process_config_line_depth(Options *options, struct passwd *pw,
140 const char *host, const char *original_host, char *line,
141 const char *filename, int linenum, int *activep, int flags, int depth);
143 /* Keyword tokens. */
148 oHost, oMatch, oInclude,
149 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
150 oGatewayPorts, oExitOnForwardFailure,
151 oPasswordAuthentication, oRSAAuthentication,
152 oChallengeResponseAuthentication, oXAuthLocation,
153 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
154 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
155 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
156 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
157 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
158 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
159 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
160 oPubkeyAuthentication,
161 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
162 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
163 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
164 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
165 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
166 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
167 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
168 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
170 oTunnel, oTunnelDevice,
171 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
173 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
174 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
175 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
176 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
177 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
178 oPubkeyAcceptedKeyTypes, oProxyJump,
179 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
182 /* Textual representations of the tokens. */
188 /* Deprecated options */
189 { "protocol", oIgnore }, /* NB. silently ignored */
190 { "cipher", oDeprecated },
191 { "fallbacktorsh", oDeprecated },
192 { "globalknownhostsfile2", oDeprecated },
193 { "rhostsauthentication", oDeprecated },
194 { "userknownhostsfile2", oDeprecated },
195 { "useroaming", oDeprecated },
196 { "usersh", oDeprecated },
197 { "useprivilegedport", oDeprecated },
199 /* Unsupported options */
200 { "afstokenpassing", oUnsupported },
201 { "kerberosauthentication", oUnsupported },
202 { "kerberostgtpassing", oUnsupported },
204 /* Sometimes-unsupported options */
206 { "gssapiauthentication", oGssAuthentication },
207 { "gssapidelegatecredentials", oGssDelegateCreds },
209 { "gssapiauthentication", oUnsupported },
210 { "gssapidelegatecredentials", oUnsupported },
213 { "smartcarddevice", oPKCS11Provider },
214 { "pkcs11provider", oPKCS11Provider },
216 { "smartcarddevice", oUnsupported },
217 { "pkcs11provider", oUnsupported },
219 { "rsaauthentication", oUnsupported },
220 { "rhostsrsaauthentication", oUnsupported },
221 { "compressionlevel", oUnsupported },
223 { "forwardagent", oForwardAgent },
224 { "forwardx11", oForwardX11 },
225 { "forwardx11trusted", oForwardX11Trusted },
226 { "forwardx11timeout", oForwardX11Timeout },
227 { "exitonforwardfailure", oExitOnForwardFailure },
228 { "xauthlocation", oXAuthLocation },
229 { "gatewayports", oGatewayPorts },
230 { "passwordauthentication", oPasswordAuthentication },
231 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
232 { "kbdinteractivedevices", oKbdInteractiveDevices },
233 { "pubkeyauthentication", oPubkeyAuthentication },
234 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
235 { "hostbasedauthentication", oHostbasedAuthentication },
236 { "challengeresponseauthentication", oChallengeResponseAuthentication },
237 { "skeyauthentication", oUnsupported },
238 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
239 { "identityfile", oIdentityFile },
240 { "identityfile2", oIdentityFile }, /* obsolete */
241 { "identitiesonly", oIdentitiesOnly },
242 { "certificatefile", oCertificateFile },
243 { "addkeystoagent", oAddKeysToAgent },
244 { "identityagent", oIdentityAgent },
245 { "hostname", oHostName },
246 { "hostkeyalias", oHostKeyAlias },
247 { "proxycommand", oProxyCommand },
249 { "ciphers", oCiphers },
251 { "remoteforward", oRemoteForward },
252 { "localforward", oLocalForward },
256 { "escapechar", oEscapeChar },
257 { "globalknownhostsfile", oGlobalKnownHostsFile },
258 { "userknownhostsfile", oUserKnownHostsFile },
259 { "connectionattempts", oConnectionAttempts },
260 { "batchmode", oBatchMode },
261 { "checkhostip", oCheckHostIP },
262 { "stricthostkeychecking", oStrictHostKeyChecking },
263 { "compression", oCompression },
264 { "tcpkeepalive", oTCPKeepAlive },
265 { "keepalive", oTCPKeepAlive }, /* obsolete */
266 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
267 { "syslogfacility", oLogFacility },
268 { "loglevel", oLogLevel },
269 { "dynamicforward", oDynamicForward },
270 { "preferredauthentications", oPreferredAuthentications },
271 { "hostkeyalgorithms", oHostKeyAlgorithms },
272 { "bindaddress", oBindAddress },
273 { "bindinterface", oBindInterface },
274 { "clearallforwardings", oClearAllForwardings },
275 { "enablesshkeysign", oEnableSSHKeysign },
276 { "verifyhostkeydns", oVerifyHostKeyDNS },
277 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
278 { "rekeylimit", oRekeyLimit },
279 { "connecttimeout", oConnectTimeout },
280 { "addressfamily", oAddressFamily },
281 { "serveraliveinterval", oServerAliveInterval },
282 { "serveralivecountmax", oServerAliveCountMax },
283 { "sendenv", oSendEnv },
284 { "setenv", oSetEnv },
285 { "controlpath", oControlPath },
286 { "controlmaster", oControlMaster },
287 { "controlpersist", oControlPersist },
288 { "hashknownhosts", oHashKnownHosts },
289 { "include", oInclude },
290 { "tunnel", oTunnel },
291 { "tunneldevice", oTunnelDevice },
292 { "localcommand", oLocalCommand },
293 { "permitlocalcommand", oPermitLocalCommand },
294 { "remotecommand", oRemoteCommand },
295 { "visualhostkey", oVisualHostKey },
296 { "kexalgorithms", oKexAlgorithms },
298 { "requesttty", oRequestTTY },
299 { "proxyusefdpass", oProxyUseFdpass },
300 { "canonicaldomains", oCanonicalDomains },
301 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
302 { "canonicalizehostname", oCanonicalizeHostname },
303 { "canonicalizemaxdots", oCanonicalizeMaxDots },
304 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
305 { "streamlocalbindmask", oStreamLocalBindMask },
306 { "streamlocalbindunlink", oStreamLocalBindUnlink },
307 { "revokedhostkeys", oRevokedHostKeys },
308 { "fingerprinthash", oFingerprintHash },
309 { "updatehostkeys", oUpdateHostkeys },
310 { "hostbasedkeytypes", oHostbasedKeyTypes },
311 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
312 { "ignoreunknown", oIgnoreUnknown },
313 { "proxyjump", oProxyJump },
315 { "hpndisabled", oDeprecated },
316 { "hpnbuffersize", oDeprecated },
317 { "tcprcvbufpoll", oDeprecated },
318 { "tcprcvbuf", oDeprecated },
319 { "noneenabled", oUnsupported },
320 { "noneswitch", oUnsupported },
321 { "versionaddendum", oVersionAddendum },
327 * Adds a local TCP/IP port forward to options. Never returns if there is an
332 add_local_forward(Options *options, const struct Forward *newfwd)
335 int i, ipport_reserved;
337 /* Don't add duplicates */
338 for (i = 0; i < options->num_local_forwards; i++) {
339 if (forward_equals(newfwd, options->local_forwards + i))
342 options->local_forwards = xreallocarray(options->local_forwards,
343 options->num_local_forwards + 1,
344 sizeof(*options->local_forwards));
345 fwd = &options->local_forwards[options->num_local_forwards++];
347 fwd->listen_host = newfwd->listen_host;
348 fwd->listen_port = newfwd->listen_port;
349 fwd->listen_path = newfwd->listen_path;
350 fwd->connect_host = newfwd->connect_host;
351 fwd->connect_port = newfwd->connect_port;
352 fwd->connect_path = newfwd->connect_path;
356 * Adds a remote TCP/IP port forward to options. Never returns if there is
361 add_remote_forward(Options *options, const struct Forward *newfwd)
366 /* Don't add duplicates */
367 for (i = 0; i < options->num_remote_forwards; i++) {
368 if (forward_equals(newfwd, options->remote_forwards + i))
371 options->remote_forwards = xreallocarray(options->remote_forwards,
372 options->num_remote_forwards + 1,
373 sizeof(*options->remote_forwards));
374 fwd = &options->remote_forwards[options->num_remote_forwards++];
376 fwd->listen_host = newfwd->listen_host;
377 fwd->listen_port = newfwd->listen_port;
378 fwd->listen_path = newfwd->listen_path;
379 fwd->connect_host = newfwd->connect_host;
380 fwd->connect_port = newfwd->connect_port;
381 fwd->connect_path = newfwd->connect_path;
382 fwd->handle = newfwd->handle;
383 fwd->allocated_port = 0;
387 clear_forwardings(Options *options)
391 for (i = 0; i < options->num_local_forwards; i++) {
392 free(options->local_forwards[i].listen_host);
393 free(options->local_forwards[i].listen_path);
394 free(options->local_forwards[i].connect_host);
395 free(options->local_forwards[i].connect_path);
397 if (options->num_local_forwards > 0) {
398 free(options->local_forwards);
399 options->local_forwards = NULL;
401 options->num_local_forwards = 0;
402 for (i = 0; i < options->num_remote_forwards; i++) {
403 free(options->remote_forwards[i].listen_host);
404 free(options->remote_forwards[i].listen_path);
405 free(options->remote_forwards[i].connect_host);
406 free(options->remote_forwards[i].connect_path);
408 if (options->num_remote_forwards > 0) {
409 free(options->remote_forwards);
410 options->remote_forwards = NULL;
412 options->num_remote_forwards = 0;
413 options->tun_open = SSH_TUNMODE_NO;
417 add_certificate_file(Options *options, const char *path, int userprovided)
421 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
422 fatal("Too many certificate files specified (max %d)",
423 SSH_MAX_CERTIFICATE_FILES);
425 /* Avoid registering duplicates */
426 for (i = 0; i < options->num_certificate_files; i++) {
427 if (options->certificate_file_userprovided[i] == userprovided &&
428 strcmp(options->certificate_files[i], path) == 0) {
429 debug2("%s: ignoring duplicate key %s", __func__, path);
434 options->certificate_file_userprovided[options->num_certificate_files] =
436 options->certificate_files[options->num_certificate_files++] =
441 add_identity_file(Options *options, const char *dir, const char *filename,
447 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
448 fatal("Too many identity files specified (max %d)",
449 SSH_MAX_IDENTITY_FILES);
451 if (dir == NULL) /* no dir, filename is absolute */
452 path = xstrdup(filename);
453 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
454 fatal("Identity file path %s too long", path);
456 /* Avoid registering duplicates */
457 for (i = 0; i < options->num_identity_files; i++) {
458 if (options->identity_file_userprovided[i] == userprovided &&
459 strcmp(options->identity_files[i], path) == 0) {
460 debug2("%s: ignoring duplicate key %s", __func__, path);
466 options->identity_file_userprovided[options->num_identity_files] =
468 options->identity_files[options->num_identity_files++] = path;
472 default_ssh_port(void)
478 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
479 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
485 * Execute a command in a shell.
486 * Return its exit status or -1 on abnormal exit.
489 execute_in_shell(const char *cmd)
495 if ((shell = getenv("SHELL")) == NULL)
496 shell = _PATH_BSHELL;
498 /* Need this to redirect subprocess stdin/out */
499 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
500 fatal("open(/dev/null): %s", strerror(errno));
502 debug("Executing command: '%.500s'", cmd);
504 /* Fork and execute the command. */
505 if ((pid = fork()) == 0) {
508 /* Redirect child stdin and stdout. Leave stderr */
509 if (dup2(devnull, STDIN_FILENO) == -1)
510 fatal("dup2: %s", strerror(errno));
511 if (dup2(devnull, STDOUT_FILENO) == -1)
512 fatal("dup2: %s", strerror(errno));
513 if (devnull > STDERR_FILENO)
515 closefrom(STDERR_FILENO + 1);
519 argv[2] = xstrdup(cmd);
522 execv(argv[0], argv);
523 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
524 /* Die with signal to make this error apparent to parent. */
525 signal(SIGTERM, SIG_DFL);
526 kill(getpid(), SIGTERM);
531 fatal("%s: fork: %.100s", __func__, strerror(errno));
535 while (waitpid(pid, &status, 0) == -1) {
536 if (errno != EINTR && errno != EAGAIN)
537 fatal("%s: waitpid: %s", __func__, strerror(errno));
539 if (!WIFEXITED(status)) {
540 error("command '%.100s' exited abnormally", cmd);
543 debug3("command returned status %d", WEXITSTATUS(status));
544 return WEXITSTATUS(status);
548 * Parse and execute a Match directive.
551 match_cfg_line(Options *options, char **condition, struct passwd *pw,
552 const char *host_arg, const char *original_host, int post_canon,
553 const char *filename, int linenum)
555 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
557 int r, port, this_result, result = 1, attributes = 0, negate;
558 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
562 * Configuration is likely to be incomplete at this point so we
563 * must be prepared to use default values.
565 port = options->port <= 0 ? default_ssh_port() : options->port;
566 ruser = options->user == NULL ? pw->pw_name : options->user;
568 host = xstrdup(options->hostname);
569 } else if (options->hostname != NULL) {
570 /* NB. Please keep in sync with ssh.c:main() */
571 host = percent_expand(options->hostname,
572 "h", host_arg, (char *)NULL);
574 host = xstrdup(host_arg);
577 debug2("checking match for '%s' host %s originally %s",
578 cp, host, original_host);
579 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
582 if ((negate = attrib[0] == '!'))
584 /* criteria "all" and "canonical" have no argument */
585 if (strcasecmp(attrib, "all") == 0) {
586 if (attributes > 1 ||
587 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
588 error("%.200s line %d: '%s' cannot be combined "
589 "with other Match attributes",
590 filename, linenum, oattrib);
595 result = negate ? 0 : 1;
599 if (strcasecmp(attrib, "canonical") == 0) {
600 r = !!post_canon; /* force bitmask member to boolean */
601 if (r == (negate ? 1 : 0))
602 this_result = result = 0;
603 debug3("%.200s line %d: %smatched '%s'",
605 this_result ? "" : "not ", oattrib);
608 /* All other criteria require an argument */
609 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
610 error("Missing Match criteria for %s", attrib);
614 if (strcasecmp(attrib, "host") == 0) {
615 criteria = xstrdup(host);
616 r = match_hostname(host, arg) == 1;
617 if (r == (negate ? 1 : 0))
618 this_result = result = 0;
619 } else if (strcasecmp(attrib, "originalhost") == 0) {
620 criteria = xstrdup(original_host);
621 r = match_hostname(original_host, arg) == 1;
622 if (r == (negate ? 1 : 0))
623 this_result = result = 0;
624 } else if (strcasecmp(attrib, "user") == 0) {
625 criteria = xstrdup(ruser);
626 r = match_pattern_list(ruser, arg, 0) == 1;
627 if (r == (negate ? 1 : 0))
628 this_result = result = 0;
629 } else if (strcasecmp(attrib, "localuser") == 0) {
630 criteria = xstrdup(pw->pw_name);
631 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
632 if (r == (negate ? 1 : 0))
633 this_result = result = 0;
634 } else if (strcasecmp(attrib, "exec") == 0) {
635 if (gethostname(thishost, sizeof(thishost)) == -1)
636 fatal("gethostname: %s", strerror(errno));
637 strlcpy(shorthost, thishost, sizeof(shorthost));
638 shorthost[strcspn(thishost, ".")] = '\0';
639 snprintf(portstr, sizeof(portstr), "%d", port);
640 snprintf(uidstr, sizeof(uidstr), "%llu",
641 (unsigned long long)pw->pw_uid);
643 cmd = percent_expand(arg,
655 /* skip execution if prior predicate failed */
656 debug3("%.200s line %d: skipped exec "
657 "\"%.100s\"", filename, linenum, cmd);
661 r = execute_in_shell(cmd);
663 fatal("%.200s line %d: match exec "
664 "'%.100s' error", filename,
667 criteria = xstrdup(cmd);
669 /* Force exit status to boolean */
671 if (r == (negate ? 1 : 0))
672 this_result = result = 0;
674 error("Unsupported Match attribute %s", attrib);
678 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
679 filename, linenum, this_result ? "": "not ",
683 if (attributes == 0) {
684 error("One or more attributes required for Match");
690 debug2("match %sfound", result ? "" : "not ");
696 /* Remove environment variable by pattern */
698 rm_env(Options *options, const char *arg, const char *filename, int linenum)
703 /* Remove an environment variable */
704 for (i = 0; i < options->num_send_env; ) {
705 cp = xstrdup(options->send_env[i]);
706 if (!match_pattern(cp, arg + 1)) {
711 debug3("%s line %d: removing environment %s",
712 filename, linenum, cp);
714 free(options->send_env[i]);
715 options->send_env[i] = NULL;
716 for (j = i; j < options->num_send_env - 1; j++) {
717 options->send_env[j] = options->send_env[j + 1];
718 options->send_env[j + 1] = NULL;
720 options->num_send_env--;
721 /* NB. don't increment i */
726 * Returns the number of the token pointed to by cp or oBadOption.
729 parse_token(const char *cp, const char *filename, int linenum,
730 const char *ignored_unknown)
734 for (i = 0; keywords[i].name; i++)
735 if (strcmp(cp, keywords[i].name) == 0)
736 return keywords[i].opcode;
737 if (ignored_unknown != NULL &&
738 match_pattern_list(cp, ignored_unknown, 1) == 1)
739 return oIgnoredUnknownOption;
740 error("%s: line %d: Bad configuration option: %s",
741 filename, linenum, cp);
745 /* Multistate option parsing */
750 static const struct multistate multistate_flag[] = {
757 static const struct multistate multistate_yesnoask[] = {
765 static const struct multistate multistate_strict_hostkey[] = {
766 { "true", SSH_STRICT_HOSTKEY_YES },
767 { "false", SSH_STRICT_HOSTKEY_OFF },
768 { "yes", SSH_STRICT_HOSTKEY_YES },
769 { "no", SSH_STRICT_HOSTKEY_OFF },
770 { "ask", SSH_STRICT_HOSTKEY_ASK },
771 { "off", SSH_STRICT_HOSTKEY_OFF },
772 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
775 static const struct multistate multistate_yesnoaskconfirm[] = {
784 static const struct multistate multistate_addressfamily[] = {
786 { "inet6", AF_INET6 },
787 { "any", AF_UNSPEC },
790 static const struct multistate multistate_controlmaster[] = {
791 { "true", SSHCTL_MASTER_YES },
792 { "yes", SSHCTL_MASTER_YES },
793 { "false", SSHCTL_MASTER_NO },
794 { "no", SSHCTL_MASTER_NO },
795 { "auto", SSHCTL_MASTER_AUTO },
796 { "ask", SSHCTL_MASTER_ASK },
797 { "autoask", SSHCTL_MASTER_AUTO_ASK },
800 static const struct multistate multistate_tunnel[] = {
801 { "ethernet", SSH_TUNMODE_ETHERNET },
802 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
803 { "true", SSH_TUNMODE_DEFAULT },
804 { "yes", SSH_TUNMODE_DEFAULT },
805 { "false", SSH_TUNMODE_NO },
806 { "no", SSH_TUNMODE_NO },
809 static const struct multistate multistate_requesttty[] = {
810 { "true", REQUEST_TTY_YES },
811 { "yes", REQUEST_TTY_YES },
812 { "false", REQUEST_TTY_NO },
813 { "no", REQUEST_TTY_NO },
814 { "force", REQUEST_TTY_FORCE },
815 { "auto", REQUEST_TTY_AUTO },
818 static const struct multistate multistate_canonicalizehostname[] = {
819 { "true", SSH_CANONICALISE_YES },
820 { "false", SSH_CANONICALISE_NO },
821 { "yes", SSH_CANONICALISE_YES },
822 { "no", SSH_CANONICALISE_NO },
823 { "always", SSH_CANONICALISE_ALWAYS },
828 * Processes a single option line as used in the configuration files. This
829 * only sets those values that have not already been set.
832 process_config_line(Options *options, struct passwd *pw, const char *host,
833 const char *original_host, char *line, const char *filename,
834 int linenum, int *activep, int flags)
836 return process_config_line_depth(options, pw, host, original_host,
837 line, filename, linenum, activep, flags, 0);
840 #define WHITESPACE " \t\r\n"
842 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
843 const char *original_host, char *line, const char *filename,
844 int linenum, int *activep, int flags, int depth)
846 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
847 char **cpptr, fwdarg[256];
848 u_int i, *uintptr, max_entries = 0;
849 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
850 int remotefwd, dynamicfwd;
851 LogLevel *log_level_ptr;
852 SyslogFacility *log_facility_ptr;
856 const struct multistate *multistate_ptr;
857 struct allowed_cname *cname;
861 if (activep == NULL) { /* We are processing a command line directive */
866 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
867 if ((len = strlen(line)) == 0)
869 for (len--; len > 0; len--) {
870 if (strchr(WHITESPACE "\f", line[len]) == NULL)
876 /* Get the keyword. (Each line is supposed to begin with a keyword). */
877 if ((keyword = strdelim(&s)) == NULL)
879 /* Ignore leading whitespace. */
880 if (*keyword == '\0')
881 keyword = strdelim(&s);
882 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
884 /* Match lowercase keyword */
887 opcode = parse_token(keyword, filename, linenum,
888 options->ignored_unknown);
892 /* don't panic, but count bad options */
896 case oIgnoredUnknownOption:
897 debug("%s line %d: Ignored unknown option \"%s\"",
898 filename, linenum, keyword);
900 case oConnectTimeout:
901 intptr = &options->connection_timeout;
904 if (!arg || *arg == '\0')
905 fatal("%s line %d: missing time value.",
907 if (strcmp(arg, "none") == 0)
909 else if ((value = convtime(arg)) == -1)
910 fatal("%s line %d: invalid time value.",
912 if (*activep && *intptr == -1)
917 intptr = &options->forward_agent;
919 multistate_ptr = multistate_flag;
922 if (!arg || *arg == '\0')
923 fatal("%s line %d: missing argument.",
926 for (i = 0; multistate_ptr[i].key != NULL; i++) {
927 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
928 value = multistate_ptr[i].value;
933 fatal("%s line %d: unsupported option \"%s\".",
934 filename, linenum, arg);
935 if (*activep && *intptr == -1)
940 intptr = &options->forward_x11;
943 case oForwardX11Trusted:
944 intptr = &options->forward_x11_trusted;
947 case oForwardX11Timeout:
948 intptr = &options->forward_x11_timeout;
952 intptr = &options->fwd_opts.gateway_ports;
955 case oExitOnForwardFailure:
956 intptr = &options->exit_on_forward_failure;
959 case oPasswordAuthentication:
960 intptr = &options->password_authentication;
963 case oKbdInteractiveAuthentication:
964 intptr = &options->kbd_interactive_authentication;
967 case oKbdInteractiveDevices:
968 charptr = &options->kbd_interactive_devices;
971 case oPubkeyAuthentication:
972 intptr = &options->pubkey_authentication;
975 case oHostbasedAuthentication:
976 intptr = &options->hostbased_authentication;
979 case oChallengeResponseAuthentication:
980 intptr = &options->challenge_response_authentication;
983 case oGssAuthentication:
984 intptr = &options->gss_authentication;
987 case oGssDelegateCreds:
988 intptr = &options->gss_deleg_creds;
992 intptr = &options->batch_mode;
996 intptr = &options->check_host_ip;
999 case oVerifyHostKeyDNS:
1000 intptr = &options->verify_host_key_dns;
1001 multistate_ptr = multistate_yesnoask;
1002 goto parse_multistate;
1004 case oStrictHostKeyChecking:
1005 intptr = &options->strict_host_key_checking;
1006 multistate_ptr = multistate_strict_hostkey;
1007 goto parse_multistate;
1010 intptr = &options->compression;
1014 intptr = &options->tcp_keep_alive;
1017 case oNoHostAuthenticationForLocalhost:
1018 intptr = &options->no_host_authentication_for_localhost;
1021 case oNumberOfPasswordPrompts:
1022 intptr = &options->number_of_password_prompts;
1027 if (!arg || *arg == '\0')
1028 fatal("%.200s line %d: Missing argument.", filename,
1030 if (strcmp(arg, "default") == 0) {
1033 if (scan_scaled(arg, &val64) == -1)
1034 fatal("%.200s line %d: Bad number '%s': %s",
1035 filename, linenum, arg, strerror(errno));
1036 if (val64 != 0 && val64 < 16)
1037 fatal("%.200s line %d: RekeyLimit too small",
1040 if (*activep && options->rekey_limit == -1)
1041 options->rekey_limit = val64;
1042 if (s != NULL) { /* optional rekey interval present */
1043 if (strcmp(s, "none") == 0) {
1044 (void)strdelim(&s); /* discard */
1047 intptr = &options->rekey_interval;
1054 if (!arg || *arg == '\0')
1055 fatal("%.200s line %d: Missing argument.", filename, linenum);
1057 intptr = &options->num_identity_files;
1058 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1059 fatal("%.200s line %d: Too many identity files specified (max %d).",
1060 filename, linenum, SSH_MAX_IDENTITY_FILES);
1061 add_identity_file(options, NULL,
1062 arg, flags & SSHCONF_USERCONF);
1066 case oCertificateFile:
1068 if (!arg || *arg == '\0')
1069 fatal("%.200s line %d: Missing argument.",
1072 intptr = &options->num_certificate_files;
1073 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1074 fatal("%.200s line %d: Too many certificate "
1075 "files specified (max %d).",
1077 SSH_MAX_CERTIFICATE_FILES);
1079 add_certificate_file(options, arg,
1080 flags & SSHCONF_USERCONF);
1084 case oXAuthLocation:
1085 charptr=&options->xauth_location;
1089 charptr = &options->user;
1092 if (!arg || *arg == '\0')
1093 fatal("%.200s line %d: Missing argument.",
1095 if (*activep && *charptr == NULL)
1096 *charptr = xstrdup(arg);
1099 case oGlobalKnownHostsFile:
1100 cpptr = (char **)&options->system_hostfiles;
1101 uintptr = &options->num_system_hostfiles;
1102 max_entries = SSH_MAX_HOSTS_FILES;
1104 if (*activep && *uintptr == 0) {
1105 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1106 if ((*uintptr) >= max_entries)
1107 fatal("%s line %d: "
1108 "too many authorized keys files.",
1110 cpptr[(*uintptr)++] = xstrdup(arg);
1115 case oUserKnownHostsFile:
1116 cpptr = (char **)&options->user_hostfiles;
1117 uintptr = &options->num_user_hostfiles;
1118 max_entries = SSH_MAX_HOSTS_FILES;
1119 goto parse_char_array;
1122 charptr = &options->hostname;
1126 charptr = &options->host_key_alias;
1129 case oPreferredAuthentications:
1130 charptr = &options->preferred_authentications;
1134 charptr = &options->bind_address;
1137 case oBindInterface:
1138 charptr = &options->bind_interface;
1141 case oPKCS11Provider:
1142 charptr = &options->pkcs11_provider;
1146 charptr = &options->proxy_command;
1147 /* Ignore ProxyCommand if ProxyJump already specified */
1148 if (options->jump_host != NULL)
1149 charptr = &options->jump_host; /* Skip below */
1152 fatal("%.200s line %d: Missing argument.", filename, linenum);
1153 len = strspn(s, WHITESPACE "=");
1154 if (*activep && *charptr == NULL)
1155 *charptr = xstrdup(s + len);
1160 fatal("%.200s line %d: Missing argument.",
1163 len = strspn(s, WHITESPACE "=");
1164 if (parse_jump(s + len, options, *activep) == -1) {
1165 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1166 filename, linenum, s + len);
1171 intptr = &options->port;
1174 if ((errstr = atoi_err(arg, &value)) != NULL)
1175 fatal("%s line %d: integer value %s.",
1176 filename, linenum, errstr);
1177 if (*activep && *intptr == -1)
1181 case oConnectionAttempts:
1182 intptr = &options->connection_attempts;
1187 if (!arg || *arg == '\0')
1188 fatal("%.200s line %d: Missing argument.", filename, linenum);
1189 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1190 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1191 filename, linenum, arg ? arg : "<NONE>");
1192 if (*activep && options->ciphers == NULL)
1193 options->ciphers = xstrdup(arg);
1198 if (!arg || *arg == '\0')
1199 fatal("%.200s line %d: Missing argument.", filename, linenum);
1200 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1201 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1202 filename, linenum, arg ? arg : "<NONE>");
1203 if (*activep && options->macs == NULL)
1204 options->macs = xstrdup(arg);
1207 case oKexAlgorithms:
1209 if (!arg || *arg == '\0')
1210 fatal("%.200s line %d: Missing argument.",
1213 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1214 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1215 filename, linenum, arg ? arg : "<NONE>");
1216 if (*activep && options->kex_algorithms == NULL)
1217 options->kex_algorithms = xstrdup(arg);
1220 case oHostKeyAlgorithms:
1221 charptr = &options->hostkeyalgorithms;
1224 if (!arg || *arg == '\0')
1225 fatal("%.200s line %d: Missing argument.",
1228 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1229 fatal("%s line %d: Bad key types '%s'.",
1230 filename, linenum, arg ? arg : "<NONE>");
1231 if (*activep && *charptr == NULL)
1232 *charptr = xstrdup(arg);
1236 log_level_ptr = &options->log_level;
1238 value = log_level_number(arg);
1239 if (value == SYSLOG_LEVEL_NOT_SET)
1240 fatal("%.200s line %d: unsupported log level '%s'",
1241 filename, linenum, arg ? arg : "<NONE>");
1242 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1243 *log_level_ptr = (LogLevel) value;
1247 log_facility_ptr = &options->log_facility;
1249 value = log_facility_number(arg);
1250 if (value == SYSLOG_FACILITY_NOT_SET)
1251 fatal("%.200s line %d: unsupported log facility '%s'",
1252 filename, linenum, arg ? arg : "<NONE>");
1253 if (*log_facility_ptr == -1)
1254 *log_facility_ptr = (SyslogFacility) value;
1258 case oRemoteForward:
1259 case oDynamicForward:
1261 if (arg == NULL || *arg == '\0')
1262 fatal("%.200s line %d: Missing port argument.",
1265 remotefwd = (opcode == oRemoteForward);
1266 dynamicfwd = (opcode == oDynamicForward);
1269 arg2 = strdelim(&s);
1270 if (arg2 == NULL || *arg2 == '\0') {
1274 fatal("%.200s line %d: Missing target "
1275 "argument.", filename, linenum);
1277 /* construct a string for parse_forward */
1278 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1283 strlcpy(fwdarg, arg, sizeof(fwdarg));
1285 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1286 fatal("%.200s line %d: Bad forwarding specification.",
1291 add_remote_forward(options, &fwd);
1293 add_local_forward(options, &fwd);
1298 case oClearAllForwardings:
1299 intptr = &options->clear_forwardings;
1304 fatal("Host directive not supported as a command-line "
1308 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1309 if ((flags & SSHCONF_NEVERMATCH) != 0)
1311 negated = *arg == '!';
1314 if (match_pattern(host, arg)) {
1316 debug("%.200s line %d: Skipping Host "
1317 "block because of negated match "
1318 "for %.100s", filename, linenum,
1324 arg2 = arg; /* logged below */
1329 debug("%.200s line %d: Applying options for %.100s",
1330 filename, linenum, arg2);
1331 /* Avoid garbage check below, as strdelim is done. */
1336 fatal("Host directive not supported as a command-line "
1338 value = match_cfg_line(options, &s, pw, host, original_host,
1339 flags & SSHCONF_POSTCANON, filename, linenum);
1341 fatal("%.200s line %d: Bad Match condition", filename,
1343 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1347 intptr = &options->escape_char;
1349 if (!arg || *arg == '\0')
1350 fatal("%.200s line %d: Missing argument.", filename, linenum);
1351 if (strcmp(arg, "none") == 0)
1352 value = SSH_ESCAPECHAR_NONE;
1353 else if (arg[1] == '\0')
1354 value = (u_char) arg[0];
1355 else if (arg[0] == '^' && arg[2] == 0 &&
1356 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1357 value = (u_char) arg[1] & 31;
1359 fatal("%.200s line %d: Bad escape character.",
1362 value = 0; /* Avoid compiler warning. */
1364 if (*activep && *intptr == -1)
1368 case oAddressFamily:
1369 intptr = &options->address_family;
1370 multistate_ptr = multistate_addressfamily;
1371 goto parse_multistate;
1373 case oEnableSSHKeysign:
1374 intptr = &options->enable_ssh_keysign;
1377 case oIdentitiesOnly:
1378 intptr = &options->identities_only;
1381 case oServerAliveInterval:
1382 intptr = &options->server_alive_interval;
1385 case oServerAliveCountMax:
1386 intptr = &options->server_alive_count_max;
1390 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1391 if (strchr(arg, '=') != NULL)
1392 fatal("%s line %d: Invalid environment name.",
1397 /* Removing an env var */
1398 rm_env(options, arg, filename, linenum);
1401 /* Adding an env var */
1402 if (options->num_send_env >= INT_MAX)
1403 fatal("%s line %d: too many send env.",
1405 options->send_env = xrecallocarray(
1406 options->send_env, options->num_send_env,
1407 options->num_send_env + 1,
1408 sizeof(*options->send_env));
1409 options->send_env[options->num_send_env++] =
1416 value = options->num_setenv;
1417 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1418 if (strchr(arg, '=') == NULL)
1419 fatal("%s line %d: Invalid SetEnv.",
1421 if (!*activep || value != 0)
1423 /* Adding a setenv var */
1424 if (options->num_setenv >= INT_MAX)
1425 fatal("%s line %d: too many SetEnv.",
1427 options->setenv = xrecallocarray(
1428 options->setenv, options->num_setenv,
1429 options->num_setenv + 1, sizeof(*options->setenv));
1430 options->setenv[options->num_setenv++] = xstrdup(arg);
1435 charptr = &options->control_path;
1438 case oControlMaster:
1439 intptr = &options->control_master;
1440 multistate_ptr = multistate_controlmaster;
1441 goto parse_multistate;
1443 case oControlPersist:
1444 /* no/false/yes/true, or a time spec */
1445 intptr = &options->control_persist;
1447 if (!arg || *arg == '\0')
1448 fatal("%.200s line %d: Missing ControlPersist"
1449 " argument.", filename, linenum);
1451 value2 = 0; /* timeout */
1452 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1454 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1456 else if ((value2 = convtime(arg)) >= 0)
1459 fatal("%.200s line %d: Bad ControlPersist argument.",
1461 if (*activep && *intptr == -1) {
1463 options->control_persist_timeout = value2;
1467 case oHashKnownHosts:
1468 intptr = &options->hash_known_hosts;
1472 intptr = &options->tun_open;
1473 multistate_ptr = multistate_tunnel;
1474 goto parse_multistate;
1478 if (!arg || *arg == '\0')
1479 fatal("%.200s line %d: Missing argument.", filename, linenum);
1480 value = a2tun(arg, &value2);
1481 if (value == SSH_TUNID_ERR)
1482 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1484 options->tun_local = value;
1485 options->tun_remote = value2;
1490 charptr = &options->local_command;
1493 case oPermitLocalCommand:
1494 intptr = &options->permit_local_command;
1497 case oRemoteCommand:
1498 charptr = &options->remote_command;
1501 case oVisualHostKey:
1502 intptr = &options->visual_host_key;
1507 fatal("Include directive not supported as a "
1508 "command-line option");
1510 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1512 * Ensure all paths are anchored. User configuration
1513 * files may begin with '~/' but system configurations
1514 * must not. If the path is relative, then treat it
1515 * as living in ~/.ssh for user configurations or
1516 * /etc/ssh for system ones.
1518 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1519 fatal("%.200s line %d: bad include path %s.",
1520 filename, linenum, arg);
1521 if (*arg != '/' && *arg != '~') {
1522 xasprintf(&arg2, "%s/%s",
1523 (flags & SSHCONF_USERCONF) ?
1524 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1526 arg2 = xstrdup(arg);
1527 memset(&gl, 0, sizeof(gl));
1528 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1529 if (r == GLOB_NOMATCH) {
1530 debug("%.200s line %d: include %s matched no "
1531 "files",filename, linenum, arg2);
1534 } else if (r != 0 || gl.gl_pathc < 0)
1535 fatal("%.200s line %d: glob failed for %s.",
1536 filename, linenum, arg2);
1539 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1540 debug3("%.200s line %d: Including file %s "
1541 "depth %d%s", filename, linenum,
1542 gl.gl_pathv[i], depth,
1543 oactive ? "" : " (parse only)");
1544 r = read_config_file_depth(gl.gl_pathv[i],
1545 pw, host, original_host, options,
1546 flags | SSHCONF_CHECKPERM |
1547 (oactive ? 0 : SSHCONF_NEVERMATCH),
1548 activep, depth + 1);
1549 if (r != 1 && errno != ENOENT) {
1550 fatal("Can't open user config file "
1551 "%.100s: %.100s", gl.gl_pathv[i],
1555 * don't let Match in includes clobber the
1556 * containing file's Match state.
1570 if ((value = parse_ipqos(arg)) == -1)
1571 fatal("%s line %d: Bad IPQoS value: %s",
1572 filename, linenum, arg);
1576 else if ((value2 = parse_ipqos(arg)) == -1)
1577 fatal("%s line %d: Bad IPQoS value: %s",
1578 filename, linenum, arg);
1580 options->ip_qos_interactive = value;
1581 options->ip_qos_bulk = value2;
1586 intptr = &options->request_tty;
1587 multistate_ptr = multistate_requesttty;
1588 goto parse_multistate;
1590 case oVersionAddendum:
1592 fatal("%.200s line %d: Missing argument.", filename,
1594 len = strspn(s, WHITESPACE);
1595 if (*activep && options->version_addendum == NULL) {
1596 if (strcasecmp(s + len, "none") == 0)
1597 options->version_addendum = xstrdup("");
1598 else if (strchr(s + len, '\r') != NULL)
1599 fatal("%.200s line %d: Invalid argument",
1602 options->version_addendum = xstrdup(s + len);
1606 case oIgnoreUnknown:
1607 charptr = &options->ignored_unknown;
1610 case oProxyUseFdpass:
1611 intptr = &options->proxy_use_fdpass;
1614 case oCanonicalDomains:
1615 value = options->num_canonical_domains != 0;
1616 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1617 if (!valid_domain(arg, 1, &errstr)) {
1618 fatal("%s line %d: %s", filename, linenum,
1621 if (!*activep || value)
1623 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1624 fatal("%s line %d: too many hostname suffixes.",
1626 options->canonical_domains[
1627 options->num_canonical_domains++] = xstrdup(arg);
1631 case oCanonicalizePermittedCNAMEs:
1632 value = options->num_permitted_cnames != 0;
1633 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1634 /* Either '*' for everything or 'list:list' */
1635 if (strcmp(arg, "*") == 0)
1639 if ((arg2 = strchr(arg, ':')) == NULL ||
1641 fatal("%s line %d: "
1642 "Invalid permitted CNAME \"%s\"",
1643 filename, linenum, arg);
1648 if (!*activep || value)
1650 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1651 fatal("%s line %d: too many permitted CNAMEs.",
1653 cname = options->permitted_cnames +
1654 options->num_permitted_cnames++;
1655 cname->source_list = xstrdup(arg);
1656 cname->target_list = xstrdup(arg2);
1660 case oCanonicalizeHostname:
1661 intptr = &options->canonicalize_hostname;
1662 multistate_ptr = multistate_canonicalizehostname;
1663 goto parse_multistate;
1665 case oCanonicalizeMaxDots:
1666 intptr = &options->canonicalize_max_dots;
1669 case oCanonicalizeFallbackLocal:
1670 intptr = &options->canonicalize_fallback_local;
1673 case oStreamLocalBindMask:
1675 if (!arg || *arg == '\0')
1676 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1677 /* Parse mode in octal format */
1678 value = strtol(arg, &endofnumber, 8);
1679 if (arg == endofnumber || value < 0 || value > 0777)
1680 fatal("%.200s line %d: Bad mask.", filename, linenum);
1681 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1684 case oStreamLocalBindUnlink:
1685 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1688 case oRevokedHostKeys:
1689 charptr = &options->revoked_host_keys;
1692 case oFingerprintHash:
1693 intptr = &options->fingerprint_hash;
1695 if (!arg || *arg == '\0')
1696 fatal("%.200s line %d: Missing argument.",
1698 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1699 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1700 filename, linenum, arg);
1701 if (*activep && *intptr == -1)
1705 case oUpdateHostkeys:
1706 intptr = &options->update_hostkeys;
1707 multistate_ptr = multistate_yesnoask;
1708 goto parse_multistate;
1710 case oHostbasedKeyTypes:
1711 charptr = &options->hostbased_key_types;
1712 goto parse_keytypes;
1714 case oPubkeyAcceptedKeyTypes:
1715 charptr = &options->pubkey_key_types;
1716 goto parse_keytypes;
1718 case oAddKeysToAgent:
1719 intptr = &options->add_keys_to_agent;
1720 multistate_ptr = multistate_yesnoaskconfirm;
1721 goto parse_multistate;
1723 case oIdentityAgent:
1724 charptr = &options->identity_agent;
1728 debug("%s line %d: Deprecated option \"%s\"",
1729 filename, linenum, keyword);
1733 error("%s line %d: Unsupported option \"%s\"",
1734 filename, linenum, keyword);
1738 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1741 /* Check that there is no garbage at end of line. */
1742 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1743 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1744 filename, linenum, arg);
1750 * Reads the config file and modifies the options accordingly. Options
1751 * should already be initialized before this call. This never returns if
1752 * there is an error. If the file does not exist, this returns 0.
1755 read_config_file(const char *filename, struct passwd *pw, const char *host,
1756 const char *original_host, Options *options, int flags)
1760 return read_config_file_depth(filename, pw, host, original_host,
1761 options, flags, &active, 0);
1764 #define READCONF_MAX_DEPTH 16
1766 read_config_file_depth(const char *filename, struct passwd *pw,
1767 const char *host, const char *original_host, Options *options,
1768 int flags, int *activep, int depth)
1772 size_t linesize = 0;
1774 int bad_options = 0;
1776 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1777 fatal("Too many recursive configuration includes");
1779 if ((f = fopen(filename, "r")) == NULL)
1782 if (flags & SSHCONF_CHECKPERM) {
1785 if (fstat(fileno(f), &sb) == -1)
1786 fatal("fstat %s: %s", filename, strerror(errno));
1787 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1788 (sb.st_mode & 022) != 0))
1789 fatal("Bad owner or permissions on %s", filename);
1792 debug("Reading configuration data %.200s", filename);
1795 * Mark that we are now processing the options. This flag is turned
1796 * on/off by Host specifications.
1799 while (getline(&line, &linesize, f) != -1) {
1800 /* Update line number counter. */
1802 if (process_config_line_depth(options, pw, host, original_host,
1803 line, filename, linenum, activep, flags, depth) != 0)
1808 if (bad_options > 0)
1809 fatal("%s: terminating, %d bad configuration options",
1810 filename, bad_options);
1814 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1816 option_clear_or_none(const char *o)
1818 return o == NULL || strcasecmp(o, "none") == 0;
1822 * Initializes options to special values that indicate that they have not yet
1823 * been set. Read_config_file will only set options with this value. Options
1824 * are processed in the following order: command line, user config file,
1825 * system config file. Last, fill_default_options is called.
1829 initialize_options(Options * options)
1831 memset(options, 'X', sizeof(*options));
1832 options->version_addendum = NULL;
1833 options->forward_agent = -1;
1834 options->forward_x11 = -1;
1835 options->forward_x11_trusted = -1;
1836 options->forward_x11_timeout = -1;
1837 options->stdio_forward_host = NULL;
1838 options->stdio_forward_port = 0;
1839 options->clear_forwardings = -1;
1840 options->exit_on_forward_failure = -1;
1841 options->xauth_location = NULL;
1842 options->fwd_opts.gateway_ports = -1;
1843 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1844 options->fwd_opts.streamlocal_bind_unlink = -1;
1845 options->pubkey_authentication = -1;
1846 options->challenge_response_authentication = -1;
1847 options->gss_authentication = -1;
1848 options->gss_deleg_creds = -1;
1849 options->password_authentication = -1;
1850 options->kbd_interactive_authentication = -1;
1851 options->kbd_interactive_devices = NULL;
1852 options->hostbased_authentication = -1;
1853 options->batch_mode = -1;
1854 options->check_host_ip = -1;
1855 options->strict_host_key_checking = -1;
1856 options->compression = -1;
1857 options->tcp_keep_alive = -1;
1859 options->address_family = -1;
1860 options->connection_attempts = -1;
1861 options->connection_timeout = -1;
1862 options->number_of_password_prompts = -1;
1863 options->ciphers = NULL;
1864 options->macs = NULL;
1865 options->kex_algorithms = NULL;
1866 options->hostkeyalgorithms = NULL;
1867 options->num_identity_files = 0;
1868 options->num_certificate_files = 0;
1869 options->hostname = NULL;
1870 options->host_key_alias = NULL;
1871 options->proxy_command = NULL;
1872 options->jump_user = NULL;
1873 options->jump_host = NULL;
1874 options->jump_port = -1;
1875 options->jump_extra = NULL;
1876 options->user = NULL;
1877 options->escape_char = -1;
1878 options->num_system_hostfiles = 0;
1879 options->num_user_hostfiles = 0;
1880 options->local_forwards = NULL;
1881 options->num_local_forwards = 0;
1882 options->remote_forwards = NULL;
1883 options->num_remote_forwards = 0;
1884 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1885 options->log_level = SYSLOG_LEVEL_NOT_SET;
1886 options->preferred_authentications = NULL;
1887 options->bind_address = NULL;
1888 options->bind_interface = NULL;
1889 options->pkcs11_provider = NULL;
1890 options->enable_ssh_keysign = - 1;
1891 options->no_host_authentication_for_localhost = - 1;
1892 options->identities_only = - 1;
1893 options->rekey_limit = - 1;
1894 options->rekey_interval = -1;
1895 options->verify_host_key_dns = -1;
1896 options->server_alive_interval = -1;
1897 options->server_alive_count_max = -1;
1898 options->send_env = NULL;
1899 options->num_send_env = 0;
1900 options->setenv = NULL;
1901 options->num_setenv = 0;
1902 options->control_path = NULL;
1903 options->control_master = -1;
1904 options->control_persist = -1;
1905 options->control_persist_timeout = 0;
1906 options->hash_known_hosts = -1;
1907 options->tun_open = -1;
1908 options->tun_local = -1;
1909 options->tun_remote = -1;
1910 options->local_command = NULL;
1911 options->permit_local_command = -1;
1912 options->remote_command = NULL;
1913 options->add_keys_to_agent = -1;
1914 options->identity_agent = NULL;
1915 options->visual_host_key = -1;
1916 options->ip_qos_interactive = -1;
1917 options->ip_qos_bulk = -1;
1918 options->request_tty = -1;
1919 options->proxy_use_fdpass = -1;
1920 options->ignored_unknown = NULL;
1921 options->num_canonical_domains = 0;
1922 options->num_permitted_cnames = 0;
1923 options->canonicalize_max_dots = -1;
1924 options->canonicalize_fallback_local = -1;
1925 options->canonicalize_hostname = -1;
1926 options->revoked_host_keys = NULL;
1927 options->fingerprint_hash = -1;
1928 options->update_hostkeys = -1;
1929 options->hostbased_key_types = NULL;
1930 options->pubkey_key_types = NULL;
1934 * A petite version of fill_default_options() that just fills the options
1935 * needed for hostname canonicalization to proceed.
1938 fill_default_options_for_canonicalization(Options *options)
1940 if (options->canonicalize_max_dots == -1)
1941 options->canonicalize_max_dots = 1;
1942 if (options->canonicalize_fallback_local == -1)
1943 options->canonicalize_fallback_local = 1;
1944 if (options->canonicalize_hostname == -1)
1945 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1949 * Called after processing other sources of option data, this fills those
1950 * options for which no value has been specified with their default values.
1953 fill_default_options(Options * options)
1955 char *all_cipher, *all_mac, *all_kex, *all_key;
1958 if (options->forward_agent == -1)
1959 options->forward_agent = 0;
1960 if (options->forward_x11 == -1)
1961 options->forward_x11 = 0;
1962 if (options->forward_x11_trusted == -1)
1963 options->forward_x11_trusted = 0;
1964 if (options->forward_x11_timeout == -1)
1965 options->forward_x11_timeout = 1200;
1967 * stdio forwarding (-W) changes the default for these but we defer
1968 * setting the values so they can be overridden.
1970 if (options->exit_on_forward_failure == -1)
1971 options->exit_on_forward_failure =
1972 options->stdio_forward_host != NULL ? 1 : 0;
1973 if (options->clear_forwardings == -1)
1974 options->clear_forwardings =
1975 options->stdio_forward_host != NULL ? 1 : 0;
1976 if (options->clear_forwardings == 1)
1977 clear_forwardings(options);
1979 if (options->xauth_location == NULL)
1980 options->xauth_location = _PATH_XAUTH;
1981 if (options->fwd_opts.gateway_ports == -1)
1982 options->fwd_opts.gateway_ports = 0;
1983 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1984 options->fwd_opts.streamlocal_bind_mask = 0177;
1985 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1986 options->fwd_opts.streamlocal_bind_unlink = 0;
1987 if (options->pubkey_authentication == -1)
1988 options->pubkey_authentication = 1;
1989 if (options->challenge_response_authentication == -1)
1990 options->challenge_response_authentication = 1;
1991 if (options->gss_authentication == -1)
1992 options->gss_authentication = 0;
1993 if (options->gss_deleg_creds == -1)
1994 options->gss_deleg_creds = 0;
1995 if (options->password_authentication == -1)
1996 options->password_authentication = 1;
1997 if (options->kbd_interactive_authentication == -1)
1998 options->kbd_interactive_authentication = 1;
1999 if (options->hostbased_authentication == -1)
2000 options->hostbased_authentication = 0;
2001 if (options->batch_mode == -1)
2002 options->batch_mode = 0;
2003 if (options->check_host_ip == -1)
2004 options->check_host_ip = 0;
2005 if (options->strict_host_key_checking == -1)
2006 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2007 if (options->compression == -1)
2008 options->compression = 0;
2009 if (options->tcp_keep_alive == -1)
2010 options->tcp_keep_alive = 1;
2011 if (options->port == -1)
2012 options->port = 0; /* Filled in ssh_connect. */
2013 if (options->address_family == -1)
2014 options->address_family = AF_UNSPEC;
2015 if (options->connection_attempts == -1)
2016 options->connection_attempts = 1;
2017 if (options->number_of_password_prompts == -1)
2018 options->number_of_password_prompts = 3;
2019 /* options->hostkeyalgorithms, default set in myproposals.h */
2020 if (options->add_keys_to_agent == -1)
2021 options->add_keys_to_agent = 0;
2022 if (options->num_identity_files == 0) {
2023 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2024 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2025 #ifdef OPENSSL_HAS_ECC
2026 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2028 add_identity_file(options, "~/",
2029 _PATH_SSH_CLIENT_ID_ED25519, 0);
2030 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2032 if (options->escape_char == -1)
2033 options->escape_char = '~';
2034 if (options->num_system_hostfiles == 0) {
2035 options->system_hostfiles[options->num_system_hostfiles++] =
2036 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2037 options->system_hostfiles[options->num_system_hostfiles++] =
2038 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2040 if (options->num_user_hostfiles == 0) {
2041 options->user_hostfiles[options->num_user_hostfiles++] =
2042 xstrdup(_PATH_SSH_USER_HOSTFILE);
2043 options->user_hostfiles[options->num_user_hostfiles++] =
2044 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2046 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2047 options->log_level = SYSLOG_LEVEL_INFO;
2048 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2049 options->log_facility = SYSLOG_FACILITY_USER;
2050 if (options->no_host_authentication_for_localhost == - 1)
2051 options->no_host_authentication_for_localhost = 0;
2052 if (options->identities_only == -1)
2053 options->identities_only = 0;
2054 if (options->enable_ssh_keysign == -1)
2055 options->enable_ssh_keysign = 0;
2056 if (options->rekey_limit == -1)
2057 options->rekey_limit = 0;
2058 if (options->rekey_interval == -1)
2059 options->rekey_interval = 0;
2061 if (options->verify_host_key_dns == -1)
2062 /* automatically trust a verified SSHFP record */
2063 options->verify_host_key_dns = 1;
2065 if (options->verify_host_key_dns == -1)
2066 options->verify_host_key_dns = 0;
2068 if (options->server_alive_interval == -1)
2069 options->server_alive_interval = 0;
2070 if (options->server_alive_count_max == -1)
2071 options->server_alive_count_max = 3;
2072 if (options->control_master == -1)
2073 options->control_master = 0;
2074 if (options->control_persist == -1) {
2075 options->control_persist = 0;
2076 options->control_persist_timeout = 0;
2078 if (options->hash_known_hosts == -1)
2079 options->hash_known_hosts = 0;
2080 if (options->tun_open == -1)
2081 options->tun_open = SSH_TUNMODE_NO;
2082 if (options->tun_local == -1)
2083 options->tun_local = SSH_TUNID_ANY;
2084 if (options->tun_remote == -1)
2085 options->tun_remote = SSH_TUNID_ANY;
2086 if (options->permit_local_command == -1)
2087 options->permit_local_command = 0;
2088 if (options->visual_host_key == -1)
2089 options->visual_host_key = 0;
2090 if (options->ip_qos_interactive == -1)
2091 options->ip_qos_interactive = IPTOS_DSCP_AF21;
2092 if (options->ip_qos_bulk == -1)
2093 options->ip_qos_bulk = IPTOS_DSCP_CS1;
2094 if (options->request_tty == -1)
2095 options->request_tty = REQUEST_TTY_AUTO;
2096 if (options->proxy_use_fdpass == -1)
2097 options->proxy_use_fdpass = 0;
2098 if (options->canonicalize_max_dots == -1)
2099 options->canonicalize_max_dots = 1;
2100 if (options->canonicalize_fallback_local == -1)
2101 options->canonicalize_fallback_local = 1;
2102 if (options->canonicalize_hostname == -1)
2103 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2104 if (options->fingerprint_hash == -1)
2105 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2106 if (options->update_hostkeys == -1)
2107 options->update_hostkeys = 0;
2109 /* Expand KEX name lists */
2110 all_cipher = cipher_alg_list(',', 0);
2111 all_mac = mac_alg_list(',');
2112 all_kex = kex_alg_list(',');
2113 all_key = sshkey_alg_list(0, 0, 1, ',');
2114 #define ASSEMBLE(what, defaults, all) \
2116 if ((r = kex_assemble_names(&options->what, \
2117 defaults, all)) != 0) \
2118 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2120 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
2121 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
2122 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
2123 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
2124 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2131 #define CLEAR_ON_NONE(v) \
2133 if (option_clear_or_none(v)) { \
2138 CLEAR_ON_NONE(options->local_command);
2139 CLEAR_ON_NONE(options->remote_command);
2140 CLEAR_ON_NONE(options->proxy_command);
2141 CLEAR_ON_NONE(options->control_path);
2142 CLEAR_ON_NONE(options->revoked_host_keys);
2143 if (options->jump_host != NULL &&
2144 strcmp(options->jump_host, "none") == 0 &&
2145 options->jump_port == 0 && options->jump_user == NULL) {
2146 free(options->jump_host);
2147 options->jump_host = NULL;
2149 /* options->identity_agent distinguishes NULL from 'none' */
2150 /* options->user will be set in the main program if appropriate */
2151 /* options->hostname will be set in the main program if appropriate */
2152 /* options->host_key_alias should not be set by default */
2153 /* options->preferred_authentications will be set in ssh */
2154 if (options->version_addendum == NULL)
2155 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2165 * parses the next field in a port forwarding specification.
2166 * sets fwd to the parsed field and advances p past the colon
2167 * or sets it to NULL at end of string.
2168 * returns 0 on success, else non-zero.
2171 parse_fwd_field(char **p, struct fwdarg *fwd)
2178 return -1; /* end of string */
2182 * A field escaped with square brackets is used literally.
2183 * XXX - allow ']' to be escaped via backslash?
2186 /* find matching ']' */
2187 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2191 /* no matching ']' or not at end of field. */
2192 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2194 /* NUL terminate the field and advance p past the colon */
2199 fwd->ispath = ispath;
2204 for (cp = *p; *cp != '\0'; cp++) {
2207 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2221 fwd->ispath = ispath;
2228 * parses a string containing a port forwarding specification of the form:
2230 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2231 * listenpath:connectpath
2233 * [listenhost:]listenport
2234 * returns number of arguments parsed or zero on error
2237 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2239 struct fwdarg fwdargs[4];
2243 memset(fwd, 0, sizeof(*fwd));
2244 memset(fwdargs, 0, sizeof(fwdargs));
2246 cp = p = xstrdup(fwdspec);
2248 /* skip leading spaces */
2249 while (isspace((u_char)*cp))
2252 for (i = 0; i < 4; ++i) {
2253 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2257 /* Check for trailing garbage */
2258 if (cp != NULL && *cp != '\0') {
2259 i = 0; /* failure */
2264 if (fwdargs[0].ispath) {
2265 fwd->listen_path = xstrdup(fwdargs[0].arg);
2266 fwd->listen_port = PORT_STREAMLOCAL;
2268 fwd->listen_host = NULL;
2269 fwd->listen_port = a2port(fwdargs[0].arg);
2271 fwd->connect_host = xstrdup("socks");
2275 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2276 fwd->listen_path = xstrdup(fwdargs[0].arg);
2277 fwd->listen_port = PORT_STREAMLOCAL;
2278 fwd->connect_path = xstrdup(fwdargs[1].arg);
2279 fwd->connect_port = PORT_STREAMLOCAL;
2280 } else if (fwdargs[1].ispath) {
2281 fwd->listen_host = NULL;
2282 fwd->listen_port = a2port(fwdargs[0].arg);
2283 fwd->connect_path = xstrdup(fwdargs[1].arg);
2284 fwd->connect_port = PORT_STREAMLOCAL;
2286 fwd->listen_host = xstrdup(fwdargs[0].arg);
2287 fwd->listen_port = a2port(fwdargs[1].arg);
2288 fwd->connect_host = xstrdup("socks");
2293 if (fwdargs[0].ispath) {
2294 fwd->listen_path = xstrdup(fwdargs[0].arg);
2295 fwd->listen_port = PORT_STREAMLOCAL;
2296 fwd->connect_host = xstrdup(fwdargs[1].arg);
2297 fwd->connect_port = a2port(fwdargs[2].arg);
2298 } else if (fwdargs[2].ispath) {
2299 fwd->listen_host = xstrdup(fwdargs[0].arg);
2300 fwd->listen_port = a2port(fwdargs[1].arg);
2301 fwd->connect_path = xstrdup(fwdargs[2].arg);
2302 fwd->connect_port = PORT_STREAMLOCAL;
2304 fwd->listen_host = NULL;
2305 fwd->listen_port = a2port(fwdargs[0].arg);
2306 fwd->connect_host = xstrdup(fwdargs[1].arg);
2307 fwd->connect_port = a2port(fwdargs[2].arg);
2312 fwd->listen_host = xstrdup(fwdargs[0].arg);
2313 fwd->listen_port = a2port(fwdargs[1].arg);
2314 fwd->connect_host = xstrdup(fwdargs[2].arg);
2315 fwd->connect_port = a2port(fwdargs[3].arg);
2318 i = 0; /* failure */
2324 if (!(i == 1 || i == 2))
2327 if (!(i == 3 || i == 4)) {
2328 if (fwd->connect_path == NULL &&
2329 fwd->listen_path == NULL)
2332 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2336 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2337 (!remotefwd && fwd->listen_port == 0))
2339 if (fwd->connect_host != NULL &&
2340 strlen(fwd->connect_host) >= NI_MAXHOST)
2342 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2343 if (fwd->connect_path != NULL &&
2344 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2346 if (fwd->listen_host != NULL &&
2347 strlen(fwd->listen_host) >= NI_MAXHOST)
2349 if (fwd->listen_path != NULL &&
2350 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2356 free(fwd->connect_host);
2357 fwd->connect_host = NULL;
2358 free(fwd->connect_path);
2359 fwd->connect_path = NULL;
2360 free(fwd->listen_host);
2361 fwd->listen_host = NULL;
2362 free(fwd->listen_path);
2363 fwd->listen_path = NULL;
2368 parse_jump(const char *s, Options *o, int active)
2370 char *orig, *sdup, *cp;
2371 char *host = NULL, *user = NULL;
2372 int ret = -1, port = -1, first;
2374 active &= o->proxy_command == NULL && o->jump_host == NULL;
2376 orig = sdup = xstrdup(s);
2379 if (strcasecmp(s, "none") == 0)
2381 if ((cp = strrchr(sdup, ',')) == NULL)
2382 cp = sdup; /* last */
2387 /* First argument and configuration is active */
2388 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2389 parse_user_host_port(cp, &user, &host, &port) != 0)
2392 /* Subsequent argument or inactive configuration */
2393 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2394 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2397 first = 0; /* only check syntax for subsequent hosts */
2398 } while (cp != sdup);
2401 if (strcasecmp(s, "none") == 0) {
2402 o->jump_host = xstrdup("none");
2405 o->jump_user = user;
2406 o->jump_host = host;
2407 o->jump_port = port;
2408 o->proxy_command = xstrdup("none");
2410 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2411 o->jump_extra = xstrdup(s);
2412 o->jump_extra[cp - s] = '\0';
2425 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2430 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2431 if (r == 0 && path != NULL)
2432 r = -1; /* path not allowed */
2436 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2438 fmt_multistate_int(int val, const struct multistate *m)
2442 for (i = 0; m[i].key != NULL; i++) {
2443 if (m[i].value == val)
2450 fmt_intarg(OpCodes code, int val)
2455 case oAddressFamily:
2456 return fmt_multistate_int(val, multistate_addressfamily);
2457 case oVerifyHostKeyDNS:
2458 case oUpdateHostkeys:
2459 return fmt_multistate_int(val, multistate_yesnoask);
2460 case oStrictHostKeyChecking:
2461 return fmt_multistate_int(val, multistate_strict_hostkey);
2462 case oControlMaster:
2463 return fmt_multistate_int(val, multistate_controlmaster);
2465 return fmt_multistate_int(val, multistate_tunnel);
2467 return fmt_multistate_int(val, multistate_requesttty);
2468 case oCanonicalizeHostname:
2469 return fmt_multistate_int(val, multistate_canonicalizehostname);
2470 case oAddKeysToAgent:
2471 return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2472 case oFingerprintHash:
2473 return ssh_digest_alg_name(val);
2487 lookup_opcode_name(OpCodes code)
2491 for (i = 0; keywords[i].name != NULL; i++)
2492 if (keywords[i].opcode == code)
2493 return(keywords[i].name);
2498 dump_cfg_int(OpCodes code, int val)
2500 printf("%s %d\n", lookup_opcode_name(code), val);
2504 dump_cfg_fmtint(OpCodes code, int val)
2506 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2510 dump_cfg_string(OpCodes code, const char *val)
2514 printf("%s %s\n", lookup_opcode_name(code), val);
2518 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2522 for (i = 0; i < count; i++)
2523 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2527 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2531 printf("%s", lookup_opcode_name(code));
2532 for (i = 0; i < count; i++)
2533 printf(" %s", vals[i]);
2538 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2540 const struct Forward *fwd;
2543 /* oDynamicForward */
2544 for (i = 0; i < count; i++) {
2546 if (code == oDynamicForward && fwd->connect_host != NULL &&
2547 strcmp(fwd->connect_host, "socks") != 0)
2549 if (code == oLocalForward && fwd->connect_host != NULL &&
2550 strcmp(fwd->connect_host, "socks") == 0)
2552 printf("%s", lookup_opcode_name(code));
2553 if (fwd->listen_port == PORT_STREAMLOCAL)
2554 printf(" %s", fwd->listen_path);
2555 else if (fwd->listen_host == NULL)
2556 printf(" %d", fwd->listen_port);
2559 fwd->listen_host, fwd->listen_port);
2561 if (code != oDynamicForward) {
2562 if (fwd->connect_port == PORT_STREAMLOCAL)
2563 printf(" %s", fwd->connect_path);
2564 else if (fwd->connect_host == NULL)
2565 printf(" %d", fwd->connect_port);
2568 fwd->connect_host, fwd->connect_port);
2576 dump_client_config(Options *o, const char *host)
2579 char buf[8], *all_key;
2581 /* This is normally prepared in ssh_kex2 */
2582 all_key = sshkey_alg_list(0, 0, 1, ',');
2583 if (kex_assemble_names( &o->hostkeyalgorithms,
2584 KEX_DEFAULT_PK_ALG, all_key) != 0)
2585 fatal("%s: kex_assemble_names failed", __func__);
2588 /* Most interesting options first: user, host, port */
2589 dump_cfg_string(oUser, o->user);
2590 dump_cfg_string(oHostName, host);
2591 dump_cfg_int(oPort, o->port);
2594 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2595 dump_cfg_fmtint(oAddressFamily, o->address_family);
2596 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2597 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2598 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2599 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2600 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2601 dump_cfg_fmtint(oCompression, o->compression);
2602 dump_cfg_fmtint(oControlMaster, o->control_master);
2603 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2604 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2605 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2606 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2607 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2608 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2609 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2610 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2612 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2613 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2615 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2616 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2617 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2618 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2619 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2620 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2621 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2622 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2623 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2624 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2625 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2626 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2627 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2628 dump_cfg_fmtint(oTunnel, o->tun_open);
2629 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2630 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2631 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2633 /* Integer options */
2634 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2635 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2636 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2637 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2638 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2639 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2641 /* String options */
2642 dump_cfg_string(oBindAddress, o->bind_address);
2643 dump_cfg_string(oBindInterface, o->bind_interface);
2644 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2645 dump_cfg_string(oControlPath, o->control_path);
2646 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2647 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2648 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2649 dump_cfg_string(oIdentityAgent, o->identity_agent);
2650 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2651 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2652 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2653 dump_cfg_string(oLocalCommand, o->local_command);
2654 dump_cfg_string(oRemoteCommand, o->remote_command);
2655 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2656 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2657 #ifdef ENABLE_PKCS11
2658 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2660 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2661 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2662 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2663 dump_cfg_string(oXAuthLocation, o->xauth_location);
2666 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2667 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2668 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2670 /* String array options */
2671 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2672 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2673 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2674 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2675 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2676 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2677 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2681 /* oConnectTimeout */
2682 if (o->connection_timeout == -1)
2683 printf("connecttimeout none\n");
2685 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2688 printf("tunneldevice");
2689 if (o->tun_local == SSH_TUNID_ANY)
2692 printf(" %d", o->tun_local);
2693 if (o->tun_remote == SSH_TUNID_ANY)
2696 printf(":%d", o->tun_remote);
2699 /* oCanonicalizePermittedCNAMEs */
2700 if ( o->num_permitted_cnames > 0) {
2701 printf("canonicalizePermittedcnames");
2702 for (i = 0; i < o->num_permitted_cnames; i++) {
2703 printf(" %s:%s", o->permitted_cnames[i].source_list,
2704 o->permitted_cnames[i].target_list);
2709 /* oControlPersist */
2710 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2711 dump_cfg_fmtint(oControlPersist, o->control_persist);
2713 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2716 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2717 printf("escapechar none\n");
2719 vis(buf, o->escape_char, VIS_WHITE, 0);
2720 printf("escapechar %s\n", buf);
2724 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2725 printf("%s\n", iptos2str(o->ip_qos_bulk));
2728 printf("rekeylimit %llu %d\n",
2729 (unsigned long long)o->rekey_limit, o->rekey_interval);
2731 /* oStreamLocalBindMask */
2732 printf("streamlocalbindmask 0%o\n",
2733 o->fwd_opts.streamlocal_bind_mask);
2736 printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2738 /* oProxyCommand / oProxyJump */
2739 if (o->jump_host == NULL)
2740 dump_cfg_string(oProxyCommand, o->proxy_command);
2742 /* Check for numeric addresses */
2743 i = strchr(o->jump_host, ':') != NULL ||
2744 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2745 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2746 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2747 /* optional additional jump spec */
2748 o->jump_extra == NULL ? "" : o->jump_extra,
2749 o->jump_extra == NULL ? "" : ",",
2751 o->jump_user == NULL ? "" : o->jump_user,
2752 o->jump_user == NULL ? "" : "@",
2753 /* opening [ if hostname is numeric */
2755 /* mandatory hostname */
2757 /* closing ] if hostname is numeric */
2759 /* optional port number */
2760 o->jump_port <= 0 ? "" : ":",
2761 o->jump_port <= 0 ? "" : buf);