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

Contents of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26