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

Diff of /trunk/Src/wptKeylist.cpp

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

revision 24 by twoaday, Sat Oct 8 10:43:08 2005 UTC revision 128 by twoaday, Mon Dec 19 13:05:59 2005 UTC
# Line 1  Line 1 
1  /* wptKeylist.cpp - Keylist element  /* wptKeylist.cpp - Keylist element
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2005 Timo Schulz
3   *      Copyright (C) 2004 Andreas Jobs   *      Copyright (C) 2004 Andreas Jobs
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
6   *   *
7   * WinPT is free software; you can redistribute it and/or   * WinPT is free software; you can redistribute it and/or
8   * modify it under the terms of the GNU General Public License   * modify it under the terms of the GNU General Public License
9   * as published by the Free Software Foundation; either version 2   * as published by the Free Software Foundation; either version 2
10   * of the License, or (at your option) any later version.   * of the License, or (at your option) any later version.
11   *     *  
12   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * General Public License for more details.   * General Public License for more details.
16   *   *
17   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
18   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
19   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20   */   */
21  #include <windows.h>  
22  #include <commctrl.h>  #ifdef HAVE_CONFIG_H
23  #include <time.h>  #include <config.h>
24    #endif
25  #include "wptCommonCtl.h"  
26  #include "wptTypes.h"  #include <windows.h>
27  #include "wptGPG.h"  #include <commctrl.h>
28  #include "wptKeylist.h"  #include <time.h>
29  #include "wptKeyManager.h"  
30  #include "wptW32API.h"  #include "wptCommonCtl.h"
31  #include "wptNLS.h"  #include "wptTypes.h"
32  #include "wptErrors.h"  #include "wptGPG.h"
33  #include "wptUTF8.h"  #include "wptKeylist.h"
34  #include "wptRegistry.h"  #include "wptKeyManager.h"
35  #include "wptContext.h"  #include "wptW32API.h"
36    #include "wptNLS.h"
37    #include "wptErrors.h"
38  #define key_is_useable(key) (!(key)->revoked && !(key)->expired && !(key)->disabled)  #include "wptUTF8.h"
39    #include "wptRegistry.h"
40  static struct listview_column_s klist_enc[] = {  #include "wptContext.h"
41      {0, 242, (char *)_("User ID")},  
42      {1, 80, (char *)_("Key ID")},  
43      {3, 46, (char *)_("Size")},  #define key_is_useable(key) (!(key)->revoked && !(key)->expired && !(key)->disabled)
44      {4, 50, (char *)_("Cipher")},  
45      {5, 70, (char *)_("Validity")},  struct key_array_s {
46      {0, 0, NULL}      char keyid[32];
47  };      int checked;
48  #define KLIST_ENC_ITEMS (DIM(klist_enc) -1)  };
49    
50  static struct listview_column_s klist[] = {  static int find_secret_key (gpgme_key_t key);
51      {0, 242, (char *)_("User ID")},  
52      {1, 78, (char *)_("Key ID")},  
53      {2, 52, (char *)_("Type")},      static key_array_s*
54      {3, 68, (char *)_("Size")},  key_array_new( size_t items )
55      {4, 66, (char *)_("Cipher")},  {
56      {5, 70, (char *)_("Validity")},      key_array_s *ka;
57      {6, 40, (char *)_("Trust")},      size_t j;
58      {7, 72, (char *) _("Creation")},      
59      {0, 0, NULL}      if( items == 0 )
60  };          return NULL;
61  #define KLIST_ITEMS (DIM(klist) - 1)      ka = new key_array_s[items + 1];
62        if( ka == NULL )
63  struct key_array_s {          return NULL;    
64      char keyid[32];      for ( j = 0; j < items; j++ )
65      int checked;          ka[j].checked = 0;
66  };      return ka;
67    } /* key_array_new */
68  static int find_secret_key( gpgme_key_t key );  
69    
70    static void
71  static key_array_s*  key_array_release( key_array_s *ka )
72  key_array_new( size_t items )  {
73  {      free_if_alloc( ka );
74      key_array_s *ka;  } /* key_array_release */
75      size_t j;  
76        
77      if( items == 0 )  static int
78          return NULL;  key_array_search( key_array_s *ka, size_t items, const char *keyid )
79      ka = new key_array_s[items + 1];  {
80      if( ka == NULL )      size_t j;
81          return NULL;          
82      for ( j = 0; j < items; j++ )      /* fixme: we need a faster search method */
83          ka[j].checked = 0;      for( j = 0; j < items; j++ ) {
84      return ka;          if( !strcmp( keyid, ka[j].keyid ) )
85  } /* key_array_new */              return 1;  
86        }
87        
88  static void      return 0;
89  key_array_release( key_array_s *ka )  } /* key_array_search */
90  {  
91      free_if_alloc( ka );  
92  } /* key_array_release */  gpgme_user_id_t
93    get_nth_userid (gpgme_key_t key, int idx)
94    {
95  static int      gpgme_user_id_t t;
96  key_array_search( key_array_s *ka, size_t items, const char *keyid )  
97  {      if (!key->uids)
98      size_t j;          return NULL;
99            t = key->uids;
100      /* fixme: we need a faster search method */      while (idx-- && t->next)
101      for( j = 0; j < items; j++ ) {          t = t->next;
102          if( !strcmp( keyid, ka[j].keyid ) )      return t;
103              return 1;    }
104      }  
105        
106      return 0;  int
107  } /* key_array_search */  count_userids (gpgme_key_t key)
108    {
109        gpgme_user_id_t u;
110  gpgme_user_id_t      int n = 1;
111  get_nth_userid (gpgme_key_t key, int idx)  
112  {      u = key->uids;
113      gpgme_user_id_t t;      if (!u)
114            return 0;
115      if (!key->uids)      while (u->next) {
116          return NULL;          u = u->next;
117      t = key->uids;          n++;
118      while (idx-- && t->next)      }
119          t = t->next;      return n;
120      return t;  }
121  }  
122    
123    gpgme_subkey_t
124  int  get_nth_key (gpgme_key_t key, int idx)
125  count_userids (gpgme_key_t key)  {
126  {      gpgme_subkey_t t;
127      gpgme_user_id_t u;  
128      int n = 0;      if (!key->subkeys)
129            return NULL;
130      u = key->uids;      t = key->subkeys;
131      if (!u)      while (idx-- && t->next)
132          return 0;          t = t->next;
133      while (u->next) {      return t;
134          u = u->next;  }
135          n++;  
136      }  
137      return n;  int
138  }  count_subkeys (gpgme_key_t key)
139    {
140        gpgme_subkey_t k;
141  gpgme_subkey_t      int n = 1;
142  get_nth_key (gpgme_key_t key, int idx)  
143  {      k = key->subkeys;
144      gpgme_subkey_t t;      if (!k)
145            return 0;
146      if (!key->subkeys)      while (k->next) {
147          return NULL;          k = k->next;
148      t = key->subkeys;          n++;
149      while (idx-- && t->next)      }
150          t = t->next;      return n;
151      return t;  }
152  }  
153    
154  int  gpgme_key_sig_t
155  count_subkeys (gpgme_key_t key)  get_selfsig (gpgme_user_id_t uid, const char *keyid, int first)
156  {  {
157      gpgme_subkey_t k;      gpgme_key_sig_t s, self_sig=NULL;
158      int n = 1;      long timestamp=0;
159    
160      k = key->subkeys;      for (s = uid->signatures; s; s = s->next) {
161      if (!k)          if (!strcmp (s->keyid+8, keyid) && s->timestamp > timestamp) {
162          return 0;              self_sig = s;
163      while (k->next) {              timestamp = s->timestamp;
164          k = k->next;              if (first)
165          n++;                  break;
166      }          }
167      return n;      }
168  }      return self_sig;
169    }
170    
171  gpgme_key_sig_t  
172  get_nth_uid_sig (gpgme_user_id_t uid, int idx)  const char*
173  {  get_key_pubalgo2 (gpgme_pubkey_algo_t alg)
174      gpgme_key_sig_t ks;  {
175        switch (alg) {
176      if (!uid->signatures)      case GPGME_PK_DSA: return "D";
177          return NULL;      case GPGME_PK_RSA: return "R";
178      ks = uid->signatures;      case GPGME_PK_ELG: return "G";
179      while (idx-- && ks->next)      default: return "?";
180          ks = ks->next;      }
181      return ks;      return "?";
182  }  }
183    
184  int  const char*
185  count_uid_sigs (gpgme_user_id_t uid)  get_key_algo (gpgme_key_t key, int keyidx)
186  {  {
187      gpgme_key_sig_t k;      static char algo_id[128];
188      int n = 0;      gpgme_subkey_t k;
189        char alg[32];
190      if (!uid->signatures)      const char *subalg;
191          return 0;      int n=0;
192      k = uid->signatures;      
193      while (k->next)      if (keyidx > 0) {
194          n++;          k = get_nth_key (key, keyidx-1);
195      return n;          subalg =  get_key_pubalgo (k->pubkey_algo);
196  }          _snprintf( algo_id, DIM (algo_id)-1, "%s", subalg);
197            return algo_id;
198        }
199  const char*      strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo));
200  get_key_algo (gpgme_key_t key, int keyidx)      n = count_subkeys (key);
201  {      if (n > 1) {
202      static char algo_id[128];          k = get_nth_key (key, n-1);
203      gpgme_subkey_t k;          subalg = get_key_pubalgo (k->pubkey_algo);
204      char alg[32];          _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg);
205      const char *subalg;          return algo_id;
206      int n=0;      }
207            return get_key_pubalgo (key->subkeys->pubkey_algo);
208      if (keyidx > 0) {  } /* get_key_algo */
209          k = get_nth_key (key, keyidx-1);  
210          subalg =  get_key_pubalgo (k->pubkey_algo);  
211          _snprintf( algo_id, DIM (algo_id)-1, "%s", subalg);  const char*
212          return algo_id;  get_key_created (long timestamp)
213      }  {
214      strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo));      static char timebuf[128];
215      n = count_subkeys (key);      struct tm *warp;
216      if (n > 1) {  
217          k = get_nth_key (key, n-1);      if (timestamp == 0 || timestamp == -1)
218          subalg = get_key_pubalgo (k->pubkey_algo);          return "????" "-??" "-??";
219          _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg);      warp = localtime( &timestamp );
220          return algo_id;      _snprintf( timebuf, sizeof timebuf - 1, "%04d-%02d-%02d",
221      }                  warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );
222      return get_key_pubalgo (key->subkeys->pubkey_algo);      return timebuf;
223  } /* get_key_algo */  } /* get_key_created */
224    
225    
226  const char*  /* Return a string presentation of the time @timestamp. */
227  get_key_created( long timestamp )  const char*
228  {  get_key_expire_date (long timestamp)
229      static char timebuf[128];  {
230      struct tm *warp;      static char timebuf[64];
231        struct tm *warp;
232      if (timestamp == 0 || timestamp == -1)  
233          return "????-??-??";      if( !timestamp )
234      warp = localtime( &timestamp );          return _("Never");
235      _snprintf( timebuf, sizeof timebuf - 1, "%04d-%02d-%02d",      warp = localtime( &timestamp );
236                  warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );      _snprintf (timebuf, sizeof timebuf -1, "%04d-%02d-%02d",
237      return timebuf;                 warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday);
238  } /* get_key_created */      return timebuf;
239    }
240    
241  const char*  
242  get_key_expire_date (long timestamp)  const char*
243  {  get_key_type (gpgme_key_t key)
244      static char timebuf[64];  {
245      struct tm *warp;      int type = find_secret_key (key);
246    
247      if( !timestamp )      if (type == 1)
248          return _("Never");          return _("Key Pair");
249      warp = localtime( &timestamp );      else if (type == 2)
250      _snprintf( timebuf, sizeof timebuf -1, "%04d-%02d-%02d",          return _("Key Pair (Card)");
251                  warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );      return _("Public Key");
252      return timebuf;  } /* get_key_type */
253  } /* get_key_expire_date */  
254    
255    const char*
256  const char*  get_key_size (gpgme_key_t key, int keyidx)
257  get_key_type (gpgme_key_t key)  {
258  {      static char size_id[64];
259      if (find_secret_key (key))      gpgme_subkey_t k;
260          return _("Key Pair");      int n, size_main, size_sub;
261      return _("Public Key");      
262  } /* get_key_type */      if (keyidx > 0) {
263            k = get_nth_key (key, keyidx-1);
264            size_main = k->length;
265  const char*          _snprintf (size_id, DIM (size_id)-1, "%d", size_main);
266  get_key_size (gpgme_key_t key, int keyidx)          return size_id;
267  {      }
268      static char size_id[64];      size_main =  key->subkeys->length;
269      gpgme_subkey_t k;      n = count_subkeys (key);
270      int n, size_main, size_sub;      if (n > 1) {
271                k = get_nth_key (key, n-1);
272      if (keyidx > 0) {          size_sub = k->length;
273          k = get_nth_key (key, keyidx-1);          _snprintf( size_id, sizeof (size_id) - 1, "%d/%d", size_main, size_sub );
274          size_main = k->length;          return size_id;
275          _snprintf (size_id, DIM (size_id)-1, "%d", size_main);      }
276          return size_id;      _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main );
277      }      return size_id;
278      size_main =  key->subkeys->length;  } /* get_key_size */
279      n = count_subkeys (key);  
280      if (n > 1) {  
281          k = get_nth_key (key, n-1);  const char*
282          size_sub = k->length;  get_key_pubalgo (gpgme_pubkey_algo_t alg)
283          _snprintf( size_id, sizeof (size_id) - 1, "%d/%d", size_main, size_sub );  {
284          return size_id;      switch (alg) {
285      }      case GPGME_PK_DSA: return "DSA";
286      _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main );      case GPGME_PK_ELG:
287      return size_id;      case GPGME_PK_ELG_E: return "ELG";
288  } /* get_key_size */      case GPGME_PK_RSA: return "RSA";
289        default: return "???";
290        }
291  const char*      return "???";
292  get_key_pubalgo (gpgme_pubkey_algo_t alg)  }
293  {  
294      switch (alg) {  const char *
295      case GPGME_PK_DSA: return "DSA";  get_key_fpr (gpgme_key_t key)
296      case GPGME_PK_ELG:  {
297      case GPGME_PK_ELG_E: return "ELG";      static char fpr_md[64];
298      case GPGME_PK_RSA: return "RSA";      const char *fpr;
299      }      char t[16], tmp[40];
300      return "???";      size_t i=0;
301  }      
302        memset (fpr_md, 0, sizeof (fpr_md));
303  const char *      fpr = key->subkeys->fpr;
304  get_key_fpr (gpgme_key_t key)      if (!fpr || !*fpr) {
305  {          memset (tmp, '0', 40);
306      static char fpr_md[64];          fpr = tmp;
307      const char *fpr;      }
308      char t[16], tmp[40];      if (strlen (fpr) == 32) {
309      size_t i=0;          strcat (fpr_md, "        ");
310                for (i=0; i < strlen (fpr)/2; i++) {
311      memset (fpr_md, 0, sizeof (fpr_md));              sprintf (t, "%c%c ", fpr[2*i], fpr[2*i+1]);
312      fpr = key->subkeys->fpr;              strcat (fpr_md, t);
313      if (!fpr || !*fpr) {          }
314          memset (tmp, '0', 40);      }
315          fpr = tmp;      else {
316      }          strcat (fpr_md, " ");
317      if (strlen (fpr) == 32) {          for (i = 0; i < strlen (fpr) / 4; i++) {
318          strcat (fpr_md, "        ");              sprintf (t, "%c%c%c%c ", fpr[4*i], fpr[4*i+1], fpr[4*i+2], fpr[4*i+3]);
319          for (i=0; i < strlen (fpr)/2; i++) {              strcat (fpr_md, t);
320              sprintf (t, "%c%c ", fpr[2*i], fpr[2*i+1]);          }
321              strcat (fpr_md, t);      }
322          }      return fpr_md;
323      }  } /* get_key_fpr */
324      else {  
325          strcat (fpr_md, " ");  
326          for (i = 0; i < strlen (fpr) / 4; i++) {  const char *
327              sprintf (t, "%c%c%c%c ", fpr[4*i], fpr[4*i+1], fpr[4*i+2], fpr[4*i+3]);  get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)
328              strcat (fpr_md, t);  {
329          }      if (key)
330      }          val = key->owner_trust; /* uididx?? */
331      return fpr_md;      switch (val) {
332  } /* get_key_fpr */      case GPGME_VALIDITY_UNKNOWN:
333        case GPGME_VALIDITY_UNDEFINED:    
334            return _("None");
335  const char *      case GPGME_VALIDITY_NEVER:    
336  get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)          return _("Never");
337  {      case GPGME_VALIDITY_MARGINAL:
338      if (key)          return _("Marginal");
339          val = key->owner_trust; /* uididx?? */      case GPGME_VALIDITY_FULL:
340      switch (val) {      case GPGME_VALIDITY_ULTIMATE:
341      case GPGME_VALIDITY_UNKNOWN:          return _("Full");
342      case GPGME_VALIDITY_UNDEFINED:          }
343          return "None";      return "";
344      case GPGME_VALIDITY_NEVER:      }
345          return "Never";  
346      case GPGME_VALIDITY_MARGINAL:  
347          return "Marginal";  const char *
348      case GPGME_VALIDITY_FULL:  get_key_trust (gpgme_key_t key, int uididx, int listmode)
349      case GPGME_VALIDITY_ULTIMATE:  {
350          return "Full";      return get_key_trust2 (key, 0, uididx, listmode);
351      }  }
352      return "";  
353  }  
354    const char *
355    get_key_trust_str (int val)
356  const char *  {
357  get_key_trust (gpgme_key_t key, int uididx, int listmode)      return get_key_trust2 (NULL, val, 0, 0);
358  {  }
359      return get_key_trust2 (key, 0, uididx, listmode);  
360  }  
361    /* Return the status of the key @key. */
362    char*
363  const char *  get_key_status (gpgme_key_t key, int uididx, int listmode)
364  get_key_trust_str (int val)  {
365  {      gpgme_user_id_t u;
366      return get_key_trust2 (NULL, val, 0, 0);      const char *attr;
367  }      u32 key_attr =0;
368    
369        if (uididx < 0 || count_userids (key) > uididx)
370  char*          uididx = 0;
371  get_key_status (gpgme_key_t key, int uididx, int listmode)      if (listmode) {
372  {          const char *s;
373      gpgme_user_id_t u;          if (key->revoked)
374      char fmt[64], * p;              s = _("Revoked");
375      const char * attr;          else if (key->expired)
376      int i = 0;              s = _("Expired");
377      u32 key_attr =0;          else if (key->disabled)
378                s = _("Disabled");
379      if (uididx < 0 || count_userids (key) > uididx)          else
380          uididx = 0;              s = "";
381      memset (fmt, 0, sizeof (fmt));          /* if the key has a special status, we don't continue to figure out
382      if (listmode) {             what any user-id validities. */
383          if (key->revoked)          if (*s)
384              sprintf (fmt, "Revoked");              return m_strdup (s);
385          else if (key->expired)      }
386              sprintf (fmt, "Expired");      u = get_nth_userid (key, uididx);
387          else if (key->disabled)      key_attr = u->validity;
388              sprintf (fmt, "Disabled");      attr = get_key_trust2 (NULL, key_attr, 0, 0);
389          /* if the key has a special status, we don't continue to figure out      return m_strdup (attr);
390             what any user-id validities. */  }
391          if (strlen (fmt) > 0)  
392              return m_strdup (fmt);  
393      }  /* Integer comparsion of @a and @b.
394      u = get_nth_userid (key, uididx);     Return values: same as in strcmp. */
395      key_attr = u->validity;  static inline int
396      attr = get_key_trust2 (NULL, key_attr, 0, 0);  int_cmp (int a, int b)
397      p = new char[strlen( attr ) + 2];  {
398      if (!p)      if (a == b) return 0;      
399          BUG (NULL);      else if (a > b) return 1;
400      sprintf (p, "%s", attr);      else return -1;
401      return p;      return 0;
402  } /* get_key_status */  }
403    
404    
405  static inline int  /* To allow to sort the keys, we need to take care of
406  int_cmp( int a, int b )     the expired/revoke status also. */
407  {  static int
408      if( a == b ) return 0;        get_ext_validity (gpgme_key_t k)
409      else if( a > b ) return 1;  {
410      else return -1;      if (k->revoked)
411      return 0;          return GPGME_VALIDITY_ULTIMATE+1;
412  }      else if (k->expired)
413            return GPGME_VALIDITY_ULTIMATE+2;
414        return k->uids->validity;
415  static int CALLBACK  }
416  keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)  
417  {  
418      static char tmpa[128], tmpb[128];      /* List view sorting callback. */
419      gpgme_key_t a, b;      static int CALLBACK
420      const char *aa = NULL, *bb = NULL;  keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
421      long ta, tb;  {
422      int na = 0, nb = 0;      gpgme_key_t a, b;
423      int cmpresult = 0;      int cmpresult = 0;
424            
425      a = (gpgme_key_t)first;      a = (gpgme_key_t)first;
426      b = (gpgme_key_t)second;          b = (gpgme_key_t)second;
427            if (!a || !b)
428      switch( sortby & ~KEYLIST_SORT_DESC ) {          BUG (NULL);
429      case KEY_SORT_USERID:      
430          aa = a->uids->uid;      switch (sortby & ~KEYLIST_SORT_DESC) {
431          bb = b->uids->uid;      case KEY_SORT_USERID:
432          cmpresult = strcmpi (aa? aa : "", bb? bb : "");          cmpresult = strcmpi (a->uids->uid, b->uids->uid);
433          break;          break;
434                    
435      case KEY_SORT_KEYID:      case KEY_SORT_KEYID:
436          aa = a->subkeys->keyid+8;          cmpresult = strcmpi (a->subkeys->keyid+8,
437          bb = b->subkeys->keyid+8;                               b->subkeys->keyid+8);
438          cmpresult = strcmpi( aa? aa : "", bb? bb : "" );          break;
439          break;  
440        case KEY_SORT_VALIDITY:
441      case KEY_SORT_VALIDITY:          cmpresult = int_cmp (get_ext_validity (a),
442          na = a->uids->validity;                               get_ext_validity (b));
443          nb = b->uids->validity;          break;
444          cmpresult = int_cmp (na, nb);  
445          break;      case KEY_SORT_OTRUST:
446            cmpresult = int_cmp (a->owner_trust, b->owner_trust);
447      case KEY_SORT_OTRUST:          break;
448          na = a->owner_trust;  
449          nb = b->owner_trust;      case KEY_SORT_IS_SECRET:
450          cmpresult = int_cmp (na, nb);          get_seckey (a->subkeys->keyid, &a);
451          break;          get_seckey (b->subkeys->keyid, &b);
452            cmpresult = int_cmp (a? a->secret : 0, b? b->secret : 0);
453      case KEY_SORT_IS_SECRET:              break;
454          aa = a->subkeys->keyid;  
455          bb = b->subkeys->keyid;      case KEY_SORT_LEN:
456          get_seckey (aa, &a);          cmpresult = int_cmp (a->subkeys->length,
457          get_seckey (bb, &b);                               b->subkeys->length);
458          if (a)          break;
459              na = a->secret;  
460          if (b)      case KEY_SORT_CREATED:
461              nb = b->secret;          cmpresult = int_cmp (a->subkeys->timestamp,
462          cmpresult = int_cmp (na, nb);                               b->subkeys->timestamp);
463          break;          break;
464    
465      case KEY_SORT_LEN:      case KEY_SORT_ALGO:
466          na = a->subkeys->length;          cmpresult = int_cmp (a->subkeys->pubkey_algo,
467          nb = b->subkeys->length;                               b->subkeys->pubkey_algo);
468          cmpresult = int_cmp( na, nb );          break;
469          break;          
470        default:
471      case KEY_SORT_CREATED:          cmpresult = strcmpi (a->uids->uid, b->uids->uid);
472          ta = a->subkeys->timestamp;          break;
473          tb = b->subkeys->timestamp;      }
474          strcpy( tmpa, get_key_created( ta ) ); aa = tmpa;      if (sortby & KEYLIST_SORT_DESC)
475          strcpy( tmpb, get_key_created( tb ) ); bb = tmpb;          return (~cmpresult + 1);
476          cmpresult = strcmpi( aa? aa : "", bb? bb : "" );      else
477          break;          return cmpresult;
478    }
479      case KEY_SORT_ALGO:  
480          na = a->subkeys->pubkey_algo;  
481          nb = b->subkeys->pubkey_algo;  /* Return the validity of the group @grp. */
482          cmpresult = int_cmp (na, nb);  static const char*
483          break;  calc_validity (gpg_group_t grp)
484            {
485      default:      int valid = 0;
486          aa = a->uids->uid;      gpg_member_t mbr;
487          bb = b->uids->uid;      gpgme_key_t key;
488          cmpresult = strcmpi( aa? aa : "", bb? bb : "" );  
489          break;      for (mbr = grp->list; mbr; mbr = mbr->next) {
490      }          if (get_pubkey (mbr->name, &key))
491      if (sortby & KEYLIST_SORT_DESC)              continue;
492          return (~cmpresult + 1);          valid = key->uids->validity;
493      else          switch (valid) {
494          return cmpresult;          case GPGME_VALIDITY_MARGINAL:
495  } /* keylist_cmp_cb */          case GPGME_VALIDITY_NEVER:
496            case GPGME_VALIDITY_UNDEFINED:
497                return get_key_trust2 (NULL, valid, 0, 0);
498  static const char*          }
499  calc_validity( gpg_group_t grp )      }
500  {      return _("Full");
501      int level = 0, valid;  }
502      gpg_member_t mbr;  
503      gpgme_key_t key;  
504    int
505      for( mbr = grp->list; mbr; mbr = mbr->next ) {  keylist_add_groups( listview_ctrl_t lv )
506          if( get_pubkey( mbr->name, &key ) )  {
507              continue;  #if 0
508          valid = key->uids->validity;      gpg_optfile_t gh;
509          switch( valid ) {            gpg_group_t grp;
510          case GPGME_VALIDITY_MARGINAL:      const char *valid;
511          case GPGME_VALIDITY_NEVER:  
512          case GPGME_VALIDITY_UNDEFINED:      gh = km_groupdb_open( );    
513              return get_key_trust2 (NULL, valid, 0, 0);      if( !gh )  
514          }          return WPTERR_FILE_OPEN;
515      }  
516      return _("Full");      for( grp = gh->grp; grp; grp = grp->next ) {
517  } /* calc_validity */          valid = calc_validity( grp );
518            listview_add_item( lv, " " );  
519            listview_add_sub_item( lv, 0, 0, grp->name );  
520  int          listview_add_sub_item( lv, 0, 1, "gpg_group_t" );      
521  keylist_add_groups( listview_ctrl_t lv )          listview_add_sub_item( lv, 0, 2, "" );  
522  {          listview_add_sub_item( lv, 0, 3, "Unknown" );
523  #if 0          listview_add_sub_item( lv, 0, 4, valid?valid : "Unknown" );
524      gpg_optfile_t gh;      }
525      gpg_group_t grp;  #endif
526      const char *valid;      return 0;
527    } /* keylist_add_groups */
528      gh = km_groupdb_open( );      
529      if( !gh )    
530          return WPTERR_FILE_OPEN;  /* Create a listview for listing keys. Use the mode given in @mode
531       and the control is given in @ctrl. */
532      for( grp = gh->grp; grp; grp = grp->next ) {  static int
533          valid = calc_validity( grp );  keylist_build (listview_ctrl_t *r_lv, HWND ctrl, int mode)
534          listview_add_item( lv, " " );    {
535          listview_add_sub_item( lv, 0, 0, grp->name );        struct listview_column_s klist_enc[] = {
536          listview_add_sub_item( lv, 0, 1, "gpg_group_t" );            {0, 242, (char *)_("User ID")},
537          listview_add_sub_item( lv, 0, 2, "" );        {1, 80, (char *)_("Key ID")},
538          listview_add_sub_item( lv, 0, 3, "Unknown" );      {3, 46, (char *)_("Size")},
539          listview_add_sub_item( lv, 0, 4, valid?valid : "Unknown" );      {4, 50, (char *)_("Cipher")},
540      }      {5, 70, (char *)_("Validity")},
541  #endif      {0, 0, NULL}
542      return 0;      };
543  } /* keylist_add_groups */  
544        struct listview_column_s klist[] = {
545        {0, 242, (char *)_("User ID")},
546  static int      {1, 78, (char *)_("Key ID")},
547  keylist_build( listview_ctrl_t *r_lv, HWND ctrl, int mode )      {2, 52, (char *)_("Type")},    
548  {      {3, 68, (char *)_("Size")},
549      listview_ctrl_t lv;      {4, 66, (char *)_("Cipher")},
550      listview_column_t col;      {5, 70, (char *)_("Validity")},
551      int j, n = 0;      {6, 40, (char *)_("Trust")},
552      int kl_nolist = 0, rc = 0;      {7, 72, (char *)_("Creation")},
553            {0, 0, NULL}
554      rc = listview_new( &lv );      };
555      if( rc )  
556          return rc;      listview_ctrl_t lv;
557            listview_column_t col;
558      lv->ctrl = ctrl;      int j, n = 0;
559      if( (mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN) ) {      int rc = 0;
560          col = klist_enc;      
561          n = KLIST_ENC_ITEMS;      rc = listview_new (&lv);
562      }        if (rc)
563      else if( (mode & KEYLIST_SIGN) ) {          return rc;
564          col = klist_enc;      
565          n = KLIST_ENC_ITEMS - 1;      lv->ctrl = ctrl;
566      }      if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN)) {
567      else {          col = klist_enc;
568          col = klist;          n = (DIM(klist_enc) -1);
569          n = KLIST_ITEMS;      }  
570      }      else if ((mode & KEYLIST_SIGN)) {
571                col = klist_enc;
572      for( j = 0; j < n; j++ )              n = (DIM(klist_enc) - 1) - 1;
573          listview_add_column( lv, &col[j] );          }
574      listview_set_ext_style( lv );      else {
575      *r_lv = lv;          col = klist;
576                n = (DIM(klist) - 1);
577      return 0;      }
578  } /* keylist_build */      
579        for( j = 0; j < n; j++ )    
580            listview_add_column( lv, &col[j] );    
581  static void      listview_set_ext_style( lv );
582  keylist_load_keycache (listview_ctrl_t lv, int mode,      *r_lv = lv;
583                         gpgme_keycache_t pubkc, gpgme_keycache_t seckc)      
584  {      return 0;
585      gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);  }
586      gpgme_key_t key, skey;  
587      const char * keyid;  
588    static void
589      if (pubkc && seckc) {  keylist_load_keycache (listview_ctrl_t lv, int mode,
590          gpgme_keycache_rewind (pubkc);                         gpg_keycache_t pubkc, gpg_keycache_t seckc)
591          while (!gpgme_keycache_next_key (pubkc, 0, &key)) {  {
592              keyid = key->subkeys->keyid;      gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
593              if (keyid && !gpgme_keycache_find_key (seckc, keyid, 0, &skey))      gpgme_key_t key, skey;
594                  keylist_add_key (lv, mode, key);      const char * keyid;
595          }        
596      }      if (pubkc && seckc) {
597      else if (pubkc) {          gpg_keycache_rewind (pubkc);
598          gpgme_keycache_rewind (pubkc);          while (!gpg_keycache_next_key (pubkc, 0, &key)) {
599          while (!err) {                  keyid = key->subkeys->keyid;
600              err = gpgme_keycache_next_key (pubkc, 0, &key);              if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))
601              if (!err)                  keylist_add_key (lv, mode, key);
602                  keylist_add_key (lv, mode, key);          }      
603          }      }
604      }      else if (pubkc) {
605  } /* keylist_load_keycache */          gpg_keycache_rewind (pubkc);
606            while (!err) {    
607                err = gpg_keycache_next_key (pubkc, 0, &key);
608  listview_ctrl_t              if (!err)
609  keylist_load (HWND ctrl, gpgme_keycache_t pubkc, gpgme_keycache_t seckc,                  keylist_add_key (lv, mode, key);
610                int mode, int sortby)          }
611  {          }
612      listview_ctrl_t lv;  }
613      int rc = 0;      
614    
615      rc = keylist_build (&lv, ctrl, mode);  /* Load the list view @ctrl with the keys from the cache.
616      if (rc)     Return value: list view context on success. */
617          return NULL;              listview_ctrl_t
618      keylist_load_keycache (lv, mode, pubkc, seckc);  keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,
619      keylist_sort (lv, sortby);                int mode, int sortby)
620      if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN))  {    
621          keylist_add_groups (lv);      listview_ctrl_t lv;
622      return lv;      int rc = 0;    
623  } /* keylist_load */  
624        rc = keylist_build (&lv, ctrl, mode);
625        if (rc)
626  int          return NULL;            
627  keylist_reload( listview_ctrl_t lv, gpgme_keycache_t pubkc, int mode, int sortby )      keylist_load_keycache (lv, mode, pubkc, seckc);
628  {      keylist_sort (lv, sortby);
629      listview_del_all( lv );      if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN))
630      keylist_load_keycache( lv, mode, pubkc, NULL );          keylist_add_groups (lv);
631      keylist_sort( lv, sortby );      return lv;
632      return 0;  }
633  } /* keylist_reload */  
634    
635    /* Reload the given key list control @lv. */
636  void  int
637  keylist_delete( listview_ctrl_t lv )  keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby)
638  {  {
639      if( lv ) {      listview_del_all (lv);
640          listview_release( lv );      keylist_load_keycache( lv, mode, pubkc, NULL );
641      }      keylist_sort (lv, sortby);
642  } /* keylist_delete */      return 0;
643    }
644    
645  static int  
646  find_secret_key( gpgme_key_t key )  void
647  {  keylist_delete (listview_ctrl_t lv)
648      const char * keyid;  {
649      gpgme_key_t skey;        if (lv) {
650            listview_release (lv);
651      keyid = key->subkeys->keyid;      }
652      if (!keyid)  }
653          return 0;  
654      get_seckey (keyid, &skey);  
655      return skey? 1 : 0;  /* Return if there is a secret for @key.
656  } /* find_secret_key */     0 means success. */
657    static int
658    find_secret_key (gpgme_key_t key)
659  static int  {
660  do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list)      const char *keyid;
661  {          winpt_key_s skey;
662      LV_ITEM lvi;      
663      gpgme_user_id_t u;      memset (&skey, 0, sizeof (skey));
664      gpgme_subkey_t k;      keyid = key->subkeys->keyid;
665      char fmt[128];      if (!keyid)
666      const char *attr;          return 0;
667      u32 key_attr;      winpt_get_seckey (keyid, &skey);
668      int idx = 0;          if (skey.ext && skey.ext->gloflags.divert_to_card)
669            return 2;
670      /* we check the pubkey algorithm here to make sure that no ElGamal      return skey.ctx? 1 : 0;
671         sign+encrypt key is used in _any_ mode */  }
672      if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {  
673          log_debug ("ElGamal (E+S) key found: %s (%s)\n",  
674                      key->uids->name, key->subkeys->keyid);  static int
675          return 0;  do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list)
676      }      {    
677        LV_ITEM lvi;
678                gpgme_user_id_t u;
679      if (listview_add_item2 (lv, " ", (void *)key))            gpgme_subkey_t k;
680          return WPTERR_GENERAL;      char fmt[128], *p;
681                const char *attr;
682      attr = key->uids->uid;      u32 key_attr;
683      memset( &lvi, 0, sizeof lvi );      int idx = 0;    
684      lvi.mask = LVIF_TEXT | LVIF_PARAM;  
685      lvi.pszText = (char *)attr;      /* we check the pubkey algorithm here to make sure that no ElGamal
686      lvi.lParam = (LPARAM )key;         sign+encrypt key is used in _any_ mode */
687      if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )        if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {
688          return WPTERR_GENERAL;          log_debug ("ElGamal (E+S) key found: %s (%s)\n",
689                               key->uids->name, key->subkeys->keyid);
690      if( uididx == -1 ) { /* request the primary user-id of the key. */          return 0;
691          attr = key->uids->uid;      }
692          uididx = 0;  
693      }          
694      else {      if (listview_add_item2 (lv, " ", (void *)key))
695          u = get_nth_userid (key, uididx);          return WPTERR_GENERAL;
696          if (!u || u->revoked || uididx < 0)  
697              uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */      attr = key->uids->uid;
698          u = get_nth_userid (key, uididx);      memset (&lvi, 0, sizeof lvi);
699          attr = key->uids->uid;      lvi.mask = LVIF_TEXT | LVIF_PARAM;
700      }      lvi.pszText = (char *)attr;
701      if( attr == NULL || strlen( attr ) < 5 ) { /* normal userids are >= 5 chars */      lvi.lParam = (LPARAM )key;
702          attr = _("Invalid User ID");      if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
703          listview_add_sub_item( lv, 0, idx++, attr );          return WPTERR_GENERAL;
704      }            
705      else {      if (uididx == -1) { /* request the primary user-id of the key. */
706          char * uid = utf8_to_wincp (attr, strlen (attr));          attr = key->uids->uid;
707          if (uid) {          uididx = 0;
708              listview_add_sub_item( lv, 0, idx++, uid );      }
709              free (uid);      else {
710          }          u = get_nth_userid (key, uididx);
711      }          if (!u || u->revoked || uididx < 0)
712      k = get_nth_key (key, keyidx);              uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */
713      if( k && k->keyid ) {          u = get_nth_userid (key, uididx);
714          _snprintf( fmt, sizeof fmt -1, "0x%s", k->keyid + 8 );          attr = u->uid;
715          listview_add_sub_item( lv, 0, idx++, fmt );      }
716      }      if (attr == NULL || strlen (attr) < 5) { /* normal userids are >= 5 chars */
717      if (list > 0) {          attr = _("Invalid User ID");
718          attr = find_secret_key (key)? "pub/sec" : "pub";          listview_add_sub_item (lv, 0, idx++, attr);
719          if (strchr( attr, '/')) {      }  
720              struct winpt_key_s k;      else {
721              winpt_get_seckey (key->subkeys->keyid, &k);          char *uid = utf8_to_wincp (attr, strlen (attr));
722              if (k.ext->gloflags.divert_to_card)          if (uid) {
723                  attr = "pub/crd";              listview_add_sub_item (lv, 0, idx++, uid);
724          }              free (uid);
725          listview_add_sub_item( lv, 0, idx++, attr );          }
726      }      }
727      if (lv->cols >= 2) {      k = get_nth_key (key, keyidx);
728          attr = get_key_size (key, list == -1? keyidx+1 : 0);      if (k && k->keyid) {
729          if (attr)          _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8);
730              listview_add_sub_item (lv, 0, idx++, attr);          listview_add_sub_item( lv, 0, idx++, fmt );
731      }      }
732      if (lv->cols >= 3) {      if (list > 0) {
733          attr = get_key_algo (key, list == -1? keyidx+1 : 0);          key_attr = find_secret_key (key);
734          if (attr)          if (!key_attr)
735              listview_add_sub_item( lv, 0, idx++, attr);              attr = "pub";
736      }          else
737      if( lv->cols >= 4 ) {              attr = key_attr == 1? "pub/sec" : "pub/crd";
738          char * status = get_key_status( key, uididx, list > 0? 1 : 0 );          listview_add_sub_item (lv, 0, idx++, attr);
739          if (!status)      }
740              return WPTERR_GENERAL;      if (lv->cols >= 2) {
741          listview_add_sub_item( lv, 0, idx++, status );          attr = get_key_size (key, list == -1? keyidx+1 : 0);
742          free_if_alloc( status );          if (attr)
743      }              listview_add_sub_item (lv, 0, idx++, attr);
744      if (lv->cols >= 5) {      }
745          const char * s = get_key_trust (key, uididx, list > 0? 1 : 0);      if (lv->cols >= 3) {
746          listview_add_sub_item (lv, 0, idx++, s);          attr = get_key_algo (key, list == -1? keyidx+1 : 0);
747      }          if (attr)
748      if( lv->cols >= 6 ) {              listview_add_sub_item( lv, 0, idx++, attr);
749          k = get_nth_key (key, keyidx);      }
750          key_attr = k->timestamp;      if( lv->cols >= 4 ) {
751          if( key_attr ) {          p = get_key_status( key, uididx, list > 0? 1 : 0 );
752              attr = get_key_created (key_attr);          if (!p)
753              listview_add_sub_item( lv, 0, idx++, attr );              return WPTERR_GENERAL;
754          }                listview_add_sub_item (lv, 0, idx++, p);
755      }          free_if_alloc (p);
756        }
757      return 0;      if (lv->cols >= 5) {
758  } /* do_addkey */          attr = get_key_trust (key, uididx, list > 0? 1 : 0);
759            listview_add_sub_item (lv, 0, idx++, attr);
760        }
761  void      if( lv->cols >= 6 ) {
762  keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)          k = get_nth_key (key, keyidx);
763  {          key_attr = k->timestamp;
764      const char *s;          if( key_attr ) {
765      char tmp[32];              attr = get_key_created (key_attr);
766                listview_add_sub_item( lv, 0, idx++, attr );
767      listview_set_item2 (lv, pos, (void *)key);          }      
768      /* the only mode we support is KYLIST_LIST in the Key Manager */      }
769        
770      s = key->uids->uid;      return 0;
771      if (s)  }
772          listview_add_sub_item (lv, pos, 0, s);  
773    
774      s = key->subkeys->keyid;  void
775      if (s) {  keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)
776          sprintf (tmp, "0x%s", s+8);  {
777          listview_add_sub_item (lv, pos, 1, tmp);      const char *s;
778      }      char tmp[32];
779    
780      s = find_secret_key (key)? "pub/sec" : "pub";      listview_set_item2 (lv, pos, (void *)key);
781      listview_add_sub_item (lv, pos, 2, s);      /* the only mode we support is KYLIST_LIST in the Key Manager */
782        
783      s = get_key_size (key, 0);      s = key->uids->uid;
784      if (s)      if (s)
785          listview_add_sub_item (lv, pos, 3, s);          listview_add_sub_item (lv, pos, 0, s);
786    
787      s = get_key_algo (key, 0);      s = key->subkeys->keyid;
788      if (s)      if (s) {
789          listview_add_sub_item (lv, pos, 4, s);          sprintf (tmp, "0x%s", s+8);
790            listview_add_sub_item (lv, pos, 1, tmp);
791      s = get_key_status (key, 0, 1);      }
792      if (s)  
793          listview_add_sub_item (lv, pos, 5, s);      s = find_secret_key (key)? "pub/sec" : "pub";
794        listview_add_sub_item (lv, pos, 2, s);
795      s = get_key_trust (key, 0, 1);  
796      if (s)      s = get_key_size (key, 0);
797          listview_add_sub_item (lv, pos, 6, s);      if (s)
798            listview_add_sub_item (lv, pos, 3, s);
799      long t = key->subkeys->timestamp;  
800      s = get_key_created (t);      s = get_key_algo (key, 0);
801      if (s)      if (s)
802          listview_add_sub_item (lv, pos, 7, s);          listview_add_sub_item (lv, pos, 4, s);
803  }  
804        s = get_key_status (key, 0, 1);
805        if (s)
806  int          listview_add_sub_item (lv, pos, 5, s);
807  keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)  
808  {      s = get_key_trust (key, 0, 1);
809      int uids, rc = 0, i, n = 0;      if (s)
810      gpgme_subkey_t k;          listview_add_sub_item (lv, pos, 6, s);
811    
812      for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) {      long t = key->subkeys->timestamp;
813          if (k->invalid) {      s = get_key_created (t);
814              log_debug ("keylist_add_key: invalid key %s\n", key->uids->name);      if (s)
815              continue; /* Don't use invalid keys */          listview_add_sub_item (lv, pos, 7, s);
816          }  }
817    
818          if (mode & KEYLIST_ALL) {  
819              uids = count_userids (key);  int
820              rc = do_addkey (lv, key, uids, i, 0);  keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)
821              if( rc )  {
822                  return rc;      int uids, rc = 0, i;
823          }      gpgme_subkey_t k;
824          else if (mode & KEYLIST_LIST)  
825              return do_addkey (lv, key, -1, i, 1);      /* if the entire key is disabled, just return. */
826          else if (mode & KEYLIST_ENCRYPT) {      if (key->disabled && !(mode & KEYLIST_LIST))
827              if (k->can_encrypt && key_is_useable (k)) {          return 0;
828                  if (mode & KEYLIST_FLAG_FILE) {  
829                      rc = do_addkey (lv, key, -1, i, -1);      for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) {
830                      if (rc)          if (k->invalid) {
831                          return rc;              log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name);
832                  }              continue; /* Don't use invalid keys */
833                  else {          }
834                      for( uids = 0;  uids < count_userids (key); uids++ ) {  
835                          rc = do_addkey( lv, key, uids, i, -1 );          if (mode & KEYLIST_ALL) {
836                          if( rc )              uids = count_userids (key);
837                              return rc;              rc = do_addkey (lv, key, uids, i, 0);
838                      }              if (rc)
839                  }                  return rc;
840              }          }
841          }          else if (mode & KEYLIST_LIST)
842          else if (mode & KEYLIST_ENCRYPT_MIN) {              return do_addkey (lv, key, -1, i, 1);
843              if( k->can_encrypt && key_is_useable (k))          else if (mode & KEYLIST_ENCRYPT) {
844              {              if (k->can_encrypt && key_is_useable (k)) {
845                  rc = do_addkey (lv, key, -1, i, -1);                  if (mode & KEYLIST_FLAG_FILE) {
846                  return rc;                      rc = do_addkey (lv, key, -1, i, -1);
847              }                      if (rc)
848          }                                return rc;
849          else if (mode & KEYLIST_SIGN) {                  }
850              if ( k->can_sign                  else {
851                  && find_secret_key( key )                      for (uids = 0;  uids < count_userids (key); uids++) {
852                  && key_is_useable (k))                          rc = do_addkey (lv, key, uids, i, -1);
853              {                          if (rc)
854                  rc = do_addkey (lv, key, -1, i, -1);                              return rc;
855                  if( rc )                      }
856                      return rc;                    }
857              }              }
858          }                }
859      }          else if (mode & KEYLIST_ENCRYPT_MIN) {
860                if( k->can_encrypt && key_is_useable (k))
861      return rc;                {
862  } /* keylist_add_key */                  rc = do_addkey (lv, key, -1, i, -1);
863                    return rc;
864                }
865  int          }      
866  keylist_sort (listview_ctrl_t lv, int sortby)          else if (mode & KEYLIST_SIGN) {
867  {                    if (k->can_sign
868      return listview_sort_items( lv, sortby, keylist_cmp_cb );                  && find_secret_key (key)
869  } /* keylist_sort */                  && key_is_useable (k)) {
870                    rc = do_addkey (lv, key, -1, i, -1);
871                    if (rc)
872  static int                      return rc;  
873  key_check_validity (const char *validity)              }
874  {              }      
875      if (strstr (validity, "Unknown")      }
876          || strstr (validity, "Undefined")  
877          || strstr (validity, "Never"))      return rc;  
878          return 0;    } /* keylist_add_key */
879      return 1;  
880  } /* key_check_validity */  
881    int
882    keylist_sort (listview_ctrl_t lv, int sortby)
883  gpgme_key_t*  {      
884  keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)      return listview_sort_items (lv, sortby, keylist_cmp_cb);
885  {  }
886      int count = 0, force_trust = 0;  
887      int n, j, ka_pos = 0, rc = 0;  
888      int k_pos=0;  /* Check that the validity @validity is at least >= marginal. */
889      char keyid[32], valid[32], id[100];  static int
890      key_array_s *ka = NULL;  key_check_validity (const char *validity)
891      gpgme_key_t *keybuf;  {    
892        if (strstr (validity, _("Unknown")) ||
893      n = listview_count_items( lv, 0 );          strstr (validity, _("Undefined")) ||
894      ka = key_array_new( n );          strstr (validity, _("Never")) ||
895      if ( !ka )          strstr (validity, _("None")))
896          BUG (NULL);          return 0;  
897        return 1;
898      keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));  }
899      if (!keybuf)  
900          BUG (NULL);  
901            /* Extract all selected recipients from the list @lv and return them
902      for( j = 0; j < n; j++ ) {     as a vector. @r_force_trust is >= 1 if one of the recipients is not
903          if( listview_get_item_state( lv, j ) || n == 1 ) {     fully trusted. @r_count returns the number of selected keys.
904              listview_get_item_text( lv, j, 1, keyid, sizeof keyid - 1 );                             Return value: the key list on success, NULL otherwise. */
905              listview_get_item_text( lv, j, 4, valid, sizeof valid -1 );  gpgme_key_t*
906              listview_get_item_text( lv, j, 0, id, sizeof id-1 );  keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)
907              /*if( !strncmp( keyid, "gpg_group_t", 5 ) ) {  {
908                  listview_get_item_text( lv, j, 0, id, sizeof id -1 );      int count = 0, force_trust = 0;
909                  rc = km_groupdb_expand_recipients( id, rset );      int n, j, ka_pos = 0, rc = 0;
910                  if( rc )      int k_pos=0;
911                      force_trust++;      char keyid[32], valid[32], id[100];
912              }*/      key_array_s *ka = NULL;
913              if( !key_check_validity( valid )      gpgme_key_t *keybuf;
914                      && !key_array_search( ka, ka_pos, keyid ) ) {  
915                  char *warn = new char[512+strlen (id) + 1];      n = listview_count_items( lv, 0 );
916                  if (!warn)      
917                      BUG (0);      ka = key_array_new( n );
918                  sprintf (warn,      if (!ka)
919                      _("It is NOT certain that the key belongs to the person\n"          BUG (NULL);
920                        "named in the user ID.  If you *really* know what you are\n"  
921                        "doing, you may answer the next question with yes\n"      keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
922                        "\n"      if (!keybuf)
923                        "Use \"%s\" anyway?"), id);          BUG (NULL);
924                  if (reg_prefs.always_trust)          
925                      rc = IDYES;      for( j = 0; j < n; j++ ) {
926                  else          if( listview_get_item_state (lv, j) || n == 1) {
927                      rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);              listview_get_item_text (lv, j, 0, id, sizeof id-1);
928                  if (rc == IDYES) {              listview_get_item_text (lv, j, 1, keyid, sizeof keyid - 1);                
929                      gpgme_key_t k;              listview_get_item_text (lv, j, 4, valid, sizeof valid -1);
930                      get_pubkey (keyid, &k);              if( !key_check_validity (valid)
931                      keybuf[k_pos++] = k;                   && !key_array_search( ka, ka_pos, keyid )) {
932                      force_trust++;                  char *warn = new char[512+strlen (id) + 1];
933                      ka[ka_pos].checked = 1;                  if (!warn)
934                      strcpy (ka[ka_pos++].keyid, keyid);                      BUG (0);
935                      count++;                  sprintf (warn,
936                  }                      _("It is NOT certain that the key belongs to the person\n"
937                  free_if_alloc (warn);                        "named in the user ID.  If you *really* know what you are\n"
938              }                        "doing, you may answer the next question with yes\n"
939              else {                        "\n"
940                  gpgme_key_t k;                        "Use \"%s\" anyway?"), id);
941                  listview_get_item_text( lv, j, 1, keyid, sizeof keyid -1 );                  if (reg_prefs.always_trust)
942                  get_pubkey (keyid, &k);                      rc = IDYES;
943                  keybuf[k_pos++] = k;                  else
944                  count++;                              rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);
945              }                  if (rc == IDYES) {
946          }                      gpgme_key_t k;
947      }                      get_pubkey (keyid, &k);
948      key_array_release (ka);                      keybuf[k_pos++] = k;
949      if (r_force_trust)                      force_trust++;
950          *r_force_trust = force_trust;                      ka[ka_pos].checked = 1;
951      if (r_count)                      strcpy (ka[ka_pos++].keyid, keyid);
952          *r_count = count;                      count++;
953      return keybuf;                  }
954  } /* keylist_get_recipients */                  free_if_alloc (warn);
955                }
956                else {
957  static int                  gpgme_key_t k;
958  keylist_get_keyflags (const char *buf, size_t buflen)                  listview_get_item_text( lv, j, 1, keyid, sizeof keyid -1 );
959  {                  get_pubkey (keyid, &k);
960      int c = 0, flags = 0;                  keybuf[k_pos++] = k;
961                    count++;        
962      if( *buf != '[' )              }
963          return KEYFLAG_NONE;          }
964      while (buf && c != ']')      }
965      {      key_array_release (ka);
966          c = *buf++;      if (r_force_trust)
967          if (c == 'R')          *r_force_trust = force_trust;
968              flags |= KEYFLAG_REVOKED;      if (r_count)
969          if (c == 'E')          *r_count = count;
970              flags |= KEYFLAG_EXPIRED;      return keybuf;
971          if (c == 'D')  }
972              flags |= KEYFLAG_DISABLED;  
973      }  
974    static int
975      return flags;  keylist_get_keyflags (const char *buf, size_t buflen)
976  } /* keylist_get_keyflags */  {
977        int c = 0, flags = 0;
978    
979  gpgme_key_t*      if( *buf != '[' )
980  keylist_enum_recipients (listview_ctrl_t lv,  int listype, int *r_count)          return KEYFLAG_NONE;
981  {      while (buf && c != ']')
982      gpgme_key_t* rset;      {
983      gpgme_key_t k;          c = *buf++;
984      int i, n, id, k_pos=0;          if (c == 'R')
985      char keyid[32], t[128], t2[128];              flags |= KEYFLAG_REVOKED;
986            if (c == 'E')
987      n = listview_count_items( lv, 0 );              flags |= KEYFLAG_EXPIRED;
988      if (!n)          if (c == 'D')
989          return 0;              flags |= KEYFLAG_DISABLED;
990      rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));      }
991      if (!rset)  
992          BUG (NULL);      return flags;
993      for( i = 0; i < n; i++ ) {  } /* keylist_get_keyflags */
994          if( !listview_get_item_state( lv, i ) )  
995              continue;  
996          listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );  gpgme_key_t*
997          switch( listype ) {  keylist_enum_recipients (listview_ctrl_t lv,  int listype, int *r_count)
998          case KEYLIST_LIST:  {
999              listview_get_item_text( lv, i, 5, t, sizeof t - 1 );      gpgme_key_t* rset;
1000              if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) {      gpgme_key_t k;
1001                  _snprintf( t2, sizeof t2 -1,      int i, n, id, k_pos=0;
1002                              _("KeyID %s.\nDo you really want to export a revoked key?"), keyid );      char keyid[32], t[128], t2[128];
1003                  id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO );  
1004                  if( id == IDNO )      n = listview_count_items (lv, 0);
1005                      continue;                if (!n)
1006              }          return 0;
1007              break;      rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));
1008          }      if (!rset)
1009          get_pubkey (keyid, &k);          BUG (NULL);
1010          rset[k_pos++] = k;      for( i = 0; i < n; i++ ) {
1011      }          if( !listview_get_item_state( lv, i ) )
1012      if (r_count)              continue;
1013          *r_count = k_pos;          listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
1014      return rset;          switch( listype ) {
1015  } /* keylist_enum_recipients */          case KEYLIST_LIST:
1016                listview_get_item_text( lv, i, 5, t, sizeof t - 1 );
1017                if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) {
1018  void                  _snprintf( t2, sizeof t2 -1,
1019  seclist_destroy (keylist_t * list)                              _("KeyID %s.\nDo you really want to export a revoked key?"), keyid );
1020  {                  id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO );
1021      keylist_t l2;                  if( id == IDNO )
1022      while (*list) {                      continue;          
1023          l2 = (*list)->next;              }
1024          safe_free (*list);              break;
1025          *list = l2;              }
1026      }          get_pubkey (keyid, &k);
1027      list = NULL;          rset[k_pos++] = k;
1028  } /* seclist_destroy */      }
1029        if (r_count)
1030            *r_count = k_pos;
1031  void      return rset;
1032  seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)  } /* keylist_enum_recipients */
1033  {      
1034      gpgme_keycache_t kc = NULL;  
1035      gpgme_key_t key = NULL;  void
1036      HWND kb;  seclist_destroy (keylist_t * list)
1037      keylist_t list=NULL, l, l2;      {
1038      long pos = 0;      keylist_t l2;
1039        while (*list) {
1040      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);          l2 = (*list)->next;
1041      kb = GetDlgItem (dlg, ctlid);          safe_free (*list);
1042      kc = keycache_get_ctx (0);          *list = l2;    
1043      if (!kc)      }
1044          BUG (0);      list = NULL;
1045      gpgme_keycache_rewind (kc);  } /* seclist_destroy */
1046        
1047      while (!gpgme_keycache_next_key (kc, 1, &key)) {  
1048          char * inf = NULL, * uid = NULL;  void
1049          const char * id;  seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)
1050          const char * keyid;  {    
1051          int algo;      gpg_keycache_t kc = NULL;
1052          size_t size = 0;      gpgme_key_t key = NULL;
1053        HWND kb;
1054          if (flags & KEYLIST_FLAG_SHORT)      keylist_t list=NULL, l, l2;    
1055              id = key->uids->name;      long pos = 0;
1056          else  
1057              id = key->uids->uid;      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
1058          keyid = key->subkeys->keyid;      kb = GetDlgItem (dlg, ctlid);
1059          algo = key->subkeys->pubkey_algo;      kc = keycache_get_ctx (0);
1060          if (!id || !keyid)      if (!kc)
1061              continue; /* fixme: error? */                BUG (0);
1062          if (!key_is_useable (key->subkeys))      gpg_keycache_rewind (kc);
1063              continue;      
1064        while (!gpg_keycache_next_key (kc, 1, &key)) {
1065          uid = utf8_to_wincp (id, strlen (id));          char *inf = NULL, *uid = NULL;
1066          size = strlen( uid ) + strlen( keyid ) + 32;          const char *id;
1067          inf = new char[size+1];          const char *keyid;
1068          if( !inf )          int algo;
1069              BUG( NULL );          size_t size = 0;
1070          _snprintf (inf, size, _("%s (%s/0x%s)"), uid,  
1071                     get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);          if (flags & KEYLIST_FLAG_SHORT)
1072          combox_add_string (kb, inf);              id = key->uids->name;
1073          free_if_alloc (inf);          else
1074          free (uid);              id = key->uids->uid;
1075          l = (struct keylist_s *)calloc (1, sizeof * l);          keyid = key->subkeys->keyid;
1076          if (!l)          algo = key->subkeys->pubkey_algo;
1077              BUG (0);          if (!id || !keyid)
1078          l->key = key;              continue;
1079          if (!list)          if (key->disabled || !key_is_useable (key->subkeys))
1080              list = l;              continue;
1081          else {  
1082              for( l2 = list; l2->next; l2 = l2->next )          uid = utf8_to_wincp (id, strlen (id));
1083                  ;          size = strlen( uid ) + strlen( keyid ) + 32;
1084              l2->next = l;          inf = new char[size+1];
1085          }          if( !inf )
1086      }              BUG( NULL );
1087      for( pos = 0, l2=list; pos < SendMessage( kb, CB_GETCOUNT, 0, 0 ); pos++, l2=l2->next )          _snprintf (inf, size, "%s (%s/0x%s)", uid,
1088          SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key );                     get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);
1089      SendMessage( kb, CB_SETCURSEL, 0, 0 );          combox_add_string (kb, inf);
1090      *ret_list = list;          free_if_alloc (inf);
1091  } /* seclist_init */          free (uid);
1092                    l = (struct keylist_s *)calloc (1, sizeof * l);
1093            if (!l)
1094  int              BUG (0);
1095  seclist_select_key (HWND dlg, int ctlid, gpgme_key_t * ret_key)          l->key = key;
1096  {          if (!list)
1097      int pos;              list = l;
1098      DWORD k = 0;          else {
1099                for( l2 = list; l2->next; l2 = l2->next )
1100      pos = SendDlgItemMessage( dlg, ctlid, CB_GETCURSEL, 0, 0 );                  ;
1101      if( pos == CB_ERR ) {              l2->next = l;
1102          msg_box( dlg, _("No key was selected."), _("Secret Key List"), MB_ERR );          }
1103          *ret_key = NULL;      }
1104      }      for( pos = 0, l2=list; pos < SendMessage( kb, CB_GETCOUNT, 0, 0 ); pos++, l2=l2->next )
1105      else {          SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key );
1106          k = SendDlgItemMessage( dlg, ctlid, CB_GETITEMDATA, pos, 0 );      SendMessage( kb, CB_SETCURSEL, 0, 0 );
1107          *ret_key = (gpgme_key_t)k;      *ret_list = list;
1108      }  }
1109      return k? 0 : -1;          
1110  } /* seclist_dlg_proc */  
1111    /* Select a secret key from the combo box with the ID @ctlid.
1112       Return the code on success in @ret_key. */
1113    int
1114    seclist_select_key (HWND dlg, int ctlid, gpgme_key_t *ret_key)
1115    {
1116        int pos;
1117        DWORD k = 0;
1118    
1119        pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
1120        if (pos == CB_ERR) {
1121            msg_box (dlg, _("No key was selected."), _("Secret Key List"), MB_ERR);
1122            *ret_key = NULL;
1123        }
1124        else {
1125            k = SendDlgItemMessage (dlg, ctlid, CB_GETITEMDATA, pos, 0);
1126            *ret_key = (gpgme_key_t)k;
1127        }
1128        return k? 0 : -1;
1129    }

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26