/[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 314 by twoaday, Sun May 13 09:44:03 2007 UTC
# Line 1  Line 1 
1  /* wptKeyEditDlgs.cpp - GPG key edit dialogs  /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2   *      Copyright (C) 2002-2006 Timo Schulz   *      Copyright (C) 2002-2007 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 12  Line 12 
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  
15   */   */
16  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
17  #include <config.h>  #include <config.h>
# Line 24  Line 20 
20  #include <windows.h>  #include <windows.h>
21  #include <commctrl.h>  #include <commctrl.h>
22  #include <time.h>  #include <time.h>
23  #include "resource.h"  #include <assert.h>
24    
25    #include "resource.h"
26  #include "wptTypes.h"  #include "wptTypes.h"
27  #include "wptW32API.h"  #include "wptW32API.h"
28  #include "wptVersion.h"  #include "wptVersion.h"
# Line 40  Line 37 
37  #include "wptKeyManager.h"  #include "wptKeyManager.h"
38  #include "wptRegistry.h"  #include "wptRegistry.h"
39  #include "wptKeyEdit.h"  #include "wptKeyEdit.h"
40    #include "StringBuffer.h"
41    
42    
43  /* All edit key commands. */  /* All edit key commands. */
44  enum keyedit_commands {      enum keyedit_commands {    
# Line 51  enum keyedit_commands { Line 50  enum keyedit_commands {
50      CMD_DELKEY,      CMD_DELKEY,
51      CMD_EXPIRE,      CMD_EXPIRE,
52      CMD_SHOWPREF,      CMD_SHOWPREF,
53      //CMD_SETPREF,      CMD_SETPREF,
54      CMD_PASSWD,      CMD_PASSWD,
55      CMD_PRIMARY,      CMD_PRIMARY,
56      CMD_TRUST,      CMD_TRUST,
# Line 61  enum keyedit_commands { Line 60  enum keyedit_commands {
60      CMD_ENABLE,          CMD_ENABLE,    
61      CMD_SIGN,      CMD_SIGN,
62      CMD_LSIGN,      CMD_LSIGN,
63      CMD_CHECK      CMD_CHECK,
64        CMD_CLEAN,
65        CMD_MINIMIZE
66  };  };
67    
68  struct cmdlist_s {  struct cmdlist_s {
# Line 88  struct cmdlist_s { Line 89  struct cmdlist_s {
89      {"SIGN", 0, CMD_SIGN},      {"SIGN", 0, CMD_SIGN},
90      {"LSIGN", 0, CMD_LSIGN},      {"LSIGN", 0, CMD_LSIGN},
91      {"CHECK", 0, CMD_CHECK},      {"CHECK", 0, CMD_CHECK},
92        {"CLEAN", 0, CMD_CLEAN},
93        {"MINIMIZE", 0, CMD_MINIMIZE},
94      {NULL, 0}        {NULL, 0}  
95  };  };
96    
# Line 115  enum uid_col_t { Line 118  enum uid_col_t {
118    
119  /* Key edit callback context. */  /* Key edit callback context. */
120  struct keyedit_cb_s {  struct keyedit_cb_s {
121      const char     *keyid;      HWND            parent; /* parent window handle. */
122      const char     *pass;      const char     *keyid;  /* key ID of the key. */
123        const char     *pass;   /* pointer to the passphrase. */
124      listview_ctrl_t lv;      listview_ctrl_t lv;
125        int             lv_pos;
126      void           *opaque;      void           *opaque;
127      unsigned int    finished:1;      unsigned int    finished:1;
128      unsigned int    is_protected:1;      unsigned int    is_protected:1;
# Line 127  typedef struct keyedit_cb_s *keyedit_cb_ Line 132  typedef struct keyedit_cb_s *keyedit_cb_
132    
133  /* Key generation callback context. */  /* Key generation callback context. */
134  struct keygen_cb_s {  struct keygen_cb_s {
135      int   bits;      int    bits;
136      int   algo;      int    algo;
137      u32   expire;      DWORD  expire; /* date of expiration or '0' for infinite valid. */
138      char *fpr;      char  *fpr;
139        char  *name;
140        char  *comment;
141        char  *email;
142  };  };
143  typedef struct keygen_cb_s *keygen_cb_t;  typedef struct keygen_cb_s *keygen_cb_t;
144    
145    /* Subclass context for the subkey list. */
146  static subclass_s keyedit_subkey_proc;  static subclass_s keyedit_subkey_proc;
147    
148    /* Subclass context for the user-id list. */
149  static subclass_s keyedit_uid_proc;  static subclass_s keyedit_uid_proc;
150    
151  int keygen_check_date (SYSTEMTIME *st);  int keygen_check_date (SYSTEMTIME *st);
152  void get_userid_preflist (char **r_prefs, int * r_flags);  void get_userid_preflist (const char *old_prefs, char **r_prefs, int *r_flags);
153  char* get_subkey_keyid (const char *keyid);  char* get_subkey_keyid (const char *keyid);
154    void ComboBox_AddString_utf8 (HWND cb, const char *txt);
155    
156    
157  /* Associate each key with a combo box entry.  /* Associate each key with a combo box entry.
158     Skip the key in @k. */     Skip the key in @k. */
159  static void  static void
160  do_init_keylist (HWND dlg, winpt_key_t k)  do_init_keylist (HWND dlg, const char *keyid)
161  {  {
162      gpg_keycache_t pub;      gpg_keycache_t pub;
163      gpgme_key_t key;      gpgme_key_t key;
164      const char *s, *kid;      const char *s, *kid;
     char *u;  
165      int i, n;      int i, n;
166    
167      pub = keycache_get_ctx (1);      pub = keycache_get_ctx (1);
     if (!pub)  
         BUG (0);  
   
168      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
169      while( !gpg_keycache_next_key (pub, 0, &key)) {      while (!gpg_keycache_next_key (pub, 0, &key)) {
170          if (key->expired || key->revoked ||          if (!key_is_useable (key) || key->invalid)
             key->disabled || key->invalid)  
171              continue;              continue;
172          s = key->uids->uid;          s = key->uids->uid;
173          kid = key->subkeys->keyid;          kid = key->subkeys->keyid;
174          if (!s || !strcmp (kid+8, k->keyid))          if (!s || !strcmp (kid+8, keyid))
175              continue;              continue;
176          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);  
177      }      }
178        
179      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
180      n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );      /* In the second loop, we set a key pointer for each element. */
181        n = SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0);
182      for (i = 0; i < n; i++) {      for (i = 0; i < n; i++) {
183          gpg_keycache_next_key (pub, 0, &key);          gpg_keycache_next_key (pub, 0, &key);
184          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 191  do_init_keylist (HWND dlg, winpt_key_t k
191  /* Add a new user-id to the list view @lv. */  /* Add a new user-id to the list view @lv. */
192  static void  static void
193  do_add_new_userid (listview_ctrl_t lv,  do_add_new_userid (listview_ctrl_t lv,
194                     const char *utf8_name, const char *email, const char *comment)                     const char *utf8_name, const char *email,
195                       const char *utf8_comment)
196  {  {
197      char *p, *uid;      StringBuffer p;
198      size_t n;      char *native;
199            
200      n = strlen (utf8_name) + strlen (email) + 16;      if (utf8_comment != NULL)
201      if (comment)          p = p + utf8_name + " (" + utf8_comment + ")";
         n += strlen (comment);  
     uid = utf8_to_native (utf8_name);  
     p = new char[n+1];  
     if (!p)  
         BUG (NULL);  
     if (comment)  
         sprintf (p, "%s (%s)", uid, comment);  
202      else      else
203          sprintf (p, "%s", uid);          p = p + utf8_name;
204      free (uid);      native = utf8_to_native (p.getBuffer ());
205    
206      listview_add_item (lv, "");      listview_add_item (lv, "");
207      listview_add_sub_item (lv, 0, 0, _("Ultimate" ));      listview_add_sub_item (lv, 0, UID_COL_VALID, _("Ultimate" ));
208      listview_add_sub_item (lv, 0, 1, p);      listview_add_sub_item (lv, 0, UID_COL_NAME, native);
209      listview_add_sub_item (lv, 0, 2, email && *email? email : "");      listview_add_sub_item (lv, 0, UID_COL_EMAIL, email && *email? email : "");
210      listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));      listview_add_sub_item (lv, 0, UID_COL_CREATION,
211      free_if_alloc (p);                             get_key_created (time (NULL)));
212        free_if_alloc (native);
213  }  }
214    
215    
# Line 217  static void Line 217  static void
217  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)
218  {  {
219      char info[128], keyid[32];      char info[128], keyid[32];
220      const char * expdate, * s;      const char *expdate, *s, *kid;
221      int n;      int n;
222            
223      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
224      _snprintf (info, sizeof info-1, "%d-bit %s",      _snprintf (info, DIM (info)-1, "%d-bit %s", keygen->bits,
                keygen->bits,  
225                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
226      _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+8);      kid = get_keyid_from_fpr (keygen->fpr);
227        _snprintf (keyid, DIM (keyid)-1, "0x%s", kid);
228        s = get_key_created (time (NULL));
229      n = listview_count_items (lv, 0);      n = listview_count_items (lv, 0);
230      listview_add_item_pos (lv, n);      listview_add_item_pos (lv, n);
231      listview_add_sub_item (lv, n, 0, info);      listview_add_sub_item (lv, n, SUBK_COL_DESC, info);
232      listview_add_sub_item (lv, n, 1, keyid);      listview_add_sub_item (lv, n, SUBK_COL_KEYID, keyid);
233      listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));      listview_add_sub_item (lv, n, SUBK_COL_CREATION, s);
234      listview_add_sub_item (lv, n, 3, expdate);      listview_add_sub_item (lv, n, SUBK_COL_EXPIRES, expdate);
235      if (flags & KM_FLAG_REVOKED)      if (flags & KM_FLAG_REVOKED)
236          s = _("Revoked");                s = _("Revoked");      
237      else if (flags & KM_FLAG_EXPIRED)      else if (flags & KM_FLAG_EXPIRED)
238          s = _("Expired");          s = _("Expired");
239      else      else
240          s = _("OK");          s = _("OK");
241      listview_add_sub_item (lv, n, 4, s);      listview_add_sub_item (lv, n, SUBK_COL_STATUS, s);
242  }  }
243    
244    
# Line 249  static int Line 250  static int
250  do_find_userid (const char *keyid, const char *email,  do_find_userid (const char *keyid, const char *email,
251                  const char *name, gpg_uid_info_t *r_inf)                  const char *name, gpg_uid_info_t *r_inf)
252  {  {
253      GpgKeyEdit *ke;      GpgKeyEdit ke;
254      gpgme_error_t err;      gpgme_error_t err;
255      gpg_uid_info_t inf, ui;      gpg_uid_info_t inf, ui;
     char *ui_name = NULL;  
256      int pos = -1;      int pos = -1;
257    
258      ke = new GpgKeyEdit (keyid);      ke.setKeyID (keyid);
259      if (!ke)      err = ke.getUseridInfo (&inf);
         BUG (NULL);  
     err = ke->getUseridInfo (&inf);  
     delete ke;  
260      if (err) {      if (err) {
261          log_box (_("user ID"), MB_ERR,          log_box (_("user ID"), MB_ERR,
262                  _("Could not get key information for: \"%s\":\n%s"),                   _("Could not get key information for: \"%s\":\n%s"),
263                  name, gpgme_strerror (err));                   name, gpgme_strerror (err));
264          return -1;          return -1;
265      }      }
266    
267      for (ui = inf; ui; ui = ui->next) {      for (ui = inf; ui; ui = ui->next) {
268          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) {  
269              if (!strcmp (ui->email, email) &&              if (!strcmp (ui->email, email) &&
270                  !strncmp (ui_name, name, strlen (name))) {                  !strncmp (ui->name, name, strlen (name))) {
271                  pos = ui->index;                  pos = ui->index;
272                  break;                  break;
273              }              }
274              continue;              continue;
275          }          }
276          if (ui->email) {          if (email && ui->email) {
277              if (!strcmp (ui->email, email)) {              if (!strcmp (ui->email, email)) {
278                  pos = ui->index;                  pos = ui->index;
279                  break;                  break;
# Line 287  do_find_userid (const char *keyid, const Line 282  do_find_userid (const char *keyid, const
282                 as the fallbck when no email address is available. */                 as the fallbck when no email address is available. */
283              continue;              continue;
284          }          }
285          if (ui_name && name && !strcmp (ui_name, name)) {          if (ui->name && name && !strcmp (ui->name, name)) {
286              pos = ui->index;              pos = ui->index;
287              break;              break;
288          }          }
# Line 296  do_find_userid (const char *keyid, const Line 291  do_find_userid (const char *keyid, const
291          *r_inf = inf;          *r_inf = inf;
292      else      else
293          gpg_uid_info_release (inf);          gpg_uid_info_release (inf);
     safe_free (ui_name);  
294      return pos;      return pos;
295  }  }
296    
# Line 312  is_jpg_file (const char *fname) Line 306  is_jpg_file (const char *fname)
306      fp = fopen (fname, "rb");      fp = fopen (fname, "rb");
307      if (!fp)      if (!fp)
308          return false;          return false;
309      n = fread (buf, 1, 10, fp);      n = fread (buf, 1, DIM (buf), fp);
310      fclose (fp);      fclose (fp);
311      if (n < 10)      if (n < DIM (buf))
312          return false;          return false;
313      return buf[6] == 'J' && buf[7] == 'F' &&      return buf[6] == 'J' && buf[7] == 'F' &&
314             buf[8] == 'I' && buf[9] == 'F';             buf[8] == 'I' && buf[9] == 'F';
# Line 325  is_jpg_file (const char *fname) Line 319  is_jpg_file (const char *fname)
319  BOOL CALLBACK  BOOL CALLBACK
320  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
321  {  {
322      static winpt_key_t k;              static keyedit_cb_t cb;
323      GpgKeyEdit *ke;      gpgme_error_t err;
324      gpgme_error_t ec;          const char *s;    
325      const char * s;          char file[128];
     char pwd[128], file[128];  
326      int id;      int id;
327    
328      switch( msg ) {      switch (msg) {
329      case WM_INITDIALOG:      case WM_INITDIALOG:
330          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
331          if (!k)          if (!cb)
332              BUG (NULL);              BUG (NULL);
333          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 advised."));
334          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."));
335          SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));          SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
336          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
# Line 345  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 338  keyedit_addphoto_dlg_proc (HWND dlg, UIN
338          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
339          break;          break;
340    
     case WM_DESTROY:  
         break;  
   
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE)  
             EndDialog (dlg, TRUE);  
         break;  
   
341      case WM_COMMAND:      case WM_COMMAND:
342          switch( LOWORD( wparam ) ) {          switch( LOWORD (wparam)) {
   
343          case IDC_ADDPHOTO_SELFILE:          case IDC_ADDPHOTO_SELFILE:
344              s = get_fileopen_dlg (dlg, _("Select Image File"),              s = get_fileopen_dlg (dlg, _("Select Image File"),
345                                    "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 355  keyedit_addphoto_dlg_proc (HWND dlg, UIN
355    
356          case IDOK:          case IDOK:
357              if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){              if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
358                  msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);                  msg_box (dlg, _("Please enter a file name."),
359                             _("Add Photo"), MB_ERR);
360                  return FALSE;                  return FALSE;
361              }              }
362              if (get_file_size (file) == 0 || get_file_size (file) > 6144 ) {              if (get_file_size (file) == 0 || get_file_size (file) > 6144) {
363                  id = msg_box (dlg, _("The JPEG is really large.\n"                  id = msg_box (dlg, _("The JPEG is really large.\n"
364                                       "Are you sure you want to use it?"),                                       "Are you sure you want to use it?"),
365                                       _("Add Photo"), MB_YESNO|MB_INFO);                                       _("Add Photo"), MB_YESNO|MB_INFO);
366                  if (id == IDNO)                  if (id == IDNO)
367                      return TRUE;                      return TRUE;
368              }              }
369              if (k->is_protected &&              
370                  !GetDlgItemText (dlg, IDC_ADDPHOTO_PASS, pwd, sizeof (pwd)-1)) {              {
371                  msg_box (dlg, _("Please enter a passphrase."), _("Add Photo"), MB_ERR);                  GpgKeyEdit ke;
372                  return FALSE;                  
373                    ke.setKeyID (cb->keyid);
374                    if (cb->pass)
375                        ke.setPassphrase (cb->pass);
376                    else
377                        ke.setNoPassphrase (true);
378                    err = ke.addPhotoid (file);
379              }              }
380              ke = new GpgKeyEdit (k->keyid);              if (err) {
381              if (!ke)                  msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
                 BUG (NULL);  
             if (k->is_protected)  
                 ke->setPassphrase (pwd);  
             else  
                 ke->setNoPassphrase (true);  
             ec = ke->addPhotoid (file);  
             delete ke;  
             wipememory (pwd, sizeof (pwd));  
             if (ec) {  
                 msg_box (dlg, gpgme_strerror (ec), _("Add Photo"), MB_ERR );  
382                  return FALSE;                  return FALSE;
383              }              }
384              else {              else {
385                  k->update = 1;                  cb->finished = 1;
386                  msg_box (dlg, _("Photo successfully added."),                  msg_box (dlg, _("Photo successfully added."),
387                           _("GnuPG Status"), MB_OK);                           _("GnuPG Status"), MB_OK);
388              }              }
# Line 422  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 403  keyedit_addphoto_dlg_proc (HWND dlg, UIN
403  BOOL CALLBACK  BOOL CALLBACK
404  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
405  {  {
406      static winpt_key_t k;      static keyedit_cb_t cb;
     static gpgme_key_t seckey;  
407      gpgme_error_t err;      gpgme_error_t err;
408      GpgKeyEdit *ke;      char *uid=NULL;
     char uid[128], pwd[128];  
409    
410      switch (msg) {      switch (msg) {
411      case WM_INITDIALOG:      case WM_INITDIALOG:
412          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
413          if (!k)          if (!cb)
             BUG (NULL);  
         if (get_seckey (k->keyid, &seckey))  
414              BUG (NULL);              BUG (NULL);
415          if (!k->is_protected)          do_init_keylist (dlg, cb->keyid);
             EnableWindow (GetDlgItem (dlg, IDC_ADDREV_PASS), FALSE);  
         do_init_keylist (dlg, k);  
416          SetDlgItemText (dlg, IDC_ADDREV_INF,          SetDlgItemText (dlg, IDC_ADDREV_INF,
417                          _("Appointing a key as designated revoker cannot be undone."));                          _("Appointing a key as designated revoker cannot be undone."));
418          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
# Line 445  keyedit_addrevoker_dlg_proc (HWND dlg, U Line 420  keyedit_addrevoker_dlg_proc (HWND dlg, U
420          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
421          SetWindowText (dlg, _("Add Revoker"));          SetWindowText (dlg, _("Add Revoker"));
422          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
423          break;          center_window (dlg, cb->parent);
   
     case WM_DESTROY:      
         break;  
   
     case WM_SYSCOMMAND:  
         if( LOWORD (wparam) == SC_CLOSE )  
             EndDialog( dlg, TRUE );  
424          break;          break;
425    
426      case WM_COMMAND:      case WM_COMMAND:
427          switch( LOWORD( wparam ) ) {          switch (LOWORD (wparam)) {
428          case IDOK:                    case IDOK:
429              if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {              if (!GetDlgItemText_utf8 (dlg, IDC_ADDREV_KEYLIST, &uid)) {
430                  msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );                  msg_box (dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR);
431                  return FALSE;                  return FALSE;
432              }              }
433                    
434              if( k->is_protected ) {              {
435                  if( !GetDlgItemText( dlg, IDC_ADDREV_PASS, pwd, sizeof pwd-1 ) ) {                  GpgKeyEdit ke;
436                      msg_box( dlg, _("Please enter the passphrase."), _("Add Revoker"), MB_ERR );                  
437                      return FALSE;                  ke.setKeyID (cb->keyid);
438                  }                  if (cb->pass)
439              }                      ke.setPassphrase (cb->pass);
440              ke = new GpgKeyEdit (k->keyid);                  else
441              if (k->is_protected)                      ke.setNoPassphrase (true);
442                  ke->setPassphrase (pwd);                  err = ke.addDesignatedRevoker (uid);
443              else              }
444                  ke->setNoPassphrase (true);  
445              err = ke->addDesignatedRevoker (uid);              safe_free (uid);
             delete ke;  
             wipememory (pwd, sizeof (pwd));  
446              if (err) {              if (err) {
447                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
448                  return TRUE;                  return TRUE;
449              }              }
450              else {              else {
451                  k->update = 1;                  cb->finished = 1;
452                  msg_box (dlg, _("Revoker successfully addded."),                  msg_box (dlg, _("Revoker successfully addded."),
453                           _("GnuPG Status"), MB_OK);                           _("GnuPG Status"), MB_OK);
454              }              }
# Line 504  BOOL CALLBACK Line 470  BOOL CALLBACK
470  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
471  {  {
472      static keyedit_cb_t ctx;      static keyedit_cb_t ctx;
473        keygen_cb_t keygen;
474      gpgme_error_t err;      gpgme_error_t err;
     GpgKeyEdit *ke;  
475      char *utf8_name = NULL;      char *utf8_name = NULL;
476      char name[128], email[128], comment[128];      char *utf8_comment = NULL;
477        char email[128];
478      int rc;      int rc;
479            
480      switch (msg) {      switch (msg) {
481      case WM_INITDIALOG:      case WM_INITDIALOG:
482          ctx = (keyedit_cb_t)lparam;          ctx = (keyedit_cb_t)lparam;
483          if( !ctx )          if (!ctx)
484              dlg_fatal_error(dlg, "Could not get dialog param!");              dlg_fatal_error(dlg, "Could not get dialog param!");
485          SetWindowText (dlg, _("Add new User ID"));          SetWindowText (dlg, _("Add new User ID"));
486          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
# Line 521  keyedit_adduid_dlg_proc (HWND dlg, UINT Line 488  keyedit_adduid_dlg_proc (HWND dlg, UINT
488          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
489          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
490          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
491          return FALSE;          center_window (dlg, ctx->parent);
           
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE)  
             EndDialog(dlg, TRUE);  
492          return FALSE;          return FALSE;
493                    
494      case WM_COMMAND:      case WM_COMMAND:
495          switch ( LOWORD( wparam ) )  {          switch ( LOWORD( wparam ) )  {
496          case IDOK:          case IDOK:
497              rc = GetDlgItemText( dlg, IDC_ADDUID_NAME, name, sizeof name-1 );              keygen = (keygen_cb_t)ctx->opaque;
498                rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_NAME, &utf8_name);
499              if (!rc || rc < 5) {              if (!rc || rc < 5) {
500                  msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );                  msg_box (dlg, _("Please enter a name (min. 5 chars.)"),
501                             _("UserID"), MB_ERR);
502                    free_if_alloc (utf8_name);
503                  return FALSE;                  return FALSE;
504              }              }
505              if (strchr (name, '@')) {              if (strchr (utf8_name, '@')) {
506                  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"),
507                             _("UserID"), MB_INFO);
508                    free_if_alloc (utf8_name);
509                  return FALSE;                  return FALSE;
510              }              }
511                                      
512              if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {              if( !GetDlgItemText (dlg, IDC_ADDUID_EMAIL, email, sizeof (email) -1)) {
513                  msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );                  msg_box (dlg, _("Please enter an email address."), _("UserID"), MB_ERR);
514                    free_if_alloc (utf8_name);
515                  return FALSE;                  return FALSE;
516              }              }
517              if (!strchr (email, '@' ) || strchr (email, ' ')) {              if (check_email_address (email)) {
518                  msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);                  msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
519                    free_if_alloc (utf8_name);
520                  return FALSE;                  return FALSE;
521              }              }
522                            
523              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);  
524    
525              ke = new GpgKeyEdit (ctx->keyid);              {
526              if (!ke)                  GpgKeyEdit ke;
527                  BUG (NULL);                  
528              if (ctx->is_protected)                  ke.setKeyID (ctx->keyid);
529                  ke->setPassphrase (ctx->pass);                  if (ctx->is_protected)
530              else                      ke.setPassphrase (ctx->pass);
531                  ke->setNoPassphrase (true);                  else
532              err = ke->addUserid (utf8_name? utf8_name : name,                      ke.setNoPassphrase (true);
533                                   rc > 0? comment : NULL, email);                  err = ke.addUserid (utf8_name, utf8_comment, email);
534                }
535              if (err)              if (err)
536                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
537              else {              else {
538                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
539                  ctx->finished = 1;                  ctx->finished = 1;
540                    /* The caller releases this items later. */
541                    keygen->name = utf8_name;
542                    keygen->comment = utf8_comment;
543                    keygen->email = m_strdup (email);
544              }              }
             delete ke;        
             if (!err && ctx->lv)  
                 do_add_new_userid (ctx->lv, utf8_name, email, rc?comment : NULL);  
             free (utf8_name);  
545              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
546              return TRUE;              return TRUE;
547                            
# Line 587  keyedit_adduid_dlg_proc (HWND dlg, UINT Line 556  keyedit_adduid_dlg_proc (HWND dlg, UINT
556  }  }
557    
558    
559    /* Initalize a combo box with default key sizes (1024-4096). */
560  static void  static void
561  init_keysize_box (HWND dlg, int ctlid)  init_keysize_box (HWND dlg, int ctlid)
562  {  {
563        /* Array with standard key-length in bits. */
564      const char *sizelist[] = {      const char *sizelist[] = {
565          "1024", "1536", "2048", "2560", "3072", "3854", "4096", NULL          "1024", "1536",
566            "2048", "3072",
567            "4096", NULL
568      };      };
569      int i;      int i;
570    
571      for (i=0; sizelist[i] != NULL; i++)      for (i=0; sizelist[i] != NULL; i++)
572          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0, (LPARAM)(char*)sizelist[i]);          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
573                                (LPARAM)(char*)sizelist[i]);
574      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
575  }  }
576    
577    
578  static int  static int
579  get_keysize_from_box (HWND dlg, int ctlid)  get_keysize_from_box (HWND dlg, int ctlid)
580  {  {
# Line 609  get_keysize_from_box (HWND dlg, int ctli Line 585  get_keysize_from_box (HWND dlg, int ctli
585      if (pos == CB_ERR)      if (pos == CB_ERR)
586          return -1;          return -1;
587      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
588      return atol (buf);      return atoi (buf);
589  }  }
590    
591    
# Line 632  BOOL CALLBACK Line 608  BOOL CALLBACK
608  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
609  {  {
610      static keyedit_cb_t ctx;      static keyedit_cb_t ctx;
611      static keygen_cb_t keygen;      keygen_cb_t keygen;
     GpgKeyEdit *ke;  
612      gpgme_error_t err;      gpgme_error_t err;
613      SYSTEMTIME st;      SYSTEMTIME st;
614      HWND lb;      HWND hwnd;
615      int index, size, valid;      int index, size, valid;
616            
617      switch (msg) {      switch (msg) {
618      case WM_INITDIALOG:      case WM_INITDIALOG:
619          ctx = (keyedit_cb_t)lparam;          ctx = (keyedit_cb_t)lparam;
620          if (!ctx)          if (!ctx)
621              dlg_fatal_error (dlg, "Could not get dialog param!");              BUG (NULL);
         keygen = (keygen_cb_t)ctx->opaque;  
   
622          SetWindowText (dlg, _("Add new Subkey"));          SetWindowText (dlg, _("Add new Subkey"));
623          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
624          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 626  keyedit_addsubkey_dlg_proc (HWND dlg, UI
626          SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
627          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
628    
629          lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);          hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
630          listbox_add_string (lb, "DSA (sign only)");          listbox_add_string (hwnd, "DSA (sign only)");
631          listbox_add_string (lb, "ElGamal (encrypt only)");          listbox_add_string (hwnd, "ElGamal (encrypt only)");
632          listbox_add_string (lb, "RSA (sign only)");          listbox_add_string (hwnd, "RSA (sign only)");
633          listbox_add_string (lb, "RSA (encrypt only)");          listbox_add_string (hwnd, "RSA (encrypt only)");
634          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
635          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
636          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
637          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
638          return FALSE;          center_window (dlg, ctx->parent);
           
     case WM_SYSCOMMAND:  
         if (LOWORD (wparam) == SC_CLOSE) {  
             EndDialog (dlg, TRUE);  
         }  
639          return FALSE;          return FALSE;
640                    
641      case WM_COMMAND:      case WM_COMMAND:
# Line 680  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 648  keyedit_addsubkey_dlg_proc (HWND dlg, UI
648          }          }
649          if (HIWORD (wparam) == LBN_SELCHANGE &&          if (HIWORD (wparam) == LBN_SELCHANGE &&
650              LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {              LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {
651                /* If the selected algorithm is DSA, automatically set the
652                   size to 1024, otherwise use the default keysize. */
653              index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);              index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);
654              if (index == 0)              SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL,
655                  SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);                                  index==0? 0 : 2, 0);
656          }          }
657    
658          switch (LOWORD (wparam)) {          switch (LOWORD (wparam)) {
659          case IDOK:          case IDOK:
660              lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);              keygen = (keygen_cb_t)ctx->opaque;
661              switch (listbox_get_cursel (lb)) {              assert (keygen);
662                hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
663                /* Map combo box numbers to GPG answers. */
664                switch (listbox_get_cursel (hwnd)) {
665              case 0: index = 2; break;              case 0: index = 2; break;
666              case 1: index = 4; break;              case 1: index = 4; break;
667              case 2: index = 5; break;              case 2: index = 5; break;
668              case 3: index = 6; break;              case 3: index = 6; break;
669              default:              default:
670                  msg_box (dlg, _("Please select one entry."), _("Add Subkey"), MB_ERR);                  msg_box (dlg, _("Please select one entry."),
671                             _("Add Subkey"), MB_ERR);
672                  return FALSE;                  return FALSE;
673              }              }
674              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
675              if (index == 2 && size != 1024) {              if (index == 2 && size != 1024) {
676                  msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),                  msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
677                           _("Add Subkey"), MB_INFO);                           _("Add Subkey"), MB_INFO);
678                  size = 1024;                  size = 1024;
679              }              }
680    
681              DateTime_GetSystemtime (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), &st);              hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
682                DateTime_GetSystemtime (hwnd, &st);
683              valid = w32_mktime (&st) - time (NULL);              valid = w32_mktime (&st) - time (NULL);
684              valid /= 86400;              valid /= 86400;
685    
# Line 718  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 693  keyedit_addsubkey_dlg_proc (HWND dlg, UI
693              if (valid > 0)              if (valid > 0)
694                  keygen->expire = time (NULL) + valid*24*60*60;                  keygen->expire = time (NULL) + valid*24*60*60;
695    
696              ke = new GpgKeyEdit (ctx->keyid);              {
697              if (!ke)                  GpgKeyEdit ke;
698                  BUG (NULL);                  
699              ke->setCallback (keygen_cb, NULL);                  ke.setKeyID (ctx->keyid);
700              if (ctx->is_protected)                  ke.setCallback (keygen_cb, NULL);
701                  ke->setPassphrase (ctx->pass);                  if (ctx->is_protected)
702              else                      ke.setPassphrase (ctx->pass);
703                  ke->setNoPassphrase (true);                  else
704              keygen_cb_dlg_create ();                      ke.setNoPassphrase (true);
705                    keygen_cb_dlg_create ();
706              err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);                  err = ke.addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
707                }
708              keygen->fpr = get_subkey_keyid (ctx->keyid);              keygen->fpr = get_subkey_keyid (ctx->keyid);
709              keygen_cb_dlg_destroy ();              keygen_cb_dlg_destroy (1);
             keygen_cb (NULL, NULL, 0, 0, 0); /* flush */  
710              if (err)              if (err)
711                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
712              else {              else {
713                  msg_box (dlg, _("Subkey successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("Subkey successfully added."),
714                  if (ctx->lv)                           _("GnuPG Status"), MB_OK);
                     do_add_new_subkey (ctx->lv, keygen, 0);  
715                  ctx->finished = 1;                  ctx->finished = 1;
716              }              }
             delete ke;  
717              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
718              return TRUE;              return TRUE;
719                            
# Line 759  BOOL Line 732  BOOL
732  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)
733  {  {
734      keyedit_cb_s cb;      keyedit_cb_s cb;
735        keygen_cb_s keygen;
736      char *pass = NULL;      char *pass = NULL;
737      int cancel = 0;      int cancel = 0;
738    
739      if (!k->key_pair) {      if (!k->key_pair) {
740          msg_box( dlg, _("There is no secret key available!"), _("Add user ID"), MB_ERR );          msg_box (dlg, _("There is no secret key available!"),
741                     _("Add user ID"), MB_ERR);
742          return FALSE;          return FALSE;
743      }      }
744    
745      if (k->is_protected) {      if (k->is_protected) {
746          pass = request_passphrase( _("Key Edit"), 1, &cancel );          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
747          if (cancel)          if (cancel)
748              return FALSE;              return FALSE;
749      }      }
750              
751      memset (&cb, 0, sizeof cb);      memset (&keygen, 0, sizeof (keygen));
752        memset (&cb, 0, sizeof (cb));
753        cb.parent = dlg;
754        cb.opaque = &keygen;
755      cb.is_protected = k->is_protected;      cb.is_protected = k->is_protected;
756      cb.pass = pass;      cb.pass = pass;
     cb.lv = lv;  
757      cb.keyid = k->keyid;      cb.keyid = k->keyid;
758      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
759                        dlg, keyedit_adduid_dlg_proc,                                dlg, keyedit_adduid_dlg_proc,        
760                        (LPARAM)&cb, _("Add user ID"),                        (LPARAM)&cb, _("Add user ID"),
761                        IDS_WINPT_KEYEDIT_ADDUID);                        IDS_WINPT_KEYEDIT_ADDUID);
762        if (lv != NULL && cb.finished)
763            do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
764      if (cb.finished)      if (cb.finished)
765          k->update = 1;          k->update = 1;
766    
767        free_if_alloc (keygen.name);
768        free_if_alloc (keygen.email);
769        free_if_alloc (keygen.comment);
770      sfree_if_alloc (pass);      sfree_if_alloc (pass);
771      return TRUE;      return TRUE;
772  }  }
773    
774    
775    /* Return the keyID of the last subkey. */
776  char*  char*
777  get_subkey_keyid (const char *keyid)  get_subkey_keyid (const char *keyid)
778  {  {
# Line 798  get_subkey_keyid (const char *keyid) Line 780  get_subkey_keyid (const char *keyid)
780      gpgme_key_t key;      gpgme_key_t key;
781      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
782      gpgme_subkey_t subk;      gpgme_subkey_t subk;
783      char *kid;      char *kid = NULL;
784    
785      err = gpgme_new (&ctx);      err = gpgme_new (&ctx);
786      if (err)      if (err)
# Line 808  get_subkey_keyid (const char *keyid) Line 790  get_subkey_keyid (const char *keyid)
790      if (err)      if (err)
791          return NULL;          return NULL;
792      subk = get_nth_key (key, count_subkeys (key));      subk = get_nth_key (key, count_subkeys (key));
793      kid = strdup (subk->keyid);      if (subk != NULL)
794            kid = strdup (subk->keyid);
795      gpgme_key_release (key);      gpgme_key_release (key);
796      return kid;      return kid;
797  }  }
# Line 823  keyedit_add_subkey (winpt_key_t k, HWND Line 806  keyedit_add_subkey (winpt_key_t k, HWND
806      int cancel = 0;      int cancel = 0;
807    
808      if (!k->key_pair) {      if (!k->key_pair) {
809          msg_box (dlg, _("There is no secret key available!"), _("Add Subkey"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"),
810                     _("Add Subkey"), MB_ERR);
811          return FALSE;          return FALSE;
812      }      }
813      if (k->is_protected) {      if (k->is_protected) {
814          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
815          if (cancel)          if (cancel)
816              return FALSE;              return FALSE;
817      }      }
818    
819      memset (&keygen, 0, sizeof (keygen));      memset (&keygen, 0, sizeof (keygen));
820      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
     cb.lv = lv;  
821      cb.keyid = k->keyid;      cb.keyid = k->keyid;
822      cb.is_protected = k->is_protected;      cb.is_protected = k->is_protected;
823      cb.pass = pass;      cb.pass = pass;
# Line 843  keyedit_add_subkey (winpt_key_t k, HWND Line 826  keyedit_add_subkey (winpt_key_t k, HWND
826                        dlg, keyedit_addsubkey_dlg_proc,                        dlg, keyedit_addsubkey_dlg_proc,
827                        (LPARAM)&cb, _("Add new Subkey"),                        (LPARAM)&cb, _("Add new Subkey"),
828                        IDS_WINPT_KEYEDIT_ADDSUBKEY);                        IDS_WINPT_KEYEDIT_ADDSUBKEY);
829      safe_free (keygen.fpr);      if (lv != NULL && cb.finished)
830            do_add_new_subkey (lv, &keygen, 0);
831      if (cb.finished)      if (cb.finished)
832          k->update = 1;          k->update = 1;
833    
834      sfree_if_alloc (pass);          safe_free (keygen.fpr);
835        sfree_if_alloc (pass);
836      return cb.finished? TRUE: FALSE;      return cb.finished? TRUE: FALSE;
837  }  }
838    
839    
840    /* Set the preferred keyserver of the given key @k. */
841  BOOL  BOOL
842  keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)  keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)
843  {  {
844      GpgKeyEdit *ke;      GpgKeyEdit ke;
845      gpgme_error_t err;      gpgme_error_t err;
846      struct URL_ctx_s *url;      struct URL_ctx_s *url;
847      char *pass;      char *pass = NULL;
848    
849      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
850      if (url->cancel == 1) {      if (url->cancel == 1) {
# Line 866  keyedit_set_pref_keyserver (winpt_key_t Line 852  keyedit_set_pref_keyserver (winpt_key_t
852          return FALSE;          return FALSE;
853      }      }
854    
855      pass = request_passphrase (_("Key Edit"), 1, &url->cancel);      pass = request_key_passphrase (k->ctx, _("Key Edit"), &url->cancel);
856      if (url->cancel) {      if (url->cancel) {
857          delete url;          delete url;
858          return FALSE;          return FALSE;
859      }      }
860    
861      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
     if (!ke)  
         BUG (NULL);  
862      if (k->is_protected)      if (k->is_protected)
863          ke->setPassphrase (pass);          ke.setPassphrase (pass);
864      else      else
865          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
866      err = ke->setPreferredKeyserver (-1, url->url);      err = ke.setPreferredKeyserver (-1, url->url);
867      if (!err)      if (!err)
868          msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);          msg_box (dlg, _("Preferred keyserver successfully set."),
869                     _("Key Edit"), MB_OK);
870        else
871            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
872    
873      sfree_if_alloc (pass);      sfree_if_alloc (pass);
     delete ke;  
874      delete url;      delete url;
875      return err == 0? 0 : WPTERR_GENERAL;      return err == 0? 0 : WPTERR_GENERAL;
876  }  }
# Line 895  keyedit_set_pref_keyserver (winpt_key_t Line 881  keyedit_set_pref_keyserver (winpt_key_t
881  BOOL  BOOL
882  keyedit_add_photo (winpt_key_t k, HWND dlg)  keyedit_add_photo (winpt_key_t k, HWND dlg)
883  {  {
884        keyedit_cb_s cb;
885        char *pass = NULL;
886        int cancel;
887        
888      if (!k->key_pair) {      if (!k->key_pair) {
889          msg_box (dlg, _("There is no secret key available!"),          msg_box (dlg, _("There is no secret key available!"),
890                   _("Add Photo"), MB_ERR);                   _("Add Photo"), MB_ERR);
891          return FALSE;          return FALSE;
892      }      }
893    
894        memset (&cb, 0, sizeof (cb));
895        if (k->is_protected) {
896            pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
897            if (cancel)
898                return FALSE;
899        }
900        cb.parent = dlg;
901        cb.pass = pass;
902        cb.keyid = k->keyid;
903      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
904                      keyedit_addphoto_dlg_proc, (LPARAM)k);                      keyedit_addphoto_dlg_proc, (LPARAM)&cb);
905    
906        if (cb.finished)
907            k->update = 1;
908        sfree_if_alloc (pass);    
909      return TRUE;      return TRUE;
910  }  }
911    
# Line 909  keyedit_add_photo (winpt_key_t k, HWND d Line 913  keyedit_add_photo (winpt_key_t k, HWND d
913  BOOL  BOOL
914  keyedit_add_revoker (winpt_key_t k, HWND dlg)  keyedit_add_revoker (winpt_key_t k, HWND dlg)
915  {  {
916        keyedit_cb_s cb;
917        char *pass = NULL;
918        int cancel;
919    
920      if (!k->key_pair) {      if (!k->key_pair) {
921          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);
922          return FALSE;          return FALSE;
923      }      }
924    
925        if (k->is_protected) {
926            pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
927            if (cancel)
928                return FALSE;
929        }
930    
931        memset (&cb, 0, sizeof (cb));
932        cb.parent = dlg;
933        cb.is_protected = k->is_protected;
934        cb.keyid = k->keyid;
935        cb.pass = pass;
936      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
937                      keyedit_addrevoker_dlg_proc, (LPARAM)k);                      keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
938    
939        if (cb.finished)
940            k->update = 1;
941        sfree_if_alloc (pass);
942      return TRUE;      return TRUE;
943  }  }
944    
# Line 950  is_idea_protect_algo (const char *keyid) Line 974  is_idea_protect_algo (const char *keyid)
974    
975      memset (&k, 0, sizeof (k));      memset (&k, 0, sizeof (k));
976      if (winpt_get_pubkey (keyid, &k))      if (winpt_get_pubkey (keyid, &k))
977          BUG (0);          BUG (NULL);
     sym_prefs = k.ext->sym_prefs;  
978      if (!k.is_v3)      if (!k.is_v3)
979          return 0;          return 0;
980        sym_prefs = k.ext->sym_prefs;
981        /* Assume that only v3 keys have no symmetric cipher
982           preferences and thus IDEA is explicit. */
983      if (!sym_prefs)      if (!sym_prefs)
984          return 1; /* assume that only v3 keys have no symmetric cipher preferences          return 1;
                      and thus IDEA is explicit. */  
985      for (n = 0; sym_prefs[n]; n++)      for (n = 0; sym_prefs[n]; n++)
986          ;          ;
987      if ((n == 0 || n == 1) && *sym_prefs == 0x01)      if ((n == 0 || n == 1) && *sym_prefs == 0x01)
# Line 968  is_idea_protect_algo (const char *keyid) Line 993  is_idea_protect_algo (const char *keyid)
993  BOOL  BOOL
994  keyedit_change_passwd (winpt_key_t k, HWND dlg)  keyedit_change_passwd (winpt_key_t k, HWND dlg)
995  {  {
996      gpgme_error_t ec;      gpgme_error_t err;
997      GpgKeyEdit *ke;      GpgKeyEdit ke;
998      char *old_pass = NULL;      char *old_pass = NULL;
999      char *new_pass = NULL;      char *new_pass = NULL;
1000      int cancel = 0;      int cancel = 0;
# Line 988  keyedit_change_passwd (winpt_key_t k, HW Line 1013  keyedit_change_passwd (winpt_key_t k, HW
1013      }      }
1014    
1015      if (k->is_protected) {      if (k->is_protected) {
1016          old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);          old_pass = request_passphrase (_("Current (old) Passphrase"),
1017                                           PASSDLG_INIT, &cancel);
1018          if (cancel)          if (cancel)
1019              return FALSE;              return FALSE;
1020      }      }
1021      new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);      new_pass = request_passphrase2 (_("New Passphrase" ),
1022                                        PASSDLG_INIT|PASSDLG_WARN_UTF8, &cancel);
1023      if (cancel) {      if (cancel) {
1024          free_if_alloc (old_pass);          sfree_if_alloc (old_pass);
1025          return FALSE;          return FALSE;
1026      }      }
1027    
1028      if (is_8bit_string (new_pass)) {      if (strlen (new_pass) == 0) {
1029          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"
1030                           "It is not suggested to use charset specific characters."),                                   "This is propably a bad idea, continue?"),
1031                           _("Key Edit"), MB_ERR);                              _("Key Edit"), MB_WARN_ASK);
1032          free_if_alloc (old_pass);          if (cancel != IDYES) {
1033          free_if_alloc (new_pass);              sfree_if_alloc (old_pass);
1034          return FALSE;              sfree_if_alloc (new_pass);
1035                return FALSE;
1036            }
1037      }      }
1038    
1039      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
1040      if (!ke)      ke.setPassphrase (k->is_protected? old_pass : NULL);
1041          BUG (NULL);      if (!k->is_protected)
1042            ke.setNoPassphrase (true);
1043      ke->setPassphrase (k->is_protected? old_pass : NULL);      err = ke.changePassphrase (new_pass, 1);
1044      ec = ke->changePassphrase (new_pass, 0);      if (err)
1045      if( ec )          msg_box (dlg, gpgme_strerror (err), _("Change Password"), MB_ERR);
         msg_box (dlg, gpgme_strerror (ec), _("Change Passwd"), MB_ERR);  
1046      else      else
1047          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);
1048      sfree_if_alloc (old_pass);      sfree_if_alloc (old_pass);
1049      sfree_if_alloc (new_pass);      sfree_if_alloc (new_pass);
1050      delete ke;  
1051      return TRUE;      return TRUE;
1052  }  }
1053    
1054                    
1055  /* Initialize sub key list from key @k and return  /* Initialize sub key list from key @k and return
1056     the new listview control. */     the new listview control. */
1057  listview_ctrl_t  listview_ctrl_t
1058  subkey_list_init (HWND dlg, winpt_key_t k)  subkey_list_init (HWND dlg, winpt_key_t k)
1059  {  {
1060      LV_ITEM lvi;      LV_ITEM lvi;
     gpgme_key_t key;  
1061      gpgme_subkey_t sub;      gpgme_subkey_t sub;
1062      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1063          {0, 80, (char *)_("Description")},          {0, 80, (char *)_("Description")},
# Line 1047  subkey_list_init (HWND dlg, winpt_key_t Line 1074  subkey_list_init (HWND dlg, winpt_key_t
1074      listview_ctrl_t lv;      listview_ctrl_t lv;
1075      char buf[256], tmp[128];      char buf[256], tmp[128];
1076      const char *t;      const char *t;
1077      int nkeys = 0, rc = 0, i, bits;          int nkeys = 0, i;
1078    
1079      if( get_pubkey( k->keyid, &key ) ) {      nkeys = count_subkeys (k->ctx);
1080          msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );      if (!nkeys)
1081          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 );  
1082                    
1083      lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
1084      for( i = 0; cols[i].fieldname != NULL; i++ )          for (i = 0; cols[i].fieldname != NULL; i++)
1085          listview_add_column( lv, &cols[i] );          listview_add_column (lv, &cols[i]);
1086                    
1087      for( i = 0; i < nkeys; i++ ) {      for (i = 0, sub = k->ctx->subkeys; i < nkeys; i++, sub = sub->next) {
1088          listview_add_item( lv, "" );          listview_add_item (lv, "");
1089          listview_add_sub_item( lv, 0, 1, "" );          listview_add_sub_item (lv, 0, 1, "");
1090          memset( &lvi, 0, sizeof lvi );          memset (&lvi, 0, sizeof (lvi));
1091          lvi.mask = LVIF_PARAM;            lvi.mask = LVIF_PARAM;  
1092          lvi.lParam = (LPARAM)key;          lvi.lParam = (LPARAM)sub;
1093          if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )          if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
1094              return NULL;              BUG (NULL);
1095      }      }
1096                    
1097      listview_set_ext_style( lv );      listview_set_ext_style (lv);
1098      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) {
1099          memset( buf, 0, sizeof buf );          _snprintf (buf, DIM (buf)-1, "%d-bit %s", sub->length,
1100                                    get_key_pubalgo (sub->pubkey_algo));
1101          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 );  
1102          t = sub->keyid;          t = sub->keyid;
1103          if( !t )          assert (t != NULL);
1104              t = "DEADBEEFDEADBEEF";          _snprintf (tmp, DIM (tmp)-1, "0x%s", t+8);
1105          _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 );  
1106    
1107          t = get_key_created (sub->timestamp);          t = get_key_created (sub->timestamp);
1108          if( !t )          if (!t)
1109              t = "????" "-??" "-??";              t = "????" "-??" "-??";
1110          listview_add_sub_item( lv, i, 2, t );          listview_add_sub_item (lv, i, SUBK_COL_CREATION, t);
1111    
1112          if( sub->expires ) {          if (sub->expires) {
1113              t = get_key_created (sub->expires);              t = get_key_created (sub->expires);
1114              listview_add_sub_item( lv, i, 3, t );              listview_add_sub_item (lv, i, SUBK_COL_EXPIRES, t);
1115          }          }
1116          else          else
1117              listview_add_sub_item( lv, i, 3, _("Never") );              listview_add_sub_item (lv, i, SUBK_COL_EXPIRES, _("Never"));
1118            if (sub->expired)
         if( sub->expired )  
1119              t = _("Expired");              t = _("Expired");
1120          else if( sub->revoked )          else if (sub->revoked)
1121              t = _("Revoked");              t = _("Revoked");
1122          else          else
1123              t = _("OK");              t = _("OK");
1124          listview_add_sub_item( lv, i, 4, t );          listview_add_sub_item (lv, i, SUBK_COL_STATUS, t);
1125    
1126          if (sub->can_certify) t = "*"; else t = "";          if (sub->can_certify) t = "*"; else t = "";
1127          listview_add_sub_item (lv, i, 5, t);          listview_add_sub_item (lv, i, SUBK_COL_C_FLAG, t);
1128          if (sub->can_sign) t = "*"; else t = "";          if (sub->can_sign) t = "*"; else t = "";
1129          listview_add_sub_item( lv, i, 6, t );          listview_add_sub_item (lv, i, SUBK_COL_S_FLAG, t);
1130          if (sub->can_encrypt) t = "*"; else t = "";          if (sub->can_encrypt) t = "*"; else t = "";
1131          listview_add_sub_item( lv, i, 7, t );          listview_add_sub_item (lv, i, SUBK_COL_E_FLAG, t);
1132          if (sub->can_authenticate) t = "*"; else t = "";          if (sub->can_authenticate) t = "*"; else t = "";
1133          listview_add_sub_item (lv, i, 8, t);          listview_add_sub_item (lv, i, SUBK_COL_A_FLAG, t);
1134      }      }
1135      return lv;      return lv;
1136  } /* subkey_list_init */  }
1137    
1138    
1139  static listview_ctrl_t  static listview_ctrl_t
1140  userid_list_init (HWND dlg, winpt_key_t k)  userid_list_init (HWND dlg, winpt_key_t k)
1141  {  {
1142      listview_ctrl_t lv = NULL;      listview_ctrl_t lv = NULL;
     gpgme_key_t key;  
1143      gpgme_key_sig_t ks;      gpgme_key_sig_t ks;
1144      gpgme_user_id_t u;      struct native_uid_s *u;
1145      int nuids = 0, rc, j, u_attr;      int nuids = 0, j, u_attr;
1146      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1147          {0,  72, (char *)_("Validity")},          {0,  72, (char *)_("Validity")},
1148          {1, 150, (char *)_("Name")},          {1, 150, (char *)_("Name")},
# Line 1146  userid_list_init (HWND dlg, winpt_key_t Line 1151  userid_list_init (HWND dlg, winpt_key_t
1151          {0, 0, 0}          {0, 0, 0}
1152      };          };    
1153      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;  
     }  
1154            
1155      nuids = count_userids (key);      nuids = count_userids (k->ctx);
1156      if (!nuids) {      if (!nuids)
1157          msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);          BUG (NULL); /* should never happen. */
         return NULL;  
     }  
1158                    
1159      rc = listview_new (&lv);      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST));
1160      if (rc)      for (j = 0; cols[j].fieldname != NULL; j++)
1161          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] );  
1162                    
1163      for( j = 0; j < nuids; j++ ) {                for (j = 0; j < nuids; j++) {
1164          listview_add_item( lv, " " );          listview_add_item (lv, " ");
1165          listview_add_sub_item( lv, 0, 1, " " );                  listview_add_sub_item (lv, 0, 1, " " );        
1166      }      }
1167    
1168      listview_set_ext_style (lv);      listview_set_ext_style (lv);
1169      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++) {
1170          if (u->revoked)          if (u->revoked)
1171              attr = _("Revoked");              attr = _("Revoked");
1172          else {          else {
1173              u_attr = (int)u->validity;              u_attr = (int)u->validity;
1174              attr = get_key_trust2 (NULL, u_attr, 0, 0);              attr = get_key_trust2 (NULL, u_attr, 0, 0);
1175          }          }
1176          listview_add_sub_item( lv, j, 0, (char *)attr );                  listview_add_sub_item (lv, j, UID_COL_VALID, (char *)attr);
   
1177          /* XXX: add comment if available */          /* XXX: add comment if available */
1178          attr = u->name;          listview_add_sub_item (lv, j, UID_COL_NAME,
1179          if (attr) {                                 u->name? u->name : _("Invalid user ID"));
1180              char *uid = utf8_to_native (attr);          if (u->email)
1181              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);  
1182    
1183          ks = get_selfsig (u, k->keyid, 1);          ks = get_selfsig (u->signatures, k->keyid, 1);
1184          if (ks)          if (ks)
1185              listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));              listview_add_sub_item (lv, j, UID_COL_CREATION,
1186                                       get_key_created (ks->timestamp));
1187      }      }
1188      if( !k->key_pair ) {      if (!k->key_pair) {
1189          CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );          CheckDlgButton (dlg, IDC_KEYUID_ADD, BST_INDETERMINATE);
1190          CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );              CheckDlgButton (dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE);
1191      }      }
1192      return lv;      return lv;
1193  } /* userid_list_init */  }
1194    
1195    
1196  static void  static void
1197  do_init_cmdlist (HWND dlg, int is_keypair)  do_init_cmdlist (HWND dlg, int is_keypair)
1198  {      {    
1199      const char *s;      const char *s;
1200      int i = 0;      int i;
1201    
1202      for (i = 0; (s=cmdlist[i].name); i++) {      for (i = 0; (s=cmdlist[i].name); i++) {
1203          if (is_keypair)          if (is_keypair)
# Line 1233  is_cmd_openpgp (int cmdid) Line 1219  is_cmd_openpgp (int cmdid)
1219      case CMD_ADDKEY:      case CMD_ADDKEY:
1220      case CMD_ADDPHOTO:      case CMD_ADDPHOTO:
1221      case CMD_ADDREVOKER:      case CMD_ADDREVOKER:
1222      //case CMD_SETPREF:      case CMD_SETPREF:
1223          return 1;          return 1;
1224      }      }
1225      return 0;      return 0;
# Line 1244  is_cmd_openpgp (int cmdid) Line 1230  is_cmd_openpgp (int cmdid)
1230  static void  static void
1231  do_show_help (HWND dlg)  do_show_help (HWND dlg)
1232  {  {
1233      char helptext[2048];      const char *help;
1234    
1235      _snprintf (helptext, sizeof (helptext)-1,      help =
1236          _(          _(
1237           "ADDUID   \t\tadd a user ID\r\n"           "ADDUID      add a user ID\r\n"
1238           "ADDPHOTO  \t\tadd a photo ID\r\n"           "ADDPHOTO    add a photo ID\r\n"
1239           "DELUID    \t\tdelete a user ID\r\n"           "DELUID      delete a user ID\r\n"
1240           "ADDKEY    \t\tadd a secondard key\r\n"           "ADDKEY      add a secondary key\r\n"
1241           "DELKEY    \t\tdelete a secondary key\r\n"           "DELKEY      delete a secondary key\r\n"
1242           "ADDREVOKER\t\tadd a revocation key\r\n"           "ADDREVOKER  add a revocation key\r\n"
1243           "EXPIRE    \t\tchange the expire date\r\n"           "EXPIRE      change the expire date\r\n"
1244           "SHOWPREF  \t\tlist preferences (verbose)\r\n"           "SHOWPREF    list preferences (verbose)\r\n"
1245           "SETPREF   \t\tset preference list\r\n"           /*"SETPREF     update specific algorithm preferences\r\n"*/
1246           "UPDPREF   \t\tupdated preferences\r\n"           "PASSWD      change the passphrase\r\n"
1247           "PASSWD    \t\tchange the passphrase\r\n"           "PRIMARY     flag user ID as primary\r\n"
1248           "PRIMARY   \t\tflag user ID as primary\r\n"           "TRUST       change the ownertrust\r\n"
1249           "TRUST     \t\tchange the ownertrust\r\n"           "REVUID      revoke a user ID\r\n"
1250           "REVUID    \t\trevoke a user ID\r\n"           "REVKEY      revoke a secondary key\r\n"
1251           "REVKEY    \t\trevoke a secondary key\r\n"           "DISABLE     disable a key\r\n"
1252           "DISABLE   \t\tdisable a key\r\n"           "ENABLE      enable a key\r\n"
1253           "ENABLE    \t\tenable a key\r\n"           "SIGN        sign a user-id (exportable)\r\n"
1254           "SIGN      \t\tsign a user-id (exportable)\r\n"           "LSIGN       sign a user-id (non-exportable)\r\n"
1255           "LSIGN     \t\tsign a user-id (non-exportable)\r\n"));           "CLEAN       remove unusable signatures from key\r\n"
1256      msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);           "MINIMIZE    remove all signatures from key\r\n"
1257             );
1258        msg_box (dlg, help, _("Key Edit Help"), MB_OK);
1259    }
1260    
1261    
1262    static gpgme_subkey_t
1263    get_subkey_bypos (const char *keyid, int idx)
1264    {
1265        gpgme_key_t key;
1266    
1267        if (get_pubkey (keyid, &key))
1268            return NULL;
1269        return get_nth_key (key, idx);
1270  }  }
1271    
1272    
1273    
1274  static int  static int
1275  do_editkey_delkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_delkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1276  {  {
1277      gpgme_error_t err;      gpgme_error_t err;
1278      GpgKeyEdit *ke;      gpgme_subkey_t subk;
1279      int j, id;      GpgKeyEdit ke;
1280        int pos, id;
1281        const char *warn;
1282      char tmp[64];      char tmp[64];
1283    
1284      if (!k->key_pair)      if (!k->key_pair)
1285          return FALSE; /* XXX: shall we allow to modify non-secret keys?? */          return FALSE;
1286    
1287      if( listview_count_items( lv, 0 ) == 1 ) {      if (listview_count_items (lv, 0) == 1) {
1288          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);
1289          return FALSE;          return FALSE;
1290      }      }
1291      if( (j = listview_get_curr_pos( lv )) == -1 ) {      pos = listview_get_curr_pos (lv);
1292          msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );      if (pos == -1) {
1293            msg_box (dlg, _("Please select a key."), _("Key Edit"), MB_ERR);
1294          return FALSE;          return FALSE;
1295      }      }
1296      if( j == 0 ) {      if (pos == 0) {
1297          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);
1298          return FALSE;          return FALSE;
1299      }      }
1300        
1301      listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );      listview_get_item_text (lv, pos, 0, tmp, DIM (tmp) -1);
1302      id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,      subk = get_subkey_bypos (k->keyid, pos);
1303                      _("\"Subkey %s.\"\n\n"      /* Issue different warning for the different key capabilities. */
1304                        "Anything encrypted to the selected subkey will no longer\n"      if (subk->can_encrypt)
1305                        "be able to be decrypted.\n\n"          warn = _("Anything encrypted to the selected subkey cannot be\n"
1306                        "Do you really want to delete this subkey?"), tmp );                   "decrypted any longer.");
1307      if( id == IDNO )      else if (subk->can_sign || subk->can_certify)
1308            warn = _("Anything signed by the selected subkey cannot be\n"
1309                     "verified any longer.");
1310        else
1311            warn = ""; /* just get rid of the warning. */
1312    
1313        id = log_box (_("Key Edit"), MB_YESNO|MB_ICONWARNING,
1314                      _("\"Subkey %s.\"\n\n%s\n\n"
1315                        "Do you really want to delete this subkey?"),
1316                      tmp, warn);
1317        if (id == IDNO)
1318          return FALSE;          return FALSE;
1319    
1320      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
1321      if (!ke)      err = ke.delKey (pos);
         BUG (NULL);  
     err = ke->delKey (j);  
1322      if (err)      if (err)
1323          msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);
1324      else {      else {
1325          listview_del_item (lv, j);          listview_del_item (lv, pos);
1326          k->update = 1;          k->update = 1;
1327          status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));          status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));
1328      }      }
     delete ke;  
1329      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1330  } /* do_editkey_delkey */  }
   
1331    
1332    
1333  /* 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 1327  static int Line 1336  static int
1336  do_editkey_expire (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_expire (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1337  {  {
1338      gpgme_error_t err;      gpgme_error_t err;
1339      GpgKeyEdit *ke;      GpgKeyEdit ke;
1340      date_s udd = {0};      date_s udd = {0};
1341      char buf[256], * pass = NULL;      char buf[256], * pass = NULL;
1342      int j, cancel = 0;      time_t exp;
1343        int pos, cancel = 0;
1344    
1345      if (!k->key_pair) {      if (!k->key_pair) {
1346          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);
1347          return FALSE;          return FALSE;
1348      }      }
1349      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1350          msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );      if (pos == -1) {
1351            msg_box (dlg, _("Please select a key."), _("Key Edit"), MB_ERR);
1352          return FALSE;          return FALSE;
1353      }      }
1354    
1355      /* If a key already expired, it is possible the user wants to      /* If a key already expired, it is possible the user wants to
1356         set a new expiration date.. */           set a new expiration date.. */
1357      listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof buf -1);      listview_get_item_text (lv, pos, SUBK_COL_STATUS, buf, DIM (buf)-1);
1358      if (!strcmp (buf, _("Expired"))) {      if (!strcmp (buf, _("Expired"))) {
1359          cancel = msg_box (dlg, _("Key already expired.\n\n"          cancel = msg_box (dlg, _("Key already expired.\n\n"
1360                            "Do you want to change the expiration date?"),                            "Do you want to change the expiration date?"),
# Line 1353  do_editkey_expire (winpt_key_t k, HWND d Line 1364  do_editkey_expire (winpt_key_t k, HWND d
1364          cancel = 0;          cancel = 0;
1365      }      }
1366    
1367      memset (&udd, 0, sizeof udd);      memset (&udd, 0, sizeof (udd));
1368      udd.text = _("Key Expiration Date");      udd.text = _("Key Expiration Date");
1369      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,          dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,    
1370                        date_dlg_proc, (LPARAM)&udd,                        date_dlg_proc, (LPARAM)&udd,
# Line 1361  do_editkey_expire (winpt_key_t k, HWND d Line 1372  do_editkey_expire (winpt_key_t k, HWND d
1372      if (udd.cancel == 1)      if (udd.cancel == 1)
1373          return FALSE;          return FALSE;
1374      if (!keygen_check_date (&udd.st)) {      if (!keygen_check_date (&udd.st)) {
1375          msg_box (dlg, _("The date you have chosen lies in the past."),          msg_box (dlg, _("The date you have chosen has already passed."),
1376                   _("Key Edit"), MB_ERR);                   _("Key Edit"), MB_ERR);
1377          return FALSE;          return FALSE;
1378      }      }
1379      if( k->is_protected ) {      if (k->is_protected) {
1380          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1381          if (cancel)          if (cancel)
1382              return FALSE;              return FALSE;
1383      }      }
1384        exp = w32_mktime (&udd.st);
1385    
1386      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
     if (!ke)  
         BUG (NULL);  
1387      if (k->is_protected)      if (k->is_protected)
1388          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1389      else      else
1390          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
1391      err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);      err = ke.setKeyExpireDate (pos, exp, false);
1392      if (err)      if (err)
1393          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1394      else {      else {
1395          _snprintf (buf, sizeof buf - 1, "%04d-%02d-%02d",                _snprintf (buf, DIM (buf)-1, "%s", get_key_created (exp));
1396                     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);  
1397          k->update = 1;          k->update = 1;
1398          msg_box (dlg, _("Subkey expire date successfully set."),          msg_box (dlg, _("Subkey expire date successfully set."),
1399                   _("GnuPG status"), MB_OK);                   _("GnuPG status"), MB_OK);
1400      }      }
1401      sfree_if_alloc (pass);      sfree_if_alloc (pass);
     delete ke;  
1402      return TRUE;      return TRUE;
1403  }  }
1404    
# Line 1402  static int Line 1410  static int
1410  do_editkey_revoke (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_revoke (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1411  {  {
1412      gpgme_error_t err;      gpgme_error_t err;
1413      GpgKeyEdit *ke;      GpgKeyEdit ke;
1414      char buf[256];      char buf[256];
1415      char *pass = NULL;      char *pass = NULL;
1416      int j, cancel = 0;      int j, cancel = 0;
# Line 1424  do_editkey_revoke (winpt_key_t k, HWND d Line 1432  do_editkey_revoke (winpt_key_t k, HWND d
1432          return FALSE;          return FALSE;
1433      }      }
1434                            
1435      listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof (buf)-1);      listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, DIM (buf)-1);
1436      if (!strcmp (buf, _("Revoked"))) {      if (!strcmp (buf, _("Revoked"))) {
1437          msg_box (dlg, _("Key already revoked."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Key already revoked."), _("Key Edit"), MB_ERR);
1438          return FALSE;          return FALSE;
1439      }      }
1440            
1441      if (k->is_protected) {      if (k->is_protected) {
1442          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1443          if (cancel)          if (cancel)
1444              return FALSE;                        return FALSE;          
1445      }      }
1446    
1447      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
     if (!ke)  
         BUG (NULL);  
1448      if (k->is_protected)      if (k->is_protected)
1449          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1450      else      else
1451          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
1452      err = ke->revokeSubkey (j, 0, NULL);      err = ke.revokeSubkey (j, 0, NULL);
1453      if (err)      if (err)
1454          msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);          msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);
1455      else {      else {
# Line 1452  do_editkey_revoke (winpt_key_t k, HWND d Line 1458  do_editkey_revoke (winpt_key_t k, HWND d
1458          msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );          msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1459      }      }
1460      sfree_if_alloc (pass);      sfree_if_alloc (pass);
     delete ke;  
1461      return TRUE;      return TRUE;
1462  }  }
1463    
# Line 1463  int Line 1468  int
1468  do_editkey_revuid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_revuid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1469  {  {
1470      gpgme_error_t err;      gpgme_error_t err;
1471      GpgKeyEdit *ke;      GpgKeyEdit ke;
1472      char buf[128], email[128];      char buf[128], email[128];
1473      char inf[512];      char inf[512];
1474      char *pass = NULL;      char *pass = NULL;
# Line 1481  do_editkey_revuid (winpt_key_t k, HWND d Line 1486  do_editkey_revuid (winpt_key_t k, HWND d
1486      }      }
1487    
1488      if( (j = listview_get_curr_pos( lv )) == -1 ) {      if( (j = listview_get_curr_pos( lv )) == -1 ) {
1489          msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );            msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1490          return FALSE;            return FALSE;  
1491      }      }
1492                            
1493      listview_get_item_text( lv, j, UID_COL_VALID, buf, sizeof buf - 1);      listview_get_item_text( lv, j, UID_COL_VALID, buf, DIM (buf) - 1);
1494      if (strstr (buf, _("Revoked"))) {      if (strstr (buf, _("Revoked"))) {
1495          msg_box (dlg, _("This user ID has been already revoked."),          msg_box (dlg, _("This user ID has been already revoked."),
1496                   _("Key Edit"), MB_INFO);                   _("Key Edit"), MB_INFO);
# Line 1493  do_editkey_revuid (winpt_key_t k, HWND d Line 1498  do_editkey_revuid (winpt_key_t k, HWND d
1498      }      }
1499                            
1500      listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);      listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);
1501      _snprintf (inf, sizeof (inf) -1, _("user ID \"%s\".\n\n"      _snprintf (inf, DIM (inf) -1, _("user ID \"%s\".\n\n"
1502                 "Do you really want to revoke this user ID?"), buf);                 "Do you really want to revoke this user ID?"), buf);
1503      if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)      if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1504          return FALSE;          return FALSE;
1505      if (k->is_protected) {      if (k->is_protected) {
1506          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1507          if (cancel)          if (cancel)
1508              return FALSE;                        return FALSE;          
1509      }      }
1510      listview_get_item_text (lv, j, UID_COL_EMAIL, email, sizeof (email)-1);      listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1511      listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof (buf)-1);      listview_get_item_text (lv, j, UID_COL_NAME, buf, DIM (buf)-1);
1512      id = do_find_userid (k->keyid, email, buf, NULL);      id = do_find_userid (k->keyid, email, buf, NULL);
1513      if (id == -1)      if (id == -1)
1514          BUG (NULL);          BUG (NULL);
1515    
1516      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
     if (!ke)  
         BUG (NULL);  
1517      if (k->is_protected)      if (k->is_protected)
1518          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1519      else      else
1520          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
1521      err = ke->revokeUserid (id);      err = ke.revokeUserid (id);
1522      if (err)      if (err)
1523          msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);
1524      else {      else {
# Line 1524  do_editkey_revuid (winpt_key_t k, HWND d Line 1527  do_editkey_revuid (winpt_key_t k, HWND d
1527          status_box (dlg, _("User ID successfully revoked"), _("GnuPG Status"));          status_box (dlg, _("User ID successfully revoked"), _("GnuPG Status"));
1528      }      }
1529      sfree_if_alloc (pass);      sfree_if_alloc (pass);
     delete ke;  
1530      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1531  }  }
1532    
# Line 1532  do_editkey_revuid (winpt_key_t k, HWND d Line 1534  do_editkey_revuid (winpt_key_t k, HWND d
1534  static int  static int
1535  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)
1536  {  {
1537      gpgme_error_t rc;      gpgme_error_t err;
1538      GpgKeyEdit *ke;      GpgKeyEdit ke;
1539      char buf[256], * pass = NULL, * prefs;      gpg_uid_info_t uidinf = NULL;
1540      int j, id, cancel=0, flags=0;      char buf[256], *pass = NULL, *prefs = NULL;
1541        int pos, id, cancel=0, flags=0;
1542    
1543      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1544        if (pos == -1) {
1545          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1546          return FALSE;          return FALSE;
1547      }      }
1548      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, pos, 2, buf, DIM (buf)-1);
1549      id = do_find_userid (k->keyid, buf, NULL, NULL);      id = do_find_userid (k->keyid, buf, NULL, &uidinf);
1550      if (id == -1)      if (id == -1)
1551          BUG (dlg);          BUG (NULL);
1552      if (k->is_protected) {      if (k->is_protected) {
1553          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1554            gpg_uid_info_release (uidinf);
1555          if (cancel)          if (cancel)
1556              return FALSE;              return FALSE;
1557      }      }
1558    
1559      ke = new GpgKeyEdit (k->keyid);      get_userid_preflist (uidinf->prefs, &prefs, &flags);
1560      if (!ke)      gpg_uid_info_release (uidinf);
1561          BUG (NULL);      if (!prefs) {
1562            sfree_if_alloc (pass);
1563            return FALSE;
1564        }
1565    
1566        ke.setKeyID (k->keyid);
1567      if (k->is_protected)      if (k->is_protected)
1568          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1569      else      else
1570          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);    
1571        err = ke.setUseridPreferences (id, prefs);
1572      get_userid_preflist (&prefs, &flags);      if (err)
1573            msg_box (dlg, gpgme_strerror (err), _("Set user ID preferences"), MB_ERR);
1574      rc = ke->setUseridPreferences (id, prefs);      else {
1575      if (rc)          k->update = 1;
1576          msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);          status_box (dlg, _("User ID preferences successfully updated"), _("GnuPG Status"));
1577        }
1578    
1579      sfree_if_alloc (pass);      sfree_if_alloc (pass);
1580      free_if_alloc (prefs);      free_if_alloc (prefs);
1581      delete ke;      return err? FALSE: TRUE;
     return 0;  
1582  }  }
1583    
1584    
# Line 1576  static int Line 1586  static int
1586  do_editkey_primary (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_primary (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1587  {  {
1588      gpgme_error_t err;      gpgme_error_t err;
1589      GpgKeyEdit *ke;      GpgKeyEdit ke;
1590      int j, id, cancel=0;      int j, id, cancel=0;
1591      char buf[256], * pass = NULL;      char valid[32];
1592        char buf[256], *pass = NULL;
1593    
1594      if (listview_count_items (lv, 0) == 1)      if (listview_count_items (lv, 0) == 1)
1595          return TRUE;          return TRUE;
1596      if ((j = listview_get_curr_pos (lv)) == -1) {      if ((j = listview_get_curr_pos (lv)) == -1) {
1597          msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1598          return FALSE;          return FALSE;
1599      }      }
1600      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, j, UID_COL_VALID, valid, DIM (valid)-1);
1601        if (!strcmp (valid, _("Revoked")))
1602            return FALSE;
1603        listview_get_item_text (lv, j, UID_COL_EMAIL, buf, DIM (buf)-1);
1604      id = do_find_userid (k->keyid, buf, NULL, NULL);      id = do_find_userid (k->keyid, buf, NULL, NULL);
1605      if (id == -1)      if (id == -1)
1606          BUG (dlg);          BUG (NULL);
1607      if (k->is_protected) {      if (k->is_protected) {
1608          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_key_passphrase (k->ctx, _("Key Edit"), &cancel);
1609          if (cancel)          if (cancel)
1610              return FALSE;              return FALSE;
1611      }      }
1612    
1613      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
1614      if (k->is_protected)      if (k->is_protected)
1615          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1616      else      else
1617          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
1618      err = ke->setPrimaryUserid (id);      err = ke.setPrimaryUserid (id);
1619      if (err)      if (err)
1620          msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);
1621      else {      else {
# Line 1610  do_editkey_primary (winpt_key_t k, HWND Line 1624  do_editkey_primary (winpt_key_t k, HWND
1624      }      }
1625    
1626      sfree_if_alloc (pass);      sfree_if_alloc (pass);
     delete ke;  
1627      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1628  }  }
1629    
# Line 1668  BOOL CALLBACK Line 1681  BOOL CALLBACK
1681  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1682  {  {
1683      static keyedit_cb_t cb = NULL;      static keyedit_cb_t cb = NULL;
1684      gpg_uid_info_t inf=NULL;      gpg_uid_info_t inf=NULL, u;
1685        gpgme_key_t key;
1686      char buf[128];      char buf[128];
1687      int pos;      int pos;
1688    
1689      switch (msg) {      switch (msg) {
1690      case WM_INITDIALOG:      case WM_INITDIALOG:
1691          cb = (keyedit_cb_t)lparam;          cb = (keyedit_cb_t)lparam;
1692          if (cb == NULL)          if (!cb)
1693              BUG (dlg);              BUG (NULL);
1694          pos = listview_get_curr_pos (cb->lv);          key = (gpgme_key_t)cb->opaque;
1695          listview_get_item_text (cb->lv, pos, 2, buf, DIM (buf)-1);          listview_get_item_text (cb->lv, cb->lv_pos,
1696          SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);                                  UID_COL_EMAIL, buf, DIM (buf)-1);
1697          pos = do_find_userid (((winpt_key_t)cb->opaque)->keyid,          pos = do_find_userid (cb->keyid, buf, NULL, &inf);
1698                                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;  
1699              gpg_uid_info_release (inf);              gpg_uid_info_release (inf);
1700              if (pos == -1) {              EndDialog (dlg, FALSE);
1701                  msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);              break;
1702                  EndDialog (dlg, TRUE);          }
1703            for (u=inf; u; u = u->next) {
1704                if (u->index == pos && u->prefs && *u->prefs) {
1705                    _snprintf (buf, DIM (buf)-1, "%s", u->name);
1706                    SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1707                    if (parse_preflist (dlg, u->prefs) <= 0)
1708                        pos = -1;
1709                    if (u->flags.mdc)
1710                        CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1711                    break;
1712              }              }
1713              if (inf->flags.mdc)          }
1714                  CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);          gpg_uid_info_release (inf);
1715            if (pos == -1) {        
1716                msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1717                EndDialog (dlg, FALSE);
1718                break;
1719          }          }
1720          SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));          SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1721          SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));          SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1722            SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1723          SetWindowText (dlg, _("Key Preferences"));          SetWindowText (dlg, _("Key Preferences"));
1724          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
1725            center_window (dlg, cb->parent);
1726          break;          break;
1727    
1728      case WM_COMMAND:      case WM_COMMAND:
# Line 1709  showpref_dlg_proc (HWND dlg, UINT msg, W Line 1730  showpref_dlg_proc (HWND dlg, UINT msg, W
1730          case IDOK:          case IDOK:
1731              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
1732              break;              break;
1733    
1734            case IDCANCEL:
1735                EndDialog (dlg, FALSE);
1736                break;
1737          }          }
1738          break;          break;
1739      }      }
# Line 1720  static int Line 1745  static int
1745  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)
1746  {  {
1747      struct keyedit_cb_s cb;      struct keyedit_cb_s cb;
1748        char status[32];
1749    
1750      if (k->is_v3)      if (k->is_v3)
1751          return TRUE;          return TRUE;
# Line 1728  do_editkey_showpref (winpt_key_t k, HWND Line 1754  do_editkey_showpref (winpt_key_t k, HWND
1754          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1755          return FALSE;          return FALSE;
1756      }      }
   
1757      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
1758        cb.parent = dlg;
1759        cb.opaque = k->ctx;
1760        cb.keyid = k->keyid;
1761      cb.lv = lv;      cb.lv = lv;
1762      cb.opaque = k;      cb.lv_pos = listview_get_curr_pos (lv);
1763    
1764        listview_get_item_text (lv, cb.lv_pos, UID_COL_VALID,
1765                                status, DIM (status)-1);
1766        if (!strcmp (status, _("Revoked")))
1767            return TRUE;
1768        
1769      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1770                      showpref_dlg_proc, (LPARAM)&cb);                      showpref_dlg_proc, (LPARAM)&cb);
1771      return TRUE;      return TRUE;
# Line 1742  static int Line 1776  static int
1776  do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1777  {  {
1778      gpgme_error_t err;      gpgme_error_t err;
1779      GpgKeyEdit *ke;      GpgKeyEdit ke;
1780      char email[128], name[128];      char email[128], name[128];
1781      char inf[384];      char inf[384];
1782      int j, id = 0;      int pos, id = 0;
1783    
1784      if (!k->key_pair)      if (!k->key_pair)
1785          return FALSE; /* XXX: see do_editkey_delsubkey */          return FALSE;
1786    
1787      if (listview_count_items (lv, 0) == 1) {      if (listview_count_items (lv, 0) == 1) {
1788          msg_box (dlg, _("Primary user ID can not be deleted!"),          msg_box (dlg, _("Primary user ID can not be deleted!"),
1789                   _("Key Edit"), MB_ERR);                   _("Key Edit"), MB_ERR);
1790          return FALSE;          return FALSE;
1791      }      }
1792      if ((j = listview_get_curr_pos (lv)) == -1) {      pos = listview_get_curr_pos (lv);
1793        if (pos == -1) {
1794          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1795          return FALSE;          return FALSE;
1796      }      }
1797            
1798      /* 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);  
1799      _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"      _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1800                                       "All signatures on this user ID will be also deleted."
1801                                       "\n\n"
1802                                     "Do you really want to delete this user ID?"),                                     "Do you really want to delete this user ID?"),
1803                                 name);                                 name);
1804      if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)      if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1805          return FALSE;          return FALSE;
1806            
1807      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);
1808      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);
1809      id = do_find_userid (k->keyid, email, name, NULL);      id = do_find_userid (k->keyid, email, name, NULL);
1810      if (id == -1)      if (id == -1)
         BUG (dlg);  
   
     ke = new GpgKeyEdit (k->keyid);  
     if (!ke)  
1811          BUG (NULL);          BUG (NULL);
1812    
1813      err = ke->delUserid (id);      ke.setKeyID (k->keyid);
1814        err = ke.delUserid (id);
1815      if (err)      if (err)
1816          msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Delete User ID"), MB_ERR);
1817      else {      else {
1818          listview_del_item (lv, j);          listview_del_item (lv, pos);
1819          k->update = 1;          k->update = 1;
1820          status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));          status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1821      }      }
     delete ke;  
1822      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1823  } /* do_editkey_deluid */  }
   
1824    
1825    
1826    /* Subclass routine for the subkey listview control to allow shortcuts. */
1827  static BOOL CALLBACK  static BOOL CALLBACK
1828  subkey_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )  subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1829  {  {
1830      switch( msg ) {      int virt_key = 0;
1831        winpt_key_t key;
1832    
1833        switch (msg) {
1834      case WM_KEYUP:      case WM_KEYUP:
1835          int virt_key = (int)wparam;          virt_key = (int)wparam;
1836          switch( virt_key ) {                  key = (winpt_key_t)keyedit_subkey_proc.opaque;
1837            if (!key || !key->key_pair)
1838                break;
1839    
1840            switch (virt_key) {
1841          case VK_DELETE:          case VK_DELETE:
1842              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1843                                  CB_SETCURSEL, CMD_DELKEY, 0 );                                  CB_SETCURSEL, CMD_DELKEY, 0);
1844              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1845              break;              break;
1846    
1847          case VK_INSERT:          case VK_INSERT:
1848              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1849                                  CB_SETCURSEL, CMD_ADDKEY, 0 );                                  CB_SETCURSEL, CMD_ADDKEY, 0);
1850              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1851              break;              break;
1852          }          }
1853      }      }
1854      return CallWindowProc( keyedit_subkey_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1855  } /* subkey_subclass_proc */  }
1856    
1857    
1858  static BOOL CALLBACK  static BOOL CALLBACK
1859  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1860  {  {
1861      switch( msg ) {      int virt_key = 0;
1862        winpt_key_t key;
1863    
1864        switch (msg) {
1865      case WM_KEYUP:      case WM_KEYUP:
1866          int virt_key = (int)wparam;          virt_key = (int)wparam;
1867            key = (winpt_key_t)keyedit_uid_proc.opaque;
1868            if (!key || !key->key_pair)
1869                break;
1870    
1871          switch (virt_key) {          switch (virt_key) {
1872          case VK_DELETE:          case VK_DELETE:
1873              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 1882  uid_subclass_proc (HWND dlg, UINT msg, W
1882              break;              break;
1883          }          }
1884      }      }
1885      return CallWindowProc( keyedit_uid_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1886  } /* uid_subclass_proc */  }
1887    
1888    
1889    /* Enable the key @k when @enable is 1, disable it otherwise. */
1890  static void  static void
1891  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,
1892                               listview_ctrl_t lv, int enable)
1893  {  {
1894      km_enable_disable_key (lv, dlg, 0, enable);      km_enable_disable_key (lv, dlg, 0, enable);
1895      k->update = 1;      k->update = 1;
1896  }  }
1897    
1898    
1899  /* Return default secret key. */  static void
1900  static gpgme_key_t  do_editkey_minimize (winpt_key_t k, HWND dlg)
1901  get_default_key (void)  {
1902  {      gpgme_error_t err;
1903      gpgme_key_t def_sk;      GpgKeyEdit ke;
1904      char *keyid = get_gnupg_default_key ();  
1905        ke.setKeyID (k->keyid);
1906      get_seckey (keyid, &def_sk);      err = ke.minimizeKey ();
1907      free_if_alloc (keyid);      if (err)
1908      return def_sk;          msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1909        else {
1910            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1911            k->update = 1;
1912        }
1913  }  }
1914    
1915    
1916  static void  static void
1917    do_editkey_clean (winpt_key_t k, HWND dlg)
1918    {
1919        gpgme_error_t err;
1920        GpgKeyEdit ke;
1921        
1922        ke.setKeyID (k->keyid);
1923        err = ke.cleanKey ();
1924        if (err)
1925            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);  
1926        else {
1927            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1928            k->update = 1;
1929        }
1930    }
1931    
1932    
1933    /* Start the dialog to list and display the status of all
1934       signatures for this key. */
1935    static void
1936  do_editkey_check (winpt_key_t k, HWND dlg)  do_editkey_check (winpt_key_t k, HWND dlg)
1937  {  {
1938      if (!k->ctx)      if (!k->ctx)
# Line 1877  static int Line 1948  static int
1948  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)
1949  {  {
1950      gpgme_error_t err;      gpgme_error_t err;
1951      GpgKeyEdit *ke;      winpt_key_s signer;
1952        GpgKeyEdit ke;
1953      char *pass = NULL;      char *pass = NULL;
1954      char email[64], name[128];      char *defkey;
1955        char email[64], name[128], valid[32];
1956      int uid_index;      int uid_index;
1957      int cancel = 0;      int cancel = 0;
1958    
# Line 1888  do_editkey_sign_userid (winpt_key_t k, H Line 1961  do_editkey_sign_userid (winpt_key_t k, H
1961          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1962          return FALSE;          return FALSE;
1963      }      }
1964        listview_get_item_text (lv, uid_index, UID_COL_VALID, valid, DIM (valid)-1);
1965        if (!strcmp (valid, _("Revoked")))
1966            return TRUE;
1967      if (mode == CMD_SIGN) {      if (mode == CMD_SIGN) {
1968          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?"),
1969                            _("Key Edit"), MB_QUEST_ASK);                            _("Key Edit"), MB_QUEST_ASK);
1970          if (cancel == IDNO)          if (cancel == IDNO)
1971              return FALSE;              return FALSE;
1972      }      }
1973        listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, DIM (email)-1);
1974      listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);      listview_get_item_text (lv, uid_index, UID_COL_NAME, name, DIM (name)-1);
     listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);  
1975      uid_index = do_find_userid (k->keyid, email, name, NULL);      uid_index = do_find_userid (k->keyid, email, name, NULL);
1976      if (k->is_protected) {  
1977          pass = request_passphrase (_("Key Edit"), 1, &cancel);      defkey = get_gnupg_default_key ();
1978        memset (&signer, 0, sizeof (signer));
1979        if (winpt_get_seckey (defkey, &signer)) {
1980            log_debug ("do_editkey_sign_userid: no default secret key.\r\n");
1981            free_if_alloc (defkey);
1982            return FALSE;
1983        }
1984        if (signer.is_protected) {
1985            pass = request_key_passphrase (signer.ctx, _("Key Edit"), &cancel);
1986          if (cancel)          if (cancel)
1987              return FALSE;              return FALSE;
1988      }      }
1989      ke = new GpgKeyEdit (k->keyid);      ke.setKeyID (k->keyid);
1990      if (k->is_protected)      if (signer.is_protected)
1991          ke->setPassphrase (pass);          ke.setPassphrase (pass);
1992      else      else
1993          ke->setNoPassphrase (true);          ke.setNoPassphrase (true);
1994      ke->setLocalUser (get_default_key ());      ke.setLocalUser (signer.ctx);
1995      err = ke->signUserid (uid_index,      err = ke.signUserid (uid_index,
1996                            mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,                            mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
1997                            0, NULL);                            0, NULL);
1998      if (!err) {      if (!err) {
# Line 1918  do_editkey_sign_userid (winpt_key_t k, H Line 2001  do_editkey_sign_userid (winpt_key_t k, H
2001      }      }
2002      else      else
2003          msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
2004      delete ke;  
2005      sfree_if_alloc (pass);      sfree_if_alloc (pass);
2006      return !err? TRUE : FALSE;      return !err? TRUE : FALSE;
2007  }  }
# Line 1933  lookup_cmd (HWND dlg) Line 2016  lookup_cmd (HWND dlg)
2016      i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);      i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
2017      if (i == LB_ERR)      if (i == LB_ERR)
2018          return LB_ERR;          return LB_ERR;
2019      GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);      GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, DIM (buf)-1);
2020      for (i=0; cmdlist[i].name != NULL; i++) {      for (i=0; cmdlist[i].name != NULL; i++) {
2021          if (!strcmp (buf, cmdlist[i].name))          if (!strcmp (buf, cmdlist[i].name))
2022              return cmdlist[i].id;              return cmdlist[i].id;
# Line 1941  lookup_cmd (HWND dlg) Line 2024  lookup_cmd (HWND dlg)
2024      return LB_ERR;      return LB_ERR;
2025  }  }
2026    
2027    
2028    
2029    gpgme_error_t key_get_revokers (winpt_key_t key, int reload,
2030                                    gpg_desig_rev_t *r_rev);
2031    
2032    /* Check if the key supports designated revokers and if
2033        secret keys exist to generate such a revoke cert. */
2034    static bool
2035    check_desig_rev (winpt_key_t key)
2036    {
2037        gpg_desig_rev_t rev, u;
2038        struct winpt_key_s sk;
2039    
2040        if (!key->ext->gloflags.has_desig_rev)
2041            return false;
2042        key_get_revokers (key, 0, &rev);
2043        for (u = rev; u; u = u->next) {
2044            memset (&sk, 0, sizeof (sk));
2045            if (!winpt_get_seckey (u->fpr+32, &sk))
2046                return true;
2047        }
2048        return false;
2049    }
2050    
2051    
2052    /* Use the gpg --desig-revoker command to create a revocation
2053       cert for a key that lists our key as a designated revoker. */
2054    static void
2055    gen_desig_revoke_cert (winpt_key_t key, HWND dlg)
2056    {
2057        const char *warn;
2058        char *inf, *p;
2059        int id;
2060    
2061        inf = km_key_get_info (key, 0);
2062        warn = _("Your keys is listed as a designated revoker for the key\n\n"
2063                 "%s\n\n"
2064                 "Are you sure you want to create a revocation certificate\n"
2065                 "which allows you to revoke the key listed above?");
2066        p = new char[strlen (inf)+1+strlen (warn)+1];
2067        sprintf (p, warn, inf);
2068        free_if_alloc (inf);
2069    
2070        id = msg_box (dlg, p, _("Key Edit"), MB_YESNO|MB_ICONWARNING);
2071        free_if_alloc (p);
2072        if (id == IDNO)
2073            return;
2074    
2075        key->internal = 1;
2076        DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKE, dlg,
2077                        key_revoke_dlg_proc, (LPARAM)key);
2078    }
2079    
2080    
2081    /* Create tooltip control for the listview header. */
2082    static HWND
2083    create_header_tooltip (HWND dlg)
2084    {
2085        TOOLINFO ti;
2086        HWND tt;
2087    
2088        tt = CreateWindow (TOOLTIPS_CLASS, (LPSTR) NULL, TTS_ALWAYSTIP,
2089                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2090                            CW_USEDEFAULT,
2091                            NULL, (HMENU) NULL, glob_hinst, NULL);
2092        if (!tt)
2093            BUG (NULL);
2094        memset (&ti, 0, sizeof (ti));
2095        ti.cbSize = sizeof (TOOLINFO);
2096        ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS;    
2097        ti.hwnd = dlg;    
2098        ti.uId = (UINT) ListView_GetHeader (GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
2099        ti.hinst = 0;
2100        ti.lpszText = (char*)_("Capabilties: C = Certify, S = Sign, E = Encrypt, A = Authenticate");
2101        SendMessage(tt, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
2102        return tt;
2103    }
2104    
2105    
2106  /* Dialog box procedure for the edit key dialog. */  /* Dialog box procedure for the edit key dialog. */
2107  BOOL CALLBACK  BOOL CALLBACK
2108  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2109  {  {
2110      static winpt_key_t k;      static winpt_key_t k;
2111      static listview_ctrl_t lvsub = NULL, lvuid = NULL;      static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2112        static HWND tt;
2113      int cmd;      int cmd;
2114      HWND item;      HWND item;
2115    
2116      switch( msg ) {      switch (msg) {
2117      case WM_INITDIALOG:      case WM_INITDIALOG:
2118          k = (winpt_key_t)lparam;          k = (winpt_key_t)lparam;
2119          if (!k)          if (!k)
2120              BUG (NULL);              BUG (NULL);
2121          do_init_cmdlist (dlg, k->key_pair);          do_init_cmdlist (dlg, k->key_pair);
2122          lvsub = subkey_list_init (dlg, k);          lvsub = subkey_list_init (dlg, k);
         if( !lvsub )  
             BUG( NULL );  
2123          lvuid = userid_list_init (dlg, k);          lvuid = userid_list_init (dlg, k);
2124          if( !lvuid )          item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2125              BUG( NULL );          keyedit_subkey_proc.opaque = (void*)k;
         item = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );  
2126          keyedit_subkey_proc.dlg = dlg;          keyedit_subkey_proc.dlg = dlg;
2127          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2128          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2129          if( keyedit_subkey_proc.old ) {          if (keyedit_subkey_proc.old) {
2130              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_subkey_proc.current ) ) {              if (!SetWindowLong (item, GWL_WNDPROC,
2131                  msg_box( dlg, _("Could not set subkey window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_subkey_proc.current)) {
2132                  BUG( NULL );                  msg_box (dlg, "Could not set subkey window procedure.",
2133                             _("Key Edit"), MB_ERR);
2134                    BUG (NULL);
2135              }              }
2136          }          }
2137          item = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );          tt = create_header_tooltip (dlg);
2138            item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2139            keyedit_uid_proc.opaque = (void*)k;
2140          keyedit_uid_proc.dlg = dlg;          keyedit_uid_proc.dlg = dlg;
2141          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2142          keyedit_uid_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2143          if( keyedit_uid_proc.old ) {          if (keyedit_uid_proc.old) {
2144              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_uid_proc.current ) ) {              if (!SetWindowLong (item, GWL_WNDPROC,
2145                  msg_box( dlg, _("Could not set user ID window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_uid_proc.current)) {
2146                  BUG( NULL );                  msg_box (dlg, "Could not set user ID window procedure.",
2147                             _("Key Edit"), MB_ERR);
2148                    BUG (NULL);
2149              }              }
2150          }          }
2151          if (k->ctx->revoked) {          if (k->ctx->revoked) {
# Line 1989  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2155  keyedit_main_dlg_proc (HWND dlg, UINT ms
2155          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2156          SetDlgItemText (dlg, IDCANCEL, _("&Close"));          SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2157          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2158            SetDlgItemText (dlg, IDC_KEYEDIT_REVOKE, _("&Revoke..."));
2159            SetDlgItemText (dlg, IDOK, _("&OK"));
2160            if (!check_desig_rev (k))
2161                ShowWindow (GetDlgItem (dlg, IDC_KEYEDIT_REVOKE), SW_HIDE);
2162          SetWindowText (dlg, _("Key Edit"));          SetWindowText (dlg, _("Key Edit"));
2163          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
2164          center_window (dlg, NULL);          center_window (dlg, NULL);
2165          return TRUE;          return TRUE;
2166    
2167      case WM_DESTROY:      case WM_DESTROY:
2168          if( lvsub ) {          if (lvsub) {
2169              listview_release( lvsub );              listview_release (lvsub);
2170              lvsub = NULL;              lvsub = NULL;
2171          }          }
2172          if( lvuid ) {          if (lvuid) {
2173              listview_release( lvuid );              listview_release (lvuid);
2174              lvuid = NULL;              lvuid = NULL;
2175          }          }
2176          break;          break;
2177    
2178      case WM_NOTIFY:      case WM_NOTIFY:
2179          NMHDR * notify;          NMHDR *notify;
2180          notify = (NMHDR *)lparam;          notify = (NMHDR *)lparam;
2181          if (notify && notify->code == NM_DBLCLK &&          if (!notify || notify->idFrom != IDC_KEYEDIT_UIDLIST)
2182              notify->idFrom == IDC_KEYEDIT_UIDLIST)              break;
2183            if (notify->code == NM_DBLCLK)
2184              do_editkey_showpref (k, dlg, lvuid);              do_editkey_showpref (k, dlg, lvuid);
2185            else if (notify->code == NM_RCLICK && k->key_pair) {
2186                HMENU hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_WINPT_KEYEDIT));
2187                HMENU popup = GetSubMenu (hm, 0);
2188                POINT p;
2189    
2190                GetCursorPos (&p);
2191                TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, dlg, NULL);
2192                DestroyMenu (hm);
2193                DestroyMenu (popup);
2194            }
2195          break;          break;
2196    
2197      case WM_COMMAND:      case WM_COMMAND:
2198          switch( LOWORD( wparam ) ) {          switch (LOWORD (wparam)) {
2199          case IDOK:          case IDOK:
2200              cmd = lookup_cmd (dlg);              cmd = lookup_cmd (dlg);
2201              if (cmd == LB_ERR) {              if (cmd == LB_ERR) {
# Line 2032  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2213  keyedit_main_dlg_proc (HWND dlg, UINT ms
2213              case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;              case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2214              case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;              case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2215              case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;              case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2216              /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/              case CMD_SETPREF:/*do_editkey_setpref (k, dlg, lvuid);*/ break;
2217              case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;              case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2218              case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;              case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2219              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 2229  keyedit_main_dlg_proc (HWND dlg, UINT ms
2229              case CMD_LSIGN: do_editkey_sign_userid (k, dlg,              case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2230                                                      lvuid, cmd);                                                      lvuid, cmd);
2231                              break;                              break;
2232                case CMD_CLEAN: do_editkey_clean (k, dlg); break;
2233                case CMD_MINIMIZE: do_editkey_minimize (k, dlg); break;
2234              }              }
2235              break;              break;          
2236    
2237          case IDCANCEL:          case IDCANCEL:
2238              EndDialog (dlg, FALSE);              EndDialog (dlg, FALSE);
# Line 2058  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2241  keyedit_main_dlg_proc (HWND dlg, UINT ms
2241          case IDC_KEYEDIT_HELP:          case IDC_KEYEDIT_HELP:
2242              do_show_help (dlg);              do_show_help (dlg);
2243              break;              break;
2244    
2245            case IDC_KEYEDIT_REVOKE:
2246                gen_desig_revoke_cert (k, dlg);
2247                break;
2248    
2249            case ID_KEYEDIT_UID_PRIM:
2250                do_editkey_primary (k, dlg, lvuid);
2251                break;
2252    
2253            case ID_KEYEDIT_UID_DEL:
2254                do_editkey_deluid (k, dlg, lvuid);
2255                break;
2256    
2257            case ID_KEYEDIT_UID_REV:
2258                do_editkey_revuid (k, dlg, lvuid);
2259                break;
2260          }          }
2261          break;          break;
2262      }      }
2263      return FALSE;      return FALSE;
2264  }  }
   

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26