/[winpt]/trunk/Src/wptMAPI.cpp
ViewVC logotype

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (hide annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 11157 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


1 twoaday 2 /* wptMAPI.cpp
2     * Copyright (C) 2003, 2004 Timo Schulz
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 twoaday 23 #if 0 /* low:priority XXX port the code */
21 twoaday 2 #include <windows.h>
22     #include <stdio.h>
23     #include <mapi.h>
24    
25     extern HINSTANCE glob_hinst;
26    
27     #include "../resource.h"
28     #include "wptTypes.h"
29     #include "wptErrors.h"
30     #include "wptW32API.h"
31     #include "wptGPG.h"
32    
33    
34     static LPMAPILOGON mapi_logon = NULL;
35     static LPMAPILOGOFF mapi_logoff = NULL;
36     static LPMAPISENDDOCUMENTS mapi_send_documents = NULL;
37     static LPMAPISENDMAIL mapi_send_mail = NULL;
38     static HINSTANCE hlib = NULL;
39     static int init = 0;
40    
41     #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)
42    
43    
44     int
45     mapi_init (void)
46     {
47     if (init)
48     return 0;
49    
50     hlib = LoadLibrary ("MAPI32.DLL");
51     if (!hlib)
52     return -1;
53    
54     mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");
55     mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");
56     mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");
57     mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");
58     if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)
59     return -1;
60     init = 1;
61    
62     return 0;
63     } /* mapi_init */
64    
65    
66     void
67     mapi_deinit (void)
68     {
69     if (hlib) {
70     FreeLibrary (hlib);
71     hlib = NULL;
72     init = 0;
73     }
74     } /* mapi_deinit */
75    
76    
77     int
78 twoaday 23 mapi_send_ascfile (char *ascfile)
79 twoaday 2 {
80     LHANDLE hd;
81     int rc;
82    
83     if (!init)
84     return 0;
85    
86     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
87     if (rc != SUCCESS_SUCCESS) {
88     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
89     goto fail;
90     }
91     rc = mapi_send_documents (0, ";", ascfile, NULL, 0);
92     if (rc == MAPI_E_USER_ABORT)
93     rc = SUCCESS_SUCCESS;
94     if (rc != SUCCESS_SUCCESS)
95     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
96    
97     fail:
98     mapi_logoff (hd, 0, 0, 0);
99     return rc;
100     }
101    
102    
103     int
104 twoaday 23 mapi_send_pubkey (const char *keyid, char *keyfile)
105 twoaday 2 {
106     LHANDLE hd;
107     const char * fmt;
108     char * keyinf = NULL;
109     int rc;
110    
111     if (!init)
112     return 0;
113    
114     fmt = _("GPG Public Key of %s");
115     keyinf = new char[strlen (fmt) + strlen (keyid) + 2];
116     if (!keyinf)
117     BUG (0);
118     sprintf (keyinf, fmt, keyid);
119     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
120     if (rc != SUCCESS_SUCCESS) {
121     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
122     goto fail;
123     }
124     rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);
125     if (rc == MAPI_E_USER_ABORT)
126     rc = SUCCESS_SUCCESS;
127     if (rc != SUCCESS_SUCCESS)
128     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
129    
130     fail:
131     mapi_logoff (hd, 0, 0, 0);
132     free_if_alloc (keyinf);
133     return rc;
134     } /* mapi_send_pubkey */
135    
136    
137     static void
138     free_mapi_msg (MapiMessage * msg)
139     {
140     if (!msg)
141     return;
142     safe_free (msg->lpszSubject);
143     safe_free (msg->lpszNoteText);
144     safe_free (msg);
145     } /* free_mapi_msg */
146    
147    
148     static void
149 twoaday 23 free_recip_tab (MapiRecipDesc *recip, size_t n)
150 twoaday 2 {
151     size_t i;
152    
153     if (!recip)
154     return;
155     if (!n)
156     return;
157     for (i=0; i < n; i++)
158     safe_free (recip[i].lpszName);
159     safe_free (recip);
160     } /* free_recip_tab */
161    
162    
163     static void
164     free_files_tab (MapiFileDesc * files, size_t n)
165     {
166     size_t i;
167    
168     if (!files)
169     return;
170     if (!n)
171     return;
172     for (i=0; i < n; i++) {
173     safe_free (files[i].lpszFileName);
174     safe_free (files[i].lpszPathName);
175     }
176     safe_free (files);
177     } /* free_files_tab */
178    
179    
180    
181     static gpgme_recipients_t
182     conv_recipients (gpgme_recipients_t rset)
183     {
184     gpgme_recipients_t r;
185     gpgme_error_t rc;
186     void * ctx=NULL;
187     const char * s;
188    
189     /* we need to convert the recipients to email addresses so
190     GPG can handle them. */
191     rc = gpgme_recipients_new (&r);
192     if (rc)
193     return NULL;
194     gpgme_recipients_enum_open (rset, &ctx);
195    
196     while ((s=gpgme_recipients_enum_read (rset, &ctx))) {
197     char * p, * q, * buf;
198     if (!(p = strchr (s, '<')) || !(q = strchr (s, '>')))
199     continue;
200     buf = (char * )calloc (1, (q-s)-(p-s)+2);
201 twoaday 22 if (!buf)
202     BUG (0);
203 twoaday 2 strncpy (buf, s+(p-s)+1, (q-s)-(p-s)-1);
204     gpgme_recipients_add_name (r, buf);
205     safe_free (buf);
206     }
207     return r;
208     } /* conv_recipients */
209    
210    
211     static char *
212 twoaday 23 secure_attachment (gpgme_recipients_t rset, const char *fname)
213 twoaday 2 {
214     char tmpdir[512+32], * p;
215     gpgme_recipients_t addrs;
216     gpgme_ctx_t ctx;
217     gpgme_error_t rc;
218    
219     if (strlen (fname) > 200)
220     BUG (0);
221     GetTempPath (sizeof tmpdir-200, tmpdir);
222     p = strrchr (fname, '\\');
223     if (!p)
224     strcat (tmpdir, fname);
225     else
226     strcat (tmpdir, fname+(p-fname)+1);
227     strcat (tmpdir, ".asc");
228    
229     rc = gpgme_new (&ctx);
230     if (rc)
231     return NULL;
232 twoaday 23 gpgme_set_armor (ctx, 1);
233 twoaday 2 addrs = conv_recipients (rset);
234     if (!addrs) {
235     msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);
236     gpgme_release (NULL);
237     return NULL;
238     }
239     rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);
240     if (rc)
241     log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);
242     gpgme_recipients_release (addrs);
243     gpgme_release (ctx);
244     return strdup (tmpdir);
245     } /* secure_attachment */
246    
247    
248     static char *
249     secure_message (gpgme_recipients_t rset, const char * data)
250     {
251     gpgme_recipients_t addrs;
252     gpgme_error_t rc;
253     gpgme_data_t in, out;
254     gpgme_ctx_t ctx;
255     char * p;
256     size_t n=0;
257    
258     rc = gpgme_new (&ctx);
259     if (rc)
260     return NULL;
261 twoaday 23 gpgme_set_armor (ctx, 1);
262 twoaday 2
263     addrs = conv_recipients (rset);
264     rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);
265     if (rc) {
266     gpgme_release (ctx);
267     return NULL;
268     }
269     gpgme_data_new (&out);
270 twoaday 23 rc = gpgme_op_encrypt (ctx, addrs, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
271 twoaday 2 if (rc)
272     log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");
273    
274 twoaday 23 p = gpgme_data_release_and_get_mem (&n);
275     p[n] = 0;
276 twoaday 2
277     gpgme_data_release (in);
278     gpgme_release (ctx);
279     gpgme_recipients_release (addrs);
280    
281     return p;
282     } /* secure_message */
283    
284    
285     int
286     mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,
287 twoaday 23 const char * subject, const char **files, size_t nfiles)
288 twoaday 2 {
289     LHANDLE hd;
290     MapiMessage * msg;
291     MapiRecipDesc * recip;
292     MapiFileDesc * attch;
293     char * p;
294     const char * s;
295     void * ctx=NULL;
296     size_t n, i=0;
297     int rc;
298    
299     if (!init)
300     return 0;
301    
302     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
303     if (rc != SUCCESS_SUCCESS) {
304     MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
305     return rc;
306     }
307    
308     msg = (MapiMessage *)calloc (1, sizeof * msg);
309 twoaday 22 if (!msg)
310     BUG (0);
311 twoaday 2 p = msg->lpszSubject = strdup (subject);
312     if (!p)
313     BUG (0);
314     p = msg->lpszNoteText = secure_message (rset, msgtxt);
315     if (!p)
316     BUG (0);
317     n = msg->nRecipCount = gpgme_recipients_count (rset);
318     recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);
319 twoaday 22 if (!recip)
320     BUG (0);
321 twoaday 2
322     gpgme_recipients_enum_open (rset, &ctx);
323     while ((s = gpgme_recipients_enum_read (rset, &ctx))) {
324     if (!i)
325     recip[i].ulRecipClass = MAPI_TO;
326     else
327     recip[i].ulRecipClass = MAPI_CC;
328     p = recip[i].lpszName = strdup (s);
329     if (!p)
330     BUG (0);
331     i++;
332     }
333     msg->lpRecips = recip;
334    
335     if (nfiles) {
336     msg->nFileCount = nfiles;
337     attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);
338 twoaday 22 if (!attch)
339     BUG (0);
340 twoaday 2 for (i=0; i < nfiles; i++) {
341     char * p = secure_attachment (rset, *files);
342     if (!p)
343     continue;
344     attch[i].lpszFileName = strdup (*files);
345     attch[i].lpszPathName = strdup (p);
346     files++;
347     safe_free (p);
348     }
349     msg->lpFiles = attch;
350     }
351    
352     rc = mapi_send_mail (hd, 0, msg, 0, 0);
353     if (rc == MAPI_E_USER_ABORT)
354     rc = SUCCESS_SUCCESS;
355     if (rc != SUCCESS_SUCCESS)
356     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
357    
358     free_recip_tab (recip, n);
359     free_files_tab (attch, nfiles);
360     free_mapi_msg (msg);
361     mapi_logoff (hd, 0, 0, 0);
362    
363     return 0;
364     } /* mapi_send_message */
365    
366    
367     static int
368     add_recipient (gpgme_recipients_t * r_rset, const char * addr)
369     {
370     gpgme_keycache_t pub = keycache_get_ctx (1);
371     gpgme_key_t key;
372     gpgme_error_t rc;
373     const char * s;
374    
375     if (!*r_rset)
376     gpgme_recipients_new (&(*r_rset));
377     rc = gpgme_keycache_find_key (pub, addr, 0, &key);
378     if (rc) {
379     log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);
380     return -1;
381     }
382 twoaday 23 s = key->uids->uid;
383 twoaday 2 if (s)
384     gpgme_recipients_add_name (*r_rset, s);
385     return 0;
386     } /* add_recipient */
387    
388    
389     static int
390     add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)
391     {
392     char buf[1024], * p;
393     int n=0;
394    
395     n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);
396     if (!n)
397     return -1;
398     p = strtok (buf, ";,");
399     while (p != NULL) {
400     add_recipient (&*r_rset, p);
401     p = strtok (NULL, ";,");
402     }
403     return 0;
404     } /* add_all_recipients */
405    
406    
407     BOOL CALLBACK
408     winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
409     {
410     static gpgme_recipients_t rset=NULL;
411     char subject[128];
412     char * msgbuf;
413     int n;
414    
415     switch (msg) {
416     case WM_INITDIALOG:
417 twoaday 23 center_window (dlg, NULL);
418 twoaday 2 SetForegroundWindow (dlg);
419     break;
420    
421     case WM_COMMAND:
422     switch (LOWORD (wparam)) {
423     case IDOK:
424     add_all_recipients (dlg, IDC_PMAIL_TO, &rset);
425     add_all_recipients (dlg, IDC_PMAIL_CC, &rset);
426     if (!gpgme_recipients_count (rset)) {
427     msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);
428     return FALSE;
429     }
430     n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);
431     if (!n)
432     strcpy (subject, "");
433     n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);
434     if (!n) {
435     msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);
436     return FALSE;
437     }
438     msgbuf = (char * )calloc (1, n+2);
439 twoaday 22 if (!msgbuf)
440     BUG (0);
441 twoaday 2 GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);
442     mapi_send_message (rset, msgbuf, subject, NULL, 0);
443     safe_free (msgbuf);
444     EndDialog (dlg, TRUE);
445     break;
446    
447     case IDCANCEL:
448     EndDialog (dlg, FALSE);
449     break;
450     }
451     break;
452     }
453    
454     return FALSE;
455     } /* winpt_mail_proc */
456 twoaday 23 #endif

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26