/[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 88 by twoaday, Mon Nov 21 12:06:59 2005 UTC revision 328 by twoaday, Fri Sep 25 16:07:38 2009 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 348  get_key_trust2 (gpgme_key_t key, int val Line 425  get_key_trust2 (gpgme_key_t key, int val
425      case GPGME_VALIDITY_MARGINAL:      case GPGME_VALIDITY_MARGINAL:
426          return _("Marginal");          return _("Marginal");
427      case GPGME_VALIDITY_FULL:      case GPGME_VALIDITY_FULL:
     case GPGME_VALIDITY_ULTIMATE:  
428          return _("Full");          return _("Full");
429        case GPGME_VALIDITY_ULTIMATE:
430            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[6];
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        listview_set_image_list (lv, 22, 14, ico, 6);
683        listview_del_all_items (lv);
684        listview_set_grid_style (lv);
685      *r_lv = lv;      *r_lv = lv;
       
     return 0;  
686  }  }
687    
688    
689  static void  static void
690  keylist_load_keycache (listview_ctrl_t lv, int mode,  keylist_load_keycache (keylist_ctrl_t kl, int mode,
691                         gpg_keycache_t pubkc, gpg_keycache_t seckc)                         gpg_keycache_t pubkc, gpg_keycache_t seckc)
692  {  {
     gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);  
693      gpgme_key_t key, skey;      gpgme_key_t key, skey;
694      const char * keyid;      struct keycache_s *c;
695        const char *keyid;
696    
697        gpg_keycache_rewind (pubkc);
698      if (pubkc && seckc) {      if (pubkc && seckc) {
699          gpg_keycache_rewind (pubkc);          while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key)) {
         while (!gpg_keycache_next_key (pubkc, 0, &key)) {  
700              keyid = key->subkeys->keyid;              keyid = key->subkeys->keyid;
701              if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))              if (keyid && !gpg_keycache_find_key (seckc, keyid, 0, &skey))
702                  keylist_add_key (lv, mode, key);                  keylist_add_key (kl, mode, c, key);
703          }                }
704      }      }
705      else if (pubkc) {      else if (pubkc) {
706          gpg_keycache_rewind (pubkc);          while (!gpg_keycache_next_key2 (pubkc, 0, &c, &key))
707          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);  
         }  
708      }      }
709  }  }
710    
711    
712  /* Load the list view @ctrl with the keys from the cache.  /* Load the list view @ctrl with the keys from the cache.
713     Return value: list view context on success. */     Return value: list view context on success. */
714  listview_ctrl_t  keylist_ctrl_t
715  keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,  keylist_load (HWND ctrl, gpg_keycache_t pubkc, gpg_keycache_t seckc,
716                int mode, int sortby)                int mode, int sortby)
717  {      {    
718      listview_ctrl_t lv;      keylist_ctrl_t kl;
719      int rc = 0;          
720        kl = new keylist_ctrl_s;
721      rc = keylist_build (&lv, ctrl, mode);      keylist_build (&kl->lv, ctrl, mode);  
722      if (rc)      keylist_load_keycache (kl, mode, pubkc, seckc);
723          return NULL;                  kl->nkeys = update_keys (kl, 0, &kl->keys);
724      keylist_load_keycache (lv, mode, pubkc, seckc);      keylist_sort (kl, sortby);    
725      keylist_sort (lv, sortby);      return kl;
     if ((mode & KEYLIST_ENCRYPT) || (mode & KEYLIST_ENCRYPT_MIN))  
         keylist_add_groups (lv);  
     return lv;  
726  }  }
727    
728    
729  /* Reload the given key list control @lv. */  /* Reload the given key list control @lv. */
730  int  int
731  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)
732  {  {
733      listview_del_all (lv);      listview_del_all_items (kl->lv);
734      keylist_load_keycache( lv, mode, pubkc, NULL );      keylist_load_keycache (kl, mode, pubkc, NULL);
735      keylist_sort (lv, sortby);      /* It is possible that the list shrinks or increases so we need to
736           rebuild the list again. */
737        free (kl->keys); kl->keys = NULL;
738        kl->nkeys = update_keys (kl, 0, &kl->keys);
739        keylist_sort (kl, sortby);
740      return 0;      return 0;
741  }  }
742    
743    
744  void  void
745  keylist_delete (listview_ctrl_t lv)  keylist_delete (keylist_ctrl_t kl)
746  {  {
747      if (lv) {      if (!kl)
748          listview_release (lv);          return;
749        if (kl->keys != NULL) {
750            free (kl->keys);
751            kl->keys = NULL;
752        }
753        if (kl->lv != NULL) {
754            listview_release (kl->lv);
755            kl->lv = NULL;
756      }      }
757  }  }
758    
759    
760  /* Return if there is a secret for @key.  
761     0 means success. */  
762    /* Enumeration for possible key icons. */
763    enum key_icontype_t {
764        IMG_KEY_PUB = 0,
765        IMG_KEY_PAIR = 1,
766        IMG_KEY_PAIR_REV = 2,
767        IMG_KEY_PUB_REV = 3
768    };
769    
770    
771  static int  static int
772  find_secret_key (gpgme_key_t key)  key_get_image_id (gpgme_key_t key)
773  {  {
774      const char *keyid;      if (find_secret_key (key))    
775      winpt_key_s skey;          return key->revoked ? IMG_KEY_PAIR_REV :IMG_KEY_PAIR;
776            if (key->revoked)
777      memset (&skey, 0, sizeof (skey));          return IMG_KEY_PUB_REV;
778      keyid = key->subkeys->keyid;      return IMG_KEY_PUB;
     if (!keyid)  
         return 0;  
     winpt_get_seckey (keyid, &skey);  
     if (skey.ext && skey.ext->gloflags.divert_to_card)  
         return 2;  
     return skey.ctx? 1 : 0;  
779  }  }
780    
781    
782  static int  static int
783  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,
784  {                 int uididx, int keyidx, int list)
785      LV_ITEM lvi;  {  
786      gpgme_user_id_t u;      gpgme_user_id_t u;
787      gpgme_subkey_t k;      gpgme_subkey_t k;
788      char fmt[128], *p;      LV_ITEM lvi;    
789        char *p;
790      const char *attr;      const char *attr;
791      u32 key_attr;      int idx = 0;
     int idx = 0;      
792    
793      /* we check the pubkey algorithm here to make sure that no ElGamal      /* we check the pubkey algorithm here to make sure that no ElGamal
794         sign+encrypt key is used in _any_ mode */         sign+encrypt key is used in _any_ mode */
795      if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {      if (list != 1 && key->subkeys->pubkey_algo == GPGME_PK_ELG) {
796          log_debug ("ElGamal (E+S) key found: %s (%s)\n",          log_debug ("ElGamal (E+S) key found: %s (%s)\n",
797                     key->uids->name, key->subkeys->keyid);                     key->uids->name, key->subkeys->keyid);
798          return 0;          return 0;
799      }      }
800    
801                if (listview_add_item2 (lv, " ", (void *)ctx))
     if (listview_add_item2 (lv, " ", (void *)key))        
802          return WPTERR_GENERAL;          return WPTERR_GENERAL;
803            
804      attr = key->uids->uid;      attr = ctx->uids->uid;
805      memset (&lvi, 0, sizeof lvi);      memset (&lvi, 0, sizeof lvi);
806      lvi.mask = LVIF_TEXT | LVIF_PARAM;      lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
807      lvi.pszText = (char *)attr;      lvi.pszText = (char *)attr;
808      lvi.lParam = (LPARAM )key;      lvi.iImage = key_get_image_id (key);
809      if (ListView_SetItem( lv->ctrl, &lvi ) == FALSE)      lvi.lParam = (LPARAM )ctx;
810        if (ListView_SetItem (lv->ctrl, &lvi) == FALSE)
811          return WPTERR_GENERAL;          return WPTERR_GENERAL;
812                    
813      if (uididx == -1) { /* request the primary user-id of the key. */      if (uididx == -1) { /* request the primary user-id of the key. */
814          attr = key->uids->uid;          attr = ctx->uids->uid;
815          uididx = 0;          uididx = 0;
816      }      }
817      else {      else {
818          u = get_nth_userid (key, uididx);          u = get_nth_userid (key, uididx);
819          if (!u || u->revoked || uididx < 0)          if (!u || u->revoked || uididx < 0)
820              uididx = 0; /* fixme: this happen sometimes but it's illegal! (<0) */              uididx = 0;
821          u = get_nth_userid (key, uididx);          u = get_nth_userid (key, uididx);
         /*attr = key->uids->uid; XXX*/  
822          attr = u->uid;          attr = u->uid;
823      }      }
824      if (attr == NULL || strlen (attr) < 5) { /* normal userids are >= 5 chars */      if (attr == NULL || strlen (attr) < 5) { /* normal userids are > 5 chars */
825          attr = _("Invalid User ID");          attr = _("Invalid User ID");
826          listview_add_sub_item (lv, 0, idx++, attr);          listview_add_sub_item (lv, 0, idx++, attr);
827      }        }  
828      else {      else        
829          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);  
         }  
     }  
830      k = get_nth_key (key, keyidx);      k = get_nth_key (key, keyidx);
831      if (k && k->keyid) {      if (k && k->keyid != NULL) {
832          _snprintf (fmt, sizeof fmt -1, "0x%s", k->keyid + 8);          char keyid[16+1];
833          listview_add_sub_item( lv, 0, idx++, fmt );  
834            _snprintf (keyid, DIM (keyid) -1, "0x%s", k->keyid + 8);
835            listview_add_sub_item (lv, 0, idx++, keyid);
836      }      }
837      if (list > 0) {      if (list > 0) {
838          key_attr = find_secret_key (key);          DWORD key_attr = find_secret_key (key);
839          if (!key_attr)          if (!key_attr)
840              attr = "pub";              attr = "pub";
841          else          else
# Line 732  do_addkey (listview_ctrl_t lv, gpgme_key Line 844  do_addkey (listview_ctrl_t lv, gpgme_key
844      }      }
845      if (lv->cols >= 2) {      if (lv->cols >= 2) {
846          attr = get_key_size (key, list == -1? keyidx+1 : 0);          attr = get_key_size (key, list == -1? keyidx+1 : 0);
847          if (attr)          if (attr != NULL)
848              listview_add_sub_item (lv, 0, idx++, attr);              listview_add_sub_item (lv, 0, idx++, attr);
849      }      }
850      if (lv->cols >= 3) {      if (lv->cols >= 3) {
851          attr = get_key_algo (key, list == -1? keyidx+1 : 0);          attr = get_key_algo (key, list == -1? keyidx+1 : 0);
852          if (attr)          if (attr != NULL)
853              listview_add_sub_item( lv, 0, idx++, attr);              listview_add_sub_item( lv, 0, idx++, attr);
854      }      }
855      if( lv->cols >= 4 ) {      if (lv->cols >= 4) {
856          p = get_key_status( key, uididx, list > 0? 1 : 0 );          p = get_key_status (key, uididx, list > 0? 1 : 0);
857          if (!p)          if (p != NULL)
858              return WPTERR_GENERAL;              listview_add_sub_item (lv, 0, idx++, p);
         listview_add_sub_item (lv, 0, idx++, p);  
859          free_if_alloc (p);          free_if_alloc (p);
860      }      }
861      if (lv->cols >= 5) {      if (lv->cols >= 5) {
862          attr = get_key_trust (key, uididx, list > 0? 1 : 0);          attr = get_key_trust (key, uididx, list > 0? 1 : 0);
863          listview_add_sub_item (lv, 0, idx++, attr);          listview_add_sub_item (lv, 0, idx++, attr);
864      }      }
865      if( lv->cols >= 6 ) {      if (lv->cols >= 6) {
866          k = get_nth_key (key, keyidx);          k = get_nth_key (key, keyidx);
867          key_attr = k->timestamp;          if (k->timestamp > 0) {
868          if( key_attr ) {              attr = get_key_created (k->timestamp);
869              attr = get_key_created (key_attr);              listview_add_sub_item (lv, 0, idx++, attr);
870              listview_add_sub_item( lv, 0, idx++, attr );          }
         }        
871      }      }
872    
873      return 0;      return 0;
874  }  }
875    
876    
877    /* Update a single column @col but for each element in the
878       listview @lv. */
879  void  void
880  keylist_upd_key (listview_ctrl_t lv, int pos, gpgme_key_t key)  keylist_upd_col (keylist_ctrl_t kl, int col)
881  {  {
882        gpgme_key_t key;
883      const char *s;      const char *s;
884        char buf[32], *p;
885    
886        for (int i=0; i < listview_count_items (kl->lv, 0); i++) {
887            key = km_get_key_ptr (kl, i, NULL);
888            if (!key)
889                continue;
890            switch (col) {
891            case KM_COL_KEYID:
892                _snprintf (buf, DIM (buf)-1, "0x%s", key->subkeys->keyid+8);
893                listview_add_sub_item (kl->lv, i, col, buf);
894                break;
895    
896            case KM_COL_CIPHER:
897                s = get_key_algo (key, 0);
898                listview_add_sub_item (kl->lv, i, col, s);
899                break;
900    
901            case KM_COL_TYPE:
902                s = find_secret_key (key)? "pub/sec" : "pub";
903                listview_add_sub_item (kl->lv, i, col, s);
904                break;
905    
906            case KM_COL_CREAT:
907                s = get_key_created (key->subkeys->timestamp);
908                listview_add_sub_item (kl->lv, i, col, s);
909                break;
910    
911            case KM_COL_DESC:
912                p = get_key_desc (key);
913                listview_add_sub_item (kl->lv, i, col, p);
914                free_if_alloc (p);
915                break;
916            }
917        }
918    }
919    
920    
921    /* Update the listview item at position @pos with the data from
922       the key @key. */
923    void
924    keylist_upd_key (keylist_ctrl_t kl, int pos,
925                     struct keycache_s *ctx, gpgme_key_t key)
926    {
927        listview_ctrl_t lv = kl->lv;
928        char *p;
929      char tmp[32];      char tmp[32];
930    
931      listview_set_item2 (lv, pos, (void *)key);      listview_set_item2 (lv, pos, (void *)ctx);
932      /* the only mode we support is KYLIST_LIST in the Key Manager */      update_key (kl, pos, key);
933        /* the only mode we support is KEYLIST_LIST in the Key Manager */
934            
935      s = key->uids->uid;      const char *s = ctx->uids->uid;
936      if (s)      if (s)
937          listview_add_sub_item (lv, pos, 0, s);          listview_add_sub_item (lv, pos, KM_COL_UID, s);
938    
939      s = key->subkeys->keyid;      s = key->subkeys->keyid;
940      if (s) {      if (s) {
941          sprintf (tmp, "0x%s", s+8);          sprintf (tmp, "0x%s", s+8);
942          listview_add_sub_item (lv, pos, 1, tmp);          listview_add_sub_item (lv, pos, KM_COL_KEYID, tmp);
943      }      }
944    
945      s = find_secret_key (key)? "pub/sec" : "pub";      s = find_secret_key (key)? "pub/sec" : "pub";
946      listview_add_sub_item (lv, pos, 2, s);      listview_add_sub_item (lv, pos, KM_COL_TYPE, s);
947    
948      s = get_key_size (key, 0);      s = get_key_size (key, 0);
949      if (s)      if (s)
950          listview_add_sub_item (lv, pos, 3, s);          listview_add_sub_item (lv, pos, KM_COL_SIZE, s);
951    
952      s = get_key_algo (key, 0);      s = get_key_algo (key, 0);
953      if (s)      if (s)
954          listview_add_sub_item (lv, pos, 4, s);          listview_add_sub_item (lv, pos, KM_COL_CIPHER, s);
955    
956      s = get_key_status (key, 0, 1);      p = get_key_status (key, 0, 1);
957      if (s)      if (p) {
958          listview_add_sub_item (lv, pos, 5, s);          listview_add_sub_item (lv, pos, KM_COL_VALID, p);
959            free_if_alloc (p);
960        }
961    
962      s = get_key_trust (key, 0, 1);      s = get_key_trust (key, 0, 1);
963      if (s)      if (s)
964          listview_add_sub_item (lv, pos, 6, s);          listview_add_sub_item (lv, pos, KM_COL_TRUST, s);
965    
966      long t = key->subkeys->timestamp;      long t = key->subkeys->timestamp;
967      s = get_key_created (t);      s = get_key_created (t);
968      if (s)      if (s)
969          listview_add_sub_item (lv, pos, 7, s);          listview_add_sub_item (lv, pos, KM_COL_CREAT, s);
970  }  }
971    
972    
973  int  int
974  keylist_add_key (listview_ctrl_t lv, int mode, gpgme_key_t key)  keylist_add_key (keylist_ctrl_t kl, int mode,
975  {                   struct keycache_s *ctx, gpgme_key_t key)
976      int uids, rc = 0, i;  {    
977      gpgme_subkey_t k;      gpgme_subkey_t k;
978        listview_ctrl_t lv = kl->lv;
979        int uids, rc, i;
980    
981      /* if the entire key is disabled, just return. */      /* if the entire key is disabled, just return. */
982      if (key->disabled && !(mode & KEYLIST_LIST))      if (key->disabled && !(mode & KEYLIST_LIST))
983          return 0;          return 0;
984    
985      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) {
986          if (k->invalid) {          if (k->invalid) {
987              log_debug ("keylist_add_key: invalid key \"%s\"\n", key->uids->name);              log_debug ("keylist_add_key: invalid key \"%s\"\n",
988                           key->uids->name);
989              continue; /* Don't use invalid keys */              continue; /* Don't use invalid keys */
990          }          }
991    
992          if (mode & KEYLIST_ALL) {          if (mode & KEYLIST_ALL) {
993              uids = count_userids (key);              uids = count_userids (key);
994              rc = do_addkey (lv, key, uids, i, 0);              rc = do_addkey (lv, ctx, key, uids, i, 0);
995              if( rc )              if (rc)
996                  return rc;                  return rc;
997          }          }
998          else if (mode & KEYLIST_LIST)          else if (mode & KEYLIST_LIST)
999              return do_addkey (lv, key, -1, i, 1);              return do_addkey (lv, ctx, key, -1, i, 1);
1000          else if (mode & KEYLIST_ENCRYPT) {          else if (mode & KEYLIST_ENCRYPT) {
1001              if (k->can_encrypt && key_is_useable (k)) {              if (k->can_encrypt && key_is_useable (k)) {
1002                  if (mode & KEYLIST_FLAG_FILE) {                  if (mode & KEYLIST_FLAG_FILE) {
1003                      rc = do_addkey (lv, key, -1, i, -1);                      rc = do_addkey (lv, ctx, key, -1, i, -1);
1004                      if (rc)                      if (rc)
1005                          return rc;                          return rc;
1006                  }                  }
1007                  else {                  else {
1008                      for( uids = 0;  uids < count_userids (key); uids++ ) {                      for (uids = 0;  uids < count_userids (key); uids++) {
1009                          rc = do_addkey( lv, key, uids, i, -1 );                          rc = do_addkey (lv, ctx, key, uids, i, -1);
1010                          if( rc )                          if (rc)
1011                              return rc;                              return rc;
1012                      }                      }
1013                  }                  }
1014              }              }
1015          }          }
1016          else if (mode & KEYLIST_ENCRYPT_MIN) {          else if (mode & KEYLIST_ENCRYPT_MIN) {
1017              if( k->can_encrypt && key_is_useable (k))              if (k->can_encrypt && key_is_useable (k)) {
1018              {                  rc = do_addkey (lv, ctx, key, -1, i, -1);
                 rc = do_addkey (lv, key, -1, i, -1);  
1019                  return rc;                  return rc;
1020              }              }
1021          }                }      
# Line 860  keylist_add_key (listview_ctrl_t lv, int Line 1023  keylist_add_key (listview_ctrl_t lv, int
1023              if (k->can_sign              if (k->can_sign
1024                  && find_secret_key (key)                  && find_secret_key (key)
1025                  && key_is_useable (k)) {                  && key_is_useable (k)) {
1026                  rc = do_addkey (lv, key, -1, i, -1);                  rc = do_addkey (lv, ctx, key, -1, i, -1);
1027                  if (rc)                  if (rc)
1028                      return rc;                        return rc;  
1029              }              }
1030          }                }      
1031      }      }
1032    
1033      return rc;        return 0;
1034  } /* keylist_add_key */  }
1035    
1036    
1037  int  int
1038  keylist_sort (listview_ctrl_t lv, int sortby)  keylist_sort (keylist_ctrl_t kl, int sortby)
1039  {        {
1040      return listview_sort_items (lv, sortby, keylist_cmp_cb);      int ret = listview_sort_items (kl->lv, sortby, keylist_cmp_cb);
1041        kl->nkeys = update_keys (kl, 1, &kl->keys);
1042        return ret;
1043  }  }
1044    
1045    
1046  /* Check that the validity @validity is at least >= marginal. */  /* Check that the validity @validity is at least >= marginal. */
1047  static int  static int
1048  key_check_validity (const char *validity)  key_check_validity (gpgme_key_t key)
1049  {      {
1050      if (strstr (validity, "Unknown") ||      gpgme_user_id_t u;
1051          strstr (validity, "Undefined") ||  
1052          strstr (validity, "Never") ||      for (u=key->uids; u; u =u->next) {
1053          strstr (validity, "None"))          if (u->validity >= GPGME_VALIDITY_MARGINAL)
1054          return 0;                return -1;
1055      return 1;      }
1056    
1057        return 0;
1058  }  }
1059    
1060    
# Line 896  key_check_validity (const char *validity Line 1063  key_check_validity (const char *validity
1063     fully trusted. @r_count returns the number of selected keys.     fully trusted. @r_count returns the number of selected keys.
1064     Return value: the key list on success, NULL otherwise. */     Return value: the key list on success, NULL otherwise. */
1065  gpgme_key_t*  gpgme_key_t*
1066  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)
1067                            
1068  {  {
1069      int count = 0, force_trust = 0;      gpgme_key_t *keybuf, key;
1070      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];  
1071      key_array_s *ka = NULL;      key_array_s *ka = NULL;
1072      gpgme_key_t *keybuf;      keycache_s *c;    
1073        size_t count = 0;
1074      n = listview_count_items( lv, 0 );      int force_trust = 0;
1075            int nkeys, ka_pos = 0, rc = 0;
1076      ka = key_array_new( n );      int k_pos=0;
     if (!ka)  
         BUG (NULL);  
1077    
1078      keybuf = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));      nkeys = listview_count_items (lv, 0);    
1079        ka = key_array_new (nkeys);
1080        keybuf = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t));
1081      if (!keybuf)      if (!keybuf)
1082          BUG (NULL);          BUG (NULL);
1083                    
1084      for( j = 0; j < n; j++ ) {      for (int j = 0; j < nkeys; j++) {
1085          if( listview_get_item_state (lv, j) || n == 1) {          if (listview_get_item_state (lv, j) || nkeys == 1) {
1086              listview_get_item_text (lv, j, 0, id, sizeof id-1);              key = km_get_key_ptr (kl, j, &c);
1087              listview_get_item_text (lv, j, 1, keyid, sizeof keyid - 1);                              if (!key)
1088              listview_get_item_text (lv, j, 4, valid, sizeof valid -1);                  BUG (0);
1089              if( !key_check_validity (valid)              if (!key_check_validity (key) &&
1090                   && !key_array_search( ka, ka_pos, keyid )) {                  !key_array_search (ka, ka_pos, key->subkeys->keyid)) {
1091                  char *warn = new char[512+strlen (id) + 1];                  StringBuffer warn;
1092                  if (!warn)                  warn = warn + c->uids->uid + ":\n\n";
1093                      BUG (0);                  warn = warn +_("It is NOT certain that the key belongs to the person\n"
1094                  sprintf (warn,                           "named in the user ID.  If you *really* know what you are\n"
1095                      _("It is NOT certain that the key belongs to the person\n"                           "doing, you may answer the next question with no\n"
1096                        "named in the user ID.  If you *really* know what you are\n"                           "\nSkip this key?");
1097                        "doing, you may answer the next question with yes\n"                  rc = msg_box (NULL, warn.getBuffer(), _("Warning"), MB_WARN_ASK);
1098                        "\n"                  if (reg_prefs.always_trust || rc == IDNO) {
1099                        "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;  
1100                      force_trust++;                      force_trust++;
1101                      ka[ka_pos].checked = 1;                      ka[ka_pos].checked = 1;
1102                      strcpy (ka[ka_pos++].keyid, keyid);                      strcpy (ka[ka_pos++].keyid, key->subkeys->keyid);
1103                      count++;                      count++;
1104                  }                  }
                 free_if_alloc (warn);  
1105              }              }
1106              else {              else {
1107                  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;  
1108                  count++;                          count++;        
1109              }              }
1110          }          }
# Line 965  keylist_get_recipients (listview_ctrl_t Line 1119  keylist_get_recipients (listview_ctrl_t
1119    
1120    
1121  static int  static int
1122  keylist_get_keyflags (const char *buf, size_t buflen)  keylist_get_keyflags (gpgme_key_t key)
1123  {  {
1124      int c = 0, flags = 0;      int flags = KEYFLAG_NONE;
1125    
1126      if( *buf != '[' )      if (key->revoked)
1127          return KEYFLAG_NONE;          flags |= KEYFLAG_REVOKED;
1128      while (buf && c != ']')      if (key->expired)
1129      {          flags |= KEYFLAG_EXPIRED;
1130          c = *buf++;      if (key->disabled)
1131          if (c == 'R')          flags |= KEYFLAG_DISABLED;
             flags |= KEYFLAG_REVOKED;  
         if (c == 'E')  
             flags |= KEYFLAG_EXPIRED;  
         if (c == 'D')  
             flags |= KEYFLAG_DISABLED;  
     }  
1132    
1133      return flags;      return flags;
1134  } /* keylist_get_keyflags */  }
1135    
1136    
1137    
1138  gpgme_key_t*  gpgme_key_t*
1139  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)
1140  {  {
1141      gpgme_key_t* rset;      gpgme_key_t *rset;
1142      gpgme_key_t k;      gpgme_key_t key;
1143      int i, n, id, k_pos=0;      listview_ctrl_t lv = kl->lv;
1144      char keyid[32], t[128], t2[128];      struct keycache_s *c;    
1145        size_t k_pos;
1146        int nkeys, id;
1147    
1148      n = listview_count_items (lv, 0);      nkeys = listview_count_items (lv, 0);
1149      if (!n)      if (!nkeys)
1150          return 0;          return 0;
1151      rset = (gpgme_key_t*)calloc (n, sizeof (gpgme_key_t));      rset = (gpgme_key_t*)calloc (nkeys+1, sizeof (gpgme_key_t));
1152      if (!rset)      if (!rset)
1153          BUG (NULL);          BUG (NULL);
1154      for( i = 0; i < n; i++ ) {      k_pos = 0;
1155          if( !listview_get_item_state( lv, i ) )      for (int i = 0; i < nkeys; i++) {
1156            if (!listview_get_item_state (lv, i))
1157              continue;              continue;
1158          listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );          key = km_get_key_ptr (kl, i, &c);
1159          switch( listype ) {          switch (listype) {
1160          case KEYLIST_LIST:          case KEYLIST_LIST:
1161              listview_get_item_text( lv, i, 5, t, sizeof t - 1 );              if (keylist_get_keyflags (key) & KEYFLAG_REVOKED) {
1162              if( keylist_get_keyflags( t, strlen( t ) ) & KEYFLAG_REVOKED ) {                  id = printf_box (_("Recipients"), MB_INFO|MB_YESNO,
1163                  _snprintf( t2, sizeof t2 -1,                  _("KeyID %s.\nDo you really want to export a revoked key?"),
1164                              _("KeyID %s.\nDo you really want to export a revoked key?"), keyid );                                   c->uids->uid);
1165                  id = msg_box( lv->ctrl, t2, _("Recipients"), MB_INFO|MB_YESNO );                  if (id == IDNO)
1166                  if( id == IDNO )                      continue;
                     continue;            
1167              }              }
1168              break;              break;
1169          }          }
1170          get_pubkey (keyid, &k);          rset[k_pos++] = key;
         rset[k_pos++] = k;  
1171      }      }
1172      if (r_count)      if (r_count)
1173          *r_count = k_pos;          *r_count = k_pos;
1174      return rset;      return rset;
1175  } /* keylist_enum_recipients */  }
1176    
1177    
1178  void  void
1179  seclist_destroy (keylist_t * list)  seclist_destroy (keylist_t *list)
1180  {  {
1181      keylist_t l2;      keylist_t l2;
1182    
1183      while (*list) {      while (*list) {
1184          l2 = (*list)->next;          l2 = (*list)->next;
1185          safe_free (*list);          safe_free (*list);
1186          *list = l2;              *list = l2;    
1187      }      }
1188      list = NULL;      *list = NULL;
1189  } /* seclist_destroy */  }
1190    
1191    
1192  void  void
1193  seclist_init (HWND dlg, int ctlid, int flags, keylist_t * ret_list)  seclist_init (HWND dlg, int ctlid, int flags, keylist_t *ret_list)
1194  {      {    
1195      gpg_keycache_t kc = NULL;      gpg_keycache_t kc;
1196      gpgme_key_t key = NULL;      gpgme_key_t key = NULL;
1197      HWND kb;      HWND kb;
1198      keylist_t list=NULL, l, l2;          keylist_t list=NULL, l, l2;    
1199      long pos = 0;      long pos;
1200    
1201      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);      SendDlgItemMessage (dlg, ctlid, CB_RESETCONTENT, 0, 0);
1202      kb = GetDlgItem (dlg, ctlid);      kb = GetDlgItem (dlg, ctlid);
# Line 1055  seclist_init (HWND dlg, int ctlid, int f Line 1206  seclist_init (HWND dlg, int ctlid, int f
1206      gpg_keycache_rewind (kc);      gpg_keycache_rewind (kc);
1207            
1208      while (!gpg_keycache_next_key (kc, 1, &key)) {      while (!gpg_keycache_next_key (kc, 1, &key)) {
1209          char *inf = NULL, *uid = NULL;          StringBuffer inf;
1210            char *uid;
1211          const char *id;          const char *id;
1212          const char *keyid;  
1213          int algo;          if (key->disabled || !key_is_useable (key->subkeys))
1214          size_t size = 0;              continue;
1215    
1216          if (flags & KEYLIST_FLAG_SHORT)          if (flags & KEYLIST_FLAG_SHORT)
1217              id = key->uids->name;              id = key->uids->name;
1218          else          else
1219              id = key->uids->uid;              id = key->uids->uid;
1220          keyid = key->subkeys->keyid;          if (!id || !key->subkeys->keyid)
1221          algo = key->subkeys->pubkey_algo;              continue;  
         if (!id || !keyid)  
             continue;  
         if (key->disabled || !key_is_useable (key->subkeys))  
             continue;  
1222    
1223          uid = utf8_to_wincp (id, strlen (id));          uid = utf8_to_native (id);
1224          size = strlen( uid ) + strlen( keyid ) + 32;          inf = uid;
1225          inf = new char[size+1];          inf = inf + " (" + get_key_pubalgo (key->subkeys->pubkey_algo) + "/";
1226          if( !inf )          inf = inf + "0x" + (key->subkeys->keyid+8) + ")";
1227              BUG( NULL );  
1228          _snprintf (inf, size, "%s (%s/0x%s)", uid,          combox_add_string (kb, inf.getBuffer ());
1229                     get_key_pubalgo (key->subkeys->pubkey_algo), keyid + 8);          safe_free (uid);
         combox_add_string (kb, inf);  
         free_if_alloc (inf);  
         free (uid);  
1230          l = (struct keylist_s *)calloc (1, sizeof * l);          l = (struct keylist_s *)calloc (1, sizeof * l);
1231          if (!l)          if (!l)
1232              BUG (0);              BUG (0);
# Line 1094  seclist_init (HWND dlg, int ctlid, int f Line 1239  seclist_init (HWND dlg, int ctlid, int f
1239              l2->next = l;              l2->next = l;
1240          }          }
1241      }      }
1242      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);
1243          SendMessage( kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key );           pos++, l2=l2->next)
1244      SendMessage( kb, CB_SETCURSEL, 0, 0 );          SendMessage (kb, CB_SETITEMDATA, pos, (LPARAM)(DWORD)l2->key);
1245        SendMessage (kb, CB_SETCURSEL, 0, 0);
1246      *ret_list = list;      *ret_list = list;
1247  }  }
1248            
1249    
1250  /* Select a secret key from the combo box with the ID @ctlid.  /* Select a secret key from the combo box with the ID @ctlid.
1251     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 1266  seclist_select_key (HWND dlg, int ctlid,
1266      }      }
1267      return k? 0 : -1;      return k? 0 : -1;
1268  }  }
1269    
1270    
1271    LRESULT
1272    keylist_listview_notify (HWND hwnd, gpgme_key_t *keys,
1273                             int ctlid, LPARAM lparam)
1274    {
1275        LPNMHDR lpnmh = (LPNMHDR) lparam;
1276        
1277        if (!lpnmh)
1278            BUG (NULL);
1279    
1280        /* Make sure the message is for the control and
1281           that we have a key list. */
1282        if (lpnmh->idFrom != (DWORD)ctlid || keys == NULL)
1283            return 0;
1284        
1285        switch (lpnmh->code) {
1286        case NM_CUSTOMDRAW:
1287            LPNMLVCUSTOMDRAW lplvcd;
1288            lplvcd = (LPNMLVCUSTOMDRAW)lparam;
1289            if (lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT)            
1290                return CDRF_NOTIFYITEMDRAW;
1291    
1292            if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {        
1293                LRESULT ret = CDRF_DODEFAULT;
1294                int pos = lplvcd->nmcd.dwItemSpec;
1295                HWND lv = GetDlgItem (hwnd, ctlid);
1296                gpgme_key_t key = keys[pos];
1297                
1298                if (key != NULL) {
1299                    HFONT hfont = (HFONT)SendMessage (lv, WM_GETFONT, 0, 0);
1300                    LOGFONT lf;
1301                    if (!GetObject (hfont, sizeof (lf), &lf))
1302                        BUG (NULL);
1303                    if (key->revoked)
1304                        lf.lfStrikeOut = TRUE;
1305                    else if (key->expired)
1306                        lf.lfItalic = TRUE;
1307                    if (find_secret_key (key))
1308                        lf.lfWeight = FW_SEMIBOLD;
1309                    hfont = CreateFontIndirect (&lf);
1310                    SelectObject (lplvcd->nmcd.hdc, hfont);
1311                    if (pos & 1)
1312                        lplvcd->clrTextBk = RGB (0xE5, 0xE5, 0xE5);
1313                    ret = CDRF_NEWFONT | CDRF_NOTIFYPOSTPAINT;
1314                }
1315                return ret;
1316            }
1317            
1318            if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT) {
1319                HFONT hfont = (HFONT)GetStockObject (DEFAULT_GUI_FONT);
1320                hfont = (HFONT)SelectObject (lplvcd->nmcd.hdc, hfont);
1321                DeleteObject (hfont);
1322                return CDRF_DODEFAULT;
1323            }
1324            return CDRF_DODEFAULT;  
1325        }
1326    
1327        return 0;
1328    }

Legend:
Removed from v.88  
changed lines
  Added in v.328

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26