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

Annotation of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


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


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 twoaday 23 /*DEBUG2 ("cmd_sign: code=%d args=`%s'\n", code, key);*/
126 twoaday 2
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 twoaday 23 if (!ctx || ctx->type != c->edit_cmd) {
590 twoaday 2 DEBUG2 ("editkey cmd handler has a wrong type (%d != %d)", ctx->type, c->edit_cmd);
591     return NULL;
592     }
593    
594     switch (c->edit_cmd) {
595     case GPGME_EDITKEY_LSIGN:
596     case GPGME_EDITKEY_SIGN:
597     case GPGME_EDITKEY_NRSIGN:
598     case GPGME_EDITKEY_TSIGN:
599     case GPGME_EDITKEY_NRLSIGN:
600     return cmd_sign_handler (ctx, code, key);
601    
602     case GPGME_EDITKEY_TRUST:
603     return cmd_trust_handler( ctx, code, key );
604    
605     case GPGME_EDITKEY_ADDUID:
606     return cmd_adduid_handler( ctx, code, key );
607    
608     case GPGME_EDITKEY_DELUID:
609     return cmd_deluid_handler( ctx, code, key, &step );
610    
611     case GPGME_EDITKEY_DELSIG:
612     return cmd_delsig_handler (ctx, code, key, &step);
613    
614     case GPGME_EDITKEY_DELKEY:
615     return cmd_delkey_handler( ctx, code, key, &step );
616    
617     case GPGME_EDITKEY_ADDKEY:
618     return cmd_addkey_handler( ctx, code, key );
619    
620     case GPGME_EDITKEY_PASSWD:
621     return cmd_passwd_handler( ctx, code, key );
622    
623     case GPGME_EDITKEY_PRIMARY:
624     return cmd_primary_handler( ctx, code, key, &step );
625    
626     case GPGME_EDITKEY_EXPIRE:
627     return cmd_expire_handler( ctx, code, key, &step );
628    
629     case GPGME_EDITKEY_REVSIG:
630     return cmd_revsig_handler( ctx, code, key, &step );
631    
632     case GPGME_EDITKEY_REVKEY:
633     return cmd_revkey_handler( ctx, code, key, &step );
634    
635     case GPGME_EDITKEY_ADDREV:
636     return cmd_addrev_handler (ctx, code, key, c, &step);
637    
638     case GPGME_EDITKEY_ADDPHOTO:
639     return cmd_addphoto_handler( ctx, code, key, &step );
640    
641     case GPGME_EDITKEY_ENABLE:
642     return cmd_enable_disable_handler( ctx, code, key, &step );
643    
644     case GPGME_EDITKEY_DISABLE:
645     return cmd_enable_disable_handler( ctx, code, key, &step );
646    
647     case GPGME_EDITKEY_SETPREF:
648     return cmd_setpref_handler (ctx, code, key);
649 twoaday 21
650     case GPGME_EDITKEY_KEYSERV:
651     return cmd_keyserv_handler (ctx, code, key);
652 twoaday 2 }
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 twoaday 21 _gpgme_gpg_add_arg (ctx->gpg, "lsign");
705 twoaday 2 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 twoaday 21 _gpgme_gpg_add_arg (ctx->gpg, "addkey");
721 twoaday 2 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 twoaday 15 while (list) {
861 twoaday 2 i = list->next;
862 twoaday 15 if (list->name) {
863 twoaday 2 safe_free (list->name);
864     list->name = NULL;
865     }
866 twoaday 15 if (list->prefs) {
867 twoaday 2 safe_free (list->prefs);
868     list->prefs = NULL;
869     }
870     safe_free (list);
871     list = i;
872     }
873     } /* gpgme_uid_info_release */
874    
875    
876     static void
877     edit_key_colon_handler (gpgme_uidinfo_t inf, char * line)
878     {
879     char *p, *pend;
880     int field = 0, len = 0;
881 twoaday 15 struct user_id_info_s *i, *t;
882 twoaday 2
883     if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
884     return;
885    
886 twoaday 15 i = calloc (1, sizeof *i);
887     if (!i)
888 twoaday 2 return;
889 twoaday 15 if (!inf->list)
890     inf->list = i;
891     else {
892     for (t=inf->list; t->next; t=t->next)
893     ;
894     t->next = i;
895     }
896 twoaday 2
897 twoaday 15 p = strdup (line);
898     if (!p)
899 twoaday 2 return;
900 twoaday 15 while (1) {
901 twoaday 2 field++;
902     pend = strsep (&p, ":");
903     if (pend == NULL)
904     break;
905    
906 twoaday 15 switch (field) {
907 twoaday 2 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 twoaday 15 _gpgme_decode_c_string (pend, &i->name, strlen (pend)+ 1);
915     if (strchr (pend, '<') != NULL) {
916     int pos = strchr (i->name, '<')- i->name + 1;
917     int end = strchr (i->name, '>') - i->name;
918     i->email = calloc (1, end-pos+2);
919     if (!i->email)
920     return;
921     memcpy (i->email, i->name+pos, (end-pos));
922     }
923 twoaday 2 break;
924    
925     case 13: /* preferences */
926 twoaday 15 if (strstr (pend, "mdc")) {
927 twoaday 2 len = strlen (pend) - 4; /* ,mdc */
928 twoaday 15 if (strstr (pend, "no-ks-modify")) {
929 twoaday 2 i->flags.no_ks_modify = 1;
930     len -= 13; /* ,no-ks-modify */
931     }
932 twoaday 21 i->prefs = calloc (1, len+1);
933 twoaday 2 if (!i->prefs)
934     return;
935     memcpy (i->prefs, pend, len);
936     i->prefs[len] = '\0';
937     i->flags.mdc = 1;
938     }
939     else {
940     i->prefs = strdup (pend);
941     if (!i->prefs)
942     return;
943 twoaday 15 i->flags.mdc = 0;
944 twoaday 2 }
945     break;
946    
947     case 14: /* idx/flags */
948 twoaday 15 i->idx = atol (pend);
949     if (strchr (pend, 'r'))
950 twoaday 2 i->flags.revoked = 1;
951 twoaday 15 if (strchr( pend, 'p'))
952 twoaday 2 i->flags.primary = 1;
953     break;
954     }
955     }
956 twoaday 15 safe_free (p);
957 twoaday 2 } /* edit_key_colon_handler */
958    
959    
960     static gpgme_error_t
961 twoaday 15 editkey_get_info_start (gpgme_ctx_t ctx, const char *keyid, gpgme_data_t out)
962 twoaday 2 {
963     gpgme_error_t rc;
964    
965     fail_on_pending_request( ctx );
966     ctx->pending = 1;
967    
968     _gpgme_gpg_release( &ctx->gpg );
969     rc = _gpgme_gpg_new( &ctx->gpg );
970     if( rc )
971     goto leave;
972    
973     _gpgme_data_set_mode( out, GPGME_DATA_MODE_IN );
974    
975     _gpgme_gpg_add_arg( ctx->gpg, "--with-colons" );
976     _gpgme_gpg_add_arg( ctx->gpg, "--edit-key" );
977     _gpgme_gpg_add_arg( ctx->gpg, keyid );
978     _gpgme_gpg_add_arg( ctx->gpg, "quit" );
979     _gpgme_gpg_add_arg( ctx->gpg, "--output" );
980     _gpgme_gpg_add_arg( ctx->gpg, "-" );
981     _gpgme_gpg_add_data( ctx->gpg, out, 1 );
982    
983     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
984    
985     leave:
986     if( rc ) {
987     ctx->pending = 0;
988     _gpgme_gpg_release( &ctx->gpg );
989     }
990     return rc;
991     } /* editkey_get_info_start */
992    
993    
994     gpgme_error_t
995     gpgme_op_editkey_get_info (gpgme_ctx_t ctx, const char * keyid,
996     gpgme_uidinfo_t * r_inf)
997     {
998     gpgme_error_t err;
999     gpgme_data_t out = NULL;
1000     gpgme_uidinfo_t inf;
1001     char buf[512];
1002    
1003     if (!ctx)
1004     return mk_error (Invalid_Value);
1005    
1006     err = gpgme_data_new( &out );
1007     if (err)
1008     return err;
1009    
1010     err = editkey_get_info_start( ctx, keyid, out );
1011 twoaday 15 if (!err) {
1012     gpgme_wait (ctx, 1);
1013 twoaday 2 ctx->pending = 0;
1014     }
1015     if (err)
1016     return err;
1017    
1018 twoaday 15 err = gpgme_uid_info_new (&inf);
1019 twoaday 2 if (err)
1020     return err;
1021    
1022     while (gpgme_data_readline (out, buf, sizeof buf -1))
1023     edit_key_colon_handler (inf, buf);
1024    
1025     gpgme_data_release (out);
1026     if (!err && r_inf)
1027     *r_inf = inf;
1028    
1029     return err;
1030     } /* gpgme_op_editkey_get_info */
1031    
1032    
1033     int
1034     gpgme_editkey_count_items( gpgme_uidinfo_t inf )
1035     {
1036     struct user_id_info_s *i;
1037     int ncount = 0;
1038    
1039     for( i = inf->list; i; i = i->next )
1040     ncount++;
1041    
1042     return ncount;
1043     } /* gpgme_editkey_count_items */
1044    
1045    
1046     ulong
1047     gpgme_editkey_get_ulong_attr( gpgme_uidinfo_t inf, int what, int idx )
1048     {
1049     struct user_id_info_s *i;
1050     ulong val;
1051    
1052     if( !inf )
1053     return 0;
1054    
1055     switch( what ) {
1056     case GPGME_ATTR_UID_REVOKED:
1057     for( i = inf->list; i && idx; i = i->next, idx-- )
1058     ;
1059     if( i )
1060     val = i->flags.revoked;
1061     break;
1062    
1063     case GPGME_ATTR_MDC:
1064     for( i = inf->list; i && idx; i = i->next, idx-- )
1065     ;
1066     if( i )
1067     val = i->flags.mdc;
1068     break;
1069    
1070     case GPGME_ATTR_UID_PRIMARY:
1071     for( i = inf->list; i && idx; i = i->next, idx-- )
1072     ;
1073     if( i )
1074     val = i->flags.primary;
1075     break;
1076    
1077     case GPGME_ATTR_VALIDITY:
1078     for( i = inf->list; i && idx; i = i->next, idx-- )
1079     ;
1080     if( i )
1081     val = i->validity;
1082     break;
1083    
1084     case GPGME_ATTR_LEVEL:
1085     for( i = inf->list; i && idx; i = i->next, idx-- )
1086     ;
1087     if( i )
1088     val = i->idx;
1089     break;
1090     }
1091    
1092     return val;
1093     } /* gpgme_editkey_get_ulong_attr */
1094    
1095    
1096     const char*
1097 twoaday 15 gpgme_editkey_get_string_attr (gpgme_uidinfo_t inf, int what, int idx)
1098 twoaday 2 {
1099 twoaday 15 const char *val=NULL;
1100 twoaday 2 struct user_id_info_s *i;
1101    
1102     if( !inf )
1103     return NULL;
1104    
1105     switch( what ) {
1106     case GPGME_ATTR_NAME:
1107 twoaday 15 for (i = inf->list; i && idx; i = i->next, idx--)
1108 twoaday 2 ;
1109 twoaday 15 if (i)
1110 twoaday 2 val = i->name;
1111     break;
1112    
1113 twoaday 15 case GPGME_ATTR_EMAIL:
1114     for (i=inf->list; i && idx; i = i->next, idx--)
1115     ;
1116     if (i)
1117     val = i->email;
1118     break;
1119    
1120 twoaday 2 case GPGME_ATTR_UID_PREFS:
1121 twoaday 15 for (i = inf->list; i && idx; i = i->next, idx--)
1122 twoaday 2 ;
1123 twoaday 15 if (i)
1124 twoaday 2 val = i->prefs;
1125     break;
1126    
1127     default:
1128     val = NULL;
1129     break;
1130     }
1131    
1132     return val;
1133     } /* gpgme_editkey_get_string_attr */
1134    
1135     #endif /*WITH_EDITKEY*/

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26