Anecdotal evidence suggests that a single EnumPrinters() call
[u/mdw/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index b727456..7cc9d20 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -515,8 +515,6 @@ static const struct ssh_compress *sccomp = NULL;
 static const struct ssh_kex *kex = NULL;
 static const struct ssh_signkey *hostkey = NULL;
 static unsigned char ssh2_session_id[20];
-int (*ssh_get_line) (const char *prompt, char *str, int maxlen,
-                    int is_pw) = NULL;
 
 static char *savedhost;
 static int savedport;
@@ -1712,6 +1710,7 @@ static int do_ssh_init(unsigned char c)
     static int vstrsize;
     static char *vlog;
     static int i;
+    static int proto1, proto2;
 
     crBegin;
 
@@ -1768,12 +1767,26 @@ static int do_ssh_init(unsigned char c)
     sfree(vlog);
 
     /*
-     * Server version "1.99" means we can choose whether we use v1
-     * or v2 protocol. Choice is based on cfg.sshprot.
+     * Decide which SSH protocol version to support.
      */
-    if (ssh_versioncmp(version, cfg.sshprot == 1 ? "2.0" : "1.99") >= 0) {
+
+    /* Anything strictly below "2.0" means protocol 1 is supported. */
+    proto1 = ssh_versioncmp(version, "2.0") < 0;
+    /* Anything greater or equal to "1.99" means protocol 2 is supported. */
+    proto2 = ssh_versioncmp(version, "1.99") >= 0;
+
+    if (cfg.sshprot == 0 && !proto1) {
+       bombout(("SSH protocol version 1 required by user but not provided by server"));
+       crReturn(0);
+    }
+    if (cfg.sshprot == 3 && !proto2) {
+       bombout(("SSH protocol version 2 required by user but not provided by server"));
+       crReturn(0);
+    }
+
+    if (proto2 && (cfg.sshprot >= 2 || !proto1)) {
        /*
-        * This is a v2 server. Begin v2 protocol.
+        * Use v2 protocol.
         */
        char verstring[80], vlog[100];
        sprintf(verstring, "SSH-2.0-%s", sshver);
@@ -1793,7 +1806,7 @@ static int do_ssh_init(unsigned char c)
        s_rdpkt = ssh2_rdpkt;
     } else {
        /*
-        * This is a v1 server. Begin v1 protocol.
+        * Use v1 protocol.
         */
        char verstring[80], vlog[100];
        sprintf(verstring, "SSH-%s-%s",
@@ -1802,11 +1815,6 @@ static int do_ssh_init(unsigned char c)
        sprintf(vlog, "We claim version: %s", verstring);
        logevent(vlog);
        strcat(verstring, "\n");
-       
-       if (cfg.sshprot == 3) {
-           bombout(("SSH protocol version 2 required by user but not provided by server"));
-           crReturn(0);
-       }
 
        logevent("Using SSH protocol version 1");
        sk_write(s, verstring, strlen(verstring));
@@ -2228,7 +2236,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
        static int pos = 0;
        static char c;
        if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
-           if (ssh_get_line) {
+           if (ssh_get_line && !ssh_getline_pw_only) {
                if (!ssh_get_line("login as: ",
                                  username, sizeof(username), FALSE)) {
                    /*
@@ -4098,7 +4106,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
             * it again.
             */
        } else if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
-           if (ssh_get_line) {
+           if (ssh_get_line && !ssh_getline_pw_only) {
                if (!ssh_get_line("login as: ",
                                  username, sizeof(username), FALSE)) {
                    /*
@@ -4327,6 +4335,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                static int authed = FALSE;
                void *r;
 
+               ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
 
                tried_agent = TRUE;
@@ -4469,6 +4478,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
 
                tried_pubkey_config = TRUE;
 
+               ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh_pkt_ctx |= SSH2_PKTCTX_PUBLICKEY;
 
                /*
@@ -4523,6 +4533,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
+               ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
 
                ssh2_pkt_init(SSH2_MSG_USERAUTH_REQUEST);
@@ -4551,6 +4562,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
                tried_keyb_inter = TRUE;
 
+               ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh_pkt_ctx |= SSH2_PKTCTX_KBDINTER;
 
                if (curr_prompt == 0) {
@@ -4601,6 +4613,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
 
            if (!method && can_passwd) {
                method = AUTH_PASSWORD;
+               ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
                ssh_pkt_ctx |= SSH2_PKTCTX_PASSWORD;
                sprintf(pwprompt, "%.90s@%.90s's password: ", username,
                        savedhost);