1 /* $OpenBSD: readconf.c,v 1.300 2018/10/05 14:26:09 naddy 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, oCASignatureAlgorithms, 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 { "casignaturealgorithms", oCASignatureAlgorithms },
276 { "bindaddress", oBindAddress },
277 { "bindinterface", oBindInterface },
278 { "clearallforwardings", oClearAllForwardings },
279 { "enablesshkeysign", oEnableSSHKeysign },
280 { "verifyhostkeydns", oVerifyHostKeyDNS },
281 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
282 { "rekeylimit", oRekeyLimit },
283 { "connecttimeout", oConnectTimeout },
284 { "addressfamily", oAddressFamily },
285 { "serveraliveinterval", oServerAliveInterval },
286 { "serveralivecountmax", oServerAliveCountMax },
287 { "sendenv", oSendEnv },
288 { "setenv", oSetEnv },
289 { "controlpath", oControlPath },
290 { "controlmaster", oControlMaster },
291 { "controlpersist", oControlPersist },
292 { "hashknownhosts", oHashKnownHosts },
293 { "include", oInclude },
294 { "tunnel", oTunnel },
295 { "tunneldevice", oTunnelDevice },
296 { "localcommand", oLocalCommand },
297 { "permitlocalcommand", oPermitLocalCommand },
298 { "remotecommand", oRemoteCommand },
299 { "visualhostkey", oVisualHostKey },
300 { "kexalgorithms", oKexAlgorithms },
302 { "requesttty", oRequestTTY },
303 { "proxyusefdpass", oProxyUseFdpass },
304 { "canonicaldomains", oCanonicalDomains },
305 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
306 { "canonicalizehostname", oCanonicalizeHostname },
307 { "canonicalizemaxdots", oCanonicalizeMaxDots },
308 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
309 { "streamlocalbindmask", oStreamLocalBindMask },
310 { "streamlocalbindunlink", oStreamLocalBindUnlink },
311 { "revokedhostkeys", oRevokedHostKeys },
312 { "fingerprinthash", oFingerprintHash },
313 { "updatehostkeys", oUpdateHostkeys },
314 { "hostbasedkeytypes", oHostbasedKeyTypes },
315 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
316 { "ignoreunknown", oIgnoreUnknown },
317 { "proxyjump", oProxyJump },
319 { "hpndisabled", oDeprecated },
320 { "hpnbuffersize", oDeprecated },
321 { "tcprcvbufpoll", oDeprecated },
322 { "tcprcvbuf", oDeprecated },
323 { "noneenabled", oUnsupported },
324 { "noneswitch", oUnsupported },
325 { "versionaddendum", oVersionAddendum },
331 * Adds a local TCP/IP port forward to options. Never returns if there is an
336 add_local_forward(Options *options, const struct Forward *newfwd)
339 int i, ipport_reserved;
341 /* Don't add duplicates */
342 for (i = 0; i < options->num_local_forwards; i++) {
343 if (forward_equals(newfwd, options->local_forwards + i))
346 options->local_forwards = xreallocarray(options->local_forwards,
347 options->num_local_forwards + 1,
348 sizeof(*options->local_forwards));
349 fwd = &options->local_forwards[options->num_local_forwards++];
351 fwd->listen_host = newfwd->listen_host;
352 fwd->listen_port = newfwd->listen_port;
353 fwd->listen_path = newfwd->listen_path;
354 fwd->connect_host = newfwd->connect_host;
355 fwd->connect_port = newfwd->connect_port;
356 fwd->connect_path = newfwd->connect_path;
360 * Adds a remote TCP/IP port forward to options. Never returns if there is
365 add_remote_forward(Options *options, const struct Forward *newfwd)
370 /* Don't add duplicates */
371 for (i = 0; i < options->num_remote_forwards; i++) {
372 if (forward_equals(newfwd, options->remote_forwards + i))
375 options->remote_forwards = xreallocarray(options->remote_forwards,
376 options->num_remote_forwards + 1,
377 sizeof(*options->remote_forwards));
378 fwd = &options->remote_forwards[options->num_remote_forwards++];
380 fwd->listen_host = newfwd->listen_host;
381 fwd->listen_port = newfwd->listen_port;
382 fwd->listen_path = newfwd->listen_path;
383 fwd->connect_host = newfwd->connect_host;
384 fwd->connect_port = newfwd->connect_port;
385 fwd->connect_path = newfwd->connect_path;
386 fwd->handle = newfwd->handle;
387 fwd->allocated_port = 0;
391 clear_forwardings(Options *options)
395 for (i = 0; i < options->num_local_forwards; i++) {
396 free(options->local_forwards[i].listen_host);
397 free(options->local_forwards[i].listen_path);
398 free(options->local_forwards[i].connect_host);
399 free(options->local_forwards[i].connect_path);
401 if (options->num_local_forwards > 0) {
402 free(options->local_forwards);
403 options->local_forwards = NULL;
405 options->num_local_forwards = 0;
406 for (i = 0; i < options->num_remote_forwards; i++) {
407 free(options->remote_forwards[i].listen_host);
408 free(options->remote_forwards[i].listen_path);
409 free(options->remote_forwards[i].connect_host);
410 free(options->remote_forwards[i].connect_path);
412 if (options->num_remote_forwards > 0) {
413 free(options->remote_forwards);
414 options->remote_forwards = NULL;
416 options->num_remote_forwards = 0;
417 options->tun_open = SSH_TUNMODE_NO;
421 add_certificate_file(Options *options, const char *path, int userprovided)
425 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
426 fatal("Too many certificate files specified (max %d)",
427 SSH_MAX_CERTIFICATE_FILES);
429 /* Avoid registering duplicates */
430 for (i = 0; i < options->num_certificate_files; i++) {
431 if (options->certificate_file_userprovided[i] == userprovided &&
432 strcmp(options->certificate_files[i], path) == 0) {
433 debug2("%s: ignoring duplicate key %s", __func__, path);
438 options->certificate_file_userprovided[options->num_certificate_files] =
440 options->certificate_files[options->num_certificate_files++] =
445 add_identity_file(Options *options, const char *dir, const char *filename,
451 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
452 fatal("Too many identity files specified (max %d)",
453 SSH_MAX_IDENTITY_FILES);
455 if (dir == NULL) /* no dir, filename is absolute */
456 path = xstrdup(filename);
457 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
458 fatal("Identity file path %s too long", path);
460 /* Avoid registering duplicates */
461 for (i = 0; i < options->num_identity_files; i++) {
462 if (options->identity_file_userprovided[i] == userprovided &&
463 strcmp(options->identity_files[i], path) == 0) {
464 debug2("%s: ignoring duplicate key %s", __func__, path);
470 options->identity_file_userprovided[options->num_identity_files] =
472 options->identity_files[options->num_identity_files++] = path;
476 default_ssh_port(void)
482 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
483 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
489 * Execute a command in a shell.
490 * Return its exit status or -1 on abnormal exit.
493 execute_in_shell(const char *cmd)
499 if ((shell = getenv("SHELL")) == NULL)
500 shell = _PATH_BSHELL;
502 /* Need this to redirect subprocess stdin/out */
503 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
504 fatal("open(/dev/null): %s", strerror(errno));
506 debug("Executing command: '%.500s'", cmd);
508 /* Fork and execute the command. */
509 if ((pid = fork()) == 0) {
512 /* Redirect child stdin and stdout. Leave stderr */
513 if (dup2(devnull, STDIN_FILENO) == -1)
514 fatal("dup2: %s", strerror(errno));
515 if (dup2(devnull, STDOUT_FILENO) == -1)
516 fatal("dup2: %s", strerror(errno));
517 if (devnull > STDERR_FILENO)
519 closefrom(STDERR_FILENO + 1);
523 argv[2] = xstrdup(cmd);
526 execv(argv[0], argv);
527 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
528 /* Die with signal to make this error apparent to parent. */
529 signal(SIGTERM, SIG_DFL);
530 kill(getpid(), SIGTERM);
535 fatal("%s: fork: %.100s", __func__, strerror(errno));
539 while (waitpid(pid, &status, 0) == -1) {
540 if (errno != EINTR && errno != EAGAIN)
541 fatal("%s: waitpid: %s", __func__, strerror(errno));
543 if (!WIFEXITED(status)) {
544 error("command '%.100s' exited abnormally", cmd);
547 debug3("command returned status %d", WEXITSTATUS(status));
548 return WEXITSTATUS(status);
552 * Parse and execute a Match directive.
555 match_cfg_line(Options *options, char **condition, struct passwd *pw,
556 const char *host_arg, const char *original_host, int post_canon,
557 const char *filename, int linenum)
559 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
561 int r, port, this_result, result = 1, attributes = 0, negate;
562 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
566 * Configuration is likely to be incomplete at this point so we
567 * must be prepared to use default values.
569 port = options->port <= 0 ? default_ssh_port() : options->port;
570 ruser = options->user == NULL ? pw->pw_name : options->user;
572 host = xstrdup(options->hostname);
573 } else if (options->hostname != NULL) {
574 /* NB. Please keep in sync with ssh.c:main() */
575 host = percent_expand(options->hostname,
576 "h", host_arg, (char *)NULL);
578 host = xstrdup(host_arg);
581 debug2("checking match for '%s' host %s originally %s",
582 cp, host, original_host);
583 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
586 if ((negate = attrib[0] == '!'))
588 /* criteria "all" and "canonical" have no argument */
589 if (strcasecmp(attrib, "all") == 0) {
590 if (attributes > 1 ||
591 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
592 error("%.200s line %d: '%s' cannot be combined "
593 "with other Match attributes",
594 filename, linenum, oattrib);
599 result = negate ? 0 : 1;
603 if (strcasecmp(attrib, "canonical") == 0) {
604 r = !!post_canon; /* force bitmask member to boolean */
605 if (r == (negate ? 1 : 0))
606 this_result = result = 0;
607 debug3("%.200s line %d: %smatched '%s'",
609 this_result ? "" : "not ", oattrib);
612 /* All other criteria require an argument */
613 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
614 error("Missing Match criteria for %s", attrib);
618 if (strcasecmp(attrib, "host") == 0) {
619 criteria = xstrdup(host);
620 r = match_hostname(host, arg) == 1;
621 if (r == (negate ? 1 : 0))
622 this_result = result = 0;
623 } else if (strcasecmp(attrib, "originalhost") == 0) {
624 criteria = xstrdup(original_host);
625 r = match_hostname(original_host, arg) == 1;
626 if (r == (negate ? 1 : 0))
627 this_result = result = 0;
628 } else if (strcasecmp(attrib, "user") == 0) {
629 criteria = xstrdup(ruser);
630 r = match_pattern_list(ruser, arg, 0) == 1;
631 if (r == (negate ? 1 : 0))
632 this_result = result = 0;
633 } else if (strcasecmp(attrib, "localuser") == 0) {
634 criteria = xstrdup(pw->pw_name);
635 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
636 if (r == (negate ? 1 : 0))
637 this_result = result = 0;
638 } else if (strcasecmp(attrib, "exec") == 0) {
639 if (gethostname(thishost, sizeof(thishost)) == -1)
640 fatal("gethostname: %s", strerror(errno));
641 strlcpy(shorthost, thishost, sizeof(shorthost));
642 shorthost[strcspn(thishost, ".")] = '\0';
643 snprintf(portstr, sizeof(portstr), "%d", port);
644 snprintf(uidstr, sizeof(uidstr), "%llu",
645 (unsigned long long)pw->pw_uid);
647 cmd = percent_expand(arg,
659 /* skip execution if prior predicate failed */
660 debug3("%.200s line %d: skipped exec "
661 "\"%.100s\"", filename, linenum, cmd);
665 r = execute_in_shell(cmd);
667 fatal("%.200s line %d: match exec "
668 "'%.100s' error", filename,
671 criteria = xstrdup(cmd);
673 /* Force exit status to boolean */
675 if (r == (negate ? 1 : 0))
676 this_result = result = 0;
678 error("Unsupported Match attribute %s", attrib);
682 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
683 filename, linenum, this_result ? "": "not ",
687 if (attributes == 0) {
688 error("One or more attributes required for Match");
694 debug2("match %sfound", result ? "" : "not ");
700 /* Remove environment variable by pattern */
702 rm_env(Options *options, const char *arg, const char *filename, int linenum)
707 /* Remove an environment variable */
708 for (i = 0; i < options->num_send_env; ) {
709 cp = xstrdup(options->send_env[i]);
710 if (!match_pattern(cp, arg + 1)) {
715 debug3("%s line %d: removing environment %s",
716 filename, linenum, cp);
718 free(options->send_env[i]);
719 options->send_env[i] = NULL;
720 for (j = i; j < options->num_send_env - 1; j++) {
721 options->send_env[j] = options->send_env[j + 1];
722 options->send_env[j + 1] = NULL;
724 options->num_send_env--;
725 /* NB. don't increment i */
730 * Returns the number of the token pointed to by cp or oBadOption.
733 parse_token(const char *cp, const char *filename, int linenum,
734 const char *ignored_unknown)
738 for (i = 0; keywords[i].name; i++)
739 if (strcmp(cp, keywords[i].name) == 0)
740 return keywords[i].opcode;
741 if (ignored_unknown != NULL &&
742 match_pattern_list(cp, ignored_unknown, 1) == 1)
743 return oIgnoredUnknownOption;
744 error("%s: line %d: Bad configuration option: %s",
745 filename, linenum, cp);
749 /* Multistate option parsing */
754 static const struct multistate multistate_flag[] = {
761 static const struct multistate multistate_yesnoask[] = {
769 static const struct multistate multistate_strict_hostkey[] = {
770 { "true", SSH_STRICT_HOSTKEY_YES },
771 { "false", SSH_STRICT_HOSTKEY_OFF },
772 { "yes", SSH_STRICT_HOSTKEY_YES },
773 { "no", SSH_STRICT_HOSTKEY_OFF },
774 { "ask", SSH_STRICT_HOSTKEY_ASK },
775 { "off", SSH_STRICT_HOSTKEY_OFF },
776 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
779 static const struct multistate multistate_yesnoaskconfirm[] = {
788 static const struct multistate multistate_addressfamily[] = {
790 { "inet6", AF_INET6 },
791 { "any", AF_UNSPEC },
794 static const struct multistate multistate_controlmaster[] = {
795 { "true", SSHCTL_MASTER_YES },
796 { "yes", SSHCTL_MASTER_YES },
797 { "false", SSHCTL_MASTER_NO },
798 { "no", SSHCTL_MASTER_NO },
799 { "auto", SSHCTL_MASTER_AUTO },
800 { "ask", SSHCTL_MASTER_ASK },
801 { "autoask", SSHCTL_MASTER_AUTO_ASK },
804 static const struct multistate multistate_tunnel[] = {
805 { "ethernet", SSH_TUNMODE_ETHERNET },
806 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
807 { "true", SSH_TUNMODE_DEFAULT },
808 { "yes", SSH_TUNMODE_DEFAULT },
809 { "false", SSH_TUNMODE_NO },
810 { "no", SSH_TUNMODE_NO },
813 static const struct multistate multistate_requesttty[] = {
814 { "true", REQUEST_TTY_YES },
815 { "yes", REQUEST_TTY_YES },
816 { "false", REQUEST_TTY_NO },
817 { "no", REQUEST_TTY_NO },
818 { "force", REQUEST_TTY_FORCE },
819 { "auto", REQUEST_TTY_AUTO },
822 static const struct multistate multistate_canonicalizehostname[] = {
823 { "true", SSH_CANONICALISE_YES },
824 { "false", SSH_CANONICALISE_NO },
825 { "yes", SSH_CANONICALISE_YES },
826 { "no", SSH_CANONICALISE_NO },
827 { "always", SSH_CANONICALISE_ALWAYS },
832 * Processes a single option line as used in the configuration files. This
833 * only sets those values that have not already been set.
836 process_config_line(Options *options, struct passwd *pw, const char *host,
837 const char *original_host, char *line, const char *filename,
838 int linenum, int *activep, int flags)
840 return process_config_line_depth(options, pw, host, original_host,
841 line, filename, linenum, activep, flags, 0);
844 #define WHITESPACE " \t\r\n"
846 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
847 const char *original_host, char *line, const char *filename,
848 int linenum, int *activep, int flags, int depth)
850 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
851 char **cpptr, fwdarg[256];
852 u_int i, *uintptr, max_entries = 0;
853 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
854 int remotefwd, dynamicfwd;
855 LogLevel *log_level_ptr;
856 SyslogFacility *log_facility_ptr;
860 const struct multistate *multistate_ptr;
861 struct allowed_cname *cname;
865 if (activep == NULL) { /* We are processing a command line directive */
870 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
871 if ((len = strlen(line)) == 0)
873 for (len--; len > 0; len--) {
874 if (strchr(WHITESPACE "\f", line[len]) == NULL)
880 /* Get the keyword. (Each line is supposed to begin with a keyword). */
881 if ((keyword = strdelim(&s)) == NULL)
883 /* Ignore leading whitespace. */
884 if (*keyword == '\0')
885 keyword = strdelim(&s);
886 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
888 /* Match lowercase keyword */
891 opcode = parse_token(keyword, filename, linenum,
892 options->ignored_unknown);
896 /* don't panic, but count bad options */
900 case oIgnoredUnknownOption:
901 debug("%s line %d: Ignored unknown option \"%s\"",
902 filename, linenum, keyword);
904 case oConnectTimeout:
905 intptr = &options->connection_timeout;
908 if (!arg || *arg == '\0')
909 fatal("%s line %d: missing time value.",
911 if (strcmp(arg, "none") == 0)
913 else if ((value = convtime(arg)) == -1)
914 fatal("%s line %d: invalid time value.",
916 if (*activep && *intptr == -1)
921 intptr = &options->forward_agent;
923 multistate_ptr = multistate_flag;
926 if (!arg || *arg == '\0')
927 fatal("%s line %d: missing argument.",
930 for (i = 0; multistate_ptr[i].key != NULL; i++) {
931 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
932 value = multistate_ptr[i].value;
937 fatal("%s line %d: unsupported option \"%s\".",
938 filename, linenum, arg);
939 if (*activep && *intptr == -1)
944 intptr = &options->forward_x11;
947 case oForwardX11Trusted:
948 intptr = &options->forward_x11_trusted;
951 case oForwardX11Timeout:
952 intptr = &options->forward_x11_timeout;
956 intptr = &options->fwd_opts.gateway_ports;
959 case oExitOnForwardFailure:
960 intptr = &options->exit_on_forward_failure;
963 case oPasswordAuthentication:
964 intptr = &options->password_authentication;
967 case oKbdInteractiveAuthentication:
968 intptr = &options->kbd_interactive_authentication;
971 case oKbdInteractiveDevices:
972 charptr = &options->kbd_interactive_devices;
975 case oPubkeyAuthentication:
976 intptr = &options->pubkey_authentication;
979 case oHostbasedAuthentication:
980 intptr = &options->hostbased_authentication;
983 case oChallengeResponseAuthentication:
984 intptr = &options->challenge_response_authentication;
987 case oGssAuthentication:
988 intptr = &options->gss_authentication;
991 case oGssDelegateCreds:
992 intptr = &options->gss_deleg_creds;
996 intptr = &options->batch_mode;
1000 intptr = &options->check_host_ip;
1003 case oVerifyHostKeyDNS:
1004 intptr = &options->verify_host_key_dns;
1005 multistate_ptr = multistate_yesnoask;
1006 goto parse_multistate;
1008 case oStrictHostKeyChecking:
1009 intptr = &options->strict_host_key_checking;
1010 multistate_ptr = multistate_strict_hostkey;
1011 goto parse_multistate;
1014 intptr = &options->compression;
1018 intptr = &options->tcp_keep_alive;
1021 case oNoHostAuthenticationForLocalhost:
1022 intptr = &options->no_host_authentication_for_localhost;
1025 case oNumberOfPasswordPrompts:
1026 intptr = &options->number_of_password_prompts;
1031 if (!arg || *arg == '\0')
1032 fatal("%.200s line %d: Missing argument.", filename,
1034 if (strcmp(arg, "default") == 0) {
1037 if (scan_scaled(arg, &val64) == -1)
1038 fatal("%.200s line %d: Bad number '%s': %s",
1039 filename, linenum, arg, strerror(errno));
1040 if (val64 != 0 && val64 < 16)
1041 fatal("%.200s line %d: RekeyLimit too small",
1044 if (*activep && options->rekey_limit == -1)
1045 options->rekey_limit = val64;
1046 if (s != NULL) { /* optional rekey interval present */
1047 if (strcmp(s, "none") == 0) {
1048 (void)strdelim(&s); /* discard */
1051 intptr = &options->rekey_interval;
1058 if (!arg || *arg == '\0')
1059 fatal("%.200s line %d: Missing argument.", filename, linenum);
1061 intptr = &options->num_identity_files;
1062 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1063 fatal("%.200s line %d: Too many identity files specified (max %d).",
1064 filename, linenum, SSH_MAX_IDENTITY_FILES);
1065 add_identity_file(options, NULL,
1066 arg, flags & SSHCONF_USERCONF);
1070 case oCertificateFile:
1072 if (!arg || *arg == '\0')
1073 fatal("%.200s line %d: Missing argument.",
1076 intptr = &options->num_certificate_files;
1077 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1078 fatal("%.200s line %d: Too many certificate "
1079 "files specified (max %d).",
1081 SSH_MAX_CERTIFICATE_FILES);
1083 add_certificate_file(options, arg,
1084 flags & SSHCONF_USERCONF);
1088 case oXAuthLocation:
1089 charptr=&options->xauth_location;
1093 charptr = &options->user;
1096 if (!arg || *arg == '\0')
1097 fatal("%.200s line %d: Missing argument.",
1099 if (*activep && *charptr == NULL)
1100 *charptr = xstrdup(arg);
1103 case oGlobalKnownHostsFile:
1104 cpptr = (char **)&options->system_hostfiles;
1105 uintptr = &options->num_system_hostfiles;
1106 max_entries = SSH_MAX_HOSTS_FILES;
1108 if (*activep && *uintptr == 0) {
1109 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1110 if ((*uintptr) >= max_entries)
1111 fatal("%s line %d: "
1112 "too many authorized keys files.",
1114 cpptr[(*uintptr)++] = xstrdup(arg);
1119 case oUserKnownHostsFile:
1120 cpptr = (char **)&options->user_hostfiles;
1121 uintptr = &options->num_user_hostfiles;
1122 max_entries = SSH_MAX_HOSTS_FILES;
1123 goto parse_char_array;
1126 charptr = &options->hostname;
1130 charptr = &options->host_key_alias;
1133 case oPreferredAuthentications:
1134 charptr = &options->preferred_authentications;
1138 charptr = &options->bind_address;
1141 case oBindInterface:
1142 charptr = &options->bind_interface;
1145 case oPKCS11Provider:
1146 charptr = &options->pkcs11_provider;
1150 charptr = &options->proxy_command;
1151 /* Ignore ProxyCommand if ProxyJump already specified */
1152 if (options->jump_host != NULL)
1153 charptr = &options->jump_host; /* Skip below */
1156 fatal("%.200s line %d: Missing argument.", filename, linenum);
1157 len = strspn(s, WHITESPACE "=");
1158 if (*activep && *charptr == NULL)
1159 *charptr = xstrdup(s + len);
1164 fatal("%.200s line %d: Missing argument.",
1167 len = strspn(s, WHITESPACE "=");
1168 if (parse_jump(s + len, options, *activep) == -1) {
1169 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1170 filename, linenum, s + len);
1176 if (!arg || *arg == '\0')
1177 fatal("%.200s line %d: Missing argument.",
1179 value = a2port(arg);
1181 fatal("%.200s line %d: Bad port '%s'.",
1182 filename, linenum, arg);
1183 if (*activep && options->port == -1)
1184 options->port = value;
1187 case oConnectionAttempts:
1188 intptr = &options->connection_attempts;
1191 if ((errstr = atoi_err(arg, &value)) != NULL)
1192 fatal("%s line %d: integer value %s.",
1193 filename, linenum, errstr);
1194 if (*activep && *intptr == -1)
1200 if (!arg || *arg == '\0')
1201 fatal("%.200s line %d: Missing argument.", filename, linenum);
1202 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1203 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1204 filename, linenum, arg ? arg : "<NONE>");
1205 if (*activep && options->ciphers == NULL)
1206 options->ciphers = xstrdup(arg);
1211 if (!arg || *arg == '\0')
1212 fatal("%.200s line %d: Missing argument.", filename, linenum);
1213 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1214 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1215 filename, linenum, arg ? arg : "<NONE>");
1216 if (*activep && options->macs == NULL)
1217 options->macs = xstrdup(arg);
1220 case oKexAlgorithms:
1222 if (!arg || *arg == '\0')
1223 fatal("%.200s line %d: Missing argument.",
1226 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1227 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1228 filename, linenum, arg ? arg : "<NONE>");
1229 if (*activep && options->kex_algorithms == NULL)
1230 options->kex_algorithms = xstrdup(arg);
1233 case oHostKeyAlgorithms:
1234 charptr = &options->hostkeyalgorithms;
1237 if (!arg || *arg == '\0')
1238 fatal("%.200s line %d: Missing argument.",
1241 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1242 fatal("%s line %d: Bad key types '%s'.",
1243 filename, linenum, arg ? arg : "<NONE>");
1244 if (*activep && *charptr == NULL)
1245 *charptr = xstrdup(arg);
1248 case oCASignatureAlgorithms:
1249 charptr = &options->ca_sign_algorithms;
1250 goto parse_keytypes;
1253 log_level_ptr = &options->log_level;
1255 value = log_level_number(arg);
1256 if (value == SYSLOG_LEVEL_NOT_SET)
1257 fatal("%.200s line %d: unsupported log level '%s'",
1258 filename, linenum, arg ? arg : "<NONE>");
1259 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1260 *log_level_ptr = (LogLevel) value;
1264 log_facility_ptr = &options->log_facility;
1266 value = log_facility_number(arg);
1267 if (value == SYSLOG_FACILITY_NOT_SET)
1268 fatal("%.200s line %d: unsupported log facility '%s'",
1269 filename, linenum, arg ? arg : "<NONE>");
1270 if (*log_facility_ptr == -1)
1271 *log_facility_ptr = (SyslogFacility) value;
1275 case oRemoteForward:
1276 case oDynamicForward:
1278 if (arg == NULL || *arg == '\0')
1279 fatal("%.200s line %d: Missing port argument.",
1282 remotefwd = (opcode == oRemoteForward);
1283 dynamicfwd = (opcode == oDynamicForward);
1286 arg2 = strdelim(&s);
1287 if (arg2 == NULL || *arg2 == '\0') {
1291 fatal("%.200s line %d: Missing target "
1292 "argument.", filename, linenum);
1294 /* construct a string for parse_forward */
1295 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1300 strlcpy(fwdarg, arg, sizeof(fwdarg));
1302 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1303 fatal("%.200s line %d: Bad forwarding specification.",
1308 add_remote_forward(options, &fwd);
1310 add_local_forward(options, &fwd);
1315 case oClearAllForwardings:
1316 intptr = &options->clear_forwardings;
1321 fatal("Host directive not supported as a command-line "
1325 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1326 if ((flags & SSHCONF_NEVERMATCH) != 0)
1328 negated = *arg == '!';
1331 if (match_pattern(host, arg)) {
1333 debug("%.200s line %d: Skipping Host "
1334 "block because of negated match "
1335 "for %.100s", filename, linenum,
1341 arg2 = arg; /* logged below */
1346 debug("%.200s line %d: Applying options for %.100s",
1347 filename, linenum, arg2);
1348 /* Avoid garbage check below, as strdelim is done. */
1353 fatal("Host directive not supported as a command-line "
1355 value = match_cfg_line(options, &s, pw, host, original_host,
1356 flags & SSHCONF_POSTCANON, filename, linenum);
1358 fatal("%.200s line %d: Bad Match condition", filename,
1360 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1364 intptr = &options->escape_char;
1366 if (!arg || *arg == '\0')
1367 fatal("%.200s line %d: Missing argument.", filename, linenum);
1368 if (strcmp(arg, "none") == 0)
1369 value = SSH_ESCAPECHAR_NONE;
1370 else if (arg[1] == '\0')
1371 value = (u_char) arg[0];
1372 else if (arg[0] == '^' && arg[2] == 0 &&
1373 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1374 value = (u_char) arg[1] & 31;
1376 fatal("%.200s line %d: Bad escape character.",
1379 value = 0; /* Avoid compiler warning. */
1381 if (*activep && *intptr == -1)
1385 case oAddressFamily:
1386 intptr = &options->address_family;
1387 multistate_ptr = multistate_addressfamily;
1388 goto parse_multistate;
1390 case oEnableSSHKeysign:
1391 intptr = &options->enable_ssh_keysign;
1394 case oIdentitiesOnly:
1395 intptr = &options->identities_only;
1398 case oServerAliveInterval:
1399 intptr = &options->server_alive_interval;
1402 case oServerAliveCountMax:
1403 intptr = &options->server_alive_count_max;
1407 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1408 if (strchr(arg, '=') != NULL)
1409 fatal("%s line %d: Invalid environment name.",
1414 /* Removing an env var */
1415 rm_env(options, arg, filename, linenum);
1418 /* Adding an env var */
1419 if (options->num_send_env >= INT_MAX)
1420 fatal("%s line %d: too many send env.",
1422 options->send_env = xrecallocarray(
1423 options->send_env, options->num_send_env,
1424 options->num_send_env + 1,
1425 sizeof(*options->send_env));
1426 options->send_env[options->num_send_env++] =
1433 value = options->num_setenv;
1434 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1435 if (strchr(arg, '=') == NULL)
1436 fatal("%s line %d: Invalid SetEnv.",
1438 if (!*activep || value != 0)
1440 /* Adding a setenv var */
1441 if (options->num_setenv >= INT_MAX)
1442 fatal("%s line %d: too many SetEnv.",
1444 options->setenv = xrecallocarray(
1445 options->setenv, options->num_setenv,
1446 options->num_setenv + 1, sizeof(*options->setenv));
1447 options->setenv[options->num_setenv++] = xstrdup(arg);
1452 charptr = &options->control_path;
1455 case oControlMaster:
1456 intptr = &options->control_master;
1457 multistate_ptr = multistate_controlmaster;
1458 goto parse_multistate;
1460 case oControlPersist:
1461 /* no/false/yes/true, or a time spec */
1462 intptr = &options->control_persist;
1464 if (!arg || *arg == '\0')
1465 fatal("%.200s line %d: Missing ControlPersist"
1466 " argument.", filename, linenum);
1468 value2 = 0; /* timeout */
1469 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1471 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1473 else if ((value2 = convtime(arg)) >= 0)
1476 fatal("%.200s line %d: Bad ControlPersist argument.",
1478 if (*activep && *intptr == -1) {
1480 options->control_persist_timeout = value2;
1484 case oHashKnownHosts:
1485 intptr = &options->hash_known_hosts;
1489 intptr = &options->tun_open;
1490 multistate_ptr = multistate_tunnel;
1491 goto parse_multistate;
1495 if (!arg || *arg == '\0')
1496 fatal("%.200s line %d: Missing argument.", filename, linenum);
1497 value = a2tun(arg, &value2);
1498 if (value == SSH_TUNID_ERR)
1499 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1501 options->tun_local = value;
1502 options->tun_remote = value2;
1507 charptr = &options->local_command;
1510 case oPermitLocalCommand:
1511 intptr = &options->permit_local_command;
1514 case oRemoteCommand:
1515 charptr = &options->remote_command;
1518 case oVisualHostKey:
1519 intptr = &options->visual_host_key;
1524 fatal("Include directive not supported as a "
1525 "command-line option");
1527 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1529 * Ensure all paths are anchored. User configuration
1530 * files may begin with '~/' but system configurations
1531 * must not. If the path is relative, then treat it
1532 * as living in ~/.ssh for user configurations or
1533 * /etc/ssh for system ones.
1535 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1536 fatal("%.200s line %d: bad include path %s.",
1537 filename, linenum, arg);
1538 if (*arg != '/' && *arg != '~') {
1539 xasprintf(&arg2, "%s/%s",
1540 (flags & SSHCONF_USERCONF) ?
1541 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1543 arg2 = xstrdup(arg);
1544 memset(&gl, 0, sizeof(gl));
1545 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1546 if (r == GLOB_NOMATCH) {
1547 debug("%.200s line %d: include %s matched no "
1548 "files",filename, linenum, arg2);
1551 } else if (r != 0 || gl.gl_pathc < 0)
1552 fatal("%.200s line %d: glob failed for %s.",
1553 filename, linenum, arg2);
1556 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1557 debug3("%.200s line %d: Including file %s "
1558 "depth %d%s", filename, linenum,
1559 gl.gl_pathv[i], depth,
1560 oactive ? "" : " (parse only)");
1561 r = read_config_file_depth(gl.gl_pathv[i],
1562 pw, host, original_host, options,
1563 flags | SSHCONF_CHECKPERM |
1564 (oactive ? 0 : SSHCONF_NEVERMATCH),
1565 activep, depth + 1);
1566 if (r != 1 && errno != ENOENT) {
1567 fatal("Can't open user config file "
1568 "%.100s: %.100s", gl.gl_pathv[i],
1572 * don't let Match in includes clobber the
1573 * containing file's Match state.
1587 if ((value = parse_ipqos(arg)) == -1)
1588 fatal("%s line %d: Bad IPQoS value: %s",
1589 filename, linenum, arg);
1593 else if ((value2 = parse_ipqos(arg)) == -1)
1594 fatal("%s line %d: Bad IPQoS value: %s",
1595 filename, linenum, arg);
1597 options->ip_qos_interactive = value;
1598 options->ip_qos_bulk = value2;
1603 intptr = &options->request_tty;
1604 multistate_ptr = multistate_requesttty;
1605 goto parse_multistate;
1607 case oVersionAddendum:
1609 fatal("%.200s line %d: Missing argument.", filename,
1611 len = strspn(s, WHITESPACE);
1612 if (*activep && options->version_addendum == NULL) {
1613 if (strcasecmp(s + len, "none") == 0)
1614 options->version_addendum = xstrdup("");
1615 else if (strchr(s + len, '\r') != NULL)
1616 fatal("%.200s line %d: Invalid argument",
1619 options->version_addendum = xstrdup(s + len);
1623 case oIgnoreUnknown:
1624 charptr = &options->ignored_unknown;
1627 case oProxyUseFdpass:
1628 intptr = &options->proxy_use_fdpass;
1631 case oCanonicalDomains:
1632 value = options->num_canonical_domains != 0;
1633 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1634 if (!valid_domain(arg, 1, &errstr)) {
1635 fatal("%s line %d: %s", filename, linenum,
1638 if (!*activep || value)
1640 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1641 fatal("%s line %d: too many hostname suffixes.",
1643 options->canonical_domains[
1644 options->num_canonical_domains++] = xstrdup(arg);
1648 case oCanonicalizePermittedCNAMEs:
1649 value = options->num_permitted_cnames != 0;
1650 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1651 /* Either '*' for everything or 'list:list' */
1652 if (strcmp(arg, "*") == 0)
1656 if ((arg2 = strchr(arg, ':')) == NULL ||
1658 fatal("%s line %d: "
1659 "Invalid permitted CNAME \"%s\"",
1660 filename, linenum, arg);
1665 if (!*activep || value)
1667 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1668 fatal("%s line %d: too many permitted CNAMEs.",
1670 cname = options->permitted_cnames +
1671 options->num_permitted_cnames++;
1672 cname->source_list = xstrdup(arg);
1673 cname->target_list = xstrdup(arg2);
1677 case oCanonicalizeHostname:
1678 intptr = &options->canonicalize_hostname;
1679 multistate_ptr = multistate_canonicalizehostname;
1680 goto parse_multistate;
1682 case oCanonicalizeMaxDots:
1683 intptr = &options->canonicalize_max_dots;
1686 case oCanonicalizeFallbackLocal:
1687 intptr = &options->canonicalize_fallback_local;
1690 case oStreamLocalBindMask:
1692 if (!arg || *arg == '\0')
1693 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1694 /* Parse mode in octal format */
1695 value = strtol(arg, &endofnumber, 8);
1696 if (arg == endofnumber || value < 0 || value > 0777)
1697 fatal("%.200s line %d: Bad mask.", filename, linenum);
1698 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1701 case oStreamLocalBindUnlink:
1702 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1705 case oRevokedHostKeys:
1706 charptr = &options->revoked_host_keys;
1709 case oFingerprintHash:
1710 intptr = &options->fingerprint_hash;
1712 if (!arg || *arg == '\0')
1713 fatal("%.200s line %d: Missing argument.",
1715 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1716 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1717 filename, linenum, arg);
1718 if (*activep && *intptr == -1)
1722 case oUpdateHostkeys:
1723 intptr = &options->update_hostkeys;
1724 multistate_ptr = multistate_yesnoask;
1725 goto parse_multistate;
1727 case oHostbasedKeyTypes:
1728 charptr = &options->hostbased_key_types;
1729 goto parse_keytypes;
1731 case oPubkeyAcceptedKeyTypes:
1732 charptr = &options->pubkey_key_types;
1733 goto parse_keytypes;
1735 case oAddKeysToAgent:
1736 intptr = &options->add_keys_to_agent;
1737 multistate_ptr = multistate_yesnoaskconfirm;
1738 goto parse_multistate;
1740 case oIdentityAgent:
1741 charptr = &options->identity_agent;
1743 if (!arg || *arg == '\0')
1744 fatal("%.200s line %d: Missing argument.",
1746 /* Extra validation if the string represents an env var. */
1747 if (arg[0] == '$' && !valid_env_name(arg + 1)) {
1748 fatal("%.200s line %d: Invalid environment name %s.",
1749 filename, linenum, arg);
1751 if (*activep && *charptr == NULL)
1752 *charptr = xstrdup(arg);
1756 debug("%s line %d: Deprecated option \"%s\"",
1757 filename, linenum, keyword);
1761 error("%s line %d: Unsupported option \"%s\"",
1762 filename, linenum, keyword);
1766 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1769 /* Check that there is no garbage at end of line. */
1770 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1771 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1772 filename, linenum, arg);
1778 * Reads the config file and modifies the options accordingly. Options
1779 * should already be initialized before this call. This never returns if
1780 * there is an error. If the file does not exist, this returns 0.
1783 read_config_file(const char *filename, struct passwd *pw, const char *host,
1784 const char *original_host, Options *options, int flags)
1788 return read_config_file_depth(filename, pw, host, original_host,
1789 options, flags, &active, 0);
1792 #define READCONF_MAX_DEPTH 16
1794 read_config_file_depth(const char *filename, struct passwd *pw,
1795 const char *host, const char *original_host, Options *options,
1796 int flags, int *activep, int depth)
1800 size_t linesize = 0;
1802 int bad_options = 0;
1804 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1805 fatal("Too many recursive configuration includes");
1807 if ((f = fopen(filename, "r")) == NULL)
1810 if (flags & SSHCONF_CHECKPERM) {
1813 if (fstat(fileno(f), &sb) == -1)
1814 fatal("fstat %s: %s", filename, strerror(errno));
1815 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1816 (sb.st_mode & 022) != 0))
1817 fatal("Bad owner or permissions on %s", filename);
1820 debug("Reading configuration data %.200s", filename);
1823 * Mark that we are now processing the options. This flag is turned
1824 * on/off by Host specifications.
1827 while (getline(&line, &linesize, f) != -1) {
1828 /* Update line number counter. */
1830 if (process_config_line_depth(options, pw, host, original_host,
1831 line, filename, linenum, activep, flags, depth) != 0)
1836 if (bad_options > 0)
1837 fatal("%s: terminating, %d bad configuration options",
1838 filename, bad_options);
1842 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1844 option_clear_or_none(const char *o)
1846 return o == NULL || strcasecmp(o, "none") == 0;
1850 * Initializes options to special values that indicate that they have not yet
1851 * been set. Read_config_file will only set options with this value. Options
1852 * are processed in the following order: command line, user config file,
1853 * system config file. Last, fill_default_options is called.
1857 initialize_options(Options * options)
1859 memset(options, 'X', sizeof(*options));
1860 options->version_addendum = NULL;
1861 options->forward_agent = -1;
1862 options->forward_x11 = -1;
1863 options->forward_x11_trusted = -1;
1864 options->forward_x11_timeout = -1;
1865 options->stdio_forward_host = NULL;
1866 options->stdio_forward_port = 0;
1867 options->clear_forwardings = -1;
1868 options->exit_on_forward_failure = -1;
1869 options->xauth_location = NULL;
1870 options->fwd_opts.gateway_ports = -1;
1871 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1872 options->fwd_opts.streamlocal_bind_unlink = -1;
1873 options->pubkey_authentication = -1;
1874 options->challenge_response_authentication = -1;
1875 options->gss_authentication = -1;
1876 options->gss_deleg_creds = -1;
1877 options->password_authentication = -1;
1878 options->kbd_interactive_authentication = -1;
1879 options->kbd_interactive_devices = NULL;
1880 options->hostbased_authentication = -1;
1881 options->batch_mode = -1;
1882 options->check_host_ip = -1;
1883 options->strict_host_key_checking = -1;
1884 options->compression = -1;
1885 options->tcp_keep_alive = -1;
1887 options->address_family = -1;
1888 options->connection_attempts = -1;
1889 options->connection_timeout = -1;
1890 options->number_of_password_prompts = -1;
1891 options->ciphers = NULL;
1892 options->macs = NULL;
1893 options->kex_algorithms = NULL;
1894 options->hostkeyalgorithms = NULL;
1895 options->ca_sign_algorithms = NULL;
1896 options->num_identity_files = 0;
1897 options->num_certificate_files = 0;
1898 options->hostname = NULL;
1899 options->host_key_alias = NULL;
1900 options->proxy_command = NULL;
1901 options->jump_user = NULL;
1902 options->jump_host = NULL;
1903 options->jump_port = -1;
1904 options->jump_extra = NULL;
1905 options->user = NULL;
1906 options->escape_char = -1;
1907 options->num_system_hostfiles = 0;
1908 options->num_user_hostfiles = 0;
1909 options->local_forwards = NULL;
1910 options->num_local_forwards = 0;
1911 options->remote_forwards = NULL;
1912 options->num_remote_forwards = 0;
1913 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1914 options->log_level = SYSLOG_LEVEL_NOT_SET;
1915 options->preferred_authentications = NULL;
1916 options->bind_address = NULL;
1917 options->bind_interface = NULL;
1918 options->pkcs11_provider = NULL;
1919 options->enable_ssh_keysign = - 1;
1920 options->no_host_authentication_for_localhost = - 1;
1921 options->identities_only = - 1;
1922 options->rekey_limit = - 1;
1923 options->rekey_interval = -1;
1924 options->verify_host_key_dns = -1;
1925 options->server_alive_interval = -1;
1926 options->server_alive_count_max = -1;
1927 options->send_env = NULL;
1928 options->num_send_env = 0;
1929 options->setenv = NULL;
1930 options->num_setenv = 0;
1931 options->control_path = NULL;
1932 options->control_master = -1;
1933 options->control_persist = -1;
1934 options->control_persist_timeout = 0;
1935 options->hash_known_hosts = -1;
1936 options->tun_open = -1;
1937 options->tun_local = -1;
1938 options->tun_remote = -1;
1939 options->local_command = NULL;
1940 options->permit_local_command = -1;
1941 options->remote_command = NULL;
1942 options->add_keys_to_agent = -1;
1943 options->identity_agent = NULL;
1944 options->visual_host_key = -1;
1945 options->ip_qos_interactive = -1;
1946 options->ip_qos_bulk = -1;
1947 options->request_tty = -1;
1948 options->proxy_use_fdpass = -1;
1949 options->ignored_unknown = NULL;
1950 options->num_canonical_domains = 0;
1951 options->num_permitted_cnames = 0;
1952 options->canonicalize_max_dots = -1;
1953 options->canonicalize_fallback_local = -1;
1954 options->canonicalize_hostname = -1;
1955 options->revoked_host_keys = NULL;
1956 options->fingerprint_hash = -1;
1957 options->update_hostkeys = -1;
1958 options->hostbased_key_types = NULL;
1959 options->pubkey_key_types = NULL;
1963 * A petite version of fill_default_options() that just fills the options
1964 * needed for hostname canonicalization to proceed.
1967 fill_default_options_for_canonicalization(Options *options)
1969 if (options->canonicalize_max_dots == -1)
1970 options->canonicalize_max_dots = 1;
1971 if (options->canonicalize_fallback_local == -1)
1972 options->canonicalize_fallback_local = 1;
1973 if (options->canonicalize_hostname == -1)
1974 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1978 * Called after processing other sources of option data, this fills those
1979 * options for which no value has been specified with their default values.
1982 fill_default_options(Options * options)
1984 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
1986 #ifdef VMWARE_GUEST_WORKAROUND
1987 char scval[7]; /* "vmware\0" */
1988 size_t scsiz = sizeof(scval);
1991 if (sysctlbyname("kern.vm_guest", scval, &scsiz, NULL, 0) == 0 &&
1992 strcmp(scval, "vmware") == 0)
1996 if (options->forward_agent == -1)
1997 options->forward_agent = 0;
1998 if (options->forward_x11 == -1)
1999 options->forward_x11 = 0;
2000 if (options->forward_x11_trusted == -1)
2001 options->forward_x11_trusted = 0;
2002 if (options->forward_x11_timeout == -1)
2003 options->forward_x11_timeout = 1200;
2005 * stdio forwarding (-W) changes the default for these but we defer
2006 * setting the values so they can be overridden.
2008 if (options->exit_on_forward_failure == -1)
2009 options->exit_on_forward_failure =
2010 options->stdio_forward_host != NULL ? 1 : 0;
2011 if (options->clear_forwardings == -1)
2012 options->clear_forwardings =
2013 options->stdio_forward_host != NULL ? 1 : 0;
2014 if (options->clear_forwardings == 1)
2015 clear_forwardings(options);
2017 if (options->xauth_location == NULL)
2018 options->xauth_location = _PATH_XAUTH;
2019 if (options->fwd_opts.gateway_ports == -1)
2020 options->fwd_opts.gateway_ports = 0;
2021 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
2022 options->fwd_opts.streamlocal_bind_mask = 0177;
2023 if (options->fwd_opts.streamlocal_bind_unlink == -1)
2024 options->fwd_opts.streamlocal_bind_unlink = 0;
2025 if (options->pubkey_authentication == -1)
2026 options->pubkey_authentication = 1;
2027 if (options->challenge_response_authentication == -1)
2028 options->challenge_response_authentication = 1;
2029 if (options->gss_authentication == -1)
2030 options->gss_authentication = 0;
2031 if (options->gss_deleg_creds == -1)
2032 options->gss_deleg_creds = 0;
2033 if (options->password_authentication == -1)
2034 options->password_authentication = 1;
2035 if (options->kbd_interactive_authentication == -1)
2036 options->kbd_interactive_authentication = 1;
2037 if (options->hostbased_authentication == -1)
2038 options->hostbased_authentication = 0;
2039 if (options->batch_mode == -1)
2040 options->batch_mode = 0;
2041 if (options->check_host_ip == -1)
2042 options->check_host_ip = 0;
2043 if (options->strict_host_key_checking == -1)
2044 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2045 if (options->compression == -1)
2046 options->compression = 0;
2047 if (options->tcp_keep_alive == -1)
2048 options->tcp_keep_alive = 1;
2049 if (options->port == -1)
2050 options->port = 0; /* Filled in ssh_connect. */
2051 if (options->address_family == -1)
2052 options->address_family = AF_UNSPEC;
2053 if (options->connection_attempts == -1)
2054 options->connection_attempts = 1;
2055 if (options->number_of_password_prompts == -1)
2056 options->number_of_password_prompts = 3;
2057 /* options->hostkeyalgorithms, default set in myproposals.h */
2058 if (options->add_keys_to_agent == -1)
2059 options->add_keys_to_agent = 0;
2060 if (options->num_identity_files == 0) {
2061 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2062 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2063 #ifdef OPENSSL_HAS_ECC
2064 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2066 add_identity_file(options, "~/",
2067 _PATH_SSH_CLIENT_ID_ED25519, 0);
2068 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2070 if (options->escape_char == -1)
2071 options->escape_char = '~';
2072 if (options->num_system_hostfiles == 0) {
2073 options->system_hostfiles[options->num_system_hostfiles++] =
2074 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2075 options->system_hostfiles[options->num_system_hostfiles++] =
2076 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2078 if (options->num_user_hostfiles == 0) {
2079 options->user_hostfiles[options->num_user_hostfiles++] =
2080 xstrdup(_PATH_SSH_USER_HOSTFILE);
2081 options->user_hostfiles[options->num_user_hostfiles++] =
2082 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2084 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2085 options->log_level = SYSLOG_LEVEL_INFO;
2086 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2087 options->log_facility = SYSLOG_FACILITY_USER;
2088 if (options->no_host_authentication_for_localhost == - 1)
2089 options->no_host_authentication_for_localhost = 0;
2090 if (options->identities_only == -1)
2091 options->identities_only = 0;
2092 if (options->enable_ssh_keysign == -1)
2093 options->enable_ssh_keysign = 0;
2094 if (options->rekey_limit == -1)
2095 options->rekey_limit = 0;
2096 if (options->rekey_interval == -1)
2097 options->rekey_interval = 0;
2099 if (options->verify_host_key_dns == -1)
2100 /* automatically trust a verified SSHFP record */
2101 options->verify_host_key_dns = 1;
2103 if (options->verify_host_key_dns == -1)
2104 options->verify_host_key_dns = 0;
2106 if (options->server_alive_interval == -1)
2107 options->server_alive_interval = 0;
2108 if (options->server_alive_count_max == -1)
2109 options->server_alive_count_max = 3;
2110 if (options->control_master == -1)
2111 options->control_master = 0;
2112 if (options->control_persist == -1) {
2113 options->control_persist = 0;
2114 options->control_persist_timeout = 0;
2116 if (options->hash_known_hosts == -1)
2117 options->hash_known_hosts = 0;
2118 if (options->tun_open == -1)
2119 options->tun_open = SSH_TUNMODE_NO;
2120 if (options->tun_local == -1)
2121 options->tun_local = SSH_TUNID_ANY;
2122 if (options->tun_remote == -1)
2123 options->tun_remote = SSH_TUNID_ANY;
2124 if (options->permit_local_command == -1)
2125 options->permit_local_command = 0;
2126 if (options->visual_host_key == -1)
2127 options->visual_host_key = 0;
2128 if (options->ip_qos_interactive == -1)
2129 #ifdef VMWARE_GUEST_WORKAROUND
2131 options->ip_qos_interactive = IPTOS_LOWDELAY;
2134 options->ip_qos_interactive = IPTOS_DSCP_AF21;
2135 if (options->ip_qos_bulk == -1)
2136 #ifdef VMWARE_GUEST_WORKAROUND
2138 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2141 options->ip_qos_bulk = IPTOS_DSCP_CS1;
2142 if (options->request_tty == -1)
2143 options->request_tty = REQUEST_TTY_AUTO;
2144 if (options->proxy_use_fdpass == -1)
2145 options->proxy_use_fdpass = 0;
2146 if (options->canonicalize_max_dots == -1)
2147 options->canonicalize_max_dots = 1;
2148 if (options->canonicalize_fallback_local == -1)
2149 options->canonicalize_fallback_local = 1;
2150 if (options->canonicalize_hostname == -1)
2151 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2152 if (options->fingerprint_hash == -1)
2153 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2154 if (options->update_hostkeys == -1)
2155 options->update_hostkeys = 0;
2157 /* Expand KEX name lists */
2158 all_cipher = cipher_alg_list(',', 0);
2159 all_mac = mac_alg_list(',');
2160 all_kex = kex_alg_list(',');
2161 all_key = sshkey_alg_list(0, 0, 1, ',');
2162 all_sig = sshkey_alg_list(0, 1, 1, ',');
2163 #define ASSEMBLE(what, defaults, all) \
2165 if ((r = kex_assemble_names(&options->what, \
2166 defaults, all)) != 0) \
2167 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2169 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
2170 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
2171 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
2172 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
2173 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2174 ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
2182 #define CLEAR_ON_NONE(v) \
2184 if (option_clear_or_none(v)) { \
2189 CLEAR_ON_NONE(options->local_command);
2190 CLEAR_ON_NONE(options->remote_command);
2191 CLEAR_ON_NONE(options->proxy_command);
2192 CLEAR_ON_NONE(options->control_path);
2193 CLEAR_ON_NONE(options->revoked_host_keys);
2194 if (options->jump_host != NULL &&
2195 strcmp(options->jump_host, "none") == 0 &&
2196 options->jump_port == 0 && options->jump_user == NULL) {
2197 free(options->jump_host);
2198 options->jump_host = NULL;
2200 /* options->identity_agent distinguishes NULL from 'none' */
2201 /* options->user will be set in the main program if appropriate */
2202 /* options->hostname will be set in the main program if appropriate */
2203 /* options->host_key_alias should not be set by default */
2204 /* options->preferred_authentications will be set in ssh */
2205 if (options->version_addendum == NULL)
2206 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2216 * parses the next field in a port forwarding specification.
2217 * sets fwd to the parsed field and advances p past the colon
2218 * or sets it to NULL at end of string.
2219 * returns 0 on success, else non-zero.
2222 parse_fwd_field(char **p, struct fwdarg *fwd)
2229 return -1; /* end of string */
2233 * A field escaped with square brackets is used literally.
2234 * XXX - allow ']' to be escaped via backslash?
2237 /* find matching ']' */
2238 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2242 /* no matching ']' or not at end of field. */
2243 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2245 /* NUL terminate the field and advance p past the colon */
2250 fwd->ispath = ispath;
2255 for (cp = *p; *cp != '\0'; cp++) {
2258 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2272 fwd->ispath = ispath;
2279 * parses a string containing a port forwarding specification of the form:
2281 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2282 * listenpath:connectpath
2284 * [listenhost:]listenport
2285 * returns number of arguments parsed or zero on error
2288 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2290 struct fwdarg fwdargs[4];
2294 memset(fwd, 0, sizeof(*fwd));
2295 memset(fwdargs, 0, sizeof(fwdargs));
2297 cp = p = xstrdup(fwdspec);
2299 /* skip leading spaces */
2300 while (isspace((u_char)*cp))
2303 for (i = 0; i < 4; ++i) {
2304 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2308 /* Check for trailing garbage */
2309 if (cp != NULL && *cp != '\0') {
2310 i = 0; /* failure */
2315 if (fwdargs[0].ispath) {
2316 fwd->listen_path = xstrdup(fwdargs[0].arg);
2317 fwd->listen_port = PORT_STREAMLOCAL;
2319 fwd->listen_host = NULL;
2320 fwd->listen_port = a2port(fwdargs[0].arg);
2322 fwd->connect_host = xstrdup("socks");
2326 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2327 fwd->listen_path = xstrdup(fwdargs[0].arg);
2328 fwd->listen_port = PORT_STREAMLOCAL;
2329 fwd->connect_path = xstrdup(fwdargs[1].arg);
2330 fwd->connect_port = PORT_STREAMLOCAL;
2331 } else if (fwdargs[1].ispath) {
2332 fwd->listen_host = NULL;
2333 fwd->listen_port = a2port(fwdargs[0].arg);
2334 fwd->connect_path = xstrdup(fwdargs[1].arg);
2335 fwd->connect_port = PORT_STREAMLOCAL;
2337 fwd->listen_host = xstrdup(fwdargs[0].arg);
2338 fwd->listen_port = a2port(fwdargs[1].arg);
2339 fwd->connect_host = xstrdup("socks");
2344 if (fwdargs[0].ispath) {
2345 fwd->listen_path = xstrdup(fwdargs[0].arg);
2346 fwd->listen_port = PORT_STREAMLOCAL;
2347 fwd->connect_host = xstrdup(fwdargs[1].arg);
2348 fwd->connect_port = a2port(fwdargs[2].arg);
2349 } else if (fwdargs[2].ispath) {
2350 fwd->listen_host = xstrdup(fwdargs[0].arg);
2351 fwd->listen_port = a2port(fwdargs[1].arg);
2352 fwd->connect_path = xstrdup(fwdargs[2].arg);
2353 fwd->connect_port = PORT_STREAMLOCAL;
2355 fwd->listen_host = NULL;
2356 fwd->listen_port = a2port(fwdargs[0].arg);
2357 fwd->connect_host = xstrdup(fwdargs[1].arg);
2358 fwd->connect_port = a2port(fwdargs[2].arg);
2363 fwd->listen_host = xstrdup(fwdargs[0].arg);
2364 fwd->listen_port = a2port(fwdargs[1].arg);
2365 fwd->connect_host = xstrdup(fwdargs[2].arg);
2366 fwd->connect_port = a2port(fwdargs[3].arg);
2369 i = 0; /* failure */
2375 if (!(i == 1 || i == 2))
2378 if (!(i == 3 || i == 4)) {
2379 if (fwd->connect_path == NULL &&
2380 fwd->listen_path == NULL)
2383 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2387 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2388 (!remotefwd && fwd->listen_port == 0))
2390 if (fwd->connect_host != NULL &&
2391 strlen(fwd->connect_host) >= NI_MAXHOST)
2393 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2394 if (fwd->connect_path != NULL &&
2395 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2397 if (fwd->listen_host != NULL &&
2398 strlen(fwd->listen_host) >= NI_MAXHOST)
2400 if (fwd->listen_path != NULL &&
2401 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2407 free(fwd->connect_host);
2408 fwd->connect_host = NULL;
2409 free(fwd->connect_path);
2410 fwd->connect_path = NULL;
2411 free(fwd->listen_host);
2412 fwd->listen_host = NULL;
2413 free(fwd->listen_path);
2414 fwd->listen_path = NULL;
2419 parse_jump(const char *s, Options *o, int active)
2421 char *orig, *sdup, *cp;
2422 char *host = NULL, *user = NULL;
2423 int ret = -1, port = -1, first;
2425 active &= o->proxy_command == NULL && o->jump_host == NULL;
2427 orig = sdup = xstrdup(s);
2430 if (strcasecmp(s, "none") == 0)
2432 if ((cp = strrchr(sdup, ',')) == NULL)
2433 cp = sdup; /* last */
2438 /* First argument and configuration is active */
2439 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2440 parse_user_host_port(cp, &user, &host, &port) != 0)
2443 /* Subsequent argument or inactive configuration */
2444 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2445 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2448 first = 0; /* only check syntax for subsequent hosts */
2449 } while (cp != sdup);
2452 if (strcasecmp(s, "none") == 0) {
2453 o->jump_host = xstrdup("none");
2456 o->jump_user = user;
2457 o->jump_host = host;
2458 o->jump_port = port;
2459 o->proxy_command = xstrdup("none");
2461 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2462 o->jump_extra = xstrdup(s);
2463 o->jump_extra[cp - s] = '\0';
2476 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2481 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2482 if (r == 0 && path != NULL)
2483 r = -1; /* path not allowed */
2487 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2489 fmt_multistate_int(int val, const struct multistate *m)
2493 for (i = 0; m[i].key != NULL; i++) {
2494 if (m[i].value == val)
2501 fmt_intarg(OpCodes code, int val)
2506 case oAddressFamily:
2507 return fmt_multistate_int(val, multistate_addressfamily);
2508 case oVerifyHostKeyDNS:
2509 case oUpdateHostkeys:
2510 return fmt_multistate_int(val, multistate_yesnoask);
2511 case oStrictHostKeyChecking:
2512 return fmt_multistate_int(val, multistate_strict_hostkey);
2513 case oControlMaster:
2514 return fmt_multistate_int(val, multistate_controlmaster);
2516 return fmt_multistate_int(val, multistate_tunnel);
2518 return fmt_multistate_int(val, multistate_requesttty);
2519 case oCanonicalizeHostname:
2520 return fmt_multistate_int(val, multistate_canonicalizehostname);
2521 case oAddKeysToAgent:
2522 return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2523 case oFingerprintHash:
2524 return ssh_digest_alg_name(val);
2538 lookup_opcode_name(OpCodes code)
2542 for (i = 0; keywords[i].name != NULL; i++)
2543 if (keywords[i].opcode == code)
2544 return(keywords[i].name);
2549 dump_cfg_int(OpCodes code, int val)
2551 printf("%s %d\n", lookup_opcode_name(code), val);
2555 dump_cfg_fmtint(OpCodes code, int val)
2557 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2561 dump_cfg_string(OpCodes code, const char *val)
2565 printf("%s %s\n", lookup_opcode_name(code), val);
2569 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2573 for (i = 0; i < count; i++)
2574 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2578 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2582 printf("%s", lookup_opcode_name(code));
2583 for (i = 0; i < count; i++)
2584 printf(" %s", vals[i]);
2589 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2591 const struct Forward *fwd;
2594 /* oDynamicForward */
2595 for (i = 0; i < count; i++) {
2597 if (code == oDynamicForward && fwd->connect_host != NULL &&
2598 strcmp(fwd->connect_host, "socks") != 0)
2600 if (code == oLocalForward && fwd->connect_host != NULL &&
2601 strcmp(fwd->connect_host, "socks") == 0)
2603 printf("%s", lookup_opcode_name(code));
2604 if (fwd->listen_port == PORT_STREAMLOCAL)
2605 printf(" %s", fwd->listen_path);
2606 else if (fwd->listen_host == NULL)
2607 printf(" %d", fwd->listen_port);
2610 fwd->listen_host, fwd->listen_port);
2612 if (code != oDynamicForward) {
2613 if (fwd->connect_port == PORT_STREAMLOCAL)
2614 printf(" %s", fwd->connect_path);
2615 else if (fwd->connect_host == NULL)
2616 printf(" %d", fwd->connect_port);
2619 fwd->connect_host, fwd->connect_port);
2627 dump_client_config(Options *o, const char *host)
2630 char buf[8], *all_key;
2632 /* This is normally prepared in ssh_kex2 */
2633 all_key = sshkey_alg_list(0, 0, 1, ',');
2634 if (kex_assemble_names( &o->hostkeyalgorithms,
2635 KEX_DEFAULT_PK_ALG, all_key) != 0)
2636 fatal("%s: kex_assemble_names failed", __func__);
2639 /* Most interesting options first: user, host, port */
2640 dump_cfg_string(oUser, o->user);
2641 dump_cfg_string(oHostName, host);
2642 dump_cfg_int(oPort, o->port);
2645 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2646 dump_cfg_fmtint(oAddressFamily, o->address_family);
2647 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2648 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2649 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2650 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2651 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2652 dump_cfg_fmtint(oCompression, o->compression);
2653 dump_cfg_fmtint(oControlMaster, o->control_master);
2654 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2655 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2656 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2657 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2658 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2659 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2660 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2661 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2663 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2664 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2666 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2667 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2668 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2669 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2670 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2671 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2672 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2673 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2674 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2675 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2676 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2677 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2678 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2679 dump_cfg_fmtint(oTunnel, o->tun_open);
2680 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2681 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2682 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2684 /* Integer options */
2685 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2686 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2687 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2688 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2689 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2690 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2692 /* String options */
2693 dump_cfg_string(oBindAddress, o->bind_address);
2694 dump_cfg_string(oBindInterface, o->bind_interface);
2695 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2696 dump_cfg_string(oControlPath, o->control_path);
2697 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2698 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2699 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2700 dump_cfg_string(oIdentityAgent, o->identity_agent);
2701 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2702 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2703 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2704 dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms ? o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
2705 dump_cfg_string(oLocalCommand, o->local_command);
2706 dump_cfg_string(oRemoteCommand, o->remote_command);
2707 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2708 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2709 #ifdef ENABLE_PKCS11
2710 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2712 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2713 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2714 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2715 dump_cfg_string(oXAuthLocation, o->xauth_location);
2718 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2719 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2720 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2722 /* String array options */
2723 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2724 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2725 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2726 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2727 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2728 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2729 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2733 /* oConnectTimeout */
2734 if (o->connection_timeout == -1)
2735 printf("connecttimeout none\n");
2737 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2740 printf("tunneldevice");
2741 if (o->tun_local == SSH_TUNID_ANY)
2744 printf(" %d", o->tun_local);
2745 if (o->tun_remote == SSH_TUNID_ANY)
2748 printf(":%d", o->tun_remote);
2751 /* oCanonicalizePermittedCNAMEs */
2752 if ( o->num_permitted_cnames > 0) {
2753 printf("canonicalizePermittedcnames");
2754 for (i = 0; i < o->num_permitted_cnames; i++) {
2755 printf(" %s:%s", o->permitted_cnames[i].source_list,
2756 o->permitted_cnames[i].target_list);
2761 /* oControlPersist */
2762 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2763 dump_cfg_fmtint(oControlPersist, o->control_persist);
2765 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2768 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2769 printf("escapechar none\n");
2771 vis(buf, o->escape_char, VIS_WHITE, 0);
2772 printf("escapechar %s\n", buf);
2776 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2777 printf("%s\n", iptos2str(o->ip_qos_bulk));
2780 printf("rekeylimit %llu %d\n",
2781 (unsigned long long)o->rekey_limit, o->rekey_interval);
2783 /* oStreamLocalBindMask */
2784 printf("streamlocalbindmask 0%o\n",
2785 o->fwd_opts.streamlocal_bind_mask);
2788 printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2790 /* oProxyCommand / oProxyJump */
2791 if (o->jump_host == NULL)
2792 dump_cfg_string(oProxyCommand, o->proxy_command);
2794 /* Check for numeric addresses */
2795 i = strchr(o->jump_host, ':') != NULL ||
2796 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2797 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2798 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2799 /* optional additional jump spec */
2800 o->jump_extra == NULL ? "" : o->jump_extra,
2801 o->jump_extra == NULL ? "" : ",",
2803 o->jump_user == NULL ? "" : o->jump_user,
2804 o->jump_user == NULL ? "" : "@",
2805 /* opening [ if hostname is numeric */
2807 /* mandatory hostname */
2809 /* closing ] if hostname is numeric */
2811 /* optional port number */
2812 o->jump_port <= 0 ? "" : ":",
2813 o->jump_port <= 0 ? "" : buf);