зеркало из https://github.com/github/putty.git
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:
Родитель
421aafb4c0
Коммит
3e83d75154
1
putty.h
1
putty.h
|
@ -147,6 +147,7 @@ typedef struct {
|
|||
enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
|
||||
char keyfile[FILENAME_MAX];
|
||||
int sshprot; /* use v1 or v2 when both available */
|
||||
int buggymac; /* MAC bug commmercial <=v2.3.x SSH2 */
|
||||
int try_tis_auth;
|
||||
/* Telnet options */
|
||||
char termtype[32];
|
||||
|
|
|
@ -78,6 +78,7 @@ void save_settings (char *section, int do_host, Config *cfg) {
|
|||
cfg->cipher == CIPHER_DES ? "des" : "3des");
|
||||
write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
|
||||
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, "RemoteCommand", cfg->remote_cmd);
|
||||
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;
|
||||
}
|
||||
gppi (sesskey, "SshProt", 1, &cfg->sshprot);
|
||||
gppi (sesskey, "BuggyMAC", 0, &cfg->buggymac);
|
||||
gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
|
||||
gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
|
||||
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;
|
||||
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_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
|
||||
};
|
||||
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 = {
|
||||
"none"
|
||||
|
@ -1828,6 +1829,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
|
|||
static int i, len;
|
||||
static char *str;
|
||||
static Bignum e, f, K;
|
||||
static const struct ssh_mac **maclist;
|
||||
static const struct ssh_cipher *cscipher_tobe = NULL;
|
||||
static const struct ssh_cipher *sccipher_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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Be prepared to work around the buggy MAC problem.
|
||||
*/
|
||||
if (cfg.buggymac)
|
||||
maclist = buggymacs;
|
||||
else
|
||||
maclist = macs;
|
||||
|
||||
begin_key_exchange:
|
||||
/*
|
||||
* 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. */
|
||||
ssh2_pkt_addstring_start();
|
||||
for (i = 0; i < lenof(macs); i++) {
|
||||
ssh2_pkt_addstring_str(macs[i]->name);
|
||||
if (i < lenof(macs)-1)
|
||||
for (i = 0; i < lenof(maclist); i++) {
|
||||
ssh2_pkt_addstring_str(maclist[i]->name);
|
||||
if (i < lenof(maclist)-1)
|
||||
ssh2_pkt_addstring_str(",");
|
||||
}
|
||||
/* List server->client MAC algorithms. */
|
||||
ssh2_pkt_addstring_start();
|
||||
for (i = 0; i < lenof(macs); i++) {
|
||||
ssh2_pkt_addstring_str(macs[i]->name);
|
||||
if (i < lenof(macs)-1)
|
||||
for (i = 0; i < lenof(maclist); i++) {
|
||||
ssh2_pkt_addstring_str(maclist[i]->name);
|
||||
if (i < lenof(maclist)-1)
|
||||
ssh2_pkt_addstring_str(",");
|
||||
}
|
||||
/* 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 */
|
||||
for (i = 0; i < lenof(macs); i++) {
|
||||
if (in_commasep_string(macs[i]->name, str, len)) {
|
||||
csmac_tobe = macs[i];
|
||||
for (i = 0; i < lenof(maclist); i++) {
|
||||
if (in_commasep_string(maclist[i]->name, str, len)) {
|
||||
csmac_tobe = maclist[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssh2_pkt_getstring(&str, &len); /* server->client mac */
|
||||
for (i = 0; i < lenof(macs); i++) {
|
||||
if (in_commasep_string(macs[i]->name, str, len)) {
|
||||
scmac_tobe = macs[i];
|
||||
for (i = 0; i < lenof(maclist); i++) {
|
||||
if (in_commasep_string(maclist[i]->name, str, len)) {
|
||||
scmac_tobe = maclist[i];
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned char *blk, int len, unsigned long seq,
|
||||
unsigned char *hmac) {
|
||||
|
@ -236,3 +244,11 @@ struct ssh_mac ssh_sha1 = {
|
|||
"hmac-sha1",
|
||||
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_CIPHERBLOWF,
|
||||
IDC_CIPHERDES,
|
||||
IDC_BUGGYMAC,
|
||||
IDC_AUTHTIS,
|
||||
IDC_PKSTATIC,
|
||||
IDC_PKEDIT,
|
||||
|
@ -1109,6 +1110,7 @@ static void init_dlg_ctrls(HWND hwnd) {
|
|||
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
|
||||
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
|
||||
CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
|
||||
CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
|
||||
CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
|
||||
CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
|
||||
cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
|
||||
|
@ -1575,6 +1577,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||
"&3DES", IDC_CIPHER3DES,
|
||||
"&Blowfish", IDC_CIPHERBLOWF,
|
||||
"&DES", IDC_CIPHERDES, NULL);
|
||||
checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
|
||||
IDC_BUGGYMAC);
|
||||
endbox(&cp);
|
||||
|
||||
treeview_insert(&tvfaff, 1, "SSH");
|
||||
|
@ -2059,6 +2063,11 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
|
|||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||
cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
|
||||
break;
|
||||
case IDC_BUGGYMAC:
|
||||
if (HIWORD(wParam) == BN_CLICKED ||
|
||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||
cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
|
||||
break;
|
||||
case IDC_AGENTFWD:
|
||||
if (HIWORD(wParam) == BN_CLICKED ||
|
||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||
|
|
Загрузка…
Ссылка в новой задаче