/[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 24 by twoaday, Sat Oct 8 10:43:08 2005 UTC revision 33 by twoaday, Tue Oct 25 07:46:20 2005 UTC
# Line 37  Line 37 
37  #include "wptAgent.h"  #include "wptAgent.h"
38  #include "wptRegistry.h"  #include "wptRegistry.h"
39    
40    const char* get_symkey_algo (int algo);
41    
42  #define item_ctrl_id( cmd ) \  #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)
# Line 45  Line 46 
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    
49    /* Overwrite passphrase and free memory. */
50    static void
51    burn_passphrase (char **pwd)
52    {
53        char *pass = *pwd;
54        wipememory (pass, strlen (pass));
55        delete []pass;
56        *pwd = NULL;
57    }
58    
59    
60  /* Dialog procedure for the passphrase callback. */  /* Dialog procedure for the passphrase callback. */
61  static BOOL CALLBACK  static BOOL CALLBACK
62  passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  passphrase_callback_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
# Line 53  passphrase_callback_proc (HWND dlg, UINT Line 65  passphrase_callback_proc (HWND dlg, UINT
65      gpgme_decrypt_result_t res;      gpgme_decrypt_result_t res;
66      gpgme_sign_result_t res_sig;      gpgme_sign_result_t res_sig;
67      gpgme_key_t key;      gpgme_key_t key;
68        gpgme_recipient_t recip, r;
69        void *ctx = NULL, *item;
70      const char *id;      const char *id;
71      char *info;      char *info;
     void *ctx = NULL, *item;  
72      int n;      int n;
73    
74      switch (msg) {      switch (msg) {
# Line 65  passphrase_callback_proc (HWND dlg, UINT Line 78  passphrase_callback_proc (HWND dlg, UINT
78              BUG (0);              BUG (0);
79          SetWindowText (dlg, c->title);          SetWindowText (dlg, c->title);
80          if (c->gpg_cmd == GPG_CMD_DECRYPT) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
81              SetDlgItemText( dlg, IDC_DECRYPT_LISTINF,              SetDlgItemText (dlg, IDC_DECRYPT_LISTINF,
82                  _("Encrypted with the following public key(s)") );                              _("Encrypted with the following public key(s)"));
83              CheckDlgButton( dlg, IDC_DECRYPT_HIDE, BST_CHECKED );              CheckDlgButton (dlg, IDC_DECRYPT_HIDE, BST_CHECKED);
84          }          }
85          else if( c->gpg_cmd == GPG_CMD_SIGN )          else if (c->gpg_cmd == GPG_CMD_SIGN)
86              CheckDlgButton (dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED);              CheckDlgButton (dlg, IDC_DECRYPT_SIGN_HIDE, BST_CHECKED);
87          res = gpgme_op_decrypt_result (c->gpg);          if (c->recipients)
88          if (res != NULL && c->gpg_cmd == GPG_CMD_DECRYPT) {              recip = c->recipients; /* recipients were already extracted. */
89              gpgme_recipient_t r;          else {
90                /* XXX: not all ENCRYPT_TO entries are listed here. */
91                res = gpgme_op_decrypt_result (c->gpg);
92                if (res->recipients)
93                    recip = res->recipients;
94            }
95            if (recip != NULL && c->gpg_cmd == GPG_CMD_DECRYPT) {
96              for (r = res->recipients; r; r = r->next) {              for (r = res->recipients; r; r = r->next) {
97                  get_pubkey (r->keyid, &key);                  get_pubkey (r->keyid, &key);
98                  if (key) {                  if (key) {
# Line 83  passphrase_callback_proc (HWND dlg, UINT Line 101  passphrase_callback_proc (HWND dlg, UINT
101                      if (!id)                      if (!id)
102                          id = _("Invalid User ID");                          id = _("Invalid User ID");
103                      uid = utf8_to_wincp (id, strlen (id));                      uid = utf8_to_wincp (id, strlen (id));
104                      info = new char [16+strlen (uid) + 4 + strlen (r->keyid) + strlen (key->uids->email) +  3];                      info = new char [32+strlen (uid)+1 + 4 + strlen (r->keyid)+1
105                                         + strlen (key->uids->email)+1];
106                      if (!info)                      if (!info)
107                          BUG (NULL);                          BUG (NULL);
108                      sprintf (info, "%s <%s> (%s, 0x%s)", uid, key->uids->email,                      sprintf (info, "%s <%s> (%s, 0x%s)", uid, key->uids->email,
# Line 92  passphrase_callback_proc (HWND dlg, UINT Line 111  passphrase_callback_proc (HWND dlg, UINT
111                                            
112                  }                  }
113                  else {                  else {
114                      info = new char [32 + strlen (r->keyid) + 2];                      info = new char [32 + strlen (r->keyid)+1 + 4];
115                      if (!info)                      if (!info)
116                          BUG (NULL);                          BUG (NULL);
117                      sprintf (info, _("Unknown (key ID 0x%s)"),                      sprintf (info, _("Unknown key ID (%s, 0x%s)"),
118                               r->keyid? r->keyid+8 : "????????");                               get_key_pubalgo (r->pubkey_algo), r->keyid+8);
119                  }                  }
120                  listbox_add_string (GetDlgItem (dlg, IDC_DECRYPT_LIST), info);                  listbox_add_string (GetDlgItem (dlg, IDC_DECRYPT_LIST), info);
121                  free (info);                  free_if_alloc (info);
122              }              }
123          }          }
124          else if (c->gpg_cmd == GPG_CMD_DECRYPT)          else if (c->gpg_cmd == GPG_CMD_DECRYPT)
125              EnableWindow (GetDlgItem (dlg, IDC_DECRYPT_LIST), FALSE);              EnableWindow (GetDlgItem (dlg, IDC_DECRYPT_LIST), FALSE);
126          SetDlgItemText( dlg, c->gpg_cmd == GPG_CMD_DECRYPT?          SetDlgItemText (dlg, c->gpg_cmd == GPG_CMD_DECRYPT?
127                          IDC_DECRYPT_PWDINFO : IDC_DECRYPT_SIGN_PWDINFO,                          IDC_DECRYPT_PWDINFO : IDC_DECRYPT_SIGN_PWDINFO,
128                          _("Please enter your passphrase") );                          c->bad_pwd? _("Bad passphrase; Enter passphrase again") :
129                            _("Please enter your passphrase"));
130          if (c->gpg_cmd == GPG_CMD_DECRYPT) {          if (c->gpg_cmd == GPG_CMD_DECRYPT) {
131              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_PWD));              SetFocus (GetDlgItem (dlg, IDC_DECRYPT_PWD));
132              if (res && !res->recipients)              if (res && !res->recipients) {
133                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, _("Symmetric encryption.\n"));                                                                      const char *s = _("Symmetric encryption.\n"
134                                      "%s encrypted data.");
135                    const char *alg = get_symkey_algo (c->sym.sym_algo);
136                    info = new char[strlen (s) + strlen (alg) + 2];
137                    if (!info)
138                        BUG (NULL);
139                    sprintf (info, s, alg);
140                    SetDlgItemText (dlg, IDC_DECRYPT_MSG, info);
141                    free_if_alloc (info);
142                }
143              else              else
144                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, c->info);                  SetDlgItemText (dlg, IDC_DECRYPT_MSG, c->info);
145          }          }
# Line 124  passphrase_callback_proc (HWND dlg, UINT Line 153  passphrase_callback_proc (HWND dlg, UINT
153          return FALSE;          return FALSE;
154    
155          case WM_SYSCOMMAND:          case WM_SYSCOMMAND:
156              if( LOWORD( wparam ) == SC_CLOSE ) {              if (LOWORD (wparam) == SC_CLOSE) {
157                  SetDlgItemText( dlg, item_ctrl_id( c->gpg_cmd ), "" );                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");
158                  c->cancel = 1;                  c->cancel = 1;
159                  EndDialog( dlg, TRUE );                  EndDialog (dlg, TRUE);
160              }              }
161              break;              break;
162    
163          case WM_COMMAND:          case WM_COMMAND:
164              switch( HIWORD( wparam ) ) {              switch (HIWORD (wparam)) {
165              case BN_CLICKED:              case BN_CLICKED:
166                  if ( LOWORD( wparam ) == IDC_DECRYPT_HIDE                  if  (LOWORD (wparam) == IDC_DECRYPT_HIDE
167                      || LOWORD( wparam ) == IDC_DECRYPT_SIGN_HIDE ) {                      || LOWORD (wparam) == IDC_DECRYPT_SIGN_HIDE) {
168                      HWND hwnd;                      HWND hwnd;
169                      int hide = IsDlgButtonChecked (dlg, item_ctrl_id2 (c->gpg_cmd));                      int hide = IsDlgButtonChecked (dlg, item_ctrl_id2 (c->gpg_cmd));
170                      hwnd = GetDlgItem (dlg, item_ctrl_id (c->gpg_cmd));                      hwnd = GetDlgItem (dlg, item_ctrl_id (c->gpg_cmd));
171                      SendMessage( hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0 );                      SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
172                      SetFocus (hwnd);                      SetFocus (hwnd);
173                  }                  }
174              }              }
175    
176              switch (LOWORD (wparam)) {              switch (LOWORD (wparam)) {
177              case IDOK:                case IDOK:  
178                  /* fixme: the item is even cached when the passphrase is not                  /* XXX: the item is even cached when the passphrase is not
179                            correct, which means that the user needs to delete all                          correct, which means that the user needs to delete all
180                            cached entries to continue. */                          cached entries to continue. */
181                  if (c->pwd) {                  if (c->pwd)
182                      delete []c->pwd;                      burn_passphrase (&c->pwd);
                     c->pwd = NULL;  
                 }  
183                  n = item_get_text_length (dlg, item_ctrl_id (c->gpg_cmd));                  n = item_get_text_length (dlg, item_ctrl_id (c->gpg_cmd));
184                  if (!n) {                  if (!n) {
185                      c->pwd = new char[2];                      c->pwd = new char[2];
186                        if (!c->pwd)
187                            BUG (NULL);
188                      strcpy (c->pwd, "");                      strcpy (c->pwd, "");
189                  }                  }
190                  else {                  else {
# Line 174  passphrase_callback_proc (HWND dlg, UINT Line 203  passphrase_callback_proc (HWND dlg, UINT
203                      else                      else
204                          agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);                          agent_put_cache (c->keyid, c->pwd, reg_prefs.cache_time);
205                  }                  }
206                    c->cancel = 0;
207                  EndDialog (dlg, TRUE);                  EndDialog (dlg, TRUE);
208                  return TRUE;                  return TRUE;
209                                    
210              case IDCANCEL:              case IDCANCEL:
211                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "" );                  SetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), "");
212                  c->cancel = 1;                  c->cancel = 1;
213                  EndDialog (dlg, FALSE);                  EndDialog (dlg, FALSE);
214                  return FALSE;                  return FALSE;
# Line 197  parse_gpg_keyid (const char *pass_info) Line 227  parse_gpg_keyid (const char *pass_info)
227  {  {
228      static char keyid[16+1];      static char keyid[16+1];
229            
230        /* XXX: check for leading alpha-chars? */
231      if (strlen (pass_info) < 16)      if (strlen (pass_info) < 16)
232          return NULL;          return NULL;
233      /* the format of the desc buffer looks like this:      /* the format of the desc buffer looks like this:
# Line 210  parse_gpg_keyid (const char *pass_info) Line 241  parse_gpg_keyid (const char *pass_info)
241    
242  /* Parse the information in @uid_hint and @pass_info to generate  /* Parse the information in @uid_hint and @pass_info to generate
243     a input message for the user in @desc. */     a input message for the user in @desc. */
244  static void  static int
245  parse_gpg_description (const char *uid_hint, const char *pass_info,  parse_gpg_description (const char *uid_hint, const char *pass_info,
246                         char *desc, int size)                         char *desc, int size)
247  {  {
248      gpgme_pubkey_algo_t algo;      gpgme_pubkey_algo_t algo;
249      char usedkey[16+1], mainkey[16+1];      char usedkey[16+1];
250        char mainkey[16+1];
251      char *uid, *p;      char *uid, *p;
252      int n=0;      int n=0;
253    
254        /* Each uid_hint contains a long key-ID so it is at least 16 bytes. */
255        if (strlen (uid_hint) < 17) {
256            *desc = 0;
257            return -1;
258        }
259    
260      while (p = strsep ((char**)&pass_info, " ")) {      while (p = strsep ((char**)&pass_info, " ")) {
261          switch (n++) {          switch (n++) {
262          case 0: strncpy (mainkey, p, 16); mainkey[16] = 0; break;          case 0: strncpy (mainkey, p, 16); mainkey[16] = 0; break;
# Line 244  parse_gpg_description (const char *uid_h Line 282  parse_gpg_description (const char *uid_h
282                       "%s key, ID %s\n"),                       "%s key, ID %s\n"),
283                       uid, get_key_pubalgo (algo), usedkey+8);                       uid, get_key_pubalgo (algo), usedkey+8);
284      free (uid);      free (uid);
285        return 0;
286  }  }
287    
288    
289  static int inline  /* Extract the serial number from the card ID @id and return it. */
290  is_hexstring (const char * p)  const char*
291    extract_serial_no (const char *id)
292  {  {
293      size_t i;      static char buf[8];
294        char *p;
295    
296      for (i=0; i < strlen (p); i++) {      p = strchr (id, '/');
297          if (!isxdigit (p[i]))      if (!p)
298              return -1;          return NULL;
299      }      strncpy (buf, id+(p-id)-6, 6);
300      return 0;      return buf;
301  }  }
302    
303    
# Line 273  passphrase_cb (void *hook, const char *u Line 314  passphrase_cb (void *hook, const char *u
314      DWORD n;      DWORD n;
315      int rc;      int rc;
316    
     /* XXX: pubkey_enc cancel does not quit gpg.exe */  
     /* XXX: handle prev_was_bad case. */  
317      if (!c)      if (!c)
318          return gpg_error (GPG_ERR_INV_ARG);          return gpg_error (GPG_ERR_INV_ARG);
319        c->bad_pwd = prev_was_bad? 1 : 0;
320        if (prev_was_bad && !c->cancel) {
321            if (c->pwd)
322                burn_passphrase (&c->pwd);
323            agent_del_cache (c->keyid);
324            c->pwd_init = 1;
325        }
326    
327      if (passphrase_info) {      if (passphrase_info) {
328            if (strlen (passphrase_info) < 16 &&
329                !strstr (passphrase_info, "OPENPGP")) {
330                /* assume symetric encryption. */
331                int n=2;
332                c->sym.sym_algo = atoi (passphrase_info);
333                if (c->sym.sym_algo > 9)
334                    n++;
335                /* XXX: be more strict. */
336                c->sym.s2k_mode = atoi (passphrase_info+n);
337                c->sym.s2k_hash = atoi (passphrase_info+n+2);
338            }
339    
340          keyid = parse_gpg_keyid (passphrase_info);          keyid = parse_gpg_keyid (passphrase_info);
341          pass = agent_get_cache (keyid+8, &item);          pass = agent_get_cache (keyid+8, &item);
342          if (pass) {          if (pass) {
# Line 296  passphrase_cb (void *hook, const char *u Line 354  passphrase_cb (void *hook, const char *u
354          if (keyid && strlen (keyid) == 16)          if (keyid && strlen (keyid) == 16)
355              strcpy (c->keyid, keyid+8);              strcpy (c->keyid, keyid+8);
356    
357          /* if the desc has a length of 32 and only hex digits, we assume a          /* if @passphrase_info contains 'OPENPGP' we assume a smart card
358             smart card has been used. */              has been used. */
359          if (uid_hint && strlen (uid_hint) == 32 && !is_hexstring (uid_hint)) {          if (strstr (passphrase_info, "OPENPGP")) {
360              char buf[16];              const char *s=passphrase_info;
361              memset (buf, 0, sizeof buf);              while (s && *s && *s != 'D')
362              strncpy (buf, uid_hint+20, 8);                  s++;
363              _snprintf (c->info, sizeof c->info-1,              _snprintf (c->info, sizeof c->info-1,
364                         _("Please enter the PIN to unlock your secret card key\n"                         _("Please enter the PIN to unlock your secret card key\n"
365                           "Card: %s"), buf);                           "Card: %s"), extract_serial_no (s));
366              c->is_card = 1;              c->is_card = 1;
367          }          }
368          else if (uid_hint)          else if (uid_hint)
# Line 321  passphrase_cb (void *hook, const char *u Line 379  passphrase_cb (void *hook, const char *u
379                                   (LPARAM)c);                                   (LPARAM)c);
380          }          }
381          if (rc == -1) {          if (rc == -1) {
382              WriteFile (hd, "\n", 1, &n, NULL);              if (!WriteFile (hd, "\n", 1, &n, NULL))
383              return gpg_error (GPG_ERR_EOF);                  log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
384                return 0;
385          }          }
386          c->pwd_init = 0;          c->pwd_init = 0;
387      }      }
388      if (c->cancel) {      if (c->cancel) {
389          WriteFile (hd, "\n", 1, &n, NULL);          if (!WriteFile (hd, "\n", 1, &n, NULL))
390          return gpg_error (GPG_ERR_EOF);              log_debug ("passphrase_cb: WriteFile() failed ec=%d\n", w32_errno);
391            return 0;
392      }      }
393    
394      WriteFile (hd, c->pwd, strlen (c->pwd), &n, NULL);      WriteFile (hd, c->pwd, strlen (c->pwd), &n, NULL);
# Line 346  set_gpg_passphrase_cb (passphrase_cb_s * Line 406  set_gpg_passphrase_cb (passphrase_cb_s *
406  {  {
407      memset (cb, 0, sizeof *cb);      memset (cb, 0, sizeof *cb);
408      cb->gpg_cmd = cmd;      cb->gpg_cmd = cmd;
409        cb->bad_pwd = 0;
410      cb->is_card = 0;      cb->is_card = 0;
411      cb->cancel = 0;      cb->cancel = 0;
412      cb->hwnd = hwnd;      cb->hwnd = hwnd;
# Line 363  set_gpg_passphrase_cb (passphrase_cb_s * Line 424  set_gpg_passphrase_cb (passphrase_cb_s *
424  void  void
425  release_gpg_passphrase_cb (passphrase_cb_s *ctx)  release_gpg_passphrase_cb (passphrase_cb_s *ctx)
426  {  {
427        gpgme_recipient_t r, n;
428    
429      if (!ctx)      if (!ctx)
430          return;          return;
431      sfree_if_alloc (ctx->pwd);      sfree_if_alloc (ctx->pwd);
432      free_if_alloc (ctx->title);      free_if_alloc (ctx->title);
433        r = ctx->recipients;
434        while (r) {
435            n = r->next;
436            safe_free (r->keyid);
437            safe_free (r);
438            r = n;
439        }
440  }  }
441    
442    
443  /* Simple check to measure passphrase (@pass) quality.  /* Simple check to measure passphrase (@pass) quality.
444     Return value: 0 on success. */     Return value: 0 on success. */
445  int  int
# Line 381  check_passwd_quality (const char *pass, Line 452  check_passwd_quality (const char *pass,
452          return -1;          return -1;
453    
454      for (i=0; i < n; i++) {      for (i=0; i < n; i++) {
455          if (isdigit (pass[i])) nd++;          if (isdigit (pass[i]))
456          if (isalpha (pass[i])) nc++;              nd++;
457            if (isalpha (pass[i]))
458                nc++;
459      }      }
460    
461        /* check that the passphrase contains letters and numbers. */
462      if (nd == n || nc == n)      if (nd == n || nc == n)
463          return -1;          return -1;
464    

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26