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

Contents of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (show annotations)
Mon Dec 12 11:19:56 2005 UTC (19 years, 2 months ago) by twoaday
File size: 11128 byte(s)
2005-12-11  Timo Schulz  <ts@g10code.com>
 
        * wptW32API.cpp (get_file_version): New.
        * wptGPGUtil.cpp (create_process): Always hide window.
        * wptClipEditDlg.cpp (clipedit_dlg_proc): Use 'Close'
        instead of 'Exit'.
        * wptKeyManager.cpp (km_http_import): New filename
        generation code.
        (km_send_to_mail_recipient): Cleanups.
        * wptKeyEditDlg.cpp (showpref_dlg_proc): Localize dialog.
        * wptKeyManagerDlg.cpp (update_ui_items): Handle the case
        when multiple keys are selected.
        (popup_multiple): New.
        * WinPT.cpp (WinMain): Check that the PTD.dll and WinPT.exe
        file versions are equal. Rewrote --keymanager code.
         
Removed temporary w32gpgme dirctory, all code is now in Src.
Changed configure files.


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 const char * s;
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 s = key->uids->uid;
394 if (s)
395 gpgme_recipients_add_name (*r_rset, s);
396 return 0;
397 } /* add_recipient */
398
399
400 static int
401 add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)
402 {
403 char buf[1024], * p;
404 int n=0;
405
406 n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);
407 if (!n)
408 return -1;
409 p = strtok (buf, ";,");
410 while (p != NULL) {
411 add_recipient (&*r_rset, p);
412 p = strtok (NULL, ";,");
413 }
414 return 0;
415 } /* add_all_recipients */
416
417
418 BOOL CALLBACK
419 winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
420 {
421 static gpgme_recipients_t rset=NULL;
422 char subject[128];
423 char * msgbuf;
424 int n;
425
426 switch (msg) {
427 case WM_INITDIALOG:
428 center_window (dlg, NULL);
429 SetForegroundWindow (dlg);
430 break;
431
432 case WM_COMMAND:
433 switch (LOWORD (wparam)) {
434 case IDOK:
435 add_all_recipients (dlg, IDC_PMAIL_TO, &rset);
436 add_all_recipients (dlg, IDC_PMAIL_CC, &rset);
437 if (!gpgme_recipients_count (rset)) {
438 msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);
439 return FALSE;
440 }
441 n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);
442 if (!n)
443 strcpy (subject, "");
444 n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);
445 if (!n) {
446 msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);
447 return FALSE;
448 }
449 msgbuf = (char * )calloc (1, n+2);
450 if (!msgbuf)
451 BUG (0);
452 GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);
453 mapi_send_message (rset, msgbuf, subject, NULL, 0);
454 safe_free (msgbuf);
455 EndDialog (dlg, TRUE);
456 break;
457
458 case IDCANCEL:
459 EndDialog (dlg, FALSE);
460 break;
461 }
462 break;
463 }
464
465 return FALSE;
466 } /* winpt_mail_proc */
467 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26