- 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
This commit is contained in:
parent
74a333bbe1
commit
1383bd8eb9
14
ChangeLog
14
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
|
20000404
|
||||||
- Add tests for RAND_add function when searching for OpenSSL
|
- Add tests for RAND_add function when searching for OpenSSL
|
||||||
- OpenBSD CVS update:
|
- OpenBSD CVS update:
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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
|
#ifdef HAVE_OPENSSL
|
||||||
#include <openssl/bn.h>
|
#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. */
|
/* Allocate space for the private part of the key in the buffer. */
|
||||||
buffer_append_space(&encrypted, &cp, buffer_len(&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,
|
cipher_encrypt(&cipher, (unsigned char *) cp,
|
||||||
(unsigned char *) buffer_ptr(&buffer),
|
(unsigned char *) buffer_ptr(&buffer),
|
||||||
buffer_len(&buffer));
|
buffer_len(&buffer));
|
||||||
|
@ -286,7 +286,7 @@ load_private_key(const char *filename, const char *passphrase,
|
||||||
xfree(buffer_get_string(&buffer, NULL));
|
xfree(buffer_get_string(&buffer, NULL));
|
||||||
|
|
||||||
/* Check that it is a supported cipher. */
|
/* 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) {
|
(1 << cipher_type)) == 0) {
|
||||||
debug("Unsupported cipher %.100s used in key file %.200s.",
|
debug("Unsupported cipher %.100s used in key file %.200s.",
|
||||||
cipher_name(cipher_type), filename);
|
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));
|
buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
|
||||||
|
|
||||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
/* 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,
|
cipher_decrypt(&cipher, (unsigned char *) cp,
|
||||||
(unsigned char *) buffer_ptr(&buffer),
|
(unsigned char *) buffer_ptr(&buffer),
|
||||||
buffer_len(&buffer));
|
buffer_len(&buffer));
|
||||||
|
|
10
channels.c
10
channels.c
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
@ -642,6 +642,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
|
||||||
char buf[16*1024];
|
char buf[16*1024];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
/** XXX handle drain efd, too */
|
||||||
if (c->efd != -1) {
|
if (c->efd != -1) {
|
||||||
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
|
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
|
||||||
FD_ISSET(c->efd, writeset) &&
|
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));
|
len = read(c->efd, buf, sizeof(buf));
|
||||||
debug("channel %d: read %d from efd %d",
|
debug("channel %d: read %d from efd %d",
|
||||||
c->self, len, c->efd);
|
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);
|
buffer_append(&c->extended, buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
24
cipher.c
24
cipher.c
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
|
@ -137,17 +137,28 @@ static char *cipher_names[] =
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
cipher_mask()
|
cipher_mask1()
|
||||||
{
|
{
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
|
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
|
||||||
mask |= 1 << SSH_CIPHER_BLOWFISH;
|
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_BLOWFISH_CBC;
|
||||||
mask |= 1 << SSH_CIPHER_3DES_CBC;
|
mask |= 1 << SSH_CIPHER_3DES_CBC;
|
||||||
mask |= 1 << SSH_CIPHER_ARCFOUR;
|
mask |= 1 << SSH_CIPHER_ARCFOUR;
|
||||||
mask |= 1 << SSH_CIPHER_CAST128_CBC;
|
mask |= 1 << SSH_CIPHER_CAST128_CBC;
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
unsigned int
|
||||||
|
cipher_mask()
|
||||||
|
{
|
||||||
|
return cipher_mask1() | cipher_mask2();
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns the name of the cipher. */
|
/* Returns the name of the cipher. */
|
||||||
|
|
||||||
|
@ -182,8 +193,7 @@ cipher_number(const char *name)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
cipher_set_key_string(CipherContext *context, int cipher,
|
cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase)
|
||||||
const char *passphrase, int for_encryption)
|
|
||||||
{
|
{
|
||||||
MD5_CTX md;
|
MD5_CTX md;
|
||||||
unsigned char digest[16];
|
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_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
|
||||||
MD5_Final(digest, &md);
|
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(digest, 0, sizeof(digest));
|
||||||
memset(&md, 0, sizeof(md));
|
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. */
|
/* Selects the cipher to use and sets the key. */
|
||||||
|
|
||||||
void
|
void
|
||||||
cipher_set_key(CipherContext *context, int cipher,
|
cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
|
||||||
const unsigned char *key, int keylen, int for_encryption)
|
int keylen)
|
||||||
{
|
{
|
||||||
unsigned char padded[32];
|
unsigned char padded[32];
|
||||||
|
|
||||||
|
|
8
cipher.h
8
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
|
#ifndef CIPHER_H
|
||||||
#define CIPHER_H
|
#define CIPHER_H
|
||||||
|
@ -76,6 +76,8 @@ typedef struct {
|
||||||
* supported cipher.
|
* supported cipher.
|
||||||
*/
|
*/
|
||||||
unsigned int cipher_mask();
|
unsigned int cipher_mask();
|
||||||
|
unsigned int cipher_mask1();
|
||||||
|
unsigned int cipher_mask2();
|
||||||
|
|
||||||
/* Returns the name of the cipher. */
|
/* Returns the name of the cipher. */
|
||||||
const char *cipher_name(int cipher);
|
const char *cipher_name(int cipher);
|
||||||
|
@ -92,7 +94,7 @@ int cipher_number(const char *name);
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cipher_set_key(CipherContext * context, int cipher,
|
cipher_set_key(CipherContext * context, int cipher,
|
||||||
const unsigned char *key, int keylen, int for_encryption);
|
const unsigned char *key, int keylen);
|
||||||
void
|
void
|
||||||
cipher_set_key_iv(CipherContext * context, int cipher,
|
cipher_set_key_iv(CipherContext * context, int cipher,
|
||||||
const unsigned char *key, int keylen,
|
const unsigned char *key, int keylen,
|
||||||
|
@ -104,7 +106,7 @@ cipher_set_key_iv(CipherContext * context, int cipher,
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cipher_set_key_string(CipherContext * context, int cipher,
|
cipher_set_key_string(CipherContext * context, int cipher,
|
||||||
const char *passphrase, int for_encryption);
|
const char *passphrase);
|
||||||
|
|
||||||
/* Encrypts data using the cipher. */
|
/* Encrypts data using the cipher. */
|
||||||
void
|
void
|
||||||
|
|
158
clientloop.c
158
clientloop.c
|
@ -12,10 +12,11 @@
|
||||||
*
|
*
|
||||||
* The main loop for the interactive session (client side).
|
* The main loop for the interactive session (client side).
|
||||||
*
|
*
|
||||||
|
* SSH2 support added by Markus Friedl.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "xmalloc.h"
|
||||||
#include "ssh.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 "authfd.h"
|
||||||
#include "readconf.h"
|
#include "readconf.h"
|
||||||
|
|
||||||
|
#include "ssh2.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "dispatch.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 quit_pending; /* Set to non-zero to quit the client loop. */
|
||||||
static int escape_char; /* Escape character. */
|
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. */
|
/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -273,16 +279,26 @@ client_make_packets_from_stdin_data()
|
||||||
void
|
void
|
||||||
client_check_window_change()
|
client_check_window_change()
|
||||||
{
|
{
|
||||||
/* Send possible window change message to the server. */
|
|
||||||
if (received_window_change_signal) {
|
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
|
|
||||||
/* Clear the window change indicator. */
|
if (! received_window_change_signal)
|
||||||
|
return;
|
||||||
|
/** XXX race */
|
||||||
received_window_change_signal = 0;
|
received_window_change_signal = 0;
|
||||||
|
|
||||||
/* Read new window size. */
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
|
||||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) >= 0) {
|
return;
|
||||||
/* Successful, send the packet now. */
|
|
||||||
|
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_start(SSH_CMSG_WINDOW_SIZE);
|
||||||
packet_put_int(ws.ws_row);
|
packet_put_int(ws.ws_row);
|
||||||
packet_put_int(ws.ws_col);
|
packet_put_int(ws.ws_col);
|
||||||
|
@ -290,7 +306,6 @@ client_check_window_change()
|
||||||
packet_put_int(ws.ws_ypixel);
|
packet_put_int(ws.ws_ypixel);
|
||||||
packet_send();
|
packet_send();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -301,15 +316,18 @@ client_check_window_change()
|
||||||
void
|
void
|
||||||
client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
|
client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
|
||||||
{
|
{
|
||||||
|
/*debug("client_wait_until_can_do_something"); */
|
||||||
|
|
||||||
/* Initialize select masks. */
|
/* Initialize select masks. */
|
||||||
FD_ZERO(readset);
|
FD_ZERO(readset);
|
||||||
|
FD_ZERO(writeset);
|
||||||
|
|
||||||
|
if (!compat20) {
|
||||||
/* Read from the connection, unless our buffers are full. */
|
/* Read from the connection, unless our buffers are full. */
|
||||||
if (buffer_len(&stdout_buffer) < buffer_high &&
|
if (buffer_len(&stdout_buffer) < buffer_high &&
|
||||||
buffer_len(&stderr_buffer) < buffer_high &&
|
buffer_len(&stderr_buffer) < buffer_high &&
|
||||||
channel_not_very_much_buffered_data())
|
channel_not_very_much_buffered_data())
|
||||||
FD_SET(connection_in, readset);
|
FD_SET(connection_in, readset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read from stdin, unless we have seen EOF or have very much
|
* Read from stdin, unless we have seen EOF or have very much
|
||||||
* buffered data to send to the server.
|
* buffered data to send to the server.
|
||||||
|
@ -317,7 +335,14 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset)
|
||||||
if (!stdin_eof && packet_not_very_much_data_to_write())
|
if (!stdin_eof && packet_not_very_much_data_to_write())
|
||||||
FD_SET(fileno(stdin), readset);
|
FD_SET(fileno(stdin), readset);
|
||||||
|
|
||||||
FD_ZERO(writeset);
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/* Add any selections by the channel mechanism. */
|
/* Add any selections by the channel mechanism. */
|
||||||
channel_prepare_select(readset, writeset);
|
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())
|
if (packet_have_data_to_write())
|
||||||
FD_SET(connection_out, writeset);
|
FD_SET(connection_out, writeset);
|
||||||
|
|
||||||
/* Select stdout if have data in buffer. */
|
/* move UP XXX */
|
||||||
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);
|
|
||||||
|
|
||||||
/* Update maximum file descriptor number, if appropriate. */
|
/* Update maximum file descriptor number, if appropriate. */
|
||||||
if (channel_max_fd() > max_fd)
|
if (channel_max_fd() > max_fd)
|
||||||
max_fd = channel_max_fd();
|
max_fd = channel_max_fd();
|
||||||
|
@ -408,10 +426,10 @@ client_suspend_self()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
client_process_input(fd_set * readset)
|
client_process_net_input(fd_set * readset)
|
||||||
{
|
{
|
||||||
int len, pid;
|
int len;
|
||||||
char buf[8192], *s;
|
char buf[8192];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read input from the server, and add any such data to the buffer of
|
* 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)) {
|
if (FD_ISSET(connection_in, readset)) {
|
||||||
/* Read as much as possible. */
|
/* Read as much as possible. */
|
||||||
len = read(connection_in, buf, sizeof(buf));
|
len = read(connection_in, buf, sizeof(buf));
|
||||||
|
/*debug("read connection_in len %d", len); XXX */
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
/* Received EOF. The remote host has closed the connection. */
|
/* Received EOF. The remote host has closed the connection. */
|
||||||
snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
|
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);
|
packet_process_incoming(buf, len);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
client_process_input(fd_set * readset)
|
||||||
|
{
|
||||||
|
int len, pid;
|
||||||
|
char buf[8192], *s;
|
||||||
|
|
||||||
/* Read input from stdin. */
|
/* Read input from stdin. */
|
||||||
if (FD_ISSET(fileno(stdin), readset)) {
|
if (FD_ISSET(fileno(stdin), readset)) {
|
||||||
/* Read as much as possible. */
|
/* Read as much as possible. */
|
||||||
|
@ -703,8 +730,6 @@ client_process_buffered_input_packets()
|
||||||
* character for terminating or suspending the session.
|
* character for terminating or suspending the session.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void client_init_dispatch(void);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
client_loop(int have_pty, int escape_char_arg)
|
client_loop(int have_pty, int escape_char_arg)
|
||||||
{
|
{
|
||||||
|
@ -753,6 +778,7 @@ client_loop(int have_pty, int escape_char_arg)
|
||||||
enter_raw_mode();
|
enter_raw_mode();
|
||||||
|
|
||||||
/* Check if we should immediately send of on stdin. */
|
/* Check if we should immediately send of on stdin. */
|
||||||
|
if (!compat20)
|
||||||
client_check_initial_eof_on_stdin();
|
client_check_initial_eof_on_stdin();
|
||||||
|
|
||||||
/* Main loop of the client for the interactive session mode. */
|
/* Main loop of the client for the interactive session mode. */
|
||||||
|
@ -762,10 +788,16 @@ client_loop(int have_pty, int escape_char_arg)
|
||||||
/* Process buffered packets sent by the server. */
|
/* Process buffered packets sent by the server. */
|
||||||
client_process_buffered_input_packets();
|
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
|
* Make packets of buffered stdin data, and buffer them for
|
||||||
* sending to the server.
|
* sending to the server.
|
||||||
*/
|
*/
|
||||||
|
if (!compat20)
|
||||||
client_make_packets_from_stdin_data();
|
client_make_packets_from_stdin_data();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -796,17 +828,21 @@ client_loop(int have_pty, int escape_char_arg)
|
||||||
/* Do channel operations. */
|
/* Do channel operations. */
|
||||||
channel_after_select(&readset, &writeset);
|
channel_after_select(&readset, &writeset);
|
||||||
|
|
||||||
/*
|
/* Buffer input from the connection. */
|
||||||
* Process input from the connection and from stdin. Buffer
|
client_process_net_input(&readset);
|
||||||
* any data that is available.
|
|
||||||
*/
|
|
||||||
client_process_input(&readset);
|
|
||||||
|
|
||||||
|
if (quit_pending)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!compat20) {
|
||||||
|
/* Buffer data from stdin */
|
||||||
|
client_process_input(&readset);
|
||||||
/*
|
/*
|
||||||
* Process output to stdout and stderr. Output to the
|
* Process output to stdout and stderr. Output to
|
||||||
* connection is processed elsewhere (above).
|
* the connection is processed elsewhere (above).
|
||||||
*/
|
*/
|
||||||
client_process_output(&writeset);
|
client_process_output(&writeset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send as much buffered packet data as possible to the sender. */
|
/* Send as much buffered packet data as possible to the sender. */
|
||||||
if (FD_ISSET(connection_out, &writeset))
|
if (FD_ISSET(connection_out, &writeset))
|
||||||
|
@ -917,6 +953,19 @@ client_input_exit_status(int type, int plen)
|
||||||
quit_pending = 1;
|
quit_pending = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
client_init_dispatch_13()
|
client_init_dispatch_13()
|
||||||
{
|
{
|
||||||
|
@ -944,8 +993,55 @@ client_init_dispatch_15()
|
||||||
void
|
void
|
||||||
client_init_dispatch()
|
client_init_dispatch()
|
||||||
{
|
{
|
||||||
if (compat13)
|
if (compat20)
|
||||||
|
client_init_dispatch_20();
|
||||||
|
else if (compat13)
|
||||||
client_init_dispatch_13();
|
client_init_dispatch_13();
|
||||||
else
|
else
|
||||||
client_init_dispatch_15();
|
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);
|
||||||
|
}
|
||||||
|
|
6
compat.c
6
compat.c
|
@ -28,7 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "ssh.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
@ -40,7 +40,9 @@ int datafellows = 0;
|
||||||
void
|
void
|
||||||
enable_compat20(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
|
void
|
||||||
enable_compat13(void)
|
enable_compat13(void)
|
||||||
|
|
|
@ -15,8 +15,8 @@ Copyright: BSD
|
||||||
Group: Applications/Internet
|
Group: Applications/Internet
|
||||||
BuildRoot: /tmp/openssh-%{version}-buildroot
|
BuildRoot: /tmp/openssh-%{version}-buildroot
|
||||||
Obsoletes: ssh
|
Obsoletes: ssh
|
||||||
PreReq: openssl
|
PreReq: openssl >= 0.9.5a
|
||||||
Requires: openssl
|
Requires: openssl >= 0.9.5a
|
||||||
BuildPreReq: perl
|
BuildPreReq: perl
|
||||||
BuildPreReq: openssl-devel
|
BuildPreReq: openssl-devel
|
||||||
BuildPreReq: tcp_wrappers
|
BuildPreReq: tcp_wrappers
|
||||||
|
|
11
kex.h
11
kex.h
|
@ -29,6 +29,17 @@
|
||||||
#ifndef KEX_H
|
#ifndef KEX_H
|
||||||
#define 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_DH1 "diffie-hellman-group1-sha1"
|
||||||
#define KEX_DSS "ssh-dss"
|
#define KEX_DSS "ssh-dss"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
32
packet.c
32
packet.c
|
@ -17,7 +17,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "xmalloc.h"
|
||||||
#include "buffer.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 "compat.h"
|
||||||
#include "ssh2.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 "buffer.h"
|
||||||
#include "kex.h"
|
#include "kex.h"
|
||||||
#include "hmac.h"
|
#include "hmac.h"
|
||||||
|
@ -152,8 +152,8 @@ packet_set_connection(int fd_in, int fd_out)
|
||||||
connection_in = fd_in;
|
connection_in = fd_in;
|
||||||
connection_out = fd_out;
|
connection_out = fd_out;
|
||||||
cipher_type = SSH_CIPHER_NONE;
|
cipher_type = SSH_CIPHER_NONE;
|
||||||
cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 1);
|
cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0);
|
||||||
cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 0);
|
cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0);
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
buffer_init(&input);
|
buffer_init(&input);
|
||||||
|
@ -352,8 +352,8 @@ packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
|
||||||
fatal("keylen too small: %d", keylen);
|
fatal("keylen too small: %d", keylen);
|
||||||
|
|
||||||
/* All other ciphers use the same key in both directions for now. */
|
/* All other ciphers use the same key in both directions for now. */
|
||||||
cipher_set_key(&receive_context, cipher, key, keylen, 0);
|
cipher_set_key(&receive_context, cipher, key, keylen);
|
||||||
cipher_set_key(&send_context, cipher, key, keylen, 1);
|
cipher_set_key(&send_context, cipher, key, keylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Starts constructing a packet to send. */
|
/* Starts constructing a packet to send. */
|
||||||
|
|
4
packet.h
4
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
|
#ifndef PACKET_H
|
||||||
#define PACKET_H
|
#define PACKET_H
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
166
ssh.c
166
ssh.c
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#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 "xmalloc.h"
|
||||||
#include "ssh.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 "authfd.h"
|
||||||
#include "readconf.h"
|
#include "readconf.h"
|
||||||
#include "uidswap.h"
|
#include "uidswap.h"
|
||||||
|
|
||||||
|
#include "ssh2.h"
|
||||||
|
#include "compat.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
|
|
||||||
#ifdef HAVE___PROGNAME
|
#ifdef HAVE___PROGNAME
|
||||||
|
@ -41,6 +44,10 @@ int debug_flag = 0;
|
||||||
|
|
||||||
int tty_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
|
* Flag indicating that nothing should be read from stdin. This can be set
|
||||||
* on the command line.
|
* on the command line.
|
||||||
|
@ -90,6 +97,9 @@ RSA *host_private_key = NULL;
|
||||||
/* Original real UID. */
|
/* Original real UID. */
|
||||||
uid_t 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. */
|
/* Prints a help message to the user. This function never returns. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -104,9 +114,9 @@ usage()
|
||||||
fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n");
|
fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n");
|
||||||
#endif /* AFS */
|
#endif /* AFS */
|
||||||
fprintf(stderr, " -x Disable X11 connection forwarding.\n");
|
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, " -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 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 Verbose; display verbose debugging messages.\n");
|
||||||
fprintf(stderr, " -V Display version number only.\n");
|
fprintf(stderr, " -V Display version number only.\n");
|
||||||
fprintf(stderr, " -P Don't allocate a privileged port.\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, " 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, " forward them to the other side by connecting to host:port.\n");
|
||||||
fprintf(stderr, " -C Enable compression.\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, " -g Allow remote hosts to connect to forwarded ports.\n");
|
||||||
fprintf(stderr, " -4 Use IPv4 only.\n");
|
fprintf(stderr, " -4 Use IPv4 only.\n");
|
||||||
fprintf(stderr, " -6 Use IPv6 only.\n");
|
fprintf(stderr, " -6 Use IPv6 only.\n");
|
||||||
|
@ -168,23 +179,22 @@ rsh_connect(char *host, char *user, Buffer * command)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ssh_session(void);
|
||||||
|
int ssh_session2(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main program for the ssh client.
|
* Main program for the ssh client.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
main(int ac, char **av)
|
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;
|
u_short fwd_port, fwd_host_port;
|
||||||
char *optarg, *cp, buf[256];
|
char *optarg, *cp, buf[256];
|
||||||
Buffer command;
|
|
||||||
struct winsize ws;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct passwd *pw, pwcopy;
|
struct passwd *pw, pwcopy;
|
||||||
int interactive = 0, dummy;
|
int dummy;
|
||||||
int have_pty = 0;
|
|
||||||
uid_t original_effective_uid;
|
uid_t original_effective_uid;
|
||||||
int plen;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save the original real uid. It will be needed later (uid-swapping
|
* Save the original real uid. It will be needed later (uid-swapping
|
||||||
|
@ -328,7 +338,7 @@ main(int ac, char **av)
|
||||||
case 'V':
|
case 'V':
|
||||||
fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
|
fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
|
||||||
SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
|
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')
|
if (opt == 'V')
|
||||||
exit(0);
|
exit(0);
|
||||||
debug_flag = 1;
|
debug_flag = 1;
|
||||||
|
@ -397,6 +407,15 @@ main(int ac, char **av)
|
||||||
options.compression = 1;
|
options.compression = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
no_shell_flag = 1;
|
||||||
|
no_tty_flag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
no_tty_flag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
dummy = 1;
|
dummy = 1;
|
||||||
if (process_config_line(&options, host ? host : "", optarg,
|
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");
|
fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
|
||||||
tty_flag = 0;
|
tty_flag = 0;
|
||||||
}
|
}
|
||||||
|
/* force */
|
||||||
|
if (no_tty_flag)
|
||||||
|
tty_flag = 0;
|
||||||
|
|
||||||
/* Get user data. */
|
/* Get user data. */
|
||||||
pw = getpwuid(original_real_uid);
|
pw = getpwuid(original_real_uid);
|
||||||
if (!pw) {
|
if (!pw) {
|
||||||
|
@ -620,6 +643,23 @@ main(int ac, char **av)
|
||||||
if (host_private_key_loaded)
|
if (host_private_key_loaded)
|
||||||
RSA_free(host_private_key); /* Destroys contents safely */
|
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. */
|
/* Enable compression if requested. */
|
||||||
if (options.compression) {
|
if (options.compression) {
|
||||||
debug("Requesting compression at level %d.", options.compression_level);
|
debug("Requesting compression at level %d.", options.compression_level);
|
||||||
|
@ -673,7 +713,7 @@ main(int ac, char **av)
|
||||||
type = packet_read(&plen);
|
type = packet_read(&plen);
|
||||||
if (type == SSH_SMSG_SUCCESS) {
|
if (type == SSH_SMSG_SUCCESS) {
|
||||||
interactive = 1;
|
interactive = 1;
|
||||||
have_pty = 1;
|
have_tty = 1;
|
||||||
} else if (type == SSH_SMSG_FAILURE)
|
} else if (type == SSH_SMSG_FAILURE)
|
||||||
log("Warning: Remote host failed or refused to allocate a pseudo tty.");
|
log("Warning: Remote host failed or refused to allocate a pseudo tty.");
|
||||||
else
|
else
|
||||||
|
@ -802,11 +842,103 @@ main(int ac, char **av)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter the interactive session. */
|
/* 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)
|
||||||
/* Exit with the status returned by the program on the remote side. */
|
{
|
||||||
exit(exit_status);
|
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);
|
||||||
|
|
||||||
|
return client_loop(tty_flag, tty_flag ? options.escape_char : -1);
|
||||||
}
|
}
|
||||||
|
|
344
sshconnect.c
344
sshconnect.c
|
@ -5,27 +5,30 @@
|
||||||
* Created: Sat Mar 18 22:15:47 1995 ylo
|
* Created: Sat Mar 18 22:15:47 1995 ylo
|
||||||
* Code to connect to a remote host, and to perform the client side of the
|
* Code to connect to a remote host, and to perform the client side of the
|
||||||
* login (authentication) dialog.
|
* login (authentication) dialog.
|
||||||
|
*
|
||||||
|
* SSH2 support added by Markus Friedl.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $");
|
RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $");
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
|
#include <openssl/bn.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
#include <openssl/bn.h>
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SSL
|
#ifdef HAVE_SSL
|
||||||
|
#include <ssl/bn.h>
|
||||||
#include <ssl/rsa.h>
|
#include <ssl/rsa.h>
|
||||||
#include <ssl/dsa.h>
|
#include <ssl/dsa.h>
|
||||||
#include <ssl/md5.h>
|
#include <ssl/md5.h>
|
||||||
#include <ssl/bn.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "ssh.h"
|
#include "ssh.h"
|
||||||
|
#include "buffer.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "authfd.h"
|
#include "authfd.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
|
@ -33,7 +36,14 @@ RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $");
|
||||||
#include "uidswap.h"
|
#include "uidswap.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "readconf.h"
|
#include "readconf.h"
|
||||||
|
|
||||||
|
#include "bufaux.h"
|
||||||
|
|
||||||
|
#include "ssh2.h"
|
||||||
|
#include "kex.h"
|
||||||
|
#include "myproposal.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
|
#include "dsa.h"
|
||||||
#include "hostfile.h"
|
#include "hostfile.h"
|
||||||
|
|
||||||
/* Session id for the current session. */
|
/* Session id for the current session. */
|
||||||
|
@ -42,6 +52,9 @@ unsigned char session_id[16];
|
||||||
/* authentications supported by server */
|
/* authentications supported by server */
|
||||||
unsigned int supported_authentications;
|
unsigned int supported_authentications;
|
||||||
|
|
||||||
|
static char *client_version_string = NULL;
|
||||||
|
static char *server_version_string = NULL;
|
||||||
|
|
||||||
extern Options options;
|
extern Options options;
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
|
@ -957,6 +970,21 @@ try_password_authentication(char *prompt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
chop(char *s)
|
||||||
|
{
|
||||||
|
char *t = s;
|
||||||
|
while (*t) {
|
||||||
|
if(*t == '\n' || *t == '\r') {
|
||||||
|
*t = '\0';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Waits for the server identification string, and sends our own
|
* Waits for the server identification string, and sends our own
|
||||||
* identification string.
|
* identification string.
|
||||||
|
@ -979,7 +1007,7 @@ ssh_exchange_identification()
|
||||||
if (buf[i] == '\r') {
|
if (buf[i] == '\r') {
|
||||||
buf[i] = '\n';
|
buf[i] = '\n';
|
||||||
buf[i + 1] = 0;
|
buf[i + 1] = 0;
|
||||||
break;
|
continue; /**XXX wait for \n */
|
||||||
}
|
}
|
||||||
if (buf[i] == '\n') {
|
if (buf[i] == '\n') {
|
||||||
buf[i + 1] = 0;
|
buf[i + 1] = 0;
|
||||||
|
@ -987,17 +1015,21 @@ ssh_exchange_identification()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[sizeof(buf) - 1] = 0;
|
buf[sizeof(buf) - 1] = 0;
|
||||||
|
server_version_string = xstrdup(buf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the versions match. In future this might accept
|
* Check that the versions match. In future this might accept
|
||||||
* several versions and set appropriate flags to handle them.
|
* several versions and set appropriate flags to handle them.
|
||||||
*/
|
*/
|
||||||
if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
|
if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
|
||||||
remote_version) != 3)
|
&remote_major, &remote_minor, remote_version) != 3)
|
||||||
fatal("Bad remote protocol version identification: '%.100s'", buf);
|
fatal("Bad remote protocol version identification: '%.100s'", buf);
|
||||||
debug("Remote protocol version %d.%d, remote software version %.100s",
|
debug("Remote protocol version %d.%d, remote software version %.100s",
|
||||||
remote_major, remote_minor, remote_version);
|
remote_major, remote_minor, remote_version);
|
||||||
|
|
||||||
|
/*** XXX option for disabling 2.0 or 1.5 */
|
||||||
|
compat_datafellows(remote_version);
|
||||||
|
|
||||||
/* Check if the remote protocol version is too old. */
|
/* Check if the remote protocol version is too old. */
|
||||||
if (remote_major == 1 && remote_minor < 3)
|
if (remote_major == 1 && remote_minor < 3)
|
||||||
fatal("Remote machine has too old SSH software version.");
|
fatal("Remote machine has too old SSH software version.");
|
||||||
|
@ -1010,6 +1042,10 @@ ssh_exchange_identification()
|
||||||
options.forward_agent = 0;
|
options.forward_agent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((remote_major == 2 && remote_minor == 0) ||
|
||||||
|
(remote_major == 1 && remote_minor == 99)) {
|
||||||
|
enable_compat20();
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Removed for now, to permit compatibility with latter versions. The
|
* Removed for now, to permit compatibility with latter versions. The
|
||||||
|
@ -1020,16 +1056,19 @@ ssh_exchange_identification()
|
||||||
fatal("Protocol major versions differ: %d vs. %d",
|
fatal("Protocol major versions differ: %d vs. %d",
|
||||||
PROTOCOL_MAJOR, remote_major);
|
PROTOCOL_MAJOR, remote_major);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Send our own protocol version identification. */
|
/* Send our own protocol version identification. */
|
||||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
|
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
|
||||||
PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
|
compat20 ? 2 : PROTOCOL_MAJOR,
|
||||||
|
compat20 ? 0 : PROTOCOL_MINOR,
|
||||||
|
SSH_VERSION);
|
||||||
if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
|
if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
|
||||||
fatal("write: %.100s", strerror(errno));
|
fatal("write: %.100s", strerror(errno));
|
||||||
|
client_version_string = xstrdup(buf);
|
||||||
|
chop(client_version_string);
|
||||||
|
chop(server_version_string);
|
||||||
|
debug("Local version string %.100s", client_version_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_cipher_default = SSH_CIPHER_3DES;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
read_yes_or_no(const char *prompt, int defval)
|
read_yes_or_no(const char *prompt, int defval)
|
||||||
{
|
{
|
||||||
|
@ -1282,6 +1321,278 @@ check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
|
||||||
check_host_key(host, hostaddr, &k);
|
check_host_key(host, hostaddr, &k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SSH2 key exchange
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||||
|
{
|
||||||
|
Kex *kex;
|
||||||
|
char *cprop[PROPOSAL_MAX];
|
||||||
|
char *sprop[PROPOSAL_MAX];
|
||||||
|
Buffer *client_kexinit;
|
||||||
|
Buffer *server_kexinit;
|
||||||
|
int payload_len, dlen;
|
||||||
|
unsigned int klen, kout;
|
||||||
|
char *ptr;
|
||||||
|
char *signature = NULL;
|
||||||
|
unsigned int slen;
|
||||||
|
char *server_host_key_blob = NULL;
|
||||||
|
Key *server_host_key;
|
||||||
|
unsigned int sbloblen;
|
||||||
|
DH *dh;
|
||||||
|
BIGNUM *dh_server_pub = 0;
|
||||||
|
BIGNUM *shared_secret = 0;
|
||||||
|
int i;
|
||||||
|
unsigned char *kbuf;
|
||||||
|
unsigned char *hash;
|
||||||
|
|
||||||
|
/* KEXINIT */
|
||||||
|
|
||||||
|
debug("Sending KEX init.");
|
||||||
|
if (options.cipher == SSH_CIPHER_ARCFOUR ||
|
||||||
|
options.cipher == SSH_CIPHER_3DES_CBC ||
|
||||||
|
options.cipher == SSH_CIPHER_CAST128_CBC ||
|
||||||
|
options.cipher == SSH_CIPHER_BLOWFISH_CBC) {
|
||||||
|
myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher);
|
||||||
|
myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);
|
||||||
|
}
|
||||||
|
if (options.compression) {
|
||||||
|
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
|
||||||
|
myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
|
||||||
|
} else {
|
||||||
|
myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
|
||||||
|
myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
|
||||||
|
}
|
||||||
|
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||||
|
cprop[i] = xstrdup(myproposal[i]);
|
||||||
|
|
||||||
|
client_kexinit = kex_init(cprop);
|
||||||
|
packet_start(SSH2_MSG_KEXINIT);
|
||||||
|
packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit));
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
|
||||||
|
debug("done");
|
||||||
|
|
||||||
|
packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
|
||||||
|
|
||||||
|
/* save payload for session_id */
|
||||||
|
server_kexinit = xmalloc(sizeof(*server_kexinit));
|
||||||
|
buffer_init(server_kexinit);
|
||||||
|
ptr = packet_get_raw(&payload_len);
|
||||||
|
buffer_append(server_kexinit, ptr, payload_len);
|
||||||
|
|
||||||
|
/* skip cookie */
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
(void) packet_get_char();
|
||||||
|
/* kex init proposal strings */
|
||||||
|
for (i = 0; i < PROPOSAL_MAX; i++) {
|
||||||
|
sprop[i] = packet_get_string(NULL);
|
||||||
|
debug("got kexinit string: %s", sprop[i]);
|
||||||
|
}
|
||||||
|
i = (int) packet_get_char();
|
||||||
|
debug("first kex follow == %d", i);
|
||||||
|
i = packet_get_int();
|
||||||
|
debug("reserved == %d", i);
|
||||||
|
|
||||||
|
debug("done read kexinit");
|
||||||
|
kex = kex_choose_conf(cprop, sprop, 0);
|
||||||
|
|
||||||
|
/* KEXDH */
|
||||||
|
|
||||||
|
debug("Sending SSH2_MSG_KEXDH_INIT.");
|
||||||
|
|
||||||
|
/* generate and send 'e', client DH public key */
|
||||||
|
dh = new_dh_group1();
|
||||||
|
packet_start(SSH2_MSG_KEXDH_INIT);
|
||||||
|
packet_put_bignum2(dh->pub_key);
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEXDH
|
||||||
|
fprintf(stderr, "\np= ");
|
||||||
|
bignum_print(dh->p);
|
||||||
|
fprintf(stderr, "\ng= ");
|
||||||
|
bignum_print(dh->g);
|
||||||
|
fprintf(stderr, "\npub= ");
|
||||||
|
bignum_print(dh->pub_key);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
DHparams_print_fp(stderr, dh);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
debug("Wait SSH2_MSG_KEXDH_REPLY.");
|
||||||
|
|
||||||
|
packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY);
|
||||||
|
|
||||||
|
debug("Got SSH2_MSG_KEXDH_REPLY.");
|
||||||
|
|
||||||
|
/* key, cert */
|
||||||
|
server_host_key_blob = packet_get_string(&sbloblen);
|
||||||
|
server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen);
|
||||||
|
if (server_host_key == NULL)
|
||||||
|
fatal("cannot decode server_host_key_blob");
|
||||||
|
|
||||||
|
check_host_key(host, hostaddr, server_host_key);
|
||||||
|
|
||||||
|
/* DH paramter f, server public DH key */
|
||||||
|
dh_server_pub = BN_new();
|
||||||
|
if (dh_server_pub == NULL)
|
||||||
|
fatal("dh_server_pub == NULL");
|
||||||
|
packet_get_bignum2(dh_server_pub, &dlen);
|
||||||
|
|
||||||
|
#ifdef DEBUG_KEXDH
|
||||||
|
fprintf(stderr, "\ndh_server_pub= ");
|
||||||
|
bignum_print(dh_server_pub);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
debug("bits %d", BN_num_bits(dh_server_pub));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* signed H */
|
||||||
|
signature = packet_get_string(&slen);
|
||||||
|
|
||||||
|
klen = DH_size(dh);
|
||||||
|
kbuf = xmalloc(klen);
|
||||||
|
kout = DH_compute_key(kbuf, dh_server_pub, dh);
|
||||||
|
#ifdef DEBUG_KEXDH
|
||||||
|
debug("shared secret: len %d/%d", klen, kout);
|
||||||
|
fprintf(stderr, "shared secret == ");
|
||||||
|
for (i = 0; i< kout; i++)
|
||||||
|
fprintf(stderr, "%02x", (kbuf[i])&0xff);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
#endif
|
||||||
|
shared_secret = BN_new();
|
||||||
|
|
||||||
|
BN_bin2bn(kbuf, kout, shared_secret);
|
||||||
|
memset(kbuf, 0, klen);
|
||||||
|
xfree(kbuf);
|
||||||
|
|
||||||
|
/* calc and verify H */
|
||||||
|
hash = kex_hash(
|
||||||
|
client_version_string,
|
||||||
|
server_version_string,
|
||||||
|
buffer_ptr(client_kexinit), buffer_len(client_kexinit),
|
||||||
|
buffer_ptr(server_kexinit), buffer_len(server_kexinit),
|
||||||
|
server_host_key_blob, sbloblen,
|
||||||
|
dh->pub_key,
|
||||||
|
dh_server_pub,
|
||||||
|
shared_secret
|
||||||
|
);
|
||||||
|
buffer_free(client_kexinit);
|
||||||
|
buffer_free(server_kexinit);
|
||||||
|
xfree(client_kexinit);
|
||||||
|
xfree(server_kexinit);
|
||||||
|
#ifdef DEBUG_KEXDH
|
||||||
|
fprintf(stderr, "hash == ");
|
||||||
|
for (i = 0; i< 20; i++)
|
||||||
|
fprintf(stderr, "%02x", (hash[i])&0xff);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
#endif
|
||||||
|
dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);
|
||||||
|
key_free(server_host_key);
|
||||||
|
|
||||||
|
kex_derive_keys(kex, hash, shared_secret);
|
||||||
|
packet_set_kex(kex);
|
||||||
|
|
||||||
|
/* have keys, free DH */
|
||||||
|
DH_free(dh);
|
||||||
|
|
||||||
|
debug("Wait SSH2_MSG_NEWKEYS.");
|
||||||
|
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
|
||||||
|
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||||
|
|
||||||
|
debug("send SSH2_MSG_NEWKEYS.");
|
||||||
|
packet_start(SSH2_MSG_NEWKEYS);
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||||
|
|
||||||
|
/* send 1st encrypted/maced/compressed message */
|
||||||
|
packet_start(SSH2_MSG_IGNORE);
|
||||||
|
packet_put_cstring("markus");
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
|
||||||
|
debug("done: KEX2.");
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Authenticate user
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ssh_userauth2(int host_key_valid, RSA *own_host_key,
|
||||||
|
uid_t original_real_uid, char *host)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
int plen;
|
||||||
|
unsigned int dlen;
|
||||||
|
int partial;
|
||||||
|
struct passwd *pw;
|
||||||
|
char *server_user, *local_user;
|
||||||
|
char *auths;
|
||||||
|
char *password;
|
||||||
|
char *service = "ssh-connection"; // service name
|
||||||
|
|
||||||
|
debug("send SSH2_MSG_SERVICE_REQUEST");
|
||||||
|
packet_start(SSH2_MSG_SERVICE_REQUEST);
|
||||||
|
packet_put_cstring("ssh-userauth");
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
|
||||||
|
type = packet_read(&plen);
|
||||||
|
if (type != SSH2_MSG_SERVICE_ACCEPT) {
|
||||||
|
fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
|
||||||
|
}
|
||||||
|
/* payload empty for ssh-2.0.13 ?? */
|
||||||
|
/* reply = packet_get_string(&payload_len); */
|
||||||
|
debug("got SSH2_MSG_SERVICE_ACCEPT");
|
||||||
|
|
||||||
|
/*XX COMMONCODE: */
|
||||||
|
/* Get local user name. Use it as server user if no user name was given. */
|
||||||
|
pw = getpwuid(original_real_uid);
|
||||||
|
if (!pw)
|
||||||
|
fatal("User id %d not found from user database.", original_real_uid);
|
||||||
|
local_user = xstrdup(pw->pw_name);
|
||||||
|
server_user = options.user ? options.user : local_user;
|
||||||
|
|
||||||
|
/* INITIAL request for auth */
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
|
packet_put_cstring(server_user);
|
||||||
|
packet_put_cstring(service);
|
||||||
|
packet_put_cstring("none");
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
type = packet_read(&plen);
|
||||||
|
if (type == SSH2_MSG_USERAUTH_SUCCESS)
|
||||||
|
break;
|
||||||
|
if (type != SSH2_MSG_USERAUTH_FAILURE)
|
||||||
|
fatal("access denied: %d", type);
|
||||||
|
/* SSH2_MSG_USERAUTH_FAILURE means: try again */
|
||||||
|
auths = packet_get_string(&dlen);
|
||||||
|
debug("authentications that can continue: %s", auths);
|
||||||
|
partial = packet_get_char();
|
||||||
|
if (partial)
|
||||||
|
debug("partial success");
|
||||||
|
if (strstr(auths, "password") == NULL)
|
||||||
|
fatal("passwd auth not supported: %s", auths);
|
||||||
|
xfree(auths);
|
||||||
|
/* try passwd */
|
||||||
|
password = read_passphrase("password: ", 0);
|
||||||
|
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
|
packet_put_cstring(server_user);
|
||||||
|
packet_put_cstring(service);
|
||||||
|
packet_put_cstring("password");
|
||||||
|
packet_put_char(0);
|
||||||
|
packet_put_cstring(password);
|
||||||
|
memset(password, 0, strlen(password));
|
||||||
|
xfree(password);
|
||||||
|
packet_send();
|
||||||
|
packet_write_wait();
|
||||||
|
}
|
||||||
|
debug("ssh-userauth2 successfull");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SSH1 key exchange
|
* SSH1 key exchange
|
||||||
*/
|
*/
|
||||||
|
@ -1293,6 +1604,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||||
RSA *host_key;
|
RSA *host_key;
|
||||||
RSA *public_key;
|
RSA *public_key;
|
||||||
int bits, rbits;
|
int bits, rbits;
|
||||||
|
int ssh_cipher_default = SSH_CIPHER_3DES;
|
||||||
unsigned char session_key[SSH_SESSION_KEY_LENGTH];
|
unsigned char session_key[SSH_SESSION_KEY_LENGTH];
|
||||||
unsigned char cookie[8];
|
unsigned char cookie[8];
|
||||||
unsigned int supported_ciphers;
|
unsigned int supported_ciphers;
|
||||||
|
@ -1427,7 +1739,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
|
||||||
RSA_free(host_key);
|
RSA_free(host_key);
|
||||||
|
|
||||||
if (options.cipher == SSH_CIPHER_NOT_SET) {
|
if (options.cipher == SSH_CIPHER_NOT_SET) {
|
||||||
if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default))
|
if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
|
||||||
options.cipher = ssh_cipher_default;
|
options.cipher = ssh_cipher_default;
|
||||||
else {
|
else {
|
||||||
debug("Cipher %s not supported, using %.100s instead.",
|
debug("Cipher %s not supported, using %.100s instead.",
|
||||||
|
@ -1640,12 +1952,16 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
|
||||||
/* Put the connection into non-blocking mode. */
|
/* Put the connection into non-blocking mode. */
|
||||||
packet_set_nonblocking();
|
packet_set_nonblocking();
|
||||||
|
|
||||||
supported_authentications = 0;
|
|
||||||
/* key exchange */
|
/* key exchange */
|
||||||
|
/* authenticate user */
|
||||||
|
if (compat20) {
|
||||||
|
ssh_kex2(host, hostaddr);
|
||||||
|
ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host);
|
||||||
|
} else {
|
||||||
|
supported_authentications = 0;
|
||||||
ssh_kex(host, hostaddr);
|
ssh_kex(host, hostaddr);
|
||||||
if (supported_authentications == 0)
|
if (supported_authentications == 0)
|
||||||
fatal("supported_authentications == 0.");
|
fatal("supported_authentications == 0.");
|
||||||
|
|
||||||
/* authenticate user */
|
|
||||||
ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);
|
ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
4
sshd.c
4
sshd.c
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshd.c,v 1.96 2000/03/28 21:15:45 markus Exp $");
|
RCSID("$OpenBSD: sshd.c,v 1.97 2000/04/04 21:37:27 markus Exp $");
|
||||||
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
|
@ -911,7 +911,7 @@ do_ssh1_kex()
|
||||||
packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
|
packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
|
||||||
|
|
||||||
/* Declare which ciphers we support. */
|
/* Declare which ciphers we support. */
|
||||||
packet_put_int(cipher_mask());
|
packet_put_int(cipher_mask1());
|
||||||
|
|
||||||
/* Declare supported authentication types. */
|
/* Declare supported authentication types. */
|
||||||
auth_mask = 0;
|
auth_mask = 0;
|
||||||
|
|
Loading…
Reference in New Issue