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

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File size: 11260 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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    
21     #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     mapi_send_ascfile (char * ascfile)
79     {
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     mapi_send_pubkey (const char * keyid, char * keyfile)
105     {
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     free_recip_tab (MapiRecipDesc * recip, size_t n)
150     {
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     secure_attachment (gpgme_recipients_t rset, const char * fname)
213     {
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     gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
233     gpgme_control (ctx, GPGME_CTRL_FORCETRUST, 1);
234     addrs = conv_recipients (rset);
235     if (!addrs) {
236     msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);
237     gpgme_release (NULL);
238     return NULL;
239     }
240     rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);
241     if (rc)
242     log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);
243     gpgme_recipients_release (addrs);
244     gpgme_release (ctx);
245     return strdup (tmpdir);
246     } /* secure_attachment */
247    
248    
249     static char *
250     secure_message (gpgme_recipients_t rset, const char * data)
251     {
252     gpgme_recipients_t addrs;
253     gpgme_error_t rc;
254     gpgme_data_t in, out;
255     gpgme_ctx_t ctx;
256     char * p;
257     size_t n=0;
258    
259     rc = gpgme_new (&ctx);
260     if (rc)
261     return NULL;
262     gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
263     gpgme_control (ctx, GPGME_CTRL_FORCETRUST, 1);
264    
265     addrs = conv_recipients (rset);
266     rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);
267     if (rc) {
268     gpgme_release (ctx);
269     return NULL;
270     }
271     gpgme_data_new (&out);
272    
273     rc = gpgme_op_encrypt (ctx, addrs, in, out);
274     if (rc)
275     log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");
276    
277     p = gpgme_data_release_and_return_string (out);
278    
279     gpgme_data_release (in);
280     gpgme_release (ctx);
281     gpgme_recipients_release (addrs);
282    
283     return p;
284     } /* secure_message */
285    
286    
287     int
288     mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,
289     const char * subject, const char ** files, size_t nfiles)
290     {
291     LHANDLE hd;
292     MapiMessage * msg;
293     MapiRecipDesc * recip;
294     MapiFileDesc * attch;
295     char * p;
296     const char * s;
297     void * ctx=NULL;
298     size_t n, i=0;
299     int rc;
300    
301     if (!init)
302     return 0;
303    
304     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
305     if (rc != SUCCESS_SUCCESS) {
306     MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
307     return rc;
308     }
309    
310     msg = (MapiMessage *)calloc (1, sizeof * msg);
311 twoaday 22 if (!msg)
312     BUG (0);
313 twoaday 2 p = msg->lpszSubject = strdup (subject);
314     if (!p)
315     BUG (0);
316     p = msg->lpszNoteText = secure_message (rset, msgtxt);
317     if (!p)
318     BUG (0);
319     n = msg->nRecipCount = gpgme_recipients_count (rset);
320     recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);
321 twoaday 22 if (!recip)
322     BUG (0);
323 twoaday 2
324     gpgme_recipients_enum_open (rset, &ctx);
325     while ((s = gpgme_recipients_enum_read (rset, &ctx))) {
326     if (!i)
327     recip[i].ulRecipClass = MAPI_TO;
328     else
329     recip[i].ulRecipClass = MAPI_CC;
330     p = recip[i].lpszName = strdup (s);
331     if (!p)
332     BUG (0);
333     i++;
334     }
335     msg->lpRecips = recip;
336    
337     if (nfiles) {
338     msg->nFileCount = nfiles;
339     attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);
340 twoaday 22 if (!attch)
341     BUG (0);
342 twoaday 2 for (i=0; i < nfiles; i++) {
343     char * p = secure_attachment (rset, *files);
344     if (!p)
345     continue;
346     attch[i].lpszFileName = strdup (*files);
347     attch[i].lpszPathName = strdup (p);
348     files++;
349     safe_free (p);
350     }
351     msg->lpFiles = attch;
352     }
353    
354     rc = mapi_send_mail (hd, 0, msg, 0, 0);
355     if (rc == MAPI_E_USER_ABORT)
356     rc = SUCCESS_SUCCESS;
357     if (rc != SUCCESS_SUCCESS)
358     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
359    
360     free_recip_tab (recip, n);
361     free_files_tab (attch, nfiles);
362     free_mapi_msg (msg);
363     mapi_logoff (hd, 0, 0, 0);
364    
365     return 0;
366     } /* mapi_send_message */
367    
368    
369     static int
370     add_recipient (gpgme_recipients_t * r_rset, const char * addr)
371     {
372     gpgme_keycache_t pub = keycache_get_ctx (1);
373     gpgme_key_t key;
374     gpgme_error_t rc;
375     const char * s;
376    
377     if (!*r_rset)
378     gpgme_recipients_new (&(*r_rset));
379     rc = gpgme_keycache_find_key (pub, addr, 0, &key);
380     if (rc) {
381     log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);
382     return -1;
383     }
384     s = gpgme_key_get_string_attr (key, GPGME_ATTR_USERID, NULL, 0);
385     if (s)
386     gpgme_recipients_add_name (*r_rset, s);
387     return 0;
388     } /* add_recipient */
389    
390    
391     static int
392     add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)
393     {
394     char buf[1024], * p;
395     int n=0;
396    
397     n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);
398     if (!n)
399     return -1;
400     p = strtok (buf, ";,");
401     while (p != NULL) {
402     add_recipient (&*r_rset, p);
403     p = strtok (NULL, ";,");
404     }
405     return 0;
406     } /* add_all_recipients */
407    
408    
409     BOOL CALLBACK
410     winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
411     {
412     static gpgme_recipients_t rset=NULL;
413     char subject[128];
414     char * msgbuf;
415     int n;
416    
417     switch (msg) {
418     case WM_INITDIALOG:
419     center_window (dlg);
420     SetForegroundWindow (dlg);
421     break;
422    
423     case WM_COMMAND:
424     switch (LOWORD (wparam)) {
425     case IDOK:
426     add_all_recipients (dlg, IDC_PMAIL_TO, &rset);
427     add_all_recipients (dlg, IDC_PMAIL_CC, &rset);
428     if (!gpgme_recipients_count (rset)) {
429     msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);
430     return FALSE;
431     }
432     n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);
433     if (!n)
434     strcpy (subject, "");
435     n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);
436     if (!n) {
437     msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);
438     return FALSE;
439     }
440     msgbuf = (char * )calloc (1, n+2);
441 twoaday 22 if (!msgbuf)
442     BUG (0);
443 twoaday 2 GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);
444     mapi_send_message (rset, msgbuf, subject, NULL, 0);
445     safe_free (msgbuf);
446     EndDialog (dlg, TRUE);
447     break;
448    
449     case IDCANCEL:
450     EndDialog (dlg, FALSE);
451     break;
452     }
453     break;
454     }
455    
456     return FALSE;
457     } /* winpt_mail_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26