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

Contents of /trunk/Src/wptKeyEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 278 - (show annotations)
Mon Jan 15 22:02:04 2007 UTC (18 years, 1 month ago) by twoaday
File size: 22414 byte(s)
See ChangeLog.


1 /* wptKeyEditCB.cpp - Key edit callback handling
2 * Copyright (C) 2005, 2006 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 (!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, sizeof (buf)-1, "%d", ctx->pubkey_algo);
349 return buf;
350 }
351 if (!strcmp (key, "keygen.size")) {
352 _snprintf (buf, sizeof (buf)-1, "%d", ctx->pubkey_size);
353 return buf;
354 }
355 if (!strcmp (key, "keygen.valid")) {
356 _snprintf (buf, sizeof (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, sizeof (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, sizeof 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 (ctx->cnt == 1 && !strcmp (key, "keyedit.add_revoker")) {
645 ctx->cnt = 2;
646 return ctx->name;
647 }
648 if (ctx->cnt == 2 && !strcmp (key, "keyedit.add_revoker.okay")) {
649 ctx->cnt = 3;
650 return "Y";
651 }
652 if (ctx->cnt == 3 && !strcmp (key, "passphrase.enter")) {
653 ctx->cnt = 4;
654 return ctx->pass;
655 }
656 if (ctx->cnt == 4 && !strcmp (key, "keyedit.prompt")) {
657 ctx->reset ();
658 return "save";
659 }
660
661 return NULL;
662 }
663
664
665 /* 'addphoto' command handler. */
666 static const char*
667 cmd_addphoto_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
668 {
669 if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
670 ctx->cmd_sent = 1;
671 return "addphoto";
672 }
673 if (!strcmp (key, "photoid.jpeg.add"))
674 return ctx->url;
675 if (!strcmp (key, "photoid.jpeg.size"))
676 return "Y";
677 if (!strcmp (key, "passphrase.enter"))
678 return ctx->pass;
679 if (!strcmp (key, "keyedit.prompt")) {
680 ctx->reset ();
681 return "save";
682 }
683 return NULL;
684 }
685
686
687 static const char*
688 cmd_minimize_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
689 {
690 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
691 ctx->cmd_sent = 1;
692 return "minimize";
693 }
694 if (!strcmp (key, "keyedit.prompt")) {
695 ctx->reset ();
696 return "save";
697 }
698
699 return NULL;
700 }
701
702 /* 'clean' command handler. */
703 static const char*
704 cmd_clean_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
705 {
706 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
707 ctx->cmd_sent = 1;
708 return "clean";
709 }
710 if (!strcmp (key, "keyedit.prompt")) {
711 ctx->reset ();
712 return "save";
713 }
714 return NULL;
715 }
716
717
718 /* 'enable' and 'disable' command handler. */
719 static const char *
720 cmd_enable_disable_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
721 const char * key, int mode)
722 {
723 if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
724 ctx->cmd_sent = 1;
725 return mode? "disable": "enable";
726 }
727 if (!strcmp (key, "keyedit.prompt")) {
728 ctx->reset ();
729 return "save";
730 }
731 return NULL;
732 }
733
734
735 /* edit key dispatch handler. */
736 static gpgme_error_t
737 editkey_command_handler (void *opaque, gpgme_status_code_t code,
738 const char *key, int fd)
739 {
740 const char *out = NULL;
741 GpgKeyEdit *ke = (GpgKeyEdit *)opaque;
742 HANDLE hd = (HANDLE)fd;
743 DWORD n;
744
745 if (!ke)
746 return gpg_error (GPG_ERR_INV_ARG);
747
748 /*log_debug ("key=%s code=%d\r\n", key, code);*/
749 switch (code) {
750 case GPGME_STATUS_ALREADY_SIGNED:
751 ke->setResult (EDITKEY_ERR_ALREADY_SIGNED);
752 break;
753
754 case GPGME_STATUS_BAD_PASSPHRASE:
755 log_debug ("editkey_command_handler: bad passphrase\n");
756 ke->setResult (EDITKEY_ERR_BAD_PASSPHRASE);
757 break;
758
759 default:
760 break;
761 }
762
763 if (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE) {
764 /* If the entered passphrase is bad, we supply empty
765 passphrase to abort and send 'quit' as soon as possible. */
766 if (!strcmp (key, "passphrase.enter"))
767 WriteFile (hd, "\n", 1, &n, NULL);
768 if (!strcmp (key, "keyedit.prompt"))
769 WriteFile (hd, "quit\n", 5, &n, NULL);
770 ke->reset ();
771 return 0;
772 }
773
774 switch (ke->getType ()) {
775 case GPG_EDITKEY_LSIGN:
776 case GPG_EDITKEY_SIGN:
777 case GPG_EDITKEY_NRSIGN:
778 case GPG_EDITKEY_TSIGN:
779 case GPG_EDITKEY_NRLSIGN:
780 out = cmd_sign_handler (ke, code, key);
781 break;
782
783 case GPG_EDITKEY_TRUST:
784 out = cmd_trust_handler (ke, code, key);
785 break;
786
787 case GPG_EDITKEY_ADDUID:
788 out = cmd_adduid_handler (ke, code, key);
789 break;
790
791 case GPG_EDITKEY_DELUID:
792 out = cmd_deluid_handler (ke, code, key);
793 break;
794
795 case GPG_EDITKEY_DELSIG:
796 out = cmd_delsig_handler (ke, code, key);
797 break;
798
799 case GPG_EDITKEY_DELKEY:
800 out = cmd_delkey_handler(ke, code, key);
801 break;
802
803 case GPG_EDITKEY_ADDKEY:
804 out = cmd_addkey_handler (ke, code, key);
805 break;
806
807 case GPG_EDITKEY_ADDCARDKEY:
808 out = cmd_addcardkey_handler (ke, code, key);
809 break;
810
811 case GPG_EDITKEY_PASSWD:
812 out = cmd_passwd_handler (ke, code, key);
813 break;
814
815 case GPG_EDITKEY_PRIMARY:
816 out = cmd_primary_handler (ke, code, key);
817 break;
818
819 case GPG_EDITKEY_EXPIRE:
820 out = cmd_expire_handler (ke, code, key);
821 break;
822
823 case GPG_EDITKEY_REVSIG:
824 out = cmd_revsig_handler (ke, code, key);
825 break;
826
827 case GPG_EDITKEY_REVKEY:
828 out = cmd_revkey_handler (ke, code, key);
829 break;
830
831 case GPG_EDITKEY_REVUID:
832 out = cmd_revuid_handler (ke, code, key);
833 break;
834
835 case GPG_EDITKEY_ADDREV:
836 out = cmd_addrev_handler (ke, code, key);
837 break;
838
839 case GPG_EDITKEY_ADDPHOTO:
840 out = cmd_addphoto_handler (ke, code, key);
841 break;
842
843 case GPG_EDITKEY_NOTATION:
844 out = cmd_notation_handler (ke, code, key);
845 break;
846
847 case GPG_EDITKEY_MINIMIZE:
848 out = cmd_minimize_handler (ke, code, key);
849 break;
850
851 case GPG_EDITKEY_CLEAN:
852 out = cmd_clean_handler (ke, code, key);
853 break;
854
855 case GPG_EDITKEY_ENABLE:
856 case GPG_EDITKEY_DISABLE:
857 n = ke->getType () == GPG_EDITKEY_DISABLE? 1: 0;
858 out = cmd_enable_disable_handler (ke, code, key, n);
859 break;
860
861 case GPG_EDITKEY_SETPREF:
862 out = cmd_setpref_handler (ke, code, key);
863 break;
864
865 case GPG_EDITKEY_KEYSERV:
866 out = cmd_keyserv_handler (ke, code, key);
867 break;
868 }
869
870 if (out != NULL) {
871 WriteFile (hd, out, strlen (out), &n, NULL);
872 WriteFile (hd, "\n", 1, &n, NULL);
873 }
874 return 0;
875 }
876
877
878 /* Check if a GPG status code occured which marks the
879 current operation as failed.
880 Return value: gpg error constant. */
881 static gpgme_error_t
882 map_result (GpgKeyEdit *ke)
883 {
884 /* XXX Sometimes ALREADY_SIGNED indicates an failure. */
885 if (!ke->getResult ())
886 return gpg_error (GPG_ERR_NO_ERROR);
887 if (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE)
888 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
889 return 0;
890 }
891
892
893 /* Wrapper around the gpgme edit interface.
894 @ctx context to use.
895 @key key on which the operation should be performed.
896 @ek key edit context.
897 Return value: 0 on success. */
898 gpgme_error_t
899 gpg_editkey (gpgme_ctx_t ctx, gpgme_key_t key, GpgKeyEdit *ek)
900 {
901 gpgme_error_t err;
902 gpgme_data_t out;
903
904 err = gpgme_data_new (&out);
905 if (err)
906 return err;
907 err = gpgme_op_edit (ctx, key, editkey_command_handler, ek, out);
908 if (!err)
909 err = map_result (ek);
910
911 gpgme_data_release (out);
912 return err;
913 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26