mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-16 03:53:01 -05:00
In SSH2, rather than sending an SSH_MSG_IGNORE after every password, just
pad the packet out to 256 bytes. Much simpler. This leavs ssh2_pkt_defer() unused, so ifdef it out. [originally from svn r5122]
This commit is contained in:
parent
214e11a7fe
commit
8a20515844
61
ssh.c
61
ssh.c
@ -533,6 +533,7 @@ struct ssh_portfwd {
|
|||||||
|
|
||||||
struct Packet {
|
struct Packet {
|
||||||
long length;
|
long length;
|
||||||
|
long forcepad; /* Force padding to at least this length */
|
||||||
int type;
|
int type;
|
||||||
unsigned long sequence;
|
unsigned long sequence;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
@ -1572,6 +1573,7 @@ static struct Packet *ssh2_pkt_init(int pkt_type)
|
|||||||
{
|
{
|
||||||
struct Packet *pkt = ssh_new_packet();
|
struct Packet *pkt = ssh_new_packet();
|
||||||
pkt->length = 5;
|
pkt->length = 5;
|
||||||
|
pkt->forcepad = 0;
|
||||||
ssh2_pkt_addbyte(pkt, (unsigned char) pkt_type);
|
ssh2_pkt_addbyte(pkt, (unsigned char) pkt_type);
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
@ -1668,12 +1670,17 @@ static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt)
|
|||||||
/*
|
/*
|
||||||
* 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.
|
||||||
|
* If pkt->forcepad is set, make sure the packet is at least that size
|
||||||
|
* after padding.
|
||||||
*/
|
*/
|
||||||
cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8; /* block size */
|
cipherblk = ssh->cscipher ? ssh->cscipher->blksize : 8; /* block size */
|
||||||
cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
|
cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
|
||||||
padding = 4;
|
padding = 4;
|
||||||
|
if (pkt->length + padding < pkt->forcepad)
|
||||||
|
padding = pkt->forcepad - pkt->length;
|
||||||
padding +=
|
padding +=
|
||||||
(cipherblk - (pkt->length + padding) % cipherblk) % cipherblk;
|
(cipherblk - (pkt->length + padding) % cipherblk) % cipherblk;
|
||||||
|
assert(padding <= 255);
|
||||||
maclen = ssh->csmac ? ssh->csmac->len : 0;
|
maclen = ssh->csmac ? ssh->csmac->len : 0;
|
||||||
ssh2_pkt_ensure(pkt, pkt->length + padding + maclen);
|
ssh2_pkt_ensure(pkt, pkt->length + padding + maclen);
|
||||||
pkt->data[4] = padding;
|
pkt->data[4] = padding;
|
||||||
@ -1791,6 +1798,7 @@ static void ssh2_pkt_send(Ssh ssh, struct Packet *pkt)
|
|||||||
ssh2_pkt_send_noqueue(ssh, pkt);
|
ssh2_pkt_send_noqueue(ssh, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* disused */
|
||||||
/*
|
/*
|
||||||
* Either queue or defer a packet, depending on whether queueing is
|
* Either queue or defer a packet, depending on whether queueing is
|
||||||
* set.
|
* set.
|
||||||
@ -1802,6 +1810,7 @@ static void ssh2_pkt_defer(Ssh ssh, struct Packet *pkt)
|
|||||||
else
|
else
|
||||||
ssh2_pkt_defer_noqueue(ssh, pkt);
|
ssh2_pkt_defer_noqueue(ssh, pkt);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the whole deferred data block constructed by
|
* Send the whole deferred data block constructed by
|
||||||
@ -6756,20 +6765,16 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
|
|||||||
}
|
}
|
||||||
} else if (s->method == AUTH_PASSWORD) {
|
} else if (s->method == AUTH_PASSWORD) {
|
||||||
/*
|
/*
|
||||||
* We send the password packet lumped tightly together with
|
* We pad out the password packet to 256 bytes to make
|
||||||
* an SSH_MSG_IGNORE packet. The IGNORE packet contains a
|
* it harder for an attacker to find the length of the
|
||||||
* string long enough to make the total length of the two
|
* user's password.
|
||||||
* packets constant. This should ensure that a passive
|
|
||||||
* listener doing traffic analyis can't work out the length
|
|
||||||
* of the password.
|
|
||||||
*
|
*
|
||||||
* For this to work, we need an assumption about the
|
* Anyone using a password longer than 256 bytes
|
||||||
* maximum length of the password packet. I think 256 is
|
* probably doesn't have much to worry about from
|
||||||
* pretty conservative. Anyone using a password longer than
|
|
||||||
* that probably doesn't have much to worry about from
|
|
||||||
* people who find out how long their password is!
|
* people who find out how long their password is!
|
||||||
*/
|
*/
|
||||||
s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
|
s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
|
s->pktout->forcepad = 256;
|
||||||
ssh2_pkt_addstring(s->pktout, s->username);
|
ssh2_pkt_addstring(s->pktout, s->username);
|
||||||
ssh2_pkt_addstring(s->pktout, "ssh-connection"); /* service requested */
|
ssh2_pkt_addstring(s->pktout, "ssh-connection"); /* service requested */
|
||||||
ssh2_pkt_addstring(s->pktout, "password");
|
ssh2_pkt_addstring(s->pktout, "password");
|
||||||
@ -6778,41 +6783,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
|
|||||||
ssh2_pkt_addstring(s->pktout, s->password);
|
ssh2_pkt_addstring(s->pktout, s->password);
|
||||||
memset(s->password, 0, sizeof(s->password));
|
memset(s->password, 0, sizeof(s->password));
|
||||||
end_log_omission(ssh, s->pktout);
|
end_log_omission(ssh, s->pktout);
|
||||||
ssh2_pkt_defer(ssh, s->pktout);
|
ssh2_pkt_send(ssh, s->pktout);
|
||||||
/*
|
|
||||||
* We'll include a string that's an exact multiple of the
|
|
||||||
* cipher block size. If the cipher is NULL for some
|
|
||||||
* reason, we don't do this trick at all because we gain
|
|
||||||
* nothing by it.
|
|
||||||
*/
|
|
||||||
if (ssh->cscipher) {
|
|
||||||
int stringlen, i;
|
|
||||||
|
|
||||||
stringlen = (256 - ssh->deferred_len);
|
|
||||||
stringlen += ssh->cscipher->blksize - 1;
|
|
||||||
stringlen -= (stringlen % ssh->cscipher->blksize);
|
|
||||||
if (ssh->cscomp) {
|
|
||||||
/*
|
|
||||||
* Temporarily disable actual compression,
|
|
||||||
* so we can guarantee to get this string
|
|
||||||
* exactly the length we want it. The
|
|
||||||
* compression-disabling routine should
|
|
||||||
* return an integer indicating how many
|
|
||||||
* bytes we should adjust our string length
|
|
||||||
* by.
|
|
||||||
*/
|
|
||||||
stringlen -=
|
|
||||||
ssh->cscomp->disable_compression(ssh->cs_comp_ctx);
|
|
||||||
}
|
|
||||||
s->pktout = ssh2_pkt_init(SSH2_MSG_IGNORE);
|
|
||||||
ssh2_pkt_addstring_start(s->pktout);
|
|
||||||
for (i = 0; i < stringlen; i++) {
|
|
||||||
char c = (char) random_byte();
|
|
||||||
ssh2_pkt_addstring_data(s->pktout, &c, 1);
|
|
||||||
}
|
|
||||||
ssh2_pkt_defer(ssh, s->pktout);
|
|
||||||
}
|
|
||||||
ssh_pkt_defersend(ssh);
|
|
||||||
logevent("Sent password");
|
logevent("Sent password");
|
||||||
s->type = AUTH_TYPE_PASSWORD;
|
s->type = AUTH_TYPE_PASSWORD;
|
||||||
} else if (s->method == AUTH_KEYBOARD_INTERACTIVE) {
|
} else if (s->method == AUTH_KEYBOARD_INTERACTIVE) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user