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

Annotation of /trunk/MyGPGME/editcard.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (hide annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File MIME type: text/plain
File size: 20956 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26