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

Diff of /trunk/Src/wptCardEditCB.cpp

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

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 36 by werner, Thu Oct 27 15:25:13 2005 UTC
# Line 1  Line 1 
1  /* wptCardEditCB.cpp - Card callbacks  /* wptCardEditCB.cpp - Card callbacks
2   *      Copyright (C) 2003, 2004, 2005 Timo Schulz   *      Copyright (C) 2003, 2004, 2005 Timo Schulz
3   *   *      Copyright (C) 2005 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
6   * WinPT is free software; you can redistribute it and/or modify   *
7   * it under the terms of the GNU General Public License as published by   * WinPT is free software; you can redistribute it and/or modify
8   * the Free Software Foundation; either version 2 of the License, or   * it under the terms of the GNU General Public License as published by
9   * (at your option) any later version.   * the Free Software Foundation; either version 2 of the License, or
10   *   * (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * GNU General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   *   * GNU General Public License for more details.
16   * You should have received a copy of the GNU General Public License   *
17   * along with this program; if not, write to the Free Software Foundation,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * along with this program; if not, gpg_write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21  #include <stdio.h>  #ifdef HAVE_CONFIG_H
22  #include <malloc.h>  #include <config.h>
23  #include <string.h>  #endif
24  #include <stdlib.h>  
25  #include <io.h>  #include <windows.h>
26    #include <windows.h>
27  #include "w32gpgme.h"  #include <stdio.h>
28  #include "wptCardEdit.h"  #include <malloc.h>
29  #include "wptCard.h"  #include <string.h>
30    #include <stdlib.h>
31  #define save_write(val) ((val)? (val) : "")  
32    #include "gpgme.h"
33    #include "wptCard.h"
34    #include "wptCardEdit.h"
35  static gpgme_error_t  #include "wptErrors.h"
36  change_pin_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)  
37  {  #define save_write(val) ((val)? (val) : "")
38      GpgCardEdit *c = (GpgCardEdit *)opaque;  static const char *stat_key = "";
39      const char *s = "";  
40    /* Wrapper to emulate write(). */
41      if (!c)  static int
42          return gpg_error (GPG_ERR_EOF);  gpg_write (int fd, const void *buf, size_t buflen)
43    {
44      if (!strcmp (key,  "cardctrl.insert_card_okay")) {      HANDLE hd = (HANDLE)fd;
45          if (c->card_cb) {      DWORD n;
46              s = c->card_cb (1, c->cb_value);  
47              write (fd, s, strlen (s));      MessageBox (NULL, (const char*)buf, stat_key, MB_OK);
48              return 0;      WriteFile (hd, buf, buflen, &n, NULL);
49          }      WriteFile (hd, "\n", 1, &n, NULL);
50      }      return n;
51      if (!strcmp (key,  "cardedit.prompt")) {  }
52          if (c->cnt++ == 0)  
53              s = "admin";  
54          else if (c->cnt++ == 1)  /* Common card handler. Handle general card status events. */
55              s = "passwd";  static gpgme_error_t
56          else  common_card_handler (GpgCardEdit *c, gpgme_status_code_t code,
57              s = "quit";                       const char *key, int fd)
58          write (fd, s, strlen (s));  {
59          return 0;      const char *s;
60      }  
61      if (!strcmp (key,  "cardutil.change_pin.menu")) {      if (!strcmp (key,  "cardctrl.insert_card.okay")) {
62          if (c->cnt++ == 2) {          if (c->card_cb) {
63              switch (c->type) {              s = c->card_cb (CARD_CTL_INSERT, c->cb_value);
64              case GPG_EDITCARD_CHUPIN: s = "1";              gpg_write (fd, s, strlen (s));
65              case GPG_EDITCARD_UNBPIN: s = "2";              return 0;
66              case GPG_EDITCARD_CHAPIN: s = "3";          }
67              default: c->cnt = 0;      s = "Q";      }
68              }  
69              write (fd, s, strlen (s));      if (code == GPGME_STATUS_CARDCTRL &&
70              return 0;          (*key == CARD_CTL_NO_CARD || *key == CARD_CTL_NO_READER))
71          }          c->setResult (GPG_CARDRES_NOCARD);
72          else if (c->cnt > 0) {  
73              c->cnt = 0;      /* This can happen for example if a wrong PIN were
74              write (fd, "Q", 1);         submitted. In such a case, we quit ASAP. */
75              return 0;      if (code == GPGME_STATUS_SC_OP_FAILURE) {
76          }          if (key && !strcmp (key, "2"))
77      }              c->setResult (GPG_CARDRES_BAD_PIN);
78      if (c->type == GPG_EDITCARD_CHUPIN) {          else if (key && !strcmp (key, "1"))
79          if (!strcmp (key, "passphrase.pin.ask")) {              c->setResult (GPG_CARDRES_CANCEL);
80              s = c->pin;          s = "quit\n";
81              c->cnt++;          gpg_write (fd, s, strlen (s));
82          }          return 0;
83          if (!strcmp (key, "passphrase.pin.new.ask")) {      }
84              s = c->pin_new;      return 0;
85              c->cnt++;  }
86          }  
87          if (!strcmp (key, "passphrase.pin.repeat")) {  
88              s = c->pin_new;  /* handler for changing PINs of cards. */
89              c->cnt++;  static gpgme_error_t
90          }  change_pin_handler (void *opaque, gpgme_status_code_t code,
91          write (fd, s, strlen (s));                      const char *key, int fd)
92      }  {
93      else if (c->type == GPG_EDITCARD_CHAPIN) {      GpgCardEdit *c = (GpgCardEdit *)opaque;
94          if (!strcmp (key, "passphrase.adminpin.ask")) {      const char *s = "";
95              s = c->pin;      int type;
96              c->cnt++;  
97          }      if (!c)
98          if (!strcmp (key, "passphrase.adminpin.new.ask")) {          return gpg_error (GPG_ERR_EOF);
99              s = c->pin_new;  
100              c->cnt++;      stat_key = key; /* XXX: debug code */
101          }  
102          if (!strcmp (key, "passphrase.pin.repeat")) {      common_card_handler (c, code, key, fd);
103              s = c->pin_new;  
104              c->cnt++;      type = c->getType ();
105          }      if (!strcmp (key,  "cardedit.prompt")) {
106          write (fd, s, strlen (s));          if (c->cnt == 0) {
107      }              c->cnt++;
108      else if (c->type == GPG_EDITCARD_UNBPIN) {              s = "admin";
109          /* todo */          }
110      }          else if (c->cnt == 1) {
111                c->cnt++;
112      return 0;              s = "passwd";
113  }          }
114            else {
115                c->reset ();
116  static gpgme_error_t              s = "quit";
117  editcard_handler (void * opaque, gpgme_status_code_t code,          }
118                    const char *key, int fd)          gpg_write (fd, s, strlen (s));
119  {          return 0;
120      GpgCardEdit *c = (GpgCardEdit *)opaque;        }
121      const char *s = "";      if (!strcmp (key,  "cardutil.change_pin.menu")) {
122            if (c->cnt == 2) {
123      if (!c)              c->cnt++;
124          return gpg_error (GPG_ERR_EOF);              switch (type) {
125                    case GPG_EDITCARD_CHUPIN: s = "1"; break;
126      if (!strcmp (key, "cardctrl.insert_card.okay")) {              case GPG_EDITCARD_UNBPIN: s = "2"; break;
127          if (c->card_cb) {              case GPG_EDITCARD_CHAPIN: s = "3"; break;
128              s =  c->card_cb (1, c->cb_value);              default:                  s = "Q";
129              write (fd, s, strlen (s));              }
130              return 0;              gpg_write (fd, s, strlen (s));
131          }              return 0;
132      }          }
133            else if (c->cnt > 0) {
134      if (!strcmp (key, "cardedit.prompt")) {              gpg_write (fd, "Q", 1);
135          if (c->cnt++ == 0) { /* first switch in the admin mode */              return 0;
136              s = "admin";          }
137              write (fd, s, strlen (s));      }
138              return 0;      if (type == GPG_EDITCARD_CHUPIN) {
139          }          if (!strcmp (key, "passphrase.pin.ask")) {
140          if (c->cnt == 1) {/* then run the send command */              s = c->pin;
141              c->cnt++;              c->cnt++;
142              switch (c->type) {          }
143              case GPG_EDITCARD_NAME:   s = "name";          if (!strcmp (key, "passphrase.pin.new.ask")) {
144              case GPG_EDITCARD_KEYURL: s = "url";              s = c->pin_new;
145              case GPG_EDITCARD_LOGIN:  s = "login";              c->cnt++;
146              case GPG_EDITCARD_SEX:    s = "sex";          }
147              case GPG_EDITCARD_LANG:   s = "lang";          if (!strcmp (key, "passphrase.pin.repeat") ||
148              case GPG_EDITCARD_GENKEY: s = "generate";              !strcmp (key, "passphrase.ask")) {
149              default:                  s =  "quit";              s = c->pin_new;
150              }              c->cnt++;
151              write (fd, s, strlen (s));          }
152              return 0;          gpg_write (fd, s, strlen (s));
153          }      }
154          else if (c->cnt >= 2) {/* done: send exit */      else if (type == GPG_EDITCARD_CHAPIN) {
155              c->cnt = 0;          if (!strcmp (key, "passphrase.adminpin.ask")) {
156              s = "quit";              s = c->admin_pin;
157              write (fd, s, strlen (s));              c->cnt++;
158              return 0;          }
159          }          if (!strcmp (key, "passphrase.adminpin.new.ask")) {
160      }              s = c->pin_new;
161      if (c->cnt > 0) {              c->cnt++;
162          if (!strcmp (key, "passphrase.adminpin.ask")) {          }
163              write (fd, c->admin_pin, strlen (c->admin_pin));          if (!strcmp (key, "passphrase.pin.repeat") ||
164              return 0;              !strcmp (key, "passphrase.ask")) {
165          }              s = c->pin_new;
166          if (!strcmp (key, "passphrase.pin.ask")) {              c->cnt++;
167              write (fd, c->pin, strlen (c->pin));          }
168              return 0;          gpg_write (fd, s, strlen (s));
169          }      }
170      }      else if (type == GPG_EDITCARD_UNBPIN) {
171      switch (c->type) {          /* todo */
172      case GPG_EDITCARD_NAME:      }
173          if (!strcmp (key, "keygen.smartcard.surname")) {  
174              s = save_write (c->edit.surname);      return 0;
175              write (fd, s, strlen (s));  }
176          }  
177          else if (!strcmp (key, "keygen.smartcard.givenname")) {  
178              s = save_write (c->edit.givenname);  /* edit card attributes handler. */
179              write (fd, s, strlen (s));  static gpgme_error_t
180          }  editcard_handler (void * opaque, gpgme_status_code_t code,
181          break;                    const char *key, int fd)
182    {
183      case GPG_EDITCARD_KEYURL:      GpgCardEdit *c = (GpgCardEdit *)opaque;  
184          if (!strcmp (key, "cardedit.change_url")) {      const char *s = "";
185              s = save_write (c->edit.keyurl);      int type;
186              write (fd, s, strlen (s));  
187          }      if (!c)
188          break;          return gpg_error (GPG_ERR_EOF);
189    
190      case GPG_EDITCARD_LOGIN:      stat_key = key;
191          if (!strcmp (key, "cardedit.change_login"))  {  
192              s = save_write (c->edit.login);      common_card_handler (c, code, key, fd);
193              write (fd, s, strlen (s));  
194          }      type = c->getType ();
195          break;      if (!strcmp (key, "cardedit.prompt")) {
196            if (c->getResult ()) { /* in case of an error we quit. */
197      case GPG_EDITCARD_SEX:              c->cnt = 0;
198          if (!strcmp (key, "cardedit.change_sex")) {              s = "quit";
199              static char buf[2];              gpg_write (fd, s, strlen (s));
200              if (c->edit.sex != 'M'              return 0;
201                  && c->edit.sex != 'F'          }
202                  && c->edit.sex != ' ') {          if (c->cnt == 0) { /* first switch in the admin mode */
203                  buf[0] = ' '; buf[1] = 0;              c->cnt++;
204              }              s = "admin";
205              else {              gpg_write (fd, s, strlen (s));
206                  buf[0] = c->edit.sex; buf[1] = 0;              return 0;
207              }          }
208              write (fd, buf, strlen (buf));          if (c->cnt == 1) {/* then run the send command */
209          }              c->cnt++;
210          break;              switch (type) {
211                case GPG_EDITCARD_NAME:   s = "name"; break;
212      case GPG_EDITCARD_LANG:              case GPG_EDITCARD_KEYURL: s = "url"; break;
213          if (!strcmp (key, "cardedit.change_lang")) {              case GPG_EDITCARD_LOGIN:  s = "login"; break;
214              s = save_write (c->edit.lang);              case GPG_EDITCARD_SEX:    s = "sex"; break;
215              write (fd, s, strlen (s));              case GPG_EDITCARD_LANG:   s = "lang"; break;
216          }              case GPG_EDITCARD_GENKEY: s = "generate"; break;
217          break;              default:                  s =  "quit";
218                }
219      case GPG_EDITCARD_GENKEY:              gpg_write (fd, s, strlen (s));
220          if (!strcmp (key, "passphrase.enter"))              return 0;
221              write (fd, c->keygen.pass, strlen (c->keygen.pass));          }
222          if (!strcmp (key, "cardedit.genkeys.backup_enc")) {          else if (c->cnt >= 2) {/* done: send exit */
223              s = c->keygen.flags & GPG_CARDFLAG_BAKENC? "Y" : "N";              c->reset ();
224              write (fd, s, strlen (s));              s = "quit";
225          }              gpg_write (fd, s, strlen (s));
226          if (!strcmp (key, "cardedit.genkeys.replace_keys")) {              return 0;
227              if (! (c->keygen.flags & GPG_CARDFLAG_REPLACE))          }
228                  c->cancel = 1;      }
229              s = c->keygen.flags & GPG_CARDFLAG_REPLACE? "Y" : "N";      if (c->cnt > 0) {
230              write (fd, s, strlen (s));          if (!strcmp (key, "passphrase.adminpin.ask")) {
231          }              gpg_write (fd, c->admin_pin, strlen (c->admin_pin));
232          else if (!strcmp (key, "keygen.valid")) {              return 0;
233              s = save_write (c->keygen.expdate);          }
234              write (fd, s, strlen (s));          if (!strcmp (key, "passphrase.pin.ask")) {
235          }              gpg_write (fd, c->pin, strlen (c->pin));
236          else if (!strcmp (key, "keygen.name")) {              return 0;
237              s = save_write (c->keygen.name);          }
238              write (fd, s, strlen (s));      }
239          }      switch (type) {
240          else if (!strcmp (key, "keygen.email")) {      case GPG_EDITCARD_NAME:
241              s = save_write (c->keygen.email);          if (!strcmp (key, "keygen.smartcard.surname")) {
242              write (fd, s, strlen (s));              s = save_write (c->edit.surname);
243          }              gpg_write (fd, s, strlen (s));
244          else if (!strcmp (key, "keygen.comment")) {          }
245              s = save_write (c->keygen.comment);          else if (!strcmp (key, "keygen.smartcard.givenname")) {
246              write (fd, s, strlen (s));              s = save_write (c->edit.givenname);
247          }              gpg_write (fd, s, strlen (s));
248          break;          }
249            break;
250      default:  
251          break;      case GPG_EDITCARD_KEYURL:
252      }          if (!strcmp (key, "cardedit.change_url")) {
253                    s = save_write (c->edit.keyurl);
254      return 0;              gpg_write (fd, s, strlen (s));
255  }          }
256            break;
257    
258  gpgme_error_t      case GPG_EDITCARD_LOGIN:
259  gpg_card_edit (gpgme_ctx_t ctx, GpgCardEdit *ce)          if (!strcmp (key, "cardedit.change_login"))  {
260  {              s = save_write (c->edit.login);
261      gpgme_error_t err;              gpg_write (fd, s, strlen (s));
262            }
263      if (ce->type > GPG_EDITCARD_CHPIN_ID)          break;
264          err = gpgme_op_card_edit (ctx, NULL, change_pin_handler, ce, NULL);  
265      else      case GPG_EDITCARD_SEX:
266          err = gpgme_op_card_edit (ctx, NULL, editcard_handler, ce, NULL);          if (!strcmp (key, "cardedit.change_sex")) {
267      return err;              static char buf[2];
268  }              if (c->edit.sex != 'M'
269                    && c->edit.sex != 'F'
270                    && c->edit.sex != ' ') {
271                    buf[0] = ' '; buf[1] = 0;
272                }
273                else {
274                    buf[0] = c->edit.sex;
275                    buf[1] = 0;
276                }
277                gpg_write (fd, buf, strlen (buf));
278            }
279            break;
280    
281        case GPG_EDITCARD_LANG:
282            if (!strcmp (key, "cardedit.change_lang")) {
283                s = save_write (c->edit.lang);
284                gpg_write (fd, s, strlen (s));
285            }
286            break;
287    
288        case GPG_EDITCARD_GENKEY:
289            if (!strcmp (key, "passphrase.enter"))
290                gpg_write (fd, c->keygen.pass, strlen (c->keygen.pass));
291            if (!strcmp (key, "cardedit.genkeys.backup_enc")) {
292                s = c->keygen.flags & GPG_CARDFLAG_BAKENC? "Y" : "N";
293                gpg_write (fd, s, strlen (s));
294            }
295            if (!strcmp (key, "cardedit.genkeys.replace_keys")) {
296                if (! (c->keygen.flags & GPG_CARDFLAG_REPLACE))
297                    c->cancel = 1;
298                s = c->keygen.flags & GPG_CARDFLAG_REPLACE? "Y" : "N";
299                gpg_write (fd, s, strlen (s));
300            }
301            else if (!strcmp (key, "keygen.valid")) {
302                s = save_write (c->keygen.expdate);
303                gpg_write (fd, s, strlen (s));
304            }
305            else if (!strcmp (key, "keygen.name")) {
306                s = save_write (c->keygen.name);
307                gpg_write (fd, s, strlen (s));
308            }
309            else if (!strcmp (key, "keygen.email")) {
310                s = save_write (c->keygen.email);
311                gpg_write (fd, s, strlen (s));
312            }
313            else if (!strcmp (key, "keygen.comment")) {
314                s = save_write (c->keygen.comment);
315                gpg_write (fd, s, strlen (s));
316            }
317            break;
318    
319        default:
320            break;
321        }
322        
323        return 0;
324    }
325    
326    
327    /* Check if a GPG status code occured which marks the
328       current operation as failed.
329       Return value: gpg error constant. */
330    static gpgme_error_t
331    map_result (GpgCardEdit *ce)
332    {
333        if (!ce->getResult ())
334            return gpg_error (GPG_ERR_NO_ERROR);
335        if (ce->getResult () & GPG_CARDRES_NOCARD)
336            return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
337        if (ce->getResult () & GPG_CARDRES_BAD_PIN)
338            return gpg_error (GPG_ERR_BAD_PIN);
339        return 0;
340    }
341    
342    
343    /* Wrapper around the gpgme card interface.
344       @ctx: context to use.
345       @ce:  card edit context.
346       Return value: 0 on success. */
347    gpgme_error_t
348    gpg_card_edit (gpgme_ctx_t ctx, GpgCardEdit *ce)
349    {
350        gpgme_data_t out;
351        gpgme_error_t err;
352    
353        err = gpgme_data_new (&out);
354        if (err)
355            return err;
356    
357        if (ce->getType () > GPG_EDITCARD_CHPIN_ID)
358            err = gpgme_op_card_edit (ctx, NULL, change_pin_handler, ce, out);
359        else
360            err = gpgme_op_card_edit (ctx, NULL, editcard_handler, ce, out);
361        if (!err)
362            err = map_result (ce);
363        
364        gpgme_data_release (out);
365        return err;
366    }

Legend:
Removed from v.23  
changed lines
  Added in v.36

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26