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

Diff of /trunk/Src/wptKeyEditDlgs.cpp

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

revision 187 by twoaday, Wed Mar 22 11:04:20 2006 UTC revision 236 by twoaday, Wed Jun 28 06:59:30 2006 UTC
# Line 24  Line 24 
24  #include <windows.h>  #include <windows.h>
25  #include <commctrl.h>  #include <commctrl.h>
26  #include <time.h>  #include <time.h>
27  #include "resource.h"  #include <assert.h>
28    
29    #include "resource.h"
30  #include "wptTypes.h"  #include "wptTypes.h"
31  #include "wptW32API.h"  #include "wptW32API.h"
32  #include "wptVersion.h"  #include "wptVersion.h"
# Line 51  enum keyedit_commands { Line 52  enum keyedit_commands {
52      CMD_DELKEY,      CMD_DELKEY,
53      CMD_EXPIRE,      CMD_EXPIRE,
54      CMD_SHOWPREF,      CMD_SHOWPREF,
55      //CMD_SETPREF,      CMD_SETPREF,
56      CMD_PASSWD,      CMD_PASSWD,
57      CMD_PRIMARY,      CMD_PRIMARY,
58      CMD_TRUST,      CMD_TRUST,
# Line 61  enum keyedit_commands { Line 62  enum keyedit_commands {
62      CMD_ENABLE,          CMD_ENABLE,    
63      CMD_SIGN,      CMD_SIGN,
64      CMD_LSIGN,      CMD_LSIGN,
65      CMD_CHECK      CMD_CHECK,
66        CMD_CLEAN,
67        CMD_MINIMIZE
68  };  };
69    
70  struct cmdlist_s {  struct cmdlist_s {
# Line 77  struct cmdlist_s { Line 80  struct cmdlist_s {
80      {"DELKEY", 1, CMD_DELKEY},      {"DELKEY", 1, CMD_DELKEY},
81      {"EXPIRE", 1, CMD_EXPIRE},      {"EXPIRE", 1, CMD_EXPIRE},
82      {"SHOWPREF", 0, CMD_SHOWPREF},      {"SHOWPREF", 0, CMD_SHOWPREF},
83      /*{"SETPREF", 1, CMD_SETPREF},*/      {"SETPREF", 1, CMD_SETPREF},
84      {"PASSWD", 1, CMD_PASSWD},      {"PASSWD", 1, CMD_PASSWD},
85      {"PRIMARY", 1, CMD_PRIMARY},      {"PRIMARY", 1, CMD_PRIMARY},
86      {"TRUST", 0, CMD_TRUST},      {"TRUST", 0, CMD_TRUST},
# Line 88  struct cmdlist_s { Line 91  struct cmdlist_s {
91      {"SIGN", 0, CMD_SIGN},      {"SIGN", 0, CMD_SIGN},
92      {"LSIGN", 0, CMD_LSIGN},      {"LSIGN", 0, CMD_LSIGN},
93      {"CHECK", 0, CMD_CHECK},      {"CHECK", 0, CMD_CHECK},
94        {"CLEAN", 0, CMD_CLEAN},
95        {"MINIMIZE", 0, CMD_MINIMIZE},
96      {NULL, 0}        {NULL, 0}  
97  };  };
98    
# Line 115  enum uid_col_t { Line 120  enum uid_col_t {
120    
121  /* Key edit callback context. */  /* Key edit callback context. */
122  struct keyedit_cb_s {  struct keyedit_cb_s {
123      const char     *keyid;      HWND            parent; /* parent window handle. */
124      const char     *pass;      const char     *keyid;  /* key ID of the key. */
125        const char     *pass;   /* pointer to the passphrase. */
126      listview_ctrl_t lv;      listview_ctrl_t lv;
127        int             lv_pos;
128      void           *opaque;      void           *opaque;
129      unsigned int    finished:1;      unsigned int    finished:1;
130      unsigned int    is_protected:1;      unsigned int    is_protected:1;
# Line 127  typedef struct keyedit_cb_s *keyedit_cb_ Line 134  typedef struct keyedit_cb_s *keyedit_cb_
134    
135  /* Key generation callback context. */  /* Key generation callback context. */
136  struct keygen_cb_s {  struct keygen_cb_s {
137      int   bits;      int    bits;
138      int   algo;      int    algo;
139      u32   expire;      DWORD  expire;
140      char *fpr;      char  *fpr;
141        char  *name;
142        char  *comment;
143        char  *email;
144  };  };
145  typedef struct keygen_cb_s *keygen_cb_t;  typedef struct keygen_cb_s *keygen_cb_t;
146    
147    /* Subclass context for the subkey list. */
148  static subclass_s keyedit_subkey_proc;  static subclass_s keyedit_subkey_proc;
149    
150    /* Subclass context for the user-id list. */
151  static subclass_s keyedit_uid_proc;  static subclass_s keyedit_uid_proc;
152    
153  int keygen_check_date (SYSTEMTIME *st);  int keygen_check_date (SYSTEMTIME *st);
154  void get_userid_preflist (char **r_prefs, int * r_flags);  void get_userid_preflist (const char *old_prefs, char **r_prefs, int *r_flags);
155  char* get_subkey_keyid (const char *keyid);  char* get_subkey_keyid (const char *keyid);
156    void ComboBox_AddString_utf8 (HWND cb, const char *txt);
157    
158    
159    /* Safe wrapper for allocation. */
160    static GpgKeyEdit*
161    create_GpgKeyEdit (const char *keyid)
162    {
163        GpgKeyEdit *ke;
164    
165        ke = new GpgKeyEdit (keyid);
166        if (!ke)
167            BUG (NULL);
168        return ke;
169    }
170    
171    
172  /* Associate each key with a combo box entry.  /* Associate each key with a combo box entry.
173     Skip the key in @k. */     Skip the key in @k. */
174  static void  static void
175  do_init_keylist (HWND dlg, winpt_key_t k)  do_init_keylist (HWND dlg, const char *keyid)
176  {  {
177      gpg_keycache_t pub;      gpg_keycache_t pub;
178      gpgme_key_t key;      gpgme_key_t key;
179      const char *s, *kid;      const char *s, *kid;
     char *u;  
180      int i, n;      int i, n;
181    
182      pub = keycache_get_ctx (1);      pub = keycache_get_ctx (1);
     if (!pub)  
         BUG (0);  
   
183      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
184      while( !gpg_keycache_next_key (pub, 0, &key)) {      while (!gpg_keycache_next_key (pub, 0, &key)) {
185          if (key->expired || key->revoked ||          if (key->expired || key->revoked ||
186              key->disabled || key->invalid)              key->disabled || key->invalid)
187              continue;              continue;
188          s = key->uids->uid;          s = key->uids->uid;
189          kid = key->subkeys->keyid;          kid = key->subkeys->keyid;
190          if (!s || !strcmp (kid+8, k->keyid))          if (!s || !strcmp (kid+8, keyid))
191              continue;              continue;
192          u = utf8_to_native (s);          ComboBox_AddString_utf8 (GetDlgItem (dlg, IDC_ADDREV_KEYLIST), s);
         SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_ADDSTRING,  
                             0, (WPARAM)(char *)u);  
         free (u);  
193      }      }
194      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
195      n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );      n = SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0);
196      for (i = 0; i < n; i++) {      for (i = 0; i < n; i++) {
197          gpg_keycache_next_key (pub, 0, &key);          gpg_keycache_next_key (pub, 0, &key);
198          SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,          SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
# Line 186  do_init_keylist (HWND dlg, winpt_key_t k Line 205  do_init_keylist (HWND dlg, winpt_key_t k
205  /* Add a new user-id to the list view @lv. */  /* Add a new user-id to the list view @lv. */
206  static void  static void
207  do_add_new_userid (listview_ctrl_t lv,  do_add_new_userid (listview_ctrl_t lv,
208                     const char *utf8_name, const char *email, const char *comment)                     const char *utf8_name, const char *email,
209                       const char *utf8_comment)
210  {  {
211      char *p, *uid;      char *p, *native;
212      size_t n;      size_t n;
213            
214      n = strlen (utf8_name) + strlen (email) + 16;      n = strlen (utf8_name) + strlen (email) + 16;
215      if (comment)      if (utf8_comment)
216          n += strlen (comment);          n += strlen (utf8_comment);
     uid = utf8_to_native (utf8_name);  
217      p = new char[n+1];      p = new char[n+1];
218      if (!p)      if (!p)
219          BUG (NULL);          BUG (NULL);
220      if (comment)      if (utf8_comment)
221          sprintf (p, "%s (%s)", uid, comment);          sprintf (p, "%s (%s)", utf8_name, utf8_comment);
222      else      else
223          sprintf (p, "%s", uid);          sprintf (p, "%s", utf8_name);
224      free (uid);      native = utf8_to_native (p);
225        free_if_alloc (p);
226    
227      listview_add_item (lv, "");      listview_add_item (lv, "");
228      listview_add_sub_item (lv, 0, 0, _("Ultimate" ));      listview_add_sub_item (lv, 0, UID_COL_VALID, _("Ultimate" ));
229      listview_add_sub_item (lv, 0, 1, p);      listview_add_sub_item (lv, 0, UID_COL_NAME, native);
230      listview_add_sub_item (lv, 0, 2, email && *email? email : "");      listview_add_sub_item (lv, 0, UID_COL_EMAIL, email && *email? email : "");
231      listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));      listview_add_sub_item (lv, 0, UID_COL_CREATION, get_key_created (time (NULL)));
232      free_if_alloc (p);      free_if_alloc (native);
233  }  }
234    
235    
# Line 217  static void Line 237  static void
237  do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)  do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)
238  {  {
239      char info[128], keyid[32];      char info[128], keyid[32];
240      const char * expdate, * s;      const char *expdate, *s, *kid;
241      int n;      int n;
242            
243      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
244      _snprintf (info, sizeof info-1, "%d-bit %s",      _snprintf (info, sizeof (info)-1, "%d-bit %s",
245                 keygen->bits,                 keygen->bits,
246                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
247      _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+8);      kid = get_keyid_from_fpr (keygen->fpr);
248        _snprintf (keyid, sizeof (keyid)-1, "0x%s", kid);
249        s = get_key_created (time (NULL));
250      n = listview_count_items (lv, 0);      n = listview_count_items (lv, 0);
251      listview_add_item_pos (lv, n);      listview_add_item_pos (lv, n);
252      listview_add_sub_item (lv, n, 0, info);      listview_add_sub_item (lv, n, SUBK_COL_DESC, info);
253      listview_add_sub_item (lv, n, 1, keyid);      listview_add_sub_item (lv, n, SUBK_COL_KEYID, keyid);
254      listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));      listview_add_sub_item (lv, n, SUBK_COL_CREATION, s);
255      listview_add_sub_item (lv, n, 3, expdate);      listview_add_sub_item (lv, n, SUBK_COL_EXPIRES, expdate);
256      if (flags & KM_FLAG_REVOKED)      if (flags & KM_FLAG_REVOKED)
257          s = _("Revoked");                s = _("Revoked");      
258      else if (flags & KM_FLAG_EXPIRED)      else if (flags & KM_FLAG_EXPIRED)
259          s = _("Expired");          s = _("Expired");
260      else      else
261          s = _("OK");          s = _("OK");
262      listview_add_sub_item (lv, n, 4, s);      listview_add_sub_item (lv, n, SUBK_COL_STATUS, s);
263  }  }
264    
265    
# Line 252  do_find_userid (const char *keyid, const Line 274  do_find_userid (const char *keyid, const
274      GpgKeyEdit *ke;      GpgKeyEdit *ke;
275      gpgme_error_t err;      gpgme_error_t err;
276      gpg_uid_info_t inf, ui;      gpg_uid_info_t inf, ui;
     char *ui_name = NULL;  
277      int pos = -1;      int pos = -1;
278    
279      ke = new GpgKeyEdit (keyid);      ke = create_GpgKeyEdit (keyid);
     if (!ke)  
         BUG (NULL);  
280      err = ke->getUseridInfo (&inf);      err = ke->getUseridInfo (&inf);
281      delete ke;      delete ke;
282      if (err) {      if (err) {
283          log_box (_("user ID"), MB_ERR,          log_box (_("user ID"), MB_ERR,
284                  _("Could not get key information for: \"%s\":\n%s"),                   _("Could not get key information for: \"%s\":\n%s"),
285                  name, gpgme_strerror (err));                   name, gpgme_strerror (err));
286          return -1;          return -1;
287      }      }
288    
289      for (ui = inf; ui; ui = ui->next) {      for (ui = inf; ui; ui = ui->next) {
290          safe_free (ui_name);          if (name && email && ui->email && ui->name) {
         ui_name = utf8_to_native (ui->name);  
         if (name && email && ui->email && ui_name) {  
291              if (!strcmp (ui->email, email) &&              if (!strcmp (ui->email, email) &&
292                  !strncmp (ui_name, name, strlen (name))) {                  !strncmp (ui->name, name, strlen (name))) {
293                  pos = ui->index;                  pos = ui->index;
294                  break;                  break;
295              }              }
296              continue;              continue;
297          }          }
298          if (ui->email) {          if (email && ui->email) {
299              if (!strcmp (ui->email, email)) {              if (!strcmp (ui->email, email)) {
300                  pos = ui->index;                  pos = ui->index;
301                  break;                  break;
# Line 287  do_find_userid (const char *keyid, const Line 304  do_find_userid (const char *keyid, const
304                 as the fallbck when no email address is available. */                 as the fallbck when no email address is available. */
305              continue;              continue;
306          }          }
307          if (ui_name && name && !strcmp (ui_name, name)) {          if (ui->name && name && !strcmp (ui->name, name)) {
308              pos = ui->index;              pos = ui->index;
309              break;              break;
310          }          }
# Line 296  do_find_userid (const char *keyid, const Line 313  do_find_userid (const char *keyid, const
313          *r_inf = inf;          *r_inf = inf;
314      else      else
315          gpg_uid_info_release (inf);          gpg_uid_info_release (inf);
     safe_free (ui_name);  
316      return pos;      return pos;
317  }  }
318    
# Line 325  is_jpg_file (const char *fname) Line 341  is_jpg_file (const char *fname)
341  BOOL CALLBACK  BOOL CALLBACK
342  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
343  {  {
344      static winpt_key_t k;              static keyedit_cb_t cb;
345      GpgKeyEdit *ke;      GpgKeyEdit *ke;
346      gpgme_error_t ec;          gpgme_error_t err;
347      const char * s;          const char *s;    
348      char pwd[128], file[128];      char file[128];
349      int id;      int id;
350    
351      switch( msg ) {      switch( msg ) {
352      case WM_INITDIALOG:      case WM_INITDIALOG:
353          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
354          if (!k)          if (!cb)
355              BUG (NULL);              BUG (NULL);
356          SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key.  If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));          SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key.  If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));
357          SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));          SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
# Line 345  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 361  keyedit_addphoto_dlg_proc (HWND dlg, UIN
361          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
362          break;          break;
363    
     case WM_DESTROY:  
         break;  
   
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE)  
             EndDialog (dlg, TRUE);  
         break;  
   
364      case WM_COMMAND:      case WM_COMMAND:
365          switch( LOWORD( wparam ) ) {          switch( LOWORD (wparam)) {
   
366          case IDC_ADDPHOTO_SELFILE:          case IDC_ADDPHOTO_SELFILE:
367              s = get_fileopen_dlg (dlg, _("Select Image File"),              s = get_fileopen_dlg (dlg, _("Select Image File"),
368                                    "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",                                    "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",
# Line 371  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 378  keyedit_addphoto_dlg_proc (HWND dlg, UIN
378    
379          case IDOK:          case IDOK:
380              if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){              if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
381                  msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);                  msg_box (dlg, _("Please enter a file name."),
382                             _("Add Photo"), MB_ERR);
383                  return FALSE;                  return FALSE;
384              }              }
385              if (get_file_size (file) == 0 || get_file_size (file) > 6144 ) {              if (get_file_size (file) == 0 || get_file_size (file) > 6144) {
386                  id = msg_box (dlg, _("The JPEG is really large.\n"                  id = msg_box (dlg, _("The JPEG is really large.\n"
387                                       "Are you sure you want to use it?"),                                       "Are you sure you want to use it?"),
388                                       _("Add Photo"), MB_YESNO|MB_INFO);                                       _("Add Photo"), MB_YESNO|MB_INFO);
389                  if (id == IDNO)                  if (id == IDNO)
390                      return TRUE;                      return TRUE;
391              }              }
392              if (k->is_protected &&              ke = create_GpgKeyEdit (cb->keyid);
393                  !GetDlgItemText (dlg, IDC_ADDPHOTO_PASS, pwd, sizeof (pwd)-1)) {              if (cb->pass)
394                  msg_box (dlg, _("Please enter a passphrase."), _("Add Photo"), MB_ERR);                  ke->setPassphrase (cb->pass);
                 return FALSE;  
             }  
             ke = new GpgKeyEdit (k->keyid);  
             if (!ke)  
                 BUG (NULL);  
             if (k->is_protected)  
                 ke->setPassphrase (pwd);  
395              else              else
396                  ke->setNoPassphrase (true);                  ke->setNoPassphrase (true);
397              ec = ke->addPhotoid (file);              err = ke->addPhotoid (file);
398              delete ke;              delete ke;
399              wipememory (pwd, sizeof (pwd));              if (err) {
400              if (ec) {                  msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
                 msg_box (dlg, gpgme_strerror (ec), _("Add Photo"), MB_ERR );  
401                  return FALSE;                  return FALSE;
402              }              }
403              else {              else {
404                  k->update = 1;                  cb->finished = 1;
405                  msg_box (dlg, _("Photo successfully added."),                  msg_box (dlg, _("Photo successfully added."),
406                           _("GnuPG Status"), MB_OK);                           _("GnuPG Status"), MB_OK);
407              }              }
# Line 422  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 422  keyedit_addphoto_dlg_proc (HWND dlg, UIN
422  BOOL CALLBACK  BOOL CALLBACK
423  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
424  {  {
425      static winpt_key_t k;      static keyedit_cb_t cb;
     static gpgme_key_t seckey;  
426      gpgme_error_t err;      gpgme_error_t err;
427      GpgKeyEdit *ke;      GpgKeyEdit *ke;
428      char uid[128], pwd[128];      char *uid=NULL;
429    
430      switch (msg) {      switch (msg) {
431      case WM_INITDIALOG:      case WM_INITDIALOG:
432          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
433          if (!k)          if (!cb)
             BUG (NULL);  
         if (get_seckey (k->keyid, &seckey))  
434              BUG (NULL);              BUG (NULL);
435          if (!k->is_protected)          do_init_keylist (dlg, cb->keyid);
             EnableWindow (GetDlgItem (dlg, IDC_ADDREV_PASS), FALSE);  
         do_init_keylist (dlg, k);  
436          SetDlgItemText (dlg, IDC_ADDREV_INF,          SetDlgItemText (dlg, IDC_ADDREV_INF,
437                          _("Appointing a key as designated revoker cannot be undone."));                          _("Appointing a key as designated revoker cannot be undone."));
438          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
# Line 445  keyedit_addrevoker_dlg_proc (HWND dlg, U Line 440  keyedit_addrevoker_dlg_proc (HWND dlg, U
440          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
441          SetWindowText (dlg, _("Add Revoker"));          SetWindowText (dlg, _("Add Revoker"));
442          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
443          break;          center_window (dlg, cb->parent);
   
     case WM_DESTROY:      
         break;  
   
     case WM_SYSCOMMAND:  
         if( LOWORD (wparam) == SC_CLOSE )  
             EndDialog( dlg, TRUE );  
444          break;          break;
445    
446      case WM_COMMAND:      case WM_COMMAND:
447          switch( LOWORD( wparam ) ) {          switch (LOWORD (wparam)) {
448          case IDOK:                    case IDOK:
449              if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {              if (!GetDlgItemText_utf8 (dlg, IDC_ADDREV_KEYLIST, &uid)) {
450                  msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );                  msg_box (dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR);
451                  return FALSE;                  return FALSE;
452              }              }
453                    
454              if( k->is_protected ) {              ke = create_GpgKeyEdit (cb->keyid);
455                  if( !GetDlgItemText( dlg, IDC_ADDREV_PASS, pwd, sizeof pwd-1 ) ) {              if (cb->pass)
456                      msg_box( dlg, _("Please enter the passphrase."), _("Add Revoker"), MB_ERR );                  ke->setPassphrase (cb->pass);
                     return FALSE;  
                 }  
             }  
             ke = new GpgKeyEdit (k->keyid);  
             if (k->is_protected)  
                 ke->setPassphrase (pwd);  
457              else              else
458                  ke->setNoPassphrase (true);                  ke->setNoPassphrase (true);
459              err = ke->addDesignatedRevoker (uid);              err = ke->addDesignatedRevoker (uid);
460              delete ke;              delete ke;
461              wipememory (pwd, sizeof (pwd));              safe_free (uid);
462              if (err) {              if (err) {
463                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
464                  return TRUE;                  return TRUE;
465              }              }
466              else {              else {
467                  k->update = 1;                  cb->finished = 1;
468                  msg_box (dlg, _("Revoker successfully addded."),                  msg_box (dlg, _("Revoker successfully addded."),
469                           _("GnuPG Status"), MB_OK);                           _("GnuPG Status"), MB_OK);
470              }              }
# Line 504  BOOL CALLBACK Line 486  BOOL CALLBACK
486  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
487  {  {
488      static keyedit_cb_t ctx;      static keyedit_cb_t ctx;
489        keygen_cb_t keygen;
490      gpgme_error_t err;      gpgme_error_t err;
491      GpgKeyEdit *ke;      GpgKeyEdit *ke;
492      char *utf8_name = NULL;      char *utf8_name = NULL;
493      char name[128], email[128], comment[128];      char *utf8_comment = NULL;
494        char email[128];
495      int rc;      int rc;
496            
497      switch (msg) {      switch (msg) {
498      case WM_INITDIALOG:      case WM_INITDIALOG:
499          ctx = (keyedit_cb_t)lparam;          ctx = (keyedit_cb_t)lparam;
500          if( !ctx )          if (!ctx)
501              dlg_fatal_error(dlg, "Could not get dialog param!");              dlg_fatal_error(dlg, "Could not get dialog param!");
502          SetWindowText (dlg, _("Add new User ID"));          SetWindowText (dlg, _("Add new User ID"));
503          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
# Line 521  keyedit_adduid_dlg_proc (HWND dlg, UINT Line 505  keyedit_adduid_dlg_proc (HWND dlg, UINT
505          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
506          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
507          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
508          return FALSE;          center_window (dlg, ctx->parent);
           
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE)  
             EndDialog(dlg, TRUE);  
509          return FALSE;          return FALSE;
510                    
511      case WM_COMMAND:      case WM_COMMAND:
512          switch ( LOWORD( wparam ) )  {          switch ( LOWORD( wparam ) )  {
513          case IDOK:          case IDOK:
514              rc = GetDlgItemText( dlg, IDC_ADDUID_NAME, name, sizeof name-1 );              keygen = (keygen_cb_t)ctx->opaque;
515                rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_NAME, &utf8_name);
516              if (!rc || rc < 5) {              if (!rc || rc < 5) {
517                  msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );                  msg_box (dlg, _("Please enter a name (min. 5 chars.)"),
518                             _("UserID"), MB_ERR);
519                    free_if_alloc (utf8_name);
520                  return FALSE;                  return FALSE;
521              }              }
522              if (strchr (name, '@')) {              if (strchr (utf8_name, '@')) {
523                  msg_box( dlg, _("Please enter the email address in the email field and not in the name field"), _("UserID"), MB_INFO );                  msg_box (dlg, _("Please enter the email address in the email field and not in the name field"),
524                             _("UserID"), MB_INFO);
525                    free_if_alloc (utf8_name);
526                  return FALSE;                  return FALSE;
527              }              }
528                                      
529              if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {              if( !GetDlgItemText (dlg, IDC_ADDUID_EMAIL, email, sizeof (email) -1)) {
530                  msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );                  msg_box (dlg, _("Please enter an email address."), _("UserID"), MB_ERR);
531                    free_if_alloc (utf8_name);
532                  return FALSE;                  return FALSE;
533              }              }
534              if (!strchr (email, '@' ) || strchr (email, ' ')) {              if (check_email_address (email)) {
535                  msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);                  msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
536                    free_if_alloc (utf8_name);
537                  return FALSE;                  return FALSE;
538              }              }
539                            
540              rc = GetDlgItemText (dlg, IDC_ADDUID_COMMENT,              rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_COMMENT, &utf8_comment);
                                  comment, sizeof comment -1);  
             utf8_name = native_to_utf8 (name);  
541    
542              ke = new GpgKeyEdit (ctx->keyid);              ke = create_GpgKeyEdit (ctx->keyid);
             if (!ke)  
                 BUG (NULL);  
543              if (ctx->is_protected)              if (ctx->is_protected)
544                  ke->setPassphrase (ctx->pass);                  ke->setPassphrase (ctx->pass);
545              else              else
546                  ke->setNoPassphrase (true);                  ke->setNoPassphrase (true);
547              err = ke->addUserid (utf8_name? utf8_name : name,              err = ke->addUserid (utf8_name, utf8_comment, email);
                                  rc > 0? comment : NULL, email);  
548              if (err)              if (err)
549                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
550              else {              else {
551                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
552                  ctx->finished = 1;                  ctx->finished = 1;
553                    /* The caller releases this items later. */
554                    keygen->name = utf8_name;
555                    keygen->comment = utf8_comment;
556                    keygen->email = m_strdup (email);
557              }              }
558              delete ke;                    delete ke;
             if (!err && ctx->lv)  
                 do_add_new_userid (ctx->lv, utf8_name, email, rc?comment : NULL);  
             free (utf8_name);  
559              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
560              return TRUE;              return TRUE;
561                            
# Line 587  keyedit_adduid_dlg_proc (HWND dlg, UINT Line 570  keyedit_adduid_dlg_proc (HWND dlg, UINT
570  }  }
571    
572    
573    /* Initalize a combo box with default key sizes (1024-4096). */
574  static void  static void
575  init_keysize_box (HWND dlg, int ctlid)  init_keysize_box (HWND dlg, int ctlid)
576  {  {
577      const char *sizelist[] = {      const char *sizelist[] = {
578          "1024", "1536", "2048", "2560", "3072", "3854", "4096", NULL          "1024", "1536",
579            "2048", "3072",
580            "4096", NULL
581      };      };
582      int i;      int i;
583    
584      for (i=0; sizelist[i] != NULL; i++)      for (i=0; sizelist[i] != NULL; i++)
585          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0, (LPARAM)(char*)sizelist[i]);          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
586                                (LPARAM)(char*)sizelist[i]);
587      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
588  }  }
589    
590    
591  static int  static int
592  get_keysize_from_box (HWND dlg, int ctlid)  get_keysize_from_box (HWND dlg, int ctlid)
593  {  {
# Line 609  get_keysize_from_box (HWND dlg, int ctli Line 598  get_keysize_from_box (HWND dlg, int ctli
598      if (pos == CB_ERR)      if (pos == CB_ERR)
599          return -1;          return -1;
600      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
601      return atol (buf);      return atoi (buf);
602  }  }
603    
604    
# Line 632  BOOL CALLBACK Line 621  BOOL CALLBACK
621  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
622  {  {
623      static keyedit_cb_t ctx;      static keyedit_cb_t ctx;
624      static keygen_cb_t keygen;      keygen_cb_t keygen;
625      GpgKeyEdit *ke;      GpgKeyEdit *ke;
626      gpgme_error_t err;      gpgme_error_t err;
627      SYSTEMTIME st;      SYSTEMTIME st;
628      HWND lb;      HWND hwnd;
629      int index, size, valid;      int index, size, valid;
630            
631      switch (msg) {      switch (msg) {
632      case WM_INITDIALOG:      case WM_INITDIALOG:
633          ctx = (keyedit_cb_t)lparam;          ctx = (keyedit_cb_t)lparam;
634          if (!ctx)          if (!ctx)
635              dlg_fatal_error (dlg, "Could not get dialog param!");              BUG (NULL);
         keygen = (keygen_cb_t)ctx->opaque;  
   
636          SetWindowText (dlg, _("Add new Subkey"));          SetWindowText (dlg, _("Add new Subkey"));
637          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
638          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));
# Line 653  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 640  keyedit_addsubkey_dlg_proc (HWND dlg, UI
640          SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
641          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
642    
643          lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);          hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
644          listbox_add_string (lb, "DSA (sign only)");          listbox_add_string (hwnd, "DSA (sign only)");
645          listbox_add_string (lb, "ElGamal (encrypt only)");          listbox_add_string (hwnd, "ElGamal (encrypt only)");
646          listbox_add_string (lb, "RSA (sign only)");          listbox_add_string (hwnd, "RSA (sign only)");
647          listbox_add_string (lb, "RSA (encrypt only)");          listbox_add_string (hwnd, "RSA (encrypt only)");
648          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
649          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
650          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
651          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
652          return FALSE;          center_window (dlg, ctx->parent);
           
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE) {  
             EndDialog (dlg, TRUE);  
         }  
653          return FALSE;          return FALSE;
654                    
655      case WM_COMMAND:      case WM_COMMAND:
# Line 687  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 669  keyedit_addsubkey_dlg_proc (HWND dlg, UI
669    
670          switch (LOWORD (wparam)) {          switch (LOWORD (wparam)) {
671          case IDOK:          case IDOK:
672              lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);              keygen = (keygen_cb_t)ctx->opaque;
673              switch (listbox_get_cursel (lb)) {              assert (keygen);
674                hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
675                switch (listbox_get_cursel (hwnd)) {
676              case 0: index = 2; break;              case 0: index = 2; break;
677              case 1: index = 4; break;              case 1: index = 4; break;
678              case 2: index = 5; break;              case 2: index = 5; break;
679              case 3: index = 6; break;              case 3: index = 6; break;
680              default:              default:
681                  msg_box (dlg, _("Please select one entry."), _("Add Subkey"), MB_ERR);                  msg_box (dlg, _("Please select one entry."),
682                             _("Add Subkey"), MB_ERR);
683                  return FALSE;                  return FALSE;
684              }              }
685              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
686              if (index == 2 && size != 1024) {              if (index == 2 && size != 1024) {
687                  msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),                  msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
688                           _("Add Subkey"), MB_INFO);                           _("Add Subkey"), MB_INFO);
689                  size = 1024;                  size = 1024;
690              }              }
691    
692              DateTime_GetSystemtime (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), &st);              hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
693                DateTime_GetSystemtime (hwnd, &st);
694              valid = w32_mktime (&st) - time (NULL);              valid = w32_mktime (&st) - time (NULL);
695              valid /= 86400;              valid /= 86400;
696    
# Line 718  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 704  keyedit_addsubkey_dlg_proc (HWND dlg, UI
704              if (valid > 0)              if (valid > 0)
705                  keygen->expire = time (NULL) + valid*24*60*60;                  keygen->expire = time (NULL) + valid*24*60*60;
706    
707              ke = new GpgKeyEdit (ctx->keyid);              ke = create_GpgKeyEdit (ctx->keyid);
             if (!ke)  
                 BUG (NULL);  
708              ke->setCallback (keygen_cb, NULL);              ke->setCallback (keygen_cb, NULL);
709              if (ctx->is_protected)              if (ctx->is_protected)
710                  ke->setPassphrase (ctx->pass);                  ke->setPassphrase (ctx->pass);
# Line 730  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 714  keyedit_addsubkey_dlg_proc (HWND dlg, UI
714    
715              err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);              err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
716              keygen->fpr = get_subkey_keyid (ctx->keyid);              keygen->fpr = get_subkey_keyid (ctx->keyid);
717              keygen_cb_dlg_destroy ();              keygen_cb_dlg_destroy (1);
             keygen_cb (NULL, NULL, 0, 0, 0); /* flush */  
718              if (err)              if (err)
719                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
720              else {              else {
721                  msg_box (dlg, _("Subkey successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("Subkey successfully added."),
722                  if (ctx->lv)                           _("GnuPG Status"), MB_OK);
                     do_add_new_subkey (ctx->lv, keygen, 0);  
723                  ctx->finished = 1;                  ctx->finished = 1;
724              }              }
725              delete ke;              delete ke;
# Line 759  BOOL Line 741  BOOL
741  keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
742  {  {
743      keyedit_cb_s cb;      keyedit_cb_s cb;
744        keygen_cb_s keygen;
745      char *pass = NULL;      char *pass = NULL;
746      int cancel = 0;      int cancel = 0;
747    
748      if (!k->key_pair) {      if (!k->key_pair) {
749          msg_box( dlg, _("There is no secret key available!"), _("Add user ID"), MB_ERR );          msg_box (dlg, _("There is no secret key available!"),
750                     _("Add user ID"), MB_ERR);
751          return FALSE;          return FALSE;
752      }      }
753    
754      if (k->is_protected) {      if (k->is_protected) {
755          pass = request_passphrase( _("Key Edit"), 1, &cancel );          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
756          if (cancel)          if (cancel)
757              return FALSE;              return FALSE;
758      }      }
759              
760        memset (&keygen, 0, sizeof (keygen));
761      memset (&cb, 0, sizeof cb);      memset (&cb, 0, sizeof cb);
762        cb.parent = dlg;
763        cb.opaque = &keygen;
764      cb.is_protected = k->is_protected;      cb.is_protected = k->is_protected;
765      cb.pass = pass;      cb.pass = pass;
     cb.lv = lv;  
766      cb.keyid = k->keyid;      cb.keyid = k->keyid;
767      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
768                        dlg, keyedit_adduid_dlg_proc,                                dlg, keyedit_adduid_dlg_proc,        
769                        (LPARAM)&cb, _("Add user ID"),                        (LPARAM)&cb, _("Add user ID"),
770                        IDS_WINPT_KEYEDIT_ADDUID);                        IDS_WINPT_KEYEDIT_ADDUID);
771        if (lv != NULL && cb.finished)
772            do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
773      if (cb.finished)      if (cb.finished)
774          k->update = 1;          k->update = 1;
775    
776        free_if_alloc (keygen.name);
777        free_if_alloc (keygen.email);
778        free_if_alloc (keygen.comment);
779      sfree_if_alloc (pass);      sfree_if_alloc (pass);
780      return TRUE;      return TRUE;
781  }  }
782    
783    
784    /* Return the keyID of the last subkey. */
785  char*  char*
786  get_subkey_keyid (const char *keyid)  get_subkey_keyid (const char *keyid)
787  {  {
# Line 798  get_subkey_keyid (const char *keyid) Line 789  get_subkey_keyid (const char *keyid)
789      gpgme_key_t key;      gpgme_key_t key;
790      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
791      gpgme_subkey_t subk;      gpgme_subkey_t subk;
792      char *kid;      char *kid = NULL;
793    
794      err = gpgme_new (&ctx);      err = gpgme_new (&ctx);
795      if (err)      if (err)
# Line 808  get_subkey_keyid (const char *keyid) Line 799  get_subkey_keyid (const char *keyid)
799      if (err)      if (err)
800          return NULL;          return NULL;
801      subk = get_nth_key (key, count_subkeys (key));      subk = get_nth_key (key, count_subkeys (key));
802      kid = strdup (subk->keyid);      if (subk != NULL)
803            kid = strdup (subk->keyid);
804      gpgme_key_release (key);      gpgme_key_release (key);
805      return kid;      return kid;
806  }  }
# Line 823  keyedit_add_subkey (winpt_key_t k, HWND Line 815  keyedit_add_subkey (winpt_key_t k, HWND
815      int cancel = 0;      int cancel = 0;
816    
817      if (!k->key_pair) {      if (!k->key_pair) {
818          msg_box (dlg, _("There is no secret key available!"), _("Add Subkey"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"),
819                     _("Add Subkey"), MB_ERR);
820          return FALSE;          return FALSE;
821      }      }
822      if (k->is_protected) {      if (k->is_protected) {
823          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
824          if (cancel)          if (cancel)
825              return FALSE;              return FALSE;
826      }      }
827    
828      memset (&keygen, 0, sizeof (keygen));      memset (&keygen, 0, sizeof (keygen));
829      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
     cb.lv = lv;  
830      cb.keyid = k->keyid;      cb.keyid = k->keyid;
831      cb.is_protected = k->is_protected;      cb.is_protected = k->is_protected;
832      cb.pass = pass;      cb.pass = pass;
# Line 843  keyedit_add_subkey (winpt_key_t k, HWND Line 835  keyedit_add_subkey (winpt_key_t k, HWND
835                        dlg, keyedit_addsubkey_dlg_proc,                        dlg, keyedit_addsubkey_dlg_proc,
836                        (LPARAM)&cb, _("Add new Subkey"),                        (LPARAM)&cb, _("Add new Subkey"),
837                        IDS_WINPT_KEYEDIT_ADDSUBKEY);                        IDS_WINPT_KEYEDIT_ADDSUBKEY);
838      safe_free (keygen.fpr);      if (lv != NULL && cb.finished)
839            do_add_new_subkey (lv, &keygen, 0);
840      if (cb.finished)      if (cb.finished)
841          k->update = 1;          k->update = 1;
842    
843      sfree_if_alloc (pass);          safe_free (keygen.fpr);
844        sfree_if_alloc (pass);
845      return cb.finished? TRUE: FALSE;      return cb.finished? TRUE: FALSE;
846  }  }
847    
848    
849    /* Set the preferred keyserver of the given key @k. */
850  BOOL  BOOL
851  keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)  keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)
852  {  {
853      GpgKeyEdit *ke;      GpgKeyEdit *ke;
854      gpgme_error_t err;      gpgme_error_t err;
855      struct URL_ctx_s *url;      struct URL_ctx_s *url;
856      char *pass;      char *pass = NULL;
857    
858      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
859      if (url->cancel == 1) {      if (url->cancel == 1) {
# Line 866  keyedit_set_pref_keyserver (winpt_key_t Line 861  keyedit_set_pref_keyserver (winpt_key_t
861          return FALSE;          return FALSE;
862      }      }
863    
864      pass = request_passphrase (_("Key Edit"), 1, &url->cancel);      pass = request_key_passphrase (k->ctx, _("Key Edit"), &url->cancel);
865      if (url->cancel) {      if (url->cancel) {
866          delete url;          delete url;
867          return FALSE;          return FALSE;
868      }      }
869    
870      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
871      if (k->is_protected)      if (k->is_protected)
872          ke->setPassphrase (pass);          ke->setPassphrase (pass);
873      else      else
# Line 882  keyedit_set_pref_keyserver (winpt_key_t Line 875  keyedit_set_pref_keyserver (winpt_key_t
875      err = ke->setPreferredKeyserver (-1, url->url);      err = ke->setPreferredKeyserver (-1, url->url);
876      if (!err)      if (!err)
877          msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);          msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
878        else
879            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
880    
881      sfree_if_alloc (pass);      sfree_if_alloc (pass);
882      delete ke;      delete ke;
# Line 895  keyedit_set_pref_keyserver (winpt_key_t Line 890  keyedit_set_pref_keyserver (winpt_key_t
890  BOOL  BOOL
891  keyedit_add_photo (winpt_key_t k, HWND dlg)  keyedit_add_photo (winpt_key_t k, HWND dlg)
892  {  {
893        keyedit_cb_s cb;
894        char *pass = NULL;
895        int cancel;
896        
897      if (!k->key_pair) {      if (!k->key_pair) {
898          msg_box (dlg, _("There is no secret key available!"),          msg_box (dlg, _("There is no secret key available!"),
899                   _("Add Photo"), MB_ERR);                   _("Add Photo"), MB_ERR);
900          return FALSE;          return FALSE;
901      }      }
902    
903        memset (&cb, 0, sizeof (cb));
904        if (k->is_protected) {
905            pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
906            if (cancel)
907                return FALSE;
908        }
909        cb.parent = dlg;
910        cb.pass = pass;
911        cb.keyid = k->keyid;
912      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
913                      keyedit_addphoto_dlg_proc, (LPARAM)k);                      keyedit_addphoto_dlg_proc, (LPARAM)&cb);
914    
915        if (cb.finished)
916            k->update = 1;
917        sfree_if_alloc (pass);    
918      return TRUE;      return TRUE;
919  }  }
920    
# Line 909  keyedit_add_photo (winpt_key_t k, HWND d Line 922  keyedit_add_photo (winpt_key_t k, HWND d
922  BOOL  BOOL
923  keyedit_add_revoker (winpt_key_t k, HWND dlg)  keyedit_add_revoker (winpt_key_t k, HWND dlg)
924  {  {
925        keyedit_cb_s cb;
926        char *pass = NULL;
927        int cancel;
928    
929      if (!k->key_pair) {      if (!k->key_pair) {
930          msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
931          return FALSE;          return FALSE;
932      }      }
933    
934        if (k->is_protected) {
935            pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
936            if (cancel)
937                return FALSE;
938        }
939    
940        memset (&cb, 0, sizeof (cb));
941        cb.parent = dlg;
942        cb.is_protected = k->is_protected;
943        cb.keyid = k->keyid;
944        cb.pass = pass;
945      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
946                      keyedit_addrevoker_dlg_proc, (LPARAM)k);                      keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
947    
948        if (cb.finished)
949            k->update = 1;
950        sfree_if_alloc (pass);
951      return TRUE;      return TRUE;
952  }  }
953    
# Line 950  is_idea_protect_algo (const char *keyid) Line 983  is_idea_protect_algo (const char *keyid)
983    
984      memset (&k, 0, sizeof (k));      memset (&k, 0, sizeof (k));
985      if (winpt_get_pubkey (keyid, &k))      if (winpt_get_pubkey (keyid, &k))
986          BUG (0);          BUG (NULL);
     sym_prefs = k.ext->sym_prefs;  
987      if (!k.is_v3)      if (!k.is_v3)
988          return 0;          return 0;
989        sym_prefs = k.ext->sym_prefs;
990      if (!sym_prefs)      if (!sym_prefs)
991          return 1; /* assume that only v3 keys have no symmetric cipher preferences          return 1; /* assume that only v3 keys have no symmetric cipher preferences
992                       and thus IDEA is explicit. */                       and thus IDEA is explicit. */
# Line 968  is_idea_protect_algo (const char *keyid) Line 1001  is_idea_protect_algo (const char *keyid)
1001  BOOL  BOOL
1002  keyedit_change_passwd (winpt_key_t k, HWND dlg)  keyedit_change_passwd (winpt_key_t k, HWND dlg)
1003  {  {
1004      gpgme_error_t ec;      gpgme_error_t err;
1005      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1006      char *old_pass = NULL;      char *old_pass = NULL;
1007      char *new_pass = NULL;      char *new_pass = NULL;
# Line 988  keyedit_change_passwd (winpt_key_t k, HW Line 1021  keyedit_change_passwd (winpt_key_t k, HW
1021      }      }
1022    
1023      if (k->is_protected) {      if (k->is_protected) {
1024          old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);          old_pass = request_passphrase (_("Current (old) Passphrase"),
1025                                           PASSDLG_INIT, &cancel);
1026          if (cancel)          if (cancel)
1027              return FALSE;              return FALSE;
1028      }      }
1029      new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);      new_pass = request_passphrase2 (_("New Passphrase" ),
1030                                        PASSDLG_INIT|PASSDLG_WARN_UTF8, &cancel);
1031      if (cancel) {      if (cancel) {
1032          free_if_alloc (old_pass);          sfree_if_alloc (old_pass);
1033          return FALSE;          return FALSE;
1034      }      }
1035    
1036      if (is_8bit_string (new_pass)) {      if (strlen (new_pass) == 0) {
1037          msg_box (dlg, _("The passphrase contains 8-bit characters.\n"          cancel = msg_box (dlg, _("Are you sure that you really don't want a passphrase?\n"
1038                           "It is not suggested to use charset specific characters."),                                   "This is propably a bad idea, still proceed?"),
1039                           _("Key Edit"), MB_ERR);                              _("Key Edit"), MB_WARN_ASK);
1040          free_if_alloc (old_pass);          if (cancel != IDYES) {
1041          free_if_alloc (new_pass);              sfree_if_alloc (old_pass);
1042          return FALSE;              sfree_if_alloc (new_pass);
1043                return FALSE;
1044            }
1045      }      }
1046    
1047      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
   
1048      ke->setPassphrase (k->is_protected? old_pass : NULL);      ke->setPassphrase (k->is_protected? old_pass : NULL);
1049      ec = ke->changePassphrase (new_pass, 0);      if (!k->is_protected)
1050      if( ec )          ke->setNoPassphrase (true);
1051          msg_box (dlg, gpgme_strerror (ec), _("Change Passwd"), MB_ERR);      err = ke->changePassphrase (new_pass, 1);
1052        if (err)
1053            msg_box (dlg, gpgme_strerror (err), _("Change Passwd"), MB_ERR);
1054      else      else
1055          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);
1056      sfree_if_alloc (old_pass);      sfree_if_alloc (old_pass);
# Line 1023  keyedit_change_passwd (winpt_key_t k, HW Line 1059  keyedit_change_passwd (winpt_key_t k, HW
1059      return TRUE;      return TRUE;
1060  }  }
1061    
1062                    
1063  /* Initialize sub key list from key @k and return  /* Initialize sub key list from key @k and return
1064     the new listview control. */     the new listview control. */
1065  listview_ctrl_t  listview_ctrl_t
1066  subkey_list_init (HWND dlg, winpt_key_t k)  subkey_list_init (HWND dlg, winpt_key_t k)
1067  {  {
1068      LV_ITEM lvi;      LV_ITEM lvi;
     gpgme_key_t key;  
1069      gpgme_subkey_t sub;      gpgme_subkey_t sub;
1070      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1071          {0, 80, (char *)_("Description")},          {0, 80, (char *)_("Description")},
# Line 1047  subkey_list_init (HWND dlg, winpt_key_t Line 1082  subkey_list_init (HWND dlg, winpt_key_t
1082      listview_ctrl_t lv;      listview_ctrl_t lv;
1083      char buf[256], tmp[128];      char buf[256], tmp[128];
1084      const char *t;      const char *t;
1085      int nkeys = 0, rc = 0, i, bits;          int nkeys = 0, i;
1086    
1087      if( get_pubkey( k->keyid, &key ) ) {      nkeys = count_subkeys (k->ctx);
1088          msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );      if (!nkeys)
1089          return NULL;          BUG (NULL); /* should never happen. */
     }  
     if (!k->ctx)  
         k->ctx = key;  
     nkeys = count_subkeys (key);  
     if( !nkeys ) {  
         msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);  
         return NULL;  
     }  
           
     rc  = listview_new( &lv );  
     if( rc )  
         BUG( dlg );  
1090                    
1091      lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
1092      for( i = 0; cols[i].fieldname != NULL; i++ )          for (i = 0; cols[i].fieldname != NULL; i++)
1093          listview_add_column( lv, &cols[i] );          listview_add_column (lv, &cols[i]);
1094                    
1095      for( i = 0; i < nkeys; i++ ) {      for (i = 0, sub = k->ctx->subkeys; i < nkeys; i++, sub = sub->next) {
1096          listview_add_item( lv, "" );          listview_add_item (lv, "");
1097          listview_add_sub_item( lv, 0, 1, "" );          listview_add_sub_item (lv, 0, 1, "");
1098          memset( &lvi, 0, sizeof lvi );          memset (&lvi, 0, sizeof (lvi));
1099          lvi.mask = LVIF_PARAM;            lvi.mask = LVIF_PARAM;  
1100          lvi.lParam = (LPARAM)key;          lvi.lParam = (LPARAM)sub;
1101          if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )          if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
1102              return NULL;              BUG (NULL);
1103      }      }
1104                    
1105      listview_set_ext_style( lv );      listview_set_ext_style (lv);
1106      for( i = 0, sub = key->subkeys; i < nkeys; i++, sub = sub->next ) {      for (i = 0, sub = k->ctx->subkeys; i < nkeys; i++, sub = sub->next) {
1107          memset( buf, 0, sizeof buf );          _snprintf (buf, sizeof buf-1, "%d-bit %s", sub->length,
1108                                    get_key_pubalgo (sub->pubkey_algo));
1109          bits = sub->length;          listview_add_sub_item (lv, i, SUBK_COL_DESC, buf);
         _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );  
         strcat( buf, tmp );  
   
         _snprintf( tmp, sizeof tmp-1, "%s", get_key_pubalgo (sub->pubkey_algo));  
         strcat( buf, tmp );  
           
         listview_add_sub_item( lv, i, 0, buf );  
1110          t = sub->keyid;          t = sub->keyid;
1111          if( !t )          assert (t != NULL);
1112              t = "DEADBEEFDEADBEEF";          _snprintf (tmp, sizeof tmp-1, "0x%s", t+8);
1113          _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );          listview_add_sub_item (lv, i, SUBK_COL_KEYID, tmp);
         listview_add_sub_item( lv, i, 1, tmp );  
1114    
1115          t = get_key_created (sub->timestamp);          t = get_key_created (sub->timestamp);
1116          if( !t )          if (!t)
1117              t = "????" "-??" "-??";              t = "????" "-??" "-??";
1118          listview_add_sub_item( lv, i, 2, t );          listview_add_sub_item (lv, i, SUBK_COL_CREATION, t);
1119    
1120          if( sub->expires ) {          if (sub->expires) {
1121              t = get_key_created (sub->expires);              t = get_key_created (sub->expires);
1122              listview_add_sub_item( lv, i, 3, t );              listview_add_sub_item (lv, i, SUBK_COL_EXPIRES, t);
1123          }          }
1124          else          else
1125              listview_add_sub_item( lv, i, 3, _("Never") );              listview_add_sub_item (lv, i, SUBK_COL_EXPIRES, _("Never"));
1126            if (sub->expired)
         if( sub->expired )  
1127              t = _("Expired");              t = _("Expired");
1128          else if( sub->revoked )          else if (sub->revoked)
1129              t = _("Revoked");              t = _("Revoked");
1130          else          else
1131              t = _("OK");              t = _("OK");
1132          listview_add_sub_item( lv, i, 4, t );          listview_add_sub_item (lv, i, SUBK_COL_STATUS, t);
1133    
1134          if (sub->can_certify) t = "*"; else t = "";          if (sub->can_certify) t = "*"; else t = "";
1135          listview_add_sub_item (lv, i, 5, t);          listview_add_sub_item (lv, i, SUBK_COL_C_FLAG, t);
1136          if (sub->can_sign) t = "*"; else t = "";          if (sub->can_sign) t = "*"; else t = "";
1137          listview_add_sub_item( lv, i, 6, t );          listview_add_sub_item( lv, i, SUBK_COL_S_FLAG, t );
1138          if (sub->can_encrypt) t = "*"; else t = "";          if (sub->can_encrypt) t = "*"; else t = "";
1139          listview_add_sub_item( lv, i, 7, t );          listview_add_sub_item( lv, i, SUBK_COL_E_FLAG, t );
1140          if (sub->can_authenticate) t = "*"; else t = "";          if (sub->can_authenticate) t = "*"; else t = "";
1141          listview_add_sub_item (lv, i, 8, t);          listview_add_sub_item (lv, i, SUBK_COL_A_FLAG, t);
1142      }      }
1143      return lv;      return lv;
1144  } /* subkey_list_init */  }
1145    
1146    
1147  static listview_ctrl_t  static listview_ctrl_t
1148  userid_list_init (HWND dlg, winpt_key_t k)  userid_list_init (HWND dlg, winpt_key_t k)
1149  {  {
1150      listview_ctrl_t lv = NULL;      listview_ctrl_t lv = NULL;
     gpgme_key_t key;  
1151      gpgme_key_sig_t ks;      gpgme_key_sig_t ks;
1152      gpgme_user_id_t u;      struct native_uid_s *u;
1153      int nuids = 0, rc, j, u_attr;      int nuids = 0, j, u_attr;
1154      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1155          {0,  72, (char *)_("Validity")},          {0,  72, (char *)_("Validity")},
1156          {1, 150, (char *)_("Name")},          {1, 150, (char *)_("Name")},
# Line 1146  userid_list_init (HWND dlg, winpt_key_t Line 1159  userid_list_init (HWND dlg, winpt_key_t
1159          {0, 0, 0}          {0, 0, 0}
1160      };          };    
1161      const char *attr;      const char *attr;
   
     if (get_pubkey (k->keyid, &key)) {  
         msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);  
         return NULL;  
     }  
1162            
1163      nuids = count_userids (key);      nuids = count_userids (k->ctx);
1164      if (!nuids) {      if (!nuids)
1165          msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);          BUG (NULL); /* should never happen. */
         return NULL;  
     }  
1166                    
1167      rc = listview_new (&lv);      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST));
1168      if (rc)      for (j = 0; cols[j].fieldname != NULL; j++)
1169          BUG (dlg);          listview_add_column (lv, &cols[j]);
     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );  
     for( j = 0; cols[j].fieldname != NULL; j++ )  
         listview_add_column( lv, &cols[j] );  
1170                    
1171      for( j = 0; j < nuids; j++ ) {                for (j = 0; j < nuids; j++) {
1172          listview_add_item( lv, " " );          listview_add_item (lv, " ");
1173          listview_add_sub_item( lv, 0, 1, " " );                  listview_add_sub_item (lv, 0, 1, " " );        
1174      }      }
1175    
1176      listview_set_ext_style (lv);      listview_set_ext_style (lv);
1177      for (j = 0, u=key->uids; j < nuids; u=u->next, j++) {      for (j = 0, u=k->ext->uids; j < nuids; u=u->next, j++) {
1178          if (u->revoked)          if (u->revoked)
1179              attr = _("Revoked");              attr = _("Revoked");
1180          else {          else {
1181              u_attr = (int)u->validity;              u_attr = (int)u->validity;
1182              attr = get_key_trust2 (NULL, u_attr, 0, 0);              attr = get_key_trust2 (NULL, u_attr, 0, 0);
1183          }          }
1184          listview_add_sub_item( lv, j, 0, (char *)attr );                  listview_add_sub_item (lv, j, UID_COL_VALID, (char *)attr);
   
1185          /* XXX: add comment if available */          /* XXX: add comment if available */
1186          attr = u->name;          listview_add_sub_item (lv, j, UID_COL_NAME,
1187          if (attr) {                                 u->name? u->name : _("Invalid user ID"));
1188              char *uid = utf8_to_native (attr);          if (u->email)
1189              if (uid) {              listview_add_sub_item (lv, j, UID_COL_EMAIL, u->email);
                 listview_add_sub_item (lv, j, 1, uid);  
                 free (uid);  
             }  
         }  
         else  
             listview_add_sub_item (lv, j, 1, _("Invalid user ID"));  
         attr = u->email;  
         if (attr)  
             listview_add_sub_item (lv, j, 2, attr);  
1190    
1191          ks = get_selfsig (u, k->keyid, 1);          ks = get_selfsig (u->signatures, k->keyid, 1);
1192          if (ks)          if (ks)
1193              listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));              listview_add_sub_item (lv, j, UID_COL_CREATION,
1194                                       get_key_created (ks->timestamp));
1195      }      }
1196      if( !k->key_pair ) {      if (!k->key_pair) {
1197          CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );          CheckDlgButton (dlg, IDC_KEYUID_ADD, BST_INDETERMINATE);
1198          CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );              CheckDlgButton (dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE);
1199      }      }
1200      return lv;      return lv;
1201  } /* userid_list_init */  }
1202    
1203    
1204  static void  static void
# Line 1233  is_cmd_openpgp (int cmdid) Line 1227  is_cmd_openpgp (int cmdid)
1227      case CMD_ADDKEY:      case CMD_ADDKEY:
1228      case CMD_ADDPHOTO:      case CMD_ADDPHOTO:
1229      case CMD_ADDREVOKER:      case CMD_ADDREVOKER:
1230      //case CMD_SETPREF:      case CMD_SETPREF:
1231          return 1;          return 1;
1232      }      }
1233      return 0;      return 0;
# Line 1244  is_cmd_openpgp (int cmdid) Line 1238  is_cmd_openpgp (int cmdid)
1238  static void  static void
1239  do_show_help (HWND dlg)  do_show_help (HWND dlg)
1240  {  {
1241      char helptext[2048];      const char *help;
1242    
1243      _snprintf (helptext, sizeof (helptext)-1,      help =
1244          _(          _(
1245           "ADDUID   \t\tadd a user ID\r\n"           "ADDUID      add a user ID\r\n"
1246           "ADDPHOTO  \t\tadd a photo ID\r\n"           "ADDPHOTO    add a photo ID\r\n"
1247           "DELUID    \t\tdelete a user ID\r\n"           "DELUID      delete a user ID\r\n"
1248           "ADDKEY    \t\tadd a secondard key\r\n"           "ADDKEY      add a secondard key\r\n"
1249           "DELKEY    \t\tdelete a secondary key\r\n"           "DELKEY      delete a secondary key\r\n"
1250           "ADDREVOKER\t\tadd a revocation key\r\n"           "ADDREVOKER  add a revocation key\r\n"
1251           "EXPIRE    \t\tchange the expire date\r\n"           "EXPIRE      change the expire date\r\n"
1252           "SHOWPREF  \t\tlist preferences (verbose)\r\n"           "SHOWPREF    list preferences (verbose)\r\n"
1253           "SETPREF   \t\tset preference list\r\n"           "SETPREF     set preference list\r\n"
1254           "UPDPREF   \t\tupdated preferences\r\n"           "UPDPREF     updated preferences\r\n"
1255           "PASSWD    \t\tchange the passphrase\r\n"           "PASSWD      change the passphrase\r\n"
1256           "PRIMARY   \t\tflag user ID as primary\r\n"           "PRIMARY     flag user ID as primary\r\n"
1257           "TRUST     \t\tchange the ownertrust\r\n"           "TRUST       change the ownertrust\r\n"
1258           "REVUID    \t\trevoke a user ID\r\n"           "REVUID      revoke a user ID\r\n"
1259           "REVKEY    \t\trevoke a secondary key\r\n"           "REVKEY      revoke a secondary key\r\n"
1260           "DISABLE   \t\tdisable a key\r\n"           "DISABLE     disable a key\r\n"
1261           "ENABLE    \t\tenable a key\r\n"           "ENABLE      enable a key\r\n"
1262           "SIGN      \t\tsign a user-id (exportable)\r\n"           "SIGN        sign a user-id (exportable)\r\n"
1263           "LSIGN     \t\tsign a user-id (non-exportable)\r\n"));           "LSIGN       sign a user-id (non-exportable)\r\n"
1264      msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);           "CLEAN       remove unusable signatures from key\r\n"
1265             "MINIMIZE    remove all signatures from key\r\n"
1266             );
1267        msg_box (dlg, help, _("Key Edit Help"), MB_OK);
1268  }  }
1269    
1270    
# Line 1276  do_editkey_delkey (winpt_key_t k, HWND d Line 1273  do_editkey_delkey (winpt_key_t k, HWND d
1273  {  {
1274      gpgme_error_t err;      gpgme_error_t err;
1275      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1276      int j, id;      int pos, id;
1277      char tmp[64];      char tmp[64];
1278    
1279      if (!k->key_pair)      if (!k->key_pair)
1280          return FALSE; /* XXX: shall we allow to modify non-secret keys?? */          return FALSE;
1281    
1282      if( listview_count_items( lv, 0 ) == 1 ) {      if (listview_count_items (lv, 0) == 1) {
1283          msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1284          return FALSE;          return FALSE;
1285      }      }
1286      if( (j = listview_get_curr_pos( lv )) == -1 ) {      pos = listview_get_curr_pos (lv);
1287          msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );      if (pos == -1) {
1288            msg_box (dlg, _("Please select a key."), _("Key Edit"), MB_ERR);
1289          return FALSE;          return FALSE;
1290      }      }
1291      if( j == 0 ) {      if (pos == 0) {
1292          msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );          msg_box (dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1293          return FALSE;          return FALSE;
1294      }      }
1295            
1296      listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );      /* XXX: change the warning to make clear that verification won't work
1297      id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,              any longer if this is a sign-only key. */
1298        listview_get_item_text (lv, pos, 0, tmp, sizeof (tmp) -1);
1299        id = log_box (_("Key Edit"), MB_YESNO|MB_ICONWARNING,
1300                      _("\"Subkey %s.\"\n\n"                      _("\"Subkey %s.\"\n\n"
1301                        "Anything encrypted to the selected subkey will no longer\n"                        "Anything encrypted to the selected subkey will no longer\n"
1302                        "be able to be decrypted.\n\n"                        "be able to be decrypted.\n\n"
1303                        "Do you really want to delete this subkey?"), tmp );                        "Do you really want to delete this subkey?"), tmp);
1304      if( id == IDNO )      if (id == IDNO)
1305          return FALSE;          return FALSE;
1306    
1307      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
1308      if (!ke)      err = ke->delKey (pos);
         BUG (NULL);  
     err = ke->delKey (j);  
1309      if (err)      if (err)
1310          msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);
1311      else {      else {
1312          listview_del_item (lv, j);          listview_del_item (lv, pos);
1313          k->update = 1;          k->update = 1;
1314          status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));          status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));
1315      }      }
1316      delete ke;      delete ke;
1317      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1318  } /* do_editkey_delkey */  }
   
1319    
1320    
1321  /* Set the expiration date for the selected key in list view @lv.  /* Set the expiration date for the selected key in list view @lv.
# Line 1330  do_editkey_expire (winpt_key_t k, HWND d Line 1327  do_editkey_expire (winpt_key_t k, HWND d
1327      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1328      date_s udd = {0};      date_s udd = {0};
1329      char buf[256], * pass = NULL;      char buf[256], * pass = NULL;
1330      int j, cancel = 0;      time_t exp;
1331        int pos, cancel = 0;
1332    
1333      if (!k->key_pair) {      if (!k->key_pair) {
1334          msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1335          return FALSE;          return FALSE;
1336      }      }
1337      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1338          msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );      if (pos == -1) {
1339            msg_box (dlg, _("Please select a key."), _("Key Edit"), MB_ERR);
1340          return FALSE;          return FALSE;
1341      }      }
1342    
1343      /* If a key already expired, it is possible the user wants to      /* If a key already expired, it is possible the user wants to
1344         set a new expiration date.. */           set a new expiration date.. */
1345      listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof buf -1);      listview_get_item_text (lv, pos, SUBK_COL_STATUS, buf, sizeof (buf)-1);
1346      if (!strcmp (buf, _("Expired"))) {      if (!strcmp (buf, _("Expired"))) {
1347          cancel = msg_box (dlg, _("Key already expired.\n\n"          cancel = msg_box (dlg, _("Key already expired.\n\n"
1348                            "Do you want to change the expiration date?"),                            "Do you want to change the expiration date?"),
# Line 1365  do_editkey_expire (winpt_key_t k, HWND d Line 1364  do_editkey_expire (winpt_key_t k, HWND d
1364                   _("Key Edit"), MB_ERR);                   _("Key Edit"), MB_ERR);
1365          return FALSE;          return FALSE;
1366      }      }
1367      if( k->is_protected ) {      if (k->is_protected) {
1368          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1369          if (cancel)          if (cancel)
1370              return FALSE;              return FALSE;
1371      }      }
1372        exp = w32_mktime (&udd.st);
1373      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
1374      if (k->is_protected)      if (k->is_protected)
1375          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1376      else      else
1377          ke->setNoPassphrase (true);          ke->setNoPassphrase (true);
1378      err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);      err = ke->setKeyExpireDate (pos, exp, false);
1379      if (err)      if (err)
1380          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1381      else {      else {
1382          _snprintf (buf, sizeof buf - 1, "%04d-%02d-%02d",                _snprintf (buf, sizeof (buf)-1, "%s", get_key_created (exp));
1383                     udd.st.wYear, udd.st.wMonth, udd.st.wDay);          listview_add_sub_item (lv, pos, SUBK_COL_EXPIRES, buf);
         listview_add_sub_item (lv, j, SUBK_COL_EXPIRES, buf);  
1384          k->update = 1;          k->update = 1;
1385          msg_box (dlg, _("Subkey expire date successfully set."),          msg_box (dlg, _("Subkey expire date successfully set."),
1386                   _("GnuPG status"), MB_OK);                   _("GnuPG status"), MB_OK);
# Line 1431  do_editkey_revoke (winpt_key_t k, HWND d Line 1427  do_editkey_revoke (winpt_key_t k, HWND d
1427      }      }
1428            
1429      if (k->is_protected) {      if (k->is_protected) {
1430          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1431          if (cancel)          if (cancel)
1432              return FALSE;                        return FALSE;          
1433      }      }
1434    
1435      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
1436      if (k->is_protected)      if (k->is_protected)
1437          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1438      else      else
# Line 1498  do_editkey_revuid (winpt_key_t k, HWND d Line 1492  do_editkey_revuid (winpt_key_t k, HWND d
1492      if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)      if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1493          return FALSE;          return FALSE;
1494      if (k->is_protected) {      if (k->is_protected) {
1495          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1496          if (cancel)          if (cancel)
1497              return FALSE;                        return FALSE;          
1498      }      }
# Line 1508  do_editkey_revuid (winpt_key_t k, HWND d Line 1502  do_editkey_revuid (winpt_key_t k, HWND d
1502      if (id == -1)      if (id == -1)
1503          BUG (NULL);          BUG (NULL);
1504    
1505      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
1506      if (k->is_protected)      if (k->is_protected)
1507          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1508      else      else
# Line 1532  do_editkey_revuid (winpt_key_t k, HWND d Line 1524  do_editkey_revuid (winpt_key_t k, HWND d
1524  static int  static int
1525  do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1526  {  {
1527      gpgme_error_t rc;      gpgme_error_t err;
1528      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1529      char buf[256], * pass = NULL, * prefs;      gpg_uid_info_t uidinf = NULL;
1530      int j, id, cancel=0, flags=0;      char buf[256], *pass = NULL, *prefs = NULL;
1531        int pos, id, cancel=0, flags=0;
1532    
1533      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1534        if (pos == -1) {
1535          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1536          return FALSE;          return FALSE;
1537      }      }
1538      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, pos, 2, buf, sizeof buf-1);
1539      id = do_find_userid (k->keyid, buf, NULL, NULL);      id = do_find_userid (k->keyid, buf, NULL, &uidinf);
1540      if (id == -1)      if (id == -1)
1541          BUG (dlg);          BUG (NULL);
1542      if (k->is_protected) {      if (k->is_protected) {
1543          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1544            gpg_uid_info_release (uidinf);
1545          if (cancel)          if (cancel)
1546              return FALSE;              return FALSE;
1547      }      }
1548    
1549      ke = new GpgKeyEdit (k->keyid);      get_userid_preflist (uidinf->prefs, &prefs, &flags);
1550      if (!ke)      gpg_uid_info_release (uidinf);
1551          BUG (NULL);      if (!prefs) {
1552            sfree_if_alloc (pass);
1553            return FALSE;
1554        }
1555    
1556        ke = create_GpgKeyEdit (k->keyid);
1557      if (k->is_protected)      if (k->is_protected)
1558          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1559      else      else
1560          ke->setNoPassphrase (true);          ke->setNoPassphrase (true);    
1561        err = ke->setUseridPreferences (id, prefs);
1562      get_userid_preflist (&prefs, &flags);      if (err)
1563            msg_box (dlg, gpgme_strerror (err), _("Set user ID preferences"), MB_ERR);
1564      rc = ke->setUseridPreferences (id, prefs);      else {
1565      if (rc)          k->update = 1;
1566          msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);          status_box (dlg, _("User ID preferences successfully updated"), _("GnuPG Status"));
1567        }
1568    
1569      sfree_if_alloc (pass);      sfree_if_alloc (pass);
1570      free_if_alloc (prefs);      free_if_alloc (prefs);
1571      delete ke;      delete ke;
1572      return 0;      return err? FALSE: TRUE;
1573  }  }
1574    
1575    
# Line 1578  do_editkey_primary (winpt_key_t k, HWND Line 1579  do_editkey_primary (winpt_key_t k, HWND
1579      gpgme_error_t err;      gpgme_error_t err;
1580      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1581      int j, id, cancel=0;      int j, id, cancel=0;
1582      char buf[256], * pass = NULL;      char valid[32];
1583        char buf[256], *pass = NULL;
1584    
1585      if (listview_count_items (lv, 0) == 1)      if (listview_count_items (lv, 0) == 1)
1586          return TRUE;          return TRUE;
1587      if ((j = listview_get_curr_pos (lv)) == -1) {      if ((j = listview_get_curr_pos (lv)) == -1) {
1588          msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1589          return FALSE;          return FALSE;
1590      }      }
1591      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, j, UID_COL_VALID, valid, sizeof (valid)-1);
1592        if (!strcmp (valid, _("Revoked")))
1593            return FALSE;
1594        listview_get_item_text (lv, j, UID_COL_EMAIL, buf, sizeof (buf)-1);
1595      id = do_find_userid (k->keyid, buf, NULL, NULL);      id = do_find_userid (k->keyid, buf, NULL, NULL);
1596      if (id == -1)      if (id == -1)
1597          BUG (dlg);          BUG (NULL);
1598      if (k->is_protected) {      if (k->is_protected) {
1599          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1600          if (cancel)          if (cancel)
1601              return FALSE;              return FALSE;
1602      }      }
1603    
1604      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
1605      if (k->is_protected)      if (k->is_protected)
1606          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1607      else      else
# Line 1668  BOOL CALLBACK Line 1673  BOOL CALLBACK
1673  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1674  {  {
1675      static keyedit_cb_t cb = NULL;      static keyedit_cb_t cb = NULL;
1676      gpg_uid_info_t inf=NULL;      gpg_uid_info_t inf=NULL, u;
1677        gpgme_key_t key;
1678      char buf[128];      char buf[128];
1679      int pos;      int pos;
1680    
1681      switch (msg) {      switch (msg) {
1682      case WM_INITDIALOG:      case WM_INITDIALOG:
1683          cb = (keyedit_cb_t)lparam;          cb = (keyedit_cb_t)lparam;
1684          if (cb == NULL)          if (!cb)
1685              BUG (dlg);              BUG (NULL);
1686          pos = listview_get_curr_pos (cb->lv);          key = (gpgme_key_t)cb->opaque;
1687          listview_get_item_text (cb->lv, pos, 2, buf, DIM (buf)-1);          listview_get_item_text (cb->lv, cb->lv_pos,
1688          SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);                                  UID_COL_EMAIL, buf, sizeof (buf)-1);
1689          pos = do_find_userid (((winpt_key_t)cb->opaque)->keyid,          pos = do_find_userid (cb->keyid, buf, NULL, &inf);
1690                                buf, NULL, &inf);          if (pos < 0 || !inf) {
         if (inf) {  
             const char *prefs = inf->prefs;  
             if (prefs && *prefs) {  
                 if (parse_preflist (dlg, prefs) <= 0)  
                     pos = -1;  
             }  
             else  
                 pos = -1;  
1691              gpg_uid_info_release (inf);              gpg_uid_info_release (inf);
1692              if (pos == -1) {              EndDialog (dlg, FALSE);
1693                  msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);              break;
1694                  EndDialog (dlg, TRUE);          }
1695            for (u=inf; u; u = u->next) {
1696                if (u->index == pos && u->prefs && *u->prefs) {
1697                    _snprintf (buf, sizeof (buf)-1, "%s", u->name);
1698                    SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1699                    if (parse_preflist (dlg, u->prefs) <= 0)
1700                        pos = -1;
1701                    if (u->flags.mdc)
1702                        CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1703                    break;
1704              }              }
1705              if (inf->flags.mdc)          }
1706                  CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);          gpg_uid_info_release (inf);
1707            if (pos == -1) {        
1708                msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1709                EndDialog (dlg, FALSE);
1710                break;
1711          }          }
1712          SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));          SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1713          SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));          SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1714            SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1715          SetWindowText (dlg, _("Key Preferences"));          SetWindowText (dlg, _("Key Preferences"));
1716          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
1717            center_window (dlg, cb->parent);
1718          break;          break;
1719    
1720      case WM_COMMAND:      case WM_COMMAND:
# Line 1709  showpref_dlg_proc (HWND dlg, UINT msg, W Line 1722  showpref_dlg_proc (HWND dlg, UINT msg, W
1722          case IDOK:          case IDOK:
1723              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
1724              break;              break;
1725    
1726            case IDCANCEL:
1727                EndDialog (dlg, FALSE);
1728                break;
1729          }          }
1730          break;          break;
1731      }      }
# Line 1720  static int Line 1737  static int
1737  do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1738  {  {
1739      struct keyedit_cb_s cb;      struct keyedit_cb_s cb;
1740        char status[32];
1741    
1742      if (k->is_v3)      if (k->is_v3)
1743          return TRUE;          return TRUE;
# Line 1728  do_editkey_showpref (winpt_key_t k, HWND Line 1746  do_editkey_showpref (winpt_key_t k, HWND
1746          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1747          return FALSE;          return FALSE;
1748      }      }
   
1749      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
1750        cb.parent = dlg;
1751        cb.opaque = k->ctx;
1752        cb.keyid = k->keyid;
1753      cb.lv = lv;      cb.lv = lv;
1754      cb.opaque = k;      cb.lv_pos = listview_get_curr_pos (lv);
1755    
1756        listview_get_item_text (lv, cb.lv_pos, UID_COL_VALID,
1757                                status, sizeof (status)-1);
1758        if (!strcmp (status, _("Revoked")))
1759            return TRUE;
1760        
1761      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1762                      showpref_dlg_proc, (LPARAM)&cb);                      showpref_dlg_proc, (LPARAM)&cb);
1763      return TRUE;      return TRUE;
# Line 1745  do_editkey_deluid (winpt_key_t k, HWND d Line 1771  do_editkey_deluid (winpt_key_t k, HWND d
1771      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1772      char email[128], name[128];      char email[128], name[128];
1773      char inf[384];      char inf[384];
1774      int j, id = 0;      int pos, id = 0;
1775    
1776      if (!k->key_pair)      if (!k->key_pair)
1777          return FALSE; /* XXX: see do_editkey_delsubkey */          return FALSE;
1778    
1779      if (listview_count_items (lv, 0) == 1) {      if (listview_count_items (lv, 0) == 1) {
1780          msg_box (dlg, _("Primary user ID can not be deleted!"),          msg_box (dlg, _("Primary user ID can not be deleted!"),
1781                   _("Key Edit"), MB_ERR);                   _("Key Edit"), MB_ERR);
1782          return FALSE;          return FALSE;
1783      }      }
1784      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1785        if (pos == -1) {
1786          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1787          return FALSE;          return FALSE;
1788      }      }
1789            
1790      /* XXX: add a hint that also all signatures will be deleted? */      listview_get_item_text (lv, pos, UID_COL_NAME, name, DIM(name) -1);
     listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);  
1791      _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"      _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1792                                       "All signatures on this user ID will be also deleted."
1793                                       "\n\n"
1794                                     "Do you really want to delete this user ID?"),                                     "Do you really want to delete this user ID?"),
1795                                 name);                                 name);
1796      if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)      if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1797          return FALSE;          return FALSE;
1798            
1799      listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);      listview_get_item_text (lv, pos, UID_COL_EMAIL, email, DIM (email)-1);
1800      listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);      listview_get_item_text (lv, pos, UID_COL_NAME, name, DIM (name)-1);
1801      id = do_find_userid (k->keyid, email, name, NULL);      id = do_find_userid (k->keyid, email, name, NULL);
1802      if (id == -1)      if (id == -1)
         BUG (dlg);  
   
     ke = new GpgKeyEdit (k->keyid);  
     if (!ke)  
1803          BUG (NULL);          BUG (NULL);
1804    
1805        ke = create_GpgKeyEdit (k->keyid);
1806      err = ke->delUserid (id);      err = ke->delUserid (id);
1807      if (err)      if (err)
1808          msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Delete User ID"), MB_ERR);
1809      else {      else {
1810          listview_del_item (lv, j);          listview_del_item (lv, pos);
1811          k->update = 1;          k->update = 1;
1812          status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));          status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1813      }      }
1814      delete ke;      delete ke;
1815      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1816  } /* do_editkey_deluid */  }
   
1817    
1818    
1819    /* Subclass routine for the subkey listview control to allow shortcuts. */
1820  static BOOL CALLBACK  static BOOL CALLBACK
1821  subkey_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )  subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1822  {  {
1823      switch( msg ) {      int virt_key = 0;
1824        winpt_key_t key;
1825    
1826        switch (msg) {
1827      case WM_KEYUP:      case WM_KEYUP:
1828          int virt_key = (int)wparam;          virt_key = (int)wparam;
1829          switch( virt_key ) {                  key = (winpt_key_t)keyedit_subkey_proc.opaque;
1830            if (!key || !key->key_pair)
1831                break;
1832    
1833            switch (virt_key) {
1834          case VK_DELETE:          case VK_DELETE:
1835              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1836                                  CB_SETCURSEL, CMD_DELKEY, 0 );                                  CB_SETCURSEL, CMD_DELKEY, 0);
1837              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1838              break;              break;
1839    
1840          case VK_INSERT:          case VK_INSERT:
1841              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1842                                  CB_SETCURSEL, CMD_ADDKEY, 0 );                                  CB_SETCURSEL, CMD_ADDKEY, 0);
1843              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1844              break;              break;
1845          }          }
1846      }      }
1847      return CallWindowProc( keyedit_subkey_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1848  } /* subkey_subclass_proc */  }
1849    
1850    
1851  static BOOL CALLBACK  static BOOL CALLBACK
1852  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1853  {  {
1854      switch( msg ) {      int virt_key = 0;
1855        winpt_key_t key;
1856    
1857        switch (msg) {
1858      case WM_KEYUP:      case WM_KEYUP:
1859          int virt_key = (int)wparam;          virt_key = (int)wparam;
1860            key = (winpt_key_t)keyedit_uid_proc.opaque;
1861            if (!key || !key->key_pair)
1862                break;
1863    
1864          switch (virt_key) {          switch (virt_key) {
1865          case VK_DELETE:          case VK_DELETE:
1866              SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
# Line 1836  uid_subclass_proc (HWND dlg, UINT msg, W Line 1875  uid_subclass_proc (HWND dlg, UINT msg, W
1875              break;              break;
1876          }          }
1877      }      }
1878      return CallWindowProc( keyedit_uid_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1879  } /* uid_subclass_proc */  }
1880    
1881    
1882    /* Enable the key @k when @enable is 1, disable it otherwise. */
1883  static void  static void
1884  do_editkey_enable_disable (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int enable)  do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1885                               listview_ctrl_t lv, int enable)
1886  {  {
1887      km_enable_disable_key (lv, dlg, 0, enable);      km_enable_disable_key (lv, dlg, 0, enable);
1888      k->update = 1;      k->update = 1;
1889  }  }
1890    
1891    
1892  /* Return default secret key. */  static void
1893  static gpgme_key_t  do_editkey_minimize (winpt_key_t k, HWND dlg)
1894  get_default_key (void)  {
1895  {      gpgme_error_t err;
1896      gpgme_key_t def_sk;      GpgKeyEdit *ke;
1897      char *keyid = get_gnupg_default_key ();  
1898        ke = create_GpgKeyEdit (k->keyid);
1899      get_seckey (keyid, &def_sk);      err = ke->minimizeKey ();
1900      free_if_alloc (keyid);      if (err)
1901      return def_sk;          msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1902        else {
1903            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1904            k->update = 1;
1905        }
1906        delete ke;
1907  }  }
1908    
1909    
1910  static void  static void
1911    do_editkey_clean (winpt_key_t k, HWND dlg)
1912    {
1913        gpgme_error_t err;
1914        GpgKeyEdit *ke;
1915        
1916        ke = create_GpgKeyEdit (k->keyid);
1917        err = ke->cleanKey ();
1918        if (err)
1919            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);  
1920        else {
1921            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1922            k->update = 1;
1923        }
1924        delete ke;
1925    }
1926    
1927    
1928    /* Start the dialog to list and display the status of all
1929       signatures for this key. */
1930    static void
1931  do_editkey_check (winpt_key_t k, HWND dlg)  do_editkey_check (winpt_key_t k, HWND dlg)
1932  {  {
1933      if (!k->ctx)      if (!k->ctx)
# Line 1877  static int Line 1943  static int
1943  do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)  do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1944  {  {
1945      gpgme_error_t err;      gpgme_error_t err;
1946        winpt_key_s signer;
1947      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1948      char *pass = NULL;      char *pass = NULL;
1949      char email[64], name[128];      char *defkey;
1950        char email[64], name[128], valid[32];
1951      int uid_index;      int uid_index;
1952      int cancel = 0;      int cancel = 0;
1953    
# Line 1888  do_editkey_sign_userid (winpt_key_t k, H Line 1956  do_editkey_sign_userid (winpt_key_t k, H
1956          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1957          return FALSE;          return FALSE;
1958      }      }
1959        listview_get_item_text (lv, uid_index, UID_COL_VALID, valid, sizeof (valid)-1);
1960        if (!strcmp (valid, _("Revoked")))
1961            return TRUE;
1962      if (mode == CMD_SIGN) {      if (mode == CMD_SIGN) {
1963          cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),          cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
1964                            _("Key Edit"), MB_QUEST_ASK);                            _("Key Edit"), MB_QUEST_ASK);
1965          if (cancel == IDNO)          if (cancel == IDNO)
1966              return FALSE;              return FALSE;
1967      }      }
   
1968      listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);      listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
1969      listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);      listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
1970      uid_index = do_find_userid (k->keyid, email, name, NULL);      uid_index = do_find_userid (k->keyid, email, name, NULL);
1971      if (k->is_protected) {  
1972          pass = request_passphrase (_("Key Edit"), 1, &cancel);      defkey = get_gnupg_default_key ();
1973        memset (&signer, 0, sizeof (signer));
1974        if (winpt_get_seckey (defkey, &signer)) {
1975            log_debug ("do_editkey_sign_userid: no default secret key.\r\n");
1976            free_if_alloc (defkey);
1977            return FALSE;
1978        }
1979        if (signer.is_protected) {
1980            pass = request_key_passphrase (signer.ctx, _("Key Edit"), &cancel);
1981          if (cancel)          if (cancel)
1982              return FALSE;              return FALSE;
1983      }      }
1984      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
1985      if (k->is_protected)      if (signer.is_protected)
1986          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1987      else      else
1988          ke->setNoPassphrase (true);          ke->setNoPassphrase (true);
1989      ke->setLocalUser (get_default_key ());      ke->setLocalUser (signer.ctx);
1990      err = ke->signUserid (uid_index,      err = ke->signUserid (uid_index,
1991                            mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,                            mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
1992                            0, NULL);                            0, NULL);
# Line 1941  lookup_cmd (HWND dlg) Line 2019  lookup_cmd (HWND dlg)
2019      return LB_ERR;      return LB_ERR;
2020  }  }
2021    
2022    
2023    
2024    gpgme_error_t key_get_revokers (winpt_key_t key, int reload,
2025                                    gpg_desig_rev_t *r_rev);
2026    
2027    /* Check if the key supports designated revokers and if
2028        secret keys exist to generate such a revoke cert. */
2029    static bool
2030    check_desig_rev (winpt_key_t key)
2031    {
2032        gpg_desig_rev_t rev, u;
2033        struct winpt_key_s sk;
2034    
2035        if (!key->ext->gloflags.has_desig_rev)
2036            return false;
2037        key_get_revokers (key, 0, &rev);
2038        for (u = rev; u; u = u->next) {
2039            memset (&sk, 0, sizeof (sk));
2040            if (!winpt_get_seckey (u->fpr+32, &sk))
2041                return true;
2042        }
2043        return false;
2044    }
2045    
2046    
2047    /* Use the gpg --desig-revoker command to create a revocation
2048       cert for a key that lists our key as a designated revoker. */
2049    static void
2050    gen_desig_revoke_cert (winpt_key_t key, HWND dlg)
2051    {
2052        const char *warn;
2053        char *inf, *p;
2054        int id;
2055    
2056        inf = km_key_get_info (key, 0);
2057        warn = _("Your keys is listed as a designated revoker for the key\n\n"
2058                 "%s\n\n"
2059                 "Are you sure you want to create a revocation certificate\n"
2060                 "which allow to revoke the key listed above?");
2061        p = new char[strlen (inf)+1+strlen (warn)+1];
2062        sprintf (p, warn, inf);
2063        free_if_alloc (inf);
2064    
2065        id = msg_box (dlg, p, _("Key Edit"), MB_YESNO|MB_ICONWARNING);
2066        free_if_alloc (p);
2067        if (id == IDNO)
2068            return;
2069    
2070        key->internal = 1;
2071        DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKE, dlg,
2072                        key_revoke_dlg_proc, (LPARAM)key);
2073    }
2074    
2075    
2076    /* Create tooltip control for the listview header. */
2077    static HWND
2078    create_header_tooltip (HWND dlg)
2079    {
2080        TOOLINFO ti;
2081        HWND tt;
2082    
2083        tt = CreateWindow (TOOLTIPS_CLASS, (LPSTR) NULL, TTS_ALWAYSTIP,
2084                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2085                            CW_USEDEFAULT,
2086                            NULL, (HMENU) NULL, glob_hinst, NULL);
2087        if (!tt)
2088            BUG (NULL);
2089        memset (&ti, 0, sizeof (ti));
2090        ti.cbSize = sizeof(TOOLINFO);
2091        ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS;    
2092        ti.hwnd = dlg;    
2093        ti.uId = (UINT) ListView_GetHeader (GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
2094        ti.hinst = 0;
2095        ti.lpszText = (char*)_("Capabilties: C = Certify, S = Sign, E = Encrypt, A = Authenticate");
2096        SendMessage(tt, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
2097        return tt;
2098    }
2099    
2100    
2101  /* Dialog box procedure for the edit key dialog. */  /* Dialog box procedure for the edit key dialog. */
2102  BOOL CALLBACK  BOOL CALLBACK
2103  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2104  {  {
2105      static winpt_key_t k;      static winpt_key_t k;
2106      static listview_ctrl_t lvsub = NULL, lvuid = NULL;      static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2107        static HWND tt;
2108      int cmd;      int cmd;
2109      HWND item;      HWND item;
2110    
2111      switch( msg ) {      switch (msg) {
2112      case WM_INITDIALOG:      case WM_INITDIALOG:
2113          k = (winpt_key_t)lparam;          k = (winpt_key_t)lparam;
2114          if (!k)          if (!k)
2115              BUG (NULL);              BUG (NULL);
2116          do_init_cmdlist (dlg, k->key_pair);          do_init_cmdlist (dlg, k->key_pair);
2117          lvsub = subkey_list_init (dlg, k);          lvsub = subkey_list_init (dlg, k);
         if( !lvsub )  
             BUG( NULL );  
2118          lvuid = userid_list_init (dlg, k);          lvuid = userid_list_init (dlg, k);
2119          if( !lvuid )          item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2120              BUG( NULL );          keyedit_subkey_proc.opaque = (void*)k;
         item = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );  
2121          keyedit_subkey_proc.dlg = dlg;          keyedit_subkey_proc.dlg = dlg;
2122          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2123          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2124          if( keyedit_subkey_proc.old ) {          if (keyedit_subkey_proc.old) {
2125              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_subkey_proc.current ) ) {              if (!SetWindowLong (item, GWL_WNDPROC,
2126                  msg_box( dlg, _("Could not set subkey window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_subkey_proc.current)) {
2127                  BUG( NULL );                  msg_box (dlg, "Could not set subkey window procedure.",
2128                             _("Key Edit"), MB_ERR);
2129                    BUG (NULL);
2130              }              }
2131          }          }
2132          item = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );          tt = create_header_tooltip (dlg);
2133            item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2134            keyedit_uid_proc.opaque = (void*)k;
2135          keyedit_uid_proc.dlg = dlg;          keyedit_uid_proc.dlg = dlg;
2136          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2137          keyedit_uid_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2138          if( keyedit_uid_proc.old ) {          if (keyedit_uid_proc.old) {
2139              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_uid_proc.current ) ) {              if (!SetWindowLong (item, GWL_WNDPROC,
2140                  msg_box( dlg, _("Could not set user ID window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_uid_proc.current)) {
2141                  BUG( NULL );                  msg_box (dlg, "Could not set user ID window procedure.",
2142                             _("Key Edit"), MB_ERR);
2143                    BUG (NULL);
2144              }              }
2145          }          }
2146          if (k->ctx->revoked) {          if (k->ctx->revoked) {
# Line 1989  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2150  keyedit_main_dlg_proc (HWND dlg, UINT ms
2150          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2151          SetDlgItemText (dlg, IDCANCEL, _("&Close"));          SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2152          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2153            SetDlgItemText (dlg, IDC_KEYEDIT_REVOKE, _("&Revoke..."));
2154            SetDlgItemText (dlg, IDOK, _("&OK"));
2155            if (!check_desig_rev (k))
2156                ShowWindow (GetDlgItem (dlg, IDC_KEYEDIT_REVOKE), SW_HIDE);
2157          SetWindowText (dlg, _("Key Edit"));          SetWindowText (dlg, _("Key Edit"));
2158          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
2159          center_window (dlg, NULL);          center_window (dlg, NULL);
2160          return TRUE;          return TRUE;
2161    
2162      case WM_DESTROY:      case WM_DESTROY:
2163          if( lvsub ) {          if (lvsub) {
2164              listview_release( lvsub );              listview_release (lvsub);
2165              lvsub = NULL;              lvsub = NULL;
2166          }          }
2167          if( lvuid ) {          if (lvuid) {
2168              listview_release( lvuid );              listview_release (lvuid);
2169              lvuid = NULL;              lvuid = NULL;
2170          }          }
2171          break;          break;
2172    
2173      case WM_NOTIFY:      case WM_NOTIFY:
2174          NMHDR * notify;          NMHDR *notify;
2175          notify = (NMHDR *)lparam;          notify = (NMHDR *)lparam;
2176          if (notify && notify->code == NM_DBLCLK &&          if (!notify || notify->idFrom != IDC_KEYEDIT_UIDLIST)
2177              notify->idFrom == IDC_KEYEDIT_UIDLIST)              break;
2178            if (notify->code == NM_DBLCLK)
2179              do_editkey_showpref (k, dlg, lvuid);              do_editkey_showpref (k, dlg, lvuid);
2180            else if (notify->code == NM_RCLICK && k->key_pair) {
2181                HMENU hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_WINPT_KEYEDIT));
2182                HMENU popup = GetSubMenu (hm, 0);
2183                POINT p;
2184    
2185                GetCursorPos (&p);
2186                TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, dlg, NULL);
2187                DestroyMenu (hm);
2188                DestroyMenu (popup);
2189            }
2190          break;          break;
2191    
2192      case WM_COMMAND:      case WM_COMMAND:
2193          switch( LOWORD( wparam ) ) {          switch (LOWORD (wparam)) {
2194          case IDOK:          case IDOK:
2195              cmd = lookup_cmd (dlg);              cmd = lookup_cmd (dlg);
2196              if (cmd == LB_ERR) {              if (cmd == LB_ERR) {
# Line 2032  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2208  keyedit_main_dlg_proc (HWND dlg, UINT ms
2208              case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;              case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2209              case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;              case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2210              case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;              case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2211              /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/              case CMD_SETPREF:/*do_editkey_setpref (k, dlg, lvuid);*/ break;
2212              case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;              case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2213              case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;              case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2214              case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;              case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
# Line 2048  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2224  keyedit_main_dlg_proc (HWND dlg, UINT ms
2224              case CMD_LSIGN: do_editkey_sign_userid (k, dlg,              case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2225                                                      lvuid, cmd);                                                      lvuid, cmd);
2226                              break;                              break;
2227                case CMD_CLEAN: do_editkey_clean (k, dlg); break;
2228                case CMD_MINIMIZE: do_editkey_minimize (k, dlg); break;
2229              }              }
2230              break;              break;          
2231    
2232          case IDCANCEL:          case IDCANCEL:
2233              EndDialog (dlg, FALSE);              EndDialog (dlg, FALSE);
# Line 2058  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2236  keyedit_main_dlg_proc (HWND dlg, UINT ms
2236          case IDC_KEYEDIT_HELP:          case IDC_KEYEDIT_HELP:
2237              do_show_help (dlg);              do_show_help (dlg);
2238              break;              break;
2239    
2240            case IDC_KEYEDIT_REVOKE:
2241                gen_desig_revoke_cert (k, dlg);
2242                break;
2243    
2244            case ID_KEYEDIT_UID_PRIM:
2245                do_editkey_primary (k, dlg, lvuid);
2246                break;
2247    
2248            case ID_KEYEDIT_UID_DEL:
2249                do_editkey_deluid (k, dlg, lvuid);
2250                break;
2251    
2252            case ID_KEYEDIT_UID_REV:
2253                do_editkey_revuid (k, dlg, lvuid);
2254                break;
2255          }          }
2256          break;          break;
2257      }      }
2258      return FALSE;      return FALSE;
2259  }  }
   

Legend:
Removed from v.187  
changed lines
  Added in v.236

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26