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

Annotation of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


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


1 twoaday 2 /* editkey.c - GPG edit key interface
2     * Copyright (C) 2001-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
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #include <stdio.h>
22     #include <string.h>
23     #include <stdlib.h>
24     #include <assert.h>
25    
26     #include "gpgme-config.h"
27     #ifdef WITH_EDITKEY
28     #include "ops.h"
29     #include "context.h"
30     #include "util.h"
31     #include "common-status.h"
32    
33     #define GET_BOOL STATUS_GET_BOOL
34     #define GET_LINE STATUS_GET_LINE
35     #define GET_HIDDEN STATUS_GET_HIDDEN
36    
37     #define do_check(code, exp, key, val) \
38     (((code) == (exp)) && (strcmp ((key), (val) ) == 0))
39    
40     #define is_sig_cmd(ctx)((ctx)->edit_cmd == GPGME_EDITKEY_SIGN \
41     || (ctx)->edit_cmd == GPGME_EDITKEY_TSIGN \
42     || (ctx)->edit_cmd == GPGME_EDITKEY_LSIGN \
43     || (ctx)->edit_cmd == GPGME_EDITKEY_NRSIGN \
44     || (ctx)->edit_cmd == GPGME_EDITKEY_NRLSIGN)
45    
46     struct editkey_result_s {
47     int bad_passphrase;
48     int already_signed;
49     int key_expired;
50     };
51    
52    
53     void
54     _gpgme_release_editkey_result (_editkey_result_t res)
55     {
56     safe_free (res);
57     }
58    
59    
60     static void
61     editkey_status_handler( gpgme_ctx_t ctx, gpg_status_code_t code, char *args )
62     {
63     if (ctx->out_of_core)
64     return;
65    
66     if (ctx->result_type == RESULT_TYPE_NONE)
67     {
68     ctx->result.editk = calloc (1, sizeof * ctx->result.editk);
69     if (!ctx->result.editk)
70     {
71     ctx->out_of_core = 1;
72     return;
73     }
74     ctx->result_type = RESULT_TYPE_EDITKEY;
75     }
76    
77     assert (ctx->result_type == RESULT_TYPE_EDITKEY);
78    
79     switch (code) {
80     case STATUS_BAD_PASSPHRASE:
81     ctx->result.editk->bad_passphrase++;
82     break;
83    
84     case STATUS_ALREADY_SIGNED:
85     ctx->result.editk->already_signed++;
86     break;
87    
88     case STATUS_KEYEXPIRED:
89     case STATUS_SIGEXPIRED:
90     ctx->result.editk->key_expired = 1;
91     break;
92    
93     case STATUS_PROGRESS:
94     _gpgme_genkey_status_handler (ctx, code, args);
95     break;
96    
97     case STATUS_KEY_CREATED:
98     safe_free( ctx->keygen_fpr );
99     ctx->keygen_fpr = strdup( args+2 );
100     if( !ctx->keygen_fpr )
101     ctx->out_of_core = 1;
102     break;
103     }
104    
105     /*DEBUG2 ("editkey_status: code=%d args=`%s'\n", code, args);*/
106     } /* editkey_status_handler */
107    
108    
109     static const char *
110     cmd_keyserv_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char * key)
111     {
112     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
113    
114     if (do_check (code, GET_LINE, key, "keyedit.add_keyserver"))
115     return ctx->u.keyserv.url;
116     if (do_check (code, GET_BOOL, key, "keyedit.confirm_keyserver"))
117     return "Y";
118     if (do_check (code, GET_HIDDEN, key, "passphrase.enter"))
119     return ctx->u.keyserv.passwd;
120     if (do_check (code, GET_LINE, key, "keyedit.prompt"))
121     return "save";
122    
123     return NULL;
124     }
125    
126     static const char*
127     cmd_sign_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
128     {
129     DEBUG2 ("cmd_sign: code=%d args=`%s'\n", code, key);
130    
131     if( !strcmp( key, "sign_uid.class" ) ) {
132     static char id[32];
133     sprintf( id, "%d", ctx->u.sign.sig_class );
134     return id;
135     }
136     if (!strcmp (key, "sign_uid.expire"))
137     return "Y"; /* the sig expires when the key expires */
138     if (!strcmp (key, "siggen.valid"))
139     return ctx->u.sign.exp_date;
140     if (!strcmp (key, "trustsig_prompt.trust_value"))
141     return ctx->u.sign.trust.val;
142     if (!strcmp (key, "trustsig_prompt.trust_depth"))
143     return ""; /* fixme */
144     if (!strcmp (key, "trustsig_prompt.trust_regexp"))
145     return ""; /* fixme */
146     if( do_check( code, GET_BOOL, key, "sign_uid.local_promote_okay" ) )
147     return "Y";
148     if( do_check( code, GET_BOOL, key, "sign_uid.okay" ) )
149     return "Y";
150     if( do_check( code, GET_BOOL, key, "keyedit.sign_all.okay" ) )
151     return "Y";
152     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
153     return ctx->u.sign.passwd;
154     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
155     return "save";
156    
157     return NULL;
158     } /* cmd_sign_handler */
159    
160    
161     static const char*
162     cmd_trust_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
163     {
164     if( do_check( code, GET_BOOL, key, "edit_ownertrust.set_ultimate.okay" ) )
165     return "Y";
166     if( do_check( code, GET_LINE, key, "edit_ownertrust.value" ) )
167     return ctx->u.trust.trust_val;
168     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
169     return "save";
170    
171     return NULL;
172     } /* cmd_trust_handler */
173    
174    
175     static const char*
176     cmd_adduid_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
177     {
178     if( do_check( code, GET_LINE, key, "keygen.name" ) )
179     return ctx->u.adduid.name;
180     if( do_check( code, GET_LINE, key, "keygen.email" ) )
181     return ctx->u.adduid.email;
182     if( do_check( code, GET_LINE, key, "keygen.comment" ) ) {
183     if( ctx->u.adduid.use_comment )
184     return ctx->u.adduid.comment;
185     return "";
186     }
187     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
188     return ctx->u.adduid.passwd;
189     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
190     return "save";
191    
192     return NULL;
193     } /* cmd_adduid_handler */
194    
195    
196     static const char*
197     cmd_deluid_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
198     int *r_step )
199     {
200     static char buf[64];
201     int step = *r_step;
202    
203     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
204     sprintf( buf, "uid %d", ctx->u.deluid.id );
205     *r_step = step = 1;
206     return buf;
207     }
208     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
209     *r_step = step = 2;
210     return "deluid";
211     }
212     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.remove.uid.okay" ) ) {
213     *r_step = step = 3;
214     return "Y";
215     }
216     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
217     *r_step = step = 0;
218     return "save";
219     }
220    
221     return NULL;
222     } /* cmd_deluid_handler */
223    
224    
225     static const char *
226     cmd_delsig_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
227     int * r_step)
228     {
229     static char buf[64];
230     int step = *r_step;
231    
232     if (step == 0 && do_check (code, GET_LINE, key, "keyedit.prompt"))
233     {
234     sprintf (buf, "uid %d", ctx->u.delsig.uid);
235     *r_step = step = 1;
236     return buf;
237     }
238     if (step == 1 && do_check (code, GET_LINE, key, "keyedit.prompt"))
239     {
240     *r_step = step = 2;
241     return "delsig";
242     }
243     if (do_check (code, GET_BOOL, key, "keyedit.delsig.unknown") ||
244     do_check (code, GET_BOOL, key, "keyedit.delsig.valid"))
245     {
246     if (++ctx->u.delsig.currno == ctx->u.delsig.signo)
247     return "Y";
248     else
249     return "N";
250     }
251     if (ctx->u.delsig.signo == 0 &&
252     do_check (code, GET_BOOL, key, "keyedit.delsig.selfsig"))
253     return "Y";
254     if (step == 2 && do_check (code, GET_LINE, key, "keyedit.prompt"))
255     {
256     *r_step = step = 0;
257     return "save";
258     }
259     return NULL;
260     }
261    
262    
263     static const char*
264     cmd_delkey_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
265     int *r_step )
266     {
267     static char buf[64];
268     int step = *r_step;
269    
270     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
271     sprintf( buf, "key %d", ctx->u.delkey.id );
272     *r_step = step = 1;
273     return buf;
274     }
275     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
276     *r_step = step = 2;
277     return "delkey";
278     }
279     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.remove.subkey.okay" ) ) {
280     *r_step = step = 3;
281     return "Y";
282     }
283     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
284     *r_step = step = 0;
285     return "save";
286     }
287    
288     return NULL;
289     } /* cmd_delkey_handler */
290    
291    
292     static const char*
293     cmd_addkey_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
294     {
295     static char buf[64];
296    
297     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
298     return ctx->u.addkey.passwd;
299     if( do_check( code, GET_LINE, key, "keygen.algo" ) ) {
300     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.algo );
301     return buf;
302     }
303     if( do_check( code, GET_LINE, key, "keygen.size" ) ) {
304     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.size );
305     return buf;
306     }
307     if( do_check( code, GET_LINE, key, "keygen.valid" ) ) {
308     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.valid );
309     return buf;
310     }
311     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
312     return "save";
313     return NULL;
314     } /* cmd_addkey_handler */
315    
316    
317     static const char*
318     cmd_passwd_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
319     {
320     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" )
321     && !ctx->u.passwd.send_old ) {
322     ctx->u.passwd.send_old = 1;
323     return ctx->u.passwd.old_passwd;
324     }
325     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
326     return ctx->u.passwd.new_passwd;
327     if( do_check( code, GET_BOOL, key, "change_passwd.empty.okay" ) )
328     return ctx->u.passwd.allow_empty? "Y" : "N";
329     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
330     return "save";
331     return NULL;
332     } /* cmd_passwd_handler */
333    
334    
335     static const char *
336     cmd_setpref_handler (gpgme_editkey_t ctx, gpg_statcode_t code, const char * key)
337     {
338     static char buf[128];
339    
340     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 0) {
341     ctx->u.pref.id++;
342     _snprintf (buf, sizeof buf-1, "setpref %s", ctx->u.pref.new_prefs);
343     return buf;
344     }
345     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 1) {
346     ctx->u.pref.id++;
347     return "updpref";
348     }
349     if (do_check (code, GET_BOOL, key, "keyedit.updpref.okay"))
350     return "Y";
351     if (do_check (code, GET_HIDDEN, key, "passphrase.enter"))
352     return ctx->u.pref.passwd;
353     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 2) {
354     ctx->u.pref.id = 0;
355     return "save";
356     }
357     return NULL;
358     } /* cmd_setpref_handler */
359    
360    
361     static const char*
362     cmd_primary_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
363     int *r_step )
364     {
365     static char buf[64];
366     int step = *r_step;
367    
368     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
369     sprintf( buf, "uid %d", ctx->u.primary.id );
370     *r_step = step = 1;
371     return buf;
372     }
373     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
374     *r_step = step = 2;
375     return "primary";
376     }
377     if( step == 2 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
378     *r_step = step = 3;
379     return ctx->u.primary.passwd;
380     }
381     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
382     *r_step = step = 0;
383     return "save";
384     }
385     return NULL;
386     } /* cmd_primary_handler */
387    
388    
389     static const char*
390     cmd_expire_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
391     int *r_step )
392     {
393     static char buf[64];
394     int step = *r_step;
395    
396     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
397     sprintf(buf, "key %d", ctx->u.expire.id);
398     *r_step = step = 1;
399     return buf;
400     }
401     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
402     *r_step = step = 2;
403     return "expire";
404     }
405     if( step == 2 && do_check( code, GET_LINE, key, "keygen.valid" ) ) {
406     *r_step = step = 3;
407     if( ctx->u.expire.days ) {
408     sprintf( buf, "%d", ctx->u.expire.days );
409     return buf;
410     }
411     else
412     return ctx->u.expire.date;
413     }
414     if( step == 3 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
415     *r_step = step = 4;
416     return ctx->u.expire.passwd;
417     }
418     if( step == 4 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
419     *r_step = step = 0;
420     return "save";
421     }
422    
423     return NULL;
424     } /* cmd_expire_handler */
425    
426    
427     const char*
428     cmd_revsig_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
429     int *r_step )
430     {
431     static char buf[64];
432     int step = *r_step;
433    
434     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
435     sprintf( buf, "uid %d", ctx->u.revsig.id );
436     *r_step = step = 1;
437     return buf;
438     }
439     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
440     *r_step = step = 2;
441     return "revsig";
442     }
443     if( step == 2 && do_check( code, GET_BOOL, key, "ask_revoke_sig.one" ) ) {
444     *r_step = step = 3;
445     return "Y";
446     }
447     if( step == 3 && do_check( code, GET_BOOL, key, "ask_revoke_sig.okay" ) ) {
448     *r_step = step = 4;
449     return "Y";
450     }
451     if( step == 4 && do_check( code, GET_LINE, key, "ask_revocation_reason.code" ) ) {
452     *r_step = step = 5;
453     return "0";
454     }
455     if( step == 5 && do_check( code, GET_LINE, key, "ask_revocation_reason.text" ) ) {
456     *r_step = step = 6;
457     return "\n";
458     }
459     if( step == 6 && do_check( code, GET_BOOL, key, "ask_revocation_reason.okay" ) ) {
460     *r_step = step = 7;
461     return "Y";
462     }
463     if( step == 7 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
464     *r_step = step = 8;
465     return ctx->u.revsig.passwd;
466     }
467     if( step == 8 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
468     *r_step = step = 0;
469     return "save";
470     }
471    
472     return NULL;
473     } /* cmd_revsig_handler */
474    
475    
476     static const char *
477     cmd_revkey_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
478     int *r_step )
479     {
480     int step = *r_step;
481     static char buf[64];
482    
483     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
484     sprintf( buf, "key %d", ctx->u.revkey.id );
485     *r_step = step = 1;
486     return buf;
487     }
488     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
489     *r_step = step = 2;
490     return "revkey";
491     }
492     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.revoke.subkey.okay" ) ) {
493     *r_step = step = 3;
494     return "Y";
495     }
496     if( step == 3 && do_check( code, GET_LINE, key, "ask_revocation_reason.code" ) ) {
497     sprintf( buf, "%d", ctx->u.revkey.reason );
498     *r_step = step = 4;
499     return buf;
500     }
501     if( step == 4 && do_check( code, GET_LINE, key, "ask_revocation_reason.text" ) ) {
502     *r_step = step = 5;
503     return "";
504     }
505     if( step == 5 && do_check( code, GET_BOOL, key, "ask_revocation_reason.okay" ) ) {
506     *r_step = step = 6;
507     return "Y";
508     }
509     if( step == 6 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
510     *r_step = step = 7;
511     return ctx->u.revkey.passwd;
512     }
513     if( step == 7 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
514     *r_step = step = 0;
515     return "save";
516     }
517     return NULL;
518     } /* cmd_revkey_handler */
519    
520    
521     static const char *
522     cmd_addrev_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
523     gpgme_ctx_t c, int * r_step)
524     {
525     int step = *r_step;
526    
527     /*DEBUG3("code=%d key=%s step=%d\n", code, key, step);*/
528     if ((step == 0 || c->result.editk->already_signed)
529     && do_check (code, GET_LINE, key, "keyedit.add_revoker")) {
530     *r_step = step = 1;
531     if (c->result.editk->already_signed) {
532     *r_step = step = 3;
533     return "";
534     }
535     return ctx->u.addrev.uid;
536     }
537     if( step == 1 && do_check( code, GET_BOOL, key, "keyedit.add_revoker.okay" ) ) {
538     *r_step = step = 2;
539     return "Y";
540     }
541     if( step == 2 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
542     *r_step = step = 3;
543     return ctx->u.addrev.passwd;
544     }
545     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
546     *r_step = step = 0;
547     return "save";
548     }
549     return NULL;
550     } /* cmd_addrev_handler */
551    
552    
553     static const char *
554     cmd_addphoto_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
555     int *r_step )
556     {
557     int step = *r_step;
558    
559     if( do_check( code, GET_LINE, key, "photoid.jpeg.add" ) )
560     return ctx->u.addphoto.jpg;
561     if( do_check( code, GET_BOOL, key, "photoid.jpeg.size" ) )
562     return "Y";
563     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
564     return ctx->u.addphoto.passwd;
565     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
566     *r_step = step = 0;
567     return "save";
568     }
569     return NULL;
570     } /* cmd_addphoto_handler */
571    
572    
573     static const char *
574     cmd_enable_disable_handler( gpgme_editkey_t ctx, gpg_status_code_t code,
575     const char * key, int *r_step )
576     {
577     *r_step = 0;
578     return "save";
579     } /* cmd_enable_disable_handler */
580    
581    
582     static const char *
583     editkey_command_handler (void * opaque, gpg_status_code_t code, const char * key)
584     {
585     static int step = 0;
586     gpgme_ctx_t c = opaque;
587     gpgme_editkey_t ctx = c->edit_opaque;
588    
589     if (!code)
590     return NULL;
591    
592     if (!ctx || ctx->type != c->edit_cmd)
593     {
594     DEBUG2 ("editkey cmd handler has a wrong type (%d != %d)", ctx->type, c->edit_cmd);
595     return NULL;
596     }
597    
598     switch (c->edit_cmd) {
599     case GPGME_EDITKEY_LSIGN:
600     case GPGME_EDITKEY_SIGN:
601     case GPGME_EDITKEY_NRSIGN:
602     case GPGME_EDITKEY_TSIGN:
603     case GPGME_EDITKEY_NRLSIGN:
604     return cmd_sign_handler (ctx, code, key);
605    
606     case GPGME_EDITKEY_TRUST:
607     return cmd_trust_handler( ctx, code, key );
608    
609     case GPGME_EDITKEY_ADDUID:
610     return cmd_adduid_handler( ctx, code, key );
611    
612     case GPGME_EDITKEY_DELUID:
613     return cmd_deluid_handler( ctx, code, key, &step );
614    
615     case GPGME_EDITKEY_DELSIG:
616     return cmd_delsig_handler (ctx, code, key, &step);
617    
618     case GPGME_EDITKEY_DELKEY:
619     return cmd_delkey_handler( ctx, code, key, &step );
620    
621     case GPGME_EDITKEY_ADDKEY:
622     return cmd_addkey_handler( ctx, code, key );
623    
624     case GPGME_EDITKEY_PASSWD:
625     return cmd_passwd_handler( ctx, code, key );
626    
627     case GPGME_EDITKEY_PRIMARY:
628     return cmd_primary_handler( ctx, code, key, &step );
629    
630     case GPGME_EDITKEY_EXPIRE:
631     return cmd_expire_handler( ctx, code, key, &step );
632    
633     case GPGME_EDITKEY_REVSIG:
634     return cmd_revsig_handler( ctx, code, key, &step );
635    
636     case GPGME_EDITKEY_REVKEY:
637     return cmd_revkey_handler( ctx, code, key, &step );
638    
639     case GPGME_EDITKEY_ADDREV:
640     return cmd_addrev_handler (ctx, code, key, c, &step);
641    
642     case GPGME_EDITKEY_ADDPHOTO:
643     return cmd_addphoto_handler( ctx, code, key, &step );
644    
645     case GPGME_EDITKEY_ENABLE:
646     return cmd_enable_disable_handler( ctx, code, key, &step );
647    
648     case GPGME_EDITKEY_DISABLE:
649     return cmd_enable_disable_handler( ctx, code, key, &step );
650    
651     case GPGME_EDITKEY_SETPREF:
652     return cmd_setpref_handler (ctx, code, key);
653     }
654    
655     return NULL;
656     } /* editkey_command_handler */
657    
658    
659     static gpgme_error_t
660     editkey_start (gpgme_ctx_t ctx, const char * keyid)
661     {
662     gpgme_error_t rc;
663    
664     if (ctx->result_type == RESULT_TYPE_EDITKEY &&
665     ctx->result.editk != NULL)
666     memset (ctx->result.editk, 0, sizeof (struct editkey_result_s));
667    
668     fail_on_pending_request (ctx);
669     ctx->pending = 1;
670    
671     /* create a process object */
672     _gpgme_gpg_release( &ctx->gpg);
673     rc = _gpgme_gpg_new( &ctx->gpg );
674     if( rc )
675     goto leave;
676    
677     _gpgme_gpg_set_status_handler ( ctx->gpg, editkey_status_handler, ctx );
678     if( ctx->edit_cmd ) {
679     rc = _gpgme_gpg_set_command_handler( ctx->gpg, editkey_command_handler, ctx );
680     if( rc )
681     goto leave;
682     }
683    
684     if (ctx->locusr) {
685     _gpgme_gpg_add_arg (ctx->gpg, "-u ");
686     _gpgme_gpg_add_arg (ctx->gpg, ctx->locusr);
687     }
688     if (is_sig_cmd (ctx) && ((gpgme_editkey_t)ctx->edit_opaque)->u.sign.exp_date)
689     _gpgme_gpg_add_arg (ctx->gpg, "--ask-cert-expire");
690     if (is_sig_cmd (ctx) && ((gpgme_editkey_t)ctx->edit_opaque)->u.sign.sig_class)
691     _gpgme_gpg_add_arg (ctx->gpg, "--ask-cert-level");
692    
693     _gpgme_gpg_add_arg (ctx->gpg, "--edit-key");
694     _gpgme_gpg_add_arg (ctx->gpg, keyid);
695     switch( ctx->edit_cmd ) {
696     case GPGME_EDITKEY_SIGN:
697     _gpgme_gpg_add_arg( ctx->gpg, "sign" );
698     break;
699    
700     case GPGME_EDITKEY_KEYSERV:
701     _gpgme_gpg_add_arg (ctx->gpg, "keyserver");
702     break;
703    
704     case GPGME_EDITKEY_LSIGN:
705     _gpgme_gpg_add_arg( ctx->gpg, "lsign" );
706     break;
707    
708     case GPGME_EDITKEY_NRSIGN:
709     _gpgme_gpg_add_arg (ctx->gpg, "nrsign");
710     break;
711    
712     case GPGME_EDITKEY_NRLSIGN:
713     _gpgme_gpg_add_arg (ctx->gpg, "nrlsign");
714     break;
715    
716     case GPGME_EDITKEY_TSIGN:
717     _gpgme_gpg_add_arg (ctx->gpg, "tsign");
718     break;
719    
720     case GPGME_EDITKEY_ADDKEY:
721     _gpgme_gpg_add_arg( ctx->gpg, "addkey" );
722     break;
723    
724     case GPGME_EDITKEY_DELUID:
725     _gpgme_gpg_add_arg( ctx->gpg, "deluid" );
726     break;
727    
728     case GPGME_EDITKEY_DELKEY:
729     _gpgme_gpg_add_arg( ctx->gpg, "delkey" );
730     break;
731    
732     case GPGME_EDITKEY_DELSIG:
733     /* we need to choose the uid before */
734     _gpgme_gpg_add_arg (ctx->gpg, "");
735     break;
736    
737     case GPGME_EDITKEY_ADDUID:
738     _gpgme_gpg_add_arg( ctx->gpg, "adduid" );
739     break;
740    
741     case GPGME_EDITKEY_TRUST:
742     _gpgme_gpg_add_arg( ctx->gpg, "trust" );
743     break;
744    
745     case GPGME_EDITKEY_PASSWD:
746     _gpgme_gpg_add_arg( ctx->gpg, "passwd" );
747     break;
748    
749     case GPGME_EDITKEY_PRIMARY:
750     /* we need to choose the uid before */
751     _gpgme_gpg_add_arg( ctx->gpg, "" );
752     break;
753    
754     case GPGME_EDITKEY_EXPIRE:
755     /* we need to choose the key before */
756     _gpgme_gpg_add_arg( ctx->gpg, "" );
757     break;
758    
759     case GPGME_EDITKEY_REVSIG:
760     /* we need to choose the uid before */
761     _gpgme_gpg_add_arg( ctx->gpg, "" );
762     break;
763    
764     case GPGME_EDITKEY_REVKEY:
765     /* we need to choose the key before */
766     _gpgme_gpg_add_arg( ctx->gpg, "" );
767     break;
768    
769     case GPGME_EDITKEY_SETPREF:
770     /* we cannot add the command here */
771     _gpgme_gpg_add_arg (ctx->gpg, "");
772    
773     case GPGME_EDITKEY_ADDREV:
774     _gpgme_gpg_add_arg( ctx->gpg, "addrevoker" );
775     break;
776    
777     case GPGME_EDITKEY_ADDPHOTO:
778     _gpgme_gpg_add_arg( ctx->gpg, "addphoto" );
779     break;
780    
781     case GPGME_EDITKEY_ENABLE:
782     _gpgme_gpg_add_arg( ctx->gpg, "enable" );
783     break;
784    
785     case GPGME_EDITKEY_DISABLE:
786     _gpgme_gpg_add_arg( ctx->gpg, "disable" );
787     break;
788    
789     default:
790     rc = mk_error( Invalid_Value );
791     goto leave;
792     }
793     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
794    
795     leave:
796     if( rc ) {
797     ctx->pending = 0;
798     _gpgme_gpg_release( &ctx->gpg );
799     }
800    
801     return rc;
802     } /* editkey_start */
803    
804    
805     static int
806     check_edit_cmd (gpgme_ctx_t ctx)
807     {
808     if (ctx->edit_cmd == GPGME_EDITKEY_DELKEY ||
809     ctx->edit_cmd == GPGME_EDITKEY_DELSIG)
810     return 0;
811     return 1;
812     }
813    
814     gpgme_error_t
815     gpgme_op_editkey( gpgme_ctx_t ctx, const char * keyid )
816     {
817     gpgme_error_t rc;
818     int use_key_check = check_edit_cmd (ctx);
819    
820     rc = editkey_start( ctx, keyid );
821     if( !rc ) {
822     gpgme_wait( ctx, 1 );
823     ctx->pending = 0;
824     if( ctx->result.editk->bad_passphrase )
825     rc = mk_error( Bad_Passphrase );
826     else if( ctx->result.editk->already_signed )
827     rc = mk_error( Conflict );
828     else if (use_key_check && ctx->result.editk->key_expired)
829     rc = mk_error (Invalid_Mode);
830     else if( gpgme_get_process_rc( ctx ) )
831     rc = mk_error( Interal_GPG_Problem );
832     }
833     return rc;
834     } /* gpgme_op_editkey */
835    
836    
837     gpgme_error_t
838     gpgme_uid_info_new( gpgme_uidinfo_t *r_inf )
839     {
840     gpgme_uidinfo_t c;
841    
842     if( !r_inf )
843     return mk_error( Invalid_Value );
844     *r_inf = NULL;
845     c = calloc( 1, sizeof *c );
846     if( !c )
847     return mk_error( Out_Of_Core );
848     *r_inf = c;
849     return 0;
850     } /* gpgme_uid_info_new */
851    
852    
853     void
854     gpgme_uid_info_release (gpgme_uidinfo_t inf)
855     {
856     struct user_id_info_s *i, *list;
857    
858     if (!inf)
859     return;
860     list = inf->list;
861     while (list)
862     {
863     i = list->next;
864     if (list->name)
865     {
866     safe_free (list->name);
867     list->name = NULL;
868     }
869     if (list->prefs)
870     {
871     safe_free (list->prefs);
872     list->prefs = NULL;
873     }
874     safe_free (list);
875     list = i;
876     }
877     } /* gpgme_uid_info_release */
878    
879    
880     static void
881     edit_key_colon_handler (gpgme_uidinfo_t inf, char * line)
882     {
883     char *p, *pend;
884     int field = 0, len = 0;
885     struct user_id_info_s *i;
886    
887     if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
888     return;
889    
890     i = calloc( 1, sizeof *i );
891     if( i == NULL )
892     return;
893     i->next = inf->list;
894     inf->list = i;
895    
896     p = strdup( line );
897     if( p == NULL )
898     return;
899     while( 1 ) {
900     field++;
901     pend = strsep (&p, ":");
902     if (pend == NULL)
903     break;
904    
905     switch (field)
906     {
907     case 2: /* trust info */
908     break;
909    
910     case 10: /* user ID */
911     i->name = calloc (1, strlen (pend)+1);
912     if (!i->name)
913     return;
914     _gpgme_decode_c_string (pend, &i->name, strlen (pend)+ 1);
915     break;
916    
917     case 13: /* preferences */
918     if (strstr (pend, "mdc"))
919     {
920     len = strlen (pend) - 4; /* ,mdc */
921     if (strstr (pend, "no-ks-modify"))
922     {
923     i->flags.no_ks_modify = 1;
924     len -= 13; /* ,no-ks-modify */
925     }
926     i->prefs = calloc (1, len);
927     if (!i->prefs)
928     return;
929     memcpy (i->prefs, pend, len);
930     i->prefs[len] = '\0';
931     i->flags.mdc = 1;
932     }
933     else {
934     i->prefs = strdup (pend);
935     if (!i->prefs)
936     return;
937     i->flags.mdc = 0;
938     }
939     break;
940    
941     case 14: /* idx/flags */
942     i->idx = atol( pend );
943     if( strchr( pend, 'r' ) )
944     i->flags.revoked = 1;
945     if( strchr( pend, 'p' ) )
946     i->flags.primary = 1;
947     break;
948     }
949     }
950     safe_free( p );
951     } /* edit_key_colon_handler */
952    
953    
954     static gpgme_error_t
955     editkey_get_info_start( gpgme_ctx_t ctx, const char *keyid, gpgme_data_t out )
956     {
957     gpgme_error_t rc;
958    
959     fail_on_pending_request( ctx );
960     ctx->pending = 1;
961    
962     _gpgme_gpg_release( &ctx->gpg );
963     rc = _gpgme_gpg_new( &ctx->gpg );
964     if( rc )
965     goto leave;
966    
967     _gpgme_data_set_mode( out, GPGME_DATA_MODE_IN );
968    
969     _gpgme_gpg_add_arg( ctx->gpg, "--with-colons" );
970     _gpgme_gpg_add_arg( ctx->gpg, "--edit-key" );
971     _gpgme_gpg_add_arg( ctx->gpg, keyid );
972     _gpgme_gpg_add_arg( ctx->gpg, "quit" );
973     _gpgme_gpg_add_arg( ctx->gpg, "--output" );
974     _gpgme_gpg_add_arg( ctx->gpg, "-" );
975     _gpgme_gpg_add_data( ctx->gpg, out, 1 );
976    
977     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
978    
979     leave:
980     if( rc ) {
981     ctx->pending = 0;
982     _gpgme_gpg_release( &ctx->gpg );
983     }
984     return rc;
985     } /* editkey_get_info_start */
986    
987    
988     gpgme_error_t
989     gpgme_op_editkey_get_info (gpgme_ctx_t ctx, const char * keyid,
990     gpgme_uidinfo_t * r_inf)
991     {
992     gpgme_error_t err;
993     gpgme_data_t out = NULL;
994     gpgme_uidinfo_t inf;
995     char buf[512];
996    
997     if (!ctx)
998     return mk_error (Invalid_Value);
999    
1000     err = gpgme_data_new( &out );
1001     if (err)
1002     return err;
1003    
1004     err = editkey_get_info_start( ctx, keyid, out );
1005     if( !err )
1006     {
1007     gpgme_wait( ctx, 1 );
1008     ctx->pending = 0;
1009     }
1010     if (err)
1011     return err;
1012    
1013     err = gpgme_uid_info_new( &inf );
1014     if (err)
1015     return err;
1016    
1017     while (gpgme_data_readline (out, buf, sizeof buf -1))
1018     edit_key_colon_handler (inf, buf);
1019    
1020     gpgme_data_release (out);
1021     if (!err && r_inf)
1022     *r_inf = inf;
1023    
1024     return err;
1025     } /* gpgme_op_editkey_get_info */
1026    
1027    
1028     int
1029     gpgme_editkey_count_items( gpgme_uidinfo_t inf )
1030     {
1031     struct user_id_info_s *i;
1032     int ncount = 0;
1033    
1034     for( i = inf->list; i; i = i->next )
1035     ncount++;
1036    
1037     return ncount;
1038     } /* gpgme_editkey_count_items */
1039    
1040    
1041     ulong
1042     gpgme_editkey_get_ulong_attr( gpgme_uidinfo_t inf, int what, int idx )
1043     {
1044     struct user_id_info_s *i;
1045     ulong val;
1046    
1047     if( !inf )
1048     return 0;
1049    
1050     switch( what ) {
1051     case GPGME_ATTR_UID_REVOKED:
1052     for( i = inf->list; i && idx; i = i->next, idx-- )
1053     ;
1054     if( i )
1055     val = i->flags.revoked;
1056     break;
1057    
1058     case GPGME_ATTR_MDC:
1059     for( i = inf->list; i && idx; i = i->next, idx-- )
1060     ;
1061     if( i )
1062     val = i->flags.mdc;
1063     break;
1064    
1065     case GPGME_ATTR_UID_PRIMARY:
1066     for( i = inf->list; i && idx; i = i->next, idx-- )
1067     ;
1068     if( i )
1069     val = i->flags.primary;
1070     break;
1071    
1072     case GPGME_ATTR_VALIDITY:
1073     for( i = inf->list; i && idx; i = i->next, idx-- )
1074     ;
1075     if( i )
1076     val = i->validity;
1077     break;
1078    
1079     case GPGME_ATTR_LEVEL:
1080     for( i = inf->list; i && idx; i = i->next, idx-- )
1081     ;
1082     if( i )
1083     val = i->idx;
1084     break;
1085     }
1086    
1087     return val;
1088     } /* gpgme_editkey_get_ulong_attr */
1089    
1090    
1091     const char*
1092     gpgme_editkey_get_string_attr( gpgme_uidinfo_t inf, int what, int idx )
1093     {
1094     const char *val;
1095     struct user_id_info_s *i;
1096    
1097     if( !inf )
1098     return NULL;
1099    
1100     switch( what ) {
1101     case GPGME_ATTR_NAME:
1102     for( i = inf->list; i && idx; i = i->next, idx-- )
1103     ;
1104     if( i )
1105     val = i->name;
1106     break;
1107    
1108     case GPGME_ATTR_UID_PREFS:
1109     for( i = inf->list; i && idx; i = i->next, idx-- )
1110     ;
1111     if( i )
1112     val = i->prefs;
1113     break;
1114    
1115     default:
1116     val = NULL;
1117     break;
1118     }
1119    
1120     return val;
1121     } /* gpgme_editkey_get_string_attr */
1122    
1123     #endif /*WITH_EDITKEY*/

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26