*/
#include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.95 2001/02/11 12:59:25 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.105 2001/03/26 08:07:09 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
*/
volatile int received_window_change_signal = 0;
-/* Flag indicating whether we have a valid host private key loaded. */
-int host_private_key_loaded = 0;
-
/* Host private key. */
-RSA *host_private_key = NULL;
+Key *host_private_key = NULL;
/* Original real UID. */
uid_t original_real_uid;
#endif /* AFS */
fprintf(stderr, " -X Enable X11 connection forwarding.\n");
fprintf(stderr, " -x Disable X11 connection forwarding.\n");
- fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n");
+ fprintf(stderr, " -i file Identity for public key authentication "
+ "(default: ~/.ssh/identity)\n");
fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n");
fprintf(stderr, " -T Do not allocate a tty.\n");
fprintf(stderr, " -v Verbose; display verbose debugging messages.\n");
fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n");
fprintf(stderr, " -c cipher Select encryption algorithm: "
- "``3des'', "
- "``blowfish''\n");
+ "``3des'', ``blowfish''\n");
+ fprintf(stderr, " -m macs Specify MAC algorithms for protocol version 2.\n");
fprintf(stderr, " -p port Connect to this port. Server must be on the same port.\n");
fprintf(stderr, " -L listen-port:host:port Forward local port to remote address\n");
fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n");
int ssh_session(void);
int ssh_session2(void);
-int guess_identity_file_type(const char *filename);
+void load_public_identity_files(void);
/*
* Main program for the ssh client.
u_short fwd_port, fwd_host_port;
char *optarg, *cp, buf[256];
struct stat st;
- struct passwd *pw, pwcopy;
+ struct passwd *pw;
int dummy;
uid_t original_effective_uid;
options.log_level++;
break;
} else {
- fatal("Too high debugging level.\n");
+ fatal("Too high debugging level.");
}
/* fallthrough */
case 'V':
- fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n",
+ fprintf(stderr,
+ "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n",
SSH_VERSION,
PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
- PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
- fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay());
+ PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2,
+ SSLeay());
if (opt == 'V')
exit(0);
break;
/* Do not allocate a tty if stdin is not a tty. */
if (!isatty(fileno(stdin)) && !force_tty_flag) {
if (tty_flag)
- log("Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
+ log("Pseudo-terminal will not be allocated because stdin is not a terminal.");
tty_flag = 0;
}
/* Get user data. */
pw = getpwuid(original_real_uid);
if (!pw) {
- log("You don't exist, go away!\n");
+ log("You don't exist, go away!");
exit(1);
}
/* Take a copy of the returned structure. */
- memset(&pwcopy, 0, sizeof(pwcopy));
- pwcopy.pw_name = xstrdup(pw->pw_name);
- pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
- pwcopy.pw_uid = pw->pw_uid;
- pwcopy.pw_gid = pw->pw_gid;
-#ifdef HAVE_PW_CLASS_IN_PASSWD
- pwcopy.pw_class = xstrdup(pw->pw_class);
-#endif
- pwcopy.pw_dir = xstrdup(pw->pw_dir);
- pwcopy.pw_shell = xstrdup(pw->pw_shell);
- pw = &pwcopy;
+ pw = pwcopy(pw);
- /* Initialize "log" output. Since we are the client all output
- actually goes to the terminal. */
- log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
+ /*
+ * Initialize "log" output. Since we are the client all output
+ * actually goes to stderr.
+ */
+ log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
/* Read per-user configuration file. */
snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE);
fill_default_options(&options);
/* reinit */
- log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
+ log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1);
+
+ seed_rng();
if (options.user == NULL)
options.user = xstrdup(pw->pw_name);
* privileges, because the file is only readable by root.
*/
if (ok && (options.protocol & SSH_PROTO_1)) {
- Key k;
- host_private_key = RSA_new();
- k.type = KEY_RSA1;
- k.rsa = host_private_key;
- if (load_private_key(_PATH_HOST_KEY_FILE, "", &k, NULL))
- host_private_key_loaded = 1;
+ host_private_key = key_load_private_type(KEY_RSA1,
+ _PATH_HOST_KEY_FILE, "", NULL);
}
/*
* Get rid of any extra privileges that we may have. We will no
}
exit(1);
}
- /* Expand ~ in options.identity_files, known host file names. */
- /* XXX mem-leaks */
- for (i = 0; i < options.num_identity_files; i++) {
- options.identity_files[i] =
- tilde_expand_filename(options.identity_files[i], original_real_uid);
- options.identity_files_type[i] = guess_identity_file_type(options.identity_files[i]);
- debug("identity file %s type %d", options.identity_files[i],
- options.identity_files_type[i]);
- }
+ /* load options.identity_files */
+ load_public_identity_files();
+
+ /* Expand ~ in known host file names. */
+ /* XXX mem-leaks: */
options.system_hostfile =
tilde_expand_filename(options.system_hostfile, original_real_uid);
options.user_hostfile =
tilde_expand_filename(options.user_hostfile2, original_real_uid);
/* Log into the remote system. This never returns if the login fails. */
- ssh_login(host_private_key_loaded, host_private_key,
- host, (struct sockaddr *)&hostaddr, original_real_uid);
+ ssh_login(host_private_key, host, (struct sockaddr *)&hostaddr,
+ original_real_uid);
/* We no longer need the host private key. Clear it now. */
- if (host_private_key_loaded)
- RSA_free(host_private_key); /* Destroys contents safely */
+ if (host_private_key != NULL)
+ key_free(host_private_key); /* Destroys contents safely */
exit_status = compat20 ? ssh_session2() : ssh_session();
packet_close();
id = packet_get_int();
len = buffer_len(&command);
- len = MAX(len, 900);
+ if (len > 900)
+ len = 900;
packet_done();
if (type == SSH2_MSG_CHANNEL_FAILURE)
fatal("Request for subsystem '%.*s' failed on channel %d",
debug("Sending command: %.*s", len, buffer_ptr(&command));
channel_request_start(id, "exec", 0);
}
- packet_put_string(buffer_ptr(&command), len);
+ packet_put_string(buffer_ptr(&command), buffer_len(&command));
packet_send();
} else {
channel_request(id, "shell", 0);
return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id);
}
-int
-guess_identity_file_type(const char *filename)
+void
+load_public_identity_files(void)
{
- struct stat st;
+ char *filename;
Key *public;
- int type = KEY_RSA1; /* default */
+ int i;
- if (stat(filename, &st) < 0) {
- /* ignore this key */
- return KEY_UNSPEC;
- }
- public = key_new(type);
- if (!load_public_key(filename, public, NULL)) {
- /* ok, so we will assume this is 'some' key */
- type = KEY_UNSPEC;
+ for (i = 0; i < options.num_identity_files; i++) {
+ filename = tilde_expand_filename(options.identity_files[i],
+ original_real_uid);
+ public = key_load_public(filename, NULL);
+ debug("identity file %s type %d", filename,
+ public ? public->type : -1);
+ xfree(options.identity_files[i]);
+ options.identity_files[i] = filename;
+ options.identity_keys[i] = public;
}
- key_free(public);
- return type;
}