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

Diff of /trunk/Src/wptKeyManager.cpp

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

revision 16 by twoaday, Mon May 9 08:54:21 2005 UTC revision 36 by werner, Thu Oct 27 15:25:13 2005 UTC
# Line 1  Line 1 
1  /* wptKeyManager.cpp - Handy functions for the Key Manager dialog  /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2   *      Copyright (C) 2001-2004 Timo Schulz   *      Copyright (C) 2001-2005 Timo Schulz
3   *   *      Copyright (C) 2005 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
6   * WinPT is free software; you can redistribute it and/or   *
7   * modify it under the terms of the GNU General Public License   * WinPT is free software; you can redistribute it and/or
8   * as published by the Free Software Foundation; either version 2   * modify it under the terms of the GNU General Public License
9   * of the License, or (at your option) any later version.   * as published by the Free Software Foundation; either version 2
10   *     * of the License, or (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *  
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   *   * General Public License for more details.
16   * You should have received a copy of the GNU General Public License   *
17   * along with WinPT; if not, write to the Free Software Foundation,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * along with WinPT; if not, write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  /* x-todo-status: OK */   */
21    #ifdef HAVE_CONFIG_H
22  #include <windows.h>  #include <config.h>
23  #include <commctrl.h>  #endif
24  #include <stdio.h>  
25  #include <io.h>  #include <windows.h>
26    #include <windows.h>
27  #include "../resource.h"  #include <commctrl.h>
28  #include "wptTypes.h"  #include <stdio.h>
29  #include "wptW32API.h"  
30  #include "wptVersion.h"  #include "gpgme.h"
31  #include "wptCommonCtl.h"  #include "../resource.h"
32  #include "wptNLS.h"  #include "wptTypes.h"
33  #include "wptErrors.h"  #include "wptW32API.h"
34  #include "wptGPG.h"  #include "wptVersion.h"
35  #include "wptContext.h"  #include "wptCommonCtl.h"
36  #include "wptKeylist.h"  #include "wptNLS.h"
37  #include "wptFileManager.h"  #include "wptErrors.h"
38  #include "wptDlgs.h"  #include "wptContext.h"
39  #include "wptKeyserver.h"  #include "wptGPG.h"
40  #include "wptKeyManager.h"  #include "wptKeylist.h"
41  #include "wptKeylist.h"  #include "wptFileManager.h"
42  #include "wptHTTP.h"  #include "wptDlgs.h"
43    #include "wptKeyserver.h"
44    #include "wptKeyManager.h"
45  static void  #include "wptKeylist.h"
46  km_get_clip_info (const char *uid, char *buf, size_t buflen)  #include "wptHTTP.h"
47  {  #include "wptKeyEdit.h"
48      gpgme_key_t pk;  #include "wptImport.h"
49      unsigned long a, algo;  
50    
51      if (get_pubkey (uid, &pk))  /* Return a user friendly key representation in @buf of
52          BUG (0);     the key given by @keyid. */
53        static void
54      a = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_CREATED, NULL, 0);  key_get_clip_info (const char *keyid, char *buf, size_t buflen)
55      algo = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_ALGO, NULL, 0);  {
56      _snprintf (buf, buflen-1,      gpgme_key_t pk;
57                 "pub %04d%s/%s %s %s\r\n"  
58                 "    Primary key fingerprint: %s\r\n",        if (get_pubkey (keyid, &pk))
59          gpgme_key_get_ulong_attr (pk, GPGME_ATTR_LEN, NULL, 0),          BUG (NULL);
60          gpgme_key_expand_attr (GPGME_ATTR_ALGO_SHORT, algo),      _snprintf (buf, buflen-1,
61          gpgme_key_get_string_attr (pk, GPGME_ATTR_KEYID, NULL, 0) + 8,                   "pub %04d%s/%s %s %s\r\n"
62          gpgme_key_expand_attr (GPGME_ATTR_CREATED, a ),                 "    Primary key fingerprint: %s\r\n",
63          gpgme_key_get_string_attr (pk, GPGME_ATTR_USERID, NULL, 0),                 pk->subkeys->length,
64          get_key_fpr (pk));                 get_key_pubalgo (pk->subkeys->pubkey_algo),
65  }                 pk->subkeys->keyid+8,
66                   get_key_created (pk->subkeys->timestamp),
67                   pk->uids->uid,
68  char*                 get_key_fpr (pk));
69  km_quote_uid (const char * uid)  }
70  {      
71      char * q = new char[strlen (uid) + 4];  
72      if (!q)  #if 0
73          BUG (NULL);  /* Quoted the user-id given by @uid. If @uid is already
74      _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);     quoted @uid is returned without any modifications.
75      return q;     Return value: quoted @uid. */
76  } /* km_quote_uid */  char*
77    km_quote_uid (const char *uid)
78    {    
79  int      char *q;
80  km_check_for_seckey (listview_ctrl_t lv, int pos, int * utrust)  
81  {      if (*uid == '"' && uid[strlen (uid)-1] == '"')
82      char t[32], t2[64];          return m_strdup (uid);
83      int type = 0;      q = new char[strlen (uid) + 4];
84            if (!q)
85      listview_get_item_text (lv, pos, 5, t, sizeof (t) - 1);          BUG (NULL);
86      listview_get_item_text (lv, pos, 2, t2, sizeof (t2) - 1);      _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
87      if (!strcmp (t2, "pub/sec"))      return q;
88          type = 1;  }
89      else if (!strcmp (t2, "pub/crd"))  #endif
90          type = 2;  
91      if (stristr (t, "ultimate") && utrust)  
92          *utrust = 1;  /* Check if list view @lv contains a secret key at position @pos.
93      return type;     If utrust is valid, set it to 1 if the key is valid -1 otherwise.
94  } /* km_check_for_seckey */     Return value: 1 normal key, 2 smart card key. */
95    int
96    km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
97  int  {
98  km_check_if_protected( listview_ctrl_t lv, int pos )      char t[32], t2[64];
99  {      int type = 0;
100      gpgme_key_t key;      
101      char keyid[32];          if (utrust)
102                *utrust = 0;
103      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );      listview_get_item_text (lv, pos, 5, t, DIM (t)-1);
104      if( get_pubkey( keyid, &key ) )      listview_get_item_text (lv, pos, 2, t2, DIM (t2)-1);
105          BUG( NULL );          if (!strcmp (t2, "pub/sec"))
106      return gpgme_key_get_ulong_attr( key, GPGME_ATTR_IS_PROTECTED, NULL, 0 );          type = 1;
107  } /* km_check_if_protected */      else if (!strcmp (t2, "pub/crd"))
108            type = 2;
109        if ((strstr (t, "Expired") || strstr (t, "Revoked")) && utrust)
110  int          *utrust = -1;
111  km_check_key_status (listview_ctrl_t lv, int pos)      else if (stristr (t, "Ultimate") && utrust)
112  {          *utrust = 1;
113      char t[128];      return type;
114      int i = 1;  }
115        
116      listview_get_item_text( lv, pos, 5, t, sizeof t - 1 );  
117      if( t[0] == '[' && t[1] == ']' )  /* Check if the key at position @pos is protected with a passwd. */
118          return 1;  int
119      for( i = 0; t[i] != ']'; i++ ) {  km_check_if_protected (listview_ctrl_t lv, int pos)
120          if( t[i] == 'E' )  {
121              msg_box(lv->ctrl, _("This key has expired!\n"      gpgme_key_t key;
122                                  "Key check failed."), _("Key Manager"), MB_ERR );      winpt_key_s k;
123          else if( t[i] == 'R' )  
124              msg_box(lv->ctrl, _("This key has been revoked by its owner!\n"      key = (gpgme_key_t)listview_get_item2 (lv, pos);
125                                  "Key check failed."), _("Key Manager"), MB_ERR );      if (!key)
126      }          return 1; /* assume yes */
127        winpt_get_pubkey (key->subkeys->keyid, &k);
128      return 0;      return k.is_protected;
129  } /* km_check_key_status */  }
130    
131    
132  int  int
133  km_get_key_status( listview_ctrl_t lv, int pos )  km_check_key_status (listview_ctrl_t lv, int pos)
134  {  {
135      char t[128];      int flags = km_get_key_status (lv, pos);
136      int i, flags = 0;      
137        if (flags & KM_FLAG_EXPIRED) {
138      if( pos == -1 )          msg_box (lv->ctrl, _("This key has expired!\n"  
139          return 0;                               "Key check failed."), _("Key Manager"), MB_ERR);
140      listview_get_item_text( lv, pos, 5, t, sizeof t-1 );          return -1;
141      for( i = 0; t[i] != ']'; i++ ) {      }
142          if( t[i] == 'E' )      else if (flags & KM_FLAG_REVOKED) {
143              flags |= KM_FLAG_EXPIRED;          msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
144          if( t[i] == 'R' )                               "Key check failed."), _("Key Manager"), MB_ERR);
145              flags |= KM_FLAG_REVOKED;          return -1;
146          if( t[i] == 'D' )      }
147              flags |= KM_FLAG_DISABLED;  
148      }      return 0;
149      return flags;  } /* km_check_key_status */
150  } /* km_get_key_status */  
151    
152    int
153  int  km_get_key_status (listview_ctrl_t lv, int pos)
154  km_enable_disable_key( listview_ctrl_t lv, HWND dlg, int pos, int enable )  {
155  {      gpgme_key_t key;
156      gpgme_ctx_t ctx;      int flags = 0;
157      gpgme_editkey_t ek;  
158      gpgme_error_t err;      if (pos == -1)
159      int edit_id;          return 0;
160      char keyid[32];      key = (gpgme_key_t)listview_get_item2 (lv, pos);
161        if (key == NULL)
162      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );          return 0;
163      err = gpgme_editkey_new( &ek );  
164      if( err )      if (key->expired)
165          BUG( NULL );          flags |= KM_FLAG_EXPIRED;
166      if( enable ) {      if (key->revoked)
167          gpgme_editkey_enable_set( ek );          flags |= KM_FLAG_REVOKED;
168          edit_id = GPGME_EDITKEY_ENABLE;      if (key->disabled)
169      }          flags |= KM_FLAG_DISABLED;
170      else {      return flags;
171          gpgme_editkey_disable_set( ek );  } /* km_get_key_status */
172          edit_id = GPGME_EDITKEY_DISABLE;  
173      }  
174      err = gpgme_new( &ctx );  /* Interface to enable or disable a key (@enable = 1 then enable).
175      if( err )     The key is retrieved from a list control @lv at the pos @pos. */
176          BUG( NULL );  int
177      gpgme_set_edit_ctx( ctx, ek, edit_id );  km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
178      err = gpgme_op_editkey( ctx, keyid );  {
179      if( !err ) {      GpgKeyEdit *ke;
180          show_msg( dlg, 1500, _("Key status changed.") );      gpgme_error_t err;
181          keycache_set_reload( 1 );      char keyid[32];
182      }  
183      else      listview_get_item_text (lv, pos, 1, keyid, DIM (keyid)-1);
184          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );  
185        ke = new GpgKeyEdit (keyid);
186      gpgme_release( ctx );      if (!ke)
187      gpgme_editkey_release( ek );          BUG (NULL);
188      return err? WPTERR_GENERAL : 0;  
189  } /* km_enable_disable_key */      err = enable? ke->enable () : ke->disable ();
190        if (!err) {
191            show_msg (dlg, 1500, _("Key status changed."));
192  int          keycache_set_reload (1); /* XXX: set update flag */
193  km_clip_export (HWND dlg, listview_ctrl_t lv)      }
194  {      else
195      gpgme_error_t err;          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
196      gpgme_recipients_t rset;      delete ke;
197      int rc, id = 0, n = 0;      return err? WPTERR_GENERAL : 0;
198        }
199      rset = keylist_enum_recipients (lv, KEYLIST_LIST);  
200      n = gpgme_recipients_count (rset);  
201      if (!n) {  
202          msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);  /* Create a string that contain all keyids from
203          rc = WPTERR_GENERAL;     the key list @rset separated by a space. */
204          goto leave;  char*
205      }  gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
206        {
207      err = gpgme_op_clip_export (rset);      char *p;
208      if (err) {      int i;
209          msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);  
210          rc = WPTERR_GENERAL;      if (!n)
211          goto leave;          return NULL;
212      }      p = (char *)calloc (1, n*(16+1)+n+2);
213      if (n == 1) {      if (!p)
214          const char *s;          BUG (NULL);
215          char buf[256];      for (i=0; i < n; i++) {
216          s = gpgme_recipients_get_name (rset, 0);          strcat (p, rset[i]->subkeys->keyid);
217          km_get_clip_info (s, buf, 255);          strcat (p, " ");
218          set_clip_text2 (NULL, buf, strlen (buf), 0);      }
219      }      return p;
220    }
221      show_msg (dlg, 1500, _("GnuPG Status: Finished"));  
222        
223  leave:  /* Export the keys given in @rset to the clipboard.
224      gpgme_recipients_release (rset);     Return value: 0 on success. */
225      return rc;  static gpgme_error_t
226  } /* km_clip_export */  gpg_clip_export (gpgme_key_t *rset, int n)
227    {
228        gpgme_error_t err = 0;
229  int      gpgme_ctx_t ctx = NULL;
230  km_privkey_export( HWND dlg, listview_ctrl_t lv, const char *fname )      gpgme_data_t keydata = NULL;
231  {      char *patt=NULL;
232      gpgme_recipients_t rset;      
233      gpgme_data_t keydata;      err = gpgme_new (&ctx);
234      gpgme_error_t err;      if (err)
235      gpgme_ctx_t ctx;          return err;
236      size_t n = 0;      gpgme_set_armor (ctx, 1);          
237        err = gpgme_data_new (&keydata);
238      rset = keylist_enum_recipients( lv, KEYLIST_LIST );      if (err)
239      n = gpgme_recipients_count( rset );          goto leave;
240      if( !n ) {  
241          msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );      patt = gpg_keylist_to_pattern (rset, n);
242          return WPTERR_GENERAL;      if (!patt) {
243      }          err = gpg_error (GPG_ERR_ENOMEM);
244      if( n > 1 ) {          goto leave;
245          msg_box( dlg, _("Only one secret key can be exported."), _("Key Manager"), MB_ERR );      }
246          return 0; /* we checked this before, so we just quit */  
247      }      err = gpgme_op_export (ctx, patt, 0, keydata);
248      err = gpgme_data_new( &keydata );      if (err)
249      if( err )          goto leave;
250          BUG( dlg );  
251      err = gpgme_new( &ctx );      gpg_data_release_and_set_clipboard (keydata, 1);
252      if( err )  
253          BUG( dlg );  leave:
254      gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );      if (patt)
255      gpgme_control( ctx, GPGME_CTRL_WITH_SECRET_KEY, 1 );          free (patt);
256        gpgme_release (ctx);
257      err = gpgme_op_export( ctx, rset, keydata );      return err;
258      if( err ) {  }
259          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );  
260          goto leave;  
261      }  /* Export the selected keys in @lv to the clipboard. */
262    int
263      log_box( _("Key Manager"), MB_OK,  km_clip_export (HWND dlg, listview_ctrl_t lv)
264               _("Secret key successfully saved in '%s'."), fname );  {
265            gpgme_error_t err;
266  leave:      gpgme_key_t *rset;
267      err = gpgme_data_release_and_set_file( keydata, fname );      char buf[256];
268      if( err )      int n=0;
269          log_box( _("Key Manager"), MB_OK,      int rc=0;
270                   _("Could not save data to '%s'."), fname );      
271      gpgme_release( ctx );      rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
272        if (!n) {
273      return (int)err;          msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
274  } /* km_privkey_export */          rc = WPTERR_GENERAL;
275            goto leave;
276        }
277  int      
278  km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)      err = gpg_clip_export (rset, n);
279  {      if (err) {
280      gpgme_recipients_t rset;          msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
281      gpgme_data_t keydata;                rc = WPTERR_GENERAL;
282      gpgme_error_t err;          goto leave;
283      gpgme_ctx_t ctx;      }
284        if (n == 1) {
285      rset = keylist_enum_recipients( lv, KEYLIST_LIST );          key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
286      if( !gpgme_recipients_count( rset ) ) {          set_clip_text2 (NULL, buf, strlen (buf), 0);
287          msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );      }
288          return WPTERR_GENERAL;  
289      }      show_msg (dlg, 1500, _("GnuPG Status: Finished"));
290            
291      err = gpgme_data_new( &keydata );  leave:
292      if( err )      free (rset);
293          BUG( dlg );      return rc;
294      err = gpgme_new( &ctx );  } /* km_clip_export */
295      if( err )  
296          BUG( dlg );  
297      gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );  /* Export the selected secret key from @lv into @fname.
298      gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);     It is only allowed to export a single secret key. */
299        int
300      err = gpgme_op_export( ctx, rset, keydata );  km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
301      if( err ) {  {
302          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );      gpgme_key_t *rset;
303          goto leave;      gpgme_error_t err;
304      }      int n = 0;
305            
306      log_box( _("Key Manager"), MB_OK,      rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
307               _("Key(s) successfully saved in '%s'."), fname );      if (!n) {
308                msg_box (dlg, _("No key was selected for export."),
309  leave:                   _("Key Manager"), MB_ERR);
310      err = gpgme_data_release_and_set_file( keydata, fname );          return WPTERR_GENERAL;
311      if( err )      }
312          log_box( _("Key Manager"), MB_OK,      if (n > 1) {
313                   _("Could not save data to '%s'."), fname );              msg_box (dlg, _("Only one secret key can be exported."),
314      gpgme_release( ctx );                   _("Key Manager"), MB_ERR);
315            free (rset);
316      return (int)err;          return 0; /* we checked this before, so we just quit */
317  } /* km_file_export */      }
318    
319        err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
320  static int      if (err)
321  extract_dash_escaped_key( void )          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
322  {      else
323      gpgme_data_t inp, plain;          log_box (_("Key Manager"), MB_OK,
324      gpgme_error_t err;                   _("Secret key successfully saved in '%s'."), fname);
325    
326      err = gpgme_data_new_from_clipboard (&inp);      free (rset);
327      if( err ) {      return err? WPTERR_GENERAL : 0;
328          msg_box( NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR );  }
329          return -1;  
330      }  
331      gpgme_data_extract_plaintext( inp, &plain );  int
332      gpgme_data_release( inp );  km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
333      gpgme_data_release_and_set_clipboard( plain );  {
334        gpgme_key_t *rset;
335      return 0;      gpgme_data_t keydata;      
336  } /* extract_dash_escaped_key */      gpgme_error_t err;
337        gpgme_ctx_t ctx;
338        char *patt;
339  int      int n;
340  km_clip_import( HWND dlg )  
341  {      rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
342      gpgme_error_t err;      if (!n) {
343      gpgme_cliptype_t pgptype;          msg_box (dlg, _("No key was selected for export."),
344      int id;                   _("Key Manager"), MB_ERR);
345      int has_data = 0;          return WPTERR_GENERAL;
346            }
347      if( !gpgme_clip_istext_avail( &has_data ) && !has_data ) {      
348          msg_box( dlg, winpt_strerror( WPTERR_CLIP_ISEMPTY ), _("Key Manager"), MB_ERR );      err = gpgme_data_new (&keydata);
349          return WPTERR_CLIP_ISEMPTY;      if (err)
350      }          BUG (NULL);
351      err = gpgme_clip_is_secured( &pgptype, &has_data );      err = gpgme_new (&ctx);
352      if( err )      if (err)
353          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );          BUG (NULL);
354      if( !has_data ) {      gpgme_set_armor (ctx, 1);
355          msg_box( dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR );  
356          return WPTERR_GENERAL;      /*gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);*/
357      }      patt = gpg_keylist_to_pattern (rset, n);
358      if( !(pgptype & GPGME_CLIP_PUBKEY) && !(pgptype & GPGME_CLIP_SECKEY) ) {      
359          msg_box( dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR );      err = gpgme_op_export( ctx, patt, 0, keydata);
360          return WPTERR_GENERAL;      if( err ) {
361      }          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
362      if( pgptype & GPGME_CLIP_DASH_ESCAPED ) {          goto leave;
363          id = msg_box( dlg, _("The key you want to import is dash escacped.\n"      }
364                               "Do you want to extract the key?"),          
365                        _("Key Manager"), MB_YESNO );      log_box( _("Key Manager"), MB_OK,
366          if( id == IDYES )               _("Key(s) successfully saved in '%s'."), fname );
367              extract_dash_escaped_key( );      
368          else  leave:
369              msg_box( dlg, _("Cannot import dash escaped OpenPGP keys."), _("Key Manager"), MB_INFO );      err = gpg_data_release_and_set_file( keydata, fname );
370      }      if (err)
371            log_box (_("Key Manager"), MB_OK,
372      dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,                   _("Could not save data to '%s'."), fname);
373                        clip_import_dlg_proc, NULL,      gpgme_release (ctx);
374                        _("Key Import"), IDS_WINPT_IMPORT );      free (patt);
375        return (int)err;
376      return 0;  } /* km_file_export */
377  } /* km_clip_import */  
378    
379    static int
380  int  extract_dash_escaped_key (void)
381  km_http_import (HWND dlg, const char * url)  {
382  {      gpgme_data_t inp, plain;
383      FILE * fp;      gpgme_error_t err;
384      char * p;  
385      char tmpdir[500];      err = gpg_data_new_from_clipboard (&inp, 0);
386      http_hd_t hd;      if (err) {
387      int statcode;          msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
388      int rc = 0;          return -1;
389        }
390      if (strncmp (url, "http://", 7)) {      gpg_data_extract_plaintext (inp, &plain);
391          log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);      gpg_data_release_and_set_clipboard (plain, 0);
392          return WPTERR_GENERAL;      gpgme_data_release (inp);
393      }  
394        return 0;
395      GetTempPath (499, tmpdir);  } /* extract_dash_escaped_key */
396      p = make_filename (tmpdir, "file_http", "tmp");  
397      if (!p)  
398          BUG (0);  /* Import keys from the clipboard. */
399      fp = fopen (p, "wb");  int
400      if (fp == NULL) {  km_clip_import (HWND dlg)
401          free_if_alloc (p);  {
402          log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));      gpgme_error_t err;
403          return WPTERR_FILE_CREAT;      int pgptype;
404      }      int id;
405      /* parse URL */      int has_data = 0;
406      rc = http_send_request2 (url, &hd);      
407      if (!rc)      if (!gpg_clip_istext_avail (&has_data) && !has_data) {
408          rc = http_parse_response (hd, &statcode);          msg_box( dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), _("Key Manager"), MB_ERR);
409      if (!rc)          return WPTERR_CLIP_ISEMPTY;
410          rc = http_parse_data (hd, fp);      }
411      http_hd_free (hd);      err = gpg_clip_is_secured (&pgptype, &has_data);
412      fclose (fp);      if (err)
413      if (rc) {          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
414          free_if_alloc (p);      if (!has_data) {
415          msg_box (dlg, http_strerror (rc), _("Key Import HTTP"), MB_ERR);          msg_box (dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR);
416          return WPTERR_GENERAL;          return WPTERR_GENERAL;
417      }      }
418      km_file_import (dlg, p);      if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
419      free_if_alloc (p);          msg_box (dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR);
420      return 0;          return WPTERR_GENERAL;
421  }      }
422        if (pgptype & PGP_DASH_ESCAPED) {
423  int          id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
424  km_file_import( HWND dlg, const char * fname )                               "Do you want to extract the key?"),
425  {                        _("Key Manager"), MB_YESNO);
426      gpgme_data_t keydata = NULL;          if (id == IDYES)
427      gpgme_ctx_t ctx;              extract_dash_escaped_key ();
428      gpgme_error_t err;          else
429      fm_state_s fm_stat;              msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
430      int import_res[14];                       _("Key Manager"), MB_INFO);
431            }
432      memset( &fm_stat, 0, sizeof fm_stat );  
433      fm_stat.opaque = m_strdup( fname );      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
434                              clip_import_dlg_proc, NULL,
435      dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,                        _("Key Import"), IDS_WINPT_IMPORT);
436                        file_import_dlg_proc, (LPARAM)&fm_stat,  
437                        _("File Import"), IDS_WINPT_IMPORT );      return 0;
438      if( fm_stat.cancel == 1 )  }
439          return WPTERR_GENERAL;  
440        
441      err = gpgme_new( &ctx );  /* Import a key from the http URL @url. */
442      if( err )  int
443          BUG( dlg );  km_http_import (HWND dlg, const char *url)
444      gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );  {
445      err = gpgme_data_new_from_file (&keydata, fname);      http_hd_t hd;
446      if( err ) {      FILE *fp;
447          msg_box( dlg, _("Could not read key-data from file."), _("Key Manager"), MB_ERR );      char *p;
448          goto leave;      char tmpfile[500];
449      }      int statcode;
450            int rc = 0;
451      err = gpgme_op_import( ctx, NULL, keydata );  
452      if( err ) {      if (strncmp (url, "http://", 7)) {
453          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );          log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
454          goto leave;          return WPTERR_GENERAL;
455      }      }
456        
457      gpgme_get_import_status( ctx, import_res, NULL );      GetTempPath (sizeof (tmpfile)-128, tmpfile);
458      print_import_status( import_res, fm_stat.implist_revcert );      p = make_filename (tmpfile, "winpt_file_http", "tmp");
459      if( import_res[GPGME_IMPSTAT_NOSELFSIG] > 0  ) {      if (!p)
460          msg_box( dlg, _("Key without a self signature was dectected!\n"          BUG (0);
461                          "(This key is NOT usable for encryption, etc)\n"      fp = fopen (p, "wb");
462                          "\n"          if (!fp) {
463                          "Cannot import these key(s)!"), _("Import"), MB_INFO );          free_if_alloc (p);
464      }          log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
465                return WPTERR_FILE_CREAT;
466  leave:              }
467      gpgme_data_release( keydata );  
468      gpgme_release( ctx );      /* parse URL */
469      free_if_alloc( fm_stat.opaque );      rc = http_send_request2 (url, &hd);
470      return (int)err;      if (!rc)
471  } /* km_file_import */          rc = http_parse_response (hd, &statcode);
472        if (!rc)
473            rc = http_parse_data (hd, fp);
474  static void      http_hd_free (hd);
475  delete_keys_from_cache (gpgme_recipients_t rset)      fclose (fp);
476  {      if (rc) {  
477      gpgme_keycache_t pub = keycache_get_ctx (1);          msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
478      void * ctx =NULL;          rc = WPTERR_GENERAL;
479      const char * s;      }
480        km_file_import (dlg, p);
481      gpgme_recipients_enum_open (rset, &ctx);      unlink (p);
482      while ((s = gpgme_recipients_enum_read (rset, &ctx)))      free_if_alloc (p);
483          gpgme_keycache_delete_key (pub, s);      return rc;
484      gpgme_recipients_enum_close (rset, &ctx);  }
485  } /* delete_keys_from_cache */  
486    
487    /* Import a key from the given file @fname.
488  int     On success an import statistics dialog is shown. */
489  km_delete_keys (listview_ctrl_t lv, HWND dlg)  int
490  {  km_file_import (HWND dlg, const char *fname)
491      gpgme_error_t err;  {
492      gpgme_recipients_t rset;      gpgme_data_t keydata = NULL;
493      char keyid[32], uid[256], date[64], keylen[64];          gpgme_ctx_t ctx;
494      int with_seckey, seckey_type=0;      gpgme_error_t err;    
495      int i, rc;      fm_state_s fm_stat;
496            gpgme_import_result_t res;
497      if( listview_get_curr_pos( lv ) == -1 ) {      
498          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );      memset (&fm_stat, 0, sizeof (fm_stat));
499          return WPTERR_GENERAL;      fm_stat.opaque = m_strdup (fname);
500      }      
501            dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
502      err = gpgme_recipients_new (&rset);                        file_import_dlg_proc, (LPARAM)&fm_stat,
503      if (err)                        _("File Import"), IDS_WINPT_IMPORT);
504          BUG (0);      if (fm_stat.cancel == 1) {
505                free_if_alloc (fm_stat.opaque);
506      for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {          return WPTERR_GENERAL;
507          if( listview_get_item_state( lv, i ) ) {      }
508              listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );      
509              listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );      err = gpgme_new (&ctx);
510              listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );      if (err)
511              listview_get_item_text( lv, i, 7, date, sizeof date - 1 );          BUG (NULL);
512              seckey_type = km_check_for_seckey( lv, i, NULL );      err = gpgme_data_new_from_file (&keydata, fname, 1);
513              if( !seckey_type ) {      if (err) {
514                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,          msg_box (dlg, _("Could not read key-data from file."),
515                                _("Do you really want to delete this key?\n\n"                   _("Key Manager"), MB_ERR);
516                                  "pub %s %s %s\n"          goto leave;
517                                  "  \"%s\""), keylen, keyid, date, uid );      }
518                  if( rc == IDYES )      
519                      gpgme_recipients_add_name( rset, keyid );      SetCursor (LoadCursor (NULL, IDC_WAIT));
520                  with_seckey = 0;      err = gpgme_op_import (ctx, keydata);
521              }      SetCursor (LoadCursor (NULL, IDC_ARROW));
522              else {      if (err) {
523                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,                          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
524                                _("Do you really want to delete this KEY PAIR?\n\n"          goto leave;
525                                  "Please remember that you are not able to decrypt\n"      }    
526                                  "messages you stored with this key any longer.\n"  
527                                  "\n"      res = gpgme_op_import_result (ctx);
528                                  "pub/sec %s %s %s\n"      if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
529                                  "  \"%s\""), keylen, keyid, date, uid );          res->new_revocations = 1;
530                  if( rc == IDYES ) {      if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
531                      if( seckey_type == 2 )          res->secret_imported = 1;
532                          msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"  
533                                          "Only the public key and the secret key \n"      print_import_status (res);
534                                          "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );      if (res->no_user_id > 0) {
535                      gpgme_recipients_add_name( rset, keyid );          msg_box (dlg, _("Key without a self signature was dectected!\n"
536                  }                          "(This key is NOT usable for encryption, etc)\n"
537                  with_seckey = 1;                          "\n"    
538              }                          "Cannot import these key(s)!"), _("Import"), MB_INFO);
539          }      }
540      }  
541        leave:
542      if (!gpgme_recipients_count (rset)) {      gpgme_data_release (keydata);
543          gpgme_recipients_release (rset);      gpgme_release (ctx);
544          return 0;      free_if_alloc (fm_stat.opaque);
545      }      return (int)err;
546        }
547      err = gpgme_op_delete_keys (rset, with_seckey);  
548      if (err) {  
549          if (err == GPGME_Invalid_Key)  /* Mark the keys in @rset as deleted in the keycache. */
550              msg_box (dlg, _("No such key."), _("Key Manager"), MB_INFO);  static void
551          else if (err == GPGME_Conflict)  delete_keys_from_cache (gpgme_key_t *rset, size_t n)
552              msg_box (dlg, _("Must delete secret key first."), _("Key Manager"), MB_INFO);  {
553          else      gpg_keycache_t pub = keycache_get_ctx (1);
554              msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);      int i=0;
555          return FALSE;  
556      }      while (n-- > 0)
557      show_msg (dlg, 1500, _("GnuPG Status: Finished"));          gpg_keycache_delete_key (pub, rset[i++]->subkeys->keyid);
558      listview_del_items (lv);  }
559      if (keyring_check_last_access ())  
560          keycache_set_reload (1);  
561      delete_keys_from_cache (rset);  /* Delete all selected keys from the list view @lv. */
562      gpgme_recipients_release (rset);  int
563    km_delete_keys (listview_ctrl_t lv, HWND dlg)
564      return (int)err;  {
565  } /* km_delete_keys */      gpgme_error_t err;
566        gpgme_ctx_t ctx;
567        gpgme_key_t *rset, k;
568  int      char keyid[32], uid[256], date[64], keylen[64];    
569  km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)      int with_seckey=0, seckey_type=0, confirm=0;
570  {      int i, rc, n, k_pos=0;
571      char keyid[32];      
572      const char *t;      if (listview_get_curr_pos (lv) == -1) {
573      int id;          msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
574                return WPTERR_GENERAL;
575      id = listview_get_curr_pos( lv );      }
576      if( id == -1 ) {          
577          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );      if (listview_count_items (lv, 1) > 8) {
578          return WPTERR_GENERAL;          i = msg_box (NULL, _("Do you really want to confirm each key?"),
579      }                       _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
580            if (i == IDCANCEL)
581      listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );              return 0;
582      id = log_box (_("Key Manager"), MB_YESNO,          if (i != IDNO)
583                    _("Do you really want to send '%s' to keyserver %s?"),              confirm = 1;
584                      keyid, host);      }
585      if (id == IDYES) {      else
586          t = keyid;          confirm = 1;
587          if (!strncmp (keyid, "0x", 2))  
588              t += 2;      n = listview_count_items (lv, 0);
589          hkp_send_key (dlg, host, port, t);      rset = (gpgme_key_t *)calloc (n+1, sizeof (gpgme_key_t));
590      }      if (!rset)
591            BUG (NULL);
592      return 0;      for( i = 0; i < n; i++ ) {
593  } /* km_send_to_keyserver */          if( listview_get_item_state( lv, i ) ) {
594                listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
595                listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
596  int              listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
597  km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )              listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
598  {              seckey_type = km_check_for_seckey (lv, i, NULL);
599      gpgme_key_t key;              if (confirm && !seckey_type) {
600      gpgme_ctx_t ctx=NULL;                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
601      gpgme_recipients_t rset=NULL;                                _("Do you really want to delete this key?\n\n"
602      gpgme_error_t rc;                                  "pub %s %s %s\n"
603      const char * s;                                  "  \"%s\""), keylen, keyid, date, uid );
604      char keyid[32], tmp[192+256], * p =NULL;                  if (rc == IDYES) {
605      int pos;                      get_pubkey (keyid, &k);
606                        rset[k_pos++] = k;
607      if( listview_count_items( lv, 1 ) > 1 ) {                  }
608          msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );                  with_seckey = 0;
609          return WPTERR_GENERAL;              }
610      }              else if (confirm) {
611      pos = listview_get_curr_pos( lv );                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,                
612      if( pos == -1 ) {                                _("Do you really want to delete this KEY PAIR?\n\n"
613          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );                                  "Please remember that you are not able to decrypt\n"
614          return WPTERR_GENERAL;                                  "messages you stored with this key any longer.\n"
615      }                                  "\n"
616      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );                                  "pub/sec %s %s %s\n"
617      if( get_pubkey( keyid, &key ) )                                  "  \"%s\""), keylen, keyid, date, uid );
618          BUG( NULL );                  if( rc == IDYES ) {
619      s = gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, 0 );                      if (seckey_type == 2)
620      GetTempPath (sizeof tmp-1, tmp);                          msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
621      strncat (tmp, s, sizeof tmp-200);                                          "Only the public key and the secret key \n"
622      strncat (tmp, ".asc", sizeof tmp-200);                                          "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
623      p = fm_quote_file (tmp);                      get_pubkey (keyid, &k);
624                        rset[k_pos++] = k;
625      rc = gpgme_recipients_new( &rset );                  }
626      if( !rc )                  with_seckey = 1;
627          rc = gpgme_recipients_add_name( rset, keyid );              }
628      if( !rc )              else {
629          rc = gpgme_new( &ctx );                  with_seckey = 1;
630      if( !rc ) {                  get_pubkey (keyid, &k);
631          gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );                  rset[k_pos++] = k;
632          rc = gpgme_op_file_export( ctx, rset, p );              }
633      }          }
634      if( rc )      }
635          msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );      
636      else      if (k_pos == 0) {
637          mapi_send_pubkey (keyid, tmp);          free (rset);
638      free_if_alloc( p );          return 0;
639      gpgme_recipients_release( rset );      }
640      gpgme_release( ctx );      
641      return rc;      err = gpgme_new (&ctx);
642  }      if (err)
643            BUG (NULL);
644        n=k_pos;
645  static void      for (i=0; i < k_pos; i++) {
646  km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)          err = gpgme_op_delete (ctx, rset[i], with_seckey);
647  {          if (err)
648      int idx;              msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
649      char keyid[32];          else
650      const char *t;              n--;
651        }
652      if (pos != 0)      if (n == 0)
653          idx = pos;          show_msg (dlg, 1500, _("GnuPG Status: Finished"));
654      else      gpgme_release (ctx);
655          idx = listview_get_curr_pos (lv);      listview_del_items (lv);
656      if (idx != -1)      delete_keys_from_cache (rset, k_pos);
657      {      free (rset);
658          listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);  
659          t = keyid;      return (int)err;
660          if (!strncmp (keyid, "0x", 2))  }
661              t += 2;  
662          hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);  
663      }  int
664  }  km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
665    {
666        char keyid[32];
667  void      const char *t;
668  km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)      int id;
669  {      
670      int idx, id, i;      id = listview_get_curr_pos( lv );
671            if( id == -1 ) {
672      if (kserver_check_inet_connection ())          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
673      {          return WPTERR_GENERAL;
674          msg_box (dlg, _("Could not connect to keyserver, abort procedure."),      }
675                   _("Key Manager"), MB_ERR);  
676          return;      listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
677      }      id = log_box (_("Key Manager"), MB_YESNO,
678      idx = listview_count_items (lv, 0);                    _("Do you really want to send '%s' to keyserver %s?"),
679      if (listview_count_items (lv, 1) == idx) {                      keyid, host);
680          id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);      if (id == IDYES) {
681          if (id == IDNO)          t = keyid;
682              return;          if (!strncmp (keyid, "0x", 2))
683          for (i = 0; i < idx; i++)              t += 2;
684              km_refresh_one_key (lv, dlg, i);          hkp_send_key (dlg, host, port, t);
685      }      }
686      else if (idx == 1)  
687          km_refresh_one_key (lv, dlg, 0);      return 0;
688      else {  } /* km_send_to_keyserver */
689          for (i=0; i < listview_count_items (lv, 0); i++) {  
690              if (listview_get_item_state (lv, i))  
691                  km_refresh_one_key (lv, dlg, i);  int
692          }  km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
693      }  {
694  } /* km_refresh_from_keyserver */  #if 0 /*FIXME*/
695        gpgme_key_t key;
696        gpgme_ctx_t ctx=NULL;
697  void      gpgme_recipients_t rset=NULL;
698  km_set_clip_info( const char *uid )      gpgme_error_t rc;
699  {          const char * s;
700      char buf[256];      char keyid[32], tmp[192+256], * p =NULL;
701            int pos;
702      km_get_clip_info (uid, buf, 255);      
703      set_clip_text( NULL, buf, strlen( buf ) );      if( listview_count_items( lv, 1 ) > 1 ) {
704  } /* km_set_clip_info */          msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
705            return WPTERR_GENERAL;
706        }
707        pos = listview_get_curr_pos( lv );
708  int      if( pos == -1 ) {
709  km_key_is_v3( listview_ctrl_t lv, int pos )          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
710  {          return WPTERR_GENERAL;
711      gpgme_key_t pk;      }
712      const char * fpr;      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
713      unsigned long algo;      if( get_pubkey( keyid, &key ) )
714      char keyid[32];          BUG( NULL );
715        s = key->uids->name;
716      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );      GetTempPath (sizeof tmp-1, tmp);
717      if( get_pubkey( keyid, &pk ) )      strncat (tmp, s, sizeof tmp-200);
718          BUG( NULL );      strncat (tmp, ".asc", sizeof tmp-200);
719      algo = gpgme_key_get_ulong_attr( pk, GPGME_ATTR_ALGO, NULL, 0 );      p = fm_quote_file (tmp);
720      fpr = gpgme_key_get_string_attr( pk, GPGME_ATTR_FPR, NULL, 0 );  
721      return strlen( fpr ) == 32 && algo == GPGME_PK_RSA? 1 : 0;      rc = gpgme_recipients_new (&rset);
722  } /* km_key_is_v3 */      if (!rc)
723            rc = gpgme_recipients_add_name (rset, keyid);
724        if (!rc)
725  void          rc = gpgme_new (&ctx);
726  km_update_default_key_str (HWND dlg, int * ret_len)      if (!rc) {
727  {          gpgme_set_armor (ctx, 1);
728      char * keyid, defkeyinf[512];          rc = gpgme_op_file_export (ctx, rset, p);
729      const char * fmt;      }
730            if (rc)
731      keyid = get_gnupg_default_key ();          msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
732      if (!keyid)      else
733          BUG (0);          mapi_send_pubkey (keyid, tmp);
734      if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')  
735          || (keyid[0] == '0' && keyid[1] == 'x') )      free_if_alloc (p);
736          fmt = _("Default Key: %s");      gpgme_recipients_release (rset);
737      else      gpgme_release (ctx);
738          fmt = _("Default Key: 0x%s");      return rc;
739      _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );  #endif
740      SetWindowText( dlg, defkeyinf );      return 0;
741      *ret_len = strlen( defkeyinf );  }
742      free_if_alloc( keyid );  
743  } /* km_return_default_key_str */  
744    static void
745    km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
746  void  {
747  km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )      int idx;
748  {      char keyid[32];
749      char text[384];      const char *t;
750      int nkeys = 0, nsec = 0, i;  
751        if (pos != 0)
752      GetWindowText( sb, text, sizeof text -1 );          idx = pos;
753      nkeys = listview_count_items( lv, 0 );      else
754      for( i = 0; i < nkeys; i++ ) {          idx = listview_get_curr_pos (lv);
755          if( km_check_for_seckey( lv, i, NULL ) )      if (idx != -1)
756              nsec++;      {
757      }          listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
758      _snprintf( text+startpos, sizeof text-1, "                %d keys (%d secret keys)", nkeys, nsec );          t = keyid;
759      SetWindowText( sb, text );          if (!strncmp (keyid, "0x", 2))
760  } /* km_complete_status_bar */              t += 2;
761            hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
762        }
763  void  }
764  km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)  
765  {  
766      gpgme_error_t err;  void
767      gpgme_ctx_t ctx;  km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
768      gpgme_editkey_t ek;  {
769      char keyid[32];      int idx, id, i;
770        
771      listview_get_item_text (lv, pos, 1, keyid, 31);      if (kserver_check_inet_connection ())
772      err = gpgme_new (&ctx);      {
773      if (err)          msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
774          BUG (0);                   _("Key Manager"), MB_ERR);
775      err = gpgme_editkey_new (&ek);          return;
776      if (err)      }
777          BUG (0);      idx = listview_count_items (lv, 0);
778      gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);      if (listview_count_items (lv, 1) == idx) {
779      gpgme_editkey_trust_set (ek, 5);          id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
780            if (id == IDNO)
781      err = gpgme_op_editkey (ctx, keyid);              return;
782      if (err)          for (i = 0; i < idx; i++)
783          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);              km_refresh_one_key (lv, dlg, i);
784      else {      }
785          show_msg (dlg, 1500, _("GnuPG Status: Finished"));      else if (idx == 1)
786          keycache_set_reload (1);          km_refresh_one_key (lv, dlg, 0);
787      }      else {
788            for (i=0; i < listview_count_items (lv, 0); i++) {
789      gpgme_release (ctx);              if (listview_get_item_state (lv, i))
790      gpgme_editkey_release (ek);                      km_refresh_one_key (lv, dlg, i);
791  }          }
792        }
793    } /* km_refresh_from_keyserver */
794  gpg_optfile_t  
795  km_groupdb_open( void )  
796  {        void
797      gpg_optfile_t opt;  km_set_clip_info (const char *uid)
798      char * optfile;  {    
799      int err = 0;      char buf[256];
800            
801      optfile = get_gnupg_cfgfile();      key_get_clip_info (uid, buf, 255);    
802      if( !optfile )      set_clip_text (NULL, buf, strlen (buf));
803          BUG( NULL );  } /* km_set_clip_info */
804      if( parse_gpg_options( optfile, &opt ) )  
805          err = 1;  
806      free_if_alloc( optfile );  
807      return err? NULL : opt;  /* Return TRUE if the key in the list @lv at pos @pos is an
808  } /* km_groupdb_open */     old version 3 key. */
809    int
810    km_key_is_v3 (listview_ctrl_t lv, int pos)
811  int  {
812  km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )      gpgme_key_t pk;
813  {        char keyid[32];
814      gpgme_keycache_t kc;  
815      gpgme_key_t pk;      listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
816      gpg_optfile_t opt;      if (get_pubkey (keyid, &pk))
817      gpg_group_t grp;              BUG (NULL);
818      gpg_member_t mbr;      if (strlen (pk->subkeys->fpr) == 32 &&
819      int no_trust = 0, n;          pk->subkeys->pubkey_algo == GPGME_PK_RSA)
820            return -1;
821      kc = keycache_get_ctx( 1 );      return 0;
822      if( !kc )  }
823          BUG( NULL );  
824    
825      opt = km_groupdb_open( );  /* Update the default key entry in the status bar for dialog @dlg. */
826      if( !opt )  void
827          return WPTERR_FILE_OPEN;  km_update_default_key_str (HWND dlg)
828        {
829      grp = find_group( opt, name );      char *keyid, defkeyinf[512];
830      if( !grp )      const char *fmt;
831          return WPTERR_GENERAL;      
832            /* XXX: also show the name? */
833      /* we are paranoid and check that all group members exist in the      keyid = get_gnupg_default_key ();
834         key cache. there is no need that it is really the real key, but      if (!keyid)
835         an entry should be available. the rest is up to GPG. */          BUG (0);
836      for( mbr = grp->list; mbr; mbr = mbr->next ) {      if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
837          if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )          || (keyid[0] == '0' && keyid[1] == 'x') )
838              BUG( NULL );          fmt = _("Default Key: %s");
839          n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );      else
840          while( n-- ) {          fmt = _("Default Key: 0x%s");
841              const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );      _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
842              if( s && stristr( s, mbr->name )      SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
843                  && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )      free_if_alloc (keyid);
844                  no_trust++;  }
845          }  
846      }  
847    /* Count all keys and show from @lv results in the status bar @sb. */
848      gpgme_recipients_add_name( rset, name );  void
849      release_gpg_options( opt );  km_complete_status_bar (HWND sb, listview_ctrl_t lv)
850        {
851      return no_trust;      char txt_sec[128], txt_pub[128];
852  } /* km_groupdb_expand_recipients */      int nkeys = 0, nsec = 0, i;
853    
854        nkeys = listview_count_items (lv, 0);
855  static HTREEITEM      for (i = 0; i < nkeys; i++) {
856  km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )          if (km_check_for_seckey (lv, i, NULL))
857  {              nsec++;
858      TVINSERTSTRUCT tvis;      }
859      HTREEITEM node;      _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
860            _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
861      memset( &tvis, 0, sizeof tvis );      SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
862      tvis.hParent = parent;      SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
863      tvis.hInsertAfter = TVI_LAST;  }
864      tvis.item.mask = TVIF_TEXT;  
865      tvis.item.pszText = (char *)text;  
866      node = TreeView_InsertItem( tree, &tvis );  /* Set trust of selected key in @lv (at @pos) to ultimate. */
867      return node;  int
868  } /* km_tv_insert_item */  km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
869    {
870        GpgKeyEdit *ke;
871  int      gpgme_error_t err;    
872  km_groups_new( km_group_t *r_gc, HWND ctrl )      char keyid[32];
873  {  
874      km_group_t gc;      listview_get_item_text (lv, pos, 1, keyid, 31);
875        
876      gc = new km_group_s;      ke = new GpgKeyEdit (keyid);
877      if (!gc)      if (!ke)
878          BUG (NULL);          BUG (0);
879      gc->tree = ctrl;  
880      gc->gh = km_groupdb_open ();      err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
881      *r_gc = gc;      if (err)
882      return 0;          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
883  } /* km_groups_new */      else
884            show_msg (dlg, 1500, _("GnuPG Status: Finished"));
885    
886  void      delete ke;
887  km_groups_sync( km_group_t gc )      return (int)err;
888  {  }
889      char * optfile;  
890    
891      optfile = get_gnupg_cfgfile ();  void
892      if( !optfile )  km_find_key (HWND dlg, listview_ctrl_t lv)
893          BUG( NULL );  {
894      commit_gpg_options( optfile, gc->gh );      int oldpos = listview_get_curr_pos (lv);
895      free_if_alloc( optfile );      int n;
896      gc->need_sync = 0;      char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
897  } /* km_groups_sync */      if (name == NULL)
898            return;
899        if (oldpos < 0)
900  void          oldpos = 0;
901  km_groups_release (km_group_t gc)      n = listview_find (lv, name);
902  {      if (n != -1) {
903      if( gc ) {          listview_select_one (lv, n);
904          /* xxx: this reset the default key (sync=1) */          listview_scroll (lv, oldpos, n);
905          gc->need_sync=0;      }
906          if (gc->need_sync)      else {
907              km_groups_sync (gc);          const char *s = _("String pattern \"%s\" not found.");
908          if (gc->gh)          char *p = new char[strlen (s) + strlen (name) + 2];
909              release_gpg_options( gc->gh );          if (!p)
910          gc->gh = NULL;              BUG (0);
911          gc->tree = NULL;          sprintf (p, s, name);
912          delete gc;          msg_box (dlg, p, _("Key Manager"), MB_INFO);
913      }              free_if_alloc (p);
914  } /* km_groups_release */      }
915        free_if_alloc (name);
916    }
917  int  
918  km_groups_load( km_group_t gc )  
919  {      
920      HTREEITEM n;  void
921      gpg_group_t grp, g;  km_dump_key (gpgme_key_t key)
922      gpg_member_t mbr;  {
923      u32 gid = 0;  #if _DEBUG
924            log_box ("DEBUG", MB_OK,
925      if( !gc->gh )               "%d %d %s %d\n%s", key->subkeys->length,
926          return 0;               key->subkeys->pubkey_algo,
927      grp = gc->gh->grp;               key->subkeys->keyid,
928      if( !grp )               key->subkeys->timestamp,
929          return 0; /* no groups */               key->uids->uid);
930            #endif
931      for( g = grp; g; g = g->next ) {  }
932          n = km_tv_insert_item( gc->tree, NULL, g->name );  
933          for( mbr = g->list; mbr; mbr = mbr->next ) {  #if 0
934              if( mbr->used && mbr->name )  gpg_optfile_t
935                  km_tv_insert_item( gc->tree, n, mbr->name );  km_groupdb_open (void)
936          }  {      
937      }      gpg_optfile_t opt;
938      DragAcceptFiles( gc->tree, TRUE );      char * optfile;
939      gc->need_sync = 0;      int err = 0;
940      return 0;      
941  } /* km_groups_load */      optfile = get_gnupg_cfgfile();
942        if( !optfile )
943            BUG( NULL );
944  int      if( parse_gpg_options( optfile, &opt ) )
945  km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )          err = 1;
946  {      free_if_alloc( optfile );
947      TVITEM tvi;      return err? NULL : opt;
948      char uid[128], valid[64], text[128];  } /* km_groupdb_open */
949      int i_valid;  
950        
951      memset( &tvi, 0, sizeof tvi );  int
952      tvi.hItem = TreeView_GetSelection( gc->tree );  km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
953      tvi.pszText = text;  {  
954      tvi.cchTextMax = sizeof text -1;      gpg_keycache_t kc;
955      tvi.mask = TVIF_TEXT;      gpgme_key_t pk;
956      TreeView_GetItem( gc->tree, &tvi );      gpg_optfile_t opt;
957            gpg_group_t grp;    
958            gpg_member_t mbr;
959      listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );      int no_trust = 0, n;
960      listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );  
961            kc = keycache_get_ctx( 1 );
962      if( strstr( valid, "Ultimate" ) )      if( !kc )
963          i_valid = 5;              BUG( NULL );
964      else if( !strstr( valid, "Full" ) )  
965          i_valid = 4;      opt = km_groupdb_open( );
966      else if( !strstr( valid, "Marginal" ) )      if( !opt )
967          i_valid = 3;          return WPTERR_FILE_OPEN;
968      else      
969          i_valid = 0;      grp = find_group( opt, name );
970            if( !grp )
971      /* we can't add the full name. one way would be to use the first          return WPTERR_GENERAL;
972         text until a space appears.      
973      group_add_entry(&gc->gh, gid, i_valid, uid);      /* we are paranoid and check that all group members exist in the
974      treeview_add_item(gc->tree, tvi.hItem, uid);         key cache. there is no need that it is really the real key, but
975      */         an entry should be available. the rest is up to GPG. */
976      gc->need_sync = 1;      for( mbr = grp->list; mbr; mbr = mbr->next ) {
977                if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
978      return 0;              BUG( NULL );
979  } /* km_groups_add */          n = count_userids (pk);
980            while( n-- ) {
981                gpgme_user_id_t u = get_nth_userid (pk, n);
982  static int              const char * s =  u->uid;
983  km_groups_del_main( km_group_t gc )              if( s && stristr( s, mbr->name )
984  {                  && u->validity < 3 )
985      TVITEM tvi;                  no_trust++;
986      char text[128];          }
987      int id;      }
988        
989      memset( &tvi, 0, sizeof tvi );      gpgme_recipients_add_name( rset, name );
990      tvi.hItem = TreeView_GetSelection( gc->tree );      release_gpg_options( opt );
991      tvi.pszText = text;      
992      tvi.cchTextMax = sizeof text -1;      return no_trust;
993      tvi.mask = TVIF_TEXT;  } /* km_groupdb_expand_recipients */
994      TreeView_GetItem( gc->tree, &tvi );  
995                                
996      id = log_box( _("Key Manager"), MB_INFO_ASK,  static HTREEITEM
997                     _("Do you really want to delete this group?\n\n%s"), text);  km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
998      if( id == IDNO )  {
999          return 0;      TVINSERTSTRUCT tvis;
1000      delete_group( gc->gh, text );          HTREEITEM node;
1001      TreeView_DeleteItem( gc->tree, &tvi );      
1002      gc->need_sync = 1;      memset( &tvis, 0, sizeof tvis );
1003            tvis.hParent = parent;
1004      return 0;      tvis.hInsertAfter = TVI_LAST;
1005  } /* km_groups_del */      tvis.item.mask = TVIF_TEXT;
1006        tvis.item.pszText = (char *)text;
1007        node = TreeView_InsertItem( tree, &tvis );
1008  static int      return node;
1009  km_groups_del_entry( km_group_t gc )  } /* km_tv_insert_item */
1010  {  
1011      TVITEM tvi;  
1012      HTREEITEM root;  int
1013      int id;  km_groups_new( km_group_t *r_gc, HWND ctrl )
1014      char text[128], info[256];  {
1015      gpg_group_t  grp = NULL;      km_group_t gc;
1016            
1017      memset( &tvi, 0, sizeof tvi );      gc = new km_group_s;
1018      tvi.hItem = TreeView_GetSelection( gc->tree );      if (!gc)
1019      tvi.pszText = text;          BUG (NULL);
1020      tvi.cchTextMax = sizeof text-1;      gc->tree = ctrl;
1021      tvi.mask = TVIF_TEXT;      gc->gh = km_groupdb_open ();
1022      TreeView_GetItem( gc->tree, &tvi );      *r_gc = gc;
1023            return 0;
1024      _snprintf( info, sizeof info -1,  } /* km_groups_new */
1025                _("Do you really want to delete this entry?\n\n%s"), text );  
1026        
1027      id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );  void
1028      if( id == IDNO )  km_groups_sync( km_group_t gc )
1029          return 0;  {
1030        char * optfile;
1031      root = TreeView_GetParent( gc->tree, tvi.hItem );  
1032      if( root ) {      optfile = get_gnupg_cfgfile ();
1033      }      if( !optfile )
1034                BUG( NULL );
1035      delete_member( gc->gh, /*fixme*/NULL, text );      commit_gpg_options( optfile, gc->gh );
1036      TreeView_DeleteItem( gc->tree, &tvi );      free_if_alloc( optfile );
1037      gc->need_sync = 1;      gc->need_sync = 0;
1038      return 0;  } /* km_groups_sync */
1039  } /* km_groups_del_entry */  
1040    
1041    void
1042  int  km_groups_release (km_group_t gc)
1043  km_groups_del( km_group_t gc )  {
1044  {      if( gc ) {
1045      if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )          /* xxx: this reset the default key (sync=1) */
1046          return km_groups_del_entry( gc );          gc->need_sync=0;
1047      else          if (gc->need_sync)
1048          return km_groups_del_main( gc );              km_groups_sync (gc);
1049  } /* km_groups_del */          if (gc->gh)
1050                release_gpg_options( gc->gh );
1051            gc->gh = NULL;
1052            gc->tree = NULL;
1053            delete gc;
1054        }    
1055    } /* km_groups_release */
1056    
1057    
1058    int
1059    km_groups_load( km_group_t gc )
1060    {    
1061        HTREEITEM n;
1062        gpg_group_t grp, g;
1063        gpg_member_t mbr;
1064        u32 gid = 0;
1065        
1066        if( !gc->gh )
1067            return 0;
1068        grp = gc->gh->grp;
1069        if( !grp )
1070            return 0; /* no groups */
1071            
1072        for( g = grp; g; g = g->next ) {
1073            n = km_tv_insert_item( gc->tree, NULL, g->name );
1074            for( mbr = g->list; mbr; mbr = mbr->next ) {
1075                if( mbr->used && mbr->name )
1076                    km_tv_insert_item( gc->tree, n, mbr->name );
1077            }
1078        }
1079        DragAcceptFiles( gc->tree, TRUE );
1080        gc->need_sync = 0;
1081        return 0;
1082    } /* km_groups_load */
1083    
1084    
1085    int
1086    km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1087    {
1088        TVITEM tvi;
1089        char uid[128], valid[64], text[128];
1090        int i_valid;
1091        
1092        memset( &tvi, 0, sizeof tvi );
1093        tvi.hItem = TreeView_GetSelection( gc->tree );
1094        tvi.pszText = text;
1095        tvi.cchTextMax = sizeof text -1;
1096        tvi.mask = TVIF_TEXT;
1097        TreeView_GetItem( gc->tree, &tvi );
1098        
1099        
1100        listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1101        listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1102        
1103        if( strstr( valid, "Ultimate" ) )
1104            i_valid = 5;    
1105        else if( !strstr( valid, "Full" ) )
1106            i_valid = 4;
1107        else if( !strstr( valid, "Marginal" ) )
1108            i_valid = 3;
1109        else
1110            i_valid = 0;
1111        
1112        /* we can't add the full name. one way would be to use the first
1113           text until a space appears.
1114        group_add_entry(&gc->gh, gid, i_valid, uid);
1115        treeview_add_item(gc->tree, tvi.hItem, uid);
1116        */
1117        gc->need_sync = 1;
1118        
1119        return 0;
1120    } /* km_groups_add */
1121    
1122    
1123    static int
1124    km_groups_del_main( km_group_t gc )
1125    {
1126        TVITEM tvi;
1127        char text[128];
1128        int id;
1129        
1130        memset( &tvi, 0, sizeof tvi );
1131        tvi.hItem = TreeView_GetSelection( gc->tree );
1132        tvi.pszText = text;
1133        tvi.cchTextMax = sizeof text -1;
1134        tvi.mask = TVIF_TEXT;
1135        TreeView_GetItem( gc->tree, &tvi );
1136                                
1137        id = log_box( _("Key Manager"), MB_INFO_ASK,
1138                       _("Do you really want to delete this group?\n\n%s"), text);
1139        if( id == IDNO )
1140            return 0;
1141        delete_group( gc->gh, text );    
1142        TreeView_DeleteItem( gc->tree, &tvi );
1143        gc->need_sync = 1;
1144        
1145        return 0;
1146    } /* km_groups_del */
1147    
1148    
1149    static int
1150    km_groups_del_entry( km_group_t gc )
1151    {
1152        TVITEM tvi;
1153        HTREEITEM root;
1154        int id;
1155        char text[128], info[256];
1156        gpg_group_t  grp = NULL;
1157        
1158        memset( &tvi, 0, sizeof tvi );
1159        tvi.hItem = TreeView_GetSelection( gc->tree );
1160        tvi.pszText = text;
1161        tvi.cchTextMax = sizeof text-1;
1162        tvi.mask = TVIF_TEXT;
1163        TreeView_GetItem( gc->tree, &tvi );
1164        
1165        _snprintf( info, sizeof info -1,
1166                  _("Do you really want to delete this entry?\n\n%s"), text );
1167        
1168        id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1169        if( id == IDNO )
1170            return 0;
1171    
1172        root = TreeView_GetParent( gc->tree, tvi.hItem );
1173        if( root ) {
1174        }
1175        
1176        delete_member( gc->gh, /*fixme*/NULL, text );
1177        TreeView_DeleteItem( gc->tree, &tvi );
1178        gc->need_sync = 1;
1179        return 0;
1180    } /* km_groups_del_entry */
1181    
1182    
1183    int
1184    km_groups_del( km_group_t gc )
1185    {
1186        if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1187            return km_groups_del_entry( gc );
1188        else
1189            return km_groups_del_main( gc );
1190    } /* km_groups_del */
1191    #endif

Legend:
Removed from v.16  
changed lines
  Added in v.36

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26