summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--authfile.c8
-rw-r--r--channels.c10
-rw-r--r--cipher.c24
-rw-r--r--cipher.h8
-rw-r--r--clientloop.c210
-rw-r--r--compat.c6
-rw-r--r--contrib/redhat/openssh.spec4
-rw-r--r--kex.h11
-rw-r--r--myproposal.h20
-rw-r--r--packet.c32
-rw-r--r--packet.h4
-rw-r--r--ssh.c162
-rw-r--r--sshconnect.c350
-rw-r--r--sshd.c4
15 files changed, 737 insertions, 130 deletions
diff --git a/ChangeLog b/ChangeLog
index 33e52284..05d37dc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+20000406
+ - OpenBSD CVS update:
+ - [channels.c]
+ close efd on eof
+ - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h]
+ ssh2 client implementation, interops w/ ssh.com and lsh servers.
+ - [sshconnect.c]
+ missing free.
+ - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c]
+ remove unused argument, split cipher_mask()
+ - [clientloop.c]
+ re-order: group ssh1 vs. ssh2
+ - Make Redhat spec require openssl >= 0.9.5a
+
20000404
- Add tests for RAND_add function when searching for OpenSSL
- OpenBSD CVS update:
diff --git a/authfile.c b/authfile.c
index a6dab757..6ce0ac61 100644
--- a/authfile.c
+++ b/authfile.c
@@ -15,7 +15,7 @@
*/
#include "includes.h"
-RCSID("$Id: authfile.c,v 1.7 2000/03/02 12:57:18 damien Exp $");
+RCSID("$Id: authfile.c,v 1.8 2000/04/06 02:32:38 damien Exp $");
#ifdef HAVE_OPENSSL
#include <openssl/bn.h>
@@ -107,7 +107,7 @@ save_private_key(const char *filename, const char *passphrase,
/* Allocate space for the private part of the key in the buffer. */
buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
- cipher_set_key_string(&cipher, cipher_type, passphrase, 1);
+ cipher_set_key_string(&cipher, cipher_type, passphrase);
cipher_encrypt(&cipher, (unsigned char *) cp,
(unsigned char *) buffer_ptr(&buffer),
buffer_len(&buffer));
@@ -286,7 +286,7 @@ load_private_key(const char *filename, const char *passphrase,
xfree(buffer_get_string(&buffer, NULL));
/* Check that it is a supported cipher. */
- if (((cipher_mask() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
+ if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
(1 << cipher_type)) == 0) {
debug("Unsupported cipher %.100s used in key file %.200s.",
cipher_name(cipher_type), filename);
@@ -298,7 +298,7 @@ load_private_key(const char *filename, const char *passphrase,
buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
- cipher_set_key_string(&cipher, cipher_type, passphrase, 0);
+ cipher_set_key_string(&cipher, cipher_type, passphrase);
cipher_decrypt(&cipher, (unsigned char *) cp,
(unsigned char *) buffer_ptr(&buffer),
buffer_len(&buffer));
diff --git a/channels.c b/channels.c
index 18f667f6..f03cf92b 100644
--- a/channels.c
+++ b/channels.c
@@ -17,7 +17,7 @@
*/
#include "includes.h"
-RCSID("$Id: channels.c,v 1.21 2000/04/04 04:39:00 damien Exp $");
+RCSID("$Id: channels.c,v 1.22 2000/04/06 02:32:38 damien Exp $");
#include "ssh.h"
#include "packet.h"
@@ -642,6 +642,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
char buf[16*1024];
int len;
+/** XXX handle drain efd, too */
if (c->efd != -1) {
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
FD_ISSET(c->efd, writeset) &&
@@ -659,7 +660,12 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
len = read(c->efd, buf, sizeof(buf));
debug("channel %d: read %d from efd %d",
c->self, len, c->efd);
- if (len > 0)
+ if (len == 0) {
+ debug("channel %d: closing efd %d",
+ c->self, c->efd);
+ close(c->efd);
+ c->efd = -1;
+ } else if (len > 0)
buffer_append(&c->extended, buf, len);
}
}
diff --git a/cipher.c b/cipher.c
index f7b7b472..8911ffef 100644
--- a/cipher.c
+++ b/cipher.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$Id: cipher.c,v 1.15 2000/04/01 01:09:23 damien Exp $");
+RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");
#include "ssh.h"
#include "cipher.h"
@@ -137,17 +137,28 @@ static char *cipher_names[] =
*/
unsigned int
-cipher_mask()
+cipher_mask1()
{
unsigned int mask = 0;
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
mask |= 1 << SSH_CIPHER_BLOWFISH;
+ return mask;
+}
+unsigned int
+cipher_mask2()
+{
+ unsigned int mask = 0;
mask |= 1 << SSH_CIPHER_BLOWFISH_CBC;
mask |= 1 << SSH_CIPHER_3DES_CBC;
mask |= 1 << SSH_CIPHER_ARCFOUR;
mask |= 1 << SSH_CIPHER_CAST128_CBC;
return mask;
}
+unsigned int
+cipher_mask()
+{
+ return cipher_mask1() | cipher_mask2();
+}
/* Returns the name of the cipher. */
@@ -182,8 +193,7 @@ cipher_number(const char *name)
*/
void
-cipher_set_key_string(CipherContext *context, int cipher,
- const char *passphrase, int for_encryption)
+cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase)
{
MD5_CTX md;
unsigned char digest[16];
@@ -192,7 +202,7 @@ cipher_set_key_string(CipherContext *context, int cipher,
MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
MD5_Final(digest, &md);
- cipher_set_key(context, cipher, digest, 16, for_encryption);
+ cipher_set_key(context, cipher, digest, 16);
memset(digest, 0, sizeof(digest));
memset(&md, 0, sizeof(md));
@@ -201,8 +211,8 @@ cipher_set_key_string(CipherContext *context, int cipher,
/* Selects the cipher to use and sets the key. */
void
-cipher_set_key(CipherContext *context, int cipher,
- const unsigned char *key, int keylen, int for_encryption)
+cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
+ int keylen)
{
unsigned char padded[32];
diff --git a/cipher.h b/cipher.h
index 6cfeb639..94c0ceee 100644
--- a/cipher.h
+++ b/cipher.h
@@ -11,7 +11,7 @@
*
*/
-/* RCSID("$Id: cipher.h,v 1.7 2000/04/01 01:09:23 damien Exp $"); */
+/* RCSID("$Id: cipher.h,v 1.8 2000/04/06 02:32:39 damien Exp $"); */
#ifndef CIPHER_H
#define CIPHER_H
@@ -76,6 +76,8 @@ typedef struct {
* supported cipher.
*/
unsigned int cipher_mask();
+unsigned int cipher_mask1();
+unsigned int cipher_mask2();
/* Returns the name of the cipher. */
const char *cipher_name(int cipher);
@@ -92,7 +94,7 @@ int cipher_number(const char *name);
*/
void
cipher_set_key(CipherContext * context, int cipher,
- const unsigned char *key, int keylen, int for_encryption);
+ const unsigned char *key, int keylen);
void
cipher_set_key_iv(CipherContext * context, int cipher,
const unsigned char *key, int keylen,
@@ -104,7 +106,7 @@ cipher_set_key_iv(CipherContext * context, int cipher,
*/
void
cipher_set_key_string(CipherContext * context, int cipher,
- const char *passphrase, int for_encryption);
+ const char *passphrase);
/* Encrypts data using the cipher. */
void
diff --git a/clientloop.c b/clientloop.c
index 1bc6d7e6..4f2e5037 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -12,10 +12,11 @@
*
* The main loop for the interactive session (client side).
*
+ * SSH2 support added by Markus Friedl.
*/
#include "includes.h"
-RCSID("$Id: clientloop.c,v 1.8 2000/04/01 01:09:23 damien Exp $");
+RCSID("$Id: clientloop.c,v 1.9 2000/04/06 02:32:39 damien Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -24,6 +25,7 @@ RCSID("$Id: clientloop.c,v 1.8 2000/04/01 01:09:23 damien Exp $");
#include "authfd.h"
#include "readconf.h"
+#include "ssh2.h"
#include "compat.h"
#include "channels.h"
#include "dispatch.h"
@@ -75,6 +77,10 @@ static unsigned long stdin_bytes, stdout_bytes, stderr_bytes;
static int quit_pending; /* Set to non-zero to quit the client loop. */
static int escape_char; /* Escape character. */
+
+void client_init_dispatch(void);
+int session_ident = -1;
+
/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
void
@@ -273,23 +279,32 @@ client_make_packets_from_stdin_data()
void
client_check_window_change()
{
- /* Send possible window change message to the server. */
- if (received_window_change_signal) {
- struct winsize ws;
-
- /* Clear the window change indicator. */
- received_window_change_signal = 0;
-
- /* Read new window size. */
- if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) >= 0) {
- /* Successful, send the packet now. */
- packet_start(SSH_CMSG_WINDOW_SIZE);
- packet_put_int(ws.ws_row);
- packet_put_int(ws.ws_col);
- packet_put_int(ws.ws_xpixel);
- packet_put_int(ws.ws_ypixel);
- packet_send();
- }
+ struct winsize ws;
+
+ if (! received_window_change_signal)
+ return;
+ /** XXX race */
+ received_window_change_signal = 0;
+
+ if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
+ return;
+
+ debug("client_check_window_change: changed");
+
+ if (compat20) {
+ channel_request_start(session_ident, "window-change", 0);
+ packet_put_int(ws.ws_col);
+ packet_put_int(ws.ws_row);
+ packet_put_int(ws.ws_xpixel);
+ packet_put_int(ws.ws_ypixel);
+ packet_send();
+ } else {
+ packet_start(SSH_CMSG_WINDOW_SIZE);
+ packet_put_int(ws.ws_row);
+ packet_put_int(ws.ws_col);
+ packet_put_int(ws.ws_xpixel);
+ packet_put_int(ws.ws_ypixel);
+ packet_send();
}
}
@@ -301,23 +316,33 @@ client_check_window_change()
void
client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
{
+ /*debug("client_wait_until_can_do_something"); */
+
/* Initialize select masks. */
FD_ZERO(readset);
+ FD_ZERO(writeset);
- /* Read from the connection, unless our buffers are full. */
- if (buffer_len(&stdout_buffer) < buffer_high &&
- buffer_len(&stderr_buffer) < buffer_high &&
- channel_not_very_much_buffered_data())
+ if (!compat20) {
+ /* Read from the connection, unless our buffers are full. */
+ if (buffer_len(&stdout_buffer) < buffer_high &&
+ buffer_len(&stderr_buffer) < buffer_high &&
+ channel_not_very_much_buffered_data())
+ FD_SET(connection_in, readset);
+ /*
+ * Read from stdin, unless we have seen EOF or have very much
+ * buffered data to send to the server.
+ */
+ if (!stdin_eof && packet_not_very_much_data_to_write())
+ FD_SET(fileno(stdin), readset);
+
+ /* Select stdout/stderr if have data in buffer. */
+ if (buffer_len(&stdout_buffer) > 0)
+ FD_SET(fileno(stdout), writeset);
+ if (buffer_len(&stderr_buffer) > 0)
+ FD_SET(fileno(stderr), writeset);
+ } else {
FD_SET(connection_in, readset);
-
- /*
- * Read from stdin, unless we have seen EOF or have very much
- * buffered data to send to the server.
- */
- if (!stdin_eof && packet_not_very_much_data_to_write())
- FD_SET(fileno(stdin), readset);
-
- FD_ZERO(writeset);
+ }
/* Add any selections by the channel mechanism. */
channel_prepare_select(readset, writeset);
@@ -326,14 +351,7 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
if (packet_have_data_to_write())
FD_SET(connection_out, writeset);
- /* Select stdout if have data in buffer. */
- if (buffer_len(&stdout_buffer) > 0)
- FD_SET(fileno(stdout), writeset);
-
- /* Select stderr if have data in buffer. */
- if (buffer_len(&stderr_buffer) > 0)
- FD_SET(fileno(stderr), writeset);
-
+/* move UP XXX */
/* Update maximum file descriptor number, if appropriate. */
if (channel_max_fd() > max_fd)
max_fd = channel_max_fd();
@@ -408,10 +426,10 @@ client_suspend_self()
}
void
-client_process_input(fd_set * readset)
+client_process_net_input(fd_set * readset)
{
- int len, pid;
- char buf[8192], *s;
+ int len;
+ char buf[8192];
/*
* Read input from the server, and add any such data to the buffer of
@@ -420,6 +438,7 @@ client_process_input(fd_set * readset)
if (FD_ISSET(connection_in, readset)) {
/* Read as much as possible. */
len = read(connection_in, buf, sizeof(buf));
+/*debug("read connection_in len %d", len); XXX */
if (len == 0) {
/* Received EOF. The remote host has closed the connection. */
snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
@@ -447,6 +466,14 @@ client_process_input(fd_set * readset)
}
packet_process_incoming(buf, len);
}
+}
+
+void
+client_process_input(fd_set * readset)
+{
+ int len, pid;
+ char buf[8192], *s;
+
/* Read input from stdin. */
if (FD_ISSET(fileno(stdin), readset)) {
/* Read as much as possible. */
@@ -703,8 +730,6 @@ client_process_buffered_input_packets()
* character for terminating or suspending the session.
*/
-void client_init_dispatch(void);
-
int
client_loop(int have_pty, int escape_char_arg)
{
@@ -753,7 +778,8 @@ client_loop(int have_pty, int escape_char_arg)
enter_raw_mode();
/* Check if we should immediately send of on stdin. */
- client_check_initial_eof_on_stdin();
+ if (!compat20)
+ client_check_initial_eof_on_stdin();
/* Main loop of the client for the interactive session mode. */
while (!quit_pending) {
@@ -762,11 +788,17 @@ client_loop(int have_pty, int escape_char_arg)
/* Process buffered packets sent by the server. */
client_process_buffered_input_packets();
+ if (compat20 && !channel_still_open()) {
+ debug("!channel_still_open.");
+ break;
+ }
+
/*
* Make packets of buffered stdin data, and buffer them for
* sending to the server.
*/
- client_make_packets_from_stdin_data();
+ if (!compat20)
+ client_make_packets_from_stdin_data();
/*
* Make packets from buffered channel data, and buffer them
@@ -796,17 +828,21 @@ client_loop(int have_pty, int escape_char_arg)
/* Do channel operations. */
channel_after_select(&readset, &writeset);
- /*
- * Process input from the connection and from stdin. Buffer
- * any data that is available.
- */
- client_process_input(&readset);
+ /* Buffer input from the connection. */
+ client_process_net_input(&readset);
- /*
- * Process output to stdout and stderr. Output to the
- * connection is processed elsewhere (above).
- */
- client_process_output(&writeset);
+ if (quit_pending)
+ break;
+
+ if (!compat20) {
+ /* Buffer data from stdin */
+ client_process_input(&readset);
+ /*
+ * Process output to stdout and stderr. Output to
+ * the connection is processed elsewhere (above).
+ */
+ client_process_output(&writeset);
+ }
/* Send as much buffered packet data as possible to the sender. */
if (FD_ISSET(connection_out, &writeset))
@@ -918,6 +954,19 @@ client_input_exit_status(int type, int plen)
}
void
+client_init_dispatch_20()
+{
+ dispatch_init(&dispatch_protocol_error);
+ dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
+ dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
+ dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
+ dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
+ dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
+ dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
+ dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
+ dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
+}
+void
client_init_dispatch_13()
{
dispatch_init(NULL);
@@ -944,8 +993,55 @@ client_init_dispatch_15()
void
client_init_dispatch()
{
- if (compat13)
+ if (compat20)
+ client_init_dispatch_20();
+ else if (compat13)
client_init_dispatch_13();
else
client_init_dispatch_15();
}
+
+void
+client_input_channel_req(int id, void *arg)
+{
+ Channel *c = NULL;
+ unsigned int len;
+ int success = 0;
+ int reply;
+ char *rtype;
+
+ rtype = packet_get_string(&len);
+ reply = packet_get_char();
+
+ log("session_input_channel_req: rtype %s reply %d", rtype, reply);
+
+ c = channel_lookup(id);
+ if (c == NULL)
+ fatal("session_input_channel_req: channel %d: bad channel", id);
+
+ if (session_ident == -1) {
+ error("client_input_channel_req: no channel %d", id);
+ } else if (id != session_ident) {
+ error("client_input_channel_req: bad channel %d != %d",
+ id, session_ident);
+ } else if (strcmp(rtype, "exit-status") == 0) {
+ success = 1;
+ exit_status = packet_get_int();
+ }
+ if (reply) {
+ packet_start(success ?
+ SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
+ packet_put_int(c->remote_id);
+ packet_send();
+ }
+ xfree(rtype);
+}
+
+void
+client_set_session_ident(int id)
+{
+ debug("client_set_session_ident: id %d", id);
+ session_ident = id;
+ channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
+ client_input_channel_req, (void *)0);
+}
diff --git a/compat.c b/compat.c
index 3ecf7101..d09f38ca 100644
--- a/compat.c
+++ b/compat.c
@@ -28,7 +28,7 @@
*/
#include "includes.h"
-RCSID("$Id: compat.c,v 1.4 2000/04/04 04:39:01 damien Exp $");
+RCSID("$Id: compat.c,v 1.5 2000/04/06 02:32:39 damien Exp $");
#include "ssh.h"
#include "packet.h"
@@ -40,7 +40,9 @@ int datafellows = 0;
void
enable_compat20(void)
{
- fatal("protocol 2.0 not implemented");
+ verbose("Enabling compatibility mode for protocol 2.0");
+ compat20 = 1;
+ packet_set_ssh2_format();
}
void
enable_compat13(void)
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index 24f0e428..35affbaa 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -15,8 +15,8 @@ Copyright: BSD
Group: Applications/Internet
BuildRoot: /tmp/openssh-%{version}-buildroot
Obsoletes: ssh
-PreReq: openssl
-Requires: openssl
+PreReq: openssl >= 0.9.5a
+Requires: openssl >= 0.9.5a
BuildPreReq: perl
BuildPreReq: openssl-devel
BuildPreReq: tcp_wrappers
diff --git a/kex.h b/kex.h
index f9e79994..81c41342 100644
--- a/kex.h
+++ b/kex.h
@@ -29,6 +29,17 @@
#ifndef KEX_H
#define KEX_H
+#include "config.h"
+
+#ifdef HAVE_OPENSSL
+# include <openssl/bn.h>
+# include <openssl/evp.h>
+#endif
+#ifdef HAVE_SSL
+# include <ssl/bn.h>
+# include <ssl/evp.h>
+#endif
+
#define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DSS "ssh-dss"
diff --git a/myproposal.h b/myproposal.h
new file mode 100644
index 00000000..7e4baff9
--- /dev/null
+++ b/myproposal.h
@@ -0,0 +1,20 @@
+#define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1"
+#define KEX_DEFAULT_PK_ALG "ssh-dss"
+#define KEX_DEFAULT_ENCRYPT "blowfish-cbc,3des-cbc,arcfour,cast128-cbc"
+#define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com"
+#define KEX_DEFAULT_COMP "zlib,none"
+#define KEX_DEFAULT_LANG ""
+
+
+static const char *myproposal[PROPOSAL_MAX] = {
+ KEX_DEFAULT_KEX,
+ KEX_DEFAULT_PK_ALG,
+ KEX_DEFAULT_ENCRYPT,
+ KEX_DEFAULT_ENCRYPT,
+ KEX_DEFAULT_MAC,
+ KEX_DEFAULT_MAC,
+ KEX_DEFAULT_COMP,
+ KEX_DEFAULT_COMP,
+ KEX_DEFAULT_LANG,
+ KEX_DEFAULT_LANG
+};
diff --git a/packet.c b/packet.c
index 39629a5e..b11519e7 100644
--- a/packet.c
+++ b/packet.c
@@ -17,7 +17,18 @@
*/
#include "includes.h"
-RCSID("$Id: packet.c,v 1.15 2000/04/04 04:57:08 damien Exp $");
+RCSID("$Id: packet.c,v 1.16 2000/04/06 02:32:40 damien Exp $");
+
+#ifdef HAVE_OPENSSL
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+# include <openssl/hmac.h>
+#endif /* HAVE_OPENSSL */
+#ifdef HAVE_SSL
+# include <ssl/bn.h>
+# include <ssl/dh.h>
+# include <ssl/hmac.h>
+#endif /* HAVE_SSL */
#include "xmalloc.h"
#include "buffer.h"
@@ -35,17 +46,6 @@ RCSID("$Id: packet.c,v 1.15 2000/04/04 04:57:08 damien Exp $");
#include "compat.h"
#include "ssh2.h"
-#ifdef HAVE_OPENSSL
-# include <openssl/bn.h>
-# include <openssl/dh.h>
-# include <openssl/hmac.h>
-#endif /* HAVE_OPENSSL */
-#ifdef HAVE_SSL
-# include <ssl/bn.h>
-# include <ssl/dh.h>
-# include <ssl/hmac.h>
-#endif /* HAVE_SSL */
-
#include "buffer.h"
#include "kex.h"
#include "hmac.h"
@@ -152,8 +152,8 @@ packet_set_connection(int fd_in, int fd_out)
connection_in = fd_in;
connection_out = fd_out;
cipher_type = SSH_CIPHER_NONE;
- cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 1);
- cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 0);
+ cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0);
+ cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0);
if (!initialized) {
initialized = 1;
buffer_init(&input);
@@ -352,8 +352,8 @@ packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
fatal("keylen too small: %d", keylen);
/* All other ciphers use the same key in both directions for now. */
- cipher_set_key(&receive_context, cipher, key, keylen, 0);
- cipher_set_key(&send_context, cipher, key, keylen, 1);
+ cipher_set_key(&receive_context, cipher, key, keylen);
+ cipher_set_key(&send_context, cipher, key, keylen);
}
/* Starts constructing a packet to send. */
diff --git a/packet.h b/packet.h
index 39c0edea..61c12be9 100644
--- a/packet.h
+++ b/packet.h
@@ -13,13 +13,11 @@
*
*/
-/* RCSID("$Id: packet.h,v 1.11 2000/04/04 04:39:03 damien Exp $"); */
+/* RCSID("$Id: packet.h,v 1.12 2000/04/06 02:32:40 damien Exp $"); */
#ifndef PACKET_H
#define PACKET_H
-#include "config.h"
-
#ifdef HAVE_OPENSSL
#include <openssl/bn.h>
#endif
diff --git a/ssh.c b/ssh.c
index 70f9d6a6..cce0e6b7 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
*/
#include "includes.h"
-RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $");
+RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $");
#include "xmalloc.h"
#include "ssh.h"
@@ -20,6 +20,9 @@ RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $");
#include "authfd.h"
#include "readconf.h"
#include "uidswap.h"
+
+#include "ssh2.h"
+#include "compat.h"
#include "channels.h"
#ifdef HAVE___PROGNAME
@@ -41,6 +44,10 @@ int debug_flag = 0;
int tty_flag = 0;
+/* don't exec a shell */
+int no_shell_flag = 0;
+int no_tty_flag = 0;
+
/*
* Flag indicating that nothing should be read from stdin. This can be set
* on the command line.
@@ -90,6 +97,9 @@ RSA *host_private_key = NULL;
/* Original real UID. */
uid_t original_real_uid;
+/* command to be executed */
+Buffer command;
+
/* Prints a help message to the user. This function never returns. */
void
@@ -104,9 +114,9 @@ usage()
fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n");
#endif /* AFS */
fprintf(stderr, " -x Disable X11 connection forwarding.\n");
- fprintf(stderr, " -X Enable X11 connection forwarding.\n");
fprintf(stderr, " -i file Identity for RSA 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, " -V Display version number only.\n");
fprintf(stderr, " -P Don't allocate a privileged port.\n");
@@ -123,6 +133,7 @@ usage()
fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0);
fprintf(stderr, " forward them to the other side by connecting to host:port.\n");
fprintf(stderr, " -C Enable compression.\n");
+ fprintf(stderr, " -N Do not execute a shell or command.\n");
fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n");
fprintf(stderr, " -4 Use IPv4 only.\n");
fprintf(stderr, " -6 Use IPv6 only.\n");
@@ -168,23 +179,22 @@ rsh_connect(char *host, char *user, Buffer * command)
exit(1);
}
+int ssh_session(void);
+int ssh_session2(void);
+
/*
* Main program for the ssh client.
*/
int
main(int ac, char **av)
{
- int i, opt, optind, type, exit_status, ok, authfd;
+ int i, opt, optind, exit_status, ok;
u_short fwd_port, fwd_host_port;
char *optarg, *cp, buf[256];
- Buffer command;
- struct winsize ws;
struct stat st;
struct passwd *pw, pwcopy;
- int interactive = 0, dummy;
- int have_pty = 0;
+ int dummy;
uid_t original_effective_uid;
- int plen;
/*
* Save the original real uid. It will be needed later (uid-swapping
@@ -328,7 +338,7 @@ main(int ac, char **av)
case 'V':
fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
- fprintf(stderr, "Compiled with SSL.\n");
+ fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay());
if (opt == 'V')
exit(0);
debug_flag = 1;
@@ -397,6 +407,15 @@ main(int ac, char **av)
options.compression = 1;
break;
+ case 'N':
+ no_shell_flag = 1;
+ no_tty_flag = 1;
+ break;
+
+ case 'T':
+ no_tty_flag = 1;
+ break;
+
case 'o':
dummy = 1;
if (process_config_line(&options, host ? host : "", optarg,
@@ -455,6 +474,10 @@ main(int ac, char **av)
fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
tty_flag = 0;
}
+ /* force */
+ if (no_tty_flag)
+ tty_flag = 0;
+
/* Get user data. */
pw = getpwuid(original_real_uid);
if (!pw) {
@@ -620,6 +643,23 @@ main(int ac, char **av)
if (host_private_key_loaded)
RSA_free(host_private_key); /* Destroys contents safely */
+ exit_status = compat20 ? ssh_session2() : ssh_session();
+ packet_close();
+ return exit_status;
+}
+
+int
+ssh_session(void)
+{
+ int type;
+ int i;
+ int plen;
+ int interactive = 0;
+ int have_tty = 0;
+ struct winsize ws;
+ int authfd;
+ char *cp;
+
/* Enable compression if requested. */
if (options.compression) {
debug("Requesting compression at level %d.", options.compression_level);
@@ -673,7 +713,7 @@ main(int ac, char **av)
type = packet_read(&plen);
if (type == SSH_SMSG_SUCCESS) {
interactive = 1;
- have_pty = 1;
+ have_tty = 1;
} else if (type == SSH_SMSG_FAILURE)
log("Warning: Remote host failed or refused to allocate a pseudo tty.");
else
@@ -802,11 +842,103 @@ main(int ac, char **av)
}
/* Enter the interactive session. */
- exit_status = client_loop(have_pty, tty_flag ? options.escape_char : -1);
+ return client_loop(have_tty, tty_flag ? options.escape_char : -1);
+}
- /* Close the connection to the remote host. */
- packet_close();
+void
+init_local_fwd(void)
+{
+ int i;
+ /* Initiate local TCP/IP port forwardings. */
+ for (i = 0; i < options.num_local_forwards; i++) {
+ debug("Connections to local port %d forwarded to remote address %.200s:%d",
+ options.local_forwards[i].port,
+ options.local_forwards[i].host,
+ options.local_forwards[i].host_port);
+ channel_request_local_forwarding(options.local_forwards[i].port,
+ options.local_forwards[i].host,
+ options.local_forwards[i].host_port,
+ options.gateway_ports);
+ }
+}
+
+extern void client_set_session_ident(int id);
+
+void
+client_init(int id, void *arg)
+{
+ int len;
+ debug("client_init id %d arg %d", id, (int)arg);
+
+ if (no_shell_flag)
+ goto done;
+
+ if (tty_flag) {
+ struct winsize ws;
+ char *cp;
+ cp = getenv("TERM");
+ if (!cp)
+ cp = "";
+ /* Store window size in the packet. */
+ if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
+ memset(&ws, 0, sizeof(ws));
+
+ channel_request_start(id, "pty-req", 0);
+ packet_put_cstring(cp);
+ packet_put_int(ws.ws_col);
+ packet_put_int(ws.ws_row);
+ packet_put_int(ws.ws_xpixel);
+ packet_put_int(ws.ws_ypixel);
+ packet_put_cstring(""); /* XXX: encode terminal modes */
+ packet_send();
+ /* XXX wait for reply */
+ }
+ len = buffer_len(&command);
+ if (len > 0) {
+ if (len > 900)
+ len = 900;
+ debug("Sending command: %.*s", len, buffer_ptr(&command));
+ channel_request_start(id, "exec", 0);
+ packet_put_string(buffer_ptr(&command), len);
+ packet_send();
+ } else {
+ channel_request(id, "shell", 0);
+ }
+ /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
+done:
+ /* register different callback, etc. XXX */
+ client_set_session_ident(id);
+}
+
+int
+ssh_session2(void)
+{
+ int window, packetmax, id;
+ int in = dup(STDIN_FILENO);
+ int out = dup(STDOUT_FILENO);
+ int err = dup(STDERR_FILENO);
+
+ if (in < 0 || out < 0 || err < 0)
+ fatal("dump in/out/err failed");
+
+ /* should be pre-session */
+ init_local_fwd();
+
+ window = 32*1024;
+ if (tty_flag) {
+ packetmax = window/8;
+ } else {
+ window *= 2;
+ packetmax = window/2;
+ }
+
+ id = channel_new(
+ "session", SSH_CHANNEL_OPENING, in, out, err,
+ window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session"));
+
+
+ channel_open(id);
+ channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0);
- /* Exit with the status returned by the program on the remote side. */
- exit(exit_status);
+ return client_loop(tty_flag, tty_flag ? options.escape_char : -1);
}
diff --git a/sshconnect.c b/sshconnect.c
index d64c0e2c..2f949609 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -5,27 +5,30 @@
* Created: Sat Mar 18 22:15: