]> andersk Git - gssapi-openssh.git/blame - openssh/ssh.c
merged OPENSSH_5_2P1_GSSAPI_20090225 to GPT-branch
[gssapi-openssh.git] / openssh / ssh.c
CommitLineData
16eb0a3b 1/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
3c0ef626 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
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.
9 *
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".
15 *
16 * Copyright (c) 1999 Niels Provos. All rights reserved.
416fd2a8 17 * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.
3c0ef626 18 *
19 * Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
20 * in Canada (German citizen).
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
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.
30 *
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.
41 */
42
43#include "includes.h"
2e437378 44
45#include <sys/types.h>
46#ifdef HAVE_SYS_STAT_H
47# include <sys/stat.h>
48#endif
49#include <sys/resource.h>
50#include <sys/ioctl.h>
51#include <sys/socket.h>
2e437378 52
53#include <ctype.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <netdb.h>
57#ifdef HAVE_PATHS_H
58#include <paths.h>
59#endif
60#include <pwd.h>
61#include <signal.h>
62#include <stdarg.h>
63#include <stddef.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67#include <unistd.h>
68
69#include <netinet/in.h>
70#include <arpa/inet.h>
3c0ef626 71
72#include <openssl/evp.h>
73#include <openssl/err.h>
bd5d5d2a 74#include "openbsd-compat/openssl-compat.h"
6f25cbdd 75#include "openbsd-compat/sys-queue.h"
3c0ef626 76
2e437378 77#include "xmalloc.h"
3c0ef626 78#include "ssh.h"
79#include "ssh1.h"
80#include "ssh2.h"
81#include "compat.h"
82#include "cipher.h"
3c0ef626 83#include "packet.h"
84#include "buffer.h"
3c0ef626 85#include "channels.h"
86#include "key.h"
87#include "authfd.h"
88#include "authfile.h"
89#include "pathnames.h"
1b56ff3d 90#include "dispatch.h"
3c0ef626 91#include "clientloop.h"
92#include "log.h"
93#include "readconf.h"
94#include "sshconnect.h"
3c0ef626 95#include "misc.h"
96#include "kex.h"
97#include "mac.h"
1b56ff3d 98#include "sshpty.h"
99#include "match.h"
100#include "msg.h"
1b56ff3d 101#include "uidswap.h"
2e437378 102#include "version.h"
3c0ef626 103
104#ifdef SMARTCARD
3c0ef626 105#include "scard.h"
106#endif
107
3c0ef626 108extern char *__progname;
3c0ef626 109
6f25cbdd 110/* Flag indicating whether debug mode is on. May be set on the command line. */
3c0ef626 111int debug_flag = 0;
112
113/* Flag indicating whether a tty should be allocated */
114int tty_flag = 0;
115int no_tty_flag = 0;
116int force_tty_flag = 0;
117
118/* don't exec a shell */
119int no_shell_flag = 0;
120
121/*
122 * Flag indicating that nothing should be read from stdin. This can be set
123 * on the command line.
124 */
125int stdin_null_flag = 0;
126
127/*
128 * Flag indicating that ssh should fork after authentication. This is useful
ff2d7a98 129 * so that the passphrase can be entered manually, and then ssh goes to the
3c0ef626 130 * background.
131 */
132int fork_after_authentication_flag = 0;
133
134/*
135 * General data structure for command line options and options configurable
136 * in configuration files. See readconf.h.
137 */
138Options options;
139
140/* optional user configfile */
141char *config = NULL;
142
143/*
144 * Name of the host we are connecting to. This is the name given on the
145 * command line, or the HostName specified for the user-supplied name in a
146 * configuration file.
147 */
148char *host;
149
150/* socket address the host resolves to */
151struct sockaddr_storage hostaddr;
152
153/* Private host keys. */
ff2d7a98 154Sensitive sensitive_data;
3c0ef626 155
156/* Original real UID. */
157uid_t original_real_uid;
ff2d7a98 158uid_t original_effective_uid;
3c0ef626 159
160/* command to be executed */
161Buffer command;
162
163/* Should we execute a command or invoke a subsystem? */
164int subsystem_flag = 0;
165
2980ea68 166/* # of replies received for global requests */
6f25cbdd 167static int remote_forward_confirms_received = 0;
2980ea68 168
e54b3d7c 169/* pid of proxycommand child process */
170pid_t proxy_command_pid = 0;
171
6f25cbdd 172/* mux.c */
173extern int muxserver_sock;
174extern u_int muxclient_command;
1b56ff3d 175
3c0ef626 176/* Prints a help message to the user. This function never returns. */
177
178static void
179usage(void)
180{
2a304a95 181 fprintf(stderr,
16eb0a3b 182"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
e00da40d 183" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
34fee935 184" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
185" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
186" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
2e437378 187" [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
2a304a95 188 );
e00da40d 189 exit(255);
3c0ef626 190}
191
3c0ef626 192static int ssh_session(void);
193static int ssh_session2(void);
194static void load_public_identity_files(void);
6f25cbdd 195
196/* from muxclient.c */
197void muxclient(const char *);
198void muxserver_listen(void);
3c0ef626 199
200/*
201 * Main program for the ssh client.
202 */
203int
204main(int ac, char **av)
205{
16eb0a3b 206 int i, opt, exit_status, use_syslog;
416fd2a8 207 char *p, *cp, *line, buf[256];
3c0ef626 208 struct stat st;
209 struct passwd *pw;
bd5d5d2a 210 int dummy, timeout_ms;
3c0ef626 211 extern int optind, optreset;
212 extern char *optarg;
34fee935 213 struct servent *sp;
214 Forward fwd;
3c0ef626 215
e00da40d 216 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
217 sanitise_stdfd();
218
70791e56 219 __progname = ssh_get_progname(av[0]);
ae43c103 220 init_pathnames();
3c0ef626 221 init_rng();
222
223 /*
224 * Save the original real uid. It will be needed later (uid-swapping
225 * may clobber the real uid).
226 */
227 original_real_uid = getuid();
228 original_effective_uid = geteuid();
416fd2a8 229
e54b3d7c 230 /*
231 * Use uid-swapping to give up root privileges for the duration of
232 * option processing. We will re-instantiate the rights when we are
233 * ready to create the privileged port, and will permanently drop
234 * them when the port has been created (actually, when the connection
235 * has been made, as we may need to create the port several times).
236 */
237 PRIV_END;
3c0ef626 238
239#ifdef HAVE_SETRLIMIT
240 /* If we are installed setuid root be careful to not drop core. */
241 if (original_real_uid != original_effective_uid) {
242 struct rlimit rlim;
243 rlim.rlim_cur = rlim.rlim_max = 0;
244 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
245 fatal("setrlimit failed: %.100s", strerror(errno));
246 }
247#endif
248 /* Get user data. */
249 pw = getpwuid(original_real_uid);
250 if (!pw) {
70791e56 251 logit("You don't exist, go away!");
e00da40d 252 exit(255);
3c0ef626 253 }
254 /* Take a copy of the returned structure. */
255 pw = pwcopy(pw);
256
3c0ef626 257 /*
258 * Set our umask to something reasonable, as some files are created
259 * with the default umask. This will make them world-readable but
260 * writable only by the owner, which is ok for all files for which we
261 * don't set the modes explicitly.
262 */
263 umask(022);
264
6f25cbdd 265 /*
266 * Initialize option structure to indicate that no values have been
267 * set.
268 */
3c0ef626 269 initialize_options(&options);
270
271 /* Parse command-line arguments. */
272 host = NULL;
16eb0a3b 273 use_syslog = 0;
3c0ef626 274
2e437378 275 again:
6f25cbdd 276 while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
16eb0a3b 277 "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) {
3c0ef626 278 switch (opt) {
279 case '1':
280 options.protocol = SSH_PROTO_1;
281 break;
282 case '2':
283 options.protocol = SSH_PROTO_2;
284 break;
285 case '4':
70791e56 286 options.address_family = AF_INET;
3c0ef626 287 break;
288 case '6':
70791e56 289 options.address_family = AF_INET6;
3c0ef626 290 break;
291 case 'n':
292 stdin_null_flag = 1;
293 break;
294 case 'f':
295 fork_after_authentication_flag = 1;
296 stdin_null_flag = 1;
297 break;
298 case 'x':
299 options.forward_x11 = 0;
300 break;
301 case 'X':
302 options.forward_x11 = 1;
303 break;
16eb0a3b 304 case 'y':
305 use_syslog = 1;
306 break;
416fd2a8 307 case 'Y':
308 options.forward_x11 = 1;
309 options.forward_x11_trusted = 1;
310 break;
3c0ef626 311 case 'g':
312 options.gateway_ports = 1;
313 break;
34fee935 314 case 'O':
315 if (strcmp(optarg, "check") == 0)
6f25cbdd 316 muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
34fee935 317 else if (strcmp(optarg, "exit") == 0)
6f25cbdd 318 muxclient_command = SSHMUX_COMMAND_TERMINATE;
34fee935 319 else
320 fatal("Invalid multiplex command.");
321 break;
e54b3d7c 322 case 'P': /* deprecated */
3c0ef626 323 options.use_privileged_port = 0;
324 break;
325 case 'a':
326 options.forward_agent = 0;
327 break;
328 case 'A':
329 options.forward_agent = 1;
330 break;
3c0ef626 331 case 'k':
416fd2a8 332 options.gss_deleg_creds = 0;
3c0ef626 333 break;
25d429a2 334 case 'K':
335 options.gss_authentication = 1;
336 options.gss_deleg_creds = 1;
337 break;
3c0ef626 338 case 'i':
339 if (stat(optarg, &st) < 0) {
340 fprintf(stderr, "Warning: Identity file %s "
34fee935 341 "not accessible: %s.\n", optarg,
342 strerror(errno));
3c0ef626 343 break;
344 }
345 if (options.num_identity_files >=
346 SSH_MAX_IDENTITY_FILES)
347 fatal("Too many identity files specified "
348 "(max %d)", SSH_MAX_IDENTITY_FILES);
349 options.identity_files[options.num_identity_files++] =
350 xstrdup(optarg);
351 break;
352 case 'I':
353#ifdef SMARTCARD
354 options.smartcard_device = xstrdup(optarg);
355#else
356 fprintf(stderr, "no support for smartcards.\n");
357#endif
358 break;
359 case 't':
360 if (tty_flag)
361 force_tty_flag = 1;
362 tty_flag = 1;
363 break;
364 case 'v':
70791e56 365 if (debug_flag == 0) {
3c0ef626 366 debug_flag = 1;
367 options.log_level = SYSLOG_LEVEL_DEBUG1;
70791e56 368 } else {
369 if (options.log_level < SYSLOG_LEVEL_DEBUG3)
370 options.log_level++;
3c0ef626 371 break;
70791e56 372 }
34fee935 373 /* FALLTHROUGH */
3c0ef626 374 case 'V':
2a304a95 375 fprintf(stderr, "%s, %s\n",
34fee935 376 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
3c0ef626 377 if (opt == 'V')
378 exit(0);
379 break;
e00da40d 380 case 'w':
381 if (options.tun_open == -1)
382 options.tun_open = SSH_TUNMODE_DEFAULT;
383 options.tun_local = a2tun(optarg, &options.tun_remote);
384 if (options.tun_local == SSH_TUNID_ERR) {
6f25cbdd 385 fprintf(stderr,
386 "Bad tun device '%s'\n", optarg);
e00da40d 387 exit(255);
388 }
389 break;
3c0ef626 390 case 'q':
391 options.log_level = SYSLOG_LEVEL_QUIET;
392 break;
393 case 'e':
394 if (optarg[0] == '^' && optarg[2] == 0 &&
395 (u_char) optarg[1] >= 64 &&
396 (u_char) optarg[1] < 128)
397 options.escape_char = (u_char) optarg[1] & 31;
398 else if (strlen(optarg) == 1)
399 options.escape_char = (u_char) optarg[0];
400 else if (strcmp(optarg, "none") == 0)
401 options.escape_char = SSH_ESCAPECHAR_NONE;
402 else {
403 fprintf(stderr, "Bad escape character '%s'.\n",
404 optarg);
e00da40d 405 exit(255);
3c0ef626 406 }
407 break;
408 case 'c':
409 if (ciphers_valid(optarg)) {
410 /* SSH2 only */
411 options.ciphers = xstrdup(optarg);
1b56ff3d 412 options.cipher = SSH_CIPHER_INVALID;
3c0ef626 413 } else {
414 /* SSH1 only */
415 options.cipher = cipher_number(optarg);
416 if (options.cipher == -1) {
417 fprintf(stderr,
418 "Unknown cipher type '%s'\n",
419 optarg);
e00da40d 420 exit(255);
3c0ef626 421 }
422 if (options.cipher == SSH_CIPHER_3DES)
423 options.ciphers = "3des-cbc";
424 else if (options.cipher == SSH_CIPHER_BLOWFISH)
425 options.ciphers = "blowfish-cbc";
426 else
427 options.ciphers = (char *)-1;
428 }
429 break;
430 case 'm':
431 if (mac_valid(optarg))
432 options.macs = xstrdup(optarg);
433 else {
434 fprintf(stderr, "Unknown mac type '%s'\n",
435 optarg);
e00da40d 436 exit(255);
3c0ef626 437 }
438 break;
1b56ff3d 439 case 'M':
34fee935 440 if (options.control_master == SSHCTL_MASTER_YES)
441 options.control_master = SSHCTL_MASTER_ASK;
442 else
443 options.control_master = SSHCTL_MASTER_YES;
1b56ff3d 444 break;
3c0ef626 445 case 'p':
446 options.port = a2port(optarg);
16eb0a3b 447 if (options.port <= 0) {
3c0ef626 448 fprintf(stderr, "Bad port '%s'\n", optarg);
e00da40d 449 exit(255);
3c0ef626 450 }
451 break;
452 case 'l':
453 options.user = optarg;
454 break;
455
456 case 'L':
16eb0a3b 457 if (parse_forward(&fwd, optarg, 0, 0))
34fee935 458 add_local_forward(&options, &fwd);
459 else {
3c0ef626 460 fprintf(stderr,
34fee935 461 "Bad local forwarding specification '%s'\n",
3c0ef626 462 optarg);
e00da40d 463 exit(255);
3c0ef626 464 }
34fee935 465 break;
466
467 case 'R':
16eb0a3b 468 if (parse_forward(&fwd, optarg, 0, 1)) {
34fee935 469 add_remote_forward(&options, &fwd);
470 } else {
3c0ef626 471 fprintf(stderr,
34fee935 472 "Bad remote forwarding specification "
473 "'%s'\n", optarg);
e00da40d 474 exit(255);
3c0ef626 475 }
3c0ef626 476 break;
477
478 case 'D':
16eb0a3b 479 if (parse_forward(&fwd, optarg, 1, 0)) {
480 add_local_forward(&options, &fwd);
34fee935 481 } else {
16eb0a3b 482 fprintf(stderr,
483 "Bad dynamic forwarding specification "
484 "'%s'\n", optarg);
e00da40d 485 exit(255);
3c0ef626 486 }
3c0ef626 487 break;
488
489 case 'C':
490 options.compression = 1;
491 break;
492 case 'N':
493 no_shell_flag = 1;
494 no_tty_flag = 1;
3c0ef626 495 break;
496 case 'o':
497 dummy = 1;
416fd2a8 498 line = xstrdup(optarg);
3c0ef626 499 if (process_config_line(&options, host ? host : "",
416fd2a8 500 line, "command-line", 0, &dummy) != 0)
e00da40d 501 exit(255);
416fd2a8 502 xfree(line);
3c0ef626 503 break;
6f25cbdd 504 case 'T':
505 no_tty_flag = 1;
506 /* ensure that the user doesn't try to backdoor a */
507 /* null cipher switch on an interactive session */
508 /* so explicitly disable it no matter what */
509 options.none_switch=0;
510 break;
3c0ef626 511 case 's':
512 subsystem_flag = 1;
513 break;
1b56ff3d 514 case 'S':
515 if (options.control_path != NULL)
516 free(options.control_path);
517 options.control_path = xstrdup(optarg);
518 break;
3c0ef626 519 case 'b':
520 options.bind_address = optarg;
521 break;
522 case 'F':
523 config = optarg;
524 break;
525 default:
526 usage();
527 }
528 }
529
530 ac -= optind;
531 av += optind;
532
533 if (ac > 0 && !host && **av != '-') {
1c14df9e 534 if (strrchr(*av, '@')) {
3c0ef626 535 p = xstrdup(*av);
1c14df9e 536 cp = strrchr(p, '@');
3c0ef626 537 if (cp == NULL || cp == p)
538 usage();
539 options.user = p;
540 *cp = '\0';
541 host = ++cp;
542 } else
543 host = *av;
1c14df9e 544 if (ac > 1) {
545 optind = optreset = 1;
3c0ef626 546 goto again;
547 }
1c14df9e 548 ac--, av++;
3c0ef626 549 }
550
551 /* Check that we got a host name. */
552 if (!host)
553 usage();
554
555 SSLeay_add_all_algorithms();
556 ERR_load_crypto_strings();
3c0ef626 557
558 /* Initialize the command to execute on remote host. */
559 buffer_init(&command);
560
561 /*
562 * Save the command to execute on the remote host in a buffer. There
563 * is no limit on the length of the command, except by the maximum
564 * packet size. Also sets the tty flag if there is no command.
565 */
566 if (!ac) {
567 /* No command specified - execute shell on a tty. */
568 tty_flag = 1;
569 if (subsystem_flag) {
570 fprintf(stderr,
571 "You must specify a subsystem to invoke.\n");
572 usage();
573 }
574 } else {
575 /* A command has been specified. Store it into the buffer. */
576 for (i = 0; i < ac; i++) {
577 if (i)
578 buffer_append(&command, " ", 1);
579 buffer_append(&command, av[i], strlen(av[i]));
580 }
581 }
582
583 /* Cannot fork to background if no command. */
6f25cbdd 584 if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
585 !no_shell_flag)
586 fatal("Cannot fork into background without a command "
587 "to execute.");
3c0ef626 588
589 /* Allocate a tty by default if no command specified. */
590 if (buffer_len(&command) == 0)
591 tty_flag = 1;
592
e54b3d7c 593 /* Force no tty */
3c0ef626 594 if (no_tty_flag)
595 tty_flag = 0;
596 /* Do not allocate a tty if stdin is not a tty. */
34fee935 597 if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) {
3c0ef626 598 if (tty_flag)
6f25cbdd 599 logit("Pseudo-terminal will not be allocated because "
600 "stdin is not a terminal.");
3c0ef626 601 tty_flag = 0;
602 }
603
604 /*
605 * Initialize "log" output. Since we are the client all output
606 * actually goes to stderr.
607 */
6f25cbdd 608 log_init(av[0],
609 options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
16eb0a3b 610 SYSLOG_FACILITY_USER, !use_syslog);
3c0ef626 611
612 /*
613 * Read per-user configuration file. Ignore the system wide config
614 * file if the user specifies a config file on the command line.
615 */
616 if (config != NULL) {
1b56ff3d 617 if (!read_config_file(config, host, &options, 0))
3c0ef626 618 fatal("Can't open user config file %.100s: "
619 "%.100s", config, strerror(errno));
2278ffa1 620 } else {
078f71c2 621 /*
622 * Since the config file parsing code aborts if it sees
623 * options it doesn't recognize, allow users to put
624 * options specific to compile-time add-ons in alternate
625 * config files so their primary config file will
626 * interoperate SSH versions that don't support those
627 * options.
628 */
629#ifdef GSSAPI
630 snprintf(buf, sizeof buf, "%.100s/%.100s.gssapi", pw->pw_dir,
631 _PATH_SSH_USER_CONFFILE);
1b56ff3d 632 (void)read_config_file(buf, host, &options, 1);
078f71c2 633#ifdef GSI
634 snprintf(buf, sizeof buf, "%.100s/%.100s.gsi", pw->pw_dir,
635 _PATH_SSH_USER_CONFFILE);
1b56ff3d 636 (void)read_config_file(buf, host, &options, 1);
078f71c2 637#endif
70791e56 638#if defined(KRB5)
078f71c2 639 snprintf(buf, sizeof buf, "%.100s/%.100s.krb", pw->pw_dir,
640 _PATH_SSH_USER_CONFFILE);
1b56ff3d 641 (void)read_config_file(buf, host, &options, 1);
078f71c2 642#endif
078f71c2 643#endif
3c0ef626 644 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
645 _PATH_SSH_USER_CONFFILE);
1b56ff3d 646 (void)read_config_file(buf, host, &options, 1);
3c0ef626 647
648 /* Read systemwide configuration file after use config. */
1b56ff3d 649 (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
650 &options, 0);
3c0ef626 651 }
652
653 /* Fill configuration defaults. */
654 fill_default_options(&options);
655
70791e56 656 channel_set_af(options.address_family);
657
3c0ef626 658 /* reinit */
16eb0a3b 659 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
3c0ef626 660
661 seed_rng();
662
70791e56 663 if (options.user == NULL) {
664 options.user = xstrdup(pw->pw_name);
665 options.implicit = 1;
666 }
2980ea68 667 else options.implicit = 0;
3c0ef626 668
6f25cbdd 669 /* Get default port if port has not been set. */
670 if (options.port == 0) {
671 sp = getservbyname(SSH_SERVICE_NAME, "tcp");
672 options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
673 }
674
675 if (options.local_command != NULL) {
676 char thishost[NI_MAXHOST];
677
678 if (gethostname(thishost, sizeof(thishost)) == -1)
679 fatal("gethostname: %s", strerror(errno));
680 snprintf(buf, sizeof(buf), "%d", options.port);
681 debug3("expanding LocalCommand: %s", options.local_command);
682 cp = options.local_command;
683 options.local_command = percent_expand(cp, "d", pw->pw_dir,
684 "h", options.hostname? options.hostname : host,
685 "l", thishost, "n", host, "r", options.user, "p", buf,
686 "u", pw->pw_name, (char *)NULL);
687 debug3("expanded LocalCommand: %s", options.local_command);
688 xfree(cp);
689 }
690
3c0ef626 691 if (options.hostname != NULL)
692 host = options.hostname;
693
70791e56 694 /* force lowercase for hostkey matching */
695 if (options.host_key_alias != NULL) {
696 for (p = options.host_key_alias; *p; p++)
697 if (isupper(*p))
2e437378 698 *p = (char)tolower(*p);
70791e56 699 }
700
1c14df9e 701 if (options.proxy_command != NULL &&
bd5d5d2a 702 strcmp(options.proxy_command, "none") == 0) {
703 xfree(options.proxy_command);
1c14df9e 704 options.proxy_command = NULL;
bd5d5d2a 705 }
34fee935 706 if (options.control_path != NULL &&
bd5d5d2a 707 strcmp(options.control_path, "none") == 0) {
708 xfree(options.control_path);
34fee935 709 options.control_path = NULL;
bd5d5d2a 710 }
1c14df9e 711
1b56ff3d 712 if (options.control_path != NULL) {
2e437378 713 char thishost[NI_MAXHOST];
714
715 if (gethostname(thishost, sizeof(thishost)) == -1)
716 fatal("gethostname: %s", strerror(errno));
34fee935 717 snprintf(buf, sizeof(buf), "%d", options.port);
718 cp = tilde_expand_filename(options.control_path,
719 original_real_uid);
bd5d5d2a 720 xfree(options.control_path);
34fee935 721 options.control_path = percent_expand(cp, "p", buf, "h", host,
2e437378 722 "r", options.user, "l", thishost, (char *)NULL);
34fee935 723 xfree(cp);
1b56ff3d 724 }
6f25cbdd 725 if (muxclient_command != 0 && options.control_path == NULL)
34fee935 726 fatal("No ControlPath specified for \"-O\" command");
727 if (options.control_path != NULL)
6f25cbdd 728 muxclient(options.control_path);
1b56ff3d 729
bd5d5d2a 730 timeout_ms = options.connection_timeout * 1000;
731
3c0ef626 732 /* Open a connection to the remote host. */
70791e56 733 if (ssh_connect(host, &hostaddr, options.port,
bd5d5d2a 734 options.address_family, options.connection_attempts, &timeout_ms,
735 options.tcp_keep_alive,
ff2d7a98 736#ifdef HAVE_CYGWIN
737 options.use_privileged_port,
738#else
739 original_effective_uid == 0 && options.use_privileged_port,
740#endif
741 options.proxy_command) != 0)
e00da40d 742 exit(255);
3c0ef626 743
bd5d5d2a 744 if (timeout_ms > 0)
745 debug3("timeout: %d ms remain after connect", timeout_ms);
746
3c0ef626 747 /*
748 * If we successfully made the connection, load the host private key
749 * in case we will need it later for combined rsa-rhosts
750 * authentication. This must be done before releasing extra
751 * privileges, because the file is only readable by root.
ff2d7a98 752 * If we cannot access the private keys, load the public keys
753 * instead and try to execute the ssh-keysign helper instead.
3c0ef626 754 */
755 sensitive_data.nkeys = 0;
756 sensitive_data.keys = NULL;
ff2d7a98 757 sensitive_data.external_keysign = 0;
758 if (options.rhosts_rsa_authentication ||
759 options.hostbased_authentication) {
3c0ef626 760 sensitive_data.nkeys = 3;
2e437378 761 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
e54b3d7c 762 sizeof(Key));
ff2d7a98 763
764 PRIV_START;
3c0ef626 765 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
2e437378 766 _PATH_HOST_KEY_FILE, "", NULL, NULL);
3c0ef626 767 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
2e437378 768 _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
3c0ef626 769 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
2e437378 770 _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
ff2d7a98 771 PRIV_END;
772
e54b3d7c 773 if (options.hostbased_authentication == 1 &&
774 sensitive_data.keys[0] == NULL &&
ff2d7a98 775 sensitive_data.keys[1] == NULL &&
776 sensitive_data.keys[2] == NULL) {
777 sensitive_data.keys[1] = key_load_public(
778 _PATH_HOST_DSA_KEY_FILE, NULL);
779 sensitive_data.keys[2] = key_load_public(
780 _PATH_HOST_RSA_KEY_FILE, NULL);
781 sensitive_data.external_keysign = 1;
782 }
3c0ef626 783 }
784 /*
785 * Get rid of any extra privileges that we may have. We will no
786 * longer need them. Also, extra privileges could make it very hard
787 * to read identity files and other non-world-readable files from the
788 * user's home directory if it happens to be on a NFS volume where
789 * root is mapped to nobody.
790 */
1b56ff3d 791 if (original_effective_uid == 0) {
792 PRIV_START;
793 permanently_set_uid(pw);
794 }
3c0ef626 795
796 /*
797 * Now that we are back to our own permissions, create ~/.ssh
e00da40d 798 * directory if it doesn't already exist.
3c0ef626 799 */
6f25cbdd 800 snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
801 strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
3c0ef626 802 if (stat(buf, &st) < 0)
803 if (mkdir(buf, 0700) < 0)
804 error("Could not create directory '%.200s'.", buf);
805
3c0ef626 806 /* load options.identity_files */
807 load_public_identity_files();
808
809 /* Expand ~ in known host file names. */
810 /* XXX mem-leaks: */
811 options.system_hostfile =
812 tilde_expand_filename(options.system_hostfile, original_real_uid);
813 options.user_hostfile =
814 tilde_expand_filename(options.user_hostfile, original_real_uid);
815 options.system_hostfile2 =
816 tilde_expand_filename(options.system_hostfile2, original_real_uid);
817 options.user_hostfile2 =
818 tilde_expand_filename(options.user_hostfile2, original_real_uid);
819
820 signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
821
6f25cbdd 822 /* Log into the remote system. Never returns if the login fails. */
bd5d5d2a 823 ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
824 pw, timeout_ms);
3c0ef626 825
826 /* We no longer need the private host keys. Clear them now. */
827 if (sensitive_data.nkeys != 0) {
828 for (i = 0; i < sensitive_data.nkeys; i++) {
829 if (sensitive_data.keys[i] != NULL) {
830 /* Destroys contents safely */
831 debug3("clear hostkey %d", i);
832 key_free(sensitive_data.keys[i]);
833 sensitive_data.keys[i] = NULL;
834 }
835 }
836 xfree(sensitive_data.keys);
837 }
838 for (i = 0; i < options.num_identity_files; i++) {
839 if (options.identity_files[i]) {
840 xfree(options.identity_files[i]);
841 options.identity_files[i] = NULL;
842 }
843 if (options.identity_keys[i]) {
844 key_free(options.identity_keys[i]);
845 options.identity_keys[i] = NULL;
846 }
847 }
848
849 exit_status = compat20 ? ssh_session2() : ssh_session();
850 packet_close();
e54b3d7c 851
6f25cbdd 852 if (options.control_path != NULL && muxserver_sock != -1)
1b56ff3d 853 unlink(options.control_path);
854
e54b3d7c 855 /*
416fd2a8 856 * Send SIGHUP to proxy command if used. We don't wait() in
e54b3d7c 857 * case it hangs and instead rely on init to reap the child
858 */
859 if (proxy_command_pid > 1)
860 kill(proxy_command_pid, SIGHUP);
861
3c0ef626 862 return exit_status;
863}
864
6f25cbdd 865/* Callback for remote forward global requests */
866static void
867ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
868{
869 Forward *rfwd = (Forward *)ctxt;
870
16eb0a3b 871 /* XXX verbose() on failure? */
6f25cbdd 872 debug("remote forward %s for: listen %d, connect %s:%d",
873 type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
874 rfwd->listen_port, rfwd->connect_host, rfwd->connect_port);
16eb0a3b 875 if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) {
876 logit("Allocated port %u for remote forward to %s:%d",
877 packet_get_int(),
878 rfwd->connect_host, rfwd->connect_port);
879 }
880
6f25cbdd 881 if (type == SSH2_MSG_REQUEST_FAILURE) {
882 if (options.exit_on_forward_failure)
883 fatal("Error: remote port forwarding failed for "
884 "listen port %d", rfwd->listen_port);
885 else
886 logit("Warning: remote port forwarding failed for "
887 "listen port %d", rfwd->listen_port);
888 }
889 if (++remote_forward_confirms_received == options.num_remote_forwards) {
890 debug("All remote forwarding requests processed");
891 if (fork_after_authentication_flag) {
892 fork_after_authentication_flag = 0;
893 if (daemon(1, 1) < 0)
894 fatal("daemon() failed: %.200s",
895 strerror(errno));
896 }
897 }
898}
899
3c0ef626 900static void
901ssh_init_forwarding(void)
902{
903 int success = 0;
904 int i;
905
906 /* Initiate local TCP/IP port forwardings. */
907 for (i = 0; i < options.num_local_forwards; i++) {
34fee935 908 debug("Local connections to %.200s:%d forwarded to remote "
909 "address %.200s:%d",
910 (options.local_forwards[i].listen_host == NULL) ?
911 (options.gateway_ports ? "*" : "LOCALHOST") :
912 options.local_forwards[i].listen_host,
913 options.local_forwards[i].listen_port,
914 options.local_forwards[i].connect_host,
915 options.local_forwards[i].connect_port);
e9a17296 916 success += channel_setup_local_fwd_listener(
34fee935 917 options.local_forwards[i].listen_host,
918 options.local_forwards[i].listen_port,
919 options.local_forwards[i].connect_host,
920 options.local_forwards[i].connect_port,
6f25cbdd 921 options.gateway_ports);
3c0ef626 922 }
2e437378 923 if (i > 0 && success != i && options.exit_on_forward_failure)
924 fatal("Could not request local forwarding.");
3c0ef626 925 if (i > 0 && success == 0)
926 error("Could not request local forwarding.");
927
928 /* Initiate remote TCP/IP port forwardings. */
929 for (i = 0; i < options.num_remote_forwards; i++) {
34fee935 930 debug("Remote connections from %.200s:%d forwarded to "
931 "local address %.200s:%d",
932 (options.remote_forwards[i].listen_host == NULL) ?
e00da40d 933 "LOCALHOST" : options.remote_forwards[i].listen_host,
34fee935 934 options.remote_forwards[i].listen_port,
935 options.remote_forwards[i].connect_host,
936 options.remote_forwards[i].connect_port);
2e437378 937 if (channel_request_remote_forwarding(
34fee935 938 options.remote_forwards[i].listen_host,
939 options.remote_forwards[i].listen_port,
940 options.remote_forwards[i].connect_host,
2e437378 941 options.remote_forwards[i].connect_port) < 0) {
942 if (options.exit_on_forward_failure)
943 fatal("Could not request remote forwarding.");
944 else
945 logit("Warning: Could not request remote "
946 "forwarding.");
947 }
6f25cbdd 948 client_register_global_confirm(ssh_confirm_remote_forward,
949 &options.remote_forwards[i]);
3c0ef626 950 }
25d429a2 951
952 /* Initiate tunnel forwarding. */
953 if (options.tun_open != SSH_TUNMODE_NO) {
954 if (client_request_tun_fwd(options.tun_open,
955 options.tun_local, options.tun_remote) == -1) {
956 if (options.exit_on_forward_failure)
957 fatal("Could not request tunnel forwarding.");
958 else
959 error("Could not request tunnel forwarding.");
960 }
961 }
3c0ef626 962}
963
964static void
965check_agent_present(void)
966{
967 if (options.forward_agent) {
e00da40d 968 /* Clear agent forwarding if we don't have an agent. */
e54b3d7c 969 if (!ssh_agent_present())
3c0ef626 970 options.forward_agent = 0;
3c0ef626 971 }
972}
973
974static int
975ssh_session(void)
976{
977 int type;
3c0ef626 978 int interactive = 0;
979 int have_tty = 0;
980 struct winsize ws;
981 char *cp;
34fee935 982 const char *display;
3c0ef626 983
984 /* Enable compression if requested. */
985 if (options.compression) {
6f25cbdd 986 debug("Requesting compression at level %d.",
987 options.compression_level);
3c0ef626 988
6f25cbdd 989 if (options.compression_level < 1 ||
990 options.compression_level > 9)
991 fatal("Compression level must be from 1 (fast) to "
992 "9 (slow, best).");
3c0ef626 993
994 /* Send the request. */
995 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
996 packet_put_int(options.compression_level);
997 packet_send();
998 packet_write_wait();
e9a17296 999 type = packet_read();
3c0ef626 1000 if (type == SSH_SMSG_SUCCESS)
1001 packet_start_compression(options.compression_level);
1002 else if (type == SSH_SMSG_FAILURE)
70791e56 1003 logit("Warning: Remote host refused compression.");
3c0ef626 1004 else
6f25cbdd 1005 packet_disconnect("Protocol error waiting for "
1006 "compression response.");
3c0ef626 1007 }
1008 /* Allocate a pseudo tty if appropriate. */
1009 if (tty_flag) {
1010 debug("Requesting pty.");
1011
1012 /* Start the packet. */
1013 packet_start(SSH_CMSG_REQUEST_PTY);
1014
1015 /* Store TERM in the packet. There is no limit on the
1016 length of the string. */
1017 cp = getenv("TERM");
1018 if (!cp)
1019 cp = "";
1020 packet_put_cstring(cp);
1021
1022 /* Store window size in the packet. */
1023 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1024 memset(&ws, 0, sizeof(ws));
2e437378 1025 packet_put_int((u_int)ws.ws_row);
1026 packet_put_int((u_int)ws.ws_col);
1027 packet_put_int((u_int)ws.ws_xpixel);
1028 packet_put_int((u_int)ws.ws_ypixel);
3c0ef626 1029
1030 /* Store tty modes in the packet. */
1031 tty_make_modes(fileno(stdin), NULL);
1032
1033 /* Send the packet, and wait for it to leave. */
1034 packet_send();
1035 packet_write_wait();
1036
1037 /* Read response from the server. */
e9a17296 1038 type = packet_read();
3c0ef626 1039 if (type == SSH_SMSG_SUCCESS) {
1040 interactive = 1;
1041 have_tty = 1;
1042 } else if (type == SSH_SMSG_FAILURE)
6f25cbdd 1043 logit("Warning: Remote host failed or refused to "
1044 "allocate a pseudo tty.");
3c0ef626 1045 else
6f25cbdd 1046 packet_disconnect("Protocol error waiting for pty "
1047 "request response.");
3c0ef626 1048 }
1049 /* Request X11 forwarding if enabled and DISPLAY is set. */
34fee935 1050 display = getenv("DISPLAY");
1051 if (options.forward_x11 && display != NULL) {
e9a17296 1052 char *proto, *data;
3c0ef626 1053 /* Get reasonable local authentication information. */
34fee935 1054 client_x11_get_proto(display, options.xauth_location,
1055 options.forward_x11_trusted, &proto, &data);
3c0ef626 1056 /* Request forwarding with authentication spoofing. */
6f25cbdd 1057 debug("Requesting X11 forwarding with authentication "
1058 "spoofing.");
34fee935 1059 x11_request_forwarding_with_spoofing(0, display, proto, data);
3c0ef626 1060
1061 /* Read response from the server. */
e9a17296 1062 type = packet_read();
3c0ef626 1063 if (type == SSH_SMSG_SUCCESS) {
1064 interactive = 1;
1065 } else if (type == SSH_SMSG_FAILURE) {
70791e56 1066 logit("Warning: Remote host denied X11 forwarding.");
3c0ef626 1067 } else {
6f25cbdd 1068 packet_disconnect("Protocol error waiting for X11 "
1069 "forwarding");
3c0ef626 1070 }
1071 }
1072 /* Tell the packet module whether this is an interactive session. */
1073 packet_set_interactive(interactive);
1074
1075 /* Request authentication agent forwarding if appropriate. */
1076 check_agent_present();
1077
1078 if (options.forward_agent) {
1079 debug("Requesting authentication agent forwarding.");
1080 auth_request_forwarding();
1081
1082 /* Read response from the server. */
e9a17296 1083 type = packet_read();
1084 packet_check_eom();
3c0ef626 1085 if (type != SSH_SMSG_SUCCESS)
70791e56 1086 logit("Warning: Remote host denied authentication agent forwarding.");
3c0ef626 1087 }
1088
1089 /* Initiate port forwardings. */
1090 ssh_init_forwarding();
1091
bd5d5d2a 1092 /* Execute a local command */
1093 if (options.local_command != NULL &&
1094 options.permit_local_command)
1095 ssh_local_cmd(options.local_command);
1096
6f25cbdd 1097 /*
1098 * If requested and we are not interested in replies to remote
1099 * forwarding requests, then let ssh continue in the background.
1100 */
1101 if (fork_after_authentication_flag &&
1102 (!options.exit_on_forward_failure ||
1103 options.num_remote_forwards == 0)) {
1104 fork_after_authentication_flag = 0;
3c0ef626 1105 if (daemon(1, 1) < 0)
1106 fatal("daemon() failed: %.200s", strerror(errno));
6f25cbdd 1107 }
3c0ef626 1108
1109 /*
1110 * If a command was specified on the command line, execute the
1111 * command now. Otherwise request the server to start a shell.
1112 */
1113 if (buffer_len(&command) > 0) {
1114 int len = buffer_len(&command);
1115 if (len > 900)
1116 len = 900;
6f25cbdd 1117 debug("Sending command: %.*s", len,
1118 (u_char *)buffer_ptr(&command));
3c0ef626 1119 packet_start(SSH_CMSG_EXEC_CMD);
1120 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1121 packet_send();
1122 packet_write_wait();
1123 } else {
1124 debug("Requesting shell.");
1125 packet_start(SSH_CMSG_EXEC_SHELL);
1126 packet_send();
1127 packet_write_wait();
1128 }
1129
1130 /* Enter the interactive session. */
1131 return client_loop(have_tty, tty_flag ?
1132 options.escape_char : SSH_ESCAPECHAR_NONE, 0);
1133}
1134
1b56ff3d 1135/* request pty/x11/agent/tcpfwd/shell for channel */
1136static void
1137ssh_session2_setup(int id, void *arg)
1138{
1139 extern char **environ;
34fee935 1140 const char *display;
1b56ff3d 1141 int interactive = tty_flag;
34fee935 1142
1143 display = getenv("DISPLAY");
1144 if (options.forward_x11 && display != NULL) {
e9a17296 1145 char *proto, *data;
3c0ef626 1146 /* Get reasonable local authentication information. */
34fee935 1147 client_x11_get_proto(display, options.xauth_location,
1148 options.forward_x11_trusted, &proto, &data);
3c0ef626 1149 /* Request forwarding with authentication spoofing. */
6f25cbdd 1150 debug("Requesting X11 forwarding with authentication "
1151 "spoofing.");
34fee935 1152 x11_request_forwarding_with_spoofing(id, display, proto, data);
3c0ef626 1153 interactive = 1;
1154 /* XXX wait for reply */
1155 }
1156
1157 check_agent_present();
1158 if (options.forward_agent) {
1159 debug("Requesting authentication agent forwarding.");
1160 channel_request_start(id, "auth-agent-req@openssh.com", 0);
1161 packet_send();
1162 }
1163
1b56ff3d 1164 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
6f25cbdd 1165 NULL, fileno(stdin), &command, environ);
3c0ef626 1166
3c0ef626 1167 packet_set_interactive(interactive);
1168}
1169
1170/* open new channel for a session */
1171static int
1172ssh_session2_open(void)
1173{
1174 Channel *c;
1175 int window, packetmax, in, out, err;
2e437378 1176 int sock;
1177 int socksize;
1178 int socksizelen = sizeof(int);
3c0ef626 1179
1180 if (stdin_null_flag) {
1181 in = open(_PATH_DEVNULL, O_RDONLY);
1182 } else {
1183 in = dup(STDIN_FILENO);
1184 }
1185 out = dup(STDOUT_FILENO);
1186 err = dup(STDERR_FILENO);
1187
1188 if (in < 0 || out < 0 || err < 0)
1189 fatal("dup() in/out/err failed");
1190
1191 /* enable nonblocking unless tty */
1192 if (!isatty(in))
1193 set_nonblock(in);
1194 if (!isatty(out))
1195 set_nonblock(out);
1196 if (!isatty(err))
1197 set_nonblock(err);
1198
2e437378 1199 /* we need to check to see if what they want to do about buffer */
1200 /* sizes here. In a hpn to nonhpn connection we want to limit */
1201 /* the window size to something reasonable in case the far side */
1202 /* has the large window bug. In hpn to hpn connection we want to */
1203 /* use the max window size but allow the user to override it */
1204 /* lastly if they disabled hpn then use the ssh std window size */
1205
1206 /* so why don't we just do a getsockopt() here and set the */
1207 /* ssh window to that? In the case of a autotuning receive */
1208 /* window the window would get stuck at the initial buffer */
1209 /* size generally less than 96k. Therefore we need to set the */
1210 /* maximum ssh window size to the maximum hpn buffer size */
bd5d5d2a 1211 /* unless the user has specifically set the tcprcvbufpoll */
2e437378 1212 /* to no. In which case we *can* just set the window to the */
1213 /* minimum of the hpn buffer size and tcp receive buffer size */
1214
6f25cbdd 1215 if (tty_flag)
2e437378 1216 options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
6f25cbdd 1217 else
1218 options.hpn_buffer_size = 2*1024*1024;
1219
1220 if (datafellows & SSH_BUG_LARGEWINDOW)
2e437378 1221 {
1222 debug("HPN to Non-HPN Connection");
2e437378 1223 }
1224 else
1225 {
2e437378 1226 if (options.tcp_rcv_buf_poll <= 0)
1227 {
6f25cbdd 1228 sock = socket(AF_INET, SOCK_STREAM, 0);
1229 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
1230 &socksize, &socksizelen);
1231 close(sock);
1232 debug("socksize %d", socksize);
1233 options.hpn_buffer_size = socksize;
1234 debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
2e437378 1235 }
1236 else
1237 {
1238 if (options.tcp_rcv_buf > 0)
6f25cbdd 1239 {
1240 /*create a socket but don't connect it */
1241 /* we use that the get the rcv socket size */
1242 sock = socket(AF_INET, SOCK_STREAM, 0);
1243 /* if they are using the tcp_rcv_buf option */
1244 /* attempt to set the buffer size to that */
1245 if (options.tcp_rcv_buf)
1246 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf,
1247 sizeof(options.tcp_rcv_buf));
1248 getsockopt(sock, SOL_SOCKET, SO_RCVBUF,
1249 &socksize, &socksizelen);
1250 close(sock);
1251 debug("socksize %d", socksize);
1252 options.hpn_buffer_size = socksize;
1253 debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
1254 }
2e437378 1255 }
1256
1257 }
1258
1259 debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
1260
1261 window = options.hpn_buffer_size;
1262
6f25cbdd 1263 channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
1264
3c0ef626 1265 packetmax = CHAN_SES_PACKET_DEFAULT;
e9a17296 1266 if (tty_flag) {
34fee935 1267 window = 4*CHAN_SES_PACKET_DEFAULT;
e9a17296 1268 window >>= 1;
1269 packetmax >>= 1;
3c0ef626 1270 }
1271 c = channel_new(
1272 "session", SSH_CHANNEL_OPENING, in, out, err,
1273 window, packetmax, CHAN_EXTENDED_WRITE,
70791e56 1274 "client-session", /*nonblock*/0);
e00da40d 1275 if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
34fee935 1276 c->dynamic_window = 1;
e00da40d 1277 debug ("Enabled Dynamic Window Scaling\n");
34fee935 1278 }
3c0ef626 1279 debug3("ssh_session2_open: channel_new: %d", c->self);
1280
1281 channel_send_open(c->self);
1282 if (!no_shell_flag)
6f25cbdd 1283 channel_register_open_confirm(c->self,
1284 ssh_session2_setup, NULL);
3c0ef626 1285
1286 return c->self;
1287}
1288
1289static int
1290ssh_session2(void)
1291{
1292 int id = -1;
1293
1294 /* XXX should be pre-session */
1295 ssh_init_forwarding();
1296
1297 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1298 id = ssh_session2_open();
1299
6f25cbdd 1300 /* If we don't expect to open a new session, then disallow it */
16eb0a3b 1301 if (options.control_master == SSHCTL_MASTER_NO &&
1302 (datafellows & SSH_NEW_OPENSSH)) {
6f25cbdd 1303 debug("Requesting no-more-sessions@openssh.com");
1304 packet_start(SSH2_MSG_GLOBAL_REQUEST);
1305 packet_put_cstring("no-more-sessions@openssh.com");
1306 packet_put_char(0);
1307 packet_send();
1308 }
1309
e00da40d 1310 /* Execute a local command */
1311 if (options.local_command != NULL &&
1312 options.permit_local_command)
1313 ssh_local_cmd(options.local_command);
1314
25d429a2 1315 /* Start listening for multiplex clients */
6f25cbdd 1316 muxserver_listen();
25d429a2 1317
3c0ef626 1318 /* If requested, let ssh continue in the background. */
6f25cbdd 1319 if (fork_after_authentication_flag) {
1320 fork_after_authentication_flag = 0;
3c0ef626 1321 if (daemon(1, 1) < 0)
1322 fatal("daemon() failed: %.200s", strerror(errno));
6f25cbdd 1323 }
3c0ef626 1324
1325 return client_loop(tty_flag, tty_flag ?
1326 options.escape_char : SSH_ESCAPECHAR_NONE, id);
1327}
1328
1329static void
1330load_public_identity_files(void)
1331{
2e437378 1332 char *filename, *cp, thishost[NI_MAXHOST];
bd5d5d2a 1333 char *pwdir = NULL, *pwname = NULL;
3c0ef626 1334 int i = 0;
2980ea68 1335 Key *public;
2e437378 1336 struct passwd *pw;
3c0ef626 1337#ifdef SMARTCARD
2980ea68 1338 Key **keys;
1339
3c0ef626 1340 if (options.smartcard_device != NULL &&
2980ea68 1341 options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
2e437378 1342 (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
2980ea68 1343 int count = 0;
1344 for (i = 0; keys[i] != NULL; i++) {
1345 count++;
6f25cbdd 1346 memmove(&options.identity_files[1],
1347 &options.identity_files[0],
2980ea68 1348 sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
6f25cbdd 1349 memmove(&options.identity_keys[1],
1350 &options.identity_keys[0],
2980ea68 1351 sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
1352 options.num_identity_files++;
1353 options.identity_keys[0] = keys[i];
70791e56 1354 options.identity_files[0] = sc_get_key_label(keys[i]);
2980ea68 1355 }
1356 if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
1357 options.num_identity_files = SSH_MAX_IDENTITY_FILES;
1358 i = count;
1359 xfree(keys);
3c0ef626 1360 }
1361#endif /* SMARTCARD */
2e437378 1362 if ((pw = getpwuid(original_real_uid)) == NULL)
1363 fatal("load_public_identity_files: getpwuid failed");
bd5d5d2a 1364 pwname = xstrdup(pw->pw_name);
1365 pwdir = xstrdup(pw->pw_dir);
2e437378 1366 if (gethostname(thishost, sizeof(thishost)) == -1)
1367 fatal("load_public_identity_files: gethostname: %s",
1368 strerror(errno));
3c0ef626 1369 for (; i < options.num_identity_files; i++) {
2e437378 1370 cp = tilde_expand_filename(options.identity_files[i],
3c0ef626 1371 original_real_uid);
bd5d5d2a 1372 filename = percent_expand(cp, "d", pwdir,
1373 "u", pwname, "l", thishost, "h", host,
2e437378 1374 "r", options.user, (char *)NULL);
1375 xfree(cp);
3c0ef626 1376 public = key_load_public(filename, NULL);
1377 debug("identity file %s type %d", filename,
1378 public ? public->type : -1);
1379 xfree(options.identity_files[i]);
1380 options.identity_files[i] = filename;
1381 options.identity_keys[i] = public;
1382 }
bd5d5d2a 1383 bzero(pwname, strlen(pwname));
1384 xfree(pwname);
1385 bzero(pwdir, strlen(pwdir));
1386 xfree(pwdir);
3c0ef626 1387}
This page took 0.323671 seconds and 5 git commands to generate.