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];
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);
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,
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) { }
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"
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;
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.
}
/* 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. */
}
}
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;
}
}
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) {
"hmac-sha1",
20
};
+
+struct ssh_mac ssh_sha1_buggy = {
+ sha1_cskey_buggy, sha1_sckey_buggy,
+ sha1_generate,
+ sha1_verify,
+ "hmac-sha1",
+ 20
+};
IDC_CIPHER3DES,
IDC_CIPHERBLOWF,
IDC_CIPHERDES,
+ IDC_BUGGYMAC,
IDC_AUTHTIS,
IDC_PKSTATIC,
IDC_PKEDIT,
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 :
"&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");
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)