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

Contents of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (show annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 21884 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

1 /* wptCardDlg.cpp - Smart Card support
2 * Copyright (C) 2003, 2004, 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 <ctype.h>
24
25 #include "../resource.h"
26 #include "gpgme.h"
27 #include "wptTypes.h"
28 #include "wptW32API.h"
29 #include "wptErrors.h"
30 #include "wptRegistry.h"
31 #include "wptVersion.h"
32 #include "wptCommonCtl.h"
33 #include "wptDlgs.h"
34 #include "wptGPG.h"
35 #include "wptUTF8.h"
36 #include "wptCardEdit.h"
37 #include "wptCard.h"
38
39 int keygen_check_date (SYSTEMTIME * st);
40
41 static const char * sex[] = {"Male", "Female", "Undefined", NULL};
42 static const char * lang[] = {"Undefined", "cs", "de", "en", "es", "fr", "hu",
43 "it", "nl", "pt", "ro", "ru", "zh", "at",
44 NULL};
45
46 static pin_cb_ctx_s pincb;
47
48 struct {
49 int ctlid;
50 const char * err;
51 } attr_tab[] = {
52 {IDC_CEDIT_AID, ""},
53 {IDC_CEDIT_VENDOR, "No Vendor"},
54 {IDC_CEDIT_VERSION,"No Version"},
55 {IDC_CEDIT_SERIAL, "No Serial-No"},
56 {IDC_CEDIT_NAME, "No Name"},
57 {IDC_CEDIT_NAME2, "No Surname"},
58 {IDC_CEDIT_KEYURL, "No Key-URL"},
59 {IDC_CEDIT_LOGIN, "No Login name"},
60 {0},
61 };
62
63
64 /* Return all card attributes from @card. @n contains
65 the number of items which were returned. */
66 char**
67 card_get_items (gpg_card_t card, int *n)
68 {
69 char **p;
70
71 *n= 8;
72 p = (char **)calloc (*n+1, sizeof (char*));
73 if (!p)
74 BUG (0);
75 p[0] = card->aid;
76 p[1] = card->vendor;
77 p[2] = card->ver;
78 p[3] = card->serial;
79 p[4] = card->givenname;
80 p[5] = card->surname;
81 p[6] = card->url;
82 p[7] = card->login;
83 return p;
84 }
85
86
87 static int
88 idx_from_lang (const char * _lang)
89 {
90 const char * s;
91 int i;
92
93 if (!_lang)
94 return 0;
95 for (i=0; (s = lang[i]); i++) {
96 if (!strcmp( _lang, s ))
97 return i;
98 }
99 return 0;
100 }
101
102
103 #if 0 /* @unused@ */
104 int
105 show_card_status (void)
106 {
107 int rc = 0;
108 int cardstat;
109
110 cardstat = pcsc_get_card_status ();
111 if ((cardstat & CARD_STATE_UNAWARE) || (cardstat & CARD_STATE_UNAVAIL))
112 rc = WPTERR_NOREADER;
113 else if (cardstat & CARD_STATE_EMPTY)
114 rc = WPTERR_NOCARD;
115 if (rc) {
116 msg_box (NULL, winpt_strerror (rc), _("Card Manager"), MB_ERR);
117 return -1;
118 }
119 return 0;
120 } /* show_card_status */
121 #endif
122
123 /* Check if there is a card in the reader and analyze the
124 returned information.
125 Return value: card context or NULL on error. */
126 gpg_card_t
127 gpg_load_scard (void)
128 {
129 gpgme_error_t err;
130 GpgCardEdit *ce;
131 gpg_card_t card = NULL;
132 struct card_cb_s cb = {0};
133
134 ce = new GpgCardEdit ();
135 if (!ce)
136 BUG (0);
137 memset (&cb, 0, sizeof (cb));
138 ce->setCallback (card_callback, &cb);
139 err = ce->getCardStatus (&card);
140 if (err) {
141 msg_box (NULL, gpgme_strerror (err), _("Card Manager"), MB_ERR);
142 goto leave;
143 }
144
145 if (!card->aid || strncmp (card->aid, "D276000124", 10)) {
146 msg_box (NULL, winpt_strerror (WPTERR_NOPGPCARD), "WinPT", MB_ERR);
147 gpg_card_release (card);
148 card = NULL;
149 }
150
151 leave:
152 delete ce;
153 return card;
154 }
155
156
157 /* Print human friendly fingerprint to control @id in the
158 dialog @dlg. @fpr contains the raw fingerprint. */
159 static void
160 print_fpr (HWND dlg, int id, const char * fpr)
161 {
162 char buf[128], dig[2];
163 size_t i, c;
164
165 if (!fpr)
166 strcpy (buf, _("No Fingerprint"));
167 else {
168 memset (buf, 0, sizeof (buf));
169 for( i=0, c=0; i < strlen (fpr); i++) {
170 dig[0] = fpr[i]; dig[1] = 0;
171 strcat (buf, dig);
172 if (++c == 4) {
173 strcat (buf, " ");
174 c=0;
175 }
176 }
177 }
178 SetDlgItemText (dlg, id, buf);
179 }
180
181
182 /* Fill in all card information from @card. into the corresponding
183 dialog item fields in the dialog @dlg.
184 Return value: 0 on success. */
185 static int
186 card_status (HWND dlg, gpg_card_t card)
187 {
188 static int fprbuf[] = {IDC_CEDIT_FPR1, IDC_CEDIT_FPR2, IDC_CEDIT_FPR3, 0};
189 const char * s;
190 char **attrs;
191 int idx=0, n=0;
192
193 if (!card->aid) {
194 msg_box( dlg, _("No OpenPGP smart card detected."), "WinPT", MB_ERR );
195 return -1;
196 }
197 SetDlgItemText (dlg, IDC_CEDIT_AID, card->aid);
198 SetDlgItemInt (dlg, IDC_CEDIT_SIGCOUNT, card->sig_count, TRUE);
199
200 for( idx=0; fprbuf[idx]; idx++ )
201 print_fpr (dlg, fprbuf[idx], card->fpr[idx]);
202
203 attrs = card_get_items (card, &n);
204 /* XXX: show version as 1.1 not 0101 */
205 for (idx=1; attr_tab[idx].ctlid; idx++) {
206 s = attrs[idx];
207 SetDlgItemText (dlg, attr_tab[idx].ctlid, s && *s? s : attr_tab[idx].err);
208 }
209 free (attrs);
210
211 idx = idx_from_lang (card->lang);
212 SendDlgItemMessage (dlg, IDC_CEDIT_LANG, CB_SETCURSEL, (WPARAM)idx, 0);
213
214 switch (card->sex) {
215 case 'm': idx=0; break;
216 case 'f': idx=1; break;
217 default :
218 case 'u': idx=2; break;
219 }
220 SendDlgItemMessage (dlg, IDC_CEDIT_SEX, CB_SETCURSEL, (WPARAM)idx, 0);
221
222 return 0;
223 }
224
225
226 /* Initialize the enum combox boxes in dialog @dlg. */
227 static void
228 prepare_dialog (HWND dlg)
229 {
230 const char * s;
231 int i;
232
233 for( i=0; (s = sex[i]); i++ )
234 SendDlgItemMessage( dlg, IDC_CEDIT_SEX, CB_ADDSTRING, 0, (LPARAM) s );
235 SendDlgItemMessage( dlg, IDC_CEDIT_SEX, CB_SETCURSEL, 0, 0 );
236 for( i=0; (s = lang[i]); i++ )
237 SendDlgItemMessage( dlg, IDC_CEDIT_LANG, CB_ADDSTRING, 0, (LPARAM)s );
238 SendDlgItemMessage( dlg, IDC_CEDIT_LANG, CB_SETCURSEL, 0, 0 );
239 }
240
241
242
243 /* Return 0 if the given string @str has the proper format. */
244 static int
245 check_string (const char *str, int flags)
246 {
247 size_t i;
248 for( i=0; i < strlen( str ); i++ ) {
249 if( flags & 0x02 && !isalpha( str[i] ) )
250 return -1;
251 }
252 return 0;
253 }
254
255
256 static int
257 do_proc_card_cmds (HWND dlg, struct pin_cb_ctx_s * pincb, gpg_card_t card)
258 {
259 static struct {
260 int id;
261 int cmd;
262 int us_ascii;
263 int changed;
264 } idctl[] = {
265 {IDC_CEDIT_NAME, GPG_EDITCARD_NAME, 1, 0},
266 {IDC_CEDIT_LANG2, GPG_EDITCARD_LANG, 1, 0},
267 {IDC_CEDIT_SEX2, GPG_EDITCARD_SEX, 1|1,0},
268 {IDC_CEDIT_KEYURL,GPG_EDITCARD_KEYURL,1, 0},
269 {IDC_CEDIT_LOGIN, GPG_EDITCARD_LOGIN, 1, 0},
270 {0}
271 };
272 gpgme_error_t err;
273 GpgCardEdit *ce;
274 char buf[256], tmp[128];
275 int errc=0, use_arg2 = 0;
276 int i, id, n=0;
277
278 /* XXX rewrite the entire function */
279 for( i=0; idctl[i].id; i++ ) /* reset */
280 idctl[i].changed = 0;
281
282 if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_LANG2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
283 idctl[1].changed = 1;
284 n++;
285 }
286 if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_SEX2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
287 idctl[2].changed = 1;
288 n++;
289 }
290
291 if( SendDlgItemMessage( dlg, IDC_CEDIT_NAME2, EM_GETMODIFY, 0, 0 ) ) {
292 idctl[0].changed = 1;
293 n++;
294 }
295 for( i=0; (id = idctl[i].id); i++ ) {
296 if( SendDlgItemMessage( dlg, id, EM_GETMODIFY, 0, 0 ) ) {
297 idctl[i].changed = 1;
298 n++;
299 }
300 }
301 if( !pincb || !card ) /* just return the changed elements */
302 return n;
303 if( !n )
304 return 0;
305
306 ce = new GpgCardEdit ();
307 if (!ce)
308 BUG( NULL );
309 ce->setAdminPIN (pincb->apin);
310 ce->setPIN (pincb->upin);
311 for( i=0; idctl[i].id; i++ ) {
312 if( idctl[i].changed ) {
313 GetDlgItemText( dlg, idctl[i].id, buf, sizeof (buf)-1 );
314 if (idctl[i].us_ascii && is_8bit_string (buf)) {
315 msg_box (dlg, _("Only plain ASCII is currently allowed."),
316 _("Card Edit"), MB_ERR);
317 errc--; continue;
318 }
319 if( (idctl[i].us_ascii & 2) && check_string( buf, 2 ) ) {
320 msg_box( dlg, _("Only alphabetic characters are allowed."),
321 _("Card Edit"), MB_ERR );
322 errc--; continue;
323 }
324 if( idctl[i].cmd == GPG_EDITCARD_NAME ) {
325 /* The "name" command actually needs two fields */
326 GetDlgItemText( dlg, IDC_CEDIT_NAME2, tmp, sizeof tmp-1 );
327 use_arg2 = 1;
328 }
329 else
330 use_arg2 = 0;
331 err = ce->doCmd (idctl[i].cmd, buf, use_arg2? tmp : NULL);
332 if (err) {
333 msg_box( dlg, _("Could not modify card attribute."),
334 _("Card Edit"), MB_ERR );
335 errc--;
336 }
337 }
338 }
339 if( !errc ) {
340 /* if the operation(s) succeeded, reset the modify flag for each control */
341 for( i = 0; idctl[i].id; i++ )
342 SendDlgItemMessage( dlg, idctl[i].id, EM_SETMODIFY, (WPARAM)(UINT)FALSE, 0 );
343 msg_box( dlg, _("Card attribute changed."), _("Card Edit"), MB_OK );
344 SetDlgItemText( dlg, IDC_CEDIT_LANG2, "" );
345 SetDlgItemText( dlg, IDC_CEDIT_SEX2, "" );
346 }
347 delete ce;
348 return errc;
349 } /* do_proc_card_cmds */
350
351
352 /* Cleanup pin callback @ctx. */
353 void
354 free_pincb (struct pin_cb_ctx_s *ctx)
355 {
356 if (!ctx)
357 return;
358 free_if_alloc (ctx->info_text);
359 sfree_if_alloc (ctx->upin);
360 sfree_if_alloc (ctx->apin);
361 }
362
363
364 /* Request a PIN from the user. @which decided if the
365 normal PIN or the admin PIN will be requested.
366 @card is used to show some information to the user.
367 @pincb is the actuall callback context.
368 Return value: 0 on success. */
369 static int
370 do_askpin (HWND dlg, int which, gpg_card_t card,
371 struct pin_cb_ctx_s *pincb)
372 {
373 const char * s, * fmt;
374 const char * n1, * n2, * serial;
375 char * p;
376 size_t n;
377
378 if( (which == GPG_EDITCARD_CHAPIN && pincb->apin) ||
379 (which == GPG_EDITCARD_CHUPIN && pincb->upin) )
380 return 0;
381
382 if( which == GPG_EDITCARD_CHAPIN )
383 s = _("Please enter the 'Admin PIN'");
384 else if( which == GPG_EDITCARD_CHUPIN )
385 s = _("Please enter the 'User PIN'");
386 else
387 s = _("Please enter the PIN");
388 pincb->which = which;
389 free_if_alloc( pincb->info_text );
390 if( card ) {
391 fmt = _("%s\nName: %s %s\nSerial-No: %s\n");
392 n1 = card->givenname;
393 n2 = card->surname;
394 if( !n1 || !n2 ) {
395 n1 = "No"; n2 = "Name";
396 }
397 serial = card->serial;
398 if (!serial)
399 serial = "No Serial ID";
400 n = strlen( n1 ) + strlen( n2 ) + strlen( fmt ) + strlen( serial ) + 3;
401 p = pincb->info_text = new char[strlen( s )+n+1 ];
402 if( !p )
403 BUG (0);
404 sprintf( p, fmt, s, n1, n2, serial );
405 }
406 else {
407 p = pincb->info_text = m_strdup (s);
408 if (!p)
409 BUG (0);
410 }
411 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PIN, dlg,
412 pin_cb_dlg_proc, (LPARAM)pincb);
413 if (!pincb->apin && !pincb->upin) {
414 safe_free (pincb->info_text);
415 return -1;
416 }
417 return 0;
418 }
419
420
421 /* Dialog box procedure for card edit. */
422 BOOL CALLBACK
423 card_edit_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
424 {
425 static gpg_card_t card;
426 char tmp[128];
427 size_t n=0;
428
429 switch (msg) {
430 case WM_INITDIALOG:
431 card = (gpg_card_t)lparam;
432 if (!card)
433 BUG (0);
434 prepare_dialog (dlg);
435 if (card_status (dlg, card ))
436 EndDialog (dlg, TRUE);
437 center_window (dlg, NULL);
438 SetForegroundWindow (dlg);
439 return TRUE;
440
441 case WM_DESTROY:
442 free_if_alloc (pincb.info_text);
443 sfree_if_alloc (pincb.apin);
444 sfree_if_alloc (pincb.upin);
445 memset (&pincb, 0, sizeof pincb);
446 break;
447
448 case WM_COMMAND:
449 switch( HIWORD( wparam ) ) {
450 case CBN_KILLFOCUS:
451 case CBN_EDITCHANGE:
452 case CBN_EDITUPDATE:
453 int ctlid = GetDlgCtrlID( (HWND)lparam );
454 int dstid = 0;
455
456 switch (ctlid) {
457 case IDC_CEDIT_LANG: dstid = IDC_CEDIT_LANG2; break;
458 case IDC_CEDIT_SEX: dstid = IDC_CEDIT_SEX2; break;
459 }
460 GetDlgItemText (dlg, ctlid, tmp, 127);
461 SetDlgItemText (dlg, dstid, tmp);
462 break;
463 }
464 switch( LOWORD( wparam ) ) {
465 case IDC_CEDIT_CHPIN:
466 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_CARD_CHPIN, dlg,
467 card_changepin_dlg_proc, NULL );
468 break;
469
470 case IDC_CEDIT_NEWKEYS:
471 if (item_get_text_length (dlg, IDC_CEDIT_FPR1) > 0) {
472 int id = msg_box (dlg,
473 _("This operation will override the keys on the card.\n"
474 "Still proceed?"), _("Card Edit"), MB_WARN|MB_YESNO);
475 if (id == IDNO)
476 return TRUE;
477 }
478 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_KEYGEN,
479 glob_hwnd, card_keygen_dlg_proc, NULL);
480 break;
481
482 case IDOK:
483 n = do_proc_card_cmds( dlg, NULL, NULL );
484 if( n ) {
485 if( do_askpin( dlg, GPG_EDITCARD_CHAPIN, card, &pincb ) )
486 EndDialog( dlg, FALSE );
487 if( do_askpin( dlg, GPG_EDITCARD_CHUPIN, card, &pincb ) )
488 EndDialog( dlg, FALSE );
489 }
490 do_proc_card_cmds( dlg, &pincb, card );
491 free_pincb( &pincb );
492 if( !n )
493 EndDialog( dlg, TRUE );
494 break;
495
496 case IDCANCEL:
497 EndDialog( dlg, FALSE );
498 break;
499 }
500 break;
501 }
502
503 return FALSE;
504 }
505
506
507 static int /* fixme: works only roughly */
508 calc_days (int y2, int m2, int d2,
509 int y1, int m1, int d1)
510
511 {
512 int n=0;
513
514 if ((y2-y1) > 0)
515 n += (y2-y1)*365;
516 if ((m2-m1) > 0)
517 n += (m2-m1)*30;
518 if ((d2-d1) > 0)
519 n += (d2-d1);
520 else if ((d2-d1) < 0)
521 n -= (d1-d2);
522 return n;
523 }
524
525
526 /* Dialog box procedure for the key generation on cards. */
527 BOOL CALLBACK
528 card_keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
529 {
530 static int state = 0;
531 static int pwd_state = 0;
532 gpgme_error_t err;
533 GpgCardEdit *ce;
534 char name[128], email[128], comment[128];
535 char pass[128];
536 int card_flags = GPG_CARDFLAG_NONE;
537 int expires=0, valid;
538 size_t n;
539
540 switch (msg) {
541 case WM_INITDIALOG:
542 state = 0;
543 pwd_state = 1;
544 center_window (dlg, NULL);
545 CheckDlgButton (dlg, IDC_CKEYGEN_REPLACE, BST_CHECKED);
546 CheckDlgButton (dlg, IDC_CKEYGEN_NEVER, BST_CHECKED);
547 CheckDlgButton (dlg, IDC_CKEYGEN_BACKUP, BST_CHECKED);
548 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID), FALSE);
549 SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_ADDSTRING, 0, (LPARAM)(const char*)"RSA");
550 SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_SETCURSEL, 0, 0);
551 SetFocus (GetDlgItem (dlg, IDC_CKEYGEN_NAME));
552 SetForegroundWindow (dlg);
553 return FALSE;
554
555 case WM_COMMAND:
556 if (HIWORD (wparam) == BN_CLICKED) {
557 switch (LOWORD (wparam)) {
558 case IDC_CKEYGEN_NEVER:
559 state ^= 1;
560 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID), state);
561 break;
562
563 case IDC_CKEYGEN_BACKUP:
564 pwd_state ^= 1;
565 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_PASS), pwd_state);
566 break;
567 }
568 }
569
570 switch (LOWORD (wparam)) {
571 case IDOK:
572 n = item_get_text_length (dlg, IDC_CKEYGEN_NAME);
573 if (!n) {
574 msg_box (dlg, _("Please enter your name."), _("Card Edit"), MB_ERR);
575 return TRUE;
576 }
577 if (n < 5) {
578 msg_box (dlg, _("Name must be at least 5 characters long."),
579 _("Card Edit"), MB_INFO);
580 return TRUE;
581 }
582 n = item_get_text_length (dlg, IDC_CKEYGEN_EMAIL);
583 if (!n) {
584 msg_box (dlg, _("Please enter your e-mail address."),
585 _("Card Edit"), MB_ERR);
586 return TRUE;
587 }
588 GetDlgItemText (dlg, IDC_CKEYGEN_NAME, name, sizeof (name)-1);
589 GetDlgItemText (dlg, IDC_CKEYGEN_EMAIL, email, sizeof (email)-1);
590 if (!strchr (email, '@') || n < 3) {
591 msg_box (dlg, _("Please enter a valid e-mail address."),
592 _("Card Edit"), MB_ERR);
593 return TRUE;
594 }
595 n = GetDlgItemText (dlg, IDC_CKEYGEN_PASS, pass, sizeof (pass)-1);
596 if (!n && pwd_state == 1) {
597 msg_box (dlg, _("Please enter an off-card passphrase."), _("Card Edit"), MB_ERR);
598 return TRUE;
599 }
600 n = item_get_text_length (dlg, IDC_CKEYGEN_COMMENT);
601 if (n > 0)
602 GetDlgItemText (dlg, IDC_CKEYGEN_COMMENT, comment, sizeof (comment)-1);
603 if (is_8bit_string (name) ||is_8bit_string (comment)) {
604 msg_box (dlg, _("Please use plain ASCII charset for the fields."),
605 _("Card Edit"), MB_INFO);
606 return TRUE;
607 }
608 memset (&pincb, 0, sizeof (pincb));
609 if (do_askpin (dlg, GPG_EDITCARD_CHAPIN, NULL, &pincb)) {
610 free_pincb (&pincb);
611 return TRUE;
612 }
613 if (do_askpin (dlg, GPG_EDITCARD_CHUPIN, NULL, &pincb)) {
614 free_pincb (&pincb);
615 return TRUE;
616 }
617 ce = new GpgCardEdit ();
618 if (!ce)
619 BUG (0);
620
621 expires = !IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER);
622 if (expires) {
623 SYSTEMTIME st, ct;
624 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_CKEYGEN_VALID), &st);
625 if (!keygen_check_date (&st)) {
626 msg_box (dlg, _("The date you have chosen lies in the past."),
627 _("Card Edit"), MB_ERR);
628 delete ce;
629 return TRUE;
630 }
631 GetSystemTime (&ct);
632 /* XXX this is not very precise */
633 valid = calc_days (st.wYear, st.wMonth, st.wDay,
634 ct.wYear, ct.wMonth, ct.wDay);
635 }
636 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_REPLACE))
637 card_flags |= GPG_CARDFLAG_REPLACE;
638 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP))
639 card_flags |= GPG_CARDFLAG_BAKENC;
640 ce->setKeygenPassphrase (pass);
641 ce->setPIN (pincb.upin);
642 ce->setAdminPIN (pincb.apin);
643
644 SetCursor( LoadCursor (NULL, IDC_WAIT));
645 err = ce->genKey (card_flags, name, email, n? comment: NULL,
646 expires? valid : 0);
647
648 SetCursor (LoadCursor (NULL, IDC_ARROW));
649 /*
650 if (gpgme_err_code (err) == GPG_ERR_CANCELLED)
651 msg_box (dlg, _("Operation was canceled. It seems that there are "
652 "existing\nkeys on the cards. You need to mark the "
653 "'Overwrite' flag."), _("Card Edit"), MB_INFO);
654 else */
655 if (err)
656 msg_box (dlg, "The operation does not succeed.\n"
657 "Please make sure you entered the right PIN's."
658 , _("Card Edit"), MB_ERR);
659 else
660 msg_box (dlg, _("Keys successfully created."),
661 _("Card Edit"), MB_OK);
662 memset (pass, 0, sizeof (pass));
663 free_pincb (&pincb);
664 delete ce;
665 break;
666
667 case IDCANCEL:
668 EndDialog (dlg, FALSE);
669 return FALSE;
670 }
671 break;
672 }
673 return FALSE;
674 }
675
676
677 /* Check if the given pinlen is valid.
678 @which decided what PIN will be used.
679 @pinlen is the pin length entered by the user.
680 Return value: 0 on success. */
681 static int
682 check_pin_len (int which, int flag, int pinlen)
683 {
684 if (!pinlen) {
685 if (flag)
686 msg_box (NULL, _("Please enter the old card PIN."), _("Card Edit"), MB_ERR);
687 else
688 msg_box (NULL, _("Please enter the new card PIN."), _("Card Edit"), MB_ERR);
689 return -1;
690 }
691 if (which == GPG_EDITCARD_CHAPIN
692 && pinlen < 8) {
693 msg_box (NULL, _("Admin PIN must be minimal 8 characters."), _("Card Edit"), MB_ERR);
694 return -1;
695 }
696 if (which == GPG_EDITCARD_CHUPIN
697 && pinlen < 6) {
698 msg_box (NULL, _("PIN must be minimal 6 characters."), _("Card Edit"), MB_ERR);
699 return -1;
700 }
701 return 0;
702 }
703
704 /* Dialog box procedure to change the PIN. */
705 BOOL CALLBACK
706 card_changepin_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
707 {
708 static int hide = 1;
709 gpgme_error_t err;
710 GpgCardEdit *ce;
711 char pold[128], pnew[128], pnew2[128];
712 int which;
713 size_t n;
714
715 switch( msg ) {
716 case WM_INITDIALOG:
717 hide = 1;
718 CheckDlgButton (dlg, IDC_CHPIN_HIDE, BST_CHECKED);
719 center_window (dlg, NULL);
720 CheckDlgButton (dlg, IDC_CHPIN_ISWORK, BST_CHECKED);
721 SetForegroundWindow (dlg);
722 break;
723
724 case WM_COMMAND:
725 if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_CHPIN_HIDE) {
726 HWND hwnd;
727 hide ^= 1;
728 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN);
729 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
730 SetFocus (hwnd);
731 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN2);
732 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
733 SetFocus (hwnd);
734 }
735 switch( LOWORD( wparam ) ) {
736 case IDOK:
737 if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISADMIN))
738 which = GPG_EDITCARD_CHAPIN;
739 else if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISWORK))
740 which = GPG_EDITCARD_CHUPIN;
741 else
742 BUG (0);
743
744 n = item_get_text_length (dlg, IDC_CHPIN_OLDPIN);
745 if (check_pin_len (which, 1, n))
746 return TRUE;
747 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN);
748 if (check_pin_len (which, 0, n))
749 return TRUE;
750 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN2);
751 if (check_pin_len (which, 0, n))
752 return TRUE;
753 GetDlgItemText (dlg, IDC_CHPIN_OLDPIN, pold, sizeof (pold)-1);
754 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN, pnew, sizeof (pnew)-1);
755 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, pnew2, sizeof (pnew2)-1);
756 if (strcmp (pnew, pnew2)) {
757 msg_box (dlg, _("Passphrases do not match. Please try again."), _("Card Edit"), MB_ERR);
758 return TRUE;
759 }
760
761 ce = new GpgCardEdit ();
762 if (!ce)
763 BUG (0);
764 ce->setPIN (pold);
765 ce->setNewPIN (pnew);
766 ce->setType (which);
767
768 err = ce->changePIN ();
769 if (err)
770 msg_box (dlg, gpgme_strerror (err), _("Card Edit"), MB_ERR);
771 else {
772 msg_box( dlg, _("PIN successfully changed."), _("Card Edit"), MB_OK );
773 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
774 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
775 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
776 }
777 delete ce;
778 break;
779
780 case IDCANCEL:
781 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
782 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
783 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
784 EndDialog( dlg, FALSE );
785 break;
786 }
787 break;
788 }
789
790 return FALSE;
791 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26