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

Diff of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.27  
changed lines
  Added in v.48

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26