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>
19 #ifdef VMWARE_GUEST_WORKAROUND
20 #include <sys/sysctl.h>
23 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <netinet/in_systm.h>
29 #include <netinet/ip.h>
30 #include <arpa/inet.h>
46 #ifdef USE_SYSTEM_GLOB
49 # include "openbsd-compat/glob.h"
54 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
63 #include "pathnames.h"
72 #include "myproposal.h"
76 /* Format of the configuration file:
78 # Configuration data is parsed as follows:
79 # 1. command line options
80 # 2. user-specific file
82 # Any configuration value is only changed the first time it is set.
83 # Thus, host-specific definitions should be at the beginning of the
84 # configuration file, and defaults at the end.
86 # Host-specific declarations. These may override anything above. A single
87 # host may match multiple declarations; these are processed in the order
88 # that they are given in.
94 HostName another.host.name.real.org
101 RemoteForward 9999 shadows.cs.hut.fi:9999
104 Host fascist.blob.com
107 PasswordAuthentication no
111 ProxyCommand ssh-proxy %h %p
114 PublicKeyAuthentication no
118 PasswordAuthentication no
124 # Defaults for various options
128 PasswordAuthentication yes
129 RSAAuthentication yes
130 RhostsRSAAuthentication yes
131 StrictHostKeyChecking yes
133 IdentityFile ~/.ssh/identity
139 static int read_config_file_depth(const char *filename, struct passwd *pw,
140 const char *host, const char *original_host, Options *options,
141 int flags, int *activep, int depth);
142 static int process_config_line_depth(Options *options, struct passwd *pw,
143 const char *host, const char *original_host, char *line,
144 const char *filename, int linenum, int *activep, int flags, int depth);
146 /* Keyword tokens. */
151 oHost, oMatch, oInclude,
152 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
153 oGatewayPorts, oExitOnForwardFailure,
154 oPasswordAuthentication, oRSAAuthentication,
155 oChallengeResponseAuthentication, oXAuthLocation,
156 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
157 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
158 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
159 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
160 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
161 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
162 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
163 oPubkeyAuthentication,
164 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
165 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
166 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
167 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
168 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
169 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
170 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
171 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
173 oTunnel, oTunnelDevice,
174 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
176 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
177 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
178 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
179 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
180 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
181 oPubkeyAcceptedKeyTypes, oProxyJump,
182 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
185 /* Textual representations of the tokens. */
191 /* Deprecated options */
192 { "protocol", oIgnore }, /* NB. silently ignored */
193 { "cipher", oDeprecated },
194 { "fallbacktorsh", oDeprecated },
195 { "globalknownhostsfile2", oDeprecated },
196 { "rhostsauthentication", oDeprecated },
197 { "userknownhostsfile2", oDeprecated },
198 { "useroaming", oDeprecated },
199 { "usersh", oDeprecated },
200 { "useprivilegedport", oDeprecated },
202 /* Unsupported options */
203 { "afstokenpassing", oUnsupported },
204 { "kerberosauthentication", oUnsupported },
205 { "kerberostgtpassing", oUnsupported },
207 /* Sometimes-unsupported options */
209 { "gssapiauthentication", oGssAuthentication },
210 { "gssapidelegatecredentials", oGssDelegateCreds },
212 { "gssapiauthentication", oUnsupported },
213 { "gssapidelegatecredentials", oUnsupported },
216 { "smartcarddevice", oPKCS11Provider },
217 { "pkcs11provider", oPKCS11Provider },
219 { "smartcarddevice", oUnsupported },
220 { "pkcs11provider", oUnsupported },
222 { "rsaauthentication", oUnsupported },
223 { "rhostsrsaauthentication", oUnsupported },
224 { "compressionlevel", oUnsupported },
226 { "forwardagent", oForwardAgent },
227 { "forwardx11", oForwardX11 },
228 { "forwardx11trusted", oForwardX11Trusted },
229 { "forwardx11timeout", oForwardX11Timeout },
230 { "exitonforwardfailure", oExitOnForwardFailure },
231 { "xauthlocation", oXAuthLocation },
232 { "gatewayports", oGatewayPorts },
233 { "passwordauthentication", oPasswordAuthentication },
234 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
235 { "kbdinteractivedevices", oKbdInteractiveDevices },
236 { "pubkeyauthentication", oPubkeyAuthentication },
237 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
238 { "hostbasedauthentication", oHostbasedAuthentication },
239 { "challengeresponseauthentication", oChallengeResponseAuthentication },
240 { "skeyauthentication", oUnsupported },
241 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
242 { "identityfile", oIdentityFile },
243 { "identityfile2", oIdentityFile }, /* obsolete */
244 { "identitiesonly", oIdentitiesOnly },
245 { "certificatefile", oCertificateFile },
246 { "addkeystoagent", oAddKeysToAgent },
247 { "identityagent", oIdentityAgent },
248 { "hostname", oHostName },
249 { "hostkeyalias", oHostKeyAlias },
250 { "proxycommand", oProxyCommand },
252 { "ciphers", oCiphers },
254 { "remoteforward", oRemoteForward },
255 { "localforward", oLocalForward },
259 { "escapechar", oEscapeChar },
260 { "globalknownhostsfile", oGlobalKnownHostsFile },
261 { "userknownhostsfile", oUserKnownHostsFile },
262 { "connectionattempts", oConnectionAttempts },
263 { "batchmode", oBatchMode },
264 { "checkhostip", oCheckHostIP },
265 { "stricthostkeychecking", oStrictHostKeyChecking },
266 { "compression", oCompression },
267 { "tcpkeepalive", oTCPKeepAlive },
268 { "keepalive", oTCPKeepAlive }, /* obsolete */
269 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
270 { "syslogfacility", oLogFacility },
271 { "loglevel", oLogLevel },
272 { "dynamicforward", oDynamicForward },
273 { "preferredauthentications", oPreferredAuthentications },
274 { "hostkeyalgorithms", oHostKeyAlgorithms },
275 { "bindaddress", oBindAddress },
276 { "bindinterface", oBindInterface },
277 { "clearallforwardings", oClearAllForwardings },
278 { "enablesshkeysign", oEnableSSHKeysign },
279 { "verifyhostkeydns", oVerifyHostKeyDNS },
280 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
281 { "rekeylimit", oRekeyLimit },
282 { "connecttimeout", oConnectTimeout },
283 { "addressfamily", oAddressFamily },
284 { "serveraliveinterval", oServerAliveInterval },
285 { "serveralivecountmax", oServerAliveCountMax },
286 { "sendenv", oSendEnv },
287 { "setenv", oSetEnv },
288 { "controlpath", oControlPath },
289 { "controlmaster", oControlMaster },
290 { "controlpersist", oControlPersist },
291 { "hashknownhosts", oHashKnownHosts },
292 { "include", oInclude },
293 { "tunnel", oTunnel },
294 { "tunneldevice", oTunnelDevice },
295 { "localcommand", oLocalCommand },
296 { "permitlocalcommand", oPermitLocalCommand },
297 { "remotecommand", oRemoteCommand },
298 { "visualhostkey", oVisualHostKey },
299 { "kexalgorithms", oKexAlgorithms },
301 { "requesttty", oRequestTTY },
302 { "proxyusefdpass", oProxyUseFdpass },
303 { "canonicaldomains", oCanonicalDomains },
304 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
305 { "canonicalizehostname", oCanonicalizeHostname },
306 { "canonicalizemaxdots", oCanonicalizeMaxDots },
307 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
308 { "streamlocalbindmask", oStreamLocalBindMask },
309 { "streamlocalbindunlink", oStreamLocalBindUnlink },
310 { "revokedhostkeys", oRevokedHostKeys },
311 { "fingerprinthash", oFingerprintHash },
312 { "updatehostkeys", oUpdateHostkeys },
313 { "hostbasedkeytypes", oHostbasedKeyTypes },
314 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
315 { "ignoreunknown", oIgnoreUnknown },
316 { "proxyjump", oProxyJump },
318 { "hpndisabled", oDeprecated },
319 { "hpnbuffersize", oDeprecated },
320 { "tcprcvbufpoll", oDeprecated },
321 { "tcprcvbuf", oDeprecated },
322 { "noneenabled", oUnsupported },
323 { "noneswitch", oUnsupported },
324 { "versionaddendum", oVersionAddendum },
330 * Adds a local TCP/IP port forward to options. Never returns if there is an
335 add_local_forward(Options *options, const struct Forward *newfwd)
338 int i, ipport_reserved;
340 /* Don't add duplicates */
341 for (i = 0; i < options->num_local_forwards; i++) {
342 if (forward_equals(newfwd, options->local_forwards + i))
345 options->local_forwards = xreallocarray(options->local_forwards,
346 options->num_local_forwards + 1,
347 sizeof(*options->local_forwards));
348 fwd = &options->local_forwards[options->num_local_forwards++];
350 fwd->listen_host = newfwd->listen_host;
351 fwd->listen_port = newfwd->listen_port;
352 fwd->listen_path = newfwd->listen_path;
353 fwd->connect_host = newfwd->connect_host;
354 fwd->connect_port = newfwd->connect_port;
355 fwd->connect_path = newfwd->connect_path;
359 * Adds a remote TCP/IP port forward to options. Never returns if there is
364 add_remote_forward(Options *options, const struct Forward *newfwd)
369 /* Don't add duplicates */
370 for (i = 0; i < options->num_remote_forwards; i++) {
371 if (forward_equals(newfwd, options->remote_forwards + i))
374 options->remote_forwards = xreallocarray(options->remote_forwards,
375 options->num_remote_forwards + 1,
376 sizeof(*options->remote_forwards));
377 fwd = &options->remote_forwards[options->num_remote_forwards++];
379 fwd->listen_host = newfwd->listen_host;
380 fwd->listen_port = newfwd->listen_port;
381 fwd->listen_path = newfwd->listen_path;
382 fwd->connect_host = newfwd->connect_host;
383 fwd->connect_port = newfwd->connect_port;
384 fwd->connect_path = newfwd->connect_path;
385 fwd->handle = newfwd->handle;
386 fwd->allocated_port = 0;
390 clear_forwardings(Options *options)
394 for (i = 0; i < options->num_local_forwards; i++) {
395 free(options->local_forwards[i].listen_host);
396 free(options->local_forwards[i].listen_path);
397 free(options->local_forwards[i].connect_host);
398 free(options->local_forwards[i].connect_path);
400 if (options->num_local_forwards > 0) {
401 free(options->local_forwards);
402 options->local_forwards = NULL;
404 options->num_local_forwards = 0;
405 for (i = 0; i < options->num_remote_forwards; i++) {
406 free(options->remote_forwards[i].listen_host);
407 free(options->remote_forwards[i].listen_path);
408 free(options->remote_forwards[i].connect_host);
409 free(options->remote_forwards[i].connect_path);
411 if (options->num_remote_forwards > 0) {
412 free(options->remote_forwards);
413 options->remote_forwards = NULL;
415 options->num_remote_forwards = 0;
416 options->tun_open = SSH_TUNMODE_NO;
420 add_certificate_file(Options *options, const char *path, int userprovided)
424 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
425 fatal("Too many certificate files specified (max %d)",
426 SSH_MAX_CERTIFICATE_FILES);
428 /* Avoid registering duplicates */
429 for (i = 0; i < options->num_certificate_files; i++) {
430 if (options->certificate_file_userprovided[i] == userprovided &&
431 strcmp(options->certificate_files[i], path) == 0) {
432 debug2("%s: ignoring duplicate key %s", __func__, path);
437 options->certificate_file_userprovided[options->num_certificate_files] =
439 options->certificate_files[options->num_certificate_files++] =
444 add_identity_file(Options *options, const char *dir, const char *filename,
450 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
451 fatal("Too many identity files specified (max %d)",
452 SSH_MAX_IDENTITY_FILES);
454 if (dir == NULL) /* no dir, filename is absolute */
455 path = xstrdup(filename);
456 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
457 fatal("Identity file path %s too long", path);
459 /* Avoid registering duplicates */
460 for (i = 0; i < options->num_identity_files; i++) {
461 if (options->identity_file_userprovided[i] == userprovided &&
462 strcmp(options->identity_files[i], path) == 0) {
463 debug2("%s: ignoring duplicate key %s", __func__, path);
469 options->identity_file_userprovided[options->num_identity_files] =
471 options->identity_files[options->num_identity_files++] = path;
475 default_ssh_port(void)
481 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
482 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
488 * Execute a command in a shell.
489 * Return its exit status or -1 on abnormal exit.
492 execute_in_shell(const char *cmd)
498 if ((shell = getenv("SHELL")) == NULL)
499 shell = _PATH_BSHELL;
501 /* Need this to redirect subprocess stdin/out */
502 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
503 fatal("open(/dev/null): %s", strerror(errno));
505 debug("Executing command: '%.500s'", cmd);
507 /* Fork and execute the command. */
508 if ((pid = fork()) == 0) {
511 /* Redirect child stdin and stdout. Leave stderr */
512 if (dup2(devnull, STDIN_FILENO) == -1)
513 fatal("dup2: %s", strerror(errno));
514 if (dup2(devnull, STDOUT_FILENO) == -1)
515 fatal("dup2: %s", strerror(errno));
516 if (devnull > STDERR_FILENO)
518 closefrom(STDERR_FILENO + 1);
522 argv[2] = xstrdup(cmd);
525 execv(argv[0], argv);
526 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
527 /* Die with signal to make this error apparent to parent. */
528 signal(SIGTERM, SIG_DFL);
529 kill(getpid(), SIGTERM);
534 fatal("%s: fork: %.100s", __func__, strerror(errno));
538 while (waitpid(pid, &status, 0) == -1) {
539 if (errno != EINTR && errno != EAGAIN)
540 fatal("%s: waitpid: %s", __func__, strerror(errno));
542 if (!WIFEXITED(status)) {
543 error("command '%.100s' exited abnormally", cmd);
546 debug3("command returned status %d", WEXITSTATUS(status));
547 return WEXITSTATUS(status);
551 * Parse and execute a Match directive.
554 match_cfg_line(Options *options, char **condition, struct passwd *pw,
555 const char *host_arg, const char *original_host, int post_canon,
556 const char *filename, int linenum)
558 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
560 int r, port, this_result, result = 1, attributes = 0, negate;
561 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
565 * Configuration is likely to be incomplete at this point so we
566 * must be prepared to use default values.
568 port = options->port <= 0 ? default_ssh_port() : options->port;
569 ruser = options->user == NULL ? pw->pw_name : options->user;
571 host = xstrdup(options->hostname);
572 } else if (options->hostname != NULL) {
573 /* NB. Please keep in sync with ssh.c:main() */
574 host = percent_expand(options->hostname,
575 "h", host_arg, (char *)NULL);
577 host = xstrdup(host_arg);
580 debug2("checking match for '%s' host %s originally %s",
581 cp, host, original_host);
582 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
585 if ((negate = attrib[0] == '!'))
587 /* criteria "all" and "canonical" have no argument */
588 if (strcasecmp(attrib, "all") == 0) {
589 if (attributes > 1 ||
590 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
591 error("%.200s line %d: '%s' cannot be combined "
592 "with other Match attributes",
593 filename, linenum, oattrib);
598 result = negate ? 0 : 1;
602 if (strcasecmp(attrib, "canonical") == 0) {
603 r = !!post_canon; /* force bitmask member to boolean */
604 if (r == (negate ? 1 : 0))
605 this_result = result = 0;
606 debug3("%.200s line %d: %smatched '%s'",
608 this_result ? "" : "not ", oattrib);
611 /* All other criteria require an argument */
612 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
613 error("Missing Match criteria for %s", attrib);
617 if (strcasecmp(attrib, "host") == 0) {
618 criteria = xstrdup(host);
619 r = match_hostname(host, arg) == 1;
620 if (r == (negate ? 1 : 0))
621 this_result = result = 0;
622 } else if (strcasecmp(attrib, "originalhost") == 0) {
623 criteria = xstrdup(original_host);
624 r = match_hostname(original_host, arg) == 1;
625 if (r == (negate ? 1 : 0))
626 this_result = result = 0;
627 } else if (strcasecmp(attrib, "user") == 0) {
628 criteria = xstrdup(ruser);
629 r = match_pattern_list(ruser, arg, 0) == 1;
630 if (r == (negate ? 1 : 0))
631 this_result = result = 0;
632 } else if (strcasecmp(attrib, "localuser") == 0) {
633 criteria = xstrdup(pw->pw_name);
634 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
635 if (r == (negate ? 1 : 0))
636 this_result = result = 0;
637 } else if (strcasecmp(attrib, "exec") == 0) {
638 if (gethostname(thishost, sizeof(thishost)) == -1)
639 fatal("gethostname: %s", strerror(errno));
640 strlcpy(shorthost, thishost, sizeof(shorthost));
641 shorthost[strcspn(thishost, ".")] = '\0';
642 snprintf(portstr, sizeof(portstr), "%d", port);
643 snprintf(uidstr, sizeof(uidstr), "%llu",
644 (unsigned long long)pw->pw_uid);
646 cmd = percent_expand(arg,
658 /* skip execution if prior predicate failed */
659 debug3("%.200s line %d: skipped exec "
660 "\"%.100s\"", filename, linenum, cmd);
664 r = execute_in_shell(cmd);
666 fatal("%.200s line %d: match exec "
667 "'%.100s' error", filename,
670 criteria = xstrdup(cmd);
672 /* Force exit status to boolean */
674 if (r == (negate ? 1 : 0))
675 this_result = result = 0;
677 error("Unsupported Match attribute %s", attrib);
681 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
682 filename, linenum, this_result ? "": "not ",
686 if (attributes == 0) {
687 error("One or more attributes required for Match");
693 debug2("match %sfound", result ? "" : "not ");
699 /* Remove environment variable by pattern */
701 rm_env(Options *options, const char *arg, const char *filename, int linenum)
706 /* Remove an environment variable */
707 for (i = 0; i < options->num_send_env; ) {
708 cp = xstrdup(options->send_env[i]);
709 if (!match_pattern(cp, arg + 1)) {
714 debug3("%s line %d: removing environment %s",
715 filename, linenum, cp);
717 free(options->send_env[i]);
718 options->send_env[i] = NULL;
719 for (j = i; j < options->num_send_env - 1; j++) {
720 options->send_env[j] = options->send_env[j + 1];
721 options->send_env[j + 1] = NULL;
723 options->num_send_env--;
724 /* NB. don't increment i */
729 * Returns the number of the token pointed to by cp or oBadOption.
732 parse_token(const char *cp, const char *filename, int linenum,
733 const char *ignored_unknown)
737 for (i = 0; keywords[i].name; i++)
738 if (strcmp(cp, keywords[i].name) == 0)
739 return keywords[i].opcode;
740 if (ignored_unknown != NULL &&
741 match_pattern_list(cp, ignored_unknown, 1) == 1)
742 return oIgnoredUnknownOption;
743 error("%s: line %d: Bad configuration option: %s",
744 filename, linenum, cp);
748 /* Multistate option parsing */
753 static const struct multistate multistate_flag[] = {
760 static const struct multistate multistate_yesnoask[] = {
768 static const struct multistate multistate_strict_hostkey[] = {
769 { "true", SSH_STRICT_HOSTKEY_YES },
770 { "false", SSH_STRICT_HOSTKEY_OFF },
771 { "yes", SSH_STRICT_HOSTKEY_YES },
772 { "no", SSH_STRICT_HOSTKEY_OFF },
773 { "ask", SSH_STRICT_HOSTKEY_ASK },
774 { "off", SSH_STRICT_HOSTKEY_OFF },
775 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
778 static const struct multistate multistate_yesnoaskconfirm[] = {
787 static const struct multistate multistate_addressfamily[] = {
789 { "inet6", AF_INET6 },
790 { "any", AF_UNSPEC },
793 static const struct multistate multistate_controlmaster[] = {
794 { "true", SSHCTL_MASTER_YES },
795 { "yes", SSHCTL_MASTER_YES },
796 { "false", SSHCTL_MASTER_NO },
797 { "no", SSHCTL_MASTER_NO },
798 { "auto", SSHCTL_MASTER_AUTO },
799 { "ask", SSHCTL_MASTER_ASK },
800 { "autoask", SSHCTL_MASTER_AUTO_ASK },
803 static const struct multistate multistate_tunnel[] = {
804 { "ethernet", SSH_TUNMODE_ETHERNET },
805 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
806 { "true", SSH_TUNMODE_DEFAULT },
807 { "yes", SSH_TUNMODE_DEFAULT },
808 { "false", SSH_TUNMODE_NO },
809 { "no", SSH_TUNMODE_NO },
812 static const struct multistate multistate_requesttty[] = {
813 { "true", REQUEST_TTY_YES },
814 { "yes", REQUEST_TTY_YES },
815 { "false", REQUEST_TTY_NO },
816 { "no", REQUEST_TTY_NO },
817 { "force", REQUEST_TTY_FORCE },
818 { "auto", REQUEST_TTY_AUTO },
821 static const struct multistate multistate_canonicalizehostname[] = {
822 { "true", SSH_CANONICALISE_YES },
823 { "false", SSH_CANONICALISE_NO },
824 { "yes", SSH_CANONICALISE_YES },
825 { "no", SSH_CANONICALISE_NO },
826 { "always", SSH_CANONICALISE_ALWAYS },
831 * Processes a single option line as used in the configuration files. This
832 * only sets those values that have not already been set.
835 process_config_line(Options *options, struct passwd *pw, const char *host,
836 const char *original_host, char *line, const char *filename,
837 int linenum, int *activep, int flags)
839 return process_config_line_depth(options, pw, host, original_host,
840 line, filename, linenum, activep, flags, 0);
843 #define WHITESPACE " \t\r\n"
845 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
846 const char *original_host, char *line, const char *filename,
847 int linenum, int *activep, int flags, int depth)
849 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
850 char **cpptr, fwdarg[256];
851 u_int i, *uintptr, max_entries = 0;
852 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
853 int remotefwd, dynamicfwd;
854 LogLevel *log_level_ptr;
855 SyslogFacility *log_facility_ptr;
859 const struct multistate *multistate_ptr;
860 struct allowed_cname *cname;
864 if (activep == NULL) { /* We are processing a command line directive */
869 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
870 if ((len = strlen(line)) == 0)
872 for (len--; len > 0; len--) {
873 if (strchr(WHITESPACE "\f", line[len]) == NULL)
879 /* Get the keyword. (Each line is supposed to begin with a keyword). */
880 if ((keyword = strdelim(&s)) == NULL)
882 /* Ignore leading whitespace. */
883 if (*keyword == '\0')
884 keyword = strdelim(&s);
885 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
887 /* Match lowercase keyword */
890 opcode = parse_token(keyword, filename, linenum,
891 options->ignored_unknown);
895 /* don't panic, but count bad options */
899 case oIgnoredUnknownOption:
900 debug("%s line %d: Ignored unknown option \"%s\"",
901 filename, linenum, keyword);
903 case oConnectTimeout:
904 intptr = &options->connection_timeout;
907 if (!arg || *arg == '\0')
908 fatal("%s line %d: missing time value.",
910 if (strcmp(arg, "none") == 0)
912 else if ((value = convtime(arg)) == -1)
913 fatal("%s line %d: invalid time value.",
915 if (*activep && *intptr == -1)
920 intptr = &options->forward_agent;
922 multistate_ptr = multistate_flag;
925 if (!arg || *arg == '\0')
926 fatal("%s line %d: missing argument.",
929 for (i = 0; multistate_ptr[i].key != NULL; i++) {
930 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
931 value = multistate_ptr[i].value;
936 fatal("%s line %d: unsupported option \"%s\".",
937 filename, linenum, arg);
938 if (*activep && *intptr == -1)
943 intptr = &options->forward_x11;
946 case oForwardX11Trusted:
947 intptr = &options->forward_x11_trusted;
950 case oForwardX11Timeout:
951 intptr = &options->forward_x11_timeout;
955 intptr = &options->fwd_opts.gateway_ports;
958 case oExitOnForwardFailure:
959 intptr = &options->exit_on_forward_failure;
962 case oPasswordAuthentication:
963 intptr = &options->password_authentication;
966 case oKbdInteractiveAuthentication:
967 intptr = &options->kbd_interactive_authentication;
970 case oKbdInteractiveDevices:
971 charptr = &options->kbd_interactive_devices;
974 case oPubkeyAuthentication:
975 intptr = &options->pubkey_authentication;
978 case oHostbasedAuthentication:
979 intptr = &options->hostbased_authentication;
982 case oChallengeResponseAuthentication:
983 intptr = &options->challenge_response_authentication;
986 case oGssAuthentication:
987 intptr = &options->gss_authentication;
990 case oGssDelegateCreds:
991 intptr = &options->gss_deleg_creds;
995 intptr = &options->batch_mode;
999 intptr = &options->check_host_ip;
1002 case oVerifyHostKeyDNS:
1003 intptr = &options->verify_host_key_dns;
1004 multistate_ptr = multistate_yesnoask;
1005 goto parse_multistate;
1007 case oStrictHostKeyChecking:
1008 intptr = &options->strict_host_key_checking;
1009 multistate_ptr = multistate_strict_hostkey;
1010 goto parse_multistate;
1013 intptr = &options->compression;
1017 intptr = &options->tcp_keep_alive;
1020 case oNoHostAuthenticationForLocalhost:
1021 intptr = &options->no_host_authentication_for_localhost;
1024 case oNumberOfPasswordPrompts:
1025 intptr = &options->number_of_password_prompts;
1030 if (!arg || *arg == '\0')
1031 fatal("%.200s line %d: Missing argument.", filename,
1033 if (strcmp(arg, "default") == 0) {
1036 if (scan_scaled(arg, &val64) == -1)
1037 fatal("%.200s line %d: Bad number '%s': %s",
1038 filename, linenum, arg, strerror(errno));
1039 if (val64 != 0 && val64 < 16)
1040 fatal("%.200s line %d: RekeyLimit too small",
1043 if (*activep && options->rekey_limit == -1)
1044 options->rekey_limit = val64;
1045 if (s != NULL) { /* optional rekey interval present */
1046 if (strcmp(s, "none") == 0) {
1047 (void)strdelim(&s); /* discard */
1050 intptr = &options->rekey_interval;
1057 if (!arg || *arg == '\0')
1058 fatal("%.200s line %d: Missing argument.", filename, linenum);
1060 intptr = &options->num_identity_files;
1061 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1062 fatal("%.200s line %d: Too many identity files specified (max %d).",
1063 filename, linenum, SSH_MAX_IDENTITY_FILES);
1064 add_identity_file(options, NULL,
1065 arg, flags & SSHCONF_USERCONF);
1069 case oCertificateFile:
1071 if (!arg || *arg == '\0')
1072 fatal("%.200s line %d: Missing argument.",
1075 intptr = &options->num_certificate_files;
1076 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1077 fatal("%.200s line %d: Too many certificate "
1078 "files specified (max %d).",
1080 SSH_MAX_CERTIFICATE_FILES);
1082 add_certificate_file(options, arg,
1083 flags & SSHCONF_USERCONF);
1087 case oXAuthLocation:
1088 charptr=&options->xauth_location;
1092 charptr = &options->user;
1095 if (!arg || *arg == '\0')
1096 fatal("%.200s line %d: Missing argument.",
1098 if (*activep && *charptr == NULL)
1099 *charptr = xstrdup(arg);
1102 case oGlobalKnownHostsFile:
1103 cpptr = (char **)&options->system_hostfiles;
1104 uintptr = &options->num_system_hostfiles;
1105 max_entries = SSH_MAX_HOSTS_FILES;
1107 if (*activep && *uintptr == 0) {
1108 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1109 if ((*uintptr) >= max_entries)
1110 fatal("%s line %d: "
1111 "too many authorized keys files.",
1113 cpptr[(*uintptr)++] = xstrdup(arg);
1118 case oUserKnownHostsFile:
1119 cpptr = (char **)&options->user_hostfiles;
1120 uintptr = &options->num_user_hostfiles;
1121 max_entries = SSH_MAX_HOSTS_FILES;
1122 goto parse_char_array;
1125 charptr = &options->hostname;
1129 charptr = &options->host_key_alias;
1132 case oPreferredAuthentications:
1133 charptr = &options->preferred_authentications;
1137 charptr = &options->bind_address;
1140 case oBindInterface:
1141 charptr = &options->bind_interface;
1144 case oPKCS11Provider:
1145 charptr = &options->pkcs11_provider;
1149 charptr = &options->proxy_command;
1150 /* Ignore ProxyCommand if ProxyJump already specified */
1151 if (options->jump_host != NULL)
1152 charptr = &options->jump_host; /* Skip below */
1155 fatal("%.200s line %d: Missing argument.", filename, linenum);
1156 len = strspn(s, WHITESPACE "=");
1157 if (*activep && *charptr == NULL)
1158 *charptr = xstrdup(s + len);
1163 fatal("%.200s line %d: Missing argument.",
1166 len = strspn(s, WHITESPACE "=");
1167 if (parse_jump(s + len, options, *activep) == -1) {
1168 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1169 filename, linenum, s + len);
1174 intptr = &options->port;
1177 if ((errstr = atoi_err(arg, &value)) != NULL)
1178 fatal("%s line %d: integer value %s.",
1179 filename, linenum, errstr);
1180 if (*activep && *intptr == -1)
1184 case oConnectionAttempts:
1185 intptr = &options->connection_attempts;
1190 if (!arg || *arg == '\0')
1191 fatal("%.200s line %d: Missing argument.", filename, linenum);
1192 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1193 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1194 filename, linenum, arg ? arg : "<NONE>");
1195 if (*activep && options->ciphers == NULL)
1196 options->ciphers = xstrdup(arg);
1201 if (!arg || *arg == '\0')
1202 fatal("%.200s line %d: Missing argument.", filename, linenum);
1203 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1204 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1205 filename, linenum, arg ? arg : "<NONE>");
1206 if (*activep && options->macs == NULL)
1207 options->macs = xstrdup(arg);
1210 case oKexAlgorithms:
1212 if (!arg || *arg == '\0')
1213 fatal("%.200s line %d: Missing argument.",
1216 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1217 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1218 filename, linenum, arg ? arg : "<NONE>");
1219 if (*activep && options->kex_algorithms == NULL)
1220 options->kex_algorithms = xstrdup(arg);
1223 case oHostKeyAlgorithms:
1224 charptr = &options->hostkeyalgorithms;
1227 if (!arg || *arg == '\0')
1228 fatal("%.200s line %d: Missing argument.",
1231 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1232 fatal("%s line %d: Bad key types '%s'.",
1233 filename, linenum, arg ? arg : "<NONE>");
1234 if (*activep && *charptr == NULL)
1235 *charptr = xstrdup(arg);
1239 log_level_ptr = &options->log_level;
1241 value = log_level_number(arg);
1242 if (value == SYSLOG_LEVEL_NOT_SET)
1243 fatal("%.200s line %d: unsupported log level '%s'",
1244 filename, linenum, arg ? arg : "<NONE>");
1245 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1246 *log_level_ptr = (LogLevel) value;
1250 log_facility_ptr = &options->log_facility;
1252 value = log_facility_number(arg);
1253 if (value == SYSLOG_FACILITY_NOT_SET)
1254 fatal("%.200s line %d: unsupported log facility '%s'",
1255 filename, linenum, arg ? arg : "<NONE>");
1256 if (*log_facility_ptr == -1)
1257 *log_facility_ptr = (SyslogFacility) value;
1261 case oRemoteForward:
1262 case oDynamicForward:
1264 if (arg == NULL || *arg == '\0')
1265 fatal("%.200s line %d: Missing port argument.",
1268 remotefwd = (opcode == oRemoteForward);
1269 dynamicfwd = (opcode == oDynamicForward);
1272 arg2 = strdelim(&s);
1273 if (arg2 == NULL || *arg2 == '\0') {
1277 fatal("%.200s line %d: Missing target "
1278 "argument.", filename, linenum);
1280 /* construct a string for parse_forward */
1281 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1286 strlcpy(fwdarg, arg, sizeof(fwdarg));
1288 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1289 fatal("%.200s line %d: Bad forwarding specification.",
1294 add_remote_forward(options, &fwd);
1296 add_local_forward(options, &fwd);
1301 case oClearAllForwardings:
1302 intptr = &options->clear_forwardings;
1307 fatal("Host directive not supported as a command-line "
1311 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1312 if ((flags & SSHCONF_NEVERMATCH) != 0)
1314 negated = *arg == '!';
1317 if (match_pattern(host, arg)) {
1319 debug("%.200s line %d: Skipping Host "
1320 "block because of negated match "
1321 "for %.100s", filename, linenum,
1327 arg2 = arg; /* logged below */
1332 debug("%.200s line %d: Applying options for %.100s",
1333 filename, linenum, arg2);
1334 /* Avoid garbage check below, as strdelim is done. */
1339 fatal("Host directive not supported as a command-line "
1341 value = match_cfg_line(options, &s, pw, host, original_host,
1342 flags & SSHCONF_POSTCANON, filename, linenum);
1344 fatal("%.200s line %d: Bad Match condition", filename,
1346 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1350 intptr = &options->escape_char;
1352 if (!arg || *arg == '\0')
1353 fatal("%.200s line %d: Missing argument.", filename, linenum);
1354 if (strcmp(arg, "none") == 0)
1355 value = SSH_ESCAPECHAR_NONE;
1356 else if (arg[1] == '\0')
1357 value = (u_char) arg[0];
1358 else if (arg[0] == '^' && arg[2] == 0 &&
1359 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1360 value = (u_char) arg[1] & 31;
1362 fatal("%.200s line %d: Bad escape character.",
1365 value = 0; /* Avoid compiler warning. */
1367 if (*activep && *intptr == -1)
1371 case oAddressFamily:
1372 intptr = &options->address_family;
1373 multistate_ptr = multistate_addressfamily;
1374 goto parse_multistate;
1376 case oEnableSSHKeysign:
1377 intptr = &options->enable_ssh_keysign;
1380 case oIdentitiesOnly:
1381 intptr = &options->identities_only;
1384 case oServerAliveInterval:
1385 intptr = &options->server_alive_interval;
1388 case oServerAliveCountMax:
1389 intptr = &options->server_alive_count_max;
1393 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1394 if (strchr(arg, '=') != NULL)
1395 fatal("%s line %d: Invalid environment name.",
1400 /* Removing an env var */
1401 rm_env(options, arg, filename, linenum);
1404 /* Adding an env var */
1405 if (options->num_send_env >= INT_MAX)
1406 fatal("%s line %d: too many send env.",
1408 options->send_env = xrecallocarray(
1409 options->send_env, options->num_send_env,
1410 options->num_send_env + 1,
1411 sizeof(*options->send_env));
1412 options->send_env[options->num_send_env++] =
1419 value = options->num_setenv;
1420 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1421 if (strchr(arg, '=') == NULL)
1422 fatal("%s line %d: Invalid SetEnv.",
1424 if (!*activep || value != 0)
1426 /* Adding a setenv var */
1427 if (options->num_setenv >= INT_MAX)
1428 fatal("%s line %d: too many SetEnv.",
1430 options->setenv = xrecallocarray(
1431 options->setenv, options->num_setenv,
1432 options->num_setenv + 1, sizeof(*options->setenv));
1433 options->setenv[options->num_setenv++] = xstrdup(arg);
1438 charptr = &options->control_path;
1441 case oControlMaster:
1442 intptr = &options->control_master;
1443 multistate_ptr = multistate_controlmaster;
1444 goto parse_multistate;
1446 case oControlPersist:
1447 /* no/false/yes/true, or a time spec */
1448 intptr = &options->control_persist;
1450 if (!arg || *arg == '\0')
1451 fatal("%.200s line %d: Missing ControlPersist"
1452 " argument.", filename, linenum);
1454 value2 = 0; /* timeout */
1455 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1457 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1459 else if ((value2 = convtime(arg)) >= 0)
1462 fatal("%.200s line %d: Bad ControlPersist argument.",
1464 if (*activep && *intptr == -1) {
1466 options->control_persist_timeout = value2;
1470 case oHashKnownHosts:
1471 intptr = &options->hash_known_hosts;
1475 intptr = &options->tun_open;
1476 multistate_ptr = multistate_tunnel;
1477 goto parse_multistate;
1481 if (!arg || *arg == '\0')
1482 fatal("%.200s line %d: Missing argument.", filename, linenum);
1483 value = a2tun(arg, &value2);
1484 if (value == SSH_TUNID_ERR)
1485 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1487 options->tun_local = value;
1488 options->tun_remote = value2;
1493 charptr = &options->local_command;
1496 case oPermitLocalCommand:
1497 intptr = &options->permit_local_command;
1500 case oRemoteCommand:
1501 charptr = &options->remote_command;
1504 case oVisualHostKey:
1505 intptr = &options->visual_host_key;
1510 fatal("Include directive not supported as a "
1511 "command-line option");
1513 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1515 * Ensure all paths are anchored. User configuration
1516 * files may begin with '~/' but system configurations
1517 * must not. If the path is relative, then treat it
1518 * as living in ~/.ssh for user configurations or
1519 * /etc/ssh for system ones.
1521 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1522 fatal("%.200s line %d: bad include path %s.",
1523 filename, linenum, arg);
1524 if (*arg != '/' && *arg != '~') {
1525 xasprintf(&arg2, "%s/%s",
1526 (flags & SSHCONF_USERCONF) ?
1527 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1529 arg2 = xstrdup(arg);
1530 memset(&gl, 0, sizeof(gl));
1531 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1532 if (r == GLOB_NOMATCH) {
1533 debug("%.200s line %d: include %s matched no "
1534 "files",filename, linenum, arg2);
1537 } else if (r != 0 || gl.gl_pathc < 0)
1538 fatal("%.200s line %d: glob failed for %s.",
1539 filename, linenum, arg2);
1542 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1543 debug3("%.200s line %d: Including file %s "
1544 "depth %d%s", filename, linenum,
1545 gl.gl_pathv[i], depth,
1546 oactive ? "" : " (parse only)");
1547 r = read_config_file_depth(gl.gl_pathv[i],
1548 pw, host, original_host, options,
1549 flags | SSHCONF_CHECKPERM |
1550 (oactive ? 0 : SSHCONF_NEVERMATCH),
1551 activep, depth + 1);
1552 if (r != 1 && errno != ENOENT) {
1553 fatal("Can't open user config file "
1554 "%.100s: %.100s", gl.gl_pathv[i],
1558 * don't let Match in includes clobber the
1559 * containing file's Match state.
1573 if ((value = parse_ipqos(arg)) == -1)
1574 fatal("%s line %d: Bad IPQoS value: %s",
1575 filename, linenum, arg);
1579 else if ((value2 = parse_ipqos(arg)) == -1)
1580 fatal("%s line %d: Bad IPQoS value: %s",
1581 filename, linenum, arg);
1583 options->ip_qos_interactive = value;
1584 options->ip_qos_bulk = value2;
1589 intptr = &options->request_tty;
1590 multistate_ptr = multistate_requesttty;
1591 goto parse_multistate;
1593 case oVersionAddendum:
1595 fatal("%.200s line %d: Missing argument.", filename,
1597 len = strspn(s, WHITESPACE);
1598 if (*activep && options->version_addendum == NULL) {
1599 if (strcasecmp(s + len, "none") == 0)
1600 options->version_addendum = xstrdup("");
1601 else if (strchr(s + len, '\r') != NULL)
1602 fatal("%.200s line %d: Invalid argument",
1605 options->version_addendum = xstrdup(s + len);
1609 case oIgnoreUnknown:
1610 charptr = &options->ignored_unknown;
1613 case oProxyUseFdpass:
1614 intptr = &options->proxy_use_fdpass;
1617 case oCanonicalDomains:
1618 value = options->num_canonical_domains != 0;
1619 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1620 if (!valid_domain(arg, 1, &errstr)) {
1621 fatal("%s line %d: %s", filename, linenum,
1624 if (!*activep || value)
1626 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1627 fatal("%s line %d: too many hostname suffixes.",
1629 options->canonical_domains[
1630 options->num_canonical_domains++] = xstrdup(arg);
1634 case oCanonicalizePermittedCNAMEs:
1635 value = options->num_permitted_cnames != 0;
1636 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1637 /* Either '*' for everything or 'list:list' */
1638 if (strcmp(arg, "*") == 0)
1642 if ((arg2 = strchr(arg, ':')) == NULL ||
1644 fatal("%s line %d: "
1645 "Invalid permitted CNAME \"%s\"",
1646 filename, linenum, arg);
1651 if (!*activep || value)
1653 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1654 fatal("%s line %d: too many permitted CNAMEs.",
1656 cname = options->permitted_cnames +
1657 options->num_permitted_cnames++;
1658 cname->source_list = xstrdup(arg);
1659 cname->target_list = xstrdup(arg2);
1663 case oCanonicalizeHostname:
1664 intptr = &options->canonicalize_hostname;
1665 multistate_ptr = multistate_canonicalizehostname;
1666 goto parse_multistate;
1668 case oCanonicalizeMaxDots:
1669 intptr = &options->canonicalize_max_dots;
1672 case oCanonicalizeFallbackLocal:
1673 intptr = &options->canonicalize_fallback_local;
1676 case oStreamLocalBindMask:
1678 if (!arg || *arg == '\0')
1679 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1680 /* Parse mode in octal format */
1681 value = strtol(arg, &endofnumber, 8);
1682 if (arg == endofnumber || value < 0 || value > 0777)
1683 fatal("%.200s line %d: Bad mask.", filename, linenum);
1684 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1687 case oStreamLocalBindUnlink:
1688 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1691 case oRevokedHostKeys:
1692 charptr = &options->revoked_host_keys;
1695 case oFingerprintHash:
1696 intptr = &options->fingerprint_hash;
1698 if (!arg || *arg == '\0')
1699 fatal("%.200s line %d: Missing argument.",
1701 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1702 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1703 filename, linenum, arg);
1704 if (*activep && *intptr == -1)
1708 case oUpdateHostkeys:
1709 intptr = &options->update_hostkeys;
1710 multistate_ptr = multistate_yesnoask;
1711 goto parse_multistate;
1713 case oHostbasedKeyTypes:
1714 charptr = &options->hostbased_key_types;
1715 goto parse_keytypes;
1717 case oPubkeyAcceptedKeyTypes:
1718 charptr = &options->pubkey_key_types;
1719 goto parse_keytypes;
1721 case oAddKeysToAgent:
1722 intptr = &options->add_keys_to_agent;
1723 multistate_ptr = multistate_yesnoaskconfirm;
1724 goto parse_multistate;
1726 case oIdentityAgent:
1727 charptr = &options->identity_agent;
1731 debug("%s line %d: Deprecated option \"%s\"",
1732 filename, linenum, keyword);
1736 error("%s line %d: Unsupported option \"%s\"",
1737 filename, linenum, keyword);
1741 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1744 /* Check that there is no garbage at end of line. */
1745 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1746 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1747 filename, linenum, arg);
1753 * Reads the config file and modifies the options accordingly. Options
1754 * should already be initialized before this call. This never returns if
1755 * there is an error. If the file does not exist, this returns 0.
1758 read_config_file(const char *filename, struct passwd *pw, const char *host,
1759 const char *original_host, Options *options, int flags)
1763 return read_config_file_depth(filename, pw, host, original_host,
1764 options, flags, &active, 0);
1767 #define READCONF_MAX_DEPTH 16
1769 read_config_file_depth(const char *filename, struct passwd *pw,
1770 const char *host, const char *original_host, Options *options,
1771 int flags, int *activep, int depth)
1775 size_t linesize = 0;
1777 int bad_options = 0;
1779 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1780 fatal("Too many recursive configuration includes");
1782 if ((f = fopen(filename, "r")) == NULL)
1785 if (flags & SSHCONF_CHECKPERM) {
1788 if (fstat(fileno(f), &sb) == -1)
1789 fatal("fstat %s: %s", filename, strerror(errno));
1790 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1791 (sb.st_mode & 022) != 0))
1792 fatal("Bad owner or permissions on %s", filename);
1795 debug("Reading configuration data %.200s", filename);
1798 * Mark that we are now processing the options. This flag is turned
1799 * on/off by Host specifications.
1802 while (getline(&line, &linesize, f) != -1) {
1803 /* Update line number counter. */
1805 if (process_config_line_depth(options, pw, host, original_host,
1806 line, filename, linenum, activep, flags, depth) != 0)
1811 if (bad_options > 0)
1812 fatal("%s: terminating, %d bad configuration options",
1813 filename, bad_options);
1817 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1819 option_clear_or_none(const char *o)
1821 return o == NULL || strcasecmp(o, "none") == 0;
1825 * Initializes options to special values that indicate that they have not yet
1826 * been set. Read_config_file will only set options with this value. Options
1827 * are processed in the following order: command line, user config file,
1828 * system config file. Last, fill_default_options is called.
1832 initialize_options(Options * options)
1834 memset(options, 'X', sizeof(*options));
1835 options->version_addendum = NULL;
1836 options->forward_agent = -1;
1837 options->forward_x11 = -1;
1838 options->forward_x11_trusted = -1;
1839 options->forward_x11_timeout = -1;
1840 options->stdio_forward_host = NULL;
1841 options->stdio_forward_port = 0;
1842 options->clear_forwardings = -1;
1843 options->exit_on_forward_failure = -1;
1844 options->xauth_location = NULL;
1845 options->fwd_opts.gateway_ports = -1;
1846 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1847 options->fwd_opts.streamlocal_bind_unlink = -1;
1848 options->pubkey_authentication = -1;
1849 options->challenge_response_authentication = -1;
1850 options->gss_authentication = -1;
1851 options->gss_deleg_creds = -1;
1852 options->password_authentication = -1;
1853 options->kbd_interactive_authentication = -1;
1854 options->kbd_interactive_devices = NULL;
1855 options->hostbased_authentication = -1;
1856 options->batch_mode = -1;
1857 options->check_host_ip = -1;
1858 options->strict_host_key_checking = -1;
1859 options->compression = -1;
1860 options->tcp_keep_alive = -1;
1862 options->address_family = -1;
1863 options->connection_attempts = -1;
1864 options->connection_timeout = -1;
1865 options->number_of_password_prompts = -1;
1866 options->ciphers = NULL;
1867 options->macs = NULL;
1868 options->kex_algorithms = NULL;
1869 options->hostkeyalgorithms = NULL;
1870 options->num_identity_files = 0;
1871 options->num_certificate_files = 0;
1872 options->hostname = NULL;
1873 options->host_key_alias = NULL;
1874 options->proxy_command = NULL;
1875 options->jump_user = NULL;
1876 options->jump_host = NULL;
1877 options->jump_port = -1;
1878 options->jump_extra = NULL;
1879 options->user = NULL;
1880 options->escape_char = -1;
1881 options->num_system_hostfiles = 0;
1882 options->num_user_hostfiles = 0;
1883 options->local_forwards = NULL;
1884 options->num_local_forwards = 0;
1885 options->remote_forwards = NULL;
1886 options->num_remote_forwards = 0;
1887 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1888 options->log_level = SYSLOG_LEVEL_NOT_SET;
1889 options->preferred_authentications = NULL;
1890 options->bind_address = NULL;
1891 options->bind_interface = NULL;
1892 options->pkcs11_provider = NULL;
1893 options->enable_ssh_keysign = - 1;
1894 options->no_host_authentication_for_localhost = - 1;
1895 options->identities_only = - 1;
1896 options->rekey_limit = - 1;
1897 options->rekey_interval = -1;
1898 options->verify_host_key_dns = -1;
1899 options->server_alive_interval = -1;
1900 options->server_alive_count_max = -1;
1901 options->send_env = NULL;
1902 options->num_send_env = 0;
1903 options->setenv = NULL;
1904 options->num_setenv = 0;
1905 options->control_path = NULL;
1906 options->control_master = -1;
1907 options->control_persist = -1;
1908 options->control_persist_timeout = 0;
1909 options->hash_known_hosts = -1;
1910 options->tun_open = -1;
1911 options->tun_local = -1;
1912 options->tun_remote = -1;
1913 options->local_command = NULL;
1914 options->permit_local_command = -1;
1915 options->remote_command = NULL;
1916 options->add_keys_to_agent = -1;
1917 options->identity_agent = NULL;
1918 options->visual_host_key = -1;
1919 options->ip_qos_interactive = -1;
1920 options->ip_qos_bulk = -1;
1921 options->request_tty = -1;
1922 options->proxy_use_fdpass = -1;
1923 options->ignored_unknown = NULL;
1924 options->num_canonical_domains = 0;
1925 options->num_permitted_cnames = 0;
1926 options->canonicalize_max_dots = -1;
1927 options->canonicalize_fallback_local = -1;
1928 options->canonicalize_hostname = -1;
1929 options->revoked_host_keys = NULL;
1930 options->fingerprint_hash = -1;
1931 options->update_hostkeys = -1;
1932 options->hostbased_key_types = NULL;
1933 options->pubkey_key_types = NULL;
1937 * A petite version of fill_default_options() that just fills the options
1938 * needed for hostname canonicalization to proceed.
1941 fill_default_options_for_canonicalization(Options *options)
1943 if (options->canonicalize_max_dots == -1)
1944 options->canonicalize_max_dots = 1;
1945 if (options->canonicalize_fallback_local == -1)
1946 options->canonicalize_fallback_local = 1;
1947 if (options->canonicalize_hostname == -1)
1948 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1952 * Called after processing other sources of option data, this fills those
1953 * options for which no value has been specified with their default values.
1956 fill_default_options(Options * options)
1958 char *all_cipher, *all_mac, *all_kex, *all_key;
1960 #ifdef VMWARE_GUEST_WORKAROUND
1961 char scval[7]; /* "vmware\0" */
1962 size_t scsiz = sizeof(scval);
1965 if (sysctlbyname("kern.vm_guest", scval, &scsiz, NULL, 0) == 0 &&
1966 strcmp(scval, "vmware") == 0)
1970 if (options->forward_agent == -1)
1971 options->forward_agent = 0;
1972 if (options->forward_x11 == -1)
1973 options->forward_x11 = 0;
1974 if (options->forward_x11_trusted == -1)
1975 options->forward_x11_trusted = 0;
1976 if (options->forward_x11_timeout == -1)
1977 options->forward_x11_timeout = 1200;
1979 * stdio forwarding (-W) changes the default for these but we defer
1980 * setting the values so they can be overridden.
1982 if (options->exit_on_forward_failure == -1)
1983 options->exit_on_forward_failure =
1984 options->stdio_forward_host != NULL ? 1 : 0;
1985 if (options->clear_forwardings == -1)
1986 options->clear_forwardings =
1987 options->stdio_forward_host != NULL ? 1 : 0;
1988 if (options->clear_forwardings == 1)
1989 clear_forwardings(options);
1991 if (options->xauth_location == NULL)
1992 options->xauth_location = _PATH_XAUTH;
1993 if (options->fwd_opts.gateway_ports == -1)
1994 options->fwd_opts.gateway_ports = 0;
1995 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1996 options->fwd_opts.streamlocal_bind_mask = 0177;
1997 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1998 options->fwd_opts.streamlocal_bind_unlink = 0;
1999 if (options->pubkey_authentication == -1)
2000 options->pubkey_authentication = 1;
2001 if (options->challenge_response_authentication == -1)
2002 options->challenge_response_authentication = 1;
2003 if (options->gss_authentication == -1)
2004 options->gss_authentication = 0;
2005 if (options->gss_deleg_creds == -1)
2006 options->gss_deleg_creds = 0;
2007 if (options->password_authentication == -1)
2008 options->password_authentication = 1;
2009 if (options->kbd_interactive_authentication == -1)
2010 options->kbd_interactive_authentication = 1;
2011 if (options->hostbased_authentication == -1)
2012 options->hostbased_authentication = 0;
2013 if (options->batch_mode == -1)
2014 options->batch_mode = 0;
2015 if (options->check_host_ip == -1)
2016 options->check_host_ip = 0;
2017 if (options->strict_host_key_checking == -1)
2018 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2019 if (options->compression == -1)
2020 options->compression = 0;
2021 if (options->tcp_keep_alive == -1)
2022 options->tcp_keep_alive = 1;
2023 if (options->port == -1)
2024 options->port = 0; /* Filled in ssh_connect. */
2025 if (options->address_family == -1)
2026 options->address_family = AF_UNSPEC;
2027 if (options->connection_attempts == -1)
2028 options->connection_attempts = 1;
2029 if (options->number_of_password_prompts == -1)
2030 options->number_of_password_prompts = 3;
2031 /* options->hostkeyalgorithms, default set in myproposals.h */
2032 if (options->add_keys_to_agent == -1)
2033 options->add_keys_to_agent = 0;
2034 if (options->num_identity_files == 0) {
2035 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2036 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2037 #ifdef OPENSSL_HAS_ECC
2038 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2040 add_identity_file(options, "~/",
2041 _PATH_SSH_CLIENT_ID_ED25519, 0);
2042 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2044 if (options->escape_char == -1)
2045 options->escape_char = '~';
2046 if (options->num_system_hostfiles == 0) {
2047 options->system_hostfiles[options->num_system_hostfiles++] =
2048 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2049 options->system_hostfiles[options->num_system_hostfiles++] =
2050 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2052 if (options->num_user_hostfiles == 0) {
2053 options->user_hostfiles[options->num_user_hostfiles++] =
2054 xstrdup(_PATH_SSH_USER_HOSTFILE);
2055 options->user_hostfiles[options->num_user_hostfiles++] =
2056 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2058 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2059 options->log_level = SYSLOG_LEVEL_INFO;
2060 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2061 options->log_facility = SYSLOG_FACILITY_USER;
2062 if (options->no_host_authentication_for_localhost == - 1)
2063 options->no_host_authentication_for_localhost = 0;
2064 if (options->identities_only == -1)
2065 options->identities_only = 0;
2066 if (options->enable_ssh_keysign == -1)
2067 options->enable_ssh_keysign = 0;
2068 if (options->rekey_limit == -1)
2069 options->rekey_limit = 0;
2070 if (options->rekey_interval == -1)
2071 options->rekey_interval = 0;
2073 if (options->verify_host_key_dns == -1)
2074 /* automatically trust a verified SSHFP record */
2075 options->verify_host_key_dns = 1;
2077 if (options->verify_host_key_dns == -1)
2078 options->verify_host_key_dns = 0;
2080 if (options->server_alive_interval == -1)
2081 options->server_alive_interval = 0;
2082 if (options->server_alive_count_max == -1)
2083 options->server_alive_count_max = 3;
2084 if (options->control_master == -1)
2085 options->control_master = 0;
2086 if (options->control_persist == -1) {
2087 options->control_persist = 0;
2088 options->control_persist_timeout = 0;
2090 if (options->hash_known_hosts == -1)
2091 options->hash_known_hosts = 0;
2092 if (options->tun_open == -1)
2093 options->tun_open = SSH_TUNMODE_NO;
2094 if (options->tun_local == -1)
2095 options->tun_local = SSH_TUNID_ANY;
2096 if (options->tun_remote == -1)
2097 options->tun_remote = SSH_TUNID_ANY;
2098 if (options->permit_local_command == -1)
2099 options->permit_local_command = 0;
2100 if (options->visual_host_key == -1)
2101 options->visual_host_key = 0;
2102 if (options->ip_qos_interactive == -1)
2103 #ifdef VMWARE_GUEST_WORKAROUND
2105 options->ip_qos_interactive = IPTOS_LOWDELAY;
2108 options->ip_qos_interactive = IPTOS_DSCP_AF21;
2109 if (options->ip_qos_bulk == -1)
2110 #ifdef VMWARE_GUEST_WORKAROUND
2112 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2115 options->ip_qos_bulk = IPTOS_DSCP_CS1;
2116 if (options->request_tty == -1)
2117 options->request_tty = REQUEST_TTY_AUTO;
2118 if (options->proxy_use_fdpass == -1)
2119 options->proxy_use_fdpass = 0;
2120 if (options->canonicalize_max_dots == -1)
2121 options->canonicalize_max_dots = 1;
2122 if (options->canonicalize_fallback_local == -1)
2123 options->canonicalize_fallback_local = 1;
2124 if (options->canonicalize_hostname == -1)
2125 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2126 if (options->fingerprint_hash == -1)
2127 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2128 if (options->update_hostkeys == -1)
2129 options->update_hostkeys = 0;
2131 /* Expand KEX name lists */
2132 all_cipher = cipher_alg_list(',', 0);
2133 all_mac = mac_alg_list(',');
2134 all_kex = kex_alg_list(',');
2135 all_key = sshkey_alg_list(0, 0, 1, ',');
2136 #define ASSEMBLE(what, defaults, all) \
2138 if ((r = kex_assemble_names(&options->what, \
2139 defaults, all)) != 0) \
2140 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2142 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
2143 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
2144 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
2145 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
2146 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2153 #define CLEAR_ON_NONE(v) \
2155 if (option_clear_or_none(v)) { \
2160 CLEAR_ON_NONE(options->local_command);
2161 CLEAR_ON_NONE(options->remote_command);
2162 CLEAR_ON_NONE(options->proxy_command);
2163 CLEAR_ON_NONE(options->control_path);
2164 CLEAR_ON_NONE(options->revoked_host_keys);
2165 if (options->jump_host != NULL &&
2166 strcmp(options->jump_host, "none") == 0 &&
2167 options->jump_port == 0 && options->jump_user == NULL) {
2168 free(options->jump_host);
2169 options->jump_host = NULL;
2171 /* options->identity_agent distinguishes NULL from 'none' */
2172 /* options->user will be set in the main program if appropriate */
2173 /* options->hostname will be set in the main program if appropriate */
2174 /* options->host_key_alias should not be set by default */
2175 /* options->preferred_authentications will be set in ssh */
2176 if (options->version_addendum == NULL)
2177 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2187 * parses the next field in a port forwarding specification.
2188 * sets fwd to the parsed field and advances p past the colon
2189 * or sets it to NULL at end of string.
2190 * returns 0 on success, else non-zero.
2193 parse_fwd_field(char **p, struct fwdarg *fwd)
2200 return -1; /* end of string */
2204 * A field escaped with square brackets is used literally.
2205 * XXX - allow ']' to be escaped via backslash?
2208 /* find matching ']' */
2209 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2213 /* no matching ']' or not at end of field. */
2214 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2216 /* NUL terminate the field and advance p past the colon */
2221 fwd->ispath = ispath;
2226 for (cp = *p; *cp != '\0'; cp++) {
2229 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2243 fwd->ispath = ispath;
2250 * parses a string containing a port forwarding specification of the form:
2252 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2253 * listenpath:connectpath
2255 * [listenhost:]listenport
2256 * returns number of arguments parsed or zero on error
2259 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2261 struct fwdarg fwdargs[4];
2265 memset(fwd, 0, sizeof(*fwd));
2266 memset(fwdargs, 0, sizeof(fwdargs));
2268 cp = p = xstrdup(fwdspec);
2270 /* skip leading spaces */
2271 while (isspace((u_char)*cp))
2274 for (i = 0; i < 4; ++i) {
2275 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2279 /* Check for trailing garbage */
2280 if (cp != NULL && *cp != '\0') {
2281 i = 0; /* failure */
2286 if (fwdargs[0].ispath) {
2287 fwd->listen_path = xstrdup(fwdargs[0].arg);
2288 fwd->listen_port = PORT_STREAMLOCAL;
2290 fwd->listen_host = NULL;
2291 fwd->listen_port = a2port(fwdargs[0].arg);
2293 fwd->connect_host = xstrdup("socks");
2297 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2298 fwd->listen_path = xstrdup(fwdargs[0].arg);
2299 fwd->listen_port = PORT_STREAMLOCAL;
2300 fwd->connect_path = xstrdup(fwdargs[1].arg);
2301 fwd->connect_port = PORT_STREAMLOCAL;
2302 } else if (fwdargs[1].ispath) {
2303 fwd->listen_host = NULL;
2304 fwd->listen_port = a2port(fwdargs[0].arg);
2305 fwd->connect_path = xstrdup(fwdargs[1].arg);
2306 fwd->connect_port = PORT_STREAMLOCAL;
2308 fwd->listen_host = xstrdup(fwdargs[0].arg);
2309 fwd->listen_port = a2port(fwdargs[1].arg);
2310 fwd->connect_host = xstrdup("socks");
2315 if (fwdargs[0].ispath) {
2316 fwd->listen_path = xstrdup(fwdargs[0].arg);
2317 fwd->listen_port = PORT_STREAMLOCAL;
2318 fwd->connect_host = xstrdup(fwdargs[1].arg);
2319 fwd->connect_port = a2port(fwdargs[2].arg);
2320 } else if (fwdargs[2].ispath) {
2321 fwd->listen_host = xstrdup(fwdargs[0].arg);
2322 fwd->listen_port = a2port(fwdargs[1].arg);
2323 fwd->connect_path = xstrdup(fwdargs[2].arg);
2324 fwd->connect_port = PORT_STREAMLOCAL;
2326 fwd->listen_host = NULL;
2327 fwd->listen_port = a2port(fwdargs[0].arg);
2328 fwd->connect_host = xstrdup(fwdargs[1].arg);
2329 fwd->connect_port = a2port(fwdargs[2].arg);
2334 fwd->listen_host = xstrdup(fwdargs[0].arg);
2335 fwd->listen_port = a2port(fwdargs[1].arg);
2336 fwd->connect_host = xstrdup(fwdargs[2].arg);
2337 fwd->connect_port = a2port(fwdargs[3].arg);
2340 i = 0; /* failure */
2346 if (!(i == 1 || i == 2))
2349 if (!(i == 3 || i == 4)) {
2350 if (fwd->connect_path == NULL &&
2351 fwd->listen_path == NULL)
2354 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2358 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2359 (!remotefwd && fwd->listen_port == 0))
2361 if (fwd->connect_host != NULL &&
2362 strlen(fwd->connect_host) >= NI_MAXHOST)
2364 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2365 if (fwd->connect_path != NULL &&
2366 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2368 if (fwd->listen_host != NULL &&
2369 strlen(fwd->listen_host) >= NI_MAXHOST)
2371 if (fwd->listen_path != NULL &&
2372 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2378 free(fwd->connect_host);
2379 fwd->connect_host = NULL;
2380 free(fwd->connect_path);
2381 fwd->connect_path = NULL;
2382 free(fwd->listen_host);
2383 fwd->listen_host = NULL;
2384 free(fwd->listen_path);
2385 fwd->listen_path = NULL;
2390 parse_jump(const char *s, Options *o, int active)
2392 char *orig, *sdup, *cp;
2393 char *host = NULL, *user = NULL;
2394 int ret = -1, port = -1, first;
2396 active &= o->proxy_command == NULL && o->jump_host == NULL;
2398 orig = sdup = xstrdup(s);
2401 if (strcasecmp(s, "none") == 0)
2403 if ((cp = strrchr(sdup, ',')) == NULL)
2404 cp = sdup; /* last */
2409 /* First argument and configuration is active */
2410 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2411 parse_user_host_port(cp, &user, &host, &port) != 0)
2414 /* Subsequent argument or inactive configuration */
2415 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2416 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2419 first = 0; /* only check syntax for subsequent hosts */
2420 } while (cp != sdup);
2423 if (strcasecmp(s, "none") == 0) {
2424 o->jump_host = xstrdup("none");
2427 o->jump_user = user;
2428 o->jump_host = host;
2429 o->jump_port = port;
2430 o->proxy_command = xstrdup("none");
2432 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2433 o->jump_extra = xstrdup(s);
2434 o->jump_extra[cp - s] = '\0';
2447 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2452 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2453 if (r == 0 && path != NULL)
2454 r = -1; /* path not allowed */
2458 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2460 fmt_multistate_int(int val, const struct multistate *m)
2464 for (i = 0; m[i].key != NULL; i++) {
2465 if (m[i].value == val)
2472 fmt_intarg(OpCodes code, int val)
2477 case oAddressFamily:
2478 return fmt_multistate_int(val, multistate_addressfamily);
2479 case oVerifyHostKeyDNS:
2480 case oUpdateHostkeys:
2481 return fmt_multistate_int(val, multistate_yesnoask);
2482 case oStrictHostKeyChecking:
2483 return fmt_multistate_int(val, multistate_strict_hostkey);
2484 case oControlMaster:
2485 return fmt_multistate_int(val, multistate_controlmaster);
2487 return fmt_multistate_int(val, multistate_tunnel);
2489 return fmt_multistate_int(val, multistate_requesttty);
2490 case oCanonicalizeHostname:
2491 return fmt_multistate_int(val, multistate_canonicalizehostname);
2492 case oAddKeysToAgent:
2493 return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2494 case oFingerprintHash:
2495 return ssh_digest_alg_name(val);
2509 lookup_opcode_name(OpCodes code)
2513 for (i = 0; keywords[i].name != NULL; i++)
2514 if (keywords[i].opcode == code)
2515 return(keywords[i].name);
2520 dump_cfg_int(OpCodes code, int val)
2522 printf("%s %d\n", lookup_opcode_name(code), val);
2526 dump_cfg_fmtint(OpCodes code, int val)
2528 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2532 dump_cfg_string(OpCodes code, const char *val)
2536 printf("%s %s\n", lookup_opcode_name(code), val);
2540 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2544 for (i = 0; i < count; i++)
2545 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2549 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2553 printf("%s", lookup_opcode_name(code));
2554 for (i = 0; i < count; i++)
2555 printf(" %s", vals[i]);
2560 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2562 const struct Forward *fwd;
2565 /* oDynamicForward */
2566 for (i = 0; i < count; i++) {
2568 if (code == oDynamicForward && fwd->connect_host != NULL &&
2569 strcmp(fwd->connect_host, "socks") != 0)
2571 if (code == oLocalForward && fwd->connect_host != NULL &&
2572 strcmp(fwd->connect_host, "socks") == 0)
2574 printf("%s", lookup_opcode_name(code));
2575 if (fwd->listen_port == PORT_STREAMLOCAL)
2576 printf(" %s", fwd->listen_path);
2577 else if (fwd->listen_host == NULL)
2578 printf(" %d", fwd->listen_port);
2581 fwd->listen_host, fwd->listen_port);
2583 if (code != oDynamicForward) {
2584 if (fwd->connect_port == PORT_STREAMLOCAL)
2585 printf(" %s", fwd->connect_path);
2586 else if (fwd->connect_host == NULL)
2587 printf(" %d", fwd->connect_port);
2590 fwd->connect_host, fwd->connect_port);
2598 dump_client_config(Options *o, const char *host)
2601 char buf[8], *all_key;
2603 /* This is normally prepared in ssh_kex2 */
2604 all_key = sshkey_alg_list(0, 0, 1, ',');
2605 if (kex_assemble_names( &o->hostkeyalgorithms,
2606 KEX_DEFAULT_PK_ALG, all_key) != 0)
2607 fatal("%s: kex_assemble_names failed", __func__);
2610 /* Most interesting options first: user, host, port */
2611 dump_cfg_string(oUser, o->user);
2612 dump_cfg_string(oHostName, host);
2613 dump_cfg_int(oPort, o->port);
2616 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2617 dump_cfg_fmtint(oAddressFamily, o->address_family);
2618 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2619 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2620 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2621 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2622 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2623 dump_cfg_fmtint(oCompression, o->compression);
2624 dump_cfg_fmtint(oControlMaster, o->control_master);
2625 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2626 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2627 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2628 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2629 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2630 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2631 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2632 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2634 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2635 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2637 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2638 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2639 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2640 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2641 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2642 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2643 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2644 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2645 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2646 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2647 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2648 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2649 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2650 dump_cfg_fmtint(oTunnel, o->tun_open);
2651 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2652 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2653 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2655 /* Integer options */
2656 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2657 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2658 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2659 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2660 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2661 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2663 /* String options */
2664 dump_cfg_string(oBindAddress, o->bind_address);
2665 dump_cfg_string(oBindInterface, o->bind_interface);
2666 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2667 dump_cfg_string(oControlPath, o->control_path);
2668 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2669 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2670 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2671 dump_cfg_string(oIdentityAgent, o->identity_agent);
2672 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2673 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2674 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2675 dump_cfg_string(oLocalCommand, o->local_command);
2676 dump_cfg_string(oRemoteCommand, o->remote_command);
2677 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2678 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2679 #ifdef ENABLE_PKCS11
2680 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2682 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2683 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2684 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2685 dump_cfg_string(oXAuthLocation, o->xauth_location);
2688 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2689 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2690 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2692 /* String array options */
2693 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2694 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2695 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2696 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2697 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2698 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2699 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2703 /* oConnectTimeout */
2704 if (o->connection_timeout == -1)
2705 printf("connecttimeout none\n");
2707 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2710 printf("tunneldevice");
2711 if (o->tun_local == SSH_TUNID_ANY)
2714 printf(" %d", o->tun_local);
2715 if (o->tun_remote == SSH_TUNID_ANY)
2718 printf(":%d", o->tun_remote);
2721 /* oCanonicalizePermittedCNAMEs */
2722 if ( o->num_permitted_cnames > 0) {
2723 printf("canonicalizePermittedcnames");
2724 for (i = 0; i < o->num_permitted_cnames; i++) {
2725 printf(" %s:%s", o->permitted_cnames[i].source_list,
2726 o->permitted_cnames[i].target_list);
2731 /* oControlPersist */
2732 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2733 dump_cfg_fmtint(oControlPersist, o->control_persist);
2735 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2738 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2739 printf("escapechar none\n");
2741 vis(buf, o->escape_char, VIS_WHITE, 0);
2742 printf("escapechar %s\n", buf);
2746 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2747 printf("%s\n", iptos2str(o->ip_qos_bulk));
2750 printf("rekeylimit %llu %d\n",
2751 (unsigned long long)o->rekey_limit, o->rekey_interval);
2753 /* oStreamLocalBindMask */
2754 printf("streamlocalbindmask 0%o\n",
2755 o->fwd_opts.streamlocal_bind_mask);
2758 printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2760 /* oProxyCommand / oProxyJump */
2761 if (o->jump_host == NULL)
2762 dump_cfg_string(oProxyCommand, o->proxy_command);
2764 /* Check for numeric addresses */
2765 i = strchr(o->jump_host, ':') != NULL ||
2766 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2767 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2768 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2769 /* optional additional jump spec */
2770 o->jump_extra == NULL ? "" : o->jump_extra,
2771 o->jump_extra == NULL ? "" : ",",
2773 o->jump_user == NULL ? "" : o->jump_user,
2774 o->jump_user == NULL ? "" : "@",
2775 /* opening [ if hostname is numeric */
2777 /* mandatory hostname */
2779 /* closing ] if hostname is numeric */
2781 /* optional port number */
2782 o->jump_port <= 0 ? "" : ":",
2783 o->jump_port <= 0 ? "" : buf);