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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 220 - (hide annotations)
Tue May 30 15:31:49 2006 UTC (18 years, 9 months ago) by twoaday
File size: 60689 byte(s)


1 werner 36 /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2 twoaday 133 * Copyright (C) 2002-2006 Timo Schulz
3 werner 36 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 werner 42 #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23    
24 werner 36 #include <windows.h>
25     #include <commctrl.h>
26 werner 47 #include <time.h>
27 twoaday 200 #include <assert.h>
28    
29 werner 47 #include "resource.h"
30 werner 36 #include "wptTypes.h"
31     #include "wptW32API.h"
32     #include "wptVersion.h"
33     #include "wptGPG.h"
34     #include "wptCommonCtl.h"
35     #include "wptContext.h"
36     #include "wptDlgs.h"
37     #include "wptNLS.h"
38     #include "wptUTF8.h"
39     #include "wptErrors.h"
40     #include "wptKeylist.h"
41     #include "wptKeyManager.h"
42     #include "wptRegistry.h"
43     #include "wptKeyEdit.h"
44    
45     /* All edit key commands. */
46     enum keyedit_commands {
47     CMD_ADDKEY = 0,
48     CMD_ADDUID,
49     CMD_ADDPHOTO,
50     CMD_ADDREVOKER,
51     CMD_DELUID,
52     CMD_DELKEY,
53     CMD_EXPIRE,
54     CMD_SHOWPREF,
55 twoaday 170 //CMD_SETPREF,
56 werner 36 CMD_PASSWD,
57     CMD_PRIMARY,
58     CMD_TRUST,
59     CMD_REVUID,
60     CMD_REVKEY,
61     CMD_DISABLE,
62 twoaday 170 CMD_ENABLE,
63     CMD_SIGN,
64     CMD_LSIGN,
65 twoaday 195 CMD_CHECK,
66 twoaday 200 CMD_CLEAN,
67 twoaday 208 CMD_MINIMIZE
68 werner 36 };
69    
70 twoaday 170 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 twoaday 175 {"CHECK", 0, CMD_CHECK},
94 twoaday 195 {"CLEAN", 0, CMD_CLEAN},
95 twoaday 208 {"MINIMIZE", 0, CMD_MINIMIZE},
96 twoaday 170 {NULL, 0}
97     };
98 werner 36
99 twoaday 170
100 werner 36 /* Symbolic ids for the subkey columns. */
101     enum subk_col_t {
102     SUBK_COL_DESC = 0,
103     SUBK_COL_KEYID = 1,
104     SUBK_COL_CREATION = 2,
105     SUBK_COL_EXPIRES = 3,
106     SUBK_COL_STATUS = 4,
107     SUBK_COL_C_FLAG = 5,
108     SUBK_COL_S_FLAG = 6,
109     SUBK_COL_E_FLAG = 7,
110     SUBK_COL_A_FLAG = 8
111     };
112    
113     /* Symbolic ids for the userid columns. */
114     enum uid_col_t {
115     UID_COL_VALID = 0,
116     UID_COL_NAME = 1,
117     UID_COL_EMAIL = 2,
118     UID_COL_CREATION = 3
119     };
120    
121 twoaday 176 /* Key edit callback context. */
122     struct keyedit_cb_s {
123 twoaday 218 HWND parent; /* parent window handle. */
124     const char *keyid; /* key ID of the key. */
125     const char *pass; /* pointer to the passphrase. */
126 werner 36 listview_ctrl_t lv;
127 twoaday 208 int lv_pos;
128 werner 36 void *opaque;
129     unsigned int finished:1;
130 twoaday 176 unsigned int is_protected:1;
131 werner 36 };
132 twoaday 176 typedef struct keyedit_cb_s *keyedit_cb_t;
133 werner 36
134 twoaday 176
135     /* Key generation callback context. */
136     struct keygen_cb_s {
137 werner 36 int bits;
138     int algo;
139     u32 expire;
140     char *fpr;
141 twoaday 200 char *name;
142     char *comment;
143     char *email;
144 werner 36 };
145 twoaday 176 typedef struct keygen_cb_s *keygen_cb_t;
146 werner 36
147 twoaday 200 /* Subclass context for the subkey list. */
148     static subclass_s keyedit_subkey_proc;
149 werner 36
150 twoaday 200 /* Subclass context for the user-id list. */
151 werner 36 static subclass_s keyedit_uid_proc;
152    
153     int keygen_check_date (SYSTEMTIME *st);
154     void get_userid_preflist (char **r_prefs, int * r_flags);
155 twoaday 150 char* get_subkey_keyid (const char *keyid);
156 werner 36
157 twoaday 204 void ComboBox_AddString_utf8 (HWND cb, const char *txt);
158 werner 36
159 twoaday 200 static GpgKeyEdit*
160     create_GpgKeyEdit (const char *keyid)
161     {
162     GpgKeyEdit *ke;
163    
164     ke = new GpgKeyEdit (keyid);
165     if (!ke)
166     BUG (NULL);
167     return ke;
168     }
169    
170    
171 werner 36 /* Associate each key with a combo box entry.
172     Skip the key in @k. */
173     static void
174 twoaday 200 do_init_keylist (HWND dlg, const char *keyid)
175 werner 36 {
176     gpg_keycache_t pub;
177     gpgme_key_t key;
178 twoaday 128 const char *s, *kid;
179 werner 36 int i, n;
180    
181     pub = keycache_get_ctx (1);
182     if (!pub)
183     BUG (0);
184    
185     gpg_keycache_rewind (pub);
186 twoaday 128 while( !gpg_keycache_next_key (pub, 0, &key)) {
187     if (key->expired || key->revoked ||
188 twoaday 78 key->disabled || key->invalid)
189     continue;
190 werner 36 s = key->uids->uid;
191     kid = key->subkeys->keyid;
192 twoaday 200 if (!s || !strcmp (kid+8, keyid))
193 werner 36 continue;
194 twoaday 204 ComboBox_AddString_utf8 (GetDlgItem (dlg, IDC_ADDREV_KEYLIST), s);
195 werner 36 }
196     gpg_keycache_rewind (pub);
197 twoaday 211 n = SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0);
198 werner 36 for (i = 0; i < n; i++) {
199     gpg_keycache_next_key (pub, 0, &key);
200     SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
201     (WPARAM)(int)i, (LPARAM)key);
202     }
203     SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETCURSEL, 0, 0);
204     }
205    
206    
207     /* Add a new user-id to the list view @lv. */
208     static void
209     do_add_new_userid (listview_ctrl_t lv,
210 twoaday 201 const char *utf8_name, const char *email,
211     const char *utf8_comment)
212 werner 36 {
213 twoaday 218 char *p, *native;
214 werner 36 size_t n;
215    
216 twoaday 185 n = strlen (utf8_name) + strlen (email) + 16;
217 twoaday 201 if (utf8_comment)
218     n += strlen (utf8_comment);
219 werner 36 p = new char[n+1];
220     if (!p)
221 twoaday 185 BUG (NULL);
222 twoaday 218 if (utf8_comment)
223 twoaday 204 sprintf (p, "%s (%s)", utf8_name, utf8_comment);
224 werner 36 else
225 twoaday 204 sprintf (p, "%s", utf8_name);
226 twoaday 218 native = utf8_to_native (p);
227     free_if_alloc (p);
228 werner 36
229     listview_add_item (lv, "");
230 twoaday 218 listview_add_sub_item (lv, 0, UID_COL_VALID, _("Ultimate" ));
231     listview_add_sub_item (lv, 0, UID_COL_NAME, native);
232     listview_add_sub_item (lv, 0, UID_COL_EMAIL, email && *email? email : "");
233     listview_add_sub_item (lv, 0, UID_COL_CREATION, get_key_created (time (NULL)));
234     free_if_alloc (native);
235 twoaday 129 }
236 werner 36
237    
238     static void
239 twoaday 176 do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)
240 werner 36 {
241     char info[128], keyid[32];
242 twoaday 200 const char *expdate, *s;
243 werner 36 int n;
244    
245     expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
246 twoaday 218 _snprintf (info, sizeof (info)-1, "%d-bit %s",
247     keygen->bits,
248 werner 36 get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
249 twoaday 218 _snprintf (keyid, sizeof (keyid)-1, "0x%s", keygen->fpr+8);
250 twoaday 211 s = get_key_created (time (NULL));
251 werner 36 n = listview_count_items (lv, 0);
252     listview_add_item_pos (lv, n);
253 twoaday 211 listview_add_sub_item (lv, n, SUBK_COL_DESC, info);
254     listview_add_sub_item (lv, n, SUBK_COL_KEYID, keyid);
255     listview_add_sub_item (lv, n, SUBK_COL_CREATION, s);
256     listview_add_sub_item (lv, n, SUBK_COL_EXPIRES, expdate);
257 twoaday 150 if (flags & KM_FLAG_REVOKED)
258     s = _("Revoked");
259     else if (flags & KM_FLAG_EXPIRED)
260     s = _("Expired");
261     else
262     s = _("OK");
263 twoaday 211 listview_add_sub_item (lv, n, SUBK_COL_STATUS, s);
264 twoaday 150 }
265 werner 36
266    
267     /* Try to find the GPG edit key index which belongs to the user ID
268 twoaday 160 given by the email address @email, @name is used as a fallback.
269     If @r_inf != NULL, the info context will be returned.
270 werner 36 Return value: index of the user ID or -1 on error. */
271     static int
272 twoaday 160 do_find_userid (const char *keyid, const char *email,
273     const char *name, gpg_uid_info_t *r_inf)
274 werner 36 {
275     GpgKeyEdit *ke;
276     gpgme_error_t err;
277     gpg_uid_info_t inf, ui;
278     int pos = -1;
279    
280 twoaday 200 ke = create_GpgKeyEdit (keyid);
281 werner 36 err = ke->getUseridInfo (&inf);
282     delete ke;
283     if (err) {
284     log_box (_("user ID"), MB_ERR,
285     _("Could not get key information for: \"%s\":\n%s"),
286     name, gpgme_strerror (err));
287     return -1;
288     }
289    
290     for (ui = inf; ui; ui = ui->next) {
291 twoaday 205 if (name && email && ui->email && ui->name) {
292 twoaday 160 if (!strcmp (ui->email, email) &&
293 twoaday 205 !strncmp (ui->name, name, strlen (name))) {
294 twoaday 160 pos = ui->index;
295     break;
296     }
297     continue;
298     }
299 twoaday 208 if (email && ui->email) {
300 twoaday 160 if (!strcmp (ui->email, email)) {
301     pos = ui->index;
302     break;
303     }
304     /* The email address is more unique, use the name just
305     as the fallbck when no email address is available. */
306     continue;
307     }
308 twoaday 205 if (ui->name && name && !strcmp (ui->name, name)) {
309 werner 36 pos = ui->index;
310     break;
311     }
312     }
313     if (r_inf)
314     *r_inf = inf;
315     else
316     gpg_uid_info_release (inf);
317     return pos;
318     }
319    
320    
321 twoaday 128 /* Return true if @fname is a JPEG file. */
322     bool
323     is_jpg_file (const char *fname)
324     {
325     FILE *fp;
326     BYTE buf[10];
327     int n;
328    
329     fp = fopen (fname, "rb");
330     if (!fp)
331     return false;
332     n = fread (buf, 1, 10, fp);
333     fclose (fp);
334     if (n < 10)
335     return false;
336     return buf[6] == 'J' && buf[7] == 'F' &&
337     buf[8] == 'I' && buf[9] == 'F';
338     }
339    
340    
341 werner 36 /* Dialog box procedure to add a photo. */
342     BOOL CALLBACK
343     keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
344     {
345 twoaday 200 static keyedit_cb_t cb;
346 werner 36 GpgKeyEdit *ke;
347 twoaday 200 gpgme_error_t err;
348     const char *s;
349     char file[128];
350 werner 36 int id;
351    
352     switch( msg ) {
353     case WM_INITDIALOG:
354 twoaday 200 cb = (keyedit_cb_t)lparam;
355     if (!cb)
356 werner 36 BUG (NULL);
357     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."));
358     SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
359     SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
360 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
361 twoaday 128 SetWindowText (dlg, _("Add Photo ID"));
362 twoaday 105 SetForegroundWindow (dlg);
363 werner 36 break;
364    
365     case WM_DESTROY:
366     break;
367    
368     case WM_SYSCOMMAND:
369 twoaday 128 if (LOWORD (wparam) == SC_CLOSE)
370     EndDialog (dlg, TRUE);
371 werner 36 break;
372    
373     case WM_COMMAND:
374 twoaday 200 switch( LOWORD (wparam)) {
375 werner 36 case IDC_ADDPHOTO_SELFILE:
376 twoaday 128 s = get_fileopen_dlg (dlg, _("Select Image File"),
377 twoaday 180 "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",
378 twoaday 128 NULL);
379     if (s && !is_jpg_file (s)) {
380     log_box (_("Add Photo"), MB_ERR,
381     _("'%s' is not a valid JPEG file."), s);
382     return FALSE;
383     }
384     if (s && *s)
385     SetDlgItemText (dlg, IDC_ADDPHOTO_FILE, s);
386 werner 36 break;
387    
388     case IDOK:
389 twoaday 128 if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
390     msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);
391 werner 36 return FALSE;
392     }
393 twoaday 218 if (get_file_size (file) == 0 || get_file_size (file) > 6144) {
394 twoaday 128 id = msg_box (dlg, _("The JPEG is really large.\n"
395 werner 36 "Are you sure you want to use it?"),
396 twoaday 128 _("Add Photo"), MB_YESNO|MB_INFO);
397     if (id == IDNO)
398 werner 36 return TRUE;
399     }
400 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
401     if (cb->pass)
402     ke->setPassphrase (cb->pass);
403 twoaday 176 else
404     ke->setNoPassphrase (true);
405 twoaday 200 err = ke->addPhotoid (file);
406 werner 36 delete ke;
407 twoaday 200 if (err) {
408     msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
409 werner 36 return FALSE;
410     }
411     else {
412 twoaday 200 cb->finished = 1;
413 twoaday 128 msg_box (dlg, _("Photo successfully added."),
414     _("GnuPG Status"), MB_OK);
415 werner 36 }
416     EndDialog (dlg, TRUE);
417     break;
418    
419     case IDCANCEL:
420     EndDialog (dlg, FALSE);
421     break;
422     }
423     break;
424     }
425     return FALSE;
426     }
427    
428    
429     /* Dialog box procedure to add a designated revoker. */
430     BOOL CALLBACK
431     keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
432     {
433 twoaday 200 static keyedit_cb_t cb;
434 twoaday 129 gpgme_error_t err;
435 werner 36 GpgKeyEdit *ke;
436 twoaday 204 char *uid=NULL;
437 werner 36
438 twoaday 129 switch (msg) {
439 werner 36 case WM_INITDIALOG:
440 twoaday 200 cb = (keyedit_cb_t)lparam;
441     if (!cb)
442 twoaday 129 BUG (NULL);
443 twoaday 200 do_init_keylist (dlg, cb->keyid);
444 twoaday 129 SetDlgItemText (dlg, IDC_ADDREV_INF,
445     _("Appointing a key as designated revoker cannot be undone."));
446 werner 36 SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
447     SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
448 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
449 twoaday 128 SetWindowText (dlg, _("Add Revoker"));
450 twoaday 105 SetForegroundWindow (dlg);
451 twoaday 218 center_window (dlg, cb->parent);
452 werner 36 break;
453    
454     case WM_SYSCOMMAND:
455 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
456     EndDialog (dlg, FALSE);
457 werner 36 break;
458    
459     case WM_COMMAND:
460 twoaday 200 switch (LOWORD (wparam)) {
461 twoaday 204 case IDOK:
462     if (!GetDlgItemText_utf8 (dlg, IDC_ADDREV_KEYLIST, &uid)) {
463     msg_box (dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR);
464 werner 36 return FALSE;
465     }
466 twoaday 204
467 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
468     if (cb->pass)
469     ke->setPassphrase (cb->pass);
470 twoaday 176 else
471     ke->setNoPassphrase (true);
472 twoaday 204 err = ke->addDesignatedRevoker (uid);
473 werner 36 delete ke;
474 twoaday 204 safe_free (uid);
475 werner 36 if (err) {
476     msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
477     return TRUE;
478     }
479     else {
480 twoaday 200 cb->finished = 1;
481 twoaday 129 msg_box (dlg, _("Revoker successfully addded."),
482     _("GnuPG Status"), MB_OK);
483 werner 36 }
484 twoaday 129 EndDialog (dlg, TRUE);
485 werner 36 break;
486    
487     case IDCANCEL:
488 twoaday 129 EndDialog (dlg, FALSE);
489 werner 36 break;
490     }
491     break;
492     }
493     return FALSE;
494     }
495    
496    
497     /* Dialog box procedure to add a new user-ID. */
498     BOOL CALLBACK
499     keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
500     {
501 twoaday 176 static keyedit_cb_t ctx;
502 twoaday 200 keygen_cb_t keygen;
503 werner 36 gpgme_error_t err;
504     GpgKeyEdit *ke;
505     char *utf8_name = NULL;
506 twoaday 201 char *utf8_comment = NULL;
507 twoaday 204 char email[128];
508 werner 36 int rc;
509    
510 twoaday 176 switch (msg) {
511 werner 36 case WM_INITDIALOG:
512 twoaday 176 ctx = (keyedit_cb_t)lparam;
513 twoaday 200 if (!ctx)
514 werner 36 dlg_fatal_error(dlg, "Could not get dialog param!");
515     SetWindowText (dlg, _("Add new User ID"));
516     SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
517     SetDlgItemText (dlg, IDC_ADDUID_INFEMAIL, _("&Email"));
518     SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
519 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
520 werner 36 SetForegroundWindow (dlg);
521 twoaday 218 center_window (dlg, ctx->parent);
522 werner 36 return FALSE;
523    
524     case WM_SYSCOMMAND:
525 twoaday 176 if (LOWORD (wparam) == SC_CLOSE)
526 werner 36 EndDialog(dlg, TRUE);
527     return FALSE;
528    
529     case WM_COMMAND:
530     switch ( LOWORD( wparam ) ) {
531     case IDOK:
532 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
533 twoaday 204 rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_NAME, &utf8_name);
534 werner 36 if (!rc || rc < 5) {
535 twoaday 204 msg_box (dlg, _("Please enter a name (min. 5 chars.)"),
536     _("UserID"), MB_ERR);
537     free_if_alloc (utf8_name);
538 werner 36 return FALSE;
539     }
540 twoaday 204 if (strchr (utf8_name, '@')) {
541     msg_box (dlg, _("Please enter the email address in the email field and not in the name field"),
542     _("UserID"), MB_INFO);
543 werner 36 return FALSE;
544     }
545 twoaday 204
546     if( !GetDlgItemText (dlg, IDC_ADDUID_EMAIL, email, sizeof (email) -1)) {
547 werner 36 msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
548     return FALSE;
549     }
550 twoaday 190 if (check_email_address (email)) {
551 twoaday 175 msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
552 werner 36 return FALSE;
553     }
554    
555 twoaday 204 rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_COMMENT, &utf8_comment);
556 werner 36
557 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
558 twoaday 176 if (ctx->is_protected)
559 werner 36 ke->setPassphrase (ctx->pass);
560 twoaday 176 else
561     ke->setNoPassphrase (true);
562 twoaday 201 err = ke->addUserid (utf8_name, utf8_comment, email);
563 werner 36 if (err)
564     msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
565     else {
566     msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
567     ctx->finished = 1;
568 twoaday 201 keygen->name = utf8_name;
569     keygen->comment = utf8_comment;
570 twoaday 200 keygen->email = m_strdup (email);
571 werner 36 }
572 twoaday 200 delete ke;
573 werner 36 EndDialog (dlg, TRUE);
574     return TRUE;
575    
576     case IDCANCEL:
577     EndDialog (dlg, FALSE);
578     return FALSE;
579     }
580     break;
581     }
582    
583     return FALSE;
584     }
585    
586    
587     static void
588     init_keysize_box (HWND dlg, int ctlid)
589     {
590     const char *sizelist[] = {
591 twoaday 200 "1024", "1536",
592 twoaday 211 "2048", "3072",
593 twoaday 200 "4096", NULL
594 werner 36 };
595     int i;
596 twoaday 200
597 werner 36 for (i=0; sizelist[i] != NULL; i++)
598 twoaday 200 SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
599     (LPARAM)(char*)sizelist[i]);
600 werner 36 SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
601     }
602    
603 twoaday 200
604 werner 36 static int
605     get_keysize_from_box (HWND dlg, int ctlid)
606     {
607     int pos;
608     char buf[32];
609    
610     pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
611     if (pos == CB_ERR)
612     return -1;
613     SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
614 twoaday 211 return atoi (buf);
615 werner 36 }
616    
617    
618 twoaday 175 /* Create a time_t from a system time @st. */
619     time_t
620     w32_mktime (SYSTEMTIME *st)
621     {
622     struct tm tm;
623    
624     memset (&tm, 0, sizeof (tm));
625     tm.tm_year = st->wYear-1900;
626     tm.tm_mday = st->wDay+1;
627     tm.tm_mon = st->wMonth-1;
628     return mktime (&tm);
629     }
630    
631    
632 twoaday 129 /* Dialog procedure for adding a new secondary key. */
633 werner 36 BOOL CALLBACK
634     keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
635     {
636 twoaday 176 static keyedit_cb_t ctx;
637 twoaday 200 keygen_cb_t keygen;
638 werner 36 GpgKeyEdit *ke;
639     gpgme_error_t err;
640 twoaday 175 SYSTEMTIME st;
641 twoaday 200 HWND hwnd;
642 werner 36 int index, size, valid;
643    
644     switch (msg) {
645     case WM_INITDIALOG:
646 twoaday 176 ctx = (keyedit_cb_t)lparam;
647 werner 36 if (!ctx)
648     dlg_fatal_error (dlg, "Could not get dialog param!");
649 twoaday 99
650 werner 36 SetWindowText (dlg, _("Add new Subkey"));
651     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
652     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));
653     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFVALID, _("Key expiration"));
654 twoaday 99 SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
655 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
656 twoaday 99
657 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
658     listbox_add_string (hwnd, "DSA (sign only)");
659     listbox_add_string (hwnd, "ElGamal (encrypt only)");
660     listbox_add_string (hwnd, "RSA (sign only)");
661     listbox_add_string (hwnd, "RSA (encrypt only)");
662 werner 36 CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
663     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
664     init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
665 twoaday 105 SetForegroundWindow (dlg);
666 twoaday 218 center_window (dlg, ctx->parent);
667 werner 36 return FALSE;
668    
669     case WM_SYSCOMMAND:
670 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
671 twoaday 150 EndDialog (dlg, TRUE);
672 werner 36 return FALSE;
673    
674     case WM_COMMAND:
675 twoaday 150 if (HIWORD (wparam) == BN_CLICKED &&
676     LOWORD (wparam) == IDC_ADDSUBKEY_EXPIRE) {
677 werner 36 if (IsDlgButtonChecked (dlg, IDC_ADDSUBKEY_EXPIRE))
678     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
679     else
680     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), TRUE);
681     }
682 twoaday 150 if (HIWORD (wparam) == LBN_SELCHANGE &&
683     LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {
684 werner 36 index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);
685     if (index == 0)
686     SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);
687     }
688    
689 twoaday 150 switch (LOWORD (wparam)) {
690 werner 36 case IDOK:
691 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
692     assert (keygen);
693     hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
694     switch (listbox_get_cursel (hwnd)) {
695 werner 36 case 0: index = 2; break;
696     case 1: index = 4; break;
697     case 2: index = 5; break;
698     case 3: index = 6; break;
699 twoaday 150 default:
700 twoaday 200 msg_box (dlg, _("Please select one entry."),
701     _("Add Subkey"), MB_ERR);
702 werner 36 return FALSE;
703     }
704     size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
705     if (index == 2 && size != 1024) {
706 twoaday 200 msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
707 twoaday 150 _("Add Subkey"), MB_INFO);
708 werner 36 size = 1024;
709     }
710 twoaday 175
711 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
712     DateTime_GetSystemtime (hwnd, &st);
713 twoaday 175 valid = w32_mktime (&st) - time (NULL);
714     valid /= 86400;
715    
716 werner 36 keygen->bits = size;
717     switch (index) {
718     case 2: keygen->algo = GPGME_PK_DSA; break;
719     case 4: keygen->algo = GPGME_PK_ELG_E; break;
720     case 5: keygen->algo = GPGME_PK_RSA_S; break;
721     case 6: keygen->algo = GPGME_PK_RSA_E; break;
722     }
723     if (valid > 0)
724     keygen->expire = time (NULL) + valid*24*60*60;
725    
726 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
727 werner 36 ke->setCallback (keygen_cb, NULL);
728 twoaday 176 if (ctx->is_protected)
729 twoaday 150 ke->setPassphrase (ctx->pass);
730 twoaday 176 else
731     ke->setNoPassphrase (true);
732 werner 36 keygen_cb_dlg_create ();
733    
734     err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
735 twoaday 150 keygen->fpr = get_subkey_keyid (ctx->keyid);
736 twoaday 211 keygen_cb_dlg_destroy (1);
737 werner 36 if (err)
738     msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
739     else {
740 twoaday 200 msg_box (dlg, _("Subkey successfully added."),
741     _("GnuPG Status"), MB_OK);
742 werner 36 ctx->finished = 1;
743     }
744     delete ke;
745 twoaday 129 EndDialog (dlg, TRUE);
746 werner 36 return TRUE;
747    
748     case IDCANCEL:
749 twoaday 129 EndDialog (dlg, FALSE);
750 werner 36 return FALSE;
751     }
752     break;
753     }
754    
755     return FALSE;
756 twoaday 129 }
757 werner 36
758    
759     BOOL
760     keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
761     {
762 twoaday 176 keyedit_cb_s cb;
763 twoaday 200 keygen_cb_s keygen;
764 werner 36 char *pass = NULL;
765     int cancel = 0;
766    
767     if (!k->key_pair) {
768 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
769     _("Add user ID"), MB_ERR);
770 werner 36 return FALSE;
771     }
772    
773     if (k->is_protected) {
774 twoaday 200 pass = request_passphrase (_("Key Edit"), 1, &cancel);
775 werner 36 if (cancel)
776     return FALSE;
777     }
778 twoaday 200
779     memset (&keygen, 0, sizeof (keygen));
780 werner 36 memset (&cb, 0, sizeof cb);
781 twoaday 218 cb.parent = dlg;
782 twoaday 200 cb.opaque = &keygen;
783 twoaday 176 cb.is_protected = k->is_protected;
784     cb.pass = pass;
785 werner 36 cb.keyid = k->keyid;
786     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
787     dlg, keyedit_adduid_dlg_proc,
788     (LPARAM)&cb, _("Add user ID"),
789     IDS_WINPT_KEYEDIT_ADDUID);
790 twoaday 200 if (lv != NULL && cb.finished)
791     do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
792 werner 36 if (cb.finished)
793     k->update = 1;
794    
795 twoaday 200 free_if_alloc (keygen.name);
796     free_if_alloc (keygen.email);
797     free_if_alloc (keygen.comment);
798 werner 36 sfree_if_alloc (pass);
799     return TRUE;
800     }
801    
802    
803 twoaday 200 /* Return the keyID of the last subkey. */
804 werner 36 char*
805 twoaday 150 get_subkey_keyid (const char *keyid)
806 werner 36 {
807     gpgme_error_t err;
808 twoaday 150 gpgme_key_t key;
809 werner 36 gpgme_ctx_t ctx;
810 twoaday 150 gpgme_subkey_t subk;
811 twoaday 200 char *kid = NULL;
812 werner 36
813     err = gpgme_new (&ctx);
814     if (err)
815     return NULL;
816     err = gpgme_get_key (ctx, keyid, &key, 0);
817 twoaday 150 gpgme_release (ctx);
818 werner 36 if (err)
819     return NULL;
820 twoaday 150 subk = get_nth_key (key, count_subkeys (key));
821 twoaday 200 if (subk != NULL)
822     kid = strdup (subk->keyid);
823 werner 36 gpgme_key_release (key);
824 twoaday 150 return kid;
825 werner 36 }
826    
827    
828     BOOL
829     keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
830     {
831 twoaday 176 keyedit_cb_s cb;
832     keygen_cb_s keygen;
833 werner 36 char *pass = NULL;
834     int cancel = 0;
835    
836     if (!k->key_pair) {
837 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
838     _("Add Subkey"), MB_ERR);
839 werner 36 return FALSE;
840     }
841     if (k->is_protected) {
842     pass = request_passphrase (_("Key Edit"), 1, &cancel);
843     if (cancel)
844     return FALSE;
845     }
846    
847     memset (&keygen, 0, sizeof (keygen));
848     memset (&cb, 0, sizeof (cb));
849     cb.keyid = k->keyid;
850 twoaday 176 cb.is_protected = k->is_protected;
851     cb.pass = pass;
852 werner 36 cb.opaque = &keygen;
853     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,
854     dlg, keyedit_addsubkey_dlg_proc,
855     (LPARAM)&cb, _("Add new Subkey"),
856     IDS_WINPT_KEYEDIT_ADDSUBKEY);
857 twoaday 200 if (lv != NULL && cb.finished)
858     do_add_new_subkey (lv, &keygen, 0);
859 werner 36 if (cb.finished)
860     k->update = 1;
861    
862 twoaday 200 safe_free (keygen.fpr);
863     sfree_if_alloc (pass);
864 werner 36 return cb.finished? TRUE: FALSE;
865     }
866    
867    
868     BOOL
869     keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)
870     {
871     GpgKeyEdit *ke;
872     gpgme_error_t err;
873     struct URL_ctx_s *url;
874 twoaday 200 char *pass = NULL;
875 werner 36
876     url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
877     if (url->cancel == 1) {
878     delete url;
879     return FALSE;
880     }
881    
882     pass = request_passphrase (_("Key Edit"), 1, &url->cancel);
883     if (url->cancel) {
884     delete url;
885     return FALSE;
886     }
887    
888 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
889 twoaday 175 if (k->is_protected)
890     ke->setPassphrase (pass);
891 twoaday 176 else
892     ke->setNoPassphrase (true);
893 twoaday 181 err = ke->setPreferredKeyserver (-1, url->url);
894 werner 36 if (!err)
895     msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
896 twoaday 188 else
897     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
898 werner 36
899     sfree_if_alloc (pass);
900     delete ke;
901 twoaday 181 delete url;
902 werner 36 return err == 0? 0 : WPTERR_GENERAL;
903     }
904    
905    
906     /* Add a photo-ID to the key specified in @k. @dlg is the handle of
907     the calling dialog. */
908     BOOL
909     keyedit_add_photo (winpt_key_t k, HWND dlg)
910     {
911 twoaday 200 keyedit_cb_s cb;
912     char *pass = NULL;
913     int cancel;
914    
915 werner 36 if (!k->key_pair) {
916 twoaday 180 msg_box (dlg, _("There is no secret key available!"),
917     _("Add Photo"), MB_ERR);
918 werner 36 return FALSE;
919     }
920 twoaday 200
921     memset (&cb, 0, sizeof (cb));
922     if (k->is_protected) {
923     pass = request_passphrase (_("Key Edit"), 1, &cancel);
924     if (cancel)
925     return FALSE;
926     }
927 twoaday 218 cb.parent = dlg;
928 twoaday 200 cb.pass = pass;
929     cb.keyid = k->keyid;
930    
931 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
932 twoaday 200 keyedit_addphoto_dlg_proc, (LPARAM)&cb);
933    
934     if (cb.finished)
935     k->update = 1;
936     sfree_if_alloc (pass);
937 werner 36 return TRUE;
938     }
939    
940    
941     BOOL
942     keyedit_add_revoker (winpt_key_t k, HWND dlg)
943     {
944 twoaday 200 keyedit_cb_s cb;
945     char *pass = NULL;
946     int cancel;
947    
948 twoaday 129 if (!k->key_pair) {
949     msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
950 werner 36 return FALSE;
951     }
952 twoaday 200
953     if (k->is_protected) {
954     pass = request_passphrase (_("Key Edit"), 1, &cancel);
955     if (cancel)
956     return FALSE;
957     }
958    
959     memset (&cb, 0, sizeof (cb));
960 twoaday 218 cb.parent = dlg;
961 twoaday 200 cb.is_protected = k->is_protected;
962     cb.keyid = k->keyid;
963     cb.pass = pass;
964 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
965 twoaday 200 keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
966    
967     if (cb.finished)
968     k->update = 1;
969     sfree_if_alloc (pass);
970 werner 36 return TRUE;
971 twoaday 129 }
972 werner 36
973    
974 twoaday 165 /* Change ownertrust of the given key @key.
975     Return TRUE if the ownertrust was changed. */
976     BOOL
977     keyedit_change_ownertrust (winpt_key_t key, HWND dlg)
978     {
979     int rc;
980    
981     rc = dialog_box_param (glob_hinst,
982     (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
983     dlg, keyedit_ownertrust_dlg_proc,
984     (LPARAM)key, _("Change Ownertrust"),
985     IDS_WINPT_KEYEDIT_OWNERTRUST);
986 twoaday 170 if (rc == TRUE) {
987     msg_box (dlg, _("Key status changed."), _("Key Edit"), MB_OK);
988 twoaday 165 key->update = 1;
989 twoaday 170 }
990 twoaday 165 return rc;
991     }
992    
993    
994 twoaday 180 /* Check if the given key is supposed to have IDEA
995     for secret key protection. */
996 werner 36 static int
997 twoaday 180 is_idea_protect_algo (const char *keyid)
998 werner 36 {
999     winpt_key_s k;
1000     const unsigned char *sym_prefs;
1001     size_t n;
1002    
1003     memset (&k, 0, sizeof (k));
1004     if (winpt_get_pubkey (keyid, &k))
1005 twoaday 180 BUG (0);
1006 werner 36 sym_prefs = k.ext->sym_prefs;
1007 twoaday 180 if (!k.is_v3)
1008     return 0;
1009 werner 36 if (!sym_prefs)
1010     return 1; /* assume that only v3 keys have no symmetric cipher preferences
1011     and thus IDEA is explicit. */
1012     for (n = 0; sym_prefs[n]; n++)
1013     ;
1014     if ((n == 0 || n == 1) && *sym_prefs == 0x01)
1015     return 1;
1016     return 0;
1017 twoaday 180 }
1018 werner 36
1019    
1020     BOOL
1021 twoaday 129 keyedit_change_passwd (winpt_key_t k, HWND dlg)
1022 werner 36 {
1023 twoaday 200 gpgme_error_t err;
1024 werner 36 GpgKeyEdit *ke;
1025 twoaday 129 char *old_pass = NULL;
1026     char *new_pass = NULL;
1027 werner 36 int cancel = 0;
1028    
1029 twoaday 175 if (!k->key_pair) {
1030     msg_box (dlg, _("There is no secret key available!"),
1031     _("Key Edit"), MB_ERR);
1032 werner 36 return FALSE;
1033     }
1034    
1035 twoaday 180 if (!idea_available && is_idea_protect_algo (k->keyid)) {
1036     msg_box (dlg, _("Cannot change passphrase because the key\n"
1037     "is protected with the IDEA encryption algorithm."),
1038     _("Key Edit"), MB_ERR);
1039 werner 36 return FALSE;
1040     }
1041    
1042 twoaday 129 if (k->is_protected) {
1043     old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);
1044 twoaday 128 if (cancel)
1045 werner 36 return FALSE;
1046     }
1047 twoaday 129 new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);
1048     if (cancel) {
1049 twoaday 220 sfree_if_alloc (old_pass);
1050 werner 36 return FALSE;
1051     }
1052    
1053 twoaday 220 if (strlen (new_pass) == 0) {
1054     cancel = msg_box (dlg, _("Are you sure that you really don't want a passphrase?\n"
1055     "This is propably a bad idea, still proceed?"),
1056     _("Key Edit"), MB_WARN_ASK);
1057     if (cancel != IDYES) {
1058     sfree_if_alloc (old_pass);
1059     sfree_if_alloc (new_pass);
1060     return FALSE;
1061     }
1062     }
1063    
1064 twoaday 129 if (is_8bit_string (new_pass)) {
1065     msg_box (dlg, _("The passphrase contains 8-bit characters.\n"
1066 werner 36 "It is not suggested to use charset specific characters."),
1067 twoaday 129 _("Key Edit"), MB_ERR);
1068 twoaday 220 sfree_if_alloc (old_pass);
1069     sfree_if_alloc (new_pass);
1070 werner 36 return FALSE;
1071     }
1072    
1073 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1074 werner 36 ke->setPassphrase (k->is_protected? old_pass : NULL);
1075 twoaday 220 if (!k->is_protected)
1076     ke->setNoPassphrase (true);
1077     err = ke->changePassphrase (new_pass, 1);
1078 twoaday 200 if (err)
1079     msg_box (dlg, gpgme_strerror (err), _("Change Passwd"), MB_ERR);
1080 werner 36 else
1081     msg_box (dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK);
1082     sfree_if_alloc (old_pass);
1083     sfree_if_alloc (new_pass);
1084     delete ke;
1085     return TRUE;
1086     }
1087    
1088    
1089 twoaday 165 /* Initialize sub key list from key @k and return
1090     the new listview control. */
1091 werner 36 listview_ctrl_t
1092 twoaday 165 subkey_list_init (HWND dlg, winpt_key_t k)
1093 werner 36 {
1094     LV_ITEM lvi;
1095     gpgme_subkey_t sub;
1096     struct listview_column_s cols[] = {
1097     {0, 80, (char *)_("Description")},
1098     {1, 78, (char *)_("Key ID")},
1099     {2, 66, (char *)_("Creation")},
1100     {3, 66, (char *)_("Expires")},
1101     {4, 64, (char *)_("Status")},
1102     {5, 16, "C"/*ertify*/},
1103     {6, 16, "S"/*ign*/},
1104     {7, 16, "E"/*ncrypt*/},
1105     {8, 16, "A"/*uth*/},
1106     {0, 0, 0}
1107     };
1108     listview_ctrl_t lv;
1109     char buf[256], tmp[128];
1110     const char *t;
1111 twoaday 211 int nkeys = 0, i, bits;
1112 werner 36
1113 twoaday 211 nkeys = count_subkeys (k->ctx);
1114 werner 36 if( !nkeys ) {
1115 twoaday 165 msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);
1116 werner 36 return NULL;
1117     }
1118    
1119 twoaday 208 listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST));
1120     for (i = 0; cols[i].fieldname != NULL; i++)
1121     listview_add_column (lv, &cols[i]);
1122 werner 36
1123 twoaday 215 for (i = 0; i < nkeys; i++) {
1124     listview_add_item (lv, "");
1125     listview_add_sub_item (lv, 0, 1, "");
1126     memset (&lvi, 0, sizeof (lvi));
1127 werner 36 lvi.mask = LVIF_PARAM;
1128 twoaday 215 lvi.lParam = (LPARAM)k->ext;
1129     if( ListView_SetItem (lv->ctrl, &lvi) == FALSE)
1130     return NULL;
1131 werner 36 }
1132    
1133     listview_set_ext_style( lv );
1134 twoaday 211 for( i = 0, sub = k->ctx->subkeys; i < nkeys; i++, sub = sub->next ) {
1135 werner 36 memset( buf, 0, sizeof buf );
1136    
1137     bits = sub->length;
1138     _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
1139     strcat( buf, tmp );
1140    
1141     _snprintf( tmp, sizeof tmp-1, "%s", get_key_pubalgo (sub->pubkey_algo));
1142     strcat( buf, tmp );
1143    
1144     listview_add_sub_item( lv, i, 0, buf );
1145     t = sub->keyid;
1146     if( !t )
1147     t = "DEADBEEFDEADBEEF";
1148     _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
1149     listview_add_sub_item( lv, i, 1, tmp );
1150    
1151     t = get_key_created (sub->timestamp);
1152     if( !t )
1153 werner 116 t = "????" "-??" "-??";
1154 werner 36 listview_add_sub_item( lv, i, 2, t );
1155    
1156     if( sub->expires ) {
1157     t = get_key_created (sub->expires);
1158     listview_add_sub_item( lv, i, 3, t );
1159     }
1160     else
1161     listview_add_sub_item( lv, i, 3, _("Never") );
1162    
1163     if( sub->expired )
1164     t = _("Expired");
1165     else if( sub->revoked )
1166     t = _("Revoked");
1167     else
1168     t = _("OK");
1169     listview_add_sub_item( lv, i, 4, t );
1170    
1171     if (sub->can_certify) t = "*"; else t = "";
1172     listview_add_sub_item (lv, i, 5, t);
1173     if (sub->can_sign) t = "*"; else t = "";
1174     listview_add_sub_item( lv, i, 6, t );
1175     if (sub->can_encrypt) t = "*"; else t = "";
1176     listview_add_sub_item( lv, i, 7, t );
1177     if (sub->can_authenticate) t = "*"; else t = "";
1178     listview_add_sub_item (lv, i, 8, t);
1179     }
1180     return lv;
1181 twoaday 200 }
1182 werner 36
1183    
1184     static listview_ctrl_t
1185     userid_list_init (HWND dlg, winpt_key_t k)
1186     {
1187     listview_ctrl_t lv = NULL;
1188     gpgme_key_sig_t ks;
1189 twoaday 207 struct native_uid_s *u;
1190 twoaday 208 int nuids = 0, j, u_attr;
1191 werner 36 struct listview_column_s cols[] = {
1192     {0, 72, (char *)_("Validity")},
1193     {1, 150, (char *)_("Name")},
1194     {2, 110, (char *)_("Email")},
1195     {3, 76, (char *)_("Creation")},
1196     {0, 0, 0}
1197     };
1198     const char *attr;
1199    
1200 twoaday 211 nuids = count_userids (k->ctx);
1201 werner 36 if (!nuids) {
1202     msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);
1203     return NULL;
1204     }
1205    
1206 twoaday 208 listview_new (&lv, GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST));
1207 werner 36 for( j = 0; cols[j].fieldname != NULL; j++ )
1208 twoaday 208 listview_add_column (lv, &cols[j]);
1209 werner 36
1210 twoaday 211 for (j = 0; j < nuids; j++) {
1211 twoaday 208 listview_add_item (lv, " ");
1212     listview_add_sub_item (lv, 0, 1, " " );
1213 werner 36 }
1214    
1215     listview_set_ext_style (lv);
1216 twoaday 208 for (j = 0, u=k->ext->uids; j < nuids; u=u->next, j++) {
1217 werner 36 if (u->revoked)
1218     attr = _("Revoked");
1219     else {
1220     u_attr = (int)u->validity;
1221     attr = get_key_trust2 (NULL, u_attr, 0, 0);
1222     }
1223 twoaday 208 listview_add_sub_item (lv, j, UID_COL_VALID, (char *)attr);
1224 werner 36 /* XXX: add comment if available */
1225 twoaday 208 listview_add_sub_item (lv, j, UID_COL_NAME,
1226 twoaday 204 u->name? u->name : _("Invalid user ID"));
1227     if (u->email)
1228 twoaday 208 listview_add_sub_item (lv, j, UID_COL_EMAIL, u->email);
1229 werner 36
1230 twoaday 208 ks = get_selfsig (u->signatures, k->keyid, 1);
1231 werner 36 if (ks)
1232 twoaday 208 listview_add_sub_item (lv, j, UID_COL_CREATION,
1233     get_key_created (ks->timestamp));
1234 werner 36 }
1235     if( !k->key_pair ) {
1236 twoaday 211 CheckDlgButton (dlg, IDC_KEYUID_ADD, BST_INDETERMINATE);
1237     CheckDlgButton (dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE);
1238 werner 36 }
1239     return lv;
1240 twoaday 200 }
1241 werner 36
1242    
1243     static void
1244 twoaday 170 do_init_cmdlist (HWND dlg, int is_keypair)
1245     {
1246     const char *s;
1247 werner 36 int i = 0;
1248    
1249 twoaday 170 for (i = 0; (s=cmdlist[i].name); i++) {
1250     if (is_keypair)
1251     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1252     (LPARAM)(char *)s);
1253     else if (!cmdlist[i].need_pair)
1254     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1255     (LPARAM)(char *)s);
1256 werner 36 }
1257 twoaday 170 SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0);
1258     }
1259 werner 36
1260    
1261 twoaday 165 /* Return 1 if the requested command is RFC2440. */
1262 werner 36 static int
1263 twoaday 165 is_cmd_openpgp (int cmdid)
1264 werner 36 {
1265 twoaday 165 switch (cmdid) {
1266 werner 36 case CMD_ADDKEY:
1267     case CMD_ADDPHOTO:
1268     case CMD_ADDREVOKER:
1269 twoaday 170 //case CMD_SETPREF:
1270 werner 36 return 1;
1271     }
1272     return 0;
1273 twoaday 165 }
1274 werner 36
1275    
1276 twoaday 165 /* Display a message box with a short description of the commands. */
1277 werner 36 static void
1278 twoaday 165 do_show_help (HWND dlg)
1279 werner 36 {
1280     char helptext[2048];
1281    
1282 twoaday 165 _snprintf (helptext, sizeof (helptext)-1,
1283 twoaday 170 _(
1284 werner 36 "ADDUID \t\tadd a user ID\r\n"
1285     "ADDPHOTO \t\tadd a photo ID\r\n"
1286     "DELUID \t\tdelete a user ID\r\n"
1287     "ADDKEY \t\tadd a secondard key\r\n"
1288     "DELKEY \t\tdelete a secondary key\r\n"
1289     "ADDREVOKER\t\tadd a revocation key\r\n"
1290     "EXPIRE \t\tchange the expire date\r\n"
1291     "SHOWPREF \t\tlist preferences (verbose)\r\n"
1292 twoaday 170 "SETPREF \t\tset preference list\r\n"
1293 werner 36 "UPDPREF \t\tupdated preferences\r\n"
1294     "PASSWD \t\tchange the passphrase\r\n"
1295     "PRIMARY \t\tflag user ID as primary\r\n"
1296     "TRUST \t\tchange the ownertrust\r\n"
1297     "REVUID \t\trevoke a user ID\r\n"
1298     "REVKEY \t\trevoke a secondary key\r\n"
1299     "DISABLE \t\tdisable a key\r\n"
1300     "ENABLE \t\tenable a key\r\n"
1301 twoaday 170 "SIGN \t\tsign a user-id (exportable)\r\n"
1302 twoaday 195 "LSIGN \t\tsign a user-id (non-exportable)\r\n"
1303     "CLEAN \t\tremove unusable signatures from key\r\n"
1304 twoaday 208 "MINIMIZE \t\tremove all signatures from key\r\n"
1305 twoaday 195 ));
1306 twoaday 165 msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);
1307     }
1308 werner 36
1309    
1310     static int
1311     do_editkey_delkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1312     {
1313     gpgme_error_t err;
1314     GpgKeyEdit *ke;
1315     int j, id;
1316     char tmp[64];
1317    
1318     if (!k->key_pair)
1319     return FALSE; /* XXX: shall we allow to modify non-secret keys?? */
1320    
1321     if( listview_count_items( lv, 0 ) == 1 ) {
1322     msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1323     return FALSE;
1324     }
1325     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1326     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1327     return FALSE;
1328     }
1329     if( j == 0 ) {
1330     msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );
1331     return FALSE;
1332     }
1333    
1334 twoaday 200 /* XXX: change the warning to make clear that verification won't work
1335     any longer if this is a sign-only key. */
1336     listview_get_item_text (lv, j, 0, tmp, sizeof (tmp) -1);
1337     id = log_box (_("Key Edit"), MB_YESNO|MB_ICONWARNING,
1338 werner 36 _("\"Subkey %s.\"\n\n"
1339     "Anything encrypted to the selected subkey will no longer\n"
1340     "be able to be decrypted.\n\n"
1341 twoaday 200 "Do you really want to delete this subkey?"), tmp);
1342     if (id == IDNO)
1343 werner 36 return FALSE;
1344    
1345     ke = new GpgKeyEdit (k->keyid);
1346     if (!ke)
1347     BUG (NULL);
1348     err = ke->delKey (j);
1349     if (err)
1350     msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);
1351     else {
1352     listview_del_item (lv, j);
1353     k->update = 1;
1354     status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));
1355     }
1356     delete ke;
1357     return err? FALSE : TRUE;
1358 twoaday 200 }
1359 werner 36
1360    
1361     /* Set the expiration date for the selected key in list view @lv.
1362     Return value: TRUE on success. */
1363     static int
1364     do_editkey_expire (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1365     {
1366     gpgme_error_t err;
1367     GpgKeyEdit *ke;
1368     date_s udd = {0};
1369     char buf[256], * pass = NULL;
1370     int j, cancel = 0;
1371    
1372     if (!k->key_pair) {
1373 twoaday 41 msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1374 werner 36 return FALSE;
1375     }
1376 twoaday 41 if ((j = listview_get_curr_pos (lv)) == -1) {
1377 werner 36 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1378     return FALSE;
1379     }
1380 twoaday 41
1381     /* If a key already expired, it is possible the user wants to
1382     set a new expiration date.. */
1383     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof buf -1);
1384     if (!strcmp (buf, _("Expired"))) {
1385     cancel = msg_box (dlg, _("Key already expired.\n\n"
1386     "Do you want to change the expiration date?"),
1387     _("Key Edit"), MB_QUEST_ASK);
1388     if (cancel == IDNO)
1389     return FALSE;
1390     cancel = 0;
1391 werner 36 }
1392 twoaday 41
1393 werner 36 memset (&udd, 0, sizeof udd);
1394     udd.text = _("Key Expiration Date");
1395     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,
1396     date_dlg_proc, (LPARAM)&udd,
1397     _("Key Expiration Date"), IDS_WINPT_DATE);
1398     if (udd.cancel == 1)
1399     return FALSE;
1400     if (!keygen_check_date (&udd.st)) {
1401     msg_box (dlg, _("The date you have chosen lies in the past."),
1402     _("Key Edit"), MB_ERR);
1403     return FALSE;
1404     }
1405     if( k->is_protected ) {
1406 twoaday 41 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1407     if (cancel)
1408 werner 36 return FALSE;
1409     }
1410    
1411     ke = new GpgKeyEdit (k->keyid);
1412     if (!ke)
1413     BUG (NULL);
1414     if (k->is_protected)
1415     ke->setPassphrase (pass);
1416 twoaday 176 else
1417     ke->setNoPassphrase (true);
1418 twoaday 175 err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);
1419 werner 36 if (err)
1420     msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1421     else {
1422     _snprintf (buf, sizeof buf - 1, "%04d-%02d-%02d",
1423     udd.st.wYear, udd.st.wMonth, udd.st.wDay);
1424     listview_add_sub_item (lv, j, SUBK_COL_EXPIRES, buf);
1425     k->update = 1;
1426     msg_box (dlg, _("Subkey expire date successfully set."),
1427     _("GnuPG status"), MB_OK);
1428     }
1429     sfree_if_alloc (pass);
1430     delete ke;
1431     return TRUE;
1432     }
1433    
1434    
1435     /* Revoke the selected key in the list view @lv. @k contains
1436     control information about the global key.
1437     Return value: TRUE on success. */
1438     static int
1439     do_editkey_revoke (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1440     {
1441     gpgme_error_t err;
1442     GpgKeyEdit *ke;
1443     char buf[256];
1444     char *pass = NULL;
1445     int j, cancel = 0;
1446    
1447     if (!k->key_pair) {
1448     msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1449     return FALSE;
1450     }
1451    
1452     if ((j = listview_get_curr_pos (lv)) == -1) {
1453     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1454     return FALSE;
1455     }
1456     else if (listview_count_items (lv, 0) == 1) {
1457     msg_box( dlg, _("No subkeys were found, if you want to revoke the\n"
1458     "whole key, please use the Key Manager command directly.\n\n"
1459     "This command is only available to revoke single subkeys"),
1460     _("Key Edit"), MB_INFO );
1461     return FALSE;
1462     }
1463    
1464     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof (buf)-1);
1465     if (!strcmp (buf, _("Revoked"))) {
1466     msg_box (dlg, _("Key already revoked."), _("Key Edit"), MB_ERR);
1467     return FALSE;
1468     }
1469    
1470     if (k->is_protected) {
1471     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1472     if (cancel)
1473     return FALSE;
1474     }
1475    
1476     ke = new GpgKeyEdit (k->keyid);
1477     if (!ke)
1478     BUG (NULL);
1479     if (k->is_protected)
1480     ke->setPassphrase (pass);
1481 twoaday 176 else
1482     ke->setNoPassphrase (true);
1483 werner 36 err = ke->revokeSubkey (j, 0, NULL);
1484     if (err)
1485     msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);
1486     else {
1487     listview_add_sub_item (lv, j, SUBK_COL_STATUS, _("Revoked"));
1488     k->update = 1;
1489     msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1490     }
1491     sfree_if_alloc (pass);
1492     delete ke;
1493     return TRUE;
1494     }
1495    
1496    
1497     /* Revoked the selected userid in list view @lv.
1498     Return value: TRUE on success. */
1499     int
1500     do_editkey_revuid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1501     {
1502     gpgme_error_t err;
1503     GpgKeyEdit *ke;
1504 twoaday 160 char buf[128], email[128];
1505     char inf[512];
1506     char *pass = NULL;
1507 werner 36 int cancel = 0, id = 0, j;
1508    
1509     if (!k->key_pair) {
1510 twoaday 160 msg_box (dlg, _("There is no secret key available!"),
1511     _("Revoke user ID"), MB_ERR);
1512 werner 36 return FALSE;
1513     }
1514    
1515 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1516     msg_box (dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR);
1517 werner 36 return FALSE;
1518     }
1519    
1520     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1521     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1522     return FALSE;
1523     }
1524    
1525 twoaday 160 listview_get_item_text( lv, j, UID_COL_VALID, buf, sizeof buf - 1);
1526     if (strstr (buf, _("Revoked"))) {
1527     msg_box (dlg, _("This user ID has been already revoked."),
1528     _("Key Edit"), MB_INFO);
1529 werner 36 return FALSE;
1530     }
1531    
1532 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);
1533     _snprintf (inf, sizeof (inf) -1, _("user ID \"%s\".\n\n"
1534     "Do you really want to revoke this user ID?"), buf);
1535     if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1536 werner 36 return FALSE;
1537 twoaday 160 if (k->is_protected) {
1538 werner 36 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1539 twoaday 68 if (cancel)
1540 werner 36 return FALSE;
1541     }
1542 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, sizeof (email)-1);
1543     listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof (buf)-1);
1544     id = do_find_userid (k->keyid, email, buf, NULL);
1545 werner 36 if (id == -1)
1546     BUG (NULL);
1547    
1548     ke = new GpgKeyEdit (k->keyid);
1549     if (!ke)
1550     BUG (NULL);
1551     if (k->is_protected)
1552     ke->setPassphrase (pass);
1553 twoaday 176 else
1554     ke->setNoPassphrase (true);
1555 werner 36 err = ke->revokeUserid (id);
1556     if (err)
1557 twoaday 160 msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);
1558 werner 36 else {
1559     listview_add_sub_item (lv, j, 0, _("Revoked"));
1560     k->update = 1;
1561     status_box (dlg, _("User ID successfully revoked"), _("GnuPG Status"));
1562     }
1563     sfree_if_alloc (pass);
1564     delete ke;
1565     return err? FALSE : TRUE;
1566     }
1567    
1568    
1569     static int
1570     do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1571     {
1572     gpgme_error_t rc;
1573     GpgKeyEdit *ke;
1574     char buf[256], * pass = NULL, * prefs;
1575     int j, id, cancel=0, flags=0;
1576    
1577     if ((j = listview_get_curr_pos (lv)) == -1) {
1578     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1579     return FALSE;
1580     }
1581     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1582 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1583 werner 36 if (id == -1)
1584     BUG (dlg);
1585     if (k->is_protected) {
1586     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1587     if (cancel)
1588     return FALSE;
1589     }
1590    
1591     ke = new GpgKeyEdit (k->keyid);
1592     if (!ke)
1593     BUG (NULL);
1594     if (k->is_protected)
1595     ke->setPassphrase (pass);
1596 twoaday 176 else
1597     ke->setNoPassphrase (true);
1598 werner 36
1599     get_userid_preflist (&prefs, &flags);
1600    
1601     rc = ke->setUseridPreferences (id, prefs);
1602 twoaday 176 if (rc)
1603     msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);
1604 werner 36
1605     sfree_if_alloc (pass);
1606     free_if_alloc (prefs);
1607     delete ke;
1608     return 0;
1609     }
1610    
1611    
1612     static int
1613     do_editkey_primary (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1614     {
1615     gpgme_error_t err;
1616     GpgKeyEdit *ke;
1617     int j, id, cancel=0;
1618 twoaday 197 char buf[256], *pass = NULL;
1619 werner 36
1620     if (listview_count_items (lv, 0) == 1)
1621     return TRUE;
1622     if ((j = listview_get_curr_pos (lv)) == -1) {
1623     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1624     return FALSE;
1625     }
1626     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1627 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1628 werner 36 if (id == -1)
1629 twoaday 197 BUG (0);
1630 werner 36 if (k->is_protected) {
1631     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1632 twoaday 128 if (cancel)
1633 werner 36 return FALSE;
1634     }
1635    
1636     ke = new GpgKeyEdit (k->keyid);
1637     if (k->is_protected)
1638     ke->setPassphrase (pass);
1639 twoaday 176 else
1640     ke->setNoPassphrase (true);
1641 werner 36 err = ke->setPrimaryUserid (id);
1642     if (err)
1643     msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);
1644     else {
1645     k->update = 1;
1646     status_box (dlg, _("User ID successfully flagged"), _("GnuPG Status"));
1647     }
1648    
1649     sfree_if_alloc (pass);
1650     delete ke;
1651     return err? FALSE : TRUE;
1652     }
1653    
1654    
1655 twoaday 123
1656 twoaday 128 #define CIPHER 11
1657     #define HASH 11
1658     #define COMPR 4
1659    
1660 werner 36 static int
1661     parse_preflist (HWND dlg, const char *list)
1662     {
1663 twoaday 123 char buf[128] = {0};
1664     char *p, *pbuf = buf;
1665     const char *ciphers[CIPHER] = {"", "IDEA", "3DES",
1666 twoaday 128 "CAST5", "BLOWFISH", "", "",
1667     "AES", "AES192", "AES256", "TWOFISH"};
1668     const char *hash[HASH] = {"", "MD5", "SHA1", "RMD160", "",
1669     "", "", "", "SHA256", "SHA384", "SHA512"};
1670 twoaday 123 const char *compress[COMPR] = {"", "ZIP", "ZLIB", "BZIP2"};
1671 werner 36 int n=0;
1672    
1673     strncpy (buf, list, 127);
1674     p = strtok (pbuf, " ");
1675     while (p != NULL) {
1676     int algid = atol (p+1);
1677     n++;
1678     switch (*p) {
1679     case 'S':
1680 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_CIPHERS, LB_ADDSTRING, 0,
1681     (LPARAM)(const char*)ciphers[algid % CIPHER]);
1682 werner 36 break;
1683    
1684     case 'H':
1685 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_HASH, LB_ADDSTRING, 0,
1686     (LPARAM)(const char*)hash[algid % HASH]);
1687 werner 36 break;
1688    
1689     case 'Z':
1690 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_ZIP, LB_ADDSTRING, 0,
1691     (LPARAM)(const char*)compress[algid % COMPR]);
1692 werner 36 break;
1693    
1694     default:
1695     n--;
1696     }
1697     p = strtok (NULL, " ");
1698     }
1699     return n;
1700     }
1701    
1702    
1703     /* Dialog box procedure to show the key preferences. */
1704     BOOL CALLBACK
1705     showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1706     {
1707 twoaday 176 static keyedit_cb_t cb = NULL;
1708 twoaday 208 gpg_uid_info_t inf=NULL, u;
1709 twoaday 200 gpgme_key_t key;
1710 werner 36 char buf[128];
1711     int pos;
1712    
1713     switch (msg) {
1714     case WM_INITDIALOG:
1715 twoaday 176 cb = (keyedit_cb_t)lparam;
1716 twoaday 200 if (!cb)
1717     BUG (NULL);
1718     key = (gpgme_key_t)cb->opaque;
1719 twoaday 208 listview_get_item_text (cb->lv, cb->lv_pos,
1720     UID_COL_EMAIL, buf, sizeof (buf)-1);
1721     pos = do_find_userid (cb->keyid, buf, NULL, &inf);
1722     if (pos < 0 || !inf) {
1723     gpg_uid_info_release (inf);
1724     EndDialog (dlg, FALSE);
1725     break;
1726     }
1727     for (u=inf; u; u = u->next) {
1728     if (u->index == pos && u->prefs && *u->prefs) {
1729     _snprintf (buf, sizeof (buf)-1, "%s", u->name);
1730     SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1731     if (parse_preflist (dlg, u->prefs) <= 0)
1732 werner 36 pos = -1;
1733 twoaday 208 if (u->flags.mdc)
1734     CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1735     break;
1736 werner 36 }
1737     }
1738 twoaday 208 gpg_uid_info_release (inf);
1739     if (pos == -1) {
1740     msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1741     EndDialog (dlg, FALSE);
1742     break;
1743     }
1744 twoaday 128 SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1745     SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1746 twoaday 200 SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1747 werner 36 SetWindowText (dlg, _("Key Preferences"));
1748     SetForegroundWindow (dlg);
1749 twoaday 218 center_window (dlg, cb->parent);
1750 werner 36 break;
1751    
1752     case WM_COMMAND:
1753     switch (LOWORD (wparam)) {
1754     case IDOK:
1755     EndDialog (dlg, TRUE);
1756     break;
1757 twoaday 211
1758     case IDCANCEL:
1759     EndDialog (dlg, FALSE);
1760     break;
1761 werner 36 }
1762     break;
1763     }
1764     return FALSE;
1765     }
1766    
1767    
1768     static int
1769     do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1770     {
1771 twoaday 176 struct keyedit_cb_s cb;
1772 twoaday 208 char status[32];
1773 werner 36
1774     if (k->is_v3)
1775     return TRUE;
1776    
1777     if (listview_get_curr_pos (lv) == -1) {
1778     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1779     return FALSE;
1780     }
1781     memset (&cb, 0, sizeof (cb));
1782 twoaday 218 cb.parent = dlg;
1783 twoaday 200 cb.opaque = k->ctx;
1784     cb.keyid = k->keyid;
1785 twoaday 208 cb.lv = lv;
1786     cb.lv_pos = listview_get_curr_pos (lv);
1787    
1788     listview_get_item_text (lv, cb.lv_pos, UID_COL_VALID,
1789     status, sizeof (status)-1);
1790     if (!strcmp (status, _("Revoked")))
1791     return TRUE;
1792    
1793 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1794     showpref_dlg_proc, (LPARAM)&cb);
1795     return TRUE;
1796     }
1797    
1798    
1799     static int
1800     do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1801     {
1802     gpgme_error_t err;
1803     GpgKeyEdit *ke;
1804 twoaday 160 char email[128], name[128];
1805     char inf[384];
1806 werner 36 int j, id = 0;
1807    
1808     if (!k->key_pair)
1809     return FALSE; /* XXX: see do_editkey_delsubkey */
1810    
1811 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1812     msg_box (dlg, _("Primary user ID can not be deleted!"),
1813     _("Key Edit"), MB_ERR);
1814 werner 36 return FALSE;
1815     }
1816 twoaday 160 if ((j = listview_get_curr_pos (lv)) == -1) {
1817     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1818 werner 36 return FALSE;
1819     }
1820    
1821     /* XXX: add a hint that also all signatures will be deleted? */
1822 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);
1823     _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1824 twoaday 193 "All signatures on this user ID will be also deleted."
1825     "\n\n"
1826 twoaday 160 "Do you really want to delete this user ID?"),
1827     name);
1828     if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1829 werner 36 return FALSE;
1830    
1831 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1832     listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);
1833     id = do_find_userid (k->keyid, email, name, NULL);
1834 werner 36 if (id == -1)
1835     BUG (dlg);
1836    
1837     ke = new GpgKeyEdit (k->keyid);
1838     if (!ke)
1839     BUG (NULL);
1840    
1841     err = ke->delUserid (id);
1842 twoaday 160 if (err)
1843     msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);
1844 werner 36 else {
1845 twoaday 160 listview_del_item (lv, j);
1846 werner 36 k->update = 1;
1847 twoaday 160 status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1848 werner 36 }
1849     delete ke;
1850     return err? FALSE : TRUE;
1851 twoaday 193 }
1852 werner 36
1853    
1854 twoaday 193 /* Subclass routine for the subkey listview control to allow shortcuts. */
1855 werner 36 static BOOL CALLBACK
1856 twoaday 193 subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1857 werner 36 {
1858 twoaday 193 int virt_key = 0;
1859     winpt_key_t key;
1860    
1861     switch (msg) {
1862 werner 36 case WM_KEYUP:
1863 twoaday 193 virt_key = (int)wparam;
1864     key = (winpt_key_t)keyedit_subkey_proc.opaque;
1865     if (!key || !key->key_pair)
1866     break;
1867    
1868     switch (virt_key) {
1869 werner 36 case VK_DELETE:
1870 twoaday 193 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1871     CB_SETCURSEL, CMD_DELKEY, 0);
1872     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1873 werner 36 break;
1874    
1875     case VK_INSERT:
1876 twoaday 200 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1877     CB_SETCURSEL, CMD_ADDKEY, 0);
1878     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1879 werner 36 break;
1880     }
1881     }
1882 twoaday 193 return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1883     }
1884 werner 36
1885    
1886     static BOOL CALLBACK
1887     uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1888     {
1889 twoaday 193 int virt_key = 0;
1890     winpt_key_t key;
1891    
1892     switch (msg) {
1893 werner 36 case WM_KEYUP:
1894 twoaday 193 virt_key = (int)wparam;
1895     key = (winpt_key_t)keyedit_uid_proc.opaque;
1896     if (!key || !key->key_pair)
1897     break;
1898    
1899 werner 36 switch (virt_key) {
1900     case VK_DELETE:
1901     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1902     CB_SETCURSEL, CMD_DELUID, 0);
1903     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1904     break;
1905    
1906     case VK_INSERT:
1907     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1908     CB_SETCURSEL, CMD_ADDUID, 0);
1909     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1910     break;
1911     }
1912     }
1913 twoaday 193 return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1914     }
1915 werner 36
1916    
1917 twoaday 193 /* Enable the key @k when @enable is 1, disable it otherwise. */
1918 twoaday 165 static void
1919 twoaday 193 do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1920     listview_ctrl_t lv, int enable)
1921 twoaday 165 {
1922     km_enable_disable_key (lv, dlg, 0, enable);
1923     k->update = 1;
1924     }
1925    
1926    
1927 twoaday 170 /* Return default secret key. */
1928     static gpgme_key_t
1929     get_default_key (void)
1930     {
1931     gpgme_key_t def_sk;
1932     char *keyid = get_gnupg_default_key ();
1933    
1934     get_seckey (keyid, &def_sk);
1935     free_if_alloc (keyid);
1936     return def_sk;
1937     }
1938    
1939    
1940 twoaday 195
1941     static void
1942 twoaday 208 do_editkey_minimize (winpt_key_t k, HWND dlg)
1943     {
1944     gpgme_error_t err;
1945     GpgKeyEdit *ke;
1946    
1947     ke = create_GpgKeyEdit (k->keyid);
1948     err = ke->minimizeKey ();
1949     if (err)
1950     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1951     else {
1952     msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1953     k->update = 1;
1954     }
1955     delete ke;
1956     }
1957    
1958    
1959     static void
1960 twoaday 195 do_editkey_clean (winpt_key_t k, HWND dlg)
1961     {
1962     gpgme_error_t err;
1963     GpgKeyEdit *ke;
1964    
1965 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1966 twoaday 195 err = ke->cleanKey ();
1967     if (err)
1968 twoaday 197 msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1969     else {
1970 twoaday 195 msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1971 twoaday 197 k->update = 1;
1972     }
1973 twoaday 195 delete ke;
1974     }
1975    
1976    
1977 twoaday 193 /* Start the dialog to list and display the status of all
1978     signatures for this key. */
1979 twoaday 175 static void
1980     do_editkey_check (winpt_key_t k, HWND dlg)
1981     {
1982 twoaday 176 if (!k->ctx)
1983     get_pubkey (k->keyid, &k->ctx);
1984     if (!k->uid && k->ctx)
1985     k->uid = k->ctx->uids->uid;
1986 twoaday 175 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYSIG_TREE, dlg,
1987 twoaday 176 sigtree_dlg_proc, (LPARAM)k);
1988 twoaday 175 }
1989    
1990    
1991 twoaday 170 static int
1992     do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1993     {
1994     gpgme_error_t err;
1995     GpgKeyEdit *ke;
1996     char *pass = NULL;
1997     char email[64], name[128];
1998     int uid_index;
1999     int cancel = 0;
2000    
2001     uid_index = listview_get_curr_pos (lv);
2002     if (uid_index == -1) {
2003     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
2004     return FALSE;
2005     }
2006     if (mode == CMD_SIGN) {
2007     cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
2008     _("Key Edit"), MB_QUEST_ASK);
2009     if (cancel == IDNO)
2010     return FALSE;
2011     }
2012    
2013     listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
2014     listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
2015     uid_index = do_find_userid (k->keyid, email, name, NULL);
2016     if (k->is_protected) {
2017     pass = request_passphrase (_("Key Edit"), 1, &cancel);
2018     if (cancel)
2019     return FALSE;
2020     }
2021 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
2022 twoaday 175 if (k->is_protected)
2023     ke->setPassphrase (pass);
2024 twoaday 176 else
2025     ke->setNoPassphrase (true);
2026 twoaday 170 ke->setLocalUser (get_default_key ());
2027     err = ke->signUserid (uid_index,
2028     mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
2029     0, NULL);
2030     if (!err) {
2031     msg_box (dlg, _("Key successfully signed."), _("Key Edit"), MB_OK);
2032     k->update = 1;
2033     }
2034     else
2035     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
2036     delete ke;
2037     sfree_if_alloc (pass);
2038     return !err? TRUE : FALSE;
2039     }
2040    
2041    
2042     static int
2043     lookup_cmd (HWND dlg)
2044     {
2045     char buf[64];
2046     int i;
2047    
2048     i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
2049     if (i == LB_ERR)
2050     return LB_ERR;
2051     GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);
2052     for (i=0; cmdlist[i].name != NULL; i++) {
2053     if (!strcmp (buf, cmdlist[i].name))
2054     return cmdlist[i].id;
2055     }
2056     return LB_ERR;
2057     }
2058    
2059 twoaday 193
2060 twoaday 208
2061     gpgme_error_t key_get_revokers (winpt_key_t key, int reload,
2062     gpg_desig_rev_t *r_rev);
2063    
2064     /* Check if the key supports designated revokers and if
2065     secret keys exist to generate such a revoke cert. */
2066     static bool
2067     check_desig_rev (winpt_key_t key)
2068     {
2069     gpg_desig_rev_t rev, u;
2070     struct winpt_key_s sk;
2071    
2072     if (!key->ext->gloflags.has_desig_rev)
2073     return false;
2074     key_get_revokers (key, 0, &rev);
2075     for (u = rev; u; u = u->next) {
2076     memset (&sk, 0, sizeof (sk));
2077     if (!winpt_get_seckey (u->fpr+32, &sk))
2078     return true;
2079     }
2080     return false;
2081     }
2082    
2083    
2084     /* Use the gpg --desig-revoker command to create a revocation
2085     cert for a key that lists our key as a designated revoker. */
2086     static void
2087     gen_desig_revoke_cert (winpt_key_t key, HWND dlg)
2088     {
2089     const char *warn;
2090     char *inf, *p;
2091     int id;
2092    
2093     inf = km_key_get_info (key, 0);
2094     warn = _("Your keys is listed as a designated revoker for the key\n\n"
2095     "%s\n\n"
2096     "Are you sure you want to create a revocation certificate\n"
2097     "which allow to revoke the key listed above?");
2098     p = new char[strlen (inf)+1+strlen (warn)+1];
2099     sprintf (p, warn, inf);
2100     free_if_alloc (inf);
2101    
2102     id = msg_box (dlg, p, _("Key Edit"), MB_YESNO|MB_ICONWARNING);
2103     free_if_alloc (p);
2104     if (id == IDNO)
2105     return;
2106    
2107     key->internal = 1;
2108     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYREVOKE, dlg,
2109     key_revoke_dlg_proc, (LPARAM)key);
2110     }
2111    
2112    
2113 twoaday 133 /* Dialog box procedure for the edit key dialog. */
2114 werner 36 BOOL CALLBACK
2115     keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2116     {
2117     static winpt_key_t k;
2118     static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2119 twoaday 165 int cmd;
2120 werner 36 HWND item;
2121    
2122 twoaday 193 switch (msg) {
2123 werner 36 case WM_INITDIALOG:
2124     k = (winpt_key_t)lparam;
2125     if (!k)
2126     BUG (NULL);
2127 twoaday 170 do_init_cmdlist (dlg, k->key_pair);
2128 werner 36 lvsub = subkey_list_init (dlg, k);
2129 twoaday 193 if (!lvsub)
2130     BUG (0);
2131 werner 36 lvuid = userid_list_init (dlg, k);
2132 twoaday 193 if (!lvuid)
2133     BUG (0);
2134     item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2135     keyedit_subkey_proc.opaque = (void*)k;
2136 werner 36 keyedit_subkey_proc.dlg = dlg;
2137     keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2138 twoaday 193 keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2139     if (keyedit_subkey_proc.old) {
2140     if( !SetWindowLong (item, GWL_WNDPROC,
2141     (LONG)keyedit_subkey_proc.current)) {
2142     msg_box (dlg, _("Could not set subkey window procedure."),
2143     _("Key Edit"), MB_ERR);
2144     BUG (0);
2145 werner 36 }
2146     }
2147 twoaday 193 item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2148     keyedit_uid_proc.opaque = (void*)k;
2149 werner 36 keyedit_uid_proc.dlg = dlg;
2150     keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2151 twoaday 193 keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2152     if (keyedit_uid_proc.old) {
2153     if (!SetWindowLong (item, GWL_WNDPROC,
2154     (LONG)keyedit_uid_proc.current)) {
2155     msg_box (dlg, _("Could not set user ID window procedure."),
2156     _("Key Edit"), MB_ERR);
2157     BUG (0);
2158 werner 36 }
2159     }
2160 twoaday 170 if (k->ctx->revoked) {
2161 werner 36 EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
2162     EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
2163     }
2164     SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2165 twoaday 117 SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2166 twoaday 88 SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2167 twoaday 208 SetDlgItemText (dlg, IDC_KEYEDIT_REVOKE, _("&Revoke..."));
2168     if (!check_desig_rev (k))
2169     ShowWindow (GetDlgItem (dlg, IDC_KEYEDIT_REVOKE), SW_HIDE);
2170 twoaday 88 SetWindowText (dlg, _("Key Edit"));
2171 twoaday 170 SetForegroundWindow (dlg);
2172     center_window (dlg, NULL);
2173 werner 36 return TRUE;
2174    
2175     case WM_DESTROY:
2176 twoaday 193 if (lvsub) {
2177     listview_release (lvsub);
2178 werner 36 lvsub = NULL;
2179     }
2180 twoaday 193 if (lvuid) {
2181     listview_release (lvuid);
2182 werner 36 lvuid = NULL;
2183     }
2184     break;
2185    
2186     case WM_NOTIFY:
2187     NMHDR * notify;
2188     notify = (NMHDR *)lparam;
2189 twoaday 218 if (!notify || notify->idFrom != IDC_KEYEDIT_UIDLIST)
2190     break;
2191     if (notify->code == NM_DBLCLK)
2192 werner 36 do_editkey_showpref (k, dlg, lvuid);
2193 twoaday 218 if (notify->code == NM_RCLICK && k->key_pair) {
2194     HMENU hm = LoadMenu (glob_hinst, MAKEINTRESOURCE (IDR_WINPT_KEYEDIT));
2195     HMENU popup = GetSubMenu (hm, 0);
2196     POINT p;
2197    
2198     GetCursorPos (&p);
2199     TrackPopupMenu (popup, TPM_RIGHTALIGN, p.x, p.y, 0, dlg, NULL);
2200     DestroyMenu (hm);
2201     DestroyMenu (popup);
2202     }
2203 werner 36 break;
2204    
2205     case WM_COMMAND:
2206 twoaday 218 switch (LOWORD (wparam)) {
2207 werner 36 case IDOK:
2208 twoaday 170 cmd = lookup_cmd (dlg);
2209 werner 36 if (cmd == LB_ERR) {
2210     msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
2211     return FALSE;
2212     }
2213     if (k->is_v3 && is_cmd_openpgp (cmd)) {
2214     msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),
2215     _("Key Edit"), MB_ERR);
2216     return FALSE;
2217     }
2218     switch (cmd) {
2219     case CMD_SHOWPREF: do_editkey_showpref (k, dlg, lvuid); break;
2220     case CMD_DELKEY: do_editkey_delkey (k, dlg, lvsub); break;
2221     case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2222     case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2223     case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2224     /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/
2225     case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2226     case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2227     case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
2228     case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
2229     case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
2230     case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
2231     case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
2232 twoaday 165 case CMD_ENABLE: do_editkey_enable_disable (k, dlg, lvsub, 1); break;
2233     case CMD_DISABLE: do_editkey_enable_disable (k, dlg, lvsub, 0); break;
2234 twoaday 175 case CMD_CHECK: do_editkey_check (k, dlg); break;
2235 twoaday 165 case CMD_TRUST: keyedit_change_ownertrust (k, dlg); break;
2236 twoaday 170 case CMD_SIGN:
2237     case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2238     lvuid, cmd);
2239     break;
2240 twoaday 212 case CMD_CLEAN: do_editkey_clean (k, dlg); break;
2241     case CMD_MINIMIZE: do_editkey_minimize (k, dlg); break;
2242 werner 36 }
2243 twoaday 218 break;
2244    
2245 werner 36 case IDCANCEL:
2246     EndDialog (dlg, FALSE);
2247     break;
2248    
2249     case IDC_KEYEDIT_HELP:
2250     do_show_help (dlg);
2251     break;
2252 twoaday 208
2253     case IDC_KEYEDIT_REVOKE:
2254     gen_desig_revoke_cert (k, dlg);
2255     break;
2256 twoaday 218
2257     case ID_KEYEDIT_UID_PRIM:
2258     do_editkey_primary (k, dlg, lvuid);
2259     break;
2260    
2261     case ID_KEYEDIT_UID_DEL:
2262     do_editkey_deluid (k, dlg, lvuid);
2263     break;
2264    
2265     case ID_KEYEDIT_UID_REV:
2266     do_editkey_revuid (k, dlg, lvuid);
2267     break;
2268 werner 36 }
2269     break;
2270     }
2271     return FALSE;
2272 twoaday 133 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26