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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (hide annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 56034 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


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 190 if (check_email_address (email)) {
549 twoaday 175 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 twoaday 188 else
886     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
887 werner 36
888     sfree_if_alloc (pass);
889     delete ke;
890 twoaday 181 delete url;
891 werner 36 return err == 0? 0 : WPTERR_GENERAL;
892     }
893    
894    
895     /* Add a photo-ID to the key specified in @k. @dlg is the handle of
896     the calling dialog. */
897     BOOL
898     keyedit_add_photo (winpt_key_t k, HWND dlg)
899     {
900     if (!k->key_pair) {
901 twoaday 180 msg_box (dlg, _("There is no secret key available!"),
902     _("Add Photo"), MB_ERR);
903 werner 36 return FALSE;
904     }
905     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
906     keyedit_addphoto_dlg_proc, (LPARAM)k);
907     return TRUE;
908     }
909    
910    
911     BOOL
912     keyedit_add_revoker (winpt_key_t k, HWND dlg)
913     {
914 twoaday 129 if (!k->key_pair) {
915     msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
916 werner 36 return FALSE;
917     }
918     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
919     keyedit_addrevoker_dlg_proc, (LPARAM)k);
920     return TRUE;
921 twoaday 129 }
922 werner 36
923    
924 twoaday 165 /* Change ownertrust of the given key @key.
925     Return TRUE if the ownertrust was changed. */
926     BOOL
927     keyedit_change_ownertrust (winpt_key_t key, HWND dlg)
928     {
929     int rc;
930    
931     rc = dialog_box_param (glob_hinst,
932     (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
933     dlg, keyedit_ownertrust_dlg_proc,
934     (LPARAM)key, _("Change Ownertrust"),
935     IDS_WINPT_KEYEDIT_OWNERTRUST);
936 twoaday 170 if (rc == TRUE) {
937     msg_box (dlg, _("Key status changed."), _("Key Edit"), MB_OK);
938 twoaday 165 key->update = 1;
939 twoaday 170 }
940 twoaday 165 return rc;
941     }
942    
943    
944 twoaday 180 /* Check if the given key is supposed to have IDEA
945     for secret key protection. */
946 werner 36 static int
947 twoaday 180 is_idea_protect_algo (const char *keyid)
948 werner 36 {
949     winpt_key_s k;
950     const unsigned char *sym_prefs;
951     size_t n;
952    
953     memset (&k, 0, sizeof (k));
954     if (winpt_get_pubkey (keyid, &k))
955 twoaday 180 BUG (0);
956 werner 36 sym_prefs = k.ext->sym_prefs;
957 twoaday 180 if (!k.is_v3)
958     return 0;
959 werner 36 if (!sym_prefs)
960     return 1; /* assume that only v3 keys have no symmetric cipher preferences
961     and thus IDEA is explicit. */
962     for (n = 0; sym_prefs[n]; n++)
963     ;
964     if ((n == 0 || n == 1) && *sym_prefs == 0x01)
965     return 1;
966     return 0;
967 twoaday 180 }
968 werner 36
969    
970     BOOL
971 twoaday 129 keyedit_change_passwd (winpt_key_t k, HWND dlg)
972 werner 36 {
973 twoaday 129 gpgme_error_t ec;
974 werner 36 GpgKeyEdit *ke;
975 twoaday 129 char *old_pass = NULL;
976     char *new_pass = NULL;
977 werner 36 int cancel = 0;
978    
979 twoaday 175 if (!k->key_pair) {
980     msg_box (dlg, _("There is no secret key available!"),
981     _("Key Edit"), MB_ERR);
982 werner 36 return FALSE;
983     }
984    
985 twoaday 180 if (!idea_available && is_idea_protect_algo (k->keyid)) {
986     msg_box (dlg, _("Cannot change passphrase because the key\n"
987     "is protected with the IDEA encryption algorithm."),
988     _("Key Edit"), MB_ERR);
989 werner 36 return FALSE;
990     }
991    
992 twoaday 129 if (k->is_protected) {
993     old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);
994 twoaday 128 if (cancel)
995 werner 36 return FALSE;
996     }
997 twoaday 129 new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);
998     if (cancel) {
999     free_if_alloc (old_pass);
1000 werner 36 return FALSE;
1001     }
1002    
1003 twoaday 129 if (is_8bit_string (new_pass)) {
1004     msg_box (dlg, _("The passphrase contains 8-bit characters.\n"
1005 werner 36 "It is not suggested to use charset specific characters."),
1006 twoaday 129 _("Key Edit"), MB_ERR);
1007     free_if_alloc (old_pass);
1008     free_if_alloc (new_pass);
1009 werner 36 return FALSE;
1010     }
1011    
1012     ke = new GpgKeyEdit (k->keyid);
1013     if (!ke)
1014     BUG (NULL);
1015    
1016     ke->setPassphrase (k->is_protected? old_pass : NULL);
1017     ec = ke->changePassphrase (new_pass, 0);
1018     if( ec )
1019     msg_box (dlg, gpgme_strerror (ec), _("Change Passwd"), MB_ERR);
1020     else
1021     msg_box (dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK);
1022     sfree_if_alloc (old_pass);
1023     sfree_if_alloc (new_pass);
1024     delete ke;
1025     return TRUE;
1026     }
1027    
1028    
1029 twoaday 165 /* Initialize sub key list from key @k and return
1030     the new listview control. */
1031 werner 36 listview_ctrl_t
1032 twoaday 165 subkey_list_init (HWND dlg, winpt_key_t k)
1033 werner 36 {
1034     LV_ITEM lvi;
1035     gpgme_key_t key;
1036     gpgme_subkey_t sub;
1037     struct listview_column_s cols[] = {
1038     {0, 80, (char *)_("Description")},
1039     {1, 78, (char *)_("Key ID")},
1040     {2, 66, (char *)_("Creation")},
1041     {3, 66, (char *)_("Expires")},
1042     {4, 64, (char *)_("Status")},
1043     {5, 16, "C"/*ertify*/},
1044     {6, 16, "S"/*ign*/},
1045     {7, 16, "E"/*ncrypt*/},
1046     {8, 16, "A"/*uth*/},
1047     {0, 0, 0}
1048     };
1049     listview_ctrl_t lv;
1050     char buf[256], tmp[128];
1051     const char *t;
1052     int nkeys = 0, rc = 0, i, bits;
1053    
1054     if( get_pubkey( k->keyid, &key ) ) {
1055     msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );
1056     return NULL;
1057     }
1058 twoaday 133 if (!k->ctx)
1059     k->ctx = key;
1060 werner 36 nkeys = count_subkeys (key);
1061     if( !nkeys ) {
1062 twoaday 165 msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);
1063 werner 36 return NULL;
1064     }
1065    
1066     rc = listview_new( &lv );
1067     if( rc )
1068     BUG( dlg );
1069    
1070     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
1071     for( i = 0; cols[i].fieldname != NULL; i++ )
1072     listview_add_column( lv, &cols[i] );
1073    
1074     for( i = 0; i < nkeys; i++ ) {
1075     listview_add_item( lv, "" );
1076     listview_add_sub_item( lv, 0, 1, "" );
1077     memset( &lvi, 0, sizeof lvi );
1078     lvi.mask = LVIF_PARAM;
1079 twoaday 165 lvi.lParam = (LPARAM)key;
1080 werner 36 if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
1081     return NULL;
1082     }
1083    
1084     listview_set_ext_style( lv );
1085     for( i = 0, sub = key->subkeys; i < nkeys; i++, sub = sub->next ) {
1086     memset( buf, 0, sizeof buf );
1087    
1088     bits = sub->length;
1089     _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
1090     strcat( buf, tmp );
1091    
1092     _snprintf( tmp, sizeof tmp-1, "%s", get_key_pubalgo (sub->pubkey_algo));
1093     strcat( buf, tmp );
1094    
1095     listview_add_sub_item( lv, i, 0, buf );
1096     t = sub->keyid;
1097     if( !t )
1098     t = "DEADBEEFDEADBEEF";
1099     _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
1100     listview_add_sub_item( lv, i, 1, tmp );
1101    
1102     t = get_key_created (sub->timestamp);
1103     if( !t )
1104 werner 116 t = "????" "-??" "-??";
1105 werner 36 listview_add_sub_item( lv, i, 2, t );
1106    
1107     if( sub->expires ) {
1108     t = get_key_created (sub->expires);
1109     listview_add_sub_item( lv, i, 3, t );
1110     }
1111     else
1112     listview_add_sub_item( lv, i, 3, _("Never") );
1113    
1114     if( sub->expired )
1115     t = _("Expired");
1116     else if( sub->revoked )
1117     t = _("Revoked");
1118     else
1119     t = _("OK");
1120     listview_add_sub_item( lv, i, 4, t );
1121    
1122     if (sub->can_certify) t = "*"; else t = "";
1123     listview_add_sub_item (lv, i, 5, t);
1124     if (sub->can_sign) t = "*"; else t = "";
1125     listview_add_sub_item( lv, i, 6, t );
1126     if (sub->can_encrypt) t = "*"; else t = "";
1127     listview_add_sub_item( lv, i, 7, t );
1128     if (sub->can_authenticate) t = "*"; else t = "";
1129     listview_add_sub_item (lv, i, 8, t);
1130     }
1131     return lv;
1132     } /* subkey_list_init */
1133    
1134    
1135     static listview_ctrl_t
1136     userid_list_init (HWND dlg, winpt_key_t k)
1137     {
1138     listview_ctrl_t lv = NULL;
1139     gpgme_key_t key;
1140     gpgme_key_sig_t ks;
1141     gpgme_user_id_t u;
1142     int nuids = 0, rc, j, u_attr;
1143     struct listview_column_s cols[] = {
1144     {0, 72, (char *)_("Validity")},
1145     {1, 150, (char *)_("Name")},
1146     {2, 110, (char *)_("Email")},
1147     {3, 76, (char *)_("Creation")},
1148     {0, 0, 0}
1149     };
1150     const char *attr;
1151    
1152 twoaday 129 if (get_pubkey (k->keyid, &key)) {
1153     msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);
1154 werner 36 return NULL;
1155     }
1156    
1157     nuids = count_userids (key);
1158     if (!nuids) {
1159     msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);
1160     return NULL;
1161     }
1162    
1163     rc = listview_new (&lv);
1164 twoaday 129 if (rc)
1165     BUG (dlg);
1166 werner 36 lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
1167     for( j = 0; cols[j].fieldname != NULL; j++ )
1168     listview_add_column( lv, &cols[j] );
1169    
1170     for( j = 0; j < nuids; j++ ) {
1171     listview_add_item( lv, " " );
1172     listview_add_sub_item( lv, 0, 1, " " );
1173     }
1174    
1175     listview_set_ext_style (lv);
1176     for (j = 0, u=key->uids; j < nuids; u=u->next, j++) {
1177     if (u->revoked)
1178     attr = _("Revoked");
1179     else {
1180     u_attr = (int)u->validity;
1181     attr = get_key_trust2 (NULL, u_attr, 0, 0);
1182     }
1183     listview_add_sub_item( lv, j, 0, (char *)attr );
1184    
1185     /* XXX: add comment if available */
1186     attr = u->name;
1187     if (attr) {
1188 twoaday 187 char *uid = utf8_to_native (attr);
1189 werner 36 if (uid) {
1190 twoaday 160 listview_add_sub_item (lv, j, 1, uid);
1191     free (uid);
1192 werner 36 }
1193     }
1194     else
1195 twoaday 160 listview_add_sub_item (lv, j, 1, _("Invalid user ID"));
1196 werner 36 attr = u->email;
1197     if (attr)
1198     listview_add_sub_item (lv, j, 2, attr);
1199    
1200 twoaday 129 ks = get_selfsig (u, k->keyid, 1);
1201 werner 36 if (ks)
1202     listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));
1203     }
1204     if( !k->key_pair ) {
1205     CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );
1206     CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );
1207     }
1208     return lv;
1209     } /* userid_list_init */
1210    
1211    
1212     static void
1213 twoaday 170 do_init_cmdlist (HWND dlg, int is_keypair)
1214     {
1215     const char *s;
1216 werner 36 int i = 0;
1217    
1218 twoaday 170 for (i = 0; (s=cmdlist[i].name); i++) {
1219     if (is_keypair)
1220     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1221     (LPARAM)(char *)s);
1222     else if (!cmdlist[i].need_pair)
1223     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1224     (LPARAM)(char *)s);
1225 werner 36 }
1226 twoaday 170 SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0);
1227     }
1228 werner 36
1229    
1230 twoaday 165 /* Return 1 if the requested command is RFC2440. */
1231 werner 36 static int
1232 twoaday 165 is_cmd_openpgp (int cmdid)
1233 werner 36 {
1234 twoaday 165 switch (cmdid) {
1235 werner 36 case CMD_ADDKEY:
1236     case CMD_ADDPHOTO:
1237     case CMD_ADDREVOKER:
1238 twoaday 170 //case CMD_SETPREF:
1239 werner 36 return 1;
1240     }
1241     return 0;
1242 twoaday 165 }
1243 werner 36
1244    
1245 twoaday 165 /* Display a message box with a short description of the commands. */
1246 werner 36 static void
1247 twoaday 165 do_show_help (HWND dlg)
1248 werner 36 {
1249     char helptext[2048];
1250    
1251 twoaday 165 _snprintf (helptext, sizeof (helptext)-1,
1252 twoaday 170 _(
1253 werner 36 "ADDUID \t\tadd a user ID\r\n"
1254     "ADDPHOTO \t\tadd a photo ID\r\n"
1255     "DELUID \t\tdelete a user ID\r\n"
1256     "ADDKEY \t\tadd a secondard key\r\n"
1257     "DELKEY \t\tdelete a secondary key\r\n"
1258     "ADDREVOKER\t\tadd a revocation key\r\n"
1259     "EXPIRE \t\tchange the expire date\r\n"
1260     "SHOWPREF \t\tlist preferences (verbose)\r\n"
1261 twoaday 170 "SETPREF \t\tset preference list\r\n"
1262 werner 36 "UPDPREF \t\tupdated preferences\r\n"
1263     "PASSWD \t\tchange the passphrase\r\n"
1264     "PRIMARY \t\tflag user ID as primary\r\n"
1265     "TRUST \t\tchange the ownertrust\r\n"
1266     "REVUID \t\trevoke a user ID\r\n"
1267     "REVKEY \t\trevoke a secondary key\r\n"
1268     "DISABLE \t\tdisable a key\r\n"
1269     "ENABLE \t\tenable a key\r\n"
1270 twoaday 170 "SIGN \t\tsign a user-id (exportable)\r\n"
1271     "LSIGN \t\tsign a user-id (non-exportable)\r\n"));
1272 twoaday 165 msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);
1273     }
1274 werner 36
1275    
1276     static int
1277     do_editkey_delkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1278     {
1279     gpgme_error_t err;
1280     GpgKeyEdit *ke;
1281     int j, id;
1282     char tmp[64];
1283    
1284     if (!k->key_pair)
1285     return FALSE; /* XXX: shall we allow to modify non-secret keys?? */
1286    
1287     if( listview_count_items( lv, 0 ) == 1 ) {
1288     msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1289     return FALSE;
1290     }
1291     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1292     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1293     return FALSE;
1294     }
1295     if( j == 0 ) {
1296     msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );
1297     return FALSE;
1298     }
1299    
1300     listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );
1301     id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,
1302     _("\"Subkey %s.\"\n\n"
1303     "Anything encrypted to the selected subkey will no longer\n"
1304     "be able to be decrypted.\n\n"
1305     "Do you really want to delete this subkey?"), tmp );
1306     if( id == IDNO )
1307     return FALSE;
1308    
1309     ke = new GpgKeyEdit (k->keyid);
1310     if (!ke)
1311     BUG (NULL);
1312     err = ke->delKey (j);
1313     if (err)
1314     msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);
1315     else {
1316     listview_del_item (lv, j);
1317     k->update = 1;
1318     status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));
1319     }
1320     delete ke;
1321     return err? FALSE : TRUE;
1322     } /* do_editkey_delkey */
1323    
1324    
1325 twoaday 175
1326 werner 36 /* Set the expiration date for the selected key in list view @lv.
1327     Return value: TRUE on success. */
1328     static int
1329     do_editkey_expire (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1330     {
1331     gpgme_error_t err;
1332     GpgKeyEdit *ke;
1333     date_s udd = {0};
1334     char buf[256], * pass = NULL;
1335     int j, cancel = 0;
1336    
1337     if (!k->key_pair) {
1338 twoaday 41 msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1339 werner 36 return FALSE;
1340     }
1341 twoaday 41 if ((j = listview_get_curr_pos (lv)) == -1) {
1342 werner 36 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1343     return FALSE;
1344     }
1345 twoaday 41
1346     /* If a key already expired, it is possible the user wants to
1347     set a new expiration date.. */
1348     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof buf -1);
1349     if (!strcmp (buf, _("Expired"))) {
1350     cancel = msg_box (dlg, _("Key already expired.\n\n"
1351     "Do you want to change the expiration date?"),
1352     _("Key Edit"), MB_QUEST_ASK);
1353     if (cancel == IDNO)
1354     return FALSE;
1355     cancel = 0;
1356 werner 36 }
1357 twoaday 41
1358 werner 36 memset (&udd, 0, sizeof udd);
1359     udd.text = _("Key Expiration Date");
1360     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,
1361     date_dlg_proc, (LPARAM)&udd,
1362     _("Key Expiration Date"), IDS_WINPT_DATE);
1363     if (udd.cancel == 1)
1364     return FALSE;
1365     if (!keygen_check_date (&udd.st)) {
1366     msg_box (dlg, _("The date you have chosen lies in the past."),
1367     _("Key Edit"), MB_ERR);
1368     return FALSE;
1369     }
1370     if( k->is_protected ) {
1371 twoaday 41 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1372     if (cancel)
1373 werner 36 return FALSE;
1374     }
1375    
1376     ke = new GpgKeyEdit (k->keyid);
1377     if (!ke)
1378     BUG (NULL);
1379     if (k->is_protected)
1380     ke->setPassphrase (pass);
1381 twoaday 176 else
1382     ke->setNoPassphrase (true);
1383 twoaday 175 err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);
1384 werner 36 if (err)
1385     msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1386     else {
1387     _snprintf (buf, sizeof buf - 1, "%04d-%02d-%02d",
1388     udd.st.wYear, udd.st.wMonth, udd.st.wDay);
1389     listview_add_sub_item (lv, j, SUBK_COL_EXPIRES, buf);
1390     k->update = 1;
1391     msg_box (dlg, _("Subkey expire date successfully set."),
1392     _("GnuPG status"), MB_OK);
1393     }
1394     sfree_if_alloc (pass);
1395     delete ke;
1396     return TRUE;
1397     }
1398    
1399    
1400     /* Revoke the selected key in the list view @lv. @k contains
1401     control information about the global key.
1402     Return value: TRUE on success. */
1403     static int
1404     do_editkey_revoke (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1405     {
1406     gpgme_error_t err;
1407     GpgKeyEdit *ke;
1408     char buf[256];
1409     char *pass = NULL;
1410     int j, cancel = 0;
1411    
1412     if (!k->key_pair) {
1413     msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1414     return FALSE;
1415     }
1416    
1417     if ((j = listview_get_curr_pos (lv)) == -1) {
1418     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1419     return FALSE;
1420     }
1421     else if (listview_count_items (lv, 0) == 1) {
1422     msg_box( dlg, _("No subkeys were found, if you want to revoke the\n"
1423     "whole key, please use the Key Manager command directly.\n\n"
1424     "This command is only available to revoke single subkeys"),
1425     _("Key Edit"), MB_INFO );
1426     return FALSE;
1427     }
1428    
1429     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof (buf)-1);
1430     if (!strcmp (buf, _("Revoked"))) {
1431     msg_box (dlg, _("Key already revoked."), _("Key Edit"), MB_ERR);
1432     return FALSE;
1433     }
1434    
1435     if (k->is_protected) {
1436     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1437     if (cancel)
1438     return FALSE;
1439     }
1440    
1441     ke = new GpgKeyEdit (k->keyid);
1442     if (!ke)
1443     BUG (NULL);
1444     if (k->is_protected)
1445     ke->setPassphrase (pass);
1446 twoaday 176 else
1447     ke->setNoPassphrase (true);
1448 werner 36 err = ke->revokeSubkey (j, 0, NULL);
1449     if (err)
1450     msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);
1451     else {
1452     listview_add_sub_item (lv, j, SUBK_COL_STATUS, _("Revoked"));
1453     k->update = 1;
1454     msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1455     }
1456     sfree_if_alloc (pass);
1457     delete ke;
1458     return TRUE;
1459     }
1460    
1461    
1462     /* Revoked the selected userid in list view @lv.
1463     Return value: TRUE on success. */
1464     int
1465     do_editkey_revuid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1466     {
1467     gpgme_error_t err;
1468     GpgKeyEdit *ke;
1469 twoaday 160 char buf[128], email[128];
1470     char inf[512];
1471     char *pass = NULL;
1472 werner 36 int cancel = 0, id = 0, j;
1473    
1474     if (!k->key_pair) {
1475 twoaday 160 msg_box (dlg, _("There is no secret key available!"),
1476     _("Revoke user ID"), MB_ERR);
1477 werner 36 return FALSE;
1478     }
1479    
1480 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1481     msg_box (dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR);
1482 werner 36 return FALSE;
1483     }
1484    
1485     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1486     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1487     return FALSE;
1488     }
1489    
1490 twoaday 160 listview_get_item_text( lv, j, UID_COL_VALID, buf, sizeof buf - 1);
1491     if (strstr (buf, _("Revoked"))) {
1492     msg_box (dlg, _("This user ID has been already revoked."),
1493     _("Key Edit"), MB_INFO);
1494 werner 36 return FALSE;
1495     }
1496    
1497 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);
1498     _snprintf (inf, sizeof (inf) -1, _("user ID \"%s\".\n\n"
1499     "Do you really want to revoke this user ID?"), buf);
1500     if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1501 werner 36 return FALSE;
1502 twoaday 160 if (k->is_protected) {
1503 werner 36 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1504 twoaday 68 if (cancel)
1505 werner 36 return FALSE;
1506     }
1507 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, sizeof (email)-1);
1508     listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof (buf)-1);
1509     id = do_find_userid (k->keyid, email, buf, NULL);
1510 werner 36 if (id == -1)
1511     BUG (NULL);
1512    
1513     ke = new GpgKeyEdit (k->keyid);
1514     if (!ke)
1515     BUG (NULL);
1516     if (k->is_protected)
1517     ke->setPassphrase (pass);
1518 twoaday 176 else
1519     ke->setNoPassphrase (true);
1520 werner 36 err = ke->revokeUserid (id);
1521     if (err)
1522 twoaday 160 msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);
1523 werner 36 else {
1524     listview_add_sub_item (lv, j, 0, _("Revoked"));
1525     k->update = 1;
1526     status_box (dlg, _("User ID successfully revoked"), _("GnuPG Status"));
1527     }
1528     sfree_if_alloc (pass);
1529     delete ke;
1530     return err? FALSE : TRUE;
1531     }
1532    
1533    
1534     static int
1535     do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1536     {
1537     gpgme_error_t rc;
1538     GpgKeyEdit *ke;
1539     char buf[256], * pass = NULL, * prefs;
1540     int j, id, cancel=0, flags=0;
1541    
1542     if ((j = listview_get_curr_pos (lv)) == -1) {
1543     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1544     return FALSE;
1545     }
1546     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1547 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1548 werner 36 if (id == -1)
1549     BUG (dlg);
1550     if (k->is_protected) {
1551     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1552     if (cancel)
1553     return FALSE;
1554     }
1555    
1556     ke = new GpgKeyEdit (k->keyid);
1557     if (!ke)
1558     BUG (NULL);
1559     if (k->is_protected)
1560     ke->setPassphrase (pass);
1561 twoaday 176 else
1562     ke->setNoPassphrase (true);
1563 werner 36
1564     get_userid_preflist (&prefs, &flags);
1565    
1566     rc = ke->setUseridPreferences (id, prefs);
1567 twoaday 176 if (rc)
1568     msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);
1569 werner 36
1570     sfree_if_alloc (pass);
1571     free_if_alloc (prefs);
1572     delete ke;
1573     return 0;
1574     }
1575    
1576    
1577     static int
1578     do_editkey_primary (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1579     {
1580     gpgme_error_t err;
1581     GpgKeyEdit *ke;
1582     int j, id, cancel=0;
1583     char buf[256], * pass = NULL;
1584    
1585     if (listview_count_items (lv, 0) == 1)
1586     return TRUE;
1587     if ((j = listview_get_curr_pos (lv)) == -1) {
1588     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1589     return FALSE;
1590     }
1591     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1592 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1593 werner 36 if (id == -1)
1594     BUG (dlg);
1595     if (k->is_protected) {
1596     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1597 twoaday 128 if (cancel)
1598 werner 36 return FALSE;
1599     }
1600    
1601     ke = new GpgKeyEdit (k->keyid);
1602     if (k->is_protected)
1603     ke->setPassphrase (pass);
1604 twoaday 176 else
1605     ke->setNoPassphrase (true);
1606 werner 36 err = ke->setPrimaryUserid (id);
1607     if (err)
1608     msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);
1609     else {
1610     k->update = 1;
1611     status_box (dlg, _("User ID successfully flagged"), _("GnuPG Status"));
1612     }
1613    
1614     sfree_if_alloc (pass);
1615     delete ke;
1616     return err? FALSE : TRUE;
1617     }
1618    
1619    
1620 twoaday 123
1621 twoaday 128 #define CIPHER 11
1622     #define HASH 11
1623     #define COMPR 4
1624    
1625 werner 36 static int
1626     parse_preflist (HWND dlg, const char *list)
1627     {
1628 twoaday 123 char buf[128] = {0};
1629     char *p, *pbuf = buf;
1630     const char *ciphers[CIPHER] = {"", "IDEA", "3DES",
1631 twoaday 128 "CAST5", "BLOWFISH", "", "",
1632     "AES", "AES192", "AES256", "TWOFISH"};
1633     const char *hash[HASH] = {"", "MD5", "SHA1", "RMD160", "",
1634     "", "", "", "SHA256", "SHA384", "SHA512"};
1635 twoaday 123 const char *compress[COMPR] = {"", "ZIP", "ZLIB", "BZIP2"};
1636 werner 36 int n=0;
1637    
1638     strncpy (buf, list, 127);
1639     p = strtok (pbuf, " ");
1640     while (p != NULL) {
1641     int algid = atol (p+1);
1642     n++;
1643     switch (*p) {
1644     case 'S':
1645 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_CIPHERS, LB_ADDSTRING, 0,
1646     (LPARAM)(const char*)ciphers[algid % CIPHER]);
1647 werner 36 break;
1648    
1649     case 'H':
1650 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_HASH, LB_ADDSTRING, 0,
1651     (LPARAM)(const char*)hash[algid % HASH]);
1652 werner 36 break;
1653    
1654     case 'Z':
1655 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_ZIP, LB_ADDSTRING, 0,
1656     (LPARAM)(const char*)compress[algid % COMPR]);
1657 werner 36 break;
1658    
1659     default:
1660     n--;
1661     }
1662     p = strtok (NULL, " ");
1663     }
1664     return n;
1665     }
1666    
1667    
1668     /* Dialog box procedure to show the key preferences. */
1669     BOOL CALLBACK
1670     showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1671     {
1672 twoaday 176 static keyedit_cb_t cb = NULL;
1673 werner 36 gpg_uid_info_t inf=NULL;
1674     char buf[128];
1675     int pos;
1676    
1677     switch (msg) {
1678     case WM_INITDIALOG:
1679 twoaday 176 cb = (keyedit_cb_t)lparam;
1680 werner 36 if (cb == NULL)
1681     BUG (dlg);
1682 twoaday 121 pos = listview_get_curr_pos (cb->lv);
1683     listview_get_item_text (cb->lv, pos, 2, buf, DIM (buf)-1);
1684 werner 36 SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1685 twoaday 160 pos = do_find_userid (((winpt_key_t)cb->opaque)->keyid,
1686     buf, NULL, &inf);
1687 werner 36 if (inf) {
1688     const char *prefs = inf->prefs;
1689     if (prefs && *prefs) {
1690     if (parse_preflist (dlg, prefs) <= 0)
1691     pos = -1;
1692     }
1693     else
1694     pos = -1;
1695     gpg_uid_info_release (inf);
1696     if (pos == -1) {
1697     msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1698     EndDialog (dlg, TRUE);
1699     }
1700     if (inf->flags.mdc)
1701     CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1702     }
1703 twoaday 128 SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1704     SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1705 werner 36 SetWindowText (dlg, _("Key Preferences"));
1706     SetForegroundWindow (dlg);
1707     break;
1708    
1709     case WM_COMMAND:
1710     switch (LOWORD (wparam)) {
1711     case IDOK:
1712     EndDialog (dlg, TRUE);
1713     break;
1714     }
1715     break;
1716     }
1717     return FALSE;
1718     }
1719    
1720    
1721     static int
1722     do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1723     {
1724 twoaday 176 struct keyedit_cb_s cb;
1725 werner 36
1726     if (k->is_v3)
1727     return TRUE;
1728    
1729     if (listview_get_curr_pos (lv) == -1) {
1730     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1731     return FALSE;
1732     }
1733    
1734     memset (&cb, 0, sizeof (cb));
1735     cb.lv = lv;
1736     cb.opaque = k;
1737     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1738     showpref_dlg_proc, (LPARAM)&cb);
1739     return TRUE;
1740     }
1741    
1742    
1743     static int
1744     do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1745     {
1746     gpgme_error_t err;
1747     GpgKeyEdit *ke;
1748 twoaday 160 char email[128], name[128];
1749     char inf[384];
1750 werner 36 int j, id = 0;
1751    
1752     if (!k->key_pair)
1753     return FALSE; /* XXX: see do_editkey_delsubkey */
1754    
1755 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1756     msg_box (dlg, _("Primary user ID can not be deleted!"),
1757     _("Key Edit"), MB_ERR);
1758 werner 36 return FALSE;
1759     }
1760 twoaday 160 if ((j = listview_get_curr_pos (lv)) == -1) {
1761     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1762 werner 36 return FALSE;
1763     }
1764    
1765     /* XXX: add a hint that also all signatures will be deleted? */
1766 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);
1767     _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1768 twoaday 193 "All signatures on this user ID will be also deleted."
1769     "\n\n"
1770 twoaday 160 "Do you really want to delete this user ID?"),
1771     name);
1772     if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1773 werner 36 return FALSE;
1774    
1775 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1776     listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);
1777     id = do_find_userid (k->keyid, email, name, NULL);
1778 werner 36 if (id == -1)
1779     BUG (dlg);
1780    
1781     ke = new GpgKeyEdit (k->keyid);
1782     if (!ke)
1783     BUG (NULL);
1784    
1785     err = ke->delUserid (id);
1786 twoaday 160 if (err)
1787     msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);
1788 werner 36 else {
1789 twoaday 160 listview_del_item (lv, j);
1790 werner 36 k->update = 1;
1791 twoaday 160 status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1792 werner 36 }
1793     delete ke;
1794     return err? FALSE : TRUE;
1795 twoaday 193 }
1796 werner 36
1797    
1798 twoaday 193 /* Subclass routine for the subkey listview control to allow shortcuts. */
1799 werner 36 static BOOL CALLBACK
1800 twoaday 193 subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1801 werner 36 {
1802 twoaday 193 int virt_key = 0;
1803     winpt_key_t key;
1804    
1805     switch (msg) {
1806 werner 36 case WM_KEYUP:
1807 twoaday 193 virt_key = (int)wparam;
1808     key = (winpt_key_t)keyedit_subkey_proc.opaque;
1809     if (!key || !key->key_pair)
1810     break;
1811    
1812     switch (virt_key) {
1813 werner 36 case VK_DELETE:
1814 twoaday 193 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1815     CB_SETCURSEL, CMD_DELKEY, 0);
1816     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1817 werner 36 break;
1818    
1819     case VK_INSERT:
1820     SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1821     CB_SETCURSEL, CMD_ADDKEY, 0 );
1822     send_cmd_id( keyedit_subkey_proc.dlg, IDOK );
1823     break;
1824     }
1825     }
1826 twoaday 193 return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1827     }
1828 werner 36
1829    
1830     static BOOL CALLBACK
1831     uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1832     {
1833 twoaday 193 int virt_key = 0;
1834     winpt_key_t key;
1835    
1836     switch (msg) {
1837 werner 36 case WM_KEYUP:
1838 twoaday 193 virt_key = (int)wparam;
1839     key = (winpt_key_t)keyedit_uid_proc.opaque;
1840     if (!key || !key->key_pair)
1841     break;
1842    
1843 werner 36 switch (virt_key) {
1844     case VK_DELETE:
1845     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1846     CB_SETCURSEL, CMD_DELUID, 0);
1847     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1848     break;
1849    
1850     case VK_INSERT:
1851     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1852     CB_SETCURSEL, CMD_ADDUID, 0);
1853     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1854     break;
1855     }
1856     }
1857 twoaday 193 return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1858     }
1859 werner 36
1860    
1861 twoaday 193 /* Enable the key @k when @enable is 1, disable it otherwise. */
1862 twoaday 165 static void
1863 twoaday 193 do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1864     listview_ctrl_t lv, int enable)
1865 twoaday 165 {
1866     km_enable_disable_key (lv, dlg, 0, enable);
1867     k->update = 1;
1868     }
1869    
1870    
1871 twoaday 170 /* Return default secret key. */
1872     static gpgme_key_t
1873     get_default_key (void)
1874     {
1875     gpgme_key_t def_sk;
1876     char *keyid = get_gnupg_default_key ();
1877    
1878     get_seckey (keyid, &def_sk);
1879     free_if_alloc (keyid);
1880     return def_sk;
1881     }
1882    
1883    
1884 twoaday 193 /* Start the dialog to list and display the status of all
1885     signatures for this key. */
1886 twoaday 175 static void
1887     do_editkey_check (winpt_key_t k, HWND dlg)
1888     {
1889 twoaday 176 if (!k->ctx)
1890     get_pubkey (k->keyid, &k->ctx);
1891     if (!k->uid && k->ctx)
1892     k->uid = k->ctx->uids->uid;
1893 twoaday 175 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYSIG_TREE, dlg,
1894 twoaday 176 sigtree_dlg_proc, (LPARAM)k);
1895 twoaday 175 }
1896    
1897    
1898 twoaday 170 static int
1899     do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1900     {
1901     gpgme_error_t err;
1902     GpgKeyEdit *ke;
1903     char *pass = NULL;
1904     char email[64], name[128];
1905     int uid_index;
1906     int cancel = 0;
1907    
1908     uid_index = listview_get_curr_pos (lv);
1909     if (uid_index == -1) {
1910     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1911     return FALSE;
1912     }
1913     if (mode == CMD_SIGN) {
1914     cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
1915     _("Key Edit"), MB_QUEST_ASK);
1916     if (cancel == IDNO)
1917     return FALSE;
1918     }
1919    
1920     listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
1921     listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
1922     uid_index = do_find_userid (k->keyid, email, name, NULL);
1923     if (k->is_protected) {
1924     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1925     if (cancel)
1926     return FALSE;
1927     }
1928     ke = new GpgKeyEdit (k->keyid);
1929 twoaday 175 if (k->is_protected)
1930     ke->setPassphrase (pass);
1931 twoaday 176 else
1932     ke->setNoPassphrase (true);
1933 twoaday 170 ke->setLocalUser (get_default_key ());
1934     err = ke->signUserid (uid_index,
1935     mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
1936     0, NULL);
1937     if (!err) {
1938     msg_box (dlg, _("Key successfully signed."), _("Key Edit"), MB_OK);
1939     k->update = 1;
1940     }
1941     else
1942     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1943     delete ke;
1944     sfree_if_alloc (pass);
1945     return !err? TRUE : FALSE;
1946     }
1947    
1948    
1949     static int
1950     lookup_cmd (HWND dlg)
1951     {
1952     char buf[64];
1953     int i;
1954    
1955     i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
1956     if (i == LB_ERR)
1957     return LB_ERR;
1958     GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);
1959     for (i=0; cmdlist[i].name != NULL; i++) {
1960     if (!strcmp (buf, cmdlist[i].name))
1961     return cmdlist[i].id;
1962     }
1963     return LB_ERR;
1964     }
1965    
1966 twoaday 193
1967 twoaday 133 /* Dialog box procedure for the edit key dialog. */
1968 werner 36 BOOL CALLBACK
1969     keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1970     {
1971     static winpt_key_t k;
1972     static listview_ctrl_t lvsub = NULL, lvuid = NULL;
1973 twoaday 165 int cmd;
1974 werner 36 HWND item;
1975    
1976 twoaday 193 switch (msg) {
1977 werner 36 case WM_INITDIALOG:
1978     k = (winpt_key_t)lparam;
1979     if (!k)
1980     BUG (NULL);
1981 twoaday 170 do_init_cmdlist (dlg, k->key_pair);
1982 werner 36 lvsub = subkey_list_init (dlg, k);
1983 twoaday 193 if (!lvsub)
1984     BUG (0);
1985 werner 36 lvuid = userid_list_init (dlg, k);
1986 twoaday 193 if (!lvuid)
1987     BUG (0);
1988     item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
1989     keyedit_subkey_proc.opaque = (void*)k;
1990 werner 36 keyedit_subkey_proc.dlg = dlg;
1991     keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
1992 twoaday 193 keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
1993     if (keyedit_subkey_proc.old) {
1994     if( !SetWindowLong (item, GWL_WNDPROC,
1995     (LONG)keyedit_subkey_proc.current)) {
1996     msg_box (dlg, _("Could not set subkey window procedure."),
1997     _("Key Edit"), MB_ERR);
1998     BUG (0);
1999 werner 36 }
2000     }
2001 twoaday 193 item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2002     keyedit_uid_proc.opaque = (void*)k;
2003 werner 36 keyedit_uid_proc.dlg = dlg;
2004     keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2005 twoaday 193 keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2006     if (keyedit_uid_proc.old) {
2007     if (!SetWindowLong (item, GWL_WNDPROC,
2008     (LONG)keyedit_uid_proc.current)) {
2009     msg_box (dlg, _("Could not set user ID window procedure."),
2010     _("Key Edit"), MB_ERR);
2011     BUG (0);
2012 werner 36 }
2013     }
2014 twoaday 170 if (k->ctx->revoked) {
2015 werner 36 EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
2016     EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
2017     }
2018     SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2019 twoaday 117 SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2020 twoaday 88 SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2021     SetWindowText (dlg, _("Key Edit"));
2022 twoaday 170 SetForegroundWindow (dlg);
2023     center_window (dlg, NULL);
2024 werner 36 return TRUE;
2025    
2026     case WM_DESTROY:
2027 twoaday 193 if (lvsub) {
2028     listview_release (lvsub);
2029 werner 36 lvsub = NULL;
2030     }
2031 twoaday 193 if (lvuid) {
2032     listview_release (lvuid);
2033 werner 36 lvuid = NULL;
2034     }
2035     break;
2036    
2037     case WM_NOTIFY:
2038     NMHDR * notify;
2039     notify = (NMHDR *)lparam;
2040     if (notify && notify->code == NM_DBLCLK &&
2041     notify->idFrom == IDC_KEYEDIT_UIDLIST)
2042     do_editkey_showpref (k, dlg, lvuid);
2043     break;
2044    
2045     case WM_COMMAND:
2046     switch( LOWORD( wparam ) ) {
2047     case IDOK:
2048 twoaday 170 cmd = lookup_cmd (dlg);
2049 werner 36 if (cmd == LB_ERR) {
2050     msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
2051     return FALSE;
2052     }
2053     if (k->is_v3 && is_cmd_openpgp (cmd)) {
2054     msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),
2055     _("Key Edit"), MB_ERR);
2056     return FALSE;
2057     }
2058     switch (cmd) {
2059     case CMD_SHOWPREF: do_editkey_showpref (k, dlg, lvuid); break;
2060     case CMD_DELKEY: do_editkey_delkey (k, dlg, lvsub); break;
2061     case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2062     case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2063     case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2064     /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/
2065     case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2066     case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2067     case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
2068     case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
2069     case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
2070     case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
2071     case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
2072 twoaday 165 case CMD_ENABLE: do_editkey_enable_disable (k, dlg, lvsub, 1); break;
2073     case CMD_DISABLE: do_editkey_enable_disable (k, dlg, lvsub, 0); break;
2074 twoaday 175 case CMD_CHECK: do_editkey_check (k, dlg); break;
2075 twoaday 165 case CMD_TRUST: keyedit_change_ownertrust (k, dlg); break;
2076 twoaday 170 case CMD_SIGN:
2077     case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2078     lvuid, cmd);
2079     break;
2080 werner 36 }
2081     break;
2082    
2083     case IDCANCEL:
2084     EndDialog (dlg, FALSE);
2085     break;
2086    
2087     case IDC_KEYEDIT_HELP:
2088     do_show_help (dlg);
2089     break;
2090     }
2091     break;
2092     }
2093     return FALSE;
2094 twoaday 133 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26