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

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 129 - (hide annotations)
Fri Dec 30 13:56:10 2005 UTC (19 years, 2 months ago) by twoaday
File size: 11182 byte(s)
2005-12-27  Timo Schulz  <ts@g10code.com>
                                                                                
        * wptListView.cpp (listview_set_view): New.
        (listview_del_column): New.
        * wptW32API.cpp (get_locale_date): New.
        (get_menu_state): New.
        (force_foreground_window): New.
        * wptVerifyList.cpp (strtimestamp): Support for
        locale date formats.
        * wptGPGUtil.cpp (gpg_revoke_cert): Handle bad
        passphrases.
        * wptKeyEditCB.cpp (editkey_command_handler): Immediately
        return when a bad passphrase was submitted.
        * wptKeyRevokersDlg.cpp (keyrevokers_dlg_proc): Change
        column order.
        * wptKeylist.cpp (keylist_upd_col): New.
        * wptKeyManagerDlg.cpp (update_ui_items): Deactivate
        'Revocation' for public keys.
        (translate_menu_strings): s/Revoke/Revoke Cert.
        (modify_listview_columns): New.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26