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

Contents of /trunk/Src/wptCardEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 270 - (show annotations)
Sat Oct 21 18:08:57 2006 UTC (18 years, 4 months ago) by twoaday
File size: 9323 byte(s)


1 /* wptCardEditCB.cpp - Card callbacks
2 * Copyright (C) 2003, 2004, 2005, 2006 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
22 #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
40 /* 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 /*
48 #ifdef _DEBUG
49 MessageBox (NULL, (const char*)buf, stat_key, MB_OK);
50 #endif
51 */
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 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 /* XXX: do we need c->reset()? */
89 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] = ' ';
279 buf[1] = 0;
280 }
281 else {
282 buf[0] = c->edit.sex;
283 buf[1] = 0;
284 }
285 gpg_write (fd, buf, strlen (buf));
286 }
287 break;
288
289 case GPG_EDITCARD_LANG:
290 if (!strcmp (key, "cardedit.change_lang")) {
291 s = save_write (c->edit.lang);
292 gpg_write (fd, s, strlen (s));
293 }
294 break;
295
296 case GPG_EDITCARD_GENKEY:
297 if (!strcmp (key, "passphrase.enter"))
298 gpg_write (fd, c->keygen.pass, strlen (c->keygen.pass));
299 if (!strcmp (key, "cardedit.genkeys.backup_enc")) {
300 s = c->keygen.flags & GPG_CARDFLAG_BAKENC? "Y" : "N";
301 gpg_write (fd, s, strlen (s));
302 }
303 if (!strcmp (key, "cardedit.genkeys.replace_keys")) {
304 if (! (c->keygen.flags & GPG_CARDFLAG_REPLACE))
305 c->cancel = 1;
306 s = c->keygen.flags & GPG_CARDFLAG_REPLACE? "Y" : "N";
307 gpg_write (fd, s, strlen (s));
308 }
309 else if (!strcmp (key, "keygen.valid")) {
310 s = save_write (c->keygen.expdate);
311 gpg_write (fd, s, strlen (s));
312 }
313 else if (!strcmp (key, "keygen.name")) {
314 s = save_write (c->keygen.name);
315 gpg_write (fd, s, strlen (s));
316 }
317 else if (!strcmp (key, "keygen.email")) {
318 s = save_write (c->keygen.email);
319 gpg_write (fd, s, strlen (s));
320 }
321 else if (!strcmp (key, "keygen.comment")) {
322 s = save_write (c->keygen.comment);
323 gpg_write (fd, s, strlen (s));
324 }
325 break;
326
327 default:
328 break;
329 }
330
331 return 0;
332 }
333
334
335 /* Check if a GPG status code occured which marks the
336 current operation as failed.
337 Return value: gpg error constant. */
338 static gpgme_error_t
339 map_result (GpgCardEdit *ce)
340 {
341 if (!ce->getResult ())
342 return gpg_error (GPG_ERR_NO_ERROR);
343 if (ce->getResult () & GPG_CARDRES_NOCARD)
344 return gpg_error (GPG_ERR_CARD_NOT_PRESENT);
345 if (ce->getResult () & GPG_CARDRES_BAD_PIN)
346 return gpg_error (GPG_ERR_BAD_PIN);
347 return 0;
348 }
349
350
351 /* Wrapper around the gpgme card interface.
352 @ctx: context to use.
353 @ce: card edit context.
354 Return value: 0 on success. */
355 gpgme_error_t
356 gpg_card_edit (gpgme_ctx_t ctx, GpgCardEdit *ce)
357 {
358 gpgme_data_t out;
359 gpgme_error_t err;
360
361 err = gpgme_data_new (&out);
362 if (err)
363 return err;
364
365 if (ce->getType () > GPG_EDITCARD_CHPIN_ID)
366 err = gpgme_op_card_edit (ctx, NULL, change_pin_handler, ce, out);
367 else
368 err = gpgme_op_card_edit (ctx, NULL, editcard_handler, ce, out);
369 if (!err)
370 err = map_result (ce);
371
372 gpgme_data_release (out);
373 return err;
374 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26