1 /* $OpenBSD: readconf.c,v 1.259 2016/07/22 03:35:11 djm Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Functions for reading the configuration files.
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
18 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/sysctl.h>
25 #include <netinet/in.h>
26 #include <netinet/in_systm.h>
27 #include <netinet/ip.h>
28 #include <arpa/inet.h>
44 #ifdef USE_SYSTEM_GLOB
47 # include "openbsd-compat/glob.h"
52 #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, oLogLevel, oCiphers, oProtocol, oMacs,
160 oPubkeyAuthentication,
161 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
162 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
163 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
164 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
165 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
166 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
167 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
168 oSendEnv, oControlPath, oControlMaster, oControlPersist,
170 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
172 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
173 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
174 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
175 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
176 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
177 oPubkeyAcceptedKeyTypes, oProxyJump,
178 oIgnoredUnknownOption, oDeprecated, oUnsupported
181 /* Textual representations of the tokens. */
187 { "forwardagent", oForwardAgent },
188 { "forwardx11", oForwardX11 },
189 { "forwardx11trusted", oForwardX11Trusted },
190 { "forwardx11timeout", oForwardX11Timeout },
191 { "exitonforwardfailure", oExitOnForwardFailure },
192 { "xauthlocation", oXAuthLocation },
193 { "gatewayports", oGatewayPorts },
194 { "useprivilegedport", oUsePrivilegedPort },
195 { "rhostsauthentication", oDeprecated },
196 { "passwordauthentication", oPasswordAuthentication },
197 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
198 { "kbdinteractivedevices", oKbdInteractiveDevices },
199 { "rsaauthentication", oRSAAuthentication },
200 { "pubkeyauthentication", oPubkeyAuthentication },
201 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
202 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
203 { "hostbasedauthentication", oHostbasedAuthentication },
204 { "challengeresponseauthentication", oChallengeResponseAuthentication },
205 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
206 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
207 { "kerberosauthentication", oUnsupported },
208 { "kerberostgtpassing", oUnsupported },
209 { "afstokenpassing", oUnsupported },
211 { "gssapiauthentication", oGssAuthentication },
212 { "gssapidelegatecredentials", oGssDelegateCreds },
214 { "gssapiauthentication", oUnsupported },
215 { "gssapidelegatecredentials", oUnsupported },
217 { "fallbacktorsh", oDeprecated },
218 { "usersh", oDeprecated },
219 { "identityfile", oIdentityFile },
220 { "identityfile2", oIdentityFile }, /* obsolete */
221 { "identitiesonly", oIdentitiesOnly },
222 { "certificatefile", oCertificateFile },
223 { "addkeystoagent", oAddKeysToAgent },
224 { "identityagent", oIdentityAgent },
225 { "hostname", oHostName },
226 { "hostkeyalias", oHostKeyAlias },
227 { "proxycommand", oProxyCommand },
229 { "cipher", oCipher },
230 { "ciphers", oCiphers },
232 { "protocol", oProtocol },
233 { "remoteforward", oRemoteForward },
234 { "localforward", oLocalForward },
238 { "escapechar", oEscapeChar },
239 { "globalknownhostsfile", oGlobalKnownHostsFile },
240 { "globalknownhostsfile2", oDeprecated },
241 { "userknownhostsfile", oUserKnownHostsFile },
242 { "userknownhostsfile2", oDeprecated },
243 { "connectionattempts", oConnectionAttempts },
244 { "batchmode", oBatchMode },
245 { "checkhostip", oCheckHostIP },
246 { "stricthostkeychecking", oStrictHostKeyChecking },
247 { "compression", oCompression },
248 { "compressionlevel", oCompressionLevel },
249 { "tcpkeepalive", oTCPKeepAlive },
250 { "keepalive", oTCPKeepAlive }, /* obsolete */
251 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
252 { "loglevel", oLogLevel },
253 { "dynamicforward", oDynamicForward },
254 { "preferredauthentications", oPreferredAuthentications },
255 { "hostkeyalgorithms", oHostKeyAlgorithms },
256 { "bindaddress", oBindAddress },
258 { "smartcarddevice", oPKCS11Provider },
259 { "pkcs11provider", oPKCS11Provider },
261 { "smartcarddevice", oUnsupported },
262 { "pkcs11provider", oUnsupported },
264 { "clearallforwardings", oClearAllForwardings },
265 { "enablesshkeysign", oEnableSSHKeysign },
266 { "verifyhostkeydns", oVerifyHostKeyDNS },
267 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
268 { "rekeylimit", oRekeyLimit },
269 { "connecttimeout", oConnectTimeout },
270 { "addressfamily", oAddressFamily },
271 { "serveraliveinterval", oServerAliveInterval },
272 { "serveralivecountmax", oServerAliveCountMax },
273 { "sendenv", oSendEnv },
274 { "controlpath", oControlPath },
275 { "controlmaster", oControlMaster },
276 { "controlpersist", oControlPersist },
277 { "hashknownhosts", oHashKnownHosts },
278 { "include", oInclude },
279 { "tunnel", oTunnel },
280 { "tunneldevice", oTunnelDevice },
281 { "localcommand", oLocalCommand },
282 { "permitlocalcommand", oPermitLocalCommand },
283 { "visualhostkey", oVisualHostKey },
284 { "useroaming", oDeprecated },
285 { "kexalgorithms", oKexAlgorithms },
287 { "requesttty", oRequestTTY },
288 { "proxyusefdpass", oProxyUseFdpass },
289 { "canonicaldomains", oCanonicalDomains },
290 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
291 { "canonicalizehostname", oCanonicalizeHostname },
292 { "canonicalizemaxdots", oCanonicalizeMaxDots },
293 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
294 { "streamlocalbindmask", oStreamLocalBindMask },
295 { "streamlocalbindunlink", oStreamLocalBindUnlink },
296 { "revokedhostkeys", oRevokedHostKeys },
297 { "fingerprinthash", oFingerprintHash },
298 { "updatehostkeys", oUpdateHostkeys },
299 { "hostbasedkeytypes", oHostbasedKeyTypes },
300 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
301 { "ignoreunknown", oIgnoreUnknown },
302 { "proxyjump", oProxyJump },
304 { "hpndisabled", oDeprecated },
305 { "hpnbuffersize", oDeprecated },
306 { "tcprcvbufpoll", oDeprecated },
307 { "tcprcvbuf", oDeprecated },
308 { "noneenabled", oUnsupported },
309 { "noneswitch", oUnsupported },
310 { "versionaddendum", oVersionAddendum },
316 * Adds a local TCP/IP port forward to options. Never returns if there is an
321 add_local_forward(Options *options, const struct Forward *newfwd)
324 extern uid_t original_real_uid;
325 int i, ipport_reserved;
327 size_t len_ipport_reserved = sizeof(ipport_reserved);
329 if (sysctlbyname("net.inet.ip.portrange.reservedhigh",
330 &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0)
331 ipport_reserved = IPPORT_RESERVED;
335 ipport_reserved = IPPORT_RESERVED;
337 if (newfwd->listen_port < ipport_reserved && original_real_uid != 0 &&
338 newfwd->listen_path == NULL)
339 fatal("Privileged ports can only be forwarded by root.");
340 /* Don't add duplicates */
341 for (i = 0; i < options->num_local_forwards; i++) {
342 if (forward_equals(newfwd, options->local_forwards + i))
345 options->local_forwards = xreallocarray(options->local_forwards,
346 options->num_local_forwards + 1,
347 sizeof(*options->local_forwards));
348 fwd = &options->local_forwards[options->num_local_forwards++];
350 fwd->listen_host = newfwd->listen_host;
351 fwd->listen_port = newfwd->listen_port;
352 fwd->listen_path = newfwd->listen_path;
353 fwd->connect_host = newfwd->connect_host;
354 fwd->connect_port = newfwd->connect_port;
355 fwd->connect_path = newfwd->connect_path;
359 * Adds a remote TCP/IP port forward to options. Never returns if there is
364 add_remote_forward(Options *options, const struct Forward *newfwd)
369 /* Don't add duplicates */
370 for (i = 0; i < options->num_remote_forwards; i++) {
371 if (forward_equals(newfwd, options->remote_forwards + i))
374 options->remote_forwards = xreallocarray(options->remote_forwards,
375 options->num_remote_forwards + 1,
376 sizeof(*options->remote_forwards));
377 fwd = &options->remote_forwards[options->num_remote_forwards++];
379 fwd->listen_host = newfwd->listen_host;
380 fwd->listen_port = newfwd->listen_port;
381 fwd->listen_path = newfwd->listen_path;
382 fwd->connect_host = newfwd->connect_host;
383 fwd->connect_port = newfwd->connect_port;
384 fwd->connect_path = newfwd->connect_path;
385 fwd->handle = newfwd->handle;
386 fwd->allocated_port = 0;
390 clear_forwardings(Options *options)
394 for (i = 0; i < options->num_local_forwards; i++) {
395 free(options->local_forwards[i].listen_host);
396 free(options->local_forwards[i].listen_path);
397 free(options->local_forwards[i].connect_host);
398 free(options->local_forwards[i].connect_path);
400 if (options->num_local_forwards > 0) {
401 free(options->local_forwards);
402 options->local_forwards = NULL;
404 options->num_local_forwards = 0;
405 for (i = 0; i < options->num_remote_forwards; i++) {
406 free(options->remote_forwards[i].listen_host);
407 free(options->remote_forwards[i].listen_path);
408 free(options->remote_forwards[i].connect_host);
409 free(options->remote_forwards[i].connect_path);
411 if (options->num_remote_forwards > 0) {
412 free(options->remote_forwards);
413 options->remote_forwards = NULL;
415 options->num_remote_forwards = 0;
416 options->tun_open = SSH_TUNMODE_NO;
420 add_certificate_file(Options *options, const char *path, int userprovided)
424 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
425 fatal("Too many certificate files specified (max %d)",
426 SSH_MAX_CERTIFICATE_FILES);
428 /* Avoid registering duplicates */
429 for (i = 0; i < options->num_certificate_files; i++) {
430 if (options->certificate_file_userprovided[i] == userprovided &&
431 strcmp(options->certificate_files[i], path) == 0) {
432 debug2("%s: ignoring duplicate key %s", __func__, path);
437 options->certificate_file_userprovided[options->num_certificate_files] =
439 options->certificate_files[options->num_certificate_files++] =
444 add_identity_file(Options *options, const char *dir, const char *filename,
450 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
451 fatal("Too many identity files specified (max %d)",
452 SSH_MAX_IDENTITY_FILES);
454 if (dir == NULL) /* no dir, filename is absolute */
455 path = xstrdup(filename);
457 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
459 /* Avoid registering duplicates */
460 for (i = 0; i < options->num_identity_files; i++) {
461 if (options->identity_file_userprovided[i] == userprovided &&
462 strcmp(options->identity_files[i], path) == 0) {
463 debug2("%s: ignoring duplicate key %s", __func__, path);
469 options->identity_file_userprovided[options->num_identity_files] =
471 options->identity_files[options->num_identity_files++] = path;
475 default_ssh_port(void)
481 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
482 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
488 * Execute a command in a shell.
489 * Return its exit status or -1 on abnormal exit.
492 execute_in_shell(const char *cmd)
497 extern uid_t original_real_uid;
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 /* Child. Permanently give up superuser privileges. */
513 permanently_drop_suid(original_real_uid);
515 /* Redirect child stdin and stdout. Leave stderr */
516 if (dup2(devnull, STDIN_FILENO) == -1)
517 fatal("dup2: %s", strerror(errno));
518 if (dup2(devnull, STDOUT_FILENO) == -1)
519 fatal("dup2: %s", strerror(errno));
520 if (devnull > STDERR_FILENO)
522 closefrom(STDERR_FILENO + 1);
526 argv[2] = xstrdup(cmd);
529 execv(argv[0], argv);
530 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
531 /* Die with signal to make this error apparent to parent. */
532 signal(SIGTERM, SIG_DFL);
533 kill(getpid(), SIGTERM);
538 fatal("%s: fork: %.100s", __func__, strerror(errno));
542 while (waitpid(pid, &status, 0) == -1) {
543 if (errno != EINTR && errno != EAGAIN)
544 fatal("%s: waitpid: %s", __func__, strerror(errno));
546 if (!WIFEXITED(status)) {
547 error("command '%.100s' exited abnormally", cmd);
550 debug3("command returned status %d", WEXITSTATUS(status));
551 return WEXITSTATUS(status);
555 * Parse and execute a Match directive.
558 match_cfg_line(Options *options, char **condition, struct passwd *pw,
559 const char *host_arg, const char *original_host, int post_canon,
560 const char *filename, int linenum)
562 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
564 int r, port, this_result, result = 1, attributes = 0, negate;
565 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
568 * Configuration is likely to be incomplete at this point so we
569 * must be prepared to use default values.
571 port = options->port <= 0 ? default_ssh_port() : options->port;
572 ruser = options->user == NULL ? pw->pw_name : options->user;
574 host = xstrdup(options->hostname);
575 } else if (options->hostname != NULL) {
576 /* NB. Please keep in sync with ssh.c:main() */
577 host = percent_expand(options->hostname,
578 "h", host_arg, (char *)NULL);
580 host = xstrdup(host_arg);
583 debug2("checking match for '%s' host %s originally %s",
584 cp, host, original_host);
585 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
588 if ((negate = attrib[0] == '!'))
590 /* criteria "all" and "canonical" have no argument */
591 if (strcasecmp(attrib, "all") == 0) {
592 if (attributes > 1 ||
593 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
594 error("%.200s line %d: '%s' cannot be combined "
595 "with other Match attributes",
596 filename, linenum, oattrib);
601 result = negate ? 0 : 1;
605 if (strcasecmp(attrib, "canonical") == 0) {
606 r = !!post_canon; /* force bitmask member to boolean */
607 if (r == (negate ? 1 : 0))
608 this_result = result = 0;
609 debug3("%.200s line %d: %smatched '%s'",
611 this_result ? "" : "not ", oattrib);
614 /* All other criteria require an argument */
615 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
616 error("Missing Match criteria for %s", attrib);
620 if (strcasecmp(attrib, "host") == 0) {
621 criteria = xstrdup(host);
622 r = match_hostname(host, arg) == 1;
623 if (r == (negate ? 1 : 0))
624 this_result = result = 0;
625 } else if (strcasecmp(attrib, "originalhost") == 0) {
626 criteria = xstrdup(original_host);
627 r = match_hostname(original_host, arg) == 1;
628 if (r == (negate ? 1 : 0))
629 this_result = result = 0;
630 } else if (strcasecmp(attrib, "user") == 0) {
631 criteria = xstrdup(ruser);
632 r = match_pattern_list(ruser, arg, 0) == 1;
633 if (r == (negate ? 1 : 0))
634 this_result = result = 0;
635 } else if (strcasecmp(attrib, "localuser") == 0) {
636 criteria = xstrdup(pw->pw_name);
637 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
638 if (r == (negate ? 1 : 0))
639 this_result = result = 0;
640 } else if (strcasecmp(attrib, "exec") == 0) {
641 if (gethostname(thishost, sizeof(thishost)) == -1)
642 fatal("gethostname: %s", strerror(errno));
643 strlcpy(shorthost, thishost, sizeof(shorthost));
644 shorthost[strcspn(thishost, ".")] = '\0';
645 snprintf(portstr, sizeof(portstr), "%d", port);
647 cmd = percent_expand(arg,
658 /* skip execution if prior predicate failed */
659 debug3("%.200s line %d: skipped exec "
660 "\"%.100s\"", filename, linenum, cmd);
664 r = execute_in_shell(cmd);
666 fatal("%.200s line %d: match exec "
667 "'%.100s' error", filename,
670 criteria = xstrdup(cmd);
672 /* Force exit status to boolean */
674 if (r == (negate ? 1 : 0))
675 this_result = result = 0;
677 error("Unsupported Match attribute %s", attrib);
681 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
682 filename, linenum, this_result ? "": "not ",
686 if (attributes == 0) {
687 error("One or more attributes required for Match");
693 debug2("match %sfound", result ? "" : "not ");
699 /* Check and prepare a domain name: removes trailing '.' and lowercases */
701 valid_domain(char *name, const char *filename, int linenum)
703 size_t i, l = strlen(name);
704 u_char c, last = '\0';
707 fatal("%s line %d: empty hostname suffix", filename, linenum);
708 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
709 fatal("%s line %d: hostname suffix \"%.100s\" "
710 "starts with invalid character", filename, linenum, name);
711 for (i = 0; i < l; i++) {
712 c = tolower((u_char)name[i]);
714 if (last == '.' && c == '.')
715 fatal("%s line %d: hostname suffix \"%.100s\" contains "
716 "consecutive separators", filename, linenum, name);
717 if (c != '.' && c != '-' && !isalnum(c) &&
718 c != '_') /* technically invalid, but common */
719 fatal("%s line %d: hostname suffix \"%.100s\" contains "
720 "invalid characters", filename, linenum, name);
723 if (name[l - 1] == '.')
728 * Returns the number of the token pointed to by cp or oBadOption.
731 parse_token(const char *cp, const char *filename, int linenum,
732 const char *ignored_unknown)
736 for (i = 0; keywords[i].name; i++)
737 if (strcmp(cp, keywords[i].name) == 0)
738 return keywords[i].opcode;
739 if (ignored_unknown != NULL &&
740 match_pattern_list(cp, ignored_unknown, 1) == 1)
741 return oIgnoredUnknownOption;
742 error("%s: line %d: Bad configuration option: %s",
743 filename, linenum, cp);
747 /* Multistate option parsing */
752 static const struct multistate multistate_flag[] = {
759 static const struct multistate multistate_yesnoask[] = {
767 static const struct multistate multistate_yesnoaskconfirm[] = {
776 static const struct multistate multistate_addressfamily[] = {
778 { "inet6", AF_INET6 },
779 { "any", AF_UNSPEC },
782 static const struct multistate multistate_controlmaster[] = {
783 { "true", SSHCTL_MASTER_YES },
784 { "yes", SSHCTL_MASTER_YES },
785 { "false", SSHCTL_MASTER_NO },
786 { "no", SSHCTL_MASTER_NO },
787 { "auto", SSHCTL_MASTER_AUTO },
788 { "ask", SSHCTL_MASTER_ASK },
789 { "autoask", SSHCTL_MASTER_AUTO_ASK },
792 static const struct multistate multistate_tunnel[] = {
793 { "ethernet", SSH_TUNMODE_ETHERNET },
794 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
795 { "true", SSH_TUNMODE_DEFAULT },
796 { "yes", SSH_TUNMODE_DEFAULT },
797 { "false", SSH_TUNMODE_NO },
798 { "no", SSH_TUNMODE_NO },
801 static const struct multistate multistate_requesttty[] = {
802 { "true", REQUEST_TTY_YES },
803 { "yes", REQUEST_TTY_YES },
804 { "false", REQUEST_TTY_NO },
805 { "no", REQUEST_TTY_NO },
806 { "force", REQUEST_TTY_FORCE },
807 { "auto", REQUEST_TTY_AUTO },
810 static const struct multistate multistate_canonicalizehostname[] = {
811 { "true", SSH_CANONICALISE_YES },
812 { "false", SSH_CANONICALISE_NO },
813 { "yes", SSH_CANONICALISE_YES },
814 { "no", SSH_CANONICALISE_NO },
815 { "always", SSH_CANONICALISE_ALWAYS },
820 * Processes a single option line as used in the configuration files. This
821 * only sets those values that have not already been set.
824 process_config_line(Options *options, struct passwd *pw, const char *host,
825 const char *original_host, char *line, const char *filename,
826 int linenum, int *activep, int flags)
828 return process_config_line_depth(options, pw, host, original_host,
829 line, filename, linenum, activep, flags, 0);
832 #define WHITESPACE " \t\r\n"
834 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
835 const char *original_host, char *line, const char *filename,
836 int linenum, int *activep, int flags, int depth)
838 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
839 char **cpptr, fwdarg[256];
840 u_int i, *uintptr, max_entries = 0;
841 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
842 LogLevel *log_level_ptr;
846 const struct multistate *multistate_ptr;
847 struct allowed_cname *cname;
850 if (activep == NULL) { /* We are processing a command line directive */
855 /* Strip trailing whitespace */
856 if ((len = strlen(line)) == 0)
858 for (len--; len > 0; len--) {
859 if (strchr(WHITESPACE, line[len]) == NULL)
865 /* Get the keyword. (Each line is supposed to begin with a keyword). */
866 if ((keyword = strdelim(&s)) == NULL)
868 /* Ignore leading whitespace. */
869 if (*keyword == '\0')
870 keyword = strdelim(&s);
871 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
873 /* Match lowercase keyword */
876 opcode = parse_token(keyword, filename, linenum,
877 options->ignored_unknown);
881 /* don't panic, but count bad options */
884 case oIgnoredUnknownOption:
885 debug("%s line %d: Ignored unknown option \"%s\"",
886 filename, linenum, keyword);
888 case oConnectTimeout:
889 intptr = &options->connection_timeout;
892 if (!arg || *arg == '\0')
893 fatal("%s line %d: missing time value.",
895 if (strcmp(arg, "none") == 0)
897 else if ((value = convtime(arg)) == -1)
898 fatal("%s line %d: invalid time value.",
900 if (*activep && *intptr == -1)
905 intptr = &options->forward_agent;
907 multistate_ptr = multistate_flag;
910 if (!arg || *arg == '\0')
911 fatal("%s line %d: missing argument.",
914 for (i = 0; multistate_ptr[i].key != NULL; i++) {
915 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
916 value = multistate_ptr[i].value;
921 fatal("%s line %d: unsupported option \"%s\".",
922 filename, linenum, arg);
923 if (*activep && *intptr == -1)
928 intptr = &options->forward_x11;
931 case oForwardX11Trusted:
932 intptr = &options->forward_x11_trusted;
935 case oForwardX11Timeout:
936 intptr = &options->forward_x11_timeout;
940 intptr = &options->fwd_opts.gateway_ports;
943 case oExitOnForwardFailure:
944 intptr = &options->exit_on_forward_failure;
947 case oUsePrivilegedPort:
948 intptr = &options->use_privileged_port;
951 case oPasswordAuthentication:
952 intptr = &options->password_authentication;
955 case oKbdInteractiveAuthentication:
956 intptr = &options->kbd_interactive_authentication;
959 case oKbdInteractiveDevices:
960 charptr = &options->kbd_interactive_devices;
963 case oPubkeyAuthentication:
964 intptr = &options->pubkey_authentication;
967 case oRSAAuthentication:
968 intptr = &options->rsa_authentication;
971 case oRhostsRSAAuthentication:
972 intptr = &options->rhosts_rsa_authentication;
975 case oHostbasedAuthentication:
976 intptr = &options->hostbased_authentication;
979 case oChallengeResponseAuthentication:
980 intptr = &options->challenge_response_authentication;
983 case oGssAuthentication:
984 intptr = &options->gss_authentication;
987 case oGssDelegateCreds:
988 intptr = &options->gss_deleg_creds;
992 intptr = &options->batch_mode;
996 intptr = &options->check_host_ip;
999 case oVerifyHostKeyDNS:
1000 intptr = &options->verify_host_key_dns;
1001 multistate_ptr = multistate_yesnoask;
1002 goto parse_multistate;
1004 case oStrictHostKeyChecking:
1005 intptr = &options->strict_host_key_checking;
1006 multistate_ptr = multistate_yesnoask;
1007 goto parse_multistate;
1010 intptr = &options->compression;
1014 intptr = &options->tcp_keep_alive;
1017 case oNoHostAuthenticationForLocalhost:
1018 intptr = &options->no_host_authentication_for_localhost;
1021 case oNumberOfPasswordPrompts:
1022 intptr = &options->number_of_password_prompts;
1025 case oCompressionLevel:
1026 intptr = &options->compression_level;
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 oPKCS11Provider:
1142 charptr = &options->pkcs11_provider;
1146 charptr = &options->proxy_command;
1147 /* Ignore ProxyCommand if ProxyJump already specified */
1148 if (options->jump_host != NULL)
1149 charptr = &options->jump_host; /* Skip below */
1152 fatal("%.200s line %d: Missing argument.", filename, linenum);
1153 len = strspn(s, WHITESPACE "=");
1154 if (*activep && *charptr == NULL)
1155 *charptr = xstrdup(s + len);
1160 fatal("%.200s line %d: Missing argument.",
1163 len = strspn(s, WHITESPACE "=");
1164 if (parse_jump(s + len, options, *activep) == -1) {
1165 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1166 filename, linenum, s + len);
1171 intptr = &options->port;
1174 if (!arg || *arg == '\0')
1175 fatal("%.200s line %d: Missing argument.", filename, linenum);
1176 if (arg[0] < '0' || arg[0] > '9')
1177 fatal("%.200s line %d: Bad number.", filename, linenum);
1179 /* Octal, decimal, or hex format? */
1180 value = strtol(arg, &endofnumber, 0);
1181 if (arg == endofnumber)
1182 fatal("%.200s line %d: Bad number.", filename, linenum);
1183 if (*activep && *intptr == -1)
1187 case oConnectionAttempts:
1188 intptr = &options->connection_attempts;
1192 intptr = &options->cipher;
1194 if (!arg || *arg == '\0')
1195 fatal("%.200s line %d: Missing argument.", filename, linenum);
1196 value = cipher_number(arg);
1198 fatal("%.200s line %d: Bad cipher '%s'.",
1199 filename, linenum, arg ? arg : "<NONE>");
1200 if (*activep && *intptr == -1)
1206 if (!arg || *arg == '\0')
1207 fatal("%.200s line %d: Missing argument.", filename, linenum);
1208 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1209 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1210 filename, linenum, arg ? arg : "<NONE>");
1211 if (*activep && options->ciphers == NULL)
1212 options->ciphers = xstrdup(arg);
1217 if (!arg || *arg == '\0')
1218 fatal("%.200s line %d: Missing argument.", filename, linenum);
1219 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1220 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1221 filename, linenum, arg ? arg : "<NONE>");
1222 if (*activep && options->macs == NULL)
1223 options->macs = xstrdup(arg);
1226 case oKexAlgorithms:
1228 if (!arg || *arg == '\0')
1229 fatal("%.200s line %d: Missing argument.",
1231 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1232 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1233 filename, linenum, arg ? arg : "<NONE>");
1234 if (*activep && options->kex_algorithms == NULL)
1235 options->kex_algorithms = xstrdup(arg);
1238 case oHostKeyAlgorithms:
1239 charptr = &options->hostkeyalgorithms;
1242 if (!arg || *arg == '\0')
1243 fatal("%.200s line %d: Missing argument.",
1245 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1246 fatal("%s line %d: Bad key types '%s'.",
1247 filename, linenum, arg ? arg : "<NONE>");
1248 if (*activep && *charptr == NULL)
1249 *charptr = xstrdup(arg);
1253 intptr = &options->protocol;
1255 if (!arg || *arg == '\0')
1256 fatal("%.200s line %d: Missing argument.", filename, linenum);
1257 value = proto_spec(arg);
1258 if (value == SSH_PROTO_UNKNOWN)
1259 fatal("%.200s line %d: Bad protocol spec '%s'.",
1260 filename, linenum, arg ? arg : "<NONE>");
1261 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1266 log_level_ptr = &options->log_level;
1268 value = log_level_number(arg);
1269 if (value == SYSLOG_LEVEL_NOT_SET)
1270 fatal("%.200s line %d: unsupported log level '%s'",
1271 filename, linenum, arg ? arg : "<NONE>");
1272 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1273 *log_level_ptr = (LogLevel) value;
1277 case oRemoteForward:
1278 case oDynamicForward:
1280 if (arg == NULL || *arg == '\0')
1281 fatal("%.200s line %d: Missing port argument.",
1284 if (opcode == oLocalForward ||
1285 opcode == oRemoteForward) {
1286 arg2 = strdelim(&s);
1287 if (arg2 == NULL || *arg2 == '\0')
1288 fatal("%.200s line %d: Missing target argument.",
1291 /* construct a string for parse_forward */
1292 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1293 } else if (opcode == oDynamicForward) {
1294 strlcpy(fwdarg, arg, sizeof(fwdarg));
1297 if (parse_forward(&fwd, fwdarg,
1298 opcode == oDynamicForward ? 1 : 0,
1299 opcode == oRemoteForward ? 1 : 0) == 0)
1300 fatal("%.200s line %d: Bad forwarding specification.",
1304 if (opcode == oLocalForward ||
1305 opcode == oDynamicForward)
1306 add_local_forward(options, &fwd);
1307 else if (opcode == oRemoteForward)
1308 add_remote_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.",
1410 if (options->num_send_env >= MAX_SEND_ENV)
1411 fatal("%s line %d: too many send env.",
1413 options->send_env[options->num_send_env++] =
1419 charptr = &options->control_path;
1422 case oControlMaster:
1423 intptr = &options->control_master;
1424 multistate_ptr = multistate_controlmaster;
1425 goto parse_multistate;
1427 case oControlPersist:
1428 /* no/false/yes/true, or a time spec */
1429 intptr = &options->control_persist;
1431 if (!arg || *arg == '\0')
1432 fatal("%.200s line %d: Missing ControlPersist"
1433 " argument.", filename, linenum);
1435 value2 = 0; /* timeout */
1436 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1438 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1440 else if ((value2 = convtime(arg)) >= 0)
1443 fatal("%.200s line %d: Bad ControlPersist argument.",
1445 if (*activep && *intptr == -1) {
1447 options->control_persist_timeout = value2;
1451 case oHashKnownHosts:
1452 intptr = &options->hash_known_hosts;
1456 intptr = &options->tun_open;
1457 multistate_ptr = multistate_tunnel;
1458 goto parse_multistate;
1462 if (!arg || *arg == '\0')
1463 fatal("%.200s line %d: Missing argument.", filename, linenum);
1464 value = a2tun(arg, &value2);
1465 if (value == SSH_TUNID_ERR)
1466 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1468 options->tun_local = value;
1469 options->tun_remote = value2;
1474 charptr = &options->local_command;
1477 case oPermitLocalCommand:
1478 intptr = &options->permit_local_command;
1481 case oVisualHostKey:
1482 intptr = &options->visual_host_key;
1487 fatal("Include directive not supported as a "
1488 "command-line option");
1490 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1492 * Ensure all paths are anchored. User configuration
1493 * files may begin with '~/' but system configurations
1494 * must not. If the path is relative, then treat it
1495 * as living in ~/.ssh for user configurations or
1496 * /etc/ssh for system ones.
1498 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1499 fatal("%.200s line %d: bad include path %s.",
1500 filename, linenum, arg);
1501 if (*arg != '/' && *arg != '~') {
1502 xasprintf(&arg2, "%s/%s",
1503 (flags & SSHCONF_USERCONF) ?
1504 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1506 arg2 = xstrdup(arg);
1507 memset(&gl, 0, sizeof(gl));
1508 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1509 if (r == GLOB_NOMATCH) {
1510 debug("%.200s line %d: include %s matched no "
1511 "files",filename, linenum, arg2);
1513 } else if (r != 0 || gl.gl_pathc < 0)
1514 fatal("%.200s line %d: glob failed for %s.",
1515 filename, linenum, arg2);
1518 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1519 debug3("%.200s line %d: Including file %s "
1520 "depth %d%s", filename, linenum,
1521 gl.gl_pathv[i], depth,
1522 oactive ? "" : " (parse only)");
1523 r = read_config_file_depth(gl.gl_pathv[i],
1524 pw, host, original_host, options,
1525 flags | SSHCONF_CHECKPERM |
1526 (oactive ? 0 : SSHCONF_NEVERMATCH),
1527 activep, depth + 1);
1529 * don't let Match in includes clobber the
1530 * containing file's Match state.
1544 if ((value = parse_ipqos(arg)) == -1)
1545 fatal("%s line %d: Bad IPQoS value: %s",
1546 filename, linenum, arg);
1550 else if ((value2 = parse_ipqos(arg)) == -1)
1551 fatal("%s line %d: Bad IPQoS value: %s",
1552 filename, linenum, arg);
1554 options->ip_qos_interactive = value;
1555 options->ip_qos_bulk = value2;
1560 intptr = &options->request_tty;
1561 multistate_ptr = multistate_requesttty;
1562 goto parse_multistate;
1564 case oVersionAddendum:
1566 fatal("%.200s line %d: Missing argument.", filename,
1568 len = strspn(s, WHITESPACE);
1569 if (*activep && options->version_addendum == NULL) {
1570 if (strcasecmp(s + len, "none") == 0)
1571 options->version_addendum = xstrdup("");
1572 else if (strchr(s + len, '\r') != NULL)
1573 fatal("%.200s line %d: Invalid argument",
1576 options->version_addendum = xstrdup(s + len);
1580 case oIgnoreUnknown:
1581 charptr = &options->ignored_unknown;
1584 case oProxyUseFdpass:
1585 intptr = &options->proxy_use_fdpass;
1588 case oCanonicalDomains:
1589 value = options->num_canonical_domains != 0;
1590 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1591 valid_domain(arg, filename, linenum);
1592 if (!*activep || value)
1594 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1595 fatal("%s line %d: too many hostname suffixes.",
1597 options->canonical_domains[
1598 options->num_canonical_domains++] = xstrdup(arg);
1602 case oCanonicalizePermittedCNAMEs:
1603 value = options->num_permitted_cnames != 0;
1604 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1605 /* Either '*' for everything or 'list:list' */
1606 if (strcmp(arg, "*") == 0)
1610 if ((arg2 = strchr(arg, ':')) == NULL ||
1612 fatal("%s line %d: "
1613 "Invalid permitted CNAME \"%s\"",
1614 filename, linenum, arg);
1619 if (!*activep || value)
1621 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1622 fatal("%s line %d: too many permitted CNAMEs.",
1624 cname = options->permitted_cnames +
1625 options->num_permitted_cnames++;
1626 cname->source_list = xstrdup(arg);
1627 cname->target_list = xstrdup(arg2);
1631 case oCanonicalizeHostname:
1632 intptr = &options->canonicalize_hostname;
1633 multistate_ptr = multistate_canonicalizehostname;
1634 goto parse_multistate;
1636 case oCanonicalizeMaxDots:
1637 intptr = &options->canonicalize_max_dots;
1640 case oCanonicalizeFallbackLocal:
1641 intptr = &options->canonicalize_fallback_local;
1644 case oStreamLocalBindMask:
1646 if (!arg || *arg == '\0')
1647 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1648 /* Parse mode in octal format */
1649 value = strtol(arg, &endofnumber, 8);
1650 if (arg == endofnumber || value < 0 || value > 0777)
1651 fatal("%.200s line %d: Bad mask.", filename, linenum);
1652 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1655 case oStreamLocalBindUnlink:
1656 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1659 case oRevokedHostKeys:
1660 charptr = &options->revoked_host_keys;
1663 case oFingerprintHash:
1664 intptr = &options->fingerprint_hash;
1666 if (!arg || *arg == '\0')
1667 fatal("%.200s line %d: Missing argument.",
1669 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1670 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1671 filename, linenum, arg);
1672 if (*activep && *intptr == -1)
1676 case oUpdateHostkeys:
1677 intptr = &options->update_hostkeys;
1678 multistate_ptr = multistate_yesnoask;
1679 goto parse_multistate;
1681 case oHostbasedKeyTypes:
1682 charptr = &options->hostbased_key_types;
1683 goto parse_keytypes;
1685 case oPubkeyAcceptedKeyTypes:
1686 charptr = &options->pubkey_key_types;
1687 goto parse_keytypes;
1689 case oAddKeysToAgent:
1690 intptr = &options->add_keys_to_agent;
1691 multistate_ptr = multistate_yesnoaskconfirm;
1692 goto parse_multistate;
1694 case oIdentityAgent:
1695 charptr = &options->identity_agent;
1699 debug("%s line %d: Deprecated option \"%s\"",
1700 filename, linenum, keyword);
1704 error("%s line %d: Unsupported option \"%s\"",
1705 filename, linenum, keyword);
1709 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1712 /* Check that there is no garbage at end of line. */
1713 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1714 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1715 filename, linenum, arg);
1721 * Reads the config file and modifies the options accordingly. Options
1722 * should already be initialized before this call. This never returns if
1723 * there is an error. If the file does not exist, this returns 0.
1726 read_config_file(const char *filename, struct passwd *pw, const char *host,
1727 const char *original_host, Options *options, int flags)
1731 return read_config_file_depth(filename, pw, host, original_host,
1732 options, flags, &active, 0);
1735 #define READCONF_MAX_DEPTH 16
1737 read_config_file_depth(const char *filename, struct passwd *pw,
1738 const char *host, const char *original_host, Options *options,
1739 int flags, int *activep, int depth)
1744 int bad_options = 0;
1746 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1747 fatal("Too many recursive configuration includes");
1749 if ((f = fopen(filename, "r")) == NULL)
1752 if (flags & SSHCONF_CHECKPERM) {
1755 if (fstat(fileno(f), &sb) == -1)
1756 fatal("fstat %s: %s", filename, strerror(errno));
1757 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1758 (sb.st_mode & 022) != 0))
1759 fatal("Bad owner or permissions on %s", filename);
1762 debug("Reading configuration data %.200s", filename);
1765 * Mark that we are now processing the options. This flag is turned
1766 * on/off by Host specifications.
1769 while (fgets(line, sizeof(line), f)) {
1770 /* Update line number counter. */
1772 if (process_config_line_depth(options, pw, host, original_host,
1773 line, filename, linenum, activep, flags, depth) != 0)
1777 if (bad_options > 0)
1778 fatal("%s: terminating, %d bad configuration options",
1779 filename, bad_options);
1783 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1785 option_clear_or_none(const char *o)
1787 return o == NULL || strcasecmp(o, "none") == 0;
1791 * Initializes options to special values that indicate that they have not yet
1792 * been set. Read_config_file will only set options with this value. Options
1793 * are processed in the following order: command line, user config file,
1794 * system config file. Last, fill_default_options is called.
1798 initialize_options(Options * options)
1800 memset(options, 'X', sizeof(*options));
1801 options->version_addendum = NULL;
1802 options->forward_agent = -1;
1803 options->forward_x11 = -1;
1804 options->forward_x11_trusted = -1;
1805 options->forward_x11_timeout = -1;
1806 options->stdio_forward_host = NULL;
1807 options->stdio_forward_port = 0;
1808 options->clear_forwardings = -1;
1809 options->exit_on_forward_failure = -1;
1810 options->xauth_location = NULL;
1811 options->fwd_opts.gateway_ports = -1;
1812 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1813 options->fwd_opts.streamlocal_bind_unlink = -1;
1814 options->use_privileged_port = -1;
1815 options->rsa_authentication = -1;
1816 options->pubkey_authentication = -1;
1817 options->challenge_response_authentication = -1;
1818 options->gss_authentication = -1;
1819 options->gss_deleg_creds = -1;
1820 options->password_authentication = -1;
1821 options->kbd_interactive_authentication = -1;
1822 options->kbd_interactive_devices = NULL;
1823 options->rhosts_rsa_authentication = -1;
1824 options->hostbased_authentication = -1;
1825 options->batch_mode = -1;
1826 options->check_host_ip = -1;
1827 options->strict_host_key_checking = -1;
1828 options->compression = -1;
1829 options->tcp_keep_alive = -1;
1830 options->compression_level = -1;
1832 options->address_family = -1;
1833 options->connection_attempts = -1;
1834 options->connection_timeout = -1;
1835 options->number_of_password_prompts = -1;
1836 options->cipher = -1;
1837 options->ciphers = NULL;
1838 options->macs = NULL;
1839 options->kex_algorithms = NULL;
1840 options->hostkeyalgorithms = NULL;
1841 options->protocol = SSH_PROTO_UNKNOWN;
1842 options->num_identity_files = 0;
1843 options->num_certificate_files = 0;
1844 options->hostname = NULL;
1845 options->host_key_alias = NULL;
1846 options->proxy_command = NULL;
1847 options->jump_user = NULL;
1848 options->jump_host = NULL;
1849 options->jump_port = -1;
1850 options->jump_extra = NULL;
1851 options->user = NULL;
1852 options->escape_char = -1;
1853 options->num_system_hostfiles = 0;
1854 options->num_user_hostfiles = 0;
1855 options->local_forwards = NULL;
1856 options->num_local_forwards = 0;
1857 options->remote_forwards = NULL;
1858 options->num_remote_forwards = 0;
1859 options->log_level = SYSLOG_LEVEL_NOT_SET;
1860 options->preferred_authentications = NULL;
1861 options->bind_address = NULL;
1862 options->pkcs11_provider = NULL;
1863 options->enable_ssh_keysign = - 1;
1864 options->no_host_authentication_for_localhost = - 1;
1865 options->identities_only = - 1;
1866 options->rekey_limit = - 1;
1867 options->rekey_interval = -1;
1868 options->verify_host_key_dns = -1;
1869 options->server_alive_interval = -1;
1870 options->server_alive_count_max = -1;
1871 options->num_send_env = 0;
1872 options->control_path = NULL;
1873 options->control_master = -1;
1874 options->control_persist = -1;
1875 options->control_persist_timeout = 0;
1876 options->hash_known_hosts = -1;
1877 options->tun_open = -1;
1878 options->tun_local = -1;
1879 options->tun_remote = -1;
1880 options->local_command = NULL;
1881 options->permit_local_command = -1;
1882 options->add_keys_to_agent = -1;
1883 options->identity_agent = NULL;
1884 options->visual_host_key = -1;
1885 options->ip_qos_interactive = -1;
1886 options->ip_qos_bulk = -1;
1887 options->request_tty = -1;
1888 options->proxy_use_fdpass = -1;
1889 options->ignored_unknown = NULL;
1890 options->num_canonical_domains = 0;
1891 options->num_permitted_cnames = 0;
1892 options->canonicalize_max_dots = -1;
1893 options->canonicalize_fallback_local = -1;
1894 options->canonicalize_hostname = -1;
1895 options->revoked_host_keys = NULL;
1896 options->fingerprint_hash = -1;
1897 options->update_hostkeys = -1;
1898 options->hostbased_key_types = NULL;
1899 options->pubkey_key_types = NULL;
1903 * A petite version of fill_default_options() that just fills the options
1904 * needed for hostname canonicalization to proceed.
1907 fill_default_options_for_canonicalization(Options *options)
1909 if (options->canonicalize_max_dots == -1)
1910 options->canonicalize_max_dots = 1;
1911 if (options->canonicalize_fallback_local == -1)
1912 options->canonicalize_fallback_local = 1;
1913 if (options->canonicalize_hostname == -1)
1914 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1918 * Called after processing other sources of option data, this fills those
1919 * options for which no value has been specified with their default values.
1922 fill_default_options(Options * options)
1924 if (options->forward_agent == -1)
1925 options->forward_agent = 0;
1926 if (options->forward_x11 == -1)
1927 options->forward_x11 = 0;
1928 if (options->forward_x11_trusted == -1)
1929 options->forward_x11_trusted = 0;
1930 if (options->forward_x11_timeout == -1)
1931 options->forward_x11_timeout = 1200;
1933 * stdio forwarding (-W) changes the default for these but we defer
1934 * setting the values so they can be overridden.
1936 if (options->exit_on_forward_failure == -1)
1937 options->exit_on_forward_failure =
1938 options->stdio_forward_host != NULL ? 1 : 0;
1939 if (options->clear_forwardings == -1)
1940 options->clear_forwardings =
1941 options->stdio_forward_host != NULL ? 1 : 0;
1942 if (options->clear_forwardings == 1)
1943 clear_forwardings(options);
1945 if (options->xauth_location == NULL)
1946 options->xauth_location = _PATH_XAUTH;
1947 if (options->fwd_opts.gateway_ports == -1)
1948 options->fwd_opts.gateway_ports = 0;
1949 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1950 options->fwd_opts.streamlocal_bind_mask = 0177;
1951 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1952 options->fwd_opts.streamlocal_bind_unlink = 0;
1953 if (options->use_privileged_port == -1)
1954 options->use_privileged_port = 0;
1955 if (options->rsa_authentication == -1)
1956 options->rsa_authentication = 1;
1957 if (options->pubkey_authentication == -1)
1958 options->pubkey_authentication = 1;
1959 if (options->challenge_response_authentication == -1)
1960 options->challenge_response_authentication = 1;
1961 if (options->gss_authentication == -1)
1962 options->gss_authentication = 0;
1963 if (options->gss_deleg_creds == -1)
1964 options->gss_deleg_creds = 0;
1965 if (options->password_authentication == -1)
1966 options->password_authentication = 1;
1967 if (options->kbd_interactive_authentication == -1)
1968 options->kbd_interactive_authentication = 1;
1969 if (options->rhosts_rsa_authentication == -1)
1970 options->rhosts_rsa_authentication = 0;
1971 if (options->hostbased_authentication == -1)
1972 options->hostbased_authentication = 0;
1973 if (options->batch_mode == -1)
1974 options->batch_mode = 0;
1975 if (options->check_host_ip == -1)
1976 options->check_host_ip = 0;
1977 if (options->strict_host_key_checking == -1)
1978 options->strict_host_key_checking = 2; /* 2 is default */
1979 if (options->compression == -1)
1980 options->compression = 0;
1981 if (options->tcp_keep_alive == -1)
1982 options->tcp_keep_alive = 1;
1983 if (options->compression_level == -1)
1984 options->compression_level = 6;
1985 if (options->port == -1)
1986 options->port = 0; /* Filled in ssh_connect. */
1987 if (options->address_family == -1)
1988 options->address_family = AF_UNSPEC;
1989 if (options->connection_attempts == -1)
1990 options->connection_attempts = 1;
1991 if (options->number_of_password_prompts == -1)
1992 options->number_of_password_prompts = 3;
1993 /* Selected in ssh_login(). */
1994 if (options->cipher == -1)
1995 options->cipher = SSH_CIPHER_NOT_SET;
1996 /* options->hostkeyalgorithms, default set in myproposals.h */
1997 if (options->protocol == SSH_PROTO_UNKNOWN)
1998 options->protocol = SSH_PROTO_2;
1999 if (options->add_keys_to_agent == -1)
2000 options->add_keys_to_agent = 0;
2001 if (options->num_identity_files == 0) {
2002 if (options->protocol & SSH_PROTO_1) {
2003 add_identity_file(options, "~/",
2004 _PATH_SSH_CLIENT_IDENTITY, 0);
2006 if (options->protocol & SSH_PROTO_2) {
2007 add_identity_file(options, "~/",
2008 _PATH_SSH_CLIENT_ID_RSA, 0);
2009 add_identity_file(options, "~/",
2010 _PATH_SSH_CLIENT_ID_DSA, 0);
2011 #ifdef OPENSSL_HAS_ECC
2012 add_identity_file(options, "~/",
2013 _PATH_SSH_CLIENT_ID_ECDSA, 0);
2015 add_identity_file(options, "~/",
2016 _PATH_SSH_CLIENT_ID_ED25519, 0);
2019 if (options->escape_char == -1)
2020 options->escape_char = '~';
2021 if (options->num_system_hostfiles == 0) {
2022 options->system_hostfiles[options->num_system_hostfiles++] =
2023 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2024 options->system_hostfiles[options->num_system_hostfiles++] =
2025 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2027 if (options->num_user_hostfiles == 0) {
2028 options->user_hostfiles[options->num_user_hostfiles++] =
2029 xstrdup(_PATH_SSH_USER_HOSTFILE);
2030 options->user_hostfiles[options->num_user_hostfiles++] =
2031 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2033 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2034 options->log_level = SYSLOG_LEVEL_INFO;
2035 if (options->no_host_authentication_for_localhost == - 1)
2036 options->no_host_authentication_for_localhost = 0;
2037 if (options->identities_only == -1)
2038 options->identities_only = 0;
2039 if (options->enable_ssh_keysign == -1)
2040 options->enable_ssh_keysign = 0;
2041 if (options->rekey_limit == -1)
2042 options->rekey_limit = 0;
2043 if (options->rekey_interval == -1)
2044 options->rekey_interval = 0;
2046 if (options->verify_host_key_dns == -1)
2047 /* automatically trust a verified SSHFP record */
2048 options->verify_host_key_dns = 1;
2050 if (options->verify_host_key_dns == -1)
2051 options->verify_host_key_dns = 0;
2053 if (options->server_alive_interval == -1)
2054 options->server_alive_interval = 0;
2055 if (options->server_alive_count_max == -1)
2056 options->server_alive_count_max = 3;
2057 if (options->control_master == -1)
2058 options->control_master = 0;
2059 if (options->control_persist == -1) {
2060 options->control_persist = 0;
2061 options->control_persist_timeout = 0;
2063 if (options->hash_known_hosts == -1)
2064 options->hash_known_hosts = 0;
2065 if (options->tun_open == -1)
2066 options->tun_open = SSH_TUNMODE_NO;
2067 if (options->tun_local == -1)
2068 options->tun_local = SSH_TUNID_ANY;
2069 if (options->tun_remote == -1)
2070 options->tun_remote = SSH_TUNID_ANY;
2071 if (options->permit_local_command == -1)
2072 options->permit_local_command = 0;
2073 if (options->visual_host_key == -1)
2074 options->visual_host_key = 0;
2075 if (options->ip_qos_interactive == -1)
2076 options->ip_qos_interactive = IPTOS_LOWDELAY;
2077 if (options->ip_qos_bulk == -1)
2078 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2079 if (options->request_tty == -1)
2080 options->request_tty = REQUEST_TTY_AUTO;
2081 if (options->proxy_use_fdpass == -1)
2082 options->proxy_use_fdpass = 0;
2083 if (options->canonicalize_max_dots == -1)
2084 options->canonicalize_max_dots = 1;
2085 if (options->canonicalize_fallback_local == -1)
2086 options->canonicalize_fallback_local = 1;
2087 if (options->canonicalize_hostname == -1)
2088 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2089 if (options->fingerprint_hash == -1)
2090 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2091 if (options->update_hostkeys == -1)
2092 options->update_hostkeys = 0;
2093 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2094 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2095 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2096 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2097 &options->hostbased_key_types) != 0 ||
2098 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2099 &options->pubkey_key_types) != 0)
2100 fatal("%s: kex_assemble_names failed", __func__);
2102 #define CLEAR_ON_NONE(v) \
2104 if (option_clear_or_none(v)) { \
2109 CLEAR_ON_NONE(options->local_command);
2110 CLEAR_ON_NONE(options->proxy_command);
2111 CLEAR_ON_NONE(options->control_path);
2112 CLEAR_ON_NONE(options->revoked_host_keys);
2113 /* options->identity_agent distinguishes NULL from 'none' */
2114 /* options->user will be set in the main program if appropriate */
2115 /* options->hostname will be set in the main program if appropriate */
2116 /* options->host_key_alias should not be set by default */
2117 /* options->preferred_authentications will be set in ssh */
2118 if (options->version_addendum == NULL)
2119 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2129 * parses the next field in a port forwarding specification.
2130 * sets fwd to the parsed field and advances p past the colon
2131 * or sets it to NULL at end of string.
2132 * returns 0 on success, else non-zero.
2135 parse_fwd_field(char **p, struct fwdarg *fwd)
2142 return -1; /* end of string */
2146 * A field escaped with square brackets is used literally.
2147 * XXX - allow ']' to be escaped via backslash?
2150 /* find matching ']' */
2151 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2155 /* no matching ']' or not at end of field. */
2156 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2158 /* NUL terminate the field and advance p past the colon */
2163 fwd->ispath = ispath;
2168 for (cp = *p; *cp != '\0'; cp++) {
2171 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2185 fwd->ispath = ispath;
2192 * parses a string containing a port forwarding specification of the form:
2194 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2195 * listenpath:connectpath
2197 * [listenhost:]listenport
2198 * returns number of arguments parsed or zero on error
2201 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2203 struct fwdarg fwdargs[4];
2207 memset(fwd, 0, sizeof(*fwd));
2208 memset(fwdargs, 0, sizeof(fwdargs));
2210 cp = p = xstrdup(fwdspec);
2212 /* skip leading spaces */
2213 while (isspace((u_char)*cp))
2216 for (i = 0; i < 4; ++i) {
2217 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2221 /* Check for trailing garbage */
2222 if (cp != NULL && *cp != '\0') {
2223 i = 0; /* failure */
2228 if (fwdargs[0].ispath) {
2229 fwd->listen_path = xstrdup(fwdargs[0].arg);
2230 fwd->listen_port = PORT_STREAMLOCAL;
2232 fwd->listen_host = NULL;
2233 fwd->listen_port = a2port(fwdargs[0].arg);
2235 fwd->connect_host = xstrdup("socks");
2239 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2240 fwd->listen_path = xstrdup(fwdargs[0].arg);
2241 fwd->listen_port = PORT_STREAMLOCAL;
2242 fwd->connect_path = xstrdup(fwdargs[1].arg);
2243 fwd->connect_port = PORT_STREAMLOCAL;
2244 } else if (fwdargs[1].ispath) {
2245 fwd->listen_host = NULL;
2246 fwd->listen_port = a2port(fwdargs[0].arg);
2247 fwd->connect_path = xstrdup(fwdargs[1].arg);
2248 fwd->connect_port = PORT_STREAMLOCAL;
2250 fwd->listen_host = xstrdup(fwdargs[0].arg);
2251 fwd->listen_port = a2port(fwdargs[1].arg);
2252 fwd->connect_host = xstrdup("socks");
2257 if (fwdargs[0].ispath) {
2258 fwd->listen_path = xstrdup(fwdargs[0].arg);
2259 fwd->listen_port = PORT_STREAMLOCAL;
2260 fwd->connect_host = xstrdup(fwdargs[1].arg);
2261 fwd->connect_port = a2port(fwdargs[2].arg);
2262 } else if (fwdargs[2].ispath) {
2263 fwd->listen_host = xstrdup(fwdargs[0].arg);
2264 fwd->listen_port = a2port(fwdargs[1].arg);
2265 fwd->connect_path = xstrdup(fwdargs[2].arg);
2266 fwd->connect_port = PORT_STREAMLOCAL;
2268 fwd->listen_host = NULL;
2269 fwd->listen_port = a2port(fwdargs[0].arg);
2270 fwd->connect_host = xstrdup(fwdargs[1].arg);
2271 fwd->connect_port = a2port(fwdargs[2].arg);
2276 fwd->listen_host = xstrdup(fwdargs[0].arg);
2277 fwd->listen_port = a2port(fwdargs[1].arg);
2278 fwd->connect_host = xstrdup(fwdargs[2].arg);
2279 fwd->connect_port = a2port(fwdargs[3].arg);
2282 i = 0; /* failure */
2288 if (!(i == 1 || i == 2))
2291 if (!(i == 3 || i == 4)) {
2292 if (fwd->connect_path == NULL &&
2293 fwd->listen_path == NULL)
2296 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2300 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2301 (!remotefwd && fwd->listen_port == 0))
2303 if (fwd->connect_host != NULL &&
2304 strlen(fwd->connect_host) >= NI_MAXHOST)
2306 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2307 if (fwd->connect_path != NULL &&
2308 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2310 if (fwd->listen_host != NULL &&
2311 strlen(fwd->listen_host) >= NI_MAXHOST)
2313 if (fwd->listen_path != NULL &&
2314 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2320 free(fwd->connect_host);
2321 fwd->connect_host = NULL;
2322 free(fwd->connect_path);
2323 fwd->connect_path = NULL;
2324 free(fwd->listen_host);
2325 fwd->listen_host = NULL;
2326 free(fwd->listen_path);
2327 fwd->listen_path = NULL;
2332 parse_jump(const char *s, Options *o, int active)
2334 char *orig, *sdup, *cp;
2335 char *host = NULL, *user = NULL;
2336 int ret = -1, port = -1, first;
2338 active &= o->proxy_command == NULL && o->jump_host == NULL;
2340 orig = sdup = xstrdup(s);
2343 if ((cp = strrchr(sdup, ',')) == NULL)
2344 cp = sdup; /* last */
2349 /* First argument and configuration is active */
2350 if (parse_user_host_port(cp, &user, &host, &port) != 0)
2353 /* Subsequent argument or inactive configuration */
2354 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2357 first = 0; /* only check syntax for subsequent hosts */
2358 } while (cp != sdup);
2361 o->jump_user = user;
2362 o->jump_host = host;
2363 o->jump_port = port;
2364 o->proxy_command = xstrdup("none");
2366 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2367 o->jump_extra = xstrdup(s);
2368 o->jump_extra[cp - s] = '\0';
2379 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2381 fmt_multistate_int(int val, const struct multistate *m)
2385 for (i = 0; m[i].key != NULL; i++) {
2386 if (m[i].value == val)
2393 fmt_intarg(OpCodes code, int val)
2398 case oAddressFamily:
2399 return fmt_multistate_int(val, multistate_addressfamily);
2400 case oVerifyHostKeyDNS:
2401 case oStrictHostKeyChecking:
2402 case oUpdateHostkeys:
2403 return fmt_multistate_int(val, multistate_yesnoask);
2404 case oControlMaster:
2405 return fmt_multistate_int(val, multistate_controlmaster);
2407 return fmt_multistate_int(val, multistate_tunnel);
2409 return fmt_multistate_int(val, multistate_requesttty);
2410 case oCanonicalizeHostname:
2411 return fmt_multistate_int(val, multistate_canonicalizehostname);
2412 case oFingerprintHash:
2413 return ssh_digest_alg_name(val);
2420 case (SSH_PROTO_1|SSH_PROTO_2):
2438 lookup_opcode_name(OpCodes code)
2442 for (i = 0; keywords[i].name != NULL; i++)
2443 if (keywords[i].opcode == code)
2444 return(keywords[i].name);
2449 dump_cfg_int(OpCodes code, int val)
2451 printf("%s %d\n", lookup_opcode_name(code), val);
2455 dump_cfg_fmtint(OpCodes code, int val)
2457 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2461 dump_cfg_string(OpCodes code, const char *val)
2465 printf("%s %s\n", lookup_opcode_name(code), val);
2469 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2473 for (i = 0; i < count; i++)
2474 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2478 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2482 printf("%s", lookup_opcode_name(code));
2483 for (i = 0; i < count; i++)
2484 printf(" %s", vals[i]);
2489 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2491 const struct Forward *fwd;
2494 /* oDynamicForward */
2495 for (i = 0; i < count; i++) {
2497 if (code == oDynamicForward &&
2498 strcmp(fwd->connect_host, "socks") != 0)
2500 if (code == oLocalForward &&
2501 strcmp(fwd->connect_host, "socks") == 0)
2503 printf("%s", lookup_opcode_name(code));
2504 if (fwd->listen_port == PORT_STREAMLOCAL)
2505 printf(" %s", fwd->listen_path);
2506 else if (fwd->listen_host == NULL)
2507 printf(" %d", fwd->listen_port);
2510 fwd->listen_host, fwd->listen_port);
2512 if (code != oDynamicForward) {
2513 if (fwd->connect_port == PORT_STREAMLOCAL)
2514 printf(" %s", fwd->connect_path);
2515 else if (fwd->connect_host == NULL)
2516 printf(" %d", fwd->connect_port);
2519 fwd->connect_host, fwd->connect_port);
2527 dump_client_config(Options *o, const char *host)
2532 /* This is normally prepared in ssh_kex2 */
2533 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2534 fatal("%s: kex_assemble_names failed", __func__);
2536 /* Most interesting options first: user, host, port */
2537 dump_cfg_string(oUser, o->user);
2538 dump_cfg_string(oHostName, host);
2539 dump_cfg_int(oPort, o->port);
2542 dump_cfg_fmtint(oAddressFamily, o->address_family);
2543 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2544 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2545 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2546 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2547 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2548 dump_cfg_fmtint(oCompression, o->compression);
2549 dump_cfg_fmtint(oControlMaster, o->control_master);
2550 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2551 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2552 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2553 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2554 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2555 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2556 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2557 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2559 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2560 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2562 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2563 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2564 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2565 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2566 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2567 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2568 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2569 dump_cfg_fmtint(oProtocol, o->protocol);
2570 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2571 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2572 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2573 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2574 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2575 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2576 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2577 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2578 dump_cfg_fmtint(oTunnel, o->tun_open);
2579 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2580 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2581 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2582 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2584 /* Integer options */
2585 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2586 dump_cfg_int(oCompressionLevel, o->compression_level);
2587 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2588 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2589 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2590 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2591 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2593 /* String options */
2594 dump_cfg_string(oBindAddress, o->bind_address);
2595 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2596 dump_cfg_string(oControlPath, o->control_path);
2597 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2598 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2599 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2600 dump_cfg_string(oIdentityAgent, o->identity_agent);
2601 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2602 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2603 dump_cfg_string(oLocalCommand, o->local_command);
2604 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2605 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2606 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2607 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2608 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2609 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2610 dump_cfg_string(oXAuthLocation, o->xauth_location);
2613 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2614 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2615 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2617 /* String array options */
2618 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2619 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2620 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2621 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2622 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2626 /* oConnectTimeout */
2627 if (o->connection_timeout == -1)
2628 printf("connecttimeout none\n");
2630 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2633 printf("tunneldevice");
2634 if (o->tun_local == SSH_TUNID_ANY)
2637 printf(" %d", o->tun_local);
2638 if (o->tun_remote == SSH_TUNID_ANY)
2641 printf(":%d", o->tun_remote);
2644 /* oCanonicalizePermittedCNAMEs */
2645 if ( o->num_permitted_cnames > 0) {
2646 printf("canonicalizePermittedcnames");
2647 for (i = 0; i < o->num_permitted_cnames; i++) {
2648 printf(" %s:%s", o->permitted_cnames[i].source_list,
2649 o->permitted_cnames[i].target_list);
2655 if (o->cipher != SSH_CIPHER_NOT_SET)
2656 printf("Cipher %s\n", cipher_name(o->cipher));
2658 /* oControlPersist */
2659 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2660 dump_cfg_fmtint(oControlPersist, o->control_persist);
2662 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2665 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2666 printf("escapechar none\n");
2668 vis(buf, o->escape_char, VIS_WHITE, 0);
2669 printf("escapechar %s\n", buf);
2673 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2674 printf("%s\n", iptos2str(o->ip_qos_bulk));
2677 printf("rekeylimit %llu %d\n",
2678 (unsigned long long)o->rekey_limit, o->rekey_interval);
2680 /* oStreamLocalBindMask */
2681 printf("streamlocalbindmask 0%o\n",
2682 o->fwd_opts.streamlocal_bind_mask);
2684 /* oProxyCommand / oProxyJump */
2685 if (o->jump_host == NULL)
2686 dump_cfg_string(oProxyCommand, o->proxy_command);
2688 /* Check for numeric addresses */
2689 i = strchr(o->jump_host, ':') != NULL ||
2690 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2691 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2692 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2693 /* optional additional jump spec */
2694 o->jump_extra == NULL ? "" : o->jump_extra,
2695 o->jump_extra == NULL ? "" : ",",
2697 o->jump_user == NULL ? "" : o->jump_user,
2698 o->jump_user == NULL ? "" : "@",
2699 /* opening [ if hostname is numeric */
2701 /* mandatory hostname */
2703 /* closing ] if hostname is numeric */
2705 /* optional port number */
2706 o->jump_port <= 0 ? "" : ":",
2707 o->jump_port <= 0 ? "" : buf);