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

Contents of /trunk/MyGPGME/editcard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 19746 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26