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

Annotation of /trunk/Src/wptCardEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 260 - (hide annotations)
Wed Aug 16 10:01:30 2006 UTC (18 years, 6 months ago) by twoaday
File size: 9320 byte(s)


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26