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

Legend:
Removed from v.25  
changed lines
  Added in v.50

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26