/[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 28 by twoaday, Thu Oct 20 12:35:59 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[1]+32, &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 - %s serial no. %s version %s",  
256                 card->card_type, 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  /* Return 0 if the given string @str has the proper format. */      SendDlgItemMessage (dlg, IDC_CEDIT_LANG, CB_SETCURSEL, 0, 0);
280  static int  }
281  check_string (const char *str, int flags)  
282  {  
283      size_t i;  /* Return 0 if the given string @str has the proper format. */
284      for (i=0; i < strlen (str); i++) {  static int
285          if (flags & 0x02 && !isalpha (str[i]))  check_string (const char *str, int flags)
286              return -1;  {
287      }      size_t i;
288      return 0;      for (i=0; i < strlen (str); i++) {
289  }          if (flags & 0x02 && !isalpha (str[i]))
290                return -1;
291        }
292  static int      return 0;
293  do_proc_card_cmds (HWND dlg, struct pin_cb_ctx_s *pincb, gpg_card_t card)  }
294  {  
295      static struct {  
296          int id;  static int
297          int cmd;  do_proc_card_cmds (HWND dlg, struct pin_cb_ctx_s *pincb, gpg_card_t card)
298          int us_ascii;  {
299          int changed;      static struct {
300      } idctl[] = {          int id;
301          {IDC_CEDIT_NAME,  GPG_EDITCARD_NAME,  1,  0},          int cmd;
302          {IDC_CEDIT_LANG2, GPG_EDITCARD_LANG,  1,  0},          int us_ascii;
303          {IDC_CEDIT_SEX2,  GPG_EDITCARD_SEX,   1|1,0},          int changed;
304          {IDC_CEDIT_KEYURL,GPG_EDITCARD_KEYURL,1|4,0},      } idctl[] = {
305          {IDC_CEDIT_LOGIN, GPG_EDITCARD_LOGIN, 1,  0},          {IDC_CEDIT_NAME,  GPG_EDITCARD_NAME,  1,  0},
306          {0}          {IDC_CEDIT_LANG2, GPG_EDITCARD_LANG,  1,  0},
307      };              {IDC_CEDIT_SEX2,  GPG_EDITCARD_SEX,   1|1,0},
308      gpgme_error_t err;          {IDC_CEDIT_KEYURL,GPG_EDITCARD_KEYURL,1|4,0},
309      GpgCardEdit *ce;          {IDC_CEDIT_LOGIN, GPG_EDITCARD_LOGIN, 1,  0},
310      char buf[256], tmp[128];          {0}
311      int errc=0, use_arg2 = 0;      };    
312      int i, id, n=0;      gpgme_error_t err;
313        GpgCardEdit *ce;
314      /* XXX rewrite the entire function */      char buf[256], tmp[128];
315      for( i=0; idctl[i].id; i++ ) /* reset */      int errc=0, use_arg2 = 0;
316          idctl[i].changed = 0;      int i, id, n=0;
317        
318      if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_LANG2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {      /* XXX rewrite the entire function */
319          idctl[1].changed = 1;      for( i=0; idctl[i].id; i++ ) /* reset */
320          n++;          idctl[i].changed = 0;
321      }      
322      if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_SEX2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {      if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_LANG2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
323          idctl[2].changed = 1;          idctl[1].changed = 1;
324          n++;          n++;
325      }      }
326            if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_SEX2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
327      if( SendDlgItemMessage( dlg, IDC_CEDIT_NAME2, EM_GETMODIFY, 0, 0 ) ) {          idctl[2].changed = 1;
328          idctl[0].changed = 1;          n++;
329          n++;      }
330      }      
331      for( i=0; (id = idctl[i].id); i++ ) {      if( SendDlgItemMessage( dlg, IDC_CEDIT_NAME2, EM_GETMODIFY, 0, 0 ) ) {
332          if( SendDlgItemMessage( dlg, id, EM_GETMODIFY, 0, 0 ) ) {          idctl[0].changed = 1;
333              idctl[i].changed = 1;          n++;
334              n++;      }
335          }      for( i=0; (id = idctl[i].id); i++ ) {
336      }          if( SendDlgItemMessage( dlg, id, EM_GETMODIFY, 0, 0 ) ) {
337      if (!pincb || !card) /* just return the changed elements */              idctl[i].changed = 1;
338          return n;              n++;
339      if (!n)          }
340          return 0;      }
341      if (!pincb->apin) {      if (!pincb || !card) /* just return the changed elements */
342          msg_box (dlg, _("No PINs found."), _("Card Edit"), MB_ERR);          return n;
343          return 0;      if (!n)
344      }          return 0;
345            if (!pincb->apin) {
346      ce = new GpgCardEdit ();          msg_box (dlg, _("No PINs found."), _("Card Edit"), MB_ERR);
347      if (!ce)          return 0;
348          BUG (NULL);      }
349      ce->setAdminPIN (pincb->apin);      
350      /*ce->setPIN (pincb->upin);*/      ce = new GpgCardEdit ();
351      for( i=0; idctl[i].id; i++ ) {      if (!ce)
352          if( idctl[i].changed ) {          BUG (NULL);
353              GetDlgItemText( dlg, idctl[i].id, buf, sizeof (buf)-1 );      ce->setAdminPIN (pincb->apin);
354              if (idctl[i].us_ascii && is_8bit_string (buf)) {      /*ce->setPIN (pincb->upin);*/
355                  msg_box (dlg, _("Only plain ASCII is currently allowed."),      for( i=0; idctl[i].id; i++ ) {
356                           _("Card Edit"), MB_ERR);          if( idctl[i].changed ) {
357                  errc--; continue;              GetDlgItemText( dlg, idctl[i].id, buf, sizeof (buf)-1 );
358              }              if (idctl[i].us_ascii && is_8bit_string (buf)) {
359              if( (idctl[i].us_ascii & 2) && check_string( buf, 2 ) ) {                  msg_box (dlg, _("Only plain ASCII is currently allowed."),
360                  msg_box( dlg, _("Only alphabetic characters are allowed."),                           _("Card Edit"), MB_ERR);
361                           _("Card Edit"), MB_ERR );                  errc--; continue;
362                  errc--; continue;              }
363              }              if( (idctl[i].us_ascii & 2) && check_string( buf, 2 ) ) {
364              if ((idctl[i].us_ascii & 4) &&                  msg_box( dlg, _("Only alphabetic characters are allowed."),
365                  (!strchr (buf, ':') || !strstr (buf, "//"))) {                           _("Card Edit"), MB_ERR );
366                  /* XXX: better URL check. */                  errc--; continue;
367                  msg_box (dlg, _("Invalid URL."), _("Card Edit"), MB_ERR);              }
368                  errc--; continue;              if ((idctl[i].us_ascii & 4) &&
369              }                  (!strchr (buf, ':') || !strstr (buf, "//"))) {
370              if( idctl[i].cmd == GPG_EDITCARD_NAME ) {                  /* XXX: better URL check. */
371                  /* The "name" command actually needs two fields */                  msg_box (dlg, _("Invalid URL."), _("Card Edit"), MB_ERR);
372                  GetDlgItemText( dlg, IDC_CEDIT_NAME2, tmp, sizeof tmp-1 );                  errc--; continue;
373                  use_arg2 = 1;              }
374              }              if( idctl[i].cmd == GPG_EDITCARD_NAME ) {
375              else                  /* The "name" command actually needs two fields */
376                  use_arg2 = 0;                  GetDlgItemText( dlg, IDC_CEDIT_NAME2, tmp, sizeof tmp-1 );
377              err = ce->doCmd (idctl[i].cmd, buf, use_arg2? tmp : NULL);                  use_arg2 = 1;
378              if (err) {              }
379                  log_box (_("Card Edit"), MB_ERR,              else
380                           _("Could not modify card attribute: %s"),                  use_arg2 = 0;
381                           gpgme_strerror (err));              err = ce->doCmd (idctl[i].cmd, buf, use_arg2? tmp : NULL);
382                  errc--;              if (err) {
383                  /* If no card is inserted, we leave the loop. */                  log_box (_("Card Edit"), MB_ERR,
384                  if (gpgme_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)                           _("Could not modify card attribute: %s"),
385                      break;                           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      if (!errc) {                      break;
390          /* if the operation(s) succeeded, reset the modify flag for each control */              }
391          for( i = 0; idctl[i].id; i++ )          }
392              SendDlgItemMessage( dlg, idctl[i].id, EM_SETMODIFY, (WPARAM)(UINT)FALSE, 0 );      }
393          msg_box( dlg, _("Card attribute changed."), _("Card Edit"), MB_OK );      if (!errc) {
394          SetDlgItemText( dlg, IDC_CEDIT_LANG2, "" );          /* if the operation(s) succeeded, reset the modify flag for each control */
395          SetDlgItemText( dlg, IDC_CEDIT_SEX2, "" );          for( i = 0; idctl[i].id; i++ )
396      }              SendDlgItemMessage( dlg, idctl[i].id, EM_SETMODIFY, (WPARAM)(UINT)FALSE, 0 );
397      delete ce;          msg_box( dlg, _("Card attribute changed."), _("Card Edit"), MB_OK );
398      return errc;          SetDlgItemText( dlg, IDC_CEDIT_LANG2, "" );
399  } /* do_proc_card_cmds */          SetDlgItemText( dlg, IDC_CEDIT_SEX2, "" );
400        }
401        delete ce;
402  /* Cleanup pin callback @ctx. */      return errc;
403  void  } /* do_proc_card_cmds */
404  free_pincb (struct pin_cb_ctx_s *ctx)  
405  {  
406      if (!ctx)  /* Cleanup pin callback @ctx. */
407          return;  void
408      free_if_alloc (ctx->info_text);  free_pincb (struct pin_cb_ctx_s *ctx)
409      sfree_if_alloc (ctx->upin);  {
410      sfree_if_alloc (ctx->apin);      if (!ctx)
411  }          return;
412        free_if_alloc (ctx->info_text);
413        sfree_if_alloc (ctx->upin);
414  /* Request a PIN from the user. @which decided if the      sfree_if_alloc (ctx->apin);
415     normal PIN or the admin PIN will be requested.  }
416     @card is used to show some information to the user.  
417     @pincb is the actuall callback context.  
418     Return value: 0 on success. */  /* Request a PIN from the user. @which decided if the
419  static int     normal PIN or the admin PIN will be requested.
420  do_askpin (HWND dlg, int which, gpg_card_t card,     @card is used to show some information to the user.
421             struct pin_cb_ctx_s *pincb)     @pincb is the actuall callback context.
422  {     Return value: 0 on success. */
423      const char * s, * fmt;  static int
424      const char * n1, * n2, * serial;  do_askpin (HWND dlg, int which, gpg_card_t card,
425      char * p;             struct pin_cb_ctx_s *pincb)
426      size_t n;  {
427        const char * s, * fmt;
428      if( (which == CARD_ADMIN_PIN && pincb->apin) ||      const char * n1, * n2, * serial;
429          (which == CARD_USER_PIN && pincb->upin) )      char * p;
430          return 0;      size_t n;
431        
432      if (which == CARD_ADMIN_PIN)      if( (which == CARD_ADMIN_PIN && pincb->apin) ||
433          s = _("Please enter the 'Admin PIN'");          (which == CARD_USER_PIN && pincb->upin) )
434      else if (which == CARD_USER_PIN)          return 0;
435          s = _("Please enter the 'User PIN'");      
436      else      if (which == CARD_ADMIN_PIN)
437          s = _("Please enter the PIN");          s = _("Please enter the 'Admin PIN'");
438      pincb->which = which;      else if (which == CARD_USER_PIN)
439      free_if_alloc( pincb->info_text );          s = _("Please enter the 'User PIN'");
440      if( card ) {      else
441          fmt = _("%s\nName: %s %s\nSerial-No: %s\n");          s = _("Please enter the PIN");
442          n1 = card->givenname;      pincb->which = which;
443          n2 = card->surname;      free_if_alloc( pincb->info_text );
444          if( !n1 || !n2 ) {      if( card ) {
445              n1 = "No"; n2 = "Name";          fmt = _("%s\nName: %s %s\nSerial-No: %s\n");
446          }              n1 = card->givenname;
447          serial = card->serial;          n2 = card->surname;
448          if (!serial)          if( !n1 || !n2 ) {
449              serial = "No Serial ID";              n1 = "No"; n2 = "Name";
450          n = strlen( n1 ) + strlen( n2 ) + strlen( fmt ) + strlen( serial ) + 3;          }    
451          p = pincb->info_text = new char[strlen( s )+n+1 ];          serial = card->serial;
452          if( !p )          if (!serial)
453              BUG (0);              serial = "No Serial ID";
454          sprintf( p, fmt, s, n1, n2, serial );          n = strlen( n1 ) + strlen( n2 ) + strlen( fmt ) + strlen( serial ) + 3;
455      }          p = pincb->info_text = new char[strlen( s )+n+1 ];
456      else {          if( !p )
457          p = pincb->info_text = m_strdup (s);              BUG (0);
458          if (!p)          sprintf( p, fmt, s, n1, n2, serial );
459              BUG (0);      }
460      }      else {
461      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PIN, dlg,          p = pincb->info_text = m_strdup (s);
462                      pin_cb_dlg_proc, (LPARAM)pincb);          if (!p)
463      if (!pincb->apin && !pincb->upin) {              BUG (0);
464          safe_free (pincb->info_text);      }
465          return -1;      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PIN, dlg,
466      }                      pin_cb_dlg_proc, (LPARAM)pincb);
467      return 0;      if (!pincb->apin && !pincb->upin) {
468  }          safe_free (pincb->info_text);
469            return -1;
470        }
471  /* Dialog box procedure for card edit. */      return 0;
472  BOOL CALLBACK  }
473  card_edit_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
474  {  
475      static gpg_card_t card;      /* Dialog box procedure for card edit. */
476      char tmp[128];  BOOL CALLBACK
477      size_t n=0;  card_edit_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
478    {
479      switch (msg) {      static gpg_card_t card;    
480      case WM_INITDIALOG:      char tmp[128];
481          card = (gpg_card_t)lparam;      size_t n=0;
482          if (!card)  
483              BUG (0);      switch (msg) {
484          prepare_dialog (dlg);      case WM_INITDIALOG:
485          if (card_status (dlg, card ))          card = (gpg_card_t)lparam;
486              EndDialog (dlg, TRUE);          if (!card)
487          center_window (dlg, NULL);              BUG (0);
488          SetForegroundWindow (dlg);          prepare_dialog (dlg);
489          return TRUE;          if (card_status (dlg, card ))
490                EndDialog (dlg, TRUE);
491      case WM_DESTROY:          center_window (dlg, NULL);
492          free_pincb (&pincb);          SetForegroundWindow (dlg);
493          memset (&pincb, 0, sizeof pincb);          return TRUE;
494          break;  
495        case WM_DESTROY:
496      case WM_COMMAND:          free_pincb (&pincb);
497          switch( HIWORD( wparam ) ) {          memset (&pincb, 0, sizeof pincb);
498          case CBN_KILLFOCUS:          break;
499          case CBN_EDITCHANGE:  
500          case CBN_EDITUPDATE:      case WM_COMMAND:
501              int ctlid = GetDlgCtrlID( (HWND)lparam );          switch( HIWORD( wparam ) ) {
502              int dstid = 0;          case CBN_KILLFOCUS:
503            case CBN_EDITCHANGE:
504              switch (ctlid) {          case CBN_EDITUPDATE:
505              case IDC_CEDIT_LANG: dstid = IDC_CEDIT_LANG2; break;              int ctlid = GetDlgCtrlID( (HWND)lparam );
506              case IDC_CEDIT_SEX:  dstid = IDC_CEDIT_SEX2; break;              int dstid = 0;
507              }        
508              GetDlgItemText (dlg, ctlid, tmp, sizeof (tmp)-1);              switch (ctlid) {
509              SetDlgItemText (dlg, dstid, tmp);              case IDC_CEDIT_LANG: dstid = IDC_CEDIT_LANG2; break;
510              break;              case IDC_CEDIT_SEX:  dstid = IDC_CEDIT_SEX2; break;
511          }              }      
512          switch (LOWORD (wparam)) {              GetDlgItemText (dlg, ctlid, tmp, sizeof (tmp)-1);
513          case IDC_CEDIT_CHPIN:              SetDlgItemText (dlg, dstid, tmp);
514              DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_CARD_CHPIN, dlg,              break;
515                              card_changepin_dlg_proc, NULL );          }
516              break;          switch (LOWORD (wparam)) {
517            case IDC_CEDIT_CHPIN:
518          case IDC_CEDIT_NEWKEYS:              DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_CARD_CHPIN, dlg,
519              if (item_get_text_length (dlg, IDC_CEDIT_FPR1) > 0) {                              card_changepin_dlg_proc, NULL );
520                  int id = msg_box (dlg,              break;
521                      _("This operation will override the keys on the card.\n"  
522                        "Still proceed?"), _("Card Edit"), MB_WARN|MB_YESNO);          case IDC_CEDIT_NEWKEYS:
523                  if (id == IDNO)              if (item_get_text_length (dlg, IDC_CEDIT_FPR1) > 0) {
524                      return TRUE;                  int id = msg_box (dlg,
525              }                      _("This operation will override the keys on the card.\n"
526              DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_KEYGEN,                        "Still proceed?"), _("Card Edit"), MB_WARN|MB_YESNO);
527                              glob_hwnd, card_keygen_dlg_proc, NULL);                  if (id == IDNO)
528              break;                      return TRUE;
529                }
530          case IDOK:              DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_KEYGEN,
531              n = do_proc_card_cmds (dlg, NULL, NULL);                              glob_hwnd, card_keygen_dlg_proc, NULL);
532              if (n) {              break;
533                  if (do_askpin (dlg, CARD_ADMIN_PIN, card, &pincb))  
534                      EndDialog (dlg, FALSE);          case IDOK:
535              }              n = do_proc_card_cmds (dlg, NULL, NULL);
536              do_proc_card_cmds (dlg, &pincb, card);              if (n) {
537              free_pincb (&pincb);                  if (do_askpin (dlg, CARD_ADMIN_PIN, card, &pincb))
538              if (!n)                      EndDialog (dlg, FALSE);
539                  EndDialog (dlg, TRUE);              }
540              break;              do_proc_card_cmds (dlg, &pincb, card);
541                free_pincb (&pincb);
542          case IDCANCEL:              if (!n)
543              EndDialog( dlg, FALSE );                  EndDialog (dlg, TRUE);
544              break;              break;
545          }  
546          break;          case IDCANCEL:
547      }              EndDialog( dlg, FALSE );
548                break;
549      return FALSE;          }
550  }          break;
551        }
552    
553  static int /* fixme: works only roughly */      return FALSE;
554  calc_days (int y2, int m2, int d2,  }
555             int y1, int m1, int d1)  
556    
557  {  static int /* fixme: works only roughly */
558      int n=0;  calc_days (int y2, int m2, int d2,
559                   int y1, int m1, int d1)
560      if ((y2-y1) > 0)  
561          n += (y2-y1)*365;  {
562      if ((m2-m1) > 0)      int n=0;
563          n += (m2-m1)*30;      
564      if ((d2-d1) > 0)      if ((y2-y1) > 0)
565          n += (d2-d1);          n += (y2-y1)*365;
566      else if ((d2-d1) < 0)      if ((m2-m1) > 0)
567          n -= (d1-d2);          n += (m2-m1)*30;
568      return n;      if ((d2-d1) > 0)
569  }          n += (d2-d1);
570        else if ((d2-d1) < 0)
571            n -= (d1-d2);
572  /* Dialog box procedure for the key generation on cards. */      return n;
573  BOOL CALLBACK  }
574  card_keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)  
575  {  
576      gpgme_error_t err;  /* Dialog box procedure for the key generation on cards. */
577      GpgCardEdit *ce;  BOOL CALLBACK
578      char name[128], email[128], comment[128];  card_keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
579      char pass[128];  {
580      int card_flags = GPG_CARDFLAG_NONE;      gpgme_error_t err;
581      int expires=0, valid;      GpgCardEdit *ce;
582      size_t n;      char name[128], email[128], comment[128];
583        char pass[128];
584      switch (msg) {      int card_flags = GPG_CARDFLAG_NONE;
585      case WM_INITDIALOG:      int expires=0, valid;
586          center_window (dlg, NULL);      size_t n;
587          CheckDlgButton (dlg, IDC_CKEYGEN_REPLACE, BST_CHECKED);  
588          CheckDlgButton (dlg, IDC_CKEYGEN_NEVER, BST_CHECKED);      switch (msg) {
589          CheckDlgButton (dlg, IDC_CKEYGEN_BACKUP, BST_CHECKED);      case WM_INITDIALOG:
590          EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID), FALSE);          center_window (dlg, NULL);
591          SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_ADDSTRING, 0,          CheckDlgButton (dlg, IDC_CKEYGEN_REPLACE, BST_CHECKED);
592                              (LPARAM)(const char*)"RSA");          CheckDlgButton (dlg, IDC_CKEYGEN_NEVER, BST_CHECKED);
593          SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_SETCURSEL, 0, 0);          CheckDlgButton (dlg, IDC_CKEYGEN_BACKUP, BST_CHECKED);
594          SetFocus (GetDlgItem (dlg, IDC_CKEYGEN_NAME));          EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID), FALSE);
595          SetForegroundWindow (dlg);          SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_ADDSTRING, 0,
596          return FALSE;                              (LPARAM)(const char*)"RSA");
597            SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_SETCURSEL, 0, 0);
598      case WM_SYSCOMMAND:          SetFocus (GetDlgItem (dlg, IDC_CKEYGEN_NAME));
599          if (LOWORD (wparam) == SC_CLOSE)          SetForegroundWindow (dlg);
600              EndDialog (dlg, TRUE);          SetDlgItemText (dlg, IDC_CKEYGEN_NAMEINF, _("&Name"));
601          return FALSE;          SetDlgItemText (dlg, IDC_CKEYGEN_CMTINF, _("&Comment (optional)"));
602            SetDlgItemText (dlg, IDC_CKEYGEN_EXPDATEINF, _("&Expire date"));
603      case WM_COMMAND:          SetDlgItemText (dlg, IDC_CKEYGEN_PWDINF, _("Off-card passphrase"));
604          if (HIWORD (wparam) == BN_CLICKED &&          SetDlgItemText (dlg, IDC_CKEYGEN_NEVER, _("&Never"));
605              (LOWORD (wparam) == IDC_CKEYGEN_BACKUP) ||          SetDlgItemText (dlg, IDC_CKEYGEN_MAILINF, _("Email &address"));
606               LOWORD (wparam) == IDC_CKEYGEN_NEVER) {          SetWindowText (dlg, _("Card Key Generation"));
607              EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID),          return FALSE;
608                            IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER)? 0: 1);  
609              EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_PASS),      case WM_SYSCOMMAND:
610                            IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)? 1 : 0);          if (LOWORD (wparam) == SC_CLOSE)
611              return TRUE;              EndDialog (dlg, TRUE);
612          }                return FALSE;
613    
614          switch (LOWORD (wparam)) {      case WM_COMMAND:
615          case IDOK:          if (HIWORD (wparam) == BN_CLICKED &&
616              n = item_get_text_length (dlg, IDC_CKEYGEN_NAME);              (LOWORD (wparam) == IDC_CKEYGEN_BACKUP) ||
617              if (!n) {               LOWORD (wparam) == IDC_CKEYGEN_NEVER) {
618                  msg_box (dlg, _("Please enter your name."), _("Card Edit"), MB_ERR);              EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID),
619                  return TRUE;                            IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER)? 0: 1);
620              }              EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_PASS),
621              if (n < 5) {                            IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)? 1 : 0);
622                  msg_box (dlg, _("Name must be at least 5 characters long."),              return TRUE;
623                           _("Card Edit"), MB_INFO);          }      
624                  return TRUE;  
625              }          switch (LOWORD (wparam)) {
626              n = item_get_text_length (dlg, IDC_CKEYGEN_EMAIL);          case IDOK:
627              if (!n) {              n = item_get_text_length (dlg, IDC_CKEYGEN_NAME);
628                  msg_box (dlg, _("Please enter your e-mail address."),              if (!n) {
629                           _("Card Edit"), MB_ERR);                  msg_box (dlg, _("Please enter your name."), _("Card Edit"), MB_ERR);
630                  return TRUE;                  return TRUE;
631              }              }
632              GetDlgItemText (dlg, IDC_CKEYGEN_NAME, name, sizeof (name)-1);              if (n < 5) {
633              GetDlgItemText (dlg, IDC_CKEYGEN_EMAIL, email, sizeof (email)-1);                  msg_box (dlg, _("Name must be at least 5 characters long."),
634              if (!strchr (email, '@') || n < 3) {                           _("Card Edit"), MB_INFO);
635                  msg_box (dlg, _("Please enter a valid e-mail address."),                  return TRUE;
636                           _("Card Edit"), MB_ERR);              }
637                  return TRUE;              n = item_get_text_length (dlg, IDC_CKEYGEN_EMAIL);
638              }              if (!n) {
639              n = GetDlgItemText (dlg, IDC_CKEYGEN_PASS, pass, sizeof (pass)-1);                  msg_box (dlg, _("Please enter your e-mail address."),
640              if (!n && IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)) {                           _("Card Edit"), MB_ERR);
641                  msg_box (dlg, _("Please enter an off-card passphrase."), _("Card Edit"), MB_ERR);                  return TRUE;
642                  return TRUE;              }
643              }              GetDlgItemText (dlg, IDC_CKEYGEN_NAME, name, sizeof (name)-1);
644              n = item_get_text_length (dlg, IDC_CKEYGEN_COMMENT);              GetDlgItemText (dlg, IDC_CKEYGEN_EMAIL, email, sizeof (email)-1);
645              if (n > 0)              if (!strchr (email, '@') || n < 3) {
646                  GetDlgItemText (dlg, IDC_CKEYGEN_COMMENT, comment, sizeof (comment)-1);                  msg_box (dlg, _("Please enter a valid e-mail address."),
647              if (is_8bit_string (name) || n > 0 && is_8bit_string (comment)) {                           _("Card Edit"), MB_ERR);
648                  msg_box (dlg, _("Please use plain ASCII charset for the fields."),                  return TRUE;
649                           _("Card Edit"), MB_INFO);              }
650                  return TRUE;              n = GetDlgItemText (dlg, IDC_CKEYGEN_PASS, pass, sizeof (pass)-1);
651              }              if (!n && IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)) {
652              memset (&pincb, 0, sizeof (pincb));                  msg_box (dlg, _("Please enter an off-card passphrase."), _("Card Edit"), MB_ERR);
653              if (do_askpin (dlg, CARD_ADMIN_PIN, NULL, &pincb)) {                  return TRUE;
654                  free_pincb (&pincb);              }
655                  return TRUE;              n = item_get_text_length (dlg, IDC_CKEYGEN_COMMENT);
656              }              if (n > 0)
657              if (do_askpin (dlg, CARD_USER_PIN, NULL, &pincb)) {                  GetDlgItemText (dlg, IDC_CKEYGEN_COMMENT, comment, sizeof (comment)-1);
658                  free_pincb (&pincb);              if (is_8bit_string (name) || n > 0 && is_8bit_string (comment)) {
659                  return TRUE;                  msg_box (dlg, _("Please use plain ASCII charset for the fields."),
660              }                           _("Card Edit"), MB_INFO);
661              ce = new GpgCardEdit ();                  return TRUE;
662              if (!ce)              }
663                  BUG (0);              memset (&pincb, 0, sizeof (pincb));
664                            if (do_askpin (dlg, CARD_ADMIN_PIN, NULL, &pincb)) {
665              expires = !IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER);                  free_pincb (&pincb);
666              if (expires) {                  return TRUE;
667                  SYSTEMTIME st, ct;              }
668                  DateTime_GetSystemtime (GetDlgItem (dlg, IDC_CKEYGEN_VALID), &st);              if (do_askpin (dlg, CARD_USER_PIN, NULL, &pincb)) {
669                  if (!keygen_check_date (&st)) {                  free_pincb (&pincb);
670                      msg_box (dlg, _("The date you have chosen lies in the past."),                  return TRUE;
671                               _("Card Edit"), MB_ERR);              }
672                      free_pincb (&pincb);              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_CANCELED)                  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.28  
changed lines
  Added in v.48

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26