The WinSock library is now loaded at run-time, which means we can
[u/mdw/putty] / pageant.c
index 50daf63..9d39e46 100644 (file)
--- a/pageant.c
+++ b/pageant.c
@@ -2,10 +2,6 @@
  * Pageant: the PuTTY Authentication Agent.
  */
 
-#include <windows.h>
-#ifndef NO_SECURITY
-#include <aclapi.h>
-#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include "ssh.h"
 #include "misc.h"
 #include "tree234.h"
-#include "winstuff.h"
+
+#ifndef NO_SECURITY
+#include <aclapi.h>
+#endif
 
 #define IDI_MAINICON 200
 #define IDI_TRAYICON 201
@@ -114,12 +113,6 @@ static gsi_fn_t getsecurityinfo;
 #endif
 
 /*
- * Exports from pageantc.c
- */
-void agent_query(void *in, int inlen, void **out, int *outlen);
-int agent_exists(void);
-
-/*
  * Forward references
  */
 static void *make_keylist1(int *length);
@@ -422,7 +415,7 @@ static void add_keyfile(Filename filename)
        int i, nkeys, bloblen;
 
        if (type == SSH_KEYTYPE_SSH1) {
-           if (!rsakey_pubblob(&filename, &blob, &bloblen)) {
+           if (!rsakey_pubblob(&filename, &blob, &bloblen, NULL)) {
                MessageBox(NULL, "Couldn't load private key.", APPNAME,
                           MB_OK | MB_ICONERROR);
                return;
@@ -430,14 +423,14 @@ static void add_keyfile(Filename filename)
            keylist = get_keylist1();
        } else {
            unsigned char *blob2;
-           blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen);
+           blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen, NULL);
            if (!blob) {
                MessageBox(NULL, "Couldn't load private key.", APPNAME,
                           MB_OK | MB_ICONERROR);
                return;
            }
            /* For our purposes we want the blob prefixed with its length */
-           blob2 = smalloc(bloblen+4);
+           blob2 = snewn(bloblen+4, unsigned char);
            PUT_32BIT(blob2, bloblen);
            memcpy(blob2 + 4, blob, bloblen);
            sfree(blob);
@@ -477,7 +470,7 @@ static void add_keyfile(Filename filename)
        needs_pass = ssh2_userkey_encrypted(&filename, &comment);
     attempts = 0;
     if (type == SSH_KEYTYPE_SSH1)
-       rkey = smalloc(sizeof(*rkey));
+       rkey = snew(struct RSAKey);
     pps.passphrase = passphrase;
     pps.comment = comment;
     original_pass = 0;
@@ -504,9 +497,9 @@ static void add_keyfile(Filename filename)
        } else
            *passphrase = '\0';
        if (type == SSH_KEYTYPE_SSH1)
-           ret = loadrsakey(&filename, rkey, passphrase);
+           ret = loadrsakey(&filename, rkey, passphrase, NULL);
        else {
-           skey = ssh2_load_userkey(&filename, passphrase);
+           skey = ssh2_load_userkey(&filename, passphrase, NULL);
            if (skey == SSH2_WRONG_PASSPHRASE)
                ret = -1;
            else if (!skey)
@@ -536,7 +529,7 @@ static void add_keyfile(Filename filename)
        if (already_running) {
            unsigned char *request, *response;
            void *vresponse;
-           int reqlen, clen, resplen;
+           int reqlen, clen, resplen, ret;
 
            clen = strlen(rkey->comment);
 
@@ -550,7 +543,7 @@ static void add_keyfile(Filename filename)
                ssh1_bignum_length(rkey->q) + 4 + clen  /* comment */
                ;
 
-           request = smalloc(reqlen);
+           request = snewn(reqlen, unsigned char);
 
            request[4] = SSH1_AGENTC_ADD_RSA_IDENTITY;
            reqlen = 5;
@@ -569,7 +562,9 @@ static void add_keyfile(Filename filename)
            reqlen += 4 + clen;
            PUT_32BIT(request, reqlen - 4);
 
-           agent_query(request, reqlen, &vresponse, &resplen);
+           ret = agent_query(request, reqlen, &vresponse, &resplen,
+                             NULL, NULL);
+           assert(ret == 1);
            response = vresponse;
            if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
                MessageBox(NULL, "The already running Pageant "
@@ -586,7 +581,7 @@ static void add_keyfile(Filename filename)
        if (already_running) {
            unsigned char *request, *response;
            void *vresponse;
-           int reqlen, alglen, clen, keybloblen, resplen;
+           int reqlen, alglen, clen, keybloblen, resplen, ret;
            alglen = strlen(skey->alg->name);
            clen = strlen(skey->comment);
 
@@ -598,7 +593,7 @@ static void add_keyfile(Filename filename)
                4 + clen               /* comment */
                ;
 
-           request = smalloc(reqlen);
+           request = snewn(reqlen, unsigned char);
 
            request[4] = SSH2_AGENTC_ADD_IDENTITY;
            reqlen = 5;
@@ -614,7 +609,9 @@ static void add_keyfile(Filename filename)
            PUT_32BIT(request, reqlen - 4);
            reqlen += clen + 4;
 
-           agent_query(request, reqlen, &vresponse, &resplen);
+           ret = agent_query(request, reqlen, &vresponse, &resplen,
+                             NULL, NULL);
+           assert(ret == 1);
            response = vresponse;
            if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS)
                MessageBox(NULL, "The already running Pageant "
@@ -657,7 +654,7 @@ static void *make_keylist1(int *length)
     }
 
     /* Allocate the buffer. */
-    p = ret = smalloc(len);
+    p = ret = snewn(len, unsigned char);
     if (length) *length = len;
 
     PUT_32BIT(p, nkeys);
@@ -702,7 +699,7 @@ static void *make_keylist2(int *length)
     }
 
     /* Allocate the buffer. */
-    p = ret = smalloc(len);
+    p = ret = snewn(len, unsigned char);
     if (length) *length = len;
 
     /*
@@ -739,16 +736,17 @@ static void *get_keylist1(void)
     if (already_running) {
        unsigned char request[5], *response;
        void *vresponse;
-       int resplen;
+       int resplen, retval;
        request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
        PUT_32BIT(request, 4);
 
-       agent_query(request, 5, &vresponse, &resplen);
+       retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
+       assert(retval == 1);
        response = vresponse;
        if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER)
            return NULL;
 
-       ret = smalloc(resplen-5);
+       ret = snewn(resplen-5, unsigned char);
        memcpy(ret, response+5, resplen-5);
        sfree(response);
     } else {
@@ -769,17 +767,18 @@ static void *get_keylist2(void)
     if (already_running) {
        unsigned char request[5], *response;
        void *vresponse;
-       int resplen;
+       int resplen, retval;
 
        request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
        PUT_32BIT(request, 4);
 
-       agent_query(request, 5, &vresponse, &resplen);
+       retval = agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
+       assert(retval == 1);
        response = vresponse;
        if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER)
            return NULL;
 
-       ret = smalloc(resplen-5);
+       ret = snewn(resplen-5, unsigned char);
        memcpy(ret, response+5, resplen-5);
        sfree(response);
     } else {
@@ -931,7 +930,7 @@ static void answer_msg(void *msg)
            struct RSAKey *key;
            char *comment;
             int commentlen;
-           key = smalloc(sizeof(struct RSAKey));
+           key = snew(struct RSAKey);
            memset(key, 0, sizeof(struct RSAKey));
            p += makekey(p, key, NULL, 1);
            p += makeprivate(p, key);
@@ -939,7 +938,7 @@ static void answer_msg(void *msg)
            p += ssh1_read_bignum(p, &key->p);  /* p */
            p += ssh1_read_bignum(p, &key->q);  /* q */
             commentlen = GET_32BIT(p);
-           comment = smalloc(commentlen+1);
+           comment = snewn(commentlen+1, char);
            if (comment) {
                memcpy(comment, p + 4, commentlen);
                 comment[commentlen] = '\0';
@@ -967,7 +966,7 @@ static void answer_msg(void *msg)
            int alglen, commlen;
            int bloblen;
 
-           key = smalloc(sizeof(struct ssh2_userkey));
+           key = snew(struct ssh2_userkey);
 
            alglen = GET_32BIT(p);
            p += 4;
@@ -995,7 +994,7 @@ static void answer_msg(void *msg)
            commlen = GET_32BIT(p);
            p += 4;
 
-           comment = smalloc(commlen + 1);
+           comment = snewn(commlen + 1, char);
            if (comment) {
                memcpy(comment, p, commlen);
                comment[commlen] = '\0';
@@ -1240,7 +1239,7 @@ static void prompt_add_keyfile(void)
 {
     OPENFILENAME of;
     char filename[FILENAME_MAX];
-    char *filelist = smalloc(8192);
+    char *filelist = snewn(8192, char);
     char *filewalker;
     int n, dirlen;
        
@@ -1387,7 +1386,7 @@ static int CALLBACK KeyListProc(HWND hwnd, UINT msg,
                }
 
                /* get item indices in an array */
-               selectedArray = smalloc(numSelected * sizeof(int));
+               selectedArray = snewn(numSelected, int);
                SendDlgItemMessage(hwnd, 100, LB_GETSELITEMS,
                                numSelected, (WPARAM)selectedArray);
                
@@ -1792,13 +1791,24 @@ void spawn_cmd(char *cmdline, char * args, int show)
     }
 }
 
+/*
+ * This is a can't-happen stub, since Pageant never makes
+ * asynchronous agent requests.
+ */
+void agent_schedule_callback(void (*callback)(void *, void *, int),
+                            void *callback_ctx, void *data, int len)
+{
+    assert(!"We shouldn't get here");
+}
+
 void cleanup_exit(int code) { exit(code); }
 
+int flags = FLAG_SYNCAGENT;
+
 int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
 {
     WNDCLASS wndclass;
     MSG msg;
-    OSVERSIONINFO osi;
     HMODULE advapi;
     char *command = NULL;
     int added_keys = 0;
@@ -1809,9 +1819,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
      * Determine whether we're an NT system (should have security
      * APIs) or a non-NT system (don't do security).
      */
-    memset(&osi, 0, sizeof(OSVERSIONINFO));
-    osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    if (GetVersionEx(&osi) && osi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+    if (!init_winver())
+    {
+       modalfatalbox("Windows refuses to report a version");
+    }
+    if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) {
        has_security = TRUE;
     } else
        has_security = FALSE;