Browse Source

Updating code for changes for vuln-agent-keylist-used-after-free

Source commit: 0722e645b9da9041b3bbef2e7ad8242c814a7f52
Martin Prikryl 5 years ago
parent
commit
3b2197fbc0
3 changed files with 33 additions and 8 deletions
  1. 5 2
      source/putty/defs.h
  2. 16 3
      source/putty/ssh1login.c
  3. 12 3
      source/putty/ssh2userauth.c

+ 5 - 2
source/putty/defs.h

@@ -15,9 +15,8 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-#ifndef WINSCP
 // This is used in pageant, pscp, psftp and servers only
-#if defined _MSC_VER && _MSC_VER < 1800
+#if (!defined WINSCP) && defined _MSC_VER && _MSC_VER < 1800
 /* Work around lack of inttypes.h and strtoumax in older MSVC */
 #define PRIx32 "x"
 #define PRIu64 "I64u"
@@ -26,8 +25,12 @@
 #define SCNu64 "I64u"
 uintmax_t strtoumax(const char *nptr, char **endptr, int base);
 #else
+#ifndef WINSCP
+// Not needed by the code WinSCP uses
 #include <inttypes.h>
 #endif
+#define SIZEx "zx"
+#define SIZEu "zu"
 #endif
 
 typedef struct conf_tag Conf;

+ 16 - 3
source/putty/ssh1login.c

@@ -127,7 +127,8 @@ static void ssh1_login_free(PacketProtocolLayer *ppl)
     if (s->cur_prompt)
         free_prompts(s->cur_prompt);
     if (s->agent_keys) {
-        for (size_t i = 0; i < s->agent_keys_len; i++) {
+        size_t i; // WINSCP
+        for (i = 0; i < s->agent_keys_len; i++) {
             freersakey(&s->agent_keys[i].key);
             strbuf_free(s->agent_keys[i].comment);
         }
@@ -522,7 +523,9 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                 /*
                  * Check that the agent response is well formed.
                  */
-                for (size_t i = 0; i < nkeys; i++) {
+                { // WINSCP
+                size_t i; // WINSCP
+                for (i = 0; i < nkeys; i++) {
                     get_rsa_ssh1_pub(s->asrc, NULL, RSA_SSH1_EXPONENT_FIRST);
                     get_string(s->asrc); /* comment */
                     if (get_err(s->asrc)) {
@@ -530,6 +533,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                         goto parsed_agent_query;
                     }
                 }
+                } // WINSCP
 
                 /*
                  * Copy the list of public-key blobs out of the Pageant
@@ -538,13 +542,17 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                 BinarySource_REWIND_TO(s->asrc, origpos);
                 s->agent_keys_len = nkeys;
                 s->agent_keys = snewn(s->agent_keys_len, agent_key);
-                for (size_t i = 0; i < nkeys; i++) {
+                { // WINSCP
+                size_t i; // WINSCP
+                for (i = 0; i < nkeys; i++) {
                     memset(&s->agent_keys[i].key, 0,
                            sizeof(s->agent_keys[i].key));
 
+                    { // WINSCP
                     const char *blobstart = get_ptr(s->asrc);
                     get_rsa_ssh1_pub(s->asrc, &s->agent_keys[i].key,
                                      RSA_SSH1_EXPONENT_FIRST);
+                    { // WINSCP
                     const char *blobend = get_ptr(s->asrc);
 
                     s->agent_keys[i].comment = strbuf_new();
@@ -552,7 +560,10 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
 
                     s->agent_keys[i].blob = make_ptrlen(
                         blobstart, blobend - blobstart);
+                    } // WINSCP
+                    } // WINSCP
                 }
+                } // WINSCP
 
                 ppl_logevent("Pageant has %"SIZEu" SSH-1 keys", nkeys);
 
@@ -617,6 +628,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                         return;
                     }
 
+                    { // WINSCP
                     strbuf *agentreq = strbuf_new_for_agent_query();
                     put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE);
 
@@ -633,6 +645,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                     ssh1_login_agent_query(s, agentreq);
                     strbuf_free(agentreq);
                     crMaybeWaitUntilV(!s->auth_agent_query);
+                    } // WINSCP
                 }
 
                 {

+ 12 - 3
source/putty/ssh2userauth.c

@@ -183,7 +183,8 @@ static void ssh2_userauth_free(PacketProtocolLayer *ppl)
         ssh_ppl_free(s->successor_layer);
 
     if (s->agent_keys) {
-        for (size_t i = 0; i < s->agent_keys_len; i++) {
+        size_t i; // WINSCP
+        for (i = 0; i < s->agent_keys_len; i++) {
             strbuf_free(s->agent_keys[i].blob);
             strbuf_free(s->agent_keys[i].comment);
         }
@@ -338,7 +339,9 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
             /*
              * Check that the agent response is well formed.
              */
-            for (size_t i = 0; i < nkeys; i++) {
+            { // WINSCP
+            size_t i; // WINSCP
+            for (i = 0; i < nkeys; i++) {
                 get_string(s->asrc);   /* blob */
                 get_string(s->asrc);   /* comment */
                 if (get_err(s->asrc)) {
@@ -346,6 +349,7 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
                     goto done_agent_query;
                 }
             }
+            } // WINSCP
 
             /*
              * Copy the list of public-key blobs out of the Pageant
@@ -354,19 +358,24 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
             BinarySource_REWIND_TO(s->asrc, origpos);
             s->agent_keys_len = nkeys;
             s->agent_keys = snewn(s->agent_keys_len, agent_key);
-            for (size_t i = 0; i < nkeys; i++) {
+            { // WINSCP
+            size_t i; // WINSCP
+            for (i = 0; i < nkeys; i++) {
                 s->agent_keys[i].blob = strbuf_new();
                 put_datapl(s->agent_keys[i].blob, get_string(s->asrc));
                 s->agent_keys[i].comment = strbuf_new();
                 put_datapl(s->agent_keys[i].comment, get_string(s->asrc));
 
+                { // WINSCP
                 /* Also, extract the algorithm string from the start
                  * of the public-key blob. */
                 BinarySource src[1];
                 BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(
                     s->agent_keys[i].blob));
                 s->agent_keys[i].algorithm = get_string(src);
+                } // WINSCP
             }
+            } // WINSCP
 
             ppl_logevent("Pageant has %"SIZEu" SSH-2 keys", nkeys);