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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Thu Apr 14 12:56:25 2005 UTC (19 years, 10 months ago) by twoaday
File size: 49102 byte(s)
2005-04-11  Timo Schulz  <twoaday@freakmail.de>
 
        * wptClipSignEncDlg.cpp (clip_signenc_dlg_proc): Reset
        'enable' flag always at the begin.
        * wptClipDecryptDlg.cpp (clip_decrypt_dlg): Show correct
        key trust. Noted by a friendly user.
        * wptListView.cpp (listview_add_item_pos): New.
        * wptKeyEditDlgs.cpp (get_subkey_fingerprint): Due to
        the fact that GPG does not return the fingerprint of
        the generated subkey any longer, we need to get it manually.
        Thanks to Maxime Brandt.
        (keyedit_addsubkey_dlg_proc): If key size too large, ask
        if this was a mistake.
        (keyedit_add_subkey): Use it here.
        (do_add_new_subkey): Fix list contrl insertion.
        * wptTypes.h (DEFAULT_KEYSIZE): Define new default keysize constant.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26