Having laboriously constructed a hints parameter for getaddrinfo, it
[u/mdw/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index a9e04bf..3ca48c5 100644 (file)
--- a/ssh.c
+++ b/ssh.c
  */
 #define SSH2_PKTCTX_DHGROUP          0x0001
 #define SSH2_PKTCTX_DHGEX            0x0002
+#define SSH2_PKTCTX_KEX_MASK         0x000F
 #define SSH2_PKTCTX_PUBLICKEY        0x0010
 #define SSH2_PKTCTX_PASSWORD         0x0020
 #define SSH2_PKTCTX_KBDINTER         0x0040
@@ -2834,8 +2835,11 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
        }
 
        /* Warn about chosen cipher if necessary. */
-       if (warn)
+       if (warn) {
+            sk_set_frozen(ssh->s, 1);
            askalg(ssh->frontend, "cipher", cipher_string);
+            sk_set_frozen(ssh->s, 0);
+        }
     }
 
     switch (s->cipher_type) {
@@ -4672,6 +4676,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
        s->maclist = macs, s->nmacs = lenof(macs);
 
   begin_key_exchange:
+    ssh->pkt_ctx &= ~SSH2_PKTCTX_KEX_MASK;
     {
        int i, j, commalist_started;
 
@@ -4889,9 +4894,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
                ssh->kex = k;
            }
            if (ssh->kex) {
-               if (s->warn)
+               if (s->warn) {
+                    sk_set_frozen(ssh->s, 1);
                    askalg(ssh->frontend, "key-exchange algorithm",
                           ssh->kex->name);
+                    sk_set_frozen(ssh->s, 0);
+                }
                break;
            }
        }
@@ -4922,9 +4930,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
                }
            }
            if (s->cscipher_tobe) {
-               if (s->warn)
+               if (s->warn) {
+                    sk_set_frozen(ssh->s, 1);
                    askalg(ssh->frontend, "client-to-server cipher",
                           s->cscipher_tobe->name);
+                    sk_set_frozen(ssh->s, 0);
+                }
                break;
            }
        }
@@ -4949,9 +4960,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
                }
            }
            if (s->sccipher_tobe) {
-               if (s->warn)
+               if (s->warn) {
+                    sk_set_frozen(ssh->s, 1);
                    askalg(ssh->frontend, "server-to-client cipher",
                           s->sccipher_tobe->name);
+                    sk_set_frozen(ssh->s, 0);
+                }
                break;
            }
        }
@@ -5108,9 +5122,11 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
      */
     s->keystr = ssh->hostkey->fmtkey(s->hkey);
     s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
+    sk_set_frozen(ssh->s, 1);
     verify_ssh_host_key(ssh->frontend,
                        ssh->savedhost, ssh->savedport, ssh->hostkey->keytype,
                        s->keystr, s->fingerprint);
+    sk_set_frozen(ssh->s, 0);
     if (!s->got_session_id) {     /* don't bother logging this in rekeys */
        logevent("Host key fingerprint is:");
        logevent(s->fingerprint);
@@ -5921,8 +5937,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
        } type;
        int gotit, need_pw, can_pubkey, can_passwd, can_keyb_inter;
-       int tried_pubkey_config, tried_agent, tried_keyb_inter;
-       int kbd_inter_running;
+       int tried_pubkey_config, tried_agent;
+       int kbd_inter_running, kbd_inter_refused;
        int we_are_in;
        int num_prompts, curr_prompt, echo;
        char username[100];
@@ -6051,8 +6067,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
 
        s->tried_pubkey_config = FALSE;
        s->tried_agent = FALSE;
-       s->tried_keyb_inter = FALSE;
        s->kbd_inter_running = FALSE;
+       s->kbd_inter_refused = FALSE;
        /* Load the pub half of ssh->cfg.keyfile so we notice if it's in Pageant */
        if (!filename_is_null(ssh->cfg.keyfile)) {
            int keytype;
@@ -6119,6 +6135,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                 */
                if (!s->gotit)
                    s->curr_prompt = 0;
+           } else if (pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) {
+               /* FIXME: perhaps we should support this? */
+               bombout(("PASSWD_CHANGEREQ not yet supported"));
+               crStopV;
            } else if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
                bombout(("Strange packet received during authentication: type %d",
                         pktin->type));
@@ -6443,10 +6463,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                }
            }
 
-           if (!s->method && s->can_keyb_inter && !s->tried_keyb_inter) {
+           if (!s->method && s->can_keyb_inter && !s->kbd_inter_refused &&
+               !s->kbd_inter_running) {
                s->method = AUTH_KEYBOARD_INTERACTIVE;
                s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
-               s->tried_keyb_inter = TRUE;
 
                ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;
@@ -6465,6 +6485,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                        s->gotit = TRUE;
                    logevent("Keyboard-interactive authentication refused");
                    s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
+                   s->kbd_inter_refused = TRUE; /* don't try it again */
                    continue;
                }
 
@@ -6475,7 +6496,6 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
            if (s->kbd_inter_running) {
                s->method = AUTH_KEYBOARD_INTERACTIVE;
                s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
-               s->tried_keyb_inter = TRUE;
 
                ssh->pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh->pkt_ctx |= SSH2_PKTCTX_KBDINTER;