1 /* $OpenBSD: readconf.c,v 1.262 2016/10/25 04:08:13 jsg 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)
59 #include "pathnames.h"
68 #include "myproposal.h"
72 /* Format of the configuration file:
74 # Configuration data is parsed as follows:
75 # 1. command line options
76 # 2. user-specific file
78 # Any configuration value is only changed the first time it is set.
79 # Thus, host-specific definitions should be at the beginning of the
80 # configuration file, and defaults at the end.
82 # Host-specific declarations. These may override anything above. A single
83 # host may match multiple declarations; these are processed in the order
84 # that they are given in.
90 HostName another.host.name.real.org
97 RemoteForward 9999 shadows.cs.hut.fi:9999
100 Host fascist.blob.com
103 PasswordAuthentication no
107 ProxyCommand ssh-proxy %h %p
110 PublicKeyAuthentication no
114 PasswordAuthentication no
120 # Defaults for various options
124 PasswordAuthentication yes
125 RSAAuthentication yes
126 RhostsRSAAuthentication yes
127 StrictHostKeyChecking yes
129 IdentityFile ~/.ssh/identity
135 static int read_config_file_depth(const char *filename, struct passwd *pw,
136 const char *host, const char *original_host, Options *options,
137 int flags, int *activep, int depth);
138 static int process_config_line_depth(Options *options, struct passwd *pw,
139 const char *host, const char *original_host, char *line,
140 const char *filename, int linenum, int *activep, int flags, int depth);
142 /* Keyword tokens. */
147 oHost, oMatch, oInclude,
148 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
149 oGatewayPorts, oExitOnForwardFailure,
150 oPasswordAuthentication, oRSAAuthentication,
151 oChallengeResponseAuthentication, oXAuthLocation,
152 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
153 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
154 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
155 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
156 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
157 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
158 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
159 oPubkeyAuthentication,
160 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
161 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
162 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
163 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
164 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
165 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
166 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
167 oSendEnv, oControlPath, oControlMaster, oControlPersist,
169 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
171 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
172 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
173 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
174 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
175 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
176 oPubkeyAcceptedKeyTypes, oProxyJump,
177 oIgnoredUnknownOption, oDeprecated, oUnsupported
180 /* Textual representations of the tokens. */
186 { "forwardagent", oForwardAgent },
187 { "forwardx11", oForwardX11 },
188 { "forwardx11trusted", oForwardX11Trusted },
189 { "forwardx11timeout", oForwardX11Timeout },
190 { "exitonforwardfailure", oExitOnForwardFailure },
191 { "xauthlocation", oXAuthLocation },
192 { "gatewayports", oGatewayPorts },
193 { "useprivilegedport", oUsePrivilegedPort },
194 { "rhostsauthentication", oDeprecated },
195 { "passwordauthentication", oPasswordAuthentication },
196 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
197 { "kbdinteractivedevices", oKbdInteractiveDevices },
198 { "rsaauthentication", oRSAAuthentication },
199 { "pubkeyauthentication", oPubkeyAuthentication },
200 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
201 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
202 { "hostbasedauthentication", oHostbasedAuthentication },
203 { "challengeresponseauthentication", oChallengeResponseAuthentication },
204 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
205 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
206 { "kerberosauthentication", oUnsupported },
207 { "kerberostgtpassing", oUnsupported },
208 { "afstokenpassing", oUnsupported },
210 { "gssapiauthentication", oGssAuthentication },
211 { "gssapidelegatecredentials", oGssDelegateCreds },
213 { "gssapiauthentication", oUnsupported },
214 { "gssapidelegatecredentials", oUnsupported },
216 { "fallbacktorsh", oDeprecated },
217 { "usersh", oDeprecated },
218 { "identityfile", oIdentityFile },
219 { "identityfile2", oIdentityFile }, /* obsolete */
220 { "identitiesonly", oIdentitiesOnly },
221 { "certificatefile", oCertificateFile },
222 { "addkeystoagent", oAddKeysToAgent },
223 { "identityagent", oIdentityAgent },
224 { "hostname", oHostName },
225 { "hostkeyalias", oHostKeyAlias },
226 { "proxycommand", oProxyCommand },
228 { "cipher", oCipher },
229 { "ciphers", oCiphers },
231 { "protocol", oProtocol },
232 { "remoteforward", oRemoteForward },
233 { "localforward", oLocalForward },
237 { "escapechar", oEscapeChar },
238 { "globalknownhostsfile", oGlobalKnownHostsFile },
239 { "globalknownhostsfile2", oDeprecated },
240 { "userknownhostsfile", oUserKnownHostsFile },
241 { "userknownhostsfile2", oDeprecated },
242 { "connectionattempts", oConnectionAttempts },
243 { "batchmode", oBatchMode },
244 { "checkhostip", oCheckHostIP },
245 { "stricthostkeychecking", oStrictHostKeyChecking },
246 { "compression", oCompression },
247 { "compressionlevel", oCompressionLevel },
248 { "tcpkeepalive", oTCPKeepAlive },
249 { "keepalive", oTCPKeepAlive }, /* obsolete */
250 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
251 { "loglevel", oLogLevel },
252 { "dynamicforward", oDynamicForward },
253 { "preferredauthentications", oPreferredAuthentications },
254 { "hostkeyalgorithms", oHostKeyAlgorithms },
255 { "bindaddress", oBindAddress },
257 { "smartcarddevice", oPKCS11Provider },
258 { "pkcs11provider", oPKCS11Provider },
260 { "smartcarddevice", oUnsupported },
261 { "pkcs11provider", oUnsupported },
263 { "clearallforwardings", oClearAllForwardings },
264 { "enablesshkeysign", oEnableSSHKeysign },
265 { "verifyhostkeydns", oVerifyHostKeyDNS },
266 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
267 { "rekeylimit", oRekeyLimit },
268 { "connecttimeout", oConnectTimeout },
269 { "addressfamily", oAddressFamily },
270 { "serveraliveinterval", oServerAliveInterval },
271 { "serveralivecountmax", oServerAliveCountMax },
272 { "sendenv", oSendEnv },
273 { "controlpath", oControlPath },
274 { "controlmaster", oControlMaster },
275 { "controlpersist", oControlPersist },
276 { "hashknownhosts", oHashKnownHosts },
277 { "include", oInclude },
278 { "tunnel", oTunnel },
279 { "tunneldevice", oTunnelDevice },
280 { "localcommand", oLocalCommand },
281 { "permitlocalcommand", oPermitLocalCommand },
282 { "visualhostkey", oVisualHostKey },
283 { "useroaming", oDeprecated },
284 { "kexalgorithms", oKexAlgorithms },
286 { "requesttty", oRequestTTY },
287 { "proxyusefdpass", oProxyUseFdpass },
288 { "canonicaldomains", oCanonicalDomains },
289 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
290 { "canonicalizehostname", oCanonicalizeHostname },
291 { "canonicalizemaxdots", oCanonicalizeMaxDots },
292 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
293 { "streamlocalbindmask", oStreamLocalBindMask },
294 { "streamlocalbindunlink", oStreamLocalBindUnlink },
295 { "revokedhostkeys", oRevokedHostKeys },
296 { "fingerprinthash", oFingerprintHash },
297 { "updatehostkeys", oUpdateHostkeys },
298 { "hostbasedkeytypes", oHostbasedKeyTypes },
299 { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes },
300 { "ignoreunknown", oIgnoreUnknown },
301 { "proxyjump", oProxyJump },
303 { "hpndisabled", oDeprecated },
304 { "hpnbuffersize", oDeprecated },
305 { "tcprcvbufpoll", oDeprecated },
306 { "tcprcvbuf", oDeprecated },
307 { "noneenabled", oUnsupported },
308 { "noneswitch", oUnsupported },
309 { "versionaddendum", oVersionAddendum },
315 * Adds a local TCP/IP port forward to options. Never returns if there is an
320 add_local_forward(Options *options, const struct Forward *newfwd)
323 extern uid_t original_real_uid;
324 int i, ipport_reserved;
326 if (!bind_permitted(newfwd->listen_port, original_real_uid) &&
327 newfwd->listen_path == NULL)
328 fatal("Privileged ports can only be forwarded by root.");
329 /* Don't add duplicates */
330 for (i = 0; i < options->num_local_forwards; i++) {
331 if (forward_equals(newfwd, options->local_forwards + i))
334 options->local_forwards = xreallocarray(options->local_forwards,
335 options->num_local_forwards + 1,
336 sizeof(*options->local_forwards));
337 fwd = &options->local_forwards[options->num_local_forwards++];
339 fwd->listen_host = newfwd->listen_host;
340 fwd->listen_port = newfwd->listen_port;
341 fwd->listen_path = newfwd->listen_path;
342 fwd->connect_host = newfwd->connect_host;
343 fwd->connect_port = newfwd->connect_port;
344 fwd->connect_path = newfwd->connect_path;
348 * Adds a remote TCP/IP port forward to options. Never returns if there is
353 add_remote_forward(Options *options, const struct Forward *newfwd)
358 /* Don't add duplicates */
359 for (i = 0; i < options->num_remote_forwards; i++) {
360 if (forward_equals(newfwd, options->remote_forwards + i))
363 options->remote_forwards = xreallocarray(options->remote_forwards,
364 options->num_remote_forwards + 1,
365 sizeof(*options->remote_forwards));
366 fwd = &options->remote_forwards[options->num_remote_forwards++];
368 fwd->listen_host = newfwd->listen_host;
369 fwd->listen_port = newfwd->listen_port;
370 fwd->listen_path = newfwd->listen_path;
371 fwd->connect_host = newfwd->connect_host;
372 fwd->connect_port = newfwd->connect_port;
373 fwd->connect_path = newfwd->connect_path;
374 fwd->handle = newfwd->handle;
375 fwd->allocated_port = 0;
379 clear_forwardings(Options *options)
383 for (i = 0; i < options->num_local_forwards; i++) {
384 free(options->local_forwards[i].listen_host);
385 free(options->local_forwards[i].listen_path);
386 free(options->local_forwards[i].connect_host);
387 free(options->local_forwards[i].connect_path);
389 if (options->num_local_forwards > 0) {
390 free(options->local_forwards);
391 options->local_forwards = NULL;
393 options->num_local_forwards = 0;
394 for (i = 0; i < options->num_remote_forwards; i++) {
395 free(options->remote_forwards[i].listen_host);
396 free(options->remote_forwards[i].listen_path);
397 free(options->remote_forwards[i].connect_host);
398 free(options->remote_forwards[i].connect_path);
400 if (options->num_remote_forwards > 0) {
401 free(options->remote_forwards);
402 options->remote_forwards = NULL;
404 options->num_remote_forwards = 0;
405 options->tun_open = SSH_TUNMODE_NO;
409 add_certificate_file(Options *options, const char *path, int userprovided)
413 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
414 fatal("Too many certificate files specified (max %d)",
415 SSH_MAX_CERTIFICATE_FILES);
417 /* Avoid registering duplicates */
418 for (i = 0; i < options->num_certificate_files; i++) {
419 if (options->certificate_file_userprovided[i] == userprovided &&
420 strcmp(options->certificate_files[i], path) == 0) {
421 debug2("%s: ignoring duplicate key %s", __func__, path);
426 options->certificate_file_userprovided[options->num_certificate_files] =
428 options->certificate_files[options->num_certificate_files++] =
433 add_identity_file(Options *options, const char *dir, const char *filename,
439 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
440 fatal("Too many identity files specified (max %d)",
441 SSH_MAX_IDENTITY_FILES);
443 if (dir == NULL) /* no dir, filename is absolute */
444 path = xstrdup(filename);
446 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
448 /* Avoid registering duplicates */
449 for (i = 0; i < options->num_identity_files; i++) {
450 if (options->identity_file_userprovided[i] == userprovided &&
451 strcmp(options->identity_files[i], path) == 0) {
452 debug2("%s: ignoring duplicate key %s", __func__, path);
458 options->identity_file_userprovided[options->num_identity_files] =
460 options->identity_files[options->num_identity_files++] = path;
464 default_ssh_port(void)
470 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
471 port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
477 * Execute a command in a shell.
478 * Return its exit status or -1 on abnormal exit.
481 execute_in_shell(const char *cmd)
486 extern uid_t original_real_uid;
488 if ((shell = getenv("SHELL")) == NULL)
489 shell = _PATH_BSHELL;
491 /* Need this to redirect subprocess stdin/out */
492 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
493 fatal("open(/dev/null): %s", strerror(errno));
495 debug("Executing command: '%.500s'", cmd);
497 /* Fork and execute the command. */
498 if ((pid = fork()) == 0) {
501 /* Child. Permanently give up superuser privileges. */
502 permanently_drop_suid(original_real_uid);
504 /* Redirect child stdin and stdout. Leave stderr */
505 if (dup2(devnull, STDIN_FILENO) == -1)
506 fatal("dup2: %s", strerror(errno));
507 if (dup2(devnull, STDOUT_FILENO) == -1)
508 fatal("dup2: %s", strerror(errno));
509 if (devnull > STDERR_FILENO)
511 closefrom(STDERR_FILENO + 1);
515 argv[2] = xstrdup(cmd);
518 execv(argv[0], argv);
519 error("Unable to execute '%.100s': %s", cmd, strerror(errno));
520 /* Die with signal to make this error apparent to parent. */
521 signal(SIGTERM, SIG_DFL);
522 kill(getpid(), SIGTERM);
527 fatal("%s: fork: %.100s", __func__, strerror(errno));
531 while (waitpid(pid, &status, 0) == -1) {
532 if (errno != EINTR && errno != EAGAIN)
533 fatal("%s: waitpid: %s", __func__, strerror(errno));
535 if (!WIFEXITED(status)) {
536 error("command '%.100s' exited abnormally", cmd);
539 debug3("command returned status %d", WEXITSTATUS(status));
540 return WEXITSTATUS(status);
544 * Parse and execute a Match directive.
547 match_cfg_line(Options *options, char **condition, struct passwd *pw,
548 const char *host_arg, const char *original_host, int post_canon,
549 const char *filename, int linenum)
551 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
553 int r, port, this_result, result = 1, attributes = 0, negate;
554 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
557 * Configuration is likely to be incomplete at this point so we
558 * must be prepared to use default values.
560 port = options->port <= 0 ? default_ssh_port() : options->port;
561 ruser = options->user == NULL ? pw->pw_name : options->user;
563 host = xstrdup(options->hostname);
564 } else if (options->hostname != NULL) {
565 /* NB. Please keep in sync with ssh.c:main() */
566 host = percent_expand(options->hostname,
567 "h", host_arg, (char *)NULL);
569 host = xstrdup(host_arg);
572 debug2("checking match for '%s' host %s originally %s",
573 cp, host, original_host);
574 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
577 if ((negate = attrib[0] == '!'))
579 /* criteria "all" and "canonical" have no argument */
580 if (strcasecmp(attrib, "all") == 0) {
581 if (attributes > 1 ||
582 ((arg = strdelim(&cp)) != NULL && *arg != '\0')) {
583 error("%.200s line %d: '%s' cannot be combined "
584 "with other Match attributes",
585 filename, linenum, oattrib);
590 result = negate ? 0 : 1;
594 if (strcasecmp(attrib, "canonical") == 0) {
595 r = !!post_canon; /* force bitmask member to boolean */
596 if (r == (negate ? 1 : 0))
597 this_result = result = 0;
598 debug3("%.200s line %d: %smatched '%s'",
600 this_result ? "" : "not ", oattrib);
603 /* All other criteria require an argument */
604 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
605 error("Missing Match criteria for %s", attrib);
609 if (strcasecmp(attrib, "host") == 0) {
610 criteria = xstrdup(host);
611 r = match_hostname(host, arg) == 1;
612 if (r == (negate ? 1 : 0))
613 this_result = result = 0;
614 } else if (strcasecmp(attrib, "originalhost") == 0) {
615 criteria = xstrdup(original_host);
616 r = match_hostname(original_host, arg) == 1;
617 if (r == (negate ? 1 : 0))
618 this_result = result = 0;
619 } else if (strcasecmp(attrib, "user") == 0) {
620 criteria = xstrdup(ruser);
621 r = match_pattern_list(ruser, arg, 0) == 1;
622 if (r == (negate ? 1 : 0))
623 this_result = result = 0;
624 } else if (strcasecmp(attrib, "localuser") == 0) {
625 criteria = xstrdup(pw->pw_name);
626 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
627 if (r == (negate ? 1 : 0))
628 this_result = result = 0;
629 } else if (strcasecmp(attrib, "exec") == 0) {
630 if (gethostname(thishost, sizeof(thishost)) == -1)
631 fatal("gethostname: %s", strerror(errno));
632 strlcpy(shorthost, thishost, sizeof(shorthost));
633 shorthost[strcspn(thishost, ".")] = '\0';
634 snprintf(portstr, sizeof(portstr), "%d", port);
636 cmd = percent_expand(arg,
647 /* skip execution if prior predicate failed */
648 debug3("%.200s line %d: skipped exec "
649 "\"%.100s\"", filename, linenum, cmd);
653 r = execute_in_shell(cmd);
655 fatal("%.200s line %d: match exec "
656 "'%.100s' error", filename,
659 criteria = xstrdup(cmd);
661 /* Force exit status to boolean */
663 if (r == (negate ? 1 : 0))
664 this_result = result = 0;
666 error("Unsupported Match attribute %s", attrib);
670 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
671 filename, linenum, this_result ? "": "not ",
675 if (attributes == 0) {
676 error("One or more attributes required for Match");
682 debug2("match %sfound", result ? "" : "not ");
688 /* Check and prepare a domain name: removes trailing '.' and lowercases */
690 valid_domain(char *name, const char *filename, int linenum)
692 size_t i, l = strlen(name);
693 u_char c, last = '\0';
696 fatal("%s line %d: empty hostname suffix", filename, linenum);
697 if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))
698 fatal("%s line %d: hostname suffix \"%.100s\" "
699 "starts with invalid character", filename, linenum, name);
700 for (i = 0; i < l; i++) {
701 c = tolower((u_char)name[i]);
703 if (last == '.' && c == '.')
704 fatal("%s line %d: hostname suffix \"%.100s\" contains "
705 "consecutive separators", filename, linenum, name);
706 if (c != '.' && c != '-' && !isalnum(c) &&
707 c != '_') /* technically invalid, but common */
708 fatal("%s line %d: hostname suffix \"%.100s\" contains "
709 "invalid characters", filename, linenum, name);
712 if (name[l - 1] == '.')
717 * Returns the number of the token pointed to by cp or oBadOption.
720 parse_token(const char *cp, const char *filename, int linenum,
721 const char *ignored_unknown)
725 for (i = 0; keywords[i].name; i++)
726 if (strcmp(cp, keywords[i].name) == 0)
727 return keywords[i].opcode;
728 if (ignored_unknown != NULL &&
729 match_pattern_list(cp, ignored_unknown, 1) == 1)
730 return oIgnoredUnknownOption;
731 error("%s: line %d: Bad configuration option: %s",
732 filename, linenum, cp);
736 /* Multistate option parsing */
741 static const struct multistate multistate_flag[] = {
748 static const struct multistate multistate_yesnoask[] = {
756 static const struct multistate multistate_yesnoaskconfirm[] = {
765 static const struct multistate multistate_addressfamily[] = {
767 { "inet6", AF_INET6 },
768 { "any", AF_UNSPEC },
771 static const struct multistate multistate_controlmaster[] = {
772 { "true", SSHCTL_MASTER_YES },
773 { "yes", SSHCTL_MASTER_YES },
774 { "false", SSHCTL_MASTER_NO },
775 { "no", SSHCTL_MASTER_NO },
776 { "auto", SSHCTL_MASTER_AUTO },
777 { "ask", SSHCTL_MASTER_ASK },
778 { "autoask", SSHCTL_MASTER_AUTO_ASK },
781 static const struct multistate multistate_tunnel[] = {
782 { "ethernet", SSH_TUNMODE_ETHERNET },
783 { "point-to-point", SSH_TUNMODE_POINTOPOINT },
784 { "true", SSH_TUNMODE_DEFAULT },
785 { "yes", SSH_TUNMODE_DEFAULT },
786 { "false", SSH_TUNMODE_NO },
787 { "no", SSH_TUNMODE_NO },
790 static const struct multistate multistate_requesttty[] = {
791 { "true", REQUEST_TTY_YES },
792 { "yes", REQUEST_TTY_YES },
793 { "false", REQUEST_TTY_NO },
794 { "no", REQUEST_TTY_NO },
795 { "force", REQUEST_TTY_FORCE },
796 { "auto", REQUEST_TTY_AUTO },
799 static const struct multistate multistate_canonicalizehostname[] = {
800 { "true", SSH_CANONICALISE_YES },
801 { "false", SSH_CANONICALISE_NO },
802 { "yes", SSH_CANONICALISE_YES },
803 { "no", SSH_CANONICALISE_NO },
804 { "always", SSH_CANONICALISE_ALWAYS },
809 * Processes a single option line as used in the configuration files. This
810 * only sets those values that have not already been set.
813 process_config_line(Options *options, struct passwd *pw, const char *host,
814 const char *original_host, char *line, const char *filename,
815 int linenum, int *activep, int flags)
817 return process_config_line_depth(options, pw, host, original_host,
818 line, filename, linenum, activep, flags, 0);
821 #define WHITESPACE " \t\r\n"
823 process_config_line_depth(Options *options, struct passwd *pw, const char *host,
824 const char *original_host, char *line, const char *filename,
825 int linenum, int *activep, int flags, int depth)
827 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
828 char **cpptr, fwdarg[256];
829 u_int i, *uintptr, max_entries = 0;
830 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
831 LogLevel *log_level_ptr;
835 const struct multistate *multistate_ptr;
836 struct allowed_cname *cname;
839 if (activep == NULL) { /* We are processing a command line directive */
844 /* Strip trailing whitespace */
845 if ((len = strlen(line)) == 0)
847 for (len--; len > 0; len--) {
848 if (strchr(WHITESPACE, line[len]) == NULL)
854 /* Get the keyword. (Each line is supposed to begin with a keyword). */
855 if ((keyword = strdelim(&s)) == NULL)
857 /* Ignore leading whitespace. */
858 if (*keyword == '\0')
859 keyword = strdelim(&s);
860 if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
862 /* Match lowercase keyword */
865 opcode = parse_token(keyword, filename, linenum,
866 options->ignored_unknown);
870 /* don't panic, but count bad options */
872 case oIgnoredUnknownOption:
873 debug("%s line %d: Ignored unknown option \"%s\"",
874 filename, linenum, keyword);
876 case oConnectTimeout:
877 intptr = &options->connection_timeout;
880 if (!arg || *arg == '\0')
881 fatal("%s line %d: missing time value.",
883 if (strcmp(arg, "none") == 0)
885 else if ((value = convtime(arg)) == -1)
886 fatal("%s line %d: invalid time value.",
888 if (*activep && *intptr == -1)
893 intptr = &options->forward_agent;
895 multistate_ptr = multistate_flag;
898 if (!arg || *arg == '\0')
899 fatal("%s line %d: missing argument.",
902 for (i = 0; multistate_ptr[i].key != NULL; i++) {
903 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
904 value = multistate_ptr[i].value;
909 fatal("%s line %d: unsupported option \"%s\".",
910 filename, linenum, arg);
911 if (*activep && *intptr == -1)
916 intptr = &options->forward_x11;
919 case oForwardX11Trusted:
920 intptr = &options->forward_x11_trusted;
923 case oForwardX11Timeout:
924 intptr = &options->forward_x11_timeout;
928 intptr = &options->fwd_opts.gateway_ports;
931 case oExitOnForwardFailure:
932 intptr = &options->exit_on_forward_failure;
935 case oUsePrivilegedPort:
936 intptr = &options->use_privileged_port;
939 case oPasswordAuthentication:
940 intptr = &options->password_authentication;
943 case oKbdInteractiveAuthentication:
944 intptr = &options->kbd_interactive_authentication;
947 case oKbdInteractiveDevices:
948 charptr = &options->kbd_interactive_devices;
951 case oPubkeyAuthentication:
952 intptr = &options->pubkey_authentication;
955 case oRSAAuthentication:
956 intptr = &options->rsa_authentication;
959 case oRhostsRSAAuthentication:
960 intptr = &options->rhosts_rsa_authentication;
963 case oHostbasedAuthentication:
964 intptr = &options->hostbased_authentication;
967 case oChallengeResponseAuthentication:
968 intptr = &options->challenge_response_authentication;
971 case oGssAuthentication:
972 intptr = &options->gss_authentication;
975 case oGssDelegateCreds:
976 intptr = &options->gss_deleg_creds;
980 intptr = &options->batch_mode;
984 intptr = &options->check_host_ip;
987 case oVerifyHostKeyDNS:
988 intptr = &options->verify_host_key_dns;
989 multistate_ptr = multistate_yesnoask;
990 goto parse_multistate;
992 case oStrictHostKeyChecking:
993 intptr = &options->strict_host_key_checking;
994 multistate_ptr = multistate_yesnoask;
995 goto parse_multistate;
998 intptr = &options->compression;
1002 intptr = &options->tcp_keep_alive;
1005 case oNoHostAuthenticationForLocalhost:
1006 intptr = &options->no_host_authentication_for_localhost;
1009 case oNumberOfPasswordPrompts:
1010 intptr = &options->number_of_password_prompts;
1013 case oCompressionLevel:
1014 intptr = &options->compression_level;
1019 if (!arg || *arg == '\0')
1020 fatal("%.200s line %d: Missing argument.", filename,
1022 if (strcmp(arg, "default") == 0) {
1025 if (scan_scaled(arg, &val64) == -1)
1026 fatal("%.200s line %d: Bad number '%s': %s",
1027 filename, linenum, arg, strerror(errno));
1028 if (val64 != 0 && val64 < 16)
1029 fatal("%.200s line %d: RekeyLimit too small",
1032 if (*activep && options->rekey_limit == -1)
1033 options->rekey_limit = val64;
1034 if (s != NULL) { /* optional rekey interval present */
1035 if (strcmp(s, "none") == 0) {
1036 (void)strdelim(&s); /* discard */
1039 intptr = &options->rekey_interval;
1046 if (!arg || *arg == '\0')
1047 fatal("%.200s line %d: Missing argument.", filename, linenum);
1049 intptr = &options->num_identity_files;
1050 if (*intptr >= SSH_MAX_IDENTITY_FILES)
1051 fatal("%.200s line %d: Too many identity files specified (max %d).",
1052 filename, linenum, SSH_MAX_IDENTITY_FILES);
1053 add_identity_file(options, NULL,
1054 arg, flags & SSHCONF_USERCONF);
1058 case oCertificateFile:
1060 if (!arg || *arg == '\0')
1061 fatal("%.200s line %d: Missing argument.",
1064 intptr = &options->num_certificate_files;
1065 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1066 fatal("%.200s line %d: Too many certificate "
1067 "files specified (max %d).",
1069 SSH_MAX_CERTIFICATE_FILES);
1071 add_certificate_file(options, arg,
1072 flags & SSHCONF_USERCONF);
1076 case oXAuthLocation:
1077 charptr=&options->xauth_location;
1081 charptr = &options->user;
1084 if (!arg || *arg == '\0')
1085 fatal("%.200s line %d: Missing argument.",
1087 if (*activep && *charptr == NULL)
1088 *charptr = xstrdup(arg);
1091 case oGlobalKnownHostsFile:
1092 cpptr = (char **)&options->system_hostfiles;
1093 uintptr = &options->num_system_hostfiles;
1094 max_entries = SSH_MAX_HOSTS_FILES;
1096 if (*activep && *uintptr == 0) {
1097 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1098 if ((*uintptr) >= max_entries)
1099 fatal("%s line %d: "
1100 "too many authorized keys files.",
1102 cpptr[(*uintptr)++] = xstrdup(arg);
1107 case oUserKnownHostsFile:
1108 cpptr = (char **)&options->user_hostfiles;
1109 uintptr = &options->num_user_hostfiles;
1110 max_entries = SSH_MAX_HOSTS_FILES;
1111 goto parse_char_array;
1114 charptr = &options->hostname;
1118 charptr = &options->host_key_alias;
1121 case oPreferredAuthentications:
1122 charptr = &options->preferred_authentications;
1126 charptr = &options->bind_address;
1129 case oPKCS11Provider:
1130 charptr = &options->pkcs11_provider;
1134 charptr = &options->proxy_command;
1135 /* Ignore ProxyCommand if ProxyJump already specified */
1136 if (options->jump_host != NULL)
1137 charptr = &options->jump_host; /* Skip below */
1140 fatal("%.200s line %d: Missing argument.", filename, linenum);
1141 len = strspn(s, WHITESPACE "=");
1142 if (*activep && *charptr == NULL)
1143 *charptr = xstrdup(s + len);
1148 fatal("%.200s line %d: Missing argument.",
1151 len = strspn(s, WHITESPACE "=");
1152 if (parse_jump(s + len, options, *activep) == -1) {
1153 fatal("%.200s line %d: Invalid ProxyJump \"%s\"",
1154 filename, linenum, s + len);
1159 intptr = &options->port;
1162 if (!arg || *arg == '\0')
1163 fatal("%.200s line %d: Missing argument.", filename, linenum);
1164 if (arg[0] < '0' || arg[0] > '9')
1165 fatal("%.200s line %d: Bad number.", filename, linenum);
1167 /* Octal, decimal, or hex format? */
1168 value = strtol(arg, &endofnumber, 0);
1169 if (arg == endofnumber)
1170 fatal("%.200s line %d: Bad number.", filename, linenum);
1171 if (*activep && *intptr == -1)
1175 case oConnectionAttempts:
1176 intptr = &options->connection_attempts;
1180 intptr = &options->cipher;
1182 if (!arg || *arg == '\0')
1183 fatal("%.200s line %d: Missing argument.", filename, linenum);
1184 value = cipher_number(arg);
1186 fatal("%.200s line %d: Bad cipher '%s'.",
1187 filename, linenum, arg ? arg : "<NONE>");
1188 if (*activep && *intptr == -1)
1194 if (!arg || *arg == '\0')
1195 fatal("%.200s line %d: Missing argument.", filename, linenum);
1196 if (!ciphers_valid(*arg == '+' ? arg + 1 : arg))
1197 fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1198 filename, linenum, arg ? arg : "<NONE>");
1199 if (*activep && options->ciphers == NULL)
1200 options->ciphers = xstrdup(arg);
1205 if (!arg || *arg == '\0')
1206 fatal("%.200s line %d: Missing argument.", filename, linenum);
1207 if (!mac_valid(*arg == '+' ? arg + 1 : arg))
1208 fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
1209 filename, linenum, arg ? arg : "<NONE>");
1210 if (*activep && options->macs == NULL)
1211 options->macs = xstrdup(arg);
1214 case oKexAlgorithms:
1216 if (!arg || *arg == '\0')
1217 fatal("%.200s line %d: Missing argument.",
1219 if (!kex_names_valid(*arg == '+' ? arg + 1 : arg))
1220 fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1221 filename, linenum, arg ? arg : "<NONE>");
1222 if (*activep && options->kex_algorithms == NULL)
1223 options->kex_algorithms = xstrdup(arg);
1226 case oHostKeyAlgorithms:
1227 charptr = &options->hostkeyalgorithms;
1230 if (!arg || *arg == '\0')
1231 fatal("%.200s line %d: Missing argument.",
1233 if (!sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))
1234 fatal("%s line %d: Bad key types '%s'.",
1235 filename, linenum, arg ? arg : "<NONE>");
1236 if (*activep && *charptr == NULL)
1237 *charptr = xstrdup(arg);
1241 intptr = &options->protocol;
1243 if (!arg || *arg == '\0')
1244 fatal("%.200s line %d: Missing argument.", filename, linenum);
1245 value = proto_spec(arg);
1246 if (value == SSH_PROTO_UNKNOWN)
1247 fatal("%.200s line %d: Bad protocol spec '%s'.",
1248 filename, linenum, arg ? arg : "<NONE>");
1249 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1254 log_level_ptr = &options->log_level;
1256 value = log_level_number(arg);
1257 if (value == SYSLOG_LEVEL_NOT_SET)
1258 fatal("%.200s line %d: unsupported log level '%s'",
1259 filename, linenum, arg ? arg : "<NONE>");
1260 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1261 *log_level_ptr = (LogLevel) value;
1265 case oRemoteForward:
1266 case oDynamicForward:
1268 if (arg == NULL || *arg == '\0')
1269 fatal("%.200s line %d: Missing port argument.",
1272 if (opcode == oLocalForward ||
1273 opcode == oRemoteForward) {
1274 arg2 = strdelim(&s);
1275 if (arg2 == NULL || *arg2 == '\0')
1276 fatal("%.200s line %d: Missing target argument.",
1279 /* construct a string for parse_forward */
1280 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
1281 } else if (opcode == oDynamicForward) {
1282 strlcpy(fwdarg, arg, sizeof(fwdarg));
1285 if (parse_forward(&fwd, fwdarg,
1286 opcode == oDynamicForward ? 1 : 0,
1287 opcode == oRemoteForward ? 1 : 0) == 0)
1288 fatal("%.200s line %d: Bad forwarding specification.",
1292 if (opcode == oLocalForward ||
1293 opcode == oDynamicForward)
1294 add_local_forward(options, &fwd);
1295 else if (opcode == oRemoteForward)
1296 add_remote_forward(options, &fwd);
1300 case oClearAllForwardings:
1301 intptr = &options->clear_forwardings;
1306 fatal("Host directive not supported as a command-line "
1310 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1311 if ((flags & SSHCONF_NEVERMATCH) != 0)
1313 negated = *arg == '!';
1316 if (match_pattern(host, arg)) {
1318 debug("%.200s line %d: Skipping Host "
1319 "block because of negated match "
1320 "for %.100s", filename, linenum,
1326 arg2 = arg; /* logged below */
1331 debug("%.200s line %d: Applying options for %.100s",
1332 filename, linenum, arg2);
1333 /* Avoid garbage check below, as strdelim is done. */
1338 fatal("Host directive not supported as a command-line "
1340 value = match_cfg_line(options, &s, pw, host, original_host,
1341 flags & SSHCONF_POSTCANON, filename, linenum);
1343 fatal("%.200s line %d: Bad Match condition", filename,
1345 *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;
1349 intptr = &options->escape_char;
1351 if (!arg || *arg == '\0')
1352 fatal("%.200s line %d: Missing argument.", filename, linenum);
1353 if (strcmp(arg, "none") == 0)
1354 value = SSH_ESCAPECHAR_NONE;
1355 else if (arg[1] == '\0')
1356 value = (u_char) arg[0];
1357 else if (arg[0] == '^' && arg[2] == 0 &&
1358 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1359 value = (u_char) arg[1] & 31;
1361 fatal("%.200s line %d: Bad escape character.",
1364 value = 0; /* Avoid compiler warning. */
1366 if (*activep && *intptr == -1)
1370 case oAddressFamily:
1371 intptr = &options->address_family;
1372 multistate_ptr = multistate_addressfamily;
1373 goto parse_multistate;
1375 case oEnableSSHKeysign:
1376 intptr = &options->enable_ssh_keysign;
1379 case oIdentitiesOnly:
1380 intptr = &options->identities_only;
1383 case oServerAliveInterval:
1384 intptr = &options->server_alive_interval;
1387 case oServerAliveCountMax:
1388 intptr = &options->server_alive_count_max;
1392 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1393 if (strchr(arg, '=') != NULL)
1394 fatal("%s line %d: Invalid environment name.",
1398 if (options->num_send_env >= MAX_SEND_ENV)
1399 fatal("%s line %d: too many send env.",
1401 options->send_env[options->num_send_env++] =
1407 charptr = &options->control_path;
1410 case oControlMaster:
1411 intptr = &options->control_master;
1412 multistate_ptr = multistate_controlmaster;
1413 goto parse_multistate;
1415 case oControlPersist:
1416 /* no/false/yes/true, or a time spec */
1417 intptr = &options->control_persist;
1419 if (!arg || *arg == '\0')
1420 fatal("%.200s line %d: Missing ControlPersist"
1421 " argument.", filename, linenum);
1423 value2 = 0; /* timeout */
1424 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1426 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1428 else if ((value2 = convtime(arg)) >= 0)
1431 fatal("%.200s line %d: Bad ControlPersist argument.",
1433 if (*activep && *intptr == -1) {
1435 options->control_persist_timeout = value2;
1439 case oHashKnownHosts:
1440 intptr = &options->hash_known_hosts;
1444 intptr = &options->tun_open;
1445 multistate_ptr = multistate_tunnel;
1446 goto parse_multistate;
1450 if (!arg || *arg == '\0')
1451 fatal("%.200s line %d: Missing argument.", filename, linenum);
1452 value = a2tun(arg, &value2);
1453 if (value == SSH_TUNID_ERR)
1454 fatal("%.200s line %d: Bad tun device.", filename, linenum);
1456 options->tun_local = value;
1457 options->tun_remote = value2;
1462 charptr = &options->local_command;
1465 case oPermitLocalCommand:
1466 intptr = &options->permit_local_command;
1469 case oVisualHostKey:
1470 intptr = &options->visual_host_key;
1475 fatal("Include directive not supported as a "
1476 "command-line option");
1478 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1480 * Ensure all paths are anchored. User configuration
1481 * files may begin with '~/' but system configurations
1482 * must not. If the path is relative, then treat it
1483 * as living in ~/.ssh for user configurations or
1484 * /etc/ssh for system ones.
1486 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1487 fatal("%.200s line %d: bad include path %s.",
1488 filename, linenum, arg);
1489 if (*arg != '/' && *arg != '~') {
1490 xasprintf(&arg2, "%s/%s",
1491 (flags & SSHCONF_USERCONF) ?
1492 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
1494 arg2 = xstrdup(arg);
1495 memset(&gl, 0, sizeof(gl));
1496 r = glob(arg2, GLOB_TILDE, NULL, &gl);
1497 if (r == GLOB_NOMATCH) {
1498 debug("%.200s line %d: include %s matched no "
1499 "files",filename, linenum, arg2);
1501 } else if (r != 0 || gl.gl_pathc < 0)
1502 fatal("%.200s line %d: glob failed for %s.",
1503 filename, linenum, arg2);
1506 for (i = 0; i < (u_int)gl.gl_pathc; i++) {
1507 debug3("%.200s line %d: Including file %s "
1508 "depth %d%s", filename, linenum,
1509 gl.gl_pathv[i], depth,
1510 oactive ? "" : " (parse only)");
1511 r = read_config_file_depth(gl.gl_pathv[i],
1512 pw, host, original_host, options,
1513 flags | SSHCONF_CHECKPERM |
1514 (oactive ? 0 : SSHCONF_NEVERMATCH),
1515 activep, depth + 1);
1517 * don't let Match in includes clobber the
1518 * containing file's Match state.
1532 if ((value = parse_ipqos(arg)) == -1)
1533 fatal("%s line %d: Bad IPQoS value: %s",
1534 filename, linenum, arg);
1538 else if ((value2 = parse_ipqos(arg)) == -1)
1539 fatal("%s line %d: Bad IPQoS value: %s",
1540 filename, linenum, arg);
1542 options->ip_qos_interactive = value;
1543 options->ip_qos_bulk = value2;
1548 intptr = &options->request_tty;
1549 multistate_ptr = multistate_requesttty;
1550 goto parse_multistate;
1552 case oVersionAddendum:
1554 fatal("%.200s line %d: Missing argument.", filename,
1556 len = strspn(s, WHITESPACE);
1557 if (*activep && options->version_addendum == NULL) {
1558 if (strcasecmp(s + len, "none") == 0)
1559 options->version_addendum = xstrdup("");
1560 else if (strchr(s + len, '\r') != NULL)
1561 fatal("%.200s line %d: Invalid argument",
1564 options->version_addendum = xstrdup(s + len);
1568 case oIgnoreUnknown:
1569 charptr = &options->ignored_unknown;
1572 case oProxyUseFdpass:
1573 intptr = &options->proxy_use_fdpass;
1576 case oCanonicalDomains:
1577 value = options->num_canonical_domains != 0;
1578 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1579 valid_domain(arg, filename, linenum);
1580 if (!*activep || value)
1582 if (options->num_canonical_domains >= MAX_CANON_DOMAINS)
1583 fatal("%s line %d: too many hostname suffixes.",
1585 options->canonical_domains[
1586 options->num_canonical_domains++] = xstrdup(arg);
1590 case oCanonicalizePermittedCNAMEs:
1591 value = options->num_permitted_cnames != 0;
1592 while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1593 /* Either '*' for everything or 'list:list' */
1594 if (strcmp(arg, "*") == 0)
1598 if ((arg2 = strchr(arg, ':')) == NULL ||
1600 fatal("%s line %d: "
1601 "Invalid permitted CNAME \"%s\"",
1602 filename, linenum, arg);
1607 if (!*activep || value)
1609 if (options->num_permitted_cnames >= MAX_CANON_DOMAINS)
1610 fatal("%s line %d: too many permitted CNAMEs.",
1612 cname = options->permitted_cnames +
1613 options->num_permitted_cnames++;
1614 cname->source_list = xstrdup(arg);
1615 cname->target_list = xstrdup(arg2);
1619 case oCanonicalizeHostname:
1620 intptr = &options->canonicalize_hostname;
1621 multistate_ptr = multistate_canonicalizehostname;
1622 goto parse_multistate;
1624 case oCanonicalizeMaxDots:
1625 intptr = &options->canonicalize_max_dots;
1628 case oCanonicalizeFallbackLocal:
1629 intptr = &options->canonicalize_fallback_local;
1632 case oStreamLocalBindMask:
1634 if (!arg || *arg == '\0')
1635 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1636 /* Parse mode in octal format */
1637 value = strtol(arg, &endofnumber, 8);
1638 if (arg == endofnumber || value < 0 || value > 0777)
1639 fatal("%.200s line %d: Bad mask.", filename, linenum);
1640 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1643 case oStreamLocalBindUnlink:
1644 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1647 case oRevokedHostKeys:
1648 charptr = &options->revoked_host_keys;
1651 case oFingerprintHash:
1652 intptr = &options->fingerprint_hash;
1654 if (!arg || *arg == '\0')
1655 fatal("%.200s line %d: Missing argument.",
1657 if ((value = ssh_digest_alg_by_name(arg)) == -1)
1658 fatal("%.200s line %d: Invalid hash algorithm \"%s\".",
1659 filename, linenum, arg);
1660 if (*activep && *intptr == -1)
1664 case oUpdateHostkeys:
1665 intptr = &options->update_hostkeys;
1666 multistate_ptr = multistate_yesnoask;
1667 goto parse_multistate;
1669 case oHostbasedKeyTypes:
1670 charptr = &options->hostbased_key_types;
1671 goto parse_keytypes;
1673 case oPubkeyAcceptedKeyTypes:
1674 charptr = &options->pubkey_key_types;
1675 goto parse_keytypes;
1677 case oAddKeysToAgent:
1678 intptr = &options->add_keys_to_agent;
1679 multistate_ptr = multistate_yesnoaskconfirm;
1680 goto parse_multistate;
1682 case oIdentityAgent:
1683 charptr = &options->identity_agent;
1687 debug("%s line %d: Deprecated option \"%s\"",
1688 filename, linenum, keyword);
1692 error("%s line %d: Unsupported option \"%s\"",
1693 filename, linenum, keyword);
1697 fatal("%s: Unimplemented opcode %d", __func__, opcode);
1700 /* Check that there is no garbage at end of line. */
1701 if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
1702 fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
1703 filename, linenum, arg);
1709 * Reads the config file and modifies the options accordingly. Options
1710 * should already be initialized before this call. This never returns if
1711 * there is an error. If the file does not exist, this returns 0.
1714 read_config_file(const char *filename, struct passwd *pw, const char *host,
1715 const char *original_host, Options *options, int flags)
1719 return read_config_file_depth(filename, pw, host, original_host,
1720 options, flags, &active, 0);
1723 #define READCONF_MAX_DEPTH 16
1725 read_config_file_depth(const char *filename, struct passwd *pw,
1726 const char *host, const char *original_host, Options *options,
1727 int flags, int *activep, int depth)
1732 int bad_options = 0;
1734 if (depth < 0 || depth > READCONF_MAX_DEPTH)
1735 fatal("Too many recursive configuration includes");
1737 if ((f = fopen(filename, "r")) == NULL)
1740 if (flags & SSHCONF_CHECKPERM) {
1743 if (fstat(fileno(f), &sb) == -1)
1744 fatal("fstat %s: %s", filename, strerror(errno));
1745 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
1746 (sb.st_mode & 022) != 0))
1747 fatal("Bad owner or permissions on %s", filename);
1750 debug("Reading configuration data %.200s", filename);
1753 * Mark that we are now processing the options. This flag is turned
1754 * on/off by Host specifications.
1757 while (fgets(line, sizeof(line), f)) {
1758 /* Update line number counter. */
1760 if (process_config_line_depth(options, pw, host, original_host,
1761 line, filename, linenum, activep, flags, depth) != 0)
1765 if (bad_options > 0)
1766 fatal("%s: terminating, %d bad configuration options",
1767 filename, bad_options);
1771 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
1773 option_clear_or_none(const char *o)
1775 return o == NULL || strcasecmp(o, "none") == 0;
1779 * Initializes options to special values that indicate that they have not yet
1780 * been set. Read_config_file will only set options with this value. Options
1781 * are processed in the following order: command line, user config file,
1782 * system config file. Last, fill_default_options is called.
1786 initialize_options(Options * options)
1788 memset(options, 'X', sizeof(*options));
1789 options->version_addendum = NULL;
1790 options->forward_agent = -1;
1791 options->forward_x11 = -1;
1792 options->forward_x11_trusted = -1;
1793 options->forward_x11_timeout = -1;
1794 options->stdio_forward_host = NULL;
1795 options->stdio_forward_port = 0;
1796 options->clear_forwardings = -1;
1797 options->exit_on_forward_failure = -1;
1798 options->xauth_location = NULL;
1799 options->fwd_opts.gateway_ports = -1;
1800 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1801 options->fwd_opts.streamlocal_bind_unlink = -1;
1802 options->use_privileged_port = -1;
1803 options->rsa_authentication = -1;
1804 options->pubkey_authentication = -1;
1805 options->challenge_response_authentication = -1;
1806 options->gss_authentication = -1;
1807 options->gss_deleg_creds = -1;
1808 options->password_authentication = -1;
1809 options->kbd_interactive_authentication = -1;
1810 options->kbd_interactive_devices = NULL;
1811 options->rhosts_rsa_authentication = -1;
1812 options->hostbased_authentication = -1;
1813 options->batch_mode = -1;
1814 options->check_host_ip = -1;
1815 options->strict_host_key_checking = -1;
1816 options->compression = -1;
1817 options->tcp_keep_alive = -1;
1818 options->compression_level = -1;
1820 options->address_family = -1;
1821 options->connection_attempts = -1;
1822 options->connection_timeout = -1;
1823 options->number_of_password_prompts = -1;
1824 options->cipher = -1;
1825 options->ciphers = NULL;
1826 options->macs = NULL;
1827 options->kex_algorithms = NULL;
1828 options->hostkeyalgorithms = NULL;
1829 options->protocol = SSH_PROTO_UNKNOWN;
1830 options->num_identity_files = 0;
1831 options->num_certificate_files = 0;
1832 options->hostname = NULL;
1833 options->host_key_alias = NULL;
1834 options->proxy_command = NULL;
1835 options->jump_user = NULL;
1836 options->jump_host = NULL;
1837 options->jump_port = -1;
1838 options->jump_extra = NULL;
1839 options->user = NULL;
1840 options->escape_char = -1;
1841 options->num_system_hostfiles = 0;
1842 options->num_user_hostfiles = 0;
1843 options->local_forwards = NULL;
1844 options->num_local_forwards = 0;
1845 options->remote_forwards = NULL;
1846 options->num_remote_forwards = 0;
1847 options->log_level = SYSLOG_LEVEL_NOT_SET;
1848 options->preferred_authentications = NULL;
1849 options->bind_address = NULL;
1850 options->pkcs11_provider = NULL;
1851 options->enable_ssh_keysign = - 1;
1852 options->no_host_authentication_for_localhost = - 1;
1853 options->identities_only = - 1;
1854 options->rekey_limit = - 1;
1855 options->rekey_interval = -1;
1856 options->verify_host_key_dns = -1;
1857 options->server_alive_interval = -1;
1858 options->server_alive_count_max = -1;
1859 options->num_send_env = 0;
1860 options->control_path = NULL;
1861 options->control_master = -1;
1862 options->control_persist = -1;
1863 options->control_persist_timeout = 0;
1864 options->hash_known_hosts = -1;
1865 options->tun_open = -1;
1866 options->tun_local = -1;
1867 options->tun_remote = -1;
1868 options->local_command = NULL;
1869 options->permit_local_command = -1;
1870 options->add_keys_to_agent = -1;
1871 options->identity_agent = NULL;
1872 options->visual_host_key = -1;
1873 options->ip_qos_interactive = -1;
1874 options->ip_qos_bulk = -1;
1875 options->request_tty = -1;
1876 options->proxy_use_fdpass = -1;
1877 options->ignored_unknown = NULL;
1878 options->num_canonical_domains = 0;
1879 options->num_permitted_cnames = 0;
1880 options->canonicalize_max_dots = -1;
1881 options->canonicalize_fallback_local = -1;
1882 options->canonicalize_hostname = -1;
1883 options->revoked_host_keys = NULL;
1884 options->fingerprint_hash = -1;
1885 options->update_hostkeys = -1;
1886 options->hostbased_key_types = NULL;
1887 options->pubkey_key_types = NULL;
1891 * A petite version of fill_default_options() that just fills the options
1892 * needed for hostname canonicalization to proceed.
1895 fill_default_options_for_canonicalization(Options *options)
1897 if (options->canonicalize_max_dots == -1)
1898 options->canonicalize_max_dots = 1;
1899 if (options->canonicalize_fallback_local == -1)
1900 options->canonicalize_fallback_local = 1;
1901 if (options->canonicalize_hostname == -1)
1902 options->canonicalize_hostname = SSH_CANONICALISE_NO;
1906 * Called after processing other sources of option data, this fills those
1907 * options for which no value has been specified with their default values.
1910 fill_default_options(Options * options)
1912 if (options->forward_agent == -1)
1913 options->forward_agent = 0;
1914 if (options->forward_x11 == -1)
1915 options->forward_x11 = 0;
1916 if (options->forward_x11_trusted == -1)
1917 options->forward_x11_trusted = 0;
1918 if (options->forward_x11_timeout == -1)
1919 options->forward_x11_timeout = 1200;
1921 * stdio forwarding (-W) changes the default for these but we defer
1922 * setting the values so they can be overridden.
1924 if (options->exit_on_forward_failure == -1)
1925 options->exit_on_forward_failure =
1926 options->stdio_forward_host != NULL ? 1 : 0;
1927 if (options->clear_forwardings == -1)
1928 options->clear_forwardings =
1929 options->stdio_forward_host != NULL ? 1 : 0;
1930 if (options->clear_forwardings == 1)
1931 clear_forwardings(options);
1933 if (options->xauth_location == NULL)
1934 options->xauth_location = _PATH_XAUTH;
1935 if (options->fwd_opts.gateway_ports == -1)
1936 options->fwd_opts.gateway_ports = 0;
1937 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1938 options->fwd_opts.streamlocal_bind_mask = 0177;
1939 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1940 options->fwd_opts.streamlocal_bind_unlink = 0;
1941 if (options->use_privileged_port == -1)
1942 options->use_privileged_port = 0;
1943 if (options->rsa_authentication == -1)
1944 options->rsa_authentication = 1;
1945 if (options->pubkey_authentication == -1)
1946 options->pubkey_authentication = 1;
1947 if (options->challenge_response_authentication == -1)
1948 options->challenge_response_authentication = 1;
1949 if (options->gss_authentication == -1)
1950 options->gss_authentication = 0;
1951 if (options->gss_deleg_creds == -1)
1952 options->gss_deleg_creds = 0;
1953 if (options->password_authentication == -1)
1954 options->password_authentication = 1;
1955 if (options->kbd_interactive_authentication == -1)
1956 options->kbd_interactive_authentication = 1;
1957 if (options->rhosts_rsa_authentication == -1)
1958 options->rhosts_rsa_authentication = 0;
1959 if (options->hostbased_authentication == -1)
1960 options->hostbased_authentication = 0;
1961 if (options->batch_mode == -1)
1962 options->batch_mode = 0;
1963 if (options->check_host_ip == -1)
1964 options->check_host_ip = 0;
1965 if (options->strict_host_key_checking == -1)
1966 options->strict_host_key_checking = 2; /* 2 is default */
1967 if (options->compression == -1)
1968 options->compression = 0;
1969 if (options->tcp_keep_alive == -1)
1970 options->tcp_keep_alive = 1;
1971 if (options->compression_level == -1)
1972 options->compression_level = 6;
1973 if (options->port == -1)
1974 options->port = 0; /* Filled in ssh_connect. */
1975 if (options->address_family == -1)
1976 options->address_family = AF_UNSPEC;
1977 if (options->connection_attempts == -1)
1978 options->connection_attempts = 1;
1979 if (options->number_of_password_prompts == -1)
1980 options->number_of_password_prompts = 3;
1981 /* Selected in ssh_login(). */
1982 if (options->cipher == -1)
1983 options->cipher = SSH_CIPHER_NOT_SET;
1984 /* options->hostkeyalgorithms, default set in myproposals.h */
1985 if (options->protocol == SSH_PROTO_UNKNOWN)
1986 options->protocol = SSH_PROTO_2;
1987 if (options->add_keys_to_agent == -1)
1988 options->add_keys_to_agent = 0;
1989 if (options->num_identity_files == 0) {
1990 if (options->protocol & SSH_PROTO_1) {
1991 add_identity_file(options, "~/",
1992 _PATH_SSH_CLIENT_IDENTITY, 0);
1994 if (options->protocol & SSH_PROTO_2) {
1995 add_identity_file(options, "~/",
1996 _PATH_SSH_CLIENT_ID_RSA, 0);
1997 add_identity_file(options, "~/",
1998 _PATH_SSH_CLIENT_ID_DSA, 0);
1999 #ifdef OPENSSL_HAS_ECC
2000 add_identity_file(options, "~/",
2001 _PATH_SSH_CLIENT_ID_ECDSA, 0);
2003 add_identity_file(options, "~/",
2004 _PATH_SSH_CLIENT_ID_ED25519, 0);
2007 if (options->escape_char == -1)
2008 options->escape_char = '~';
2009 if (options->num_system_hostfiles == 0) {
2010 options->system_hostfiles[options->num_system_hostfiles++] =
2011 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);
2012 options->system_hostfiles[options->num_system_hostfiles++] =
2013 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);
2015 if (options->num_user_hostfiles == 0) {
2016 options->user_hostfiles[options->num_user_hostfiles++] =
2017 xstrdup(_PATH_SSH_USER_HOSTFILE);
2018 options->user_hostfiles[options->num_user_hostfiles++] =
2019 xstrdup(_PATH_SSH_USER_HOSTFILE2);
2021 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2022 options->log_level = SYSLOG_LEVEL_INFO;
2023 if (options->no_host_authentication_for_localhost == - 1)
2024 options->no_host_authentication_for_localhost = 0;
2025 if (options->identities_only == -1)
2026 options->identities_only = 0;
2027 if (options->enable_ssh_keysign == -1)
2028 options->enable_ssh_keysign = 0;
2029 if (options->rekey_limit == -1)
2030 options->rekey_limit = 0;
2031 if (options->rekey_interval == -1)
2032 options->rekey_interval = 0;
2034 if (options->verify_host_key_dns == -1)
2035 /* automatically trust a verified SSHFP record */
2036 options->verify_host_key_dns = 1;
2038 if (options->verify_host_key_dns == -1)
2039 options->verify_host_key_dns = 0;
2041 if (options->server_alive_interval == -1)
2042 options->server_alive_interval = 0;
2043 if (options->server_alive_count_max == -1)
2044 options->server_alive_count_max = 3;
2045 if (options->control_master == -1)
2046 options->control_master = 0;
2047 if (options->control_persist == -1) {
2048 options->control_persist = 0;
2049 options->control_persist_timeout = 0;
2051 if (options->hash_known_hosts == -1)
2052 options->hash_known_hosts = 0;
2053 if (options->tun_open == -1)
2054 options->tun_open = SSH_TUNMODE_NO;
2055 if (options->tun_local == -1)
2056 options->tun_local = SSH_TUNID_ANY;
2057 if (options->tun_remote == -1)
2058 options->tun_remote = SSH_TUNID_ANY;
2059 if (options->permit_local_command == -1)
2060 options->permit_local_command = 0;
2061 if (options->visual_host_key == -1)
2062 options->visual_host_key = 0;
2063 if (options->ip_qos_interactive == -1)
2064 options->ip_qos_interactive = IPTOS_LOWDELAY;
2065 if (options->ip_qos_bulk == -1)
2066 options->ip_qos_bulk = IPTOS_THROUGHPUT;
2067 if (options->request_tty == -1)
2068 options->request_tty = REQUEST_TTY_AUTO;
2069 if (options->proxy_use_fdpass == -1)
2070 options->proxy_use_fdpass = 0;
2071 if (options->canonicalize_max_dots == -1)
2072 options->canonicalize_max_dots = 1;
2073 if (options->canonicalize_fallback_local == -1)
2074 options->canonicalize_fallback_local = 1;
2075 if (options->canonicalize_hostname == -1)
2076 options->canonicalize_hostname = SSH_CANONICALISE_NO;
2077 if (options->fingerprint_hash == -1)
2078 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
2079 if (options->update_hostkeys == -1)
2080 options->update_hostkeys = 0;
2081 if (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||
2082 kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||
2083 kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||
2084 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2085 &options->hostbased_key_types) != 0 ||
2086 kex_assemble_names(KEX_DEFAULT_PK_ALG,
2087 &options->pubkey_key_types) != 0)
2088 fatal("%s: kex_assemble_names failed", __func__);
2090 #define CLEAR_ON_NONE(v) \
2092 if (option_clear_or_none(v)) { \
2097 CLEAR_ON_NONE(options->local_command);
2098 CLEAR_ON_NONE(options->proxy_command);
2099 CLEAR_ON_NONE(options->control_path);
2100 CLEAR_ON_NONE(options->revoked_host_keys);
2101 /* options->identity_agent distinguishes NULL from 'none' */
2102 /* options->user will be set in the main program if appropriate */
2103 /* options->hostname will be set in the main program if appropriate */
2104 /* options->host_key_alias should not be set by default */
2105 /* options->preferred_authentications will be set in ssh */
2106 if (options->version_addendum == NULL)
2107 options->version_addendum = xstrdup(SSH_VERSION_FREEBSD);
2117 * parses the next field in a port forwarding specification.
2118 * sets fwd to the parsed field and advances p past the colon
2119 * or sets it to NULL at end of string.
2120 * returns 0 on success, else non-zero.
2123 parse_fwd_field(char **p, struct fwdarg *fwd)
2130 return -1; /* end of string */
2134 * A field escaped with square brackets is used literally.
2135 * XXX - allow ']' to be escaped via backslash?
2138 /* find matching ']' */
2139 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2143 /* no matching ']' or not at end of field. */
2144 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2146 /* NUL terminate the field and advance p past the colon */
2151 fwd->ispath = ispath;
2156 for (cp = *p; *cp != '\0'; cp++) {
2159 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2173 fwd->ispath = ispath;
2180 * parses a string containing a port forwarding specification of the form:
2182 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2183 * listenpath:connectpath
2185 * [listenhost:]listenport
2186 * returns number of arguments parsed or zero on error
2189 parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2191 struct fwdarg fwdargs[4];
2195 memset(fwd, 0, sizeof(*fwd));
2196 memset(fwdargs, 0, sizeof(fwdargs));
2198 cp = p = xstrdup(fwdspec);
2200 /* skip leading spaces */
2201 while (isspace((u_char)*cp))
2204 for (i = 0; i < 4; ++i) {
2205 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2209 /* Check for trailing garbage */
2210 if (cp != NULL && *cp != '\0') {
2211 i = 0; /* failure */
2216 if (fwdargs[0].ispath) {
2217 fwd->listen_path = xstrdup(fwdargs[0].arg);
2218 fwd->listen_port = PORT_STREAMLOCAL;
2220 fwd->listen_host = NULL;
2221 fwd->listen_port = a2port(fwdargs[0].arg);
2223 fwd->connect_host = xstrdup("socks");
2227 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2228 fwd->listen_path = xstrdup(fwdargs[0].arg);
2229 fwd->listen_port = PORT_STREAMLOCAL;
2230 fwd->connect_path = xstrdup(fwdargs[1].arg);
2231 fwd->connect_port = PORT_STREAMLOCAL;
2232 } else if (fwdargs[1].ispath) {
2233 fwd->listen_host = NULL;
2234 fwd->listen_port = a2port(fwdargs[0].arg);
2235 fwd->connect_path = xstrdup(fwdargs[1].arg);
2236 fwd->connect_port = PORT_STREAMLOCAL;
2238 fwd->listen_host = xstrdup(fwdargs[0].arg);
2239 fwd->listen_port = a2port(fwdargs[1].arg);
2240 fwd->connect_host = xstrdup("socks");
2245 if (fwdargs[0].ispath) {
2246 fwd->listen_path = xstrdup(fwdargs[0].arg);
2247 fwd->listen_port = PORT_STREAMLOCAL;
2248 fwd->connect_host = xstrdup(fwdargs[1].arg);
2249 fwd->connect_port = a2port(fwdargs[2].arg);
2250 } else if (fwdargs[2].ispath) {
2251 fwd->listen_host = xstrdup(fwdargs[0].arg);
2252 fwd->listen_port = a2port(fwdargs[1].arg);
2253 fwd->connect_path = xstrdup(fwdargs[2].arg);
2254 fwd->connect_port = PORT_STREAMLOCAL;
2256 fwd->listen_host = NULL;
2257 fwd->listen_port = a2port(fwdargs[0].arg);
2258 fwd->connect_host = xstrdup(fwdargs[1].arg);
2259 fwd->connect_port = a2port(fwdargs[2].arg);
2264 fwd->listen_host = xstrdup(fwdargs[0].arg);
2265 fwd->listen_port = a2port(fwdargs[1].arg);
2266 fwd->connect_host = xstrdup(fwdargs[2].arg);
2267 fwd->connect_port = a2port(fwdargs[3].arg);
2270 i = 0; /* failure */
2276 if (!(i == 1 || i == 2))
2279 if (!(i == 3 || i == 4)) {
2280 if (fwd->connect_path == NULL &&
2281 fwd->listen_path == NULL)
2284 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
2288 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
2289 (!remotefwd && fwd->listen_port == 0))
2291 if (fwd->connect_host != NULL &&
2292 strlen(fwd->connect_host) >= NI_MAXHOST)
2294 /* XXX - if connecting to a remote socket, max sun len may not match this host */
2295 if (fwd->connect_path != NULL &&
2296 strlen(fwd->connect_path) >= PATH_MAX_SUN)
2298 if (fwd->listen_host != NULL &&
2299 strlen(fwd->listen_host) >= NI_MAXHOST)
2301 if (fwd->listen_path != NULL &&
2302 strlen(fwd->listen_path) >= PATH_MAX_SUN)
2308 free(fwd->connect_host);
2309 fwd->connect_host = NULL;
2310 free(fwd->connect_path);
2311 fwd->connect_path = NULL;
2312 free(fwd->listen_host);
2313 fwd->listen_host = NULL;
2314 free(fwd->listen_path);
2315 fwd->listen_path = NULL;
2320 parse_jump(const char *s, Options *o, int active)
2322 char *orig, *sdup, *cp;
2323 char *host = NULL, *user = NULL;
2324 int ret = -1, port = -1, first;
2326 active &= o->proxy_command == NULL && o->jump_host == NULL;
2328 orig = sdup = xstrdup(s);
2331 if ((cp = strrchr(sdup, ',')) == NULL)
2332 cp = sdup; /* last */
2337 /* First argument and configuration is active */
2338 if (parse_user_host_port(cp, &user, &host, &port) != 0)
2341 /* Subsequent argument or inactive configuration */
2342 if (parse_user_host_port(cp, NULL, NULL, NULL) != 0)
2345 first = 0; /* only check syntax for subsequent hosts */
2346 } while (cp != sdup);
2349 o->jump_user = user;
2350 o->jump_host = host;
2351 o->jump_port = port;
2352 o->proxy_command = xstrdup("none");
2354 if ((cp = strrchr(s, ',')) != NULL && cp != s) {
2355 o->jump_extra = xstrdup(s);
2356 o->jump_extra[cp - s] = '\0';
2367 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
2369 fmt_multistate_int(int val, const struct multistate *m)
2373 for (i = 0; m[i].key != NULL; i++) {
2374 if (m[i].value == val)
2381 fmt_intarg(OpCodes code, int val)
2386 case oAddressFamily:
2387 return fmt_multistate_int(val, multistate_addressfamily);
2388 case oVerifyHostKeyDNS:
2389 case oStrictHostKeyChecking:
2390 case oUpdateHostkeys:
2391 return fmt_multistate_int(val, multistate_yesnoask);
2392 case oControlMaster:
2393 return fmt_multistate_int(val, multistate_controlmaster);
2395 return fmt_multistate_int(val, multistate_tunnel);
2397 return fmt_multistate_int(val, multistate_requesttty);
2398 case oCanonicalizeHostname:
2399 return fmt_multistate_int(val, multistate_canonicalizehostname);
2400 case oFingerprintHash:
2401 return ssh_digest_alg_name(val);
2408 case (SSH_PROTO_1|SSH_PROTO_2):
2426 lookup_opcode_name(OpCodes code)
2430 for (i = 0; keywords[i].name != NULL; i++)
2431 if (keywords[i].opcode == code)
2432 return(keywords[i].name);
2437 dump_cfg_int(OpCodes code, int val)
2439 printf("%s %d\n", lookup_opcode_name(code), val);
2443 dump_cfg_fmtint(OpCodes code, int val)
2445 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
2449 dump_cfg_string(OpCodes code, const char *val)
2453 printf("%s %s\n", lookup_opcode_name(code), val);
2457 dump_cfg_strarray(OpCodes code, u_int count, char **vals)
2461 for (i = 0; i < count; i++)
2462 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
2466 dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
2470 printf("%s", lookup_opcode_name(code));
2471 for (i = 0; i < count; i++)
2472 printf(" %s", vals[i]);
2477 dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
2479 const struct Forward *fwd;
2482 /* oDynamicForward */
2483 for (i = 0; i < count; i++) {
2485 if (code == oDynamicForward &&
2486 strcmp(fwd->connect_host, "socks") != 0)
2488 if (code == oLocalForward &&
2489 strcmp(fwd->connect_host, "socks") == 0)
2491 printf("%s", lookup_opcode_name(code));
2492 if (fwd->listen_port == PORT_STREAMLOCAL)
2493 printf(" %s", fwd->listen_path);
2494 else if (fwd->listen_host == NULL)
2495 printf(" %d", fwd->listen_port);
2498 fwd->listen_host, fwd->listen_port);
2500 if (code != oDynamicForward) {
2501 if (fwd->connect_port == PORT_STREAMLOCAL)
2502 printf(" %s", fwd->connect_path);
2503 else if (fwd->connect_host == NULL)
2504 printf(" %d", fwd->connect_port);
2507 fwd->connect_host, fwd->connect_port);
2515 dump_client_config(Options *o, const char *host)
2520 /* This is normally prepared in ssh_kex2 */
2521 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2522 fatal("%s: kex_assemble_names failed", __func__);
2524 /* Most interesting options first: user, host, port */
2525 dump_cfg_string(oUser, o->user);
2526 dump_cfg_string(oHostName, host);
2527 dump_cfg_int(oPort, o->port);
2530 dump_cfg_fmtint(oAddressFamily, o->address_family);
2531 dump_cfg_fmtint(oBatchMode, o->batch_mode);
2532 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
2533 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
2534 dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);
2535 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
2536 dump_cfg_fmtint(oCompression, o->compression);
2537 dump_cfg_fmtint(oControlMaster, o->control_master);
2538 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
2539 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
2540 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
2541 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
2542 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
2543 dump_cfg_fmtint(oForwardX11, o->forward_x11);
2544 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
2545 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2547 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2548 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2550 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2551 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
2552 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
2553 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
2554 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2555 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2556 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2557 dump_cfg_fmtint(oProtocol, o->protocol);
2558 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2559 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2560 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2561 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2562 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2563 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2564 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2565 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
2566 dump_cfg_fmtint(oTunnel, o->tun_open);
2567 dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);
2568 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
2569 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
2570 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
2572 /* Integer options */
2573 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2574 dump_cfg_int(oCompressionLevel, o->compression_level);
2575 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2576 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2577 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
2578 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
2579 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
2581 /* String options */
2582 dump_cfg_string(oBindAddress, o->bind_address);
2583 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2584 dump_cfg_string(oControlPath, o->control_path);
2585 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2586 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2587 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2588 dump_cfg_string(oIdentityAgent, o->identity_agent);
2589 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2590 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2591 dump_cfg_string(oLocalCommand, o->local_command);
2592 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2593 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2594 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2595 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2596 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2597 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2598 dump_cfg_string(oXAuthLocation, o->xauth_location);
2601 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
2602 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
2603 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
2605 /* String array options */
2606 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
2607 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
2608 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
2609 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
2610 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
2614 /* oConnectTimeout */
2615 if (o->connection_timeout == -1)
2616 printf("connecttimeout none\n");
2618 dump_cfg_int(oConnectTimeout, o->connection_timeout);
2621 printf("tunneldevice");
2622 if (o->tun_local == SSH_TUNID_ANY)
2625 printf(" %d", o->tun_local);
2626 if (o->tun_remote == SSH_TUNID_ANY)
2629 printf(":%d", o->tun_remote);
2632 /* oCanonicalizePermittedCNAMEs */
2633 if ( o->num_permitted_cnames > 0) {
2634 printf("canonicalizePermittedcnames");
2635 for (i = 0; i < o->num_permitted_cnames; i++) {
2636 printf(" %s:%s", o->permitted_cnames[i].source_list,
2637 o->permitted_cnames[i].target_list);
2643 if (o->cipher != SSH_CIPHER_NOT_SET)
2644 printf("Cipher %s\n", cipher_name(o->cipher));
2646 /* oControlPersist */
2647 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2648 dump_cfg_fmtint(oControlPersist, o->control_persist);
2650 dump_cfg_int(oControlPersist, o->control_persist_timeout);
2653 if (o->escape_char == SSH_ESCAPECHAR_NONE)
2654 printf("escapechar none\n");
2656 vis(buf, o->escape_char, VIS_WHITE, 0);
2657 printf("escapechar %s\n", buf);
2661 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
2662 printf("%s\n", iptos2str(o->ip_qos_bulk));
2665 printf("rekeylimit %llu %d\n",
2666 (unsigned long long)o->rekey_limit, o->rekey_interval);
2668 /* oStreamLocalBindMask */
2669 printf("streamlocalbindmask 0%o\n",
2670 o->fwd_opts.streamlocal_bind_mask);
2672 /* oProxyCommand / oProxyJump */
2673 if (o->jump_host == NULL)
2674 dump_cfg_string(oProxyCommand, o->proxy_command);
2676 /* Check for numeric addresses */
2677 i = strchr(o->jump_host, ':') != NULL ||
2678 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
2679 snprintf(buf, sizeof(buf), "%d", o->jump_port);
2680 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
2681 /* optional additional jump spec */
2682 o->jump_extra == NULL ? "" : o->jump_extra,
2683 o->jump_extra == NULL ? "" : ",",
2685 o->jump_user == NULL ? "" : o->jump_user,
2686 o->jump_user == NULL ? "" : "@",
2687 /* opening [ if hostname is numeric */
2689 /* mandatory hostname */
2691 /* closing ] if hostname is numeric */
2693 /* optional port number */
2694 o->jump_port <= 0 ? "" : ":",
2695 o->jump_port <= 0 ? "" : buf);