/[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 12 by twoaday, Thu Apr 14 12:56:25 2005 UTC revision 179 by twoaday, Fri Feb 24 13:12:26 2006 UTC
# Line 1  Line 1 
1  /* wptClipDecryptDlg.cpp - Clipboard decrypt dialog  /* wptClipDecryptDlg.cpp - Clipboard decrypt dialog
2   *      Copyright (C) 2000-2004 Timo Schulz   *      Copyright (C) 2000-2005 Timo Schulz
3   *   *      Copyright (C) 2005 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
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   * WinPT is free software; you can redistribute it and/or modify
8   * the Free Software Foundation; either version 2 of the License, or   * it under the terms of the GNU General Public License as published by
9   * (at your option) any later version.   * the Free Software Foundation; either version 2 of the License, or
10   *   * (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * GNU General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   *   * GNU General Public License for more details.
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,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * along with WinPT; if not, write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21  #include <windows.h>  
22    #ifdef HAVE_CONFIG_H
23  #include "wptTypes.h"  #include <config.h>
24  #include "wptW32API.h"  #endif
25  #include "wptAgent.h"  
26  #include "wptNLS.h"  #include <windows.h>
27  #include "wptGPG.h"  
28  #include "wptVersion.h"  #include "wptTypes.h"
29  #include "wptErrors.h"  #include "wptW32API.h"
30  #include "wptCommonCtl.h"  #include "wptAgent.h"
31  #include "wptContext.h"  #include "wptNLS.h"
32  #include "wptDlgs.h"  #include "wptGPG.h"
33  #include "wptKeylist.h"  #include "wptVersion.h"
34  #include "wptFileManager.h"  #include "wptErrors.h"
35  #include "../resource.h"  #include "wptCommonCtl.h"
36    #include "wptContext.h"
37  char *  #include "wptDlgs.h"
38  get_key_userid (const char * keyid)  #include "wptKeylist.h"
39  {  #include "wptFileManager.h"
40      gpgme_key_t key;  #include "wptUTF8.h"
41      const char * s;  #include "resource.h"
42      char * p;  
43    bool secret_key_available (gpgme_recipient_t rset);
44      if( get_pubkey( keyid, &key ) )  
45          return m_strdup( "" );  /* Return the primary user-ID of the key with the keyid @keyid.
46      s = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );     Caller must free string. */
47      if( !s )  char*
48          s = _("user ID not found");  get_key_userid (const char *keyid)
49      p = new char[strlen( s ) + 4 + 8];  {
50      if( !p )      gpgme_key_t key;
51          BUG( NULL );      char *p, *uid;
52      sprintf( p, "\n    \"%s\"", s );  
53      return p;      if (get_pubkey (keyid, &key))
54  } /* get_key_userid */          return m_strdup (_("user ID not found"));
55        uid = utf8_to_wincp2 (key->uids->uid);
56        if (!uid)
57  static gpgme_error_t          uid = strdup (_("user ID not found"));
58  list_recipients (gpgme_ctx_t ctx, gpgme_recipients_t *r_rset)      p = new char[strlen (uid) + 4 + 8];
59  {      if (!p)
60      gpgme_error_t rc;          BUG (NULL);
61      gpgme_data_t clipdat;      sprintf (p, "\n    \"%s\"", uid);
62        safe_free (uid);
63      rc = gpgme_data_new_from_clipboard (&clipdat);      return p;
64      if (!rc)  }
65          rc = gpgme_op_list_keys (clipdat, NULL, r_rset);  
66      gpgme_data_release (clipdat);  
67      return rc;  /* Decrypt the clipboard contents and on success
68  } /* list_recipients */     replace the data with the plaintext.
69       Return value: 0 on success. */
70    gpgme_error_t
71  int  gpgme_op_clip_decrypt (gpgme_ctx_t ctx)
72  algo_from_list (gpgme_recipients_t rset, const char * keyid)  {
73  {      gpgme_error_t err;
74      void * ctx = NULL;      gpgme_data_t ciph = NULL;
75      const char * s;      gpgme_data_t plain = NULL;
76        
77      gpgme_recipients_enum_open (rset, &ctx);      err = gpg_data_new_from_clipboard (&ciph, 0);
78      while ((s = gpgme_recipients_enum_read (rset, &ctx))) {      if (err)
79          if (!strcmp( s+1, keyid))          return err;
80              return *s;  
81      }      err = gpgme_data_new (&plain);
82      return 0;      if (err) {
83  } /* algo_from_list */          gpgme_data_release (ciph);
84            return err;
85        }
86  int  
87  clip_decrypt_dlg (HWND hwnd)      err = gpgme_op_decrypt_verify (ctx, ciph, plain);
88  {  
89      gpgme_error_t rc;      gpg_data_release_and_set_clipboard (plain, 0);
90      gpgme_ctx_t ctx = NULL;      gpgme_data_release (ciph);
91      gpgme_recipients_t keys = NULL;      return err;
92      gpgme_sig_t sig = NULL;  }
93      gpgme_op_flags_t flags;  
94      passphrase_cb_s pwd;  
95      const char *created, *s;  /* Convenient function to provide clipboard decryption.
96      char keyid[17] = {0};     @hwnd is the parent window used for showing messsages.
97      int novalid = 0;     Return value: 0 on success. */
98      unsigned int pkalgo = 0;  gpgme_error_t
99      u32 t, sigstat;  clip_decrypt_dlg (HWND hwnd)
100        {
101      rc = gpgme_new (&ctx);      gpgme_error_t err;
102      if (rc)      gpgme_ctx_t ctx = NULL;
103          BUG (0);      gpgme_signature_t sig = NULL;
104      gpgme_enable_logging (ctx);      gpgme_decrypt_result_t res;
105        gpgme_verify_result_t sigres;
106      /* allow to verify data generated by 'gpg -a --sign foo' */      passphrase_cb_s pwd;
107      if (fm_assume_onepass_sig (NULL) == 0) {      const char *s;
108          rc = list_recipients (ctx, &keys);      char *uid;
109          if (rc) {      int pgp_type = 0;
110              gpgme_show_error (hwnd, rc, ctx, _("Decryption"), MB_ERR);      int novalid = 0;
111              gpgme_release (ctx);  
112              return rc;      /* allow to verify data generated by 'gpg -a --sign foo' */
113          }      if (fm_assume_onepass_sig (NULL) == 0) {
114      }          /* XXX: addtitional steps needed? */
115        }
116      set_gpg_passphrase_cb (ctx, &pwd, GPG_CMD_DECRYPT, hwnd, _("Decryption"));  
117      pwd.enc_to = keys;      err = gpgme_new (&ctx);
118      rc = gpgme_op_clip_decrypt (ctx);      if (err)
119      memset (pwd.pwd, 0, sizeof pwd.pwd);          BUG (NULL);
120      if (pwd.cancel)      set_gpg_passphrase_cb (&pwd, ctx, GPG_CMD_DECRYPT, hwnd, _("Decryption"));
121          goto leave;      gpg_get_recipients (NULL, &pwd.recipients);
122    
123      if (rc == GPGME_Bad_Passphrase)      err = gpgme_op_clip_decrypt (ctx);
124          agent_del_cache (pwd.keyid);      if (pwd.cancel)
125      gpgme_decrypt_get_status (ctx, keyid, &flags);          goto leave;
126      if (rc == GPGME_No_Seckey && (flags & GPGME_OPFLAG_NOSECKEY)) {      if (gpgme_err_code (err) ==  GPG_ERR_BAD_PASSPHRASE)
127          char * p = get_key_userid (keyid+8);          agent_del_cache (pwd.keyid);
128          int pkalgo = algo_from_list (keys, keyid);  
129          log_box (_("Decryption"), MB_ERR,      res = gpgme_op_decrypt_result (ctx);
130                   _("Encrypted with %s key, ID %s.%s\n"      if (err && res->recipients && !secret_key_available (res->recipients)) {
131                     "Decryption failed: secret key not available."),          gpgme_recipient_t r = res->recipients;
132                     gpgme_key_expand_attr( GPGME_ATTR_ALGO, pkalgo),          uid = get_key_userid (r->keyid+8);
133                     keyid+8, p);          log_box (_("Decryption"), MB_ERR,
134          free_if_alloc (p);                   _("Encrypted with %s key, ID %s.%s\n"
135          goto leave;                     "Decryption failed: secret key not available."),
136      }                     get_key_pubalgo (r->pubkey_algo), r->keyid+8, uid);
137      else if (rc) {          free_if_alloc (uid);
138          gpgme_cliptype_t pgp_type;          goto leave;
139          gpgme_clip_get_pgptype (&pgp_type);      }
140          if (rc == GPGME_No_Data && (pgp_type & GPGME_CLIP_MESSAGE))      else if (res->unsupported_algorithm) {
141              msg_box (hwnd, _("Broken OpenPGP message (maybe: quoted printable character in armor)."), _("Decryption"), MB_INFO);          log_box (_("Decryption"), MB_ERR, _("Unsupported algorithm: %s"),
142          else                   res->unsupported_algorithm);
143              gpgme_show_error (hwnd, rc, ctx, _("Decryption"), MB_ERR);      }
144          goto leave;      else if (err) {
145      }          gpg_clip_get_pgptype (&pgp_type);
146            if (gpgme_err_code (err) == GPG_ERR_NO_DATA && (pgp_type & PGP_MESSAGE))
147      if (flags & GPGME_OPFLAG_BADMDC) {              msg_box (hwnd, _("Broken OpenPGP message (maybe: quoted printable "
148          const char *s;                               "character in armor)."), _("Decryption"), MB_INFO);
149          s = _("WARNING: encrypted message has been manipulated!\n"          else
150              "\n"              msg_box (hwnd, gpgme_strerror (err), _("Decryption"), MB_ERR);
151              "Do *NOT* trust any text or data output from this file!\n"          goto leave;
152              "It is likely, the data was corrupted during the transport\n"      }
153              "but it might be also possible that this is part of an attack.");  
154          msg_box (hwnd, s, _("*** IMPORTANT ***"), MB_INFO);      if (0) { /* XXX: Bad MDC */
155      }          s = _("WARNING: encrypted message has been manipulated!\n"
156                    "\n"
157      show_msg (hwnd, 1500, _("GnuPG Status: Finished"));              "Do *NOT* trust any text or data output from this file!\n"
158      gpgme_decrypt_get_sig_ctx (ctx, &sig);              "It is likely, the data was corrupted during the transport\n"
159      sigstat = gpgme_sig_get_ulong_attr (sig, 0, GPGME_ATTR_VALIDITY);              "but it might be also possible that this is part of an attack.");
160      if (sig && sigstat != GPGME_SIG_STAT_ERROR) {          msg_box (hwnd, s, _("*** IMPORTANT ***"), MB_INFO);
161          gpgme_key_t key;      }
162          const char * val;  
163          char keyid[16+1];      show_msg (GetDesktopWindow (), 1500, _("GnuPG Status: Finished"));
164            
165          val = gpgme_sig_get_string_attr( sig, GPGME_ATTR_KEYID );      sigres = gpgme_op_verify_result (ctx);
166          if( !val )      if (sigres && sigres->signatures) {
167              val = "DEADBEEFDEADBEEF";          gpgme_key_t key=NULL;
168          _snprintf( keyid, sizeof(keyid)-1, "%s", val+8 );          const char *keyid;
169          sigstat = gpgme_sig_get_ulong_attr( sig, 0, GPGME_ATTR_VALIDITY );  
170          if( get_pubkey( keyid, &key ) )          sig = sigres->signatures;
171              goto leave;          if (!sig->fpr)
172                BUG (NULL);
173          t = gpgme_sig_get_ulong_attr( sig, 0, GPGME_ATTR_OTRUST );          if (strlen (sig->fpr) > 16)
174          if( t == GPGME_VALIDITY_FULL || t == GPGME_VALIDITY_ULTIMATE )              keyid = strlen (sig->fpr) == 40? sig->fpr+24 : sig->fpr+16;
175              s = _("Signature Status: Created with a fully trusted key");          else
176          else if ( t == GPGME_VALIDITY_MARGINAL )              keyid = sig->fpr;
177              s = _("Signature Status: Created with a marginal trusted key");  
178          else if ( t == GPGME_VALIDITY_UNKNOWN          get_pubkey (keyid, &key);
179                    || t == GPGME_VALIDITY_UNDEFINED          if (key) {
180                    || t == GPGME_VALIDITY_NEVER ) {              if (key->owner_trust == GPGME_VALIDITY_FULL ||
181              novalid = 1;                  key->owner_trust == GPGME_VALIDITY_ULTIMATE)
182              s =  _("Signature Status: Created with an UNTRUSTED key");                  s = _("Signature Status: Created with a fully trusted key");
183          }              else if (key->owner_trust == GPGME_VALIDITY_MARGINAL)
184          else                  s = _("Signature Status: Created with a marginal trusted key");
185              s = _("Signature Status: Created with an invalid key");              else if (key->owner_trust == GPGME_VALIDITY_NEVER) {
186          t = gpgme_sig_get_ulong_attr( sig, 0, GPGME_ATTR_CREATED );                  novalid = 1;
187          created = strtimestamp( t );                  s =  _("Signature Status: Created with an UNTRUSTED key");
188          t = gpgme_key_get_ulong_attr( key, GPGME_ATTR_VALIDITY, NULL, 0 );              }
189          val = gpgme_sig_get_string_attr( sig, GPGME_ATTR_USERID );              else
190          if( !val )                  s = _("Signature Status: Created with an undefined trusted key");
191              val = _("Invalid User ID");              uid = utf8_to_wincp2 (key->uids->uid);
192          log_box( _("WinPT Verify"), MB_OK,          }
193                   _("%s\n"          else {
194                     "%s\n"                    s = "";
195                     "Signature made %s\n"              uid = strdup (_("user ID not found"));
196                     "From \"%s\" using key ID 0x%s"          }
197                     "%s %s"),          log_box (_("WinPT Verify"), MB_OK,
198                     s, gpg_sigstat[sigstat % SIGSTAT_MASK], created,                   _("%s\n"
199                     val, keyid,                     "%s\n"
200                     novalid? "\nPrimary key fingerprint: " : "",                     "Signature made: %s\n"
201                     novalid? get_key_fpr( key ) : ""                     "From \"%s\" using key ID 0x%s"
202                     );                     "%s %s"),
203      }                     s, get_gpg_sigstat (sig->summary),
204                           strtimestamp (sig->timestamp),
205  leave:                     uid, keyid+8,
206      gpgme_release( ctx );                     novalid? "\nPrimary key fingerprint: " : "",
207      gpgme_recipients_release( keys );                     novalid? get_key_fpr (key) : "");
208      gpgme_sig_release( sig );          safe_free (uid);
209      return rc;      }
210  } /* clip_decrypt_dlg */      
211    leave:
212        release_gpg_passphrase_cb (&pwd);
213        gpgme_release (ctx);
214        return err;
215    }

Legend:
Removed from v.12  
changed lines
  Added in v.179

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26