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

Legend:
Removed from v.32  
changed lines
  Added in v.278

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26