]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - pageantc.c
Added Pageant, a first-attempt PuTTY authentication agent
[PuTTY.git] / pageantc.c
1 /*
2  * Pageant client code.
3  */
4
5 #include <windows.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 #ifdef TESTMODE
10 #define debug(x) (printf x)
11 #else
12 #define debug(x)
13 #endif
14
15 int agent_exists(void) {
16     HWND hwnd;
17     hwnd = FindWindow("Pageant", "Pageant");
18     if (!hwnd)
19         return FALSE;
20     else
21         return TRUE;
22 }
23
24 void agent_query(void *in, int inlen, void **out, int *outlen) {
25 #if 0
26 #define MAILSLOTNAME "\\\\.\\mailslot\\pageant_listener"
27     SECURITY_ATTRIBUTES sa;
28     HANDLE my_mailslot, agent_mailslot;
29     char name[64];
30     char *p;
31     DWORD msglen, byteswritten, bytesread, inid;
32
33     *out = NULL;
34     *outlen = 0;
35
36     agent_mailslot = CreateFile(MAILSLOTNAME, GENERIC_WRITE,
37                                 FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
38                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
39                                 (HANDLE)NULL);
40     debug(("opened %s: %p\n", MAILSLOTNAME, agent_mailslot));
41     if (agent_mailslot == INVALID_HANDLE_VALUE)
42         return;
43
44     inid = GetCurrentThreadId();
45     inid--;
46
47     sa.nLength = sizeof(sa);
48     sa.lpSecurityDescriptor = NULL;
49     sa.bInheritHandle = TRUE;
50
51     do {
52         sprintf(name, "\\\\.\\mailslot\\pclient_request_%08x", ++inid);
53         /*
54          * Five-minute timeout.
55          */
56         my_mailslot = CreateMailslot(name, 0, 0, &sa);
57         debug(("mailslot %s: %p\n", name, my_mailslot));
58     } while (my_mailslot == INVALID_HANDLE_VALUE);
59     Sleep(3000);
60
61     msglen = strlen(name) + 1 + inlen;
62     p = malloc(msglen);
63     if (!p) {
64         CloseHandle(my_mailslot);
65         CloseHandle(agent_mailslot);
66         return;
67     }
68
69     strcpy(p, name);
70     memcpy(p+strlen(p)+1, in, inlen);
71
72     debug(("ooh\n"));
73     if (WriteFile(agent_mailslot, p, msglen, &byteswritten, NULL) == 0) {
74         debug(("eek!\n"));
75         free(p);
76         CloseHandle(my_mailslot);
77         CloseHandle(agent_mailslot);
78         return;
79     }
80     debug(("aah\n"));
81     free(p);
82     CloseHandle(agent_mailslot);
83
84     WaitForSingleObject(my_mailslot, 3000000);
85     debug(("waited\n"));
86     if (!GetMailslotInfo(my_mailslot, NULL, &msglen, NULL, NULL)) {
87         CloseHandle(my_mailslot);
88         return;
89     }
90     if (msglen == MAILSLOT_NO_MESSAGE) {
91         debug(("no message\n"));
92         CloseHandle(my_mailslot);
93         return;
94     }
95     debug(("msglen=%d\n", msglen));
96     p = malloc(msglen);
97     if (!p) {
98         CloseHandle(my_mailslot);
99         return;
100     }
101     if (ReadFile(my_mailslot, p, msglen, &bytesread, NULL) == 0 &&
102         bytesread == msglen) {
103         *out = p;
104         *outlen = msglen;
105     }
106     CloseHandle(my_mailslot);
107 #endif
108     HWND hwnd;
109     char mapname[64];
110     HANDLE filemap;
111     void *p, *ret;
112     int id, retlen;
113     COPYDATASTRUCT cds;
114
115     *out = NULL;
116     *outlen = 0;
117
118     hwnd = FindWindow("Pageant", "Pageant");
119     debug(("hwnd is %p\n", hwnd));
120     if (!hwnd)
121         return;
122     cds.dwData = 0;                    /* FIXME */
123     cds.cbData = inlen;
124     cds.lpData = in;
125     id = SendMessage(hwnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
126     debug(("return is %d\n", id));
127     if (id > 0) {
128         sprintf(mapname, "PageantReply%08x", id);
129         filemap = OpenFileMapping(FILE_MAP_READ, FALSE, mapname);
130         debug(("name is `%s', filemap is %p\n", mapname, filemap));
131         debug(("error is %d\n", GetLastError()));
132         if (filemap != NULL && filemap != INVALID_HANDLE_VALUE) {
133             p = MapViewOfFile(filemap, FILE_MAP_READ, 0, 0, 0);
134             debug(("p is %p\n", p));
135             if (p) {
136                 retlen = *(int *)p;
137                 debug(("len is %d\n", retlen));
138                 ret = malloc(retlen);
139                 if (ret) {
140                     memcpy(ret, ((int *)p) + 1, retlen);
141                     *out = ret;
142                     *outlen = retlen;
143                 }
144                 UnmapViewOfFile(p);
145             }
146             CloseHandle(filemap);
147         }
148         /* FIXME: tell agent to close its handle too */
149     }
150 }
151
152 #ifdef TESTMODE
153
154 int main(void) {
155     void *msg;
156     int len;
157     int i;
158
159     agent_query("\0\0\0\1\1", 5, &msg, &len);
160     debug(("%d:", len));
161     for (i = 0; i < len; i++)
162         debug((" %02x", ((unsigned char *)msg)[i]));
163     debug(("\n"));
164     return 0;
165 }
166
167 #endif