mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 09:12:24 +00:00
Implement Zlib compression, in both SSH1 and SSH2.
[originally from svn r792]
This commit is contained in:
parent
84077ea5ee
commit
462063cdc5
3
Makefile
3
Makefile
@ -69,7 +69,7 @@ MOBJ2 = tree234.$(OBJ)
|
|||||||
##-- objects putty pscp plink
|
##-- objects putty pscp plink
|
||||||
OBJS1 = sshcrc.$(OBJ) sshdes.$(OBJ) sshmd5.$(OBJ) sshrsa.$(OBJ) sshrand.$(OBJ)
|
OBJS1 = sshcrc.$(OBJ) sshdes.$(OBJ) sshmd5.$(OBJ) sshrsa.$(OBJ) sshrand.$(OBJ)
|
||||||
OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshdss.$(OBJ)
|
OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshdss.$(OBJ)
|
||||||
OBJS3 = sshbn.$(OBJ) sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ)
|
OBJS3 = sshbn.$(OBJ) sshpubk.$(OBJ) ssh.$(OBJ) pageantc.$(OBJ) sshzlib.$(OBJ)
|
||||||
##-- objects pageant
|
##-- objects pageant
|
||||||
PAGE1 = pageant.$(OBJ) sshrsa.$(OBJ) sshpubk.$(OBJ) sshdes.$(OBJ) sshbn.$(OBJ)
|
PAGE1 = pageant.$(OBJ) sshrsa.$(OBJ) sshpubk.$(OBJ) sshdes.$(OBJ) sshbn.$(OBJ)
|
||||||
PAGE2 = sshmd5.$(OBJ) version.$(OBJ) tree234.$(OBJ)
|
PAGE2 = sshmd5.$(OBJ) version.$(OBJ) tree234.$(OBJ)
|
||||||
@ -229,6 +229,7 @@ sshdh.$(OBJ): sshdh.c ssh.h
|
|||||||
sshdss.$(OBJ): sshdss.c ssh.h
|
sshdss.$(OBJ): sshdss.c ssh.h
|
||||||
sshbn.$(OBJ): sshbn.c ssh.h
|
sshbn.$(OBJ): sshbn.c ssh.h
|
||||||
sshpubk.$(OBJ): sshpubk.c ssh.h
|
sshpubk.$(OBJ): sshpubk.c ssh.h
|
||||||
|
sshzlib.$(OBJ): sshzlib.c ssh.h
|
||||||
scp.$(OBJ): scp.c putty.h network.h winstuff.h
|
scp.$(OBJ): scp.c putty.h network.h winstuff.h
|
||||||
version.$(OBJ): version.c
|
version.$(OBJ): version.c
|
||||||
be_all.$(OBJ): be_all.c
|
be_all.$(OBJ): be_all.c
|
||||||
|
1
putty.h
1
putty.h
@ -140,6 +140,7 @@ typedef struct {
|
|||||||
/* SSH options */
|
/* SSH options */
|
||||||
char remote_cmd[512];
|
char remote_cmd[512];
|
||||||
int nopty;
|
int nopty;
|
||||||
|
int compression;
|
||||||
int agentfwd;
|
int agentfwd;
|
||||||
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
||||||
char keyfile[FILENAME_MAX];
|
char keyfile[FILENAME_MAX];
|
||||||
|
@ -66,6 +66,7 @@ void save_settings (char *section, int do_host, Config *cfg) {
|
|||||||
}
|
}
|
||||||
write_setting_s (sesskey, "UserName", cfg->username);
|
write_setting_s (sesskey, "UserName", cfg->username);
|
||||||
write_setting_i (sesskey, "NoPTY", cfg->nopty);
|
write_setting_i (sesskey, "NoPTY", cfg->nopty);
|
||||||
|
write_setting_i (sesskey, "Compression", cfg->compression);
|
||||||
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
|
write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
|
||||||
write_setting_s (sesskey, "RemoteCmd", cfg->remote_cmd);
|
write_setting_s (sesskey, "RemoteCmd", cfg->remote_cmd);
|
||||||
write_setting_s (sesskey, "Cipher", cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
|
write_setting_s (sesskey, "Cipher", cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
|
||||||
@ -186,6 +187,7 @@ void load_settings (char *section, int do_host, Config *cfg) {
|
|||||||
}
|
}
|
||||||
gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
|
gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
|
||||||
gppi (sesskey, "NoPTY", 0, &cfg->nopty);
|
gppi (sesskey, "NoPTY", 0, &cfg->nopty);
|
||||||
|
gppi (sesskey, "Compression", 0, &cfg->compression);
|
||||||
gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
|
gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
|
||||||
gpps (sesskey, "RemoteCmd", "", cfg->remote_cmd, sizeof(cfg->remote_cmd));
|
gpps (sesskey, "RemoteCmd", "", cfg->remote_cmd, sizeof(cfg->remote_cmd));
|
||||||
{
|
{
|
||||||
|
187
ssh.c
187
ssh.c
@ -51,6 +51,7 @@
|
|||||||
#define SSH1_CMSG_EXIT_CONFIRMATION 33 /* 0x21 */
|
#define SSH1_CMSG_EXIT_CONFIRMATION 33 /* 0x21 */
|
||||||
#define SSH1_MSG_IGNORE 32 /* 0x20 */
|
#define SSH1_MSG_IGNORE 32 /* 0x20 */
|
||||||
#define SSH1_MSG_DEBUG 36 /* 0x24 */
|
#define SSH1_MSG_DEBUG 36 /* 0x24 */
|
||||||
|
#define SSH1_CMSG_REQUEST_COMPRESSION 37 /* 0x25 */
|
||||||
#define SSH1_CMSG_AUTH_TIS 39 /* 0x27 */
|
#define SSH1_CMSG_AUTH_TIS 39 /* 0x27 */
|
||||||
#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40 /* 0x28 */
|
#define SSH1_SMSG_AUTH_TIS_CHALLENGE 40 /* 0x28 */
|
||||||
#define SSH1_CMSG_AUTH_TIS_RESPONSE 41 /* 0x29 */
|
#define SSH1_CMSG_AUTH_TIS_RESPONSE 41 /* 0x29 */
|
||||||
@ -186,10 +187,19 @@ const static struct ssh_mac *macs[] = {
|
|||||||
const static struct ssh_mac *buggymacs[] = {
|
const static struct ssh_mac *buggymacs[] = {
|
||||||
&ssh_sha1_buggy, &ssh_md5, &ssh_mac_none };
|
&ssh_sha1_buggy, &ssh_md5, &ssh_mac_none };
|
||||||
|
|
||||||
|
static void ssh_comp_none_init(void) { }
|
||||||
|
static int ssh_comp_none_block(unsigned char *block, int len,
|
||||||
|
unsigned char **outblock, int *outlen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const static struct ssh_compress ssh_comp_none = {
|
const static struct ssh_compress ssh_comp_none = {
|
||||||
"none"
|
"none",
|
||||||
|
ssh_comp_none_init, ssh_comp_none_block,
|
||||||
|
ssh_comp_none_init, ssh_comp_none_block
|
||||||
};
|
};
|
||||||
const static struct ssh_compress *compressions[] = { &ssh_comp_none };
|
extern const struct ssh_compress ssh_zlib;
|
||||||
|
const static struct ssh_compress *compressions[] = {
|
||||||
|
&ssh_zlib, &ssh_comp_none };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2-3-4 tree storing channels.
|
* 2-3-4 tree storing channels.
|
||||||
@ -226,6 +236,7 @@ static SHA_State exhash;
|
|||||||
static Socket s = NULL;
|
static Socket s = NULL;
|
||||||
|
|
||||||
static unsigned char session_key[32];
|
static unsigned char session_key[32];
|
||||||
|
static int ssh1_compressing;
|
||||||
static const struct ssh_cipher *cipher = NULL;
|
static const struct ssh_cipher *cipher = NULL;
|
||||||
static const struct ssh_cipher *cscipher = NULL;
|
static const struct ssh_cipher *cscipher = NULL;
|
||||||
static const struct ssh_cipher *sccipher = NULL;
|
static const struct ssh_cipher *sccipher = NULL;
|
||||||
@ -373,9 +384,6 @@ next_packet:
|
|||||||
debug(("\r\n"));
|
debug(("\r\n"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pktin.type = pktin.data[st->pad];
|
|
||||||
pktin.body = pktin.data + st->pad + 1;
|
|
||||||
|
|
||||||
st->realcrc = crc32(pktin.data, st->biglen-4);
|
st->realcrc = crc32(pktin.data, st->biglen-4);
|
||||||
st->gotcrc = GET_32BIT(pktin.data+st->biglen-4);
|
st->gotcrc = GET_32BIT(pktin.data+st->biglen-4);
|
||||||
if (st->gotcrc != st->realcrc) {
|
if (st->gotcrc != st->realcrc) {
|
||||||
@ -383,6 +391,39 @@ next_packet:
|
|||||||
crReturn(0);
|
crReturn(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pktin.body = pktin.data + st->pad + 1;
|
||||||
|
|
||||||
|
if (ssh1_compressing) {
|
||||||
|
unsigned char *decompblk;
|
||||||
|
int decomplen;
|
||||||
|
#if 0
|
||||||
|
int i;
|
||||||
|
debug(("Packet payload pre-decompression:\n"));
|
||||||
|
for (i = -1; i < pktin.length; i++)
|
||||||
|
debug((" %02x", (unsigned char)pktin.body[i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
zlib_decompress_block(pktin.body-1, pktin.length+1,
|
||||||
|
&decompblk, &decomplen);
|
||||||
|
|
||||||
|
if (pktin.maxlen < st->pad + decomplen) {
|
||||||
|
pktin.maxlen = st->pad + decomplen;
|
||||||
|
pktin.data = realloc(pktin.data, pktin.maxlen+APIEXTRA);
|
||||||
|
if (!pktin.data)
|
||||||
|
fatalbox("Out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pktin.body-1, decompblk, decomplen);
|
||||||
|
free(decompblk);
|
||||||
|
pktin.length = decomplen-1;
|
||||||
|
#if 0
|
||||||
|
debug(("Packet payload post-decompression:\n"));
|
||||||
|
for (i = -1; i < pktin.length; i++)
|
||||||
|
debug((" %02x", (unsigned char)pktin.body[i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
|
if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
|
||||||
pktin.type == SSH1_SMSG_STDERR_DATA ||
|
pktin.type == SSH1_SMSG_STDERR_DATA ||
|
||||||
pktin.type == SSH1_MSG_DEBUG ||
|
pktin.type == SSH1_MSG_DEBUG ||
|
||||||
@ -395,6 +436,8 @@ next_packet:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pktin.type = pktin.body[-1];
|
||||||
|
|
||||||
if (pktin.type == SSH1_MSG_DEBUG) {
|
if (pktin.type == SSH1_MSG_DEBUG) {
|
||||||
/* log debug message */
|
/* log debug message */
|
||||||
char buf[80];
|
char buf[80];
|
||||||
@ -515,6 +558,34 @@ next_packet:
|
|||||||
}
|
}
|
||||||
st->incoming_sequence++; /* whether or not we MACed */
|
st->incoming_sequence++; /* whether or not we MACed */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decompress packet payload.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned char *newpayload;
|
||||||
|
int newlen;
|
||||||
|
if (sccomp && sccomp->decompress(pktin.data+5, pktin.length-5,
|
||||||
|
&newpayload, &newlen)) {
|
||||||
|
if (pktin.maxlen < newlen+5) {
|
||||||
|
pktin.maxlen = newlen+5;
|
||||||
|
pktin.data = (pktin.data == NULL ? malloc(pktin.maxlen+APIEXTRA) :
|
||||||
|
realloc(pktin.data, pktin.maxlen+APIEXTRA));
|
||||||
|
if (!pktin.data)
|
||||||
|
fatalbox("Out of memory");
|
||||||
|
}
|
||||||
|
pktin.length = 5 + newlen;
|
||||||
|
memcpy(pktin.data+5, newpayload, newlen);
|
||||||
|
#if 0
|
||||||
|
debug(("Post-decompression payload:\r\n"));
|
||||||
|
for (st->i = 0; st->i < newlen; st->i++)
|
||||||
|
debug((" %02x", (unsigned char)pktin.data[5+st->i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
free(newpayload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pktin.savedpos = 6;
|
pktin.savedpos = 6;
|
||||||
pktin.type = pktin.data[5];
|
pktin.type = pktin.data[5];
|
||||||
|
|
||||||
@ -524,7 +595,7 @@ next_packet:
|
|||||||
crFinish(0);
|
crFinish(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void s_wrpkt_start(int type, int len) {
|
static void ssh1_pktout_size(int len) {
|
||||||
int pad, biglen;
|
int pad, biglen;
|
||||||
|
|
||||||
len += 5; /* type and CRC */
|
len += 5; /* type and CRC */
|
||||||
@ -546,20 +617,46 @@ static void s_wrpkt_start(int type, int len) {
|
|||||||
if (!pktout.data)
|
if (!pktout.data)
|
||||||
fatalbox("Out of memory");
|
fatalbox("Out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
pktout.type = type;
|
|
||||||
pktout.body = pktout.data+4+pad+1;
|
pktout.body = pktout.data+4+pad+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void s_wrpkt_start(int type, int len) {
|
||||||
|
ssh1_pktout_size(len);
|
||||||
|
pktout.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
static void s_wrpkt(void) {
|
static void s_wrpkt(void) {
|
||||||
int pad, len, biglen, i;
|
int pad, len, biglen, i;
|
||||||
unsigned long crc;
|
unsigned long crc;
|
||||||
|
|
||||||
|
pktout.body[-1] = pktout.type;
|
||||||
|
|
||||||
|
if (ssh1_compressing) {
|
||||||
|
unsigned char *compblk;
|
||||||
|
int complen;
|
||||||
|
#if 0
|
||||||
|
debug(("Packet payload pre-compression:\n"));
|
||||||
|
for (i = -1; i < pktout.length; i++)
|
||||||
|
debug((" %02x", (unsigned char)pktout.body[i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
zlib_compress_block(pktout.body-1, pktout.length+1,
|
||||||
|
&compblk, &complen);
|
||||||
|
ssh1_pktout_size(complen-1);
|
||||||
|
memcpy(pktout.body-1, compblk, complen);
|
||||||
|
free(compblk);
|
||||||
|
#if 0
|
||||||
|
debug(("Packet payload post-compression:\n"));
|
||||||
|
for (i = -1; i < pktout.length; i++)
|
||||||
|
debug((" %02x", (unsigned char)pktout.body[i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
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);
|
||||||
@ -767,6 +864,26 @@ static void ssh2_pkt_send(void) {
|
|||||||
int cipherblk, maclen, padding, i;
|
int cipherblk, maclen, padding, i;
|
||||||
static unsigned long outgoing_sequence = 0;
|
static unsigned long outgoing_sequence = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compress packet payload.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
debug(("Pre-compression payload:\r\n"));
|
||||||
|
for (i = 5; i < pktout.length; i++)
|
||||||
|
debug((" %02x", (unsigned char)pktout.data[i]));
|
||||||
|
debug(("\r\n"));
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
unsigned char *newpayload;
|
||||||
|
int newlen;
|
||||||
|
if (cscomp && cscomp->compress(pktout.data+5, pktout.length-5,
|
||||||
|
&newpayload, &newlen)) {
|
||||||
|
pktout.length = 5;
|
||||||
|
ssh2_pkt_adddata(newpayload, newlen);
|
||||||
|
free(newpayload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add padding. At least four bytes, and must also bring total
|
* Add padding. At least four bytes, and must also bring total
|
||||||
* length (minus MAC) up to a multiple of the block size.
|
* length (minus MAC) up to a multiple of the block size.
|
||||||
@ -1637,6 +1754,21 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {
|
|||||||
logevent("Allocated pty");
|
logevent("Allocated pty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfg.compression) {
|
||||||
|
send_packet(SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
|
||||||
|
do { crReturnV; } while (!ispkt);
|
||||||
|
if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {
|
||||||
|
bombout(("Protocol confusion"));
|
||||||
|
crReturnV;
|
||||||
|
} else if (pktin.type == SSH1_SMSG_FAILURE) {
|
||||||
|
c_write("Server refused to compress\r\n", 32);
|
||||||
|
}
|
||||||
|
logevent("Started compression");
|
||||||
|
ssh1_compressing = TRUE;
|
||||||
|
zlib_compress_init();
|
||||||
|
zlib_decompress_init();
|
||||||
|
}
|
||||||
|
|
||||||
if (*cfg.remote_cmd)
|
if (*cfg.remote_cmd)
|
||||||
send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
|
send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
|
||||||
else
|
else
|
||||||
@ -1845,12 +1977,13 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
static unsigned char exchange_hash[20];
|
static unsigned char exchange_hash[20];
|
||||||
static unsigned char keyspace[40];
|
static unsigned char keyspace[40];
|
||||||
static const struct ssh_cipher *preferred_cipher;
|
static const struct ssh_cipher *preferred_cipher;
|
||||||
|
static const struct ssh_compress *preferred_comp;
|
||||||
|
|
||||||
crBegin;
|
crBegin;
|
||||||
random_init();
|
random_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the preferred cipher.
|
* Set up the preferred cipher and compression.
|
||||||
*/
|
*/
|
||||||
if (cfg.cipher == CIPHER_BLOWFISH) {
|
if (cfg.cipher == CIPHER_BLOWFISH) {
|
||||||
preferred_cipher = &ssh_blowfish_ssh2;
|
preferred_cipher = &ssh_blowfish_ssh2;
|
||||||
@ -1863,6 +1996,10 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
/* Shouldn't happen, but we do want to initialise to _something_. */
|
/* Shouldn't happen, but we do want to initialise to _something_. */
|
||||||
preferred_cipher = &ssh_3des_ssh2;
|
preferred_cipher = &ssh_3des_ssh2;
|
||||||
}
|
}
|
||||||
|
if (cfg.compression)
|
||||||
|
preferred_comp = &ssh_zlib;
|
||||||
|
else
|
||||||
|
preferred_comp = &ssh_comp_none;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Be prepared to work around the buggy MAC problem.
|
* Be prepared to work around the buggy MAC problem.
|
||||||
@ -1925,16 +2062,18 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
/* List client->server compression algorithms. */
|
/* List client->server compression algorithms. */
|
||||||
ssh2_pkt_addstring_start();
|
ssh2_pkt_addstring_start();
|
||||||
for (i = 0; i < lenof(compressions); i++) {
|
for (i = 0; i < lenof(compressions)+1; i++) {
|
||||||
ssh2_pkt_addstring_str(compressions[i]->name);
|
const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
|
||||||
if (i < lenof(compressions)-1)
|
ssh2_pkt_addstring_str(c->name);
|
||||||
|
if (i < lenof(compressions))
|
||||||
ssh2_pkt_addstring_str(",");
|
ssh2_pkt_addstring_str(",");
|
||||||
}
|
}
|
||||||
/* List server->client compression algorithms. */
|
/* List server->client compression algorithms. */
|
||||||
ssh2_pkt_addstring_start();
|
ssh2_pkt_addstring_start();
|
||||||
for (i = 0; i < lenof(compressions); i++) {
|
for (i = 0; i < lenof(compressions)+1; i++) {
|
||||||
ssh2_pkt_addstring_str(compressions[i]->name);
|
const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
|
||||||
if (i < lenof(compressions)-1)
|
ssh2_pkt_addstring_str(c->name);
|
||||||
|
if (i < lenof(compressions))
|
||||||
ssh2_pkt_addstring_str(",");
|
ssh2_pkt_addstring_str(",");
|
||||||
}
|
}
|
||||||
/* List client->server languages. Empty list. */
|
/* List client->server languages. Empty list. */
|
||||||
@ -2007,16 +2146,18 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ssh2_pkt_getstring(&str, &len); /* client->server compression */
|
ssh2_pkt_getstring(&str, &len); /* client->server compression */
|
||||||
for (i = 0; i < lenof(compressions); i++) {
|
for (i = 0; i < lenof(compressions)+1; i++) {
|
||||||
if (in_commasep_string(compressions[i]->name, str, len)) {
|
const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
|
||||||
cscomp_tobe = compressions[i];
|
if (in_commasep_string(c->name, str, len)) {
|
||||||
|
cscomp_tobe = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ssh2_pkt_getstring(&str, &len); /* server->client compression */
|
ssh2_pkt_getstring(&str, &len); /* server->client compression */
|
||||||
for (i = 0; i < lenof(compressions); i++) {
|
for (i = 0; i < lenof(compressions)+1; i++) {
|
||||||
if (in_commasep_string(compressions[i]->name, str, len)) {
|
const struct ssh_compress *c = i==0 ? preferred_comp : compressions[i-1];
|
||||||
sccomp_tobe = compressions[i];
|
if (in_commasep_string(c->name, str, len)) {
|
||||||
|
sccomp_tobe = c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2105,6 +2246,8 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
scmac = scmac_tobe;
|
scmac = scmac_tobe;
|
||||||
cscomp = cscomp_tobe;
|
cscomp = cscomp_tobe;
|
||||||
sccomp = sccomp_tobe;
|
sccomp = sccomp_tobe;
|
||||||
|
cscomp->compress_init();
|
||||||
|
sccomp->decompress_init();
|
||||||
/*
|
/*
|
||||||
* Set IVs after keys.
|
* Set IVs after keys.
|
||||||
*/
|
*/
|
||||||
|
16
ssh.h
16
ssh.h
@ -137,6 +137,12 @@ struct ssh_hostkey {
|
|||||||
|
|
||||||
struct ssh_compress {
|
struct ssh_compress {
|
||||||
char *name;
|
char *name;
|
||||||
|
void (*compress_init)(void);
|
||||||
|
int (*compress)(unsigned char *block, int len,
|
||||||
|
unsigned char **outblock, int *outlen);
|
||||||
|
void (*decompress_init)(void);
|
||||||
|
int (*decompress)(unsigned char *block, int len,
|
||||||
|
unsigned char **outblock, int *outlen);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef MSCRYPTOAPI
|
#ifndef MSCRYPTOAPI
|
||||||
@ -197,3 +203,13 @@ int rsa_generate(struct RSAKey *key, struct RSAAux *aux, int bits,
|
|||||||
progfn_t pfn, void *pfnparam);
|
progfn_t pfn, void *pfnparam);
|
||||||
Bignum primegen(int bits, int modulus, int residue,
|
Bignum primegen(int bits, int modulus, int residue,
|
||||||
int phase, progfn_t pfn, void *pfnparam);
|
int phase, progfn_t pfn, void *pfnparam);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* zlib compression.
|
||||||
|
*/
|
||||||
|
void zlib_compress_init(void);
|
||||||
|
void zlib_decompress_init(void);
|
||||||
|
int zlib_compress_block(unsigned char *block, int len,
|
||||||
|
unsigned char **outblock, int *outlen);
|
||||||
|
int zlib_decompress_block(unsigned char *block, int len,
|
||||||
|
unsigned char **outblock, int *outlen);
|
||||||
|
14
win_res.rc
14
win_res.rc
@ -31,24 +31,24 @@ BEGIN
|
|||||||
END
|
END
|
||||||
|
|
||||||
/* Accelerators used: aco */
|
/* Accelerators used: aco */
|
||||||
IDD_MAINBOX DIALOG DISCARDABLE 0, 0, 280, 232
|
IDD_MAINBOX DIALOG DISCARDABLE 0, 0, 280, 242
|
||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "PuTTY Configuration"
|
CAPTION "PuTTY Configuration"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "&Open", IDOK, 184, 215, 44, 14
|
DEFPUSHBUTTON "&Open", IDOK, 184, 225, 44, 14
|
||||||
PUSHBUTTON "&Cancel", IDCANCEL, 231, 215, 44, 14
|
PUSHBUTTON "&Cancel", IDCANCEL, 231, 225, 44, 14
|
||||||
PUSHBUTTON "&About", IDC_ABOUT, 3, 215, 44, 14, NOT WS_TABSTOP
|
PUSHBUTTON "&About", IDC_ABOUT, 3, 225, 44, 14, NOT WS_TABSTOP
|
||||||
END
|
END
|
||||||
|
|
||||||
/* Accelerators used: ac */
|
/* Accelerators used: ac */
|
||||||
IDD_RECONF DIALOG DISCARDABLE 0, 0, 280, 232
|
IDD_RECONF DIALOG DISCARDABLE 0, 0, 280, 242
|
||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "PuTTY Reconfiguration"
|
CAPTION "PuTTY Reconfiguration"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "&Apply", IDOK, 184, 215, 44, 14
|
DEFPUSHBUTTON "&Apply", IDOK, 184, 225, 44, 14
|
||||||
PUSHBUTTON "&Cancel", IDCANCEL, 231, 215, 44, 14
|
PUSHBUTTON "&Cancel", IDCANCEL, 231, 225, 44, 14
|
||||||
END
|
END
|
||||||
|
|
||||||
/* Accelerators used: co */
|
/* Accelerators used: co */
|
||||||
|
10
windlg.c
10
windlg.c
@ -326,6 +326,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
|
|||||||
IDC_AGENTFWD,
|
IDC_AGENTFWD,
|
||||||
IDC_CMDSTATIC,
|
IDC_CMDSTATIC,
|
||||||
IDC_CMDEDIT,
|
IDC_CMDEDIT,
|
||||||
|
IDC_COMPRESS,
|
||||||
sshpanelend,
|
sshpanelend,
|
||||||
|
|
||||||
selectionpanelstart,
|
selectionpanelstart,
|
||||||
@ -486,6 +487,7 @@ static void init_dlg_ctrls(HWND hwnd) {
|
|||||||
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
|
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
|
||||||
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
|
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
|
||||||
CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
|
CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
|
||||||
|
CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
|
||||||
CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
|
CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
|
||||||
CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
|
CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
|
||||||
CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
|
CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
|
||||||
@ -631,7 +633,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
|
SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
|
||||||
|
|
||||||
r.left = 3; r.right = r.left + 75;
|
r.left = 3; r.right = r.left + 75;
|
||||||
r.top = 13; r.bottom = r.top + 196;
|
r.top = 13; r.bottom = r.top + 206;
|
||||||
MapDialogRect(hwnd, &r);
|
MapDialogRect(hwnd, &r);
|
||||||
treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
|
treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
|
||||||
WS_CHILD | WS_VISIBLE |
|
WS_CHILD | WS_VISIBLE |
|
||||||
@ -972,6 +974,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
beginbox(&cp, "Protocol options",
|
beginbox(&cp, "Protocol options",
|
||||||
IDC_BOX_SSH3, IDC_BOXT_SSH3);
|
IDC_BOX_SSH3, IDC_BOXT_SSH3);
|
||||||
checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
|
checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
|
||||||
|
checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
|
||||||
radioline(&cp, "Preferred SSH protocol version:",
|
radioline(&cp, "Preferred SSH protocol version:",
|
||||||
IDC_SSHPROTSTATIC, 2,
|
IDC_SSHPROTSTATIC, 2,
|
||||||
"&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
|
"&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
|
||||||
@ -1497,6 +1500,11 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
|
cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
|
||||||
break;
|
break;
|
||||||
|
case IDC_COMPRESS:
|
||||||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
|
cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
|
||||||
|
break;
|
||||||
case IDC_BUGGYMAC:
|
case IDC_BUGGYMAC:
|
||||||
if (HIWORD(wParam) == BN_CLICKED ||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
|
Loading…
Reference in New Issue
Block a user