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

Contents of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 77 - (show annotations)
Mon Nov 14 15:01:01 2005 UTC (19 years, 3 months ago) by twoaday
File size: 11135 byte(s)
2005-11-12  Timo Schulz  <ts@g10code.com>
 
        Fix more GCC warnings.
 
2005-11-10  Timo Schulz  <ts@g10code.com>
 
        * wptClipSignDlg.cpp (one_key_proc): Use
        release_gpg_passphrase_cb() to free the context.
        * wptListView.cpp (listview_deselect_all): New.
        * wptMAPI.cpp (mapi_send_pubkey): Works again.
        * wptFileManagerDlg.cpp (file_manager_dlg_proc): Support encrypt &
        zip.
        * wptPassphraseCB.cpp (passphrase_callback_proc): Fix passphrase
        caching for signing operations.
        * wptKeyManager.cpp (km_send_to_mail_recipient): Works again.
        * wptFileManager.cpp (fm_send_file): Likewise.
        (fm_encrypt_into_zip): 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 extern HINSTANCE glob_hinst;
29
30 #include "resource.h"
31 #include "wptTypes.h"
32 #include "wptErrors.h"
33 #include "wptW32API.h"
34 #include "wptGPG.h"
35
36
37 static LPMAPILOGON mapi_logon = NULL;
38 static LPMAPILOGOFF mapi_logoff = NULL;
39 static LPMAPISENDDOCUMENTS mapi_send_documents = NULL;
40 static LPMAPISENDMAIL mapi_send_mail = NULL;
41 static HINSTANCE hlib = NULL;
42 static int init = 0;
43
44 #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)
45
46
47 /* Load MAPI library and set function pointers.
48 Return value: 0 on success. */
49 int
50 mapi_init (void)
51 {
52 if (init)
53 return 0;
54
55 hlib = LoadLibrary ("MAPI32.DLL");
56 if (!hlib)
57 return -1;
58
59 mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");
60 mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");
61 mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");
62 mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");
63 if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)
64 return -1;
65 init = 1;
66
67 return 0;
68 }
69
70
71 /* Free library and cleanup. */
72 void
73 mapi_deinit (void)
74 {
75 if (hlib) {
76 FreeLibrary (hlib);
77 hlib = NULL;
78 init = 0;
79 }
80 }
81
82
83 /* Send the file given in @ascfile via the MAPI mechanism. */
84 int
85 mapi_send_ascfile (char *ascfile)
86 {
87 LHANDLE hd;
88 int rc;
89
90 if (!init)
91 return 0;
92
93 rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
94 if (rc != SUCCESS_SUCCESS) {
95 MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
96 goto fail;
97 }
98 rc = mapi_send_documents (0, ";", ascfile, NULL, 0);
99 if (rc == MAPI_E_USER_ABORT)
100 rc = SUCCESS_SUCCESS;
101 if (rc != SUCCESS_SUCCESS)
102 MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
103
104 fail:
105 mapi_logoff (hd, 0, 0, 0);
106 return rc;
107 }
108
109
110 /* Send a public key stored in @keyfile with the keyid @keyid
111 via the MAPI mechanism to a mail recipient.
112 Return value: SUCCESS_SUCCESS on succes. */
113 int
114 mapi_send_pubkey (const char *keyid, char *keyfile)
115 {
116 LHANDLE hd;
117 const char * fmt;
118 char * keyinf = NULL;
119 int rc;
120
121 if (!init)
122 return 0;
123
124 fmt = _("GPG Public Key of %s");
125 keyinf = new char[strlen (fmt) + strlen (keyid) + 2];
126 if (!keyinf)
127 BUG (0);
128 sprintf (keyinf, fmt, keyid);
129 rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
130 if (rc != SUCCESS_SUCCESS) {
131 MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
132 goto fail;
133 }
134 rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);
135 if (rc == MAPI_E_USER_ABORT)
136 rc = SUCCESS_SUCCESS;
137 if (rc != SUCCESS_SUCCESS)
138 MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
139
140 fail:
141 mapi_logoff (hd, 0, 0, 0);
142 free_if_alloc (keyinf);
143 return rc;
144 }
145
146
147 #if 0 /* low:priority XXX port the code */
148 static void
149 free_mapi_msg (MapiMessage * msg)
150 {
151 if (!msg)
152 return;
153 safe_free (msg->lpszSubject);
154 safe_free (msg->lpszNoteText);
155 safe_free (msg);
156 } /* free_mapi_msg */
157
158
159 static void
160 free_recip_tab (MapiRecipDesc *recip, size_t n)
161 {
162 size_t i;
163
164 if (!recip)
165 return;
166 if (!n)
167 return;
168 for (i=0; i < n; i++)
169 safe_free (recip[i].lpszName);
170 safe_free (recip);
171 } /* free_recip_tab */
172
173
174 static void
175 free_files_tab (MapiFileDesc * files, size_t n)
176 {
177 size_t i;
178
179 if (!files)
180 return;
181 if (!n)
182 return;
183 for (i=0; i < n; i++) {
184 safe_free (files[i].lpszFileName);
185 safe_free (files[i].lpszPathName);
186 }
187 safe_free (files);
188 } /* free_files_tab */
189
190
191
192 static gpgme_recipients_t
193 conv_recipients (gpgme_recipients_t rset)
194 {
195 gpgme_recipients_t r;
196 gpgme_error_t rc;
197 void * ctx=NULL;
198 const char * s;
199
200 /* we need to convert the recipients to email addresses so
201 GPG can handle them. */
202 rc = gpgme_recipients_new (&r);
203 if (rc)
204 return NULL;
205 gpgme_recipients_enum_open (rset, &ctx);
206
207 while ((s=gpgme_recipients_enum_read (rset, &ctx))) {
208 char * p, * q, * buf;
209 if (!(p = strchr (s, '<')) || !(q = strchr (s, '>')))
210 continue;
211 buf = (char * )calloc (1, (q-s)-(p-s)+2);
212 if (!buf)
213 BUG (0);
214 strncpy (buf, s+(p-s)+1, (q-s)-(p-s)-1);
215 gpgme_recipients_add_name (r, buf);
216 safe_free (buf);
217 }
218 return r;
219 } /* conv_recipients */
220
221
222 static char *
223 secure_attachment (gpgme_recipients_t rset, const char *fname)
224 {
225 char tmpdir[512+32], * p;
226 gpgme_recipients_t addrs;
227 gpgme_ctx_t ctx;
228 gpgme_error_t rc;
229
230 if (strlen (fname) > 200)
231 BUG (0);
232 GetTempPath (sizeof tmpdir-200, tmpdir);
233 p = strrchr (fname, '\\');
234 if (!p)
235 strcat (tmpdir, fname);
236 else
237 strcat (tmpdir, fname+(p-fname)+1);
238 strcat (tmpdir, ".asc");
239
240 rc = gpgme_new (&ctx);
241 if (rc)
242 return NULL;
243 gpgme_set_armor (ctx, 1);
244 addrs = conv_recipients (rset);
245 if (!addrs) {
246 msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);
247 gpgme_release (NULL);
248 return NULL;
249 }
250 rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);
251 if (rc)
252 log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);
253 gpgme_recipients_release (addrs);
254 gpgme_release (ctx);
255 return strdup (tmpdir);
256 } /* secure_attachment */
257
258
259 static gpgme_error_t
260 secure_message (gpgme_recipients_t rset, const char *data,
261 char *enc_msg, size_t *r_enclen)
262 {
263 gpgme_recipients_t addrs;
264 gpgme_error_t rc;
265 gpgme_data_t in, out;
266 gpgme_ctx_t ctx;
267 char * p;
268 size_t n=0;
269
270 rc = gpgme_new (&ctx);
271 if (rc)
272 return NULL;
273 gpgme_set_armor (ctx, 1);
274
275 addrs = conv_recipients (rset);
276 rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);
277 if (rc) {
278 gpgme_release (ctx);
279 return rc;
280 }
281 gpgme_data_new (&out);
282 rc = gpgme_op_encrypt (ctx, addrs, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
283 if (rc)
284 log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");
285
286 *r_enc_msg = gpgme_data_release_and_get_mem (&n);
287 *r_enclen = n;
288
289 gpgme_data_release (in);
290 gpgme_release (ctx);
291 gpgme_recipients_release (addrs);
292
293 return rc;
294 } /* secure_message */
295
296
297 int
298 mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,
299 const char * subject, const char **files, size_t nfiles)
300 {
301 LHANDLE hd;
302 MapiMessage * msg;
303 MapiRecipDesc * recip;
304 MapiFileDesc * attch;
305 char * p;
306 const char * s;
307 void * ctx=NULL;
308 size_t n, i=0, encmsg_len=0;
309 int rc;
310
311 if (!init)
312 return 0;
313
314 rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
315 if (rc != SUCCESS_SUCCESS) {
316 MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
317 return rc;
318 }
319
320 msg = (MapiMessage *)calloc (1, sizeof * msg);
321 if (!msg)
322 BUG (0);
323 p = msg->lpszSubject = strdup (subject);
324 if (!p)
325 BUG (0);
326 p = msg->lpszNoteText = secure_message (rset, msgtxt, &p, &encmsg_len);
327 if (!p)
328 BUG (0);
329 n = msg->nRecipCount = gpgme_recipients_count (rset);
330 recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);
331 if (!recip)
332 BUG (0);
333
334 gpgme_recipients_enum_open (rset, &ctx);
335 while ((s = gpgme_recipients_enum_read (rset, &ctx))) {
336 if (!i)
337 recip[i].ulRecipClass = MAPI_TO;
338 else
339 recip[i].ulRecipClass = MAPI_CC;
340 p = recip[i].lpszName = strdup (s);
341 if (!p)
342 BUG (0);
343 i++;
344 }
345 msg->lpRecips = recip;
346
347 if (nfiles) {
348 msg->nFileCount = nfiles;
349 attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);
350 if (!attch)
351 BUG (0);
352 for (i=0; i < nfiles; i++) {
353 char * p = secure_attachment (rset, *files);
354 if (!p)
355 continue;
356 attch[i].lpszFileName = strdup (*files);
357 attch[i].lpszPathName = strdup (p);
358 files++;
359 safe_free (p);
360 }
361 msg->lpFiles = attch;
362 }
363
364 rc = mapi_send_mail (hd, 0, msg, 0, 0);
365 if (rc == MAPI_E_USER_ABORT)
366 rc = SUCCESS_SUCCESS;
367 if (rc != SUCCESS_SUCCESS)
368 MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
369
370 free_recip_tab (recip, n);
371 free_files_tab (attch, nfiles);
372 free_mapi_msg (msg);
373 gpgme_free (p);
374 mapi_logoff (hd, 0, 0, 0);
375
376 return 0;
377 } /* mapi_send_message */
378
379
380 static int
381 add_recipient (gpgme_recipients_t * r_rset, const char * addr)
382 {
383 gpg_keycache_t pub = keycache_get_ctx (1);
384 gpgme_key_t key;
385 gpgme_error_t rc;
386 const char * s;
387
388 if (!*r_rset)
389 gpgme_recipients_new (&(*r_rset));
390 rc = gpgme_keycache_find_key (pub, addr, 0, &key);
391 if (rc) {
392 log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);
393 return -1;
394 }
395 s = key->uids->uid;
396 if (s)
397 gpgme_recipients_add_name (*r_rset, s);
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