/[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 88 by twoaday, Mon Nov 21 12:06:59 2005 UTC revision 211 by twoaday, Sun May 7 12:36:48 2006 UTC
# Line 1  Line 1 
1  /* wptKeyEditDlgs.cpp - GPG key edit dialogs  /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2   *      Copyright (C) 2002-2005 Timo Schulz   *      Copyright (C) 2002-2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 17  Line 17 
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
   
20  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
21  #include <config.h>  #include <config.h>
22  #endif  #endif
23    
24  #include <windows.h>  #include <windows.h>
 #include <oleauto.h>  
25  #include <commctrl.h>  #include <commctrl.h>
26  #include <time.h>  #include <time.h>
27    #include <assert.h>
28    
29  #include "resource.h"  #include "resource.h"
   
30  #include "wptTypes.h"  #include "wptTypes.h"
31  #include "wptW32API.h"  #include "wptW32API.h"
32  #include "wptVersion.h"  #include "wptVersion.h"
# Line 50  enum keyedit_commands { Line 48  enum keyedit_commands {
48      CMD_ADDUID,      CMD_ADDUID,
49      CMD_ADDPHOTO,      CMD_ADDPHOTO,
50      CMD_ADDREVOKER,      CMD_ADDREVOKER,
     /*CMD_FPR,*/  
51      CMD_DELUID,      CMD_DELUID,
52      CMD_DELKEY,      CMD_DELKEY,
     CMD_DELPHOTO,  
     /*CMD_DELSIG,*/  
53      CMD_EXPIRE,      CMD_EXPIRE,
     /*CMD_PREF,*/  
54      CMD_SHOWPREF,      CMD_SHOWPREF,
55      /*CMD_SETPREF,*/      //CMD_SETPREF,
     /*CMD_UPDPREF,*/  
56      CMD_PASSWD,      CMD_PASSWD,
57      CMD_PRIMARY,      CMD_PRIMARY,
58      CMD_TRUST,      CMD_TRUST,
     /*CMD_REVSIG,*/  
59      CMD_REVUID,      CMD_REVUID,
60      CMD_REVKEY,      CMD_REVKEY,
61      CMD_DISABLE,      CMD_DISABLE,
62      CMD_ENABLE,      CMD_ENABLE,    
63      /*CMD_SHOWPHOTO,*/      CMD_SIGN,
64        CMD_LSIGN,
65        CMD_CHECK,
66        CMD_CLEAN,
67        CMD_MINIMIZE
68    };
69    
70    struct cmdlist_s {
71        const char   *name;
72        unsigned int  need_pair:1;
73        int       id;
74    } cmdlist[] = {
75        {"ADDKEY", 1, CMD_ADDKEY},
76        {"ADDUID", 1, CMD_ADDUID},
77        {"ADDPHOTO", 1, CMD_ADDPHOTO},
78        {"ADDREVOKER", 1, CMD_ADDREVOKER},
79        {"DELUID", 1, CMD_DELUID},
80        {"DELKEY", 1, CMD_DELKEY},
81        {"EXPIRE", 1, CMD_EXPIRE},
82        {"SHOWPREF", 0, CMD_SHOWPREF},
83        /*{"SETPREF", 1, CMD_SETPREF},*/
84        {"PASSWD", 1, CMD_PASSWD},
85        {"PRIMARY", 1, CMD_PRIMARY},
86        {"TRUST", 0, CMD_TRUST},
87        {"REVUID", 1, CMD_REVUID},
88        {"REVKEY", 1, CMD_REVKEY},
89        {"DISABLE", 0, CMD_DISABLE},
90        {"ENABLE", 0, CMD_ENABLE},
91        {"SIGN", 0, CMD_SIGN},
92        {"LSIGN", 0, CMD_LSIGN},
93        {"CHECK", 0, CMD_CHECK},
94        {"CLEAN", 0, CMD_CLEAN},
95        {"MINIMIZE", 0, CMD_MINIMIZE},
96        {NULL, 0}  
97  };  };
98    
99    
# Line 93  enum uid_col_t { Line 118  enum uid_col_t {
118      UID_COL_CREATION    = 3      UID_COL_CREATION    = 3
119  };  };
120    
121  struct keyedit_callback_s {  /* Key edit callback context. */
122    struct keyedit_cb_s {
123      const char     *keyid;      const char     *keyid;
124      const char     *pass;      const char     *pass;
125      listview_ctrl_t lv;      listview_ctrl_t lv;
126        int             lv_pos;
127      void           *opaque;      void           *opaque;
128      unsigned int    finished:1;      unsigned int    finished:1;
129        unsigned int    is_protected:1;
130  };  };
131  typedef struct keyedit_callback_s KEYEDIT_CB;  typedef struct keyedit_cb_s *keyedit_cb_t;
132    
133    
134  struct keygen_callback_s {  /* Key generation callback context. */
135    struct keygen_cb_s {
136      int   bits;      int   bits;
137      int   algo;      int   algo;
138      u32   expire;      u32   expire;
139      char *fpr;      char *fpr;
140        char *name;
141        char *comment;
142        char *email;
143  };  };
144  typedef struct keygen_callback_s KEYGEN_CB;  typedef struct keygen_cb_s *keygen_cb_t;
   
145    
146    /* Subclass context for the subkey list. */
147  static subclass_s keyedit_subkey_proc;  static subclass_s keyedit_subkey_proc;
148    
149    /* Subclass context for the user-id list. */
150  static subclass_s keyedit_uid_proc;  static subclass_s keyedit_uid_proc;
151    
152  int keygen_check_date (SYSTEMTIME *st);  int keygen_check_date (SYSTEMTIME *st);
153  void get_userid_preflist (char **r_prefs, int * r_flags);  void get_userid_preflist (char **r_prefs, int * r_flags);
154  char* get_subkey_fingerprint (const char *keyid);  char* get_subkey_keyid (const char *keyid);
155    
156    void ComboBox_AddString_utf8 (HWND cb, const char *txt);
157    
158    static GpgKeyEdit*
159    create_GpgKeyEdit (const char *keyid)
160    {
161        GpgKeyEdit *ke;
162    
163        ke = new GpgKeyEdit (keyid);
164        if (!ke)
165            BUG (NULL);
166        return ke;
167    }
168    
169    
170  /* Associate each key with a combo box entry.  /* Associate each key with a combo box entry.
171     Skip the key in @k. */     Skip the key in @k. */
172  static void  static void
173  do_init_keylist (HWND dlg, winpt_key_t k)  do_init_keylist (HWND dlg, const char *keyid)
174  {  {
175      gpg_keycache_t pub;      gpg_keycache_t pub;
176      gpgme_key_t key;      gpgme_key_t key;
177      const char * s, * kid;      const char *s, *kid;
     char * u;  
178      int i, n;      int i, n;
179    
180      pub = keycache_get_ctx (1);      pub = keycache_get_ctx (1);
# Line 135  do_init_keylist (HWND dlg, winpt_key_t k Line 182  do_init_keylist (HWND dlg, winpt_key_t k
182          BUG (0);          BUG (0);
183    
184      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
185      while( !gpg_keycache_next_key( pub, 0, &key ) ) {      while( !gpg_keycache_next_key (pub, 0, &key)) {
186          if (key->expired || key->revoked ||          if (key->expired || key->revoked ||
187              key->disabled || key->invalid)              key->disabled || key->invalid)
188              continue;              continue;
           
189          s = key->uids->uid;          s = key->uids->uid;
190          kid = key->subkeys->keyid;          kid = key->subkeys->keyid;
191          if (!s || !strcmp (kid+8, k->keyid+2))          if (!s || !strcmp (kid+8, keyid))
192              continue;              continue;
193          u = utf8_to_wincp (s, strlen (s));          ComboBox_AddString_utf8 (GetDlgItem (dlg, IDC_ADDREV_KEYLIST), s);
         SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_ADDSTRING,  
                             0, (WPARAM)(char *)u);  
         free (u);  
194      }      }
195      gpg_keycache_rewind (pub);      gpg_keycache_rewind (pub);
196      n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );      n = SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0);
197      for (i = 0; i < n; i++) {      for (i = 0; i < n; i++) {
198          gpg_keycache_next_key (pub, 0, &key);          gpg_keycache_next_key (pub, 0, &key);
199          SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,          SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
# Line 163  do_init_keylist (HWND dlg, winpt_key_t k Line 206  do_init_keylist (HWND dlg, winpt_key_t k
206  /* Add a new user-id to the list view @lv. */  /* Add a new user-id to the list view @lv. */
207  static void  static void
208  do_add_new_userid (listview_ctrl_t lv,  do_add_new_userid (listview_ctrl_t lv,
209                     const char * name, const char *email, const char * comment)                     const char *utf8_name, const char *email,
210                       const char *utf8_comment)
211  {  {
212      char * p;      char *p;
213      size_t n;      size_t n;
214            
215      n = strlen (name) + strlen (email) + 16;      n = strlen (utf8_name) + strlen (email) + 16;
216      if (comment)      if (utf8_comment)
217          n += strlen (comment);          n += strlen (utf8_comment);
218      p = new char[n+1];      p = new char[n+1];
219      if (!p)      if (!p)
220          BUG( NULL );          BUG (NULL);
221      if (comment)      if (utf8_comment) {
222          sprintf (p, "%s (%s)", name, comment);          sprintf (p, "%s (%s)", utf8_name, utf8_comment);
223        }
224      else      else
225          sprintf (p, "%s", name);          sprintf (p, "%s", utf8_name);
226    
227      listview_add_item (lv, "");      listview_add_item (lv, "");
228      listview_add_sub_item (lv, 0, 0, _("Ultimate" ));      listview_add_sub_item (lv, 0, 0, _("Ultimate" ));
# Line 185  do_add_new_userid (listview_ctrl_t lv, Line 230  do_add_new_userid (listview_ctrl_t lv,
230      listview_add_sub_item (lv, 0, 2, email && *email? email : "");      listview_add_sub_item (lv, 0, 2, email && *email? email : "");
231      listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));      listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));
232      free_if_alloc (p);      free_if_alloc (p);
233  } /* do_add_new_userid */  }
234    
235    
236  static void  static void
237  do_add_new_subkey (listview_ctrl_t lv, KEYGEN_CB *keygen, unsigned int flags)  do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)
238  {  {
239      char info[128], keyid[32];      char info[128], keyid[32];
240      const char * expdate, * s;      const char *expdate, *s;
241      int n;      int n;
242            
243      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");      expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
244      _snprintf (info, sizeof info-1, "%d-bit %s",      _snprintf (info, sizeof info-1, "%d-bit %s",
245                 keygen->bits,                 keygen->bits,
246                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));                 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
247      _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+32);      _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+8);
248        s = get_key_created (time (NULL));
249      n = listview_count_items (lv, 0);      n = listview_count_items (lv, 0);
250      listview_add_item_pos (lv, n);      listview_add_item_pos (lv, n);
251      listview_add_sub_item (lv, n, 0, info);      listview_add_sub_item (lv, n, SUBK_COL_DESC, info);
252      listview_add_sub_item (lv, n, 1, keyid);      listview_add_sub_item (lv, n, SUBK_COL_KEYID, keyid);
253      listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));      listview_add_sub_item (lv, n, SUBK_COL_CREATION, s);
254      listview_add_sub_item (lv, n, 3, expdate);      listview_add_sub_item (lv, n, SUBK_COL_EXPIRES, expdate);
255      if (flags & KM_FLAG_REVOKED) s = _("Revoked");            if (flags & KM_FLAG_REVOKED)
256      else if (flags & KM_FLAG_EXPIRED) s = _("Expired");          s = _("Revoked");      
257      else s = _("OK");      else if (flags & KM_FLAG_EXPIRED)
258      listview_add_sub_item (lv, n, 4, s);          s = _("Expired");
259  } /* do_add_new_subkey */      else
260            s = _("OK");
261        listview_add_sub_item (lv, n, SUBK_COL_STATUS, s);
262    }
263    
264    
265  /* Try to find the GPG edit key index which belongs to the user ID  /* Try to find the GPG edit key index which belongs to the user ID
266     given by @name. If @r_inf != NULL, the info context will be returned.     given by the email address @email, @name is used as a fallback.
267       If @r_inf != NULL, the info context will be returned.
268     Return value: index of the user ID or -1 on error. */     Return value: index of the user ID or -1 on error. */
269  static int  static int
270  do_find_userid (const char *keyid, const char *name, gpg_uid_info_t *r_inf)  do_find_userid (const char *keyid, const char *email,
271                    const char *name, gpg_uid_info_t *r_inf)
272  {  {
273      GpgKeyEdit *ke;      GpgKeyEdit *ke;
274      gpgme_error_t err;      gpgme_error_t err;
275      gpg_uid_info_t inf, ui;      gpg_uid_info_t inf, ui;
276      int pos = -1;      int pos = -1;
277    
278      ke = new GpgKeyEdit (keyid);      ke = create_GpgKeyEdit (keyid);
     if (!ke)  
         BUG (NULL);  
279      err = ke->getUseridInfo (&inf);      err = ke->getUseridInfo (&inf);
280      delete ke;      delete ke;
281      if (err) {      if (err) {
# Line 237  do_find_userid (const char *keyid, const Line 286  do_find_userid (const char *keyid, const
286      }      }
287    
288      for (ui = inf; ui; ui = ui->next) {      for (ui = inf; ui; ui = ui->next) {
289          if (!strcmp (ui->email, name)) {          if (name && email && ui->email && ui->name) {
290                if (!strcmp (ui->email, email) &&
291                    !strncmp (ui->name, name, strlen (name))) {
292                    pos = ui->index;
293                    break;
294                }
295                continue;
296            }
297            if (email && ui->email) {
298                if (!strcmp (ui->email, email)) {
299                    pos = ui->index;
300                    break;
301                }
302                /* The email address is more unique, use the name just
303                   as the fallbck when no email address is available. */
304                continue;
305            }
306            if (ui->name && name && !strcmp (ui->name, name)) {
307              pos = ui->index;              pos = ui->index;
308              break;              break;
309          }          }
# Line 250  do_find_userid (const char *keyid, const Line 316  do_find_userid (const char *keyid, const
316  }  }
317    
318    
319    /* Return true if @fname is a JPEG file. */
320    bool
321    is_jpg_file (const char *fname)
322    {
323        FILE *fp;
324        BYTE buf[10];
325        int n;
326    
327        fp = fopen (fname, "rb");
328        if (!fp)
329            return false;
330        n = fread (buf, 1, 10, fp);
331        fclose (fp);
332        if (n < 10)
333            return false;
334        return buf[6] == 'J' && buf[7] == 'F' &&
335               buf[8] == 'I' && buf[9] == 'F';
336    }
337    
338    
339  /* Dialog box procedure to add a photo. */  /* Dialog box procedure to add a photo. */
340  BOOL CALLBACK  BOOL CALLBACK
341  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
342  {  {
343      static winpt_key_t k;              static keyedit_cb_t cb;
344      GpgKeyEdit *ke;      GpgKeyEdit *ke;
345      gpgme_error_t ec;          gpgme_error_t err;
346      const char * s;          const char *s;    
347      char pwd[128], file[128];      char file[128];
348      int id;      int id;
349    
350      switch( msg ) {      switch( msg ) {
351      case WM_INITDIALOG:      case WM_INITDIALOG:
352          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
353          if (!k)          if (!cb)
354              BUG (NULL);              BUG (NULL);
355          SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key.  If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));          SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key.  If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));
356          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."));
357          SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));          SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
358          SetForegroundWindow( dlg );          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
359            SetWindowText (dlg, _("Add Photo ID"));
360            SetForegroundWindow (dlg);
361          break;          break;
362    
363      case WM_DESTROY:      case WM_DESTROY:
364          break;          break;
365    
366      case WM_SYSCOMMAND:      case WM_SYSCOMMAND:
367          if( LOWORD (wparam) == SC_CLOSE )          if (LOWORD (wparam) == SC_CLOSE)
368              EndDialog( dlg, TRUE );              EndDialog (dlg, TRUE);
369          break;          break;
370    
371      case WM_COMMAND:      case WM_COMMAND:
372          switch( LOWORD( wparam ) ) {          switch( LOWORD (wparam)) {
   
373          case IDC_ADDPHOTO_SELFILE:          case IDC_ADDPHOTO_SELFILE:
374              s = get_fileopen_dlg( dlg, _("Select Image File"), _("JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0"), NULL );              s = get_fileopen_dlg (dlg, _("Select Image File"),
375              if( s && *s )                                    "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",
376                  SetDlgItemText( dlg, IDC_ADDPHOTO_FILE, s );                                    NULL);
377                if (s && !is_jpg_file (s)) {
378                    log_box (_("Add Photo"), MB_ERR,
379                             _("'%s' is not a valid JPEG file."), s);
380                    return FALSE;
381                }
382                if (s && *s)
383                    SetDlgItemText (dlg, IDC_ADDPHOTO_FILE, s);
384              break;              break;
385    
386          case IDOK:          case IDOK:
387              if( !GetDlgItemText( dlg, IDC_ADDPHOTO_FILE, file, sizeof file-1 ) ){              if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
388                  msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR );                  msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);
389                  return FALSE;                  return FALSE;
390              }              }
391              if( get_file_size( file ) == 0 || get_file_size( file ) > 6144 ) {              if (get_file_size (file) == 0 || get_file_size (file) > 6144 ) {
392                  id = msg_box( dlg, _("The JPEG is really large.\n"                  id = msg_box (dlg, _("The JPEG is really large.\n"
393                                       "Are you sure you want to use it?"),                                       "Are you sure you want to use it?"),
394                                       _("Add Photo"), MB_YESNO|MB_INFO );                                       _("Add Photo"), MB_YESNO|MB_INFO);
395                  if( id == IDNO )                  if (id == IDNO)
396                      return TRUE;                      return TRUE;
397              }              }
398              if( k->is_protected ) {              ke = create_GpgKeyEdit (cb->keyid);
399                  if( !GetDlgItemText( dlg, IDC_ADDPHOTO_PASS, pwd, sizeof pwd-1 ) ) {              if (cb->pass)
400                      msg_box( dlg, _("Please enter a passphrase."), _("Add Photo"), MB_ERR );                  ke->setPassphrase (cb->pass);
401                      return FALSE;              else
402                  }                  ke->setNoPassphrase (true);
403              }              err = ke->addPhotoid (file);
             ke = new GpgKeyEdit (k->keyid);  
             if (!ke)  
                 BUG (NULL);  
   
             if (k->is_protected)  
                 ke->setPassphrase (pwd);  
             ec = ke->addPhotoid (file);  
404              delete ke;              delete ke;
405              memset (pwd, 0, sizeof pwd);              if (err) {
406              if (ec) {                  msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
                 msg_box (dlg, gpgme_strerror (ec), _("Add Photo"), MB_ERR );  
407                  return FALSE;                  return FALSE;
408              }              }
409              else {              else {
410                  k->update = 1;                  cb->finished = 1;
411                  msg_box (dlg, _("Photo successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("Photo successfully added."),
412                             _("GnuPG Status"), MB_OK);
413              }              }
414              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
415              break;              break;
# Line 341  keyedit_addphoto_dlg_proc (HWND dlg, UIN Line 428  keyedit_addphoto_dlg_proc (HWND dlg, UIN
428  BOOL CALLBACK  BOOL CALLBACK
429  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
430  {  {
431      static winpt_key_t k;      static keyedit_cb_t cb;
     static gpgme_key_t seckey;      
     GpgKeyEdit *ke;  
432      gpgme_error_t err;      gpgme_error_t err;
433      char uid[128], pwd[128];      GpgKeyEdit *ke;
434            char *uid=NULL;
435    
436      switch( msg ) {      switch (msg) {
437      case WM_INITDIALOG:      case WM_INITDIALOG:
438          k = (winpt_key_t)lparam;          cb = (keyedit_cb_t)lparam;
439          if( !k )          if (!cb)
440              BUG( NULL );              BUG (NULL);
441          if( get_seckey( k->keyid, &seckey ) )            do_init_keylist (dlg, cb->keyid);
442              BUG( NULL );          SetDlgItemText (dlg, IDC_ADDREV_INF,
443          if (!k->is_protected)                          _("Appointing a key as designated revoker cannot be undone."));
             EnableWindow (GetDlgItem (dlg, IDC_ADDREV_PASS), FALSE);  
         do_init_keylist (dlg, k);  
         SetDlgItemText (dlg, IDC_ADDREV_INF, _("Appointing a key as designated revoker cannot be undone."));  
444          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));          SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
445          SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));          SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
446          SetForegroundWindow( dlg );          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
447          break;          SetWindowText (dlg, _("Add Revoker"));
448            SetForegroundWindow (dlg);
     case WM_DESTROY:      
449          break;          break;
450    
451      case WM_SYSCOMMAND:      case WM_SYSCOMMAND:
452          if( LOWORD (wparam) == SC_CLOSE )          if (LOWORD (wparam) == SC_CLOSE)
453              EndDialog( dlg, TRUE );              EndDialog (dlg, FALSE);
454          break;          break;
455    
456      case WM_COMMAND:      case WM_COMMAND:
457          switch( LOWORD( wparam ) ) {          switch (LOWORD (wparam)) {
458          case IDOK:                    case IDOK:
459              if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {              if (!GetDlgItemText_utf8 (dlg, IDC_ADDREV_KEYLIST, &uid)) {
460                  msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );                  msg_box (dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR);
461                  return FALSE;                  return FALSE;
462              }              }
463                    
464              if( k->is_protected ) {              ke = create_GpgKeyEdit (cb->keyid);
465                  if( !GetDlgItemText( dlg, IDC_ADDREV_PASS, pwd, sizeof pwd-1 ) ) {              if (cb->pass)
466                      msg_box( dlg, _("Please enter the passphrase."), _("Add Revoker"), MB_ERR );                  ke->setPassphrase (cb->pass);
467                      return FALSE;              else
468                  }                  ke->setNoPassphrase (true);
             }  
             ke = new GpgKeyEdit (k->keyid);  
             if (k->is_protected)  
                 ke->setPassphrase (pwd);  
469              err = ke->addDesignatedRevoker (uid);              err = ke->addDesignatedRevoker (uid);
470              delete ke;              delete ke;
471              memset (pwd, 0, sizeof pwd);              safe_free (uid);
472              if (err) {              if (err) {
473                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
474                  return TRUE;                  return TRUE;
475              }              }
476              else {              else {
477                  k->update = 1;                  cb->finished = 1;
478                  msg_box (dlg, _("Revoker successfully addded."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("Revoker successfully addded."),
479                             _("GnuPG Status"), MB_OK);
480              }              }
481              EndDialog( dlg, TRUE );              EndDialog (dlg, TRUE);
482              break;              break;
483    
484          case IDCANCEL:          case IDCANCEL:
485              EndDialog( dlg, FALSE );              EndDialog (dlg, FALSE);
486              break;              break;
487          }          }
488          break;          break;
# Line 417  keyedit_addrevoker_dlg_proc (HWND dlg, U Line 495  keyedit_addrevoker_dlg_proc (HWND dlg, U
495  BOOL CALLBACK  BOOL CALLBACK
496  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
497  {  {
498      static KEYEDIT_CB *ctx;      static keyedit_cb_t ctx;
499        keygen_cb_t keygen;
500      gpgme_error_t err;      gpgme_error_t err;
501      GpgKeyEdit *ke;      GpgKeyEdit *ke;
502      char *utf8_name = NULL;      char *utf8_name = NULL;
503      char name[128], email[128], comment[128];      char *utf8_comment = NULL;
504        char email[128];
505      int rc;      int rc;
506            
507      switch ( msg ) {      switch (msg) {
508      case WM_INITDIALOG:      case WM_INITDIALOG:
509          ctx = (KEYEDIT_CB *)lparam;          ctx = (keyedit_cb_t)lparam;
510          if( !ctx )          if (!ctx)
511              dlg_fatal_error(dlg, "Could not get dialog param!");              dlg_fatal_error(dlg, "Could not get dialog param!");
     #ifndef LANG_DE  
512          SetWindowText (dlg, _("Add new User ID"));          SetWindowText (dlg, _("Add new User ID"));
513          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));          SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
514          SetDlgItemText (dlg, IDC_ADDUID_INFEMAIL, _("&Email"));          SetDlgItemText (dlg, IDC_ADDUID_INFEMAIL, _("&Email"));
515          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));          SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
516      #endif          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
517          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
518          return FALSE;          return FALSE;
519                    
520      case WM_SYSCOMMAND:      case WM_SYSCOMMAND:
521          if (LOWORD (wparam) == SC_CLOSE) {          if (LOWORD (wparam) == SC_CLOSE)
522              EndDialog(dlg, TRUE);              EndDialog(dlg, TRUE);
         }  
523          return FALSE;          return FALSE;
524                    
525      case WM_COMMAND:      case WM_COMMAND:
526          switch ( LOWORD( wparam ) )  {          switch ( LOWORD( wparam ) )  {
527          case IDOK:          case IDOK:
528              rc = GetDlgItemText( dlg, IDC_ADDUID_NAME, name, sizeof name-1 );              keygen = (keygen_cb_t)ctx->opaque;
529                rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_NAME, &utf8_name);
530              if (!rc || rc < 5) {              if (!rc || rc < 5) {
531                  msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );                  msg_box (dlg, _("Please enter a name (min. 5 chars.)"),
532                             _("UserID"), MB_ERR);
533                    free_if_alloc (utf8_name);
534                  return FALSE;                  return FALSE;
535              }              }
536              if (strchr (name, '@')) {              if (strchr (utf8_name, '@')) {
537                  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"),
538                             _("UserID"), MB_INFO);
539                  return FALSE;                  return FALSE;
540              }              }
541                                      
542              if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {              if( !GetDlgItemText (dlg, IDC_ADDUID_EMAIL, email, sizeof (email) -1)) {
543                  msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );                  msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
544                  return FALSE;                  return FALSE;
545              }              }
546              if( !strchr( email, '@' ) || strchr (email, ' ')) {              if (check_email_address (email)) {
547                  msg_box( dlg, _("Invalid email address."), _("UserID"), MB_ERR );                  msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
548                  return FALSE;                  return FALSE;
549              }              }
550                            
551              rc = GetDlgItemText( dlg, IDC_ADDUID_COMMENT, comment, sizeof comment -1 );              rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_COMMENT, &utf8_comment);
552    
553              /* XXX: something is wrong with the encoding :-( */              ke = create_GpgKeyEdit (ctx->keyid);
554              utf8_name = wincp_to_utf8 (name, strlen (name));              if (ctx->is_protected)
   
             ke = new GpgKeyEdit (ctx->keyid);  
             if (!ke)  
                 BUG (NULL);  
             if (ctx->pass)  
555                  ke->setPassphrase (ctx->pass);                  ke->setPassphrase (ctx->pass);
556              err = ke->addUserid (utf8_name? utf8_name : name,              else
557                                   rc > 0? comment : NULL, email);                  ke->setNoPassphrase (true);
558                err = ke->addUserid (utf8_name, utf8_comment, email);
559              if (err)              if (err)
560                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
561              else {              else {
562                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
563                  ctx->finished = 1;                  ctx->finished = 1;
564                    keygen->name = utf8_name;
565                    keygen->comment = utf8_comment;
566                    keygen->email = m_strdup (email);
567              }              }
568              delete ke;              delete ke;
             free (utf8_name);  
             if (!err && ctx->lv)  
                 do_add_new_userid (ctx->lv, name, email, rc?comment : NULL);  
569              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
570              return TRUE;              return TRUE;
571                            
# Line 502  keyedit_adduid_dlg_proc (HWND dlg, UINT Line 580  keyedit_adduid_dlg_proc (HWND dlg, UINT
580  }  }
581    
582    
 static int  
 diff_time (HWND dt, SYSTEMTIME *in_exp)  
 {  
     SYSTEMTIME exp, now;  
     double e=0, n=0;  
   
     if (in_exp)  
         memcpy (&exp, in_exp, sizeof (SYSTEMTIME));  
     else  
         DateTime_GetSystemtime (dt, &exp);  
     GetSystemTime (&now);  
     SystemTimeToVariantTime (&exp, &e);  
     SystemTimeToVariantTime (&now, &n);  
     if (n > e)  
         return 0;  
     return (int)(e-n);  
 }  
   
   
583  static void  static void
584  init_keysize_box (HWND dlg, int ctlid)  init_keysize_box (HWND dlg, int ctlid)
585  {  {
586      const char *sizelist[] = {      const char *sizelist[] = {
587          "1024", "1536", "2048", "2560", "3072", "3854", "4096", NULL          "1024", "1536",
588            "2048", "3072",
589            "4096", NULL
590      };      };
591      int i;      int i;
592    
593      for (i=0; sizelist[i] != NULL; i++)      for (i=0; sizelist[i] != NULL; i++)
594          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0, (LPARAM)(char*)sizelist[i]);          SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
595                                (LPARAM)(char*)sizelist[i]);
596      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);      SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
597  }  }
598    
599    
600  static int  static int
601  get_keysize_from_box (HWND dlg, int ctlid)  get_keysize_from_box (HWND dlg, int ctlid)
602  {  {
# Line 543  get_keysize_from_box (HWND dlg, int ctli Line 607  get_keysize_from_box (HWND dlg, int ctli
607      if (pos == CB_ERR)      if (pos == CB_ERR)
608          return -1;          return -1;
609      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);      SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
610      return atol (buf);      return atoi (buf);
611  }  }
612    
613    
614    /* Create a time_t from a system time @st. */
615    time_t
616    w32_mktime (SYSTEMTIME *st)
617    {
618        struct tm tm;
619    
620        memset (&tm, 0, sizeof (tm));
621        tm.tm_year = st->wYear-1900;
622        tm.tm_mday = st->wDay+1;
623        tm.tm_mon = st->wMonth-1;
624        return mktime (&tm);
625    }
626    
627    
628    /* Dialog procedure for adding a new secondary key. */
629  BOOL CALLBACK  BOOL CALLBACK
630  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
631  {  {
632      static KEYEDIT_CB *ctx;      static keyedit_cb_t ctx;
633      static KEYGEN_CB *keygen;      keygen_cb_t keygen;
634      GpgKeyEdit *ke;      GpgKeyEdit *ke;
635      gpgme_error_t err;      gpgme_error_t err;
636      HWND lb;      SYSTEMTIME st;
637        HWND hwnd;
638      int index, size, valid;      int index, size, valid;
639            
640      switch (msg) {      switch (msg) {
641      case WM_INITDIALOG:      case WM_INITDIALOG:
642          ctx = (KEYEDIT_CB *)lparam;          ctx = (keyedit_cb_t)lparam;
643          if (!ctx)          if (!ctx)
644              dlg_fatal_error (dlg, "Could not get dialog param!");              dlg_fatal_error (dlg, "Could not get dialog param!");
645          keygen = (KEYGEN_CB *)ctx->opaque;  
 #ifndef LANG_DE  
646          SetWindowText (dlg, _("Add new Subkey"));          SetWindowText (dlg, _("Add new Subkey"));
647          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
648          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));
649          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFVALID, _("Key expiration"));          SetDlgItemText (dlg, IDC_ADDSUBKEY_INFVALID, _("Key expiration"));
650  #endif          SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
651          lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);          SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
652          listbox_add_string (lb, "DSA (sign only)");  
653          listbox_add_string (lb, "ElGamal (encrypt only)");          hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
654          listbox_add_string (lb, "RSA (sign only)");          listbox_add_string (hwnd, "DSA (sign only)");
655          listbox_add_string (lb, "RSA (encrypt only)");          listbox_add_string (hwnd, "ElGamal (encrypt only)");
656            listbox_add_string (hwnd, "RSA (sign only)");
657            listbox_add_string (hwnd, "RSA (encrypt only)");
658          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);          CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
659          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);          EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
660          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);          init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
661          SetForegroundWindow( dlg );          SetForegroundWindow (dlg);
662          return FALSE;          return FALSE;
663                    
664      case WM_SYSCOMMAND:      case WM_SYSCOMMAND:
665          if( LOWORD (wparam) == SC_CLOSE ) {          if (LOWORD (wparam) == SC_CLOSE)
666              EndDialog( dlg, TRUE );              EndDialog (dlg, TRUE);
         }  
667          return FALSE;          return FALSE;
668                    
669      case WM_COMMAND:      case WM_COMMAND:
670          if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_ADDSUBKEY_EXPIRE) {          if (HIWORD (wparam) == BN_CLICKED &&
671                LOWORD (wparam) == IDC_ADDSUBKEY_EXPIRE) {
672              if (IsDlgButtonChecked (dlg, IDC_ADDSUBKEY_EXPIRE))              if (IsDlgButtonChecked (dlg, IDC_ADDSUBKEY_EXPIRE))
673                  EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);                  EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
674              else              else
675                  EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), TRUE);                  EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), TRUE);
676          }          }
677          if (HIWORD (wparam) == LBN_SELCHANGE && LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {          if (HIWORD (wparam) == LBN_SELCHANGE &&
678                LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {
679              index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);              index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);
680              if (index == 0)              if (index == 0)
681                  SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);                  SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);
682          }          }
683    
684          switch ( LOWORD(wparam) ) {                  switch (LOWORD (wparam)) {
685          case IDOK:          case IDOK:
686              lb = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);              keygen = (keygen_cb_t)ctx->opaque;
687              switch (listbox_get_cursel (lb)) {              assert (keygen);
688                hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
689                switch (listbox_get_cursel (hwnd)) {
690              case 0: index = 2; break;              case 0: index = 2; break;
691              case 1: index = 4; break;              case 1: index = 4; break;
692              case 2: index = 5; break;              case 2: index = 5; break;
693              case 3: index = 6; break;              case 3: index = 6; break;
694              default:              default:
695                  msg_box( dlg, _("Please select one entry."), _("Add Subkey"), MB_ERR );                  msg_box (dlg, _("Please select one entry."),
696                             _("Add Subkey"), MB_ERR);
697                  return FALSE;                  return FALSE;
698              }              }
699              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);              size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
700              if (index == 2 && size != 1024) {              if (index == 2 && size != 1024) {
701                  msg_box( dlg,_("DSS uses a fixed keysize of 1024. Size changed."), _("Add Subkey"), MB_INFO );                  msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
702                             _("Add Subkey"), MB_INFO);
703                  size = 1024;                  size = 1024;
704              }              }
705              valid = diff_time (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), NULL);  
706                hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
707                DateTime_GetSystemtime (hwnd, &st);
708                valid = w32_mktime (&st) - time (NULL);
709                valid /= 86400;
710    
711              keygen->bits = size;              keygen->bits = size;
712              switch (index) {              switch (index) {
# Line 628  keyedit_addsubkey_dlg_proc (HWND dlg, UI Line 718  keyedit_addsubkey_dlg_proc (HWND dlg, UI
718              if (valid > 0)              if (valid > 0)
719                  keygen->expire = time (NULL) + valid*24*60*60;                  keygen->expire = time (NULL) + valid*24*60*60;
720    
721              ke = new GpgKeyEdit (ctx->keyid);              ke = create_GpgKeyEdit (ctx->keyid);
             if (!ke)  
                 BUG (NULL);  
722              ke->setCallback (keygen_cb, NULL);              ke->setCallback (keygen_cb, NULL);
723              if (ctx->pass)              if (ctx->is_protected)
724                  ke->setPassphrase (ctx->pass);                        ke->setPassphrase (ctx->pass);
725                else
726                    ke->setNoPassphrase (true);
727              keygen_cb_dlg_create ();              keygen_cb_dlg_create ();
728    
729              err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);              err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
730              keygen->fpr = get_subkey_fingerprint (ctx->keyid);              keygen->fpr = get_subkey_keyid (ctx->keyid);
731              keygen_cb_dlg_destroy ();              keygen_cb_dlg_destroy (1);
             keygen_cb (NULL, NULL, 0, 0, 0); /* flush */  
732              if (err)              if (err)
733                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);                  msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
734              else {              else {
735                  msg_box (dlg, _("Subkey successfully added."), _("GnuPG Status"), MB_OK);                  msg_box (dlg, _("Subkey successfully added."),
736                  if (ctx->lv)                           _("GnuPG Status"), MB_OK);
                     do_add_new_subkey (ctx->lv, keygen, /*XXXk->flags*/0);  
737                  ctx->finished = 1;                  ctx->finished = 1;
738              }              }
739              delete ke;              delete ke;
740              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
741              return TRUE;              return TRUE;
742                            
743          case IDCANCEL:          case IDCANCEL:
744              EndDialog( dlg, FALSE );              EndDialog (dlg, FALSE);
745              return FALSE;              return FALSE;
746          }          }
747          break;          break;
748      }      }
749            
750      return FALSE;      return FALSE;
751  } /* keyedit_addsubkey_dlg_proc */  }
752    
753    
754  BOOL  BOOL
755  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)
756  {  {
757      KEYEDIT_CB cb;      keyedit_cb_s cb;
758        keygen_cb_s keygen;
759      char *pass = NULL;      char *pass = NULL;
760      int cancel = 0;      int cancel = 0;
761    
762      if (!k->key_pair) {      if (!k->key_pair) {
763          msg_box( dlg, _("There is no secret key available!"), _("Add user ID"), MB_ERR );          msg_box (dlg, _("There is no secret key available!"),
764                     _("Add user ID"), MB_ERR);
765          return FALSE;          return FALSE;
766      }      }
767    
768      if (k->is_protected) {      if (k->is_protected) {
769          pass = request_passphrase( _("Key Edit"), 1, &cancel );          pass = request_passphrase (_("Key Edit"), 1, &cancel);
770          if (cancel)          if (cancel)
771              return FALSE;              return FALSE;
772      }      }
773              
774        memset (&keygen, 0, sizeof (keygen));
775      memset (&cb, 0, sizeof cb);      memset (&cb, 0, sizeof cb);
776      cb.pass = k->is_protected? pass : NULL;      cb.opaque = &keygen;
777      cb.lv = lv;      cb.is_protected = k->is_protected;
778        cb.pass = pass;
779      cb.keyid = k->keyid;      cb.keyid = k->keyid;
780      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
781                        dlg, keyedit_adduid_dlg_proc,                                dlg, keyedit_adduid_dlg_proc,        
782                        (LPARAM)&cb, _("Add user ID"),                        (LPARAM)&cb, _("Add user ID"),
783                        IDS_WINPT_KEYEDIT_ADDUID);                        IDS_WINPT_KEYEDIT_ADDUID);
784        if (lv != NULL && cb.finished)
785            do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
786      if (cb.finished)      if (cb.finished)
787          k->update = 1;          k->update = 1;
788    
789        free_if_alloc (keygen.name);
790        free_if_alloc (keygen.email);
791        free_if_alloc (keygen.comment);
792      sfree_if_alloc (pass);      sfree_if_alloc (pass);
793      return TRUE;      return TRUE;
794  }  }
795    
796    
797    /* Return the keyID of the last subkey. */
798  char*  char*
799  get_subkey_fingerprint (const char *keyid)  get_subkey_keyid (const char *keyid)
800  {  {
801      gpgme_error_t err;      gpgme_error_t err;
802      gpgme_key_t key, main;      gpgme_key_t key;
803      gpgme_ctx_t ctx;      gpgme_ctx_t ctx;
804      gpgme_subkey_t last_sk, k, new_sk;      gpgme_subkey_t subk;
805      int n;      char *kid = NULL;
806    
807      err = gpgme_new (&ctx);      err = gpgme_new (&ctx);
808      if (err)      if (err)
809          return NULL;          return NULL;
810      err = gpgme_get_key (ctx, keyid, &key, 0);      err = gpgme_get_key (ctx, keyid, &key, 0);
811        gpgme_release (ctx);
812      if (err)      if (err)
813          return NULL;          return NULL;
814      /* XXX: this is very slow and complicated */      subk = get_nth_key (key, count_subkeys (key));
815            if (subk != NULL)
816      n = count_subkeys (key);          kid = strdup (subk->keyid);
     last_sk = get_nth_key (key, n-1);  
     new_sk = (gpgme_subkey_t)calloc (1, sizeof *new_sk);  
     if (!new_sk)  
         BUG (NULL);  
     memcpy (new_sk, last_sk, sizeof *last_sk);  
     new_sk->fpr = strdup (last_sk->fpr);  
     new_sk->keyid = strdup (last_sk->keyid);  
   
     get_pubkey (keyid, &main);  
     for (k=main->subkeys; k->next; k=k->next)  
         ;  
     k->next = new_sk;  
   
817      gpgme_key_release (key);      gpgme_key_release (key);
818      return new_sk->fpr;      return kid;
819  }  }
820    
821    
822  BOOL  BOOL
823  keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)  keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
824  {  {
825      KEYEDIT_CB cb;      keyedit_cb_s cb;
826      KEYGEN_CB keygen;      keygen_cb_s keygen;
827      char *pass = NULL;      char *pass = NULL;
828      int cancel = 0;      int cancel = 0;
829    
830      if (!k->key_pair) {      if (!k->key_pair) {
831          msg_box (dlg, _("There is no secret key available!"), _("Add Subkey"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"),
832                     _("Add Subkey"), MB_ERR);
833          return FALSE;          return FALSE;
834      }      }
835      if (k->is_protected) {      if (k->is_protected) {
# Line 755  keyedit_add_subkey (winpt_key_t k, HWND Line 841  keyedit_add_subkey (winpt_key_t k, HWND
841      memset (&keygen, 0, sizeof (keygen));      memset (&keygen, 0, sizeof (keygen));
842      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
843      cb.keyid = k->keyid;      cb.keyid = k->keyid;
844      cb.pass = k->is_protected? pass : NULL;      cb.is_protected = k->is_protected;
845        cb.pass = pass;
846      cb.opaque = &keygen;      cb.opaque = &keygen;
847      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,          dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,    
848                        dlg, keyedit_addsubkey_dlg_proc,                        dlg, keyedit_addsubkey_dlg_proc,
849                        (LPARAM)&cb, _("Add new Subkey"),                        (LPARAM)&cb, _("Add new Subkey"),
850                        IDS_WINPT_KEYEDIT_ADDSUBKEY);                        IDS_WINPT_KEYEDIT_ADDSUBKEY);
851        if (lv != NULL && cb.finished)
852            do_add_new_subkey (lv, &keygen, 0);
853      if (cb.finished)      if (cb.finished)
854          k->update = 1;          k->update = 1;
855    
856      sfree_if_alloc (pass);          safe_free (keygen.fpr);
857        sfree_if_alloc (pass);
858      return cb.finished? TRUE: FALSE;      return cb.finished? TRUE: FALSE;
859  }  }
860    
# Line 775  keyedit_set_pref_keyserver (winpt_key_t Line 865  keyedit_set_pref_keyserver (winpt_key_t
865      GpgKeyEdit *ke;      GpgKeyEdit *ke;
866      gpgme_error_t err;      gpgme_error_t err;
867      struct URL_ctx_s *url;      struct URL_ctx_s *url;
868      char *pass;      char *pass = NULL;
869    
870      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);      url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
871      if (url->cancel == 1) {      if (url->cancel == 1) {
# Line 789  keyedit_set_pref_keyserver (winpt_key_t Line 879  keyedit_set_pref_keyserver (winpt_key_t
879          return FALSE;          return FALSE;
880      }      }
881    
882      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
883      if (!ke)      if (k->is_protected)
884          BUG (NULL);          ke->setPassphrase (pass);
885      ke->setPassphrase (pass);      else
886      err = ke->setPreferredKeyserver (0 /* XXX */, url->url);          ke->setNoPassphrase (true);
887        err = ke->setPreferredKeyserver (-1, url->url);
888      if (!err)      if (!err)
889          msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);          msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
890        else
891            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
892    
893      sfree_if_alloc (pass);      sfree_if_alloc (pass);
894      delete ke;      delete ke;
895      delete url;          delete url;
896      return err == 0? 0 : WPTERR_GENERAL;      return err == 0? 0 : WPTERR_GENERAL;
897  }  }
898    
# Line 809  keyedit_set_pref_keyserver (winpt_key_t Line 902  keyedit_set_pref_keyserver (winpt_key_t
902  BOOL  BOOL
903  keyedit_add_photo (winpt_key_t k, HWND dlg)  keyedit_add_photo (winpt_key_t k, HWND dlg)
904  {  {
905        keyedit_cb_s cb;
906        char *pass = NULL;
907        int cancel;
908        
909      if (!k->key_pair) {      if (!k->key_pair) {
910          msg_box (dlg, _("There is no secret key available!"), _("Add Photo"), MB_ERR);          msg_box (dlg, _("There is no secret key available!"),
911                     _("Add Photo"), MB_ERR);
912          return FALSE;          return FALSE;
913      }      }
914    
915        memset (&cb, 0, sizeof (cb));
916        if (k->is_protected) {
917            pass = request_passphrase (_("Key Edit"), 1, &cancel);
918            if (cancel)
919                return FALSE;
920        }
921        cb.pass = pass;
922        cb.keyid = k->keyid;
923    
924      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
925                      keyedit_addphoto_dlg_proc, (LPARAM)k);                      keyedit_addphoto_dlg_proc, (LPARAM)&cb);
926    
927        if (cb.finished)
928            k->update = 1;
929        sfree_if_alloc (pass);    
930      return TRUE;      return TRUE;
931  }  }
932    
# Line 822  keyedit_add_photo (winpt_key_t k, HWND d Line 934  keyedit_add_photo (winpt_key_t k, HWND d
934  BOOL  BOOL
935  keyedit_add_revoker (winpt_key_t k, HWND dlg)  keyedit_add_revoker (winpt_key_t k, HWND dlg)
936  {  {
937      if( !k->key_pair ) {      keyedit_cb_s cb;
938          msg_box( dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR );      char *pass = NULL;
939        int cancel;
940    
941        if (!k->key_pair) {
942            msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
943          return FALSE;          return FALSE;
944      }      }
945    
946        if (k->is_protected) {
947            pass = request_passphrase (_("Key Edit"), 1, &cancel);
948            if (cancel)
949                return FALSE;
950        }
951    
952        memset (&cb, 0, sizeof (cb));
953        cb.is_protected = k->is_protected;
954        cb.keyid = k->keyid;
955        cb.pass = pass;
956      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
957                      keyedit_addrevoker_dlg_proc, (LPARAM)k);                      keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
958    
959        if (cb.finished)
960            k->update = 1;
961        sfree_if_alloc (pass);
962      return TRUE;      return TRUE;
963  } /* keyedit_add_revoker */  }
964    
965    
966    /* Change ownertrust of the given key @key.
967       Return TRUE if the ownertrust was changed. */
968    BOOL
969    keyedit_change_ownertrust (winpt_key_t key, HWND dlg)
970    {
971        int rc;
972    
973        rc = dialog_box_param (glob_hinst,
974                                 (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
975                                 dlg, keyedit_ownertrust_dlg_proc,
976                                 (LPARAM)key, _("Change Ownertrust"),
977                                 IDS_WINPT_KEYEDIT_OWNERTRUST);
978        if (rc == TRUE) {
979            msg_box (dlg, _("Key status changed."), _("Key Edit"), MB_OK);
980            key->update = 1;
981        }
982        return rc;
983    }
984    
985    
986    /* Check if the given key is supposed to have IDEA
987       for secret key protection. */
988  static int  static int
989  is_idea_protect_algo (const char * keyid)  is_idea_protect_algo (const char *keyid)
990  {  {
991      winpt_key_s k;      winpt_key_s k;
992      const unsigned char *sym_prefs;      const unsigned char *sym_prefs;
# Line 841  is_idea_protect_algo (const char * keyid Line 994  is_idea_protect_algo (const char * keyid
994    
995      memset (&k, 0, sizeof (k));      memset (&k, 0, sizeof (k));
996      if (winpt_get_pubkey (keyid, &k))      if (winpt_get_pubkey (keyid, &k))
997          BUG (NULL);          BUG (0);
998      sym_prefs = k.ext->sym_prefs;      sym_prefs = k.ext->sym_prefs;
999        if (!k.is_v3)
1000            return 0;
1001      if (!sym_prefs)      if (!sym_prefs)
1002          return 1; /* assume that only v3 keys have no symmetric cipher preferences          return 1; /* assume that only v3 keys have no symmetric cipher preferences
1003                       and thus IDEA is explicit. */                       and thus IDEA is explicit. */
# Line 851  is_idea_protect_algo (const char * keyid Line 1006  is_idea_protect_algo (const char * keyid
1006      if ((n == 0 || n == 1) && *sym_prefs == 0x01)      if ((n == 0 || n == 1) && *sym_prefs == 0x01)
1007          return 1;          return 1;
1008      return 0;      return 0;
1009  } /* is_idea_protect_algo */  }
1010    
1011    
1012  BOOL  BOOL
1013  keyedit_change_passwd( winpt_key_t k, HWND dlg )  keyedit_change_passwd (winpt_key_t k, HWND dlg)
1014  {  {
1015        gpgme_error_t err;
1016      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1017      gpgme_error_t ec;          char *old_pass = NULL;
1018      char *old_pass = NULL, *new_pass = NULL;      char *new_pass = NULL;
1019      int cancel = 0;      int cancel = 0;
1020    
1021      if( !k->key_pair ) {      if (!k->key_pair) {
1022          msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );          msg_box (dlg, _("There is no secret key available!"),
1023                     _("Key Edit"), MB_ERR);
1024          return FALSE;          return FALSE;
1025      }      }
1026    
1027      if( !idea_available && is_idea_protect_algo( k->keyid ) ) {      if (!idea_available && is_idea_protect_algo (k->keyid)) {
1028          msg_box( dlg, _("Cannot change passphrase because the key\n"          msg_box (dlg, _("Cannot change passphrase because the key\n"
1029                          "is protected with the IDEA encryption algorithm."),                          "is protected with the IDEA encryption algorithm."),
1030                          _("Key Edit"), MB_ERR );                          _("Key Edit"), MB_ERR);
1031          return FALSE;          return FALSE;
1032      }      }
1033    
1034      if( k->is_protected ) {      if (k->is_protected) {
1035          old_pass = request_passphrase( _("Current (old) Passphrase"), 1, &cancel );          old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);
1036          if( cancel )          if (cancel)
1037              return FALSE;              return FALSE;
1038      }      }
1039      new_pass = request_passphrase( _("New Passphrase" ), 1, &cancel );      new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);
1040      if( cancel ) {      if (cancel) {
1041          free_if_alloc( old_pass );          free_if_alloc (old_pass);
1042          return FALSE;          return FALSE;
1043      }      }
1044    
1045      if( is_8bit_string( new_pass ) ) {      if (is_8bit_string (new_pass)) {
1046          msg_box( dlg, _("The passphrase contains 8-bit characters.\n"          msg_box (dlg, _("The passphrase contains 8-bit characters.\n"
1047                           "It is not suggested to use charset specific characters."),                           "It is not suggested to use charset specific characters."),
1048                           _("Key Edit"), MB_ERR );                           _("Key Edit"), MB_ERR);
1049          free_if_alloc( old_pass );          free_if_alloc (old_pass);
1050          free_if_alloc( new_pass );          free_if_alloc (new_pass);
1051          return FALSE;          return FALSE;
1052      }      }
1053    
1054      ke = new GpgKeyEdit (k->keyid);      ke = create_GpgKeyEdit (k->keyid);
     if (!ke)  
         BUG (NULL);  
   
1055      ke->setPassphrase (k->is_protected? old_pass : NULL);      ke->setPassphrase (k->is_protected? old_pass : NULL);
1056      ec = ke->changePassphrase (new_pass, 0);      err = ke->changePassphrase (new_pass, 0);
1057      if( ec )      if (err)
1058          msg_box (dlg, gpgme_strerror (ec), _("Change Passwd"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Change Passwd"), MB_ERR);
1059      else      else
1060          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);          msg_box (dlg, _("Passphrase successfully changed."),  _("GnuPG status"), MB_OK);
1061      sfree_if_alloc (old_pass);      sfree_if_alloc (old_pass);
# Line 911  keyedit_change_passwd( winpt_key_t k, HW Line 1065  keyedit_change_passwd( winpt_key_t k, HW
1065  }  }
1066    
1067    
1068    /* Initialize sub key list from key @k and return
1069       the new listview control. */
1070  listview_ctrl_t  listview_ctrl_t
1071  subkey_list_init( HWND dlg, winpt_key_t k )  subkey_list_init (HWND dlg, winpt_key_t k)
1072  {  {
1073      LV_ITEM lvi;      LV_ITEM lvi;
     gpgme_key_t key;  
1074      gpgme_subkey_t sub;      gpgme_subkey_t sub;
1075      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1076          {0, 80, (char *)_("Description")},          {0, 80, (char *)_("Description")},
# Line 932  subkey_list_init( HWND dlg, winpt_key_t Line 1087  subkey_list_init( HWND dlg, winpt_key_t
1087      listview_ctrl_t lv;      listview_ctrl_t lv;
1088      char buf[256], tmp[128];      char buf[256], tmp[128];
1089      const char *t;      const char *t;
1090      int nkeys = 0, rc = 0, i, bits;          int nkeys = 0, i, bits;
1091    
1092      if( get_pubkey( k->keyid, &key ) ) {      nkeys = count_subkeys (k->ctx);
         msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );  
         return NULL;  
     }  
     nkeys = count_subkeys (key);  
1093      if( !nkeys ) {      if( !nkeys ) {
1094          msg_box( dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR );          msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);
1095          return NULL;          return NULL;
1096      }      }
1097                    
1098      rc  = listview_new( &lv );      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
1099      if( rc )      for (i = 0; cols[i].fieldname != NULL; i++)
1100          BUG( dlg );          listview_add_column (lv, &cols[i]);
           
     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );  
     for( i = 0; cols[i].fieldname != NULL; i++ )      
         listview_add_column( lv, &cols[i] );  
1101                    
1102      for( i = 0; i < nkeys; i++ ) {      for( i = 0; i < nkeys; i++ ) {
1103          listview_add_item( lv, "" );          listview_add_item( lv, "" );
1104          listview_add_sub_item( lv, 0, 1, "" );          listview_add_sub_item( lv, 0, 1, "" );
1105          memset( &lvi, 0, sizeof lvi );          memset( &lvi, 0, sizeof lvi );
1106          lvi.mask = LVIF_PARAM;            lvi.mask = LVIF_PARAM;  
1107          lvi.lParam = (LPARAM )key;          lvi.lParam = (LPARAM)k->ctx;
1108          if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )          if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
1109              return NULL;              return NULL;
1110      }      }
1111                    
1112      listview_set_ext_style( lv );      listview_set_ext_style( lv );
1113      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 ) {
1114          memset( buf, 0, sizeof buf );          memset( buf, 0, sizeof buf );
1115    
1116          bits = sub->length;          bits = sub->length;
# Line 982  subkey_list_init( HWND dlg, winpt_key_t Line 1129  subkey_list_init( HWND dlg, winpt_key_t
1129    
1130          t = get_key_created (sub->timestamp);          t = get_key_created (sub->timestamp);
1131          if( !t )          if( !t )
1132              t = "????-??-??";              t = "????" "-??" "-??";
1133          listview_add_sub_item( lv, i, 2, t );          listview_add_sub_item( lv, i, 2, t );
1134    
1135          if( sub->expires ) {          if( sub->expires ) {
# Line 1010  subkey_list_init( HWND dlg, winpt_key_t Line 1157  subkey_list_init( HWND dlg, winpt_key_t
1157          listview_add_sub_item (lv, i, 8, t);          listview_add_sub_item (lv, i, 8, t);
1158      }      }
1159      return lv;      return lv;
1160  } /* subkey_list_init */  }
1161    
1162    
1163  static listview_ctrl_t  static listview_ctrl_t
1164  userid_list_init (HWND dlg, winpt_key_t k)  userid_list_init (HWND dlg, winpt_key_t k)
1165  {  {
1166      listview_ctrl_t lv = NULL;      listview_ctrl_t lv = NULL;
     gpgme_key_t key;  
1167      gpgme_key_sig_t ks;      gpgme_key_sig_t ks;
1168      gpgme_user_id_t u;      struct native_uid_s *u;
1169      int nuids = 0, rc, j, u_attr;      int nuids = 0, j, u_attr;
1170      struct listview_column_s cols[] = {      struct listview_column_s cols[] = {
1171          {0,  72, (char *)_("Validity")},          {0,  72, (char *)_("Validity")},
1172          {1, 150, (char *)_("Name")},          {1, 150, (char *)_("Name")},
# Line 1029  userid_list_init (HWND dlg, winpt_key_t Line 1175  userid_list_init (HWND dlg, winpt_key_t
1175          {0, 0, 0}          {0, 0, 0}
1176      };          };    
1177      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;  
     }  
1178            
1179      nuids = count_userids (key);      nuids = count_userids (k->ctx);
1180      if (!nuids) {      if (!nuids) {
1181          msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);
1182          return NULL;          return NULL;
1183      }      }
1184                    
1185      rc = listview_new (&lv);      listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST));
     if( rc )  
         BUG( dlg );          
     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );  
1186      for( j = 0; cols[j].fieldname != NULL; j++ )      for( j = 0; cols[j].fieldname != NULL; j++ )
1187          listview_add_column( lv, &cols[j] );          listview_add_column (lv, &cols[j]);
1188                    
1189      for( j = 0; j < nuids; j++ ) {                for (j = 0; j < nuids; j++) {
1190          listview_add_item( lv, " " );          listview_add_item (lv, " ");
1191          listview_add_sub_item( lv, 0, 1, " " );                  listview_add_sub_item (lv, 0, 1, " " );        
1192      }      }
1193    
1194      listview_set_ext_style (lv);      listview_set_ext_style (lv);
1195      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++) {
1196          if (u->revoked)          if (u->revoked)
1197              attr = _("Revoked");              attr = _("Revoked");
1198          else {          else {
1199              u_attr = (int)u->validity;              u_attr = (int)u->validity;
1200              attr = get_key_trust2 (NULL, u_attr, 0, 0);              attr = get_key_trust2 (NULL, u_attr, 0, 0);
1201          }          }
1202          listview_add_sub_item( lv, j, 0, (char *)attr );                  listview_add_sub_item (lv, j, UID_COL_VALID, (char *)attr);
   
1203          /* XXX: add comment if available */          /* XXX: add comment if available */
1204          attr = u->name;          listview_add_sub_item (lv, j, UID_COL_NAME,
1205          if (attr) {                                 u->name? u->name : _("Invalid user ID"));
1206              char * uid = utf8_to_wincp (attr, strlen (attr));          if (u->email)
1207              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);  
1208    
1209          ks = get_selfsig (u, k->keyid+2, 1);          ks = get_selfsig (u->signatures, k->keyid, 1);
1210          if (ks)          if (ks)
1211              listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));              listview_add_sub_item (lv, j, UID_COL_CREATION,
1212                                       get_key_created (ks->timestamp));
1213      }      }
1214      if( !k->key_pair ) {      if( !k->key_pair ) {
1215          CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );          CheckDlgButton (dlg, IDC_KEYUID_ADD, BST_INDETERMINATE);
1216          CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );              CheckDlgButton (dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE);
1217      }      }
1218      return lv;      return lv;
1219  } /* userid_list_init */  }
1220    
1221    
1222  static void  static void
1223  do_init_cmdlist( HWND dlg )  do_init_cmdlist (HWND dlg, int is_keypair)
1224  {  {    
1225      const char *cmdlist[] = {      const char *s;
         "ADDKEY",  
         "ADDUID",  
         "ADDPHOTO",  
         "ADDREVOKER",  
         /*"FPR",*/  
         "DELUID",  
         "DELKEY",  
         "DELPHOTO",  
         /*"DELSIG",*/  
         "EXPIRE",  
         /*"PREF",*/  
         "SHOWPREF",  
         /*"SETPREF",*/  
         "PASSWD",  
         "PRIMARY",  
         "TRUST",  
         /*"REVSIG",*/  
         "REVUID",  
         "REVKEY",  
         "DISABLE",  
         "ENABLE",  
         "SHOWPHOTO",  
         NULL  
     };  
     const char * s;  
1226      int i = 0;      int i = 0;
1227    
1228      for( i = 0; (s=cmdlist[i]); i++ ) {      for (i = 0; (s=cmdlist[i].name); i++) {
1229          SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,          if (is_keypair)
1230                              (LPARAM)(char *)s );              SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1231                                    (LPARAM)(char *)s);
1232            else if (!cmdlist[i].need_pair)
1233                SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1234                                    (LPARAM)(char *)s);
1235      }      }
1236      SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0 );      SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0);
1237  } /* do_init_cmdlist */  }
1238    
1239    
1240    /* Return 1 if the requested command is RFC2440. */
1241  static int  static int
1242  is_cmd_openpgp( int cmdid )  is_cmd_openpgp (int cmdid)
1243  {  {
1244      switch( cmdid ) {      switch (cmdid) {
1245      case CMD_ADDKEY:      case CMD_ADDKEY:
1246      case CMD_ADDPHOTO:      case CMD_ADDPHOTO:
1247      case CMD_ADDREVOKER:      case CMD_ADDREVOKER:
1248      case CMD_DELPHOTO:      //case CMD_SETPREF:
     /*case CMD_SHOWPHOTO:*/  
     /*case CMD_SETPREF:*/  
1249          return 1;          return 1;
1250      }      }
1251      return 0;      return 0;
1252  } /* is_cmd_openpgp */  }
1253    
1254    
1255    /* Display a message box with a short description of the commands. */
1256  static void  static void
1257  do_show_help( HWND dlg )  do_show_help (HWND dlg)
1258  {  {
1259      char helptext[2048];      char helptext[2048];
1260    
1261      _snprintf( helptext, sizeof helptext-1,      _snprintf (helptext, sizeof (helptext)-1,
1262          _(/*"FPR            \t\tshow fingerprint\r\n"*/          _(
1263           "ADDUID   \t\tadd a user ID\r\n"           "ADDUID   \t\tadd a user ID\r\n"
1264           "ADDPHOTO  \t\tadd a photo ID\r\n"           "ADDPHOTO  \t\tadd a photo ID\r\n"
1265           "DELUID    \t\tdelete a user ID\r\n"           "DELUID    \t\tdelete a user ID\r\n"
1266           "ADDKEY    \t\tadd a secondard key\r\n"           "ADDKEY    \t\tadd a secondard key\r\n"
1267           "DELKEY    \t\tdelete a secondary key\r\n"           "DELKEY    \t\tdelete a secondary key\r\n"
1268           "ADDREVOKER\t\tadd a revocation key\r\n"           "ADDREVOKER\t\tadd a revocation key\r\n"
          /*"DELSIG    \t\tdelete signatures\r\n"*/  
1269           "EXPIRE    \t\tchange the expire date\r\n"           "EXPIRE    \t\tchange the expire date\r\n"
          /*"PREF            \t\tlist preferences (expert)\r\n"  
1270           "SHOWPREF  \t\tlist preferences (verbose)\r\n"           "SHOWPREF  \t\tlist preferences (verbose)\r\n"
1271           "SETPREF   \t\tset preference list\r\n"*/           "SETPREF   \t\tset preference list\r\n"
1272           "UPDPREF   \t\tupdated preferences\r\n"           "UPDPREF   \t\tupdated preferences\r\n"
1273           "PASSWD    \t\tchange the passphrase\r\n"           "PASSWD    \t\tchange the passphrase\r\n"
1274           "PRIMARY   \t\tflag user ID as primary\r\n"           "PRIMARY   \t\tflag user ID as primary\r\n"
1275           "TRUST     \t\tchange the ownertrust\r\n"           "TRUST     \t\tchange the ownertrust\r\n"
          /*"REVSIG    \t\trevoke signatures\r\n"*/  
1276           "REVUID    \t\trevoke a user ID\r\n"           "REVUID    \t\trevoke a user ID\r\n"
1277           "REVKEY    \t\trevoke a secondary key\r\n"           "REVKEY    \t\trevoke a secondary key\r\n"
1278           "DISABLE   \t\tdisable a key\r\n"           "DISABLE   \t\tdisable a key\r\n"
1279           "ENABLE    \t\tenable a key\r\n"           "ENABLE    \t\tenable a key\r\n"
1280           /*"SHOWPHOTO \t\tshow photo ID\r\n"*/) );           "SIGN      \t\tsign a user-id (exportable)\r\n"
1281      msg_box( dlg, helptext, _("Key Edit Help"), MB_OK );           "LSIGN     \t\tsign a user-id (non-exportable)\r\n"
1282  } /* do_show_help */           "CLEAN     \t\tremove unusable signatures from key\r\n"
1283             "MINIMIZE  \t\tremove all signatures from key\r\n"
1284             ));
1285        msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);
1286    }
1287    
1288    
1289  static int  static int
# Line 1201  do_editkey_delkey (winpt_key_t k, HWND d Line 1310  do_editkey_delkey (winpt_key_t k, HWND d
1310          return FALSE;          return FALSE;
1311      }      }
1312            
1313      listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );      /* XXX: change the warning to make clear that verification won't work
1314      id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,              any longer if this is a sign-only key. */
1315        listview_get_item_text (lv, j, 0, tmp, sizeof (tmp) -1);
1316        id = log_box (_("Key Edit"), MB_YESNO|MB_ICONWARNING,
1317                      _("\"Subkey %s.\"\n\n"                      _("\"Subkey %s.\"\n\n"
1318                        "Anything encrypted to the selected subkey will no longer\n"                        "Anything encrypted to the selected subkey will no longer\n"
1319                        "be able to be decrypted.\n\n"                        "be able to be decrypted.\n\n"
1320                        "Do you really want to delete this subkey?"), tmp );                        "Do you really want to delete this subkey?"), tmp);
1321      if( id == IDNO )      if (id == IDNO)
1322          return FALSE;          return FALSE;
1323    
1324      ke = new GpgKeyEdit (k->keyid);      ke = new GpgKeyEdit (k->keyid);
# Line 1223  do_editkey_delkey (winpt_key_t k, HWND d Line 1334  do_editkey_delkey (winpt_key_t k, HWND d
1334      }      }
1335      delete ke;      delete ke;
1336      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1337  } /* do_editkey_delkey */  }
1338    
1339    
1340  /* 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 1281  do_editkey_expire (winpt_key_t k, HWND d Line 1392  do_editkey_expire (winpt_key_t k, HWND d
1392          BUG (NULL);          BUG (NULL);
1393      if (k->is_protected)      if (k->is_protected)
1394          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1395      err = ke->setKeyExpireDate (j, diff_time (NULL, &udd.st), true);      else
1396            ke->setNoPassphrase (true);
1397        err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);
1398      if (err)      if (err)
1399          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1400      else {      else {
# Line 1344  do_editkey_revoke (winpt_key_t k, HWND d Line 1457  do_editkey_revoke (winpt_key_t k, HWND d
1457          BUG (NULL);          BUG (NULL);
1458      if (k->is_protected)      if (k->is_protected)
1459          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1460        else
1461            ke->setNoPassphrase (true);
1462      err = ke->revokeSubkey (j, 0, NULL);      err = ke->revokeSubkey (j, 0, NULL);
1463      if (err)      if (err)
1464          msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);          msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);
# Line 1365  do_editkey_revuid (winpt_key_t k, HWND d Line 1480  do_editkey_revuid (winpt_key_t k, HWND d
1480  {  {
1481      gpgme_error_t err;      gpgme_error_t err;
1482      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1483      char buf[256], t[512];      char buf[128], email[128];
1484      char *pass=NULL;      char inf[512];
1485        char *pass = NULL;
1486      int cancel = 0, id = 0, j;      int cancel = 0, id = 0, j;
1487    
1488      if (!k->key_pair) {      if (!k->key_pair) {
1489          msg_box( dlg, _("There is no secret key available!"), _("Revoke user ID"), MB_ERR );          msg_box (dlg, _("There is no secret key available!"),
1490                     _("Revoke user ID"), MB_ERR);
1491          return FALSE;          return FALSE;
1492      }      }
1493    
1494      if( listview_count_items( lv, 0 ) == 1 ) {      if (listview_count_items (lv, 0) == 1) {
1495          msg_box( dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR );            msg_box (dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR);  
1496          return FALSE;          return FALSE;
1497      }      }
1498    
# Line 1384  do_editkey_revuid (winpt_key_t k, HWND d Line 1501  do_editkey_revuid (winpt_key_t k, HWND d
1501          return FALSE;            return FALSE;  
1502      }      }
1503                            
1504      listview_get_item_text( lv, j, 0, buf, sizeof buf - 1 );      listview_get_item_text( lv, j, UID_COL_VALID, buf, sizeof buf - 1);
1505      if( strstr( buf, _("Revoked") ) ) {      if (strstr (buf, _("Revoked"))) {
1506          msg_box( dlg, _("This user ID has been already revoked."), _("Key Edit"), MB_INFO );          msg_box (dlg, _("This user ID has been already revoked."),
1507                     _("Key Edit"), MB_INFO);
1508          return FALSE;          return FALSE;
1509      }      }
1510                            
1511      listview_get_item_text (lv, j, 1, buf, sizeof buf -1);      listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);
1512      _snprintf( t, sizeof t -1, _("user ID \"%s\".\n\n"      _snprintf (inf, sizeof (inf) -1, _("user ID \"%s\".\n\n"
1513                  "Do you really want to revoke this user ID?"), buf );                 "Do you really want to revoke this user ID?"), buf);
1514      if( msg_box( dlg, t, _("Key Edit"), MB_WARN_ASK) == IDNO )      if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1515          return FALSE;          return FALSE;
1516      if( k->is_protected ) {      if (k->is_protected) {
1517          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_passphrase (_("Key Edit"), 1, &cancel);
1518          if (cancel)          if (cancel)
1519              return FALSE;                        return FALSE;          
1520      }      }
1521      listview_get_item_text (lv, j, 2, buf, sizeof (buf)-1);      listview_get_item_text (lv, j, UID_COL_EMAIL, email, sizeof (email)-1);
1522      id = do_find_userid (k->keyid, buf, NULL);      listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof (buf)-1);
1523        id = do_find_userid (k->keyid, email, buf, NULL);
1524      if (id == -1)      if (id == -1)
1525          BUG (NULL);          BUG (NULL);
1526    
# Line 1410  do_editkey_revuid (winpt_key_t k, HWND d Line 1529  do_editkey_revuid (winpt_key_t k, HWND d
1529          BUG (NULL);          BUG (NULL);
1530      if (k->is_protected)      if (k->is_protected)
1531          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1532        else
1533            ke->setNoPassphrase (true);
1534      err = ke->revokeUserid (id);      err = ke->revokeUserid (id);
1535      if (err)      if (err)
1536          msg_box (dlg, gpgme_strerror (err), _("Revoke Signature"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);
1537      else {      else {
1538          listview_add_sub_item (lv, j, 0, _("Revoked"));          listview_add_sub_item (lv, j, 0, _("Revoked"));
1539          k->update = 1;          k->update = 1;
# Line 1437  do_editkey_setpref (winpt_key_t k, HWND Line 1558  do_editkey_setpref (winpt_key_t k, HWND
1558          return FALSE;          return FALSE;
1559      }      }
1560      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1561      id = do_find_userid (k->keyid, buf, NULL);      id = do_find_userid (k->keyid, buf, NULL, NULL);
1562      if (id == -1)      if (id == -1)
1563          BUG (dlg);          BUG (dlg);
1564      if (k->is_protected) {      if (k->is_protected) {
# Line 1451  do_editkey_setpref (winpt_key_t k, HWND Line 1572  do_editkey_setpref (winpt_key_t k, HWND
1572          BUG (NULL);          BUG (NULL);
1573      if (k->is_protected)      if (k->is_protected)
1574          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1575        else
1576            ke->setNoPassphrase (true);
1577    
1578      get_userid_preflist (&prefs, &flags);      get_userid_preflist (&prefs, &flags);
1579    
1580      rc = ke->setUseridPreferences (id, prefs);      rc = ke->setUseridPreferences (id, prefs);
1581      /* XXX */      if (rc)
1582            msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);
1583    
1584      sfree_if_alloc (pass);      sfree_if_alloc (pass);
1585      free_if_alloc (prefs);      free_if_alloc (prefs);
# Line 1470  do_editkey_primary (winpt_key_t k, HWND Line 1594  do_editkey_primary (winpt_key_t k, HWND
1594      gpgme_error_t err;      gpgme_error_t err;
1595      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1596      int j, id, cancel=0;      int j, id, cancel=0;
1597      char buf[256], * pass = NULL;      char buf[256], *pass = NULL;
1598    
1599      if (listview_count_items (lv, 0) == 1)      if (listview_count_items (lv, 0) == 1)
1600          return TRUE;          return TRUE;
# Line 1479  do_editkey_primary (winpt_key_t k, HWND Line 1603  do_editkey_primary (winpt_key_t k, HWND
1603          return FALSE;          return FALSE;
1604      }      }
1605      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);      listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1606      id = do_find_userid (k->keyid, buf, NULL);      id = do_find_userid (k->keyid, buf, NULL, NULL);
1607      if (id == -1)      if (id == -1)
1608          BUG (dlg);          BUG (0);
1609      if (k->is_protected) {      if (k->is_protected) {
1610          pass = request_passphrase (_("Key Edit"), 1, &cancel);          pass = request_passphrase (_("Key Edit"), 1, &cancel);
1611          if( cancel )          if (cancel)
1612              return FALSE;              return FALSE;
1613      }      }
1614    
1615      ke = new GpgKeyEdit (k->keyid);      ke = new GpgKeyEdit (k->keyid);
1616      if (k->is_protected)      if (k->is_protected)
1617          ke->setPassphrase (pass);          ke->setPassphrase (pass);
1618        else
1619            ke->setNoPassphrase (true);
1620      err = ke->setPrimaryUserid (id);      err = ke->setPrimaryUserid (id);
1621      if (err)      if (err)
1622          msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);          msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);
# Line 1505  do_editkey_primary (winpt_key_t k, HWND Line 1631  do_editkey_primary (winpt_key_t k, HWND
1631  }  }
1632    
1633    
1634    
1635    #define CIPHER  11
1636    #define HASH    11
1637    #define COMPR    4
1638    
1639  static int  static int
1640  parse_preflist (HWND dlg, const char *list)  parse_preflist (HWND dlg, const char *list)
1641  {  {
1642      char *p, buf[128] = {0}, *pbuf = buf;      char buf[128] = {0};
1643      const char *ciphers[11] = {0, "IDEA", "3DES", "CAST5", "BLOWFISH", 0, 0, "AES", "AES192", "AES256", "TWOFISH"};      char *p, *pbuf = buf;
1644      const char *hash[11] = {0, "MD5", "SHA1", "RMD160", 0, 0, 0, 0, "SHA256", "SHA384", "SHA512"};      const char *ciphers[CIPHER] = {"", "IDEA", "3DES",
1645      const char *compress[4] = {0, "ZIP", "ZLIB", "BZIP2"};                                     "CAST5", "BLOWFISH", "", "",
1646                                       "AES", "AES192", "AES256", "TWOFISH"};
1647        const char *hash[HASH] = {"", "MD5", "SHA1", "RMD160", "",
1648                                  "", "", "", "SHA256", "SHA384", "SHA512"};
1649        const char *compress[COMPR] = {"", "ZIP", "ZLIB", "BZIP2"};
1650      int n=0;      int n=0;
1651    
1652      strncpy (buf, list, 127);      strncpy (buf, list, 127);
# Line 1521  parse_preflist (HWND dlg, const char *li Line 1656  parse_preflist (HWND dlg, const char *li
1656          n++;          n++;
1657          switch (*p) {          switch (*p) {
1658          case 'S':          case 'S':
1659              SendDlgItemMessage (dlg, IDC_SHOWPREF_CIPHERS, LB_ADDSTRING, 0, (LPARAM)(const char*)ciphers[algid % 11]);              SendDlgItemMessage (dlg, IDC_SHOWPREF_CIPHERS, LB_ADDSTRING, 0,
1660                                    (LPARAM)(const char*)ciphers[algid % CIPHER]);
1661              break;              break;
1662    
1663          case 'H':          case 'H':
1664              SendDlgItemMessage (dlg, IDC_SHOWPREF_HASH, LB_ADDSTRING, 0, (LPARAM)(const char*)hash[algid % 10]);              SendDlgItemMessage (dlg, IDC_SHOWPREF_HASH, LB_ADDSTRING, 0,
1665                                    (LPARAM)(const char*)hash[algid % HASH]);
1666              break;              break;
1667    
1668          case 'Z':          case 'Z':
1669              SendDlgItemMessage (dlg, IDC_SHOWPREF_ZIP, LB_ADDSTRING, 0, (LPARAM)(const char*)compress[algid % 4]);              SendDlgItemMessage (dlg, IDC_SHOWPREF_ZIP, LB_ADDSTRING, 0,
1670                                    (LPARAM)(const char*)compress[algid % COMPR]);
1671              break;              break;
1672    
1673          default:          default:
# Line 1545  parse_preflist (HWND dlg, const char *li Line 1683  parse_preflist (HWND dlg, const char *li
1683  BOOL CALLBACK  BOOL CALLBACK
1684  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1685  {  {
1686      static keyedit_callback_s *cb = NULL;      static keyedit_cb_t cb = NULL;
1687      gpg_uid_info_t inf=NULL;      gpg_uid_info_t inf=NULL, u;
1688        gpgme_key_t key;
1689      char buf[128];      char buf[128];
1690      int pos;      int pos;
1691    
1692      switch (msg) {      switch (msg) {
1693      case WM_INITDIALOG:      case WM_INITDIALOG:
1694          cb = (keyedit_callback_s *)lparam;          cb = (keyedit_cb_t)lparam;
1695          if (cb == NULL)          if (!cb)
1696              BUG (dlg);              BUG (NULL);
1697          listview_get_item_text (cb->lv, listview_get_curr_pos (cb->lv), 2, buf, DIM (buf)-1);          key = (gpgme_key_t)cb->opaque;
1698          SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);          listview_get_item_text (cb->lv, cb->lv_pos,
1699          pos = do_find_userid (((winpt_key_t)cb->opaque)->keyid, buf, &inf);                                  UID_COL_EMAIL, buf, sizeof (buf)-1);
1700          if (inf) {          pos = do_find_userid (cb->keyid, buf, NULL, &inf);
1701              const char *prefs = inf->prefs;          if (pos < 0 || !inf) {
             if (prefs && *prefs) {  
                 if (parse_preflist (dlg, prefs) <= 0)  
                     pos = -1;  
             }  
             else  
                 pos = -1;  
1702              gpg_uid_info_release (inf);              gpg_uid_info_release (inf);
1703              if (pos == -1) {              EndDialog (dlg, FALSE);
1704                  msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);              break;
1705                  EndDialog (dlg, TRUE);          }
1706            for (u=inf; u; u = u->next) {
1707                if (u->index == pos && u->prefs && *u->prefs) {
1708                    _snprintf (buf, sizeof (buf)-1, "%s", u->name);
1709                    SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1710                    if (parse_preflist (dlg, u->prefs) <= 0)
1711                        pos = -1;
1712                    if (u->flags.mdc)
1713                        CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1714                    break;
1715              }              }
             if (inf->flags.mdc)  
                 CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);  
1716          }          }
1717            gpg_uid_info_release (inf);
1718            if (pos == -1) {        
1719                msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1720                EndDialog (dlg, FALSE);
1721                break;
1722            }
1723            SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1724            SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1725            SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1726          SetWindowText (dlg, _("Key Preferences"));          SetWindowText (dlg, _("Key Preferences"));
1727          SetForegroundWindow (dlg);          SetForegroundWindow (dlg);
1728          break;          break;
# Line 1583  showpref_dlg_proc (HWND dlg, UINT msg, W Line 1732  showpref_dlg_proc (HWND dlg, UINT msg, W
1732          case IDOK:          case IDOK:
1733              EndDialog (dlg, TRUE);              EndDialog (dlg, TRUE);
1734              break;              break;
1735    
1736            case IDCANCEL:
1737                EndDialog (dlg, FALSE);
1738                break;
1739          }          }
1740          break;          break;
1741      }      }
# Line 1593  showpref_dlg_proc (HWND dlg, UINT msg, W Line 1746  showpref_dlg_proc (HWND dlg, UINT msg, W
1746  static int  static int
1747  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)
1748  {  {
1749      struct keyedit_callback_s cb;      struct keyedit_cb_s cb;
1750        char status[32];
1751    
1752      if (k->is_v3)      if (k->is_v3)
1753          return TRUE;          return TRUE;
# Line 1602  do_editkey_showpref (winpt_key_t k, HWND Line 1756  do_editkey_showpref (winpt_key_t k, HWND
1756          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);          msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1757          return FALSE;          return FALSE;
1758      }      }
   
1759      memset (&cb, 0, sizeof (cb));      memset (&cb, 0, sizeof (cb));
1760        cb.opaque = k->ctx;
1761        cb.keyid = k->keyid;
1762      cb.lv = lv;      cb.lv = lv;
1763      cb.opaque = k;      cb.lv_pos = listview_get_curr_pos (lv);
1764    
1765        listview_get_item_text (lv, cb.lv_pos, UID_COL_VALID,
1766                                status, sizeof (status)-1);
1767        if (!strcmp (status, _("Revoked")))
1768            return TRUE;
1769        
1770      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1771                      showpref_dlg_proc, (LPARAM)&cb);                      showpref_dlg_proc, (LPARAM)&cb);
1772      return TRUE;      return TRUE;
# Line 1617  do_editkey_deluid (winpt_key_t k, HWND d Line 1778  do_editkey_deluid (winpt_key_t k, HWND d
1778  {  {
1779      gpgme_error_t err;      gpgme_error_t err;
1780      GpgKeyEdit *ke;      GpgKeyEdit *ke;
1781      char buf[256], t[512];      char email[128], name[128];
1782        char inf[384];
1783      int j, id = 0;      int j, id = 0;
1784    
1785      if (!k->key_pair)      if (!k->key_pair)
1786          return FALSE; /* XXX: see do_editkey_delsubkey */          return FALSE; /* XXX: see do_editkey_delsubkey */
1787    
1788      if( listview_count_items( lv, 0 ) == 1 ) {      if (listview_count_items (lv, 0) == 1) {
1789          msg_box( dlg, _("Primary user ID can not be deleted!"), _("Key Edit"), MB_ERR );          msg_box (dlg, _("Primary user ID can not be deleted!"),
1790                     _("Key Edit"), MB_ERR);
1791          return FALSE;          return FALSE;
1792      }      }
1793      if( (j = listview_get_curr_pos( lv )) == -1 ) {      if ((j = listview_get_curr_pos (lv)) == -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? */      /* XXX: add a hint that also all signatures will be deleted? */
1799      listview_get_item_text( lv, j, 1, buf, DIM(buf) -1 );      listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);
1800      _snprintf( t, DIM (t)-1, _("user ID \"%s\".\n\n"      _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1801                                 "Do you really want to delete this user ID?"),                                     "All signatures on this user ID will be also deleted."
1802                                 buf);                                     "\n\n"
1803      if( msg_box( dlg, t, _("Key Edit"), MB_YESNO|MB_ICONWARNING ) == IDNO )                                     "Do you really want to delete this user ID?"),
1804                                   name);
1805        if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1806          return FALSE;          return FALSE;
1807            
1808      listview_get_item_text (lv, j, 2, buf, DIM (buf)-1);      listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1809      id = do_find_userid (k->keyid, buf, NULL);      listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);
1810        id = do_find_userid (k->keyid, email, name, NULL);
1811      if (id == -1)      if (id == -1)
1812          BUG (dlg);          BUG (dlg);
1813    
# Line 1650  do_editkey_deluid (winpt_key_t k, HWND d Line 1816  do_editkey_deluid (winpt_key_t k, HWND d
1816          BUG (NULL);          BUG (NULL);
1817    
1818      err = ke->delUserid (id);      err = ke->delUserid (id);
1819      if( err )      if (err)
1820          msg_box( dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR );          msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);
1821      else {      else {
1822          listview_del_item( lv, j );          listview_del_item (lv, j);
1823          k->update = 1;          k->update = 1;
1824          status_box( dlg, _("User ID successfully deleted"), _("GnuPG Status") );          status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1825      }      }
1826      delete ke;      delete ke;
1827      return err? FALSE : TRUE;      return err? FALSE : TRUE;
1828  } /* do_editkey_deluid */  }
   
1829    
1830    
1831    /* Subclass routine for the subkey listview control to allow shortcuts. */
1832  static BOOL CALLBACK  static BOOL CALLBACK
1833  subkey_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )  subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1834  {  {
1835      switch( msg ) {      int virt_key = 0;
1836        winpt_key_t key;
1837    
1838        switch (msg) {
1839      case WM_KEYUP:      case WM_KEYUP:
1840          int virt_key = (int)wparam;          virt_key = (int)wparam;
1841          switch( virt_key ) {                  key = (winpt_key_t)keyedit_subkey_proc.opaque;
1842            if (!key || !key->key_pair)
1843                break;
1844    
1845            switch (virt_key) {
1846          case VK_DELETE:          case VK_DELETE:
1847              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1848                                  CB_SETCURSEL, CMD_DELKEY, 0 );                                  CB_SETCURSEL, CMD_DELKEY, 0);
1849              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1850              break;              break;
1851    
1852          case VK_INSERT:          case VK_INSERT:
1853              SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1854                                  CB_SETCURSEL, CMD_ADDKEY, 0 );                                  CB_SETCURSEL, CMD_ADDKEY, 0);
1855              send_cmd_id( keyedit_subkey_proc.dlg, IDOK );              send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1856              break;              break;
1857          }          }
1858      }      }
1859      return CallWindowProc( keyedit_subkey_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1860  } /* subkey_subclass_proc */  }
1861    
1862    
1863  static BOOL CALLBACK  static BOOL CALLBACK
1864  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1865  {  {
1866      switch( msg ) {      int virt_key = 0;
1867        winpt_key_t key;
1868    
1869        switch (msg) {
1870      case WM_KEYUP:      case WM_KEYUP:
1871          int virt_key = (int)wparam;          virt_key = (int)wparam;
1872            key = (winpt_key_t)keyedit_uid_proc.opaque;
1873            if (!key || !key->key_pair)
1874                break;
1875    
1876          switch (virt_key) {          switch (virt_key) {
1877          case VK_DELETE:          case VK_DELETE:
1878              SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,              SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
# Line 1707  uid_subclass_proc (HWND dlg, UINT msg, W Line 1887  uid_subclass_proc (HWND dlg, UINT msg, W
1887              break;              break;
1888          }          }
1889      }      }
1890      return CallWindowProc( keyedit_uid_proc.old, dlg, msg, wparam, lparam );      return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1891  } /* uid_subclass_proc */  }
1892    
1893    
1894    /* Enable the key @k when @enable is 1, disable it otherwise. */
1895    static void
1896    do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1897                               listview_ctrl_t lv, int enable)
1898    {
1899        km_enable_disable_key (lv, dlg, 0, enable);
1900        k->update = 1;
1901    }
1902    
1903    
1904    /* Return default secret key. */
1905    static gpgme_key_t
1906    get_default_key (void)
1907    {
1908        gpgme_key_t def_sk;
1909        char *keyid = get_gnupg_default_key ();
1910    
1911        get_seckey (keyid, &def_sk);
1912        free_if_alloc (keyid);
1913        return def_sk;
1914    }
1915    
1916    
1917    
1918    static void
1919    do_editkey_minimize (winpt_key_t k, HWND dlg)
1920    {
1921        gpgme_error_t err;
1922        GpgKeyEdit *ke;
1923    
1924        ke = create_GpgKeyEdit (k->keyid);
1925        err = ke->minimizeKey ();
1926        if (err)
1927            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1928        else {
1929            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1930            k->update = 1;
1931        }
1932        delete ke;
1933    }
1934    
1935    
1936    static void
1937    do_editkey_clean (winpt_key_t k, HWND dlg)
1938    {
1939        gpgme_error_t err;
1940        GpgKeyEdit *ke;
1941        
1942        ke = create_GpgKeyEdit (k->keyid);
1943        err = ke->cleanKey ();
1944        if (err)
1945            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);  
1946        else {
1947            msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1948            k->update = 1;
1949        }
1950        delete ke;
1951    }
1952    
1953    
1954    /* Start the dialog to list and display the status of all
1955       signatures for this key. */
1956    static void
1957    do_editkey_check (winpt_key_t k, HWND dlg)
1958    {
1959        if (!k->ctx)
1960            get_pubkey (k->keyid, &k->ctx);
1961        if (!k->uid && k->ctx)
1962            k->uid = k->ctx->uids->uid;
1963        DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYSIG_TREE, dlg,
1964                        sigtree_dlg_proc, (LPARAM)k);
1965    }
1966    
1967    
1968    static int
1969    do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1970    {
1971        gpgme_error_t err;
1972        GpgKeyEdit *ke;
1973        char *pass = NULL;
1974        char email[64], name[128];
1975        int uid_index;
1976        int cancel = 0;
1977    
1978        uid_index = listview_get_curr_pos (lv);
1979        if (uid_index == -1) {
1980            msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1981            return FALSE;
1982        }
1983        if (mode == CMD_SIGN) {
1984            cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
1985                              _("Key Edit"), MB_QUEST_ASK);
1986            if (cancel == IDNO)
1987                return FALSE;
1988        }
1989    
1990        listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
1991        listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
1992        uid_index = do_find_userid (k->keyid, email, name, NULL);
1993        if (k->is_protected) {
1994            pass = request_passphrase (_("Key Edit"), 1, &cancel);
1995            if (cancel)
1996                return FALSE;
1997        }
1998        ke = create_GpgKeyEdit (k->keyid);
1999        if (k->is_protected)
2000            ke->setPassphrase (pass);
2001        else
2002            ke->setNoPassphrase (true);
2003        ke->setLocalUser (get_default_key ());
2004        err = ke->signUserid (uid_index,
2005                              mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
2006                              0, NULL);
2007        if (!err) {
2008            msg_box (dlg, _("Key successfully signed."), _("Key Edit"), MB_OK);
2009            k->update = 1;
2010        }
2011        else
2012            msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
2013        delete ke;
2014        sfree_if_alloc (pass);
2015        return !err? TRUE : FALSE;
2016    }
2017    
2018    
2019    static int
2020    lookup_cmd (HWND dlg)
2021    {
2022        char buf[64];
2023        int i;
2024    
2025        i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
2026        if (i == LB_ERR)
2027            return LB_ERR;
2028        GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);
2029        for (i=0; cmdlist[i].name != NULL; i++) {
2030            if (!strcmp (buf, cmdlist[i].name))
2031                return cmdlist[i].id;
2032        }
2033        return LB_ERR;
2034    }
2035    
2036    
2037    
2038    gpgme_error_t key_get_revokers (winpt_key_t key, int reload,
2039                                    gpg_desig_rev_t *r_rev);
2040    
2041    /* Check if the key supports designated revokers and if
2042        secret keys exist to generate such a revoke cert. */
2043    static bool
2044    check_desig_rev (winpt_key_t key)
2045    {
2046        gpg_desig_rev_t rev, u;
2047        struct winpt_key_s sk;
2048    
2049        if (!key->ext->gloflags.has_desig_rev)
2050            return false;
2051        key_get_revokers (key, 0, &rev);
2052        for (u = rev; u; u = u->next) {
2053            memset (&sk, 0, sizeof (sk));
2054            if (!winpt_get_seckey (u->fpr+32, &sk))
2055                return true;
2056        }
2057        return false;
2058    }
2059    
2060    
2061    /* Use the gpg --desig-revoker command to create a revocation
2062       cert for a key that lists our key as a designated revoker. */
2063    static void
2064    gen_desig_revoke_cert (winpt_key_t key, HWND dlg)
2065    {
2066        const char *warn;
2067        char *inf, *p;
2068        int id;
2069    
2070        inf = km_key_get_info (key, 0);
2071        warn = _("Your keys is listed as a designated revoker for the key\n\n"
2072                 "%s\n\n"
2073                 "Are you sure you want to create a revocation certificate\n"
2074                 "which allow to revoke the key listed above?");
2075        p = new char[strlen (inf)+1+strlen (warn)+1];
2076        sprintf (p, warn, inf);
2077        free_if_alloc (inf);
2078    
2079        id = msg_box (dlg, p, _("Key Edit"), MB_YESNO|MB_ICONWARNING);
2080        free_if_alloc (p);
2081        if (id == IDNO)
2082            return;
2083    
2084        key->internal = 1;
2085        DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKE, dlg,
2086                        key_revoke_dlg_proc, (LPARAM)key);
2087    }
2088    
2089    
2090    /* Dialog box procedure for the edit key dialog. */
2091  BOOL CALLBACK  BOOL CALLBACK
2092  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2093  {  {
2094      static winpt_key_t k;      static winpt_key_t k;
2095      static listview_ctrl_t lvsub = NULL, lvuid = NULL;      static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2096      int cmd, idxsub = 0;      int cmd;
2097      HWND item;      HWND item;
2098    
2099      switch( msg ) {      switch (msg) {
2100      case WM_INITDIALOG:      case WM_INITDIALOG:
2101          k = (winpt_key_t)lparam;          k = (winpt_key_t)lparam;
2102          if (!k)          if (!k)
2103              BUG (NULL);              BUG (NULL);
2104          do_init_cmdlist (dlg);          do_init_cmdlist (dlg, k->key_pair);
2105          lvsub = subkey_list_init (dlg, k);          lvsub = subkey_list_init (dlg, k);
2106          if( !lvsub )          if (!lvsub)
2107              BUG( NULL );              BUG (0);
2108          lvuid = userid_list_init (dlg, k);          lvuid = userid_list_init (dlg, k);
2109          if( !lvuid )          if (!lvuid)
2110              BUG( NULL );              BUG (0);
2111          item = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );          item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2112            keyedit_subkey_proc.opaque = (void*)k;
2113          keyedit_subkey_proc.dlg = dlg;          keyedit_subkey_proc.dlg = dlg;
2114          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;          keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2115          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2116          if( keyedit_subkey_proc.old ) {          if (keyedit_subkey_proc.old) {
2117              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_subkey_proc.current ) ) {              if( !SetWindowLong (item, GWL_WNDPROC,
2118                  msg_box( dlg, _("Could not set subkey window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_subkey_proc.current)) {
2119                  BUG( NULL );                  msg_box (dlg, _("Could not set subkey window procedure."),
2120                             _("Key Edit"), MB_ERR);
2121                    BUG (0);
2122              }              }
2123          }          }
2124          item = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );          item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2125            keyedit_uid_proc.opaque = (void*)k;
2126          keyedit_uid_proc.dlg = dlg;          keyedit_uid_proc.dlg = dlg;
2127          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;          keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2128          keyedit_uid_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );          keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2129          if( keyedit_uid_proc.old ) {          if (keyedit_uid_proc.old) {
2130              if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_uid_proc.current ) ) {              if (!SetWindowLong (item, GWL_WNDPROC,
2131                  msg_box( dlg, _("Could not set user ID window procedure."), _("Key Edit"), MB_ERR );                                  (LONG)keyedit_uid_proc.current)) {
2132                  BUG( NULL );                  msg_box (dlg, _("Could not set user ID window procedure."),
2133                             _("Key Edit"), MB_ERR);
2134                    BUG (0);
2135              }              }
2136          }          }
2137          if (!k->key_pair) {          if (k->ctx->revoked) {
2138              EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);              EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
2139              EnableWindow (GetDlgItem (dlg, IDOK), FALSE);              EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
2140          }          }
2141          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));          SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2142          SetDlgItemText (dlg, IDCANCEL, _("&Exit"));          SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2143          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));          SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2144            SetDlgItemText (dlg, IDC_KEYEDIT_REVOKE, _("&Revoke..."));
2145            if (!check_desig_rev (k))
2146                ShowWindow (GetDlgItem (dlg, IDC_KEYEDIT_REVOKE), SW_HIDE);
2147          SetWindowText (dlg, _("Key Edit"));          SetWindowText (dlg, _("Key Edit"));
2148                    SetForegroundWindow (dlg);
2149          SetForegroundWindow( dlg );          center_window (dlg, NULL);
         center_window( dlg, NULL );  
2150          return TRUE;          return TRUE;
2151    
2152      case WM_DESTROY:      case WM_DESTROY:
2153          if( lvsub ) {          if (lvsub) {
2154              listview_release( lvsub );              listview_release (lvsub);
2155              lvsub = NULL;              lvsub = NULL;
2156          }          }
2157          if( lvuid ) {          if (lvuid) {
2158              listview_release( lvuid );              listview_release (lvuid);
2159              lvuid = NULL;              lvuid = NULL;
2160          }          }
2161          break;          break;
# Line 1786  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2171  keyedit_main_dlg_proc (HWND dlg, UINT ms
2171      case WM_COMMAND:      case WM_COMMAND:
2172          switch( LOWORD( wparam ) ) {          switch( LOWORD( wparam ) ) {
2173          case IDOK:          case IDOK:
2174              cmd = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);              cmd = lookup_cmd (dlg);
2175              if (cmd == LB_ERR) {              if (cmd == LB_ERR) {
2176                  msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );                  msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
2177                  return FALSE;                  return FALSE;
2178              }              }
             idxsub = listview_get_curr_pos (lvsub);  
2179              if (k->is_v3 && is_cmd_openpgp (cmd)) {              if (k->is_v3 && is_cmd_openpgp (cmd)) {
2180                  msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),                  msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),
2181                                  _("Key Edit"), MB_ERR);                                  _("Key Edit"), MB_ERR);
# Line 1811  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2195  keyedit_main_dlg_proc (HWND dlg, UINT ms
2195              case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;              case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
2196              case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;              case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
2197              case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;              case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
2198              case CMD_ENABLE: km_enable_disable_key( lvsub, dlg, idxsub, 1 ); break;              case CMD_ENABLE: do_editkey_enable_disable (k, dlg, lvsub, 1); break;
2199              case CMD_DISABLE: km_enable_disable_key( lvsub, dlg, idxsub, 0 ); break;              case CMD_DISABLE: do_editkey_enable_disable (k, dlg, lvsub, 0); break;
2200                case CMD_CHECK: do_editkey_check (k, dlg); break;
2201                case CMD_TRUST: keyedit_change_ownertrust (k, dlg); break;
2202                case CMD_SIGN:
2203                case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2204                                                        lvuid, cmd);
2205                                break;
2206                case CMD_CLEAN: do_editkey_clean (k, dlg);
2207                case CMD_MINIMIZE: do_editkey_minimize (k, dlg);
2208              }              }
2209              break;              break;
2210                
2211          case IDCANCEL:          case IDCANCEL:
2212              EndDialog (dlg, FALSE);              EndDialog (dlg, FALSE);
2213              break;              break;
# Line 1823  keyedit_main_dlg_proc (HWND dlg, UINT ms Line 2215  keyedit_main_dlg_proc (HWND dlg, UINT ms
2215          case IDC_KEYEDIT_HELP:          case IDC_KEYEDIT_HELP:
2216              do_show_help (dlg);              do_show_help (dlg);
2217              break;              break;
2218    
2219            case IDC_KEYEDIT_REVOKE:
2220                gen_desig_revoke_cert (k, dlg);
2221                break;
2222          }          }
2223          break;          break;
2224      }      }
2225      return FALSE;      return FALSE;
2226  } /* keyedit_main_dlg_proc */  }

Legend:
Removed from v.88  
changed lines
  Added in v.211

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26