diff --git a/putty.h b/putty.h index 0971fab3..27838a10 100644 --- a/putty.h +++ b/putty.h @@ -134,6 +134,7 @@ typedef struct { int nopty; enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher; int try_tis_auth; + int ssh_compression; /* Telnet options */ char termtype[32]; char termspeed[32]; @@ -194,6 +195,14 @@ GLOBAL int default_port; 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. */ diff --git a/scp.h b/scp.h index 754f65c1..25370d79 100644 --- a/scp.h +++ b/scp.h @@ -3,12 +3,7 @@ * 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 */ -extern int scp_flags; extern void (*ssh_get_password)(const char *prompt, char *str, int maxlen); char * ssh_scp_init(char *host, int port, char *cmd, char **realhost); int ssh_scp_recv(unsigned char *buf, int len); diff --git a/ssh.c b/ssh.c index a355c297..b917a575 100644 --- a/ssh.c +++ b/ssh.c @@ -15,10 +15,6 @@ #define TRUE 1 #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_SMSG_PUBLIC_KEY 2 #define SSH_CMSG_SESSION_KEY 3 @@ -38,11 +34,13 @@ #define SSH_CMSG_EXIT_CONFIRMATION 33 #define SSH_MSG_IGNORE 32 #define SSH_MSG_DEBUG 36 +#define SSH_CMSG_REQUEST_COMPRESSION 37 #define SSH_CMSG_AUTH_TIS 39 #define SSH_SMSG_AUTH_TIS_CHALLENGE 40 #define SSH_CMSG_AUTH_TIS_RESPONSE 41 #define SSH_AUTH_TIS 5 +#define COMPRESSION_LEVEL 5 #define GET_32BIT(cp) \ (((unsigned long)(unsigned char)(cp)[0] << 24) | \ @@ -80,7 +78,7 @@ static SOCKET s = INVALID_SOCKET; static unsigned char session_key[32]; 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; 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 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. * Decihper and verify the packet when it is completely read. @@ -192,22 +208,9 @@ next_packet: pad = 8 - (len % 8); biglen = len + pad; - pktin.length = len - 5; - if (pktin.maxlen < biglen) { - pktin.maxlen = 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"); - } + if (pktin.maxlen < biglen) + pktalloc(&pktin, biglen); to_read = biglen; p = pktin.data; @@ -228,15 +231,23 @@ next_packet: if (cipher) cipher->decrypt(pktin.data, biglen); - pktin.type = pktin.data[pad]; - pktin.body = pktin.data + pad + 1; - realcrc = crc32(pktin.data, biglen-4); gotcrc = GET_32BIT(pktin.data+biglen-4); if (gotcrc != realcrc) { 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 || pktin.type == SSH_SMSG_STDERR_DATA || pktin.type == SSH_MSG_DEBUG || @@ -281,20 +292,8 @@ static void s_wrpkt_start(int type, int len) { biglen = len + pad; pktout.length = len-5; - if (pktout.maxlen < biglen) { - pktout.maxlen = biglen; -#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"); - } + if (pktout.maxlen < biglen + 4) + pktalloc(&pktout, biglen + 4); pktout.type = type; pktout.body = pktout.data+4+pad+1; @@ -307,8 +306,21 @@ static void s_wrpkt(void) { len = pktout.length + 5; /* type and CRC */ pad = 8 - (len%8); biglen = len + pad; - 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= negsize) { negsize += 64; events = srealloc (events, negsize * sizeof(*events));