/[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 73 by twoaday, Tue Nov 8 07:15:13 2005 UTC revision 432 by twoaday, Mon Apr 9 14:13:10 2012 UTC
# Line 1  Line 1 
1  /* wptKeylist.cpp - Keylist element  /* wptKeylist.cpp - Keylist element
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006, 2009 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.
# Line 13  Line 13 
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.
  *  
  * You should have received a copy of the GNU General Public License  
  * along with WinPT; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
16   */   */
17  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
18  #include <config.h>  #include <config.h>
# Line 37  Line 33 
33  #include "wptUTF8.h"  #include "wptUTF8.h"
34  #include "wptRegistry.h"  #include "wptRegistry.h"
35  #include "wptContext.h"  #include "wptContext.h"
36    #include "wptVersion.h"
37    #include "resource.h"
38    #include "StringBuffer.h"
39    
40    
 #define key_is_useable(key) (!(key)->revoked && !(key)->expired && !(key)->disabled)  
   
 static struct listview_column_s klist_enc[] = {  
     {0, 242, (char *)_("User ID")},  
     {1, 80, (char *)_("Key ID")},  
     {3, 46, (char *)_("Size")},  
     {4, 50, (char *)_("Cipher")},  
     {5, 70, (char *)_("Validity")},  
     {0, 0, NULL}  
 };  
 #define KLIST_ENC_ITEMS (DIM(klist_enc) -1)  
   
 static struct listview_column_s klist[] = {  
     {0, 242, (char *)_("User ID")},  
     {1, 78, (char *)_("Key ID")},  
     {2, 52, (char *)_("Type")},      
     {3, 68, (char *)_("Size")},  
     {4, 66, (char *)_("Cipher")},  
     {5, 70, (char *)_("Validity")},  
     {6, 40, (char *)_("Trust")},  
     {7, 72, (char *)_("Creation")},  
     {0, 0, NULL}  
 };  
 #define KLIST_ITEMS (DIM(klist) - 1)  
   
41  struct key_array_s {  struct key_array_s {
42      char keyid[32];      char keyid[32];
43      int checked;      int  checked;
44  };  };
45    
 static int find_secret_key (gpgme_key_t key);  
   
46    
47  static key_array_s*  static key_array_s*
48  key_array_new( size_t items )  key_array_new (DWORD items)
49  {  {
50      key_array_s *ka;      key_array_s *ka;
     size_t j;  
51            
52      if( items == 0 )      if (items == 0)
53          return NULL;          BUG (NULL);
54      ka = new key_array_s[items + 1];      ka = new key_array_s[items + 1];
55      if( ka == NULL )      if (!ka)
56          return NULL;              BUG (NULL);
57      for ( j = 0; j < items; j++ )      for (DWORD i = 0; i < items; i++)
58          ka[j].checked = 0;          ka[i].checked = 0;
59      return ka;      return ka;
60  } /* key_array_new */  }
   
61    
62  static void  static void
63  key_array_release( key_array_s *ka )  key_array_release (key_array_s *ka)
64  {  {
65      free_if_alloc( ka );      free_if_alloc (ka);
66  } /* key_array_release */  }
67    
68    
69    /* Check if the keyid @keyid is in the key array @ka.
70       Return value: 1 if it exists, 0 otherwise. */
71  static int  static int
72  key_array_search( key_array_s *ka, size_t items, const char *keyid )  key_array_search (key_array_s *ka, DWORD items, const char *keyid)
73  {  {
74      size_t j;      for (DWORD i = 0; i < items; i++) {
75                if (!stricmp (keyid, ka[i].keyid))
     /* fixme: we need a faster search method */  
     for( j = 0; j < items; j++ ) {  
         if( !strcmp( keyid, ka[j].keyid ) )  
76              return 1;                return 1;  
77      }      }
       
78      return 0;      return 0;
79  } /* key_array_search */  }
80    
81    
82    /* Return if there is a secret for @key.
83       0 means success. */
84    static int
85    find_secret_key (gpgme_key_t key)
86    {
87        winpt_key_s skey;
88        
89        if (!key->subkeys->keyid)
90            return 0;
91        memset (&skey, 0, sizeof (skey));
92        if (winpt_get_seckey (key->subkeys->keyid, &skey))
93            return 0;
94        if (skey.ext && skey.ext->gloflags.divert_to_card)
95            return 2;
96        return skey.ctx? 1 : 0;
97    }
98    
99    
100    /* Update the gpgme key pointer of a single entry. */
101    static void
102    update_key (keylist_ctrl_t kl, int pos,
103                gpgme_key_t key)
104    {
105        if ((size_t)pos > kl->nkeys)
106            BUG (0);
107        kl->keys[pos] = key;
108    }
109    
110    
111    /* If @re_sorted == 0, then all keys from the key list control
112       are stored as references in the array.
113       Otherwise we just re-order the references in the array. */
114    static size_t
115    update_keys (keylist_ctrl_t kl, int re_sorted,
116                 gpgme_key_t **r_list)
117    {
118        gpgme_key_t *rset;
119        gpgme_key_t key;
120        listview_ctrl_t lv = kl->lv;
121        struct keycache_s *c;    
122        size_t k_pos;
123        int nkeys;
124    
125        nkeys = listview_count_items (lv, 0);
126        if (!nkeys)
127            BUG (0);
128        
129        if (!re_sorted) {
130            rset = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t));
131            *r_list = rset;
132        }
133        else
134            rset = *r_list;
135        k_pos = 0;
136        for (int i = 0; i < nkeys; i++) {
137            key = km_get_key_ptr (kl, i, &c);
138            rset[k_pos++] = key;
139        }
140        return k_pos;
141    }
142    
143    
144  gpgme_user_id_t  gpgme_user_id_t
# Line 173  count_subkeys (gpgme_key_t key) Line 203  count_subkeys (gpgme_key_t key)
203  }  }
204    
205    
206    /* Return the self signature of the key @keyid.
207       If first is set, the first self sig will be returned. */
208  gpgme_key_sig_t  gpgme_key_sig_t
209  get_selfsig (gpgme_user_id_t uid, const char *keyid, int first)  get_selfsig (gpgme_key_sig_t sigs, const char *keyid, int first)
210  {  {
211      gpgme_key_sig_t s, self_sig=NULL;      gpgme_key_sig_t s, self_sig=NULL;
212      long timestamp=0;      long timestamp=0;
213        int off = 0;
214    
215      for (s = uid->signatures; s; s = s->next) {      if (strlen (keyid) == 8)
216          if (!strcmp (s->keyid+8, keyid) && s->timestamp > timestamp) {          off = 8;
217    
218        for (s = sigs; s; s = s->next) {
219            if (!strcmp (s->keyid+off, keyid) && s->timestamp > timestamp) {
220              self_sig = s;              self_sig = s;
221              timestamp = s->timestamp;              timestamp = s->timestamp;
222              if (first)              if (first) /* do not search for later self sigs. */
223                  break;                  break;
224          }          }
225      }      }
# Line 191  get_selfsig (gpgme_user_id_t uid, const Line 227  get_selfsig (gpgme_user_id_t uid, const
227  }  }
228    
229    
   
230  const char*  const char*
231  get_key_algo (gpgme_key_t key, int keyidx)  get_key_algo (gpgme_key_t key, int keyidx)
232  {  {
# Line 199  get_key_algo (gpgme_key_t key, int keyid Line 234  get_key_algo (gpgme_key_t key, int keyid
234      gpgme_subkey_t k;      gpgme_subkey_t k;
235      char alg[32];      char alg[32];
236      const char *subalg;      const char *subalg;
237      int n=0;      int n;
238            
239      if (keyidx > 0) {      if (keyidx > 0) {
240          k = get_nth_key (key, keyidx-1);          k = get_nth_key (key, keyidx-1);
241          subalg =  get_key_pubalgo (k->pubkey_algo);          subalg =  get_key_pubalgo (k->pubkey_algo);
242          _snprintf( algo_id, DIM (algo_id)-1, "%s", subalg);          _snprintf (algo_id, DIM (algo_id)-1, "%s", subalg);
243          return algo_id;          return algo_id;
244      }      }
245      strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo));      strcpy (alg, get_key_pubalgo (key->subkeys->pubkey_algo));
246      n = count_subkeys (key);      n = count_subkeys (key);
247      if (n > 1) {      if (n > 1) {
248          k = get_nth_key (key, n-1);          do {
249                k = get_nth_key (key, --n);
250                if (k->revoked || k->expired)
251                    continue;
252                else
253                    break;
254            } while (n > 0);
255          subalg = get_key_pubalgo (k->pubkey_algo);          subalg = get_key_pubalgo (k->pubkey_algo);
256          _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg);          if (k == key->subkeys)
257                _snprintf (algo_id, DIM (algo_id)-1, "%s", subalg);
258            else
259                _snprintf (algo_id, DIM (algo_id)-1, "%s/%s", alg, subalg);
260          return algo_id;          return algo_id;
261      }      }
262      return get_key_pubalgo (key->subkeys->pubkey_algo);      return get_key_pubalgo (key->subkeys->pubkey_algo);
263  } /* get_key_algo */  }
264    
265    
266  const char*  const char*
267  get_key_created (long timestamp)  get_key_created (long timestamp)
268  {  {
269      static char timebuf[128];      static char timebuf[128];  
     struct tm *warp;  
270    
271      if (timestamp == 0 || timestamp == -1)      if (timestamp < 1)
272            return "????" "-??" "-??";
273        if (!get_locale_date (timestamp, timebuf, DIM (timebuf)-1))
274          return "????" "-??" "-??";          return "????" "-??" "-??";
     warp = localtime( &timestamp );  
     _snprintf( timebuf, sizeof timebuf - 1, "%04d-%02d-%02d",  
                 warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday );  
275      return timebuf;      return timebuf;
276  } /* get_key_created */  }
277    
278    
279  /* Return a string presentation of the time @timestamp. */  /* Return a string presentation of the time @timestamp. */
# Line 239  const char* Line 281  const char*
281  get_key_expire_date (long timestamp)  get_key_expire_date (long timestamp)
282  {  {
283      static char timebuf[64];      static char timebuf[64];
     struct tm *warp;  
284    
285      if( !timestamp )      if (timestamp == 0)
286          return _("Never");          return _("Never");
287      warp = localtime( &timestamp );      if (!get_locale_date (timestamp, timebuf, DIM (timebuf)-1))
288      _snprintf (timebuf, sizeof timebuf -1, "%04d-%02d-%02d",          return "????" "-??" "-??";
                warp->tm_year + 1900, warp->tm_mon + 1, warp->tm_mday);  
289      return timebuf;      return timebuf;
290  }  }
291    
# Line 260  get_key_type (gpgme_key_t key) Line 300  get_key_type (gpgme_key_t key)
300      else if (type == 2)      else if (type == 2)
301          return _("Key Pair (Card)");          return _("Key Pair (Card)");
302      return _("Public Key");      return _("Public Key");
303  } /* get_key_type */  }
304    
305    
306  const char*  const char*
# Line 281  get_key_size (gpgme_key_t key, int keyid Line 321  get_key_size (gpgme_key_t key, int keyid
321      if (n > 1) {      if (n > 1) {
322          k = get_nth_key (key, n-1);          k = get_nth_key (key, n-1);
323          size_sub = k->length;          size_sub = k->length;
324          _snprintf( size_id, sizeof (size_id) - 1, "%d/%d", size_main, size_sub );          _snprintf (size_id, DIM (size_id) - 1, "%d/%d",
325                        size_main, size_sub);
326          return size_id;          return size_id;
327      }      }
328      _snprintf( size_id, sizeof (size_id) - 1, "%d", size_main );      _snprintf (size_id, DIM (size_id) - 1, "%d", size_main);
329      return size_id;      return size_id;
330  } /* get_key_size */  }
331    
332    
333    const char*
334    get_key_pubalgo2 (gpgme_pubkey_algo_t alg)
335    {
336        switch (alg) {
337        case GPGME_PK_DSA: return "D";
338        case GPGME_PK_RSA: return "R";
339        case GPGME_PK_ELG: return "G";
340        default: return "?";
341        }
342        return "?";
343    }
344    
345    
346  const char*  const char*
# Line 296  get_key_pubalgo (gpgme_pubkey_algo_t alg Line 350  get_key_pubalgo (gpgme_pubkey_algo_t alg
350      case GPGME_PK_DSA: return "DSA";      case GPGME_PK_DSA: return "DSA";
351      case GPGME_PK_ELG:      case GPGME_PK_ELG:
352      case GPGME_PK_ELG_E: return "ELG";      case GPGME_PK_ELG_E: return "ELG";
353      case GPGME_PK_RSA: return "RSA";      case 0: /* XXX: do we still need this?? */
354        case GPGME_PK_RSA:
355        case GPGME_PK_RSA_S:
356        case GPGME_PK_RSA_E: return "RSA";
357      default: return "???";      default: return "???";
358      }      }
359      return "???";      return "???";
360  }  }
361    
362  const char *  
363    const char*
364  get_key_fpr (gpgme_key_t key)  get_key_fpr (gpgme_key_t key)
365  {  {
366      static char fpr_md[64];      static char fpr_md[64];
367      const char *fpr;      const char *fpr;
368      char t[16], tmp[40];      char t[16], tmp[40];
369      size_t i=0;      size_t i;
370            
371      memset (fpr_md, 0, sizeof (fpr_md));      memset (fpr_md, 0, sizeof (fpr_md));
372      fpr = key->subkeys->fpr;      fpr = key->subkeys->fpr;
# Line 331  get_key_fpr (gpgme_key_t key) Line 389  get_key_fpr (gpgme_key_t key)
389          }          }
390      }      }
391      return fpr_md;      return fpr_md;
392  } /* get_key_fpr */  }
393    
394    
395  const char *  /* Extract the key ID from the fingerprint.
396       A long ID will be converted into a short ID. */
397    const char*
398    get_keyid_from_fpr (const char *fpr)
399    {
400        if (!fpr)
401            return "????????";
402        if (strlen (fpr) == 40)
403            fpr += 32;
404        else if (strlen (fpr) == 32)
405            fpr += 24;
406        else if (strlen (fpr) == 16)
407            fpr += 8;
408        else
409            return "????????";
410        return fpr;
411    }
412    
413    
414    const char*
415  get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)  get_key_trust2 (gpgme_key_t key, int val, int uididx, int listmode)
416  {  {
417      if (key)      if (key)
# Line 342  get_key_trust2 (gpgme_key_t key, int val Line 419  get_key_trust2 (gpgme_key_t key, int val
419      switch (val) {      switch (val) {
420      case GPGME_VALIDITY_UNKNOWN:      case GPGME_VALIDITY_UNKNOWN:
421      case GPGME_VALIDITY_UNDEFINED:          case GPGME_VALIDITY_UNDEFINED:    
422          return "None";          return _("None");
423      case GPGME_VALIDITY_NEVER:          case GPGME_VALIDITY_NEVER:    
424          return "Never";          return _("Never");
425      case GPGME_VALIDITY_MARGINAL:      case GPGME_VALIDITY_MARGINAL:
426          return "Marginal";          return _("Marginal");
427      case GPGME_VALIDITY_FULL:      case GPGME_VALIDITY_FULL:
428            return _("Full");
429      case GPGME_VALIDITY_ULTIMATE:      case GPGME_VALIDITY_ULTIMATE:
430          return "Full";          return _("Ultimate");
431      }      }
432      return "";      return "";
433  }  }
434    
435    
436  const char *  const char*
437  get_key_trust (gpgme_key_t key, int uididx, int listmode)  get_key_trust (gpgme_key_t key, int uididx, int listmode)
438  {  {
439      return get_key_trust2 (key, 0, uididx, listmode);      return get_key_trust2 (key, 0, uididx, listmode);
440  }  }
441    
442    
443  const char *  const char*
444  get_key_trust_str (int val)  get_key_trust_str (int val)
445  {  {
446      return get_key_trust2 (NULL, val, 0, 0);      return get_key_trust2 (NULL, val, 0, 0);
# Line 380  get_key_status (gpgme_key_t key, int uid Line 458  get_key_status (gpgme_key_t key, int uid
458      if (uididx < 0 || count_userids (key) > uididx)      if (uididx < 0 || count_userids (key) > uididx)
459          uididx = 0;          uididx = 0;
460      if (listmode) {      if (listmode) {
461          const char *s;          const char *s;
         
462          if (key->revoked)          if (key->revoked)
463              s = _("Revoked");              s = _("Revoked");
464          else if (key->expired)          else if (key->expired)
465              s = _("Expired");              s = _("Expired");
466          else if (key->disabled)          else if (key->disabled)
467              s = _("Disabled");              s = _("Disabled");
468          else          else
469            s = "";              s = "";
           
470          /* if the key has a special status, we don't continue to figure out          /* if the key has a special status, we don't continue to figure out
471             what any user-id validities. */             the user-id validities. */
472          if (*s)          if (*s)
473              return m_strdup (s);              return m_strdup (s);
474      }      }
# Line 403  get_key_status (gpgme_key_t key, int uid Line 479  get_key_status (gpgme_key_t key, int uid
479  }  }
480    
481    
482    /* Return human readable description of the key @key. */
483    char*
484    get_key_desc (gpgme_key_t key)
485    {
486        gpgme_key_t sk;
487        const char *state, *alg, *type;
488        char *desc;
489        StringBuffer p;
490    
491        state = "";
492        if (key->disabled)
493            state = _("Disabled");
494        if (key->expired)
495            state = _("Expired");
496        if (key->revoked)
497            state = _("Revoked");
498    
499        /* If the fingerprint has 32 octets, we assume MD5 and thus
500           an old, version 3, RSA key which is called 'Legacy' by other
501           OpenPGP programs. */
502        if (strlen (key->subkeys->fpr) == 32)
503            alg = "RSA Legacy";
504        else
505            alg = "OpenPGP";
506        type = _("public key");
507        if (!get_seckey (key->subkeys->keyid+8, &sk))
508            type = _("key pair");
509        p = state;
510        p = p + " " + alg + " " + type;
511        desc = m_strdup (p.getBuffer ());
512        return desc;
513    }
514    
515    
516  /* Integer comparsion of @a and @b.  /* Integer comparsion of @a and @b.
517     Return values: same as in strcmp. */     Return values: same as in strcmp. */
518  static inline int  static inline int
# Line 424  get_ext_validity (gpgme_key_t k) Line 534  get_ext_validity (gpgme_key_t k)
534          return GPGME_VALIDITY_ULTIMATE+1;          return GPGME_VALIDITY_ULTIMATE+1;
535      else if (k->expired)      else if (k->expired)
536          return GPGME_VALIDITY_ULTIMATE+2;          return GPGME_VALIDITY_ULTIMATE+2;
537        else if (k->disabled)
538            return GPGME_VALIDITY_ULTIMATE+3;
539      return k->uids->validity;      return k->uids->validity;
540  }  }
541    
# Line 432  get_ext_validity (gpgme_key_t k) Line 544  get_ext_validity (gpgme_key_t k)
544  static int CALLBACK  static int CALLBACK
545  keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)  keylist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
546  {  {
547        struct keycache_s *aa, *bb;
548      gpgme_key_t a, b;      gpgme_key_t a, b;
549      int cmpresult = 0;      int cmpresult = 0;
550            
551      a = (gpgme_key_t)first;      aa = (struct keycache_s *)first;
552      b = (gpgme_key_t)second;      bb = (struct keycache_s *)second;
553      if (!a || !b)      if (!aa || !bb)
554          BUG (NULL);          BUG (NULL);
555        a = aa->key;
556        b = bb->key;
557            
558      switch (sortby & ~KEYLIST_SORT_DESC) {      switch (sortby & ~KEYLIST_SORT_DESC) {
559      case KEY_SORT_USERID:      case KEY_SORT_USERID:
# Line 491  keylist_cmp_cb (LPARAM first, LPARAM sec Line 606  keylist_cmp_cb (LPARAM first, LPARAM sec
606  }  }
607    
608    
609  /* Return the validity of the group @grp. */  int
610  static const char*  keylist_add_groups (keylist_ctrl_t kl)
 calc_validity (gpg_group_t grp)  
611  {  {
612      int valid=0;      return 0;
     gpg_member_t mbr;  
     gpgme_key_t key;  
   
     for (mbr = grp->list; mbr; mbr = mbr->next) {  
         if (get_pubkey (mbr->name, &key))  
             continue;  
         valid = key->uids->validity;  
         switch (valid) {  
         case GPGME_VALIDITY_MARGINAL:  
         case GPGME_VALIDITY_NEVER:  
         case GPGME_VALIDITY_UNDEFINED:  
             return get_key_trust2 (NULL, valid, 0, 0);  
         }  
     }  
     return _("Full");  
613  }  }
614    
615    
616  int  /* Synchronize the key array with the contents
617  keylist_add_groups( listview_ctrl_t lv )     of the keylist. */
618    void
619    keylist_sync (keylist_ctrl_t kl)
620  {  {
621  #if 0      free (kl->keys);
622      gpg_optfile_t gh;      kl->nkeys = update_keys (kl, 0, &kl->keys);
623      gpg_group_t grp;  }
     const char *valid;  
   
     gh = km_groupdb_open( );      
     if( !gh )    
         return WPTERR_FILE_OPEN;  
   
     for( grp = gh->grp; grp; grp = grp->next ) {  
         valid = calc_validity( grp );  
         listview_add_item( lv, " " );    
         listview_add_sub_item( lv, 0, 0, grp->name );    
         listview_add_sub_item( lv, 0, 1, "gpg_group_t" );        
         listview_add_sub_item( lv, 0, 2, "" );    
         listview_add_sub_item( lv, 0, 3, "Unknown" );  
         listview_add_sub_item( lv, 0, 4, valid?valid : "Unknown" );  
     }  
 #endif  
     return 0;  
 } /* keylist_add_groups */  
624    
625    
626  /* Create a listview for listing keys. Use the mode given in @mode  /* Create a listview for listing keys. Use the mode given in @mode
627     and the control is given in @ctrl. */     and the control is given in @ctrl. */
628  static int  static void
629  keylist_build (listview_ctrl_t *r_lv, HWND ctrl, int mode)  keylist_build (listview_ctrl_t *r_lv, HWND ctrl, int mode)
630  {  {
631        struct listview_column_s klist_enc[] = {
632        {0, 242, (char *)_("User ID")},
633        {1, 80, (char *)_("Key ID")},
634        {3, 46, (char *)_("Size")},
635        {4, 50, (char *)_("Cipher")},
636        {5, 70, (char *)_("Validity")},
637        {0, 0, NULL}
638        };
639        struct listview_column_s klist[] = {
640        {0, 240, (char *)_("User ID")},
641        {1, 78, (char *)_("Key ID")},
642        {2, 52, (char *)_("Type")},    
643        {3, 66, (char *)_("Size")},
644        {4, 60, (char *)_("Cipher")},
645        {5, 66, (char *)_("Validity")},
646        {6, 58, (char *)_("Trust")},
647        {7, 72, (char *)_("Creation")},
648        {0, 0, NULL}
649        };
650        HICON ico[7];
651      listview_ctrl_t lv;      listview_ctrl_t lv;
652      listview_column_t col;      listview_column_t col;
653      int j, n = 0;      int ncols = 0, ext_chkbox = 0;
     int rc = 0;  
654            
655      rc = listview_new (&lv);      listview_new (&lv, ctrl);
656      if( rc )      if (mode & KEYLIST_ENCRYPT_MIN) {
         return rc;  
       
     lv->ctrl = ctrl;  
     if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN)) {  
657          col = klist_enc;          col = klist_enc;
658          n = KLIST_ENC_ITEMS;          ncols = (DIM (klist_enc) - 1);
659            ext_chkbox = 1;
660      }        }  
661      else if ((mode & KEYLIST_SIGN)) {      else if (mode & KEYLIST_SIGN) {
662          col = klist_enc;          col = klist_enc;
663          n = KLIST_ENC_ITEMS - 1;          ncols = (DIM (klist_enc) - 1) - 1;
664            ext_chkbox = 1;
665      }      }
666      else {      else {
667          col = klist;          col = klist;
668          n = KLIST_ITEMS;          ncols = (DIM (klist) - 1);
669      }      }
670            
671      for( j = 0; j < n; j++ )          for (int j = 0; j < ncols; j++)
672          listview_add_column( lv, &col[j] );              listview_add_column (lv, &col[j]);
673      listview_set_ext_style( lv );      listview_set_ext_style (lv);
674        if (ext_chkbox)
675            listview_set_chkbox_style (lv);
676        ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY);
677        ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR);
678        ico[2] = LoadIcon (glob_hinst, (LPCTSTR)IDI_REV_KEYPAIR);
679        ico[3] = LoadIcon (glob_hinst, (LPCTSTR)IDI_REV_PUBKEY);
680        ico[4] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_DOWNARROW);
681        ico[5] = LoadIcon (glob_hinst, (LPCTSTR)IDI_SORT_UPARROW);
682        ico[6] = LoadIcon (glob_hinst, (LPCTSTR)IDI_EXP_PUBKEY);
683        listview_set_image_list (lv, 20, 16, ico, 7);
684        listview_del_all_items (lv);
685        listview_set_grid_style (lv);
686      *r_lv = lv;      *r_lv = lv;
       
     return 0;  
687  }  }
688    
689    
690  static void  static void
691  keylist_load_keycache (listview_ctrl_t lv, int mode,  keylist_load_keycache (keylist_ctrl_t kl, int mode,
692                         gpg_keycache_t pubkc, gpg_keycache_t seckc)                         gpg_keycache_t pubkc, gpg_keycache_t seckc)
693  {  {
     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);  
694      gpgme_key_t key, skey;      gpgme_key_t key, skey;
695      const char * keyid;      struct keycache_s *c;
696        const char *keyid;
697    
698        gpg_keycache_rewind (pubkc);
699      if (pubkc && seckc) {      if (pubkc && seckc) {
700          gpg_keycache_rewind (pubkc);          while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) {
         while (!gpg_keycache_next_key (pubkc, 0, &key)) {  
701              keyid = key->subkeys->keyid;              keyid = key->subkeys->keyid;
702              if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))              if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))
703                  keylist_add_key (lv, mode, key);                  keylist_add_key (kl, mode, c, key);
704          }                }
705      }      }
706      else if (pubkc) {      else if (pubkc) {
707          gpg_keycache_rewind (pubkc);          while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key))
708          while (!err) {                  keylist_add_key (kl, mode, c, key);
             err = gpg_keycache_next_key (pubkc, 0, &key);  
             if (!err)  
                 keylist_add_key (lv, mode, key);  
         }  
709      }      }
710  }  }
711    
712    
713  /* Load the list view @ctrl with the keys from the cache.  /* Load the list view @ctrl with the keys from the cache.
714     Return value: list view context on success. */     Return value: list view context on success. */
715  listview_ctrl_t  keylist_ctrl_t
716  keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,  keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,
717                int mode, int sortby)                int mode, int sortby)
718  {      {    
719      listview_ctrl_t lv;      keylist_ctrl_t kl;
720      int rc = 0;          
721        kl = new keylist_ctrl_s;
722      rc = keylist_build (&lv, ctrl, mode);      keylist_build (&kl->lv, ctrl, mode);  
723      if (rc)      keylist_load_keycache (kl, mode, pubkc, seckc);
724          return NULL;                  kl->nkeys = update_keys (kl, 0, &kl->keys);
725      keylist_load_keycache (lv, mode, pubkc, seckc);      keylist_sort (kl, sortby);    
726      keylist_sort (lv, sortby);      return kl;
     if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN))  
         keylist_add_groups (lv);  
     return lv;  
727  }  }
728    
729    
730  /* Reload the given key list control @lv. */  /* Reload the given key list control @lv. */
731  int  int
732  keylist_reload (listview_ctrl_t lv, gpg_keycache_t pubkc, int mode, int sortby)  keylist_reload (keylist_ctrl_t kl, gpg_keycache_t pubkc, int mode, int sortby)
733  {  {
734      listview_del_all (lv);      listview_del_all_items (kl->lv);
735      keylist_load_keycache( lv, mode, pubkc, NULL );      keylist_load_keycache (kl, mode, pubkc, NULL);
736      keylist_sort (lv, sortby);      /* It is possible that the list shrinks or increases so we need to
737           rebuild the list again. */
738        free (kl->keys); kl->keys = NULL;
739        kl->nkeys = update_keys (kl, 0, &kl->keys);
740        keylist_sort (kl, sortby);
741      return 0;      return 0;
742  }  }
743    
744    
745  void  void
746  keylist_delete (listview_ctrl_t lv)  keylist_delete (keylist_ctrl_t kl)
747  {  {
748      if (lv) {      if (!kl)
749          listview_release (lv);          return;
750        if (kl->keys != NULL) {
751            free (kl->keys);
752            kl->keys = NULL;
753        }
754        if (kl->lv != NULL) {
755            listview_release (kl->lv);
756            kl->lv = NULL;
757      }      }
758  }  }
759    
760    
761  /* Return if there is a secret for @key.  
762     0 means success. */  
763    /* Enumeration for possible key icons. */
764    enum key_icontype_t {
765        IMG_KEY_PUB = 0,
766        IMG_KEY_PAIR = 1,
767        IMG_KEY_PAIR_REV = 2,
768        IMG_KEY_PUB_REV = 3,
769        IMG_KEY_PUB_EXP = 6,
770    };
771    
772    
773  static int  static int
774  find_secret_key (gpgme_key_t key)  key_get_image_id (gpgme_key_t key)
775  {  {
776      const char *keyid;      if (find_secret_key (key))    
777      winpt_key_s skey;          return key->revoked ? IMG_KEY_PAIR_REV :IMG_KEY_PAIR;
778            if (key->revoked)
779      memset (&skey, 0, sizeof (skey));          return IMG_KEY_PUB_REV;
780      keyid = key->subkeys->keyid;      if (key->expired)
781      if (!keyid)          return IMG_KEY_PUB_EXP;
782          return 0;      return IMG_KEY_PUB;
     winpt_get_seckey (keyid, &skey);  
     if (skey.ext && skey.ext->gloflags.divert_to_card)  
         return 2;  
     return skey.ctx? 1 : 0;  
783  }  }
784    
785    
786  static int  static int
787  do_addkey (listview_ctrl_t lv, gpgme_key_t key, int uididx, int keyidx, int list)  do_addkey (listview_ctrl_t lv, struct keycache_s *ctx, gpgme_key_t key,
788  {                 int uididx, int keyidx, int list)
789      LV_ITEM lvi;  {  
790      gpgme_user_id_t u;      gpgme_user_id_t u;
791      gpgme_subkey_t k;      gpgme_subkey_t k;
792      char fmt[128], *p;      LV_ITEM lvi;    
793        char *p;
794      const char *attr;      const char *attr;
795      u32 key_attr;      int idx = 0;
     int idx = 0;      
796    
797      /* we check the pubkey algorithm here to make sure that no ElGamal      /* we check the pubkey algorithm here to make sure that no ElGamal
798         sign+encrypt key is used in _any_ mode */         sign+encrypt key is used in _any_ mode */
799      if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {      if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {
800          log_debug ("ElGamal (E+S) key found: %s (%s)\n",          log_debug ("ElGamal (E+S) key found: %s (%s)\n",
801                     key->uids->name, key->subkeys->keyid);                     key->uids->name, key->subkeys->keyid);
802          return 0;          return 0;
803      }      }
804    
805                if (listview_add_item2 (lv, " ", (void *)ctx))
     if (listview_add_item2 (lv, " ", (void *)key))        
806          return WPTERR_GENERAL;          return WPTERR_GENERAL;
807            
808      attr = key->uids->uid;      attr = ctx->uids->uid;
809      memset (&lvi, 0, sizeof lvi);      memset (&lvi, 0, sizeof lvi);
810      lvi.mask = LVIF_TEXT | LVIF_PARAM;      lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
811      lvi.pszText = (char *)attr;      lvi.pszText = (char *)attr;
812      lvi.lParam = (LPARAM )key;      lvi.iImage = key_get_image_id (key);
813      if (ListView_SetItem( lv->ctrl, &lvi ) == FALSE)      lvi.lParam = (LPARAM )ctx;
814        if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
815          return WPTERR_GENERAL;          return WPTERR_GENERAL;
816                    
817      if (uididx == -1) { /* request the primary user-id of the key. */      if (uididx == -1) { /* request the primary user-id of the key. */
818          attr = key->uids->uid;          attr = ctx->uids->uid;
819          uididx = 0;          uididx = 0;
820      }      }
821      else {      else {
822          u = get_nth_userid (key, uididx);          u = get_nth_userid (key, uididx);
823          if (!u || u->revoked || uididx < 0)          if (!u || u->revoked || uididx < 0)
824              uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */              uididx = 0;
825          u = get_nth_userid (key, uididx);          u = get_nth_userid (key, uididx);
         /*attr = key->uids->uid; XXX*/  
826          attr = u->uid;          attr = u->uid;
827      }      }
828      if (attr == NULL || strlen (attr) < 5) { /* normal userids are >= 5 chars */      if (attr == NULL || strlen (attr) < 5) { /* normal userids are > 5 chars */
829          attr = _("Invalid User ID");          attr = _("Invalid User ID");
830          listview_add_sub_item (lv, 0, idx++, attr);          listview_add_sub_item (lv, 0, idx++, attr);
831      }        }  
832      else {      else        
833          char *uid = utf8_to_wincp (attr, strlen (attr));          listview_add_sub_item (lv, 0, idx++, attr);
         if (uid) {  
             listview_add_sub_item (lv, 0, idx++, uid);  
             free (uid);  
         }  
     }  
834      k = get_nth_key (key, keyidx);      k = get_nth_key (key, keyidx);
835      if (k && k->keyid) {      if (k && k->keyid != NULL) {
836          _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8);          char keyid[16+1];
837          listview_add_sub_item( lv, 0, idx++, fmt );  
838            _snprintf (keyid, DIM (keyid) -1, "0x%s", k->keyid + 8);
839            listview_add_sub_item (lv, 0, idx++, keyid);
840      }      }
841      if (list > 0) {      if (list > 0) {
842          key_attr = find_secret_key (key);          DWORD key_attr = find_secret_key (key);
843          if (!key_attr)          if (!key_attr)
844              attr = "pub";              attr = "pub";
845          else          else
# Line 732  do_addkey (listview_ctrl_t lv, gpgme_key Line 848  do_addkey (listview_ctrl_t lv, gpgme_key
848      }      }
849      if (lv->cols >= 2) {      if (lv->cols >= 2) {
850          attr = get_key_size (key, list == -1? keyidx+1 : 0);          attr = get_key_size (key, list == -1? keyidx+1 : 0);
851          if (attr)          if (attr != NULL)
852              listview_add_sub_item (lv, 0, idx++, attr);              listview_add_sub_item (lv, 0, idx++, attr);
853      }      }
854      if (lv->cols >= 3) {      if (lv->cols >= 3) {
855          attr = get_key_algo (key, list == -1? keyidx+1 : 0);          attr = get_key_algo (key, list == -1? keyidx+1 : 0);
856          if (attr)          if (attr != NULL)
857              listview_add_sub_item( lv, 0, idx++, attr);              listview_add_sub_item( lv, 0, idx++, attr);
858      }      }
859      if( lv->cols >= 4 ) {      if (lv->cols >= 4) {
860          p = get_key_status( key, uididx, list > 0? 1 : 0 );          p = get_key_status (key, uididx, list > 0? 1 : 0);
861          if (!p)          if (p != NULL)
862              return WPTERR_GENERAL;              listview_add_sub_item (lv, 0, idx++, p);
         listview_add_sub_item (lv, 0, idx++, p);  
863          free_if_alloc (p);          free_if_alloc (p);
864      }      }
865      if (lv->cols >= 5) {      if (lv->cols >= 5) {
866          attr = get_key_trust (key, uididx, list > 0? 1 : 0);          attr = get_key_trust (key, uididx, list > 0? 1 : 0);
867          listview_add_sub_item (lv, 0, idx++, attr);          listview_add_sub_item (lv, 0, idx++, attr);
868      }      }
869      if( lv->cols >= 6 ) {      if (lv->cols >= 6) {
870          k = get_nth_key (key, keyidx);          k = get_nth_key (key, keyidx);
871          key_attr = k->timestamp;          if (k->timestamp > 0) {
872          if( key_attr ) {              attr = get_key_created (k->timestamp);
873              attr = get_key_created (key_attr);              listview_add_sub_item (lv, 0, idx++, attr);
874              listview_add_sub_item( lv, 0, idx++, attr );          }
         }        
875      }      }
876    
877      return 0;      return 0;
878  }  }
879    
880    
881    /* Update a single column @col but for each element in the
882       listview @lv. */
883  void  void
884  keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)  keylist_upd_col (keylist_ctrl_t kl, int col)
885  {  {
886        gpgme_key_t key;
887      const char *s;      const char *s;
888        char buf[32], *p;
889    
890        for (int i=0; i < listview_count_items (kl->lv, 0); i++) {
891            key = km_get_key_ptr (kl, i, NULL);
892            if (!key)
893                continue;
894            switch (col) {
895            case KM_COL_KEYID:
896                _snprintf (buf, DIM (buf)-1, "0x%s", key->subkeys->keyid+8);
897                listview_add_sub_item (kl->lv, i, col, buf);
898                break;
899    
900            case KM_COL_CIPHER:
901                s = get_key_algo (key, 0);
902                listview_add_sub_item (kl->lv, i, col, s);
903                break;
904    
905            case KM_COL_TYPE:
906                s = find_secret_key (key)? "pub/sec" : "pub";
907                listview_add_sub_item (kl->lv, i, col, s);
908                break;
909    
910            case KM_COL_CREAT:
911                s = get_key_created (key->subkeys->timestamp);
912                listview_add_sub_item (kl->lv, i, col, s);
913                break;
914    
915            case KM_COL_DESC:
916                p = get_key_desc (key);
917                listview_add_sub_item (kl->lv, i, col, p);
918                free_if_alloc (p);
919                break;
920            }
921        }
922    }
923    
924    
925    /* Update the listview item at position @pos with the data from
926       the key @key. */
927    void
928    keylist_upd_key (keylist_ctrl_t kl, int pos,
929                     struct keycache_s *ctx, gpgme_key_t key)
930    {
931        listview_ctrl_t lv = kl->lv;
932        char *p;
933      char tmp[32];      char tmp[32];
934    
935      listview_set_item2 (lv, pos, (void *)key);      listview_set_item2 (lv, pos, (void *)ctx);
936      /* the only mode we support is KYLIST_LIST in the Key Manager */      update_key (kl, pos, key);
937        /* the only mode we support is KEYLIST_LIST in the Key Manager */
938            
939      s = key->uids->uid;      const char *s = ctx->uids->uid;
940      if (s)      if (s)
941          listview_add_sub_item (lv, pos, 0, s);          listview_add_sub_item (lv, pos, KM_COL_UID, s);
942    
943      s = key->subkeys->keyid;      s = key->subkeys->keyid;
944      if (s) {      if (s) {
945          sprintf (tmp, "0x%s", s+8);          sprintf (tmp, "0x%s", s+8);
946          listview_add_sub_item (lv, pos, 1, tmp);          listview_add_sub_item (lv, pos, KM_COL_KEYID, tmp);
947      }      }
948    
949      s = find_secret_key (key)? "pub/sec" : "pub";      s = find_secret_key (key)? "pub/sec" : "pub";
950      listview_add_sub_item (lv, pos, 2, s);      listview_add_sub_item (lv, pos, KM_COL_TYPE, s);
951    
952      s = get_key_size (key, 0);      s = get_key_size (key, 0);
953      if (s)      if (s)
954          listview_add_sub_item (lv, pos, 3, s);          listview_add_sub_item (lv, pos, KM_COL_SIZE, s);
955    
956      s = get_key_algo (key, 0);      s = get_key_algo (key, 0);
957      if (s)      if (s)
958          listview_add_sub_item (lv, pos, 4, s);          listview_add_sub_item (lv, pos, KM_COL_CIPHER, s);
959    
960      s = get_key_status (key, 0, 1);      p = get_key_status (key, 0, 1);
961      if (s)      if (p) {
962          listview_add_sub_item (lv, pos, 5, s);          listview_add_sub_item (lv, pos, KM_COL_VALID, p);
963            free_if_alloc (p);
964        }
965    
966      s = get_key_trust (key, 0, 1);      s = get_key_trust (key, 0, 1);
967      if (s)      if (s)
968          listview_add_sub_item (lv, pos, 6, s);          listview_add_sub_item (lv, pos, KM_COL_TRUST, s);
969    
970      long t = key->subkeys->timestamp;      long t = key->subkeys->timestamp;
971      s = get_key_created (t);      s = get_key_created (t);
972      if (s)      if (s)
973          listview_add_sub_item (lv, pos, 7, s);          listview_add_sub_item (lv, pos, KM_COL_CREAT, s);
974  }  }
975    
976    
977  int  int
978  keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)  keylist_add_key (keylist_ctrl_t kl, int mode,
979  {                   struct keycache_s *ctx, gpgme_key_t key)
980      int uids, rc = 0, i;  {    
981      gpgme_subkey_t k;      gpgme_subkey_t k;
982        listview_ctrl_t lv = kl->lv;
983        int uids, rc, i;
984    
985      /* if the entire key is disabled, just return. */      /* if the entire key is disabled, just return. */
986      if (key->disabled)      if (key->disabled && !(mode & KEYLIST_LIST))
987          return 0;          return 0;
988    
989      for (k=key->subkeys, i = 0; i < count_subkeys (key); i++, k=k->next) {      for (k = key->subkeys, i = 0; i < count_subkeys (key); i++, k = k->next) {
990          if (k->invalid) {          if (k->invalid) {
991              log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name);              log_debug ("keylist_add_key: invalid key \"%s\"\n",
992                           key->uids->name);
993              continue; /* Don't use invalid keys */              continue; /* Don't use invalid keys */
994          }          }
995    
996          if (mode & KEYLIST_ALL) {          if (mode & KEYLIST_ALL) {
997              uids = count_userids (key);              uids = count_userids (key);
998              rc = do_addkey (lv, key, uids, i, 0);              rc = do_addkey (lv, ctx, key, uids, i, 0);
999              if( rc )              if (rc)
1000                  return rc;                  return rc;
1001          }          }
1002          else if (mode & KEYLIST_LIST)          else if (mode & KEYLIST_LIST)
1003              return do_addkey (lv, key, -1, i, 1);              return do_addkey (lv, ctx, key, -1, i, 1);
1004          else if (mode & KEYLIST_ENCRYPT) {          else if (mode & KEYLIST_ENCRYPT) {
1005              if (k->can_encrypt && key_is_useable (k)) {              if (k->can_encrypt && key_is_useable (k)) {
1006                  if (mode & KEYLIST_FLAG_FILE) {                  if (mode & KEYLIST_FLAG_FILE) {
1007                      rc = do_addkey (lv, key, -1, i, -1);                      rc = do_addkey (lv, ctx, key, -1, i, -1);
1008                      if (rc)                      if (rc)
1009                          return rc;                          return rc;
1010                  }                  }
1011                  else {                  else {
1012                      for( uids = 0;  uids < count_userids (key); uids++ ) {                      for (uids = 0;  uids < count_userids (key); uids++) {
1013                          rc = do_addkey( lv, key, uids, i, -1 );                          rc = do_addkey (lv, ctx, key, uids, i, -1);
1014                          if( rc )                          if (rc)
1015                              return rc;                              return rc;
1016                      }                      }
1017                  }                  }
1018              }              }
1019          }          }
1020          else if (mode & KEYLIST_ENCRYPT_MIN) {          else if (mode & KEYLIST_ENCRYPT_MIN) {
1021              if( k->can_encrypt && key_is_useable (k))              if (k->can_encrypt && key_is_useable (k)) {
1022              {                  rc = do_addkey (lv, ctx, key, -1, i, -1);
                 rc = do_addkey (lv, key, -1, i, -1);  
1023                  return rc;                  return rc;
1024              }              }
1025          }                }      
# Line 860  keylist_add_key (listview_ctrl_t lv, int Line 1027  keylist_add_key (listview_ctrl_t lv, int
1027              if (k->can_sign              if (k->can_sign
1028                  && find_secret_key (key)                  && find_secret_key (key)
1029                  && key_is_useable (k)) {                  && key_is_useable (k)) {
1030                  rc = do_addkey (lv, key, -1, i, -1);                  rc = do_addkey (lv, ctx, key, -1, i, -1);
1031                  if (rc)                  if (rc)
1032                      return rc;                        return rc;  
1033              }              }
1034          }                }      
1035      }      }
1036    
1037      return rc;        return 0;
1038  } /* keylist_add_key */  }
1039    
1040    
1041  int  int
1042  keylist_sort (listview_ctrl_t lv, int sortby)  keylist_sort (keylist_ctrl_t kl, int sortby)
1043  {        {
1044      return listview_sort_items (lv, sortby, keylist_cmp_cb);      int ret = listview_sort_items (kl->lv, sortby, keylist_cmp_cb);
1045        kl->nkeys = update_keys (kl, 1, &kl->keys);
1046        return ret;
1047  }  }
1048    
1049    
1050  /* Check that the validity @validity is at least >= marginal. */  /* Check that the validity @validity is at least >= marginal. */
1051  static int  static int
1052  key_check_validity (const char *validity)  key_check_validity (gpgme_key_t key)
1053  {      {
1054      if (strstr (validity, "Unknown") ||      gpgme_user_id_t u;
1055          strstr (validity, "Undefined") ||  
1056          strstr (validity, "Never") ||      for (u=key->uids; u; u =u->next) {
1057          strstr (validity, "None"))          if (u->validity >= GPGME_VALIDITY_MARGINAL)
1058          return 0;                return -1;
1059      return 1;      }
1060    
1061        return 0;
1062  }  }
1063    
1064    
# Line 896  key_check_validity (const char *validity Line 1067  key_check_validity (const char *validity
1067     fully trusted. @r_count returns the number of selected keys.     fully trusted. @r_count returns the number of selected keys.
1068     Return value: the key list on success, NULL otherwise. */     Return value: the key list on success, NULL otherwise. */
1069  gpgme_key_t*  gpgme_key_t*
1070  keylist_get_recipients (listview_ctrl_t lv, int *r_force_trust, int *r_count)  keylist_get_recipients (keylist_ctrl_t kl, int *r_force_trust, size_t *r_count)
1071                            
1072  {  {
1073      int count = 0, force_trust = 0;      gpgme_key_t *keybuf, key;
1074      int n, j, ka_pos = 0, rc = 0;      listview_ctrl_t lv = kl->lv;
     int k_pos=0;  
     char keyid[32], valid[32], id[100];  
1075      key_array_s *ka = NULL;      key_array_s *ka = NULL;
1076      gpgme_key_t *keybuf;      keycache_s *c;    
1077        size_t count = 0;
1078      n = listview_count_items( lv, 0 );      int force_trust = 0;
1079            int nkeys, ka_pos = 0, rc = 0;
1080      ka = key_array_new( n );      int k_pos=0;
     if (!ka)  
         BUG (NULL);  
1081    
1082      keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));      nkeys = listview_count_items (lv, 0);    
1083        ka = key_array_new (nkeys);
1084        keybuf = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t));
1085      if (!keybuf)      if (!keybuf)
1086          BUG (NULL);          BUG (NULL);
1087                    
1088      for( j = 0; j < n; j++ ) {      for (int j = 0; j < nkeys; j++) {
1089          if( listview_get_item_state (lv, j) || n == 1) {          if (listview_get_item_state (lv, j) || nkeys == 1) {
1090              listview_get_item_text (lv, j, 0, id, sizeof id-1);              key = km_get_key_ptr (kl, j, &c);
1091              listview_get_item_text (lv, j, 1, keyid, sizeof keyid - 1);                              if (!key)
1092              listview_get_item_text (lv, j, 4, valid, sizeof valid -1);                  BUG (0);
1093              if( !key_check_validity (valid)              if (!key_check_validity (key) &&
1094                   && !key_array_search( ka, ka_pos, keyid )) {                  !key_array_search (ka, ka_pos, key->subkeys->keyid)) {
1095                  char *warn = new char[512+strlen (id) + 1];                  StringBuffer warn;
1096                  if (!warn)                  warn = warn + c->uids->uid + ":\n\n";
1097                      BUG (0);                  warn = warn +_("It is NOT certain that the key belongs to the person\n"
1098                  sprintf (warn,                           "named in the user ID.  If you *really* know what you are\n"
1099                      _("It is NOT certain that the key belongs to the person\n"                           "doing, you may answer the next question with no\n"
1100                        "named in the user ID.  If you *really* know what you are\n"                           "\nSkip this key?");
1101                        "doing, you may answer the next question with yes\n"                  rc = msg_box (NULL, warn.getBuffer(), _("Warning"), MB_WARN_ASK);
1102                        "\n"                  if (reg_prefs.always_trust || rc == IDNO) {
1103                        "Use \"%s\" anyway?"), id);                      keybuf[k_pos++] = key;
                 if (reg_prefs.always_trust)  
                     rc = IDYES;  
                 else  
                     rc = msg_box (NULL, warn, _("Recipients"), MB_ERR_ASK);  
                 if (rc == IDYES) {  
                     gpgme_key_t k;  
                     get_pubkey (keyid, &k);  
                     keybuf[k_pos++] = k;  
1104                      force_trust++;                      force_trust++;
1105                      ka[ka_pos].checked = 1;                      ka[ka_pos].checked = 1;
1106                      strcpy (ka[ka_pos++].keyid, keyid);                      strcpy (ka[ka_pos++].keyid, key->subkeys->keyid);
1107                      count++;                      count++;
1108                  }                  }
                 free_if_alloc (warn);  
1109              }              }
1110              else {              else {
1111                  gpgme_key_t k;                  keybuf[k_pos++] = key;
                 listview_get_item_text( lv, j, 1, keyid, sizeof keyid -1 );  
                 get_pubkey (keyid, &k);  
                 keybuf[k_pos++] = k;  
1112                  count++;                          count++;        
1113              }              }
1114          }          }
# Line 965  keylist_get_recipients (listview_ctrl_t Line 1123  keylist_get_recipients (listview_ctrl_t
1123    
1124    
1125  static int  static int
1126  keylist_get_keyflags (const char *buf, size_t buflen)  keylist_get_keyflags (gpgme_key_t key)
1127  {  {
1128      int c = 0, flags = 0;      int flags = KEYFLAG_NONE;
1129    
1130      if( *buf != '[' )      if (key->revoked)
1131          return KEYFLAG_NONE;          flags |= KEYFLAG_REVOKED;
1132      while (buf && c != ']')      if (key->expired)
1133      {          flags |= KEYFLAG_EXPIRED;
1134          c = *buf++;      if (key->disabled)
1135          if (c == 'R')          flags |= KEYFLAG_DISABLED;
             flags |= KEYFLAG_REVOKED;  
         if (c == 'E')  
             flags |= KEYFLAG_EXPIRED;  
         if (c == 'D')  
             flags |= KEYFLAG_DISABLED;  
     }  
1136    
1137      return flags;      return flags;
1138  } /* keylist_get_keyflags */  }
1139    
1140    
1141    
1142  gpgme_key_t*  gpgme_key_t*
1143  keylist_enum_recipients (listview_ctrl_t lv,  int listype, int *r_count)  keylist_enum_recipients (keylist_ctrl_t kl,  int listype, size_t *r_count)
1144  {  {
1145      gpgme_key_t* rset;      gpgme_key_t *rset;
1146      gpgme_key_t k;      gpgme_key_t key;
1147      int i, n, id, k_pos=0;      listview_ctrl_t lv = kl->lv;
1148      char keyid[32], t[128], t2[128];      struct keycache_s *c;    
1149        size_t k_pos;
1150        int nkeys, id;
1151    
1152      n = listview_count_items (lv, 0);      nkeys = listview_count_items (lv, 0);
1153      if (!n)      if (!nkeys)
1154          return 0;          return 0;
1155      rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));      rset = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t));
1156      if (!rset)      if (!rset)
1157          BUG (NULL);          BUG (NULL);
1158      for( i = 0; i < n; i++ ) {      k_pos = 0;
1159          if( !listview_get_item_state( lv, i ) )      for (int i = 0; i < nkeys; i++) {
1160            if (!listview_get_item_state (lv, i))
1161              continue;              continue;
1162          listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );          key = km_get_key_ptr (kl, i, &c);
1163          switch( listype ) {          switch (listype) {
1164          case KEYLIST_LIST:          case KEYLIST_LIST:
1165              listview_get_item_text( lv, i, 5, t, sizeof t - 1 );              if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) {
1166              if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) {                  id = printf_box (_("Recipients"), MB_INFO|MB_YESNO,
1167                  _snprintf( t2, sizeof t2 -1,                  _("KeyID %s.\nDo you really want to export a revoked key?"),
1168                              _("KeyID %s.\nDo you really want to export a revoked key?"), keyid );                                   c->uids->uid);
1169                  id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO );                  if (id == IDNO)
1170                  if( id == IDNO )                      continue;
                     continue;            
1171              }              }
1172              break;              break;
1173          }          }
1174          get_pubkey (keyid, &k);          rset[k_pos++] = key;
         rset[k_pos++] = k;  
1175      }      }
1176      if (r_count)      if (r_count)
1177          *r_count = k_pos;          *r_count = k_pos;
1178      return rset;      return rset;
1179  } /* keylist_enum_recipients */  }
1180    
1181    
1182  void  void
1183  seclist_destroy (keylist_t * list)  seclist_destroy (keylist_t *list)
1184  {  {
1185      keylist_t l2;      keylist_t l2;
1186    
1187      while (*list) {      while (*list) {
1188          l2 = (*list)->next;          l2 = (*list)->next;
1189          safe_free (*list);          safe_free (*list);
1190          *list = l2;              *list = l2;    
1191      }      }
1192      list = NULL;      *list = NULL;
1193  } /* seclist_destroy */  }
1194    
1195    
1196  void  void
1197  seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)  seclist_init (HWND dlg, int ctlid, int flags, keylist_t *ret_list)
1198  {      {    
1199      gpg_keycache_t kc = NULL;      gpg_keycache_t kc;
1200      gpgme_key_t key = NULL;      gpgme_key_t key = NULL;
1201      HWND kb;      HWND kb;
1202      keylist_t list=NULL, l, l2;          keylist_t list=NULL, l, l2;    
1203      long pos = 0;      long pos;
1204    
1205      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
1206      kb = GetDlgItem (dlg, ctlid);      kb = GetDlgItem (dlg, ctlid);
# Line 1055  seclist_init (HWND dlg, int ctlid, int f Line 1210  seclist_init (HWND dlg, int ctlid, int f
1210      gpg_keycache_rewind (kc);      gpg_keycache_rewind (kc);
1211            
1212      while (!gpg_keycache_next_key (kc, 1, &key)) {      while (!gpg_keycache_next_key (kc, 1, &key)) {
1213          char *inf = NULL, *uid = NULL;          StringBuffer inf;
1214            char *uid;
1215          const char *id;          const char *id;
1216          const char *keyid;  
1217          int algo;          if (key->disabled || !key_is_useable (key->subkeys))
1218          size_t size = 0;              continue;
1219    
1220          if (flags & KEYLIST_FLAG_SHORT)          if (flags & KEYLIST_FLAG_SHORT)
1221              id = key->uids->name;              id = key->uids->name;
1222          else          else
1223              id = key->uids->uid;              id = key->uids->uid;
1224          keyid = key->subkeys->keyid;          if (!id || !key->subkeys->keyid)
1225          algo = key->subkeys->pubkey_algo;              continue;  
1226          if (!id || !keyid)  
1227              continue;          uid = utf8_to_native (id);
1228          if (key->disabled || !key_is_useable (key->subkeys))          inf = uid;
1229              continue;          inf = inf + " (" + get_key_pubalgo (key->subkeys->pubkey_algo) + "/";
1230            inf = inf + "0x" + (key->subkeys->keyid+8) + ")";
1231    
1232          uid = utf8_to_wincp (id, strlen (id));          combox_add_string (kb, inf.getBuffer ());
1233          size = strlen( uid ) + strlen( keyid ) + 32;          safe_free (uid);
         inf = new char[size+1];  
         if( !inf )  
             BUG( NULL );  
         _snprintf (inf, size, "%s (%s/0x%s)", uid,  
                    get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);  
         combox_add_string (kb, inf);  
         free_if_alloc (inf);  
         free (uid);  
1234          l = (struct keylist_s *)calloc (1, sizeof * l);          l = (struct keylist_s *)calloc (1, sizeof * l);
1235          if (!l)          if (!l)
1236              BUG (0);              BUG (0);
# Line 1094  seclist_init (HWND dlg, int ctlid, int f Line 1243  seclist_init (HWND dlg, int ctlid, int f
1243              l2->next = l;              l2->next = l;
1244          }          }
1245      }      }
1246      for( pos = 0, l2=list; pos < SendMessage( kb, CB_GETCOUNT, 0, 0 ); pos++, l2=l2->next )      for (pos = 0, l2=list; pos < SendMessage (kb, CB_GETCOUNT, 0, 0);
1247          SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key );           pos++, l2=l2->next)
1248      SendMessage( kb, CB_SETCURSEL, 0, 0 );          SendMessage (kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key);
1249        SendMessage (kb, CB_SETCURSEL, 0, 0);
1250      *ret_list = list;      *ret_list = list;
1251  }  }
1252            
1253    
1254  /* Select a secret key from the combo box with the ID @ctlid.  /* Select a secret key from the combo box with the ID @ctlid.
1255     Return the code on success in @ret_key. */     Return the code on success in @ret_key. */
# Line 1120  seclist_select_key (HWND dlg, int ctlid, Line 1270  seclist_select_key (HWND dlg, int ctlid,
1270      }      }
1271      return k? 0 : -1;      return k? 0 : -1;
1272  }  }
1273    
1274    
1275    LRESULT
1276    keylist_listview_notify (HWND hwnd, gpgme_key_t *keys,
1277                             int ctlid, LPARAM lparam)
1278    {
1279        LPNMHDR lpnmh = (LPNMHDR) lparam;
1280        
1281        if (!lpnmh)
1282            BUG (NULL);
1283    
1284        /* Make sure the message is for the control and
1285           that we have a key list. */
1286        if (lpnmh->idFrom != (DWORD)ctlid || keys == NULL)
1287            return 0;
1288        
1289        switch (lpnmh->code) {
1290        case NM_CUSTOMDRAW:
1291            LPNMLVCUSTOMDRAW lplvcd;
1292            lplvcd = (LPNMLVCUSTOMDRAW)lparam;
1293            if (lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT)            
1294                return CDRF_NOTIFYITEMDRAW;
1295    
1296            if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {        
1297                LRESULT ret = CDRF_DODEFAULT;
1298                int pos = lplvcd->nmcd.dwItemSpec;
1299                HWND lv = GetDlgItem (hwnd, ctlid);
1300                gpgme_key_t key = keys[pos];
1301                
1302                if (key != NULL) {
1303                    HFONT hfont = (HFONT)SendMessage (lv, WM_GETFONT, 0, 0);
1304                    LOGFONT lf;
1305                    if (!GetObject (hfont, sizeof (lf), &lf))
1306                        BUG (NULL);
1307                    if (key->revoked)
1308                        lf.lfStrikeOut = TRUE;
1309                    else if (key->expired)
1310                        lf.lfItalic = TRUE;
1311                    if (find_secret_key (key))
1312                        lf.lfWeight = FW_SEMIBOLD;
1313                    hfont = CreateFontIndirect (&lf);
1314                    SelectObject (lplvcd->nmcd.hdc, hfont);
1315                    if (pos & 1)
1316                        lplvcd->clrTextBk = RGB (0xE5, 0xE5, 0xE5);
1317                    ret = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT;
1318                }
1319                return ret;
1320            }
1321            
1322            if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT) {
1323                HFONT hfont = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
1324                hfont = (HFONT)SelectObject (lplvcd->nmcd.hdc, hfont);
1325                DeleteObject (hfont);
1326                return CDRF_DODEFAULT;
1327            }
1328            return CDRF_DODEFAULT;  
1329        }
1330    
1331        return 0;
1332    }

Legend:
Removed from v.73  
changed lines
  Added in v.432

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26