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>
20 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <netinet/in_systm.h>
26 #include <netinet/ip.h>
27 #include <arpa/inet.h>
43 #ifdef USE_SYSTEM_GLOB
46 # include "openbsd-compat/glob.h"
51 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
60 #include "pathnames.h"
69 #include "myproposal.h"
73 /* Format of the configuration file:
75 # Configuration data is parsed as follows:
76 # 1. command line options
77 # 2. user-specific file
79 # Any configuration value is only changed the first time it is set.
80 # Thus, host-specific definitions should be at the beginning of the
81 # configuration file, and defaults at the end.
83 # Host-specific declarations. These may override anything above. A single
84 # host may match multiple declarations; these are processed in the order
85 # that they are given in.
91 HostName another.host.name.real.org
98 RemoteForward 9999 shadows.cs.hut.fi:9999
101 Host fascist.blob.com
104 PasswordAuthentication no
108 ProxyCommand ssh-proxy %h %p
111 PublicKeyAuthentication no
115 PasswordAuthentication no
121 # Defaults for various options
125 PasswordAuthentication yes
126 RSAAuthentication yes
127 RhostsRSAAuthentication yes
128 StrictHostKeyChecking yes
130 IdentityFile ~/.ssh/identity
136 static int read_config_file_depth(const char *filename, struct passwd *pw,
137 const char *host, const char *original_host, Options *options,
138 int flags, int *activep, int depth);
139 static int process_config_line_depth(Options *options, struct passwd *pw,
140 const char *host, const char *original_host, char *line,
141 const char *filename, int linenum, int *activep, int flags, int depth);
143 /* Keyword tokens. */
148 oHost, oMatch, oInclude,
149 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
150 oGatewayPorts, oExitOnForwardFailure,
151 oPasswordAuthentication, oRSAAuthentication,
152 oChallengeResponseAuthentication, oXAuthLocation,
153 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
154 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
155 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
156 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
157 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
158 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
159 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
160 oPubkeyAuthentication,
161 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
162 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
163 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
164 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
165 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
166 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
167 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
168 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
170 oTunnel, oTunnelDevice,
171 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
173 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
174 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
175 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
176 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
177 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
178 oPubkeyAcceptedKeyTypes, oCASignatureAlgorithms, oProxyJump,
179 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
182 /* Textual representations of the tokens. */
188 /* Deprecated options */
189 { "protocol", oIgnore }, /* NB. silently ignored */
190 { "cipher", oDeprecated },
191 { "fallbacktorsh", oDeprecated },
192 { "globalknownhostsfile2", oDeprecated },
193 { "rhostsauthentication", oDeprecated },
194 { "userknownhostsfile2", oDeprecated },
195 { "useroaming", oDeprecated },
196 { "usersh", oDeprecated },
197 { "useprivilegedport", oDeprecated },
199 /* Unsupported options */
200 { "afstokenpassing", oUnsupported },
201 { "kerberosauthentication", oUnsupported },
202 { "kerberostgtpassing", oUnsupported },
204 /* Sometimes-unsupported options */
206 { "gssapiauthentication", oGssAuthentication },
207 { "gssapidelegatecredentials", oGssDelegateCreds },
209 { "gssapiauthentication", oUnsupported },
210 { "gssapidelegatecredentials", oUnsupported },
213 { "smartcarddevice", oPKCS11Provider },
214 { "pkcs11provider", oPKCS11Provider },
216 { "smartcarddevice", oUnsupported },
217 { "pkcs11provider", oUnsupported },
219 { "rsaauthentication", oUnsupported },
220 { "rhostsrsaauthentication", oUnsupported },
221 { "compressionlevel", oUnsupported },
223 { "forwardagent", oForwardAgent },
224 { "forwardx11", oForwardX11 },
225 { "forwardx11trusted", oForwardX11Trusted },
226 { "forwardx11timeout", oForwardX11Timeout },
227 { "exitonforwardfailure", oExitOnForwardFailure },
228 { "xauthlocation", oXAuthLocation },
229 { "gatewayports", oGatewayPorts },
230 { "passwordauthentication", oPasswordAuthentication },
231 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
232 { "kbdinteractivedevices", oKbdInteractiveDevices },
233 { "pubkeyauthentication", oPubkeyAuthentication },
234 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
235 { "hostbasedauthentication", oHostbasedAuthentication },
236 { "challengeresponseauthentication", oChallengeResponseAuthentication },
237 { "skeyauthentication", oUnsupported },
238 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
239 { "identityfile", oIdentityFile },
240 { "identityfile2", oIdentityFile }, /* obsolete */
241 { "identitiesonly", oIdentitiesOnly },
242 { "certificatefile", oCertificateFile },
243 { "addkeystoagent", oAddKeysToAgent },
244 { "identityagent", oIdentityAgent },
245 { "hostname", oHostName },
246 { "hostkeyalias", oHostKeyAlias },
247 { "proxycommand", oProxyCommand },
249 { "ciphers", oCiphers },
251 { "remoteforward", oRemoteForward },
252 { "localforward", oLocalForward },
256 { "escapechar", oEscapeChar },
257 { "globalknownhostsfile", oGlobalKnownHostsFile },
258 { "userknownhostsfile", oUserKnownHostsFile },
259 { "connectionattempts", oConnectionAttempts },
260 { "batchmode", oBatchMode },
261 { "checkhostip", oCheckHostIP },
262 { "stricthostkeychecking", oStrictHostKeyChecking },
263 { "compression", oCompression },
264 { "tcpkeepalive", oTCPKeepAlive },
265 { "keepalive", oTCPKeepAlive }, /* obsolete */
266 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
267 { "syslogfacility", oLogFacility },
268 { "loglevel", oLogLevel },
269 { "dynamicforward", oDynamicForward },
270 { "preferredauthentications", oPreferredAuthentications },
271 { "hostkeyalgorithms", oHostKeyAlgorithms },
272 { "casignaturealgorithms", oCASignatureAlgorithms },
273 { "bindaddress", oBindAddress },
274 { "bindinterface", oBindInterface },
275 { "clearallforwardings", oClearAllForwardings },
276 { "enablesshkeysign", oEnableSSHKeysign },
277 { "verifyhostkeydns", oVerifyHostKeyDNS },
278 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
279 { "rekeylimit", oRekeyLimit },
280 { "connecttimeout", oConnectTimeout },
281 { "addressfamily", oAddressFamily },
282 { "serveraliveinterval", oServerAliveInterval },
283 { "serveralivecountmax", oServerAliveCountMax },
284 { "sendenv", oSendEnv },
285 { "setenv", oSetEnv },
286 { "controlpath", oControlPath },
287 { "controlmaster", oControlMaster },
288 { "controlpersist", oControlPersist },
289 { "hashknownhosts", oHashKnownHosts },
290 { "include", oInclude },
291 { "tunnel", oTunnel },
292 { "tunneldevice", oTunnelDevice },
293 { "localcommand", oLocalCommand },
294 { "permitlocalcommand", oPermitLocalCommand },
295 { "remotecommand", oRemoteCommand },
296 { "visualhostkey", oVisualHostKey },
297 { "kexalgorithms", oKexAlgorithms },
299 { "requesttty", oRequestTTY },
300 { "proxyusefdpass", oProxyUseFdpass },
301 { "canonicaldomains", oCanonicalDomains },
302 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
303 { "canonicalizehostname", oCanonicalizeHostname },
304 { "canonicalizemaxdots", oCanonicalizeMaxDots },
305 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
306 { "streamlocalbindmask", oStreamLocalBindMask },
307 { "streamlocalbindunlink", oStreamLocalBindUnlink },
308 { "revokedhostkeys", oRevokedHostKeys },
309 { "fingerprinthash", oFingerprintHash },
310 { "updatehostkeys", oUpdateHostkeys },
311 { "hostbasedkeytypes", oHostbasedKeyTypes },
312 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
313 { "ignoreunknown", oIgnoreUnknown },
314 { "proxyjump", oProxyJump },
316 { "hpndisabled", oDeprecated },
317 { "hpnbuffersize", oDeprecated },
318 { "tcprcvbufpoll", oDeprecated },
319 { "tcprcvbuf", oDeprecated },
320 { "noneenabled", oUnsupported },
321 { "noneswitch", oUnsupported },
322 { "versionaddendum", oVersionAddendum },
328 * Adds a local TCP/IP port forward to options. Never returns if there is an
333 add_local_forward(Options *options, const struct Forward *newfwd)
338 /* Don't add duplicates */
339 for (i = 0; i < options->num_local_forwards; i++) {
340 if (forward_equals(newfwd, options->local_forwards + i))
343 options->local_forwards = xreallocarray(options->local_forwards,
344 options->num_local_forwards + 1,
345 sizeof(*options->local_forwards));
346 fwd = &options->local_forwards[options->num_local_forwards++];
348 fwd->listen_host = newfwd->listen_host;
349 fwd->listen_port = newfwd->listen_port;
350 fwd->listen_path = newfwd->listen_path;
351 fwd->connect_host = newfwd->connect_host;
352 fwd->connect_port = newfwd->connect_port;
353 fwd->connect_path = newfwd->connect_path;
357 * Adds a remote TCP/IP port forward to options. Never returns if there is
362 add_remote_forward(Options *options, const struct Forward *newfwd)
367 /* Don't add duplicates */
368 for (i = 0; i < options->num_remote_forwards; i++) {
369 if (forward_equals(newfwd, options->remote_forwards + i))
372 options->remote_forwards = xreallocarray(options->remote_forwards,
373 options->num_remote_forwards + 1,
374 sizeof(*options->remote_forwards));
375 fwd = &options->remote_forwards[options->num_remote_forwards++];
377 fwd->listen_host = newfwd->listen_host;
378 fwd->listen_port = newfwd->listen_port;
379 fwd->listen_path = newfwd->listen_path;
380 fwd->connect_host = newfwd->connect_host;
381 fwd->connect_port = newfwd->connect_port;
382 fwd->connect_path = newfwd->connect_path;
383 fwd->handle = newfwd->handle;
384 fwd->allocated_port = 0;
388 clear_forwardings(Options *options)
392 for (i = 0; i < options->num_local_forwards; i++) {
393 free(options->local_forwards[i].listen_host);
394 free(options->local_forwards[i].listen_path);
395 free(options->local_forwards[i].connect_host);
396 free(options->local_forwards[i].connect_path);
398 if (options->num_local_forwards > 0) {
399 free(options->local_forwards);
400 options->local_forwards = NULL;
402 options->num_local_forwards = 0;
403 for (i = 0; i < options->num_remote_forwards; i++) {
404 free(options->remote_forwards[i].listen_host);
405 free(options->remote_forwards[i].listen_path);
406 free(options->remote_forwards[i].connect_host);
407 free(options->remote_forwards[i].connect_path);
409 if (options->num_remote_forwards > 0) {
410 free(options->remote_forwards);
411 options->remote_forwards = NULL;
413 options->num_remote_forwards = 0;
414 options->tun_open = SSH_TUNMODE_NO;
418 add_certificate_file(Options *options, const char *path, int userprovided)
422 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
423 fatal("Too many certificate files specified (max %d)",
424 SSH_MAX_CERTIFICATE_FILES);
426 /* Avoid registering duplicates */
427 for (i = 0; i < options->num_certificate_files; i++) {
428 if (options->certificate_file_userprovided[i] == userprovided &&
429 strcmp(options->certificate_files[i], path) == 0) {
430 debug2("%s: ignoring duplicate key %s", __func__, path);
435 options->certificate_file_userprovided[options->num_certificate_files] =
437 options->certificate_files[options->num_certificate_files++] =
442 add_identity_file(Options *options, const char *dir, const char *filename,
448 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
449 fatal("Too many identity files specified (max %d)",
450 SSH_MAX_IDENTITY_FILES);
452 if (dir == NULL) /* no dir, filename is absolute */
453 path = xstrdup(filename);
454 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
455 fatal("Identity file path %s too long", path);
457 /* Avoid registering duplicates */
458 for (i = 0; i < options->num_identity_files; i++) {
459 if (options->identity_file_userprovided[i] == userprovided &&
460 strcmp(options->identity_files[i], path) == 0) {
461 debug2("%s: ignoring duplicate key %s", __func__, path);
467 options->identity_file_userprovided[options->num_identity_files] =
469 options->identity_files[options->num_identity_files++] = path;
473 default_ssh_port(void)
479 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
480 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
486 * Execute a command in a shell.
487 * Return its exit status or -1 on abnormal exit.
490 execute_in_shell(const char *cmd)
496 if ((shell = getenv("SHELL")) == NULL)
497 shell = _PATH_BSHELL;
499 /* Need this to redirect subprocess stdin/out */
500 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
501 fatal("open(/dev/null): %s", strerror(errno));
503 debug("Executing command: '%.500s'", cmd);
505 /* Fork and execute the command. */
506 if ((pid = fork()) == 0) {
509 /* Redirect child stdin and stdout. Leave stderr */
510 if (dup2(devnull, STDIN_FILENO) == -1)
511 fatal("dup2: %s", strerror(errno));
512 if (dup2(devnull, STDOUT_FILENO) == -1)
513 fatal("dup2: %s", strerror(errno));
514 if (devnull > STDERR_FILENO)
516 closefrom(STDERR_FILENO + 1);
520 argv[2] = xstrdup(cmd);
523 execv(argv[0], argv);
524 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
525 /* Die with signal to make this error apparent to parent. */
526 signal(SIGTERM, SIG_DFL);
527 kill(getpid(), SIGTERM);
532 fatal("%s: fork: %.100s", __func__, strerror(errno));
536 while (waitpid(pid, &status, 0) == -1) {
537 if (errno != EINTR && errno != EAGAIN)
538 fatal("%s: waitpid: %s", __func__, strerror(errno));
540 if (!WIFEXITED(status)) {
541 error("command '%.100s' exited abnormally", cmd);
544 debug3("command returned status %d", WEXITSTATUS(status));
545 return WEXITSTATUS(status);
549 * Parse and execute a Match directive.
552 match_cfg_line(Options *options, char **condition, struct passwd *pw,
553 const char *host_arg, const char *original_host, int post_canon,
554 const char *filename, int linenum)
556 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
558 int r, port, this_result, result = 1, attributes = 0, negate;
559 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
563 * Configuration is likely to be incomplete at this point so we
564 * must be prepared to use default values.
566 port = options->port <= 0 ? default_ssh_port() : options->port;
567 ruser = options->user == NULL ? pw->pw_name : options->user;
569 host = xstrdup(options->hostname);
570 } else if (options->hostname != NULL) {
571 /* NB. Please keep in sync with ssh.c:main() */
572 host = percent_expand(options->hostname,
573 "h", host_arg, (char *)NULL);
575 host = xstrdup(host_arg);
578 debug2("checking match for '%s' host %s originally %s",
579 cp, host, original_host);
580 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
583 if ((negate = attrib[0] == '!'))
585 /* criteria "all" and "canonical" have no argument */
586 if (strcasecmp(attrib, "all") == 0) {
587 if (attributes > 1 ||
588 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
589 error("%.200s line %d: '%s' cannot be combined "
590 "with other Match attributes",
591 filename, linenum, oattrib);
596 result = negate ? 0 : 1;
600 if (strcasecmp(attrib, "canonical") == 0) {
601 r = !!post_canon; /* force bitmask member to boolean */
602 if (r == (negate ? 1 : 0))
603 this_result = result = 0;
604 debug3("%.200s line %d: %smatched '%s'",
606 this_result ? "" : "not ", oattrib);
609 /* All other criteria require an argument */
610 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
611 error("Missing Match criteria for %s", attrib);
615 if (strcasecmp(attrib, "host") == 0) {
616 criteria = xstrdup(host);
617 r = match_hostname(host, arg) == 1;
618 if (r == (negate ? 1 : 0))
619 this_result = result = 0;
620 } else if (strcasecmp(attrib, "originalhost") == 0) {
621 criteria = xstrdup(original_host);
622 r = match_hostname(original_host, arg) == 1;
623 if (r == (negate ? 1 : 0))
624 this_result = result = 0;
625 } else if (strcasecmp(attrib, "user") == 0) {
626 criteria = xstrdup(ruser);
627 r = match_pattern_list(ruser, arg, 0) == 1;
628 if (r == (negate ? 1 : 0))
629 this_result = result = 0;
630 } else if (strcasecmp(attrib, "localuser") == 0) {
631 criteria = xstrdup(pw->pw_name);
632 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
633 if (r == (negate ? 1 : 0))
634 this_result = result = 0;
635 } else if (strcasecmp(attrib, "exec") == 0) {
636 if (gethostname(thishost, sizeof(thishost)) == -1)
637 fatal("gethostname: %s", strerror(errno));
638 strlcpy(shorthost, thishost, sizeof(shorthost));
639 shorthost[strcspn(thishost, ".")] = '\0';
640 snprintf(portstr, sizeof(portstr), "%d", port);
641 snprintf(uidstr, sizeof(uidstr), "%llu",
642 (unsigned long long)pw->pw_uid);
644 cmd = percent_expand(arg,
656 /* skip execution if prior predicate failed */
657 debug3("%.200s line %d: skipped exec "
658 "\"%.100s\"", filename, linenum, cmd);
662 r = execute_in_shell(cmd);
664 fatal("%.200s line %d: match exec "
665 "'%.100s' error", filename,
668 criteria = xstrdup(cmd);
670 /* Force exit status to boolean */
672 if (r == (negate ? 1 : 0))
673 this_result = result = 0;
675 error("Unsupported Match attribute %s", attrib);
679 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
680 filename, linenum, this_result ? "": "not ",
684 if (attributes == 0) {
685 error("One or more attributes required for Match");
691 debug2("match %sfound", result ? "" : "not ");
697 /* Remove environment variable by pattern */
699 rm_env(Options *options, const char *arg, const char *filename, int linenum)
704 /* Remove an environment variable */
705 for (i = 0; i < options->num_send_env; ) {
706 cp = xstrdup(options->send_env[i]);
707 if (!match_pattern(cp, arg + 1)) {
712 debug3("%s line %d: removing environment %s",
713 filename, linenum, cp);
715 free(options->send_env[i]);
716 options->send_env[i] = NULL;
717 for (j = i; j < options->num_send_env - 1; j++) {
718 options->send_env[j] = options->send_env[j + 1];
719 options->send_env[j + 1] = NULL;
721 options->num_send_env--;
722 /* NB. don't increment i */
727 * Returns the number of the token pointed to by cp or oBadOption.
730 parse_token(const char *cp, const char *filename, int linenum,
731 const char *ignored_unknown)
735 for (i = 0; keywords[i].name; i++)
736 if (strcmp(cp, keywords[i].name) == 0)
737 return keywords[i].opcode;
738 if (ignored_unknown != NULL &&
739 match_pattern_list(cp, ignored_unknown, 1) == 1)
740 return oIgnoredUnknownOption;
741 error("%s: line %d: Bad configuration option: %s",
742 filename, linenum, cp);
746 /* Multistate option parsing */
751 static const struct multistate multistate_flag[] = {
758 static const struct multistate multistate_yesnoask[] = {
766 static const struct multistate multistate_strict_hostkey[] = {
767 { "true", SSH_STRICT_HOSTKEY_YES },
768 { "false", SSH_STRICT_HOSTKEY_OFF },
769 { "yes", SSH_STRICT_HOSTKEY_YES },
770 { "no", SSH_STRICT_HOSTKEY_OFF },
771 { "ask", SSH_STRICT_HOSTKEY_ASK },
772 { "off", SSH_STRICT_HOSTKEY_OFF },
773 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
776 static const struct multistate multistate_yesnoaskconfirm[] = {
785 static const struct multistate multistate_addressfamily[] = {
787 { "inet6", AF_INET6 },
788 { "any", AF_UNSPEC },
791 static const struct multistate multistate_controlmaster[] = {
792 { "true", SSHCTL_MASTER_YES },
793 { "yes", SSHCTL_MASTER_YES },
794 { "false", SSHCTL_MASTER_NO },
795 { "no", SSHCTL_MASTER_NO },
796 { "auto", SSHCTL_MASTER_AUTO },
797 { "ask", SSHCTL_MASTER_ASK },
798 { "autoask", SSHCTL_MASTER_AUTO_ASK },
801 static const struct multistate multistate_tunnel[] = {
802 { "ethernet", SSH_TUNMODE_ETHERNET },
803 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
804 { "true", SSH_TUNMODE_DEFAULT },
805 { "yes", SSH_TUNMODE_DEFAULT },
806 { "false", SSH_TUNMODE_NO },
807 { "no", SSH_TUNMODE_NO },
810 static const struct multistate multistate_requesttty[] = {
811 { "true", REQUEST_TTY_YES },
812 { "yes", REQUEST_TTY_YES },
813 { "false", REQUEST_TTY_NO },
814 { "no", REQUEST_TTY_NO },
815 { "force", REQUEST_TTY_FORCE },
816 { "auto", REQUEST_TTY_AUTO },
819 static const struct multistate multistate_canonicalizehostname[] = {
820 { "true", SSH_CANONICALISE_YES },
821 { "false", SSH_CANONICALISE_NO },
822 { "yes", SSH_CANONICALISE_YES },
823 { "no", SSH_CANONICALISE_NO },
824 { "always", SSH_CANONICALISE_ALWAYS },
829 * Processes a single option line as used in the configuration files. This
830 * only sets those values that have not already been set.
833 process_config_line(Options *options, struct passwd *pw, const char *host,
834 const char *original_host, char *line, const char *filename,
835 int linenum, int *activep, int flags)
837 return process_config_line_depth(options, pw, host, original_host,
838 line, filename, linenum, activep, flags, 0);
841 #define WHITESPACE " \t\r\n"
843 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
844 const char *original_host, char *line, const char *filename,
845 int linenum, int *activep, int flags, int depth)
847 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
848 char **cpptr, fwdarg[256];
849 u_int i, *uintptr, max_entries = 0;
850 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
851 int remotefwd, dynamicfwd;
852 LogLevel *log_level_ptr;
853 SyslogFacility *log_facility_ptr;
857 const struct multistate *multistate_ptr;
858 struct allowed_cname *cname;
862 if (activep == NULL) { /* We are processing a command line directive */
867 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
868 if ((len = strlen(line)) == 0)
870 for (len--; len > 0; len--) {
871 if (strchr(WHITESPACE "\f", line[len]) == NULL)
877 /* Get the keyword. (Each line is supposed to begin with a keyword). */
878 if ((keyword = strdelim(&s)) == NULL)
880 /* Ignore leading whitespace. */
881 if (*keyword == '\0')
882 keyword = strdelim(&s);
883 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
885 /* Match lowercase keyword */
888 opcode = parse_token(keyword, filename, linenum,
889 options->ignored_unknown);
893 /* don't panic, but count bad options */
897 case oIgnoredUnknownOption:
898 debug("%s line %d: Ignored unknown option \"%s\"",
899 filename, linenum, keyword);
901 case oConnectTimeout:
902 intptr = &options->connection_timeout;
905 if (!arg || *arg == '\0')
906 fatal("%s line %d: missing time value.",
908 if (strcmp(arg, "none") == 0)
910 else if ((value = convtime(arg)) == -1)
911 fatal("%s line %d: invalid time value.",
913 if (*activep && *intptr == -1)
918 intptr = &options->forward_agent;
920 multistate_ptr = multistate_flag;
923 if (!arg || *arg == '\0')
924 fatal("%s line %d: missing argument.",
927 for (i = 0; multistate_ptr[i].key != NULL; i++) {
928 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
929 value = multistate_ptr[i].value;
934 fatal("%s line %d: unsupported option \"%s\".",
935 filename, linenum, arg);
936 if (*activep && *intptr == -1)
941 intptr = &options->forward_x11;
944 case oForwardX11Trusted:
945 intptr = &options->forward_x11_trusted;
948 case oForwardX11Timeout:
949 intptr = &options->forward_x11_timeout;
953 intptr = &options->fwd_opts.gateway_ports;
956 case oExitOnForwardFailure:
957 intptr = &options->exit_on_forward_failure;
960 case oPasswordAuthentication:
961 intptr = &options->password_authentication;
964 case oKbdInteractiveAuthentication:
965 intptr = &options->kbd_interactive_authentication;
968 case oKbdInteractiveDevices:
969 charptr = &options->kbd_interactive_devices;
972 case oPubkeyAuthentication:
973 intptr = &options->pubkey_authentication;
976 case oHostbasedAuthentication:
977 intptr = &options->hostbased_authentication;
980 case oChallengeResponseAuthentication:
981 intptr = &options->challenge_response_authentication;
984 case oGssAuthentication:
985 intptr = &options->gss_authentication;
988 case oGssDelegateCreds:
989 intptr = &options->gss_deleg_creds;
993 intptr = &options->batch_mode;
997 intptr = &options->check_host_ip;
1000 case oVerifyHostKeyDNS:
1001 intptr = &options->verify_host_key_dns;
1002 multistate_ptr = multistate_yesnoask;
1003 goto parse_multistate;
1005 case oStrictHostKeyChecking:
1006 intptr = &options->strict_host_key_checking;
1007 multistate_ptr = multistate_strict_hostkey;
1008 goto parse_multistate;
1011 intptr = &options->compression;
1015 intptr = &options->tcp_keep_alive;
1018 case oNoHostAuthenticationForLocalhost:
1019 intptr = &options->no_host_authentication_for_localhost;
1022 case oNumberOfPasswordPrompts:
1023 intptr = &options->number_of_password_prompts;
1028 if (!arg || *arg == '\0')
1029 fatal("%.200s line %d: Missing argument.", filename,
1031 if (strcmp(arg, "default") == 0) {
1034 if (scan_scaled(arg, &val64) == -1)
1035 fatal("%.200s line %d: Bad number '%s': %s",
1036 filename, linenum, arg, strerror(errno));
1037 if (val64 != 0 && val64 < 16)
1038 fatal("%.200s line %d: RekeyLimit too small",
1041 if (*activep && options->rekey_limit == -1)
1042 options->rekey_limit = val64;
1043 if (s != NULL) { /* optional rekey interval present */
1044 if (strcmp(s, "none") == 0) {
1045 (void)strdelim(&s); /* discard */
1048 intptr = &options->rekey_interval;
1055 if (!arg || *arg == '\0')
1056 fatal("%.200s line %d: Missing argument.", filename, linenum);
1058 intptr = &options->num_identity_files;
1059 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1060 fatal("%.200s line %d: Too many identity files specified (max %d).",
1061 filename, linenum, SSH_MAX_IDENTITY_FILES);
1062 add_identity_file(options, NULL,
1063 arg, flags & SSHCONF_USERCONF);
1067 case oCertificateFile:
1069 if (!arg || *arg == '\0')
1070 fatal("%.200s line %d: Missing argument.",
1073 intptr = &options->num_certificate_files;
1074 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1075 fatal("%.200s line %d: Too many certificate "
1076 "files specified (max %d).",
1078 SSH_MAX_CERTIFICATE_FILES);
1080 add_certificate_file(options, arg,
1081 flags & SSHCONF_USERCONF);
1085 case oXAuthLocation:
1086 charptr=&options->xauth_location;
1090 charptr = &options->user;
1093 if (!arg || *arg == '\0')
1094 fatal("%.200s line %d: Missing argument.",
1096 if (*activep && *charptr == NULL)
1097 *charptr = xstrdup(arg);
1100 case oGlobalKnownHostsFile:
1101 cpptr = (char **)&options->system_hostfiles;
1102 uintptr = &options->num_system_hostfiles;
1103 max_entries = SSH_MAX_HOSTS_FILES;
1105 if (*activep && *uintptr == 0) {
1106 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1107 if ((*uintptr) >= max_entries)
1108 fatal("%s line %d: "
1109 "too many authorized keys files.",
1111 cpptr[(*uintptr)++] = xstrdup(arg);
1116 case oUserKnownHostsFile:
1117 cpptr = (char **)&options->user_hostfiles;
1118 uintptr = &options->num_user_hostfiles;
1119 max_entries = SSH_MAX_HOSTS_FILES;
1120 goto parse_char_array;
1123 charptr = &options->hostname;
1127 charptr = &options->host_key_alias;
1130 case oPreferredAuthentications:
1131 charptr = &options->preferred_authentications;
1135 charptr = &options->bind_address;
1138 case oBindInterface:
1139 charptr = &options->bind_interface;
1142 case oPKCS11Provider:
1143 charptr = &options->pkcs11_provider;
1147 charptr = &options->proxy_command;
1148 /* Ignore ProxyCommand if ProxyJump already specified */
1149 if (options->jump_host != NULL)
1150 charptr = &options->jump_host; /* Skip below */
1153 fatal("%.200s line %d: Missing argument.", filename, linenum);
1154 len = strspn(s, WHITESPACE "=");
1155 if (*activep && *charptr == NULL)
1156 *charptr = xstrdup(s + len);
1161 fatal("%.200s line %d: Missing argument.",
1164 len = strspn(s, WHITESPACE "=");
1165 if (parse_jump(s + len, options, *activep) == -1) {
1166 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1167 filename, linenum, s + len);
1173 if (!arg || *arg == '\0')
1174 fatal("%.200s line %d: Missing argument.",
1176 value = a2port(arg);
1178 fatal("%.200s line %d: Bad port '%s'.",
1179 filename, linenum, arg);
1180 if (*activep && options->port == -1)
1181 options->port = value;
1184 case oConnectionAttempts:
1185 intptr = &options->connection_attempts;
1188 if ((errstr = atoi_err(arg, &value)) != NULL)
1189 fatal("%s line %d: integer value %s.",
1190 filename, linenum, errstr);
1191 if (*activep && *intptr == -1)
1197 if (!arg || *arg == '\0')
1198 fatal("%.200s line %d: Missing argument.", filename, linenum);
1199 if (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))
1200 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1201 filename, linenum, arg ? arg : "<NONE>");
1202 if (*activep && options->ciphers == NULL)
1203 options->ciphers = xstrdup(arg);
1208 if (!arg || *arg == '\0')
1209 fatal("%.200s line %d: Missing argument.", filename, linenum);
1210 if (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))
1211 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1212 filename, linenum, arg ? arg : "<NONE>");
1213 if (*activep && options->macs == NULL)
1214 options->macs = xstrdup(arg);
1217 case oKexAlgorithms:
1219 if (!arg || *arg == '\0')
1220 fatal("%.200s line %d: Missing argument.",
1223 !kex_names_valid(*arg == '+' ? arg + 1 : arg))
1224 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1225 filename, linenum, arg ? arg : "<NONE>");
1226 if (*activep && options->kex_algorithms == NULL)
1227 options->kex_algorithms = xstrdup(arg);
1230 case oHostKeyAlgorithms:
1231 charptr = &options->hostkeyalgorithms;
1234 if (!arg || *arg == '\0')
1235 fatal("%.200s line %d: Missing argument.",
1238 !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1239 fatal("%s line %d: Bad key types '%s'.",
1240 filename, linenum, arg ? arg : "<NONE>");
1241 if (*activep && *charptr == NULL)
1242 *charptr = xstrdup(arg);
1245 case oCASignatureAlgorithms:
1246 charptr = &options->ca_sign_algorithms;
1247 goto parse_keytypes;
1250 log_level_ptr = &options->log_level;
1252 value = log_level_number(arg);
1253 if (value == SYSLOG_LEVEL_NOT_SET)
1254 fatal("%.200s line %d: unsupported log level '%s'",
1255 filename, linenum, arg ? arg : "<NONE>");
1256 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1257 *log_level_ptr = (LogLevel) value;
1261 log_facility_ptr = &options->log_facility;
1263 value = log_facility_number(arg);
1264 if (value == SYSLOG_FACILITY_NOT_SET)
1265 fatal("%.200s line %d: unsupported log facility '%s'",
1266 filename, linenum, arg ? arg : "<NONE>");
1267 if (*log_facility_ptr == -1)
1268 *log_facility_ptr = (SyslogFacility) value;
1272 case oRemoteForward:
1273 case oDynamicForward:
1275 if (arg == NULL || *arg == '\0')
1276 fatal("%.200s line %d: Missing port argument.",
1279 remotefwd = (opcode == oRemoteForward);
1280 dynamicfwd = (opcode == oDynamicForward);
1283 arg2 = strdelim(&s);
1284 if (arg2 == NULL || *arg2 == '\0') {
1288 fatal("%.200s line %d: Missing target "
1289 "argument.", filename, linenum);
1291 /* construct a string for parse_forward */
1292 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1297 strlcpy(fwdarg, arg, sizeof(fwdarg));
1299 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1300 fatal("%.200s line %d: Bad forwarding specification.",
1305 add_remote_forward(options, &fwd);
1307 add_local_forward(options, &fwd);
1312 case oClearAllForwardings:
1313 intptr = &options->clear_forwardings;
1318 fatal("Host directive not supported as a command-line "
1322 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1323 if ((flags & SSHCONF_NEVERMATCH) != 0)
1325 negated = *arg == '!';
1328 if (match_pattern(host, arg)) {
1330 debug("%.200s line %d: Skipping Host "
1331 "block because of negated match "
1332 "for %.100s", filename, linenum,
1338 arg2 = arg; /* logged below */
1343 debug("%.200s line %d: Applying options for %.100s",
1344 filename, linenum, arg2);
1345 /* Avoid garbage check below, as strdelim is done. */
1350 fatal("Host directive not supported as a command-line "
1352 value = match_cfg_line(options, &s, pw, host, original_host,
1353 flags & SSHCONF_POSTCANON, filename, linenum);
1355 fatal("%.200s line %d: Bad Match condition", filename,
1357 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1361 intptr = &options->escape_char;
1363 if (!arg || *arg == '\0')
1364 fatal("%.200s line %d: Missing argument.", filename, linenum);
1365 if (strcmp(arg, "none") == 0)
1366 value = SSH_ESCAPECHAR_NONE;
1367 else if (arg[1] == '\0')
1368 value = (u_char) arg[0];
1369 else if (arg[0] == '^' && arg[2] == 0 &&
1370 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1371 value = (u_char) arg[1] & 31;
1373 fatal("%.200s line %d: Bad escape character.",
1376 value = 0; /* Avoid compiler warning. */
1378 if (*activep && *intptr == -1)
1382 case oAddressFamily:
1383 intptr = &options->address_family;
1384 multistate_ptr = multistate_addressfamily;
1385 goto parse_multistate;
1387 case oEnableSSHKeysign:
1388 intptr = &options->enable_ssh_keysign;
1391 case oIdentitiesOnly:
1392 intptr = &options->identities_only;
1395 case oServerAliveInterval:
1396 intptr = &options->server_alive_interval;
1399 case oServerAliveCountMax:
1400 intptr = &options->server_alive_count_max;
1404 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1405 if (strchr(arg, '=') != NULL)
1406 fatal("%s line %d: Invalid environment name.",
1411 /* Removing an env var */
1412 rm_env(options, arg, filename, linenum);
1415 /* Adding an env var */
1416 if (options->num_send_env >= INT_MAX)
1417 fatal("%s line %d: too many send env.",
1419 options->send_env = xrecallocarray(
1420 options->send_env, options->num_send_env,
1421 options->num_send_env + 1,
1422 sizeof(*options->send_env));
1423 options->send_env[options->num_send_env++] =
1430 value = options->num_setenv;
1431 while ((arg = strdelimw(&s)) != NULL && *arg != '\0') {
1432 if (strchr(arg, '=') == NULL)
1433 fatal("%s line %d: Invalid SetEnv.",
1435 if (!*activep || value != 0)
1437 /* Adding a setenv var */
1438 if (options->num_setenv >= INT_MAX)
1439 fatal("%s line %d: too many SetEnv.",
1441 options->setenv = xrecallocarray(
1442 options->setenv, options->num_setenv,
1443 options->num_setenv + 1, sizeof(*options->setenv));
1444 options->setenv[options->num_setenv++] = xstrdup(arg);
1449 charptr = &options->control_path;
1452 case oControlMaster:
1453 intptr = &options->control_master;
1454 multistate_ptr = multistate_controlmaster;
1455 goto parse_multistate;
1457 case oControlPersist:
1458 /* no/false/yes/true, or a time spec */
1459 intptr = &options->control_persist;
1461 if (!arg || *arg == '\0')
1462 fatal("%.200s line %d: Missing ControlPersist"
1463 " argument.", filename, linenum);
1465 value2 = 0; /* timeout */
1466 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1468 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1470 else if ((value2 = convtime(arg)) >= 0)
1473 fatal("%.200s line %d: Bad ControlPersist argument.",
1475 if (*activep && *intptr == -1) {
1477 options->control_persist_timeout = value2;
1481 case oHashKnownHosts:
1482 intptr = &options->hash_known_hosts;
1486 intptr = &options->tun_open;
1487 multistate_ptr = multistate_tunnel;
1488 goto parse_multistate;
1492 if (!arg || *arg == '\0')
1493 fatal("%.200s line %d: Missing argument.", filename, linenum);
1494 value = a2tun(arg, &value2);
1495 if (value == SSH_TUNID_ERR)
1496 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1498 options->tun_local = value;
1499 options->tun_remote = value2;
1504 charptr = &options->local_command;
1507 case oPermitLocalCommand:
1508 intptr = &options->permit_local_command;
1511 case oRemoteCommand:
1512 charptr = &options->remote_command;
1515 case oVisualHostKey:
1516 intptr = &options->visual_host_key;
1521 fatal("Include directive not supported as a "
1522 "command-line option");
1524 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1526 * Ensure all paths are anchored. User configuration
1527 * files may begin with '~/' but system configurations
1528 * must not. If the path is relative, then treat it
1529 * as living in ~/.ssh for user configurations or
1530 * /etc/ssh for system ones.
1532 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1533 fatal("%.200s line %d: bad include path %s.",
1534 filename, linenum, arg);
1535 if (*arg != '/' && *arg != '~') {
1536 xasprintf(&arg2, "%s/%s",
1537 (flags & SSHCONF_USERCONF) ?
1538 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1540 arg2 = xstrdup(arg);
1541 memset(&gl, 0, sizeof(gl));
1542 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1543 if (r == GLOB_NOMATCH) {
1544 debug("%.200s line %d: include %s matched no "
1545 "files",filename, linenum, arg2);
1548 } else if (r != 0 || gl.gl_pathc < 0)
1549 fatal("%.200s line %d: glob failed for %s.",
1550 filename, linenum, arg2);
1553 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1554 debug3("%.200s line %d: Including file %s "
1555 "depth %d%s", filename, linenum,
1556 gl.gl_pathv[i], depth,
1557 oactive ? "" : " (parse only)");
1558 r = read_config_file_depth(gl.gl_pathv[i],
1559 pw, host, original_host, options,
1560 flags | SSHCONF_CHECKPERM |
1561 (oactive ? 0 : SSHCONF_NEVERMATCH),
1562 activep, depth + 1);
1563 if (r != 1 && errno != ENOENT) {
1564 fatal("Can't open user config file "
1565 "%.100s: %.100s", gl.gl_pathv[i],
1569 * don't let Match in includes clobber the
1570 * containing file's Match state.
1584 if ((value = parse_ipqos(arg)) == -1)
1585 fatal("%s line %d: Bad IPQoS value: %s",
1586 filename, linenum, arg);
1590 else if ((value2 = parse_ipqos(arg)) == -1)
1591 fatal("%s line %d: Bad IPQoS value: %s",
1592 filename, linenum, arg);
1594 options->ip_qos_interactive = value;
1595 options->ip_qos_bulk = value2;
1600 intptr = &options->request_tty;
1601 multistate_ptr = multistate_requesttty;
1602 goto parse_multistate;
1604 case oVersionAddendum:
1606 fatal("%.200s line %d: Missing argument.", filename,
1608 len = strspn(s, WHITESPACE);
1609 if (*activep && options->version_addendum == NULL) {
1610 if (strcasecmp(s + len, "none") == 0)
1611 options->version_addendum = xstrdup("");
1612 else if (strchr(s + len, '\r') != NULL)
1613 fatal("%.200s line %d: Invalid argument",
1616 options->version_addendum = xstrdup(s + len);
1620 case oIgnoreUnknown:
1621 charptr = &options->ignored_unknown;
1624 case oProxyUseFdpass:
1625 intptr = &options->proxy_use_fdpass;
1628 case oCanonicalDomains:
1629 value = options->num_canonical_domains != 0;
1630 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1631 if (!valid_domain(arg, 1, &errstr)) {
1632 fatal("%s line %d: %s", filename, linenum,
1635 if (!*activep || value)
1637 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1638 fatal("%s line %d: too many hostname suffixes.",
1640 options->canonical_domains[
1641 options->num_canonical_domains++] = xstrdup(arg);
1645 case oCanonicalizePermittedCNAMEs:
1646 value = options->num_permitted_cnames != 0;
1647 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1648 /* Either '*' for everything or 'list:list' */
1649 if (strcmp(arg, "*") == 0)
1653 if ((arg2 = strchr(arg, ':')) == NULL ||
1655 fatal("%s line %d: "
1656 "Invalid permitted CNAME \"%s\"",
1657 filename, linenum, arg);
1662 if (!*activep || value)
1664 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1665 fatal("%s line %d: too many permitted CNAMEs.",
1667 cname = options->permitted_cnames +
1668 options->num_permitted_cnames++;
1669 cname->source_list = xstrdup(arg);
1670 cname->target_list = xstrdup(arg2);
1674 case oCanonicalizeHostname:
1675 intptr = &options->canonicalize_hostname;
1676 multistate_ptr = multistate_canonicalizehostname;
1677 goto parse_multistate;
1679 case oCanonicalizeMaxDots:
1680 intptr = &options->canonicalize_max_dots;
1683 case oCanonicalizeFallbackLocal:
1684 intptr = &options->canonicalize_fallback_local;
1687 case oStreamLocalBindMask:
1689 if (!arg || *arg == '\0')
1690 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1691 /* Parse mode in octal format */
1692 value = strtol(arg, &endofnumber, 8);
1693 if (arg == endofnumber || value < 0 || value > 0777)
1694 fatal("%.200s line %d: Bad mask.", filename, linenum);
1695 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1698 case oStreamLocalBindUnlink:
1699 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1702 case oRevokedHostKeys:
1703 charptr = &options->revoked_host_keys;
1706 case oFingerprintHash:
1707 intptr = &options->fingerprint_hash;
1709 if (!arg || *arg == '\0')
1710 fatal("%.200s line %d: Missing argument.",
1712 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1713 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1714 filename, linenum, arg);
1715 if (*activep && *intptr == -1)
1719 case oUpdateHostkeys:
1720 intptr = &options->update_hostkeys;
1721 multistate_ptr = multistate_yesnoask;
1722 goto parse_multistate;
1724 case oHostbasedKeyTypes:
1725 charptr = &options->hostbased_key_types;
1726 goto parse_keytypes;
1728 case oPubkeyAcceptedKeyTypes:
1729 charptr = &options->pubkey_key_types;
1730 goto parse_keytypes;
1732 case oAddKeysToAgent:
1733 intptr = &options->add_keys_to_agent;
1734 multistate_ptr = multistate_yesnoaskconfirm;
1735 goto parse_multistate;
1737 case oIdentityAgent:
1738 charptr = &options->identity_agent;
1740 if (!arg || *arg == '\0')
1741 fatal("%.200s line %d: Missing argument.",
1743 /* Extra validation if the string represents an env var. */
1744 if (arg[0] == '$' && !valid_env_name(arg + 1)) {
1745 fatal("%.200s line %d: Invalid environment name %s.",
1746 filename, linenum, arg);
1748 if (*activep && *charptr == NULL)
1749 *charptr = xstrdup(arg);
1753 debug("%s line %d: Deprecated option \"%s\"",
1754 filename, linenum, keyword);
1758 error("%s line %d: Unsupported option \"%s\"",
1759 filename, linenum, keyword);
1763 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1766 /* Check that there is no garbage at end of line. */
1767 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1768 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1769 filename, linenum, arg);
1775 * Reads the config file and modifies the options accordingly. Options
1776 * should already be initialized before this call. This never returns if
1777 * there is an error. If the file does not exist, this returns 0.
1780 read_config_file(const char *filename, struct passwd *pw, const char *host,
1781 const char *original_host, Options *options, int flags)
1785 return read_config_file_depth(filename, pw, host, original_host,
1786 options, flags, &active, 0);
1789 #define READCONF_MAX_DEPTH 16
1791 read_config_file_depth(const char *filename, struct passwd *pw,
1792 const char *host, const char *original_host, Options *options,
1793 int flags, int *activep, int depth)
1797 size_t linesize = 0;
1799 int bad_options = 0;
1801 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1802 fatal("Too many recursive configuration includes");
1804 if ((f = fopen(filename, "r")) == NULL)
1807 if (flags & SSHCONF_CHECKPERM) {
1810 if (fstat(fileno(f), &sb) == -1)
1811 fatal("fstat %s: %s", filename, strerror(errno));
1812 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1813 (sb.st_mode & 022) != 0))
1814 fatal("Bad owner or permissions on %s", filename);
1817 debug("Reading configuration data %.200s", filename);
1820 * Mark that we are now processing the options. This flag is turned
1821 * on/off by Host specifications.
1824 while (getline(&line, &linesize, f) != -1) {
1825 /* Update line number counter. */
1827 if (process_config_line_depth(options, pw, host, original_host,
1828 line, filename, linenum, activep, flags, depth) != 0)
1833 if (bad_options > 0)
1834 fatal("%s: terminating, %d bad configuration options",
1835 filename, bad_options);
1839 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1841 option_clear_or_none(const char *o)
1843 return o == NULL || strcasecmp(o, "none") == 0;
1847 * Initializes options to special values that indicate that they have not yet
1848 * been set. Read_config_file will only set options with this value. Options
1849 * are processed in the following order: command line, user config file,
1850 * system config file. Last, fill_default_options is called.
1854 initialize_options(Options * options)
1856 memset(options, 'X', sizeof(*options));
1857 options->version_addendum = NULL;
1858 options->forward_agent = -1;
1859 options->forward_x11 = -1;
1860 options->forward_x11_trusted = -1;
1861 options->forward_x11_timeout = -1;
1862 options->stdio_forward_host = NULL;
1863 options->stdio_forward_port = 0;
1864 options->clear_forwardings = -1;
1865 options->exit_on_forward_failure = -1;
1866 options->xauth_location = NULL;
1867 options->fwd_opts.gateway_ports = -1;
1868 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1869 options->fwd_opts.streamlocal_bind_unlink = -1;
1870 options->pubkey_authentication = -1;
1871 options->challenge_response_authentication = -1;
1872 options->gss_authentication = -1;
1873 options->gss_deleg_creds = -1;
1874 options->password_authentication = -1;
1875 options->kbd_interactive_authentication = -1;
1876 options->kbd_interactive_devices = NULL;
1877 options->hostbased_authentication = -1;
1878 options->batch_mode = -1;
1879 options->check_host_ip = -1;
1880 options->strict_host_key_checking = -1;
1881 options->compression = -1;
1882 options->tcp_keep_alive = -1;
1884 options->address_family = -1;
1885 options->connection_attempts = -1;
1886 options->connection_timeout = -1;
1887 options->number_of_password_prompts = -1;
1888 options->ciphers = NULL;
1889 options->macs = NULL;
1890 options->kex_algorithms = NULL;
1891 options->hostkeyalgorithms = NULL;
1892 options->ca_sign_algorithms = NULL;
1893 options->num_identity_files = 0;
1894 options->num_certificate_files = 0;
1895 options->hostname = NULL;
1896 options->host_key_alias = NULL;
1897 options->proxy_command = NULL;
1898 options->jump_user = NULL;
1899 options->jump_host = NULL;
1900 options->jump_port = -1;
1901 options->jump_extra = NULL;
1902 options->user = NULL;
1903 options->escape_char = -1;
1904 options->num_system_hostfiles = 0;
1905 options->num_user_hostfiles = 0;
1906 options->local_forwards = NULL;
1907 options->num_local_forwards = 0;
1908 options->remote_forwards = NULL;
1909 options->num_remote_forwards = 0;
1910 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1911 options->log_level = SYSLOG_LEVEL_NOT_SET;
1912 options->preferred_authentications = NULL;
1913 options->bind_address = NULL;
1914 options->bind_interface = NULL;
1915 options->pkcs11_provider = NULL;
1916 options->enable_ssh_keysign = - 1;
1917 options->no_host_authentication_for_localhost = - 1;
1918 options->identities_only = - 1;
1919 options->rekey_limit = - 1;
1920 options->rekey_interval = -1;
1921 options->verify_host_key_dns = -1;
1922 options->server_alive_interval = -1;
1923 options->server_alive_count_max = -1;
1924 options->send_env = NULL;
1925 options->num_send_env = 0;
1926 options->setenv = NULL;
1927 options->num_setenv = 0;
1928 options->control_path = NULL;
1929 options->control_master = -1;
1930 options->control_persist = -1;
1931 options->control_persist_timeout = 0;
1932 options->hash_known_hosts = -1;
1933 options->tun_open = -1;
1934 options->tun_local = -1;
1935 options->tun_remote = -1;
1936 options->local_command = NULL;
1937 options->permit_local_command = -1;
1938 options->remote_command = NULL;
1939 options->add_keys_to_agent = -1;
1940 options->identity_agent = NULL;
1941 options->visual_host_key = -1;
1942 options->ip_qos_interactive = -1;
1943 options->ip_qos_bulk = -1;
1944 options->request_tty = -1;
1945 options->proxy_use_fdpass = -1;
1946 options->ignored_unknown = NULL;
1947 options->num_canonical_domains = 0;
1948 options->num_permitted_cnames = 0;
1949 options->canonicalize_max_dots = -1;
1950 options->canonicalize_fallback_local = -1;
1951 options->canonicalize_hostname = -1;
1952 options->revoked_host_keys = NULL;
1953 options->fingerprint_hash = -1;
1954 options->update_hostkeys = -1;
1955 options->hostbased_key_types = NULL;
1956 options->pubkey_key_types = NULL;
1960 * A petite version of fill_default_options() that just fills the options
1961 * needed for hostname canonicalization to proceed.
1964 fill_default_options_for_canonicalization(Options *options)
1966 if (options->canonicalize_max_dots == -1)
1967 options->canonicalize_max_dots = 1;
1968 if (options->canonicalize_fallback_local == -1)
1969 options->canonicalize_fallback_local = 1;
1970 if (options->canonicalize_hostname == -1)
1971 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1975 * Called after processing other sources of option data, this fills those
1976 * options for which no value has been specified with their default values.
1979 fill_default_options(Options * options)
1981 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
1984 if (options->forward_agent == -1)
1985 options->forward_agent = 0;
1986 if (options->forward_x11 == -1)
1987 options->forward_x11 = 0;
1988 if (options->forward_x11_trusted == -1)
1989 options->forward_x11_trusted = 0;
1990 if (options->forward_x11_timeout == -1)
1991 options->forward_x11_timeout = 1200;
1993 * stdio forwarding (-W) changes the default for these but we defer
1994 * setting the values so they can be overridden.
1996 if (options->exit_on_forward_failure == -1)
1997 options->exit_on_forward_failure =
1998 options->stdio_forward_host != NULL ? 1 : 0;
1999 if (options->clear_forwardings == -1)
2000 options->clear_forwardings =
2001 options->stdio_forward_host != NULL ? 1 : 0;
2002 if (options->clear_forwardings == 1)
2003 clear_forwardings(options);
2005 if (options->xauth_location == NULL)
2006 options->xauth_location = _PATH_XAUTH;
2007 if (options->fwd_opts.gateway_ports == -1)
2008 options->fwd_opts.gateway_ports = 0;
2009 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
2010 options->fwd_opts.streamlocal_bind_mask = 0177;
2011 if (options->fwd_opts.streamlocal_bind_unlink == -1)
2012 options->fwd_opts.streamlocal_bind_unlink = 0;
2013 if (options->pubkey_authentication == -1)
2014 options->pubkey_authentication = 1;
2015 if (options->challenge_response_authentication == -1)
2016 options->challenge_response_authentication = 1;
2017 if (options->gss_authentication == -1)
2018 options->gss_authentication = 0;
2019 if (options->gss_deleg_creds == -1)
2020 options->gss_deleg_creds = 0;
2021 if (options->password_authentication == -1)
2022 options->password_authentication = 1;
2023 if (options->kbd_interactive_authentication == -1)
2024 options->kbd_interactive_authentication = 1;
2025 if (options->hostbased_authentication == -1)
2026 options->hostbased_authentication = 0;
2027 if (options->batch_mode == -1)
2028 options->batch_mode = 0;
2029 if (options->check_host_ip == -1)
2030 options->check_host_ip = 0;
2031 if (options->strict_host_key_checking == -1)
2032 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
2033 if (options->compression == -1)
2034 options->compression = 0;
2035 if (options->tcp_keep_alive == -1)
2036 options->tcp_keep_alive = 1;
2037 if (options->port == -1)
2038 options->port = 0; /* Filled in ssh_connect. */
2039 if (options->address_family == -1)
2040 options->address_family = AF_UNSPEC;
2041 if (options->connection_attempts == -1)
2042 options->connection_attempts = 1;
2043 if (options->number_of_password_prompts == -1)
2044 options->number_of_password_prompts = 3;
2045 /* options->hostkeyalgorithms, default set in myproposals.h */
2046 if (options->add_keys_to_agent == -1)
2047 options->add_keys_to_agent = 0;
2048 if (options->num_identity_files == 0) {
2049 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
2050 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
2051 #ifdef OPENSSL_HAS_ECC
2052 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
2054 add_identity_file(options, "~/",
2055 _PATH_SSH_CLIENT_ID_ED25519, 0);
2056 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2058 if (options->escape_char == -1)
2059 options->escape_char = '~';
2060 if (options->num_system_hostfiles == 0) {
2061 options->system_hostfiles[options->num_system_hostfiles++] =
2062 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2063 options->system_hostfiles[options->num_system_hostfiles++] =
2064 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2066 if (options->num_user_hostfiles == 0) {
2067 options->user_hostfiles[options->num_user_hostfiles++] =
2068 xstrdup(_PATH_SSH_USER_HOSTFILE);
2069 options->user_hostfiles[options->num_user_hostfiles++] =
2070 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2072 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2073 options->log_level = SYSLOG_LEVEL_INFO;
2074 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2075 options->log_facility = SYSLOG_FACILITY_USER;
2076 if (options->no_host_authentication_for_localhost == - 1)
2077 options->no_host_authentication_for_localhost = 0;
2078 if (options->identities_only == -1)
2079 options->identities_only = 0;
2080 if (options->enable_ssh_keysign == -1)
2081 options->enable_ssh_keysign = 0;
2082 if (options->rekey_limit == -1)
2083 options->rekey_limit = 0;
2084 if (options->rekey_interval == -1)
2085 options->rekey_interval = 0;
2087 if (options->verify_host_key_dns == -1)
2088 /* automatically trust a verified SSHFP record */
2089 options->verify_host_key_dns = 1;
2091 if (options->verify_host_key_dns == -1)
2092 options->verify_host_key_dns = 0;
2094 if (options->server_alive_interval == -1)
2095 options->server_alive_interval = 0;
2096 if (options->server_alive_count_max == -1)
2097 options->server_alive_count_max = 3;
2098 if (options->control_master == -1)
2099 options->control_master = 0;
2100 if (options->control_persist == -1) {
2101 options->control_persist = 0;
2102 options->control_persist_timeout = 0;
2104 if (options->hash_known_hosts == -1)
2105 options->hash_known_hosts = 0;
2106 if (options->tun_open == -1)
2107 options->tun_open = SSH_TUNMODE_NO;
2108 if (options->tun_local == -1)
2109 options->tun_local = SSH_TUNID_ANY;
2110 if (options->tun_remote == -1)
2111 options->tun_remote = SSH_TUNID_ANY;
2112 if (options->permit_local_command == -1)
2113 options->permit_local_command = 0;
2114 if (options->visual_host_key == -1)
2115 options->visual_host_key = 0;
2116 if (options->ip_qos_interactive == -1)
2117 options->ip_qos_interactive = IPTOS_DSCP_AF21;
2118 if (options->ip_qos_bulk == -1)
2119 options->ip_qos_bulk = IPTOS_DSCP_CS1;
2120 if (options->request_tty == -1)
2121 options->request_tty = REQUEST_TTY_AUTO;
2122 if (options->proxy_use_fdpass == -1)
2123 options->proxy_use_fdpass = 0;
2124 if (options->canonicalize_max_dots == -1)
2125 options->canonicalize_max_dots = 1;
2126 if (options->canonicalize_fallback_local == -1)
2127 options->canonicalize_fallback_local = 1;
2128 if (options->canonicalize_hostname == -1)
2129 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2130 if (options->fingerprint_hash == -1)
2131 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2132 if (options->update_hostkeys == -1)
2133 options->update_hostkeys = 0;
2135 /* Expand KEX name lists */
2136 all_cipher = cipher_alg_list(',', 0);
2137 all_mac = mac_alg_list(',');
2138 all_kex = kex_alg_list(',');
2139 all_key = sshkey_alg_list(0, 0, 1, ',');
2140 all_sig = sshkey_alg_list(0, 1, 1, ',');
2141 #define ASSEMBLE(what, defaults, all) \
2143 if ((r = kex_assemble_names(&options->what, \
2144 defaults, all)) != 0) \
2145 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2147 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher);
2148 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac);
2149 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex);
2150 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
2151 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2152 ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
2160 #define CLEAR_ON_NONE(v) \
2162 if (option_clear_or_none(v)) { \
2167 CLEAR_ON_NONE(options->local_command);
2168 CLEAR_ON_NONE(options->remote_command);
2169 CLEAR_ON_NONE(options->proxy_command);
2170 CLEAR_ON_NONE(options->control_path);
2171 CLEAR_ON_NONE(options->revoked_host_keys);
2172 if (options->jump_host != NULL &&
2173 strcmp(options->jump_host, "none") == 0 &&
2174 options->jump_port == 0 && options->jump_user == NULL) {
2175 free(options->jump_host);
2176 options->jump_host = NULL;
2178 /* options->identity_agent distinguishes NULL from 'none' */
2179 /* options->user will be set in the main program if appropriate */
2180 /* options->hostname will be set in the main program if appropriate */
2181 /* options->host_key_alias should not be set by default */
2182 /* options->preferred_authentications will be set in ssh */
2183 if (options->version_addendum == NULL)
2184 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2194 * parses the next field in a port forwarding specification.
2195 * sets fwd to the parsed field and advances p past the colon
2196 * or sets it to NULL at end of string.
2197 * returns 0 on success, else non-zero.
2200 parse_fwd_field(char **p, struct fwdarg *fwd)
2207 return -1; /* end of string */
2211 * A field escaped with square brackets is used literally.
2212 * XXX - allow ']' to be escaped via backslash?
2215 /* find matching ']' */
2216 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2220 /* no matching ']' or not at end of field. */
2221 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2223 /* NUL terminate the field and advance p past the colon */
2228 fwd->ispath = ispath;
2233 for (cp = *p; *cp != '\0'; cp++) {
2236 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2250 fwd->ispath = ispath;
2257 * parses a string containing a port forwarding specification of the form:
2259 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2260 * listenpath:connectpath
2262 * [listenhost:]listenport
2263 * returns number of arguments parsed or zero on error
2266 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2268 struct fwdarg fwdargs[4];
2272 memset(fwd, 0, sizeof(*fwd));
2273 memset(fwdargs, 0, sizeof(fwdargs));
2275 cp = p = xstrdup(fwdspec);
2277 /* skip leading spaces */
2278 while (isspace((u_char)*cp))
2281 for (i = 0; i < 4; ++i) {
2282 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2286 /* Check for trailing garbage */
2287 if (cp != NULL && *cp != '\0') {
2288 i = 0; /* failure */
2293 if (fwdargs[0].ispath) {
2294 fwd->listen_path = xstrdup(fwdargs[0].arg);
2295 fwd->listen_port = PORT_STREAMLOCAL;
2297 fwd->listen_host = NULL;
2298 fwd->listen_port = a2port(fwdargs[0].arg);
2300 fwd->connect_host = xstrdup("socks");
2304 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2305 fwd->listen_path = xstrdup(fwdargs[0].arg);
2306 fwd->listen_port = PORT_STREAMLOCAL;
2307 fwd->connect_path = xstrdup(fwdargs[1].arg);
2308 fwd->connect_port = PORT_STREAMLOCAL;
2309 } else if (fwdargs[1].ispath) {
2310 fwd->listen_host = NULL;
2311 fwd->listen_port = a2port(fwdargs[0].arg);
2312 fwd->connect_path = xstrdup(fwdargs[1].arg);
2313 fwd->connect_port = PORT_STREAMLOCAL;
2315 fwd->listen_host = xstrdup(fwdargs[0].arg);
2316 fwd->listen_port = a2port(fwdargs[1].arg);
2317 fwd->connect_host = xstrdup("socks");
2322 if (fwdargs[0].ispath) {
2323 fwd->listen_path = xstrdup(fwdargs[0].arg);
2324 fwd->listen_port = PORT_STREAMLOCAL;
2325 fwd->connect_host = xstrdup(fwdargs[1].arg);
2326 fwd->connect_port = a2port(fwdargs[2].arg);
2327 } else if (fwdargs[2].ispath) {
2328 fwd->listen_host = xstrdup(fwdargs[0].arg);
2329 fwd->listen_port = a2port(fwdargs[1].arg);
2330 fwd->connect_path = xstrdup(fwdargs[2].arg);
2331 fwd->connect_port = PORT_STREAMLOCAL;
2333 fwd->listen_host = NULL;
2334 fwd->listen_port = a2port(fwdargs[0].arg);
2335 fwd->connect_host = xstrdup(fwdargs[1].arg);
2336 fwd->connect_port = a2port(fwdargs[2].arg);
2341 fwd->listen_host = xstrdup(fwdargs[0].arg);
2342 fwd->listen_port = a2port(fwdargs[1].arg);
2343 fwd->connect_host = xstrdup(fwdargs[2].arg);
2344 fwd->connect_port = a2port(fwdargs[3].arg);
2347 i = 0; /* failure */
2353 if (!(i == 1 || i == 2))
2356 if (!(i == 3 || i == 4)) {
2357 if (fwd->connect_path == NULL &&
2358 fwd->listen_path == NULL)
2361 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2365 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2366 (!remotefwd && fwd->listen_port == 0))
2368 if (fwd->connect_host != NULL &&
2369 strlen(fwd->connect_host) >= NI_MAXHOST)
2371 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2372 if (fwd->connect_path != NULL &&
2373 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2375 if (fwd->listen_host != NULL &&
2376 strlen(fwd->listen_host) >= NI_MAXHOST)
2378 if (fwd->listen_path != NULL &&
2379 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2385 free(fwd->connect_host);
2386 fwd->connect_host = NULL;
2387 free(fwd->connect_path);
2388 fwd->connect_path = NULL;
2389 free(fwd->listen_host);
2390 fwd->listen_host = NULL;
2391 free(fwd->listen_path);
2392 fwd->listen_path = NULL;
2397 parse_jump(const char *s, Options *o, int active)
2399 char *orig, *sdup, *cp;
2400 char *host = NULL, *user = NULL;
2401 int ret = -1, port = -1, first;
2403 active &= o->proxy_command == NULL && o->jump_host == NULL;
2405 orig = sdup = xstrdup(s);
2408 if (strcasecmp(s, "none") == 0)
2410 if ((cp = strrchr(sdup, ',')) == NULL)
2411 cp = sdup; /* last */
2416 /* First argument and configuration is active */
2417 if (parse_ssh_uri(cp, &user, &host, &port) == -1 ||
2418 parse_user_host_port(cp, &user, &host, &port) != 0)
2421 /* Subsequent argument or inactive configuration */
2422 if (parse_ssh_uri(cp, NULL, NULL, NULL) == -1 ||
2423 parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2426 first = 0; /* only check syntax for subsequent hosts */
2427 } while (cp != sdup);
2430 if (strcasecmp(s, "none") == 0) {
2431 o->jump_host = xstrdup("none");
2434 o->jump_user = user;
2435 o->jump_host = host;
2436 o->jump_port = port;
2437 o->proxy_command = xstrdup("none");
2439 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2440 o->jump_extra = xstrdup(s);
2441 o->jump_extra[cp - s] = '\0';
2454 parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
2459 r = parse_uri("ssh", uri, userp, hostp, portp, &path);
2460 if (r == 0 && path != NULL)
2461 r = -1; /* path not allowed */
2465 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2467 fmt_multistate_int(int val, const struct multistate *m)
2471 for (i = 0; m[i].key != NULL; i++) {
2472 if (m[i].value == val)
2479 fmt_intarg(OpCodes code, int val)
2484 case oAddressFamily:
2485 return fmt_multistate_int(val, multistate_addressfamily);
2486 case oVerifyHostKeyDNS:
2487 case oUpdateHostkeys:
2488 return fmt_multistate_int(val, multistate_yesnoask);
2489 case oStrictHostKeyChecking:
2490 return fmt_multistate_int(val, multistate_strict_hostkey);
2491 case oControlMaster:
2492 return fmt_multistate_int(val, multistate_controlmaster);
2494 return fmt_multistate_int(val, multistate_tunnel);
2496 return fmt_multistate_int(val, multistate_requesttty);
2497 case oCanonicalizeHostname:
2498 return fmt_multistate_int(val, multistate_canonicalizehostname);
2499 case oAddKeysToAgent:
2500 return fmt_multistate_int(val, multistate_yesnoaskconfirm);
2501 case oFingerprintHash:
2502 return ssh_digest_alg_name(val);
2516 lookup_opcode_name(OpCodes code)
2520 for (i = 0; keywords[i].name != NULL; i++)
2521 if (keywords[i].opcode == code)
2522 return(keywords[i].name);
2527 dump_cfg_int(OpCodes code, int val)
2529 printf("%s %d\n", lookup_opcode_name(code), val);
2533 dump_cfg_fmtint(OpCodes code, int val)
2535 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2539 dump_cfg_string(OpCodes code, const char *val)
2543 printf("%s %s\n", lookup_opcode_name(code), val);
2547 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2551 for (i = 0; i < count; i++)
2552 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2556 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2560 printf("%s", lookup_opcode_name(code));
2561 for (i = 0; i < count; i++)
2562 printf(" %s", vals[i]);
2567 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2569 const struct Forward *fwd;
2572 /* oDynamicForward */
2573 for (i = 0; i < count; i++) {
2575 if (code == oDynamicForward && fwd->connect_host != NULL &&
2576 strcmp(fwd->connect_host, "socks") != 0)
2578 if (code == oLocalForward && fwd->connect_host != NULL &&
2579 strcmp(fwd->connect_host, "socks") == 0)
2581 printf("%s", lookup_opcode_name(code));
2582 if (fwd->listen_port == PORT_STREAMLOCAL)
2583 printf(" %s", fwd->listen_path);
2584 else if (fwd->listen_host == NULL)
2585 printf(" %d", fwd->listen_port);
2588 fwd->listen_host, fwd->listen_port);
2590 if (code != oDynamicForward) {
2591 if (fwd->connect_port == PORT_STREAMLOCAL)
2592 printf(" %s", fwd->connect_path);
2593 else if (fwd->connect_host == NULL)
2594 printf(" %d", fwd->connect_port);
2597 fwd->connect_host, fwd->connect_port);
2605 dump_client_config(Options *o, const char *host)
2608 char buf[8], *all_key;
2610 /* This is normally prepared in ssh_kex2 */
2611 all_key = sshkey_alg_list(0, 0, 1, ',');
2612 if (kex_assemble_names( &o->hostkeyalgorithms,
2613 KEX_DEFAULT_PK_ALG, all_key) != 0)
2614 fatal("%s: kex_assemble_names failed", __func__);
2617 /* Most interesting options first: user, host, port */
2618 dump_cfg_string(oUser, o->user);
2619 dump_cfg_string(oHostName, host);
2620 dump_cfg_int(oPort, o->port);
2623 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
2624 dump_cfg_fmtint(oAddressFamily, o->address_family);
2625 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2626 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2627 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2628 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2629 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2630 dump_cfg_fmtint(oCompression, o->compression);
2631 dump_cfg_fmtint(oControlMaster, o->control_master);
2632 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2633 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2634 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2635 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2636 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2637 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2638 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2639 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2641 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2642 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2644 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2645 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2646 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2647 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2648 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2649 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2650 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2651 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2652 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2653 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2654 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2655 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2656 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2657 dump_cfg_fmtint(oTunnel, o->tun_open);
2658 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2659 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2660 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2662 /* Integer options */
2663 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2664 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2665 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2666 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2667 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2668 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2670 /* String options */
2671 dump_cfg_string(oBindAddress, o->bind_address);
2672 dump_cfg_string(oBindInterface, o->bind_interface);
2673 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2674 dump_cfg_string(oControlPath, o->control_path);
2675 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2676 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2677 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2678 dump_cfg_string(oIdentityAgent, o->identity_agent);
2679 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
2680 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2681 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2682 dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms ? o->ca_sign_algorithms : SSH_ALLOWED_CA_SIGALGS);
2683 dump_cfg_string(oLocalCommand, o->local_command);
2684 dump_cfg_string(oRemoteCommand, o->remote_command);
2685 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2686 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2687 #ifdef ENABLE_PKCS11
2688 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2690 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2691 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2692 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2693 dump_cfg_string(oXAuthLocation, o->xauth_location);
2696 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2697 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2698 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2700 /* String array options */
2701 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2702 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2703 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
2704 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2705 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2706 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2707 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
2711 /* oConnectTimeout */
2712 if (o->connection_timeout == -1)
2713 printf("connecttimeout none\n");
2715 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2718 printf("tunneldevice");
2719 if (o->tun_local == SSH_TUNID_ANY)
2722 printf(" %d", o->tun_local);
2723 if (o->tun_remote == SSH_TUNID_ANY)
2726 printf(":%d", o->tun_remote);
2729 /* oCanonicalizePermittedCNAMEs */
2730 if ( o->num_permitted_cnames > 0) {
2731 printf("canonicalizePermittedcnames");
2732 for (i = 0; i < o->num_permitted_cnames; i++) {
2733 printf(" %s:%s", o->permitted_cnames[i].source_list,
2734 o->permitted_cnames[i].target_list);
2739 /* oControlPersist */
2740 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2741 dump_cfg_fmtint(oControlPersist, o->control_persist);
2743 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2746 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2747 printf("escapechar none\n");
2749 vis(buf, o->escape_char, VIS_WHITE, 0);
2750 printf("escapechar %s\n", buf);
2754 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2755 printf("%s\n", iptos2str(o->ip_qos_bulk));
2758 printf("rekeylimit %llu %d\n",
2759 (unsigned long long)o->rekey_limit, o->rekey_interval);
2761 /* oStreamLocalBindMask */
2762 printf("streamlocalbindmask 0%o\n",
2763 o->fwd_opts.streamlocal_bind_mask);
2766 printf("syslogfacility %s\n", log_facility_name(o->log_facility));
2768 /* oProxyCommand / oProxyJump */
2769 if (o->jump_host == NULL)
2770 dump_cfg_string(oProxyCommand, o->proxy_command);
2772 /* Check for numeric addresses */
2773 i = strchr(o->jump_host, ':') != NULL ||
2774 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2775 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2776 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2777 /* optional additional jump spec */
2778 o->jump_extra == NULL ? "" : o->jump_extra,
2779 o->jump_extra == NULL ? "" : ",",
2781 o->jump_user == NULL ? "" : o->jump_user,
2782 o->jump_user == NULL ? "" : "@",
2783 /* opening [ if hostname is numeric */
2785 /* mandatory hostname */
2787 /* closing ] if hostname is numeric */
2789 /* optional port number */
2790 o->jump_port <= 0 ? "" : ":",
2791 o->jump_port <= 0 ? "" : buf);