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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 306 - (hide annotations)
Fri Mar 23 14:07:24 2007 UTC (17 years, 11 months ago) by twoaday
File size: 61267 byte(s)


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26