5 Author: Tatu Ylonen <ylo@cs.hut.fi>
7 Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
10 Created: Sat Mar 18 16:36:11 1995 ylo
12 Ssh client program. This program can be used to log into a remote machine.
13 The software supports strong authentication, encryption, and forwarding
14 of X11, TCP/IP, and authentication connections.
16 Modified to work with SSL by Niels Provos <provos@citi.umich.edu> in Canada.
31 /* Flag indicating whether debug mode is on. This can be set on the
35 /* Flag indicating whether quiet mode is on. */
38 /* Flag indicating whether to allocate a pseudo tty. This can be set on the
39 command line, and is automatically set if no command is given on the command
43 /* Flag indicating that nothing should be read from stdin. This can be set
44 on the command line. */
45 int stdin_null_flag = 0;
47 /* Flag indicating that ssh should fork after authentication. This is useful
48 so that the pasphrase can be entered manually, and then ssh goes to the
50 int fork_after_authentication_flag = 0;
52 /* General data structure for command line options and options configurable
53 in configuration files. See readconf.h. */
56 /* Name of the host we are connecting to. This is the name given on the
57 command line, or the HostName specified for the user-supplied name
58 in a configuration file. */
61 /* socket address the host resolves to */
62 struct sockaddr_in hostaddr;
64 /* Flag to indicate that we have received a window change signal which has
65 not yet been processed. This will cause a message indicating the new
66 window size to be sent to the server a little later. This is volatile
67 because this is updated in a signal handler. */
68 volatile int received_window_change_signal = 0;
70 /* Value of argv[0] (set in the main program). */
73 /* Flag indicating whether we have a valid host private key loaded. */
74 int host_private_key_loaded = 0;
76 /* Host private key. */
77 RSA *host_private_key = NULL;
79 /* Original real UID. */
80 uid_t original_real_uid;
82 /* Prints a help message to the user. This function never returns. */
87 fprintf(stderr, "Usage: %s [options] host [command]\n", av0);
88 fprintf(stderr, "Options:\n");
89 fprintf(stderr, " -l user Log in using this user name.\n");
90 fprintf(stderr, " -n Redirect input from /dev/null.\n");
91 fprintf(stderr, " -a Disable authentication agent forwarding.\n");
93 fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n");
95 fprintf(stderr, " -x Disable X11 connection forwarding.\n");
96 fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n");
97 fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n");
98 fprintf(stderr, " -v Verbose; display verbose debugging messages.\n");
99 fprintf(stderr, " -V Display version number only.\n");
100 fprintf(stderr, " -P Don't allocate a privileged port.\n");
101 fprintf(stderr, " -q Quiet; don't display any warning messages.\n");
102 fprintf(stderr, " -f Fork into background after authentication.\n");
103 fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n");
105 fprintf(stderr, " -c cipher Select encryption algorithm: "
108 fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n");
109 fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n");
110 fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n");
111 fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0);
112 fprintf(stderr, " forward them to the other side by connecting to host:port.\n");
113 fprintf(stderr, " -C Enable compression.\n");
114 fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n");
115 fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n");
119 /* Connects to the given host using rsh (or prints an error message and exits
120 if rsh is not available). This function never returns. */
123 rsh_connect(char *host, char *user, Buffer *command)
128 log("Using rsh. WARNING: Connection will not be encrypted.");
129 /* Build argument list for rsh. */
131 args[i++] = _PATH_RSH;
132 args[i++] = host; /* may have to come after user on some systems */
138 if (buffer_len(command) > 0)
140 buffer_append(command, "\0", 1);
141 args[i++] = buffer_ptr(command);
146 for (i = 0; args[i]; i++)
149 fprintf(stderr, " ");
150 fprintf(stderr, "%s", args[i]);
152 fprintf(stderr, "\n");
154 execv(_PATH_RSH, args);
159 /* Main program for the ssh client. */
162 main(int ac, char **av)
164 int i, opt, optind, type, exit_status, ok, fwd_port, fwd_host_port, authfd;
165 char *optarg, *cp, buf[256];
169 struct passwd *pw, pwcopy;
170 int interactive = 0, dummy;
171 uid_t original_effective_uid;
174 /* Save the original real uid. It will be needed later (uid-swapping may
175 clobber the real uid). */
176 original_real_uid = getuid();
177 original_effective_uid = geteuid();
179 /* If we are installed setuid root be careful to not drop core. */
180 if (original_real_uid != original_effective_uid)
183 rlim.rlim_cur = rlim.rlim_max = 0;
184 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
185 fatal("setrlimit failed: %.100s", strerror(errno));
188 /* Use uid-swapping to give up root privileges for the duration of option
189 processing. We will re-instantiate the rights when we are ready to
190 create the privileged port, and will permanently drop them when the
191 port has been created (actually, when the connection has been made, as
192 we may need to create the port several times). */
193 temporarily_use_uid(original_real_uid);
195 /* Set our umask to something reasonable, as some files are created with
196 the default umask. This will make them world-readable but writable
197 only by the owner, which is ok for all files for which we don't set
198 the modes explicitly. */
201 /* Save our own name. */
204 /* Initialize option structure to indicate that no values have been set. */
205 initialize_options(&options);
207 /* Parse command-line arguments. */
210 /* If program name is not one of the standard names, use it as host name. */
211 if (strchr(av0, '/'))
212 cp = strrchr(av0, '/') + 1;
215 if (strcmp(cp, "rsh") != 0 && strcmp(cp, "ssh") != 0 &&
216 strcmp(cp, "rlogin") != 0 && strcmp(cp, "slogin") != 0)
219 for (optind = 1; optind < ac; optind++)
221 if (av[optind][0] != '-')
225 if ((cp = strchr(av[optind], '@'))) {
226 options.user = av[optind];
237 if (strchr("eilcpLRo", opt)) /* options with arguments */
239 optarg = av[optind] + 2;
240 if (strcmp(optarg, "") == 0)
242 if (optind >= ac - 1)
244 optarg = av[++optind];
260 fork_after_authentication_flag = 1;
265 options.forward_x11 = 0;
269 options.forward_x11 = 1;
273 options.gateway_ports = 1;
277 options.use_privileged_port = 0;
281 options.forward_agent = 0;
285 options.kerberos_tgt_passing = 0;
286 options.afs_token_passing = 0;
290 if (stat(optarg, &st) < 0)
292 fprintf(stderr, "Warning: Identity file %s does not exist.\n",
296 if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES)
297 fatal("Too many identity files specified (max %d)",
298 SSH_MAX_IDENTITY_FILES);
299 options.identity_files[options.num_identity_files++] =
310 fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
311 SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
312 fprintf(stderr, "Compiled with SSL.\n");
322 if (optarg[0] == '^' && optarg[2] == 0 &&
323 (unsigned char)optarg[1] >= 64 && (unsigned char)optarg[1] < 128)
324 options.escape_char = (unsigned char)optarg[1] & 31;
326 if (strlen(optarg) == 1)
327 options.escape_char = (unsigned char)optarg[0];
329 if (strcmp(optarg, "none") == 0)
330 options.escape_char = -2;
333 fprintf(stderr, "Bad escape character '%s'.\n", optarg);
339 options.cipher = cipher_number(optarg);
340 if (options.cipher == -1)
342 fprintf(stderr, "Unknown cipher type '%s'\n", optarg);
348 options.port = atoi(optarg);
349 if (options.port < 1 || options.port > 65535)
351 fprintf(stderr, "Bad port %s.\n", optarg);
357 options.user = optarg;
361 if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf,
362 &fwd_host_port) != 3)
364 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
368 add_remote_forward(&options, fwd_port, buf, fwd_host_port);
372 if (sscanf(optarg, "%d:%255[^:]:%d", &fwd_port, buf,
373 &fwd_host_port) != 3)
375 fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg);
379 add_local_forward(&options, fwd_port, buf, fwd_host_port);
383 options.compression = 1;
388 process_config_line(&options, host ? host : "", optarg,
389 "command-line", 0, &dummy);
397 /* Check that we got a host name. */
401 /* check if RSA support exists */
402 if (rsa_alive() == 0) {
403 extern char *__progname;
406 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
411 /* Initialize the command to execute on remote host. */
412 buffer_init(&command);
414 /* Save the command to execute on the remote host in a buffer. There is
415 no limit on the length of the command, except by the maximum packet
416 size. Also sets the tty flag if there is no command. */
419 /* No command specified - execute shell on a tty. */
424 /* A command has been specified. Store it into the buffer. */
425 for (i = optind; i < ac; i++)
428 buffer_append(&command, " ", 1);
429 buffer_append(&command, av[i], strlen(av[i]));
433 /* Cannot fork to background if no command. */
434 if (fork_after_authentication_flag && buffer_len(&command) == 0)
435 fatal("Cannot fork into background without a command to execute.");
437 /* Allocate a tty by default if no command specified. */
438 if (buffer_len(&command) == 0)
441 /* Do not allocate a tty if stdin is not a tty. */
442 if (!isatty(fileno(stdin)))
445 fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
450 pw = getpwuid(original_real_uid);
453 fprintf(stderr, "You don't exist, go away!\n");
457 /* Take a copy of the returned structure. */
458 memset(&pwcopy, 0, sizeof(pwcopy));
459 pwcopy.pw_name = xstrdup(pw->pw_name);
460 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
461 pwcopy.pw_uid = pw->pw_uid;
462 pwcopy.pw_gid = pw->pw_gid;
463 pwcopy.pw_dir = xstrdup(pw->pw_dir);
464 pwcopy.pw_shell = xstrdup(pw->pw_shell);
467 /* Initialize "log" output. Since we are the client all output actually
468 goes to the terminal. */
469 log_init(av[0], 1, debug_flag, quiet_flag, SYSLOG_FACILITY_USER);
471 /* Read per-user configuration file. */
472 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_CONFFILE);
473 read_config_file(buf, host, &options);
475 /* Read systemwide configuration file. */
476 read_config_file(HOST_CONFIG_FILE, host, &options);
478 /* Fill configuration defaults. */
479 fill_default_options(&options);
480 if (options.user == NULL)
481 options.user = xstrdup(pw->pw_name);
483 if (options.hostname != NULL)
484 host = options.hostname;
486 /* Find canonic host name. */
487 if (strchr(host, '.') == 0)
489 struct hostent *hp = gethostbyname(host);
492 if (strchr(hp->h_name, '.') != 0)
493 host = xstrdup(hp->h_name);
494 else if (hp->h_aliases != 0
495 && hp->h_aliases[0] != 0
496 && strchr(hp->h_aliases[0], '.') != 0)
497 host = xstrdup(hp->h_aliases[0]);
501 /* Disable rhosts authentication if not running as root. */
502 if (original_effective_uid != 0 || !options.use_privileged_port)
504 options.rhosts_authentication = 0;
505 options.rhosts_rsa_authentication = 0;
508 /* If using rsh has been selected, exec it now (without trying anything
509 else). Note that we must release privileges first. */
512 /* Restore our superuser privileges. This must be done before
513 permanently setting the uid. */
516 /* Switch to the original uid permanently. */
517 permanently_set_uid(original_real_uid);
520 rsh_connect(host, options.user, &command);
521 fatal("rsh_connect returned");
524 /* Restore our superuser privileges. */
527 /* Open a connection to the remote host. This needs root privileges if
528 rhosts_{rsa_}authentication is enabled. */
530 ok = ssh_connect(host, &hostaddr, options.port, options.connection_attempts,
531 !options.rhosts_authentication &&
532 !options.rhosts_rsa_authentication,
533 original_real_uid, options.proxy_command);
535 /* If we successfully made the connection, load the host private key in
536 case we will need it later for combined rsa-rhosts authentication.
537 This must be done before releasing extra privileges, because the file
538 is only readable by root. */
541 host_private_key = RSA_new();
542 if (load_private_key(HOST_KEY_FILE, "", host_private_key, NULL))
543 host_private_key_loaded = 1;
546 /* Get rid of any extra privileges that we may have. We will no longer need
547 them. Also, extra privileges could make it very hard to read identity
548 files and other non-world-readable files from the user's home directory
549 if it happens to be on a NFS volume where root is mapped to nobody. */
550 permanently_set_uid(original_real_uid);
552 /* Now that we are back to our own permissions, create ~/.ssh directory
553 if it doesn\'t already exist. */
554 snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, SSH_USER_DIR);
555 if (stat(buf, &st) < 0)
556 if (mkdir(buf, 0755) < 0)
557 error("Could not create directory '%.200s'.", buf);
559 /* Check if the connection failed, and try "rsh" if appropriate. */
562 if (options.port != 0)
563 log("Secure connection to %.100s on port %d refused%.100s.",
565 options.fallback_to_rsh ? "; reverting to insecure method" : "");
567 log("Secure connection to %.100s refused%.100s.", host,
568 options.fallback_to_rsh ? "; reverting to insecure method" : "");
570 if (options.fallback_to_rsh)
572 rsh_connect(host, options.user, &command);
573 fatal("rsh_connect returned");
578 /* Expand ~ in options.identity_files. */
579 for (i = 0; i < options.num_identity_files; i++)
580 options.identity_files[i] =
581 tilde_expand_filename(options.identity_files[i], original_real_uid);
583 /* Expand ~ in known host file names. */
584 options.system_hostfile = tilde_expand_filename(options.system_hostfile,
586 options.user_hostfile = tilde_expand_filename(options.user_hostfile,
589 /* Log into the remote system. This never returns if the login fails. */
590 ssh_login(host_private_key_loaded, host_private_key,
591 host, &hostaddr, &options, original_real_uid);
593 /* We no longer need the host private key. Clear it now. */
594 if (host_private_key_loaded)
595 RSA_free(host_private_key); /* Destroys contents safely */
597 /* Close connection cleanly after attack. */
598 cipher_attack_detected = packet_disconnect;
600 /* If requested, fork and let ssh continue in the background. */
601 if (fork_after_authentication_flag)
605 fatal("fork failed: %.100s", strerror(errno));
611 /* Enable compression if requested. */
612 if (options.compression)
614 debug("Requesting compression at level %d.", options.compression_level);
616 if (options.compression_level < 1 || options.compression_level > 9)
617 fatal("Compression level must be from 1 (fast) to 9 (slow, best).");
619 /* Send the request. */
620 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
621 packet_put_int(options.compression_level);
624 type = packet_read(&plen);
625 if (type == SSH_SMSG_SUCCESS)
626 packet_start_compression(options.compression_level);
627 else if (type == SSH_SMSG_FAILURE)
628 log("Warning: Remote host refused compression.");
630 packet_disconnect("Protocol error waiting for compression response.");
633 /* Allocate a pseudo tty if appropriate. */
636 debug("Requesting pty.");
638 /* Start the packet. */
639 packet_start(SSH_CMSG_REQUEST_PTY);
641 /* Store TERM in the packet. There is no limit on the length of the
646 packet_put_string(cp, strlen(cp));
648 /* Store window size in the packet. */
649 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
650 memset(&ws, 0, sizeof(ws));
651 packet_put_int(ws.ws_row);
652 packet_put_int(ws.ws_col);
653 packet_put_int(ws.ws_xpixel);
654 packet_put_int(ws.ws_ypixel);
656 /* Store tty modes in the packet. */
657 tty_make_modes(fileno(stdin));
659 /* Send the packet, and wait for it to leave. */
663 /* Read response from the server. */
664 type = packet_read(&plen);
665 if (type == SSH_SMSG_SUCCESS)
667 else if (type == SSH_SMSG_FAILURE)
668 log("Warning: Remote host failed or refused to allocate a pseudo tty.");
670 packet_disconnect("Protocol error waiting for pty request response.");
673 /* Request X11 forwarding if enabled and DISPLAY is set. */
674 if (options.forward_x11 && getenv("DISPLAY") != NULL)
676 char line[512], proto[512], data[512];
678 int forwarded = 0, got_data = 0, i;
681 /* Try to get Xauthority information for the display. */
682 snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null",
683 XAUTH_PATH, getenv("DISPLAY"));
684 f = popen(line, "r");
685 if (f && fgets(line, sizeof(line), f) &&
686 sscanf(line, "%*s %s %s", proto, data) == 2)
690 #endif /* XAUTH_PATH */
691 /* If we didn't get authentication data, just make up some data. The
692 forwarding code will check the validity of the response anyway, and
693 substitute this data. The X11 server, however, will ignore this
694 fake data and use whatever authentication mechanisms it was using
695 otherwise for the local connection. */
700 strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
701 for (i = 0; i < 16; i++) {
704 snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
709 /* Got local authentication reasonable information. Request forwarding
710 with authentication spoofing. */
711 debug("Requesting X11 forwarding with authentication spoofing.");
712 x11_request_forwarding_with_spoofing(proto, data);
714 /* Read response from the server. */
715 type = packet_read(&plen);
716 if (type == SSH_SMSG_SUCCESS)
721 else if (type == SSH_SMSG_FAILURE)
722 log("Warning: Remote host denied X11 forwarding.");
724 packet_disconnect("Protocol error waiting for X11 forwarding");
727 /* Tell the packet module whether this is an interactive session. */
728 packet_set_interactive(interactive, options.keepalives);
730 /* Clear agent forwarding if we don\'t have an agent. */
731 authfd = ssh_get_authentication_socket();
733 options.forward_agent = 0;
735 ssh_close_authentication_socket(authfd);
737 /* Request authentication agent forwarding if appropriate. */
738 if (options.forward_agent)
740 debug("Requesting authentication agent forwarding.");
741 auth_request_forwarding();
743 /* Read response from the server. */
744 type = packet_read(&plen);
745 packet_integrity_check(plen, 0, type);
746 if (type != SSH_SMSG_SUCCESS)
747 log("Warning: Remote host denied authentication agent forwarding.");
750 /* Initiate local TCP/IP port forwardings. */
751 for (i = 0; i < options.num_local_forwards; i++)
753 debug("Connections to local port %d forwarded to remote address %.200s:%d",
754 options.local_forwards[i].port, options.local_forwards[i].host,
755 options.local_forwards[i].host_port);
756 channel_request_local_forwarding(options.local_forwards[i].port,
757 options.local_forwards[i].host,
758 options.local_forwards[i].host_port);
761 /* Initiate remote TCP/IP port forwardings. */
762 for (i = 0; i < options.num_remote_forwards; i++)
764 debug("Connections to remote port %d forwarded to local address %.200s:%d",
765 options.remote_forwards[i].port, options.remote_forwards[i].host,
766 options.remote_forwards[i].host_port);
767 channel_request_remote_forwarding(options.remote_forwards[i].port,
768 options.remote_forwards[i].host,
769 options.remote_forwards[i].host_port);
772 /* If a command was specified on the command line, execute the command now.
773 Otherwise request the server to start a shell. */
774 if (buffer_len(&command) > 0)
776 int len = buffer_len(&command);
779 debug("Sending command: %.*s", len, buffer_ptr(&command));
780 packet_start(SSH_CMSG_EXEC_CMD);
781 packet_put_string(buffer_ptr(&command), buffer_len(&command));
787 debug("Requesting shell.");
788 packet_start(SSH_CMSG_EXEC_SHELL);
793 /* Enter the interactive session. */
794 exit_status = client_loop(tty_flag, tty_flag ? options.escape_char : -1);
796 /* Close the connection to the remote host. */
799 /* Exit with the status returned by the program on the remote side. */