/[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 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 128 by twoaday, Mon Dec 19 13:05:59 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    
22  #include <windows.h>  #ifdef HAVE_CONFIG_H
23  #include <commctrl.h>  #include <config.h>
24  #include <stdio.h>  #endif
25  #include <io.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;  #include "wptCrypto.h"
50    
51      if (get_pubkey (uid, &pk))  
52          BUG (0);  /* Return a user friendly key representation in @buf of
53           the key given by @keyid. */
54      a = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_CREATED, NULL, 0);  static void
55      algo = gpgme_key_get_ulong_attr (pk, GPGME_ATTR_ALGO, NULL, 0);  key_get_clip_info (const char *keyid, char *buf, size_t buflen)
56      _snprintf (buf, buflen-1,  {
57                 "pub %04d%s/%s %s %s\r\n"      gpgme_key_t pk;
58                 "    Primary key fingerprint: %s\r\n",    
59          gpgme_key_get_ulong_attr (pk, GPGME_ATTR_LEN, NULL, 0),      if (get_pubkey (keyid, &pk))
60          gpgme_key_expand_attr (GPGME_ATTR_ALGO_SHORT, algo),          BUG (NULL);
61          gpgme_key_get_string_attr (pk, GPGME_ATTR_KEYID, NULL, 0) + 8,        _snprintf (buf, buflen-1,
62          gpgme_key_expand_attr (GPGME_ATTR_CREATED, a ),                 "pub %04d%s/%s %s %s\r\n"
63          gpgme_key_get_string_attr (pk, GPGME_ATTR_USERID, NULL, 0),                 "    Primary key fingerprint: %s\r\n",
64          get_key_fpr (pk));                 pk->subkeys->length,
65  }                 get_key_pubalgo2 (pk->subkeys->pubkey_algo),
66                   pk->subkeys->keyid+8,
67                   get_key_created (pk->subkeys->timestamp),
68  char*                 pk->uids->uid,
69  km_quote_uid (const char * uid)                 get_key_fpr (pk));
70  {      }
71      char * q = new char[strlen (uid) + 4];  
72      if (!q)  
73          BUG (NULL);  /* Return a general description of the key @key. */
74      _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);  static char*
75      return q;  key_get_info (gpgme_key_t pk, int is_sec)
76  } /* km_quote_uid */  {
77        const char *fmt = "%s %04d%s/0x%s %s\n  \"%s\"";
78        char *p;
79  int      int n;
80  km_check_for_seckey (listview_ctrl_t lv, int pos, int * utrust)  
81  {      n = strlen (fmt) + 8 + 2 + 16 + 12 + strlen (pk->uids->uid) + 32;
82      char t[128], t2[128];      p = new char[n+1];
83      int type=0;      if (!p)
84                BUG (NULL);
85      listview_get_item_text (lv, pos, 5, t, sizeof t -1);      _snprintf (p, n, fmt, is_sec? "sec" : "pub",
86      listview_get_item_text (lv, pos, 2, t2, sizeof t2  -1);                 pk->subkeys->length,
87      if (!strcmp (t2, "pub/sec"))                 get_key_pubalgo2 (pk->subkeys->pubkey_algo),
88          type = 1;                 pk->subkeys->keyid+8, get_key_created (pk->subkeys->timestamp),
89      else if (!strcmp (t2, "pub/crd"))                 pk->uids->uid);
90          type = 2;      return p;
91      if (stristr (t, "ultimate") && utrust)  }
92          *utrust = 1;  
93      return type;  
94  } /* km_check_for_seckey */  #if 0
95    /* Quoted the user-id given by @uid. If @uid is already
96       quoted @uid is returned without any modifications.
97  int     Return value: quoted @uid. */
98  km_check_if_protected( listview_ctrl_t lv, int pos )  char*
99  {  km_quote_uid (const char *uid)
100      gpgme_key_t key;  {    
101      char keyid[32];          char *q;
102        
103      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );      if (*uid == '"' && uid[strlen (uid)-1] == '"')
104      if( get_pubkey( keyid, &key ) )          return m_strdup (uid);
105          BUG( NULL );          q = new char[strlen (uid) + 4];
106      return gpgme_key_get_ulong_attr( key, GPGME_ATTR_IS_PROTECTED, NULL, 0 );      if (!q)
107  } /* km_check_if_protected */          BUG (NULL);
108        _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
109        return q;
110  int  }
111  km_check_key_status (listview_ctrl_t lv, int pos)  #endif
112  {  
113      char t[128];  
114      int i = 1;  /* Check if list view @lv contains a secret key at position @pos.
115           If utrust is valid, set it to 1 if the key is valid -1 otherwise.
116      listview_get_item_text( lv, pos, 5, t, sizeof t - 1 );     Return value: 1 normal key, 2 smart card key. */
117      if( t[0] == '[' && t[1] == ']' )  int
118          return 1;  km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
119      for( i = 0; t[i] != ']'; i++ ) {  {
120          if( t[i] == 'E' )      gpgme_key_t key;
121              msg_box(lv->ctrl, _("This key has expired!\n"      winpt_key_s sk;
122                                  "Key check failed."), _("Key Manager"), MB_ERR );      int type = 0;
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      }          BUG (NULL);
127        if (utrust)
128      return 0;          *utrust = 0;
129  } /* km_check_key_status */      memset (&sk, 0, sizeof (sk));
130        if (!winpt_get_seckey (key->subkeys->keyid+8, &sk))
131            type = 1;
132  int      if (sk.ext && sk.ext->gloflags.divert_to_card)
133  km_get_key_status( listview_ctrl_t lv, int pos )          type = 2;
134  {      if (utrust && (key->expired || key->revoked))
135      char t[128];          *utrust = -1;
136      int i, flags = 0;      else if (utrust && key->owner_trust == GPGME_VALIDITY_ULTIMATE)
137            *utrust = 1;
138      if( pos == -1 )      return type;
139          return 0;  }
140      listview_get_item_text( lv, pos, 5, t, sizeof t-1 );  
141      for( i = 0; t[i] != ']'; i++ ) {  
142          if( t[i] == 'E' )  /* Check if the key at position @pos is protected with a passwd. */
143              flags |= KM_FLAG_EXPIRED;  int
144          if( t[i] == 'R' )  km_check_if_protected (listview_ctrl_t lv, int pos)
145              flags |= KM_FLAG_REVOKED;  {
146          if( t[i] == 'D' )      gpgme_key_t key;
147              flags |= KM_FLAG_DISABLED;      winpt_key_s k;
148      }  
149      return flags;      key = (gpgme_key_t)listview_get_item2 (lv, pos);
150  } /* km_get_key_status */      if (!key)
151            return 1; /* assume yes */
152        winpt_get_pubkey (key->subkeys->keyid, &k);
153  int      return k.is_protected;
154  km_enable_disable_key( listview_ctrl_t lv, HWND dlg, int pos, int enable )  }
155  {  
156      gpgme_ctx_t ctx;  
157      gpgme_editkey_t ek;  /* Check if the key has a good status.
158      gpgme_error_t err;     Return value: 0 on success. */
159      int edit_id;  int
160      char keyid[32];  km_check_key_status (listview_ctrl_t lv, int pos)
161    {
162      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );      int flags = km_get_key_status (lv, pos);
163      err = gpgme_editkey_new( &ek );      
164      if( err )      if (flags & KM_FLAG_EXPIRED) {
165          BUG( NULL );          msg_box (lv->ctrl, _("This key has expired!\n"  
166      if( enable ) {                               "Key check failed."), _("Key Manager"), MB_ERR);
167          gpgme_editkey_enable_set( ek );          return -1;
168          edit_id = GPGME_EDITKEY_ENABLE;      }
169      }      else if (flags & KM_FLAG_REVOKED) {
170      else {          msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
171          gpgme_editkey_disable_set( ek );                               "Key check failed."), _("Key Manager"), MB_ERR);
172          edit_id = GPGME_EDITKEY_DISABLE;          return -1;
173      }      }
174      err = gpgme_new( &ctx );  
175      if( err )      return 0;
176          BUG( NULL );  }
177      gpgme_set_edit_ctx( ctx, ek, edit_id );  
178      err = gpgme_op_editkey( ctx, keyid );  
179      if( !err ) {  /* Return all key flags ORed. */
180          show_msg( dlg, 1500, _("Key status changed.") );  int
181          keycache_set_reload( 1 );  km_get_key_status (listview_ctrl_t lv, int pos)
182      }  {
183      else      gpgme_key_t key;
184          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );      int flags = 0;
185    
186      gpgme_release( ctx );      if (pos == -1)
187      gpgme_editkey_release( ek );          return 0;
188      return err? WPTERR_GENERAL : 0;      key = (gpgme_key_t)listview_get_item2 (lv, pos);
189  } /* km_enable_disable_key */      if (key == NULL)
190            return 0;
191    
192  int      if (key->expired)
193  km_clip_export (HWND dlg, listview_ctrl_t lv)          flags |= KM_FLAG_EXPIRED;
194  {      if (key->revoked)
195      gpgme_error_t err;          flags |= KM_FLAG_REVOKED;
196      gpgme_recipients_t rset;      if (key->disabled)
197      int rc, id = 0, n = 0;          flags |= KM_FLAG_DISABLED;
198            return flags;
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);  /* Interface to enable or disable a key (@enable = 1 then enable).
203          rc = WPTERR_GENERAL;     The key is retrieved from a list control @lv at the pos @pos. */
204          goto leave;  int
205      }  km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
206        {
207      err = gpgme_op_clip_export (rset);      gpgme_error_t err;
208      if (err) {      gpgme_key_t key;
209          msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);      GpgKeyEdit *ke;
210          rc = WPTERR_GENERAL;  
211          goto leave;      key = (gpgme_key_t)listview_get_item2 (lv, pos);
212      }      if (!key)
213      if (n == 1) {          BUG (NULL);
214          const char *s;      ke = new GpgKeyEdit (key->subkeys->keyid);
215          char buf[256];      if (!ke)
216          s = gpgme_recipients_get_name (rset, 0);          BUG (NULL);
217          km_get_clip_info (s, buf, 255);  
218          set_clip_text2 (NULL, buf, strlen (buf), 0);      err = enable? ke->enable () : ke->disable ();
219      }      if (!err)
220            show_msg (dlg, 1500, _("Key status changed."));
221      show_msg (dlg, 1500, _("GnuPG Status: Finished"));      else
222                msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
223  leave:      delete ke;
224      gpgme_recipients_release (rset);      return err? WPTERR_GENERAL : 0;
225      return rc;  }
226  } /* km_clip_export */  
227    
228    
229  int  /* Create a string that contain all keyids from
230  km_privkey_export( HWND dlg, listview_ctrl_t lv, const char *fname )     the key list @rset separated by a space. */
231  {  char*
232      gpgme_recipients_t rset;  gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
233      gpgme_data_t keydata;  {
234      gpgme_error_t err;      char *p;
235      gpgme_ctx_t ctx;      int i;
236      size_t n = 0;  
237        if (!n)
238      rset = keylist_enum_recipients( lv, KEYLIST_LIST );          return NULL;
239      n = gpgme_recipients_count( rset );      p = (char *)calloc (1, n*(16+1)+n+2);
240      if( !n ) {      if (!p)
241          msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );          BUG (NULL);
242          return WPTERR_GENERAL;      for (i=0; i < n; i++) {
243      }          strcat (p, rset[i]->subkeys->keyid);
244      if( n > 1 ) {          strcat (p, " ");
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 */      return p;
247      }  }
248      err = gpgme_data_new( &keydata );  
249      if( err )  
250          BUG( dlg );  /* Export the keys given in @rset to the clipboard.
251      err = gpgme_new( &ctx );     Return value: 0 on success. */
252      if( err )  static gpgme_error_t
253          BUG( dlg );  gpg_clip_export (gpgme_key_t *rset, int n)
254      gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );  {
255      gpgme_control( ctx, GPGME_CTRL_WITH_SECRET_KEY, 1 );      gpgme_error_t err = 0;
256        gpgme_ctx_t ctx = NULL;
257      err = gpgme_op_export( ctx, rset, keydata );      gpgme_data_t keydata = NULL;
258      if( err ) {      char *patt=NULL;
259          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );      
260          goto leave;      err = gpgme_new (&ctx);
261      }      if (err)
262            return err;
263      log_box( _("Key Manager"), MB_OK,      gpgme_set_armor (ctx, 1);          
264               _("Secret key successfully saved in '%s'."), fname );      err = gpgme_data_new (&keydata);
265            if (err)
266  leave:          goto leave;
267      err = gpgme_data_release_and_set_file( keydata, fname );  
268      if( err )      patt = gpg_keylist_to_pattern (rset, n);
269          log_box( _("Key Manager"), MB_OK,      if (!patt) {
270                   _("Could not save data to '%s'."), fname );          err = gpg_error (GPG_ERR_ENOMEM);
271      gpgme_release( ctx );          goto leave;
272        }
273      return (int)err;  
274  } /* km_privkey_export */      err = gpgme_op_export (ctx, patt, 0, keydata);
275        if (err)
276            goto leave;
277  int  
278  km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)      gpg_data_release_and_set_clipboard (keydata, 1);
279  {  
280      gpgme_recipients_t rset;  leave:
281      gpgme_data_t keydata;            if (patt)
282      gpgme_error_t err;          free (patt);
283      gpgme_ctx_t ctx;      gpgme_release (ctx);
284        return err;
285      rset = keylist_enum_recipients( lv, KEYLIST_LIST );  }
286      if( !gpgme_recipients_count( rset ) ) {  
287          msg_box( dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR );  
288          return WPTERR_GENERAL;  /* Export the selected keys in @lv to the clipboard. */
289      }  int
290        km_clip_export (HWND dlg, listview_ctrl_t lv)
291      err = gpgme_data_new( &keydata );  {
292      if( err )      gpgme_error_t err;
293          BUG( dlg );      gpgme_key_t *rset;
294      err = gpgme_new( &ctx );      char buf[256];
295      if( err )      int n=0;
296          BUG( dlg );      int rc=0;
297      gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );      
298      gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);      rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
299            if (!n) {
300      err = gpgme_op_export( ctx, rset, keydata );          msg_box (dlg, _("No key was selected for export."),
301      if( err ) {                   _("Key Manager"), MB_ERR);
302          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );          rc = WPTERR_GENERAL;
303          goto leave;          goto leave;
304      }      }
305                
306      log_box( _("Key Manager"), MB_OK,      err = gpg_clip_export (rset, n);
307               _("Key(s) successfully saved in '%s'."), fname );      if (err) {
308                msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
309  leave:          rc = WPTERR_GENERAL;
310      err = gpgme_data_release_and_set_file( keydata, fname );          goto leave;
311      if( err )      }
312          log_box( _("Key Manager"), MB_OK,      if (n == 1) {
313                   _("Could not save data to '%s'."), fname );              key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
314      gpgme_release( ctx );          set_clip_text2 (NULL, buf, strlen (buf), 0);
315        }
316      return (int)err;  
317  } /* km_file_export */      show_msg (dlg, 1500, _("GnuPG Status: Finished"));
318        
319    leave:
320  static int      free (rset);
321  extract_dash_escaped_key( void )      return rc;
322  {  }
323      gpgme_data_t inp, plain;  
324      gpgme_error_t err;  
325    /* Export the selected secret key from @lv into @fname.
326      err = gpgme_data_new_from_clipboard (&inp);     It is only allowed to export a single secret key. */
327      if( err ) {  int
328          msg_box( NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR );  km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
329          return -1;  {
330      }      gpgme_key_t *rset;
331      gpgme_data_extract_plaintext( inp, &plain );      gpgme_error_t err;
332      gpgme_data_release( inp );      int n = 0;
333      gpgme_data_release_and_set_clipboard( plain );  
334        rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
335      return 0;      if (!n) {
336  } /* extract_dash_escaped_key */          msg_box (dlg, _("No key was selected for export."),
337                     _("Key Manager"), MB_ERR);
338            return WPTERR_GENERAL;
339  int      }
340  km_clip_import( HWND dlg )      if (n > 1) {
341  {          msg_box (dlg, _("Only one secret key can be exported."),
342      gpgme_error_t err;                   _("Key Manager"), MB_ERR);
343      gpgme_cliptype_t pgptype;          free (rset);
344      int id;          return 0; /* we checked this before, so we just quit */
345      int has_data = 0;      }
346        
347      if( !gpgme_clip_istext_avail( &has_data ) && !has_data ) {      err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
348          msg_box( dlg, winpt_strerror( WPTERR_CLIP_ISEMPTY ), _("Key Manager"), MB_ERR );      if (err)
349          return WPTERR_CLIP_ISEMPTY;          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
350      }      else
351      err = gpgme_clip_is_secured( &pgptype, &has_data );          log_box (_("Key Manager"), MB_OK,
352      if( err )                   _("Secret key successfully saved in '%s'."), fname);
353          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );  
354      if( !has_data ) {      free (rset);
355          msg_box( dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR );      return err? WPTERR_GENERAL : 0;
356          return WPTERR_GENERAL;  }
357      }  
358      if( !(pgptype & GPGME_CLIP_PUBKEY) && !(pgptype & GPGME_CLIP_SECKEY) ) {  
359          msg_box( dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR );  int
360          return WPTERR_GENERAL;  km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
361      }  {
362      if( pgptype & GPGME_CLIP_DASH_ESCAPED ) {      gpgme_key_t *rset;
363          id = msg_box( dlg, _("The key you want to import is dash escacped.\n"      gpgme_data_t keydata;      
364                               "Do you want to extract the key?"),      gpgme_error_t err;
365                        _("Key Manager"), MB_YESNO );      gpgme_ctx_t ctx;
366          if( id == IDYES )      char *patt;
367              extract_dash_escaped_key( );      int n;
368          else  
369              msg_box( dlg, _("Cannot import dash escaped OpenPGP keys."), _("Key Manager"), MB_INFO );      rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
370      }      if (!n) {
371            msg_box (dlg, _("No key was selected for export."),
372      dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,                   _("Key Manager"), MB_ERR);
373                        clip_import_dlg_proc, NULL,          return WPTERR_GENERAL;
374                        _("Key Import"), IDS_WINPT_IMPORT );      }
375        
376      return 0;      err = gpgme_data_new (&keydata);
377  } /* km_clip_import */      if (err)
378            BUG (NULL);
379        err = gpgme_new (&ctx);
380  int      if (err)
381  km_http_import (HWND dlg, const char * url)          BUG (NULL);
382  {      gpgme_set_armor (ctx, 1);
383      FILE * fp;  
384      char * p;      /*gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);*/
385      char tmpdir[500];      patt = gpg_keylist_to_pattern (rset, n);
386      http_hd_t hd;      
387      int statcode;      err = gpgme_op_export (ctx, patt, 0, keydata);
388      int rc = 0;      if( err ) {
389            msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
390      if (strncmp (url, "http://", 7)) {          goto leave;
391          log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);      }
392          return WPTERR_GENERAL;  
393      }      log_box (_("Key Manager"), MB_OK,
394                 _("Key(s) successfully saved in '%s'."), fname);
395      GetTempPath (499, tmpdir);      
396      p = make_filename (tmpdir, "file_http", "tmp");  leave:
397      if (!p)      err = gpg_data_release_and_set_file (keydata, fname);
398          BUG (0);      if (err)
399      fp = fopen (p, "wb");          log_box (_("Key Manager"), MB_OK,
400      if (fp == NULL) {                   _("Could not save data to '%s'."), fname);
401          free_if_alloc (p);      gpgme_release (ctx);
402          log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));      free (patt);
403          return WPTERR_FILE_CREAT;      return (int)err;
404      }  }
405      /* parse URL */  
406      rc = http_send_request2 (url, &hd);  
407      if (!rc)  /* Read a dash escaped key from the clipboard
408          rc = http_parse_response (hd, &statcode);     unescape it and write it back. */
409      if (!rc)  static int
410          rc = http_parse_data (hd, fp);  extract_dash_escaped_key (void)
411      http_hd_free (hd);  {
412      fclose (fp);      gpgme_data_t inp, plain;
413      if (rc) {      gpgme_error_t err;
414          free_if_alloc (p);  
415          msg_box (dlg, http_strerror (rc), _("Key Import HTTP"), MB_ERR);      err = gpg_data_new_from_clipboard (&inp, 0);
416          return WPTERR_GENERAL;      if (err) {
417      }          msg_box (NULL, gpgme_strerror (err), _("Key Manager"), MB_ERR);
418      km_file_import (dlg, p);          return -1;
419      free_if_alloc (p);      }
420      return 0;      gpg_data_extract_plaintext (inp, &plain);
421  }      gpg_data_release_and_set_clipboard (plain, 0);
422        gpgme_data_release (inp);
423  int  
424  km_file_import( HWND dlg, const char * fname )      return 0;
425  {  }
426      gpgme_data_t keydata = NULL;  
427      gpgme_ctx_t ctx;  
428      gpgme_error_t err;  /* Import keys from the clipboard. */
429      fm_state_s fm_stat;  int
430      int import_res[14];  km_clip_import (HWND dlg)
431        {
432      memset( &fm_stat, 0, sizeof fm_stat );      gpgme_error_t err;
433      fm_stat.opaque = m_strdup( fname );      int pgptype;
434            int id;
435      dialog_box_param( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,      int has_data = 0;
436                        file_import_dlg_proc, (LPARAM)&fm_stat,      
437                        _("File Import"), IDS_WINPT_IMPORT );      if (!gpg_clip_istext_avail (&has_data) && !has_data) {
438      if( fm_stat.cancel == 1 )          msg_box (dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY),
439          return WPTERR_GENERAL;                   _("Key Manager"), MB_ERR);
440                return WPTERR_CLIP_ISEMPTY;
441      err = gpgme_new( &ctx );      }
442      if( err )      err = gpg_clip_is_secured (&pgptype, &has_data);
443          BUG( dlg );      if (err)
444      gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
445      err = gpgme_data_new_from_file (&keydata, fname);      if (!has_data) {
446      if( err ) {          msg_box (dlg, _("No valid OpenPGP data found."),
447          msg_box( dlg, _("Could not read key-data from file."), _("Key Manager"), MB_ERR );                   _("Key Manager"), MB_ERR);
448          goto leave;          return WPTERR_GENERAL;
449      }      }
450            if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
451      err = gpgme_op_import( ctx, NULL, keydata );          msg_box (dlg, _("No valid OpenPGP keys found."),
452      if( err ) {                   _("Key Manager"), MB_ERR);
453          msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );          return WPTERR_GENERAL;
454          goto leave;      }
455      }      if (pgptype & PGP_DASH_ESCAPED) {
456                id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
457      gpgme_get_import_status( ctx, import_res, NULL );                               "Do you want to extract the key?"),
458      print_import_status( import_res, fm_stat.implist_revcert );                        _("Key Manager"), MB_YESNO);
459      if( import_res[GPGME_IMPSTAT_NOSELFSIG] > 0  ) {          if (id == IDYES)
460          msg_box( dlg, _("Key without a self signature was dectected!\n"              extract_dash_escaped_key ();
461                          "(This key is NOT usable for encryption, etc)\n"          else
462                          "\n"                  msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
463                          "Cannot import these key(s)!"), _("Import"), MB_INFO );                       _("Key Manager"), MB_INFO);
464      }      }
465        
466  leave:              dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
467      gpgme_data_release( keydata );                        clip_import_dlg_proc, 0,
468      gpgme_release( ctx );                        _("Key Import"), IDS_WINPT_IMPORT);
469      free_if_alloc( fm_stat.opaque );  
470      return (int)err;      return 0;
471  } /* km_file_import */  }
472    
473    
474  static void  /* Import a key from the http URL @url. */
475  delete_keys_from_cache (gpgme_recipients_t rset)  int
476  {  km_http_import (HWND dlg, const char *url)
477      gpgme_keycache_t pub = keycache_get_ctx (1);  {
478      void * ctx =NULL;      http_hd_t hd;
479      const char * s;      FILE *fp;
480        char *p;
481      gpgme_recipients_enum_open (rset, &ctx);      char tmpfile[500];
482      while ((s = gpgme_recipients_enum_read (rset, &ctx)))      int statcode;
483          gpgme_keycache_delete_key (pub, s);      int rc = 0;
484      gpgme_recipients_enum_close (rset, &ctx);  
485  } /* delete_keys_from_cache */      if (strncmp (url, "http://", 7)) {
486            log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
487            return WPTERR_GENERAL;
488  int      }
489  km_delete_keys (listview_ctrl_t lv, HWND dlg)  
490  {      GetTempPath (sizeof (tmpfile)-128, tmpfile);
491      gpgme_error_t err;      p = make_filename (tmpfile, "winpt_file_http", "tmp");
492      gpgme_recipients_t rset;      if (!p)
493      char keyid[32], uid[256], date[64], keylen[64];              BUG (0);
494      int with_seckey, seckey_type=0;      fp = fopen (p, "wb");
495      int i, rc;      if (!fp) {
496                free_if_alloc (p);
497      if( listview_get_curr_pos( lv ) == -1 ) {          log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p,
498          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );                   winpt_strerror (WPTERR_FILE_CREAT));
499          return WPTERR_GENERAL;          return WPTERR_FILE_CREAT;
500      }      }
501        
502      err = gpgme_recipients_new (&rset);      /* parse URL */
503      if (err)      rc = http_send_request2 (url, &hd);
504          BUG (0);      if (!rc)
505                rc = http_parse_response (hd, &statcode);
506      for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {      if (!rc)
507          if( listview_get_item_state( lv, i ) ) {          rc = http_parse_data (hd, fp);
508              listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );      http_hd_free (hd);
509              listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );      fclose (fp);
510              listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );      if (rc) {  
511              listview_get_item_text( lv, i, 7, date, sizeof date - 1 );          msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
512              seckey_type = km_check_for_seckey( lv, i, NULL );          rc = WPTERR_GENERAL;
513              if( !seckey_type ) {      }
514                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,      km_file_import (dlg, p);
515                                _("Do you really want to delete this key?\n\n"      remove (p);
516                                  "pub %s %s %s\n"      free_if_alloc (p);
517                                  "  \"%s\""), keylen, keyid, date, uid );      return rc;
518                  if( rc == IDYES )  }
519                      gpgme_recipients_add_name( rset, keyid );  
520                  with_seckey = 0;  
521              }  /* Import a key from the given file @fname.
522              else {     On success an import statistics dialog is shown. */
523                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,                  int
524                                _("Do you really want to delete this KEY PAIR?\n\n"  km_file_import (HWND dlg, const char *fname)
525                                  "Please remember that you are not able to decrypt\n"  {
526                                  "messages you stored with this key any longer.\n"      gpgme_data_t keydata = NULL;
527                                  "\n"      gpgme_ctx_t ctx;
528                                  "pub/sec %s %s %s\n"      gpgme_error_t err;    
529                                  "  \"%s\""), keylen, keyid, date, uid );      fm_state_s fm_stat;
530                  if( rc == IDYES ) {      gpgme_import_result_t res;
531                      if( seckey_type == 2 )      
532                          msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"      memset (&fm_stat, 0, sizeof (fm_stat));
533                                          "Only the public key and the secret key \n"      fm_stat.opaque = m_strdup (fname);
534                                          "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );      
535                      gpgme_recipients_add_name( rset, keyid );      dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
536                  }                        file_import_dlg_proc, (LPARAM)&fm_stat,
537                  with_seckey = 1;                        _("File Import"), IDS_WINPT_IMPORT);
538              }      if (fm_stat.cancel == 1) {
539          }          free_if_alloc (fm_stat.opaque);
540      }          return WPTERR_GENERAL;
541            }
542      if (!gpgme_recipients_count (rset)) {      
543          gpgme_recipients_release (rset);      err = gpgme_new (&ctx);
544          return 0;      if (err)
545      }          BUG (NULL);
546            err = gpgme_data_new_from_file (&keydata, fname, 1);
547      err = gpgme_op_delete_keys (rset, with_seckey);      if (err) {
548      if (err) {          msg_box (dlg, _("Could not read key-data from file."),
549          if (err == GPGME_Invalid_Key)                   _("Key Manager"), MB_ERR);
550              msg_box (dlg, _("No such key."), _("Key Manager"), MB_INFO);          goto leave;
551          else if (err == GPGME_Conflict)      }
552              msg_box (dlg, _("Must delete secret key first."), _("Key Manager"), MB_INFO);      
553          else      SetCursor (LoadCursor (NULL, IDC_WAIT));
554              msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);      err = gpgme_op_import (ctx, keydata);
555          return FALSE;      SetCursor (LoadCursor (NULL, IDC_ARROW));
556      }      if (err) {
557      show_msg (dlg, 1500, _("GnuPG Status: Finished"));          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
558      listview_del_items (lv);          goto leave;
559      if (keyring_check_last_access ())      }    
560          keycache_set_reload (1);  
561      delete_keys_from_cache (rset);      res = gpgme_op_import_result (ctx);
562      gpgme_recipients_release (rset);      if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
563            res->new_revocations = 1;
564      return (int)err;      if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
565  } /* km_delete_keys */          res->secret_imported = 1;
566    
567        /* XXX: if we import a key pair but the secret key comes first,
568  int              no_{valid}_user_id is 1 even so the public key, which comes
569  km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)              later is valid and self-signed. */
570  {      print_import_status (res);
571      char keyid[32];      if (res->no_user_id > 0) {
572      const char *t;          msg_box (dlg, _("Key without a self signature was dectected!\n"
573      int id;                          "(This key is NOT usable for encryption, etc)\n"
574                                "\n"    
575      id = listview_get_curr_pos( lv );                          "Cannot import these key(s)!"), _("Import"), MB_INFO);
576      if( id == -1 ) {      }
577          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );  
578          return WPTERR_GENERAL;  leave:
579      }      gpgme_data_release (keydata);
580        gpgme_release (ctx);
581      listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );      free_if_alloc (fm_stat.opaque);
582      id = log_box (_("Key Manager"), MB_YESNO,      return (int)err;
583                    _("Do you really want to send '%s' to keyserver %s?"),  }
584                      keyid, host);  
585      if (id == IDYES) {  
586          t = keyid;  /* Mark the keys in @rset as deleted in the keycache. */
587          if (!strncmp (keyid, "0x", 2))  static void
588              t += 2;  delete_keys_from_cache (gpgme_key_t *rset, size_t n)
589          hkp_send_key (dlg, host, port, t);  {
590      }      gpg_keycache_t pub = keycache_get_ctx (1);
591        int i=0;
592      return 0;  
593  } /* km_send_to_keyserver */      while (n-- > 0)
594            gpg_keycache_delete_key (pub, rset[i++]->subkeys->keyid);
595    }
596  int  
597  km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )  
598  {  /* Delete all selected keys from the list view @lv. */
599      gpgme_key_t key;  int
600      gpgme_ctx_t ctx=NULL;  km_delete_keys (listview_ctrl_t lv, HWND dlg)
601      gpgme_recipients_t rset=NULL;  {
602      gpgme_error_t rc;      gpgme_error_t err;
603      const char * s;      gpgme_ctx_t ctx;
604      char keyid[32], tmp[192+256], * p =NULL;      gpgme_key_t *rset;
605      int pos;      gpgme_key_t key;
606        char keyid[32];
607      if( listview_count_items( lv, 1 ) > 1 ) {      char *p;
608          msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );      int with_seckey=0, seckey_type=0, confirm=0;
609          return WPTERR_GENERAL;      int i, rc, n, k_pos=0;
610      }      
611      pos = listview_get_curr_pos( lv );      if (listview_get_curr_pos (lv) == -1) {
612      if( pos == -1 ) {          msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
613          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );          return -1;
614          return WPTERR_GENERAL;      }
615      }          
616      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );      if (listview_count_items (lv, 1) > 8) {
617      if( get_pubkey( keyid, &key ) )          i = msg_box (NULL, _("Do you really want to confirm each key?"),
618          BUG( NULL );                       _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
619      s = gpgme_key_get_string_attr( key, GPGME_ATTR_NAME, NULL, 0 );          if (i == IDCANCEL)
620      GetTempPath (sizeof tmp-1, tmp);              return 0;
621      strncat (tmp, s, sizeof tmp-200);          if (i != IDNO)
622      strncat (tmp, ".asc", sizeof tmp-200);              confirm = 1;
623      p = fm_quote_file (tmp);      }
624        else
625      rc = gpgme_recipients_new( &rset );          confirm = 1;
626      if( !rc )  
627          rc = gpgme_recipients_add_name( rset, keyid );      n = listview_count_items (lv, 0);
628      if( !rc )      rset = (gpgme_key_t *)calloc (n+1, sizeof (gpgme_key_t));
629          rc = gpgme_new( &ctx );      if (!rset)
630      if( !rc ) {          BUG (NULL);
631          gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );      for (i = 0; i < n; i++) {
632          rc = gpgme_op_file_export( ctx, rset, p );          if (listview_get_item_state(lv, i)) {
633      }              key = (gpgme_key_t)listview_get_item2 (lv, i);
634      if( rc )              if (!key)
635          msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );                  BUG (NULL);
636      else              seckey_type = km_check_for_seckey (lv, i, NULL);
637          mapi_send_pubkey (keyid, tmp);              if (confirm && !seckey_type) {
638      free_if_alloc( p );                  p = key_get_info (key, 0);
639      gpgme_recipients_release( rset );                  rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
640      gpgme_release( ctx );                                    _("Do you really want to delete this key?\n\n"
641      return rc;                                  "%s"), p);
642  }                  if (rc == IDYES)
643                        rset[k_pos++] = key;
644                    with_seckey = 0;
645  static void                  free_if_alloc (p);
646  km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)              }
647  {              else if (confirm) {
648      int idx;                  p = key_get_info (key, 1);
649      char keyid[32];                  rc = log_box (_("Key Manager"), MB_YESNO|MB_ICONWARNING,                
650      const char *t;                                _("Do you really want to delete this KEY PAIR?\n\n"
651                                    "Please remember that you are not able to decrypt\n"
652      if (pos != 0)                                  "messages you stored with this key any longer.\n"
653          idx = pos;                                  "\n"
654      else                                  "%s"), p);
655          idx = listview_get_curr_pos (lv);                  if( rc == IDYES ) {
656      if (idx != -1)                      if (seckey_type == 2)
657      {                          msg_box (dlg, _("The actual secret key is stored on a smartcard.\n"
658          listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);                                          "Only the public key and the secret key \n"
659          t = keyid;                                          "placeholder will be deleted.\n"),
660          if (!strncmp (keyid, "0x", 2))                                          _("Key Manager"), MB_OK);
661              t += 2;                      rset[k_pos++] = key;
662          hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);                  }
663      }                  with_seckey = 1;
664  }                  free_if_alloc (p);
665                }
666                else {
667  void                  with_seckey = 1;
668  km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)                  get_pubkey (keyid, &key);
669  {                  rset[k_pos++] = key;
670      int idx, id, i;              }
671                }
672      if (kserver_check_inet_connection ())      }
673      {      
674          msg_box (dlg, _("Could not connect to keyserver, abort procedure."),      if (k_pos == 0) {
675                   _("Key Manager"), MB_ERR);          free (rset);
676          return;          return 0;
677      }      }
678      idx = listview_count_items (lv, 0);  
679      if (listview_count_items (lv, 1) == idx) {      err = gpgme_new (&ctx);
680          id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);      if (err)
681          if (id == IDNO)          BUG (NULL);
682              return;      n = k_pos;
683          for (i = 0; i < idx; i++)      for (i=0; i < k_pos; i++) {
684              km_refresh_one_key (lv, dlg, i);          err = gpgme_op_delete (ctx, rset[i], with_seckey);
685      }          if (err)
686      else if (idx == 1)              msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
687          km_refresh_one_key (lv, dlg, 0);          else
688      else {              n--;
689          for (i=0; i < listview_count_items (lv, 0); i++) {      }
690              if (listview_get_item_state (lv, i))      if (n == 0)
691                  km_refresh_one_key (lv, dlg, i);          show_msg (dlg, 1500, _("GnuPG Status: Finished"));      
692          }      gpgme_release (ctx);
693      }      listview_del_items (lv);
694  } /* km_refresh_from_keyserver */      delete_keys_from_cache (rset, k_pos);
695        free (rset);
696    
697  void      return (int)err;
698  km_set_clip_info( const char *uid )  }
699  {      
700      char buf[256];  
701        /* Send the select key in @lv to the keyserver @host:@port. */
702      km_get_clip_info (uid, buf, 255);      int
703      set_clip_text( NULL, buf, strlen( buf ) );  km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char *host, u16 port)
704  } /* km_set_clip_info */  {
705        gpgme_key_t key;
706        int id;
707        
708  int      id = listview_get_curr_pos (lv);
709  km_key_is_v3( listview_ctrl_t lv, int pos )      if (id == -1) {
710  {          msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
711      gpgme_key_t pk;          return WPTERR_GENERAL;
712      const char * fpr;      }
713      unsigned long algo;  
714      char keyid[32];      key = (gpgme_key_t)listview_get_item2 (lv, id);
715        if (!key)
716      listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );          BUG (NULL);
717      if( get_pubkey( keyid, &pk ) )      id = log_box (_("Key Manager"), MB_YESNO,
718          BUG( NULL );                    _("Do you really want to send '%s' to keyserver %s?"),
719      algo = gpgme_key_get_ulong_attr( pk, GPGME_ATTR_ALGO, NULL, 0 );                      key->subkeys->keyid+8, host);
720      fpr = gpgme_key_get_string_attr( pk, GPGME_ATTR_FPR, NULL, 0 );      if (id == IDYES)
721      return strlen( fpr ) == 32 && algo == GPGME_PK_RSA? 1 : 0;          hkp_send_key (dlg, host, port, key->subkeys->keyid+8);
722  } /* km_key_is_v3 */  
723        return 0;
724    }
725  void  
726  km_update_default_key_str (HWND dlg, int * ret_len)  
727  {  /* Send the selected key in @lv via MAPI to a mail recipient. */
728      char * keyid, defkeyinf[512];  int
729      const char * fmt;  km_send_to_mail_recipient (listview_ctrl_t lv, HWND dlg)
730        {
731      keyid = get_gnupg_default_key ();      gpgme_key_t key;
732      if (!keyid)      gpgme_ctx_t ctx=NULL;
733          BUG (0);      gpgme_data_t out;
734      if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')      gpgme_error_t rc;
735          || (keyid[0] == '0' && keyid[1] == 'x') )      char tmp[128];
736          fmt = _("Default Key: %s");      char *fname;
737      else      int pos;
738          fmt = _("Default Key: 0x%s");  
739      _snprintf( defkeyinf, sizeof defkeyinf - 1, fmt, keyid );      if (listview_count_items (lv, 1) > 1) {
740      SetWindowText( dlg, defkeyinf );          msg_box (dlg, _("Please only select one key."),
741      *ret_len = strlen( defkeyinf );                   _("Key Manager"), MB_INFO|MB_OK);
742      free_if_alloc( keyid );          return WPTERR_GENERAL;
743  } /* km_return_default_key_str */      }
744        pos = listview_get_curr_pos (lv);
745        if (pos == -1) {
746  void          msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
747  km_complete_status_bar( HWND sb, listview_ctrl_t lv, int startpos )          return WPTERR_GENERAL;
748  {      }
749      char text[384];      key = (gpgme_key_t)listview_get_item2 (lv, pos);
750      int nkeys = 0, nsec = 0, i;      if (!key)
751            BUG (NULL);
752      GetWindowText( sb, text, sizeof text -1 );  
753      nkeys = listview_count_items( lv, 0 );      GetTempPath (sizeof (tmp)-1, tmp);
754      for( i = 0; i < nkeys; i++ ) {      if (tmp[strlen (tmp)-1] == '\\')
755          if( km_check_for_seckey( lv, i, NULL ) )          tmp[strlen (tmp)-1] = 0;
756              nsec++;      fname = make_filename (tmp, key->uids->name, "asc");
757      }      for (pos=0; pos < (int)strlen (fname); pos++) {
758      _snprintf( text+startpos, sizeof text-1, "                %d keys (%d secret keys)", nkeys, nsec );          if (fname[pos] == ' ')
759      SetWindowText( sb, text );              fname[pos] = '_';
760  } /* km_complete_status_bar */      }
761    
762        rc = gpgme_new (&ctx);
763  void      if (rc)
764  km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)          BUG (NULL);
765  {      rc = gpgme_data_new (&out);
766      gpgme_error_t err;      if (rc)
767      gpgme_ctx_t ctx;          BUG (NULL);
768      gpgme_editkey_t ek;  
769      char keyid[32];      gpgme_set_armor (ctx, 1);
770        rc = gpgme_op_export (ctx, key->subkeys->keyid, 0, out);
771      listview_get_item_text (lv, pos, 1, keyid, 31);      if (rc)
772      err = gpgme_new (&ctx);          msg_box (dlg, gpgme_strerror (rc), _("Key Manager"), MB_ERR);
773      if (err)      else
774          BUG (0);          mapi_send_pubkey (key->subkeys->keyid+8, fname);
775      err = gpgme_editkey_new (&ek);  
776      if (err)      gpg_data_release_and_set_file (out, fname);
777          BUG (0);      gpgme_release (ctx);
778      gpgme_set_edit_ctx (ctx, ek, GPGME_EDITKEY_TRUST);      free_if_alloc (fname);
779      gpgme_editkey_trust_set (ek, 5);      return rc;
780    }
781      err = gpgme_op_editkey (ctx, keyid);  
782      if (err)  
783          msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);  static void
784      else {  km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
785          show_msg (dlg, 1500, _("GnuPG Status: Finished"));  {
786          keycache_set_reload (1);      gpgme_key_t key;
787      }      int idx;
788    
789      gpgme_release (ctx);      if (pos != 0)
790      gpgme_editkey_release (ek);              idx = pos;
791  }      else
792            idx = listview_get_curr_pos (lv);
793        if (idx != -1) {
794  gpg_optfile_t          key = (gpgme_key_t)listview_get_item2 (lv, idx);
795  km_groupdb_open( void )          hkp_recv_key (dlg, default_keyserver, default_keyserver_port,
796  {                              key->subkeys->keyid+8, 0, KM_KS_REFRESH);
797      gpg_optfile_t opt;      }
798      char * optfile;  }
799      int err = 0;  
800        
801      optfile = get_gnupg_cfgfile();  /* Refresh all keys from the default keyserver. */
802      if( !optfile )  void
803          BUG( NULL );  km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
804      if( parse_gpg_options( optfile, &opt ) )  {
805          err = 1;      int idx, id, i;
806      free_if_alloc( optfile );      
807      return err? NULL : opt;      if (kserver_check_inet_connection ()) {
808  } /* km_groupdb_open */          msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
809                     _("Key Manager"), MB_ERR);
810            return;
811  int      }
812  km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )      idx = listview_count_items (lv, 0);
813  {        if (listview_count_items (lv, 1) == idx) {
814      gpgme_keycache_t kc;          id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"),
815      gpgme_key_t pk;                        _("Key Manager"), MB_YESNO);
816      gpg_optfile_t opt;          if (id == IDNO)
817      gpg_group_t grp;                  return;
818      gpg_member_t mbr;          for (i = 0; i < idx; i++)
819      int no_trust = 0, n;              km_refresh_one_key (lv, dlg, i);
820        }
821      kc = keycache_get_ctx( 1 );      else if (idx == 1)
822      if( !kc )          km_refresh_one_key (lv, dlg, 0);
823          BUG( NULL );      else {
824            for (i=0; i < listview_count_items (lv, 0); i++) {
825      opt = km_groupdb_open( );              if (listview_get_item_state (lv, i))
826      if( !opt )                  km_refresh_one_key (lv, dlg, i);
827          return WPTERR_FILE_OPEN;          }
828            }
829      grp = find_group( opt, name );  }
830      if( !grp )  
831          return WPTERR_GENERAL;  
832        void
833      /* we are paranoid and check that all group members exist in the  km_set_clip_info (const char *uid)
834         key cache. there is no need that it is really the real key, but  {    
835         an entry should be available. the rest is up to GPG. */      char buf[256];
836      for( mbr = grp->list; mbr; mbr = mbr->next ) {      
837          if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )      key_get_clip_info (uid, buf, 255);    
838              BUG( NULL );      set_clip_text (NULL, buf, strlen (buf));
839          n = gpgme_key_count_items( pk, GPGME_ATTR_USERID );  }
840          while( n-- ) {  
841              const char * s = gpgme_key_get_string_attr( pk, GPGME_ATTR_USERID, NULL, n );  
842              if( s && stristr( s, mbr->name )  
843                  && gpgme_key_get_ulong_attr( pk, GPGME_ATTR_VALIDITY, NULL, n ) < 3 )  /* Return TRUE if the key in the list @lv at pos @pos is an
844                  no_trust++;     old version 3 key. */
845          }  int
846      }  km_key_is_v3 (listview_ctrl_t lv, int pos)
847    {
848      gpgme_recipients_add_name( rset, name );      gpgme_key_t pk;
849      release_gpg_options( opt );  
850            pk = (gpgme_key_t)listview_get_item2 (lv, pos);
851      return no_trust;      if (!pk)
852  } /* km_groupdb_expand_recipients */          BUG (NULL);
853        if (strlen (pk->subkeys->fpr) == 32 &&
854            pk->subkeys->pubkey_algo == GPGME_PK_RSA)
855  static HTREEITEM          return -1;
856  km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )      return 0;
857  {  }
858      TVINSERTSTRUCT tvis;  
859      HTREEITEM node;  
860        /* Update the default key entry in the status bar for dialog @dlg. */
861      memset( &tvis, 0, sizeof tvis );  void
862      tvis.hParent = parent;  km_update_default_key_str (HWND dlg)
863      tvis.hInsertAfter = TVI_LAST;  {
864      tvis.item.mask = TVIF_TEXT;      char *keyid, defkeyinf[512];
865      tvis.item.pszText = (char *)text;      const char *fmt;
866      node = TreeView_InsertItem( tree, &tvis );      
867      return node;      /* XXX: also show the name? */
868  } /* km_tv_insert_item */      keyid = get_gnupg_default_key ();
869        if (!keyid)
870            return;
871  int      if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
872  km_groups_new( km_group_t *r_gc, HWND ctrl )          || (keyid[0] == '0' && keyid[1] == 'x') )
873  {          fmt = _("Default Key: %s");
874      km_group_t gc;      else
875                fmt = _("Default Key: 0x%s");
876      gc = new km_group_s;      _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
877      if (!gc)      SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
878          BUG (NULL);      free_if_alloc (keyid);
879      gc->tree = ctrl;  }
880      gc->gh = km_groupdb_open ();  
881      *r_gc = gc;  
882      return 0;  /* Count all keys and show from @lv results in the status bar @sb. */
883  } /* km_groups_new */  void
884    km_update_status_bar (HWND sb, listview_ctrl_t lv)
885    {
886  void      char txt_sec[128], txt_pub[128];
887  km_groups_sync( km_group_t gc )      int nkeys = 0, nsec = 0;
888  {      int i;
889      char * optfile;  
890        nkeys = listview_count_items (lv, 0);
891      optfile = get_gnupg_cfgfile ();      for (i = 0; i < nkeys; i++) {
892      if( !optfile )          if (km_check_for_seckey (lv, i, NULL))
893          BUG( NULL );              nsec++;
894      commit_gpg_options( optfile, gc->gh );      }
895      free_if_alloc( optfile );      _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
896      gc->need_sync = 0;      _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
897  } /* km_groups_sync */      SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
898        SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
899    }
900  void  
901  km_groups_release (km_group_t gc)  
902  {  /* Set trust of selected key in @lv (at @pos) to ultimate. */
903      if( gc ) {  int
904          /* xxx: this reset the default key (sync=1) */  km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
905          gc->need_sync=0;  {
906          if (gc->need_sync)      gpgme_error_t err;
907              km_groups_sync (gc);      gpgme_key_t key;
908          if (gc->gh)      GpgKeyEdit *ke;
909              release_gpg_options( gc->gh );  
910          gc->gh = NULL;      key = (gpgme_key_t)listview_get_item2 (lv, pos);
911          gc->tree = NULL;      if (!key)
912          delete gc;          BUG (NULL);
913      }          ke = new GpgKeyEdit (key->subkeys->keyid);
914  } /* km_groups_release */      if (!ke)
915            BUG (0);
916    
917  int      err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
918  km_groups_load( km_group_t gc )      if (err)
919  {              msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
920      HTREEITEM n;      else
921      gpg_group_t grp, g;          show_msg (dlg, 1500, _("GnuPG Status: Finished"));
922      gpg_member_t mbr;  
923      u32 gid = 0;      delete ke;
924            return (int)err;
925      if( !gc->gh )  }
926          return 0;  
927      grp = gc->gh->grp;  
928      if( !grp )  void
929          return 0; /* no groups */  km_find_key (HWND dlg, listview_ctrl_t lv)
930            {
931      for( g = grp; g; g = g->next ) {      int oldpos = listview_get_curr_pos (lv);
932          n = km_tv_insert_item( gc->tree, NULL, g->name );      int n;
933          for( mbr = g->list; mbr; mbr = mbr->next ) {      char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
934              if( mbr->used && mbr->name )      if (name == NULL)
935                  km_tv_insert_item( gc->tree, n, mbr->name );          return;
936          }      if (oldpos < 0)
937      }          oldpos = 0;
938      DragAcceptFiles( gc->tree, TRUE );      n = listview_find (lv, name);
939      gc->need_sync = 0;      if (n != -1) {
940      return 0;          listview_select_one (lv, n);
941  } /* km_groups_load */          listview_scroll (lv, oldpos, n);
942        }
943        else {
944  int          const char *s = _("String pattern \"%s\" not found.");
945  km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )          char *p = new char[strlen (s) + strlen (name) + 2];
946  {          if (!p)
947      TVITEM tvi;              BUG (0);
948      char uid[128], valid[64], text[128];          sprintf (p, s, name);
949      int i_valid;          msg_box (dlg, p, _("Key Manager"), MB_INFO);
950                free_if_alloc (p);
951      memset( &tvi, 0, sizeof tvi );      }
952      tvi.hItem = TreeView_GetSelection( gc->tree );      free_if_alloc (name);
953      tvi.pszText = text;  }
     tvi.cchTextMax = sizeof text -1;  
     tvi.mask = TVIF_TEXT;  
     TreeView_GetItem( gc->tree, &tvi );  
       
       
     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );  
     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );  
       
     if( strstr( valid, "Ultimate" ) )  
         i_valid = 5;      
     else if( !strstr( valid, "Full" ) )  
         i_valid = 4;  
     else if( !strstr( valid, "Marginal" ) )  
         i_valid = 3;  
     else  
         i_valid = 0;  
       
     /* we can't add the full name. one way would be to use the first  
        text until a space appears.  
     group_add_entry(&gc->gh, gid, i_valid, uid);  
     treeview_add_item(gc->tree, tvi.hItem, uid);  
     */  
     gc->need_sync = 1;  
       
     return 0;  
 } /* km_groups_add */  
   
   
 static int  
 km_groups_del_main( km_group_t gc )  
 {  
     TVITEM tvi;  
     char text[128];  
     int id;  
       
     memset( &tvi, 0, sizeof tvi );  
     tvi.hItem = TreeView_GetSelection( gc->tree );  
     tvi.pszText = text;  
     tvi.cchTextMax = sizeof text -1;  
     tvi.mask = TVIF_TEXT;  
     TreeView_GetItem( gc->tree, &tvi );  
                               
     id = log_box( _("Key Manager"), MB_INFO_ASK,  
                    _("Do you really want to delete this group?\n\n%s"), text);  
     if( id == IDNO )  
         return 0;  
     delete_group( gc->gh, text );      
     TreeView_DeleteItem( gc->tree, &tvi );  
     gc->need_sync = 1;  
       
     return 0;  
 } /* km_groups_del */  
   
   
 static int  
 km_groups_del_entry( km_group_t gc )  
 {  
     TVITEM tvi;  
     HTREEITEM root;  
     int id;  
     char text[128], info[256];  
     gpg_group_t  grp = NULL;  
       
     memset( &tvi, 0, sizeof tvi );  
     tvi.hItem = TreeView_GetSelection( gc->tree );  
     tvi.pszText = text;  
     tvi.cchTextMax = sizeof text-1;  
     tvi.mask = TVIF_TEXT;  
     TreeView_GetItem( gc->tree, &tvi );  
       
     _snprintf( info, sizeof info -1,  
               _("Do you really want to delete this entry?\n\n%s"), text );  
       
     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );  
     if( id == IDNO )  
         return 0;  
   
     root = TreeView_GetParent( gc->tree, tvi.hItem );  
     if( root ) {  
     }  
       
     delete_member( gc->gh, /*fixme*/NULL, text );  
     TreeView_DeleteItem( gc->tree, &tvi );  
     gc->need_sync = 1;  
     return 0;  
 } /* km_groups_del_entry */  
   
   
 int  
 km_groups_del( km_group_t gc )  
 {  
     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )  
         return km_groups_del_entry( gc );  
     else  
         return km_groups_del_main( gc );  
 } /* km_groups_del */  

Legend:
Removed from v.2  
changed lines
  Added in v.128

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26