/[winpt]/trunk/Src/wptKeyEditCB.cpp
ViewVC logotype

Contents of /trunk/Src/wptKeyEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 333 - (show annotations)
Tue Oct 13 10:51:21 2009 UTC (15 years, 4 months ago) by twoaday
File size: 22493 byte(s)


1 /* wptKeyEditCB.cpp - Key edit callback handling
2 * Copyright (C) 2005, 2006, 2009 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <windows.h>
26
27 #include "gpgme.h"
28 #include "wptCommonCtl.h"
29 #include "wptContext.h"
30 #include "wptKeyEdit.h"
31 #include "wptErrors.h"
32 #include "wptTypes.h"
33
34
35 /* Possible errors for the edit key operation. */
36 enum editkey_error_t {
37 EDITKEY_ERR_ALREADY_SIGNED = 1,
38 EDITKEY_ERR_BAD_PASSPHRASE = 2
39 };
40
41 typedef gpgme_status_code_t status_code_t;
42
43
44 /* 'notation' command handler. */
45 static const char*
46 cmd_notation_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
47 {
48 static char buf[32];
49
50 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
51 int uid = ctx->getUseridIndex ();
52 ctx->cmd_sent = 1;
53 if (uid != -1) {
54 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
55 return buf;
56 }
57 }
58 if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 0) {
59 ctx->cnt = 1;
60 return "notation";
61 }
62 if (!strcmp (key, "keyedit.add_notation"))
63 return ctx->notation;
64 if (!strcmp (key, "passphrase.enter"))
65 return ctx->pass;
66
67 return NULL;
68 }
69
70
71 /* 'keyserver' command handler. */
72 static const char*
73 cmd_keyserv_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
74 {
75 static char buf[32];
76
77 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
78 int uid = ctx->getUseridIndex ();
79 ctx->cmd_sent = 1;
80 if (uid != -1) {
81 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
82 return buf;
83 }
84 }
85 if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 0) {
86 ctx->cnt = 1;
87 return "keyserver";
88 }
89 if (!strcmp (key, "keyedit.add_keyserver"))
90 return ctx->url;
91 if (!strcmp (key, "keyedit.confirm_keyserver"))
92 return "Y";
93 if (!strcmp (key, "passphrase.enter"))
94 return ctx->pass;
95 if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 1) {
96 ctx->reset ();
97 return "save";
98 }
99
100 return NULL;
101 }
102
103
104 /* 'sign' command handler. */
105 static const char*
106 cmd_sign_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
107 {
108 static char buf[32];
109
110 if (ctx->getUseridIndex () != -1 &&
111 ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
112 ctx->cnt++;
113 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
114 return buf;
115 }
116
117 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
118 ctx->cmd_sent = 1;
119 switch (ctx->getType ()) {
120 case GPG_EDITKEY_SIGN: return "sign";
121 case GPG_EDITKEY_TSIGN: return "tsign";
122 case GPG_EDITKEY_LSIGN: return "lsign";
123 case GPG_EDITKEY_NRSIGN: return "nrsign";
124 case GPG_EDITKEY_NRLSIGN: return "nrlsign";
125 }
126 }
127 if (!strcmp (key, "sign_uid.class")) {
128 sprintf (buf, "%d", ctx->sig_class);
129 return buf;
130 }
131 if (!strcmp (key, "sign_uid.expire"))
132 return "Y"; /* the sig expires when the key expires */
133 if (!strcmp (key, "siggen.valid"))
134 return ctx->exp_date? ctx->exp_date : "0";
135 if (!strcmp (key, "trustsig_prompt.trust_value")) {
136 sprintf (buf, "%d", ctx->trust_id);
137 return buf;
138 }
139 if (!strcmp (key, "trustsig_prompt.trust_depth"))
140 return ""; /* fixme */
141 if (!strcmp (key, "trustsig_prompt.trust_regexp"))
142 return ""; /* fixme */
143 if (!strcmp (key, "sign_uid.local_promote_okay" ) )
144 return "Y";
145 if (!strcmp (key, "sign_uid.okay" ) )
146 return "Y";
147 if (!strcmp (key, "keyedit.sign_all.okay"))
148 return "Y";
149 if (!ctx->usePassphraseCallback() && !strcmp (key, "passphrase.enter"))
150 return ctx->pass;
151 if (!strcmp (key, "keyedit.prompt")) {
152 ctx->reset ();
153 return "save";
154 }
155
156 return NULL;
157 }
158
159 /* 'trust' command handler. */
160 static const char*
161 cmd_trust_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
162 {
163 static char buf[4];
164
165 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
166 ctx->cmd_sent = 1;
167 return "trust";
168 }
169 if (!strcmp (key, "edit_ownertrust.set_ultimate.okay"))
170 return "Y";
171 if (!strcmp (key, "edit_ownertrust.value" )) {
172 sprintf (buf, "%d", ctx->trust_id);
173 return buf;
174 }
175 if (!strcmp (key, "keyedit.prompt")) {
176 ctx->reset ();
177 return "save";
178 }
179
180 return NULL;
181 }
182
183
184 /* 'adduid' command handler. */
185 static const char*
186 cmd_adduid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
187 {
188 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
189 ctx->cmd_sent = 1;
190 return "adduid";
191 }
192 if (!strcmp (key, "keygen.name"))
193 return ctx->name;
194 if (!strcmp (key, "keygen.email"))
195 return ctx->email;
196 if (!strcmp (key, "keygen.comment"))
197 return ctx->cmt? ctx->cmt : "";
198 if (!strcmp (key, "passphrase.enter"))
199 return ctx->pass;
200 if( !strcmp (key, "keyedit.prompt")) {
201 ctx->reset ();
202 return "save";
203 }
204
205 return NULL;
206 }
207
208
209 static const char*
210 cmd_deluid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
211 const char *key)
212 {
213 static char buf[64];
214
215 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
216 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
217 ctx->cnt = 1;
218 return buf;
219 }
220 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
221 ctx->cnt = 2;
222 return "deluid";
223 }
224 if (ctx->cnt == 2 && !strcmp (key, "keyedit.remove.uid.okay")) {
225 ctx->cnt = 3;
226 return "Y";
227 }
228 if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt" )) {
229 ctx->reset ();
230 return "save";
231 }
232
233 return NULL;
234 }
235
236
237 static const char*
238 cmd_delsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
239 {
240 static char buf[64];
241 static int sig_cnt = 0;
242
243 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
244 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
245 ctx->cnt = 1;
246 return buf;
247 }
248 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
249 ctx->cnt = 2;
250 return "delsig";
251 }
252 if (!strcmp (key, "keyedit.delsig.unknown") ||
253 !strcmp (key, "keyedit.delsig.valid")) {
254 if (++sig_cnt == ctx->getSigIndex ())
255 return "Y";
256 else
257 return "N";
258 }
259 if (!strcmp (key, "keyedit.delsig.selfsig"))
260 return "Y";
261 if (ctx->cnt == 2 && !strcmp (key, "keyedit.prompt")) {
262 sig_cnt = 0;
263 ctx->reset ();
264 return "save";
265 }
266 return NULL;
267 }
268
269
270 /* 'delkey' command handler. */
271 static const char*
272 cmd_delkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
273 const char *key)
274 {
275 static char buf[64];
276
277 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
278 _snprintf (buf, DIM (buf)-1, "key %d", ctx->getKeyIndex ());
279 ctx->cnt = 1;
280 return buf;
281 }
282 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
283 ctx->cnt = 2;
284 return "delkey";
285 }
286 if (ctx->cnt == 2 && !strcmp (key, "keyedit.remove.subkey.okay")) {
287 ctx->cnt = 3;
288 return "Y";
289 }
290 if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt")) {
291 ctx->reset ();
292 return "save";
293 }
294
295 return NULL;
296 }
297
298
299 /* 'addcardkey' command handler. */
300 static const char*
301 cmd_addcardkey_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
302 {
303 static char buf[32];
304
305 /* XXX: actually we mix up things here, it would be better to
306 implement this in CardEditCB but because the edit-key
307 interface is used, we have to implement it here. */
308 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
309 ctx->cmd_sent = 1;
310 return "addcardkey";
311 }
312 if (!strcmp (key, "cardedit.genkeys.subkeytype")) {
313 sprintf (buf, "%d", ctx->getKeyIndex ());
314 return buf;
315 }
316 if (!strcmp (key, "cardedit.genkeys.replace_key"))
317 return "Y"; /* better issue an extra warning? */
318 if (!strcmp (key, "passphrase.adminpin.ask"))
319 return ctx->pass;
320 if (!strcmp (key, "passphrase.pin.ask"))
321 return ctx->new_pass;
322 if (!strcmp (key, "keygen.valid")) {
323 sprintf (buf, "%d", ctx->getValidDays ());
324 return buf;
325 }
326 if (!strcmp (key, "keyedit.prompt")) {
327 ctx->reset ();
328 return "save";
329 }
330 return NULL;
331 }
332
333
334 /* 'addkey' command handler. */
335 static const char*
336 cmd_addkey_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
337 {
338 static char buf[64];
339
340 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
341 ctx->cmd_sent = 1;
342 return "addkey";
343 }
344
345 if (!strcmp (key, "passphrase.enter"))
346 return ctx->pass;
347 if (!strcmp (key, "keygen.algo")) {
348 _snprintf (buf, DIM (buf)-1, "%d", ctx->pubkey_algo);
349 return buf;
350 }
351 if (!strcmp (key, "keygen.size")) {
352 _snprintf (buf, DIM (buf)-1, "%d", ctx->pubkey_size);
353 return buf;
354 }
355 if (!strcmp (key, "keygen.valid")) {
356 _snprintf (buf, DIM (buf)-1, "%d", ctx->getValidDays ());
357 return buf;
358 }
359 if (!strcmp (key, "keyedit.prompt")) {
360 ctx->reset ();
361 return "save";
362 }
363 return NULL;
364 }
365
366
367 /* 'passwd' command handler. */
368 static const char*
369 cmd_passwd_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
370 {
371 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
372 ctx->cmd_sent = 1;
373 return "passwd";
374 }
375 if (ctx->cnt == 0 && !strcmp (key, "passphrase.enter")) {
376 ctx->cnt = 1;
377 /* it is possible that there is no old passphrase. */
378 if (!ctx->pass && ctx->flags)
379 return "";
380 return ctx->pass;
381 }
382 if (!strcmp (key, "passphrase.enter" ))
383 return ctx->new_pass;
384 if (!strcmp (key, "change_passwd.empty.okay" ))
385 return ctx->flags? "Y" : "N";
386 if (!strcmp (key, "keyedit.prompt")) {
387 ctx->reset ();
388 return "save";
389 }
390
391 return NULL;
392 }
393
394
395 /* 'setpref' command handler. */
396 static const char*
397 cmd_setpref_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
398 {
399 static char buf[128] = {0};
400
401 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
402 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
403 ctx->cmd_sent = 1;
404 ctx->cnt = 1;
405 return buf;
406 }
407 if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 1) {
408 _snprintf (buf, DIM (buf)-1, "setpref %s", ctx->new_prefs);
409 ctx->cnt = 2;
410 return buf;
411 }
412 if (!strcmp (key, "keyedit.setpref.okay"))
413 return "Y";
414 if (!strcmp (key, "passphrase.enter"))
415 return ctx->pass;
416 if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 2) {
417 ctx->reset ();
418 return "save";
419 }
420 return buf;
421 }
422
423
424 /* 'primary' command handler. */
425 static const char*
426 cmd_primary_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
427 const char *key)
428 {
429 static char buf[64];
430
431 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
432 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
433 ctx->cnt = 1;
434 return buf;
435 }
436 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt" )) {
437 ctx->cnt = 2;
438 return "primary";
439 }
440 if (ctx->cnt == 2 && !strcmp (key, "passphrase.enter")) {
441 ctx->cnt = 3;
442 return ctx->pass;
443 }
444 if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt")) {
445 ctx->reset ();
446 return "save";
447 }
448 return NULL;
449 }
450
451
452 /* 'expire' command handler. */
453 static const char*
454 cmd_expire_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
455 const char *key)
456 {
457 static char buf[64];
458
459 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
460 _snprintf (buf, DIM (buf)-1, "key %d", ctx->getKeyIndex ());
461 ctx->cnt = 1;
462 return buf;
463 }
464 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
465 ctx->cnt = 2;
466 return "expire";
467 }
468 if (ctx->cnt == 2 && !strcmp (key, "keygen.valid" )) {
469 ctx->cnt = 3;
470 sprintf (buf, "%d", ctx->getValidDays ());
471 return buf;
472 }
473 if (ctx->cnt == 3 && !strcmp (key, "passphrase.enter")) {
474 ctx->cnt = 4;
475 return ctx->pass;
476 }
477 if (ctx->cnt == 4 && !strcmp (key, "keyedit.prompt")) {
478 ctx->reset ();
479 return "save";
480 }
481
482 return NULL;
483 }
484
485
486 /* 'revuid' command handler. */
487 const char*
488 cmd_revuid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
489 const char *key)
490 {
491 static char buf[32];
492
493 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
494 ctx->cnt = 1;
495 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
496 return buf;
497 }
498 else if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
499 ctx->cnt = 2;
500 return "revuid";
501 }
502 else if (ctx->cnt == 2 && !strcmp (key, "keyedit.revoke.uid.okay")) {
503 ctx->cnt = 3;
504 return "Y";
505 }
506 else if (ctx->cnt == 3 && !strcmp (key, "ask_revocation_reason.code")) {
507 ctx->cnt = 4;
508 return "4";
509 }
510 else if (ctx->cnt == 4 && !strcmp (key, "ask_revocation_reason.text")) {
511 ctx->cnt = 5;
512 return "";
513 }
514 else if (ctx->cnt == 5 && !strcmp (key, "ask_revocation_reason.okay")) {
515 ctx->cnt = 6;
516 return "Y";
517 }
518 else if (ctx->cnt == 6 && !strcmp (key, "passphrase.enter")) {
519 ctx->cnt = 7;
520 return ctx->pass;
521 }
522 else if (ctx->cnt == 7 && !strcmp (key, "keyedit.prompt")) {
523 ctx->reset ();
524 return "save";
525 }
526 return NULL;
527 }
528
529
530 const char*
531 cmd_revsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
532 const char *key)
533 {
534 static char buf[64];
535
536 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt" )) {
537 _snprintf (buf, DIM (buf)-1, "uid %d", ctx->getUseridIndex ());
538 ctx->cnt = 1;
539 return buf;
540 }
541 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
542 ctx->cnt = 2;
543 return "revsig";
544 }
545 if (ctx->cnt == 2 && !strcmp (key, "ask_revoke_sig.one")) {
546 ctx->cnt = 3;
547 return "Y";
548 }
549 if (ctx->cnt == 3 && !strcmp (key, "ask_revoke_sig.okay")) {
550 ctx->cnt = 4;
551 return "Y";
552 }
553 if (ctx->cnt == 4 && !strcmp (key, "ask_revocation_reason.code")) {
554 ctx->cnt = 5;
555 return "0";
556 }
557 if (ctx->cnt == 5 && !strcmp (key, "ask_revocation_reason.text" )) {
558 ctx->cnt = 6;
559 return "";
560 }
561 if (ctx->cnt == 6 && !strcmp (key, "ask_revocation_reason.okay" ) ) {
562 ctx->cnt = 7;
563 return "Y";
564 }
565 if (ctx->cnt == 7 && !strcmp (key, "passphrase.enter" ) ) {
566 ctx->cnt = 8;
567 return ctx->pass;
568 }
569 if (ctx->cnt == 8 && !strcmp (key, "keyedit.prompt")) {
570 ctx->reset ();
571 return "save";
572 }
573
574 return NULL;
575 }
576
577
578 /* 'revoke' command handler. */
579 static const char *
580 cmd_revkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
581 const char *key)
582 {
583 static char buf[64];
584
585 if (ctx->cnt == 0 && !strcmp ( key, "keyedit.prompt" ) ) {
586 _snprintf (buf, DIM (buf)-1, "key %d", ctx->getKeyIndex ());
587 ctx->cnt = 1;
588 return buf;
589 }
590 if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
591 ctx->cnt = 2;
592 return "revkey";
593 }
594 if (ctx->cnt == 2 && !strcmp (key, "keyedit.revoke.subkey.okay")) {
595 ctx->cnt = 3;
596 return "Y";
597 }
598 if (ctx->cnt == 3 && !strcmp ( key, "ask_revocation_reason.code")) {
599 sprintf( buf, "%d", ctx->reason);
600 ctx->cnt = 4;
601 return buf;
602 }
603 if (ctx->cnt == 4 && !strcmp (key, "ask_revocation_reason.text")) {
604 ctx->cnt = 5;
605 return "";
606 }
607 if (ctx->cnt == 5 && !strcmp (key, "ask_revocation_reason.okay")) {
608 ctx->cnt = 6;
609 return "Y";
610 }
611 if (ctx->cnt == 6 && !strcmp (key, "passphrase.enter")) {
612 ctx->cnt = 7;
613 return ctx->pass;
614 }
615 if (ctx->cnt == 7 && !strcmp ( key, "keyedit.prompt")) {
616 ctx->reset ();
617 return "save";
618 }
619 return NULL;
620 }
621
622
623 /* 'addrevoker' command handler. */
624 static const char *
625 cmd_addrev_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
626 const char *key)
627 {
628
629 /* If the isuser already signed the key, send an empty
630 string and jump to quit. */
631 if (ctx->getResult () & EDITKEY_ERR_ALREADY_SIGNED
632 && ctx->cnt != -1 && ctx->cnt != 4) {
633 ctx->cnt = -1;
634 return "";
635 }
636 if (ctx->cnt == -1) {
637 ctx->cnt = 4;
638 return ""; /* empty value to abort. */
639 }
640 if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
641 ctx->cnt = 1;
642 return "addrevoker";
643 }
644 if (!strcmp (key, "keyedit.add_revoker"))
645 return ctx->name;
646
647 if (!strcmp (key, "keyedit.add_revoker.okay"))
648 return "Y";
649
650 if (!strcmp (key, "passphrase.enter"))
651 return ctx->pass;
652
653 if (ctx->cnt > 0 && !strcmp (key, "keyedit.prompt")) {
654 ctx->reset ();
655 return "save";
656 }
657
658 return NULL;
659 }
660
661
662 /* 'addphoto' command handler. */
663 static const char*
664 cmd_addphoto_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
665 {
666 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
667 ctx->cmd_sent = 1;
668 return "addphoto";
669 }
670 if (!strcmp (key, "photoid.jpeg.add"))
671 return ctx->url;
672 if (!strcmp (key, "photoid.jpeg.size"))
673 return "Y";
674 if (!strcmp (key, "passphrase.enter"))
675 return ctx->pass;
676 if (!strcmp (key, "keyedit.prompt")) {
677 ctx->reset ();
678 return "save";
679 }
680 return NULL;
681 }
682
683
684 static const char*
685 cmd_minimize_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
686 {
687 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
688 ctx->cmd_sent = 1;
689 return "minimize";
690 }
691 if (!strcmp (key, "keyedit.prompt")) {
692 ctx->reset ();
693 return "save";
694 }
695
696 return NULL;
697 }
698
699 /* 'clean' command handler. */
700 static const char*
701 cmd_clean_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
702 {
703 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
704 ctx->cmd_sent = 1;
705 return "clean";
706 }
707 if (!strcmp (key, "keyedit.prompt")) {
708 ctx->reset ();
709 return "save";
710 }
711 return NULL;
712 }
713
714
715 /* 'enable' and 'disable' command handler. */
716 static const char *
717 cmd_enable_disable_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
718 const char * key, int mode)
719 {
720 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
721 ctx->cmd_sent = 1;
722 return mode? "disable": "enable";
723 }
724 if (!strcmp (key, "keyedit.prompt")) {
725 ctx->reset ();
726 return "save";
727 }
728 return NULL;
729 }
730
731
732 /* edit key dispatch handler. */
733 static gpgme_error_t
734 editkey_command_handler (void *opaque, gpgme_status_code_t code,
735 const char *key, int fd)
736 {
737 const char *out = NULL;
738 GpgKeyEdit *ke = (GpgKeyEdit *)opaque;
739 HANDLE hd = (HANDLE)fd;
740 DWORD n;
741
742 if (!ke)
743 return gpg_error (GPG_ERR_INV_ARG);
744
745 /*log_debug ("key=%s code=%d\r\n", key, code);*/
746 switch (code) {
747 case GPGME_STATUS_ALREADY_SIGNED:
748 ke->setResult (EDITKEY_ERR_ALREADY_SIGNED);
749 break;
750
751 //case GPGME_STATUS_GOOD_PASSPHRASE:
752 // ke->setResult (0);
753 // break;
754
755 case GPGME_STATUS_BAD_PASSPHRASE:
756 if (!ke->usePassphraseCallback ()) {
757 log_debug ("editkey_command_handler: bad passphrase\n");
758 ke->setResult (EDITKEY_ERR_BAD_PASSPHRASE);
759 }
760 break;
761
762 default:
763 break;
764 }
765
766 /* If the entered passphrase is bad, we supply empty
767 passphrase to abort and send 'quit' as soon as possible.
768 But this semantic is not used when we use the callback mode. */
769 if (!ke->usePassphraseCallback() &&
770 (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE)) {
771
772 if (!strcmp (key, "passphrase.enter"))
773 WriteFile (hd, "\n", 1, &n, NULL);
774 if (!strcmp (key, "keyedit.prompt"))
775 WriteFile (hd, "quit\n", 5, &n, NULL);
776 ke->reset ();
777 return 0;
778 }
779
780 switch (ke->getType ()) {
781 case GPG_EDITKEY_LSIGN:
782 case GPG_EDITKEY_SIGN:
783 case GPG_EDITKEY_NRSIGN:
784 case GPG_EDITKEY_TSIGN:
785 case GPG_EDITKEY_NRLSIGN:
786 out = cmd_sign_handler (ke, code, key);
787 break;
788
789 case GPG_EDITKEY_TRUST:
790 out = cmd_trust_handler (ke, code, key);
791 break;
792
793 case GPG_EDITKEY_ADDUID:
794 out = cmd_adduid_handler (ke, code, key);
795 break;
796
797 case GPG_EDITKEY_DELUID:
798 out = cmd_deluid_handler (ke, code, key);
799 break;
800
801 case GPG_EDITKEY_DELSIG:
802 out = cmd_delsig_handler (ke, code, key);
803 break;
804
805 case GPG_EDITKEY_DELKEY:
806 out = cmd_delkey_handler(ke, code, key);
807 break;
808
809 case GPG_EDITKEY_ADDKEY:
810 out = cmd_addkey_handler (ke, code, key);
811 break;
812
813 case GPG_EDITKEY_ADDCARDKEY:
814 out = cmd_addcardkey_handler (ke, code, key);
815 break;
816
817 case GPG_EDITKEY_PASSWD:
818 out = cmd_passwd_handler (ke, code, key);
819 break;
820
821 case GPG_EDITKEY_PRIMARY:
822 out = cmd_primary_handler (ke, code, key);
823 break;
824
825 case GPG_EDITKEY_EXPIRE:
826 out = cmd_expire_handler (ke, code, key);
827 break;
828
829 case GPG_EDITKEY_REVSIG:
830 out = cmd_revsig_handler (ke, code, key);
831 break;
832
833 case GPG_EDITKEY_REVKEY:
834 out = cmd_revkey_handler (ke, code, key);
835 break;
836
837 case GPG_EDITKEY_REVUID:
838 out = cmd_revuid_handler (ke, code, key);
839 break;
840
841 case GPG_EDITKEY_ADDREV:
842 out = cmd_addrev_handler (ke, code, key);
843 break;
844
845 case GPG_EDITKEY_ADDPHOTO:
846 out = cmd_addphoto_handler (ke, code, key);
847 break;
848
849 case GPG_EDITKEY_NOTATION:
850 out = cmd_notation_handler (ke, code, key);
851 break;
852
853 case GPG_EDITKEY_MINIMIZE:
854 out = cmd_minimize_handler (ke, code, key);
855 break;
856
857 case GPG_EDITKEY_CLEAN:
858 out = cmd_clean_handler (ke, code, key);
859 break;
860
861 case GPG_EDITKEY_ENABLE:
862 case GPG_EDITKEY_DISABLE:
863 n = ke->getType () == GPG_EDITKEY_DISABLE? 1: 0;
864 out = cmd_enable_disable_handler (ke, code, key, n);
865 break;
866
867 case GPG_EDITKEY_SETPREF:
868 out = cmd_setpref_handler (ke, code, key);
869 break;
870
871 case GPG_EDITKEY_KEYSERV:
872 out = cmd_keyserv_handler (ke, code, key);
873 break;
874 }
875
876 if (out != NULL) {
877 WriteFile (hd, out, strlen (out), &n, NULL);
878 WriteFile (hd, "\n", 1, &n, NULL);
879 }
880 return 0;
881 }
882
883
884 /* Check if a GPG status code occured which marks the
885 current operation as failed.
886 Return value: gpg error constant. */
887 static gpgme_error_t
888 map_result (GpgKeyEdit *ke)
889 {
890 if (!ke->getResult ())
891 return gpg_error (GPG_ERR_NO_ERROR);
892 if (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE)
893 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
894 return 0;
895 }
896
897
898 /* Wrapper around the gpgme edit interface.
899 @ctx context to use.
900 @key key on which the operation should be performed.
901 @ek key edit context.
902 Return value: 0 on success. */
903 gpgme_error_t
904 gpg_editkey (gpgme_ctx_t ctx, gpgme_key_t key, GpgKeyEdit *ek)
905 {
906 gpgme_error_t err;
907 gpgme_data_t out;
908
909 err = gpgme_data_new (&out);
910 if (err)
911 return err;
912 err = gpgme_op_edit (ctx, key, editkey_command_handler, ek, out);
913 if (!err)
914 err = map_result (ek);
915
916 gpgme_data_release (out);
917 return err;
918 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26