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

Contents of /trunk/MyGPGME/editkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show annotations)
Mon May 9 08:53:51 2005 UTC (19 years, 9 months ago) by twoaday
File MIME type: text/plain
File size: 30106 byte(s)
Some bug fixes for 'showpref'.

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