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

Diff of /trunk/Src/wptCardEdit.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 69 by twoaday, Sat Nov 5 12:28:12 2005 UTC
# Line 1  Line 1 
1  /* wptCardEdit.cpp - OpenPGP editing interface  /* wptCardEdit.cpp - OpenPGP editing interface
2   *      Copyright (C) 2005 Timo Schulz   *      Copyright (C) 2005 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
7   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
8   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <windows.h>  #ifdef HAVE_CONFIG_H
22  #include <time.h>  #include <config.h>
23    #endif
24  #include "gpgme.h"  
25  #include "wptCard.h"  #include <windows.h>
26  #include "wptCardEdit.h"  #include <time.h>
27  #include "wptGPG.h"  
28  #include "wptErrors.h"  #include "gpgme.h"
29    #include "wptCard.h"
30  /* Create a new Smartcard context. */  #include "wptCardEdit.h"
31  static gpgme_error_t  #include "wptGPG.h"
32  gpg_card_new (gpg_card_t *ret_card)  #include "wptErrors.h"
33  {  
34      gpg_card_t c;  /* Create a new Smartcard context. */
35    static gpgme_error_t
36      if (!ret_card)  gpg_card_new (gpg_card_t *ret_card)
37          return gpg_error (GPG_ERR_INV_ARG);  {
38      *ret_card = NULL;      gpg_card_t c;
39      c = (gpg_card_t)calloc (1, sizeof *c);  
40      if (!c)      if (!ret_card)
41          return gpg_error (GPG_ERR_ENOMEM);          return gpg_error (GPG_ERR_INV_ARG);
42      *ret_card = c;      *ret_card = NULL;
43      return 0;      c = (gpg_card_t)calloc (1, sizeof *c);
44  }      if (!c)
45            return gpg_error (GPG_ERR_ENOMEM);
46        *ret_card = c;
47  /* Release an existing Smartcard context. @card. */      return 0;
48  void  }
49  gpg_card_release (gpg_card_t card)  
50  {  
51      int i;  /* Release an existing Smartcard context. @card. */
52    void
53      if (!card)  gpg_card_release (gpg_card_t card)
54          return;  {
55      if (card->aid)      int i;
56          free (card->aid);    
57      if (card->version)      if (!card)
58          free (card->version);          return;
59      if (card->lang)      if (card->aid)
60          free (card->lang);          free (card->aid);  
61      if (card->login)      if (card->version)
62          free (card->login);          free (card->version);
63      for (i=0; i < 3; i++) {      if (card->lang)
64          if (card->fpr[i])          free (card->lang);
65              free (card->fpr[i]);      if (card->login)
66          if (card->ca_fpr[i])          free (card->login);
67              free (card->ca_fpr[i]);      for (i=0; i < 3; i++) {
68          if (card->fpr_created_str[i])          if (card->fpr[i])
69              free (card->fpr_created_str[i]);              free (card->fpr[i]);
70      }          if (card->ca_fpr[i])
71      if (card->surname)              free (card->ca_fpr[i]);
72          free (card->surname);          if (card->fpr_created_str[i])
73      if (card->givenname)              free (card->fpr_created_str[i]);
74          free (card->givenname);      }
75      if (card->serial)      if (card->surname)
76          free (card->serial);          free (card->surname);
77      if (card->vendor)      if (card->givenname)
78          free (card->vendor);          free (card->givenname);
79      if (card->url)      if (card->serial)
80          free (card->url);          free (card->serial);
81      if (card->card_type)      if (card->vendor)
82          free (card->card_type);          free (card->vendor);
83      free (card);      if (card->url)
84            free (card->url);
85  }      if (card->card_type)
86            free (card->card_type);
87        free (card);
88  /* Parse the timestamp @long_ts and return a string  
89     representation of it (format: YYYY-DD-MM HH:MM:SS). */  }
90  static char*  
91  get_str_timestamp (long long_ts)  
92  {  /* Parse the timestamp @long_ts and return a string
93      struct tm *tm;     representation of it (format: YYYY-DD-MM HH:MM:SS). */
94      char *p, *fmt;  static char*
95    get_str_timestamp (long long_ts)
96      tm = localtime (&long_ts);  {
97      fmt = "%04d-%02d-%02d %02d:%02d:%02d";      struct tm *tm;
98      p = (char*)calloc (1, strlen (fmt)+32);      char *p, *fmt;
99      if (!p)  
100          abort ();      tm = localtime (&long_ts);
101      sprintf (p, fmt,      fmt = "%04d-%02d-%02d %02d:%02d:%02d";
102               tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,      p = (char*)calloc (1, strlen (fmt)+32);
103               tm->tm_hour, tm->tm_min, tm->tm_sec);      if (!p)
104      return p;          abort ();
105  }      sprintf (p, fmt,
106                 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
107                 tm->tm_hour, tm->tm_min, tm->tm_sec);
108  /* Colon handler for parsing the GPG card colon output. */      return p;
109  static gpgme_error_t  }
110  statuscard_colon_handler (gpg_card_t card, char * line)  
111  {  
112      enum rectype_t {  /* Colon handler for parsing the GPG card colon output. */
113          CARD_None = 0,  static gpgme_error_t
114          CARD_AID,  statuscard_colon_handler (gpg_card_t card, char * line)
115          CARD_Version,  {
116          CARD_Vendor,      enum rectype_t {
117          CARD_Serial,          CARD_None = 0,
118          CARD_Name,          CARD_AID,
119          CARD_Lang,          CARD_Version,
120          CARD_Sex,          CARD_Vendor,
121          CARD_Url,          CARD_Serial,
122          CARD_Login,          CARD_Name,
123          CARD_MaxPinLen,          CARD_Lang,
124          CARD_SigCount,          CARD_Sex,
125          CARD_CAFpr,          CARD_Url,
126          CARD_Fpr,          CARD_Login,
127          CARD_FprTime          CARD_MaxPinLen,
128      };          CARD_SigCount,
129      enum rectype_t rectype;              CARD_CAFpr,
130      char *p, *pend;          CARD_Fpr,
131      int field = 0;          CARD_FprTime
132        };
133      if (!line)      enum rectype_t rectype = (rectype_t)0;
134          return gpg_error (GPG_ERR_EOF);      char *p, *pend;
135        int field = 0;
136      for (p = line; p; p = pend) {  
137          field++;      if (!line)
138          pend = strchr (p, ':');          return gpg_error (GPG_ERR_EOF);
139          if (pend)  
140              *pend++ = 0;      for (p = line; p; p = pend) {
141            field++;
142          if (field == 1) {          pend = strchr (p, ':');
143              if (!strcmp (p, "AID"))          if (pend)
144                  rectype = CARD_AID;              *pend++ = 0;
145              else if( !strcmp( p, "version" ) )  
146                  rectype = CARD_Version;          if (field == 1) {
147              else if( !strcmp( p, "vendor" ) )              if (!strcmp (p, "AID"))
148                  rectype = CARD_Vendor;                  rectype = CARD_AID;
149              else if( !strcmp( p, "serial" ) )              else if( !strcmp( p, "version" ) )
150                  rectype = CARD_Serial;                  rectype = CARD_Version;
151              else if( !strcmp( p, "name" ) )              else if( !strcmp( p, "vendor" ) )
152                  rectype = CARD_Name;                  rectype = CARD_Vendor;
153              else if( !strcmp( p, "lang" ) )              else if( !strcmp( p, "serial" ) )
154                  rectype = CARD_Lang;                  rectype = CARD_Serial;
155              else if( !strcmp( p, "sex" ) )              else if( !strcmp( p, "name" ) )
156                  rectype = CARD_Sex;                  rectype = CARD_Name;
157              else if( !strcmp( p, "url" ) )              else if( !strcmp( p, "lang" ) )
158                  rectype = CARD_Url;                  rectype = CARD_Lang;
159              else if( !strcmp( p, "login" ) )              else if( !strcmp( p, "sex" ) )
160                  rectype = CARD_Login;                  rectype = CARD_Sex;
161              else if( !strcmp( p, "maxpinlen" ) )              else if( !strcmp( p, "url" ) )
162                  rectype = CARD_MaxPinLen;                  rectype = CARD_Url;
163              else if( !strcmp( p, "sigcount" ) )              else if( !strcmp( p, "login" ) )
164                  rectype = CARD_SigCount;                  rectype = CARD_Login;
165              else if (!strcmp (p, "cafpr"))              else if( !strcmp( p, "maxpinlen" ) )
166                  rectype = CARD_CAFpr;                  rectype = CARD_MaxPinLen;
167              else if (!strcmp (p, "fpr"))              else if( !strcmp( p, "sigcount" ) )
168                  rectype = CARD_Fpr;                          rectype = CARD_SigCount;
169              else if (!strcmp (p, "fprtime"))              else if (!strcmp (p, "cafpr"))
170                  rectype = CARD_FprTime;                  rectype = CARD_CAFpr;
171              else              else if (!strcmp (p, "fpr"))
172                  rectype = CARD_None;                  rectype = CARD_Fpr;        
173          }              else if (!strcmp (p, "fprtime"))
174          switch (rectype) {                  rectype = CARD_FprTime;
175          case CARD_AID:              else
176              if (field == 2) {                  rectype = CARD_None;
177                  card->aid = strdup (p);          }
178                  if (!card->aid)          switch (rectype) {
179                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_AID:
180              }              if (field == 2) {
181              else if (field == 3) {                  card->aid = strdup (p);
182                  card->card_type = strdup (p);                  if (!card->aid)
183                  if (!card->card_type)                      return gpg_error (GPG_ERR_ENOMEM);
184                      return gpg_error (GPG_ERR_ENOMEM);              }
185              }              else if (field == 3) {
186              break;                  card->card_type = strdup (p);
187                    if (!card->card_type)
188          case CARD_Version:                      return gpg_error (GPG_ERR_ENOMEM);
189              if (field == 2) {              }
190                  card->version = strdup (p);              break;
191                  if (!card->version)  
192                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Version:
193              }              if (field == 2) {
194              break;                  card->version = strdup (p);
195                    if (!card->version)
196          case CARD_Vendor:                      return gpg_error (GPG_ERR_ENOMEM);
197              if (field == 3) {              }
198                  card->vendor = strdup (p);              break;
199                  if (!card->vendor)  
200                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Vendor:
201              }              if (field == 3) {
202              break;                  card->vendor = strdup (p);
203                    if (!card->vendor)
204          case CARD_Serial:                      return gpg_error (GPG_ERR_ENOMEM);
205              if (field == 2) {              }
206                  card->serial = strdup (p);              break;
207                  if (!card->serial)  
208                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Serial:
209              }              if (field == 2) {
210              break;                  card->serial = strdup (p);
211          case CARD_Name:                  if (!card->serial)
212              if (field == 2) {                      return gpg_error (GPG_ERR_ENOMEM);
213                  card->givenname = strdup (p);              }
214                  if (!card->givenname)              break;
215                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Name:
216              }              if (field == 2) {
217              else if (field == 3) {                  card->givenname = strdup (p);
218                  card->surname = strdup (p);                  if (!card->givenname)
219                  if (!card->surname)                      return gpg_error (GPG_ERR_ENOMEM);
220                      return gpg_error (GPG_ERR_ENOMEM);              }
221              }              else if (field == 3) {
222              break;                  card->surname = strdup (p);
223          case CARD_Lang:                  if (!card->surname)
224              if( field == 2 ) {                      return gpg_error (GPG_ERR_ENOMEM);
225                  card->lang = strdup (p);              }
226                  if (!card->lang)              break;
227                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Lang:
228              }              if( field == 2 ) {
229              break;                  card->lang = strdup (p);
230          case CARD_Sex:                  if (!card->lang)
231              if( field == 2 )                      return gpg_error (GPG_ERR_ENOMEM);
232                  card->sex = *p;              }
233              break;              break;
234            case CARD_Sex:
235          case CARD_Url:              if( field == 2 )
236              if( field == 2 ) {                  card->sex = *p;
237                  if (card->url)              break;
238                      free (card->url);  
239                  card->url = (char*)calloc (1, strlen (p) + 1);          case CARD_Url:
240                  if( !card->url ) {              if( field == 2 ) {
241                      return gpg_error (GPG_ERR_ENOMEM);                  if (card->url)
242                  }                      free (card->url);
243                  gpg_decode_c_string (p, &card->url, strlen (p) + 1);                  card->url = (char*)calloc (1, strlen (p) + 1);
244                  if (!card->url)                  if( !card->url ) {
245                      return gpg_error (GPG_ERR_ENOMEM);                      return gpg_error (GPG_ERR_ENOMEM);
246              }                  }
247              break;                  gpg_decode_c_string (p, &card->url, strlen (p) + 1);
248                    if (!card->url)
249          case CARD_Login:                      return gpg_error (GPG_ERR_ENOMEM);
250              if (field == 2) {              }
251                  card->login = strdup (p);              break;
252                  if (!card->login)  
253                      return gpg_error (GPG_ERR_ENOMEM);          case CARD_Login:
254              }              if (field == 2) {
255              break;                  card->login = strdup (p);
256                    if (!card->login)
257          case CARD_MaxPinLen:                      return gpg_error (GPG_ERR_ENOMEM);
258              break;              }
259                break;
260          case CARD_SigCount:  
261              if (field == 2)          case CARD_MaxPinLen:
262                  card->sig_count = atol (p);              break;
263              break;  
264            case CARD_SigCount:
265          case CARD_CAFpr:              if (field == 2)
266              if (!p)                  card->sig_count = atol (p);
267                  break;              break;
268              if (field > 4 || field == 1)  
269                  break;          case CARD_CAFpr:
270              card->ca_fpr[field-2] = strdup (p);              if (!p)
271              if (!card->ca_fpr[field-2])                  break;
272                  return gpg_error (GPG_ERR_ENOMEM);              if (field > 4 || field == 1)
273              break;                  break;
274                card->ca_fpr[field-2] = strdup (p);
275          case CARD_Fpr:              if (!card->ca_fpr[field-2])
276              if (field > 4 || field == 1) /* max 3 fprs */                  return gpg_error (GPG_ERR_ENOMEM);
277                  break;              break;
278              card->fpr[field-2] = strdup (p);  
279              if (!card->fpr[field-2])          case CARD_Fpr:
280                  return gpg_error (GPG_ERR_ENOMEM);              if (field > 4 || field == 1) /* max 3 fprs */
281              break;                  break;
282                card->fpr[field-2] = strdup (p);
283          case CARD_FprTime:              if (!card->fpr[field-2])
284              if (field > 4 || field == 1)                  return gpg_error (GPG_ERR_ENOMEM);
285                  break;              break;
286              card->fpr_created[field-2] = strtoul (p, NULL, 10);  
287              card->fpr_created_str[field-2] = get_str_timestamp (strtoul (p, NULL, 10));          case CARD_FprTime:
288              if (!card->fpr_created_str[field-2])              if (field > 4 || field == 1)
289                  return gpg_error (GPG_ERR_ENOMEM);                  break;
290              break;              card->fpr_created[field-2] = strtoul (p, NULL, 10);
291                card->fpr_created_str[field-2] = get_str_timestamp (strtoul (p, NULL, 10));
292          }              if (!card->fpr_created_str[field-2])
293      }                  return gpg_error (GPG_ERR_ENOMEM);
294      return 0;              break;
295  }              
296            default:
297                break;
298  /* Dummy handler to get the colon data and then quit. */          }
299  static gpgme_error_t      }
300  list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)      return 0;
301  {  }
302      static int wait_card=0;  
303      GpgCardEdit *ce = (GpgCardEdit *)opaque;  
304      const char *s="";      /* Dummy handler to get the colon data and then quit. */
305      DWORD n;  static gpgme_error_t
306            list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
307    {
308      if (code == GPGME_STATUS_CARDCTRL) {      static int wait_card=0;
309          if (!strcmp (key, "5"))      GpgCardEdit *ce = (GpgCardEdit *)opaque;
310              ce->setResult (GPG_CARDRES_NOCARD);      const char *s="";    
311          else if (!strcmp (key, "1"))      DWORD n;
312              wait_card = 1;          
313      }  
314      if (wait_card && !strcmp (key, "cardctrl.insert_card.okay")) {      if (code == GPGME_STATUS_CARDCTRL) {
315          n = MessageBox (NULL, _("Please insert the card and click OK or Cancel to abort."),          if (!strcmp (key, "5"))
316                          _("GPG Card Status"), MB_ICONQUESTION|MB_OKCANCEL);              ce->setResult (GPG_CARDRES_NOCARD);
317          if (n == IDCANCEL) {          else if (!strcmp (key, "1"))
318              ce->setResult (GPG_CARDRES_CANCEL);              wait_card = 1;
319              WriteFile ((HANDLE)fd, "c\n", 2, &n, NULL);      }
320              wait_card = 0;      if (wait_card && !strcmp (key, "cardctrl.insert_card.okay")) {
321          }          n = MessageBox (NULL, _("Please insert the card and click OK or Cancel to abort."),
322      }                          _("GPG Card Status"), MB_ICONQUESTION|MB_OKCANCEL);
323      if (!strcmp (key, "cardedit.prompt")) {          if (n == IDCANCEL) {
324          s = "quit\n";              ce->setResult (GPG_CARDRES_CANCEL);
325          if (!WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL))              WriteFile ((HANDLE)fd, "c\n", 2, &n, NULL);
326              log_debug ("list_handler: WriteFile() failed ec=%d\r\n",              wait_card = 0;
327                         (int)GetLastError ());          }
328          wait_card = 0;      }
329      }      if (!strcmp (key, "cardedit.prompt")) {
330      return 0;          s = "quit\n";
331  }          if (!WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL))
332                log_debug ("list_handler: WriteFile() failed ec=%d\r\n",
333                           (int)GetLastError ());
334  /* Construct an empty object. */          wait_card = 0;
335  GpgCardEdit::GpgCardEdit (void)      }
336  {      return 0;
337      pin = NULL;  }
338      pin_new = NULL;  
339      admin_pin = NULL;  
340    /* Construct an empty object. */
341      keygen.comment = NULL;  GpgCardEdit::GpgCardEdit (void)
342      keygen.email = NULL;  {
343      keygen.name = NULL;      pin = NULL;
344      keygen.expdate = NULL;      pin_new = NULL;
345      keygen.key_fpr = NULL;      admin_pin = NULL;
346    
347      type = 0;      keygen.comment = NULL;
348      cnt = 0;      keygen.email = NULL;
349      cancel = 0;      keygen.name = NULL;
350      result = 0;      keygen.expdate = NULL;
351        keygen.key_fpr = NULL;
352      gpgme_new (&ctx); /* XXX: check return code */  
353  }      type = 0;
354        cnt = 0;
355  /* Release the object. */      cancel = 0;
356  GpgCardEdit::~GpgCardEdit (void)      result = 0;
357  {      
358      if (keygen.name)      gpgme_new (&ctx); /* XXX: check return code */
359          free (keygen.name);  }
360      if (keygen.comment)  
361          free (keygen.comment);  /* Release the object. */
362      if (keygen.email)  GpgCardEdit::~GpgCardEdit (void)
363          free (keygen.email);  {    
364      if (keygen.expdate)      if (keygen.name)
365          free (keygen.expdate);          free (keygen.name);
366      if (keygen.key_fpr)      if (keygen.comment)
367          free (keygen.key_fpr);          free (keygen.comment);
368      gpgme_release (ctx);      if (keygen.email)
369  }          free (keygen.email);
370        if (keygen.expdate)
371            free (keygen.expdate);
372  /* Set the user PIN for the object to @pin. */      if (keygen.key_fpr)
373  void          free (keygen.key_fpr);
374  GpgCardEdit::setPIN (const char *pin)      gpgme_release (ctx);
375  {  }
376      this->pin = pin;  
377  }  
378    /* Set the user PIN for the object to @pin. */
379  /* Set the admin PIN for the object to @admin_pin. */  void
380  void  GpgCardEdit::setPIN (const char *_pin)
381  GpgCardEdit::setAdminPIN (const char *admin_pin)  {
382  {      this->pin = _pin;
383      this->admin_pin = admin_pin;  }
384  }  
385    /* Set the admin PIN for the object to @admin_pin. */
386    void
387  /* Set the new user PIN for the object to @new_pin. */  GpgCardEdit::setAdminPIN (const char *_admin_pin)
388  void  {
389  GpgCardEdit::setNewPIN (const char *new_pin)      this->admin_pin = _admin_pin;
390  {  }
391      this->pin_new = new_pin;  
392  }  
393    /* Set the new user PIN for the object to @new_pin. */
394    void
395  /* Set the passphrase needed when generating a key to @pass. */  GpgCardEdit::setNewPIN (const char *_new_pin)
396  void  {
397  GpgCardEdit::setKeygenPassphrase (const char *pass)      this->pin_new = _new_pin;
398  {  }
399      this->keygen.pass = pass;  
400  }  
401    /* Set the passphrase needed when generating a key to @pass. */
402    void
403  /* Set the callback to @cb and the hook value to @cb_value. */  GpgCardEdit::setKeygenPassphrase (const char *_pass)
404  void  {
405  GpgCardEdit::setCallback (const char* (*cb)(int code, void *opaque),      this->keygen.pass = _pass;
406                            void *cb_value)  }
407  {  
408      this->cb_value = cb_value;  
409      this->card_cb = cb;  /* Set the callback to @cb and the hook value to @cb_value. */
410  }  void
411    GpgCardEdit::setCallback (const char* (*cb)(int code, void *opaque),
412                              void *cb_value)
413  /* Read the information from the inserted card and return  {
414     it in form of a card context @r_card.      this->cb_value = cb_value;
415     Return value: 0 on success. */      this->card_cb = cb;
416  gpgme_error_t  }
417  GpgCardEdit::getCardStatus (gpg_card_t *r_card)  
418  {  
419      gpgme_data_t out = NULL;  /* Read the information from the inserted card and return
420      gpgme_error_t err;     it in form of a card context @r_card.
421      gpg_card_t card=NULL;     Return value: 0 on success. */
422      char buf[200];  gpgme_error_t
423    GpgCardEdit::getCardStatus (gpg_card_t *r_card)
424      if (!r_card)  {
425          return gpg_error (GPG_ERR_INV_ARG);      gpgme_data_t out = NULL;
426        gpgme_error_t err;
427      err = gpg_card_new (&card);      gpg_card_t card=NULL;
428      if (err)      char buf[200];
429          return err;  
430        if (!r_card)
431      err = gpgme_data_new (&out);          return gpg_error (GPG_ERR_INV_ARG);
432      if (err) {  
433          gpg_card_release (card);      err = gpg_card_new (&card);
434          return err;      if (err)
435      }          return err;
436        
437      err = gpgme_op_card_edit  (ctx, NULL, list_handler, this, out);      err = gpgme_data_new (&out);
438      gpgme_data_rewind (out);      if (err) {
439      if (err) {          gpg_card_release (card);
440          gpgme_data_release (out);          return err;
441          gpg_card_release (card);      }
442          return err;      
443      }      err = gpgme_op_card_edit  (ctx, NULL, list_handler, this, out);
444      if (getResult () & GPG_CARDRES_NOCARD ||      gpgme_data_rewind (out);
445          getResult () & GPG_CARDRES_CANCEL) {      if (err) {
446          gpg_card_release (card);          gpgme_data_release (out);
447          gpgme_data_release (out);          gpg_card_release (card);
448          return gpg_error (GPG_ERR_CARD_NOT_PRESENT);          return err;
449      }      }
450        if (getResult () & GPG_CARDRES_NOCARD ||
451      *r_card = card;          getResult () & GPG_CARDRES_CANCEL) {
452      while (gpg_data_readline (out, buf, sizeof (buf)-2) > 0) {          gpg_card_release (card);
453          err = statuscard_colon_handler (card, buf);          gpgme_data_release (out);
454          if (err)          return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
455              break;      }
456      }  
457      gpgme_data_release (out);      *r_card = card;
458        while (gpg_data_readline (out, buf, sizeof (buf)-2) > 0) {
459      return err;          err = statuscard_colon_handler (card, buf);
460  }          if (err)
461                break;
462        }
463  /* Generate a key on a smart card with the following params:      gpgme_data_release (out);
464     @flags: user specific params.  
465     @name: name of the key holder.      return err;
466     @email: email of the key holder.  }
467     @comment: optional comment.  
468     @valid: how long is the key valid in days.  
469     Return value: 0 on success. */  /* Generate a key on a smart card with the following params:
470  gpgme_error_t     @flags: user specific params.
471  GpgCardEdit::genKey (int flags, const char *name,     @name: name of the key holder.
472                       const char *email, const char *comment, long valid,     @email: email of the key holder.
473                       char **r_key_fpr)     @comment: optional comment.
474  {     @valid: how long is the key valid in days.
475      gpgme_error_t err;     Return value: 0 on success. */
476    gpgme_error_t
477      if (!name || !email)  GpgCardEdit::genKey (int flags, const char *name,
478          return gpg_error (GPG_ERR_INV_ARG);                       const char *email, const char *comment, long valid,
479      if (!this->keygen.pass)                       char **r_key_fpr)
480          return gpg_error (GPG_ERR_INV_OBJ);  {
481        gpgme_error_t err;
482      type = GPG_EDITCARD_GENKEY;  
483      this->keygen.flags = flags;      if (!name || !email)
484            return gpg_error (GPG_ERR_INV_ARG);
485      if (this->keygen.name)      if (!this->keygen.pass)
486          free (this->keygen.name);          return gpg_error (GPG_ERR_INV_OBJ);
487      this->keygen.name = strdup (name);  
488      if (this->keygen.email)      type = GPG_EDITCARD_GENKEY;
489          free (this->keygen.email);      this->keygen.flags = flags;
490      this->keygen.email = strdup (email);  
491      if (this->keygen.comment)      if (this->keygen.name)
492          free (this->keygen.comment);          free (this->keygen.name);
493      this->keygen.comment = comment? strdup (comment) : strdup ("");      this->keygen.name = strdup (name);
494      if (this->keygen.expdate)      if (this->keygen.email)
495          free (this->keygen.expdate);          free (this->keygen.email);
496      this->keygen.expdate = (char*)calloc (1, 16);      this->keygen.email = strdup (email);
497      if (this->keygen.expdate)      if (this->keygen.comment)
498          sprintf (this->keygen.expdate, "%d", valid);          free (this->keygen.comment);
499        this->keygen.comment = comment? strdup (comment) : strdup ("");
500      if (!this->keygen.name || !this->keygen.email)      if (this->keygen.expdate)
501          return gpg_error (GPG_ERR_ENOMEM);          free (this->keygen.expdate);
502        this->keygen.expdate = (char*)calloc (1, 16);
503      err = gpg_card_edit (ctx, this);      if (this->keygen.expdate)
504      if (!err)          sprintf (this->keygen.expdate, "%d", valid);
505          err = getResult () & GPG_CARDRES_CANCEL? gpg_error (GPG_ERR_CANCELED) : 0;  
506      if (!err && r_key_fpr)      if (!this->keygen.name || !this->keygen.email)
507          *r_key_fpr = strdup (keygen.key_fpr? keygen.key_fpr : "");          return gpg_error (GPG_ERR_ENOMEM);
508      return err;  
509  }      err = gpg_card_edit (ctx, this);
510        if (!err)
511            err = getResult () & GPG_CARDRES_CANCEL? gpg_error (GPG_ERR_CANCELED) : 0;
512  /* Change the pin from @pin to @pin_new.      if (!err && r_key_fpr)
513     Return value: 0 on success. */          *r_key_fpr = strdup (keygen.key_fpr? keygen.key_fpr : "");
514  gpgme_error_t      return err;
515  GpgCardEdit::changePIN (int type)  }
516  {  
517      gpgme_error_t err;  
518    /* Change the pin from @pin to @pin_new.
519      if (!this->pin_new)     Return value: 0 on success. */
520          return gpg_error (GPG_ERR_INV_ARG);  gpgme_error_t
521    GpgCardEdit::changePIN (int _type)
522      if (!type) {  {
523          if (this->pin && this->pin_new)      gpgme_error_t err;
524              this->type = GPG_EDITCARD_CHUPIN;  
525          else if (this->pin && this->admin_pin)      if (!this->pin_new)
526              this->type = GPG_EDITCARD_CHAPIN;          return gpg_error (GPG_ERR_INV_ARG);
527          else  
528              this->type = GPG_EDITCARD_UNBPIN;      if (!_type) {
529      }          if (this->pin && this->pin_new)
530      else              this->type = GPG_EDITCARD_CHUPIN;
531          this->type = type;          else if (this->pin && this->admin_pin)
532      /* check if the user provided the needed PIN. */              this->type = GPG_EDITCARD_CHAPIN;
533      if ((this->type == GPG_EDITCARD_CHUPIN && !this->pin) ||          else
534          (this->type == GPG_EDITCARD_CHAPIN && !this->admin_pin))              this->type = GPG_EDITCARD_UNBPIN;
535          return gpg_error (GPG_ERR_INV_ARG);      }
536        else
537      err = gpg_card_edit (ctx, this);          this->type = _type;
538      return err;      /* check if the user provided the needed PIN. */
539  }      if ((this->type == GPG_EDITCARD_CHUPIN && !this->pin) ||
540            (this->type == GPG_EDITCARD_CHAPIN && !this->admin_pin))
541            return gpg_error (GPG_ERR_INV_ARG);
542  gpgme_error_t  
543  GpgCardEdit::updateName (const char *given, const char *sur)      err = gpg_card_edit (ctx, this);
544  {      return err;
545      gpgme_error_t err;  }
546    
547      if (!this->admin_pin)  
548          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
549    GpgCardEdit::updateName (const char *given, const char *sur)
550      this->type = GPG_EDITCARD_NAME;  {
551      this->edit.surname = sur;      gpgme_error_t err;
552      this->edit.givenname = given;  
553        if (!this->admin_pin)
554      err = gpg_card_edit (ctx, this);          return gpg_error (GPG_ERR_INV_OBJ);
555      return err;  
556  }      this->type = GPG_EDITCARD_NAME;
557            this->edit.surname = sur;
558  gpgme_error_t      this->edit.givenname = given;
559  GpgCardEdit::updateURL (const char *url)  
560  {      err = gpg_card_edit (ctx, this);
561      gpgme_error_t err;      return err;
562    }
563      if (!this->admin_pin)      
564          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
565    GpgCardEdit::updateURL (const char *_url)
566      type = GPG_EDITCARD_KEYURL;  {
567      this->edit.keyurl = url;      gpgme_error_t err;
568    
569      err = gpg_card_edit (ctx, this);      if (!this->admin_pin)
570      return err;          return gpg_error (GPG_ERR_INV_OBJ);
571  }  
572        type = GPG_EDITCARD_KEYURL;
573        this->edit.keyurl = _url;
574  gpgme_error_t  
575  GpgCardEdit::updateLogin (const char *login)      err = gpg_card_edit (ctx, this);
576  {      return err;
577      gpgme_error_t err;  }
578    
579      if (!this->admin_pin)  
580          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
581    GpgCardEdit::updateLogin (const char *login)
582      this->type = GPG_EDITCARD_LOGIN;  {
583      this->edit.login = login;      gpgme_error_t err;
584    
585      err = gpg_card_edit (ctx, this);      if (!this->admin_pin)
586      return err;          return gpg_error (GPG_ERR_INV_OBJ);
587  }  
588        this->type = GPG_EDITCARD_LOGIN;
589  gpgme_error_t      this->edit.login = login;
590  GpgCardEdit::updateSex (char sex)  
591  {      err = gpg_card_edit (ctx, this);
592      gpgme_error_t err;      return err;
593    }
594      if (!this->admin_pin)  
595          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
596    GpgCardEdit::updateSex (char sex)
597      type = GPG_EDITCARD_SEX;  {
598      this->edit.sex = sex;      gpgme_error_t err;
599    
600      err = gpg_card_edit (ctx, this);      if (!this->admin_pin)
601      return err;          return gpg_error (GPG_ERR_INV_OBJ);
602  }  
603        type = GPG_EDITCARD_SEX;
604  gpgme_error_t      this->edit.sex = sex;
605  GpgCardEdit::updateLanguage (const char *lang)  
606  {      err = gpg_card_edit (ctx, this);
607      gpgme_error_t err;      return err;
608    }
609      if (!this->admin_pin)  
610          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
611    GpgCardEdit::updateLanguage (const char *lang)
612      type = GPG_EDITCARD_LANG;  {
613      this->edit.lang = lang;      gpgme_error_t err;
614    
615      err = gpg_card_edit (ctx, this);      if (!this->admin_pin)
616      return err;          return gpg_error (GPG_ERR_INV_OBJ);
617  }  
618        type = GPG_EDITCARD_LANG;
619        this->edit.lang = lang;
620  /* Fetch the key specified by the url stored on the card.  
621     Return value: 0 on success. */      err = gpg_card_edit (ctx, this);
622  gpgme_error_t      return err;
623  GpgCardEdit::fetchKey (void)  }
624  {  
625      gpgme_error_t err = 0;  
626    /* Fetch the key specified by the url stored on the card.
627      if (!this->pin)     Return value: 0 on success. */
628          return gpg_error (GPG_ERR_INV_OBJ);  gpgme_error_t
629    GpgCardEdit::fetchKey (void)
630      return 0;  {
631  }      if (!this->pin)
632            return gpg_error (GPG_ERR_INV_OBJ);
633    
634  /* Dispatcher for the various commands. @cmd is the card command ID      return 0;
635     and @arg1 and @arg2 the actual values for the command.  }
636     Return value: 0 on success. */  
637  gpgme_error_t  
638  GpgCardEdit:: doCmd (int cmd, const char *arg1, const char *arg2)  /* Dispatcher for the various commands. @cmd is the card command ID
639  {     and @arg1 and @arg2 the actual values for the command.
640      switch (cmd) {     Return value: 0 on success. */
641      case GPG_EDITCARD_NAME:  gpgme_error_t
642          return updateName (arg1, arg2); /* given, surname */  GpgCardEdit:: doCmd (int cmd, const char *arg1, const char *arg2)
643    {
644      case GPG_EDITCARD_LANG:      switch (cmd) {
645          return updateLanguage (arg1); /* lang */      case GPG_EDITCARD_NAME:
646            return updateName (arg1, arg2); /* given, surname */
647      case GPG_EDITCARD_SEX:  
648          return updateSex (*arg1); /* sex */      case GPG_EDITCARD_LANG:
649            return updateLanguage (arg1); /* lang */
650      case GPG_EDITCARD_KEYURL:  
651          return updateURL (arg1); /* url */      case GPG_EDITCARD_SEX:
652            return updateSex (*arg1); /* sex */
653      case GPG_EDITCARD_LOGIN:  
654          return updateLogin (arg1); /* login */      case GPG_EDITCARD_KEYURL:
655            return updateURL (arg1); /* url */
656      default:  
657          return gpg_error (GPG_ERR_INV_VALUE);      case GPG_EDITCARD_LOGIN:
658      }          return updateLogin (arg1); /* login */
659    
660      return 0;      default:
661  }          return gpg_error (GPG_ERR_INV_VALUE);
662        }
663    
664  /* Set the result for the executed operation.      return 0;
665     The values will be ORed. */  }
666  void  
667  GpgCardEdit::setResult (int res)  
668  {  /* Set the result for the executed operation.
669      result |= res;     The values will be ORed. */
670  }  void
671    GpgCardEdit::setResult (int res)
672    {
673  /* Return the result of the executed operation. */      result |= res;
674  int  }
675  GpgCardEdit::getResult (void)  
676  {  
677      return result;  /* Return the result of the executed operation. */
678  }  int
679    GpgCardEdit::getResult (void)
680    {
681  /* Reset the object state. */      return result;
682  void  }
683  GpgCardEdit::reset (void)  
684  {  
685      cnt = 0;  /* Reset the object state. */
686  }  void
687    GpgCardEdit::reset (void)
688    {
689  /* Return card command type */      cnt = 0;
690  int  }
691  GpgCardEdit::getType (void)  
692  {  
693      return type;  /* Return card command type */
694  }  int
695    GpgCardEdit::getType (void)
696    {
697        return type;
698    }

Legend:
Removed from v.28  
changed lines
  Added in v.69

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26