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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 207 - (hide annotations)
Fri Apr 28 10:28:24 2006 UTC (18 years, 10 months ago) by twoaday
File size: 57092 byte(s)
Bug fixes and cleanups.


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 werner 36 };
68    
69 twoaday 170 struct cmdlist_s {
70     const char *name;
71     unsigned int need_pair:1;
72     int id;
73     } cmdlist[] = {
74     {"ADDKEY", 1, CMD_ADDKEY},
75     {"ADDUID", 1, CMD_ADDUID},
76     {"ADDPHOTO", 1, CMD_ADDPHOTO},
77     {"ADDREVOKER", 1, CMD_ADDREVOKER},
78     {"DELUID", 1, CMD_DELUID},
79     {"DELKEY", 1, CMD_DELKEY},
80     {"EXPIRE", 1, CMD_EXPIRE},
81     {"SHOWPREF", 0, CMD_SHOWPREF},
82     /*{"SETPREF", 1, CMD_SETPREF},*/
83     {"PASSWD", 1, CMD_PASSWD},
84     {"PRIMARY", 1, CMD_PRIMARY},
85     {"TRUST", 0, CMD_TRUST},
86     {"REVUID", 1, CMD_REVUID},
87     {"REVKEY", 1, CMD_REVKEY},
88     {"DISABLE", 0, CMD_DISABLE},
89     {"ENABLE", 0, CMD_ENABLE},
90     {"SIGN", 0, CMD_SIGN},
91     {"LSIGN", 0, CMD_LSIGN},
92 twoaday 175 {"CHECK", 0, CMD_CHECK},
93 twoaday 195 {"CLEAN", 0, CMD_CLEAN},
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 werner 36 const char *keyid;
122     const char *pass;
123     listview_ctrl_t lv;
124     void *opaque;
125     unsigned int finished:1;
126 twoaday 176 unsigned int is_protected:1;
127 werner 36 };
128 twoaday 176 typedef struct keyedit_cb_s *keyedit_cb_t;
129 werner 36
130 twoaday 176
131     /* Key generation callback context. */
132     struct keygen_cb_s {
133 werner 36 int bits;
134     int algo;
135     u32 expire;
136     char *fpr;
137 twoaday 200 char *name;
138     char *comment;
139     char *email;
140 werner 36 };
141 twoaday 176 typedef struct keygen_cb_s *keygen_cb_t;
142 werner 36
143 twoaday 200 /* Subclass context for the subkey list. */
144     static subclass_s keyedit_subkey_proc;
145 werner 36
146 twoaday 200 /* Subclass context for the user-id list. */
147 werner 36 static subclass_s keyedit_uid_proc;
148    
149     int keygen_check_date (SYSTEMTIME *st);
150     void get_userid_preflist (char **r_prefs, int * r_flags);
151 twoaday 150 char* get_subkey_keyid (const char *keyid);
152 werner 36
153 twoaday 204 void ComboBox_AddString_utf8 (HWND cb, const char *txt);
154 werner 36
155 twoaday 200 static GpgKeyEdit*
156     create_GpgKeyEdit (const char *keyid)
157     {
158     GpgKeyEdit *ke;
159    
160     ke = new GpgKeyEdit (keyid);
161     if (!ke)
162     BUG (NULL);
163     return ke;
164     }
165    
166    
167 werner 36 /* Associate each key with a combo box entry.
168     Skip the key in @k. */
169     static void
170 twoaday 200 do_init_keylist (HWND dlg, const char *keyid)
171 werner 36 {
172     gpg_keycache_t pub;
173     gpgme_key_t key;
174 twoaday 128 const char *s, *kid;
175 werner 36 int i, n;
176    
177     pub = keycache_get_ctx (1);
178     if (!pub)
179     BUG (0);
180    
181     gpg_keycache_rewind (pub);
182 twoaday 128 while( !gpg_keycache_next_key (pub, 0, &key)) {
183     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     n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );
194     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 204 char *p;
210 werner 36 size_t n;
211    
212 twoaday 185 n = strlen (utf8_name) + strlen (email) + 16;
213 twoaday 201 if (utf8_comment)
214     n += strlen (utf8_comment);
215 werner 36 p = new char[n+1];
216     if (!p)
217 twoaday 185 BUG (NULL);
218 twoaday 201 if (utf8_comment) {
219 twoaday 204 sprintf (p, "%s (%s)", utf8_name, utf8_comment);
220 twoaday 201 }
221 werner 36 else
222 twoaday 204 sprintf (p, "%s", utf8_name);
223 werner 36
224     listview_add_item (lv, "");
225     listview_add_sub_item (lv, 0, 0, _("Ultimate" ));
226     listview_add_sub_item (lv, 0, 1, p);
227     listview_add_sub_item (lv, 0, 2, email && *email? email : "");
228     listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));
229     free_if_alloc (p);
230 twoaday 129 }
231 werner 36
232    
233     static void
234 twoaday 176 do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)
235 werner 36 {
236     char info[128], keyid[32];
237 twoaday 200 const char *expdate, *s;
238 werner 36 int n;
239    
240     expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
241     _snprintf (info, sizeof info-1, "%d-bit %s",
242     keygen->bits,
243     get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
244 twoaday 150 _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+8);
245 werner 36 n = listview_count_items (lv, 0);
246     listview_add_item_pos (lv, n);
247     listview_add_sub_item (lv, n, 0, info);
248     listview_add_sub_item (lv, n, 1, keyid);
249     listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));
250     listview_add_sub_item (lv, n, 3, expdate);
251 twoaday 150 if (flags & KM_FLAG_REVOKED)
252     s = _("Revoked");
253     else if (flags & KM_FLAG_EXPIRED)
254     s = _("Expired");
255     else
256     s = _("OK");
257 werner 36 listview_add_sub_item (lv, n, 4, s);
258 twoaday 150 }
259 werner 36
260    
261     /* Try to find the GPG edit key index which belongs to the user ID
262 twoaday 160 given by the email address @email, @name is used as a fallback.
263     If @r_inf != NULL, the info context will be returned.
264 werner 36 Return value: index of the user ID or -1 on error. */
265     static int
266 twoaday 160 do_find_userid (const char *keyid, const char *email,
267     const char *name, gpg_uid_info_t *r_inf)
268 werner 36 {
269     GpgKeyEdit *ke;
270     gpgme_error_t err;
271     gpg_uid_info_t inf, ui;
272     int pos = -1;
273    
274 twoaday 200 ke = create_GpgKeyEdit (keyid);
275 werner 36 err = ke->getUseridInfo (&inf);
276     delete ke;
277     if (err) {
278     log_box (_("user ID"), MB_ERR,
279     _("Could not get key information for: \"%s\":\n%s"),
280     name, gpgme_strerror (err));
281     return -1;
282     }
283    
284     for (ui = inf; ui; ui = ui->next) {
285 twoaday 205 if (name && email && ui->email && ui->name) {
286 twoaday 160 if (!strcmp (ui->email, email) &&
287 twoaday 205 !strncmp (ui->name, name, strlen (name))) {
288 twoaday 160 pos = ui->index;
289     break;
290     }
291     continue;
292     }
293     if (ui->email) {
294     if (!strcmp (ui->email, email)) {
295     pos = ui->index;
296     break;
297     }
298     /* The email address is more unique, use the name just
299     as the fallbck when no email address is available. */
300     continue;
301     }
302 twoaday 205 if (ui->name && name && !strcmp (ui->name, name)) {
303 werner 36 pos = ui->index;
304     break;
305     }
306     }
307     if (r_inf)
308     *r_inf = inf;
309     else
310     gpg_uid_info_release (inf);
311     return pos;
312     }
313    
314    
315 twoaday 128 /* Return true if @fname is a JPEG file. */
316     bool
317     is_jpg_file (const char *fname)
318     {
319     FILE *fp;
320     BYTE buf[10];
321     int n;
322    
323     fp = fopen (fname, "rb");
324     if (!fp)
325     return false;
326     n = fread (buf, 1, 10, fp);
327     fclose (fp);
328     if (n < 10)
329     return false;
330     return buf[6] == 'J' && buf[7] == 'F' &&
331     buf[8] == 'I' && buf[9] == 'F';
332     }
333    
334    
335 werner 36 /* Dialog box procedure to add a photo. */
336     BOOL CALLBACK
337     keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
338     {
339 twoaday 200 static keyedit_cb_t cb;
340 werner 36 GpgKeyEdit *ke;
341 twoaday 200 gpgme_error_t err;
342     const char *s;
343     char file[128];
344 werner 36 int id;
345    
346     switch( msg ) {
347     case WM_INITDIALOG:
348 twoaday 200 cb = (keyedit_cb_t)lparam;
349     if (!cb)
350 werner 36 BUG (NULL);
351     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."));
352     SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
353     SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
354 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
355 twoaday 128 SetWindowText (dlg, _("Add Photo ID"));
356 twoaday 105 SetForegroundWindow (dlg);
357 werner 36 break;
358    
359     case WM_DESTROY:
360     break;
361    
362     case WM_SYSCOMMAND:
363 twoaday 128 if (LOWORD (wparam) == SC_CLOSE)
364     EndDialog (dlg, TRUE);
365 werner 36 break;
366    
367     case WM_COMMAND:
368 twoaday 200 switch( LOWORD (wparam)) {
369 werner 36 case IDC_ADDPHOTO_SELFILE:
370 twoaday 128 s = get_fileopen_dlg (dlg, _("Select Image File"),
371 twoaday 180 "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",
372 twoaday 128 NULL);
373     if (s && !is_jpg_file (s)) {
374     log_box (_("Add Photo"), MB_ERR,
375     _("'%s' is not a valid JPEG file."), s);
376     return FALSE;
377     }
378     if (s && *s)
379     SetDlgItemText (dlg, IDC_ADDPHOTO_FILE, s);
380 werner 36 break;
381    
382     case IDOK:
383 twoaday 128 if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
384     msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);
385 werner 36 return FALSE;
386     }
387 twoaday 128 if (get_file_size (file) == 0 || get_file_size (file) > 6144 ) {
388     id = msg_box (dlg, _("The JPEG is really large.\n"
389 werner 36 "Are you sure you want to use it?"),
390 twoaday 128 _("Add Photo"), MB_YESNO|MB_INFO);
391     if (id == IDNO)
392 werner 36 return TRUE;
393     }
394 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
395     if (cb->pass)
396     ke->setPassphrase (cb->pass);
397 twoaday 176 else
398     ke->setNoPassphrase (true);
399 twoaday 200 err = ke->addPhotoid (file);
400 werner 36 delete ke;
401 twoaday 200 if (err) {
402     msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
403 werner 36 return FALSE;
404     }
405     else {
406 twoaday 200 cb->finished = 1;
407 twoaday 128 msg_box (dlg, _("Photo successfully added."),
408     _("GnuPG Status"), MB_OK);
409 werner 36 }
410     EndDialog (dlg, TRUE);
411     break;
412    
413     case IDCANCEL:
414     EndDialog (dlg, FALSE);
415     break;
416     }
417     break;
418     }
419     return FALSE;
420     }
421    
422    
423     /* Dialog box procedure to add a designated revoker. */
424     BOOL CALLBACK
425     keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
426     {
427 twoaday 200 static keyedit_cb_t cb;
428 twoaday 129 gpgme_error_t err;
429 werner 36 GpgKeyEdit *ke;
430 twoaday 204 char *uid=NULL;
431 werner 36
432 twoaday 129 switch (msg) {
433 werner 36 case WM_INITDIALOG:
434 twoaday 200 cb = (keyedit_cb_t)lparam;
435     if (!cb)
436 twoaday 129 BUG (NULL);
437 twoaday 200 do_init_keylist (dlg, cb->keyid);
438 twoaday 129 SetDlgItemText (dlg, IDC_ADDREV_INF,
439     _("Appointing a key as designated revoker cannot be undone."));
440 werner 36 SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
441     SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
442 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
443 twoaday 128 SetWindowText (dlg, _("Add Revoker"));
444 twoaday 105 SetForegroundWindow (dlg);
445 werner 36 break;
446    
447     case WM_DESTROY:
448     break;
449    
450     case WM_SYSCOMMAND:
451 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
452     EndDialog (dlg, FALSE);
453 werner 36 break;
454    
455     case WM_COMMAND:
456 twoaday 200 switch (LOWORD (wparam)) {
457 twoaday 204 case IDOK:
458     if (!GetDlgItemText_utf8 (dlg, IDC_ADDREV_KEYLIST, &uid)) {
459     msg_box (dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR);
460 werner 36 return FALSE;
461     }
462 twoaday 204
463 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
464     if (cb->pass)
465     ke->setPassphrase (cb->pass);
466 twoaday 176 else
467     ke->setNoPassphrase (true);
468 twoaday 204 err = ke->addDesignatedRevoker (uid);
469 werner 36 delete ke;
470 twoaday 204 safe_free (uid);
471 werner 36 if (err) {
472     msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
473     return TRUE;
474     }
475     else {
476 twoaday 200 cb->finished = 1;
477 twoaday 129 msg_box (dlg, _("Revoker successfully addded."),
478     _("GnuPG Status"), MB_OK);
479 werner 36 }
480 twoaday 129 EndDialog (dlg, TRUE);
481 werner 36 break;
482    
483     case IDCANCEL:
484 twoaday 129 EndDialog (dlg, FALSE);
485 werner 36 break;
486     }
487     break;
488     }
489     return FALSE;
490     }
491    
492    
493     /* Dialog box procedure to add a new user-ID. */
494     BOOL CALLBACK
495     keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
496     {
497 twoaday 176 static keyedit_cb_t ctx;
498 twoaday 200 keygen_cb_t keygen;
499 werner 36 gpgme_error_t err;
500     GpgKeyEdit *ke;
501     char *utf8_name = NULL;
502 twoaday 201 char *utf8_comment = NULL;
503 twoaday 204 char email[128];
504 werner 36 int rc;
505    
506 twoaday 176 switch (msg) {
507 werner 36 case WM_INITDIALOG:
508 twoaday 176 ctx = (keyedit_cb_t)lparam;
509 twoaday 200 if (!ctx)
510 werner 36 dlg_fatal_error(dlg, "Could not get dialog param!");
511     SetWindowText (dlg, _("Add new User ID"));
512     SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
513     SetDlgItemText (dlg, IDC_ADDUID_INFEMAIL, _("&Email"));
514     SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
515 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
516 werner 36 SetForegroundWindow (dlg);
517     return FALSE;
518    
519     case WM_SYSCOMMAND:
520 twoaday 176 if (LOWORD (wparam) == SC_CLOSE)
521 werner 36 EndDialog(dlg, TRUE);
522     return FALSE;
523    
524     case WM_COMMAND:
525     switch ( LOWORD( wparam ) ) {
526     case IDOK:
527 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
528 twoaday 204 rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_NAME, &utf8_name);
529 werner 36 if (!rc || rc < 5) {
530 twoaday 204 msg_box (dlg, _("Please enter a name (min. 5 chars.)"),
531     _("UserID"), MB_ERR);
532     free_if_alloc (utf8_name);
533 werner 36 return FALSE;
534     }
535 twoaday 204 if (strchr (utf8_name, '@')) {
536     msg_box (dlg, _("Please enter the email address in the email field and not in the name field"),
537     _("UserID"), MB_INFO);
538 werner 36 return FALSE;
539     }
540 twoaday 204
541     if( !GetDlgItemText (dlg, IDC_ADDUID_EMAIL, email, sizeof (email) -1)) {
542 werner 36 msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
543     return FALSE;
544     }
545 twoaday 190 if (check_email_address (email)) {
546 twoaday 175 msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
547 werner 36 return FALSE;
548     }
549    
550 twoaday 204 rc = GetDlgItemText_utf8 (dlg, IDC_ADDUID_COMMENT, &utf8_comment);
551 werner 36
552 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
553 twoaday 176 if (ctx->is_protected)
554 werner 36 ke->setPassphrase (ctx->pass);
555 twoaday 176 else
556     ke->setNoPassphrase (true);
557 twoaday 201 err = ke->addUserid (utf8_name, utf8_comment, email);
558 werner 36 if (err)
559     msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
560     else {
561     msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
562     ctx->finished = 1;
563 twoaday 201 keygen->name = utf8_name;
564     keygen->comment = utf8_comment;
565 twoaday 200 keygen->email = m_strdup (email);
566 werner 36 }
567 twoaday 200 delete ke;
568 werner 36 EndDialog (dlg, TRUE);
569     return TRUE;
570    
571     case IDCANCEL:
572     EndDialog (dlg, FALSE);
573     return FALSE;
574     }
575     break;
576     }
577    
578     return FALSE;
579     }
580    
581    
582     static void
583     init_keysize_box (HWND dlg, int ctlid)
584     {
585     const char *sizelist[] = {
586 twoaday 200 "1024", "1536",
587     "2048", "2560",
588     "3072", "3854",
589     "4096", NULL
590 werner 36 };
591     int i;
592 twoaday 200
593 werner 36 for (i=0; sizelist[i] != NULL; i++)
594 twoaday 200 SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
595     (LPARAM)(char*)sizelist[i]);
596 werner 36 SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
597     }
598    
599 twoaday 200
600 werner 36 static int
601     get_keysize_from_box (HWND dlg, int ctlid)
602     {
603     int pos;
604     char buf[32];
605    
606     pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
607     if (pos == CB_ERR)
608     return -1;
609     SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
610     return atol (buf);
611     }
612    
613    
614 twoaday 175 /* Create a time_t from a system time @st. */
615     time_t
616     w32_mktime (SYSTEMTIME *st)
617     {
618     struct tm tm;
619    
620     memset (&tm, 0, sizeof (tm));
621     tm.tm_year = st->wYear-1900;
622     tm.tm_mday = st->wDay+1;
623     tm.tm_mon = st->wMonth-1;
624     return mktime (&tm);
625     }
626    
627    
628 twoaday 129 /* Dialog procedure for adding a new secondary key. */
629 werner 36 BOOL CALLBACK
630     keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
631     {
632 twoaday 176 static keyedit_cb_t ctx;
633 twoaday 200 keygen_cb_t keygen;
634 werner 36 GpgKeyEdit *ke;
635     gpgme_error_t err;
636 twoaday 175 SYSTEMTIME st;
637 twoaday 200 HWND hwnd;
638 werner 36 int index, size, valid;
639    
640     switch (msg) {
641     case WM_INITDIALOG:
642 twoaday 176 ctx = (keyedit_cb_t)lparam;
643 werner 36 if (!ctx)
644     dlg_fatal_error (dlg, "Could not get dialog param!");
645 twoaday 99
646 werner 36 SetWindowText (dlg, _("Add new Subkey"));
647     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
648     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));
649     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFVALID, _("Key expiration"));
650 twoaday 99 SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
651 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
652 twoaday 99
653 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
654     listbox_add_string (hwnd, "DSA (sign only)");
655     listbox_add_string (hwnd, "ElGamal (encrypt only)");
656     listbox_add_string (hwnd, "RSA (sign only)");
657     listbox_add_string (hwnd, "RSA (encrypt only)");
658 werner 36 CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
659     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
660     init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
661 twoaday 105 SetForegroundWindow (dlg);
662 werner 36 return FALSE;
663    
664     case WM_SYSCOMMAND:
665 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
666 twoaday 150 EndDialog (dlg, TRUE);
667 werner 36 return FALSE;
668    
669     case WM_COMMAND:
670 twoaday 150 if (HIWORD (wparam) == BN_CLICKED &&
671     LOWORD (wparam) == IDC_ADDSUBKEY_EXPIRE) {
672 werner 36 if (IsDlgButtonChecked (dlg, IDC_ADDSUBKEY_EXPIRE))
673     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
674     else
675     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), TRUE);
676     }
677 twoaday 150 if (HIWORD (wparam) == LBN_SELCHANGE &&
678     LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {
679 werner 36 index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);
680     if (index == 0)
681     SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);
682     }
683    
684 twoaday 150 switch (LOWORD (wparam)) {
685 werner 36 case IDOK:
686 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
687     assert (keygen);
688     hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
689     switch (listbox_get_cursel (hwnd)) {
690 werner 36 case 0: index = 2; break;
691     case 1: index = 4; break;
692     case 2: index = 5; break;
693     case 3: index = 6; break;
694 twoaday 150 default:
695 twoaday 200 msg_box (dlg, _("Please select one entry."),
696     _("Add Subkey"), MB_ERR);
697 werner 36 return FALSE;
698     }
699     size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
700     if (index == 2 && size != 1024) {
701 twoaday 200 msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
702 twoaday 150 _("Add Subkey"), MB_INFO);
703 werner 36 size = 1024;
704     }
705 twoaday 175
706 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
707     DateTime_GetSystemtime (hwnd, &st);
708 twoaday 175 valid = w32_mktime (&st) - time (NULL);
709     valid /= 86400;
710    
711 werner 36 keygen->bits = size;
712     switch (index) {
713     case 2: keygen->algo = GPGME_PK_DSA; break;
714     case 4: keygen->algo = GPGME_PK_ELG_E; break;
715     case 5: keygen->algo = GPGME_PK_RSA_S; break;
716     case 6: keygen->algo = GPGME_PK_RSA_E; break;
717     }
718     if (valid > 0)
719     keygen->expire = time (NULL) + valid*24*60*60;
720    
721 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
722 werner 36 ke->setCallback (keygen_cb, NULL);
723 twoaday 176 if (ctx->is_protected)
724 twoaday 150 ke->setPassphrase (ctx->pass);
725 twoaday 176 else
726     ke->setNoPassphrase (true);
727 werner 36 keygen_cb_dlg_create ();
728    
729     err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
730 twoaday 150 keygen->fpr = get_subkey_keyid (ctx->keyid);
731 werner 36 keygen_cb_dlg_destroy ();
732     keygen_cb (NULL, NULL, 0, 0, 0); /* flush */
733     if (err)
734     msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
735     else {
736 twoaday 200 msg_box (dlg, _("Subkey successfully added."),
737     _("GnuPG Status"), MB_OK);
738 werner 36 ctx->finished = 1;
739     }
740     delete ke;
741 twoaday 129 EndDialog (dlg, TRUE);
742 werner 36 return TRUE;
743    
744     case IDCANCEL:
745 twoaday 129 EndDialog (dlg, FALSE);
746 werner 36 return FALSE;
747     }
748     break;
749     }
750    
751     return FALSE;
752 twoaday 129 }
753 werner 36
754    
755     BOOL
756     keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
757     {
758 twoaday 176 keyedit_cb_s cb;
759 twoaday 200 keygen_cb_s keygen;
760 werner 36 char *pass = NULL;
761     int cancel = 0;
762    
763     if (!k->key_pair) {
764 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
765     _("Add user ID"), MB_ERR);
766 werner 36 return FALSE;
767     }
768    
769     if (k->is_protected) {
770 twoaday 200 pass = request_passphrase (_("Key Edit"), 1, &cancel);
771 werner 36 if (cancel)
772     return FALSE;
773     }
774 twoaday 200
775     memset (&keygen, 0, sizeof (keygen));
776 werner 36 memset (&cb, 0, sizeof cb);
777 twoaday 200 cb.opaque = &keygen;
778 twoaday 176 cb.is_protected = k->is_protected;
779     cb.pass = pass;
780 werner 36 cb.keyid = k->keyid;
781     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
782     dlg, keyedit_adduid_dlg_proc,
783     (LPARAM)&cb, _("Add user ID"),
784     IDS_WINPT_KEYEDIT_ADDUID);
785 twoaday 200 if (lv != NULL && cb.finished)
786     do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
787 werner 36 if (cb.finished)
788     k->update = 1;
789    
790 twoaday 200 free_if_alloc (keygen.name);
791     free_if_alloc (keygen.email);
792     free_if_alloc (keygen.comment);
793 werner 36 sfree_if_alloc (pass);
794     return TRUE;
795     }
796    
797    
798 twoaday 200 /* Return the keyID of the last subkey. */
799 werner 36 char*
800 twoaday 150 get_subkey_keyid (const char *keyid)
801 werner 36 {
802     gpgme_error_t err;
803 twoaday 150 gpgme_key_t key;
804 werner 36 gpgme_ctx_t ctx;
805 twoaday 150 gpgme_subkey_t subk;
806 twoaday 200 char *kid = NULL;
807 werner 36
808     err = gpgme_new (&ctx);
809     if (err)
810     return NULL;
811     err = gpgme_get_key (ctx, keyid, &key, 0);
812 twoaday 150 gpgme_release (ctx);
813 werner 36 if (err)
814     return NULL;
815 twoaday 150 subk = get_nth_key (key, count_subkeys (key));
816 twoaday 200 if (subk != NULL)
817     kid = strdup (subk->keyid);
818 werner 36 gpgme_key_release (key);
819 twoaday 150 return kid;
820 werner 36 }
821    
822    
823     BOOL
824     keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
825     {
826 twoaday 176 keyedit_cb_s cb;
827     keygen_cb_s keygen;
828 werner 36 char *pass = NULL;
829     int cancel = 0;
830    
831     if (!k->key_pair) {
832 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
833     _("Add Subkey"), MB_ERR);
834 werner 36 return FALSE;
835     }
836     if (k->is_protected) {
837     pass = request_passphrase (_("Key Edit"), 1, &cancel);
838     if (cancel)
839     return FALSE;
840     }
841    
842     memset (&keygen, 0, sizeof (keygen));
843     memset (&cb, 0, sizeof (cb));
844     cb.keyid = k->keyid;
845 twoaday 176 cb.is_protected = k->is_protected;
846     cb.pass = pass;
847 werner 36 cb.opaque = &keygen;
848     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,
849     dlg, keyedit_addsubkey_dlg_proc,
850     (LPARAM)&cb, _("Add new Subkey"),
851     IDS_WINPT_KEYEDIT_ADDSUBKEY);
852 twoaday 200 if (lv != NULL && cb.finished)
853     do_add_new_subkey (lv, &keygen, 0);
854 werner 36 if (cb.finished)
855     k->update = 1;
856    
857 twoaday 200 safe_free (keygen.fpr);
858     sfree_if_alloc (pass);
859 werner 36 return cb.finished? TRUE: FALSE;
860     }
861    
862    
863     BOOL
864     keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)
865     {
866     GpgKeyEdit *ke;
867     gpgme_error_t err;
868     struct URL_ctx_s *url;
869 twoaday 200 char *pass = NULL;
870 werner 36
871     url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
872     if (url->cancel == 1) {
873     delete url;
874     return FALSE;
875     }
876    
877     pass = request_passphrase (_("Key Edit"), 1, &url->cancel);
878     if (url->cancel) {
879     delete url;
880     return FALSE;
881     }
882    
883 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
884 twoaday 175 if (k->is_protected)
885     ke->setPassphrase (pass);
886 twoaday 176 else
887     ke->setNoPassphrase (true);
888 twoaday 181 err = ke->setPreferredKeyserver (-1, url->url);
889 werner 36 if (!err)
890     msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
891 twoaday 188 else
892     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
893 werner 36
894     sfree_if_alloc (pass);
895     delete ke;
896 twoaday 181 delete url;
897 werner 36 return err == 0? 0 : WPTERR_GENERAL;
898     }
899    
900    
901     /* Add a photo-ID to the key specified in @k. @dlg is the handle of
902     the calling dialog. */
903     BOOL
904     keyedit_add_photo (winpt_key_t k, HWND dlg)
905     {
906 twoaday 200 keyedit_cb_s cb;
907     char *pass = NULL;
908     int cancel;
909    
910 werner 36 if (!k->key_pair) {
911 twoaday 180 msg_box (dlg, _("There is no secret key available!"),
912     _("Add Photo"), MB_ERR);
913 werner 36 return FALSE;
914     }
915 twoaday 200
916     memset (&cb, 0, sizeof (cb));
917     if (k->is_protected) {
918     pass = request_passphrase (_("Key Edit"), 1, &cancel);
919     if (cancel)
920     return FALSE;
921     }
922     cb.pass = pass;
923     cb.keyid = k->keyid;
924    
925 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
926 twoaday 200 keyedit_addphoto_dlg_proc, (LPARAM)&cb);
927    
928     if (cb.finished)
929     k->update = 1;
930     sfree_if_alloc (pass);
931 werner 36 return TRUE;
932     }
933    
934    
935     BOOL
936     keyedit_add_revoker (winpt_key_t k, HWND dlg)
937     {
938 twoaday 200 keyedit_cb_s cb;
939     char *pass = NULL;
940     int cancel;
941    
942 twoaday 129 if (!k->key_pair) {
943     msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
944 werner 36 return FALSE;
945     }
946 twoaday 200
947     if (k->is_protected) {
948     pass = request_passphrase (_("Key Edit"), 1, &cancel);
949     if (cancel)
950     return FALSE;
951     }
952    
953     memset (&cb, 0, sizeof (cb));
954     cb.is_protected = k->is_protected;
955     cb.keyid = k->keyid;
956     cb.pass = pass;
957 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
958 twoaday 200 keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
959    
960     if (cb.finished)
961     k->update = 1;
962     sfree_if_alloc (pass);
963 werner 36 return TRUE;
964 twoaday 129 }
965 werner 36
966    
967 twoaday 165 /* Change ownertrust of the given key @key.
968     Return TRUE if the ownertrust was changed. */
969     BOOL
970     keyedit_change_ownertrust (winpt_key_t key, HWND dlg)
971     {
972     int rc;
973    
974     rc = dialog_box_param (glob_hinst,
975     (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
976     dlg, keyedit_ownertrust_dlg_proc,
977     (LPARAM)key, _("Change Ownertrust"),
978     IDS_WINPT_KEYEDIT_OWNERTRUST);
979 twoaday 170 if (rc == TRUE) {
980     msg_box (dlg, _("Key status changed."), _("Key Edit"), MB_OK);
981 twoaday 165 key->update = 1;
982 twoaday 170 }
983 twoaday 165 return rc;
984     }
985    
986    
987 twoaday 180 /* Check if the given key is supposed to have IDEA
988     for secret key protection. */
989 werner 36 static int
990 twoaday 180 is_idea_protect_algo (const char *keyid)
991 werner 36 {
992     winpt_key_s k;
993     const unsigned char *sym_prefs;
994     size_t n;
995    
996     memset (&k, 0, sizeof (k));
997     if (winpt_get_pubkey (keyid, &k))
998 twoaday 180 BUG (0);
999 werner 36 sym_prefs = k.ext->sym_prefs;
1000 twoaday 180 if (!k.is_v3)
1001     return 0;
1002 werner 36 if (!sym_prefs)
1003     return 1; /* assume that only v3 keys have no symmetric cipher preferences
1004     and thus IDEA is explicit. */
1005     for (n = 0; sym_prefs[n]; n++)
1006     ;
1007     if ((n == 0 || n == 1) && *sym_prefs == 0x01)
1008     return 1;
1009     return 0;
1010 twoaday 180 }
1011 werner 36
1012    
1013     BOOL
1014 twoaday 129 keyedit_change_passwd (winpt_key_t k, HWND dlg)
1015 werner 36 {
1016 twoaday 200 gpgme_error_t err;
1017 werner 36 GpgKeyEdit *ke;
1018 twoaday 129 char *old_pass = NULL;
1019     char *new_pass = NULL;
1020 werner 36 int cancel = 0;
1021    
1022 twoaday 175 if (!k->key_pair) {
1023     msg_box (dlg, _("There is no secret key available!"),
1024     _("Key Edit"), MB_ERR);
1025 werner 36 return FALSE;
1026     }
1027    
1028 twoaday 180 if (!idea_available && is_idea_protect_algo (k->keyid)) {
1029     msg_box (dlg, _("Cannot change passphrase because the key\n"
1030     "is protected with the IDEA encryption algorithm."),
1031     _("Key Edit"), MB_ERR);
1032 werner 36 return FALSE;
1033     }
1034    
1035 twoaday 129 if (k->is_protected) {
1036     old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);
1037 twoaday 128 if (cancel)
1038 werner 36 return FALSE;
1039     }
1040 twoaday 129 new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);
1041     if (cancel) {
1042     free_if_alloc (old_pass);
1043 werner 36 return FALSE;
1044     }
1045    
1046 twoaday 129 if (is_8bit_string (new_pass)) {
1047     msg_box (dlg, _("The passphrase contains 8-bit characters.\n"
1048 werner 36 "It is not suggested to use charset specific characters."),
1049 twoaday 129 _("Key Edit"), MB_ERR);
1050     free_if_alloc (old_pass);
1051     free_if_alloc (new_pass);
1052 werner 36 return FALSE;
1053     }
1054    
1055 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1056 werner 36 ke->setPassphrase (k->is_protected? old_pass : NULL);
1057 twoaday 200 err = ke->changePassphrase (new_pass, 0);
1058     if (err)
1059     msg_box (dlg, gpgme_strerror (err), _("Change Passwd"), MB_ERR);
1060 werner 36 else
1061     msg_box (dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK);
1062     sfree_if_alloc (old_pass);
1063     sfree_if_alloc (new_pass);
1064     delete ke;
1065     return TRUE;
1066     }
1067    
1068    
1069 twoaday 165 /* Initialize sub key list from key @k and return
1070     the new listview control. */
1071 werner 36 listview_ctrl_t
1072 twoaday 165 subkey_list_init (HWND dlg, winpt_key_t k)
1073 werner 36 {
1074     LV_ITEM lvi;
1075     gpgme_key_t key;
1076     gpgme_subkey_t sub;
1077     struct listview_column_s cols[] = {
1078     {0, 80, (char *)_("Description")},
1079     {1, 78, (char *)_("Key ID")},
1080     {2, 66, (char *)_("Creation")},
1081     {3, 66, (char *)_("Expires")},
1082     {4, 64, (char *)_("Status")},
1083     {5, 16, "C"/*ertify*/},
1084     {6, 16, "S"/*ign*/},
1085     {7, 16, "E"/*ncrypt*/},
1086     {8, 16, "A"/*uth*/},
1087     {0, 0, 0}
1088     };
1089     listview_ctrl_t lv;
1090     char buf[256], tmp[128];
1091     const char *t;
1092     int nkeys = 0, rc = 0, i, bits;
1093    
1094 twoaday 200 if (get_pubkey (k->keyid, &key)) {
1095     msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);
1096 werner 36 return NULL;
1097     }
1098 twoaday 133 if (!k->ctx)
1099     k->ctx = key;
1100 werner 36 nkeys = count_subkeys (key);
1101     if( !nkeys ) {
1102 twoaday 165 msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);
1103 werner 36 return NULL;
1104     }
1105    
1106     rc = listview_new( &lv );
1107     if( rc )
1108     BUG( dlg );
1109    
1110     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
1111     for( i = 0; cols[i].fieldname != NULL; i++ )
1112     listview_add_column( lv, &cols[i] );
1113    
1114     for( i = 0; i < nkeys; i++ ) {
1115     listview_add_item( lv, "" );
1116     listview_add_sub_item( lv, 0, 1, "" );
1117     memset( &lvi, 0, sizeof lvi );
1118     lvi.mask = LVIF_PARAM;
1119 twoaday 165 lvi.lParam = (LPARAM)key;
1120 werner 36 if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
1121     return NULL;
1122     }
1123    
1124     listview_set_ext_style( lv );
1125     for( i = 0, sub = key->subkeys; i < nkeys; i++, sub = sub->next ) {
1126     memset( buf, 0, sizeof buf );
1127    
1128     bits = sub->length;
1129     _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
1130     strcat( buf, tmp );
1131    
1132     _snprintf( tmp, sizeof tmp-1, "%s", get_key_pubalgo (sub->pubkey_algo));
1133     strcat( buf, tmp );
1134    
1135     listview_add_sub_item( lv, i, 0, buf );
1136     t = sub->keyid;
1137     if( !t )
1138     t = "DEADBEEFDEADBEEF";
1139     _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
1140     listview_add_sub_item( lv, i, 1, tmp );
1141    
1142     t = get_key_created (sub->timestamp);
1143     if( !t )
1144 werner 116 t = "????" "-??" "-??";
1145 werner 36 listview_add_sub_item( lv, i, 2, t );
1146    
1147     if( sub->expires ) {
1148     t = get_key_created (sub->expires);
1149     listview_add_sub_item( lv, i, 3, t );
1150     }
1151     else
1152     listview_add_sub_item( lv, i, 3, _("Never") );
1153    
1154     if( sub->expired )
1155     t = _("Expired");
1156     else if( sub->revoked )
1157     t = _("Revoked");
1158     else
1159     t = _("OK");
1160     listview_add_sub_item( lv, i, 4, t );
1161    
1162     if (sub->can_certify) t = "*"; else t = "";
1163     listview_add_sub_item (lv, i, 5, t);
1164     if (sub->can_sign) t = "*"; else t = "";
1165     listview_add_sub_item( lv, i, 6, t );
1166     if (sub->can_encrypt) t = "*"; else t = "";
1167     listview_add_sub_item( lv, i, 7, t );
1168     if (sub->can_authenticate) t = "*"; else t = "";
1169     listview_add_sub_item (lv, i, 8, t);
1170     }
1171     return lv;
1172 twoaday 200 }
1173 werner 36
1174    
1175     static listview_ctrl_t
1176     userid_list_init (HWND dlg, winpt_key_t k)
1177     {
1178     listview_ctrl_t lv = NULL;
1179     gpgme_key_t key;
1180     gpgme_key_sig_t ks;
1181 twoaday 207 gpgme_user_id_t u2;
1182     struct native_uid_s *u;
1183 werner 36 int nuids = 0, rc, j, u_attr;
1184     struct listview_column_s cols[] = {
1185     {0, 72, (char *)_("Validity")},
1186     {1, 150, (char *)_("Name")},
1187     {2, 110, (char *)_("Email")},
1188     {3, 76, (char *)_("Creation")},
1189     {0, 0, 0}
1190     };
1191     const char *attr;
1192    
1193 twoaday 129 if (get_pubkey (k->keyid, &key)) {
1194     msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);
1195 werner 36 return NULL;
1196     }
1197    
1198     nuids = count_userids (key);
1199     if (!nuids) {
1200     msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);
1201     return NULL;
1202     }
1203    
1204     rc = listview_new (&lv);
1205 twoaday 129 if (rc)
1206     BUG (dlg);
1207 werner 36 lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
1208     for( j = 0; cols[j].fieldname != NULL; j++ )
1209     listview_add_column( lv, &cols[j] );
1210    
1211     for( j = 0; j < nuids; j++ ) {
1212     listview_add_item( lv, " " );
1213     listview_add_sub_item( lv, 0, 1, " " );
1214     }
1215    
1216     listview_set_ext_style (lv);
1217 twoaday 207 for (j = 0, u2 = key->uids, u=k->ext->uids; j < nuids;
1218     u2=u2->next, u=u->next, j++) {
1219 werner 36 if (u->revoked)
1220     attr = _("Revoked");
1221     else {
1222     u_attr = (int)u->validity;
1223     attr = get_key_trust2 (NULL, u_attr, 0, 0);
1224     }
1225 twoaday 204 listview_add_sub_item (lv, j, 0, (char *)attr);
1226 werner 36 /* XXX: add comment if available */
1227 twoaday 204 listview_add_sub_item (lv, j, 1,
1228     u->name? u->name : _("Invalid user ID"));
1229     if (u->email)
1230     listview_add_sub_item (lv, j, 2, u->email);
1231 werner 36
1232 twoaday 207 ks = get_selfsig (u2, k->keyid, 1);
1233 werner 36 if (ks)
1234     listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));
1235     }
1236     if( !k->key_pair ) {
1237     CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );
1238     CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );
1239     }
1240     return lv;
1241 twoaday 200 }
1242 werner 36
1243    
1244     static void
1245 twoaday 170 do_init_cmdlist (HWND dlg, int is_keypair)
1246     {
1247     const char *s;
1248 werner 36 int i = 0;
1249    
1250 twoaday 170 for (i = 0; (s=cmdlist[i].name); i++) {
1251     if (is_keypair)
1252     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1253     (LPARAM)(char *)s);
1254     else if (!cmdlist[i].need_pair)
1255     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1256     (LPARAM)(char *)s);
1257 werner 36 }
1258 twoaday 170 SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0);
1259     }
1260 werner 36
1261    
1262 twoaday 165 /* Return 1 if the requested command is RFC2440. */
1263 werner 36 static int
1264 twoaday 165 is_cmd_openpgp (int cmdid)
1265 werner 36 {
1266 twoaday 165 switch (cmdid) {
1267 werner 36 case CMD_ADDKEY:
1268     case CMD_ADDPHOTO:
1269     case CMD_ADDREVOKER:
1270 twoaday 170 //case CMD_SETPREF:
1271 werner 36 return 1;
1272     }
1273     return 0;
1274 twoaday 165 }
1275 werner 36
1276    
1277 twoaday 165 /* Display a message box with a short description of the commands. */
1278 werner 36 static void
1279 twoaday 165 do_show_help (HWND dlg)
1280 werner 36 {
1281     char helptext[2048];
1282    
1283 twoaday 165 _snprintf (helptext, sizeof (helptext)-1,
1284 twoaday 170 _(
1285 werner 36 "ADDUID \t\tadd a user ID\r\n"
1286     "ADDPHOTO \t\tadd a photo ID\r\n"
1287     "DELUID \t\tdelete a user ID\r\n"
1288     "ADDKEY \t\tadd a secondard key\r\n"
1289     "DELKEY \t\tdelete a secondary key\r\n"
1290     "ADDREVOKER\t\tadd a revocation key\r\n"
1291     "EXPIRE \t\tchange the expire date\r\n"
1292     "SHOWPREF \t\tlist preferences (verbose)\r\n"
1293 twoaday 170 "SETPREF \t\tset preference list\r\n"
1294 werner 36 "UPDPREF \t\tupdated preferences\r\n"
1295     "PASSWD \t\tchange the passphrase\r\n"
1296     "PRIMARY \t\tflag user ID as primary\r\n"
1297     "TRUST \t\tchange the ownertrust\r\n"
1298     "REVUID \t\trevoke a user ID\r\n"
1299     "REVKEY \t\trevoke a secondary key\r\n"
1300     "DISABLE \t\tdisable a key\r\n"
1301     "ENABLE \t\tenable a key\r\n"
1302 twoaday 170 "SIGN \t\tsign a user-id (exportable)\r\n"
1303 twoaday 195 "LSIGN \t\tsign a user-id (non-exportable)\r\n"
1304     "CLEAN \t\tremove unusable signatures from key\r\n"
1305     ));
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 werner 36 gpg_uid_info_t inf=NULL;
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     _snprintf (buf, sizeof (buf)-1, "%s <%s>",
1720     key->uids->name, key->uids->email);
1721 werner 36 SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1722 twoaday 200 pos = do_find_userid (cb->keyid, key->uids->email, NULL, &inf);
1723 werner 36 if (inf) {
1724     const char *prefs = inf->prefs;
1725     if (prefs && *prefs) {
1726     if (parse_preflist (dlg, prefs) <= 0)
1727     pos = -1;
1728     }
1729     else
1730     pos = -1;
1731     gpg_uid_info_release (inf);
1732     if (pos == -1) {
1733     msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1734     EndDialog (dlg, TRUE);
1735     }
1736     if (inf->flags.mdc)
1737     CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1738     }
1739 twoaday 128 SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1740     SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1741 twoaday 200 SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1742 werner 36 SetWindowText (dlg, _("Key Preferences"));
1743     SetForegroundWindow (dlg);
1744     break;
1745    
1746     case WM_COMMAND:
1747     switch (LOWORD (wparam)) {
1748     case IDOK:
1749     EndDialog (dlg, TRUE);
1750     break;
1751     }
1752     break;
1753     }
1754     return FALSE;
1755     }
1756    
1757    
1758     static int
1759     do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1760     {
1761 twoaday 176 struct keyedit_cb_s cb;
1762 werner 36
1763     if (k->is_v3)
1764     return TRUE;
1765    
1766     if (listview_get_curr_pos (lv) == -1) {
1767     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1768     return FALSE;
1769     }
1770    
1771     memset (&cb, 0, sizeof (cb));
1772 twoaday 200 cb.opaque = k->ctx;
1773     cb.keyid = k->keyid;
1774 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1775     showpref_dlg_proc, (LPARAM)&cb);
1776     return TRUE;
1777     }
1778    
1779    
1780     static int
1781     do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1782     {
1783     gpgme_error_t err;
1784     GpgKeyEdit *ke;
1785 twoaday 160 char email[128], name[128];
1786     char inf[384];
1787 werner 36 int j, id = 0;
1788    
1789     if (!k->key_pair)
1790     return FALSE; /* XXX: see do_editkey_delsubkey */
1791    
1792 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1793     msg_box (dlg, _("Primary user ID can not be deleted!"),
1794     _("Key Edit"), MB_ERR);
1795 werner 36 return FALSE;
1796     }
1797 twoaday 160 if ((j = listview_get_curr_pos (lv)) == -1) {
1798     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1799 werner 36 return FALSE;
1800     }
1801    
1802     /* XXX: add a hint that also all signatures will be deleted? */
1803 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);
1804     _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1805 twoaday 193 "All signatures on this user ID will be also deleted."
1806     "\n\n"
1807 twoaday 160 "Do you really want to delete this user ID?"),
1808     name);
1809     if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1810 werner 36 return FALSE;
1811    
1812 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1813     listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);
1814     id = do_find_userid (k->keyid, email, name, NULL);
1815 werner 36 if (id == -1)
1816     BUG (dlg);
1817    
1818     ke = new GpgKeyEdit (k->keyid);
1819     if (!ke)
1820     BUG (NULL);
1821    
1822     err = ke->delUserid (id);
1823 twoaday 160 if (err)
1824     msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);
1825 werner 36 else {
1826 twoaday 160 listview_del_item (lv, j);
1827 werner 36 k->update = 1;
1828 twoaday 160 status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1829 werner 36 }
1830     delete ke;
1831     return err? FALSE : TRUE;
1832 twoaday 193 }
1833 werner 36
1834    
1835 twoaday 193 /* Subclass routine for the subkey listview control to allow shortcuts. */
1836 werner 36 static BOOL CALLBACK
1837 twoaday 193 subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1838 werner 36 {
1839 twoaday 193 int virt_key = 0;
1840     winpt_key_t key;
1841    
1842     switch (msg) {
1843 werner 36 case WM_KEYUP:
1844 twoaday 193 virt_key = (int)wparam;
1845     key = (winpt_key_t)keyedit_subkey_proc.opaque;
1846     if (!key || !key->key_pair)
1847     break;
1848    
1849     switch (virt_key) {
1850 werner 36 case VK_DELETE:
1851 twoaday 193 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1852     CB_SETCURSEL, CMD_DELKEY, 0);
1853     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1854 werner 36 break;
1855    
1856     case VK_INSERT:
1857 twoaday 200 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1858     CB_SETCURSEL, CMD_ADDKEY, 0);
1859     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1860 werner 36 break;
1861     }
1862     }
1863 twoaday 193 return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1864     }
1865 werner 36
1866    
1867     static BOOL CALLBACK
1868     uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1869     {
1870 twoaday 193 int virt_key = 0;
1871     winpt_key_t key;
1872    
1873     switch (msg) {
1874 werner 36 case WM_KEYUP:
1875 twoaday 193 virt_key = (int)wparam;
1876     key = (winpt_key_t)keyedit_uid_proc.opaque;
1877     if (!key || !key->key_pair)
1878     break;
1879    
1880 werner 36 switch (virt_key) {
1881     case VK_DELETE:
1882     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1883     CB_SETCURSEL, CMD_DELUID, 0);
1884     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1885     break;
1886    
1887     case VK_INSERT:
1888     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1889     CB_SETCURSEL, CMD_ADDUID, 0);
1890     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1891     break;
1892     }
1893     }
1894 twoaday 193 return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1895     }
1896 werner 36
1897    
1898 twoaday 193 /* Enable the key @k when @enable is 1, disable it otherwise. */
1899 twoaday 165 static void
1900 twoaday 193 do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1901     listview_ctrl_t lv, int enable)
1902 twoaday 165 {
1903     km_enable_disable_key (lv, dlg, 0, enable);
1904     k->update = 1;
1905     }
1906    
1907    
1908 twoaday 170 /* Return default secret key. */
1909     static gpgme_key_t
1910     get_default_key (void)
1911     {
1912     gpgme_key_t def_sk;
1913     char *keyid = get_gnupg_default_key ();
1914    
1915     get_seckey (keyid, &def_sk);
1916     free_if_alloc (keyid);
1917     return def_sk;
1918     }
1919    
1920    
1921 twoaday 195
1922     static void
1923     do_editkey_clean (winpt_key_t k, HWND dlg)
1924     {
1925     gpgme_error_t err;
1926     GpgKeyEdit *ke;
1927    
1928 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1929 twoaday 195 err = ke->cleanKey ();
1930     if (err)
1931 twoaday 197 msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1932     else {
1933 twoaday 195 msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1934 twoaday 197 k->update = 1;
1935     }
1936 twoaday 195 delete ke;
1937     }
1938    
1939    
1940 twoaday 193 /* Start the dialog to list and display the status of all
1941     signatures for this key. */
1942 twoaday 175 static void
1943     do_editkey_check (winpt_key_t k, HWND dlg)
1944     {
1945 twoaday 176 if (!k->ctx)
1946     get_pubkey (k->keyid, &k->ctx);
1947     if (!k->uid && k->ctx)
1948     k->uid = k->ctx->uids->uid;
1949 twoaday 175 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYSIG_TREE, dlg,
1950 twoaday 176 sigtree_dlg_proc, (LPARAM)k);
1951 twoaday 175 }
1952    
1953    
1954 twoaday 170 static int
1955     do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1956     {
1957     gpgme_error_t err;
1958     GpgKeyEdit *ke;
1959     char *pass = NULL;
1960     char email[64], name[128];
1961     int uid_index;
1962     int cancel = 0;
1963    
1964     uid_index = listview_get_curr_pos (lv);
1965     if (uid_index == -1) {
1966     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1967     return FALSE;
1968     }
1969     if (mode == CMD_SIGN) {
1970     cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
1971     _("Key Edit"), MB_QUEST_ASK);
1972     if (cancel == IDNO)
1973     return FALSE;
1974     }
1975    
1976     listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
1977     listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
1978     uid_index = do_find_userid (k->keyid, email, name, NULL);
1979     if (k->is_protected) {
1980     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1981     if (cancel)
1982     return FALSE;
1983     }
1984 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1985 twoaday 175 if (k->is_protected)
1986     ke->setPassphrase (pass);
1987 twoaday 176 else
1988     ke->setNoPassphrase (true);
1989 twoaday 170 ke->setLocalUser (get_default_key ());
1990     err = ke->signUserid (uid_index,
1991     mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
1992     0, NULL);
1993     if (!err) {
1994     msg_box (dlg, _("Key successfully signed."), _("Key Edit"), MB_OK);
1995     k->update = 1;
1996     }
1997     else
1998     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1999     delete ke;
2000     sfree_if_alloc (pass);
2001     return !err? TRUE : FALSE;
2002     }
2003    
2004    
2005     static int
2006     lookup_cmd (HWND dlg)
2007     {
2008     char buf[64];
2009     int i;
2010    
2011     i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
2012     if (i == LB_ERR)
2013     return LB_ERR;
2014     GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);
2015     for (i=0; cmdlist[i].name != NULL; i++) {
2016     if (!strcmp (buf, cmdlist[i].name))
2017     return cmdlist[i].id;
2018     }
2019     return LB_ERR;
2020     }
2021    
2022 twoaday 193
2023 twoaday 133 /* Dialog box procedure for the edit key dialog. */
2024 werner 36 BOOL CALLBACK
2025     keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2026     {
2027     static winpt_key_t k;
2028     static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2029 twoaday 165 int cmd;
2030 werner 36 HWND item;
2031    
2032 twoaday 193 switch (msg) {
2033 werner 36 case WM_INITDIALOG:
2034     k = (winpt_key_t)lparam;
2035     if (!k)
2036     BUG (NULL);
2037 twoaday 170 do_init_cmdlist (dlg, k->key_pair);
2038 werner 36 lvsub = subkey_list_init (dlg, k);
2039 twoaday 193 if (!lvsub)
2040     BUG (0);
2041 werner 36 lvuid = userid_list_init (dlg, k);
2042 twoaday 193 if (!lvuid)
2043     BUG (0);
2044     item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2045     keyedit_subkey_proc.opaque = (void*)k;
2046 werner 36 keyedit_subkey_proc.dlg = dlg;
2047     keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2048 twoaday 193 keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2049     if (keyedit_subkey_proc.old) {
2050     if( !SetWindowLong (item, GWL_WNDPROC,
2051     (LONG)keyedit_subkey_proc.current)) {
2052     msg_box (dlg, _("Could not set subkey window procedure."),
2053     _("Key Edit"), MB_ERR);
2054     BUG (0);
2055 werner 36 }
2056     }
2057 twoaday 193 item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2058     keyedit_uid_proc.opaque = (void*)k;
2059 werner 36 keyedit_uid_proc.dlg = dlg;
2060     keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2061 twoaday 193 keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2062     if (keyedit_uid_proc.old) {
2063     if (!SetWindowLong (item, GWL_WNDPROC,
2064     (LONG)keyedit_uid_proc.current)) {
2065     msg_box (dlg, _("Could not set user ID window procedure."),
2066     _("Key Edit"), MB_ERR);
2067     BUG (0);
2068 werner 36 }
2069     }
2070 twoaday 170 if (k->ctx->revoked) {
2071 werner 36 EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
2072     EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
2073     }
2074     SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2075 twoaday 117 SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2076 twoaday 88 SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2077     SetWindowText (dlg, _("Key Edit"));
2078 twoaday 170 SetForegroundWindow (dlg);
2079     center_window (dlg, NULL);
2080 werner 36 return TRUE;
2081    
2082     case WM_DESTROY:
2083 twoaday 193 if (lvsub) {
2084     listview_release (lvsub);
2085 werner 36 lvsub = NULL;
2086     }
2087 twoaday 193 if (lvuid) {
2088     listview_release (lvuid);
2089 werner 36 lvuid = NULL;
2090     }
2091     break;
2092    
2093     case WM_NOTIFY:
2094     NMHDR * notify;
2095     notify = (NMHDR *)lparam;
2096     if (notify && notify->code == NM_DBLCLK &&
2097     notify->idFrom == IDC_KEYEDIT_UIDLIST)
2098     do_editkey_showpref (k, dlg, lvuid);
2099     break;
2100    
2101     case WM_COMMAND:
2102     switch( LOWORD( wparam ) ) {
2103     case IDOK:
2104 twoaday 170 cmd = lookup_cmd (dlg);
2105 werner 36 if (cmd == LB_ERR) {
2106     msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
2107     return FALSE;
2108     }
2109     if (k->is_v3 && is_cmd_openpgp (cmd)) {
2110     msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),
2111     _("Key Edit"), MB_ERR);
2112     return FALSE;
2113     }
2114     switch (cmd) {
2115     case CMD_SHOWPREF: do_editkey_showpref (k, dlg, lvuid); break;
2116     case CMD_DELKEY: do_editkey_delkey (k, dlg, lvsub); break;
2117     case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2118     case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2119     case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2120     /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/
2121     case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2122     case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2123     case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
2124     case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
2125     case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
2126     case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
2127     case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
2128 twoaday 165 case CMD_ENABLE: do_editkey_enable_disable (k, dlg, lvsub, 1); break;
2129     case CMD_DISABLE: do_editkey_enable_disable (k, dlg, lvsub, 0); break;
2130 twoaday 175 case CMD_CHECK: do_editkey_check (k, dlg); break;
2131 twoaday 165 case CMD_TRUST: keyedit_change_ownertrust (k, dlg); break;
2132 twoaday 170 case CMD_SIGN:
2133     case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2134     lvuid, cmd);
2135     break;
2136 twoaday 195 case CMD_CLEAN: do_editkey_clean (k, dlg);
2137 werner 36 }
2138     break;
2139    
2140     case IDCANCEL:
2141     EndDialog (dlg, FALSE);
2142     break;
2143    
2144     case IDC_KEYEDIT_HELP:
2145     do_show_help (dlg);
2146     break;
2147     }
2148     break;
2149     }
2150     return FALSE;
2151 twoaday 133 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26