mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-18 19:41:01 -05:00
Jacob's patch for a drag-list to select SSH ciphers. Heavily hacked
by me to make the drag list behaviour slightly more intuitive. WARNING: DO NOT LOOK AT pl_itemfrompt() IF YOU ARE SQUEAMISH. [originally from svn r1199]
This commit is contained in:
170
ssh.c
170
ssh.c
@ -1862,31 +1862,45 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
|
||||
|
||||
logevent("Encrypted session key");
|
||||
|
||||
switch (cfg.cipher) {
|
||||
case CIPHER_BLOWFISH:
|
||||
cipher_type = SSH_CIPHER_BLOWFISH;
|
||||
break;
|
||||
case CIPHER_DES:
|
||||
cipher_type = SSH_CIPHER_DES;
|
||||
break;
|
||||
case CIPHER_3DES:
|
||||
cipher_type = SSH_CIPHER_3DES;
|
||||
break;
|
||||
case CIPHER_AES:
|
||||
c_write_str("AES not supported in SSH1, falling back to 3DES\r\n");
|
||||
cipher_type = SSH_CIPHER_3DES;
|
||||
break;
|
||||
}
|
||||
if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
|
||||
c_write_str
|
||||
("Selected cipher not supported, falling back to 3DES\r\n");
|
||||
cipher_type = SSH_CIPHER_3DES;
|
||||
if ((supported_ciphers_mask & (1 << cipher_type)) == 0) {
|
||||
bombout(("Server violates SSH 1 protocol by "
|
||||
"not supporting 3DES encryption"));
|
||||
{
|
||||
int cipher_chosen = 0, warn = 0;
|
||||
char *cipher_string = NULL;
|
||||
for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
|
||||
int next_cipher = cfg.ssh_cipherlist[i];
|
||||
if (next_cipher == CIPHER_WARN) {
|
||||
/* If/when we choose a cipher, warn about it */
|
||||
warn = 1;
|
||||
} else if (next_cipher == CIPHER_AES) {
|
||||
/* XXX Probably don't need to mention this. */
|
||||
logevent("AES not supported in SSH1, skipping");
|
||||
} else {
|
||||
switch (next_cipher) {
|
||||
case CIPHER_3DES: cipher_type = SSH_CIPHER_3DES;
|
||||
cipher_string = "3DES"; break;
|
||||
case CIPHER_BLOWFISH: cipher_type = SSH_CIPHER_BLOWFISH;
|
||||
cipher_string = "Blowfish"; break;
|
||||
case CIPHER_DES: cipher_type = SSH_CIPHER_DES;
|
||||
cipher_string = "single-DES"; break;
|
||||
}
|
||||
if (supported_ciphers_mask & (1 << cipher_type))
|
||||
cipher_chosen = 1;
|
||||
}
|
||||
}
|
||||
if (!cipher_chosen) {
|
||||
if ((supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0)
|
||||
bombout(("Server violates SSH 1 protocol by not "
|
||||
"supporting 3DES encryption"));
|
||||
else
|
||||
/* shouldn't happen */
|
||||
bombout(("No supported ciphers found"));
|
||||
crReturn(0);
|
||||
}
|
||||
|
||||
/* Warn about chosen cipher if necessary. */
|
||||
if (warn)
|
||||
askcipher(cipher_string, 0);
|
||||
}
|
||||
|
||||
switch (cipher_type) {
|
||||
case SSH_CIPHER_3DES:
|
||||
logevent("Using 3DES encryption");
|
||||
@ -2992,7 +3006,7 @@ static void ssh2_mkkey(Bignum K, char *H, char *sessid, char chr,
|
||||
*/
|
||||
static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||
{
|
||||
static int i, j, len, nbits, pbits;
|
||||
static int i, j, len, nbits, pbits, warn;
|
||||
static char *str;
|
||||
static Bignum p, g, e, f, K;
|
||||
static int kex_init_value, kex_reply_value;
|
||||
@ -3009,7 +3023,8 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||
static void *hkey; /* actual host key */
|
||||
static unsigned char exchange_hash[20];
|
||||
static unsigned char keyspace[40];
|
||||
static const struct ssh2_ciphers *preferred_cipher;
|
||||
static int n_preferred_ciphers;
|
||||
static const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
|
||||
static const struct ssh_compress *preferred_comp;
|
||||
static int first_kex;
|
||||
|
||||
@ -3018,21 +3033,40 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||
first_kex = 1;
|
||||
|
||||
/*
|
||||
* Set up the preferred cipher and compression.
|
||||
* Set up the preferred ciphers. (NULL => warn below here)
|
||||
*/
|
||||
if (cfg.cipher == CIPHER_BLOWFISH) {
|
||||
preferred_cipher = &ssh2_blowfish;
|
||||
} else if (cfg.cipher == CIPHER_DES) {
|
||||
logevent("Single DES not supported in SSH2; using 3DES");
|
||||
preferred_cipher = &ssh2_3des;
|
||||
} else if (cfg.cipher == CIPHER_3DES) {
|
||||
preferred_cipher = &ssh2_3des;
|
||||
} else if (cfg.cipher == CIPHER_AES) {
|
||||
preferred_cipher = &ssh2_aes;
|
||||
} else {
|
||||
/* Shouldn't happen, but we do want to initialise to _something_. */
|
||||
preferred_cipher = &ssh2_3des;
|
||||
n_preferred_ciphers = 0;
|
||||
for (i = 0; i < CIPHER_MAX; i++) {
|
||||
switch (cfg.ssh_cipherlist[i]) {
|
||||
case CIPHER_BLOWFISH:
|
||||
preferred_ciphers[n_preferred_ciphers] = &ssh2_blowfish;
|
||||
n_preferred_ciphers++;
|
||||
break;
|
||||
case CIPHER_DES:
|
||||
/* Not supported in SSH2; silently drop */
|
||||
break;
|
||||
case CIPHER_3DES:
|
||||
preferred_ciphers[n_preferred_ciphers] = &ssh2_3des;
|
||||
n_preferred_ciphers++;
|
||||
break;
|
||||
case CIPHER_AES:
|
||||
preferred_ciphers[n_preferred_ciphers] = &ssh2_aes;
|
||||
n_preferred_ciphers++;
|
||||
break;
|
||||
case CIPHER_WARN:
|
||||
/* Flag for later. Don't bother if it's the last in
|
||||
* the list. */
|
||||
if (i < CIPHER_MAX - 1) {
|
||||
preferred_ciphers[n_preferred_ciphers] = NULL;
|
||||
n_preferred_ciphers++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up preferred compression.
|
||||
*/
|
||||
if (cfg.compression)
|
||||
preferred_comp = &ssh_zlib;
|
||||
else
|
||||
@ -3069,23 +3103,23 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||
}
|
||||
/* List client->server encryption algorithms. */
|
||||
ssh2_pkt_addstring_start();
|
||||
for (i = 0; i < lenof(ciphers) + 1; i++) {
|
||||
const struct ssh2_ciphers *c =
|
||||
i == 0 ? preferred_cipher : ciphers[i - 1];
|
||||
for (i = 0; i < n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = preferred_ciphers[i];
|
||||
if (!c) continue; /* warning flag */
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
ssh2_pkt_addstring_str(c->list[j]->name);
|
||||
if (i < lenof(ciphers) || j < c->nciphers - 1)
|
||||
if (i < n_preferred_ciphers || j < c->nciphers - 1)
|
||||
ssh2_pkt_addstring_str(",");
|
||||
}
|
||||
}
|
||||
/* List server->client encryption algorithms. */
|
||||
ssh2_pkt_addstring_start();
|
||||
for (i = 0; i < lenof(ciphers) + 1; i++) {
|
||||
const struct ssh2_ciphers *c =
|
||||
i == 0 ? preferred_cipher : ciphers[i - 1];
|
||||
for (i = 0; i < n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = preferred_ciphers[i];
|
||||
if (!c) continue; /* warning flag */
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
ssh2_pkt_addstring_str(c->list[j]->name);
|
||||
if (i < lenof(ciphers) || j < c->nciphers - 1)
|
||||
if (i < n_preferred_ciphers || j < c->nciphers - 1)
|
||||
ssh2_pkt_addstring_str(",");
|
||||
}
|
||||
}
|
||||
@ -3171,30 +3205,44 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
||||
}
|
||||
}
|
||||
ssh2_pkt_getstring(&str, &len); /* client->server cipher */
|
||||
for (i = 0; i < lenof(ciphers) + 1; i++) {
|
||||
const struct ssh2_ciphers *c =
|
||||
i == 0 ? preferred_cipher : ciphers[i - 1];
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
cscipher_tobe = c->list[j];
|
||||
break;
|
||||
warn = 0;
|
||||
for (i = 0; i < n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = preferred_ciphers[i];
|
||||
if (!c) {
|
||||
warn = 1;
|
||||
} else {
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
cscipher_tobe = c->list[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cscipher_tobe)
|
||||
if (cscipher_tobe) {
|
||||
if (warn)
|
||||
askcipher(cscipher_tobe->name, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssh2_pkt_getstring(&str, &len); /* server->client cipher */
|
||||
for (i = 0; i < lenof(ciphers) + 1; i++) {
|
||||
const struct ssh2_ciphers *c =
|
||||
i == 0 ? preferred_cipher : ciphers[i - 1];
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
sccipher_tobe = c->list[j];
|
||||
break;
|
||||
warn = 0;
|
||||
for (i = 0; i < n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = preferred_ciphers[i];
|
||||
if (!c) {
|
||||
warn = 1;
|
||||
} else {
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
sccipher_tobe = c->list[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sccipher_tobe)
|
||||
if (sccipher_tobe) {
|
||||
if (warn)
|
||||
askcipher(sccipher_tobe->name, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssh2_pkt_getstring(&str, &len); /* client->server mac */
|
||||
for (i = 0; i < nmacs; i++) {
|
||||
|
Reference in New Issue
Block a user