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

Contents of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show 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 /* editkey.c - GPG edit key interface
2 * Copyright (C) 2001-2005 Timo Schulz
3 *
4 * This file is part of MyGPGME.
5 *
6 * MyGPGME is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * MyGPGME is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <assert.h>
25
26 #include "gpgme-config.h"
27 #ifdef WITH_EDITKEY
28 #include "ops.h"
29 #include "context.h"
30 #include "util.h"
31 #include "common-status.h"
32
33 #define GET_BOOL STATUS_GET_BOOL
34 #define GET_LINE STATUS_GET_LINE
35 #define GET_HIDDEN STATUS_GET_HIDDEN
36
37 #define do_check(code, exp, key, val) \
38 (((code) == (exp)) && (strcmp ((key), (val) ) == 0))
39
40 #define is_sig_cmd(ctx)((ctx)->edit_cmd == GPGME_EDITKEY_SIGN \
41 || (ctx)->edit_cmd == GPGME_EDITKEY_TSIGN \
42 || (ctx)->edit_cmd == GPGME_EDITKEY_LSIGN \
43 || (ctx)->edit_cmd == GPGME_EDITKEY_NRSIGN \
44 || (ctx)->edit_cmd == GPGME_EDITKEY_NRLSIGN)
45
46 struct editkey_result_s {
47 int bad_passphrase;
48 int already_signed;
49 int key_expired;
50 };
51
52
53 void
54 _gpgme_release_editkey_result (_editkey_result_t res)
55 {
56 safe_free (res);
57 }
58
59
60 static void
61 editkey_status_handler( gpgme_ctx_t ctx, gpg_status_code_t code, char *args )
62 {
63 if (ctx->out_of_core)
64 return;
65
66 if (ctx->result_type == RESULT_TYPE_NONE) {
67 ctx->result.editk = calloc (1, sizeof * ctx->result.editk);
68 if (!ctx->result.editk) {
69 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 cmd_addkey_handler (gpgme_editkey_t ctx, gpg_status_code_t code, const char *key)
290 {
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
524 /*DEBUG3("code=%d key=%s step=%d\n", code, key, step);*/
525 if ((step == 0 /*|| c->result.editk->already_signed*/)
526 && do_check (code, GET_LINE, key, "keyedit.add_revoker")) {
527 *r_step = step = 1;
528 if (c->result.editk && c->result.editk->already_signed) {
529 *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
651 case GPGME_EDITKEY_KEYSERV:
652 return cmd_keyserv_handler (ctx, code, key);
653 }
654
655 return NULL;
656 } /* editkey_command_handler */
657
658
659 static gpgme_error_t
660 editkey_start (gpgme_ctx_t ctx, const char * keyid)
661 {
662 gpgme_error_t rc;
663
664 if (ctx->result_type == RESULT_TYPE_EDITKEY &&
665 ctx->result.editk != NULL)
666 memset (ctx->result.editk, 0, sizeof (struct editkey_result_s));
667
668 fail_on_pending_request (ctx);
669 ctx->pending = 1;
670
671 /* create a process object */
672 _gpgme_gpg_release( &ctx->gpg);
673 rc = _gpgme_gpg_new( &ctx->gpg );
674 if( rc )
675 goto leave;
676
677 _gpgme_gpg_set_status_handler ( ctx->gpg, editkey_status_handler, ctx );
678 if( ctx->edit_cmd ) {
679 rc = _gpgme_gpg_set_command_handler( ctx->gpg, editkey_command_handler, ctx );
680 if( rc )
681 goto leave;
682 }
683
684 if (ctx->locusr) {
685 _gpgme_gpg_add_arg (ctx->gpg, "-u ");
686 _gpgme_gpg_add_arg (ctx->gpg, ctx->locusr);
687 }
688 if (is_sig_cmd (ctx) && ((gpgme_editkey_t)ctx->edit_opaque)->u.sign.exp_date)
689 _gpgme_gpg_add_arg (ctx->gpg, "--ask-cert-expire");
690 if (is_sig_cmd (ctx) && ((gpgme_editkey_t)ctx->edit_opaque)->u.sign.sig_class)
691 _gpgme_gpg_add_arg (ctx->gpg, "--ask-cert-level");
692
693 _gpgme_gpg_add_arg (ctx->gpg, "--edit-key");
694 _gpgme_gpg_add_arg (ctx->gpg, keyid);
695 switch( ctx->edit_cmd ) {
696 case GPGME_EDITKEY_SIGN:
697 _gpgme_gpg_add_arg( ctx->gpg, "sign" );
698 break;
699
700 case GPGME_EDITKEY_KEYSERV:
701 _gpgme_gpg_add_arg (ctx->gpg, "keyserver");
702 break;
703
704 case GPGME_EDITKEY_LSIGN:
705 _gpgme_gpg_add_arg (ctx->gpg, "lsign");
706 break;
707
708 case GPGME_EDITKEY_NRSIGN:
709 _gpgme_gpg_add_arg (ctx->gpg, "nrsign");
710 break;
711
712 case GPGME_EDITKEY_NRLSIGN:
713 _gpgme_gpg_add_arg (ctx->gpg, "nrlsign");
714 break;
715
716 case GPGME_EDITKEY_TSIGN:
717 _gpgme_gpg_add_arg (ctx->gpg, "tsign");
718 break;
719
720 case GPGME_EDITKEY_ADDKEY:
721 _gpgme_gpg_add_arg (ctx->gpg, "addkey");
722 break;
723
724 case GPGME_EDITKEY_DELUID:
725 _gpgme_gpg_add_arg( ctx->gpg, "deluid" );
726 break;
727
728 case GPGME_EDITKEY_DELKEY:
729 _gpgme_gpg_add_arg( ctx->gpg, "delkey" );
730 break;
731
732 case GPGME_EDITKEY_DELSIG:
733 /* we need to choose the uid before */
734 _gpgme_gpg_add_arg (ctx->gpg, "");
735 break;
736
737 case GPGME_EDITKEY_ADDUID:
738 _gpgme_gpg_add_arg( ctx->gpg, "adduid" );
739 break;
740
741 case GPGME_EDITKEY_TRUST:
742 _gpgme_gpg_add_arg( ctx->gpg, "trust" );
743 break;
744
745 case GPGME_EDITKEY_PASSWD:
746 _gpgme_gpg_add_arg( ctx->gpg, "passwd" );
747 break;
748
749 case GPGME_EDITKEY_PRIMARY:
750 /* we need to choose the uid before */
751 _gpgme_gpg_add_arg( ctx->gpg, "" );
752 break;
753
754 case GPGME_EDITKEY_EXPIRE:
755 /* we need to choose the key before */
756 _gpgme_gpg_add_arg( ctx->gpg, "" );
757 break;
758
759 case GPGME_EDITKEY_REVSIG:
760 /* we need to choose the uid before */
761 _gpgme_gpg_add_arg( ctx->gpg, "" );
762 break;
763
764 case GPGME_EDITKEY_REVKEY:
765 /* we need to choose the key before */
766 _gpgme_gpg_add_arg( ctx->gpg, "" );
767 break;
768
769 case GPGME_EDITKEY_SETPREF:
770 /* we cannot add the command here */
771 _gpgme_gpg_add_arg (ctx->gpg, "");
772
773 case GPGME_EDITKEY_ADDREV:
774 _gpgme_gpg_add_arg( ctx->gpg, "addrevoker" );
775 break;
776
777 case GPGME_EDITKEY_ADDPHOTO:
778 _gpgme_gpg_add_arg( ctx->gpg, "addphoto" );
779 break;
780
781 case GPGME_EDITKEY_ENABLE:
782 _gpgme_gpg_add_arg( ctx->gpg, "enable" );
783 break;
784
785 case GPGME_EDITKEY_DISABLE:
786 _gpgme_gpg_add_arg( ctx->gpg, "disable" );
787 break;
788
789 default:
790 rc = mk_error( Invalid_Value );
791 goto leave;
792 }
793 rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
794
795 leave:
796 if( rc ) {
797 ctx->pending = 0;
798 _gpgme_gpg_release( &ctx->gpg );
799 }
800
801 return rc;
802 } /* editkey_start */
803
804
805 static int
806 check_edit_cmd (gpgme_ctx_t ctx)
807 {
808 if (ctx->edit_cmd == GPGME_EDITKEY_DELKEY ||
809 ctx->edit_cmd == GPGME_EDITKEY_DELSIG)
810 return 0;
811 return 1;
812 }
813
814 gpgme_error_t
815 gpgme_op_editkey( gpgme_ctx_t ctx, const char * keyid )
816 {
817 gpgme_error_t rc;
818 int use_key_check = check_edit_cmd (ctx);
819
820 rc = editkey_start( ctx, keyid );
821 if( !rc ) {
822 gpgme_wait( ctx, 1 );
823 ctx->pending = 0;
824 if( ctx->result.editk->bad_passphrase )
825 rc = mk_error( Bad_Passphrase );
826 else if( ctx->result.editk->already_signed )
827 rc = mk_error( Conflict );
828 else if (use_key_check && ctx->result.editk->key_expired)
829 rc = mk_error (Invalid_Mode);
830 else if( gpgme_get_process_rc( ctx ) )
831 rc = mk_error( Internal_GPG_Problem );
832 }
833 return rc;
834 } /* gpgme_op_editkey */
835
836
837 gpgme_error_t
838 gpgme_uid_info_new( gpgme_uidinfo_t *r_inf )
839 {
840 gpgme_uidinfo_t c;
841
842 if( !r_inf )
843 return mk_error( Invalid_Value );
844 *r_inf = NULL;
845 c = calloc( 1, sizeof *c );
846 if( !c )
847 return mk_error( Out_Of_Core );
848 *r_inf = c;
849 return 0;
850 } /* gpgme_uid_info_new */
851
852
853 void
854 gpgme_uid_info_release (gpgme_uidinfo_t inf)
855 {
856 struct user_id_info_s *i, *list;
857
858 if (!inf)
859 return;
860 list = inf->list;
861 while (list) {
862 i = list->next;
863 if (list->name) {
864 safe_free (list->name);
865 list->name = NULL;
866 }
867 if (list->prefs) {
868 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 struct user_id_info_s *i, *t;
883
884 if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
885 return;
886
887 i = calloc (1, sizeof *i);
888 if (!i)
889 return;
890 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
898 p = strdup (line);
899 if (!p)
900 return;
901 while (1) {
902 field++;
903 pend = strsep (&p, ":");
904 if (pend == NULL)
905 break;
906
907 switch (field) {
908 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 _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 break;
925
926 case 13: /* preferences */
927 if (strstr (pend, "mdc")) {
928 len = strlen (pend) - 4; /* ,mdc */
929 if (strstr (pend, "no-ks-modify")) {
930 i->flags.no_ks_modify = 1;
931 len -= 13; /* ,no-ks-modify */
932 }
933 i->prefs = calloc (1, len+1);
934 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 i->flags.mdc = 0;
945 }
946 break;
947
948 case 14: /* idx/flags */
949 i->idx = atol (pend);
950 if (strchr (pend, 'r'))
951 i->flags.revoked = 1;
952 if (strchr( pend, 'p'))
953 i->flags.primary = 1;
954 break;
955 }
956 }
957 safe_free (p);
958 } /* edit_key_colon_handler */
959
960
961 static gpgme_error_t
962 editkey_get_info_start (gpgme_ctx_t ctx, const char *keyid, gpgme_data_t out)
963 {
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 if (!err) {
1013 gpgme_wait (ctx, 1);
1014 ctx->pending = 0;
1015 }
1016 if (err)
1017 return err;
1018
1019 err = gpgme_uid_info_new (&inf);
1020 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 gpgme_editkey_get_string_attr (gpgme_uidinfo_t inf, int what, int idx)
1099 {
1100 const char *val=NULL;
1101 struct user_id_info_s *i;
1102
1103 if( !inf )
1104 return NULL;
1105
1106 switch( what ) {
1107 case GPGME_ATTR_NAME:
1108 for (i = inf->list; i && idx; i = i->next, idx--)
1109 ;
1110 if (i)
1111 val = i->name;
1112 break;
1113
1114 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 case GPGME_ATTR_UID_PREFS:
1122 for (i = inf->list; i && idx; i = i->next, idx--)
1123 ;
1124 if (i)
1125 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