mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-26 01:32:25 +00:00
SSH compression by linking with zlib.dll if present (compression
quietly becomes unavailable if zlib.dll not found). Thanks to Joris van Rantwijk (again). [originally from svn r511]
This commit is contained in:
parent
7a01fd48b6
commit
e3e48f45c7
9
putty.h
9
putty.h
@ -134,6 +134,7 @@ typedef struct {
|
|||||||
int nopty;
|
int nopty;
|
||||||
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
||||||
int try_tis_auth;
|
int try_tis_auth;
|
||||||
|
int ssh_compression;
|
||||||
/* Telnet options */
|
/* Telnet options */
|
||||||
char termtype[32];
|
char termtype[32];
|
||||||
char termspeed[32];
|
char termspeed[32];
|
||||||
@ -194,6 +195,14 @@ GLOBAL int default_port;
|
|||||||
|
|
||||||
struct RSAKey; /* be a little careful of scope */
|
struct RSAKey; /* be a little careful of scope */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needed for PuTTY Secure Copy
|
||||||
|
*/
|
||||||
|
#define SCP_FLAG 1
|
||||||
|
#define SCP_VERBOSE 2
|
||||||
|
#define IS_SCP ((scp_flags & SCP_FLAG) != 0)
|
||||||
|
GLOBAL int scp_flags;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exports from window.c.
|
* Exports from window.c.
|
||||||
*/
|
*/
|
||||||
|
5
scp.h
5
scp.h
@ -3,12 +3,7 @@
|
|||||||
* Joris van Rantwijk, Aug 1999, Jun 2000.
|
* Joris van Rantwijk, Aug 1999, Jun 2000.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SCP_FLAG 1
|
|
||||||
#define SCP_VERBOSE 2
|
|
||||||
#define IS_SCP ((scp_flags & SCP_FLAG) != 0)
|
|
||||||
|
|
||||||
/* Exported from ssh.c */
|
/* Exported from ssh.c */
|
||||||
extern int scp_flags;
|
|
||||||
extern void (*ssh_get_password)(const char *prompt, char *str, int maxlen);
|
extern void (*ssh_get_password)(const char *prompt, char *str, int maxlen);
|
||||||
char * ssh_scp_init(char *host, int port, char *cmd, char **realhost);
|
char * ssh_scp_init(char *host, int port, char *cmd, char **realhost);
|
||||||
int ssh_scp_recv(unsigned char *buf, int len);
|
int ssh_scp_recv(unsigned char *buf, int len);
|
||||||
|
103
ssh.c
103
ssh.c
@ -15,10 +15,6 @@
|
|||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define logevent(s) { logevent(s); \
|
|
||||||
if (IS_SCP && (scp_flags & SCP_VERBOSE) != 0) \
|
|
||||||
fprintf(stderr, "%s\n", s); }
|
|
||||||
|
|
||||||
#define SSH_MSG_DISCONNECT 1
|
#define SSH_MSG_DISCONNECT 1
|
||||||
#define SSH_SMSG_PUBLIC_KEY 2
|
#define SSH_SMSG_PUBLIC_KEY 2
|
||||||
#define SSH_CMSG_SESSION_KEY 3
|
#define SSH_CMSG_SESSION_KEY 3
|
||||||
@ -38,11 +34,13 @@
|
|||||||
#define SSH_CMSG_EXIT_CONFIRMATION 33
|
#define SSH_CMSG_EXIT_CONFIRMATION 33
|
||||||
#define SSH_MSG_IGNORE 32
|
#define SSH_MSG_IGNORE 32
|
||||||
#define SSH_MSG_DEBUG 36
|
#define SSH_MSG_DEBUG 36
|
||||||
|
#define SSH_CMSG_REQUEST_COMPRESSION 37
|
||||||
#define SSH_CMSG_AUTH_TIS 39
|
#define SSH_CMSG_AUTH_TIS 39
|
||||||
#define SSH_SMSG_AUTH_TIS_CHALLENGE 40
|
#define SSH_SMSG_AUTH_TIS_CHALLENGE 40
|
||||||
#define SSH_CMSG_AUTH_TIS_RESPONSE 41
|
#define SSH_CMSG_AUTH_TIS_RESPONSE 41
|
||||||
|
|
||||||
#define SSH_AUTH_TIS 5
|
#define SSH_AUTH_TIS 5
|
||||||
|
#define COMPRESSION_LEVEL 5
|
||||||
|
|
||||||
#define GET_32BIT(cp) \
|
#define GET_32BIT(cp) \
|
||||||
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
|
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
|
||||||
@ -80,7 +78,7 @@ static SOCKET s = INVALID_SOCKET;
|
|||||||
|
|
||||||
static unsigned char session_key[32];
|
static unsigned char session_key[32];
|
||||||
static struct ssh_cipher *cipher = NULL;
|
static struct ssh_cipher *cipher = NULL;
|
||||||
int scp_flags = 0;
|
static int use_compression = 0;
|
||||||
void (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
|
void (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
|
||||||
|
|
||||||
static char *savedhost;
|
static char *savedhost;
|
||||||
@ -155,6 +153,24 @@ static void ssh_protocol(unsigned char *in, int inlen, int ispkt);
|
|||||||
static void ssh_size(void);
|
static void ssh_size(void);
|
||||||
|
|
||||||
|
|
||||||
|
static void pktalloc(struct Packet *pkt, long newlen)
|
||||||
|
{
|
||||||
|
if (pkt->maxlen < newlen) {
|
||||||
|
pkt->maxlen = newlen;
|
||||||
|
#ifdef MSCRYPTOAPI
|
||||||
|
/* Allocate enough buffer space for extra block
|
||||||
|
* for MS CryptEncrypt() */
|
||||||
|
pkt->data = (pkt->data == NULL ? malloc(newlen+8) :
|
||||||
|
realloc(pkt->data, newlen+8));
|
||||||
|
#else
|
||||||
|
pkt->data = (pkt->data == NULL ? malloc(newlen) :
|
||||||
|
realloc(pkt->data, newlen));
|
||||||
|
#endif
|
||||||
|
if (!pkt->data)
|
||||||
|
fatalbox("Out of memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Collect incoming data in the incoming packet buffer.
|
* Collect incoming data in the incoming packet buffer.
|
||||||
* Decihper and verify the packet when it is completely read.
|
* Decihper and verify the packet when it is completely read.
|
||||||
@ -192,22 +208,9 @@ next_packet:
|
|||||||
|
|
||||||
pad = 8 - (len % 8);
|
pad = 8 - (len % 8);
|
||||||
biglen = len + pad;
|
biglen = len + pad;
|
||||||
pktin.length = len - 5;
|
|
||||||
|
|
||||||
if (pktin.maxlen < biglen) {
|
if (pktin.maxlen < biglen)
|
||||||
pktin.maxlen = biglen;
|
pktalloc(&pktin, biglen);
|
||||||
#ifdef MSCRYPTOAPI
|
|
||||||
/* Allocate enough buffer space for extra block
|
|
||||||
* for MS CryptEncrypt() */
|
|
||||||
pktin.data = (pktin.data == NULL ? malloc(biglen+8) :
|
|
||||||
realloc(pktin.data, biglen+8));
|
|
||||||
#else
|
|
||||||
pktin.data = (pktin.data == NULL ? malloc(biglen) :
|
|
||||||
realloc(pktin.data, biglen));
|
|
||||||
#endif
|
|
||||||
if (!pktin.data)
|
|
||||||
fatalbox("Out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
to_read = biglen;
|
to_read = biglen;
|
||||||
p = pktin.data;
|
p = pktin.data;
|
||||||
@ -228,15 +231,23 @@ next_packet:
|
|||||||
if (cipher)
|
if (cipher)
|
||||||
cipher->decrypt(pktin.data, biglen);
|
cipher->decrypt(pktin.data, biglen);
|
||||||
|
|
||||||
pktin.type = pktin.data[pad];
|
|
||||||
pktin.body = pktin.data + pad + 1;
|
|
||||||
|
|
||||||
realcrc = crc32(pktin.data, biglen-4);
|
realcrc = crc32(pktin.data, biglen-4);
|
||||||
gotcrc = GET_32BIT(pktin.data+biglen-4);
|
gotcrc = GET_32BIT(pktin.data+biglen-4);
|
||||||
if (gotcrc != realcrc) {
|
if (gotcrc != realcrc) {
|
||||||
fatalbox("Incorrect CRC received on packet");
|
fatalbox("Incorrect CRC received on packet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_compression) {
|
||||||
|
ssh_decompress(pktin.data + pad, len - 4, &p, &len);
|
||||||
|
pktin.length = len - 1;
|
||||||
|
pktin.type = p[0];
|
||||||
|
pktin.body = p + 1;
|
||||||
|
} else {
|
||||||
|
pktin.length = len - 5;
|
||||||
|
pktin.type = pktin.data[pad];
|
||||||
|
pktin.body = pktin.data + pad + 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (pktin.type == SSH_SMSG_STDOUT_DATA ||
|
if (pktin.type == SSH_SMSG_STDOUT_DATA ||
|
||||||
pktin.type == SSH_SMSG_STDERR_DATA ||
|
pktin.type == SSH_SMSG_STDERR_DATA ||
|
||||||
pktin.type == SSH_MSG_DEBUG ||
|
pktin.type == SSH_MSG_DEBUG ||
|
||||||
@ -281,20 +292,8 @@ static void s_wrpkt_start(int type, int len) {
|
|||||||
biglen = len + pad;
|
biglen = len + pad;
|
||||||
|
|
||||||
pktout.length = len-5;
|
pktout.length = len-5;
|
||||||
if (pktout.maxlen < biglen) {
|
if (pktout.maxlen < biglen + 4)
|
||||||
pktout.maxlen = biglen;
|
pktalloc(&pktout, biglen + 4);
|
||||||
#ifdef MSCRYPTOAPI
|
|
||||||
/* Allocate enough buffer space for extra block
|
|
||||||
* for MS CryptEncrypt() */
|
|
||||||
pktout.data = (pktout.data == NULL ? malloc(biglen+12) :
|
|
||||||
realloc(pktout.data, biglen+12));
|
|
||||||
#else
|
|
||||||
pktout.data = (pktout.data == NULL ? malloc(biglen+4) :
|
|
||||||
realloc(pktout.data, biglen+4));
|
|
||||||
#endif
|
|
||||||
if (!pktout.data)
|
|
||||||
fatalbox("Out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
pktout.type = type;
|
pktout.type = type;
|
||||||
pktout.body = pktout.data+4+pad+1;
|
pktout.body = pktout.data+4+pad+1;
|
||||||
@ -307,8 +306,21 @@ static void s_wrpkt(void) {
|
|||||||
len = pktout.length + 5; /* type and CRC */
|
len = pktout.length + 5; /* type and CRC */
|
||||||
pad = 8 - (len%8);
|
pad = 8 - (len%8);
|
||||||
biglen = len + pad;
|
biglen = len + pad;
|
||||||
|
|
||||||
pktout.body[-1] = pktout.type;
|
pktout.body[-1] = pktout.type;
|
||||||
|
|
||||||
|
if (use_compression) {
|
||||||
|
unsigned char *p;
|
||||||
|
unsigned int n;
|
||||||
|
pktout.body = NULL;
|
||||||
|
ssh_compress(pktout.data + 4 + pad, pktout.length + 1, &p, &n);
|
||||||
|
len = n + 4;
|
||||||
|
pad = 8 - (len%8);
|
||||||
|
biglen = len + pad;
|
||||||
|
if (pktout.maxlen < biglen + 4)
|
||||||
|
pktalloc(&pktout, biglen + 4);
|
||||||
|
memcpy(pktout.data + 4 + pad, p, n);
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<pad; i++)
|
for (i=0; i<pad; i++)
|
||||||
pktout.data[i+4] = random_byte();
|
pktout.data[i+4] = random_byte();
|
||||||
crc = crc32(pktout.data+4, biglen-4);
|
crc = crc32(pktout.data+4, biglen-4);
|
||||||
@ -853,6 +865,21 @@ static int do_ssh_login(unsigned char *in, int inlen, int ispkt)
|
|||||||
|
|
||||||
logevent("Authentication successful");
|
logevent("Authentication successful");
|
||||||
|
|
||||||
|
if (cfg.ssh_compression &&
|
||||||
|
ssh_compression_init(COMPRESSION_LEVEL)) {
|
||||||
|
send_packet(SSH_CMSG_REQUEST_COMPRESSION,
|
||||||
|
PKT_INT, COMPRESSION_LEVEL, PKT_END);
|
||||||
|
crWaitUntil(ispkt);
|
||||||
|
if (pktin.type == SSH_SMSG_SUCCESS) {
|
||||||
|
use_compression = 1;
|
||||||
|
logevent("Enabled SSH packet compression");
|
||||||
|
} else if (pktin.type == SSH_SMSG_FAILURE) {
|
||||||
|
logevent("Server does not support packet compression");
|
||||||
|
} else {
|
||||||
|
fatalbox("Strange packet received, type %d", pktin.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crFinish(1);
|
crFinish(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
ssh.h
7
ssh.h
@ -62,3 +62,10 @@ int random_byte(void);
|
|||||||
void random_add_noise(void *noise, int length);
|
void random_add_noise(void *noise, int length);
|
||||||
|
|
||||||
void logevent (char *);
|
void logevent (char *);
|
||||||
|
|
||||||
|
int ssh_compression_init(int);
|
||||||
|
void ssh_compress(unsigned char *src, unsigned int srclen,
|
||||||
|
unsigned char **dest, unsigned int *destlen);
|
||||||
|
void ssh_decompress(unsigned char *src, unsigned int srclen,
|
||||||
|
unsigned char **dest, unsigned int *destlen);
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
#define IDC3_CIPHERBLOWF 1021
|
#define IDC3_CIPHERBLOWF 1021
|
||||||
#define IDC3_CIPHERDES 1022
|
#define IDC3_CIPHERDES 1022
|
||||||
#define IDC3_AUTHTIS 1023
|
#define IDC3_AUTHTIS 1023
|
||||||
|
#define IDC3_COMPRESS 1024
|
||||||
|
|
||||||
#define IDC4_MBSTATIC 1001
|
#define IDC4_MBSTATIC 1001
|
||||||
#define IDC4_MBWINDOWS 1002
|
#define IDC4_MBWINDOWS 1002
|
||||||
|
@ -198,6 +198,7 @@ BEGIN
|
|||||||
AUTORADIOBUTTON "&Blowfish", IDC3_CIPHERBLOWF, 84, 50, 40, 10
|
AUTORADIOBUTTON "&Blowfish", IDC3_CIPHERBLOWF, 84, 50, 40, 10
|
||||||
AUTORADIOBUTTON "&DES", IDC3_CIPHERDES, 127, 50, 30, 10
|
AUTORADIOBUTTON "&DES", IDC3_CIPHERDES, 127, 50, 30, 10
|
||||||
AUTOCHECKBOX "Attempt TIS authentication", IDC3_AUTHTIS, 3, 60, 162, 10
|
AUTOCHECKBOX "Attempt TIS authentication", IDC3_AUTHTIS, 3, 60, 162, 10
|
||||||
|
AUTOCHECKBOX "Enable packet compression", IDC3_COMPRESS, 3, 70, 162, 10
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_PANEL4 DIALOG DISCARDABLE 6, 30, 168, 163
|
IDD_PANEL4 DIALOG DISCARDABLE 6, 30, 168, 163
|
||||||
|
10
windlg.c
10
windlg.c
@ -152,6 +152,7 @@ static void save_settings (char *section, int do_host) {
|
|||||||
wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
|
wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
|
||||||
cfg.cipher == CIPHER_DES ? "des" : "3des");
|
cfg.cipher == CIPHER_DES ? "des" : "3des");
|
||||||
wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
|
wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
|
||||||
|
wppi (sesskey, "SSHCompression", cfg.ssh_compression);
|
||||||
wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
|
wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
|
||||||
wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
|
wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
|
||||||
wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
|
wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
|
||||||
@ -288,6 +289,7 @@ static void load_settings (char *section, int do_host) {
|
|||||||
cfg.cipher = CIPHER_3DES;
|
cfg.cipher = CIPHER_3DES;
|
||||||
}
|
}
|
||||||
gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
|
gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
|
||||||
|
gppi (sesskey, "SSHCompression", 0, &cfg.ssh_compression);
|
||||||
gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
|
gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
|
||||||
gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
|
gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
|
||||||
gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
|
gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
|
||||||
@ -956,6 +958,7 @@ static int CALLBACK SshProc (HWND hwnd, UINT msg,
|
|||||||
|
|
||||||
IDC3_CIPHER3DES);
|
IDC3_CIPHER3DES);
|
||||||
CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
|
CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
|
||||||
|
CheckDlgButton (hwnd, IDC3_COMPRESS, cfg.ssh_compression);
|
||||||
break;
|
break;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (LOWORD(wParam)) {
|
switch (LOWORD(wParam)) {
|
||||||
@ -992,6 +995,11 @@ static int CALLBACK SshProc (HWND hwnd, UINT msg,
|
|||||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
|
cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
|
||||||
break;
|
break;
|
||||||
|
case IDC3_COMPRESS:
|
||||||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
|
cfg.ssh_compression = IsDlgButtonChecked (hwnd, IDC3_COMPRESS);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1423,6 +1431,8 @@ void do_defaults (char *session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void logevent (char *string) {
|
void logevent (char *string) {
|
||||||
|
if (IS_SCP && (scp_flags & SCP_VERBOSE) != 0)
|
||||||
|
fprintf(stderr, "%s\n", string);
|
||||||
if (nevents >= negsize) {
|
if (nevents >= negsize) {
|
||||||
negsize += 64;
|
negsize += 64;
|
||||||
events = srealloc (events, negsize * sizeof(*events));
|
events = srealloc (events, negsize * sizeof(*events));
|
||||||
|
Loading…
Reference in New Issue
Block a user