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

Annotation of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Wed Jul 27 11:17:44 2005 UTC (19 years, 7 months ago) by twoaday
File MIME type: text/plain
File size: 30120 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.c (_gpgme_add_comment): Forgot to alloc an extra
        byte for the '0'. This fixes a lot of crashes related to
        file operations.
        * keylist.c (gpgme_op_keylist_getkey): Use the param for
        'pub' or 'sec' mode.
        * keycache.c (gpgme_keycache_update_key): If the key is
        not in the cache, add it and if the cache contain secret
        key, sync it with the pub cache.
        * editkey.c (edit_key_colon_handler): Allocate 1 byte for
        the NUL-char.  This also fixes a lot of reported crashes
        related to the showpref feature.
 


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.add_keyserver"))
111     return ctx->u.keyserv.url;
112     if (do_check (code, GET_BOOL, key, "keyedit.confirm_keyserver"))
113     return "Y";
114     if (do_check (code, GET_HIDDEN, key, "passphrase.enter"))
115     return ctx->u.keyserv.passwd;
116     if (do_check (code, GET_LINE, key, "keyedit.prompt"))
117     return "save";
118    
119     return NULL;
120     }
121    
122     static const char*
123     cmd_sign_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
124     {
125     DEBUG2 ("cmd_sign: code=%d args=`%s'\n", code, key);
126    
127     if( !strcmp( key, "sign_uid.class" ) ) {
128     static char id[32];
129     sprintf( id, "%d", ctx->u.sign.sig_class );
130     return id;
131     }
132     if (!strcmp (key, "sign_uid.expire"))
133     return "Y"; /* the sig expires when the key expires */
134     if (!strcmp (key, "siggen.valid"))
135     return ctx->u.sign.exp_date;
136     if (!strcmp (key, "trustsig_prompt.trust_value"))
137     return ctx->u.sign.trust.val;
138     if (!strcmp (key, "trustsig_prompt.trust_depth"))
139     return ""; /* fixme */
140     if (!strcmp (key, "trustsig_prompt.trust_regexp"))
141     return ""; /* fixme */
142     if( do_check( code, GET_BOOL, key, "sign_uid.local_promote_okay" ) )
143     return "Y";
144     if( do_check( code, GET_BOOL, key, "sign_uid.okay" ) )
145     return "Y";
146     if( do_check( code, GET_BOOL, key, "keyedit.sign_all.okay" ) )
147     return "Y";
148     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
149     return ctx->u.sign.passwd;
150     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
151     return "save";
152    
153     return NULL;
154     } /* cmd_sign_handler */
155    
156    
157     static const char*
158     cmd_trust_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
159     {
160     if( do_check( code, GET_BOOL, key, "edit_ownertrust.set_ultimate.okay" ) )
161     return "Y";
162     if( do_check( code, GET_LINE, key, "edit_ownertrust.value" ) )
163     return ctx->u.trust.trust_val;
164     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
165     return "save";
166    
167     return NULL;
168     } /* cmd_trust_handler */
169    
170    
171     static const char*
172     cmd_adduid_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
173     {
174     if( do_check( code, GET_LINE, key, "keygen.name" ) )
175     return ctx->u.adduid.name;
176     if( do_check( code, GET_LINE, key, "keygen.email" ) )
177     return ctx->u.adduid.email;
178     if( do_check( code, GET_LINE, key, "keygen.comment" ) ) {
179     if( ctx->u.adduid.use_comment )
180     return ctx->u.adduid.comment;
181     return "";
182     }
183     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
184     return ctx->u.adduid.passwd;
185     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
186     return "save";
187    
188     return NULL;
189     } /* cmd_adduid_handler */
190    
191    
192     static const char*
193     cmd_deluid_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
194     int *r_step )
195     {
196     static char buf[64];
197     int step = *r_step;
198    
199     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
200     sprintf( buf, "uid %d", ctx->u.deluid.id );
201     *r_step = step = 1;
202     return buf;
203     }
204     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
205     *r_step = step = 2;
206     return "deluid";
207     }
208     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.remove.uid.okay" ) ) {
209     *r_step = step = 3;
210     return "Y";
211     }
212     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
213     *r_step = step = 0;
214     return "save";
215     }
216    
217     return NULL;
218     } /* cmd_deluid_handler */
219    
220    
221     static const char *
222     cmd_delsig_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
223     int * r_step)
224     {
225     static char buf[64];
226     int step = *r_step;
227    
228     if (step == 0 && do_check (code, GET_LINE, key, "keyedit.prompt"))
229     {
230     sprintf (buf, "uid %d", ctx->u.delsig.uid);
231     *r_step = step = 1;
232     return buf;
233     }
234     if (step == 1 && do_check (code, GET_LINE, key, "keyedit.prompt"))
235     {
236     *r_step = step = 2;
237     return "delsig";
238     }
239     if (do_check (code, GET_BOOL, key, "keyedit.delsig.unknown") ||
240     do_check (code, GET_BOOL, key, "keyedit.delsig.valid"))
241     {
242     if (++ctx->u.delsig.currno == ctx->u.delsig.signo)
243     return "Y";
244     else
245     return "N";
246     }
247     if (ctx->u.delsig.signo == 0 &&
248     do_check (code, GET_BOOL, key, "keyedit.delsig.selfsig"))
249     return "Y";
250     if (step == 2 && do_check (code, GET_LINE, key, "keyedit.prompt"))
251     {
252     *r_step = step = 0;
253     return "save";
254     }
255     return NULL;
256     }
257    
258    
259     static const char*
260     cmd_delkey_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
261     int *r_step )
262     {
263     static char buf[64];
264     int step = *r_step;
265    
266     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
267     sprintf( buf, "key %d", ctx->u.delkey.id );
268     *r_step = step = 1;
269     return buf;
270     }
271     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
272     *r_step = step = 2;
273     return "delkey";
274     }
275     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.remove.subkey.okay" ) ) {
276     *r_step = step = 3;
277     return "Y";
278     }
279     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
280     *r_step = step = 0;
281     return "save";
282     }
283    
284     return NULL;
285     } /* cmd_delkey_handler */
286    
287    
288     static const char*
289 twoaday 7 cmd_addkey_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char *key)
290 twoaday 2 {
291     static char buf[64];
292    
293     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
294     return ctx->u.addkey.passwd;
295     if( do_check( code, GET_LINE, key, "keygen.algo" ) ) {
296     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.algo );
297     return buf;
298     }
299     if( do_check( code, GET_LINE, key, "keygen.size" ) ) {
300     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.size );
301     return buf;
302     }
303     if( do_check( code, GET_LINE, key, "keygen.valid" ) ) {
304     _snprintf( buf, sizeof buf-1, "%d", ctx->u.addkey.valid );
305     return buf;
306     }
307     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
308     return "save";
309     return NULL;
310     } /* cmd_addkey_handler */
311    
312    
313     static const char*
314     cmd_passwd_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key )
315     {
316     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" )
317     && !ctx->u.passwd.send_old ) {
318     ctx->u.passwd.send_old = 1;
319     return ctx->u.passwd.old_passwd;
320     }
321     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
322     return ctx->u.passwd.new_passwd;
323     if( do_check( code, GET_BOOL, key, "change_passwd.empty.okay" ) )
324     return ctx->u.passwd.allow_empty? "Y" : "N";
325     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) )
326     return "save";
327     return NULL;
328     } /* cmd_passwd_handler */
329    
330    
331     static const char *
332     cmd_setpref_handler (gpgme_editkey_t ctx, gpg_statcode_t code, const char * key)
333     {
334     static char buf[128];
335    
336     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 0) {
337     ctx->u.pref.id++;
338     _snprintf (buf, sizeof buf-1, "setpref %s", ctx->u.pref.new_prefs);
339     return buf;
340     }
341     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 1) {
342     ctx->u.pref.id++;
343     return "updpref";
344     }
345     if (do_check (code, GET_BOOL, key, "keyedit.updpref.okay"))
346     return "Y";
347     if (do_check (code, GET_HIDDEN, key, "passphrase.enter"))
348     return ctx->u.pref.passwd;
349     if (do_check (code, GET_LINE, key, "keyedit.prompt") && ctx->u.pref.id == 2) {
350     ctx->u.pref.id = 0;
351     return "save";
352     }
353     return NULL;
354     } /* cmd_setpref_handler */
355    
356    
357     static const char*
358     cmd_primary_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
359     int *r_step )
360     {
361     static char buf[64];
362     int step = *r_step;
363    
364     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
365     sprintf( buf, "uid %d", ctx->u.primary.id );
366     *r_step = step = 1;
367     return buf;
368     }
369     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
370     *r_step = step = 2;
371     return "primary";
372     }
373     if( step == 2 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
374     *r_step = step = 3;
375     return ctx->u.primary.passwd;
376     }
377     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
378     *r_step = step = 0;
379     return "save";
380     }
381     return NULL;
382     } /* cmd_primary_handler */
383    
384    
385     static const char*
386     cmd_expire_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
387     int *r_step )
388     {
389     static char buf[64];
390     int step = *r_step;
391    
392     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
393     sprintf(buf, "key %d", ctx->u.expire.id);
394     *r_step = step = 1;
395     return buf;
396     }
397     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
398     *r_step = step = 2;
399     return "expire";
400     }
401     if( step == 2 && do_check( code, GET_LINE, key, "keygen.valid" ) ) {
402     *r_step = step = 3;
403     if( ctx->u.expire.days ) {
404     sprintf( buf, "%d", ctx->u.expire.days );
405     return buf;
406     }
407     else
408     return ctx->u.expire.date;
409     }
410     if( step == 3 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
411     *r_step = step = 4;
412     return ctx->u.expire.passwd;
413     }
414     if( step == 4 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
415     *r_step = step = 0;
416     return "save";
417     }
418    
419     return NULL;
420     } /* cmd_expire_handler */
421    
422    
423     const char*
424     cmd_revsig_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
425     int *r_step )
426     {
427     static char buf[64];
428     int step = *r_step;
429    
430     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
431     sprintf( buf, "uid %d", ctx->u.revsig.id );
432     *r_step = step = 1;
433     return buf;
434     }
435     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
436     *r_step = step = 2;
437     return "revsig";
438     }
439     if( step == 2 && do_check( code, GET_BOOL, key, "ask_revoke_sig.one" ) ) {
440     *r_step = step = 3;
441     return "Y";
442     }
443     if( step == 3 && do_check( code, GET_BOOL, key, "ask_revoke_sig.okay" ) ) {
444     *r_step = step = 4;
445     return "Y";
446     }
447     if( step == 4 && do_check( code, GET_LINE, key, "ask_revocation_reason.code" ) ) {
448     *r_step = step = 5;
449     return "0";
450     }
451     if( step == 5 && do_check( code, GET_LINE, key, "ask_revocation_reason.text" ) ) {
452     *r_step = step = 6;
453     return "\n";
454     }
455     if( step == 6 && do_check( code, GET_BOOL, key, "ask_revocation_reason.okay" ) ) {
456     *r_step = step = 7;
457     return "Y";
458     }
459     if( step == 7 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
460     *r_step = step = 8;
461     return ctx->u.revsig.passwd;
462     }
463     if( step == 8 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
464     *r_step = step = 0;
465     return "save";
466     }
467    
468     return NULL;
469     } /* cmd_revsig_handler */
470    
471    
472     static const char *
473     cmd_revkey_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
474     int *r_step )
475     {
476     int step = *r_step;
477     static char buf[64];
478    
479     if( step == 0 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
480     sprintf( buf, "key %d", ctx->u.revkey.id );
481     *r_step = step = 1;
482     return buf;
483     }
484     if( step == 1 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
485     *r_step = step = 2;
486     return "revkey";
487     }
488     if( step == 2 && do_check( code, GET_BOOL, key, "keyedit.revoke.subkey.okay" ) ) {
489     *r_step = step = 3;
490     return "Y";
491     }
492     if( step == 3 && do_check( code, GET_LINE, key, "ask_revocation_reason.code" ) ) {
493     sprintf( buf, "%d", ctx->u.revkey.reason );
494     *r_step = step = 4;
495     return buf;
496     }
497     if( step == 4 && do_check( code, GET_LINE, key, "ask_revocation_reason.text" ) ) {
498     *r_step = step = 5;
499     return "";
500     }
501     if( step == 5 && do_check( code, GET_BOOL, key, "ask_revocation_reason.okay" ) ) {
502     *r_step = step = 6;
503     return "Y";
504     }
505     if( step == 6 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
506     *r_step = step = 7;
507     return ctx->u.revkey.passwd;
508     }
509     if( step == 7 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
510     *r_step = step = 0;
511     return "save";
512     }
513     return NULL;
514     } /* cmd_revkey_handler */
515    
516    
517     static const char *
518     cmd_addrev_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char * key,
519     gpgme_ctx_t c, int * r_step)
520     {
521     int step = *r_step;
522    
523 twoaday 7
524 twoaday 2 /*DEBUG3("code=%d key=%s step=%d\n", code, key, step);*/
525 twoaday 7 if ((step == 0 /*|| c->result.editk->already_signed*/)
526 twoaday 2 && do_check (code, GET_LINE, key, "keyedit.add_revoker")) {
527     *r_step = step = 1;
528 twoaday 7 if (c->result.editk && c->result.editk->already_signed) {
529 twoaday 2 *r_step = step = 3;
530     return "";
531     }
532     return ctx->u.addrev.uid;
533     }
534     if( step == 1 && do_check( code, GET_BOOL, key, "keyedit.add_revoker.okay" ) ) {
535     *r_step = step = 2;
536     return "Y";
537     }
538     if( step == 2 && do_check( code, GET_HIDDEN, key, "passphrase.enter" ) ) {
539     *r_step = step = 3;
540     return ctx->u.addrev.passwd;
541     }
542     if( step == 3 && do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
543     *r_step = step = 0;
544     return "save";
545     }
546     return NULL;
547     } /* cmd_addrev_handler */
548    
549    
550     static const char *
551     cmd_addphoto_handler( gpgme_editkey_t ctx, gpg_status_code_t code, const char *key,
552     int *r_step )
553     {
554     int step = *r_step;
555    
556     if( do_check( code, GET_LINE, key, "photoid.jpeg.add" ) )
557     return ctx->u.addphoto.jpg;
558     if( do_check( code, GET_BOOL, key, "photoid.jpeg.size" ) )
559     return "Y";
560     if( do_check( code, GET_HIDDEN, key, "passphrase.enter" ) )
561     return ctx->u.addphoto.passwd;
562     if( do_check( code, GET_LINE, key, "keyedit.prompt" ) ) {
563     *r_step = step = 0;
564     return "save";
565     }
566     return NULL;
567     } /* cmd_addphoto_handler */
568    
569    
570     static const char *
571     cmd_enable_disable_handler( gpgme_editkey_t ctx, gpg_status_code_t code,
572     const char * key, int *r_step )
573     {
574     *r_step = 0;
575     return "save";
576     } /* cmd_enable_disable_handler */
577    
578    
579     static const char *
580     editkey_command_handler (void * opaque, gpg_status_code_t code, const char * key)
581     {
582     static int step = 0;
583     gpgme_ctx_t c = opaque;
584     gpgme_editkey_t ctx = c->edit_opaque;
585    
586     if (!code)
587     return NULL;
588    
589     if (!ctx || ctx->type != c->edit_cmd)
590     {
591     DEBUG2 ("editkey cmd handler has a wrong type (%d != %d)", ctx->type, c->edit_cmd);
592     return NULL;
593     }
594    
595     switch (c->edit_cmd) {
596     case GPGME_EDITKEY_LSIGN:
597     case GPGME_EDITKEY_SIGN:
598     case GPGME_EDITKEY_NRSIGN:
599     case GPGME_EDITKEY_TSIGN:
600     case GPGME_EDITKEY_NRLSIGN:
601     return cmd_sign_handler (ctx, code, key);
602    
603     case GPGME_EDITKEY_TRUST:
604     return cmd_trust_handler( ctx, code, key );
605    
606     case GPGME_EDITKEY_ADDUID:
607     return cmd_adduid_handler( ctx, code, key );
608    
609     case GPGME_EDITKEY_DELUID:
610     return cmd_deluid_handler( ctx, code, key, &step );
611    
612     case GPGME_EDITKEY_DELSIG:
613     return cmd_delsig_handler (ctx, code, key, &step);
614    
615     case GPGME_EDITKEY_DELKEY:
616     return cmd_delkey_handler( ctx, code, key, &step );
617    
618     case GPGME_EDITKEY_ADDKEY:
619     return cmd_addkey_handler( ctx, code, key );
620    
621     case GPGME_EDITKEY_PASSWD:
622     return cmd_passwd_handler( ctx, code, key );
623    
624     case GPGME_EDITKEY_PRIMARY:
625     return cmd_primary_handler( ctx, code, key, &step );
626    
627     case GPGME_EDITKEY_EXPIRE:
628     return cmd_expire_handler( ctx, code, key, &step );
629    
630     case GPGME_EDITKEY_REVSIG:
631     return cmd_revsig_handler( ctx, code, key, &step );
632    
633     case GPGME_EDITKEY_REVKEY:
634     return cmd_revkey_handler( ctx, code, key, &step );
635    
636     case GPGME_EDITKEY_ADDREV:
637     return cmd_addrev_handler (ctx, code, key, c, &step);
638    
639     case GPGME_EDITKEY_ADDPHOTO:
640     return cmd_addphoto_handler( ctx, code, key, &step );
641    
642     case GPGME_EDITKEY_ENABLE:
643     return cmd_enable_disable_handler( ctx, code, key, &step );
644    
645     case GPGME_EDITKEY_DISABLE:
646     return cmd_enable_disable_handler( ctx, code, key, &step );
647    
648     case GPGME_EDITKEY_SETPREF:
649     return cmd_setpref_handler (ctx, code, key);
650 twoaday 21
651     case GPGME_EDITKEY_KEYSERV:
652     return cmd_keyserv_handler (ctx, code, key);
653 twoaday 2 }
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 twoaday 21 _gpgme_gpg_add_arg (ctx->gpg, "lsign");
706 twoaday 2 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 twoaday 21 _gpgme_gpg_add_arg (ctx->gpg, "addkey");
722 twoaday 2 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 twoaday 7 rc = mk_error( Internal_GPG_Problem );
832 twoaday 2 }
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 twoaday 15 while (list) {
862 twoaday 2 i = list->next;
863 twoaday 15 if (list->name) {
864 twoaday 2 safe_free (list->name);
865     list->name = NULL;
866     }
867 twoaday 15 if (list->prefs) {
868 twoaday 2 safe_free (list->prefs);
869     list->prefs = NULL;
870     }
871     safe_free (list);
872     list = i;
873     }
874     } /* gpgme_uid_info_release */
875    
876    
877     static void
878     edit_key_colon_handler (gpgme_uidinfo_t inf, char * line)
879     {
880     char *p, *pend;
881     int field = 0, len = 0;
882 twoaday 15 struct user_id_info_s *i, *t;
883 twoaday 2
884     if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
885     return;
886    
887 twoaday 15 i = calloc (1, sizeof *i);
888     if (!i)
889 twoaday 2 return;
890 twoaday 15 if (!inf->list)
891     inf->list = i;
892     else {
893     for (t=inf->list; t->next; t=t->next)
894     ;
895     t->next = i;
896     }
897 twoaday 2
898 twoaday 15 p = strdup (line);
899     if (!p)
900 twoaday 2 return;
901 twoaday 15 while (1) {
902 twoaday 2 field++;
903     pend = strsep (&p, ":");
904     if (pend == NULL)
905     break;
906    
907 twoaday 15 switch (field) {
908 twoaday 2 case 2: /* trust info */
909     break;
910    
911     case 10: /* user ID */
912     i->name = calloc (1, strlen (pend)+1);
913     if (!i->name)
914     return;
915 twoaday 15 _gpgme_decode_c_string (pend, &i->name, strlen (pend)+ 1);
916     if (strchr (pend, '<') != NULL) {
917     int pos = strchr (i->name, '<')- i->name + 1;
918     int end = strchr (i->name, '>') - i->name;
919     i->email = calloc (1, end-pos+2);
920     if (!i->email)
921     return;
922     memcpy (i->email, i->name+pos, (end-pos));
923     }
924 twoaday 2 break;
925    
926     case 13: /* preferences */
927 twoaday 15 if (strstr (pend, "mdc")) {
928 twoaday 2 len = strlen (pend) - 4; /* ,mdc */
929 twoaday 15 if (strstr (pend, "no-ks-modify")) {
930 twoaday 2 i->flags.no_ks_modify = 1;
931     len -= 13; /* ,no-ks-modify */
932     }
933 twoaday 21 i->prefs = calloc (1, len+1);
934 twoaday 2 if (!i->prefs)
935     return;
936     memcpy (i->prefs, pend, len);
937     i->prefs[len] = '\0';
938     i->flags.mdc = 1;
939     }
940     else {
941     i->prefs = strdup (pend);
942     if (!i->prefs)
943     return;
944 twoaday 15 i->flags.mdc = 0;
945 twoaday 2 }
946     break;
947    
948     case 14: /* idx/flags */
949 twoaday 15 i->idx = atol (pend);
950     if (strchr (pend, 'r'))
951 twoaday 2 i->flags.revoked = 1;
952 twoaday 15 if (strchr( pend, 'p'))
953 twoaday 2 i->flags.primary = 1;
954     break;
955     }
956     }
957 twoaday 15 safe_free (p);
958 twoaday 2 } /* edit_key_colon_handler */
959    
960    
961     static gpgme_error_t
962 twoaday 15 editkey_get_info_start (gpgme_ctx_t ctx, const char *keyid, gpgme_data_t out)
963 twoaday 2 {
964     gpgme_error_t rc;
965    
966     fail_on_pending_request( ctx );
967     ctx->pending = 1;
968    
969     _gpgme_gpg_release( &ctx->gpg );
970     rc = _gpgme_gpg_new( &ctx->gpg );
971     if( rc )
972     goto leave;
973    
974     _gpgme_data_set_mode( out, GPGME_DATA_MODE_IN );
975    
976     _gpgme_gpg_add_arg( ctx->gpg, "--with-colons" );
977     _gpgme_gpg_add_arg( ctx->gpg, "--edit-key" );
978     _gpgme_gpg_add_arg( ctx->gpg, keyid );
979     _gpgme_gpg_add_arg( ctx->gpg, "quit" );
980     _gpgme_gpg_add_arg( ctx->gpg, "--output" );
981     _gpgme_gpg_add_arg( ctx->gpg, "-" );
982     _gpgme_gpg_add_data( ctx->gpg, out, 1 );
983    
984     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
985    
986     leave:
987     if( rc ) {
988     ctx->pending = 0;
989     _gpgme_gpg_release( &ctx->gpg );
990     }
991     return rc;
992     } /* editkey_get_info_start */
993    
994    
995     gpgme_error_t
996     gpgme_op_editkey_get_info (gpgme_ctx_t ctx, const char * keyid,
997     gpgme_uidinfo_t * r_inf)
998     {
999     gpgme_error_t err;
1000     gpgme_data_t out = NULL;
1001     gpgme_uidinfo_t inf;
1002     char buf[512];
1003    
1004     if (!ctx)
1005     return mk_error (Invalid_Value);
1006    
1007     err = gpgme_data_new( &out );
1008     if (err)
1009     return err;
1010    
1011     err = editkey_get_info_start( ctx, keyid, out );
1012 twoaday 15 if (!err) {
1013     gpgme_wait (ctx, 1);
1014 twoaday 2 ctx->pending = 0;
1015     }
1016     if (err)
1017     return err;
1018    
1019 twoaday 15 err = gpgme_uid_info_new (&inf);
1020 twoaday 2 if (err)
1021     return err;
1022    
1023     while (gpgme_data_readline (out, buf, sizeof buf -1))
1024     edit_key_colon_handler (inf, buf);
1025    
1026     gpgme_data_release (out);
1027     if (!err && r_inf)
1028     *r_inf = inf;
1029    
1030     return err;
1031     } /* gpgme_op_editkey_get_info */
1032    
1033    
1034     int
1035     gpgme_editkey_count_items( gpgme_uidinfo_t inf )
1036     {
1037     struct user_id_info_s *i;
1038     int ncount = 0;
1039    
1040     for( i = inf->list; i; i = i->next )
1041     ncount++;
1042    
1043     return ncount;
1044     } /* gpgme_editkey_count_items */
1045    
1046    
1047     ulong
1048     gpgme_editkey_get_ulong_attr( gpgme_uidinfo_t inf, int what, int idx )
1049     {
1050     struct user_id_info_s *i;
1051     ulong val;
1052    
1053     if( !inf )
1054     return 0;
1055    
1056     switch( what ) {
1057     case GPGME_ATTR_UID_REVOKED:
1058     for( i = inf->list; i && idx; i = i->next, idx-- )
1059     ;
1060     if( i )
1061     val = i->flags.revoked;
1062     break;
1063    
1064     case GPGME_ATTR_MDC:
1065     for( i = inf->list; i && idx; i = i->next, idx-- )
1066     ;
1067     if( i )
1068     val = i->flags.mdc;
1069     break;
1070    
1071     case GPGME_ATTR_UID_PRIMARY:
1072     for( i = inf->list; i && idx; i = i->next, idx-- )
1073     ;
1074     if( i )
1075     val = i->flags.primary;
1076     break;
1077    
1078     case GPGME_ATTR_VALIDITY:
1079     for( i = inf->list; i && idx; i = i->next, idx-- )
1080     ;
1081     if( i )
1082     val = i->validity;
1083     break;
1084    
1085     case GPGME_ATTR_LEVEL:
1086     for( i = inf->list; i && idx; i = i->next, idx-- )
1087     ;
1088     if( i )
1089     val = i->idx;
1090     break;
1091     }
1092    
1093     return val;
1094     } /* gpgme_editkey_get_ulong_attr */
1095    
1096    
1097     const char*
1098 twoaday 15 gpgme_editkey_get_string_attr (gpgme_uidinfo_t inf, int what, int idx)
1099 twoaday 2 {
1100 twoaday 15 const char *val=NULL;
1101 twoaday 2 struct user_id_info_s *i;
1102    
1103     if( !inf )
1104     return NULL;
1105    
1106     switch( what ) {
1107     case GPGME_ATTR_NAME:
1108 twoaday 15 for (i = inf->list; i && idx; i = i->next, idx--)
1109 twoaday 2 ;
1110 twoaday 15 if (i)
1111 twoaday 2 val = i->name;
1112     break;
1113    
1114 twoaday 15 case GPGME_ATTR_EMAIL:
1115     for (i=inf->list; i && idx; i = i->next, idx--)
1116     ;
1117     if (i)
1118     val = i->email;
1119     break;
1120    
1121 twoaday 2 case GPGME_ATTR_UID_PREFS:
1122 twoaday 15 for (i = inf->list; i && idx; i = i->next, idx--)
1123 twoaday 2 ;
1124 twoaday 15 if (i)
1125 twoaday 2 val = i->prefs;
1126     break;
1127    
1128     default:
1129     val = NULL;
1130     break;
1131     }
1132    
1133     return val;
1134     } /* gpgme_editkey_get_string_attr */
1135    
1136     #endif /*WITH_EDITKEY*/

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26