1 /* $OpenBSD: ssh.c,v 1.602 2024/12/06 16:21:48 djm Exp $ */
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * Ssh client program. This program can be used to log into a remote machine.
7 * The software supports strong authentication, encryption, and forwarding
8 * of X11, TCP/IP, and authentication connections.
10 * As far as I am concerned, the code I have written for this software
11 * can be used freely for any purpose. Any derived versions of this
12 * software must be clearly marked as such, and if the derived work is
13 * incompatible with the protocol description in the RFC file, it must be
14 * called by a name other than "ssh" or "Secure Shell".
16 * Copyright (c) 1999 Niels Provos. All rights reserved.
17 * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.
19 * Modified to work with SSLeay by Niels Provos <provos@citi.umich.edu>
20 * in Canada (German citizen).
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 #include <sys/types.h>
46 #ifdef HAVE_SYS_STAT_H
47 # include <sys/stat.h>
49 #include <sys/resource.h>
50 #include <sys/ioctl.h>
51 #include <sys/socket.h>
73 #include <netinet/in.h>
74 #include <arpa/inet.h>
77 #include <openssl/evp.h>
78 #include <openssl/err.h>
80 #include "openbsd-compat/openssl-compat.h"
81 #include "openbsd-compat/sys-queue.h"
95 #include "pathnames.h"
97 #include "clientloop.h"
100 #include "readconf.h"
101 #include "sshconnect.h"
109 #include "myproposal.h"
113 #include "ssh-pkcs11.h"
116 extern char *__progname
;
118 /* Saves a copy of argv for setproctitle emulation */
119 #ifndef HAVE_SETPROCTITLE
120 static char **saved_av
;
123 /* Flag indicating whether debug mode is on. May be set on the command line. */
126 /* Flag indicating whether a tty should be requested */
130 * Flag indicating that the current process should be backgrounded and
131 * a new mux-client launched in the foreground for ControlPersist.
133 static int need_controlpersist_detach
= 0;
135 /* Copies of flags for ControlPersist foreground mux-client */
136 static int ostdin_null_flag
, osession_type
, otty_flag
, orequest_tty
;
137 static int ofork_after_authentication
;
140 * General data structure for command line options and options configurable
141 * in configuration files. See readconf.h.
145 /* optional user configfile */
149 * Name of the host we are connecting to. This is the name given on the
150 * command line, or the Hostname specified for the user-supplied name in a
151 * configuration file.
156 * A config can specify a path to forward, overriding SSH_AUTH_SOCK. If this is
157 * not NULL, forward the socket at this path instead.
159 char *forward_agent_sock_path
= NULL
;
161 /* socket address the host resolves to */
162 struct sockaddr_storage hostaddr
;
164 /* Private host keys. */
165 Sensitive sensitive_data
;
167 /* command to be executed */
168 struct sshbuf
*command
;
170 /* # of replies received for global requests */
171 static int forward_confirms_pending
= -1;
174 extern int muxserver_sock
;
175 extern u_int muxclient_command
;
177 /* Prints a help message to the user. This function never returns. */
183 "usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address]\n"
184 " [-c cipher_spec] [-D [bind_address:]port] [-E log_file]\n"
185 " [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file]\n"
186 " [-J destination] [-L address] [-l login_name] [-m mac_spec]\n"
187 " [-O ctl_cmd] [-o option] [-P tag] [-p port] [-R address]\n"
188 " [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n"
189 " destination [command [argument ...]]\n"
190 " ssh [-Q query_option]\n"
195 static int ssh_session2(struct ssh
*, const struct ssh_conn_info
*);
196 static void load_public_identity_files(const struct ssh_conn_info
*);
197 static void main_sigchld_handler(int);
199 /* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */
201 tilde_expand_paths(char **paths
, u_int num_paths
)
206 for (i
= 0; i
< num_paths
; i
++) {
207 cp
= tilde_expand_filename(paths
[i
], getuid());
214 * Expands the set of percent_expand options used by the majority of keywords
215 * in the client that support percent expansion.
216 * Caller must free returned string.
219 default_client_percent_expand(const char *str
,
220 const struct ssh_conn_info
*cinfo
)
222 return percent_expand(str
,
223 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo
),
228 * Expands the set of percent_expand options used by the majority of keywords
229 * AND perform environment variable substitution.
230 * Caller must free returned string.
233 default_client_percent_dollar_expand(const char *str
,
234 const struct ssh_conn_info
*cinfo
)
238 ret
= percent_dollar_expand(str
,
239 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo
),
242 fatal("invalid environment variable expansion");
247 * Attempt to resolve a host name / port to a set of addresses and
248 * optionally return any CNAMEs encountered along the way.
249 * Returns NULL on failure.
250 * NB. this function must operate with a options having undefined members.
252 static struct addrinfo
*
253 resolve_host(const char *name
, int port
, int logerr
, char *cname
, size_t clen
)
255 char strport
[NI_MAXSERV
];
256 const char *errstr
= NULL
;
257 struct addrinfo hints
, *res
;
259 LogLevel loglevel
= SYSLOG_LEVEL_DEBUG1
;
262 port
= default_ssh_port();
265 debug3_f("lookup %s:%d", name
, port
);
267 snprintf(strport
, sizeof strport
, "%d", port
);
268 memset(&hints
, 0, sizeof(hints
));
269 hints
.ai_family
= options
.address_family
== -1 ?
270 AF_UNSPEC
: options
.address_family
;
271 hints
.ai_socktype
= SOCK_STREAM
;
273 hints
.ai_flags
= AI_CANONNAME
;
274 if ((gaierr
= getaddrinfo(name
, strport
, &hints
, &res
)) != 0) {
275 if (logerr
|| (gaierr
!= EAI_NONAME
&& gaierr
!= EAI_NODATA
))
276 loglevel
= SYSLOG_LEVEL_ERROR
;
277 do_log2(loglevel
, "%s: Could not resolve hostname %.100s: %s",
278 __progname
, name
, ssh_gai_strerror(gaierr
));
281 if (cname
!= NULL
&& res
->ai_canonname
!= NULL
) {
282 if (!valid_domain(res
->ai_canonname
, 0, &errstr
)) {
283 error("ignoring bad CNAME \"%s\" for host \"%s\": %s",
284 res
->ai_canonname
, name
, errstr
);
285 } else if (strlcpy(cname
, res
->ai_canonname
, clen
) >= clen
) {
286 error_f("host \"%s\" cname \"%s\" too long (max %lu)",
287 name
, res
->ai_canonname
, (u_long
)clen
);
295 /* Returns non-zero if name can only be an address and not a hostname */
297 is_addr_fast(const char *name
)
299 return (strchr(name
, '%') != NULL
|| strchr(name
, ':') != NULL
||
300 strspn(name
, "0123456789.") == strlen(name
));
303 /* Returns non-zero if name represents a valid, single address */
305 is_addr(const char *name
)
307 char strport
[NI_MAXSERV
];
308 struct addrinfo hints
, *res
;
310 if (is_addr_fast(name
))
313 snprintf(strport
, sizeof strport
, "%u", default_ssh_port());
314 memset(&hints
, 0, sizeof(hints
));
315 hints
.ai_family
= options
.address_family
== -1 ?
316 AF_UNSPEC
: options
.address_family
;
317 hints
.ai_socktype
= SOCK_STREAM
;
318 hints
.ai_flags
= AI_NUMERICHOST
|AI_NUMERICSERV
;
319 if (getaddrinfo(name
, strport
, &hints
, &res
) != 0)
321 if (res
== NULL
|| res
->ai_next
!= NULL
) {
330 * Attempt to resolve a numeric host address / port to a single address.
331 * Returns a canonical address string.
332 * Returns NULL on failure.
333 * NB. this function must operate with a options having undefined members.
335 static struct addrinfo
*
336 resolve_addr(const char *name
, int port
, char *caddr
, size_t clen
)
338 char addr
[NI_MAXHOST
], strport
[NI_MAXSERV
];
339 struct addrinfo hints
, *res
;
343 port
= default_ssh_port();
344 snprintf(strport
, sizeof strport
, "%u", port
);
345 memset(&hints
, 0, sizeof(hints
));
346 hints
.ai_family
= options
.address_family
== -1 ?
347 AF_UNSPEC
: options
.address_family
;
348 hints
.ai_socktype
= SOCK_STREAM
;
349 hints
.ai_flags
= AI_NUMERICHOST
|AI_NUMERICSERV
;
350 if ((gaierr
= getaddrinfo(name
, strport
, &hints
, &res
)) != 0) {
351 debug2_f("could not resolve name %.100s as address: %s",
352 name
, ssh_gai_strerror(gaierr
));
356 debug_f("getaddrinfo %.100s returned no addresses", name
);
359 if (res
->ai_next
!= NULL
) {
360 debug_f("getaddrinfo %.100s returned multiple addresses", name
);
363 if ((gaierr
= getnameinfo(res
->ai_addr
, res
->ai_addrlen
,
364 addr
, sizeof(addr
), NULL
, 0, NI_NUMERICHOST
)) != 0) {
365 debug_f("Could not format address for name %.100s: %s",
366 name
, ssh_gai_strerror(gaierr
));
369 if (strlcpy(caddr
, addr
, clen
) >= clen
) {
370 error_f("host \"%s\" addr \"%s\" too long (max %lu)",
371 name
, addr
, (u_long
)clen
);
382 * Check whether the cname is a permitted replacement for the hostname
383 * and perform the replacement if it is.
384 * NB. this function must operate with a options having undefined members.
387 check_follow_cname(int direct
, char **namep
, const char *cname
)
390 struct allowed_cname
*rule
;
392 if (*cname
== '\0' || !config_has_permitted_cnames(&options
) ||
393 strcmp(*namep
, cname
) == 0)
395 if (options
.canonicalize_hostname
== SSH_CANONICALISE_NO
)
398 * Don't attempt to canonicalize names that will be interpreted by
399 * a proxy or jump host unless the user specifically requests so.
402 options
.canonicalize_hostname
!= SSH_CANONICALISE_ALWAYS
)
404 debug3_f("check \"%s\" CNAME \"%s\"", *namep
, cname
);
405 for (i
= 0; i
< options
.num_permitted_cnames
; i
++) {
406 rule
= options
.permitted_cnames
+ i
;
407 if (match_pattern_list(*namep
, rule
->source_list
, 1) != 1 ||
408 match_pattern_list(cname
, rule
->target_list
, 1) != 1)
410 verbose("Canonicalized DNS aliased hostname "
411 "\"%s\" => \"%s\"", *namep
, cname
);
413 *namep
= xstrdup(cname
);
420 * Attempt to resolve the supplied hostname after applying the user's
421 * canonicalization rules. Returns the address list for the host or NULL
422 * if no name was found after canonicalization.
423 * NB. this function must operate with a options having undefined members.
425 static struct addrinfo
*
426 resolve_canonicalize(char **hostp
, int port
)
428 int i
, direct
, ndots
;
429 char *cp
, *fullhost
, newname
[NI_MAXHOST
];
430 struct addrinfo
*addrs
;
433 * Attempt to canonicalise addresses, regardless of
434 * whether hostname canonicalisation was requested
436 if ((addrs
= resolve_addr(*hostp
, port
,
437 newname
, sizeof(newname
))) != NULL
) {
438 debug2_f("hostname %.100s is address", *hostp
);
439 if (strcasecmp(*hostp
, newname
) != 0) {
440 debug2_f("canonicalised address \"%s\" => \"%s\"",
443 *hostp
= xstrdup(newname
);
449 * If this looks like an address but didn't parse as one, it might
450 * be an address with an invalid interface scope. Skip further
451 * attempts at canonicalisation.
453 if (is_addr_fast(*hostp
)) {
454 debug_f("hostname %.100s is an unrecognised address", *hostp
);
458 if (options
.canonicalize_hostname
== SSH_CANONICALISE_NO
)
462 * Don't attempt to canonicalize names that will be interpreted by
463 * a proxy unless the user specifically requests so.
465 direct
= option_clear_or_none(options
.proxy_command
) &&
466 option_clear_or_none(options
.jump_host
);
468 options
.canonicalize_hostname
!= SSH_CANONICALISE_ALWAYS
)
471 /* If domain name is anchored, then resolve it now */
472 if ((*hostp
)[strlen(*hostp
) - 1] == '.') {
473 debug3_f("name is fully qualified");
474 fullhost
= xstrdup(*hostp
);
475 if ((addrs
= resolve_host(fullhost
, port
, 0,
476 newname
, sizeof(newname
))) != NULL
)
482 /* Don't apply canonicalization to sufficiently-qualified hostnames */
484 for (cp
= *hostp
; *cp
!= '\0'; cp
++) {
488 if (ndots
> options
.canonicalize_max_dots
) {
489 debug3_f("not canonicalizing hostname \"%s\" (max dots %d)",
490 *hostp
, options
.canonicalize_max_dots
);
493 /* Attempt each supplied suffix */
494 for (i
= 0; i
< options
.num_canonical_domains
; i
++) {
495 if (strcasecmp(options
.canonical_domains
[i
], "none") == 0)
497 xasprintf(&fullhost
, "%s.%s.", *hostp
,
498 options
.canonical_domains
[i
]);
499 debug3_f("attempting \"%s\" => \"%s\"", *hostp
, fullhost
);
500 if ((addrs
= resolve_host(fullhost
, port
, 0,
501 newname
, sizeof(newname
))) == NULL
) {
506 /* Remove trailing '.' */
507 fullhost
[strlen(fullhost
) - 1] = '\0';
508 /* Follow CNAME if requested */
509 if (!check_follow_cname(direct
, &fullhost
, newname
)) {
510 debug("Canonicalized hostname \"%s\" => \"%s\"",
518 if (!options
.canonicalize_fallback_local
)
519 fatal("%s: Could not resolve host \"%s\"", __progname
, *hostp
);
520 debug2_f("host %s not found in any suffix", *hostp
);
525 * Check the result of hostkey loading, ignoring some errors and either
526 * discarding the key or fatal()ing for others.
529 check_load(int r
, struct sshkey
**k
, const char *path
, const char *message
)
533 /* Check RSA keys size and discard if undersized */
534 if (k
!= NULL
&& *k
!= NULL
&&
535 (r
= sshkey_check_rsa_length(*k
,
536 options
.required_rsa_size
)) != 0) {
537 error_r(r
, "load %s \"%s\"", message
, path
);
542 case SSH_ERR_INTERNAL_ERROR
:
543 case SSH_ERR_ALLOC_FAIL
:
544 fatal_r(r
, "load %s \"%s\"", message
, path
);
545 case SSH_ERR_SYSTEM_ERROR
:
546 /* Ignore missing files */
551 error_r(r
, "load %s \"%s\"", message
, path
);
557 * Read per-user configuration file. Ignore the system wide config
558 * file if the user specifies a config file on the command line.
561 process_config_files(const char *host_name
, struct passwd
*pw
, int final_pass
,
562 int *want_final_pass
)
567 if (config
!= NULL
) {
568 if (strcasecmp(config
, "none") != 0 &&
569 !read_config_file(config
, pw
, host
, host_name
, &options
,
570 SSHCONF_USERCONF
| (final_pass
? SSHCONF_FINAL
: 0),
572 fatal("Can't open user config file %.100s: "
573 "%.100s", config
, strerror(errno
));
575 r
= snprintf(buf
, sizeof buf
, "%s/%s", pw
->pw_dir
,
576 _PATH_SSH_USER_CONFFILE
);
577 if (r
> 0 && (size_t)r
< sizeof(buf
))
578 (void)read_config_file(buf
, pw
, host
, host_name
,
579 &options
, SSHCONF_CHECKPERM
| SSHCONF_USERCONF
|
580 (final_pass
? SSHCONF_FINAL
: 0), want_final_pass
);
582 /* Read systemwide configuration file after user config. */
583 (void)read_config_file(_PATH_HOST_CONFIG_FILE
, pw
,
584 host
, host_name
, &options
,
585 final_pass
? SSHCONF_FINAL
: 0, want_final_pass
);
589 /* Rewrite the port number in an addrinfo list of addresses */
591 set_addrinfo_port(struct addrinfo
*addrs
, int port
)
593 struct addrinfo
*addr
;
595 for (addr
= addrs
; addr
!= NULL
; addr
= addr
->ai_next
) {
596 switch (addr
->ai_family
) {
598 ((struct sockaddr_in
*)addr
->ai_addr
)->
599 sin_port
= htons(port
);
602 ((struct sockaddr_in6
*)addr
->ai_addr
)->
603 sin6_port
= htons(port
);
610 ssh_conn_info_free(struct ssh_conn_info
*cinfo
)
614 free(cinfo
->conn_hash_hex
);
615 free(cinfo
->shorthost
);
617 free(cinfo
->keyalias
);
618 free(cinfo
->thishost
);
619 free(cinfo
->host_arg
);
620 free(cinfo
->portstr
);
621 free(cinfo
->remhost
);
622 free(cinfo
->remuser
);
623 free(cinfo
->homedir
);
624 free(cinfo
->locuser
);
625 free(cinfo
->jmphost
);
630 valid_hostname(const char *s
)
636 for (i
= 0; s
[i
] != 0; i
++) {
637 if (strchr("'`\"$\\;&<>|(){}", s
[i
]) != NULL
||
638 isspace((u_char
)s
[i
]) || iscntrl((u_char
)s
[i
]))
645 valid_ruser(const char *s
)
651 for (i
= 0; s
[i
] != 0; i
++) {
652 if (strchr("'`\";&<>|(){}", s
[i
]) != NULL
)
654 /* Disallow '-' after whitespace */
655 if (isspace((u_char
)s
[i
]) && s
[i
+ 1] == '-')
657 /* Disallow \ in last position */
658 if (s
[i
] == '\\' && s
[i
+ 1] == '\0')
665 * Main program for the ssh client.
668 main(int ac
, char **av
)
670 struct ssh
*ssh
= NULL
;
671 int i
, r
, opt
, exit_status
, use_syslog
, direct
, timeout_ms
;
672 int was_addr
, config_test
= 0, opt_terminated
= 0, want_final_pass
= 0;
673 char *p
, *cp
, *line
, *argv0
, *logfile
;
674 char cname
[NI_MAXHOST
], thishost
[NI_MAXHOST
];
677 extern int optind
, optreset
;
680 struct addrinfo
*addrs
= NULL
;
683 struct ssh_conn_info
*cinfo
= NULL
;
685 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
689 * Discard other fds that are hanging around. These can cause problem
690 * with backgrounded ssh processes started by ControlPersist.
692 closefrom(STDERR_FILENO
+ 1);
694 __progname
= ssh_get_progname(av
[0]);
696 #ifndef HAVE_SETPROCTITLE
697 /* Prepare for later setproctitle emulation */
698 /* Save argv so it isn't clobbered by setproctitle() emulation */
699 saved_av
= xcalloc(ac
+ 1, sizeof(*saved_av
));
700 for (i
= 0; i
< ac
; i
++)
701 saved_av
[i
] = xstrdup(av
[i
]);
703 compat_init_setproctitle(ac
, av
);
710 pw
= getpwuid(getuid());
712 logit("No user exists for uid %lu", (u_long
)getuid());
715 /* Take a copy of the returned structure. */
719 * Set our umask to something reasonable, as some files are created
720 * with the default umask. This will make them world-readable but
721 * writable only by the owner, which is ok for all files for which we
722 * don't set the modes explicitly.
724 umask(022 | umask(077));
729 * Initialize option structure to indicate that no values have been
732 initialize_options(&options
);
735 * Prepare main ssh transport/connection structures
737 if ((ssh
= ssh_alloc_session_state()) == NULL
)
738 fatal("Couldn't allocate session state");
739 channel_init_channels(ssh
);
741 /* Parse command-line arguments. */
748 while ((opt
= getopt(ac
, av
, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
749 "AB:CD:E:F:GI:J:KL:MNO:P:Q:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
752 fatal("SSH protocol v.1 is no longer supported");
758 options
.address_family
= AF_INET
;
761 options
.address_family
= AF_INET6
;
764 options
.stdin_null
= 1;
767 options
.fork_after_authentication
= 1;
768 options
.stdin_null
= 1;
771 options
.forward_x11
= 0;
774 options
.forward_x11
= 1;
786 options
.forward_x11
= 1;
787 options
.forward_x11_trusted
= 1;
790 options
.fwd_opts
.gateway_ports
= 1;
793 if (options
.stdio_forward_host
!= NULL
)
794 fatal("Cannot specify multiplexing "
796 else if (muxclient_command
!= 0)
797 fatal("Multiplexing command already specified");
798 if (strcmp(optarg
, "check") == 0)
799 muxclient_command
= SSHMUX_COMMAND_ALIVE_CHECK
;
800 else if (strcmp(optarg
, "forward") == 0)
801 muxclient_command
= SSHMUX_COMMAND_FORWARD
;
802 else if (strcmp(optarg
, "exit") == 0)
803 muxclient_command
= SSHMUX_COMMAND_TERMINATE
;
804 else if (strcmp(optarg
, "stop") == 0)
805 muxclient_command
= SSHMUX_COMMAND_STOP
;
806 else if (strcmp(optarg
, "cancel") == 0)
807 muxclient_command
= SSHMUX_COMMAND_CANCEL_FWD
;
808 else if (strcmp(optarg
, "proxy") == 0)
809 muxclient_command
= SSHMUX_COMMAND_PROXY
;
811 fatal("Invalid multiplex command.");
814 if (options
.tag
== NULL
)
815 options
.tag
= xstrdup(optarg
);
819 if (strcmp(optarg
, "cipher") == 0 ||
820 strcasecmp(optarg
, "Ciphers") == 0)
821 cp
= cipher_alg_list('\n', 0);
822 else if (strcmp(optarg
, "cipher-auth") == 0)
823 cp
= cipher_alg_list('\n', 1);
824 else if (strcmp(optarg
, "mac") == 0 ||
825 strcasecmp(optarg
, "MACs") == 0)
826 cp
= mac_alg_list('\n');
827 else if (strcmp(optarg
, "kex") == 0 ||
828 strcasecmp(optarg
, "KexAlgorithms") == 0)
829 cp
= kex_alg_list('\n');
830 else if (strcmp(optarg
, "key") == 0)
831 cp
= sshkey_alg_list(0, 0, 0, '\n');
832 else if (strcmp(optarg
, "key-cert") == 0)
833 cp
= sshkey_alg_list(1, 0, 0, '\n');
834 else if (strcmp(optarg
, "key-plain") == 0)
835 cp
= sshkey_alg_list(0, 1, 0, '\n');
836 else if (strcmp(optarg
, "key-ca-sign") == 0 ||
837 strcasecmp(optarg
, "CASignatureAlgorithms") == 0)
838 cp
= sshkey_alg_list(0, 1, 1, '\n');
839 else if (strcmp(optarg
, "key-sig") == 0 ||
840 strcasecmp(optarg
, "PubkeyAcceptedKeyTypes") == 0 || /* deprecated name */
841 strcasecmp(optarg
, "PubkeyAcceptedAlgorithms") == 0 ||
842 strcasecmp(optarg
, "HostKeyAlgorithms") == 0 ||
843 strcasecmp(optarg
, "HostbasedKeyTypes") == 0 || /* deprecated name */
844 strcasecmp(optarg
, "HostbasedAcceptedKeyTypes") == 0 || /* deprecated name */
845 strcasecmp(optarg
, "HostbasedAcceptedAlgorithms") == 0)
846 cp
= sshkey_alg_list(0, 0, 1, '\n');
847 else if (strcmp(optarg
, "sig") == 0)
848 cp
= sshkey_alg_list(0, 1, 1, '\n');
849 else if (strcmp(optarg
, "protocol-version") == 0)
851 else if (strcmp(optarg
, "compression") == 0) {
852 cp
= xstrdup(compression_alg_list(0));
854 for (n
= 0; n
< len
; n
++)
857 } else if (strcmp(optarg
, "help") == 0) {
859 "cipher\ncipher-auth\ncompression\nkex\n"
860 "key\nkey-cert\nkey-plain\nkey-sig\nmac\n"
861 "protocol-version\nsig");
864 fatal("Unsupported query \"%s\"", optarg
);
870 options
.forward_agent
= 0;
873 options
.forward_agent
= 1;
876 options
.gss_deleg_creds
= 0;
879 options
.gss_authentication
= 1;
880 options
.gss_deleg_creds
= 1;
883 p
= tilde_expand_filename(optarg
, getuid());
884 if (stat(p
, &st
) == -1)
885 fprintf(stderr
, "Warning: Identity file %s "
886 "not accessible: %s.\n", p
,
889 add_identity_file(&options
, NULL
, p
, 1);
894 free(options
.pkcs11_provider
);
895 options
.pkcs11_provider
= xstrdup(optarg
);
897 fprintf(stderr
, "no support for PKCS#11.\n");
901 if (options
.jump_host
!= NULL
) {
902 fatal("Only a single -J option is permitted "
903 "(use commas to separate multiple "
906 if (options
.proxy_command
!= NULL
)
907 fatal("Cannot specify -J with ProxyCommand");
908 if (parse_jump(optarg
, &options
, 1) == -1)
909 fatal("Invalid -J argument");
910 options
.proxy_command
= xstrdup("none");
913 if (options
.request_tty
== REQUEST_TTY_YES
)
914 options
.request_tty
= REQUEST_TTY_FORCE
;
916 options
.request_tty
= REQUEST_TTY_YES
;
919 if (debug_flag
== 0) {
921 options
.log_level
= SYSLOG_LEVEL_DEBUG1
;
923 if (options
.log_level
< SYSLOG_LEVEL_DEBUG3
) {
930 fprintf(stderr
, "%s, %s\n",
931 SSH_RELEASE
, SSH_OPENSSL_VERSION
);
935 if (options
.tun_open
== -1)
936 options
.tun_open
= SSH_TUNMODE_DEFAULT
;
937 options
.tun_local
= a2tun(optarg
, &options
.tun_remote
);
938 if (options
.tun_local
== SSH_TUNID_ERR
) {
940 "Bad tun device '%s'\n", optarg
);
945 if (options
.stdio_forward_host
!= NULL
)
946 fatal("stdio forward already specified");
947 if (muxclient_command
!= 0)
948 fatal("Cannot specify stdio forward with -O");
949 if (parse_forward(&fwd
, optarg
, 1, 0)) {
950 options
.stdio_forward_host
=
951 fwd
.listen_port
== PORT_STREAMLOCAL
?
952 fwd
.listen_path
: fwd
.listen_host
;
953 options
.stdio_forward_port
= fwd
.listen_port
;
954 free(fwd
.connect_host
);
957 "Bad stdio forwarding specification '%s'\n",
961 options
.request_tty
= REQUEST_TTY_NO
;
962 options
.session_type
= SESSION_TYPE_NONE
;
965 options
.log_level
= SYSLOG_LEVEL_QUIET
;
968 if (strlen(optarg
) == 2 && optarg
[0] == '^' &&
969 (u_char
) optarg
[1] >= 64 &&
970 (u_char
) optarg
[1] < 128)
971 options
.escape_char
= (u_char
) optarg
[1] & 31;
972 else if (strlen(optarg
) == 1)
973 options
.escape_char
= (u_char
) optarg
[0];
974 else if (strcmp(optarg
, "none") == 0)
975 options
.escape_char
= SSH_ESCAPECHAR_NONE
;
977 fprintf(stderr
, "Bad escape character '%s'.\n",
983 if (!ciphers_valid(*optarg
== '+' || *optarg
== '^' ?
984 optarg
+ 1 : optarg
)) {
985 fprintf(stderr
, "Unknown cipher type '%s'\n",
989 free(options
.ciphers
);
990 options
.ciphers
= xstrdup(optarg
);
993 if (mac_valid(optarg
)) {
995 options
.macs
= xstrdup(optarg
);
997 fprintf(stderr
, "Unknown mac type '%s'\n",
1003 if (options
.control_master
== SSHCTL_MASTER_YES
)
1004 options
.control_master
= SSHCTL_MASTER_ASK
;
1006 options
.control_master
= SSHCTL_MASTER_YES
;
1009 if (options
.port
== -1) {
1010 options
.port
= a2port(optarg
);
1011 if (options
.port
<= 0) {
1012 fprintf(stderr
, "Bad port '%s'\n",
1019 if (options
.user
== NULL
)
1020 options
.user
= optarg
;
1024 if (parse_forward(&fwd
, optarg
, 0, 0))
1025 add_local_forward(&options
, &fwd
);
1028 "Bad local forwarding specification '%s'\n",
1035 if (parse_forward(&fwd
, optarg
, 0, 1) ||
1036 parse_forward(&fwd
, optarg
, 1, 1)) {
1037 add_remote_forward(&options
, &fwd
);
1040 "Bad remote forwarding specification "
1047 if (parse_forward(&fwd
, optarg
, 1, 0)) {
1048 add_local_forward(&options
, &fwd
);
1051 "Bad dynamic forwarding specification "
1059 options
.compression
= 1;
1061 error("Compression not supported, disabling.");
1065 if (options
.session_type
!= -1 &&
1066 options
.session_type
!= SESSION_TYPE_NONE
)
1067 fatal("Cannot specify -N with -s/SessionType");
1068 options
.session_type
= SESSION_TYPE_NONE
;
1069 options
.request_tty
= REQUEST_TTY_NO
;
1072 options
.request_tty
= REQUEST_TTY_NO
;
1075 line
= xstrdup(optarg
);
1076 if (process_config_line(&options
, pw
,
1077 host
? host
: "", host
? host
: "", line
,
1078 "command-line", 0, NULL
, SSHCONF_USERCONF
) != 0)
1083 if (options
.session_type
!= -1 &&
1084 options
.session_type
!= SESSION_TYPE_SUBSYSTEM
)
1085 fatal("Cannot specify -s with -N/SessionType");
1086 options
.session_type
= SESSION_TYPE_SUBSYSTEM
;
1089 free(options
.control_path
);
1090 options
.control_path
= xstrdup(optarg
);
1093 options
.bind_address
= optarg
;
1096 options
.bind_interface
= optarg
;
1106 if (optind
> 1 && strcmp(av
[optind
- 1], "--") == 0)
1112 if (ac
> 0 && !host
) {
1115 switch (parse_ssh_uri(*av
, &tuser
, &host
, &tport
)) {
1120 if (options
.user
== NULL
) {
1121 options
.user
= tuser
;
1125 if (options
.port
== -1 && tport
!= -1)
1126 options
.port
= tport
;
1130 cp
= strrchr(p
, '@');
1134 if (options
.user
== NULL
) {
1145 if (ac
> 1 && !opt_terminated
) {
1146 optind
= optreset
= 1;
1152 /* Check that we got a host name. */
1156 if (!valid_hostname(host
))
1157 fatal("hostname contains invalid characters");
1158 if (options
.user
!= NULL
&& !valid_ruser(options
.user
))
1159 fatal("remote username contains invalid characters");
1160 options
.host_arg
= xstrdup(host
);
1162 /* Initialize the command to execute on remote host. */
1163 if ((command
= sshbuf_new()) == NULL
)
1164 fatal("sshbuf_new failed");
1167 * Save the command to execute on the remote host in a buffer. There
1168 * is no limit on the length of the command, except by the maximum
1169 * packet size. Also sets the tty flag if there is no command.
1172 /* No command specified - execute shell on a tty. */
1173 if (options
.session_type
== SESSION_TYPE_SUBSYSTEM
) {
1175 "You must specify a subsystem to invoke.\n");
1179 /* A command has been specified. Store it into the buffer. */
1180 for (i
= 0; i
< ac
; i
++) {
1181 if ((r
= sshbuf_putf(command
, "%s%s",
1182 i
? " " : "", av
[i
])) != 0)
1183 fatal_fr(r
, "buffer error");
1187 ssh_signal(SIGPIPE
, SIG_IGN
); /* ignore SIGPIPE early */
1190 * Initialize "log" output. Since we are the client all output
1191 * goes to stderr unless otherwise specified by -y or -E.
1193 if (use_syslog
&& logfile
!= NULL
)
1194 fatal("Can't specify both -y and -E");
1195 if (logfile
!= NULL
)
1196 log_redirect_stderr_to(logfile
);
1198 options
.log_level
== SYSLOG_LEVEL_NOT_SET
?
1199 SYSLOG_LEVEL_INFO
: options
.log_level
,
1200 options
.log_facility
== SYSLOG_FACILITY_NOT_SET
?
1201 SYSLOG_FACILITY_USER
: options
.log_facility
,
1205 logit("%s, %s", SSH_RELEASE
, SSH_OPENSSL_VERSION
);
1207 /* Parse the configuration files */
1208 process_config_files(options
.host_arg
, pw
, 0, &want_final_pass
);
1209 if (want_final_pass
)
1210 debug("configuration requests final Match pass");
1212 /* Hostname canonicalisation needs a few options filled. */
1213 fill_default_options_for_canonicalization(&options
);
1215 /* If the user has replaced the hostname then take it into use now */
1216 if (options
.hostname
!= NULL
) {
1217 /* NB. Please keep in sync with readconf.c:match_cfg_line() */
1218 cp
= percent_expand(options
.hostname
,
1219 "h", host
, (char *)NULL
);
1222 free(options
.hostname
);
1223 options
.hostname
= xstrdup(host
);
1226 /* Don't lowercase addresses, they will be explicitly canonicalised */
1227 if ((was_addr
= is_addr(host
)) == 0)
1231 * Try to canonicalize if requested by configuration or the
1232 * hostname is an address.
1234 if (options
.canonicalize_hostname
!= SSH_CANONICALISE_NO
|| was_addr
)
1235 addrs
= resolve_canonicalize(&host
, options
.port
);
1238 * If CanonicalizePermittedCNAMEs have been specified but
1239 * other canonicalization did not happen (by not being requested
1240 * or by failing with fallback) then the hostname may still be changed
1241 * as a result of CNAME following.
1243 * Try to resolve the bare hostname name using the system resolver's
1244 * usual search rules and then apply the CNAME follow rules.
1246 * Skip the lookup if a ProxyCommand is being used unless the user
1247 * has specifically requested canonicalisation for this case via
1248 * CanonicalizeHostname=always
1250 direct
= option_clear_or_none(options
.proxy_command
) &&
1251 option_clear_or_none(options
.jump_host
);
1252 if (addrs
== NULL
&& config_has_permitted_cnames(&options
) && (direct
||
1253 options
.canonicalize_hostname
== SSH_CANONICALISE_ALWAYS
)) {
1254 if ((addrs
= resolve_host(host
, options
.port
,
1255 direct
, cname
, sizeof(cname
))) == NULL
) {
1256 /* Don't fatal proxied host names not in the DNS */
1258 cleanup_exit(255); /* logged in resolve_host */
1260 check_follow_cname(direct
, &host
, cname
);
1264 * If canonicalisation is enabled then re-parse the configuration
1265 * files as new stanzas may match.
1267 if (options
.canonicalize_hostname
!= 0 && !want_final_pass
) {
1268 debug("hostname canonicalisation enabled, "
1269 "will re-parse configuration");
1270 want_final_pass
= 1;
1273 if (want_final_pass
) {
1274 debug("re-parsing configuration");
1275 free(options
.hostname
);
1276 options
.hostname
= xstrdup(host
);
1277 process_config_files(options
.host_arg
, pw
, 1, NULL
);
1279 * Address resolution happens early with canonicalisation
1280 * enabled and the port number may have changed since, so
1281 * reset it in address list
1283 if (addrs
!= NULL
&& options
.port
> 0)
1284 set_addrinfo_port(addrs
, options
.port
);
1287 /* Fill configuration defaults. */
1288 if (fill_default_options(&options
) != 0)
1291 if (options
.user
== NULL
)
1292 options
.user
= xstrdup(pw
->pw_name
);
1295 * If ProxyJump option specified, then construct a ProxyCommand now.
1297 if (options
.jump_host
!= NULL
) {
1299 const char *jumpuser
= options
.jump_user
, *sshbin
= argv0
;
1300 int port
= options
.port
, jumpport
= options
.jump_port
;
1303 port
= default_ssh_port();
1305 jumpport
= default_ssh_port();
1306 if (jumpuser
== NULL
)
1307 jumpuser
= options
.user
;
1308 if (strcmp(options
.jump_host
, host
) == 0 && port
== jumpport
&&
1309 strcmp(options
.user
, jumpuser
) == 0)
1310 fatal("jumphost loop via %s", options
.jump_host
);
1313 * Try to use SSH indicated by argv[0], but fall back to
1314 * "ssh" if it appears unavailable.
1316 if (strchr(argv0
, '/') != NULL
&& access(argv0
, X_OK
) != 0)
1319 /* Consistency check */
1320 if (options
.proxy_command
!= NULL
)
1321 fatal("inconsistent options: ProxyCommand+ProxyJump");
1322 /* Never use FD passing for ProxyJump */
1323 options
.proxy_use_fdpass
= 0;
1324 snprintf(port_s
, sizeof(port_s
), "%d", options
.jump_port
);
1325 xasprintf(&options
.proxy_command
,
1326 "%s%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s",
1328 /* Optional "-l user" argument if jump_user set */
1329 options
.jump_user
== NULL
? "" : " -l ",
1330 options
.jump_user
== NULL
? "" : options
.jump_user
,
1331 /* Optional "-p port" argument if jump_port set */
1332 options
.jump_port
<= 0 ? "" : " -p ",
1333 options
.jump_port
<= 0 ? "" : port_s
,
1334 /* Optional additional jump hosts ",..." */
1335 options
.jump_extra
== NULL
? "" : " -J ",
1336 options
.jump_extra
== NULL
? "" : options
.jump_extra
,
1337 /* Optional "-F" argument if -F specified */
1338 config
== NULL
? "" : " -F ",
1339 config
== NULL
? "" : config
,
1340 /* Optional "-v" arguments if -v set */
1341 debug_flag
? " -" : "",
1343 /* Mandatory hostname */
1345 debug("Setting implicit ProxyCommand from ProxyJump: %s",
1346 options
.proxy_command
);
1349 if (options
.port
== 0)
1350 options
.port
= default_ssh_port();
1351 channel_set_af(ssh
, options
.address_family
);
1353 /* Tidy and check options */
1354 if (options
.host_key_alias
!= NULL
)
1355 lowercase(options
.host_key_alias
);
1356 if (options
.proxy_command
!= NULL
&&
1357 strcmp(options
.proxy_command
, "-") == 0 &&
1358 options
.proxy_use_fdpass
)
1359 fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
1360 if (options
.update_hostkeys
== SSH_UPDATE_HOSTKEYS_ASK
) {
1361 if (options
.control_persist
&& options
.control_path
!= NULL
) {
1362 debug("UpdateHostKeys=ask is incompatible with "
1363 "ControlPersist; disabling");
1364 options
.update_hostkeys
= 0;
1365 } else if (sshbuf_len(command
) != 0 ||
1366 options
.remote_command
!= NULL
||
1367 options
.request_tty
== REQUEST_TTY_NO
) {
1368 debug("UpdateHostKeys=ask is incompatible with "
1369 "remote command execution; disabling");
1370 options
.update_hostkeys
= 0;
1371 } else if (options
.log_level
< SYSLOG_LEVEL_INFO
) {
1372 /* no point logging anything; user won't see it */
1373 options
.update_hostkeys
= 0;
1376 if (options
.connection_attempts
<= 0)
1377 fatal("Invalid number of ConnectionAttempts");
1379 if (sshbuf_len(command
) != 0 && options
.remote_command
!= NULL
)
1380 fatal("Cannot execute command-line and remote command.");
1382 /* Cannot fork to background if no command. */
1383 if (options
.fork_after_authentication
&& sshbuf_len(command
) == 0 &&
1384 options
.remote_command
== NULL
&&
1385 options
.session_type
!= SESSION_TYPE_NONE
)
1386 fatal("Cannot fork into background without a command "
1390 log_init(argv0
, options
.log_level
, options
.log_facility
, !use_syslog
);
1391 for (j
= 0; j
< options
.num_log_verbose
; j
++) {
1392 if (strcasecmp(options
.log_verbose
[j
], "none") == 0)
1394 log_verbose_add(options
.log_verbose
[j
]);
1397 if (options
.request_tty
== REQUEST_TTY_YES
||
1398 options
.request_tty
== REQUEST_TTY_FORCE
)
1401 /* Allocate a tty by default if no command specified. */
1402 if (sshbuf_len(command
) == 0 && options
.remote_command
== NULL
)
1403 tty_flag
= options
.request_tty
!= REQUEST_TTY_NO
;
1406 if (options
.request_tty
== REQUEST_TTY_NO
||
1407 (muxclient_command
&& muxclient_command
!= SSHMUX_COMMAND_PROXY
) ||
1408 options
.session_type
== SESSION_TYPE_NONE
)
1410 /* Do not allocate a tty if stdin is not a tty. */
1411 if ((!isatty(fileno(stdin
)) || options
.stdin_null
) &&
1412 options
.request_tty
!= REQUEST_TTY_FORCE
) {
1414 logit("Pseudo-terminal will not be allocated because "
1415 "stdin is not a terminal.");
1419 /* Set up strings used to percent_expand() arguments */
1420 cinfo
= xcalloc(1, sizeof(*cinfo
));
1421 if (gethostname(thishost
, sizeof(thishost
)) == -1)
1422 fatal("gethostname: %s", strerror(errno
));
1423 cinfo
->thishost
= xstrdup(thishost
);
1424 thishost
[strcspn(thishost
, ".")] = '\0';
1425 cinfo
->shorthost
= xstrdup(thishost
);
1426 xasprintf(&cinfo
->portstr
, "%d", options
.port
);
1427 xasprintf(&cinfo
->uidstr
, "%llu",
1428 (unsigned long long)pw
->pw_uid
);
1429 cinfo
->keyalias
= xstrdup(options
.host_key_alias
?
1430 options
.host_key_alias
: options
.host_arg
);
1431 cinfo
->host_arg
= xstrdup(options
.host_arg
);
1432 cinfo
->remhost
= xstrdup(host
);
1433 cinfo
->remuser
= xstrdup(options
.user
);
1434 cinfo
->homedir
= xstrdup(pw
->pw_dir
);
1435 cinfo
->locuser
= xstrdup(pw
->pw_name
);
1436 cinfo
->jmphost
= xstrdup(options
.jump_host
== NULL
?
1437 "" : options
.jump_host
);
1438 cinfo
->conn_hash_hex
= ssh_connection_hash(cinfo
->thishost
,
1439 cinfo
->remhost
, cinfo
->portstr
, cinfo
->remuser
, cinfo
->jmphost
);
1442 * Expand tokens in arguments. NB. LocalCommand is expanded later,
1443 * after port-forwarding is set up, so it may pick up any local
1444 * tunnel interface name allocated.
1446 if (options
.remote_command
!= NULL
) {
1447 debug3("expanding RemoteCommand: %s", options
.remote_command
);
1448 cp
= options
.remote_command
;
1449 options
.remote_command
= default_client_percent_expand(cp
,
1451 debug3("expanded RemoteCommand: %s", options
.remote_command
);
1453 if ((r
= sshbuf_put(command
, options
.remote_command
,
1454 strlen(options
.remote_command
))) != 0)
1455 fatal_fr(r
, "buffer error");
1458 if (options
.control_path
!= NULL
) {
1459 cp
= tilde_expand_filename(options
.control_path
, getuid());
1460 free(options
.control_path
);
1461 options
.control_path
= default_client_percent_dollar_expand(cp
,
1466 if (options
.identity_agent
!= NULL
) {
1467 p
= tilde_expand_filename(options
.identity_agent
, getuid());
1468 cp
= default_client_percent_dollar_expand(p
, cinfo
);
1470 free(options
.identity_agent
);
1471 options
.identity_agent
= cp
;
1474 if (options
.revoked_host_keys
!= NULL
) {
1475 p
= tilde_expand_filename(options
.revoked_host_keys
, getuid());
1476 cp
= default_client_percent_dollar_expand(p
, cinfo
);
1478 free(options
.revoked_host_keys
);
1479 options
.revoked_host_keys
= cp
;
1482 if (options
.forward_agent_sock_path
!= NULL
) {
1483 p
= tilde_expand_filename(options
.forward_agent_sock_path
,
1485 cp
= default_client_percent_dollar_expand(p
, cinfo
);
1487 free(options
.forward_agent_sock_path
);
1488 options
.forward_agent_sock_path
= cp
;
1489 if (stat(options
.forward_agent_sock_path
, &st
) != 0) {
1490 error("Cannot forward agent socket path \"%s\": %s",
1491 options
.forward_agent_sock_path
, strerror(errno
));
1492 if (options
.exit_on_forward_failure
)
1497 if (options
.version_addendum
!= NULL
) {
1498 cp
= default_client_percent_dollar_expand(
1499 options
.version_addendum
, cinfo
);
1500 free(options
.version_addendum
);
1501 options
.version_addendum
= cp
;
1504 if (options
.num_system_hostfiles
> 0 &&
1505 strcasecmp(options
.system_hostfiles
[0], "none") == 0) {
1506 if (options
.num_system_hostfiles
> 1)
1507 fatal("Invalid GlobalKnownHostsFiles: \"none\" "
1508 "appears with other entries");
1509 free(options
.system_hostfiles
[0]);
1510 options
.system_hostfiles
[0] = NULL
;
1511 options
.num_system_hostfiles
= 0;
1514 if (options
.num_user_hostfiles
> 0 &&
1515 strcasecmp(options
.user_hostfiles
[0], "none") == 0) {
1516 if (options
.num_user_hostfiles
> 1)
1517 fatal("Invalid UserKnownHostsFiles: \"none\" "
1518 "appears with other entries");
1519 free(options
.user_hostfiles
[0]);
1520 options
.user_hostfiles
[0] = NULL
;
1521 options
.num_user_hostfiles
= 0;
1523 for (j
= 0; j
< options
.num_user_hostfiles
; j
++) {
1524 if (options
.user_hostfiles
[j
] == NULL
)
1526 cp
= tilde_expand_filename(options
.user_hostfiles
[j
], getuid());
1527 p
= default_client_percent_dollar_expand(cp
, cinfo
);
1528 if (strcmp(options
.user_hostfiles
[j
], p
) != 0)
1529 debug3("expanded UserKnownHostsFile '%s' -> "
1530 "'%s'", options
.user_hostfiles
[j
], p
);
1531 free(options
.user_hostfiles
[j
]);
1533 options
.user_hostfiles
[j
] = p
;
1536 for (i
= 0; i
< options
.num_local_forwards
; i
++) {
1537 if (options
.local_forwards
[i
].listen_path
!= NULL
) {
1538 cp
= options
.local_forwards
[i
].listen_path
;
1539 p
= options
.local_forwards
[i
].listen_path
=
1540 default_client_percent_expand(cp
, cinfo
);
1541 if (strcmp(cp
, p
) != 0)
1542 debug3("expanded LocalForward listen path "
1543 "'%s' -> '%s'", cp
, p
);
1546 if (options
.local_forwards
[i
].connect_path
!= NULL
) {
1547 cp
= options
.local_forwards
[i
].connect_path
;
1548 p
= options
.local_forwards
[i
].connect_path
=
1549 default_client_percent_expand(cp
, cinfo
);
1550 if (strcmp(cp
, p
) != 0)
1551 debug3("expanded LocalForward connect path "
1552 "'%s' -> '%s'", cp
, p
);
1557 for (i
= 0; i
< options
.num_remote_forwards
; i
++) {
1558 if (options
.remote_forwards
[i
].listen_path
!= NULL
) {
1559 cp
= options
.remote_forwards
[i
].listen_path
;
1560 p
= options
.remote_forwards
[i
].listen_path
=
1561 default_client_percent_expand(cp
, cinfo
);
1562 if (strcmp(cp
, p
) != 0)
1563 debug3("expanded RemoteForward listen path "
1564 "'%s' -> '%s'", cp
, p
);
1567 if (options
.remote_forwards
[i
].connect_path
!= NULL
) {
1568 cp
= options
.remote_forwards
[i
].connect_path
;
1569 p
= options
.remote_forwards
[i
].connect_path
=
1570 default_client_percent_expand(cp
, cinfo
);
1571 if (strcmp(cp
, p
) != 0)
1572 debug3("expanded RemoteForward connect path "
1573 "'%s' -> '%s'", cp
, p
);
1579 dump_client_config(&options
, host
);
1583 /* Expand SecurityKeyProvider if it refers to an environment variable */
1584 if (options
.sk_provider
!= NULL
&& *options
.sk_provider
== '$' &&
1585 strlen(options
.sk_provider
) > 1) {
1586 if ((cp
= getenv(options
.sk_provider
+ 1)) == NULL
) {
1587 debug("Authenticator provider %s did not resolve; "
1588 "disabling", options
.sk_provider
);
1589 free(options
.sk_provider
);
1590 options
.sk_provider
= NULL
;
1592 debug2("resolved SecurityKeyProvider %s => %s",
1593 options
.sk_provider
, cp
);
1594 free(options
.sk_provider
);
1595 options
.sk_provider
= xstrdup(cp
);
1599 if (muxclient_command
!= 0 && options
.control_path
== NULL
)
1600 fatal("No ControlPath specified for \"-O\" command");
1601 if (options
.control_path
!= NULL
) {
1603 if ((sock
= muxclient(options
.control_path
)) >= 0) {
1604 ssh_packet_set_connection(ssh
, sock
, sock
);
1605 ssh_packet_set_mux(ssh
);
1611 * If hostname canonicalisation was not enabled, then we may not
1612 * have yet resolved the hostname. Do so now.
1614 if (addrs
== NULL
&& options
.proxy_command
== NULL
) {
1615 debug2("resolving \"%s\" port %d", host
, options
.port
);
1616 if ((addrs
= resolve_host(host
, options
.port
, 1,
1617 cname
, sizeof(cname
))) == NULL
)
1618 cleanup_exit(255); /* resolve_host logs the error */
1621 if (options
.connection_timeout
>= INT_MAX
/1000)
1622 timeout_ms
= INT_MAX
;
1624 timeout_ms
= options
.connection_timeout
* 1000;
1626 /* Apply channels timeouts, if set */
1627 channel_clear_timeouts(ssh
);
1628 for (j
= 0; j
< options
.num_channel_timeouts
; j
++) {
1629 debug3("applying channel timeout %s",
1630 options
.channel_timeouts
[j
]);
1631 if (parse_pattern_interval(options
.channel_timeouts
[j
],
1633 fatal_f("internal error: bad timeout %s",
1634 options
.channel_timeouts
[j
]);
1636 channel_add_timeout(ssh
, cp
, i
);
1640 /* Open a connection to the remote host. */
1641 if (ssh_connect(ssh
, host
, options
.host_arg
, addrs
, &hostaddr
,
1642 options
.port
, options
.connection_attempts
,
1643 &timeout_ms
, options
.tcp_keep_alive
) != 0)
1647 freeaddrinfo(addrs
);
1649 ssh_packet_set_timeout(ssh
, options
.server_alive_interval
,
1650 options
.server_alive_count_max
);
1653 debug3("timeout: %d ms remain after connect", timeout_ms
);
1656 * If we successfully made the connection and we have hostbased auth
1657 * enabled, load the public keys so we can later use the ssh-keysign
1658 * helper to sign challenges.
1660 sensitive_data
.nkeys
= 0;
1661 sensitive_data
.keys
= NULL
;
1662 if (options
.hostbased_authentication
) {
1665 sensitive_data
.nkeys
= 10;
1666 sensitive_data
.keys
= xcalloc(sensitive_data
.nkeys
,
1667 sizeof(*sensitive_data
.keys
));
1669 /* XXX check errors? */
1670 #define L_PUBKEY(p,o) do { \
1671 if ((o) >= sensitive_data.nkeys) \
1672 fatal_f("pubkey out of array bounds"); \
1673 check_load(sshkey_load_public(p, &(sensitive_data.keys[o]), NULL), \
1674 &(sensitive_data.keys[o]), p, "pubkey"); \
1675 if (sensitive_data.keys[o] != NULL) { \
1676 debug2("hostbased key %d: %s key from \"%s\"", o, \
1677 sshkey_ssh_name(sensitive_data.keys[o]), p); \
1681 #define L_CERT(p,o) do { \
1682 if ((o) >= sensitive_data.nkeys) \
1683 fatal_f("cert out of array bounds"); \
1684 check_load(sshkey_load_cert(p, &(sensitive_data.keys[o])), \
1685 &(sensitive_data.keys[o]), p, "cert"); \
1686 if (sensitive_data.keys[o] != NULL) { \
1687 debug2("hostbased key %d: %s cert from \"%s\"", o, \
1688 sshkey_ssh_name(sensitive_data.keys[o]), p); \
1693 if (options
.hostbased_authentication
== 1) {
1694 L_CERT(_PATH_HOST_ECDSA_KEY_FILE
, 0);
1695 L_CERT(_PATH_HOST_ED25519_KEY_FILE
, 1);
1696 L_CERT(_PATH_HOST_RSA_KEY_FILE
, 2);
1698 L_CERT(_PATH_HOST_DSA_KEY_FILE
, 3);
1700 L_PUBKEY(_PATH_HOST_ECDSA_KEY_FILE
, 4);
1701 L_PUBKEY(_PATH_HOST_ED25519_KEY_FILE
, 5);
1702 L_PUBKEY(_PATH_HOST_RSA_KEY_FILE
, 6);
1704 L_PUBKEY(_PATH_HOST_DSA_KEY_FILE
, 7);
1706 L_CERT(_PATH_HOST_XMSS_KEY_FILE
, 8);
1707 L_PUBKEY(_PATH_HOST_XMSS_KEY_FILE
, 9);
1709 debug("HostbasedAuthentication enabled but no "
1710 "local public host keys could be loaded.");
1714 /* load options.identity_files */
1715 load_public_identity_files(cinfo
);
1717 /* optionally set the SSH_AUTHSOCKET_ENV_NAME variable */
1718 if (options
.identity_agent
&&
1719 strcmp(options
.identity_agent
, SSH_AUTHSOCKET_ENV_NAME
) != 0) {
1720 if (strcmp(options
.identity_agent
, "none") == 0) {
1721 unsetenv(SSH_AUTHSOCKET_ENV_NAME
);
1723 cp
= options
.identity_agent
;
1724 /* legacy (limited) format */
1725 if (cp
[0] == '$' && cp
[1] != '{') {
1726 if (!valid_env_name(cp
+ 1)) {
1727 fatal("Invalid IdentityAgent "
1728 "environment variable name %s", cp
);
1730 if ((p
= getenv(cp
+ 1)) == NULL
)
1731 unsetenv(SSH_AUTHSOCKET_ENV_NAME
);
1733 setenv(SSH_AUTHSOCKET_ENV_NAME
, p
, 1);
1735 /* identity_agent specifies a path directly */
1736 setenv(SSH_AUTHSOCKET_ENV_NAME
, cp
, 1);
1741 if (options
.forward_agent
&& options
.forward_agent_sock_path
!= NULL
) {
1742 cp
= options
.forward_agent_sock_path
;
1744 if (!valid_env_name(cp
+ 1)) {
1745 fatal("Invalid ForwardAgent environment variable name %s", cp
);
1747 if ((p
= getenv(cp
+ 1)) != NULL
)
1748 forward_agent_sock_path
= xstrdup(p
);
1750 options
.forward_agent
= 0;
1753 forward_agent_sock_path
= cp
;
1757 /* Expand ~ in known host file names. */
1758 tilde_expand_paths(options
.system_hostfiles
,
1759 options
.num_system_hostfiles
);
1760 tilde_expand_paths(options
.user_hostfiles
, options
.num_user_hostfiles
);
1762 ssh_signal(SIGCHLD
, main_sigchld_handler
);
1764 /* Log into the remote system. Never returns if the login fails. */
1765 ssh_login(ssh
, &sensitive_data
, host
, (struct sockaddr
*)&hostaddr
,
1766 options
.port
, pw
, timeout_ms
, cinfo
);
1768 /* We no longer need the private host keys. Clear them now. */
1769 if (sensitive_data
.nkeys
!= 0) {
1770 for (i
= 0; i
< sensitive_data
.nkeys
; i
++) {
1771 if (sensitive_data
.keys
[i
] != NULL
) {
1772 /* Destroys contents safely */
1773 debug3("clear hostkey %d", i
);
1774 sshkey_free(sensitive_data
.keys
[i
]);
1775 sensitive_data
.keys
[i
] = NULL
;
1778 free(sensitive_data
.keys
);
1780 for (i
= 0; i
< options
.num_identity_files
; i
++) {
1781 free(options
.identity_files
[i
]);
1782 options
.identity_files
[i
] = NULL
;
1783 if (options
.identity_keys
[i
]) {
1784 sshkey_free(options
.identity_keys
[i
]);
1785 options
.identity_keys
[i
] = NULL
;
1788 for (i
= 0; i
< options
.num_certificate_files
; i
++) {
1789 free(options
.certificate_files
[i
]);
1790 options
.certificate_files
[i
] = NULL
;
1793 #ifdef ENABLE_PKCS11
1794 (void)pkcs11_del_provider(options
.pkcs11_provider
);
1798 exit_status
= ssh_session2(ssh
, cinfo
);
1799 ssh_conn_info_free(cinfo
);
1800 ssh_packet_close(ssh
);
1802 if (options
.control_path
!= NULL
&& muxserver_sock
!= -1)
1803 unlink(options
.control_path
);
1805 /* Kill ProxyCommand if it is running. */
1806 ssh_kill_proxy_command();
1812 control_persist_detach(void)
1816 debug_f("backgrounding master process");
1819 * master (current process) into the background, and make the
1820 * foreground process a client of the backgrounded master.
1822 switch ((pid
= fork())) {
1824 fatal_f("fork: %s", strerror(errno
));
1826 /* Child: master process continues mainloop */
1830 * Parent: set up mux client to connect to backgrounded
1833 debug2_f("background process is %ld", (long)pid
);
1834 options
.stdin_null
= ostdin_null_flag
;
1835 options
.request_tty
= orequest_tty
;
1836 tty_flag
= otty_flag
;
1837 options
.fork_after_authentication
= ofork_after_authentication
;
1838 options
.session_type
= osession_type
;
1839 close(muxserver_sock
);
1840 muxserver_sock
= -1;
1841 options
.control_master
= SSHCTL_MASTER_NO
;
1842 (void)muxclient(options
.control_path
);
1843 /* muxclient() doesn't return on success. */
1844 fatal("Failed to connect to new control master");
1846 if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag
)) == -1)
1847 error_f("stdfd_devnull failed");
1849 setproctitle("%s [mux]", options
.control_path
);
1852 /* Do fork() after authentication. Used by "ssh -f" */
1856 if (need_controlpersist_detach
)
1857 control_persist_detach();
1858 debug("forking to background");
1859 options
.fork_after_authentication
= 0;
1860 if (daemon(1, 1) == -1)
1861 fatal("daemon() failed: %.200s", strerror(errno
));
1862 if (stdfd_devnull(1, 1, !(log_is_on_stderr() && debug_flag
)) == -1)
1863 error_f("stdfd_devnull failed");
1867 forwarding_success(void)
1869 if (forward_confirms_pending
== -1)
1871 if (--forward_confirms_pending
== 0) {
1872 debug_f("all expected forwarding replies received");
1873 if (options
.fork_after_authentication
)
1876 debug2_f("%d expected forwarding replies remaining",
1877 forward_confirms_pending
);
1881 /* Callback for remote forward global requests */
1883 ssh_confirm_remote_forward(struct ssh
*ssh
, int type
, u_int32_t seq
, void *ctxt
)
1885 struct Forward
*rfwd
= (struct Forward
*)ctxt
;
1889 /* XXX verbose() on failure? */
1890 debug("remote forward %s for: listen %s%s%d, connect %s:%d",
1891 type
== SSH2_MSG_REQUEST_SUCCESS
? "success" : "failure",
1892 rfwd
->listen_path
? rfwd
->listen_path
:
1893 rfwd
->listen_host
? rfwd
->listen_host
: "",
1894 (rfwd
->listen_path
|| rfwd
->listen_host
) ? ":" : "",
1895 rfwd
->listen_port
, rfwd
->connect_path
? rfwd
->connect_path
:
1896 rfwd
->connect_host
, rfwd
->connect_port
);
1897 if (rfwd
->listen_path
== NULL
&& rfwd
->listen_port
== 0) {
1898 if (type
== SSH2_MSG_REQUEST_SUCCESS
) {
1899 if ((r
= sshpkt_get_u32(ssh
, &port
)) != 0)
1900 fatal_fr(r
, "parse packet");
1902 error("Invalid allocated port %u for remote "
1903 "forward to %s:%d", port
,
1904 rfwd
->connect_host
, rfwd
->connect_port
);
1905 /* Ensure failure processing runs below */
1906 type
= SSH2_MSG_REQUEST_FAILURE
;
1907 channel_update_permission(ssh
,
1910 rfwd
->allocated_port
= (int)port
;
1911 logit("Allocated port %u for remote "
1913 rfwd
->allocated_port
, rfwd
->connect_path
?
1914 rfwd
->connect_path
: rfwd
->connect_host
,
1915 rfwd
->connect_port
);
1916 channel_update_permission(ssh
,
1917 rfwd
->handle
, rfwd
->allocated_port
);
1920 channel_update_permission(ssh
, rfwd
->handle
, -1);
1924 if (type
== SSH2_MSG_REQUEST_FAILURE
) {
1925 if (options
.exit_on_forward_failure
) {
1926 if (rfwd
->listen_path
!= NULL
)
1927 fatal("Error: remote port forwarding failed "
1928 "for listen path %s", rfwd
->listen_path
);
1930 fatal("Error: remote port forwarding failed "
1931 "for listen port %d", rfwd
->listen_port
);
1933 if (rfwd
->listen_path
!= NULL
)
1934 logit("Warning: remote port forwarding failed "
1935 "for listen path %s", rfwd
->listen_path
);
1937 logit("Warning: remote port forwarding failed "
1938 "for listen port %d", rfwd
->listen_port
);
1941 forwarding_success();
1945 client_cleanup_stdio_fwd(struct ssh
*ssh
, int id
, int force
, void *arg
)
1947 debug("stdio forwarding: done");
1952 ssh_stdio_confirm(struct ssh
*ssh
, int id
, int success
, void *arg
)
1955 fatal("stdio forwarding failed");
1959 ssh_tun_confirm(struct ssh
*ssh
, int id
, int success
, void *arg
)
1962 error("Tunnel forwarding failed");
1963 if (options
.exit_on_forward_failure
)
1967 debug_f("tunnel forward established, id=%d", id
);
1968 forwarding_success();
1972 ssh_init_stdio_forwarding(struct ssh
*ssh
)
1977 if (options
.stdio_forward_host
== NULL
)
1980 debug3_f("%s:%d", options
.stdio_forward_host
,
1981 options
.stdio_forward_port
);
1983 if ((in
= dup(STDIN_FILENO
)) == -1 ||
1984 (out
= dup(STDOUT_FILENO
)) == -1)
1985 fatal_f("dup() in/out failed");
1986 if ((c
= channel_connect_stdio_fwd(ssh
, options
.stdio_forward_host
,
1987 options
.stdio_forward_port
, in
, out
,
1988 CHANNEL_NONBLOCK_STDIO
)) == NULL
)
1989 fatal_f("channel_connect_stdio_fwd failed");
1990 channel_register_cleanup(ssh
, c
->self
, client_cleanup_stdio_fwd
, 0);
1991 channel_register_open_confirm(ssh
, c
->self
, ssh_stdio_confirm
, NULL
);
1995 ssh_init_forward_permissions(struct ssh
*ssh
, const char *what
, char **opens
,
2000 char *addr
, *arg
, *oarg
;
2001 int where
= FORWARD_LOCAL
;
2003 channel_clear_permission(ssh
, FORWARD_ADM
, where
);
2005 return; /* permit any */
2007 /* handle keywords: "any" / "none" */
2008 if (num_opens
== 1 && strcmp(opens
[0], "any") == 0)
2010 if (num_opens
== 1 && strcmp(opens
[0], "none") == 0) {
2011 channel_disable_admin(ssh
, where
);
2014 /* Otherwise treat it as a list of permitted host:port */
2015 for (i
= 0; i
< num_opens
; i
++) {
2016 oarg
= arg
= xstrdup(opens
[i
]);
2017 addr
= hpdelim(&arg
);
2019 fatal_f("missing host in %s", what
);
2020 addr
= cleanhostname(addr
);
2021 if (arg
== NULL
|| ((port
= permitopen_port(arg
)) < 0))
2022 fatal_f("bad port number in %s", what
);
2023 /* Send it to channels layer */
2024 channel_add_permission(ssh
, FORWARD_ADM
,
2031 ssh_init_forwarding(struct ssh
*ssh
, char **ifname
)
2036 ssh_init_forward_permissions(ssh
, "permitremoteopen",
2037 options
.permitted_remote_opens
,
2038 options
.num_permitted_remote_opens
);
2040 if (options
.exit_on_forward_failure
)
2041 forward_confirms_pending
= 0; /* track pending requests */
2042 /* Initiate local TCP/IP port forwardings. */
2043 for (i
= 0; i
< options
.num_local_forwards
; i
++) {
2044 debug("Local connections to %.200s:%d forwarded to remote "
2045 "address %.200s:%d",
2046 (options
.local_forwards
[i
].listen_path
!= NULL
) ?
2047 options
.local_forwards
[i
].listen_path
:
2048 (options
.local_forwards
[i
].listen_host
== NULL
) ?
2049 (options
.fwd_opts
.gateway_ports
? "*" : "LOCALHOST") :
2050 options
.local_forwards
[i
].listen_host
,
2051 options
.local_forwards
[i
].listen_port
,
2052 (options
.local_forwards
[i
].connect_path
!= NULL
) ?
2053 options
.local_forwards
[i
].connect_path
:
2054 options
.local_forwards
[i
].connect_host
,
2055 options
.local_forwards
[i
].connect_port
);
2056 success
+= channel_setup_local_fwd_listener(ssh
,
2057 &options
.local_forwards
[i
], &options
.fwd_opts
);
2059 if (i
> 0 && success
!= i
&& options
.exit_on_forward_failure
)
2060 fatal("Could not request local forwarding.");
2061 if (i
> 0 && success
== 0)
2062 error("Could not request local forwarding.");
2064 /* Initiate remote TCP/IP port forwardings. */
2065 for (i
= 0; i
< options
.num_remote_forwards
; i
++) {
2066 debug("Remote connections from %.200s:%d forwarded to "
2067 "local address %.200s:%d",
2068 (options
.remote_forwards
[i
].listen_path
!= NULL
) ?
2069 options
.remote_forwards
[i
].listen_path
:
2070 (options
.remote_forwards
[i
].listen_host
== NULL
) ?
2071 "LOCALHOST" : options
.remote_forwards
[i
].listen_host
,
2072 options
.remote_forwards
[i
].listen_port
,
2073 (options
.remote_forwards
[i
].connect_path
!= NULL
) ?
2074 options
.remote_forwards
[i
].connect_path
:
2075 options
.remote_forwards
[i
].connect_host
,
2076 options
.remote_forwards
[i
].connect_port
);
2077 if ((options
.remote_forwards
[i
].handle
=
2078 channel_request_remote_forwarding(ssh
,
2079 &options
.remote_forwards
[i
])) >= 0) {
2080 client_register_global_confirm(
2081 ssh_confirm_remote_forward
,
2082 &options
.remote_forwards
[i
]);
2083 forward_confirms_pending
++;
2084 } else if (options
.exit_on_forward_failure
)
2085 fatal("Could not request remote forwarding.");
2087 logit("Warning: Could not request remote forwarding.");
2090 /* Initiate tunnel forwarding. */
2091 if (options
.tun_open
!= SSH_TUNMODE_NO
) {
2092 if ((*ifname
= client_request_tun_fwd(ssh
,
2093 options
.tun_open
, options
.tun_local
,
2094 options
.tun_remote
, ssh_tun_confirm
, NULL
)) != NULL
)
2095 forward_confirms_pending
++;
2096 else if (options
.exit_on_forward_failure
)
2097 fatal("Could not request tunnel forwarding.");
2099 error("Could not request tunnel forwarding.");
2101 if (forward_confirms_pending
> 0) {
2102 debug_f("expecting replies for %d forwards",
2103 forward_confirms_pending
);
2108 check_agent_present(void)
2112 if (options
.forward_agent
) {
2113 /* Clear agent forwarding if we don't have an agent. */
2114 if ((r
= ssh_get_authentication_socket(NULL
)) != 0) {
2115 options
.forward_agent
= 0;
2116 if (r
!= SSH_ERR_AGENT_NOT_PRESENT
)
2117 debug_r(r
, "ssh_get_authentication_socket");
2123 ssh_session2_setup(struct ssh
*ssh
, int id
, int success
, void *arg
)
2125 extern char **environ
;
2126 const char *display
, *term
;
2127 int r
, interactive
= tty_flag
;
2128 char *proto
= NULL
, *data
= NULL
;
2131 return; /* No need for error message, channels code sends one */
2133 display
= getenv("DISPLAY");
2134 if (display
== NULL
&& options
.forward_x11
)
2135 debug("X11 forwarding requested but DISPLAY not set");
2136 if (options
.forward_x11
&& client_x11_get_proto(ssh
, display
,
2137 options
.xauth_location
, options
.forward_x11_trusted
,
2138 options
.forward_x11_timeout
, &proto
, &data
) == 0) {
2139 /* Request forwarding with authentication spoofing. */
2140 debug("Requesting X11 forwarding with authentication "
2142 x11_request_forwarding_with_spoofing(ssh
, id
, display
, proto
,
2144 client_expect_confirm(ssh
, id
, "X11 forwarding", CONFIRM_WARN
);
2145 /* XXX exit_on_forward_failure */
2149 check_agent_present();
2150 if (options
.forward_agent
) {
2151 debug("Requesting authentication agent forwarding.");
2152 channel_request_start(ssh
, id
, "auth-agent-req@openssh.com", 0);
2153 if ((r
= sshpkt_send(ssh
)) != 0)
2154 fatal_fr(r
, "send packet");
2157 /* Tell the packet module whether this is an interactive session. */
2158 ssh_packet_set_interactive(ssh
, interactive
,
2159 options
.ip_qos_interactive
, options
.ip_qos_bulk
);
2161 if ((term
= lookup_env_in_list("TERM", options
.setenv
,
2162 options
.num_setenv
)) == NULL
|| *term
== '\0')
2163 term
= getenv("TERM");
2164 client_session2_setup(ssh
, id
, tty_flag
,
2165 options
.session_type
== SESSION_TYPE_SUBSYSTEM
, term
,
2166 NULL
, fileno(stdin
), command
, environ
);
2169 /* open new channel for a session */
2171 ssh_session2_open(struct ssh
*ssh
)
2174 int window
, packetmax
, in
, out
, err
;
2176 if (options
.stdin_null
) {
2177 in
= open(_PATH_DEVNULL
, O_RDONLY
);
2179 in
= dup(STDIN_FILENO
);
2181 out
= dup(STDOUT_FILENO
);
2182 err
= dup(STDERR_FILENO
);
2184 if (in
== -1 || out
== -1 || err
== -1)
2185 fatal("dup() in/out/err failed");
2187 window
= CHAN_SES_WINDOW_DEFAULT
;
2188 packetmax
= CHAN_SES_PACKET_DEFAULT
;
2193 c
= channel_new(ssh
,
2194 "session", SSH_CHANNEL_OPENING
, in
, out
, err
,
2195 window
, packetmax
, CHAN_EXTENDED_WRITE
,
2196 "client-session", CHANNEL_NONBLOCK_STDIO
);
2198 debug3_f("channel_new: %d", c
->self
);
2200 channel_send_open(ssh
, c
->self
);
2201 if (options
.session_type
!= SESSION_TYPE_NONE
)
2202 channel_register_open_confirm(ssh
, c
->self
,
2203 ssh_session2_setup
, NULL
);
2209 ssh_session2(struct ssh
*ssh
, const struct ssh_conn_info
*cinfo
)
2211 int r
, interactive
, id
= -1;
2212 char *cp
, *tun_fwd_ifname
= NULL
;
2214 /* XXX should be pre-session */
2215 if (!options
.control_persist
)
2216 ssh_init_stdio_forwarding(ssh
);
2218 ssh_init_forwarding(ssh
, &tun_fwd_ifname
);
2220 if (options
.local_command
!= NULL
) {
2221 debug3("expanding LocalCommand: %s", options
.local_command
);
2222 cp
= options
.local_command
;
2223 options
.local_command
= percent_expand(cp
,
2224 DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(cinfo
),
2225 "T", tun_fwd_ifname
== NULL
? "NONE" : tun_fwd_ifname
,
2227 debug3("expanded LocalCommand: %s", options
.local_command
);
2231 /* Start listening for multiplex clients */
2232 if (!ssh_packet_get_mux(ssh
))
2233 muxserver_listen(ssh
);
2236 * If we are in control persist mode and have a working mux listen
2237 * socket, then prepare to background ourselves and have a foreground
2238 * client attach as a control client.
2239 * NB. we must save copies of the flags that we override for
2240 * the backgrounding, since we defer attachment of the client until
2241 * after the connection is fully established (in particular,
2242 * async rfwd replies have been received for ExitOnForwardFailure).
2244 if (options
.control_persist
&& muxserver_sock
!= -1) {
2245 ostdin_null_flag
= options
.stdin_null
;
2246 osession_type
= options
.session_type
;
2247 orequest_tty
= options
.request_tty
;
2248 otty_flag
= tty_flag
;
2249 ofork_after_authentication
= options
.fork_after_authentication
;
2250 options
.stdin_null
= 1;
2251 options
.session_type
= SESSION_TYPE_NONE
;
2253 if ((osession_type
!= SESSION_TYPE_NONE
||
2254 options
.stdio_forward_host
!= NULL
))
2255 need_controlpersist_detach
= 1;
2256 options
.fork_after_authentication
= 1;
2259 * ControlPersist mux listen socket setup failed, attempt the
2260 * stdio forward setup that we skipped earlier.
2262 if (options
.control_persist
&& muxserver_sock
== -1)
2263 ssh_init_stdio_forwarding(ssh
);
2265 if (options
.session_type
!= SESSION_TYPE_NONE
)
2266 id
= ssh_session2_open(ssh
);
2268 interactive
= options
.control_master
== SSHCTL_MASTER_NO
;
2269 /* ControlPersist may have clobbered ControlMaster, so check */
2270 if (need_controlpersist_detach
)
2271 interactive
= otty_flag
!= 0;
2272 ssh_packet_set_interactive(ssh
, interactive
,
2273 options
.ip_qos_interactive
, options
.ip_qos_bulk
);
2276 /* If we don't expect to open a new session, then disallow it */
2277 if (options
.control_master
== SSHCTL_MASTER_NO
&&
2278 (ssh
->compat
& SSH_NEW_OPENSSH
)) {
2279 debug("Requesting no-more-sessions@openssh.com");
2280 if ((r
= sshpkt_start(ssh
, SSH2_MSG_GLOBAL_REQUEST
)) != 0 ||
2281 (r
= sshpkt_put_cstring(ssh
,
2282 "no-more-sessions@openssh.com")) != 0 ||
2283 (r
= sshpkt_put_u8(ssh
, 0)) != 0 ||
2284 (r
= sshpkt_send(ssh
)) != 0)
2285 fatal_fr(r
, "send packet");
2288 /* Execute a local command */
2289 if (options
.local_command
!= NULL
&&
2290 options
.permit_local_command
)
2291 ssh_local_cmd(options
.local_command
);
2294 * stdout is now owned by the session channel; clobber it here
2295 * so future channel closes are propagated to the local fd.
2296 * NB. this can only happen after LocalCommand has completed,
2297 * as it may want to write to stdout.
2299 if (!need_controlpersist_detach
&& stdfd_devnull(0, 1, 0) == -1)
2300 error_f("stdfd_devnull failed");
2303 * If requested and we are not interested in replies to remote
2304 * forwarding requests, then let ssh continue in the background.
2306 if (options
.fork_after_authentication
) {
2307 if (options
.exit_on_forward_failure
&&
2308 options
.num_remote_forwards
> 0) {
2309 debug("deferring postauth fork until remote forward "
2310 "confirmation received");
2315 return client_loop(ssh
, tty_flag
, tty_flag
?
2316 options
.escape_char
: SSH_ESCAPECHAR_NONE
, id
);
2319 /* Loads all IdentityFile and CertificateFile keys */
2321 load_public_identity_files(const struct ssh_conn_info
*cinfo
)
2323 char *filename
, *cp
;
2324 struct sshkey
*public;
2326 u_int n_ids
, n_certs
;
2327 char *identity_files
[SSH_MAX_IDENTITY_FILES
];
2328 struct sshkey
*identity_keys
[SSH_MAX_IDENTITY_FILES
];
2329 int identity_file_userprovided
[SSH_MAX_IDENTITY_FILES
];
2330 char *certificate_files
[SSH_MAX_CERTIFICATE_FILES
];
2331 struct sshkey
*certificates
[SSH_MAX_CERTIFICATE_FILES
];
2332 int certificate_file_userprovided
[SSH_MAX_CERTIFICATE_FILES
];
2333 #ifdef ENABLE_PKCS11
2334 struct sshkey
**keys
= NULL
;
2335 char **comments
= NULL
;
2339 n_ids
= n_certs
= 0;
2340 memset(identity_files
, 0, sizeof(identity_files
));
2341 memset(identity_keys
, 0, sizeof(identity_keys
));
2342 memset(identity_file_userprovided
, 0,
2343 sizeof(identity_file_userprovided
));
2344 memset(certificate_files
, 0, sizeof(certificate_files
));
2345 memset(certificates
, 0, sizeof(certificates
));
2346 memset(certificate_file_userprovided
, 0,
2347 sizeof(certificate_file_userprovided
));
2349 #ifdef ENABLE_PKCS11
2350 if (options
.pkcs11_provider
!= NULL
&&
2351 options
.num_identity_files
< SSH_MAX_IDENTITY_FILES
&&
2352 (pkcs11_init(!options
.batch_mode
) == 0) &&
2353 (nkeys
= pkcs11_add_provider(options
.pkcs11_provider
, NULL
,
2354 &keys
, &comments
)) > 0) {
2355 for (i
= 0; i
< nkeys
; i
++) {
2356 if (n_ids
>= SSH_MAX_IDENTITY_FILES
) {
2357 sshkey_free(keys
[i
]);
2361 identity_keys
[n_ids
] = keys
[i
];
2362 identity_files
[n_ids
] = comments
[i
]; /* transferred */
2368 #endif /* ENABLE_PKCS11 */
2369 for (i
= 0; i
< options
.num_identity_files
; i
++) {
2370 if (n_ids
>= SSH_MAX_IDENTITY_FILES
||
2371 strcasecmp(options
.identity_files
[i
], "none") == 0) {
2372 free(options
.identity_files
[i
]);
2373 options
.identity_files
[i
] = NULL
;
2376 cp
= tilde_expand_filename(options
.identity_files
[i
], getuid());
2377 filename
= default_client_percent_dollar_expand(cp
, cinfo
);
2379 check_load(sshkey_load_public(filename
, &public, NULL
),
2380 &public, filename
, "pubkey");
2381 debug("identity file %s type %d", filename
,
2382 public ? public->type
: -1);
2383 free(options
.identity_files
[i
]);
2384 identity_files
[n_ids
] = filename
;
2385 identity_keys
[n_ids
] = public;
2386 identity_file_userprovided
[n_ids
] =
2387 options
.identity_file_userprovided
[i
];
2388 if (++n_ids
>= SSH_MAX_IDENTITY_FILES
)
2392 * If no certificates have been explicitly listed then try
2393 * to add the default certificate variant too.
2395 if (options
.num_certificate_files
!= 0)
2397 xasprintf(&cp
, "%s-cert", filename
);
2398 check_load(sshkey_load_public(cp
, &public, NULL
),
2399 &public, filename
, "pubkey");
2400 debug("identity file %s type %d", cp
,
2401 public ? public->type
: -1);
2402 if (public == NULL
) {
2406 if (!sshkey_is_cert(public)) {
2407 debug_f("key %s type %s is not a certificate",
2408 cp
, sshkey_type(public));
2409 sshkey_free(public);
2413 /* NB. leave filename pointing to private key */
2414 identity_files
[n_ids
] = xstrdup(filename
);
2415 identity_keys
[n_ids
] = public;
2416 identity_file_userprovided
[n_ids
] =
2417 options
.identity_file_userprovided
[i
];
2421 if (options
.num_certificate_files
> SSH_MAX_CERTIFICATE_FILES
)
2422 fatal_f("too many certificates");
2423 for (i
= 0; i
< options
.num_certificate_files
; i
++) {
2424 cp
= tilde_expand_filename(options
.certificate_files
[i
],
2426 filename
= default_client_percent_dollar_expand(cp
, cinfo
);
2429 check_load(sshkey_load_public(filename
, &public, NULL
),
2430 &public, filename
, "certificate");
2431 debug("certificate file %s type %d", filename
,
2432 public ? public->type
: -1);
2433 free(options
.certificate_files
[i
]);
2434 options
.certificate_files
[i
] = NULL
;
2435 if (public == NULL
) {
2439 if (!sshkey_is_cert(public)) {
2440 debug_f("key %s type %s is not a certificate",
2441 filename
, sshkey_type(public));
2442 sshkey_free(public);
2446 certificate_files
[n_certs
] = filename
;
2447 certificates
[n_certs
] = public;
2448 certificate_file_userprovided
[n_certs
] =
2449 options
.certificate_file_userprovided
[i
];
2453 options
.num_identity_files
= n_ids
;
2454 memcpy(options
.identity_files
, identity_files
, sizeof(identity_files
));
2455 memcpy(options
.identity_keys
, identity_keys
, sizeof(identity_keys
));
2456 memcpy(options
.identity_file_userprovided
,
2457 identity_file_userprovided
, sizeof(identity_file_userprovided
));
2459 options
.num_certificate_files
= n_certs
;
2460 memcpy(options
.certificate_files
,
2461 certificate_files
, sizeof(certificate_files
));
2462 memcpy(options
.certificates
, certificates
, sizeof(certificates
));
2463 memcpy(options
.certificate_file_userprovided
,
2464 certificate_file_userprovided
,
2465 sizeof(certificate_file_userprovided
));
2469 main_sigchld_handler(int sig
)
2471 int save_errno
= errno
;
2475 while ((pid
= waitpid(-1, &status
, WNOHANG
)) > 0 ||
2476 (pid
== -1 && errno
== EINTR
))