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

Diff of /trunk/Src/wptSigList.cpp

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

revision 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 139 by twoaday, Wed Jan 11 12:19:41 2006 UTC
# Line 1  Line 1 
1  /* wptSigList.cpp - Listview for key signatures  /* wptSigList.cpp - Listview for key signatures
2   *      Copyright (C) 2001-2004 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *   *      Copyright (C) 2005, 2006 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
6   * WinPT is free software; you can redistribute it and/or   *
7   * modify it under the terms of the GNU General Public License   * WinPT is free software; you can redistribute it and/or
8   * as published by the Free Software Foundation; either version 2   * modify it under the terms of the GNU General Public License
9   * of the License, or (at your option) any later version.   * as published by the Free Software Foundation; either version 2
10   *     * of the License, or (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *  
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   *   * General Public License for more details.
16   * You should have received a copy of the GNU General Public License   *
17   * along with WinPT; if not, write to the Free Software Foundation,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * along with WinPT; if not, write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21  #include <windows.h>  
22  #include <time.h>  #ifdef HAVE_CONFIG_H
23    #include <config.h>
24  #include "wptGPG.h"  #endif
25  #include "wptCommonCtl.h"  
26  #include "wptKeylist.h"  #include <windows.h>
27  #include "wptNLS.h"  #include <time.h>
28  #include "wptUTF8.h"  
29  #include "wptErrors.h"  #include "wptGPG.h"
30  #include "wptTypes.h"  #include "wptCommonCtl.h"
31  #include "wptW32API.h"  #include "wptKeylist.h"
32    #include "wptNLS.h"
33    #include "wptUTF8.h"
34  #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)  #include "wptErrors.h"
35    #include "wptTypes.h"
36  static int  #include "wptW32API.h"
37  siglist_build( listview_ctrl_t * lv, HWND ctrl )  
38  {  
39      struct listview_ctrl_s *c;  /* Is the given signature an user-id signature? */
40      struct listview_column_s implist[] = {  #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)
41          {0, 240, (char *)_("User ID")},  
42          {1,  50, (char *)_("Valid")},  
43          {2,  40, (char *)_("Class")},  /* Create a signature list control in @lv with the parent window
44          {3,  68, (char *)_("Creation")},     given in @ctrl.
45          {4,  80, (char *)_("Key ID")},     Return value: 0 on success. */
46          {5,  68, (char *)_("Expiration")},  static int
47          {6,  56, (char *)_("Algorithm")},  siglist_build (listview_ctrl_t * lv, HWND ctrl)
48          {0,   0, NULL}  {
49      };        struct listview_ctrl_s *c;
50      int j, rc = 0;      struct listview_column_s implist[] = {
51                {0, 240, (char *)_("User ID")},
52      rc = listview_new( &c );          {1,  50, (char *)_("Valid")},
53      if( rc )          {2,  44, (char *)_("Class")},
54          return rc;          {3,  68, (char *)_("Creation")},
55      c->ctrl = ctrl;          {4,  80, (char *)_("Key ID")},
56      for ( j=0; implist[j].fieldname != NULL; j++ )          {5,  68, (char *)_("Expiration")},
57          listview_add_column( c, &implist[j] );          {6,  56, (char *)_("Algorithm")},
58      listview_set_ext_style( c );          {0,   0, NULL}
59      *lv = c;      };  
60      return 0;      int j, rc = 0;
61  } /* siglist_build */      
62        rc = listview_new (&c);
63        if (rc)
64  void          return rc;
65  siglist_delete( listview_ctrl_t lv )      c->ctrl = ctrl;
66  {      for  (j=0; implist[j].fieldname != NULL; j++)
67      if( lv ) {          listview_add_column (c, &implist[j]);
68          listview_release( lv );      listview_set_ext_style (c);
69      }      *lv = c;
70  } /* siglist_delete */      return 0;
71    }
72    
73  static char *  
74  indent_string( const char * old, int ilvl )  /* Delete the signature control in @lv. */
75  {  void
76      char * p;  siglist_delete( listview_ctrl_t lv )
77      int i;  {
78        if (lv) {
79      p = new char[strlen( old ) + 1 + ilvl];          listview_release (lv);
80      if( !p )      }
81          BUG( NULL );  }
82      for( i = 0; i < ilvl; i++ )  
83          p[i] = ' ';  
84      strcpy( p+i, old );  /* Indent the string in @old with the level @ilvl.
85      return p;      Return value: indented string. */
86  } /* indent_string */  static char *
87    indent_string (const char * old, int ilvl)
88    {
89  static int      char * p;
90  siglist_add_key( listview_ctrl_t lv, gpgme_key_t key, int idx )      int i;
91  {  
92      char t[128];      p = new char[strlen (old) + 1 + ilvl];
93      const char *attr;      if (!p)
94      const char *s;          BUG (NULL);
95      int sig_class;      for (i = 0; i < ilvl; i++)
96      int rc = 0, key_attr, root = 0;          p[i] = ' ';
97            strcpy (p+i, old);
98      s = gpgme_key_get_string_attr( key, GPGME_ATTR_SIG_KEYID, NULL, idx );      return p;
99      root = s && strlen( s )? 0 : 1;  }
100    
101      sig_class = gpgme_key_get_ulong_attr( key, GPGME_ATTR_SIG_CLASS, NULL, idx );  
102      if( !IS_UID_CERT( sig_class ) && !root )  /* Add an item at the given pos @pos with the opaque param @ks. */
103          return 0;  int
104    add_keysig_item (listview_ctrl_t ctx, int pos, gpgme_key_sig_t ks)
105      rc = listview_add_item( lv, " " );  {
106      if( rc )          LV_ITEM lvi;
107          return rc;  
108        memset (&lvi, 0, sizeof lvi);
109      attr = gpgme_key_get_string_attr( key, GPGME_ATTR_SIG_ISSUER, NULL, idx );      lvi.iItem = pos;
110      if( attr && strlen( attr ) ) {      lvi.lParam = (LPARAM)ks;
111          char * uid = utf8_to_wincp (attr, strlen (attr)), * p;      lvi.mask = LVIF_PARAM;
112          p = root? m_strdup( uid ) : indent_string( uid, 2 );      if (ListView_InsertItem (ctx->ctrl, &lvi) != pos)
113          listview_add_sub_item( lv, 0, 0, p );          return -1;
114          free( uid );      return 0;
115          free_if_alloc( p );  }
116      }  
117      else  
118          listview_add_sub_item( lv, 0, 0, _("  user ID not found") );  /* Add an userid signature @ks from the userid @uid to the sig list
119       control @lv.
120      if( root )     Return value: 0 on success. */
121          return 0;  static int
122    siglist_add_key (listview_ctrl_t lv, gpgme_user_id_t uid,
123      key_attr = gpgme_key_get_ulong_attr( key, GPGME_ATTR_SIG_STAT, NULL, idx );                   gpgme_key_sig_t ks, int pos)
124      if( key_attr == GPGME_SIG_STAT_NONE )        {
125          return WPTERR_GENERAL;      gpgme_key_t key=NULL;
126      switch (key_attr) {      char t[128];
127      case GPGME_SIG_STAT_GOOD: s = "YES";   break;      const char *attr;
128      case GPGME_SIG_STAT_NOKEY:s = "NOKEY"; break;      const char *s;
129      case GPGME_SIG_STAT_BAD:  s = "NO";    break;      int key_attr, no_uid = 0;
130      case GPGME_SIG_STAT_NOSIG:s = "NOSIG"; break;      int rc = 0;
131      case GPGME_SIG_STAT_ERROR:  
132      default:                  s = "ERROR"; break;      if (ks && !IS_UID_CERT (ks->sig_class))
133      }          return 0;
134      listview_add_sub_item( lv, 0, 1, s );      
135        rc = add_keysig_item (lv, pos, ks);
136      switch (sig_class) {      if (rc)
137      case 0x10: strcpy (t, " "); break;          return rc;
138      case 0x11: strcpy (t, "1"); break;  
139      case 0x12: strcpy (t, "2"); break;      attr = NULL;
140      case 0x13: strcpy (t, "3"); break;      if (!uid) {
141      }          get_pubkey (ks->keyid, &key);
142      key_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_SIG_FLAGS, NULL, idx);          if (key)
143      if (key_attr)              attr = key->uids->uid;
144          strcat (t, " ");      }
145      if (key_attr & GPGME_SIGF_LOCAL)      else
146          strcat (t, "L");          attr = uid->uid;
147      if (key_attr & GPGME_SIGF_NREV)      if (attr && strlen (attr)) {
148          strcat (t, "R");          char *uid_utf8 = utf8_to_wincp (attr, strlen (attr));
149      listview_add_sub_item (lv, 0, 2, t);          char *p = uid? m_strdup (uid_utf8) : indent_string (uid_utf8, 2);
150            listview_add_sub_item (lv, pos, 0, p);
151      key_attr = gpgme_key_get_ulong_attr( key, GPGME_ATTR_SIG_CREATED, NULL, idx );          free (uid_utf8);
152      if( key_attr ) {          free_if_alloc (p);
153          s = get_key_created( key_attr );      }
154          listview_add_sub_item( lv, 0, 3, s );      else {
155      }          listview_add_sub_item (lv, pos, 0, _("  user ID not found"));
156                no_uid = 1;
157      attr = gpgme_key_get_string_attr( key, GPGME_ATTR_SIG_KEYID, NULL, idx );      }
158      if( attr && strlen( attr ) == 16 ) {  
159          _snprintf( t, sizeof t -1, "0x%s", attr + 8 );      if (uid)
160          listview_add_sub_item( lv, 0, 4, t );          return 0;
161      }  
162        switch (gpgme_err_code (ks->status)) {
163      key_attr = gpgme_key_get_ulong_attr (key, GPGME_ATTR_SIG_EXPIRES, NULL, idx);      case GPG_ERR_NO_ERROR:     s = "YES";   break;
164      if (key_attr)      case GPG_ERR_NO_PUBKEY:    s = "NOKEY"; break;
165      {      case GPG_ERR_BAD_SIGNATURE:s = "NO";    break;
166          s = get_key_created (key_attr);      default:                   s = "ERROR"; break;
167          listview_add_sub_item (lv, 0, 5, s);      }
168      }      if (no_uid)
169            s = "NOKEY";
170      key_attr = gpgme_key_get_ulong_attr( key, GPGME_ATTR_SIG_ALGO, NULL, idx );      listview_add_sub_item (lv, pos, 1, s);
171      attr = gpgme_key_expand_attr( GPGME_ATTR_ALGO, key_attr );  
172      if( attr )      switch (ks->sig_class) {
173          listview_add_sub_item( lv, 0, 6, (char *)attr );      case 0x10: strcpy (t, " "); break;
174            case 0x11: strcpy (t, "1"); break;
175      return 0;      case 0x12: strcpy (t, "2"); break;
176  } /* siglist_add_key */      case 0x13: strcpy (t, "3"); break;
177        }
178            
179  listview_ctrl_t      strcat (t, " ");
180  siglist_load( HWND ctrl, const char *keyid )      if (!ks->exportable)
181  {              strcat (t, "L");
182      gpgme_key_t key;      /*if (key_attr & GPGME_SIGF_NREV)
183      listview_ctrl_t lv;          strcat (t, "R");*/
184      int rc = 0, i;      listview_add_sub_item (lv, pos, 2, t);
185    
186      if( siglist_build( &lv, ctrl ) )      key_attr = ks->timestamp;
187          BUG( NULL );      if( key_attr ) {
188      rc = get_pubkey( keyid, &key );          s = get_key_created (key_attr);
189      if( rc )          listview_add_sub_item (lv, pos, 3, s);
190          BUG( NULL );      }
191      for( i = 0; i < gpgme_key_count_items( key, GPGME_ATTR_SIG_KEYID ); i++ ) {      
192          rc = siglist_add_key( lv, key, i );      attr = ks->keyid;
193          if( rc )      if (attr && strlen (attr) == 16) {
194              break;          _snprintf (t, sizeof (t) -1, "0x%s", attr + 8);
195      }          listview_add_sub_item (lv, pos, 4, t);
196      if( rc ) {      }
197          siglist_delete( lv );  
198          lv = NULL;      key_attr = ks->expires;
199      }      if (key_attr) {
200      return lv;          s = get_key_created (key_attr);
201  } /* siglist_load */          listview_add_sub_item (lv, pos, 5, s);
202        }
203    
204        attr = get_key_pubalgo (ks->pubkey_algo);
205        if (attr)
206            listview_add_sub_item (lv, pos, 6, (char *)attr);
207    
208        return 0;
209    }
210    
211    
212    /* Load a signature list with the signatures of the key with
213       the keyID @keyid. The parent window is in @ctrl.
214       Return value is the handle to the listview control. */
215    listview_ctrl_t
216    siglist_load (HWND ctrl, const char *keyid)
217    {    
218        gpgme_key_t key;
219        gpgme_user_id_t u;
220        gpgme_key_sig_t s;
221        listview_ctrl_t lv;
222        int pos = 0;
223        int rc;
224    
225        if (siglist_build (&lv, ctrl))
226            BUG (NULL);
227        rc = get_pubkey(keyid, &key);
228        if (rc)
229            BUG (NULL);
230    
231        for (u=key->uids; u; u = u->next) {
232            siglist_add_key (lv, u, NULL, pos++);
233            for (s = u->signatures; s; s = s->next) {
234                if (!IS_UID_CERT (s->sig_class))
235                    continue;
236                rc = siglist_add_key (lv, NULL, s, pos++);
237                if (rc)
238                    break;
239            }
240        }
241        if (rc) {
242            siglist_delete (lv);
243            lv = NULL;
244        }
245        return lv;
246    }
247    
248    
249    /* Integer comparsion of @a and @b.
250       Return values: same as in strcmp. */
251    static inline int
252    int_cmp (int a, int b)
253    {
254        if (a == b) return 0;      
255        else if (a > b) return 1;
256        else return -1;
257        return 0;
258    }
259    
260    
261    /* Sorting callback for the signature list. */
262    static int CALLBACK
263    siglist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
264    {
265        gpgme_key_sig_t a, b;
266        int cmpresult=0;
267    
268        a = (gpgme_key_sig_t)first;
269        b = (gpgme_key_sig_t)second;
270        if (!a || !b)
271            return -1; /* this indicates that one item is a root item. */
272    
273        switch (sortby) {
274        case KEY_SORT_KEYID:
275            cmpresult = strcmp (a->keyid, b->keyid);
276            break;
277    
278        case KEY_SORT_CREATED:
279            cmpresult = int_cmp (a->timestamp, b->timestamp);
280            break;
281    
282        case KEY_SORT_ALGO:
283            cmpresult = int_cmp (a->pubkey_algo, b->pubkey_algo);
284            break;
285    
286        case KEY_SORT_VALIDITY:
287            cmpresult = int_cmp (a->status, b->status);
288            break;
289    
290        case SIG_SORT_EXPIRE:
291            cmpresult = int_cmp (a->expires, a->expires);
292            break;
293    
294        case SIG_SORT_CLASS:
295            cmpresult = int_cmp (a->sig_class, b->sig_class);
296            break;
297        }
298        return cmpresult;
299    }
300    
301    
302    /* Sort the signature list @sigl by @sortby. */
303    void
304    siglist_sort (listview_ctrl_t sigl, int sortby)
305    {
306        listview_sort_items (sigl, sortby, siglist_cmp_cb);
307    }

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26