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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Mon Apr 4 06:59:24 2005 UTC (19 years, 10 months ago) by twoaday
File size: 48202 byte(s)
2005-03-04  Timo Schulz  <twoaday@g10code.com>
 
        * GPG asks twice for the new PIN. Thanks to Achim.
        * wptCardDlg.cpp (card_changepin_dlg_proc): Reset the 'safety' pin also.        Only check the passphrase if the backup flag is enabled. Again thanks to        Achim.
 
2005-03-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptKeySignDlg.cpp (do_fill_seckeylist): Skip secret keys without
        a public key. Noted by Kurt Fitzner.
 
2005-03-22  Timo Schulz  <twoaday@freakmail.de>
 
        * WinPT.cpp (WinMain): --debug as an alias for --enable-debug.
        (enable_mobile_mode): New.
        * wptKeyEditDlg.cpp (keyedit_addsubkey_dlg_proc): Use new
        ID's for adding subkeys.
 


1 /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2 * Copyright (C) 2002-2005 Timo Schulz
3 *
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
21 #include <windows.h>
22 #include <commctrl.h>
23 #include "../resource.h"
24
25 #include "wptTypes.h"
26 #include "wptW32API.h"
27 #include "wptVersion.h"
28 #include "wptGPG.h"
29 #include "wptCommonCtl.h"
30 #include "wptContext.h"
31 #include "wptDlgs.h"
32 #include "wptNLS.h"
33 #include "wptUTF8.h"
34 #include "wptErrors.h"
35 #include "wptKeylist.h"
36 #include "wptKeyManager.h"
37 #include "wptRegistry.h"
38
39
40 enum keyedit_commands {
41 CMD_ADDKEY = 0,
42 CMD_ADDUID,
43 CMD_ADDPHOTO,
44 CMD_ADDREVOKER,
45 /*CMD_FPR,*/
46 CMD_DELUID,
47 CMD_DELKEY,
48 CMD_DELPHOTO,
49 /*CMD_DELSIG,*/
50 CMD_EXPIRE,
51 /*CMD_PREF,
52 CMD_SHOWPREF,
53 CMD_SETPREF,*/
54 CMD_UPDPREF,
55 CMD_PASSWD,
56 CMD_PRIMARY,
57 CMD_TRUST,
58 /*CMD_REVSIG,*/
59 CMD_REVUID,
60 CMD_REVKEY,
61 CMD_DISABLE,
62 CMD_ENABLE,
63 /*CMD_SHOWPHOTO,*/
64 };
65
66
67 struct keyedit_callback_s {
68 gpgme_editkey_t ek;
69 const char * pass;
70 listview_ctrl_t lv;
71 void * opaque;
72 };
73 typedef struct keyedit_callback_s KEYEDIT_CB;
74
75 struct keygen_callback_s {
76 int bits;
77 int algo;
78 u32 expire;
79 char * fpr;
80 };
81 typedef struct keygen_callback_s KEYGEN_CB;
82
83
84 static subclass_s keyedit_subkey_proc;
85 static subclass_s keyedit_uid_proc;
86
87 int keygen_check_date( SYSTEMTIME * st );
88 void get_userid_preflist (char ** r_prefs, int * r_flags);
89
90 static void
91 do_init_keylist (HWND dlg, winpt_key_t k)
92 {
93 gpgme_keycache_t pub;
94 gpgme_key_t key;
95 const char * s, * kid;
96 char * u;
97 int i, n;
98
99 pub = keycache_get_ctx (1);
100 if (!pub)
101 BUG (0);
102
103 while( !gpgme_keycache_next_key( pub, 0, &key ) ) {
104 s = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, 0 );
105 kid = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0);
106 if (!s || !strcmp (kid+8, k->keyid+2))
107 continue;
108 u = utf8_to_wincp (s, strlen (s));
109 SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_ADDSTRING,
110 0, (WPARAM)(char *)u);
111 free( u );
112 }
113 gpgme_keycache_rewind( pub );
114 n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );
115 for( i = 0; i < n; i++ ) {
116 gpgme_keycache_next_key( pub, 0, &key );
117 SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
118 (WPARAM)(int)i, (LPARAM)key );
119 }
120 SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_SETCURSEL, 0, 0 );
121 } /* do_init_keylist */
122
123
124 static void
125 do_add_new_userid( listview_ctrl_t lv, const char * name, const char *email,
126 const char * comment )
127 {
128 char * p;
129 size_t n;
130
131 n = strlen( name ) + strlen( email ) + 16;
132 if( comment )
133 n += strlen( comment );
134 p = new char[n+1];
135 if( !p )
136 BUG( NULL );
137 if( comment )
138 sprintf( p, "%s (%s) %s", name, comment, email );
139 else
140 sprintf( p, "%s %s", name, email );
141 listview_add_item( lv, "" );
142 listview_add_sub_item( lv, 0, 0, _("Ultimate" ) );
143 listview_add_sub_item( lv, 0, 1, p );
144 listview_add_sub_item( lv, 0, 2, _("OK") );
145 free_if_alloc( p );
146 } /* do_add_new_userid */
147
148
149 static void
150 do_add_new_subkey (listview_ctrl_t lv, KEYGEN_CB * keygen, unsigned int flags)
151 {
152 char info[128], keyid[32];
153 const char * expdate, * s;
154
155 expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
156 _snprintf( info, sizeof info-1, "%d-bit %s",
157 keygen->bits, gpgme_key_expand_attr( GPGME_ATTR_ALGO, keygen->algo ) );
158 _snprintf( keyid, sizeof keyid-1, "0x%s", keygen->fpr+32 );
159 listview_add_item( lv, "" );
160 listview_add_sub_item( lv, 0, 0, info );
161 listview_add_sub_item( lv, 0, 1, keyid );
162 listview_add_sub_item( lv, 0, 2, get_key_created( time(NULL) ) );
163 listview_add_sub_item( lv, 0, 3, expdate );
164 if( flags & KM_FLAG_REVOKED ) s = _("Revoked");
165 else if( flags & KM_FLAG_EXPIRED ) s = _("Expired");
166 else s = _("OK");
167 listview_add_sub_item( lv, 0, 4, s );
168 } /* do_add_new_subkey */
169
170
171 static int
172 do_find_userid (const char * keyid, const char * name)
173 {
174 gpgme_uidinfo_t inf;
175 gpgme_ctx_t ctx;
176 gpgme_error_t err;
177 int nitems = 0, pos = -1;
178 const char * s;
179 char * utf8_name=NULL;
180
181 err = gpgme_new (&ctx);
182 if (err)
183 BUG (0);
184 err = gpgme_op_editkey_get_info (ctx, keyid, &inf);
185 if (err)
186 {
187 log_box (_("user ID"), MB_ERR, _("Could not get key information for: \"%s\""), name);
188 gpgme_release (ctx);
189 return -1;
190 }
191 gpgme_release (ctx);
192 nitems = gpgme_editkey_count_items (inf);
193 while (nitems--)
194 {
195 s = gpgme_editkey_get_string_attr (inf, GPGME_ATTR_NAME, nitems);
196 if (!s)
197 continue;
198 utf8_name = utf8_to_wincp (s, strlen (s));
199 if (!strcmp (utf8_name, name))
200 {
201 pos = gpgme_editkey_get_ulong_attr (inf, GPGME_ATTR_LEVEL, nitems);
202 free (utf8_name);
203 break;
204 }
205 free (utf8_name); utf8_name=NULL;
206 }
207
208 gpgme_uid_info_release (inf);
209 return pos;
210 } /* do_find_userid */
211
212
213 BOOL CALLBACK
214 keyedit_addphoto_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
215 {
216 static winpt_key_t k;
217 gpgme_editkey_t ek;
218 gpgme_error_t ec;
219 gpgme_ctx_t ctx;
220 const char * s;
221 char pwd[128], file[128];
222 int id;
223
224 switch( msg ) {
225 case WM_INITDIALOG:
226 k = (winpt_key_t)lparam;
227 if( !k )
228 BUG( NULL );
229 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."));
230 SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
231 SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
232 SetForegroundWindow( dlg );
233 break;
234
235 case WM_DESTROY:
236 break;
237
238 case WM_SYSCOMMAND:
239 if( LOWORD (wparam) == SC_CLOSE )
240 EndDialog( dlg, TRUE );
241 break;
242
243 case WM_COMMAND:
244 switch( LOWORD( wparam ) ) {
245
246 case IDC_ADDPHOTO_SELFILE:
247 s = get_filename_dlg( dlg, FILE_OPEN, _("Select Image File"), _("JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0"), NULL );
248 if( s && *s )
249 SetDlgItemText( dlg, IDC_ADDPHOTO_FILE, s );
250 break;
251
252 case IDOK:
253 if( !GetDlgItemText( dlg, IDC_ADDPHOTO_FILE, file, sizeof file-1 ) ){
254 msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR );
255 return FALSE;
256 }
257 if( get_file_size( file ) == 0 || get_file_size( file ) > 6144 ) {
258 id = msg_box( dlg, _("The JPEG is really large.\n"
259 "Are you sure you want to use it?"),
260 _("Add Photo"), MB_YESNO|MB_INFO );
261 if( id == IDNO )
262 return TRUE;
263 }
264 if( k->is_protected ) {
265 if( !GetDlgItemText( dlg, IDC_ADDPHOTO_PASS, pwd, sizeof pwd-1 ) ) {
266 msg_box( dlg, _("Please enter a passphrase."), _("Add Photo"), MB_ERR );
267 return FALSE;
268 }
269 }
270 ec = gpgme_editkey_new( &ek );
271 if( !ec )
272 ec = gpgme_new( &ctx );
273 if( ec )
274 BUG( NULL );
275 gpgme_enable_logging( ctx );
276 gpgme_editkey_addphoto_set( ek, file, k->is_protected? pwd : NULL );
277 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDPHOTO );
278 ec = gpgme_op_editkey( ctx, k->keyid );
279 gpgme_editkey_release( ek );
280 if( ec ) {
281 gpgme_show_error( dlg, ec, ctx, _("Add Photo"), MB_ERR );
282 gpgme_release( ctx );
283 return FALSE;
284 }
285 else {
286 keycache_set_reload( 1 );
287 msg_box( dlg, _("Photo successfully added."), _("GnuPG Status"), MB_OK );
288 }
289 gpgme_release( ctx );
290 EndDialog( dlg, TRUE );
291 break;
292
293 case IDCANCEL:
294 EndDialog( dlg, FALSE );
295 break;
296 }
297 break;
298 }
299 return FALSE;
300 } /* keyedit_addphoto_dlg_proc */
301
302
303 BOOL CALLBACK
304 keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
305 {
306 static winpt_key_t k;
307 static gpgme_key_t seckey;
308 gpgme_editkey_t ek;
309 gpgme_ctx_t ctx;
310 gpgme_error_t ec;
311 char uid[128], pwd[128];
312
313
314 switch( msg ) {
315 case WM_INITDIALOG:
316 k = (winpt_key_t)lparam;
317 if( !k )
318 BUG( NULL );
319 if( get_seckey( k->keyid, &seckey ) )
320 BUG( NULL );
321 if( !k->is_protected )
322 EnableWindow( GetDlgItem( dlg, IDC_ADDREV_PASS ), FALSE );
323 do_init_keylist( dlg, k );
324 SetDlgItemText (dlg, IDC_ADDREV_INF, _("Appointing a key as designated revoker cannot be undone."));
325 SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
326 SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
327 SetForegroundWindow( dlg );
328 break;
329
330 case WM_DESTROY:
331 break;
332
333 case WM_SYSCOMMAND:
334 if( LOWORD (wparam) == SC_CLOSE )
335 EndDialog( dlg, TRUE );
336 break;
337
338 case WM_COMMAND:
339 switch( LOWORD( wparam ) ) {
340 case IDOK:
341 if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {
342 msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );
343 return FALSE;
344 }
345
346 if( k->is_protected ) {
347 if( !GetDlgItemText( dlg, IDC_ADDREV_PASS, pwd, sizeof pwd-1 ) ) {
348 msg_box( dlg, _("Please enter the passphrase."), _("Add Revoker"), MB_ERR );
349 return FALSE;
350 }
351 }
352 ec = gpgme_editkey_new( &ek );
353 if( !ec )
354 ec = gpgme_new( &ctx );
355 if( ec )
356 BUG( NULL );
357 gpgme_enable_logging( ctx );
358 gpgme_editkey_addrev_set( ek, uid, k->is_protected? pwd : NULL );
359 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDREV );
360 ec = gpgme_op_editkey( ctx, k->keyid );
361 gpgme_editkey_release( ek );
362 memset( pwd, 0, sizeof pwd );
363 if( ec ) {
364 gpgme_show_error( dlg, ec, ctx, _("Add Revoker"), MB_ERR );
365 gpgme_release( ctx );
366 return FALSE;
367 }
368 else {
369 msg_box( dlg, _("Revoker successfully addded."), _("GnuPG Status"), MB_OK );
370 keycache_set_reload( 1 );
371 }
372 gpgme_release( ctx );
373 EndDialog( dlg, TRUE );
374 break;
375
376 case IDCANCEL:
377 EndDialog( dlg, FALSE );
378 break;
379 }
380 break;
381 }
382 return FALSE;
383 } /* keyedit_addrevoker_dlg_proc */
384
385
386 BOOL CALLBACK
387 keyedit_adduid_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
388 {
389 static KEYEDIT_CB *ctx;
390 char *utf8_name = NULL;
391 char name[128], email[128], comment[128];
392 int rc;
393
394 switch ( msg ) {
395 case WM_INITDIALOG:
396 ctx = (KEYEDIT_CB *)lparam;
397 if( !ctx )
398 dlg_fatal_error(dlg, "Could not get dialog param!");
399 #ifndef LANG_DE
400 SetWindowText( dlg, _("Add new User ID") );
401 SetDlgItemText( dlg, IDC_ADDUID_INFNAME, _("&Name") );
402 SetDlgItemText( dlg, IDC_ADDUID_INFEMAIL, _("&Email") );
403 SetDlgItemText( dlg, IDC_ADDUID_INFCOMMENT, _("&Comment") );
404 #endif
405 SetForegroundWindow( dlg );
406 return FALSE;
407
408 case WM_SYSCOMMAND:
409 if( LOWORD (wparam) == SC_CLOSE ) {
410 gpgme_editkey_make_invalid( ctx->ek );
411 EndDialog(dlg, TRUE);
412 }
413 return FALSE;
414
415 case WM_COMMAND:
416 switch ( LOWORD( wparam ) ) {
417 case IDOK:
418 rc = GetDlgItemText( dlg, IDC_ADDUID_NAME, name, sizeof name-1 );
419 if( !rc || rc < 5 ) {
420 msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );
421 return FALSE;
422 }
423 if( strchr( name, '@' ) ) {
424 msg_box( dlg, _("Please enter the email address in the email field and not in the name field"), _("UserID"), MB_INFO );
425 return FALSE;
426 }
427
428 if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {
429 msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
430 return FALSE;
431 }
432 if( !strchr( email, '@' ) ) {
433 msg_box( dlg, _("Invalid email address."), _("UserID"), MB_ERR );
434 return FALSE;
435 }
436
437 rc = GetDlgItemText( dlg, IDC_ADDUID_COMMENT, comment, sizeof comment -1 );
438
439 /* xxx: something is wrong with the encoding :-( */
440 utf8_name = wincp_to_utf8 (name, strlen (name));
441
442 gpgme_editkey_adduid_set( ctx->ek, utf8_name? utf8_name : name, email,
443 rc? comment: NULL, ctx->pass );
444 free( utf8_name );
445 if( ctx->lv )
446 do_add_new_userid( ctx->lv, name, email, rc?comment : NULL );
447 EndDialog( dlg, TRUE );
448 return TRUE;
449
450 case IDCANCEL:
451 gpgme_editkey_make_invalid( ctx->ek );
452 EndDialog( dlg, FALSE );
453 return FALSE;
454 }
455 break;
456 }
457
458 return FALSE;
459 } /* keyedit_adduid_dlg_proc */
460
461
462 BOOL CALLBACK
463 keyedit_addsubkey_dlg_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
464 {
465 static KEYEDIT_CB * ctx;
466 static KEYGEN_CB * keygen;
467 gpgme_error_t rc;
468 int index, size, valid;
469 HWND lb;
470
471 switch ( msg ) {
472 case WM_INITDIALOG:
473 ctx = (KEYEDIT_CB *)lparam;
474 if( !ctx )
475 dlg_fatal_error( dlg, "Could not get dialog param!" );
476 keygen = (KEYGEN_CB *)ctx->opaque;
477 #ifndef LANG_DE
478 SetWindowText( dlg, _("Add new Subkey") );
479 SetDlgItemText( dlg, IDC_ADDSUBKEY_INFALGO, _("Key type") );
480 SetDlgItemText( dlg, IDC_ADDSUBKEY_INFSIZE, _("Size") );
481 SetDlgItemText( dlg, IDC_ADDSUBKEY_INFVALID,
482 _("Valid for 'n' days. 0 means forever") );
483 #endif
484 lb = GetDlgItem( dlg, IDC_ADDSUBKEY_ALGO );
485 listbox_add_string( lb, "DSA (sign only)");
486 listbox_add_string( lb, "ElGamal (encrypt only)" );
487 listbox_add_string( lb, "RSA (sign only)");
488 listbox_add_string( lb, "RSA (encrypt only)" );
489 SetDlgItemInt( dlg, IDC_ADDSUBKEY_VALID, 0, FALSE );
490 SetDlgItemInt( dlg, IDC_ADDSUBKEY_SIZE, 2048, FALSE );
491 SetForegroundWindow( dlg );
492 return FALSE;
493
494 case WM_SYSCOMMAND:
495 if( LOWORD (wparam) == SC_CLOSE ) {
496 gpgme_editkey_make_invalid( ctx->ek );
497 EndDialog( dlg, TRUE );
498 }
499 return FALSE;
500
501 case WM_COMMAND:
502 switch ( LOWORD(wparam) ) {
503 case IDOK:
504 lb = GetDlgItem( dlg, IDC_ADDSUBKEY_ALGO );
505 switch (listbox_get_cursel (lb)) {
506 case 0: index = 2; break;
507 case 1: index = 4; break;
508 case 2: index = 5; break;
509 case 3: index = 6; break;
510 default:
511 msg_box( dlg, _("Please select one entry."), _("Add Subkey"), MB_ERR );
512 return FALSE;
513 }
514 if (gpgver[0] == 1 && gpgver[1] == 2) { /* GPG 1.2.x kludge */
515 if (listbox_get_cursel (lb) > 1)
516 index++;
517 }
518 size = GetDlgItemInt( dlg, IDC_ADDSUBKEY_SIZE, NULL, TRUE );
519 if( !size ) {
520 msg_box( dlg, _("Please enter the keysize."), _("Add Subkey"), MB_ERR );
521 return FALSE;
522 }
523 else if( index == 2 && size != 1024 ) {
524 msg_box( dlg,_("DSS uses a fixed keysize of 1024. Size changed."), _("Add Subkey"), MB_INFO );
525 size = 1024;
526 }
527 else if( size > 4096 ) {
528 msg_box( dlg, _("Chosen size should be between 1024 and 4096. Size changed."), _("Add Subkey"), MB_ERR );
529 size = 4096;
530 }
531 else if( size < 1024 ) {
532 msg_box( dlg, _("Keys with a size of less then 1024 are considered insecure.\n"
533 "Size changed to 1024!"), _("Add Subkey"), MB_INFO );
534 size = 1024;
535 }
536 valid = GetDlgItemInt( dlg, IDC_ADDSUBKEY_VALID, NULL, TRUE );
537 if( valid < 0 ) {
538 msg_box( dlg, _("Please enter the days the key is valid."), _("Add Subkey"), MB_ERR );
539 return FALSE;
540 }
541 rc = gpgme_editkey_addkey_set (ctx->ek, ctx->pass, index, size, valid);
542 if (rc) {
543 msg_box (dlg, gpgme_strerror (rc), _("Add Subkey"), MB_ERR);
544 return FALSE;
545 }
546 keygen->bits = size;
547 switch (index) {
548 case 2: keygen->algo = GPGME_PK_DSA; break;
549 case 4: keygen->algo = GPGME_PK_ELG_E; break;
550 case 5: keygen->algo = GPGME_PK_RSA_S; break;
551 case 6: keygen->algo = GPGME_PK_RSA_E; break;
552 }
553 if (valid)
554 keygen->expire = time (NULL) + valid*24*60*60;
555 EndDialog( dlg, TRUE );
556 return TRUE;
557
558 case IDCANCEL:
559 gpgme_editkey_make_invalid( ctx ->ek );
560 EndDialog( dlg, FALSE );
561 return FALSE;
562 }
563 break;
564 }
565
566 return FALSE;
567 } /* keyedit_addsubkey_dlg_proc */
568
569
570 BOOL
571 keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
572 {
573 gpgme_error_t ec;
574 gpgme_ctx_t ctx;
575 gpgme_editkey_t ek;
576 KEYEDIT_CB cb;
577 char * pass = NULL;
578 int cancel = 0;
579
580 if( !k->key_pair ) {
581 msg_box( dlg, _("There is no secret key available!"), _("Add user ID"), MB_ERR );
582 return FALSE;
583 }
584
585 if (k->is_protected) {
586 pass = request_passphrase( _("Key Edit"), 1, &cancel );
587 if( cancel )
588 return FALSE;
589 }
590
591 ec = gpgme_editkey_new( &ek );
592 if( ec )
593 BUG( dlg );
594
595 memset( &cb, 0, sizeof cb );
596 cb.ek = ek;
597 cb.pass = k->is_protected? pass : NULL;
598 cb.lv = lv;
599 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
600 dlg, keyedit_adduid_dlg_proc,
601 (LPARAM)&cb, _("Add user ID"),
602 IDS_WINPT_KEYEDIT_ADDUID );
603 if( !gpgme_editkey_is_valid( ek ) ) {
604 free_if_alloc( pass );
605 return FALSE;
606 }
607
608 ec = gpgme_new( &ctx );
609 if( ec )
610 BUG( dlg );
611 gpgme_enable_logging( ctx );
612 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDUID );
613 ec = gpgme_op_editkey( ctx, k->keyid );
614 if( ec )
615 gpgme_show_error( dlg, ec, ctx, _("Add user ID"), MB_ERR );
616 else {
617 msg_box(dlg, _("User ID successfully added"), _("GnuPG Status"), MB_OK );
618 keycache_set_reload( 1 );
619 }
620 gpgme_editkey_release( ek );
621 gpgme_release( ctx );
622 free_if_alloc( pass );
623 return TRUE;
624 } /* keyedit_add_userid */
625
626
627 BOOL
628 keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
629 {
630 gpgme_error_t ec;
631 gpgme_ctx_t ctx;
632 gpgme_editkey_t ek;
633 KEYEDIT_CB cb;
634 KEYGEN_CB keygen;
635 char * pass = NULL;
636 int cancel = 0;
637
638 if( !k->key_pair ) {
639 msg_box( dlg, _("There is no secret key available!"), _("Add Subkey"), MB_ERR );
640 return FALSE;
641 }
642 if( k->is_protected ) {
643 pass = request_passphrase (_("Key Edit"), 1, &cancel);
644 if( cancel )
645 return FALSE;
646 }
647 ec = gpgme_editkey_new( &ek );
648 if( ec )
649 BUG( dlg );
650
651 memset( &keygen, 0, sizeof keygen );
652 memset( &cb, 0, sizeof cb );
653 cb.ek = ek;
654 cb.pass = k->is_protected? pass : NULL;
655 cb.opaque = &keygen;
656 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,
657 dlg, keyedit_addsubkey_dlg_proc,
658 (LPARAM)&cb, _("Add new Subkey" ),
659 IDS_WINPT_KEYEDIT_ADDSUBKEY );
660 if( !gpgme_editkey_is_valid( ek ) ) {
661 free_if_alloc( pass );
662 return FALSE;
663 }
664
665 ec = gpgme_new( &ctx );
666 if( ec )
667 BUG( dlg );
668 gpgme_enable_logging( ctx );
669 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_ADDKEY );
670 gpgme_set_progress_cb( ctx, keygen_cb, NULL );
671 keygen_cb_dlg_create ();
672
673 ec = gpgme_op_editkey( ctx, k->keyid );
674 keygen.fpr = (char *)gpgme_control (ctx, GPGME_CTRL_FPR, -1);
675 keygen_cb_dlg_destroy ();
676 keygen_cb (NULL, NULL, 0, 0, 0); /* flush */
677 if( ec )
678 gpgme_show_error( dlg, ec, ctx, _("Add Subkey"), MB_ERR );
679 else {
680 msg_box( dlg, _("Subkey successfully added."), _("GnuPG Status"), MB_OK );
681 if( lv )
682 do_add_new_subkey( lv, &keygen, k->flags );
683 keycache_set_reload( 1 );
684 }
685 free_if_alloc( pass );
686 gpgme_editkey_release( ek );
687 gpgme_release( ctx );
688
689 return ec? FALSE : TRUE;
690 } /* keyedit_add_subkey */
691
692
693 BOOL
694 keyedit_add_photo( winpt_key_t k, HWND dlg )
695 {
696 if( !k->key_pair ) {
697 msg_box( dlg, _("There is no secret key available!"), _("Add Photo"), MB_ERR );
698 return FALSE;
699 }
700 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
701 keyedit_addphoto_dlg_proc, (LPARAM)k );
702 return TRUE;
703 } /* keyedit_add_photo */
704
705
706 BOOL
707 keyedit_add_revoker (winpt_key_t k, HWND dlg)
708 {
709 if( !k->key_pair ) {
710 msg_box( dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR );
711 return FALSE;
712 }
713 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
714 keyedit_addrevoker_dlg_proc, (LPARAM)k );
715 return TRUE;
716 } /* keyedit_add_revoker */
717
718
719 static int
720 is_idea_protect_algo( const char * keyid )
721 {
722 gpgme_key_t key;
723 const char * sym_prefs;
724 size_t n;
725
726 if( get_pubkey( keyid, &key ) )
727 BUG( NULL );
728 sym_prefs = gpgme_key_get_string_attr( key, GPGME_ATTR_KEY_SYMPREFS, NULL, 0 );
729 if( !sym_prefs )
730 return 1; /* assume that only v3 keys have no symmetric cipher preferences
731 and thus IDEA is explicit. */
732 for( n = 0; sym_prefs[n]; n++ )
733 ;
734 if( (n == 0 || n == 1) && *sym_prefs == 0x01 )
735 return 1;
736 return 0;
737 } /* is_idea_protect_algo */
738
739
740 BOOL
741 keyedit_change_passwd( winpt_key_t k, HWND dlg )
742 {
743 gpgme_error_t ec;
744 gpgme_ctx_t ctx;
745 gpgme_editkey_t ek;
746 char * old_pass = NULL, * new_pass = NULL;
747 int cancel = 0;
748
749 if( !k->key_pair ) {
750 msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
751 return FALSE;
752 }
753
754 if( !idea_available && is_idea_protect_algo( k->keyid ) ) {
755 msg_box( dlg, _("Cannot change passphrase because the key\n"
756 "is protected with the IDEA encryption algorithm."),
757 _("Key Edit"), MB_ERR );
758 return FALSE;
759 }
760
761 if( k->is_protected ) {
762 old_pass = request_passphrase( _("Current (old) Passphrase"), 1, &cancel );
763 if( cancel )
764 return FALSE;
765 }
766 new_pass = request_passphrase( _("New Passphrase" ), 1, &cancel );
767 if( cancel ) {
768 free_if_alloc( old_pass );
769 return FALSE;
770 }
771
772 if( is_8bit_string( new_pass ) ) {
773 msg_box( dlg, _("The passphrase contains 8-bit characters.\n"
774 "It is not suggested to use charset specific characters."),
775 _("Key Edit"), MB_ERR );
776 free_if_alloc( old_pass );
777 free_if_alloc( new_pass );
778 return FALSE;
779 }
780
781 ec = gpgme_new( &ctx );
782 if( !ec )
783 ec = gpgme_editkey_new( &ek );
784 if( ec )
785 BUG( NULL );
786 gpgme_enable_logging( ctx );
787 gpgme_editkey_passwd_set( ek, k->is_protected? old_pass : NULL, new_pass, 0 );
788 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_PASSWD );
789 ec = gpgme_op_editkey( ctx, k->keyid );
790 if( ec )
791 gpgme_show_error( dlg, ec, ctx, _("Change Passwd"), MB_ERR );
792 else
793 msg_box( dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK );
794 free_if_alloc( old_pass );
795 free_if_alloc( new_pass );
796 gpgme_editkey_release( ek );
797 gpgme_release( ctx );
798 return TRUE;
799 } /* keyedit_change_passwd */
800
801
802 listview_ctrl_t
803 subkey_list_init( HWND dlg, winpt_key_t k )
804 {
805 LV_ITEM lvi;
806 gpgme_key_t key;
807 struct listview_column_s cols[] = {
808 {0, 80, (char *)_("Description")},
809 {1, 78, (char *)_("Key ID")},
810 {2, 66, (char *)_("Creation")},
811 {3, 66, (char *)_("Expires")},
812 {4, 64, (char *)_("Status")},
813 {5, 16, "C"/*ertify*/},
814 {6, 16, "S"/*ign*/},
815 {7, 16, "E"/*ncrypt*/},
816 {8, 16, "A"/*uth*/},
817 {0, 0, 0}
818 };
819 listview_ctrl_t lv;
820 char buf[256], tmp[128];
821 const char *t;
822 int nkeys = 0, rc = 0, i, bits, j;
823
824 if( get_pubkey( k->keyid, &key ) ) {
825 msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );
826 return NULL;
827 }
828
829 nkeys = gpgme_key_count_items( key, GPGME_ATTR_KEYID );
830 if( !nkeys ) {
831 msg_box( dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR );
832 return NULL;
833 }
834
835 rc = listview_new( &lv );
836 if( rc )
837 BUG( dlg );
838
839 lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
840 for( i = 0; cols[i].fieldname != NULL; i++ )
841 listview_add_column( lv, &cols[i] );
842
843 for( i = 0; i < nkeys; i++ ) {
844 listview_add_item( lv, "" );
845 listview_add_sub_item( lv, 0, 1, "" );
846 memset( &lvi, 0, sizeof lvi );
847 lvi.mask = LVIF_PARAM;
848 lvi.lParam = (LPARAM )key;
849 if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
850 return NULL;
851 }
852
853 listview_set_ext_style( lv );
854 for( i = 0; i < nkeys; i++ ) {
855 memset( buf, 0, sizeof buf );
856
857 bits = gpgme_key_get_ulong_attr( key, GPGME_ATTR_LEN, NULL, i );
858 _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
859 strcat( buf, tmp );
860
861 j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_ALGO, NULL, i );
862 t = gpgme_key_expand_attr( GPGME_ATTR_ALGO, j );
863 _snprintf( tmp, sizeof tmp-1, "%s", t );
864 strcat( buf, tmp );
865
866 listview_add_sub_item( lv, i, 0, buf );
867 t = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, i );
868 if( !t )
869 t = "DEADBEEFDEADBEEF";
870 _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
871 listview_add_sub_item( lv, i, 1, tmp );
872
873 j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_CREATED, NULL, i );
874 t = gpgme_key_expand_attr( GPGME_ATTR_CREATED, j );
875 if( !t )
876 t = "????-??-??";
877 listview_add_sub_item( lv, i, 2, t );
878
879 j = gpgme_key_get_ulong_attr( key, GPGME_ATTR_EXPIRES, NULL, i );
880 if( j ) {
881 t = gpgme_key_expand_attr( GPGME_ATTR_CREATED, j );
882 listview_add_sub_item( lv, i, 3, t );
883 }
884 else
885 listview_add_sub_item( lv, i, 3, _("Never") );
886
887 if( gpgme_key_get_ulong_attr(key, GPGME_ATTR_KEY_EXPIRED, NULL, i ) )
888 t = _("Expired");
889 else if( gpgme_key_get_ulong_attr( key, GPGME_ATTR_KEY_REVOKED, NULL, i ) )
890 t = _("Revoked");
891 else
892 t = _("OK");
893 listview_add_sub_item( lv, i, 4, t );
894
895 gpgme_key_get_cability( key, GPGME_ATTR_CAN_CERTIFY, i )?
896 t = "*" : t = "";
897 listview_add_sub_item( lv, i, 5, t );
898 gpgme_key_get_cability( key, GPGME_ATTR_CAN_SIGN, i )?
899 t = "*" : t = "";
900 listview_add_sub_item( lv, i, 6, t );
901 gpgme_key_get_cability( key, GPGME_ATTR_CAN_ENCRYPT, i )?
902 t = "*" : t = "";
903 listview_add_sub_item( lv, i, 7, t );
904
905 gpgme_key_get_cability (key, GPGME_ATTR_CAN_AUTH, i)?
906 t = "*" : t = "";
907 listview_add_sub_item (lv, i, 8, t);
908 }
909 return lv;
910 } /* subkey_list_init */
911
912
913 static listview_ctrl_t
914 userid_list_init (HWND dlg, winpt_key_t k)
915 {
916 listview_ctrl_t lv = NULL;
917 gpgme_key_t key;
918 int nuids = 0, rc, j, u_attr;
919 struct listview_column_s cols[] = {
920 {0, 72, (char *)_("Validity")},
921 {1, 250, (char *)_("Name")},
922 {2, 76, (char *)_("Creation")},
923 {0, 0, 0}
924 };
925 const char *attr;
926
927 if( get_pubkey( k->keyid, &key ) ) {
928 msg_box( dlg, _("Could not find key."), _("Key Edit"), MB_ERR );
929 return NULL;
930 }
931
932 nuids = gpgme_key_count_items( key, GPGME_ATTR_USERID );
933 if( !nuids ) {
934 msg_box( dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR );
935 return NULL;
936 }
937
938 rc = listview_new( &lv );
939 if( rc )
940 BUG( dlg );
941 lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
942 for( j = 0; cols[j].fieldname != NULL; j++ )
943 listview_add_column( lv, &cols[j] );
944
945 for( j = 0; j < nuids; j++ ) {
946 listview_add_item( lv, " " );
947 listview_add_sub_item( lv, 0, 1, " " );
948 }
949
950 listview_set_ext_style (lv);
951 for (j = 0; j < nuids; j++) {
952 if (gpgme_key_get_ulong_attr (key, GPGME_ATTR_UID_REVOKED, NULL, j))
953 attr = _("Revoked");
954 else {
955 u_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_VALIDITY, NULL, j);
956 attr = gpgme_key_expand_attr (GPGME_ATTR_VALIDITY, u_attr);
957 }
958 listview_add_sub_item( lv, j, 0, (char *)attr );
959
960 attr = gpgme_key_get_string_attr( key, GPGME_ATTR_USERID, NULL, j );
961 if( attr ) {
962 char * uid = utf8_to_wincp (attr, strlen (attr));
963 if (uid) {
964 listview_add_sub_item( lv, j, 1, uid );
965 free( uid );
966 }
967 }
968 else
969 listview_add_sub_item( lv, j, 1, _("Invalid user ID") );
970 u_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_UID_CREATED, NULL, j);
971 if (u_attr)
972 listview_add_sub_item (lv, j, 2, get_key_created (u_attr));
973 }
974 if( !k->key_pair ) {
975 CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );
976 CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );
977 }
978 return lv;
979 } /* userid_list_init */
980
981
982 static void
983 do_init_cmdlist( HWND dlg )
984 {
985 const char *cmdlist[] = {
986 "ADDKEY",
987 "ADDUID",
988 "ADDPHOTO",
989 "ADDREVOKER",
990 /*"FPR",*/
991 "DELUID",
992 "DELKEY",
993 "DELPHOTO",
994 /*"DELSIG",*/
995 "EXPIRE",
996 /*"PREF",
997 "SHOWPREF",
998 "SETPREF",*/
999 "UPDPREF",
1000 "PASSWD",
1001 "PRIMARY",
1002 "TRUST",
1003 /*"REVSIG",*/
1004 "REVUID",
1005 "REVKEY",
1006 "DISABLE",
1007 "ENABLE",
1008 "SHOWPHOTO",
1009 NULL
1010 };
1011 const char * s;
1012 int i = 0;
1013
1014 for( i = 0; (s=cmdlist[i]); i++ ) {
1015 SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1016 (LPARAM)(char *)s );
1017 }
1018 SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0 );
1019 } /* do_init_cmdlist */
1020
1021
1022 static int
1023 is_cmd_openpgp( int cmdid )
1024 {
1025 switch( cmdid ) {
1026 case CMD_ADDKEY:
1027 case CMD_ADDPHOTO:
1028 case CMD_ADDREVOKER:
1029 case CMD_DELPHOTO:
1030 /*case CMD_SHOWPHOTO:*/
1031 case CMD_UPDPREF:
1032 return 1;
1033 }
1034 return 0;
1035 } /* is_cmd_openpgp */
1036
1037
1038 static void
1039 do_show_help( HWND dlg )
1040 {
1041 char helptext[2048];
1042
1043 _snprintf( helptext, sizeof helptext-1,
1044 _(/*"FPR \t\tshow fingerprint\r\n"*/
1045 "ADDUID \t\tadd a user ID\r\n"
1046 "ADDPHOTO \t\tadd a photo ID\r\n"
1047 "DELUID \t\tdelete a user ID\r\n"
1048 "ADDKEY \t\tadd a secondard key\r\n"
1049 "DELKEY \t\tdelete a secondary key\r\n"
1050 "ADDREVOKER\t\tadd a revocation key\r\n"
1051 /*"DELSIG \t\tdelete signatures\r\n"*/
1052 "EXPIRE \t\tchange the expire date\r\n"
1053 /*"PREF \t\tlist preferences (expert)\r\n"
1054 "SHOWPREF \t\tlist preferences (verbose)\r\n"
1055 "SETPREF \t\tset preference list\r\n"*/
1056 "UPDPREF \t\tupdated preferences\r\n"
1057 "PASSWD \t\tchange the passphrase\r\n"
1058 "PRIMARY \t\tflag user ID as primary\r\n"
1059 "TRUST \t\tchange the ownertrust\r\n"
1060 /*"REVSIG \t\trevoke signatures\r\n"*/
1061 "REVUID \t\trevoke a user ID\r\n"
1062 "REVKEY \t\trevoke a secondary key\r\n"
1063 "DISABLE \t\tdisable a key\r\n"
1064 "ENABLE \t\tenable a key\r\n"
1065 /*"SHOWPHOTO \t\tshow photo ID\r\n"*/) );
1066 msg_box( dlg, helptext, _("Key Edit Help"), MB_OK );
1067 } /* do_show_help */
1068
1069
1070 static int
1071 do_editkey_delkey( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1072 {
1073 int j, id;
1074 char tmp[64];
1075 gpgme_error_t ec;
1076 gpgme_editkey_t ek;
1077 gpgme_ctx_t ctx;
1078
1079 if( listview_count_items( lv, 0 ) == 1 ) {
1080 msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1081 return FALSE;
1082 }
1083 if( (j = listview_get_curr_pos( lv )) == -1 ) {
1084 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1085 return FALSE;
1086 }
1087 if( j == 0 ) {
1088 msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );
1089 return FALSE;
1090 }
1091
1092 listview_get_item_text( lv, j, 0, tmp, sizeof tmp -1 );
1093 id = log_box( _("Key Edit"), MB_YESNO|MB_ICONWARNING,
1094 _("\"Subkey %s.\"\n\n"
1095 "Anything encrypted to the selected subkey will no longer\n"
1096 "be able to be decrypted.\n\n"
1097 "Do you really want to delete this subkey?"), tmp );
1098 if( id == IDNO )
1099 return FALSE;
1100
1101 ec = gpgme_new( &ctx );
1102 if( !ec )
1103 ec = gpgme_editkey_new( &ek );
1104 if( ec )
1105 BUG( dlg );
1106 gpgme_enable_logging( ctx );
1107 gpgme_editkey_delkey_set_id( ek, j );
1108 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_DELKEY );
1109 ec = gpgme_op_editkey( ctx, k->keyid );
1110 if( ec )
1111 gpgme_show_error( dlg, ec, ctx, _("Delete Subkey"), MB_ERR );
1112 else {
1113 listview_del_item( lv, j );
1114 keycache_set_reload( 1 );
1115 status_box( dlg, _("Subkey successfully deleted."), _("GnuPG status") );
1116 }
1117 gpgme_editkey_release( ek );
1118 gpgme_release( ctx );
1119 return ec? FALSE : TRUE;
1120 } /* do_editkey_delkey */
1121
1122
1123 static int
1124 do_editkey_expire( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1125 {
1126 gpgme_error_t ec;
1127 gpgme_editkey_t ek;
1128 gpgme_ctx_t ctx;
1129 date_s udd = {0};
1130 char buf[256], * pass = NULL;
1131 int j, cancel = 0;
1132
1133 if( !k->key_pair ) {
1134 msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
1135 return FALSE;
1136 }
1137 if ( (j = listview_get_curr_pos( lv )) == -1 ) {
1138 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1139 return FALSE;
1140 }
1141
1142 listview_get_item_text( lv, j, 3, buf, sizeof buf -1 );
1143 if( !strcmp( buf, _("Expired") ) ) {
1144 msg_box( dlg, _("Key already expired!"), _("Key Edit"), MB_ERR );
1145 return FALSE;
1146 }
1147 memset( &udd, 0, sizeof udd );
1148 udd.text = _("Key Expiration Date");
1149 dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,
1150 date_dlg_proc, (LPARAM)&udd,
1151 _("Key Expiration Date"), IDS_WINPT_DATE );
1152 if( udd.cancel == 1 )
1153 return FALSE;
1154 if( !keygen_check_date( &udd.st ) ) {
1155 msg_box( dlg, _("The date you have chosen lies in the past."), _("Key Edit"), MB_ERR );
1156 return FALSE;
1157 }
1158 if( k->is_protected ) {
1159 pass = request_passphrase (_("Key Edit"), 1, &cancel );
1160 if( cancel )
1161 return FALSE;
1162 }
1163 _snprintf( buf, sizeof buf - 1, "%04d-%02d-%02d",
1164 udd.st.wYear, udd.st.wMonth, udd.st.wDay );
1165 ec = gpgme_editkey_new( &ek );
1166 if( !ec )
1167 ec = gpgme_new( &ctx );
1168 if( ec )
1169 BUG( dlg );
1170 gpgme_editkey_expire_set( ek, j, 0, buf, k->is_protected? pass : NULL );
1171 gpgme_enable_logging( ctx );
1172 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_EXPIRE );
1173 ec = gpgme_op_editkey( ctx, k->keyid );
1174 if( ec )
1175 gpgme_show_error( dlg, ec, ctx, _("Expire Subkey"), MB_ERR );
1176 else {
1177 listview_add_sub_item( lv, j, 3, buf );
1178 keycache_set_reload( 1 );
1179 msg_box( dlg, _("Subkey expire date successfully set."), _("GnuPG status"), MB_OK );
1180 }
1181 free_if_alloc( pass );
1182 gpgme_release( ctx );
1183 gpgme_editkey_release( ek );
1184 return TRUE;
1185 } /* do_editkey_expire */
1186
1187
1188 static int
1189 do_editkey_revoke( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1190 {
1191 gpgme_ctx_t ctx;
1192 gpgme_error_t ec;
1193 gpgme_editkey_t ek;
1194 char buf[256], * pass = NULL;
1195 int j, cancel = 0;
1196
1197 if( !k->key_pair ) {
1198 msg_box( dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR );
1199 return FALSE;
1200
1201 }
1202
1203 if( (j = listview_get_curr_pos( lv )) == -1 ) {
1204 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1205 return FALSE;
1206 }
1207 else if( listview_count_items( lv, 0 ) == 1 ) {
1208 msg_box( dlg, _("No subkeys were found, if you want to revoke the\n"
1209 "whole key, please use the Key Manager command directly.\n\n"
1210 "This command is only available to revoke single subkeys"),
1211 _("Key Edit"), MB_INFO );
1212 return FALSE;
1213 }
1214
1215 listview_get_item_text( lv, j, 3, buf, sizeof buf-1 );
1216 if( !strcmp( buf, _("Revoked") ) ) {
1217 msg_box( dlg, _("Key already revoked."), _("Key Edit"), MB_ERR );
1218 return FALSE;
1219 }
1220
1221 if( k->is_protected ) {
1222 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1223 if( cancel )
1224 return FALSE;
1225 }
1226
1227 ec = gpgme_editkey_new( &ek );
1228 if( !ec )
1229 ec = gpgme_new( &ctx );
1230 if( ec )
1231 BUG( NULL );
1232 gpgme_enable_logging( ctx );
1233 gpgme_editkey_revkey_set( ek, j, 0, k->is_protected? pass : NULL );
1234 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_REVKEY );
1235 ec = gpgme_op_editkey( ctx, k->keyid );
1236 if( ec )
1237 gpgme_show_error( dlg, ec, ctx, _("Revoke Subkey"), MB_ERR );
1238 else {
1239 listview_add_sub_item( lv, j, 5, _("Revoked") );
1240 keycache_set_reload( 1 );
1241 msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1242 }
1243 free_if_alloc( pass );
1244 gpgme_release( ctx );
1245 gpgme_editkey_release( ek );
1246 return TRUE;
1247 } /* do_editkey_revoke */
1248
1249
1250 int
1251 do_editkey_revuid( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1252 {
1253 gpgme_ctx_t ctx;
1254 gpgme_error_t ec;
1255 gpgme_editkey_t ek;
1256 char buf[256], t[512], * pass;
1257 int cancel = 0, id = 0, j;
1258
1259 if( !k->key_pair ) {
1260 msg_box( dlg, _("There is no secret key available!"), _("Revoke user ID"), MB_ERR );
1261 return FALSE;
1262 }
1263
1264 if( listview_count_items( lv, 0 ) == 1 ) {
1265 msg_box( dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR );
1266 return FALSE;
1267 }
1268
1269 if( (j = listview_get_curr_pos( lv )) == -1 ) {
1270 msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1271 return FALSE;
1272 }
1273
1274 listview_get_item_text( lv, j, 0, buf, sizeof buf - 1 );
1275 if( strstr( buf, _("Revoked") ) ) {
1276 msg_box( dlg, _("This user ID has been already revoked."), _("Key Edit"), MB_INFO );
1277 return FALSE;
1278 }
1279
1280 listview_get_item_text( lv, j, 1, buf, sizeof buf -1 );
1281 _snprintf( t, sizeof t -1, _("user ID \"%s\".\n\n"
1282 "Do you really want to revoke this user ID?"), buf );
1283 if( msg_box( dlg, t, _("Key Edit"), MB_YESNO|MB_ICONWARNING ) == IDNO )
1284 return FALSE;
1285 if( k->is_protected ) {
1286 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1287 if( cancel )
1288 return FALSE;
1289 }
1290 id = do_find_userid( k->keyid, buf );
1291 if( id == -1 )
1292 BUG( dlg );
1293 ec = gpgme_new( &ctx );
1294 if( !ec )
1295 ec = gpgme_editkey_new( &ek );
1296 if( ec )
1297 BUG( dlg );
1298 gpgme_enable_logging( ctx );
1299 gpgme_editkey_revsig_set( ek, id, k->is_protected? pass : NULL );
1300 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_REVSIG );
1301 ec = gpgme_op_editkey( ctx, k->keyid );
1302 if( ec )
1303 gpgme_show_error( dlg, ec, ctx, _("Revoke Signature"), MB_ERR );
1304 else {
1305 listview_add_sub_item( lv, j, 2, _("Revoked") );
1306 keycache_set_reload( 1 );
1307 status_box( dlg, _("User ID successfully revoked"), _("GnuPG Status") );
1308 }
1309 free_if_alloc( pass );
1310 gpgme_editkey_release( ek );
1311 gpgme_release( ctx );
1312 return ec? FALSE : TRUE;
1313 } /* do_editkey_revuid */
1314
1315
1316 static int
1317 do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1318 {
1319 gpgme_ctx_t ctx;
1320 gpgme_editkey_t ek;
1321 gpgme_error_t rc;
1322 char buf[256], * pass = NULL, * prefs;
1323 int j, id, cancel=0, flags=0;
1324
1325 if ((j = listview_get_curr_pos (lv)) == -1) {
1326 msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1327 return FALSE;
1328 }
1329 listview_get_item_text (lv, j, 1, buf, sizeof buf-1);
1330 id = do_find_userid (k->keyid, buf);
1331 if (id == -1)
1332 BUG (dlg);
1333 if (k->is_protected) {
1334 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1335 if (cancel)
1336 return FALSE;
1337 }
1338 rc = gpgme_new (&ctx);
1339 if (!rc)
1340 rc = gpgme_editkey_new (&ek);
1341 if (rc)
1342 BUG (NULL);
1343
1344 get_userid_preflist (&prefs, &flags);
1345 gpgme_editkey_setpref_set (ek, prefs, id, pass);
1346 gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_SETPREF);
1347 rc = gpgme_op_editkey (ctx, k->keyid);
1348 free_if_alloc (pass);
1349
1350 free_if_alloc (prefs);
1351 gpgme_release (ctx);
1352 gpgme_editkey_release (ek);
1353 return 0;
1354 }
1355
1356
1357 static int
1358 do_editkey_primary( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1359 {
1360 gpgme_ctx_t ctx;
1361 gpgme_editkey_t ek;
1362 gpgme_error_t ec;
1363 int j, id, cancel=0;
1364 char buf[256], * pass = NULL;
1365
1366 if( (j = listview_get_curr_pos( lv )) == -1 ) {
1367 msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1368 return FALSE;
1369 }
1370 listview_get_item_text( lv, j, 1, buf, sizeof buf-1 );
1371 id = do_find_userid (k->keyid, buf);
1372 if( id == -1 )
1373 BUG( dlg );
1374 if( k->is_protected ) {
1375 pass = request_passphrase( _("Key Edit"), 1, &cancel );
1376 if( cancel )
1377 return FALSE;
1378 }
1379
1380 ec = gpgme_new( &ctx );
1381 if( !ec )
1382 ec = gpgme_editkey_new( &ek );
1383 if( ec )
1384 BUG( dlg );
1385 gpgme_enable_logging( ctx );
1386 gpgme_editkey_primary_set( ek, id, k->is_protected? pass : NULL );
1387 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_PRIMARY );
1388 ec = gpgme_op_editkey( ctx, k->keyid );
1389 if( ec )
1390 gpgme_show_error( dlg, ec, ctx, _("Primary"), MB_ERR );
1391 else {
1392 keycache_set_reload( 1 );
1393 status_box( dlg, _("User ID successfully flagged"), _("GnuPG Status") );
1394 }
1395
1396 free_if_alloc( pass );
1397 gpgme_editkey_release( ek );
1398 gpgme_release( ctx );
1399 return ec? FALSE : TRUE;
1400 } /* do_editkey_primary */
1401
1402
1403 static int
1404 do_editkey_deluid( winpt_key_t k, HWND dlg, listview_ctrl_t lv )
1405 {
1406 gpgme_ctx_t ctx;
1407 gpgme_editkey_t ek;
1408 gpgme_error_t ec;
1409 char buf[256], t[512];
1410 int j, id = 0;
1411
1412 if( listview_count_items( lv, 0 ) == 1 ) {
1413 msg_box( dlg, _("Primary user ID can not be deleted!"), _("Key Edit"), MB_ERR );
1414 return FALSE;
1415 }
1416 if( (j = listview_get_curr_pos( lv )) == -1 ) {
1417 msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1418 return FALSE;
1419 }
1420
1421 listview_get_item_text( lv, j, 1, buf, sizeof buf -1 );
1422 _snprintf( t, sizeof t -1, _("user ID \"%s\".\n\n"
1423 "Do you really want to delete this user ID?"), buf );
1424 if( msg_box( dlg, t, _("Key Edit"), MB_YESNO|MB_ICONWARNING ) == IDNO )
1425 return FALSE;
1426
1427 id = do_find_userid( k->keyid, buf );
1428 if( id == -1 )
1429 BUG( dlg );
1430 ec = gpgme_new( &ctx );
1431 if( !ec )
1432 ec = gpgme_editkey_new( &ek );
1433 if( ec )
1434 BUG( dlg );
1435 gpgme_enable_logging( ctx );
1436 gpgme_editkey_deluid_set_id( ek, id );
1437 gpgme_set_edit_ctx( ctx, ek, GPGME_EDITKEY_DELUID );
1438 ec = gpgme_op_editkey( ctx, k->keyid );
1439 if( ec )
1440 gpgme_show_error( dlg, ec, ctx, _("Delete user ID"), MB_ERR );
1441 else {
1442 listview_del_item( lv, j );
1443 keycache_set_reload( 1 );
1444 status_box( dlg, _("User ID successfully deleted"), _("GnuPG Status") );
1445 }
1446 gpgme_editkey_release( ek );
1447 gpgme_release( ctx );
1448 return ec? FALSE : TRUE;
1449 } /* do_editkey_deluid */
1450
1451
1452
1453 static BOOL CALLBACK
1454 subkey_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
1455 {
1456 switch( msg ) {
1457 case WM_KEYUP:
1458 int virt_key = (int)wparam;
1459 switch( virt_key ) {
1460 case VK_DELETE:
1461 SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1462 CB_SETCURSEL, CMD_DELKEY, 0 );
1463 send_cmd_id( keyedit_subkey_proc.dlg, IDOK );
1464 break;
1465
1466 case VK_INSERT:
1467 SendDlgItemMessage( keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1468 CB_SETCURSEL, CMD_ADDKEY, 0 );
1469 send_cmd_id( keyedit_subkey_proc.dlg, IDOK );
1470 break;
1471 }
1472 }
1473 return CallWindowProc( keyedit_subkey_proc.old, dlg, msg, wparam, lparam );
1474 } /* subkey_subclass_proc */
1475
1476
1477 static BOOL CALLBACK
1478 uid_subclass_proc( HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam )
1479 {
1480 switch( msg ) {
1481 case WM_KEYUP:
1482 int virt_key = (int)wparam;
1483 switch( virt_key ) {
1484 case VK_DELETE:
1485 SendDlgItemMessage( keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1486 CB_SETCURSEL, CMD_DELUID, 0 );
1487 send_cmd_id( keyedit_uid_proc.dlg, IDOK );
1488 break;
1489
1490 case VK_INSERT:
1491 SendDlgItemMessage( keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1492 CB_SETCURSEL, CMD_ADDUID, 0 );
1493 send_cmd_id( keyedit_uid_proc.dlg, IDOK );
1494 break;
1495 }
1496 }
1497 return CallWindowProc( keyedit_uid_proc.old, dlg, msg, wparam, lparam );
1498 } /* uid_subclass_proc */
1499
1500
1501 BOOL CALLBACK
1502 keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1503 {
1504 static winpt_key_t k;
1505 static listview_ctrl_t lvsub = NULL, lvuid = NULL;
1506 int cmd, idxsub = 0;
1507 HWND item;
1508
1509 switch( msg ) {
1510 case WM_INITDIALOG:
1511 k = (winpt_key_t)lparam;
1512 if( !k )
1513 BUG( NULL );
1514 do_init_cmdlist( dlg );
1515 lvsub = subkey_list_init( dlg, k );
1516 if( !lvsub )
1517 BUG( NULL );
1518 lvuid = userid_list_init (dlg, k);
1519 if( !lvuid )
1520 BUG( NULL );
1521 item = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
1522 keyedit_subkey_proc.dlg = dlg;
1523 keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
1524 keyedit_subkey_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );
1525 if( keyedit_subkey_proc.old ) {
1526 if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_subkey_proc.current ) ) {
1527 msg_box( dlg, _("Could not set subkey window procedure."), _("Key Edit"), MB_ERR );
1528 BUG( NULL );
1529 }
1530 }
1531 item = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
1532 keyedit_uid_proc.dlg = dlg;
1533 keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
1534 keyedit_uid_proc.old = (WNDPROC)GetWindowLong( item, GWL_WNDPROC );
1535 if( keyedit_uid_proc.old ) {
1536 if( !SetWindowLong( item, GWL_WNDPROC, (LONG)keyedit_uid_proc.current ) ) {
1537 msg_box( dlg, _("Could not set user ID window procedure."), _("Key Edit"), MB_ERR );
1538 BUG( NULL );
1539 }
1540 }
1541 if (!k->key_pair) {
1542 EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
1543 EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
1544 }
1545 SetForegroundWindow( dlg );
1546 center_window( dlg );
1547 return TRUE;
1548
1549 case WM_DESTROY:
1550 if( lvsub ) {
1551 listview_release( lvsub );
1552 lvsub = NULL;
1553 }
1554 if( lvuid ) {
1555 listview_release( lvuid );
1556 lvuid = NULL;
1557 }
1558 break;
1559
1560 case WM_COMMAND:
1561 switch( LOWORD( wparam ) ) {
1562 case IDOK:
1563 cmd = SendDlgItemMessage( dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0 );
1564 if( cmd == LB_ERR ) {
1565 msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
1566 return FALSE;
1567 }
1568 idxsub = listview_get_curr_pos( lvsub );
1569 if( km_key_is_v3( lvsub, idxsub==-1? 0 : idxsub ) && is_cmd_openpgp( cmd ) ) {
1570 msg_box( dlg, _("This command cannot be used with PGP 2 (v3) keys\n"
1571 " because it is not OpenPGP compliant."),
1572 _("Key Edit"), MB_ERR );
1573 return FALSE;
1574 }
1575 switch( cmd ) {
1576 case CMD_DELKEY: do_editkey_delkey( k, dlg, lvsub ); break;
1577 case CMD_ADDKEY: keyedit_add_subkey( k, dlg, lvsub ); break;
1578 case CMD_EXPIRE: do_editkey_expire( k, dlg, lvsub ); break;
1579 case CMD_REVKEY: do_editkey_revoke( k, dlg, lvsub ); break;
1580 case CMD_UPDPREF:do_editkey_setpref( k, dlg, lvuid ); break;
1581 case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
1582 case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
1583 case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
1584 case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
1585 case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
1586 case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
1587 case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
1588 case CMD_ENABLE: km_enable_disable_key( lvsub, dlg, idxsub, 1 ); break;
1589 case CMD_DISABLE: km_enable_disable_key( lvsub, dlg, idxsub, 0 ); break;
1590 }
1591 break;
1592
1593 case IDCANCEL:
1594 EndDialog( dlg, FALSE );
1595 break;
1596
1597 case IDC_KEYEDIT_HELP:
1598 do_show_help( dlg );
1599 break;
1600 }
1601 break;
1602 }
1603 return FALSE;
1604 } /* keyedit_main_dlg_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26