From: simon Date: Tue, 4 Feb 2003 13:02:51 +0000 (+0000) Subject: Add another bug workaround, this one for old OpenSSH (<2.3) servers X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/dda87a288bfdd67b3572a8f219c66382b1045782 Add another bug workaround, this one for old OpenSSH (<2.3) servers which have a strange idea of what data should be signed in a PK auth request. This actually got in my way while doing serious things at work! :-) git-svn-id: svn://svn.tartarus.org/sgt/putty@2800 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/doc/config.but b/doc/config.but index 6e4539c6..77a5566b 100644 --- a/doc/config.but +++ b/doc/config.but @@ -1,4 +1,4 @@ -\versionid $Id: config.but,v 1.53 2003/02/01 02:09:02 jacob Exp $ +\versionid $Id: config.but,v 1.54 2003/02/04 13:02:51 simon Exp $ \C{config} Configuring PuTTY @@ -2172,6 +2172,24 @@ workaround, you need to enable it manually. This is an SSH2-specific bug. +\S{config-ssh-bug-pksessid2} \q{Misuses the session ID in PK auth} + +\cfg{winhelp-topic}{ssh.bugs.rsapad2} + +Versions below 2.3 of OpenSSH require SSH2 public-key authentication +to be done slightly differently: the data to be signed by the client +contains the session ID formatted in a different way. If public-key +authentication mysteriously does not work but the Event Log (see +\k{using-eventlog}) thinks it has successfully sent a signature, it +might be worth enabling the workaround for this bug to see if it +helps. + +If this bug is detected, PuTTY will sign data in the way OpenSSH +expects. If this bug is enabled when talking to a correct server, +SSH2 public-key authentication will fail. + +This is an SSH2-specific bug. + \H{config-file} Storing configuration in a file PuTTY does not currently support storing its configuration in a file diff --git a/putty.h b/putty.h index 72d0cd22..5c5b1c18 100644 --- a/putty.h +++ b/putty.h @@ -439,7 +439,7 @@ struct config_tag { /* SSH bug compatibility modes */ int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1, sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2, - sshbug_dhgex2; + sshbug_dhgex2, sshbug_pksessid2; /* Options for pterm. Should split out into platform-dependent part. */ int stamp_utmp; int login_shell; diff --git a/settings.c b/settings.c index a4c514f0..790b9334 100644 --- a/settings.c +++ b/settings.c @@ -343,6 +343,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2); write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2); write_setting_i(sesskey, "BugDHGEx2", 2-cfg->sshbug_dhgex2); + write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2); write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp); write_setting_i(sesskey, "LoginShell", cfg->login_shell); write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left); @@ -616,6 +617,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) gppi(sesskey, "BugDeriveKey2", 0, &i); cfg->sshbug_derivekey2 = 2-i; gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i; gppi(sesskey, "BugDHGEx2", 0, &i); cfg->sshbug_dhgex2 = 2-i; + gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i; gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp); gppi(sesskey, "LoginShell", 1, &cfg->login_shell); gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left); diff --git a/ssh.c b/ssh.c index 88af2480..ba2e0753 100644 --- a/ssh.c +++ b/ssh.c @@ -163,6 +163,7 @@ static const char *const ssh2_disconnect_reasons[] = { #define BUG_SSH2_RSA_PADDING 16 #define BUG_SSH2_DERIVEKEY 32 #define BUG_SSH2_DH_GEX 64 +#define BUG_SSH2_PK_SESSIONID 128 #define translate(x) if (type == x) return #x #define translatec(x,ctx) if (type == x && (pkt_ctx & ctx)) return #x @@ -1792,6 +1793,17 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) logevent("We believe remote version has SSH2 RSA padding bug"); } + if (ssh->cfg.sshbug_pksessid2 == FORCE_ON || + (ssh->cfg.sshbug_pksessid2 == AUTO && + wc_match("OpenSSH_2.[0-2]*", imp))) { + /* + * These versions have the SSH2 session-ID bug in + * public-key authentication. + */ + ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID; + logevent("We believe remote version has SSH2 public-key-session-ID bug"); + } + if (ssh->cfg.sshbug_dhgex2 == FORCE_ON) { /* * User specified the SSH2 DH GEX bug. @@ -4629,6 +4641,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) ssh2_pkt_addstring_data(ssh, s->pkblob, s->pklen); s->siglen = ssh->pktout.length - 5 + 4 + 20; + if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID) + s->siglen -= 4; s->len = 1; /* message type */ s->len += 4 + s->pklen; /* key blob */ s->len += 4 + s->siglen; /* data to sign */ @@ -4644,8 +4658,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) PUT_32BIT(s->q, s->siglen); s->q += 4; /* Now the data to be signed... */ - PUT_32BIT(s->q, 20); - s->q += 4; + if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) { + PUT_32BIT(s->q, 20); + s->q += 4; + } memcpy(s->q, ssh->v2_session_id, 20); s->q += 20; memcpy(s->q, ssh->pktout.data + 5, @@ -4894,6 +4910,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) } else { unsigned char *pkblob, *sigblob, *sigdata; int pkblob_len, sigblob_len, sigdata_len; + int p; /* * We have loaded the private key and the server @@ -4919,11 +4936,19 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) * outgoing packet. */ sigdata_len = ssh->pktout.length - 5 + 4 + 20; + if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID) + sigdata_len -= 4; sigdata = smalloc(sigdata_len); - PUT_32BIT(sigdata, 20); - memcpy(sigdata + 4, ssh->v2_session_id, 20); - memcpy(sigdata + 24, ssh->pktout.data + 5, + p = 0; + if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) { + PUT_32BIT(sigdata+p, 20); + p += 4; + } + memcpy(sigdata+p, ssh->v2_session_id, 20); p += 20; + memcpy(sigdata+p, ssh->pktout.data + 5, ssh->pktout.length - 5); + p += ssh->pktout.length - 5; + assert(p == sigdata_len); sigblob = key->alg->sign(key->data, (char *)sigdata, sigdata_len, &sigblob_len); ssh2_add_sigblob(ssh, pkblob, pkblob_len, diff --git a/windlg.c b/windlg.c index 944cfda9..9299a006 100644 --- a/windlg.c +++ b/windlg.c @@ -559,6 +559,8 @@ enum { IDCX_ABOUT = IDC_BUGD_RSAPAD2, IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, + IDC_BUGS_PKSESSID2, + IDC_BUGD_PKSESSID2, sshbugspanelend, selectionpanelstart, @@ -1066,6 +1068,9 @@ char *help_context_cmd(int id) case IDC_BUGS_DHGEX2: case IDC_BUGD_DHGEX2: return "JI(`',`ssh.bugs.dhgex2')"; + case IDC_BUGS_PKSESSID2: + case IDC_BUGD_PKSESSID2: + return "JI(`',`ssh.bugs.pksessid2')"; default: return NULL; @@ -1426,6 +1431,13 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2, CB_SETCURSEL, cfg.sshbug_dhgex2 == FORCE_ON ? 2 : cfg.sshbug_dhgex2 == FORCE_OFF ? 1 : 0, 0); + SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Auto"); + SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"Off"); + SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_ADDSTRING, 0, (LPARAM)"On"); + SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, CB_SETCURSEL, + cfg.sshbug_pksessid2 == FORCE_ON ? 2 : + cfg.sshbug_pksessid2 == FORCE_OFF ? 1 : 0, 0); } struct treeview_faff { @@ -2039,6 +2051,8 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) IDC_BUGS_RSAPAD2, IDC_BUGD_RSAPAD2, 20); staticddl(&cp, "Chokes on &Diffie-Hellman group exchange", IDC_BUGS_DHGEX2, IDC_BUGD_DHGEX2, 20); + staticddl(&cp, "Misuses the sessio&n ID in PK auth", + IDC_BUGS_PKSESSID2, IDC_BUGD_PKSESSID2, 20); endbox(&cp); } } @@ -3678,6 +3692,14 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, index == 1 ? FORCE_OFF : FORCE_ON); } break; + case IDC_BUGD_PKSESSID2: + if (HIWORD(wParam) == CBN_SELCHANGE) { + int index = SendDlgItemMessage(hwnd, IDC_BUGD_PKSESSID2, + CB_GETCURSEL, 0, 0); + cfg.sshbug_pksessid2 = (index == 0 ? AUTO : + index == 1 ? FORCE_OFF : FORCE_ON); + } + break; } return 0; case WM_HELP: