quietly becomes unavailable if zlib.dll not found). Thanks to Joris
van Rantwijk (again).
[originally from svn r511]
int nopty;
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
int try_tis_auth;
int nopty;
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
int try_tis_auth;
/* Telnet options */
char termtype[32];
char termspeed[32];
/* Telnet options */
char termtype[32];
char termspeed[32];
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.
*/
* 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 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);
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);
-#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
#define SSH_MSG_DISCONNECT 1
#define SSH_SMSG_PUBLIC_KEY 2
#define SSH_CMSG_SESSION_KEY 3
#define SSH_CMSG_EXIT_CONFIRMATION 33
#define SSH_MSG_IGNORE 32
#define SSH_MSG_DEBUG 36
#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 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) | \
#define GET_32BIT(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
static unsigned char session_key[32];
static struct ssh_cipher *cipher = NULL;
static unsigned char session_key[32];
static struct ssh_cipher *cipher = NULL;
+static int use_compression = 0;
void (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
static char *savedhost;
void (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
static char *savedhost;
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.
* Decihper and verify the packet when it is completely read.
/*
* Collect incoming data in the incoming packet buffer.
* Decihper and verify the packet when it is completely read.
pad = 8 - (len % 8);
biglen = len + pad;
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;
to_read = biglen;
p = pktin.data;
if (cipher)
cipher->decrypt(pktin.data, biglen);
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");
}
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 ||
if (pktin.type == SSH_SMSG_STDOUT_DATA ||
pktin.type == SSH_SMSG_STDERR_DATA ||
pktin.type == SSH_MSG_DEBUG ||
biglen = len + pad;
pktout.length = len-5;
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;
pktout.type = type;
pktout.body = pktout.data+4+pad+1;
len = pktout.length + 5; /* type and CRC */
pad = 8 - (len%8);
biglen = len + pad;
len = pktout.length + 5; /* type and CRC */
pad = 8 - (len%8);
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++)
pktout.data[i+4] = random_byte();
crc = crc32(pktout.data+4, biglen-4);
for (i=0; i<pad; i++)
pktout.data[i+4] = random_byte();
crc = crc32(pktout.data+4, biglen-4);
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);
+ }
+ }
+
void random_add_noise(void *noise, int length);
void logevent (char *);
void random_add_noise(void *noise, int length);
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);
+
#define IDC3_CIPHERBLOWF 1021
#define IDC3_CIPHERDES 1022
#define IDC3_AUTHTIS 1023
#define IDC3_CIPHERBLOWF 1021
#define IDC3_CIPHERDES 1022
#define IDC3_AUTHTIS 1023
+#define IDC3_COMPRESS 1024
#define IDC4_MBSTATIC 1001
#define IDC4_MBWINDOWS 1002
#define IDC4_MBSTATIC 1001
#define IDC4_MBWINDOWS 1002
AUTORADIOBUTTON "&Blowfish", IDC3_CIPHERBLOWF, 84, 50, 40, 10
AUTORADIOBUTTON "&DES", IDC3_CIPHERDES, 127, 50, 30, 10
AUTOCHECKBOX "Attempt TIS authentication", IDC3_AUTHTIS, 3, 60, 162, 10
AUTORADIOBUTTON "&Blowfish", IDC3_CIPHERBLOWF, 84, 50, 40, 10
AUTORADIOBUTTON "&DES", IDC3_CIPHERDES, 127, 50, 30, 10
AUTOCHECKBOX "Attempt TIS authentication", IDC3_AUTHTIS, 3, 60, 162, 10
+ AUTOCHECKBOX "Enable packet compression", IDC3_COMPRESS, 3, 70, 162, 10
END
IDD_PANEL4 DIALOG DISCARDABLE 6, 30, 168, 163
END
IDD_PANEL4 DIALOG DISCARDABLE 6, 30, 168, 163
wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
cfg.cipher == CIPHER_DES ? "des" : "3des");
wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
cfg.cipher == CIPHER_DES ? "des" : "3des");
wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
+ wppi (sesskey, "SSHCompression", cfg.ssh_compression);
wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
cfg.cipher = CIPHER_3DES;
}
gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
cfg.cipher = CIPHER_3DES;
}
gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
+ gppi (sesskey, "SSHCompression", 0, &cfg.ssh_compression);
gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
IDC3_CIPHER3DES);
CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
IDC3_CIPHER3DES);
CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
+ CheckDlgButton (hwnd, IDC3_COMPRESS, cfg.ssh_compression);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
HIWORD(wParam) == BN_DOUBLECLICKED)
cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
break;
HIWORD(wParam) == BN_DOUBLECLICKED)
cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
break;
+ case IDC3_COMPRESS:
+ if (HIWORD(wParam) == BN_CLICKED ||
+ HIWORD(wParam) == BN_DOUBLECLICKED)
+ cfg.ssh_compression = IsDlgButtonChecked (hwnd, IDC3_COMPRESS);
+ break;
}
void logevent (char *string) {
}
void logevent (char *string) {
+ if (IS_SCP && (scp_flags & SCP_VERBOSE) != 0)
+ fprintf(stderr, "%s\n", string);
if (nevents >= negsize) {
negsize += 64;
events = srealloc (events, negsize * sizeof(*events));
if (nevents >= negsize) {
negsize += 64;
events = srealloc (events, negsize * sizeof(*events));