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

Diff of /trunk/Src/wptKeyEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.28  
changed lines
  Added in v.328

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26