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

Contents of /trunk/Src/wptCardEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations)
Mon Oct 17 08:49:30 2005 UTC (19 years, 4 months ago) by twoaday
File size: 9472 byte(s)
More bug fixes all over the place.
See ChangeLog for details.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26