/[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 48 by werner, Mon Oct 31 21:14:11 2005 UTC revision 207 by twoaday, Fri Apr 28 10:28:24 2006 UTC
# Line 1  Line 1 
1  /* wptMAPI.cpp  /* wptMAPI.cpp - MAPI interface for sending keys.
2   *      Copyright (C) 2003, 2004 Timo Schulz   *      Copyright (C) 2003, 2004, 2005, 2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 25  Line 25 
25  #include <stdio.h>  #include <stdio.h>
26  #include <mapi.h>  #include <mapi.h>
27    
 extern HINSTANCE glob_hinst;  
   
28  #include "resource.h"  #include "resource.h"
29  #include "wptTypes.h"  #include "wptTypes.h"
30  #include "wptErrors.h"  #include "wptErrors.h"
31  #include "wptW32API.h"  #include "wptW32API.h"
32  #include "wptGPG.h"  #include "wptGPG.h"
33    #include "wptVersion.h"
34    #include "wptCommonCtl.h"
35    #include "wptKeyManager.h"
36    
37    
38  static LPMAPILOGON          mapi_logon = NULL;  static LPMAPILOGON          mapi_logon = NULL;
# Line 44  static int                 init = 0; Line 45  static int                 init = 0;
45  #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)  #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  int
51  mapi_init (void)  mapi_init (void)
52  {  {
# Line 63  mapi_init (void) Line 66  mapi_init (void)
66      init = 1;      init = 1;
67    
68      return 0;      return 0;
69  } /* mapi_init */  }
70    
71    
72    /* Free library and cleanup. */
73  void  void
74  mapi_deinit (void)  mapi_deinit (void)
75  {  {
# Line 74  mapi_deinit (void) Line 78  mapi_deinit (void)
78          hlib = NULL;          hlib = NULL;
79          init = 0;          init = 0;
80      }      }
81  } /* mapi_deinit */  }
82    
83  #if 0 /* low:priority XXX port the code */  
84    /* Send the file given in @ascfile via the MAPI mechanism. */
85  int  int
86  mapi_send_ascfile (char *ascfile)  mapi_send_ascfile (char *ascfile)
87  {  {
# Line 103  fail: Line 108  fail:
108  }  }
109    
110    
 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 */  
   
   
111  static void  static void
112  free_mapi_msg (MapiMessage * msg)  free_mapi_msg (MapiMessage *msg)
113  {  {
114      if (!msg)      if (!msg)
115          return;          return;
116      safe_free (msg->lpszSubject);      safe_free (msg->lpszSubject);
117      safe_free (msg->lpszNoteText);      safe_free (msg->lpszNoteText);
118      safe_free (msg);      safe_free (msg);
119  } /* free_mapi_msg */  }
120    
121    
122  static void  static void
# Line 160  free_recip_tab (MapiRecipDesc *recip, si Line 131  free_recip_tab (MapiRecipDesc *recip, si
131      for (i=0; i < n; i++)      for (i=0; i < n; i++)
132          safe_free (recip[i].lpszName);          safe_free (recip[i].lpszName);
133      safe_free (recip);      safe_free (recip);
134  } /* free_recip_tab */  }
135    
136    
137  static void  static void
138  free_files_tab (MapiFileDesc * files, size_t n)  free_files_tab (MapiFileDesc *files, size_t n)
139  {  {
140      size_t i;      size_t i;
141    
# Line 177  free_files_tab (MapiFileDesc * files, si Line 148  free_files_tab (MapiFileDesc * files, si
148          safe_free (files[i].lpszPathName);          safe_free (files[i].lpszPathName);
149      }      }
150      safe_free (files);      safe_free (files);
151  } /* 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 gpgme_error_t  
 secure_message (gpgme_recipients_t rset, const char *data,  
                 char *enc_msg, size_t *r_enclen)  
 {  
     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 rc;  
     }  
     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");  
   
     *r_enc_msg = gpgme_data_release_and_get_mem (&n);  
     *r_enclen = n;  
   
     gpgme_data_release (in);  
     gpgme_release (ctx);  
     gpgme_recipients_release (addrs);  
   
     return rc;  
 } /* secure_message */  
152    
153    
154    /* Same as mapi_send_pubkey but there is an additional note. */
155  int  int
156  mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,  mapi_send_pubkey_ext (winpt_key_t key, const char *keyfile, int flags)
                    const char * subject, const char **files, size_t nfiles)  
157  {  {
158      LHANDLE hd;      LHANDLE hd;
159      MapiMessage * msg;      MapiMessage *msg;
160      MapiRecipDesc * recip;      MapiRecipDesc *recip;
161      MapiFileDesc * attch;      MapiFileDesc *attch;
162      char * p;      gpgme_key_t to = key->ctx;
163      const char * s;      char *p, *kinf;
164      void * ctx=NULL;      const char *s;
     size_t n, i=0, encmsg_len=0;  
165      int rc;      int rc;
166    
167      if (!init)      if (!init)
# Line 309  mapi_send_message (gpgme_recipients_t rs Line 173  mapi_send_message (gpgme_recipients_t rs
173          return rc;          return rc;
174      }      }
175    
176      msg = (MapiMessage *)calloc (1, sizeof * msg);      msg = (MapiMessage *)calloc (1, sizeof *msg);
177      if (!msg)      if (!msg)
178          BUG (0);          BUG (0);
179      p = msg->lpszSubject = strdup (subject);      p = msg->lpszSubject = strdup ("OpenPGP Public Key");
180      if (!p)      if (!p)
181          BUG (0);          BUG (0);
182      p = msg->lpszNoteText = secure_message (rset, msgtxt, &p, &encmsg_len);  
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)      if (!p)
196          BUG (0);          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;  
197    
198      if (nfiles) {      /* If the key was signed, we assume it shall be sent back to the owner. */
199          msg->nFileCount = nfiles;      if (flags) {
200          attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);          recip = (MapiRecipDesc *)calloc (1, sizeof *recip);
201          if (!attch)          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);              BUG (0);
207          for (i=0; i < nfiles; i++) {          msg->lpRecips = recip;
208              char * p = secure_attachment (rset, *files);          msg->nRecipCount = 1;
209              if (!p)      }
210                  continue;      else {
211              attch[i].lpszFileName = strdup (*files);                  msg->lpRecips = recip = NULL;
212              attch[i].lpszPathName = strdup (p);          msg->nRecipCount = 0;
             files++;  
             safe_free (p);  
         }  
         msg->lpFiles = attch;  
213      }      }
214    
215      rc = mapi_send_mail (hd, 0, msg, 0, 0);      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)      if (rc == MAPI_E_USER_ABORT)
225          rc = SUCCESS_SUCCESS;          rc = SUCCESS_SUCCESS;
226      if (rc != SUCCESS_SUCCESS)      if (rc != SUCCESS_SUCCESS)
227          MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);          MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
228    
229      free_recip_tab (recip, n);      free_recip_tab (recip, 1);
230      free_files_tab (attch, nfiles);      free_files_tab (attch, 1);
231      free_mapi_msg (msg);      free_mapi_msg (msg);
     gpgme_free (p);  
232      mapi_logoff (hd, 0, 0, 0);      mapi_logoff (hd, 0, 0, 0);
233    
234      return 0;      return 0;
235  } /* mapi_send_message */  }
   
   
 static int  
 add_recipient (gpgme_recipients_t * r_rset, const char * addr)  
 {  
     gpg_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;  
236    
     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 */  
237    
238    
239  BOOL CALLBACK  int
240  winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  mapi_send_pubkey (const char *keyid, char *keyfile)
241  {  {
242      static gpgme_recipients_t rset=NULL;      winpt_key_s key;
     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;  
     }  
243    
244      return FALSE;      memset (&key, 0, sizeof (key));
245  } /* winpt_mail_proc */      if (winpt_get_pubkey (keyid, &key))
246  #endif          return -1;
247        return mapi_send_pubkey_ext (&key, keyfile, 0);
248    }

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26