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

Annotation of /trunk/MyGPGME/editcard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (hide 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 twoaday 2 /* 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 twoaday 5 if (c->cnt == 0) {
95 twoaday 2 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 twoaday 5 default: c->cnt = 0; return "Q";
101 twoaday 2 }
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 twoaday 5 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.pin.ask")) {
111     s = c->u.pin.pinold;
112 twoaday 2 c->cnt++;
113     }
114 twoaday 5 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 twoaday 2 return s;
123     }
124     else if (ctx->edit_cmd == GPGME_EDITCARD_CHAPIN)
125     {
126 twoaday 5 if (ON_EVENT (STATUS_GET_HIDDEN, "passphrase.adminpin.ask")) {
127     s = c->u.pin.pinold;
128 twoaday 2 c->cnt++;
129     }
130 twoaday 5 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 twoaday 2 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 twoaday 5 gpgme_changepin_set (gpgme_editcard_t chpin, int which,
313     const char * pinold, const char * pinnew)
314 twoaday 2 {
315 twoaday 5 if (!chpin)
316     return mk_error (Invalid_Value);
317 twoaday 2 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