summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/ssh.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-06-23 14:01:54 +0000
committerdes <des@FreeBSD.org>2002-06-23 14:01:54 +0000
commit610201f50fdb0594e9885594b69e4ee69c71dd08 (patch)
treeb7e89b45c0327694bc87ec94464fd0a685e1ef1d /crypto/openssh/ssh.c
parentf58c4e7f5e1985bae7ed77fb0e8b2766eb4824e9 (diff)
downloadFreeBSD-src-610201f50fdb0594e9885594b69e4ee69c71dd08.zip
FreeBSD-src-610201f50fdb0594e9885594b69e4ee69c71dd08.tar.gz
Vendor import of OpenSSH 3.3.
Diffstat (limited to 'crypto/openssh/ssh.c')
-rw-r--r--crypto/openssh/ssh.c216
1 files changed, 80 insertions, 136 deletions
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 44af61f..f59dc44 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -13,6 +13,7 @@
* called by a name other than "ssh" or "Secure Shell".
*
* Copyright (c) 1999 Niels Provos. All rights reserved.
+ * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
* Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
* in Canada (German citizen).
@@ -39,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.164 2002/02/14 23:28:00 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.179 2002/06/12 01:09:52 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@@ -52,7 +53,6 @@ RCSID("$OpenBSD: ssh.c,v 1.164 2002/02/14 23:28:00 markus Exp $");
#include "xmalloc.h"
#include "packet.h"
#include "buffer.h"
-#include "uidswap.h"
#include "channels.h"
#include "key.h"
#include "authfd.h"
@@ -70,7 +70,6 @@ RCSID("$OpenBSD: ssh.c,v 1.164 2002/02/14 23:28:00 markus Exp $");
#include "sshtty.h"
#ifdef SMARTCARD
-#include <openssl/engine.h>
#include "scard.h"
#endif
@@ -99,7 +98,7 @@ int stdin_null_flag = 0;
/*
* Flag indicating that ssh should fork after authentication. This is useful
- * so that the pasphrase can be entered manually, and then ssh goes to the
+ * so that the passphrase can be entered manually, and then ssh goes to the
* background.
*/
int fork_after_authentication_flag = 0;
@@ -124,13 +123,11 @@ char *host;
struct sockaddr_storage hostaddr;
/* Private host keys. */
-struct {
- Key **keys;
- int nkeys;
-} sensitive_data;
+Sensitive sensitive_data;
/* Original real UID. */
uid_t original_real_uid;
+uid_t original_effective_uid;
/* command to be executed */
Buffer command;
@@ -138,6 +135,9 @@ Buffer command;
/* Should we execute a command or invoke a subsystem? */
int subsystem_flag = 0;
+/* # of replies received for global requests */
+static int client_global_request_id = 0;
+
/* Prints a help message to the user. This function never returns. */
static void
@@ -192,44 +192,6 @@ usage(void)
exit(1);
}
-/*
- * Connects to the given host using rsh (or prints an error message and exits
- * if rsh is not available). This function never returns.
- */
-static void
-rsh_connect(char *host, char *user, Buffer * command)
-{
- char *args[10];
- int i;
-
- log("Using rsh. WARNING: Connection will not be encrypted.");
- /* Build argument list for rsh. */
- i = 0;
- args[i++] = _PATH_RSH;
- /* host may have to come after user on some systems */
- args[i++] = host;
- if (user) {
- args[i++] = "-l";
- args[i++] = user;
- }
- if (buffer_len(command) > 0) {
- buffer_append(command, "\0", 1);
- args[i++] = buffer_ptr(command);
- }
- args[i++] = NULL;
- if (debug_flag) {
- for (i = 0; args[i]; i++) {
- if (i != 0)
- fprintf(stderr, " ");
- fprintf(stderr, "%s", args[i]);
- }
- fprintf(stderr, "\n");
- }
- execv(_PATH_RSH, args);
- perror(_PATH_RSH);
- exit(1);
-}
-
static int ssh_session(void);
static int ssh_session2(void);
static void load_public_identity_files(void);
@@ -240,14 +202,13 @@ static void load_public_identity_files(void);
int
main(int ac, char **av)
{
- int i, opt, exit_status, cerr;
+ int i, opt, exit_status;
u_short fwd_port, fwd_host_port;
char sfwd_port[6], sfwd_host_port[6];
char *p, *cp, buf[256];
struct stat st;
struct passwd *pw;
int dummy;
- uid_t original_effective_uid;
extern int optind, optreset;
extern char *optarg;
@@ -281,7 +242,7 @@ main(int ac, char **av)
* them when the port has been created (actually, when the connection
* has been made, as we may need to create the port several times).
*/
- temporarily_use_uid(pw);
+ PRIV_END;
/*
* Set our umask to something reasonable, as some files are created
@@ -462,7 +423,7 @@ again:
/* NOTREACHED */
}
if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
+ (fwd_host_port = a2port(sfwd_host_port)) == 0) {
fprintf(stderr,
"Bad forwarding port(s) '%s'\n", optarg);
exit(1);
@@ -630,52 +591,48 @@ again:
"originating port will not be trusted.");
options.rhosts_authentication = 0;
}
- /*
- * If using rsh has been selected, exec it now (without trying
- * anything else). Note that we must release privileges first.
- */
- if (options.use_rsh) {
- /*
- * Restore our superuser privileges. This must be done
- * before permanently setting the uid.
- */
- restore_uid();
-
- /* Switch to the original uid permanently. */
- permanently_set_uid(pw);
-
- /* Execute rsh. */
- rsh_connect(host, options.user, &command);
- fatal("rsh_connect returned");
- }
- /* Restore our superuser privileges. */
- restore_uid();
-
/* Open a connection to the remote host. */
- cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
+ if (ssh_connect(host, &hostaddr, options.port, IPv4or6,
options.connection_attempts,
- original_effective_uid != 0 || !options.use_privileged_port,
- pw, options.proxy_command);
+ original_effective_uid == 0 && options.use_privileged_port,
+ options.proxy_command) != 0)
+ exit(1);
/*
* If we successfully made the connection, load the host private key
* in case we will need it later for combined rsa-rhosts
* authentication. This must be done before releasing extra
* privileges, because the file is only readable by root.
+ * If we cannot access the private keys, load the public keys
+ * instead and try to execute the ssh-keysign helper instead.
*/
sensitive_data.nkeys = 0;
sensitive_data.keys = NULL;
- if (!cerr && (options.rhosts_rsa_authentication ||
- options.hostbased_authentication)) {
+ sensitive_data.external_keysign = 0;
+ if (options.rhosts_rsa_authentication ||
+ options.hostbased_authentication) {
sensitive_data.nkeys = 3;
sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
+
+ PRIV_START;
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL);
sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL);
sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL);
+ PRIV_END;
+
+ if (sensitive_data.keys[0] == NULL &&
+ sensitive_data.keys[1] == NULL &&
+ sensitive_data.keys[2] == NULL) {
+ sensitive_data.keys[1] = key_load_public(
+ _PATH_HOST_DSA_KEY_FILE, NULL);
+ sensitive_data.keys[2] = key_load_public(
+ _PATH_HOST_RSA_KEY_FILE, NULL);
+ sensitive_data.external_keysign = 1;
+ }
}
/*
* Get rid of any extra privileges that we may have. We will no
@@ -684,15 +641,8 @@ again:
* user's home directory if it happens to be on a NFS volume where
* root is mapped to nobody.
*/
-
- /*
- * Note that some legacy systems need to postpone the following call
- * to permanently_set_uid() until the private hostkey is destroyed
- * with RSA_free(). Otherwise the calling user could ptrace() the
- * process, read the private hostkey and impersonate the host.
- * OpenBSD does not allow ptracing of setuid processes.
- */
- permanently_set_uid(pw);
+ seteuid(original_real_uid);
+ setuid(original_real_uid);
/*
* Now that we are back to our own permissions, create ~/.ssh
@@ -703,21 +653,6 @@ again:
if (mkdir(buf, 0700) < 0)
error("Could not create directory '%.200s'.", buf);
- /* Check if the connection failed, and try "rsh" if appropriate. */
- if (cerr) {
- if (!options.fallback_to_rsh)
- exit(1);
- if (options.port != 0)
- log("Secure connection to %.100s on port %hu refused; "
- "reverting to insecure method",
- host, options.port);
- else
- log("Secure connection to %.100s refused; "
- "reverting to insecure method.", host);
-
- rsh_connect(host, options.user, &command);
- fatal("rsh_connect returned");
- }
/* load options.identity_files */
load_public_identity_files();
@@ -735,8 +670,7 @@ again:
signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
/* Log into the remote system. This never returns if the login fails. */
- ssh_login(sensitive_data.keys, sensitive_data.nkeys,
- host, (struct sockaddr *)&hostaddr, pw);
+ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw);
/* We no longer need the private host keys. Clear them now. */
if (sensitive_data.nkeys != 0) {
@@ -788,10 +722,10 @@ x11_get_proto(char **_proto, char **_data)
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
- snprintf(line, sizeof line, "%.100s list unix:%s 2>"
+ snprintf(line, sizeof line, "%s list unix:%s 2>"
_PATH_DEVNULL, options.xauth_location, display+10);
else
- snprintf(line, sizeof line, "%.100s list %.200s 2>"
+ snprintf(line, sizeof line, "%s list %.200s 2>"
_PATH_DEVNULL, options.xauth_location, display);
debug2("x11_get_proto %s", line);
f = popen(line, "r");
@@ -1021,6 +955,27 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
len, (u_char *)buffer_ptr(&command), id);
}
+void
+client_global_request_reply(int type, u_int32_t seq, void *ctxt)
+{
+ int i;
+
+ i = client_global_request_id++;
+ if (i >= options.num_remote_forwards) {
+ debug("client_global_request_reply: too many replies %d > %d",
+ i, options.num_remote_forwards);
+ return;
+ }
+ debug("remote forward %s for: listen %d, connect %s:%d",
+ type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
+ options.remote_forwards[i].port,
+ options.remote_forwards[i].host,
+ options.remote_forwards[i].host_port);
+ if (type == SSH2_MSG_REQUEST_FAILURE)
+ log("Warning: remote port forwarding failed for listen port %d",
+ options.remote_forwards[i].port);
+}
+
/* request pty/x11/agent/tcpfwd/shell for channel */
static void
ssh_session2_setup(int id, void *arg)
@@ -1080,7 +1035,7 @@ ssh_session2_setup(int id, void *arg)
debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));
channel_request_start(id, "subsystem", /*want reply*/ 1);
/* register callback for reply */
- /* XXX we asume that client_loop has already been called */
+ /* XXX we assume that client_loop has already been called */
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
} else {
@@ -1167,40 +1122,29 @@ static void
load_public_identity_files(void)
{
char *filename;
- Key *public;
int i = 0;
-
+ Key *public;
#ifdef SMARTCARD
+ Key **keys;
+
if (options.smartcard_device != NULL &&
- options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES &&
- (public = sc_get_key(options.smartcard_device)) != NULL ) {
- Key *new;
-
- if (options.num_identity_files + 2 > SSH_MAX_IDENTITY_FILES)
- options.num_identity_files = SSH_MAX_IDENTITY_FILES - 2;
- memmove(&options.identity_files[2], &options.identity_files[0],
- sizeof(char *) * options.num_identity_files);
- options.num_identity_files += 2;
- i = 2;
-
- /* XXX ssh1 vs ssh2 */
- new = key_new(KEY_RSA);
- new->flags = KEY_FLAG_EXT;
- BN_copy(new->rsa->n, public->rsa->n);
- BN_copy(new->rsa->e, public->rsa->e);
- RSA_set_method(new->rsa, sc_get_engine());
- options.identity_keys[0] = new;
- options.identity_files[0] = xstrdup("smartcard rsa key");;
-
- new = key_new(KEY_RSA1);
- new->flags = KEY_FLAG_EXT;
- BN_copy(new->rsa->n, public->rsa->n);
- BN_copy(new->rsa->e, public->rsa->e);
- RSA_set_method(new->rsa, sc_get_engine());
- options.identity_keys[1] = new;
- options.identity_files[1] = xstrdup("smartcard rsa1 key");
-
- key_free(public);
+ options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
+ (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {
+ int count = 0;
+ for (i = 0; keys[i] != NULL; i++) {
+ count++;
+ memmove(&options.identity_files[1], &options.identity_files[0],
+ sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
+ memmove(&options.identity_keys[1], &options.identity_keys[0],
+ sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
+ options.num_identity_files++;
+ options.identity_keys[0] = keys[i];
+ options.identity_files[0] = xstrdup("smartcard key");;
+ }
+ if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
+ options.num_identity_files = SSH_MAX_IDENTITY_FILES;
+ i = count;
+ xfree(keys);
}
#endif /* SMARTCARD */
for (; i < options.num_identity_files; i++) {
OpenPOWER on IntegriCloud