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

Annotation of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 65 - (hide annotations)
Thu Nov 3 16:55:25 2005 UTC (19 years, 3 months ago) by twoaday
File size: 23366 byte(s)
Minor changes to avoid GCC warnings.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26