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

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26