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

Contents of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 129 - (show 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 /* wptMAPI.cpp
2 * Copyright (C) 2003, 2004, 2005 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 #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 #include "resource.h"
29 #include "wptTypes.h"
30 #include "wptErrors.h"
31 #include "wptW32API.h"
32 #include "wptGPG.h"
33 #include "wptVersion.h"
34
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 /* Load MAPI library and set function pointers.
46 Return value: 0 on success. */
47 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 }
67
68
69 /* Free library and cleanup. */
70 void
71 mapi_deinit (void)
72 {
73 if (hlib) {
74 FreeLibrary (hlib);
75 hlib = NULL;
76 init = 0;
77 }
78 }
79
80
81 /* Send the file given in @ascfile via the MAPI mechanism. */
82 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 /* 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 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 }
143
144
145 #if 0 /* low:priority XXX port the code */
146 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 add_recipient (gpgme_recipients_t *r_rset, const char *addr)
380 {
381 gpg_keycache_t pub = keycache_get_ctx (1);
382 gpgme_key_t key;
383 gpgme_error_t rc;
384 char *uid;
385
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 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 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