/[winpt]/trunk/MyGPGME/editcard.c
ViewVC logotype

Contents of /trunk/MyGPGME/editcard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations)
Mon Mar 7 13:21:36 2005 UTC (19 years, 11 months ago) by twoaday
File MIME type: text/plain
File size: 20072 byte(s)
2005-03-03  Timo Schulz  <twoaday@g10code.com>
                                                                                
        * wptCardDlg.cpp (card_changepin_dlg_proc): Add item to re-type the
        new PIN. Suggested by Achim.
        Support to show the unmasked PIN.
        Modified TAB-order.
        * wptPINDlg.cpp (pin_cb_dlg_proc): Show unmasked PIN.
 
        * Fixed wrong GPG --command-fd strings. Thanks to Achim.
 
2005-03-04  Timo Schulz  <twoaday@g10code.com>
 
        * GPG asks twice for the new PIN. Thanks to Achim.
        * wptCardDlg.cpp (card_changepin_dlg_proc): Reset the 'safety' pin also.        Only check the passphrase if the backup flag is enabled. Again thanks to        Achim.
 
2005-03-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptKeySignDlg.cpp (do_fill_seckeylist): Skip secret keys without
        a public key. Noted by Kurt Fitzner.
 


1 /* editcard.c - OpenPGP Smartcard Support
2 * Copyright (C) 2003, 2004 Timo Schulz
3 *
4 * This file is part of MyGPGME.
5 *
6 * MyGPGME is free software; you can redistribute it and/or modify
7 * 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
9 * (at your option) any later version.
10 *
11 * MyGPGME is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
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,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <stdio.h>
22
23 #include "gpgme-config.h"
24 #ifdef WITH_EDITCARD
25 #include "ops.h"
26 #include "context.h"
27 #include "util.h"
28 #include "types.h"
29
30
31 #define save_write(val) ((val)? (val) : "")
32
33 #define ON_EVENT(_code, _key) (code == (_code) && !strcmp (key, _key))
34
35
36 static void
37 card_status_handler (gpgme_ctx_t ctx, gpg_status_code_t code, char * args)
38 {
39 if (!ctx || ctx->out_of_core)
40 return;
41
42 switch( code ) {
43 case STATUS_CARDCTRL:
44 break;
45
46 case STATUS_KEY_CREATED:
47 safe_free (ctx->keygen_fpr);
48 ctx->keygen_fpr = strdup (args+2);
49 if (!ctx->keygen_fpr)
50 ctx->out_of_core = 1;
51 break;
52 }
53 } /* card_status_handler */
54
55
56 static const char *
57 statuscard_command_handler (void * opaque, gpg_status_code_t code,
58 const char * key)
59 {
60 gpgme_ctx_t ctx = opaque;
61 gpgme_editcard_t c = ctx->edit_opaque;
62
63 if (!c || ctx->out_of_core)
64 return NULL;
65
66 if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card.okay"))
67 {
68 if (c->card_cb )
69 return c->card_cb (1, c->cb_value);
70 }
71
72 return NULL;
73 } /* statuscard_command_handler */
74
75
76 static const char *
77 changepin_command_handler (void * opaque, gpg_status_code_t code,
78 const char * key)
79 {
80 gpgme_ctx_t ctx = opaque;
81 gpgme_editcard_t c = ctx->edit_opaque;
82 const char * s = "";
83
84 if( !c || ctx->out_of_core )
85 return NULL;
86
87 if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card_okay"))
88 {
89 if (c->card_cb)
90 return c->card_cb (1, c->cb_value);
91 }
92 if (ON_EVENT (STATUS_GET_LINE, "cardutil.change_pin.menu"))
93 {
94 if (c->cnt == 0) {
95 c->cnt++;
96 switch (ctx->edit_cmd) {
97 case GPGME_EDITCARD_CHUPIN: return "1";
98 case GPGME_EDITCARD_UNBPIN: return "2";
99 case GPGME_EDITCARD_CHAPIN: return "3";
100 default: c->cnt = 0; return "Q";
101 }
102 }
103 else if (c->cnt) {
104 c->cnt = 0;
105 return "Q";
106 }
107 }
108 if (ctx->edit_cmd == GPGME_EDITCARD_CHUPIN)
109 {
110 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.ask")) {
111 s = c->u.pin.pinold;
112 c->cnt++;
113 }
114 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.new.ask")) {
115 s = c->u.pin.pinnew;
116 c->cnt++;
117 }
118 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.repeat")) {
119 s = c->u.pin.pinnew;
120 c->cnt++;
121 }
122 return s;
123 }
124 else if (ctx->edit_cmd == GPGME_EDITCARD_CHAPIN)
125 {
126 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.adminpin.ask")) {
127 s = c->u.pin.pinold;
128 c->cnt++;
129 }
130 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.adminpin.new.ask")) {
131 s = c->u.pin.pinnew;
132 c->cnt++;
133 }
134 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.repeat")) {
135 s = c->u.pin.pinnew;
136 c->cnt++;
137 }
138 return s;
139 }
140 else if (ctx->edit_cmd == GPGME_EDITCARD_UNBPIN)
141 {
142 /* todo */
143 }
144
145 return NULL;
146 } /* changepin_command_handler */
147
148
149 static const char *
150 editcard_command_handler (void * opaque, gpg_status_code_t code, const char * key)
151 {
152 gpgme_ctx_t ctx = opaque;
153 gpgme_editcard_t c = ctx->edit_opaque;
154
155 DEBUG3 ("type=%d code=%d key=%s\n", c->type, code, key);
156
157 if (!c || ctx->out_of_core)
158 return NULL;
159
160 if (ON_EVENT (STATUS_GET_LINE, "cardctrl.insert_card.okay")) {
161 if (c->card_cb)
162 return c->card_cb (1, c->cb_value);
163 }
164
165 if (ON_EVENT (STATUS_GET_LINE, "cardedit.prompt"))
166 {
167 if (c->cnt == 0) /* first switch in the admin mode */
168 {
169 c->cnt++;
170 return "admin";
171 }
172 if (c->cnt == 1) /* then run the send command */
173 {
174 c->cnt++;
175 switch (ctx->edit_cmd)
176 {
177 case GPGME_EDITCARD_NAME: return "name";
178 case GPGME_EDITCARD_KEYURL: return "url";
179 case GPGME_EDITCARD_LOGIN: return "login";
180 case GPGME_EDITCARD_SEX: return "sex";
181 case GPGME_EDITCARD_LANG: return "lang";
182 case GPGME_EDITCARD_GENKEY: return "generate";
183 default: return "quit";
184 }
185 }
186 else if (c->cnt >= 2) /* done: send exit */
187 {
188 c->cnt = 0;
189 return "quit";
190 }
191 }
192 if (c->cnt > 0 && code == STATUS_GET_HIDDEN)
193 {
194 if (!strcmp (key, "passphrase.adminpin.ask"))
195 return c->apin;
196 if (!strcmp (key, "passphrase.pin.ask"))
197 return c->upin;
198 }
199 switch (ctx->edit_cmd)
200 {
201 case GPGME_EDITCARD_NAME:
202 if (ON_EVENT (STATUS_GET_LINE, "keygen.smartcard.surname"))
203 return save_write (c->u.edit.surname);
204 else if (ON_EVENT (STATUS_GET_LINE, "keygen.smartcard.givenname"))
205 return save_write (c->u.edit.givenname);
206 break;
207
208 case GPGME_EDITCARD_KEYURL:
209 if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_url"))
210 return save_write (c->u.edit.keyurl);
211 break;
212
213 case GPGME_EDITCARD_LOGIN:
214 if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_login"))
215 return save_write (c->u.edit.login);
216 break;
217
218 case GPGME_EDITCARD_SEX:
219 if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_sex"))
220 {
221 if (c->u.edit.sex != 'M'
222 && c->u.edit.sex != 'F'
223 && c->u.edit.sex != ' ')
224 return " ";
225 else
226 {
227 static char buf[2];
228 buf[0] = c->u.edit.sex; buf[1] = 0;
229 return buf;
230 }
231 }
232 break;
233
234 case GPGME_EDITCARD_LANG:
235 if (ON_EVENT (STATUS_GET_LINE, "cardedit.change_lang"))
236 return save_write (c->u.edit.lang);
237 break;
238
239 case GPGME_EDITCARD_GENKEY:
240 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.enter"))
241 return c->keygen.passwd;
242 if (ON_EVENT (STATUS_GET_BOOL, "cardedit.genkeys.backup_enc") ||
243 ON_EVENT (STATUS_GET_LINE, "cardedit.genkeys.backup_enc"))
244 return c->keygen.flags & GPGME_CARDFLAG_BAKENC? "Y" : "N";
245 if (ON_EVENT (STATUS_GET_BOOL, "cardedit.genkeys.replace_keys"))
246 {
247 if (! (c->keygen.flags & GPGME_CARDFLAG_REPLACE))
248 c->cancel = 1;
249 return c->keygen.flags & GPGME_CARDFLAG_REPLACE? "Y" : "N";
250 }
251 else if (ON_EVENT (STATUS_GET_LINE, "keygen.valid"))
252 return save_write (c->keygen.expdate);
253 else if (ON_EVENT (STATUS_GET_LINE, "keygen.name"))
254 return save_write (c->keygen.name);
255 else if (ON_EVENT (STATUS_GET_LINE, "keygen.email"))
256 return save_write (c->keygen.email);
257 else if (ON_EVENT (STATUS_GET_LINE, "keygen.comment"))
258 return save_write (c->keygen.comment);
259 break;
260
261 default:
262 return NULL;
263 }
264 return NULL;
265 } /* editcard_command_handler */
266
267
268 static gpgme_error_t
269 changepin_start( gpgme_ctx_t ctx )
270 {
271 gpgme_error_t rc;
272
273 ctx->pending=1;
274
275 _gpgme_gpg_release( &ctx->gpg );
276 rc = _gpgme_gpg_new( &ctx->gpg );
277 if( rc )
278 return rc;
279
280 _gpgme_gpg_set_status_handler( ctx->gpg, card_status_handler, ctx );
281 _gpgme_gpg_set_command_handler( ctx->gpg, changepin_command_handler, ctx );
282
283 _gpgme_gpg_add_arg( ctx->gpg, "--change-pin" );
284
285 rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
286 if( rc ) {
287 ctx->pending =0;
288 _gpgme_gpg_release( &ctx->gpg );
289 }
290
291 return rc;
292 } /* changepin_start */
293
294
295 gpgme_error_t
296 gpgme_op_changepin( gpgme_ctx_t ctx )
297 {
298 gpgme_error_t rc;
299
300 rc = changepin_start( ctx );
301 if( !rc ) {
302 gpgme_wait( ctx, 1 );
303 ctx->pending = 0;
304 if( gpgme_get_process_rc( ctx ) )
305 rc = mk_error( Interal_GPG_Problem );
306 }
307 return rc;
308 } /* gpgme_op_changepin */
309
310
311 gpgme_error_t
312 gpgme_changepin_set (gpgme_editcard_t chpin, int which,
313 const char * pinold, const char * pinnew)
314 {
315 if (!chpin)
316 return mk_error (Invalid_Value);
317 chpin->type = which;
318 chpin->u.pin.pinnew = pinnew;
319 chpin->u.pin.pinold = pinold;
320 return 0;
321 } /* gpgme_changepin_set */
322
323
324 static gpgme_error_t
325 editcard_start (gpgme_ctx_t ctx)
326 {
327 gpgme_error_t rc;
328
329 ctx->pending = 1;
330
331 _gpgme_gpg_release (&ctx->gpg);
332 rc = _gpgme_gpg_new (&ctx->gpg);
333 if (rc)
334 return rc;
335
336 _gpgme_gpg_set_status_handler (ctx->gpg, card_status_handler, ctx);
337 if (ctx->edit_cmd)
338 _gpgme_gpg_set_command_handler (ctx->gpg, editcard_command_handler, ctx);
339
340 _gpgme_gpg_add_arg (ctx->gpg, "--card-edit");
341
342 rc = _gpgme_gpg_spawn (ctx->gpg, ctx);
343 if (rc) {
344 ctx->pending = 0;
345 _gpgme_gpg_release (&ctx->gpg);
346 }
347
348 return rc;
349 } /* editcard_start */
350
351
352 gpgme_error_t
353 gpgme_op_editcard (gpgme_ctx_t ctx)
354 {
355 gpgme_error_t rc;
356
357 rc = editcard_start (ctx);
358 if (!rc) {
359 gpgme_wait (ctx, 1);
360 ctx->pending = 0;
361 if (((gpgme_editcard_t)ctx->edit_opaque)->cancel)
362 rc = mk_error (Canceled);
363 else if (ctx->keygen_fpr)
364 rc = mk_error (No_Error);
365 else if (gpgme_get_process_rc (ctx))
366 rc = mk_error (Interal_GPG_Problem);
367 }
368 return rc;
369 } /* gpgme_op_editcard */
370
371
372 gpgme_error_t
373 gpgme_editcard_new (gpgme_editcard_t * r_ctx)
374 {
375 gpgme_editcard_t ctx;
376
377 if (!r_ctx)
378 return mk_error (Invalid_Value);
379 *r_ctx = NULL;
380 ctx = calloc (1, sizeof * ctx);
381 if (!ctx)
382 return mk_error (Out_Of_Core);
383 *r_ctx = ctx;
384 return 0;
385 } /* gpgme_editcard_new */
386
387
388 void
389 gpgme_editcard_release (gpgme_editcard_t ctx)
390 {
391 if (!ctx)
392 return;
393 safe_free (ctx->keygen.name);
394 safe_free (ctx->keygen.comment);
395 safe_free (ctx->keygen.email);
396 safe_free (ctx->keygen.expdate);
397 safe_free (ctx );
398 } /* gpgme_editcard_release */
399
400
401 gpgme_error_t
402 gpgme_editcard_set_passwd (gpgme_editcard_t ctx, const char * passwd)
403 {
404 if (!ctx)
405 return mk_error (Invalid_Value);
406 ctx->type = GPGME_EDITCARD_GENKEY;
407 ctx->keygen.passwd = passwd;
408 return 0;
409 }
410
411 gpgme_error_t
412 gpgme_editcard_set_keygen_params (gpgme_editcard_t ctx, int flags,
413 const char * name, const char * email,
414 const char * comment, const char * expdate)
415 {
416 char * p;
417
418 if (!ctx)
419 return mk_error (Invalid_Value);
420 if (!name || !email)
421 return mk_error (Invalid_Value);
422
423 ctx->type = GPGME_EDITCARD_GENKEY;
424 ctx->keygen.flags = flags;
425
426 p = ctx->keygen.name = strdup (name);
427 if (!p)
428 return mk_error (Out_Of_Core);
429 p = ctx->keygen.email = strdup (email);
430 if (!p)
431 return mk_error (Out_Of_Core);
432 p = ctx->keygen.comment = comment? strdup (comment) : strdup ("");
433 if (!p)
434 return mk_error (Out_Of_Core);
435 p = ctx->keygen.expdate = expdate? strdup (expdate) : strdup ("0");
436 if (!p)
437 return mk_error(Out_Of_Core);
438 return 0;
439 } /* gpgme_editcard_set_keygen_params */
440
441
442 void
443 gpgme_editcard_set_callback (gpgme_editcard_t ctx,
444 const char *(*cb) (int code, void * opaque),
445 void * cb_value)
446 {
447 if (!ctx)
448 return;
449 ctx->card_cb = cb;
450 ctx->cb_value = cb_value;
451 } /* gpgme_editcard_set_callback */
452
453
454 gpgme_error_t
455 gpgme_editcard_control (gpgme_editcard_t ctx, int cmd, const void * val)
456 {
457 const char * p;
458
459 if (!ctx)
460 return mk_error (Invalid_Value);
461
462 switch (cmd) {
463 case GPGME_EDITCARD_NAME:
464 ctx->u.edit.givenname = (const char *)val;
465 break;
466
467 case GPGME_EDITCARD_NAME2:
468 ctx->u.edit.surname = (const char *)val;
469 break;
470
471 case GPGME_EDITCARD_KEYURL:
472 ctx->u.edit.keyurl = (const char *)val;
473 break;
474
475 case GPGME_EDITCARD_LOGIN:
476 ctx->u.edit.login = (const char *)val;
477 break;
478
479 case GPGME_EDITCARD_SEX:
480 p = (const char *)val;
481 ctx->u.edit.sex = *p;
482 break;
483
484 case GPGME_EDITCARD_LANG:
485 ctx->u.edit.lang = (const char *)val;
486 break;
487
488 case GPGME_EDITCARD_APIN:
489 ctx->apin = (const char *)val;
490 break;
491
492 case GPGME_EDITCARD_UPIN:
493 ctx->upin = (const char *)val;
494 break;
495
496 default:
497 return mk_error (Invalid_Mode);
498 }
499 /* in some cases we do not want to change the command ID:
500 1. when the given name will be set but the surname command
501 already set the command ID.
502 2. the pin is stored because the pin is no real command */
503 if (cmd == GPGME_EDITCARD_NAME2
504 || cmd == GPGME_EDITCARD_APIN
505 || cmd == GPGME_EDITCARD_UPIN)
506 ;
507 else
508 ctx->type = cmd;
509 return 0;
510 } /* gpgme_editcard_control */
511
512
513 static void
514 statuscard_colon_handler( gpgme_ctx_t ctx, char * line )
515 {
516 enum rectype_t {
517 CARD_None = 0,
518 CARD_AID,
519 CARD_Version,
520 CARD_Vendor,
521 CARD_Serial,
522 CARD_Name,
523 CARD_Lang,
524 CARD_Sex,
525 CARD_Url,
526 CARD_Login,
527 CARD_MaxPinLen,
528 CARD_SigCount,
529 CARD_Fpr
530 };
531 enum rectype_t rectype;
532 gpgme_card_t card;
533 char * t, * p, * pend;
534 int field = 0;
535
536 if( ctx->out_of_core )
537 return;
538
539 if( !line )
540 return ; /* EOF */
541
542 if( !ctx->card && gpgme_card_new( &ctx->card ) ) {
543 ctx->out_of_core = 1;
544 return;
545 }
546 card = ctx->card;
547
548 for( p = line; p; p = pend ) {
549 field++;
550 pend = strchr( p, ':' );
551 if( pend )
552 *pend++ = 0;
553
554 if( field == 1 ) {
555 if( !strcmp( p, "AID" ) )
556 rectype = CARD_AID;
557 else if( !strcmp( p, "version" ) )
558 rectype = CARD_Version;
559 else if( !strcmp( p, "vendor" ) )
560 rectype = CARD_Vendor;
561 else if( !strcmp( p, "serial" ) )
562 rectype = CARD_Serial;
563 else if( !strcmp( p, "name" ) )
564 rectype = CARD_Name;
565 else if( !strcmp( p, "lang" ) )
566 rectype = CARD_Lang;
567 else if( !strcmp( p, "sex" ) )
568 rectype = CARD_Sex;
569 else if( !strcmp( p, "url" ) )
570 rectype = CARD_Url;
571 else if( !strcmp( p, "login" ) )
572 rectype = CARD_Login;
573 else if( !strcmp( p, "maxpinlen" ) )
574 rectype = CARD_MaxPinLen;
575 else if( !strcmp( p, "sigcount" ) )
576 rectype = CARD_SigCount;
577 else if( !strcmp( p, "fpr" ) )
578 rectype = CARD_Fpr;
579 else
580 rectype = CARD_None;
581 }
582 switch( rectype ) {
583 case CARD_AID:
584 if( field == 2 ) {
585 t = card->aid = strdup( p );
586 if( !t )
587 ctx->out_of_core = 1;
588 }
589 break;
590 case CARD_Version:
591 if( field == 2 ) {
592 t = card->version = strdup( p );
593 if( !t )
594 ctx->out_of_core = 1;
595 }
596 break;
597 case CARD_Vendor:
598 if( field == 3 ) {
599 t = card->vendor = strdup( p );
600 if( !t )
601 ctx->out_of_core = 1;
602 }
603 break;
604 case CARD_Serial:
605 if( field == 2 ) {
606 t = card->serial = strdup( p );
607 if( !t )
608 ctx->out_of_core = 1;
609 }
610 break;
611 case CARD_Name:
612 if( field == 2 ) {
613 t = card->givenname = strdup( p );
614 if( !t )
615 ctx->out_of_core = 1;
616 }
617 else if( field == 3 ) {
618 t = card->surname = strdup( p );
619 if( !t )
620 ctx->out_of_core = 1;
621 }
622 break;
623 case CARD_Lang:
624 if( field == 2 )
625 card->lang = strdup( p ) ;
626 break;
627 case CARD_Sex:
628 if( field == 2 )
629 card->sex = *p;
630 break;
631 case CARD_Url:
632 if( field == 2 ) {
633 safe_free( card->url );
634 card->url = calloc( 1, strlen( p ) + 1 );
635 if( !card->url ) {
636 ctx->out_of_core = 1;
637 return;
638 }
639 _gpgme_decode_c_string (p, &card->url, strlen (p) + 1);
640 }
641 break;
642 case CARD_Login:
643 if( field == 2 ) {
644 t = card->login = strdup( p );
645 if( !t )
646 ctx->out_of_core = 1;
647 }
648 break;
649 case CARD_MaxPinLen:
650 break;
651 case CARD_SigCount:
652 if( field == 2 )
653 card->sig_count = atol( p );
654 break;
655 case CARD_Fpr:
656 if( field == 2 || field == 3 || field == 4 ) {
657 t = card->fpr[ctx->tmp_i++] = strdup( p );
658 if( !t )
659 ctx->out_of_core = 1;
660 }
661 break;
662 }
663 }
664 } /* statuscard_colon_handler */
665
666
667 static gpgme_error_t
668 status_card_start( gpgme_ctx_t ctx, gpgme_data_t tmp_out )
669 {
670 gpgme_error_t rc;
671
672 if( !ctx || !tmp_out )
673 return mk_error( Invalid_Value );
674 _gpgme_data_set_mode( tmp_out, GPGME_DATA_MODE_IN );
675
676 ctx->pending = 1;
677
678 _gpgme_gpg_release( &ctx->gpg );
679 rc = _gpgme_gpg_new( &ctx->gpg );
680 if( rc )
681 return rc;
682
683 _gpgme_gpg_set_command_handler( ctx->gpg, statuscard_command_handler, ctx );
684 if( ctx->use_logging )
685 _gpgme_gpg_set_logging_handler( ctx->gpg, ctx );
686
687 _gpgme_gpg_add_arg( ctx->gpg, "--with-colons" );
688 _gpgme_gpg_add_arg( ctx->gpg, "--card-status" );
689 _gpgme_gpg_add_arg( ctx->gpg, "--output" );
690 _gpgme_gpg_add_arg( ctx->gpg, "-" );
691 _gpgme_gpg_add_data( ctx->gpg, tmp_out, 1 );
692
693 rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
694 if( rc ) {
695 ctx->pending = 0;
696 _gpgme_gpg_release( &ctx->gpg );
697 }
698 return rc;
699 } /* status_card_start */
700
701
702 gpgme_error_t
703 gpgme_op_statuscard( gpgme_ctx_t ctx, gpgme_card_t * ret_card )
704 {
705 gpgme_data_t tmp = NULL;
706 gpgme_error_t rc;
707 char buf[200];
708
709 if (!ret_card || !ctx)
710 return mk_error (Invalid_Value);
711
712 rc = gpgme_data_new (&tmp);
713 if (rc)
714 return rc;
715
716 rc = status_card_start( ctx, tmp );
717 if( !rc ) {
718 gpgme_wait( ctx, 1 );
719 ctx->pending = 0;
720 if( gpgme_get_process_rc( ctx ) )
721 rc = mk_error( Interal_GPG_Problem );
722 }
723
724 gpgme_data_rewind( tmp );
725 while( !rc && gpgme_data_readline( tmp, buf, sizeof buf-2 ) )
726 statuscard_colon_handler( ctx, buf );
727 gpgme_data_release( tmp );
728 ctx->tmp_i = 0;
729 *ret_card = ctx->card;
730 return rc;
731 } /* gpgme_op_statuscard */
732
733
734 gpgme_error_t
735 gpgme_card_new( gpgme_card_t * ret_card )
736 {
737 gpgme_card_t c;
738
739 if (!ret_card)
740 return mk_error( Invalid_Value );
741 *ret_card = NULL;
742 c = calloc( 1, sizeof * c );
743 if( !c )
744 return mk_error( Out_Of_Core );
745 *ret_card = c;
746 return 0;
747 } /* gpgme_card_new */
748
749
750 void
751 gpgme_card_release( gpgme_card_t card )
752 {
753 int i;
754
755 if( !card )
756 return;
757 safe_free( card->aid );
758 safe_free( card->version );
759 safe_free( card->lang );
760 safe_free( card->login );
761 for( i=0; i < 3; i++ )
762 safe_free( card->fpr[i] );
763 safe_free( card->surname );
764 safe_free( card->givenname );
765 safe_free( card->serial );
766 safe_free( card->vendor );
767 safe_free( card->url );
768 safe_free( card );
769 } /* gpgme_card_release */
770
771
772 const char *
773 gpgme_card_get_string_attr( gpgme_card_t card, gpgme_attr_t what,
774 void ** reserved, int idx )
775 {
776 const char * s;
777
778 if( !card )
779 return NULL;
780
781 switch( what ) {
782 case GPGME_ATTR_CARD_AID:
783 s=card->aid;
784 break;
785
786 case GPGME_ATTR_CARD_VER:
787 s=card->version;
788 break;
789
790 case GPGME_ATTR_CARD_VENDOR:
791 s=card->vendor;
792 break;
793
794 case GPGME_ATTR_CARD_NAME:
795 s=card->givenname;
796 break;
797
798 case GPGME_ATTR_CARD_NAME2:
799 s=card->surname;
800 break;
801
802 case GPGME_ATTR_CARD_LANG:
803 s=card->lang;
804 break;
805
806 case GPGME_ATTR_CARD_URL:
807 s=card->url;
808 break;
809
810 case GPGME_ATTR_CARD_LOGIN:
811 s=card->login;
812 break;
813
814 case GPGME_ATTR_CARD_FPR:
815 if( idx >= 0 && idx <= 3 )
816 s=card->fpr[idx];
817 else
818 s=NULL;
819 break;
820
821 case GPGME_ATTR_CARD_SERIAL:
822 s=card->serial;
823 break;
824
825 default:
826 s=NULL;
827 break;
828 }
829 return s;
830 } /* gpgme_card_get_string_attr */
831
832
833 unsigned long
834 gpgme_card_get_ulong_attr( gpgme_card_t card, gpgme_attr_t what,
835 void ** reserved, int idx )
836 {
837 unsigned long t;
838
839 if( !card )
840 return 0;
841
842 switch( what ) {
843 case GPGME_ATTR_CARD_SIGCOUNT:
844 t = card->sig_count;
845 break;
846
847 case GPGME_ATTR_CARD_SEX:
848 t = card->sex;
849 break;
850
851 default:
852 t = 0;
853 break;
854 }
855 return t;
856 } /* gpgme_card_get_ulong_attr */
857
858 #endif /* WITH_EDITCARD */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26