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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 187 - (hide annotations)
Wed Mar 22 11:04:20 2006 UTC (18 years, 11 months ago) by twoaday
File size: 55431 byte(s)
2006-03-21  Timo Schulz  <ts@g10code.de>
 
        * wptUTF8.cpp (native_to_utf8): Use directly W32 API.
        (utf8_to_native): Likewise. Remove cp850 conversion.
        * wptKeyEditDlgs.cpp (do_find_userid): Correct UTF8 handling.
        * wptKeyManager.cpp (km_delete_keys): Do not reset 'with_seckey'
        flag.

Prepare new release...


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26