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

Diff of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 207 by twoaday, Fri Apr 28 10:28:24 2006 UTC
# Line 1  Line 1 
 /* wptMAPI.cpp  
  *      Copyright (C) 2003, 2004 Timo Schulz  
  *  
  * This file is part of WinPT.  
  *  
  * WinPT is free software; you can redistribute it and/or modify  
  * it under the terms of the GNU General Public License as published by  
  * the Free Software Foundation; either version 2 of the License, or  
  * (at your option) any later version.  
  *  
  * WinPT is distributed in the hope that it will be useful,  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
  * GNU General Public License for more details.  
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  
  */  
 #if 0 /* low:priority XXX port the code */  
 #include <windows.h>  
 #include <stdio.h>  
 #include <mapi.h>  
   
 extern HINSTANCE glob_hinst;  
   
 #include "../resource.h"  
 #include "wptTypes.h"  
 #include "wptErrors.h"  
 #include "wptW32API.h"  
 #include "wptGPG.h"  
   
   
 static LPMAPILOGON          mapi_logon = NULL;  
 static LPMAPILOGOFF         mapi_logoff = NULL;      
 static LPMAPISENDDOCUMENTS  mapi_send_documents = NULL;  
 static LPMAPISENDMAIL       mapi_send_mail = NULL;  
 static HINSTANCE            hlib = NULL;  
 static int                  init = 0;  
   
 #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)  
   
   
 int  
 mapi_init (void)  
 {  
     if (init)  
         return 0;  
   
     hlib = LoadLibrary ("MAPI32.DLL");  
     if (!hlib)  
         return -1;  
   
     mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");  
     mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");  
     mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");  
     mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");  
     if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)  
         return -1;  
     init = 1;  
   
     return 0;  
 } /* mapi_init */  
   
   
 void  
 mapi_deinit (void)  
 {  
     if (hlib) {  
         FreeLibrary (hlib);  
         hlib = NULL;  
         init = 0;  
     }  
 } /* mapi_deinit */  
   
   
 int  
 mapi_send_ascfile (char *ascfile)  
 {  
     LHANDLE hd;  
     int rc;  
   
     if (!init)  
         return 0;  
   
     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);  
     if (rc != SUCCESS_SUCCESS) {  
         MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);  
         goto fail;  
     }  
     rc = mapi_send_documents (0, ";", ascfile, NULL, 0);  
     if (rc == MAPI_E_USER_ABORT)  
         rc = SUCCESS_SUCCESS;  
     if (rc != SUCCESS_SUCCESS)  
         MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);  
   
 fail:  
     mapi_logoff (hd, 0, 0, 0);  
     return rc;  
 }  
   
   
 int  
 mapi_send_pubkey (const char *keyid, char *keyfile)  
 {  
     LHANDLE hd;  
     const char * fmt;  
     char * keyinf = NULL;  
     int rc;  
   
     if (!init)  
         return 0;  
   
     fmt = _("GPG Public Key of %s");  
     keyinf = new char[strlen (fmt) + strlen (keyid) + 2];  
     if (!keyinf)  
         BUG (0);  
     sprintf (keyinf, fmt, keyid);  
     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);  
     if (rc != SUCCESS_SUCCESS) {  
         MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);  
         goto fail;  
     }  
     rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);  
     if (rc == MAPI_E_USER_ABORT)  
         rc = SUCCESS_SUCCESS;  
     if (rc != SUCCESS_SUCCESS)  
         MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);  
   
 fail:  
     mapi_logoff (hd, 0, 0, 0);  
     free_if_alloc (keyinf);  
     return rc;  
 } /* mapi_send_pubkey */  
   
   
 static void  
 free_mapi_msg (MapiMessage * msg)  
 {  
     if (!msg)  
         return;  
     safe_free (msg->lpszSubject);  
     safe_free (msg->lpszNoteText);  
     safe_free (msg);  
 } /* free_mapi_msg */  
   
   
 static void  
 free_recip_tab (MapiRecipDesc *recip, size_t n)  
 {  
     size_t i;  
   
     if (!recip)  
         return;  
     if (!n)  
         return;  
     for (i=0; i < n; i++)  
         safe_free (recip[i].lpszName);  
     safe_free (recip);  
 } /* free_recip_tab */  
   
   
 static void  
 free_files_tab (MapiFileDesc * files, size_t n)  
 {  
     size_t i;  
   
     if (!files)  
         return;  
     if (!n)  
         return;  
     for (i=0; i < n; i++) {  
         safe_free (files[i].lpszFileName);  
         safe_free (files[i].lpszPathName);  
     }  
     safe_free (files);  
 } /* free_files_tab */  
   
   
   
 static gpgme_recipients_t  
 conv_recipients (gpgme_recipients_t rset)  
 {  
     gpgme_recipients_t r;  
     gpgme_error_t rc;  
     void * ctx=NULL;  
     const char * s;  
   
     /* we need to convert the recipients to email addresses so  
        GPG can handle them. */  
     rc = gpgme_recipients_new (&r);  
     if (rc)  
         return NULL;  
     gpgme_recipients_enum_open (rset, &ctx);  
   
     while ((s=gpgme_recipients_enum_read (rset, &ctx))) {  
         char * p, * q, * buf;  
         if (!(p = strchr (s, '<')) || !(q = strchr (s, '>')))  
             continue;  
         buf = (char * )calloc (1, (q-s)-(p-s)+2);  
         if (!buf)  
             BUG (0);  
         strncpy (buf, s+(p-s)+1, (q-s)-(p-s)-1);  
         gpgme_recipients_add_name (r, buf);  
         safe_free (buf);  
     }  
     return r;  
 } /* conv_recipients */  
   
   
 static char *  
 secure_attachment (gpgme_recipients_t rset, const char *fname)  
 {  
     char tmpdir[512+32], * p;  
     gpgme_recipients_t addrs;  
     gpgme_ctx_t ctx;  
     gpgme_error_t rc;  
   
     if (strlen (fname) > 200)  
         BUG (0);  
     GetTempPath (sizeof tmpdir-200, tmpdir);  
     p = strrchr (fname, '\\');  
     if (!p)  
         strcat (tmpdir, fname);  
     else  
         strcat (tmpdir, fname+(p-fname)+1);  
     strcat (tmpdir, ".asc");  
   
     rc = gpgme_new (&ctx);  
     if (rc)  
         return NULL;  
     gpgme_set_armor (ctx, 1);  
     addrs = conv_recipients (rset);  
     if (!addrs) {  
         msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);  
         gpgme_release (NULL);  
         return NULL;  
     }  
     rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);  
     if (rc)  
         log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);  
     gpgme_recipients_release (addrs);  
     gpgme_release (ctx);  
     return strdup (tmpdir);  
 } /* secure_attachment */  
   
   
 static char *  
 secure_message (gpgme_recipients_t rset, const char * data)  
 {  
     gpgme_recipients_t addrs;  
     gpgme_error_t rc;  
     gpgme_data_t in, out;  
     gpgme_ctx_t ctx;  
     char * p;  
     size_t n=0;  
   
     rc = gpgme_new (&ctx);  
     if (rc)  
         return NULL;  
     gpgme_set_armor (ctx, 1);  
   
     addrs = conv_recipients (rset);  
     rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);  
     if (rc) {  
         gpgme_release (ctx);  
         return NULL;  
     }  
     gpgme_data_new (&out);  
     rc = gpgme_op_encrypt (ctx, addrs, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);  
     if (rc)  
         log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");  
   
     p = gpgme_data_release_and_get_mem (&n);  
     p[n] = 0;  
   
     gpgme_data_release (in);  
     gpgme_release (ctx);  
     gpgme_recipients_release (addrs);  
   
     return p;  
 } /* secure_message */  
   
   
 int  
 mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,  
                    const char * subject, const char **files, size_t nfiles)  
 {  
     LHANDLE hd;  
     MapiMessage * msg;  
     MapiRecipDesc * recip;  
     MapiFileDesc * attch;  
     char * p;  
     const char * s;  
     void * ctx=NULL;  
     size_t n, i=0;  
     int rc;  
   
     if (!init)  
         return 0;  
   
     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);  
     if (rc != SUCCESS_SUCCESS) {  
         MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);  
         return rc;  
     }  
   
     msg = (MapiMessage *)calloc (1, sizeof * msg);  
     if (!msg)  
         BUG (0);  
     p = msg->lpszSubject = strdup (subject);  
     if (!p)  
         BUG (0);  
     p = msg->lpszNoteText = secure_message (rset, msgtxt);  
     if (!p)  
         BUG (0);  
     n = msg->nRecipCount = gpgme_recipients_count (rset);  
     recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);  
     if (!recip)  
         BUG (0);  
       
     gpgme_recipients_enum_open (rset, &ctx);  
     while ((s = gpgme_recipients_enum_read (rset, &ctx))) {  
         if (!i)  
             recip[i].ulRecipClass = MAPI_TO;  
         else  
             recip[i].ulRecipClass = MAPI_CC;      
         p = recip[i].lpszName = strdup (s);  
         if (!p)  
             BUG (0);  
         i++;  
     }  
     msg->lpRecips = recip;  
   
     if (nfiles) {  
         msg->nFileCount = nfiles;  
         attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);  
         if (!attch)  
             BUG (0);  
         for (i=0; i < nfiles; i++) {  
             char * p = secure_attachment (rset, *files);  
             if (!p)  
                 continue;  
             attch[i].lpszFileName = strdup (*files);          
             attch[i].lpszPathName = strdup (p);  
             files++;  
             safe_free (p);  
         }  
         msg->lpFiles = attch;  
     }  
   
     rc = mapi_send_mail (hd, 0, msg, 0, 0);  
     if (rc == MAPI_E_USER_ABORT)  
         rc = SUCCESS_SUCCESS;  
     if (rc != SUCCESS_SUCCESS)  
         MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);  
   
     free_recip_tab (recip, n);  
     free_files_tab (attch, nfiles);  
     free_mapi_msg (msg);  
     mapi_logoff (hd, 0, 0, 0);  
   
     return 0;  
 } /* mapi_send_message */  
   
   
 static int  
 add_recipient (gpgme_recipients_t * r_rset, const char * addr)  
 {  
     gpgme_keycache_t pub = keycache_get_ctx (1);  
     gpgme_key_t key;  
     gpgme_error_t rc;  
     const char * s;  
   
     if (!*r_rset)  
         gpgme_recipients_new (&(*r_rset));  
     rc = gpgme_keycache_find_key (pub, addr, 0, &key);  
     if (rc) {  
         log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);  
         return -1;  
     }  
     s = key->uids->uid;  
     if (s)  
         gpgme_recipients_add_name (*r_rset, s);  
     return 0;  
 } /* add_recipient */  
   
   
 static int  
 add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)  
 {      
     char buf[1024], * p;  
     int n=0;  
   
     n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);  
     if (!n)  
         return -1;  
     p = strtok (buf, ";,");  
     while (p != NULL) {  
         add_recipient (&*r_rset, p);  
         p = strtok (NULL, ";,");  
     }  
     return 0;  
 } /* add_all_recipients */  
   
   
 BOOL CALLBACK  
 winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
 {  
     static gpgme_recipients_t rset=NULL;  
     char subject[128];  
     char * msgbuf;  
     int n;  
   
     switch (msg) {  
     case WM_INITDIALOG:  
         center_window (dlg, NULL);  
         SetForegroundWindow (dlg);  
         break;  
   
     case WM_COMMAND:  
         switch (LOWORD (wparam)) {  
         case IDOK:  
             add_all_recipients (dlg, IDC_PMAIL_TO, &rset);  
             add_all_recipients (dlg, IDC_PMAIL_CC, &rset);  
             if (!gpgme_recipients_count (rset)) {  
                 msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);  
                 return FALSE;  
             }  
             n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);  
             if (!n)  
                 strcpy (subject, "");  
             n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);  
             if (!n) {  
                 msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);  
                 return FALSE;  
             }  
             msgbuf = (char * )calloc (1, n+2);  
             if (!msgbuf)  
                 BUG (0);  
             GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);  
             mapi_send_message (rset, msgbuf, subject, NULL, 0);  
             safe_free (msgbuf);  
             EndDialog (dlg, TRUE);  
             break;  
   
         case IDCANCEL:  
             EndDialog (dlg, FALSE);  
             break;  
         }  
         break;  
     }  
   
     return FALSE;  
 } /* winpt_mail_proc */  
 #endif  
1    /* wptMAPI.cpp - MAPI interface for sending keys.
2     *      Copyright (C) 2003, 2004, 2005, 2006 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    #include "wptCommonCtl.h"
35    #include "wptKeyManager.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    /* Load MAPI library and set function pointers.
49       Return value: 0 on success. */
50    int
51    mapi_init (void)
52    {
53        if (init)
54            return 0;
55    
56        hlib = LoadLibrary ("MAPI32.DLL");
57        if (!hlib)
58            return -1;
59    
60        mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");
61        mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");
62        mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");
63        mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");
64        if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)
65            return -1;
66        init = 1;
67    
68        return 0;
69    }
70    
71    
72    /* Free library and cleanup. */
73    void
74    mapi_deinit (void)
75    {
76        if (hlib) {
77            FreeLibrary (hlib);
78            hlib = NULL;
79            init = 0;
80        }
81    }
82    
83    
84    /* Send the file given in @ascfile via the MAPI mechanism. */
85    int
86    mapi_send_ascfile (char *ascfile)
87    {
88        LHANDLE hd;
89        int rc;
90    
91        if (!init)
92            return 0;
93    
94        rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
95        if (rc != SUCCESS_SUCCESS) {
96            MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
97            goto fail;
98        }
99        rc = mapi_send_documents (0, ";", ascfile, NULL, 0);
100        if (rc == MAPI_E_USER_ABORT)
101            rc = SUCCESS_SUCCESS;
102        if (rc != SUCCESS_SUCCESS)
103            MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
104    
105    fail:
106        mapi_logoff (hd, 0, 0, 0);
107        return rc;
108    }
109    
110    
111    static void
112    free_mapi_msg (MapiMessage *msg)
113    {
114        if (!msg)
115            return;
116        safe_free (msg->lpszSubject);
117        safe_free (msg->lpszNoteText);
118        safe_free (msg);
119    }
120    
121    
122    static void
123    free_recip_tab (MapiRecipDesc *recip, size_t n)
124    {
125        size_t i;
126    
127        if (!recip)
128            return;
129        if (!n)
130            return;
131        for (i=0; i < n; i++)
132            safe_free (recip[i].lpszName);
133        safe_free (recip);
134    }
135    
136    
137    static void
138    free_files_tab (MapiFileDesc *files, size_t n)
139    {
140        size_t i;
141    
142        if (!files)
143            return;
144        if (!n)
145            return;
146        for (i=0; i < n; i++) {
147            safe_free (files[i].lpszFileName);
148            safe_free (files[i].lpszPathName);
149        }
150        safe_free (files);
151    }
152    
153    
154    /* Same as mapi_send_pubkey but there is an additional note. */
155    int
156    mapi_send_pubkey_ext (winpt_key_t key, const char *keyfile, int flags)
157    {
158        LHANDLE hd;
159        MapiMessage *msg;
160        MapiRecipDesc *recip;
161        MapiFileDesc *attch;
162        gpgme_key_t to = key->ctx;
163        char *p, *kinf;
164        const char *s;
165        int rc;
166    
167        if (!init)
168            return 0;
169    
170        rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
171        if (rc != SUCCESS_SUCCESS) {
172            MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
173            return rc;
174        }
175    
176        msg = (MapiMessage *)calloc (1, sizeof *msg);
177        if (!msg)
178            BUG (0);
179        p = msg->lpszSubject = strdup ("OpenPGP Public Key");
180        if (!p)
181            BUG (0);
182    
183        s = "Attached is this OpenPGP public key:\n%s\n\n"
184            "Import this key via the clipboard or the Key Manager to\n"
185            "exchange encrypted mails with the key holder and to be able\n"
186            "to verify its signatures.\n"
187            "\n"
188            "If you don't have WinPT, you can download it at http://www.winpt.org";
189        kinf = km_key_get_info (key, 0);
190        p = (char*)malloc (strlen (s) + strlen (kinf) + 2);
191        sprintf (p, s, kinf);
192        free_if_alloc (kinf);
193    
194        p = msg->lpszNoteText = p;
195        if (!p)
196            BUG (0);
197    
198        /* If the key was signed, we assume it shall be sent back to the owner. */
199        if (flags) {
200            recip = (MapiRecipDesc *)calloc (1, sizeof *recip);
201            if (!recip)
202                BUG (0);
203            recip[0].ulRecipClass = MAPI_TO;
204            p = recip[0].lpszName = strdup (to->uids->uid);
205            if (!p)    
206                BUG (0);
207            msg->lpRecips = recip;
208            msg->nRecipCount = 1;
209        }
210        else {
211            msg->lpRecips = recip = NULL;
212            msg->nRecipCount = 0;
213        }
214    
215        msg->nFileCount = 1;
216        attch = (MapiFileDesc *)calloc (1, sizeof *attch);
217        if (!attch)
218            BUG (0);
219        attch[0].lpszFileName = strdup (keyfile);
220        attch[0].lpszPathName = strdup (keyfile);
221        msg->lpFiles = attch;
222    
223        rc = mapi_send_mail (hd, 0, msg, MAPI_DIALOG , 0);
224        if (rc == MAPI_E_USER_ABORT)
225            rc = SUCCESS_SUCCESS;
226        if (rc != SUCCESS_SUCCESS)
227            MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
228    
229        free_recip_tab (recip, 1);
230        free_files_tab (attch, 1);
231        free_mapi_msg (msg);
232        mapi_logoff (hd, 0, 0, 0);
233    
234        return 0;
235    }
236    
237    
238    
239    int
240    mapi_send_pubkey (const char *keyid, char *keyfile)
241    {
242        winpt_key_s key;
243    
244        memset (&key, 0, sizeof (key));
245        if (winpt_get_pubkey (keyid, &key))
246            return -1;
247        return mapi_send_pubkey_ext (&key, keyfile, 0);
248    }

Legend:
Removed from v.23  
changed lines
  Added in v.207

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26