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

Diff of /trunk/Src/wptClipDecryptDlg.cpp

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

revision 24 by twoaday, Sat Oct 8 10:43:08 2005 UTC revision 286 by twoaday, Fri Mar 9 19:34:17 2007 UTC
# Line 1  Line 1 
1  /* wptClipDecryptDlg.cpp - Clipboard decrypt dialog  /* wptClipDecryptDlg.cpp - Clipboard decryption
2   *      Copyright (C) 2000-2005 Timo Schulz   *      Copyright (C) 2000-2007 Timo Schulz
3   *      Copyright (C) 2005 g10 Code GmbH   *      Copyright (C) 2005 g10 Code GmbH
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
6   *   *
7   * WinPT is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
8   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
9   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.   * (at your option) any later version.
11   *   *
12   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.   * GNU General Public License for more details.
16   *   */
17   * You should have received a copy of the GNU General Public License  #ifdef HAVE_CONFIG_H
18   * along with WinPT; if not, write to the Free Software Foundation,  #include <config.h>
19   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  #endif
20   */  
21    #include <windows.h>
22  #include <windows.h>  #include <assert.h>
23    #include <time.h>
24  #include "wptTypes.h"  
25  #include "wptW32API.h"  #include "wptTypes.h"
26  #include "wptAgent.h"  #include "wptW32API.h"
27  #include "wptNLS.h"  #include "wptAgent.h"
28  #include "wptGPG.h"  #include "wptNLS.h"
29  #include "wptVersion.h"  #include "wptGPG.h"
30  #include "wptErrors.h"  #include "wptVersion.h"
31  #include "wptCommonCtl.h"  #include "wptErrors.h"
32  #include "wptContext.h"  #include "wptCommonCtl.h"
33  #include "wptDlgs.h"  #include "wptContext.h"
34  #include "wptKeylist.h"  #include "wptDlgs.h"
35  #include "wptFileManager.h"  #include "wptKeylist.h"
36  #include "../resource.h"  #include "wptUTF8.h"
37    #include "resource.h"
38  /* Return the primary user-ID of the key with the keyid @keyid.  #include "StringBuffer.h"
39     Caller must free string. */  
40  char*  bool is_seckey_available (gpgme_recipient_t rset);
41  get_key_userid (const char *keyid)  char* get_pka_status (gpgme_signature_t sig);
42  {  
43      gpgme_key_t key;  
44      const char *s;  /* Return the primary user-ID of the key with the keyid @keyid.
45      char *p;     Caller must free string. */
46    char*
47      if (get_pubkey (keyid, &key))  get_key_userid (const char *keyid)
48          return m_strdup (_("user ID not found"));  {
49      s = key->uids->uid;      winpt_key_s key;
50      if (!s)      StringBuffer p;
51          s = _("user ID not found");      const char *userid;
52      p = new char[strlen (s) + 4 + 8];      char *uid;
53      if (!p)  
54          BUG (NULL);      p = "\n    ";  
55      sprintf (p, "\n    \"%s\"", s);      memset (&key, 0, sizeof (key));
56      return p;      if (winpt_get_pubkey (keyid, &key))
57  }          userid = (_("user ID not found"));
58        else
59            userid = key.ext->uids->uid;
60  /* Decrypt the clipboard contents and on success      p = p + "\"" + userid + "\"";
61     replace the data with the plaintext.  
62     Return value: 0 on success. */      winpt_release_pubkey (&key);
63  gpgme_error_t      uid = p.getBufferCopy ();
64  gpgme_op_clip_decrypt (gpgme_ctx_t ctx)      return uid;
65  {  }
66      gpgme_error_t err;  
67      gpgme_data_t ciph = NULL;  
68      gpgme_data_t plain = NULL;  /* Decrypt the clipboard contents and on success
69           replace the data with the plaintext.
70      err = gpg_data_new_from_clipboard (&ciph, 0);     Return value: 0 on success. */
71      if (err)  gpgme_error_t
72          return err;  gpgme_op_clip_decrypt (gpgme_ctx_t ctx)
73    {
74      err = gpgme_data_new (&plain);      gpgme_error_t err;
75      if (err) {      gpgme_data_t ciph = NULL;
76          gpgme_data_release (ciph);      gpgme_data_t plain = NULL;
77          return err;      
78      }      err = gpg_data_new_from_clipboard (&ciph, 0);
79        if (err)
80      err = gpgme_op_decrypt (ctx, ciph, plain);          return err;
81    
82      gpg_data_release_and_set_clipboard (plain, 0);      err = gpgme_data_new (&plain);
83      gpgme_data_release (ciph);      if (err) {
84      return err;          gpgme_data_release (ciph);
85  }          return err;
86        }
87    
88  /* Convenient function to provide clipboard decryption.      err = gpgme_op_decrypt_verify (ctx, ciph, plain);
89     @hwnd is the parent window used for showing messsages.  
90     Return value: 0 on success. */      gpg_data_release_and_set_clipboard (plain, 0);
91  gpgme_error_t      gpgme_data_release (ciph);
92  clip_decrypt_dlg (HWND hwnd)      return err;
93  {  }
94      gpgme_error_t err;  
95      gpgme_ctx_t ctx = NULL;  
96      gpgme_signature_t sig = NULL;  /* Return humand readable ownertrust description for verification info. */
97      gpgme_decrypt_result_t res;  const char*
98      gpgme_verify_result_t sigres;  verify_get_key_ownertrust (gpgme_validity_t key_ot, int *novalid)
99      passphrase_cb_s pwd;  {
100      const char *created, *s;      const char *s;
101      char keyid[16+1] = {0};  
102      int novalid = 0;      if (novalid)
103            *novalid = 0; /* reset */
104      /* allow to verify data generated by 'gpg -a --sign foo' */      if (key_ot == GPGME_VALIDITY_FULL ||
105      if (fm_assume_onepass_sig (NULL) == 0) {          key_ot == GPGME_VALIDITY_ULTIMATE)
106          /* XXX: addtitional steps needed? */          s = _("Signature status: created with a fully trusted key");    
107      }      else if (key_ot == GPGME_VALIDITY_MARGINAL)    
108            s = _("Signature status: created with a marginal trusted key");
109      err = gpgme_new (&ctx);      else if (key_ot == GPGME_VALIDITY_NEVER) {
110      if (err)          if (novalid)
111          BUG (NULL);              *novalid = 1;
112      set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_DECRYPT, hwnd, _("Decryption"));          s =  _("Signature status: created with an UNTRUSTED key");      
113      err = gpgme_op_clip_decrypt (ctx);      }
114      if (pwd.cancel)      else
115          goto leave;          s = _("Signature status: created with an undefined trusted key");
116      if (gpgme_err_code (err) ==  GPG_ERR_BAD_PASSPHRASE)      return s;
117          agent_del_cache (pwd.keyid);  }
118    
119      res = gpgme_op_decrypt_result (ctx);  
120      if (err == gpg_error (GPG_ERR_NO_SECKEY) && res->recipients) {  /* Return a signature specific header and footer for the clipboard. */
121          gpgme_recipient_t r = res->recipients;  void
122          char *p = get_key_userid (r->keyid+8);  verify_get_clip_info (gpgme_signature_t sig, char **r_header, char **r_footer)
123            {
124          log_box (_("Decryption"), MB_ERR,      struct winpt_key_s pk;
125                   _("Encrypted with %s key, ID %s.%s\n"      const char *head = _("*** PGP SIGNATURE VERIFICATION ***\r\n"
126                     "Decryption failed: secret key not available."),                           "*** Signature made:    %s\r\n"
127                     get_key_pubalgo (r->pubkey_algo), r->keyid+8, p);                           "*** Signature verfied: %s\r\n"
128          free_if_alloc (p);                           "*** %s\r\n"
129          goto leave;                           "*** Signature result:  %s\r\n"
130      }                           "*** Signer: %s (0x%s)\r\n"
131      else if (err) {                           "*** BEGIN PGP DECRYPTED TEXT ***\r\n");
132          gpgme_pgptype_t pgp_type;      const char *foot = _("\r\n*** END PGP DECRYPTED TEXT ***");
133          gpgme_clip_get_pgptype (&pgp_type);      const char *stat, *ot, *uid, *keyid;
134          if (err == gpg_error (GPG_ERR_NO_DATA) && (pgp_type & PGP_MESSAGE))      char made[128], ver[128];
135              msg_box (hwnd, _("Broken OpenPGP message (maybe: quoted printable "      char *p;
136                               "character in armor)."), _("Decryption"), MB_INFO);  
137          else      if (winpt_get_pubkey (sig->fpr, &pk)) {
138              msg_box (hwnd, gpgme_strerror (err), _("Decryption"), MB_ERR);          uid = _("user ID not found");
139          goto leave;          ot = verify_get_key_ownertrust (GPGME_VALIDITY_UNDEFINED, NULL);
140      }      }
141        else {
142      /* Too paranoid??          uid = pk.ext->uids->uid;
143      if (flags & GPGME_OPFLAG_BADMDC) {          ot = verify_get_key_ownertrust (pk.ctx->owner_trust, NULL);
144          const char *s;      }
145          s = _("WARNING: encrypted message has been manipulated!\n"      
146              "\n"      if (!get_locale_timedate (sig->timestamp, made, DIM (made)-1))
147              "Do *NOT* trust any text or data output from this file!\n"          _snprintf (made, DIM (made)-1, "'unknown time'");
148              "It is likely, the data was corrupted during the transport\n"      if (!get_locale_timedate (time (NULL), ver, DIM (ver)-1))
149              "but it might be also possible that this is part of an attack.");          _snprintf (ver, DIM (ver)-1, "'unknown time'");
150          msg_box (hwnd, s, _("*** IMPORTANT ***"), MB_INFO);      stat = get_gpg_sigstat (sig->summary);
151      }*/      p = new char[strlen (head) + strlen (stat) + strlen (made) +
152                         strlen (sig->fpr) + strlen (ot) + strlen (ver) +
153                     strlen (uid) + 1];
154      show_msg (GetDesktopWindow (), 1500, _("GnuPG Status: Finished"));      if (!p)
155            BUG (0);
156      sigres = gpgme_op_verify_result (ctx);      if (strlen (sig->fpr) == 32) { /* RSA:MD5 */
157      if (sigres && sigres->signatures) {          if (pk.ext != NULL)
158          gpgme_key_t key;              keyid = pk.ext->key->subkeys->keyid+8;
159          const char * val;          else
160          char keyid[16+1];              keyid = sig->fpr; /* show the fingerprint in case of problems. */
161        }
162          sig = sigres->signatures;      else
163          if (!sig->fpr)          keyid = get_keyid_from_fpr (sig->fpr);
164              val = "????????????????";      sprintf (p, head, made, ver, ot, stat, uid, keyid);
165          else      *r_header = p;
166              val = strlen (sig->fpr) == 40? sig->fpr+32 : sig->fpr + 24;      *r_footer = m_strdup (foot);
167          _snprintf (keyid, sizeof (keyid)-1, "%s", val+8);  }
168    
169          get_pubkey (keyid, &key);  
170          if (key->owner_trust == GPGME_VALIDITY_FULL ||  /* Show a human readable description of the given signature @sig. */
171              key->owner_trust == GPGME_VALIDITY_ULTIMATE)  void
172              s = _("Signature Status: Created with a fully trusted key");  verify_show_signature_state (gpgme_signature_t sig)
173          else if (key->owner_trust == GPGME_VALIDITY_MARGINAL)  {
174              s = _("Signature Status: Created with a marginal trusted key");      winpt_key_s key;
175          else if (key->owner_trust == GPGME_VALIDITY_NEVER) {      const char *keyid, *uid;
176              novalid = 1;      const char *s;
177              s =  _("Signature Status: Created with an UNTRUSTED key");      char *pka_info = NULL, timebuf[128];
178          }      int novalid = 0;
179          else  
180              s = _("Signature Status: Created with an undefined trusted key");      assert (sig->fpr != NULL);
181          created = strtimestamp (sig->timestamp);          
182        memset (&key, 0, sizeof (key));
183          if (key)      if (!winpt_get_pubkey (sig->fpr, &key)) {
184              val = key->uids->uid;          s = verify_get_key_ownertrust (key.ctx->owner_trust, &novalid);
185          else          uid = key.ext->uids->uid;      
186              val = _("user ID not found");      }
187          log_box (_("WinPT Verify"), MB_OK,      else {
188                   _("%s\n"          s = "";
189                     "%s\n"          uid = _("user ID not found");
190                     "Signature made %s\n"      }
191                     "From \"%s\" using key ID 0x%s"  
192                     "%s %s"),      if (!get_locale_timedate (sig->timestamp, timebuf, DIM (timebuf)-1))
193                     s, get_gpg_sigstat (sig->summary), created,          _snprintf (timebuf, DIM (timebuf)-1, "'unknown time'");
194                     val, keyid,  
195                     novalid? "\nPrimary key fingerprint: " : "",      if (strlen (sig->fpr) == 32) {
196                     novalid? get_key_fpr (key) : "");          if (key.ctx != NULL)
197      }              keyid = key.ctx->subkeys->keyid+8;
198                else
199  leave:              keyid = sig->fpr; /* in case of problems show the fingerprint. */
200      release_gpg_passphrase_cb (&pwd);      }  
201      gpgme_release (ctx);      else
202      return err;          keyid = get_keyid_from_fpr (sig->fpr);
203  }      
204        pka_info = get_pka_status (sig);
205        log_box (_("Decrypt Verify"), novalid? MB_WARN : MB_OK,
206                 _("%s\n"
207                   "%s\n"
208                   "Signature made: %s\n"
209                   "From \"%s\" using key ID 0x%s"
210                   "%s %s\n%s"),
211                   s, get_gpg_sigstat (sig->summary),                  
212                   timebuf, uid, keyid,
213                   novalid? "\nPrimary key fingerprint: " : "",
214                   novalid? get_key_fpr (key.ctx) : "",
215                   pka_info? pka_info : ""
216                   );
217        free_if_alloc (pka_info);
218        winpt_release_pubkey (&key);
219    }
220    
221    
222    /* Convenient function to provide clipboard decryption.
223       @hwnd is the parent window used for showing messsages.
224       Return value: 0 on success. */
225    gpgme_error_t
226    clip_decrypt_dlg (HWND hwnd, int use_viewer)
227    {
228        gpgme_error_t err;
229        gpgme_ctx_t ctx = NULL;
230        gpgme_decrypt_result_t res;
231        gpgme_verify_result_t sigres;
232        passphrase_cb_s pwd;
233        int pgp_type = 0;
234    
235        /* allow to verify data generated by 'gpg -a --sign foo' */
236        if (fm_assume_onepass_sig (NULL) == 1) {
237            dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_VERIFY, hwnd,
238                              clip_verify_dlg_proc, 0,
239                              _("Verify"), IDS_WINPT_VERIFY);
240            return 0;
241        }
242    
243        err = gpgme_new (&ctx);
244        if (err)
245            BUG (NULL);
246        set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_DECRYPT, hwnd, _("Decryption"));
247        gpg_get_recipients (NULL, &pwd.recipients);
248    
249        err = gpgme_op_clip_decrypt (ctx);
250        if (pwd.cancel)
251            goto leave;
252        if (gpgme_err_code (err) ==  GPG_ERR_BAD_PASSPHRASE)
253            agent_del_cache (pwd.keyid);
254    
255        res = gpgme_op_decrypt_result (ctx);
256        if (err && res->recipients && !is_seckey_available (res->recipients)) {
257            gpgme_recipient_t r = res->recipients;
258            char *u = get_key_userid (r->keyid+8);
259            log_box (_("Decryption"), MB_ERR,
260                     _("Encrypted with %s key, ID 0x%s.%s\n"
261                       "Decryption failed: secret key not available."),
262                       get_key_pubalgo (r->pubkey_algo), r->keyid+8, u);
263            free_if_alloc (u);
264            goto leave;
265        }
266        else if (res->unsupported_algorithm) {
267            log_box (_("Decryption"), MB_ERR, _("Unsupported algorithm: %s"),
268                     res->unsupported_algorithm);
269        }
270        else if (err) {
271            gpg_clip_get_pgptype (&pgp_type);
272            if (gpgme_err_code (err) == GPG_ERR_NO_DATA && (pgp_type & PGP_MESSAGE))
273                msg_box (hwnd, _("Broken OpenPGP message (maybe: quoted printable "
274                                 "character in armor)."), _("Decryption"), MB_INFO);
275            else
276                msg_box (hwnd, gpgme_strerror (err), _("Decryption"), MB_ERR);
277            goto leave;
278        }
279    
280        #if 0
281        if (status_bad_mdc) { /* XXX: Bad MDC */
282            const char *s =
283                _("WARNING: encrypted message has been manipulated!\n"
284                "\n"
285                "Do *NOT* trust any text or data output from this file!\n"
286                "It is likely that the data was corrupted in transport\n"
287                "but it might be also possible that this is part of an attack.");
288            msg_box (hwnd, s, _("*** IMPORTANT ***"), MB_INFO);
289        }
290        #endif
291    
292        show_msg (GetDesktopWindow (), 1500, _("GnuPG Status: Finished"));
293    
294        sigres = gpgme_op_verify_result (ctx);
295        if (sigres && sigres->signatures) {
296            if (!use_viewer)
297                verify_show_signature_state (sigres->signatures);
298            else
299                DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CLIPEDIT,
300                                hwnd, clip_edit_dlg_proc,
301                                (LPARAM)sigres->signatures);
302        }
303        else if (use_viewer)
304            DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CLIPEDIT,
305                                hwnd, clip_edit_dlg_proc, 0);
306    
307    leave:
308        release_gpg_passphrase_cb (&pwd);
309        gpgme_release (ctx);
310        return err;
311    }

Legend:
Removed from v.24  
changed lines
  Added in v.286

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26