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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 185 - (hide annotations)
Mon Mar 20 12:48:52 2006 UTC (18 years, 11 months ago) by twoaday
File size: 55440 byte(s)
2006-03-20  Timo Schulz  <ts@g10code.de>

        * wptUTF8.cpp (get_native_charset): Removed.
        (utf8_to_native): Rewritten.
        * wptKeyEditDlgs.cpp (do_add_new_userid): Correct charset
        handling.
        * wptKeygenCBDlg.cpp (keygen_cb): Do proper reset if needed.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26