/[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 149 by twoaday, Fri Dec 30 13:56:10 2005 UTC revision 150 by twoaday, Wed Jan 18 11:52:45 2006 UTC
# Line 1  Line 1 
1  /* wptMAPI.cpp  /* wptMAPI.cpp - MAPI interface for sending keys.
2   *      Copyright (C) 2003, 2004, 2005 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 31  Line 31 
31  #include "wptW32API.h"  #include "wptW32API.h"
32  #include "wptGPG.h"  #include "wptGPG.h"
33  #include "wptVersion.h"  #include "wptVersion.h"
34    #include "wptCommonCtl.h"
35    #include "wptKeyManager.h"
36    
37    
38  static LPMAPILOGON          mapi_logon = NULL;  static LPMAPILOGON          mapi_logon = NULL;
39  static LPMAPILOGOFF         mapi_logoff = NULL;      static LPMAPILOGOFF         mapi_logoff = NULL;    
# Line 105  fail: Line 108  fail:
108  }  }
109    
110    
 /* Send a public key stored in @keyfile with the keyid @keyid  
    via the MAPI mechanism to a mail recipient.  
    Return value: SUCCESS_SUCCESS on succes. */  
 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;  
 }  
   
   
 #if 0 /* low:priority XXX port the code */  
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 166  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 183  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 (gpgme_key_t to, 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;      char *p, *kinf;
163      const char * s;      const char *s;
     void * ctx=NULL;  
     size_t n, i=0, encmsg_len=0;  
164      int rc;      int rc;
165    
166      if (!init)      if (!init)
# Line 315  mapi_send_message (gpgme_recipients_t rs Line 172  mapi_send_message (gpgme_recipients_t rs
172          return rc;          return rc;
173      }      }
174    
175      msg = (MapiMessage *)calloc (1, sizeof * msg);      msg = (MapiMessage *)calloc (1, sizeof *msg);
176      if (!msg)      if (!msg)
177          BUG (0);          BUG (0);
178      p = msg->lpszSubject = strdup (subject);      p = msg->lpszSubject = strdup ("OpenPGP Public Key");
179      if (!p)      if (!p)
180          BUG (0);          BUG (0);
181      p = msg->lpszNoteText = secure_message (rset, msgtxt, &p, &encmsg_len);  
182        s = "Attached is this OpenPGP public key:\n%s\n\n"
183            "Import this key via the clipboard or the Key Manager to\n"
184            "exchange encrypted mails with the key holder and to be able\n"
185            "to verify its signatures.\n"
186            "\n"
187            "If you don't have WinPT, you can download it at http://www.winpt.org";
188        kinf = km_key_get_info (to, 0);
189        p = (char*)malloc (strlen (s) + strlen (kinf) + 2);
190        sprintf (p, s, kinf);
191        free_if_alloc (kinf);
192    
193        p = msg->lpszNoteText = p;
194      if (!p)      if (!p)
195          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;  
196    
197      if (nfiles) {      /* If the key was signed, we assume it shall be sent back to the owner. */
198          msg->nFileCount = nfiles;      if (flags) {
199          attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);          recip = (MapiRecipDesc *)calloc (1, sizeof *recip);
200          if (!attch)          if (!recip)
201              BUG (0);              BUG (0);
202          for (i=0; i < nfiles; i++) {          recip[0].ulRecipClass = MAPI_TO;
203              char * p = secure_attachment (rset, *files);          p = recip[0].lpszName = strdup (to->uids->uid);
204              if (!p)          if (!p)    
205                  continue;              BUG (0);
206              attch[i].lpszFileName = strdup (*files);                  msg->lpRecips = recip;
207              attch[i].lpszPathName = strdup (p);          msg->nRecipCount = 1;
208              files++;      }
209              safe_free (p);      else {
210          }          msg->lpRecips = recip = NULL;
211          msg->lpFiles = attch;          msg->nRecipCount = 0;
212      }      }
213    
214      rc = mapi_send_mail (hd, 0, msg, 0, 0);      msg->nFileCount = 1;
215        attch = (MapiFileDesc *)calloc (1, sizeof *attch);
216        if (!attch)
217            BUG (0);
218        attch[0].lpszFileName = strdup (keyfile);
219        attch[0].lpszPathName = strdup (keyfile);
220        msg->lpFiles = attch;
221    
222        rc = mapi_send_mail (hd, 0, msg, MAPI_DIALOG , 0);
223      if (rc == MAPI_E_USER_ABORT)      if (rc == MAPI_E_USER_ABORT)
224          rc = SUCCESS_SUCCESS;          rc = SUCCESS_SUCCESS;
225      if (rc != SUCCESS_SUCCESS)      if (rc != SUCCESS_SUCCESS)
226          MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);          MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
227    
228      free_recip_tab (recip, n);      free_recip_tab (recip, 1);
229      free_files_tab (attch, nfiles);      free_files_tab (attch, 1);
230      free_mapi_msg (msg);      free_mapi_msg (msg);
     gpgme_free (p);  
231      mapi_logoff (hd, 0, 0, 0);      mapi_logoff (hd, 0, 0, 0);
232    
233      return 0;      return 0;
234  } /* mapi_send_message */  }
235    
236    
237  static int  #if 0
238  add_recipient (gpgme_recipients_t *r_rset, const char *addr)  /* Send a public key stored in @keyfile with the keyid @keyid
239       via the MAPI mechanism to a mail recipient.
240       Return value: SUCCESS_SUCCESS on succes. */
241    int
242    mapi_send_pubkey2 (const char *keyid, char *keyfile)
243  {  {
244      gpg_keycache_t pub = keycache_get_ctx (1);      LHANDLE hd;
245      gpgme_key_t key;      const char * fmt;
246      gpgme_error_t rc;      char * keyinf = NULL;
247      char *uid;      int rc;
   
     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;  
     }  
     if (key->uids->uid) {  
         uid = utf8_to_wincp2 (key->uids->uid);  
         gpgme_recipients_add_name (*r_rset, uid);  
         free_if_alloc (uid);  
     }  
     return 0;  
 } /* add_recipient */  
   
248    
249  static int      if (!init)
250  add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)          return 0;
 {      
     char buf[1024], * p;  
     int n=0;  
251    
252      n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);      fmt = _("GPG Public Key of %s");
253      if (!n)      keyinf = new char[strlen (fmt) + strlen (keyid) + 2];
254          return -1;      if (!keyinf)
255      p = strtok (buf, ";,");          BUG (0);
256      while (p != NULL) {      sprintf (keyinf, fmt, keyid);
257          add_recipient (&*r_rset, p);      rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
258          p = strtok (NULL, ";,");      if (rc != SUCCESS_SUCCESS) {
259            MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
260            goto fail;
261      }      }
262      return 0;      rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);
263  } /* add_all_recipients */      if (rc == MAPI_E_USER_ABORT)
264            rc = SUCCESS_SUCCESS;
265        if (rc != SUCCESS_SUCCESS)
266            MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
267    
268    fail:
269        mapi_logoff (hd, 0, 0, 0);
270        free_if_alloc (keyinf);
271        return rc;
272    }
273    #endif
274    
275  BOOL CALLBACK  
276  winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  int
277    mapi_send_pubkey (const char *keyid, char *keyfile)
278  {  {
279      static gpgme_recipients_t rset=NULL;      gpgme_key_t 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;  
     }  
280    
281      return FALSE;      get_pubkey (keyid, &key);
282  } /* winpt_mail_proc */      return mapi_send_pubkey_ext (key, keyfile, 0);
283  #endif  }

Legend:
Removed from v.149  
changed lines
  Added in v.150

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26