1 /* $OpenBSD: readconf.c,v 1.369 2022/09/17 10:33:18 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".
17 #include <sys/types.h>
19 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netinet/in_systm.h>
25 #include <netinet/ip.h>
26 #include <arpa/inet.h>
42 #ifdef USE_SYSTEM_GLOB
45 # include "openbsd-compat/glob.h"
50 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
59 #include "pathnames.h"
68 #include "myproposal.h"
71 /* Format of the configuration file:
73 # Configuration data is parsed as follows:
74 # 1. command line options
75 # 2. user-specific file
77 # Any configuration value is only changed the first time it is set.
78 # Thus, host-specific definitions should be at the beginning of the
79 # configuration file, and defaults at the end.
81 # Host-specific declarations. These may override anything above. A single
82 # host may match multiple declarations; these are processed in the order
83 # that they are given in.
89 Hostname another.host.name.real.org
96 RemoteForward 9999 shadows.cs.hut.fi:9999
102 PasswordAuthentication no
106 ProxyCommand ssh-proxy %h %p
109 PublicKeyAuthentication no
113 PasswordAuthentication no
119 # Defaults for various options
123 PasswordAuthentication yes
124 StrictHostKeyChecking yes
126 IdentityFile ~/.ssh/identity
132 static int read_config_file_depth(const char *filename
, struct passwd
*pw
,
133 const char *host
, const char *original_host
, Options
*options
,
134 int flags
, int *activep
, int *want_final_pass
, int depth
);
135 static int process_config_line_depth(Options
*options
, struct passwd
*pw
,
136 const char *host
, const char *original_host
, char *line
,
137 const char *filename
, int linenum
, int *activep
, int flags
,
138 int *want_final_pass
, int depth
);
140 /* Keyword tokens. */
144 oHost
, oMatch
, oInclude
,
145 oForwardAgent
, oForwardX11
, oForwardX11Trusted
, oForwardX11Timeout
,
146 oGatewayPorts
, oExitOnForwardFailure
,
147 oPasswordAuthentication
,
149 oIdentityFile
, oHostname
, oPort
, oRemoteForward
, oLocalForward
,
151 oCertificateFile
, oAddKeysToAgent
, oIdentityAgent
,
152 oUser
, oEscapeChar
, oProxyCommand
,
153 oGlobalKnownHostsFile
, oUserKnownHostsFile
, oConnectionAttempts
,
154 oBatchMode
, oCheckHostIP
, oStrictHostKeyChecking
, oCompression
,
155 oTCPKeepAlive
, oNumberOfPasswordPrompts
,
156 oLogFacility
, oLogLevel
, oLogVerbose
, oCiphers
, oMacs
,
157 oPubkeyAuthentication
,
158 oKbdInteractiveAuthentication
, oKbdInteractiveDevices
, oHostKeyAlias
,
159 oDynamicForward
, oPreferredAuthentications
, oHostbasedAuthentication
,
160 oHostKeyAlgorithms
, oBindAddress
, oBindInterface
, oPKCS11Provider
,
161 oClearAllForwardings
, oNoHostAuthenticationForLocalhost
,
162 oEnableSSHKeysign
, oRekeyLimit
, oVerifyHostKeyDNS
, oConnectTimeout
,
163 oAddressFamily
, oGssAuthentication
, oGssDelegateCreds
,
164 oServerAliveInterval
, oServerAliveCountMax
, oIdentitiesOnly
,
165 oSendEnv
, oSetEnv
, oControlPath
, oControlMaster
, oControlPersist
,
167 oTunnel
, oTunnelDevice
,
168 oLocalCommand
, oPermitLocalCommand
, oRemoteCommand
,
170 oKexAlgorithms
, oIPQoS
, oRequestTTY
, oSessionType
, oStdinNull
,
171 oForkAfterAuthentication
, oIgnoreUnknown
, oProxyUseFdpass
,
172 oCanonicalDomains
, oCanonicalizeHostname
, oCanonicalizeMaxDots
,
173 oCanonicalizeFallbackLocal
, oCanonicalizePermittedCNAMEs
,
174 oStreamLocalBindMask
, oStreamLocalBindUnlink
, oRevokedHostKeys
,
175 oFingerprintHash
, oUpdateHostkeys
, oHostbasedAcceptedAlgorithms
,
176 oPubkeyAcceptedAlgorithms
, oCASignatureAlgorithms
, oProxyJump
,
177 oSecurityKeyProvider
, oKnownHostsCommand
, oRequiredRSASize
,
178 oIgnore
, oIgnoredUnknownOption
, oDeprecated
, oUnsupported
181 /* Textual representations of the tokens. */
187 /* Deprecated options */
188 { "protocol", oIgnore
}, /* NB. silently ignored */
189 { "cipher", oDeprecated
},
190 { "fallbacktorsh", oDeprecated
},
191 { "globalknownhostsfile2", oDeprecated
},
192 { "rhostsauthentication", oDeprecated
},
193 { "userknownhostsfile2", oDeprecated
},
194 { "useroaming", oDeprecated
},
195 { "usersh", oDeprecated
},
196 { "useprivilegedport", oDeprecated
},
198 /* Unsupported options */
199 { "afstokenpassing", oUnsupported
},
200 { "kerberosauthentication", oUnsupported
},
201 { "kerberostgtpassing", oUnsupported
},
202 { "rsaauthentication", oUnsupported
},
203 { "rhostsrsaauthentication", oUnsupported
},
204 { "compressionlevel", oUnsupported
},
206 /* Sometimes-unsupported options */
208 { "gssapiauthentication", oGssAuthentication
},
209 { "gssapidelegatecredentials", oGssDelegateCreds
},
211 { "gssapiauthentication", oUnsupported
},
212 { "gssapidelegatecredentials", oUnsupported
},
215 { "pkcs11provider", oPKCS11Provider
},
216 { "smartcarddevice", oPKCS11Provider
},
218 { "smartcarddevice", oUnsupported
},
219 { "pkcs11provider", oUnsupported
},
222 { "forwardagent", oForwardAgent
},
223 { "forwardx11", oForwardX11
},
224 { "forwardx11trusted", oForwardX11Trusted
},
225 { "forwardx11timeout", oForwardX11Timeout
},
226 { "exitonforwardfailure", oExitOnForwardFailure
},
227 { "xauthlocation", oXAuthLocation
},
228 { "gatewayports", oGatewayPorts
},
229 { "passwordauthentication", oPasswordAuthentication
},
230 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication
},
231 { "kbdinteractivedevices", oKbdInteractiveDevices
},
232 { "challengeresponseauthentication", oKbdInteractiveAuthentication
}, /* alias */
233 { "skeyauthentication", oKbdInteractiveAuthentication
}, /* alias */
234 { "tisauthentication", oKbdInteractiveAuthentication
}, /* alias */
235 { "pubkeyauthentication", oPubkeyAuthentication
},
236 { "dsaauthentication", oPubkeyAuthentication
}, /* alias */
237 { "hostbasedauthentication", oHostbasedAuthentication
},
238 { "identityfile", oIdentityFile
},
239 { "identityfile2", oIdentityFile
}, /* obsolete */
240 { "identitiesonly", oIdentitiesOnly
},
241 { "certificatefile", oCertificateFile
},
242 { "addkeystoagent", oAddKeysToAgent
},
243 { "identityagent", oIdentityAgent
},
244 { "hostname", oHostname
},
245 { "hostkeyalias", oHostKeyAlias
},
246 { "proxycommand", oProxyCommand
},
248 { "ciphers", oCiphers
},
250 { "remoteforward", oRemoteForward
},
251 { "localforward", oLocalForward
},
252 { "permitremoteopen", oPermitRemoteOpen
},
256 { "escapechar", oEscapeChar
},
257 { "globalknownhostsfile", oGlobalKnownHostsFile
},
258 { "userknownhostsfile", oUserKnownHostsFile
},
259 { "connectionattempts", oConnectionAttempts
},
260 { "batchmode", oBatchMode
},
261 { "checkhostip", oCheckHostIP
},
262 { "stricthostkeychecking", oStrictHostKeyChecking
},
263 { "compression", oCompression
},
264 { "tcpkeepalive", oTCPKeepAlive
},
265 { "keepalive", oTCPKeepAlive
}, /* obsolete */
266 { "numberofpasswordprompts", oNumberOfPasswordPrompts
},
267 { "syslogfacility", oLogFacility
},
268 { "loglevel", oLogLevel
},
269 { "logverbose", oLogVerbose
},
270 { "dynamicforward", oDynamicForward
},
271 { "preferredauthentications", oPreferredAuthentications
},
272 { "hostkeyalgorithms", oHostKeyAlgorithms
},
273 { "casignaturealgorithms", oCASignatureAlgorithms
},
274 { "bindaddress", oBindAddress
},
275 { "bindinterface", oBindInterface
},
276 { "clearallforwardings", oClearAllForwardings
},
277 { "enablesshkeysign", oEnableSSHKeysign
},
278 { "verifyhostkeydns", oVerifyHostKeyDNS
},
279 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost
},
280 { "rekeylimit", oRekeyLimit
},
281 { "connecttimeout", oConnectTimeout
},
282 { "addressfamily", oAddressFamily
},
283 { "serveraliveinterval", oServerAliveInterval
},
284 { "serveralivecountmax", oServerAliveCountMax
},
285 { "sendenv", oSendEnv
},
286 { "setenv", oSetEnv
},
287 { "controlpath", oControlPath
},
288 { "controlmaster", oControlMaster
},
289 { "controlpersist", oControlPersist
},
290 { "hashknownhosts", oHashKnownHosts
},
291 { "include", oInclude
},
292 { "tunnel", oTunnel
},
293 { "tunneldevice", oTunnelDevice
},
294 { "localcommand", oLocalCommand
},
295 { "permitlocalcommand", oPermitLocalCommand
},
296 { "remotecommand", oRemoteCommand
},
297 { "visualhostkey", oVisualHostKey
},
298 { "kexalgorithms", oKexAlgorithms
},
300 { "requesttty", oRequestTTY
},
301 { "sessiontype", oSessionType
},
302 { "stdinnull", oStdinNull
},
303 { "forkafterauthentication", oForkAfterAuthentication
},
304 { "proxyusefdpass", oProxyUseFdpass
},
305 { "canonicaldomains", oCanonicalDomains
},
306 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal
},
307 { "canonicalizehostname", oCanonicalizeHostname
},
308 { "canonicalizemaxdots", oCanonicalizeMaxDots
},
309 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs
},
310 { "streamlocalbindmask", oStreamLocalBindMask
},
311 { "streamlocalbindunlink", oStreamLocalBindUnlink
},
312 { "revokedhostkeys", oRevokedHostKeys
},
313 { "fingerprinthash", oFingerprintHash
},
314 { "updatehostkeys", oUpdateHostkeys
},
315 { "hostbasedacceptedalgorithms", oHostbasedAcceptedAlgorithms
},
316 { "hostbasedkeytypes", oHostbasedAcceptedAlgorithms
}, /* obsolete */
317 { "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms
},
318 { "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms
}, /* obsolete */
319 { "ignoreunknown", oIgnoreUnknown
},
320 { "proxyjump", oProxyJump
},
321 { "securitykeyprovider", oSecurityKeyProvider
},
322 { "knownhostscommand", oKnownHostsCommand
},
323 { "requiredrsasize", oRequiredRSASize
},
328 static const char *lookup_opcode_name(OpCodes code
);
331 kex_default_pk_alg(void)
335 if (pkalgs
== NULL
) {
338 all_key
= sshkey_alg_list(0, 0, 1, ',');
339 pkalgs
= match_filter_allowlist(KEX_DEFAULT_PK_ALG
, all_key
);
346 ssh_connection_hash(const char *thishost
, const char *host
, const char *portstr
,
349 struct ssh_digest_ctx
*md
;
350 u_char conn_hash
[SSH_DIGEST_MAX_LENGTH
];
352 if ((md
= ssh_digest_start(SSH_DIGEST_SHA1
)) == NULL
||
353 ssh_digest_update(md
, thishost
, strlen(thishost
)) < 0 ||
354 ssh_digest_update(md
, host
, strlen(host
)) < 0 ||
355 ssh_digest_update(md
, portstr
, strlen(portstr
)) < 0 ||
356 ssh_digest_update(md
, user
, strlen(user
)) < 0 ||
357 ssh_digest_final(md
, conn_hash
, sizeof(conn_hash
)) < 0)
358 fatal_f("mux digest failed");
360 return tohex(conn_hash
, ssh_digest_bytes(SSH_DIGEST_SHA1
));
364 * Adds a local TCP/IP port forward to options. Never returns if there is an
369 add_local_forward(Options
*options
, const struct Forward
*newfwd
)
374 /* Don't add duplicates */
375 for (i
= 0; i
< options
->num_local_forwards
; i
++) {
376 if (forward_equals(newfwd
, options
->local_forwards
+ i
))
379 options
->local_forwards
= xreallocarray(options
->local_forwards
,
380 options
->num_local_forwards
+ 1,
381 sizeof(*options
->local_forwards
));
382 fwd
= &options
->local_forwards
[options
->num_local_forwards
++];
384 fwd
->listen_host
= newfwd
->listen_host
;
385 fwd
->listen_port
= newfwd
->listen_port
;
386 fwd
->listen_path
= newfwd
->listen_path
;
387 fwd
->connect_host
= newfwd
->connect_host
;
388 fwd
->connect_port
= newfwd
->connect_port
;
389 fwd
->connect_path
= newfwd
->connect_path
;
393 * Adds a remote TCP/IP port forward to options. Never returns if there is
398 add_remote_forward(Options
*options
, const struct Forward
*newfwd
)
403 /* Don't add duplicates */
404 for (i
= 0; i
< options
->num_remote_forwards
; i
++) {
405 if (forward_equals(newfwd
, options
->remote_forwards
+ i
))
408 options
->remote_forwards
= xreallocarray(options
->remote_forwards
,
409 options
->num_remote_forwards
+ 1,
410 sizeof(*options
->remote_forwards
));
411 fwd
= &options
->remote_forwards
[options
->num_remote_forwards
++];
413 fwd
->listen_host
= newfwd
->listen_host
;
414 fwd
->listen_port
= newfwd
->listen_port
;
415 fwd
->listen_path
= newfwd
->listen_path
;
416 fwd
->connect_host
= newfwd
->connect_host
;
417 fwd
->connect_port
= newfwd
->connect_port
;
418 fwd
->connect_path
= newfwd
->connect_path
;
419 fwd
->handle
= newfwd
->handle
;
420 fwd
->allocated_port
= 0;
424 clear_forwardings(Options
*options
)
428 for (i
= 0; i
< options
->num_local_forwards
; i
++) {
429 free(options
->local_forwards
[i
].listen_host
);
430 free(options
->local_forwards
[i
].listen_path
);
431 free(options
->local_forwards
[i
].connect_host
);
432 free(options
->local_forwards
[i
].connect_path
);
434 if (options
->num_local_forwards
> 0) {
435 free(options
->local_forwards
);
436 options
->local_forwards
= NULL
;
438 options
->num_local_forwards
= 0;
439 for (i
= 0; i
< options
->num_remote_forwards
; i
++) {
440 free(options
->remote_forwards
[i
].listen_host
);
441 free(options
->remote_forwards
[i
].listen_path
);
442 free(options
->remote_forwards
[i
].connect_host
);
443 free(options
->remote_forwards
[i
].connect_path
);
445 if (options
->num_remote_forwards
> 0) {
446 free(options
->remote_forwards
);
447 options
->remote_forwards
= NULL
;
449 options
->num_remote_forwards
= 0;
450 options
->tun_open
= SSH_TUNMODE_NO
;
454 add_certificate_file(Options
*options
, const char *path
, int userprovided
)
458 if (options
->num_certificate_files
>= SSH_MAX_CERTIFICATE_FILES
)
459 fatal("Too many certificate files specified (max %d)",
460 SSH_MAX_CERTIFICATE_FILES
);
462 /* Avoid registering duplicates */
463 for (i
= 0; i
< options
->num_certificate_files
; i
++) {
464 if (options
->certificate_file_userprovided
[i
] == userprovided
&&
465 strcmp(options
->certificate_files
[i
], path
) == 0) {
466 debug2_f("ignoring duplicate key %s", path
);
471 options
->certificate_file_userprovided
[options
->num_certificate_files
] =
473 options
->certificate_files
[options
->num_certificate_files
++] =
478 add_identity_file(Options
*options
, const char *dir
, const char *filename
,
484 if (options
->num_identity_files
>= SSH_MAX_IDENTITY_FILES
)
485 fatal("Too many identity files specified (max %d)",
486 SSH_MAX_IDENTITY_FILES
);
488 if (dir
== NULL
) /* no dir, filename is absolute */
489 path
= xstrdup(filename
);
490 else if (xasprintf(&path
, "%s%s", dir
, filename
) >= PATH_MAX
)
491 fatal("Identity file path %s too long", path
);
493 /* Avoid registering duplicates */
494 for (i
= 0; i
< options
->num_identity_files
; i
++) {
495 if (options
->identity_file_userprovided
[i
] == userprovided
&&
496 strcmp(options
->identity_files
[i
], path
) == 0) {
497 debug2_f("ignoring duplicate key %s", path
);
503 options
->identity_file_userprovided
[options
->num_identity_files
] =
505 options
->identity_files
[options
->num_identity_files
++] = path
;
509 default_ssh_port(void)
515 sp
= getservbyname(SSH_SERVICE_NAME
, "tcp");
516 port
= sp
? ntohs(sp
->s_port
) : SSH_DEFAULT_PORT
;
522 * Execute a command in a shell.
523 * Return its exit status or -1 on abnormal exit.
526 execute_in_shell(const char *cmd
)
532 if ((shell
= getenv("SHELL")) == NULL
)
533 shell
= _PATH_BSHELL
;
535 if (access(shell
, X_OK
) == -1) {
536 fatal("Shell \"%s\" is not executable: %s",
537 shell
, strerror(errno
));
540 debug("Executing command: '%.500s'", cmd
);
542 /* Fork and execute the command. */
543 if ((pid
= fork()) == 0) {
546 if (stdfd_devnull(1, 1, 0) == -1)
547 fatal_f("stdfd_devnull failed");
548 closefrom(STDERR_FILENO
+ 1);
552 argv
[2] = xstrdup(cmd
);
555 execv(argv
[0], argv
);
556 error("Unable to execute '%.100s': %s", cmd
, strerror(errno
));
557 /* Die with signal to make this error apparent to parent. */
558 ssh_signal(SIGTERM
, SIG_DFL
);
559 kill(getpid(), SIGTERM
);
564 fatal_f("fork: %.100s", strerror(errno
));
566 while (waitpid(pid
, &status
, 0) == -1) {
567 if (errno
!= EINTR
&& errno
!= EAGAIN
)
568 fatal_f("waitpid: %s", strerror(errno
));
570 if (!WIFEXITED(status
)) {
571 error("command '%.100s' exited abnormally", cmd
);
574 debug3("command returned status %d", WEXITSTATUS(status
));
575 return WEXITSTATUS(status
);
579 * Parse and execute a Match directive.
582 match_cfg_line(Options
*options
, char **condition
, struct passwd
*pw
,
583 const char *host_arg
, const char *original_host
, int final_pass
,
584 int *want_final_pass
, const char *filename
, int linenum
)
586 char *arg
, *oattrib
, *attrib
, *cmd
, *cp
= *condition
, *host
, *criteria
;
588 int r
, port
, this_result
, result
= 1, attributes
= 0, negate
;
589 char thishost
[NI_MAXHOST
], shorthost
[NI_MAXHOST
], portstr
[NI_MAXSERV
];
593 * Configuration is likely to be incomplete at this point so we
594 * must be prepared to use default values.
596 port
= options
->port
<= 0 ? default_ssh_port() : options
->port
;
597 ruser
= options
->user
== NULL
? pw
->pw_name
: options
->user
;
599 host
= xstrdup(options
->hostname
);
600 } else if (options
->hostname
!= NULL
) {
601 /* NB. Please keep in sync with ssh.c:main() */
602 host
= percent_expand(options
->hostname
,
603 "h", host_arg
, (char *)NULL
);
605 host
= xstrdup(host_arg
);
608 debug2("checking match for '%s' host %s originally %s",
609 cp
, host
, original_host
);
610 while ((oattrib
= attrib
= strdelim(&cp
)) && *attrib
!= '\0') {
611 /* Terminate on comment */
612 if (*attrib
== '#') {
613 cp
= NULL
; /* mark all arguments consumed */
616 arg
= criteria
= NULL
;
618 if ((negate
= attrib
[0] == '!'))
620 /* Criterion "all" has no argument and must appear alone */
621 if (strcasecmp(attrib
, "all") == 0) {
622 if (attributes
> 1 || ((arg
= strdelim(&cp
)) != NULL
&&
623 *arg
!= '\0' && *arg
!= '#')) {
624 error("%.200s line %d: '%s' cannot be combined "
625 "with other Match attributes",
626 filename
, linenum
, oattrib
);
630 if (arg
!= NULL
&& *arg
== '#')
631 cp
= NULL
; /* mark all arguments consumed */
633 result
= negate
? 0 : 1;
637 /* criteria "final" and "canonical" have no argument */
638 if (strcasecmp(attrib
, "canonical") == 0 ||
639 strcasecmp(attrib
, "final") == 0) {
641 * If the config requests "Match final" then remember
642 * this so we can perform a second pass later.
644 if (strcasecmp(attrib
, "final") == 0 &&
645 want_final_pass
!= NULL
)
646 *want_final_pass
= 1;
647 r
= !!final_pass
; /* force bitmask member to boolean */
648 if (r
== (negate
? 1 : 0))
649 this_result
= result
= 0;
650 debug3("%.200s line %d: %smatched '%s'",
652 this_result
? "" : "not ", oattrib
);
655 /* All other criteria require an argument */
656 if ((arg
= strdelim(&cp
)) == NULL
||
657 *arg
== '\0' || *arg
== '#') {
658 error("Missing Match criteria for %s", attrib
);
662 if (strcasecmp(attrib
, "host") == 0) {
663 criteria
= xstrdup(host
);
664 r
= match_hostname(host
, arg
) == 1;
665 if (r
== (negate
? 1 : 0))
666 this_result
= result
= 0;
667 } else if (strcasecmp(attrib
, "originalhost") == 0) {
668 criteria
= xstrdup(original_host
);
669 r
= match_hostname(original_host
, arg
) == 1;
670 if (r
== (negate
? 1 : 0))
671 this_result
= result
= 0;
672 } else if (strcasecmp(attrib
, "user") == 0) {
673 criteria
= xstrdup(ruser
);
674 r
= match_pattern_list(ruser
, arg
, 0) == 1;
675 if (r
== (negate
? 1 : 0))
676 this_result
= result
= 0;
677 } else if (strcasecmp(attrib
, "localuser") == 0) {
678 criteria
= xstrdup(pw
->pw_name
);
679 r
= match_pattern_list(pw
->pw_name
, arg
, 0) == 1;
680 if (r
== (negate
? 1 : 0))
681 this_result
= result
= 0;
682 } else if (strcasecmp(attrib
, "exec") == 0) {
683 char *conn_hash_hex
, *keyalias
;
685 if (gethostname(thishost
, sizeof(thishost
)) == -1)
686 fatal("gethostname: %s", strerror(errno
));
687 strlcpy(shorthost
, thishost
, sizeof(shorthost
));
688 shorthost
[strcspn(thishost
, ".")] = '\0';
689 snprintf(portstr
, sizeof(portstr
), "%d", port
);
690 snprintf(uidstr
, sizeof(uidstr
), "%llu",
691 (unsigned long long)pw
->pw_uid
);
692 conn_hash_hex
= ssh_connection_hash(thishost
, host
,
694 keyalias
= options
->host_key_alias
?
695 options
->host_key_alias
: host
;
697 cmd
= percent_expand(arg
,
712 /* skip execution if prior predicate failed */
713 debug3("%.200s line %d: skipped exec "
714 "\"%.100s\"", filename
, linenum
, cmd
);
718 r
= execute_in_shell(cmd
);
720 fatal("%.200s line %d: match exec "
721 "'%.100s' error", filename
,
724 criteria
= xstrdup(cmd
);
726 /* Force exit status to boolean */
728 if (r
== (negate
? 1 : 0))
729 this_result
= result
= 0;
731 error("Unsupported Match attribute %s", attrib
);
735 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",
736 filename
, linenum
, this_result
? "": "not ",
740 if (attributes
== 0) {
741 error("One or more attributes required for Match");
747 debug2("match %sfound", result
? "" : "not ");
753 /* Remove environment variable by pattern */
755 rm_env(Options
*options
, const char *arg
, const char *filename
, int linenum
)
757 u_int i
, j
, onum_send_env
= options
->num_send_env
;
759 /* Remove an environment variable */
760 for (i
= 0; i
< options
->num_send_env
; ) {
761 if (!match_pattern(options
->send_env
[i
], arg
+ 1)) {
765 debug3("%s line %d: removing environment %s",
766 filename
, linenum
, options
->send_env
[i
]);
767 free(options
->send_env
[i
]);
768 options
->send_env
[i
] = NULL
;
769 for (j
= i
; j
< options
->num_send_env
- 1; j
++) {
770 options
->send_env
[j
] = options
->send_env
[j
+ 1];
771 options
->send_env
[j
+ 1] = NULL
;
773 options
->num_send_env
--;
774 /* NB. don't increment i */
776 if (onum_send_env
!= options
->num_send_env
) {
777 options
->send_env
= xrecallocarray(options
->send_env
,
778 onum_send_env
, options
->num_send_env
,
779 sizeof(*options
->send_env
));
784 * Returns the number of the token pointed to by cp or oBadOption.
787 parse_token(const char *cp
, const char *filename
, int linenum
,
788 const char *ignored_unknown
)
792 for (i
= 0; keywords
[i
].name
; i
++)
793 if (strcmp(cp
, keywords
[i
].name
) == 0)
794 return keywords
[i
].opcode
;
795 if (ignored_unknown
!= NULL
&&
796 match_pattern_list(cp
, ignored_unknown
, 1) == 1)
797 return oIgnoredUnknownOption
;
798 error("%s: line %d: Bad configuration option: %s",
799 filename
, linenum
, cp
);
803 /* Multistate option parsing */
808 static const struct multistate multistate_flag
[] = {
815 static const struct multistate multistate_yesnoask
[] = {
823 static const struct multistate multistate_strict_hostkey
[] = {
824 { "true", SSH_STRICT_HOSTKEY_YES
},
825 { "false", SSH_STRICT_HOSTKEY_OFF
},
826 { "yes", SSH_STRICT_HOSTKEY_YES
},
827 { "no", SSH_STRICT_HOSTKEY_OFF
},
828 { "ask", SSH_STRICT_HOSTKEY_ASK
},
829 { "off", SSH_STRICT_HOSTKEY_OFF
},
830 { "accept-new", SSH_STRICT_HOSTKEY_NEW
},
833 static const struct multistate multistate_yesnoaskconfirm
[] = {
842 static const struct multistate multistate_addressfamily
[] = {
844 { "inet6", AF_INET6
},
845 { "any", AF_UNSPEC
},
848 static const struct multistate multistate_controlmaster
[] = {
849 { "true", SSHCTL_MASTER_YES
},
850 { "yes", SSHCTL_MASTER_YES
},
851 { "false", SSHCTL_MASTER_NO
},
852 { "no", SSHCTL_MASTER_NO
},
853 { "auto", SSHCTL_MASTER_AUTO
},
854 { "ask", SSHCTL_MASTER_ASK
},
855 { "autoask", SSHCTL_MASTER_AUTO_ASK
},
858 static const struct multistate multistate_tunnel
[] = {
859 { "ethernet", SSH_TUNMODE_ETHERNET
},
860 { "point-to-point", SSH_TUNMODE_POINTOPOINT
},
861 { "true", SSH_TUNMODE_DEFAULT
},
862 { "yes", SSH_TUNMODE_DEFAULT
},
863 { "false", SSH_TUNMODE_NO
},
864 { "no", SSH_TUNMODE_NO
},
867 static const struct multistate multistate_requesttty
[] = {
868 { "true", REQUEST_TTY_YES
},
869 { "yes", REQUEST_TTY_YES
},
870 { "false", REQUEST_TTY_NO
},
871 { "no", REQUEST_TTY_NO
},
872 { "force", REQUEST_TTY_FORCE
},
873 { "auto", REQUEST_TTY_AUTO
},
876 static const struct multistate multistate_sessiontype
[] = {
877 { "none", SESSION_TYPE_NONE
},
878 { "subsystem", SESSION_TYPE_SUBSYSTEM
},
879 { "default", SESSION_TYPE_DEFAULT
},
882 static const struct multistate multistate_canonicalizehostname
[] = {
883 { "true", SSH_CANONICALISE_YES
},
884 { "false", SSH_CANONICALISE_NO
},
885 { "yes", SSH_CANONICALISE_YES
},
886 { "no", SSH_CANONICALISE_NO
},
887 { "always", SSH_CANONICALISE_ALWAYS
},
890 static const struct multistate multistate_pubkey_auth
[] = {
891 { "true", SSH_PUBKEY_AUTH_ALL
},
892 { "false", SSH_PUBKEY_AUTH_NO
},
893 { "yes", SSH_PUBKEY_AUTH_ALL
},
894 { "no", SSH_PUBKEY_AUTH_NO
},
895 { "unbound", SSH_PUBKEY_AUTH_UNBOUND
},
896 { "host-bound", SSH_PUBKEY_AUTH_HBOUND
},
899 static const struct multistate multistate_compression
[] = {
901 { "yes", COMP_ZLIB
},
908 parse_multistate_value(const char *arg
, const char *filename
, int linenum
,
909 const struct multistate
*multistate_ptr
)
913 if (!arg
|| *arg
== '\0') {
914 error("%s line %d: missing argument.", filename
, linenum
);
917 for (i
= 0; multistate_ptr
[i
].key
!= NULL
; i
++) {
918 if (strcasecmp(arg
, multistate_ptr
[i
].key
) == 0)
919 return multistate_ptr
[i
].value
;
925 * Processes a single option line as used in the configuration files. This
926 * only sets those values that have not already been set.
929 process_config_line(Options
*options
, struct passwd
*pw
, const char *host
,
930 const char *original_host
, char *line
, const char *filename
,
931 int linenum
, int *activep
, int flags
)
933 return process_config_line_depth(options
, pw
, host
, original_host
,
934 line
, filename
, linenum
, activep
, flags
, NULL
, 0);
937 #define WHITESPACE " \t\r\n"
939 process_config_line_depth(Options
*options
, struct passwd
*pw
, const char *host
,
940 const char *original_host
, char *line
, const char *filename
,
941 int linenum
, int *activep
, int flags
, int *want_final_pass
, int depth
)
943 char *str
, **charptr
, *endofnumber
, *keyword
, *arg
, *arg2
, *p
;
944 char **cpptr
, ***cppptr
, fwdarg
[256];
945 u_int i
, *uintptr
, uvalue
, max_entries
= 0;
946 int r
, oactive
, negated
, opcode
, *intptr
, value
, value2
, cmdline
= 0;
947 int remotefwd
, dynamicfwd
;
948 LogLevel
*log_level_ptr
;
949 SyslogFacility
*log_facility_ptr
;
953 const struct multistate
*multistate_ptr
;
954 struct allowed_cname
*cname
;
957 char **oav
= NULL
, **av
;
961 if (activep
== NULL
) { /* We are processing a command line directive */
966 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
967 if ((len
= strlen(line
)) == 0)
969 for (len
--; len
> 0; len
--) {
970 if (strchr(WHITESPACE
"\f", line
[len
]) == NULL
)
976 /* Get the keyword. (Each line is supposed to begin with a keyword). */
977 if ((keyword
= strdelim(&str
)) == NULL
)
979 /* Ignore leading whitespace. */
980 if (*keyword
== '\0')
981 keyword
= strdelim(&str
);
982 if (keyword
== NULL
|| !*keyword
|| *keyword
== '\n' || *keyword
== '#')
984 /* Match lowercase keyword */
987 /* Prepare to parse remainder of line */
989 str
+= strspn(str
, WHITESPACE
);
990 if (str
== NULL
|| *str
== '\0') {
991 error("%s line %d: no argument after keyword \"%s\"",
992 filename
, linenum
, keyword
);
995 opcode
= parse_token(keyword
, filename
, linenum
,
996 options
->ignored_unknown
);
997 if (argv_split(str
, &oac
, &oav
, 1) != 0) {
998 error("%s line %d: invalid quotes", filename
, linenum
);
1006 /* don't panic, but count bad options */
1011 case oIgnoredUnknownOption
:
1012 debug("%s line %d: Ignored unknown option \"%s\"",
1013 filename
, linenum
, keyword
);
1016 case oConnectTimeout
:
1017 intptr
= &options
->connection_timeout
;
1019 arg
= argv_next(&ac
, &av
);
1020 if (!arg
|| *arg
== '\0') {
1021 error("%s line %d: missing time value.",
1025 if (strcmp(arg
, "none") == 0)
1027 else if ((value
= convtime(arg
)) == -1) {
1028 error("%s line %d: invalid time value.",
1032 if (*activep
&& *intptr
== -1)
1037 intptr
= &options
->forward_agent
;
1039 arg
= argv_next(&ac
, &av
);
1040 if (!arg
|| *arg
== '\0') {
1041 error("%s line %d: missing argument.",
1047 multistate_ptr
= multistate_flag
;
1048 for (i
= 0; multistate_ptr
[i
].key
!= NULL
; i
++) {
1049 if (strcasecmp(arg
, multistate_ptr
[i
].key
) == 0) {
1050 value
= multistate_ptr
[i
].value
;
1055 if (*activep
&& *intptr
== -1)
1059 /* ForwardAgent wasn't 'yes' or 'no', assume a path */
1060 if (*activep
&& *intptr
== -1)
1063 charptr
= &options
->forward_agent_sock_path
;
1064 goto parse_agent_path
;
1067 intptr
= &options
->forward_x11
;
1069 multistate_ptr
= multistate_flag
;
1071 arg
= argv_next(&ac
, &av
);
1072 if ((value
= parse_multistate_value(arg
, filename
, linenum
,
1073 multistate_ptr
)) == -1) {
1074 error("%s line %d: unsupported option \"%s\".",
1075 filename
, linenum
, arg
);
1078 if (*activep
&& *intptr
== -1)
1082 case oForwardX11Trusted
:
1083 intptr
= &options
->forward_x11_trusted
;
1086 case oForwardX11Timeout
:
1087 intptr
= &options
->forward_x11_timeout
;
1091 intptr
= &options
->fwd_opts
.gateway_ports
;
1094 case oExitOnForwardFailure
:
1095 intptr
= &options
->exit_on_forward_failure
;
1098 case oPasswordAuthentication
:
1099 intptr
= &options
->password_authentication
;
1102 case oKbdInteractiveAuthentication
:
1103 intptr
= &options
->kbd_interactive_authentication
;
1106 case oKbdInteractiveDevices
:
1107 charptr
= &options
->kbd_interactive_devices
;
1110 case oPubkeyAuthentication
:
1111 multistate_ptr
= multistate_pubkey_auth
;
1112 intptr
= &options
->pubkey_authentication
;
1113 goto parse_multistate
;
1115 case oHostbasedAuthentication
:
1116 intptr
= &options
->hostbased_authentication
;
1119 case oGssAuthentication
:
1120 intptr
= &options
->gss_authentication
;
1123 case oGssDelegateCreds
:
1124 intptr
= &options
->gss_deleg_creds
;
1128 intptr
= &options
->batch_mode
;
1132 intptr
= &options
->check_host_ip
;
1135 case oVerifyHostKeyDNS
:
1136 intptr
= &options
->verify_host_key_dns
;
1137 multistate_ptr
= multistate_yesnoask
;
1138 goto parse_multistate
;
1140 case oStrictHostKeyChecking
:
1141 intptr
= &options
->strict_host_key_checking
;
1142 multistate_ptr
= multistate_strict_hostkey
;
1143 goto parse_multistate
;
1146 intptr
= &options
->compression
;
1147 multistate_ptr
= multistate_compression
;
1148 goto parse_multistate
;
1151 intptr
= &options
->tcp_keep_alive
;
1154 case oNoHostAuthenticationForLocalhost
:
1155 intptr
= &options
->no_host_authentication_for_localhost
;
1158 case oNumberOfPasswordPrompts
:
1159 intptr
= &options
->number_of_password_prompts
;
1163 arg
= argv_next(&ac
, &av
);
1164 if (!arg
|| *arg
== '\0') {
1165 error("%.200s line %d: Missing argument.", filename
,
1169 if (strcmp(arg
, "default") == 0) {
1172 if (scan_scaled(arg
, &val64
) == -1) {
1173 error("%.200s line %d: Bad number '%s': %s",
1174 filename
, linenum
, arg
, strerror(errno
));
1177 if (val64
!= 0 && val64
< 16) {
1178 error("%.200s line %d: RekeyLimit too small",
1183 if (*activep
&& options
->rekey_limit
== -1)
1184 options
->rekey_limit
= val64
;
1185 if (ac
!= 0) { /* optional rekey interval present */
1186 if (strcmp(av
[0], "none") == 0) {
1187 (void)argv_next(&ac
, &av
); /* discard */
1190 intptr
= &options
->rekey_interval
;
1196 arg
= argv_next(&ac
, &av
);
1197 if (!arg
|| *arg
== '\0') {
1198 error("%.200s line %d: Missing argument.",
1203 intptr
= &options
->num_identity_files
;
1204 if (*intptr
>= SSH_MAX_IDENTITY_FILES
) {
1205 error("%.200s line %d: Too many identity files "
1206 "specified (max %d).", filename
, linenum
,
1207 SSH_MAX_IDENTITY_FILES
);
1210 add_identity_file(options
, NULL
,
1211 arg
, flags
& SSHCONF_USERCONF
);
1215 case oCertificateFile
:
1216 arg
= argv_next(&ac
, &av
);
1217 if (!arg
|| *arg
== '\0') {
1218 error("%.200s line %d: Missing argument.",
1223 intptr
= &options
->num_certificate_files
;
1224 if (*intptr
>= SSH_MAX_CERTIFICATE_FILES
) {
1225 error("%.200s line %d: Too many certificate "
1226 "files specified (max %d).",
1228 SSH_MAX_CERTIFICATE_FILES
);
1231 add_certificate_file(options
, arg
,
1232 flags
& SSHCONF_USERCONF
);
1236 case oXAuthLocation
:
1237 charptr
=&options
->xauth_location
;
1241 charptr
= &options
->user
;
1243 arg
= argv_next(&ac
, &av
);
1244 if (!arg
|| *arg
== '\0') {
1245 error("%.200s line %d: Missing argument.",
1249 if (*activep
&& *charptr
== NULL
)
1250 *charptr
= xstrdup(arg
);
1253 case oGlobalKnownHostsFile
:
1254 cpptr
= (char **)&options
->system_hostfiles
;
1255 uintptr
= &options
->num_system_hostfiles
;
1256 max_entries
= SSH_MAX_HOSTS_FILES
;
1259 value
= *uintptr
== 0; /* was array empty when we started? */
1260 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1262 error("%s line %d: keyword %s empty argument",
1263 filename
, linenum
, keyword
);
1266 /* Allow "none" only in first position */
1267 if (strcasecmp(arg
, "none") == 0) {
1268 if (i
> 0 || ac
> 0) {
1269 error("%s line %d: keyword %s \"none\" "
1270 "argument must appear alone.",
1271 filename
, linenum
, keyword
);
1276 if (*activep
&& value
) {
1277 if ((*uintptr
) >= max_entries
) {
1278 error("%s line %d: too many %s "
1279 "entries.", filename
, linenum
,
1283 cpptr
[(*uintptr
)++] = xstrdup(arg
);
1288 case oUserKnownHostsFile
:
1289 cpptr
= (char **)&options
->user_hostfiles
;
1290 uintptr
= &options
->num_user_hostfiles
;
1291 max_entries
= SSH_MAX_HOSTS_FILES
;
1292 goto parse_char_array
;
1295 charptr
= &options
->hostname
;
1299 charptr
= &options
->host_key_alias
;
1302 case oPreferredAuthentications
:
1303 charptr
= &options
->preferred_authentications
;
1307 charptr
= &options
->bind_address
;
1310 case oBindInterface
:
1311 charptr
= &options
->bind_interface
;
1314 case oPKCS11Provider
:
1315 charptr
= &options
->pkcs11_provider
;
1318 case oSecurityKeyProvider
:
1319 charptr
= &options
->sk_provider
;
1322 case oKnownHostsCommand
:
1323 charptr
= &options
->known_hosts_command
;
1327 charptr
= &options
->proxy_command
;
1328 /* Ignore ProxyCommand if ProxyJump already specified */
1329 if (options
->jump_host
!= NULL
)
1330 charptr
= &options
->jump_host
; /* Skip below */
1333 error("%.200s line %d: Missing argument.",
1337 len
= strspn(str
, WHITESPACE
"=");
1338 if (*activep
&& *charptr
== NULL
)
1339 *charptr
= xstrdup(str
+ len
);
1345 error("%.200s line %d: Missing argument.",
1349 len
= strspn(str
, WHITESPACE
"=");
1351 if (parse_jump(str
+ len
, options
, *activep
) == -1) {
1352 error("%.200s line %d: Invalid ProxyJump \"%s\"",
1353 filename
, linenum
, str
+ len
);
1360 arg
= argv_next(&ac
, &av
);
1361 if (!arg
|| *arg
== '\0') {
1362 error("%.200s line %d: Missing argument.",
1366 value
= a2port(arg
);
1368 error("%.200s line %d: Bad port '%s'.",
1369 filename
, linenum
, arg
);
1372 if (*activep
&& options
->port
== -1)
1373 options
->port
= value
;
1376 case oConnectionAttempts
:
1377 intptr
= &options
->connection_attempts
;
1379 arg
= argv_next(&ac
, &av
);
1380 if ((errstr
= atoi_err(arg
, &value
)) != NULL
) {
1381 error("%s line %d: integer value %s.",
1382 filename
, linenum
, errstr
);
1385 if (*activep
&& *intptr
== -1)
1390 arg
= argv_next(&ac
, &av
);
1391 if (!arg
|| *arg
== '\0') {
1392 error("%.200s line %d: Missing argument.",
1397 !ciphers_valid(*arg
== '+' || *arg
== '^' ? arg
+ 1 : arg
)){
1398 error("%.200s line %d: Bad SSH2 cipher spec '%s'.",
1399 filename
, linenum
, arg
? arg
: "<NONE>");
1402 if (*activep
&& options
->ciphers
== NULL
)
1403 options
->ciphers
= xstrdup(arg
);
1407 arg
= argv_next(&ac
, &av
);
1408 if (!arg
|| *arg
== '\0') {
1409 error("%.200s line %d: Missing argument.",
1414 !mac_valid(*arg
== '+' || *arg
== '^' ? arg
+ 1 : arg
)) {
1415 error("%.200s line %d: Bad SSH2 MAC spec '%s'.",
1416 filename
, linenum
, arg
? arg
: "<NONE>");
1419 if (*activep
&& options
->macs
== NULL
)
1420 options
->macs
= xstrdup(arg
);
1423 case oKexAlgorithms
:
1424 arg
= argv_next(&ac
, &av
);
1425 if (!arg
|| *arg
== '\0') {
1426 error("%.200s line %d: Missing argument.",
1431 !kex_names_valid(*arg
== '+' || *arg
== '^' ?
1433 error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",
1434 filename
, linenum
, arg
? arg
: "<NONE>");
1437 if (*activep
&& options
->kex_algorithms
== NULL
)
1438 options
->kex_algorithms
= xstrdup(arg
);
1441 case oHostKeyAlgorithms
:
1442 charptr
= &options
->hostkeyalgorithms
;
1444 arg
= argv_next(&ac
, &av
);
1445 if (!arg
|| *arg
== '\0') {
1446 error("%.200s line %d: Missing argument.",
1451 !sshkey_names_valid2(*arg
== '+' || *arg
== '^' ?
1452 arg
+ 1 : arg
, 1)) {
1453 error("%s line %d: Bad key types '%s'.",
1454 filename
, linenum
, arg
? arg
: "<NONE>");
1457 if (*activep
&& *charptr
== NULL
)
1458 *charptr
= xstrdup(arg
);
1461 case oCASignatureAlgorithms
:
1462 charptr
= &options
->ca_sign_algorithms
;
1463 goto parse_pubkey_algos
;
1466 log_level_ptr
= &options
->log_level
;
1467 arg
= argv_next(&ac
, &av
);
1468 value
= log_level_number(arg
);
1469 if (value
== SYSLOG_LEVEL_NOT_SET
) {
1470 error("%.200s line %d: unsupported log level '%s'",
1471 filename
, linenum
, arg
? arg
: "<NONE>");
1474 if (*activep
&& *log_level_ptr
== SYSLOG_LEVEL_NOT_SET
)
1475 *log_level_ptr
= (LogLevel
) value
;
1479 log_facility_ptr
= &options
->log_facility
;
1480 arg
= argv_next(&ac
, &av
);
1481 value
= log_facility_number(arg
);
1482 if (value
== SYSLOG_FACILITY_NOT_SET
) {
1483 error("%.200s line %d: unsupported log facility '%s'",
1484 filename
, linenum
, arg
? arg
: "<NONE>");
1487 if (*log_facility_ptr
== -1)
1488 *log_facility_ptr
= (SyslogFacility
) value
;
1492 cppptr
= &options
->log_verbose
;
1493 uintptr
= &options
->num_log_verbose
;
1495 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1497 error("%s line %d: keyword %s empty argument",
1498 filename
, linenum
, keyword
);
1501 /* Allow "none" only in first position */
1502 if (strcasecmp(arg
, "none") == 0) {
1503 if (i
> 0 || ac
> 0) {
1504 error("%s line %d: keyword %s \"none\" "
1505 "argument must appear alone.",
1506 filename
, linenum
, keyword
);
1511 if (*activep
&& *uintptr
== 0) {
1512 *cppptr
= xrecallocarray(*cppptr
, *uintptr
,
1513 *uintptr
+ 1, sizeof(**cppptr
));
1514 (*cppptr
)[(*uintptr
)++] = xstrdup(arg
);
1520 case oRemoteForward
:
1521 case oDynamicForward
:
1522 arg
= argv_next(&ac
, &av
);
1523 if (!arg
|| *arg
== '\0') {
1524 error("%.200s line %d: Missing argument.",
1529 remotefwd
= (opcode
== oRemoteForward
);
1530 dynamicfwd
= (opcode
== oDynamicForward
);
1533 arg2
= argv_next(&ac
, &av
);
1534 if (arg2
== NULL
|| *arg2
== '\0') {
1538 error("%.200s line %d: Missing target "
1539 "argument.", filename
, linenum
);
1543 /* construct a string for parse_forward */
1544 snprintf(fwdarg
, sizeof(fwdarg
), "%s:%s", arg
,
1549 strlcpy(fwdarg
, arg
, sizeof(fwdarg
));
1551 if (parse_forward(&fwd
, fwdarg
, dynamicfwd
, remotefwd
) == 0) {
1552 error("%.200s line %d: Bad forwarding specification.",
1559 add_remote_forward(options
, &fwd
);
1561 add_local_forward(options
, &fwd
);
1566 case oPermitRemoteOpen
:
1567 uintptr
= &options
->num_permitted_remote_opens
;
1568 cppptr
= &options
->permitted_remote_opens
;
1569 arg
= argv_next(&ac
, &av
);
1570 if (!arg
|| *arg
== '\0')
1571 fatal("%s line %d: missing %s specification",
1572 filename
, linenum
, lookup_opcode_name(opcode
));
1573 uvalue
= *uintptr
; /* modified later */
1574 if (strcmp(arg
, "any") == 0 || strcmp(arg
, "none") == 0) {
1575 if (*activep
&& uvalue
== 0) {
1577 *cppptr
= xcalloc(1, sizeof(**cppptr
));
1578 (*cppptr
)[0] = xstrdup(arg
);
1582 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1583 arg2
= xstrdup(arg
);
1586 fatal("%s line %d: missing host in %s",
1588 lookup_opcode_name(opcode
));
1590 p
= cleanhostname(p
);
1592 * don't want to use permitopen_port to avoid
1593 * dependency on channels.[ch] here.
1596 (strcmp(arg
, "*") != 0 && a2port(arg
) <= 0)) {
1597 fatal("%s line %d: bad port number in %s",
1599 lookup_opcode_name(opcode
));
1601 if (*activep
&& uvalue
== 0) {
1602 opt_array_append(filename
, linenum
,
1603 lookup_opcode_name(opcode
),
1604 cppptr
, uintptr
, arg2
);
1610 case oClearAllForwardings
:
1611 intptr
= &options
->clear_forwardings
;
1616 error("Host directive not supported as a command-line "
1622 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1624 error("%s line %d: keyword %s empty argument",
1625 filename
, linenum
, keyword
);
1628 if ((flags
& SSHCONF_NEVERMATCH
) != 0) {
1632 negated
= *arg
== '!';
1635 if (match_pattern(host
, arg
)) {
1637 debug("%.200s line %d: Skipping Host "
1638 "block because of negated match "
1639 "for %.100s", filename
, linenum
,
1646 arg2
= arg
; /* logged below */
1651 debug("%.200s line %d: Applying options for %.100s",
1652 filename
, linenum
, arg2
);
1657 error("Host directive not supported as a command-line "
1661 value
= match_cfg_line(options
, &str
, pw
, host
, original_host
,
1662 flags
& SSHCONF_FINAL
, want_final_pass
,
1665 error("%.200s line %d: Bad Match condition", filename
,
1669 *activep
= (flags
& SSHCONF_NEVERMATCH
) ? 0 : value
;
1671 * If match_cfg_line() didn't consume all its arguments then
1672 * arrange for the extra arguments check below to fail.
1675 if (str
== NULL
|| *str
== '\0')
1680 intptr
= &options
->escape_char
;
1681 arg
= argv_next(&ac
, &av
);
1682 if (!arg
|| *arg
== '\0') {
1683 error("%.200s line %d: Missing argument.",
1687 if (strcmp(arg
, "none") == 0)
1688 value
= SSH_ESCAPECHAR_NONE
;
1689 else if (arg
[1] == '\0')
1690 value
= (u_char
) arg
[0];
1691 else if (arg
[0] == '^' && arg
[2] == 0 &&
1692 (u_char
) arg
[1] >= 64 && (u_char
) arg
[1] < 128)
1693 value
= (u_char
) arg
[1] & 31;
1695 error("%.200s line %d: Bad escape character.",
1699 if (*activep
&& *intptr
== -1)
1703 case oAddressFamily
:
1704 intptr
= &options
->address_family
;
1705 multistate_ptr
= multistate_addressfamily
;
1706 goto parse_multistate
;
1708 case oEnableSSHKeysign
:
1709 intptr
= &options
->enable_ssh_keysign
;
1712 case oIdentitiesOnly
:
1713 intptr
= &options
->identities_only
;
1716 case oServerAliveInterval
:
1717 intptr
= &options
->server_alive_interval
;
1720 case oServerAliveCountMax
:
1721 intptr
= &options
->server_alive_count_max
;
1725 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1726 if (*arg
== '\0' || strchr(arg
, '=') != NULL
) {
1727 error("%s line %d: Invalid environment name.",
1734 /* Removing an env var */
1735 rm_env(options
, arg
, filename
, linenum
);
1738 opt_array_append(filename
, linenum
,
1739 lookup_opcode_name(opcode
),
1740 &options
->send_env
, &options
->num_send_env
, arg
);
1745 value
= options
->num_setenv
;
1746 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1747 if (strchr(arg
, '=') == NULL
) {
1748 error("%s line %d: Invalid SetEnv.",
1752 if (!*activep
|| value
!= 0)
1754 if (lookup_setenv_in_list(arg
, options
->setenv
,
1755 options
->num_setenv
) != NULL
) {
1756 debug2("%s line %d: ignoring duplicate env "
1757 "name \"%.64s\"", filename
, linenum
, arg
);
1760 opt_array_append(filename
, linenum
,
1761 lookup_opcode_name(opcode
),
1762 &options
->setenv
, &options
->num_setenv
, arg
);
1767 charptr
= &options
->control_path
;
1770 case oControlMaster
:
1771 intptr
= &options
->control_master
;
1772 multistate_ptr
= multistate_controlmaster
;
1773 goto parse_multistate
;
1775 case oControlPersist
:
1776 /* no/false/yes/true, or a time spec */
1777 intptr
= &options
->control_persist
;
1778 arg
= argv_next(&ac
, &av
);
1779 if (!arg
|| *arg
== '\0') {
1780 error("%.200s line %d: Missing ControlPersist"
1781 " argument.", filename
, linenum
);
1785 value2
= 0; /* timeout */
1786 if (strcmp(arg
, "no") == 0 || strcmp(arg
, "false") == 0)
1788 else if (strcmp(arg
, "yes") == 0 || strcmp(arg
, "true") == 0)
1790 else if ((value2
= convtime(arg
)) >= 0)
1793 error("%.200s line %d: Bad ControlPersist argument.",
1797 if (*activep
&& *intptr
== -1) {
1799 options
->control_persist_timeout
= value2
;
1803 case oHashKnownHosts
:
1804 intptr
= &options
->hash_known_hosts
;
1808 intptr
= &options
->tun_open
;
1809 multistate_ptr
= multistate_tunnel
;
1810 goto parse_multistate
;
1813 arg
= argv_next(&ac
, &av
);
1814 if (!arg
|| *arg
== '\0') {
1815 error("%.200s line %d: Missing argument.",
1819 value
= a2tun(arg
, &value2
);
1820 if (value
== SSH_TUNID_ERR
) {
1821 error("%.200s line %d: Bad tun device.",
1825 if (*activep
&& options
->tun_local
== -1) {
1826 options
->tun_local
= value
;
1827 options
->tun_remote
= value2
;
1832 charptr
= &options
->local_command
;
1835 case oPermitLocalCommand
:
1836 intptr
= &options
->permit_local_command
;
1839 case oRemoteCommand
:
1840 charptr
= &options
->remote_command
;
1843 case oVisualHostKey
:
1844 intptr
= &options
->visual_host_key
;
1849 error("Include directive not supported as a "
1850 "command-line option");
1854 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1856 error("%s line %d: keyword %s empty argument",
1857 filename
, linenum
, keyword
);
1861 * Ensure all paths are anchored. User configuration
1862 * files may begin with '~/' but system configurations
1863 * must not. If the path is relative, then treat it
1864 * as living in ~/.ssh for user configurations or
1865 * /etc/ssh for system ones.
1867 if (*arg
== '~' && (flags
& SSHCONF_USERCONF
) == 0) {
1868 error("%.200s line %d: bad include path %s.",
1869 filename
, linenum
, arg
);
1872 if (!path_absolute(arg
) && *arg
!= '~') {
1873 xasprintf(&arg2
, "%s/%s",
1874 (flags
& SSHCONF_USERCONF
) ?
1875 "~/" _PATH_SSH_USER_DIR
: SSHDIR
, arg
);
1877 arg2
= xstrdup(arg
);
1878 memset(&gl
, 0, sizeof(gl
));
1879 r
= glob(arg2
, GLOB_TILDE
, NULL
, &gl
);
1880 if (r
== GLOB_NOMATCH
) {
1881 debug("%.200s line %d: include %s matched no "
1882 "files",filename
, linenum
, arg2
);
1885 } else if (r
!= 0) {
1886 error("%.200s line %d: glob failed for %s.",
1887 filename
, linenum
, arg2
);
1892 for (i
= 0; i
< gl
.gl_pathc
; i
++) {
1893 debug3("%.200s line %d: Including file %s "
1894 "depth %d%s", filename
, linenum
,
1895 gl
.gl_pathv
[i
], depth
,
1896 oactive
? "" : " (parse only)");
1897 r
= read_config_file_depth(gl
.gl_pathv
[i
],
1898 pw
, host
, original_host
, options
,
1899 flags
| SSHCONF_CHECKPERM
|
1900 (oactive
? 0 : SSHCONF_NEVERMATCH
),
1901 activep
, want_final_pass
, depth
+ 1);
1902 if (r
!= 1 && errno
!= ENOENT
) {
1903 error("Can't open user config file "
1904 "%.100s: %.100s", gl
.gl_pathv
[i
],
1910 * don't let Match in includes clobber the
1911 * containing file's Match state.
1924 arg
= argv_next(&ac
, &av
);
1925 if ((value
= parse_ipqos(arg
)) == -1) {
1926 error("%s line %d: Bad IPQoS value: %s",
1927 filename
, linenum
, arg
);
1930 arg
= argv_next(&ac
, &av
);
1933 else if ((value2
= parse_ipqos(arg
)) == -1) {
1934 error("%s line %d: Bad IPQoS value: %s",
1935 filename
, linenum
, arg
);
1938 if (*activep
&& options
->ip_qos_interactive
== -1) {
1939 options
->ip_qos_interactive
= value
;
1940 options
->ip_qos_bulk
= value2
;
1945 intptr
= &options
->request_tty
;
1946 multistate_ptr
= multistate_requesttty
;
1947 goto parse_multistate
;
1950 intptr
= &options
->session_type
;
1951 multistate_ptr
= multistate_sessiontype
;
1952 goto parse_multistate
;
1955 intptr
= &options
->stdin_null
;
1958 case oForkAfterAuthentication
:
1959 intptr
= &options
->fork_after_authentication
;
1962 case oIgnoreUnknown
:
1963 charptr
= &options
->ignored_unknown
;
1966 case oProxyUseFdpass
:
1967 intptr
= &options
->proxy_use_fdpass
;
1970 case oCanonicalDomains
:
1971 value
= options
->num_canonical_domains
!= 0;
1973 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
1975 error("%s line %d: keyword %s empty argument",
1976 filename
, linenum
, keyword
);
1979 /* Allow "none" only in first position */
1980 if (strcasecmp(arg
, "none") == 0) {
1981 if (i
> 0 || ac
> 0) {
1982 error("%s line %d: keyword %s \"none\" "
1983 "argument must appear alone.",
1984 filename
, linenum
, keyword
);
1989 if (!valid_domain(arg
, 1, &errstr
)) {
1990 error("%s line %d: %s", filename
, linenum
,
1994 if (!*activep
|| value
)
1996 if (options
->num_canonical_domains
>=
1997 MAX_CANON_DOMAINS
) {
1998 error("%s line %d: too many hostname suffixes.",
2002 options
->canonical_domains
[
2003 options
->num_canonical_domains
++] = xstrdup(arg
);
2007 case oCanonicalizePermittedCNAMEs
:
2008 value
= options
->num_permitted_cnames
!= 0;
2010 while ((arg
= argv_next(&ac
, &av
)) != NULL
) {
2012 * Either 'none' (only in first position), '*' for
2013 * everything or 'list:list'
2015 if (strcasecmp(arg
, "none") == 0) {
2016 if (i
> 0 || ac
> 0) {
2017 error("%s line %d: keyword %s \"none\" "
2018 "argument must appear alone.",
2019 filename
, linenum
, keyword
);
2023 } else if (strcmp(arg
, "*") == 0) {
2027 if ((arg2
= strchr(arg
, ':')) == NULL
||
2029 error("%s line %d: "
2030 "Invalid permitted CNAME \"%s\"",
2031 filename
, linenum
, arg
);
2038 if (!*activep
|| value
)
2040 if (options
->num_permitted_cnames
>=
2041 MAX_CANON_DOMAINS
) {
2042 error("%s line %d: too many permitted CNAMEs.",
2046 cname
= options
->permitted_cnames
+
2047 options
->num_permitted_cnames
++;
2048 cname
->source_list
= xstrdup(arg
);
2049 cname
->target_list
= xstrdup(arg2
);
2053 case oCanonicalizeHostname
:
2054 intptr
= &options
->canonicalize_hostname
;
2055 multistate_ptr
= multistate_canonicalizehostname
;
2056 goto parse_multistate
;
2058 case oCanonicalizeMaxDots
:
2059 intptr
= &options
->canonicalize_max_dots
;
2062 case oCanonicalizeFallbackLocal
:
2063 intptr
= &options
->canonicalize_fallback_local
;
2066 case oStreamLocalBindMask
:
2067 arg
= argv_next(&ac
, &av
);
2068 if (!arg
|| *arg
== '\0') {
2069 error("%.200s line %d: Missing StreamLocalBindMask "
2070 "argument.", filename
, linenum
);
2073 /* Parse mode in octal format */
2074 value
= strtol(arg
, &endofnumber
, 8);
2075 if (arg
== endofnumber
|| value
< 0 || value
> 0777) {
2076 error("%.200s line %d: Bad mask.", filename
, linenum
);
2079 options
->fwd_opts
.streamlocal_bind_mask
= (mode_t
)value
;
2082 case oStreamLocalBindUnlink
:
2083 intptr
= &options
->fwd_opts
.streamlocal_bind_unlink
;
2086 case oRevokedHostKeys
:
2087 charptr
= &options
->revoked_host_keys
;
2090 case oFingerprintHash
:
2091 intptr
= &options
->fingerprint_hash
;
2092 arg
= argv_next(&ac
, &av
);
2093 if (!arg
|| *arg
== '\0') {
2094 error("%.200s line %d: Missing argument.",
2098 if ((value
= ssh_digest_alg_by_name(arg
)) == -1) {
2099 error("%.200s line %d: Invalid hash algorithm \"%s\".",
2100 filename
, linenum
, arg
);
2103 if (*activep
&& *intptr
== -1)
2107 case oUpdateHostkeys
:
2108 intptr
= &options
->update_hostkeys
;
2109 multistate_ptr
= multistate_yesnoask
;
2110 goto parse_multistate
;
2112 case oHostbasedAcceptedAlgorithms
:
2113 charptr
= &options
->hostbased_accepted_algos
;
2114 goto parse_pubkey_algos
;
2116 case oPubkeyAcceptedAlgorithms
:
2117 charptr
= &options
->pubkey_accepted_algos
;
2118 goto parse_pubkey_algos
;
2120 case oAddKeysToAgent
:
2121 arg
= argv_next(&ac
, &av
);
2122 arg2
= argv_next(&ac
, &av
);
2123 value
= parse_multistate_value(arg
, filename
, linenum
,
2124 multistate_yesnoaskconfirm
);
2125 value2
= 0; /* unlimited lifespan by default */
2126 if (value
== 3 && arg2
!= NULL
) {
2127 /* allow "AddKeysToAgent confirm 5m" */
2128 if ((value2
= convtime(arg2
)) == -1 ||
2130 error("%s line %d: invalid time value.",
2134 } else if (value
== -1 && arg2
== NULL
) {
2135 if ((value2
= convtime(arg
)) == -1 ||
2137 error("%s line %d: unsupported option",
2141 value
= 1; /* yes */
2142 } else if (value
== -1 || arg2
!= NULL
) {
2143 error("%s line %d: unsupported option",
2147 if (*activep
&& options
->add_keys_to_agent
== -1) {
2148 options
->add_keys_to_agent
= value
;
2149 options
->add_keys_to_agent_lifespan
= value2
;
2153 case oIdentityAgent
:
2154 charptr
= &options
->identity_agent
;
2155 arg
= argv_next(&ac
, &av
);
2156 if (!arg
|| *arg
== '\0') {
2157 error("%.200s line %d: Missing argument.",
2162 /* Extra validation if the string represents an env var. */
2163 if ((arg2
= dollar_expand(&r
, arg
)) == NULL
|| r
) {
2164 error("%.200s line %d: Invalid environment expansion "
2165 "%s.", filename
, linenum
, arg
);
2169 /* check for legacy environment format */
2170 if (arg
[0] == '$' && arg
[1] != '{' &&
2171 !valid_env_name(arg
+ 1)) {
2172 error("%.200s line %d: Invalid environment name %s.",
2173 filename
, linenum
, arg
);
2176 if (*activep
&& *charptr
== NULL
)
2177 *charptr
= xstrdup(arg
);
2180 case oRequiredRSASize
:
2181 intptr
= &options
->required_rsa_size
;
2185 debug("%s line %d: Deprecated option \"%s\"",
2186 filename
, linenum
, keyword
);
2191 error("%s line %d: Unsupported option \"%s\"",
2192 filename
, linenum
, keyword
);
2197 error("%s line %d: Unimplemented opcode %d",
2198 filename
, linenum
, opcode
);
2202 /* Check that there is no garbage at end of line. */
2204 error("%.200s line %d: keyword %s extra arguments "
2205 "at end of line", filename
, linenum
, keyword
);
2212 argv_free(oav
, oac
);
2217 * Reads the config file and modifies the options accordingly. Options
2218 * should already be initialized before this call. This never returns if
2219 * there is an error. If the file does not exist, this returns 0.
2222 read_config_file(const char *filename
, struct passwd
*pw
, const char *host
,
2223 const char *original_host
, Options
*options
, int flags
,
2224 int *want_final_pass
)
2228 return read_config_file_depth(filename
, pw
, host
, original_host
,
2229 options
, flags
, &active
, want_final_pass
, 0);
2232 #define READCONF_MAX_DEPTH 16
2234 read_config_file_depth(const char *filename
, struct passwd
*pw
,
2235 const char *host
, const char *original_host
, Options
*options
,
2236 int flags
, int *activep
, int *want_final_pass
, int depth
)
2240 size_t linesize
= 0;
2242 int bad_options
= 0;
2244 if (depth
< 0 || depth
> READCONF_MAX_DEPTH
)
2245 fatal("Too many recursive configuration includes");
2247 if ((f
= fopen(filename
, "r")) == NULL
)
2250 if (flags
& SSHCONF_CHECKPERM
) {
2253 if (fstat(fileno(f
), &sb
) == -1)
2254 fatal("fstat %s: %s", filename
, strerror(errno
));
2255 if (((sb
.st_uid
!= 0 && sb
.st_uid
!= getuid()) ||
2256 (sb
.st_mode
& 022) != 0))
2257 fatal("Bad owner or permissions on %s", filename
);
2260 debug("Reading configuration data %.200s", filename
);
2263 * Mark that we are now processing the options. This flag is turned
2264 * on/off by Host specifications.
2267 while (getline(&line
, &linesize
, f
) != -1) {
2268 /* Update line number counter. */
2271 * Trim out comments and strip whitespace.
2272 * NB - preserve newlines, they are needed to reproduce
2273 * line numbers later for error messages.
2275 if (process_config_line_depth(options
, pw
, host
, original_host
,
2276 line
, filename
, linenum
, activep
, flags
, want_final_pass
,
2282 if (bad_options
> 0)
2283 fatal("%s: terminating, %d bad configuration options",
2284 filename
, bad_options
);
2288 /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
2290 option_clear_or_none(const char *o
)
2292 return o
== NULL
|| strcasecmp(o
, "none") == 0;
2296 * Returns 1 if CanonicalizePermittedCNAMEs have been specified, 0 otherwise.
2297 * Allowed to be called on non-final configuration.
2300 config_has_permitted_cnames(Options
*options
)
2302 if (options
->num_permitted_cnames
== 1 &&
2303 strcasecmp(options
->permitted_cnames
[0].source_list
, "none") == 0 &&
2304 strcmp(options
->permitted_cnames
[0].target_list
, "") == 0)
2306 return options
->num_permitted_cnames
> 0;
2310 * Initializes options to special values that indicate that they have not yet
2311 * been set. Read_config_file will only set options with this value. Options
2312 * are processed in the following order: command line, user config file,
2313 * system config file. Last, fill_default_options is called.
2317 initialize_options(Options
* options
)
2319 memset(options
, 'X', sizeof(*options
));
2320 options
->forward_agent
= -1;
2321 options
->forward_agent_sock_path
= NULL
;
2322 options
->forward_x11
= -1;
2323 options
->forward_x11_trusted
= -1;
2324 options
->forward_x11_timeout
= -1;
2325 options
->stdio_forward_host
= NULL
;
2326 options
->stdio_forward_port
= 0;
2327 options
->clear_forwardings
= -1;
2328 options
->exit_on_forward_failure
= -1;
2329 options
->xauth_location
= NULL
;
2330 options
->fwd_opts
.gateway_ports
= -1;
2331 options
->fwd_opts
.streamlocal_bind_mask
= (mode_t
)-1;
2332 options
->fwd_opts
.streamlocal_bind_unlink
= -1;
2333 options
->pubkey_authentication
= -1;
2334 options
->gss_authentication
= -1;
2335 options
->gss_deleg_creds
= -1;
2336 options
->password_authentication
= -1;
2337 options
->kbd_interactive_authentication
= -1;
2338 options
->kbd_interactive_devices
= NULL
;
2339 options
->hostbased_authentication
= -1;
2340 options
->batch_mode
= -1;
2341 options
->check_host_ip
= -1;
2342 options
->strict_host_key_checking
= -1;
2343 options
->compression
= -1;
2344 options
->tcp_keep_alive
= -1;
2346 options
->address_family
= -1;
2347 options
->connection_attempts
= -1;
2348 options
->connection_timeout
= -1;
2349 options
->number_of_password_prompts
= -1;
2350 options
->ciphers
= NULL
;
2351 options
->macs
= NULL
;
2352 options
->kex_algorithms
= NULL
;
2353 options
->hostkeyalgorithms
= NULL
;
2354 options
->ca_sign_algorithms
= NULL
;
2355 options
->num_identity_files
= 0;
2356 memset(options
->identity_keys
, 0, sizeof(options
->identity_keys
));
2357 options
->num_certificate_files
= 0;
2358 memset(options
->certificates
, 0, sizeof(options
->certificates
));
2359 options
->hostname
= NULL
;
2360 options
->host_key_alias
= NULL
;
2361 options
->proxy_command
= NULL
;
2362 options
->jump_user
= NULL
;
2363 options
->jump_host
= NULL
;
2364 options
->jump_port
= -1;
2365 options
->jump_extra
= NULL
;
2366 options
->user
= NULL
;
2367 options
->escape_char
= -1;
2368 options
->num_system_hostfiles
= 0;
2369 options
->num_user_hostfiles
= 0;
2370 options
->local_forwards
= NULL
;
2371 options
->num_local_forwards
= 0;
2372 options
->remote_forwards
= NULL
;
2373 options
->num_remote_forwards
= 0;
2374 options
->permitted_remote_opens
= NULL
;
2375 options
->num_permitted_remote_opens
= 0;
2376 options
->log_facility
= SYSLOG_FACILITY_NOT_SET
;
2377 options
->log_level
= SYSLOG_LEVEL_NOT_SET
;
2378 options
->num_log_verbose
= 0;
2379 options
->log_verbose
= NULL
;
2380 options
->preferred_authentications
= NULL
;
2381 options
->bind_address
= NULL
;
2382 options
->bind_interface
= NULL
;
2383 options
->pkcs11_provider
= NULL
;
2384 options
->sk_provider
= NULL
;
2385 options
->enable_ssh_keysign
= - 1;
2386 options
->no_host_authentication_for_localhost
= - 1;
2387 options
->identities_only
= - 1;
2388 options
->rekey_limit
= - 1;
2389 options
->rekey_interval
= -1;
2390 options
->verify_host_key_dns
= -1;
2391 options
->server_alive_interval
= -1;
2392 options
->server_alive_count_max
= -1;
2393 options
->send_env
= NULL
;
2394 options
->num_send_env
= 0;
2395 options
->setenv
= NULL
;
2396 options
->num_setenv
= 0;
2397 options
->control_path
= NULL
;
2398 options
->control_master
= -1;
2399 options
->control_persist
= -1;
2400 options
->control_persist_timeout
= 0;
2401 options
->hash_known_hosts
= -1;
2402 options
->tun_open
= -1;
2403 options
->tun_local
= -1;
2404 options
->tun_remote
= -1;
2405 options
->local_command
= NULL
;
2406 options
->permit_local_command
= -1;
2407 options
->remote_command
= NULL
;
2408 options
->add_keys_to_agent
= -1;
2409 options
->add_keys_to_agent_lifespan
= -1;
2410 options
->identity_agent
= NULL
;
2411 options
->visual_host_key
= -1;
2412 options
->ip_qos_interactive
= -1;
2413 options
->ip_qos_bulk
= -1;
2414 options
->request_tty
= -1;
2415 options
->session_type
= -1;
2416 options
->stdin_null
= -1;
2417 options
->fork_after_authentication
= -1;
2418 options
->proxy_use_fdpass
= -1;
2419 options
->ignored_unknown
= NULL
;
2420 options
->num_canonical_domains
= 0;
2421 options
->num_permitted_cnames
= 0;
2422 options
->canonicalize_max_dots
= -1;
2423 options
->canonicalize_fallback_local
= -1;
2424 options
->canonicalize_hostname
= -1;
2425 options
->revoked_host_keys
= NULL
;
2426 options
->fingerprint_hash
= -1;
2427 options
->update_hostkeys
= -1;
2428 options
->hostbased_accepted_algos
= NULL
;
2429 options
->pubkey_accepted_algos
= NULL
;
2430 options
->known_hosts_command
= NULL
;
2431 options
->required_rsa_size
= -1;
2435 * A petite version of fill_default_options() that just fills the options
2436 * needed for hostname canonicalization to proceed.
2439 fill_default_options_for_canonicalization(Options
*options
)
2441 if (options
->canonicalize_max_dots
== -1)
2442 options
->canonicalize_max_dots
= 1;
2443 if (options
->canonicalize_fallback_local
== -1)
2444 options
->canonicalize_fallback_local
= 1;
2445 if (options
->canonicalize_hostname
== -1)
2446 options
->canonicalize_hostname
= SSH_CANONICALISE_NO
;
2450 * Called after processing other sources of option data, this fills those
2451 * options for which no value has been specified with their default values.
2454 fill_default_options(Options
* options
)
2456 char *all_cipher
, *all_mac
, *all_kex
, *all_key
, *all_sig
;
2457 char *def_cipher
, *def_mac
, *def_kex
, *def_key
, *def_sig
;
2460 if (options
->forward_agent
== -1)
2461 options
->forward_agent
= 0;
2462 if (options
->forward_x11
== -1)
2463 options
->forward_x11
= 0;
2464 if (options
->forward_x11_trusted
== -1)
2465 options
->forward_x11_trusted
= 0;
2466 if (options
->forward_x11_timeout
== -1)
2467 options
->forward_x11_timeout
= 1200;
2469 * stdio forwarding (-W) changes the default for these but we defer
2470 * setting the values so they can be overridden.
2472 if (options
->exit_on_forward_failure
== -1)
2473 options
->exit_on_forward_failure
=
2474 options
->stdio_forward_host
!= NULL
? 1 : 0;
2475 if (options
->clear_forwardings
== -1)
2476 options
->clear_forwardings
=
2477 options
->stdio_forward_host
!= NULL
? 1 : 0;
2478 if (options
->clear_forwardings
== 1)
2479 clear_forwardings(options
);
2481 if (options
->xauth_location
== NULL
)
2482 options
->xauth_location
= xstrdup(_PATH_XAUTH
);
2483 if (options
->fwd_opts
.gateway_ports
== -1)
2484 options
->fwd_opts
.gateway_ports
= 0;
2485 if (options
->fwd_opts
.streamlocal_bind_mask
== (mode_t
)-1)
2486 options
->fwd_opts
.streamlocal_bind_mask
= 0177;
2487 if (options
->fwd_opts
.streamlocal_bind_unlink
== -1)
2488 options
->fwd_opts
.streamlocal_bind_unlink
= 0;
2489 if (options
->pubkey_authentication
== -1)
2490 options
->pubkey_authentication
= SSH_PUBKEY_AUTH_ALL
;
2491 if (options
->gss_authentication
== -1)
2492 options
->gss_authentication
= 0;
2493 if (options
->gss_deleg_creds
== -1)
2494 options
->gss_deleg_creds
= 0;
2495 if (options
->password_authentication
== -1)
2496 options
->password_authentication
= 1;
2497 if (options
->kbd_interactive_authentication
== -1)
2498 options
->kbd_interactive_authentication
= 1;
2499 if (options
->hostbased_authentication
== -1)
2500 options
->hostbased_authentication
= 0;
2501 if (options
->batch_mode
== -1)
2502 options
->batch_mode
= 0;
2503 if (options
->check_host_ip
== -1)
2504 options
->check_host_ip
= 0;
2505 if (options
->strict_host_key_checking
== -1)
2506 options
->strict_host_key_checking
= SSH_STRICT_HOSTKEY_ASK
;
2507 if (options
->compression
== -1)
2508 options
->compression
= 0;
2509 if (options
->tcp_keep_alive
== -1)
2510 options
->tcp_keep_alive
= 1;
2511 if (options
->port
== -1)
2512 options
->port
= 0; /* Filled in ssh_connect. */
2513 if (options
->address_family
== -1)
2514 options
->address_family
= AF_UNSPEC
;
2515 if (options
->connection_attempts
== -1)
2516 options
->connection_attempts
= 1;
2517 if (options
->number_of_password_prompts
== -1)
2518 options
->number_of_password_prompts
= 3;
2519 /* options->hostkeyalgorithms, default set in myproposals.h */
2520 if (options
->add_keys_to_agent
== -1) {
2521 options
->add_keys_to_agent
= 0;
2522 options
->add_keys_to_agent_lifespan
= 0;
2524 if (options
->num_identity_files
== 0) {
2525 add_identity_file(options
, "~/", _PATH_SSH_CLIENT_ID_RSA
, 0);
2526 #ifdef OPENSSL_HAS_ECC
2527 add_identity_file(options
, "~/", _PATH_SSH_CLIENT_ID_ECDSA
, 0);
2528 add_identity_file(options
, "~/",
2529 _PATH_SSH_CLIENT_ID_ECDSA_SK
, 0);
2531 add_identity_file(options
, "~/",
2532 _PATH_SSH_CLIENT_ID_ED25519
, 0);
2533 add_identity_file(options
, "~/",
2534 _PATH_SSH_CLIENT_ID_ED25519_SK
, 0);
2535 add_identity_file(options
, "~/", _PATH_SSH_CLIENT_ID_XMSS
, 0);
2536 add_identity_file(options
, "~/", _PATH_SSH_CLIENT_ID_DSA
, 0);
2538 if (options
->escape_char
== -1)
2539 options
->escape_char
= '~';
2540 if (options
->num_system_hostfiles
== 0) {
2541 options
->system_hostfiles
[options
->num_system_hostfiles
++] =
2542 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE
);
2543 options
->system_hostfiles
[options
->num_system_hostfiles
++] =
2544 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2
);
2546 if (options
->update_hostkeys
== -1) {
2547 if (options
->verify_host_key_dns
<= 0 &&
2548 (options
->num_user_hostfiles
== 0 ||
2549 (options
->num_user_hostfiles
== 1 && strcmp(options
->
2550 user_hostfiles
[0], _PATH_SSH_USER_HOSTFILE
) == 0)))
2551 options
->update_hostkeys
= SSH_UPDATE_HOSTKEYS_YES
;
2553 options
->update_hostkeys
= SSH_UPDATE_HOSTKEYS_NO
;
2555 if (options
->num_user_hostfiles
== 0) {
2556 options
->user_hostfiles
[options
->num_user_hostfiles
++] =
2557 xstrdup(_PATH_SSH_USER_HOSTFILE
);
2558 options
->user_hostfiles
[options
->num_user_hostfiles
++] =
2559 xstrdup(_PATH_SSH_USER_HOSTFILE2
);
2561 if (options
->log_level
== SYSLOG_LEVEL_NOT_SET
)
2562 options
->log_level
= SYSLOG_LEVEL_INFO
;
2563 if (options
->log_facility
== SYSLOG_FACILITY_NOT_SET
)
2564 options
->log_facility
= SYSLOG_FACILITY_USER
;
2565 if (options
->no_host_authentication_for_localhost
== - 1)
2566 options
->no_host_authentication_for_localhost
= 0;
2567 if (options
->identities_only
== -1)
2568 options
->identities_only
= 0;
2569 if (options
->enable_ssh_keysign
== -1)
2570 options
->enable_ssh_keysign
= 0;
2571 if (options
->rekey_limit
== -1)
2572 options
->rekey_limit
= 0;
2573 if (options
->rekey_interval
== -1)
2574 options
->rekey_interval
= 0;
2575 if (options
->verify_host_key_dns
== -1)
2576 options
->verify_host_key_dns
= 0;
2577 if (options
->server_alive_interval
== -1)
2578 options
->server_alive_interval
= 0;
2579 if (options
->server_alive_count_max
== -1)
2580 options
->server_alive_count_max
= 3;
2581 if (options
->control_master
== -1)
2582 options
->control_master
= 0;
2583 if (options
->control_persist
== -1) {
2584 options
->control_persist
= 0;
2585 options
->control_persist_timeout
= 0;
2587 if (options
->hash_known_hosts
== -1)
2588 options
->hash_known_hosts
= 0;
2589 if (options
->tun_open
== -1)
2590 options
->tun_open
= SSH_TUNMODE_NO
;
2591 if (options
->tun_local
== -1)
2592 options
->tun_local
= SSH_TUNID_ANY
;
2593 if (options
->tun_remote
== -1)
2594 options
->tun_remote
= SSH_TUNID_ANY
;
2595 if (options
->permit_local_command
== -1)
2596 options
->permit_local_command
= 0;
2597 if (options
->visual_host_key
== -1)
2598 options
->visual_host_key
= 0;
2599 if (options
->ip_qos_interactive
== -1)
2600 options
->ip_qos_interactive
= IPTOS_DSCP_AF21
;
2601 if (options
->ip_qos_bulk
== -1)
2602 options
->ip_qos_bulk
= IPTOS_DSCP_CS1
;
2603 if (options
->request_tty
== -1)
2604 options
->request_tty
= REQUEST_TTY_AUTO
;
2605 if (options
->session_type
== -1)
2606 options
->session_type
= SESSION_TYPE_DEFAULT
;
2607 if (options
->stdin_null
== -1)
2608 options
->stdin_null
= 0;
2609 if (options
->fork_after_authentication
== -1)
2610 options
->fork_after_authentication
= 0;
2611 if (options
->proxy_use_fdpass
== -1)
2612 options
->proxy_use_fdpass
= 0;
2613 if (options
->canonicalize_max_dots
== -1)
2614 options
->canonicalize_max_dots
= 1;
2615 if (options
->canonicalize_fallback_local
== -1)
2616 options
->canonicalize_fallback_local
= 1;
2617 if (options
->canonicalize_hostname
== -1)
2618 options
->canonicalize_hostname
= SSH_CANONICALISE_NO
;
2619 if (options
->fingerprint_hash
== -1)
2620 options
->fingerprint_hash
= SSH_FP_HASH_DEFAULT
;
2621 #ifdef ENABLE_SK_INTERNAL
2622 if (options
->sk_provider
== NULL
)
2623 options
->sk_provider
= xstrdup("internal");
2625 if (options
->sk_provider
== NULL
)
2626 options
->sk_provider
= xstrdup("$SSH_SK_PROVIDER");
2628 if (options
->required_rsa_size
== -1)
2629 options
->required_rsa_size
= SSH_RSA_MINIMUM_MODULUS_SIZE
;
2631 /* Expand KEX name lists */
2632 all_cipher
= cipher_alg_list(',', 0);
2633 all_mac
= mac_alg_list(',');
2634 all_kex
= kex_alg_list(',');
2635 all_key
= sshkey_alg_list(0, 0, 1, ',');
2636 all_sig
= sshkey_alg_list(0, 1, 1, ',');
2637 /* remove unsupported algos from default lists */
2638 def_cipher
= match_filter_allowlist(KEX_CLIENT_ENCRYPT
, all_cipher
);
2639 def_mac
= match_filter_allowlist(KEX_CLIENT_MAC
, all_mac
);
2640 def_kex
= match_filter_allowlist(KEX_CLIENT_KEX
, all_kex
);
2641 def_key
= match_filter_allowlist(KEX_DEFAULT_PK_ALG
, all_key
);
2642 def_sig
= match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS
, all_sig
);
2643 #define ASSEMBLE(what, defaults, all) \
2645 if ((r = kex_assemble_names(&options->what, \
2646 defaults, all)) != 0) { \
2647 error_fr(r, "%s", #what); \
2651 ASSEMBLE(ciphers
, def_cipher
, all_cipher
);
2652 ASSEMBLE(macs
, def_mac
, all_mac
);
2653 ASSEMBLE(kex_algorithms
, def_kex
, all_kex
);
2654 ASSEMBLE(hostbased_accepted_algos
, def_key
, all_key
);
2655 ASSEMBLE(pubkey_accepted_algos
, def_key
, all_key
);
2656 ASSEMBLE(ca_sign_algorithms
, def_sig
, all_sig
);
2659 #define CLEAR_ON_NONE(v) \
2661 if (option_clear_or_none(v)) { \
2666 CLEAR_ON_NONE(options
->local_command
);
2667 CLEAR_ON_NONE(options
->remote_command
);
2668 CLEAR_ON_NONE(options
->proxy_command
);
2669 CLEAR_ON_NONE(options
->control_path
);
2670 CLEAR_ON_NONE(options
->revoked_host_keys
);
2671 CLEAR_ON_NONE(options
->pkcs11_provider
);
2672 CLEAR_ON_NONE(options
->sk_provider
);
2673 CLEAR_ON_NONE(options
->known_hosts_command
);
2674 if (options
->jump_host
!= NULL
&&
2675 strcmp(options
->jump_host
, "none") == 0 &&
2676 options
->jump_port
== 0 && options
->jump_user
== NULL
) {
2677 free(options
->jump_host
);
2678 options
->jump_host
= NULL
;
2680 if (options
->num_permitted_cnames
== 1 &&
2681 !config_has_permitted_cnames(options
)) {
2682 /* clean up CanonicalizePermittedCNAMEs=none */
2683 free(options
->permitted_cnames
[0].source_list
);
2684 free(options
->permitted_cnames
[0].target_list
);
2685 memset(options
->permitted_cnames
, '\0',
2686 sizeof(*options
->permitted_cnames
));
2687 options
->num_permitted_cnames
= 0;
2689 /* options->identity_agent distinguishes NULL from 'none' */
2690 /* options->user will be set in the main program if appropriate */
2691 /* options->hostname will be set in the main program if appropriate */
2692 /* options->host_key_alias should not be set by default */
2693 /* options->preferred_authentications will be set in ssh */
2712 free_options(Options
*o
)
2719 #define FREE_ARRAY(type, n, a) \
2722 for (_i = 0; _i < (n); _i++) \
2726 free(o
->forward_agent_sock_path
);
2727 free(o
->xauth_location
);
2728 FREE_ARRAY(u_int
, o
->num_log_verbose
, o
->log_verbose
);
2729 free(o
->log_verbose
);
2732 free(o
->hostkeyalgorithms
);
2733 free(o
->kex_algorithms
);
2734 free(o
->ca_sign_algorithms
);
2736 free(o
->host_key_alias
);
2737 free(o
->proxy_command
);
2739 FREE_ARRAY(u_int
, o
->num_system_hostfiles
, o
->system_hostfiles
);
2740 FREE_ARRAY(u_int
, o
->num_user_hostfiles
, o
->user_hostfiles
);
2741 free(o
->preferred_authentications
);
2742 free(o
->bind_address
);
2743 free(o
->bind_interface
);
2744 free(o
->pkcs11_provider
);
2745 free(o
->sk_provider
);
2746 for (i
= 0; i
< o
->num_identity_files
; i
++) {
2747 free(o
->identity_files
[i
]);
2748 sshkey_free(o
->identity_keys
[i
]);
2750 for (i
= 0; i
< o
->num_certificate_files
; i
++) {
2751 free(o
->certificate_files
[i
]);
2752 sshkey_free(o
->certificates
[i
]);
2754 free(o
->identity_agent
);
2755 for (i
= 0; i
< o
->num_local_forwards
; i
++) {
2756 free(o
->local_forwards
[i
].listen_host
);
2757 free(o
->local_forwards
[i
].listen_path
);
2758 free(o
->local_forwards
[i
].connect_host
);
2759 free(o
->local_forwards
[i
].connect_path
);
2761 free(o
->local_forwards
);
2762 for (i
= 0; i
< o
->num_remote_forwards
; i
++) {
2763 free(o
->remote_forwards
[i
].listen_host
);
2764 free(o
->remote_forwards
[i
].listen_path
);
2765 free(o
->remote_forwards
[i
].connect_host
);
2766 free(o
->remote_forwards
[i
].connect_path
);
2768 free(o
->remote_forwards
);
2769 free(o
->stdio_forward_host
);
2770 FREE_ARRAY(u_int
, o
->num_send_env
, o
->send_env
);
2772 FREE_ARRAY(u_int
, o
->num_setenv
, o
->setenv
);
2774 free(o
->control_path
);
2775 free(o
->local_command
);
2776 free(o
->remote_command
);
2777 FREE_ARRAY(int, o
->num_canonical_domains
, o
->canonical_domains
);
2778 for (i
= 0; i
< o
->num_permitted_cnames
; i
++) {
2779 free(o
->permitted_cnames
[i
].source_list
);
2780 free(o
->permitted_cnames
[i
].target_list
);
2782 free(o
->revoked_host_keys
);
2783 free(o
->hostbased_accepted_algos
);
2784 free(o
->pubkey_accepted_algos
);
2787 free(o
->jump_extra
);
2788 free(o
->ignored_unknown
);
2789 explicit_bzero(o
, sizeof(*o
));
2800 * parses the next field in a port forwarding specification.
2801 * sets fwd to the parsed field and advances p past the colon
2802 * or sets it to NULL at end of string.
2803 * returns 0 on success, else non-zero.
2806 parse_fwd_field(char **p
, struct fwdarg
*fwd
)
2813 return -1; /* end of string */
2817 * A field escaped with square brackets is used literally.
2818 * XXX - allow ']' to be escaped via backslash?
2821 /* find matching ']' */
2822 for (ep
= cp
+ 1; *ep
!= ']' && *ep
!= '\0'; ep
++) {
2826 /* no matching ']' or not at end of field. */
2827 if (ep
[0] != ']' || (ep
[1] != ':' && ep
[1] != '\0'))
2829 /* NUL terminate the field and advance p past the colon */
2834 fwd
->ispath
= ispath
;
2839 for (cp
= *p
; *cp
!= '\0'; cp
++) {
2842 memmove(cp
, cp
+ 1, strlen(cp
+ 1) + 1);
2856 fwd
->ispath
= ispath
;
2863 * parses a string containing a port forwarding specification of the form:
2865 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2866 * listenpath:connectpath
2868 * [listenhost:]listenport
2869 * returns number of arguments parsed or zero on error
2872 parse_forward(struct Forward
*fwd
, const char *fwdspec
, int dynamicfwd
, int remotefwd
)
2874 struct fwdarg fwdargs
[4];
2878 memset(fwd
, 0, sizeof(*fwd
));
2879 memset(fwdargs
, 0, sizeof(fwdargs
));
2882 * We expand environment variables before checking if we think they're
2883 * paths so that if ${VAR} expands to a fully qualified path it is
2884 * treated as a path.
2886 cp
= p
= dollar_expand(&err
, fwdspec
);
2887 if (p
== NULL
|| err
)
2890 /* skip leading spaces */
2891 while (isspace((u_char
)*cp
))
2894 for (i
= 0; i
< 4; ++i
) {
2895 if (parse_fwd_field(&cp
, &fwdargs
[i
]) != 0)
2899 /* Check for trailing garbage */
2900 if (cp
!= NULL
&& *cp
!= '\0') {
2901 i
= 0; /* failure */
2906 if (fwdargs
[0].ispath
) {
2907 fwd
->listen_path
= xstrdup(fwdargs
[0].arg
);
2908 fwd
->listen_port
= PORT_STREAMLOCAL
;
2910 fwd
->listen_host
= NULL
;
2911 fwd
->listen_port
= a2port(fwdargs
[0].arg
);
2913 fwd
->connect_host
= xstrdup("socks");
2917 if (fwdargs
[0].ispath
&& fwdargs
[1].ispath
) {
2918 fwd
->listen_path
= xstrdup(fwdargs
[0].arg
);
2919 fwd
->listen_port
= PORT_STREAMLOCAL
;
2920 fwd
->connect_path
= xstrdup(fwdargs
[1].arg
);
2921 fwd
->connect_port
= PORT_STREAMLOCAL
;
2922 } else if (fwdargs
[1].ispath
) {
2923 fwd
->listen_host
= NULL
;
2924 fwd
->listen_port
= a2port(fwdargs
[0].arg
);
2925 fwd
->connect_path
= xstrdup(fwdargs
[1].arg
);
2926 fwd
->connect_port
= PORT_STREAMLOCAL
;
2928 fwd
->listen_host
= xstrdup(fwdargs
[0].arg
);
2929 fwd
->listen_port
= a2port(fwdargs
[1].arg
);
2930 fwd
->connect_host
= xstrdup("socks");
2935 if (fwdargs
[0].ispath
) {
2936 fwd
->listen_path
= xstrdup(fwdargs
[0].arg
);
2937 fwd
->listen_port
= PORT_STREAMLOCAL
;
2938 fwd
->connect_host
= xstrdup(fwdargs
[1].arg
);
2939 fwd
->connect_port
= a2port(fwdargs
[2].arg
);
2940 } else if (fwdargs
[2].ispath
) {
2941 fwd
->listen_host
= xstrdup(fwdargs
[0].arg
);
2942 fwd
->listen_port
= a2port(fwdargs
[1].arg
);
2943 fwd
->connect_path
= xstrdup(fwdargs
[2].arg
);
2944 fwd
->connect_port
= PORT_STREAMLOCAL
;
2946 fwd
->listen_host
= NULL
;
2947 fwd
->listen_port
= a2port(fwdargs
[0].arg
);
2948 fwd
->connect_host
= xstrdup(fwdargs
[1].arg
);
2949 fwd
->connect_port
= a2port(fwdargs
[2].arg
);
2954 fwd
->listen_host
= xstrdup(fwdargs
[0].arg
);
2955 fwd
->listen_port
= a2port(fwdargs
[1].arg
);
2956 fwd
->connect_host
= xstrdup(fwdargs
[2].arg
);
2957 fwd
->connect_port
= a2port(fwdargs
[3].arg
);
2960 i
= 0; /* failure */
2966 if (!(i
== 1 || i
== 2))
2969 if (!(i
== 3 || i
== 4)) {
2970 if (fwd
->connect_path
== NULL
&&
2971 fwd
->listen_path
== NULL
)
2974 if (fwd
->connect_port
<= 0 && fwd
->connect_path
== NULL
)
2978 if ((fwd
->listen_port
< 0 && fwd
->listen_path
== NULL
) ||
2979 (!remotefwd
&& fwd
->listen_port
== 0))
2981 if (fwd
->connect_host
!= NULL
&&
2982 strlen(fwd
->connect_host
) >= NI_MAXHOST
)
2985 * XXX - if connecting to a remote socket, max sun len may not
2988 if (fwd
->connect_path
!= NULL
&&
2989 strlen(fwd
->connect_path
) >= PATH_MAX_SUN
)
2991 if (fwd
->listen_host
!= NULL
&&
2992 strlen(fwd
->listen_host
) >= NI_MAXHOST
)
2994 if (fwd
->listen_path
!= NULL
&&
2995 strlen(fwd
->listen_path
) >= PATH_MAX_SUN
)
3001 free(fwd
->connect_host
);
3002 fwd
->connect_host
= NULL
;
3003 free(fwd
->connect_path
);
3004 fwd
->connect_path
= NULL
;
3005 free(fwd
->listen_host
);
3006 fwd
->listen_host
= NULL
;
3007 free(fwd
->listen_path
);
3008 fwd
->listen_path
= NULL
;
3013 parse_jump(const char *s
, Options
*o
, int active
)
3015 char *orig
, *sdup
, *cp
;
3016 char *host
= NULL
, *user
= NULL
;
3017 int r
, ret
= -1, port
= -1, first
;
3019 active
&= o
->proxy_command
== NULL
&& o
->jump_host
== NULL
;
3021 orig
= sdup
= xstrdup(s
);
3023 /* Remove comment and trailing whitespace */
3024 if ((cp
= strchr(orig
, '#')) != NULL
)
3030 if (strcasecmp(s
, "none") == 0)
3032 if ((cp
= strrchr(sdup
, ',')) == NULL
)
3033 cp
= sdup
; /* last */
3038 /* First argument and configuration is active */
3039 r
= parse_ssh_uri(cp
, &user
, &host
, &port
);
3040 if (r
== -1 || (r
== 1 &&
3041 parse_user_host_port(cp
, &user
, &host
, &port
) != 0))
3044 /* Subsequent argument or inactive configuration */
3045 r
= parse_ssh_uri(cp
, NULL
, NULL
, NULL
);
3046 if (r
== -1 || (r
== 1 &&
3047 parse_user_host_port(cp
, NULL
, NULL
, NULL
) != 0))
3050 first
= 0; /* only check syntax for subsequent hosts */
3051 } while (cp
!= sdup
);
3054 if (strcasecmp(s
, "none") == 0) {
3055 o
->jump_host
= xstrdup("none");
3058 o
->jump_user
= user
;
3059 o
->jump_host
= host
;
3060 o
->jump_port
= port
;
3061 o
->proxy_command
= xstrdup("none");
3063 if ((cp
= strrchr(s
, ',')) != NULL
&& cp
!= s
) {
3064 o
->jump_extra
= xstrdup(s
);
3065 o
->jump_extra
[cp
- s
] = '\0';
3078 parse_ssh_uri(const char *uri
, char **userp
, char **hostp
, int *portp
)
3080 char *user
= NULL
, *host
= NULL
, *path
= NULL
;
3083 r
= parse_uri("ssh", uri
, &user
, &host
, &port
, &path
);
3084 if (r
== 0 && path
!= NULL
)
3085 r
= -1; /* path not allowed */
3087 if (userp
!= NULL
) {
3091 if (hostp
!= NULL
) {
3104 /* XXX the following is a near-vebatim copy from servconf.c; refactor */
3106 fmt_multistate_int(int val
, const struct multistate
*m
)
3110 for (i
= 0; m
[i
].key
!= NULL
; i
++) {
3111 if (m
[i
].value
== val
)
3118 fmt_intarg(OpCodes code
, int val
)
3123 case oAddressFamily
:
3124 return fmt_multistate_int(val
, multistate_addressfamily
);
3125 case oVerifyHostKeyDNS
:
3126 case oUpdateHostkeys
:
3127 return fmt_multistate_int(val
, multistate_yesnoask
);
3128 case oStrictHostKeyChecking
:
3129 return fmt_multistate_int(val
, multistate_strict_hostkey
);
3130 case oControlMaster
:
3131 return fmt_multistate_int(val
, multistate_controlmaster
);
3133 return fmt_multistate_int(val
, multistate_tunnel
);
3135 return fmt_multistate_int(val
, multistate_requesttty
);
3137 return fmt_multistate_int(val
, multistate_sessiontype
);
3138 case oCanonicalizeHostname
:
3139 return fmt_multistate_int(val
, multistate_canonicalizehostname
);
3140 case oAddKeysToAgent
:
3141 return fmt_multistate_int(val
, multistate_yesnoaskconfirm
);
3142 case oPubkeyAuthentication
:
3143 return fmt_multistate_int(val
, multistate_pubkey_auth
);
3144 case oFingerprintHash
:
3145 return ssh_digest_alg_name(val
);
3159 lookup_opcode_name(OpCodes code
)
3163 for (i
= 0; keywords
[i
].name
!= NULL
; i
++)
3164 if (keywords
[i
].opcode
== code
)
3165 return(keywords
[i
].name
);
3170 dump_cfg_int(OpCodes code
, int val
)
3172 printf("%s %d\n", lookup_opcode_name(code
), val
);
3176 dump_cfg_fmtint(OpCodes code
, int val
)
3178 printf("%s %s\n", lookup_opcode_name(code
), fmt_intarg(code
, val
));
3182 dump_cfg_string(OpCodes code
, const char *val
)
3186 printf("%s %s\n", lookup_opcode_name(code
), val
);
3190 dump_cfg_strarray(OpCodes code
, u_int count
, char **vals
)
3194 for (i
= 0; i
< count
; i
++)
3195 printf("%s %s\n", lookup_opcode_name(code
), vals
[i
]);
3199 dump_cfg_strarray_oneline(OpCodes code
, u_int count
, char **vals
)
3203 printf("%s", lookup_opcode_name(code
));
3206 for (i
= 0; i
< count
; i
++)
3207 printf(" %s", vals
[i
]);
3212 dump_cfg_forwards(OpCodes code
, u_int count
, const struct Forward
*fwds
)
3214 const struct Forward
*fwd
;
3217 /* oDynamicForward */
3218 for (i
= 0; i
< count
; i
++) {
3220 if (code
== oDynamicForward
&& fwd
->connect_host
!= NULL
&&
3221 strcmp(fwd
->connect_host
, "socks") != 0)
3223 if (code
== oLocalForward
&& fwd
->connect_host
!= NULL
&&
3224 strcmp(fwd
->connect_host
, "socks") == 0)
3226 printf("%s", lookup_opcode_name(code
));
3227 if (fwd
->listen_port
== PORT_STREAMLOCAL
)
3228 printf(" %s", fwd
->listen_path
);
3229 else if (fwd
->listen_host
== NULL
)
3230 printf(" %d", fwd
->listen_port
);
3233 fwd
->listen_host
, fwd
->listen_port
);
3235 if (code
!= oDynamicForward
) {
3236 if (fwd
->connect_port
== PORT_STREAMLOCAL
)
3237 printf(" %s", fwd
->connect_path
);
3238 else if (fwd
->connect_host
== NULL
)
3239 printf(" %d", fwd
->connect_port
);
3242 fwd
->connect_host
, fwd
->connect_port
);
3250 dump_client_config(Options
*o
, const char *host
)
3253 char buf
[8], *all_key
;
3256 * Expand HostKeyAlgorithms name lists. This isn't handled in
3257 * fill_default_options() like the other algorithm lists because
3258 * the host key algorithms are by default dynamically chosen based
3259 * on the host's keys found in known_hosts.
3261 all_key
= sshkey_alg_list(0, 0, 1, ',');
3262 if ((r
= kex_assemble_names(&o
->hostkeyalgorithms
, kex_default_pk_alg(),
3264 fatal_fr(r
, "expand HostKeyAlgorithms");
3267 /* Most interesting options first: user, host, port */
3268 dump_cfg_string(oUser
, o
->user
);
3269 dump_cfg_string(oHostname
, host
);
3270 dump_cfg_int(oPort
, o
->port
);
3273 dump_cfg_fmtint(oAddressFamily
, o
->address_family
);
3274 dump_cfg_fmtint(oBatchMode
, o
->batch_mode
);
3275 dump_cfg_fmtint(oCanonicalizeFallbackLocal
, o
->canonicalize_fallback_local
);
3276 dump_cfg_fmtint(oCanonicalizeHostname
, o
->canonicalize_hostname
);
3277 dump_cfg_fmtint(oCheckHostIP
, o
->check_host_ip
);
3278 dump_cfg_fmtint(oCompression
, o
->compression
);
3279 dump_cfg_fmtint(oControlMaster
, o
->control_master
);
3280 dump_cfg_fmtint(oEnableSSHKeysign
, o
->enable_ssh_keysign
);
3281 dump_cfg_fmtint(oClearAllForwardings
, o
->clear_forwardings
);
3282 dump_cfg_fmtint(oExitOnForwardFailure
, o
->exit_on_forward_failure
);
3283 dump_cfg_fmtint(oFingerprintHash
, o
->fingerprint_hash
);
3284 dump_cfg_fmtint(oForwardX11
, o
->forward_x11
);
3285 dump_cfg_fmtint(oForwardX11Trusted
, o
->forward_x11_trusted
);
3286 dump_cfg_fmtint(oGatewayPorts
, o
->fwd_opts
.gateway_ports
);
3288 dump_cfg_fmtint(oGssAuthentication
, o
->gss_authentication
);
3289 dump_cfg_fmtint(oGssDelegateCreds
, o
->gss_deleg_creds
);
3291 dump_cfg_fmtint(oHashKnownHosts
, o
->hash_known_hosts
);
3292 dump_cfg_fmtint(oHostbasedAuthentication
, o
->hostbased_authentication
);
3293 dump_cfg_fmtint(oIdentitiesOnly
, o
->identities_only
);
3294 dump_cfg_fmtint(oKbdInteractiveAuthentication
, o
->kbd_interactive_authentication
);
3295 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost
, o
->no_host_authentication_for_localhost
);
3296 dump_cfg_fmtint(oPasswordAuthentication
, o
->password_authentication
);
3297 dump_cfg_fmtint(oPermitLocalCommand
, o
->permit_local_command
);
3298 dump_cfg_fmtint(oProxyUseFdpass
, o
->proxy_use_fdpass
);
3299 dump_cfg_fmtint(oPubkeyAuthentication
, o
->pubkey_authentication
);
3300 dump_cfg_fmtint(oRequestTTY
, o
->request_tty
);
3301 dump_cfg_fmtint(oSessionType
, o
->session_type
);
3302 dump_cfg_fmtint(oStdinNull
, o
->stdin_null
);
3303 dump_cfg_fmtint(oForkAfterAuthentication
, o
->fork_after_authentication
);
3304 dump_cfg_fmtint(oStreamLocalBindUnlink
, o
->fwd_opts
.streamlocal_bind_unlink
);
3305 dump_cfg_fmtint(oStrictHostKeyChecking
, o
->strict_host_key_checking
);
3306 dump_cfg_fmtint(oTCPKeepAlive
, o
->tcp_keep_alive
);
3307 dump_cfg_fmtint(oTunnel
, o
->tun_open
);
3308 dump_cfg_fmtint(oVerifyHostKeyDNS
, o
->verify_host_key_dns
);
3309 dump_cfg_fmtint(oVisualHostKey
, o
->visual_host_key
);
3310 dump_cfg_fmtint(oUpdateHostkeys
, o
->update_hostkeys
);
3312 /* Integer options */
3313 dump_cfg_int(oCanonicalizeMaxDots
, o
->canonicalize_max_dots
);
3314 dump_cfg_int(oConnectionAttempts
, o
->connection_attempts
);
3315 dump_cfg_int(oForwardX11Timeout
, o
->forward_x11_timeout
);
3316 dump_cfg_int(oNumberOfPasswordPrompts
, o
->number_of_password_prompts
);
3317 dump_cfg_int(oServerAliveCountMax
, o
->server_alive_count_max
);
3318 dump_cfg_int(oServerAliveInterval
, o
->server_alive_interval
);
3319 dump_cfg_int(oRequiredRSASize
, o
->required_rsa_size
);
3321 /* String options */
3322 dump_cfg_string(oBindAddress
, o
->bind_address
);
3323 dump_cfg_string(oBindInterface
, o
->bind_interface
);
3324 dump_cfg_string(oCiphers
, o
->ciphers
);
3325 dump_cfg_string(oControlPath
, o
->control_path
);
3326 dump_cfg_string(oHostKeyAlgorithms
, o
->hostkeyalgorithms
);
3327 dump_cfg_string(oHostKeyAlias
, o
->host_key_alias
);
3328 dump_cfg_string(oHostbasedAcceptedAlgorithms
, o
->hostbased_accepted_algos
);
3329 dump_cfg_string(oIdentityAgent
, o
->identity_agent
);
3330 dump_cfg_string(oIgnoreUnknown
, o
->ignored_unknown
);
3331 dump_cfg_string(oKbdInteractiveDevices
, o
->kbd_interactive_devices
);
3332 dump_cfg_string(oKexAlgorithms
, o
->kex_algorithms
);
3333 dump_cfg_string(oCASignatureAlgorithms
, o
->ca_sign_algorithms
);
3334 dump_cfg_string(oLocalCommand
, o
->local_command
);
3335 dump_cfg_string(oRemoteCommand
, o
->remote_command
);
3336 dump_cfg_string(oLogLevel
, log_level_name(o
->log_level
));
3337 dump_cfg_string(oMacs
, o
->macs
);
3338 #ifdef ENABLE_PKCS11
3339 dump_cfg_string(oPKCS11Provider
, o
->pkcs11_provider
);
3341 dump_cfg_string(oSecurityKeyProvider
, o
->sk_provider
);
3342 dump_cfg_string(oPreferredAuthentications
, o
->preferred_authentications
);
3343 dump_cfg_string(oPubkeyAcceptedAlgorithms
, o
->pubkey_accepted_algos
);
3344 dump_cfg_string(oRevokedHostKeys
, o
->revoked_host_keys
);
3345 dump_cfg_string(oXAuthLocation
, o
->xauth_location
);
3346 dump_cfg_string(oKnownHostsCommand
, o
->known_hosts_command
);
3349 dump_cfg_forwards(oDynamicForward
, o
->num_local_forwards
, o
->local_forwards
);
3350 dump_cfg_forwards(oLocalForward
, o
->num_local_forwards
, o
->local_forwards
);
3351 dump_cfg_forwards(oRemoteForward
, o
->num_remote_forwards
, o
->remote_forwards
);
3353 /* String array options */
3354 dump_cfg_strarray(oIdentityFile
, o
->num_identity_files
, o
->identity_files
);
3355 dump_cfg_strarray_oneline(oCanonicalDomains
, o
->num_canonical_domains
, o
->canonical_domains
);
3356 dump_cfg_strarray(oCertificateFile
, o
->num_certificate_files
, o
->certificate_files
);
3357 dump_cfg_strarray_oneline(oGlobalKnownHostsFile
, o
->num_system_hostfiles
, o
->system_hostfiles
);
3358 dump_cfg_strarray_oneline(oUserKnownHostsFile
, o
->num_user_hostfiles
, o
->user_hostfiles
);
3359 dump_cfg_strarray(oSendEnv
, o
->num_send_env
, o
->send_env
);
3360 dump_cfg_strarray(oSetEnv
, o
->num_setenv
, o
->setenv
);
3361 dump_cfg_strarray_oneline(oLogVerbose
,
3362 o
->num_log_verbose
, o
->log_verbose
);
3366 /* PermitRemoteOpen */
3367 if (o
->num_permitted_remote_opens
== 0)
3368 printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen
));
3370 dump_cfg_strarray_oneline(oPermitRemoteOpen
,
3371 o
->num_permitted_remote_opens
, o
->permitted_remote_opens
);
3373 /* AddKeysToAgent */
3374 if (o
->add_keys_to_agent_lifespan
<= 0)
3375 dump_cfg_fmtint(oAddKeysToAgent
, o
->add_keys_to_agent
);
3377 printf("addkeystoagent%s %d\n",
3378 o
->add_keys_to_agent
== 3 ? " confirm" : "",
3379 o
->add_keys_to_agent_lifespan
);
3383 if (o
->forward_agent_sock_path
== NULL
)
3384 dump_cfg_fmtint(oForwardAgent
, o
->forward_agent
);
3386 dump_cfg_string(oForwardAgent
, o
->forward_agent_sock_path
);
3388 /* oConnectTimeout */
3389 if (o
->connection_timeout
== -1)
3390 printf("connecttimeout none\n");
3392 dump_cfg_int(oConnectTimeout
, o
->connection_timeout
);
3395 printf("tunneldevice");
3396 if (o
->tun_local
== SSH_TUNID_ANY
)
3399 printf(" %d", o
->tun_local
);
3400 if (o
->tun_remote
== SSH_TUNID_ANY
)
3403 printf(":%d", o
->tun_remote
);
3406 /* oCanonicalizePermittedCNAMEs */
3407 printf("canonicalizePermittedcnames");
3408 if (o
->num_permitted_cnames
== 0)
3410 for (i
= 0; i
< o
->num_permitted_cnames
; i
++) {
3411 printf(" %s:%s", o
->permitted_cnames
[i
].source_list
,
3412 o
->permitted_cnames
[i
].target_list
);
3416 /* oControlPersist */
3417 if (o
->control_persist
== 0 || o
->control_persist_timeout
== 0)
3418 dump_cfg_fmtint(oControlPersist
, o
->control_persist
);
3420 dump_cfg_int(oControlPersist
, o
->control_persist_timeout
);
3423 if (o
->escape_char
== SSH_ESCAPECHAR_NONE
)
3424 printf("escapechar none\n");
3426 vis(buf
, o
->escape_char
, VIS_WHITE
, 0);
3427 printf("escapechar %s\n", buf
);
3431 printf("ipqos %s ", iptos2str(o
->ip_qos_interactive
));
3432 printf("%s\n", iptos2str(o
->ip_qos_bulk
));
3435 printf("rekeylimit %llu %d\n",
3436 (unsigned long long)o
->rekey_limit
, o
->rekey_interval
);
3438 /* oStreamLocalBindMask */
3439 printf("streamlocalbindmask 0%o\n",
3440 o
->fwd_opts
.streamlocal_bind_mask
);
3443 printf("syslogfacility %s\n", log_facility_name(o
->log_facility
));
3445 /* oProxyCommand / oProxyJump */
3446 if (o
->jump_host
== NULL
)
3447 dump_cfg_string(oProxyCommand
, o
->proxy_command
);
3449 /* Check for numeric addresses */
3450 i
= strchr(o
->jump_host
, ':') != NULL
||
3451 strspn(o
->jump_host
, "1234567890.") == strlen(o
->jump_host
);
3452 snprintf(buf
, sizeof(buf
), "%d", o
->jump_port
);
3453 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
3454 /* optional additional jump spec */
3455 o
->jump_extra
== NULL
? "" : o
->jump_extra
,
3456 o
->jump_extra
== NULL
? "" : ",",
3458 o
->jump_user
== NULL
? "" : o
->jump_user
,
3459 o
->jump_user
== NULL
? "" : "@",
3460 /* opening [ if hostname is numeric */
3462 /* mandatory hostname */
3464 /* closing ] if hostname is numeric */
3466 /* optional port number */
3467 o
->jump_port
<= 0 ? "" : ":",
3468 o
->jump_port
<= 0 ? "" : buf
);