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

Contents of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (show annotations)
Tue Oct 18 07:57:13 2005 UTC (19 years, 4 months ago) by twoaday
File size: 11261 byte(s)
Some bug fixes and adjustments for the latest
GPGME changes.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26