mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-21 04:55:02 -05:00
Add a config option to emulate the HMAC bug in commercial SSH v2.3.x
and earlier (namely, it uses only 16 bytes of key rather than 20). [originally from svn r706]
This commit is contained in:
parent
421aafb4c0
commit
3e83d75154
1
putty.h
1
putty.h
@ -147,6 +147,7 @@ typedef struct {
|
|||||||
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
||||||
char keyfile[FILENAME_MAX];
|
char keyfile[FILENAME_MAX];
|
||||||
int sshprot; /* use v1 or v2 when both available */
|
int sshprot; /* use v1 or v2 when both available */
|
||||||
|
int buggymac; /* MAC bug commmercial <=v2.3.x SSH2 */
|
||||||
int try_tis_auth;
|
int try_tis_auth;
|
||||||
/* Telnet options */
|
/* Telnet options */
|
||||||
char termtype[32];
|
char termtype[32];
|
||||||
|
@ -78,6 +78,7 @@ void save_settings (char *section, int do_host, Config *cfg) {
|
|||||||
cfg->cipher == CIPHER_DES ? "des" : "3des");
|
cfg->cipher == CIPHER_DES ? "des" : "3des");
|
||||||
write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
|
write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
|
||||||
write_setting_i (sesskey, "SshProt", cfg->sshprot);
|
write_setting_i (sesskey, "SshProt", cfg->sshprot);
|
||||||
|
write_setting_i (sesskey, "BuggyMAC", cfg->buggymac);
|
||||||
write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile);
|
write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile);
|
||||||
write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd);
|
write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd);
|
||||||
write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ);
|
write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ);
|
||||||
@ -198,6 +199,7 @@ void load_settings (char *section, int do_host, Config *cfg) {
|
|||||||
cfg->cipher = CIPHER_3DES;
|
cfg->cipher = CIPHER_3DES;
|
||||||
}
|
}
|
||||||
gppi (sesskey, "SshProt", 1, &cfg->sshprot);
|
gppi (sesskey, "SshProt", 1, &cfg->sshprot);
|
||||||
|
gppi (sesskey, "BuggyMAC", 0, &cfg->buggymac);
|
||||||
gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
|
gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
|
||||||
gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
|
gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
|
||||||
gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd,
|
gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd,
|
||||||
|
36
ssh.c
36
ssh.c
@ -167,7 +167,7 @@ const static struct ssh_kex *kex_algs[] = { &ssh_diffiehellman };
|
|||||||
extern const struct ssh_hostkey ssh_dss;
|
extern const struct ssh_hostkey ssh_dss;
|
||||||
const static struct ssh_hostkey *hostkey_algs[] = { &ssh_dss };
|
const static struct ssh_hostkey *hostkey_algs[] = { &ssh_dss };
|
||||||
|
|
||||||
extern const struct ssh_mac ssh_sha1;
|
extern const struct ssh_mac ssh_sha1, ssh_sha1_buggy;
|
||||||
|
|
||||||
static void nullmac_key(unsigned char *key) { }
|
static void nullmac_key(unsigned char *key) { }
|
||||||
static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { }
|
static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { }
|
||||||
@ -176,6 +176,7 @@ const static struct ssh_mac ssh_mac_none = {
|
|||||||
nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0
|
nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0
|
||||||
};
|
};
|
||||||
const static struct ssh_mac *macs[] = { &ssh_sha1, &ssh_mac_none };
|
const static struct ssh_mac *macs[] = { &ssh_sha1, &ssh_mac_none };
|
||||||
|
const static struct ssh_mac *buggymacs[] = { &ssh_sha1_buggy, &ssh_mac_none };
|
||||||
|
|
||||||
const static struct ssh_compress ssh_comp_none = {
|
const static struct ssh_compress ssh_comp_none = {
|
||||||
"none"
|
"none"
|
||||||
@ -1828,6 +1829,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
static int i, len;
|
static int i, len;
|
||||||
static char *str;
|
static char *str;
|
||||||
static Bignum e, f, K;
|
static Bignum e, f, K;
|
||||||
|
static const struct ssh_mac **maclist;
|
||||||
static const struct ssh_cipher *cscipher_tobe = NULL;
|
static const struct ssh_cipher *cscipher_tobe = NULL;
|
||||||
static const struct ssh_cipher *sccipher_tobe = NULL;
|
static const struct ssh_cipher *sccipher_tobe = NULL;
|
||||||
static const struct ssh_mac *csmac_tobe = NULL;
|
static const struct ssh_mac *csmac_tobe = NULL;
|
||||||
@ -1858,6 +1860,14 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
preferred_cipher = &ssh_3des_ssh2;
|
preferred_cipher = &ssh_3des_ssh2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Be prepared to work around the buggy MAC problem.
|
||||||
|
*/
|
||||||
|
if (cfg.buggymac)
|
||||||
|
maclist = buggymacs;
|
||||||
|
else
|
||||||
|
maclist = macs;
|
||||||
|
|
||||||
begin_key_exchange:
|
begin_key_exchange:
|
||||||
/*
|
/*
|
||||||
* Construct and send our key exchange packet.
|
* Construct and send our key exchange packet.
|
||||||
@ -1897,16 +1907,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
/* List client->server MAC algorithms. */
|
/* List client->server MAC algorithms. */
|
||||||
ssh2_pkt_addstring_start();
|
ssh2_pkt_addstring_start();
|
||||||
for (i = 0; i < lenof(macs); i++) {
|
for (i = 0; i < lenof(maclist); i++) {
|
||||||
ssh2_pkt_addstring_str(macs[i]->name);
|
ssh2_pkt_addstring_str(maclist[i]->name);
|
||||||
if (i < lenof(macs)-1)
|
if (i < lenof(maclist)-1)
|
||||||
ssh2_pkt_addstring_str(",");
|
ssh2_pkt_addstring_str(",");
|
||||||
}
|
}
|
||||||
/* List server->client MAC algorithms. */
|
/* List server->client MAC algorithms. */
|
||||||
ssh2_pkt_addstring_start();
|
ssh2_pkt_addstring_start();
|
||||||
for (i = 0; i < lenof(macs); i++) {
|
for (i = 0; i < lenof(maclist); i++) {
|
||||||
ssh2_pkt_addstring_str(macs[i]->name);
|
ssh2_pkt_addstring_str(maclist[i]->name);
|
||||||
if (i < lenof(macs)-1)
|
if (i < lenof(maclist)-1)
|
||||||
ssh2_pkt_addstring_str(",");
|
ssh2_pkt_addstring_str(",");
|
||||||
}
|
}
|
||||||
/* List client->server compression algorithms. */
|
/* List client->server compression algorithms. */
|
||||||
@ -1979,16 +1989,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ssh2_pkt_getstring(&str, &len); /* client->server mac */
|
ssh2_pkt_getstring(&str, &len); /* client->server mac */
|
||||||
for (i = 0; i < lenof(macs); i++) {
|
for (i = 0; i < lenof(maclist); i++) {
|
||||||
if (in_commasep_string(macs[i]->name, str, len)) {
|
if (in_commasep_string(maclist[i]->name, str, len)) {
|
||||||
csmac_tobe = macs[i];
|
csmac_tobe = maclist[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ssh2_pkt_getstring(&str, &len); /* server->client mac */
|
ssh2_pkt_getstring(&str, &len); /* server->client mac */
|
||||||
for (i = 0; i < lenof(macs); i++) {
|
for (i = 0; i < lenof(maclist); i++) {
|
||||||
if (in_commasep_string(macs[i]->name, str, len)) {
|
if (in_commasep_string(maclist[i]->name, str, len)) {
|
||||||
scmac_tobe = macs[i];
|
scmac_tobe = maclist[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
sshsha.c
16
sshsha.c
@ -199,6 +199,14 @@ static void sha1_sckey(unsigned char *key) {
|
|||||||
sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 20);
|
sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sha1_cskey_buggy(unsigned char *key) {
|
||||||
|
sha1_key(&sha1_cs_mac_s1, &sha1_cs_mac_s2, key, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sha1_sckey_buggy(unsigned char *key) {
|
||||||
|
sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 16);
|
||||||
|
}
|
||||||
|
|
||||||
static void sha1_do_hmac(SHA_State *s1, SHA_State *s2,
|
static void sha1_do_hmac(SHA_State *s1, SHA_State *s2,
|
||||||
unsigned char *blk, int len, unsigned long seq,
|
unsigned char *blk, int len, unsigned long seq,
|
||||||
unsigned char *hmac) {
|
unsigned char *hmac) {
|
||||||
@ -236,3 +244,11 @@ struct ssh_mac ssh_sha1 = {
|
|||||||
"hmac-sha1",
|
"hmac-sha1",
|
||||||
20
|
20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ssh_mac ssh_sha1_buggy = {
|
||||||
|
sha1_cskey_buggy, sha1_sckey_buggy,
|
||||||
|
sha1_generate,
|
||||||
|
sha1_verify,
|
||||||
|
"hmac-sha1",
|
||||||
|
20
|
||||||
|
};
|
||||||
|
9
windlg.c
9
windlg.c
@ -945,6 +945,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
|
|||||||
IDC_CIPHER3DES,
|
IDC_CIPHER3DES,
|
||||||
IDC_CIPHERBLOWF,
|
IDC_CIPHERBLOWF,
|
||||||
IDC_CIPHERDES,
|
IDC_CIPHERDES,
|
||||||
|
IDC_BUGGYMAC,
|
||||||
IDC_AUTHTIS,
|
IDC_AUTHTIS,
|
||||||
IDC_PKSTATIC,
|
IDC_PKSTATIC,
|
||||||
IDC_PKEDIT,
|
IDC_PKEDIT,
|
||||||
@ -1109,6 +1110,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_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,
|
||||||
cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
|
cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
|
||||||
@ -1575,6 +1577,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||||||
"&3DES", IDC_CIPHER3DES,
|
"&3DES", IDC_CIPHER3DES,
|
||||||
"&Blowfish", IDC_CIPHERBLOWF,
|
"&Blowfish", IDC_CIPHERBLOWF,
|
||||||
"&DES", IDC_CIPHERDES, NULL);
|
"&DES", IDC_CIPHERDES, NULL);
|
||||||
|
checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
|
||||||
|
IDC_BUGGYMAC);
|
||||||
endbox(&cp);
|
endbox(&cp);
|
||||||
|
|
||||||
treeview_insert(&tvfaff, 1, "SSH");
|
treeview_insert(&tvfaff, 1, "SSH");
|
||||||
@ -2059,6 +2063,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_BUGGYMAC:
|
||||||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
|
cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
|
||||||
|
break;
|
||||||
case IDC_AGENTFWD:
|
case IDC_AGENTFWD:
|
||||||
if (HIWORD(wParam) == BN_CLICKED ||
|
if (HIWORD(wParam) == BN_CLICKED ||
|
||||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user