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

Diff of /trunk/Src/wptPassphraseCB.cpp

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

revision 95 by twoaday, Thu Nov 24 12:09:28 2005 UTC revision 304 by twoaday, Wed Mar 21 10:59:31 2007 UTC
# Line 1  Line 1 
1  /* wptPassphraseCB.cpp - GPGME Passphrase Callback  /* wptPassphraseCB.cpp - GPGME Passphrase Callback
2   *      Copyright (C) 2001, 2002, 2003, 2005 Timo Schulz   *      Copyright (C) 2001, 2002-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.
# Line 13  Line 13 
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 GNU   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * General Public License for more details.   * General Public License for more details.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
16   */   */
   
17  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
18  #include <config.h>  #include <config.h>
19  #endif  #endif
# Line 34  Line 29 
29  #include "wptCommonCtl.h"  #include "wptCommonCtl.h"
30  #include "wptContext.h"  #include "wptContext.h"
31  #include "wptDlgs.h"  #include "wptDlgs.h"
 #include "wptUTF8.h"  
32  #include "wptErrors.h"  #include "wptErrors.h"
33  #include "wptTypes.h"  #include "wptTypes.h"
34  #include "wptKeylist.h"  #include "wptKeylist.h"
35  #include "wptAgent.h"  #include "wptAgent.h"
36  #include "wptRegistry.h"  #include "wptRegistry.h"
37    #include "wptUTF8.h"
38    #include "StringBuffer.h"
39    
 const char* get_symkey_algo (int algo);  
40    
41  #define item_ctrl_id( cmd ) \  /* Return the control ID dependent on the mode (sign or decrypt). */
42    #define item_ctrl_id(cmd) \
43      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)
44    
45  #define item_ctrl_id2(cmd) \  #define item_ctrl_id2(cmd) \
46      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_HIDE : IDC_DECRYPT_SIGN_HIDE)      ((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_HIDE : IDC_DECRYPT_SIGN_HIDE)
47    
48    const char* get_symkey_algo (int algo);
49    void ListBox_AddString_utf8 (HWND lb, const char *txt);
50    
51    
52  /* Overwrite passphrase and free memory. */  /* Overwrite passphrase and free memory. */
53  static void  static void
54  burn_passphrase (char **pwd)  burn_passphrase (char **pwd)
55  {  {
56      char *pass = *pwd;      char *pass = *pwd;
57    
58      wipememory (pass, strlen (pass));      wipememory (pass, strlen (pass));
59      delete []pass;      delete []pass;
60      *pwd = NULL;      *pwd = NULL;
# Line 68  passphrase_callback_proc (HWND dlg, UINT Line 68  passphrase_callback_proc (HWND dlg, UINT
68      static passphrase_cb_s *c;      static passphrase_cb_s *c;
69      gpgme_decrypt_result_t res=NULL;      gpgme_decrypt_result_t res=NULL;
70      gpgme_sign_result_t res_sig=NULL;      gpgme_sign_result_t res_sig=NULL;
     gpgme_key_t key;  
71      gpgme_recipient_t recip=NULL, r;      gpgme_recipient_t recip=NULL, r;
72        winpt_key_s key;
73      void *item;      void *item;
     const char *id;  
     char *info;  
74      int n;      int n;
75    
76      switch (msg) {      switch (msg) {
77        case WM_ACTIVATE:
78            /* Some people complained that it is no longer possible to
79               paste in the passphrase in this dialog. When this option
80               is enabled, the ordinary passphrase control will be used. */
81            if (!reg_prefs.no_safe_pwd_ctrl)
82                safe_edit_control_init (dlg, item_ctrl_id (c->gpg_cmd));
83            break;
84    
85        case WM_DESTROY:
86            if (!reg_prefs.no_safe_pwd_ctrl)
87                safe_edit_control_free (dlg, item_ctrl_id (c->gpg_cmd));
88            break;
89    
90      case WM_INITDIALOG:      case WM_INITDIALOG:
91          c = (passphrase_cb_s *)lparam;          c = (passphrase_cb_s *)lparam;
92          if (!c)          if (!c)
93              BUG (0);              BUG (0);
94          SetDlgItemText (dlg, IDC_DECRYPT_HIDE, _("&Hide Typing"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
95          SetWindowText (dlg, c->title);          SetWindowText (dlg, c->title);
96          if (c->gpg_cmd == GPG_CMD_DECRYPT) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
97                SetDlgItemText (dlg, IDC_DECRYPT_HIDE, _("&Hide Typing"));
98              SetDlgItemText (dlg, IDC_DECRYPT_LISTINF,              SetDlgItemText (dlg, IDC_DECRYPT_LISTINF,
99                              _("Encrypted with the following public key(s)"));                              _("Encrypted with the following public key(s)"));
100              CheckDlgButton (dlg, IDC_DECRYPT_HIDE, BST_CHECKED);              CheckDlgButton (dlg, IDC_DECRYPT_HIDE, BST_CHECKED);
# Line 91  passphrase_callback_proc (HWND dlg, UINT Line 103  passphrase_callback_proc (HWND dlg, UINT
103              SetDlgItemText (dlg, IDC_DECRYPT_SIGN_HIDE, _("&Hide Typing"));              SetDlgItemText (dlg, IDC_DECRYPT_SIGN_HIDE, _("&Hide Typing"));
104              CheckDlgButton (dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED);              CheckDlgButton (dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED);
105          }          }
106            /* Because it depends on the order the keys are stored in the
107               keyring whether res->recipients is complete or not, we also
108               support that the recipients were externally extracted and then
109               we use this list. */
110          if (c->recipients)          if (c->recipients)
111              recip = c->recipients; /* recipients were already extracted. */              recip = c->recipients; /* recipients were already extracted. */
112          else {          else {
             /* XXX: not all ENCRYPT_TO entries are listed here. */  
113              res = gpgme_op_decrypt_result (c->gpg);              res = gpgme_op_decrypt_result (c->gpg);
114              if (res && res->recipients)              if (res && res->recipients)
115                  recip = res->recipients;                  recip = res->recipients;
116          }          }
117          if (recip != NULL && c->gpg_cmd == GPG_CMD_DECRYPT) {          if (recip != NULL && c->gpg_cmd == GPG_CMD_DECRYPT) {
118              for (r = res->recipients; r; r = r->next) {              StringBuffer inf;
119                  get_pubkey (r->keyid, &key);  
120                  if (key) {              for (r = recip; r; r = r->next) {
121                      char *uid;                  memset (&key, 0, sizeof (key));
122                      id = key->uids->name;                  if (!winpt_get_pubkey (r->keyid, &key)) {
123                      if (!id)                      gpgme_user_id_t u = key.ctx->uids;
                         id = _("Invalid User ID");  
                     uid = utf8_to_wincp (id, strlen (id));  
                     info = new char [32+strlen (uid)+1 + 4 + strlen (r->keyid)+1  
                                      + strlen (key->uids->email)+1];  
                     if (!info)  
                         BUG (NULL);  
                     sprintf (info, "%s <%s> (%s, 0x%s)", uid, key->uids->email,  
                              get_key_pubalgo (r->pubkey_algo), r->keyid+8);  
                     free (uid);  
124                                            
125                        inf = (u->name? u->name : _("Invalid User ID"));
126                        if (u->email != NULL && strlen (u->email) > 1)
127                            inf = inf + " <" + u->email + ">";
128                        inf = inf + " (" + get_key_pubalgo (r->pubkey_algo);
129                        inf = inf + ", 0x" + (r->keyid+8) + ")";
130                  }                  }
131                  else {                  else {
132                      info = new char [32 + strlen (r->keyid)+1 + 4];                      inf = _("Unknown key ID");
133                      if (!info)                      inf = inf + " (" + get_key_pubalgo (r->pubkey_algo);
134                          BUG (NULL);                      inf = inf + ", 0x" + (r->keyid+8) + ")";
                     sprintf (info, _("Unknown key ID (%s, 0x%s)"),  
                              get_key_pubalgo (r->pubkey_algo), r->keyid+8);  
135                  }                  }
136                  listbox_add_string (GetDlgItem (dlg, IDC_DECRYPT_LIST), info);                  ListBox_AddString_utf8 (GetDlgItem (dlg, IDC_DECRYPT_LIST),
137                  free_if_alloc (info);                                          inf.getBuffer ());
138                    winpt_release_pubkey (&key);
139              }              }
140          }          }
141          else if (c->gpg_cmd == GPG_CMD_DECRYPT)          else if (c->gpg_cmd == GPG_CMD_DECRYPT)
# Line 137  passphrase_callback_proc (HWND dlg, UINT Line 147  passphrase_callback_proc (HWND dlg, UINT
147          if (c->gpg_cmd == GPG_CMD_DECRYPT) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
148              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_PWD));              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_PWD));
149              if (res && !res->recipients) {              if (res && !res->recipients) {
150                  const char *s = _("Symmetric encryption.\n"                  StringBuffer sinf;
151                                    "%s encrypted data.");  
152                  const char *alg = get_symkey_algo (c->sym.sym_algo);                  sinf = _("Symmetric encryption.");
153                  info = new char[strlen (s) + strlen (alg) + 2];                  sinf = sinf + "\n" + get_symkey_algo (c->sym.sym_algo);
154                  if (!info)                  sinf = sinf + " " + _("encrypted data.");
155                      BUG (NULL);                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, sinf.getBuffer ());
                 sprintf (info, s, alg);  
                 SetDlgItemText (dlg, IDC_DECRYPT_MSG, info);  
                 free_if_alloc (info);  
156              }              }
157              else              else
158                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, c->info);                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, c->info);
159          }          }
160          else {          else {
161              SetFocus( GetDlgItem (dlg, IDC_DECRYPT_SIGN_PWD));              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_SIGN_PWD));
162              SetDlgItemText (dlg, IDC_DECRYPT_SIGN_MSG, c->info);              SetDlgItemText (dlg, IDC_DECRYPT_SIGN_MSG, c->info);
163          }          }
164          center_window (dlg, NULL);          center_window (dlg, NULL);
165          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
         set_active_window (dlg);  
166          return FALSE;          return FALSE;
167    
         case WM_SYSCOMMAND:  
             if (LOWORD (wparam) == SC_CLOSE) {  
                 SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");  
                 c->cancel = 1;  
                 EndDialog (dlg, TRUE);  
             }  
             break;  
   
168          case WM_COMMAND:          case WM_COMMAND:
169              switch (HIWORD (wparam)) {              switch (HIWORD (wparam)) {
170              case BN_CLICKED:              case BN_CLICKED:
# Line 195  passphrase_callback_proc (HWND dlg, UINT Line 193  passphrase_callback_proc (HWND dlg, UINT
193                      strcpy (c->pwd, "");                      strcpy (c->pwd, "");
194                  }                  }
195                  else {                  else {
196                      c->pwd = new char[n+2];                      char *p = new char[n+2];
197                      if (!c->pwd)                      if (!p)
198                          BUG (NULL);                          BUG (NULL);
199                      GetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), c->pwd, n+1);                      /* Get the passphrase and convert it utf8.
200                           This does not just the us-ascii charset. */
201                        SafeGetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), p, n+1);
202                        c->pwd = native_to_utf8 (p);
203                        sfree_if_alloc (p);
204                  }                  }
205                  res = gpgme_op_decrypt_result (c->gpg);                  res = gpgme_op_decrypt_result (c->gpg);
206                  if (!res)                  if (!res)
207                      res_sig = gpgme_op_sign_result (c->gpg);                                  res_sig = gpgme_op_sign_result (c->gpg);
208                  if (reg_prefs.cache_time > 0 && !c->is_card &&                  if (!c->is_card && reg_prefs.cache_time > 0 &&
209                      (res || res_sig)) {                      (res || res_sig)) {
210                      if (agent_get_cache (c->keyid, &item))                                            if (agent_get_cache (c->keyid, &item))
211                          agent_unlock_cache_entry (&item);                          agent_unlock_cache_entry (&item);
212                      else                      else
213                          agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);                          agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
# Line 218  passphrase_callback_proc (HWND dlg, UINT Line 220  passphrase_callback_proc (HWND dlg, UINT
220                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");
221                  c->cancel = 1;                  c->cancel = 1;
222                  EndDialog (dlg, FALSE);                  EndDialog (dlg, FALSE);
223                  return FALSE;                  return TRUE;
224              }              }
225              break;              break;
226      }      }
# Line 257  parse_gpg_description (const char *uid_h Line 259  parse_gpg_description (const char *uid_h
259      gpgme_pubkey_algo_t algo;      gpgme_pubkey_algo_t algo;
260      char usedkey[16+1];      char usedkey[16+1];
261      char mainkey[16+1];      char mainkey[16+1];
262      char *uid, *p;      char *p, *uid;
263      int n=0;      int n=0;
264    
265      algo = (gpgme_pubkey_algo_t)0;      algo = (gpgme_pubkey_algo_t)0;
# Line 278  parse_gpg_description (const char *uid_h Line 280  parse_gpg_description (const char *uid_h
280      uid_hint += 16; /* skip keyid */      uid_hint += 16; /* skip keyid */
281      uid_hint += 1;  /* space */      uid_hint += 1;  /* space */
282    
283      uid = utf8_to_wincp (uid_hint, strlen (uid_hint));      uid = utf8_to_native (uid_hint);
   
284      if (strcmp (usedkey, mainkey))      if (strcmp (usedkey, mainkey))
285          _snprintf (desc, size-1,          _snprintf (desc, size-1,
286                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for user:\n"
287                       "user: \"%s\"\n"                       "\"%s\"\n"
288                       "%s key, ID %s (main key ID %s)\n"),                       "%s key, ID 0x%s (main key ID 0x%s)\n"),
289                     uid, get_key_pubalgo (algo), usedkey+8, mainkey+8);                     uid, get_key_pubalgo (algo), usedkey+8, mainkey+8);
290      else if (!strcmp (usedkey, mainkey))      else if (!strcmp (usedkey, mainkey))
291          _snprintf (desc, size-1,          _snprintf (desc, size-1,
292                     _("You need a passphrase to unlock the secret key for\n"                     _("You need a passphrase to unlock the secret key for user:\n"
293                       "user: \"%s\"\n"                       "\"%s\"\n"
294                       "%s key, ID %s\n"),                       "%s key, ID 0x%s\n"),
295                       uid, get_key_pubalgo (algo), usedkey+8);                       uid, get_key_pubalgo (algo), usedkey+8);
296      free (uid);      safe_free (uid);
297      return 0;      return 0;
298  }  }
299    
# Line 307  extract_serial_no (const char *id) Line 308  extract_serial_no (const char *id)
308      p = strchr (id, '/');      p = strchr (id, '/');
309      if (!p) {      if (!p) {
310          log_debug ("extract_serial_no: error '%s'\r\n", id);          log_debug ("extract_serial_no: error '%s'\r\n", id);
311          return NULL;          return "";
312      }      }
313        memset (buf, 0, sizeof (buf));
314      strncpy (buf, id+(p-id)-6, 6);      strncpy (buf, id+(p-id)-6, 6);
315      return buf;      return buf;
316  }  }
# Line 328  passphrase_cb (void *hook, const char *u Line 330  passphrase_cb (void *hook, const char *u
330      int rc = 0;      int rc = 0;
331    
332      if (!c) {      if (!c) {
333          log_debug ("passphrase_cb: error '!c'\r\n");          log_debug ("passphrase_cb: error no valid callback\r\n");
334          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
335      }      }
336      c->bad_pwd = prev_was_bad? 1 : 0;      c->bad_pwd = prev_was_bad? 1 : 0;
# Line 375  passphrase_cb (void *hook, const char *u Line 377  passphrase_cb (void *hook, const char *u
377              const char *s=passphrase_info;              const char *s=passphrase_info;
378              while (s && *s && *s != 'D')              while (s && *s && *s != 'D')
379                  s++;                  s++;
380              _snprintf (c->info, sizeof c->info-1,              _snprintf (c->info, DIM (c->info)-1,
381                         _("Please enter the PIN to unlock your secret card key\n"                         _("Please enter the PIN to unlock your secret card key\n"
382                           "Card: %s"), extract_serial_no (s));                           "Card: %s"), extract_serial_no (s));
383              c->is_card = 1;              c->is_card = 1;
384          }          }
385          else if (uid_hint)          else if (uid_hint)
386              parse_gpg_description (uid_hint, passphrase_info,              parse_gpg_description (uid_hint, passphrase_info,
387                                     c->info, sizeof c->info - 1);                                     c->info, sizeof (c->info) - 1);
388          if (c->gpg_cmd == GPG_CMD_DECRYPT) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
389              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,              rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,
390                                   (HWND)c->hwnd, passphrase_callback_proc,                                   (HWND)c->hwnd, passphrase_callback_proc,
# Line 396  passphrase_cb (void *hook, const char *u Line 398  passphrase_cb (void *hook, const char *u
398          if (rc == -1) {          if (rc == -1) {
399              if (!WriteFile (hd, "\n", 1, &n, NULL))              if (!WriteFile (hd, "\n", 1, &n, NULL))
400                  log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);                  log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
401                log_debug ("passphrase_cb: could not create dialog box\n");
402              return 0;              return 0;
403          }          }
404          c->pwd_init = 0;          c->pwd_init = 0;
405      }      }
406      if (c->cancel) {      if (c->cancel || !c->pwd) {
407          if (!WriteFile (hd, "\n", 1, &n, NULL))          if (!WriteFile (hd, "\n", 1, &n, NULL))
408              log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);              log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
409          return 0;          return 0;
# Line 430  set_gpg_passphrase_cb (passphrase_cb_s * Line 433  set_gpg_passphrase_cb (passphrase_cb_s *
433      cb->pwd_init = 1;      cb->pwd_init = 1;
434      free_if_alloc (cb->title);      free_if_alloc (cb->title);
435      cb->title = m_strdup (title);      cb->title = m_strdup (title);
     if (!cb->title)  
         BUG (NULL);  
436      gpgme_set_passphrase_cb (ctx, passphrase_cb, cb);      gpgme_set_passphrase_cb (ctx, passphrase_cb, cb);
437      cb->gpg = ctx;      cb->gpg = ctx;
438  }  }
439    
440    
441  /* Release a passphrase callback @ctx. */  /* Release the gpg recipient list. */
442  void  void
443  release_gpg_passphrase_cb (passphrase_cb_s *ctx)  release_gpg_recipients (gpgme_recipient_t *recipients)
444  {  {
445      gpgme_recipient_t r, n;      gpgme_recipient_t r, n;
446    
447      if (!ctx)      r = *recipients;
448          return;      while (r != NULL) {
     sfree_if_alloc (ctx->pwd);  
     free_if_alloc (ctx->title);  
     r = ctx->recipients;  
     while (r) {  
449          n = r->next;          n = r->next;
450          safe_free (r->keyid);          safe_free (r->keyid);
451          safe_free (r);          safe_free (r);
452          r = n;          r = n;
453      }      }
454        *recipients = NULL;
455    }
456    
457    
458    
459    /* Release a passphrase callback @ctx. */
460    void
461    release_gpg_passphrase_cb (passphrase_cb_s *ctx)
462    {
463        if (!ctx)
464            return;
465        sfree_if_alloc (ctx->pwd);
466        free_if_alloc (ctx->title);
467        release_gpg_recipients (&ctx->recipients);
468  }  }
469    
470    
471  /* Simple check to measure passphrase (@pass) quality.  /* _Simple_ check to measure passphrase (@pass) quality.
472     Return value: 0 on success. */     Return value: 0 on success. */
473  int  int
474  check_passwd_quality (const char *pass, int strict)  check_passwd_quality (const char *pass, int strict)
475  {  {
476      int i, nd=0, nc=0, n;      int i, nd=0, nc=0, n;
477    
478        /* A good passphrase should be at least 8 characters. */
479      n = strlen (pass);      n = strlen (pass);
480      if (n < 8)      if (n < 8)
481          return -1;          return -1;
482    
483      for (i=0; i < n; i++) {      for (i=0; i < n; i++) {
484          if (isdigit (pass[i]))          if (isdigit (pass[i]))
485              nd++;              nd++;
486          if (isalpha (pass[i]))          if (isalpha (pass[i]))
487              nc++;              nc++;
488      }      }
489    
490      /* check that the passphrase contains letters and numbers. */      /* Check that the passphrase contains letters and numbers. */
491      if (nd == n || nc == n)      if (nd == n || nc == n)
492          return -1;          return -1;
493    

Legend:
Removed from v.95  
changed lines
  Added in v.304

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26