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

Annotation of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Mon Apr 4 07:01:43 2005 UTC (19 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 29694 byte(s)
2005-03-22  Timo Schulz  <twoaday@freakmail.de>
                                                                                
        * editcard.c: Support new status-fd entries SC_OP_SUCCESS
        and SC_OP_FAILURE.
        * editkey.c (cmd_addrev_handler): Check if context != NULL.
        * import.c (import_command_handler): Wrong function signature.
        Noted by Kurt Fitzner.
        * types.h: Fixed encrypt_result_s. Noted by Kurt.
        * gpgme.h (gpgme_editkey_addrev_set): Changed return type.
        Kudos to Kurt.
        * key.c: Removed some unreachable code. By Kurt.
                                                                                


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26