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

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Sat Oct 8 10:43:08 2005 UTC (19 years, 4 months ago) by twoaday
File size: 11155 byte(s)
Bug fixes to correct some problems introduced by
the MyGPGME to GPGME port.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26