/[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 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 299 by twoaday, Sun Mar 18 19:58:12 2007 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,  
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  #ifdef HAVE_CONFIG_H
19   */  #include <config.h>
20    #endif
21  #include <windows.h>  
22  #include <time.h>  #include <windows.h>
23    #include <time.h>
24  #include "wptGPG.h"  
25  #include "wptCommonCtl.h"  #include "resource.h"
26  #include "wptKeylist.h"  #include "wptGPG.h"
27  #include "wptNLS.h"  #include "wptCommonCtl.h"
28  #include "wptUTF8.h"  #include "wptKeylist.h"
29  #include "wptErrors.h"  #include "wptNLS.h"
30  #include "wptTypes.h"  #include "wptErrors.h"
31  #include "wptW32API.h"  #include "wptTypes.h"
32    #include "wptW32API.h"
33    #include "wptVersion.h"
34  /* Is the given signature an user-id signature? */  #include "wptContext.h"
35  #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)  
36    
37    /* Is the given signature an user-id signature? */
38  /* Create a signature list control in @lv with the parent window  #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)
39     given in @ctrl.  
40     Return value: 0 on success. */  
41  static int  /* Create a signature list control in @lv with the parent window
42  siglist_build (listview_ctrl_t * lv, HWND ctrl)     given in @ctrl.
43  {     Return value: 0 on success. */
44      struct listview_ctrl_s *c;  static void
45      struct listview_column_s implist[] = {  siglist_build (listview_ctrl_t *lv, HWND ctrl)
46          {0, 240, (char *)_("User ID")},  {
47          {1,  50, (char *)_("Valid")},      listview_ctrl_t c;
48          {2,  40, (char *)_("Class")},      struct listview_column_s implist[] = {
49          {3,  68, (char *)_("Creation")},          {0, 240, (char *)_("User ID")},
50          {4,  80, (char *)_("Key ID")},          {1,  50, (char *)_("Valid")},
51          {5,  68, (char *)_("Expiration")},          {2,  44, (char *)_("Class")},
52          {6,  56, (char *)_("Algorithm")},          {3,  68, (char *)_("Creation")},
53          {0,   0, NULL}          {4,  80, (char *)_("Key ID")},
54      };            {5,  68, (char *)_("Expiration")},
55      int j, rc = 0;          {6,  56, (char *)_("Algorithm")},
56                {0,   0, NULL}
57      rc = listview_new( &c );      };
58      if( rc )      int j;
59          return rc;  
60      c->ctrl = ctrl;      listview_new (&c, ctrl);
61      for ( j=0; implist[j].fieldname != NULL; j++ )      for  (j=0; implist[j].fieldname != NULL; j++)
62          listview_add_column( c, &implist[j] );          listview_add_column (c, &implist[j]);
63      listview_set_ext_style( c );      listview_set_ext_style (c);
64      *lv = c;      listview_del_all_items (c);
65      return 0;      *lv = c;
66  }  }
67    
68    
69  /* Delete the signature control in @lv. */  /* Delete the signature control in @lv. */
70  void  void
71  siglist_delete( listview_ctrl_t lv )  siglist_delete (listview_ctrl_t lv)
72  {  {
73      if( lv ) {      if (lv) {
74          listview_release( lv );          listview_release (lv);
75      }      }
76  }  }
77    
78    
79  /* Indent the string in @old with the level @ilvl.  /* Indent the string in @old with the level @ilvl.
80      Return value: indented string. */      Return value: indented string. */
81  static char *  static char*
82  indent_string (const char * old, int ilvl)  indent_string (const char *old, int ilvl)
83  {  {
84      char * p;      char *p;
85      int i;      int i;
86    
87      p = new char[strlen (old) + 1 + ilvl];      p = new char[strlen (old) + 1 + ilvl];
88      if (!p)      if (!p)
89          BUG (NULL);          BUG (NULL);
90      for (i = 0; i < ilvl; i++)      for (i = 0; i < ilvl; i++)
91          p[i] = ' ';          p[i] = ' ';
92      strcpy (p+i, old);      strcpy (p+i, old);
93      return p;      return p;
94  }  }
95    
96    
97  /* Add an userid signature with the index @idx from the userid @uid  /* Add an item at the given pos @pos with the opaque param @ks. */
98     to the sig list control @lv.  int
99     Return value: 0 on success. */  add_keysig_item (listview_ctrl_t ctx, int pos, gpgme_key_sig_t ks)
100  static int  {
101  siglist_add_key( listview_ctrl_t lv, gpgme_user_id_t uid, int idx)      LV_ITEM lvi;
102  {  
103      gpgme_key_sig_t ks;      memset (&lvi, 0, sizeof (lvi));
104      gpgme_key_t     key=NULL;      lvi.iItem = pos;
105      char t[128];      lvi.lParam = (LPARAM)ks;
106      const char *attr;      lvi.mask = LVIF_PARAM;
107      const char *s;      if (ListView_InsertItem (ctx->ctrl, &lvi) != pos)
108      int rc = 0, key_attr, root = 0;          return -1;
109            return 0;
110      ks = get_nth_uid_sig (uid, idx);  }
111    
112      if( !IS_UID_CERT( ks->sig_class ) )  
113          return 0;  /* Add an userid signature @ks from the userid @uid to the sig list
114       control @lv.
115      rc = listview_add_item (lv, " ");     Return value: 0 on success. */
116      if( rc )      static int
117          return rc;  siglist_add_key (listview_ctrl_t lv, struct native_uid_s *uid,
118                     gpgme_key_sig_t ks, int pos)
119      get_pubkey (ks->keyid, &key);  {
120      if (key) {      struct winpt_key_s key;    
121          attr = key->uids->uid;      const char *attr;
122          if( attr && strlen( attr ) ) {      const char *s;
123              char * uid = utf8_to_wincp (attr, strlen (attr)), * p;      char t[128];
124              p = indent_string( uid, 2 );      int no_uid = 0;
125              listview_add_sub_item( lv, 0, 0, p );      int rc;
126              free( uid );  
127              free_if_alloc( p );      if (ks && !IS_UID_CERT (ks->sig_class))
128          }          return 0;
129          else      
130              listview_add_sub_item( lv, 0, 0, _("  user ID not found") );      rc = add_keysig_item (lv, pos, ks);
131      }      if (rc)
132            return rc;
133      if( root )  
134          return 0;      attr = NULL;
135        if (!uid) {
136      switch (gpg_error ((gpg_err_code_t)ks->status)) {          memset (&key, 0, sizeof (key));
137      case GPG_ERR_NO_ERROR:     s = "YES";   break;          winpt_get_pubkey (ks->keyid, &key);
138      case GPG_ERR_NO_PUBKEY:    s = "NOKEY"; break;          if (key.ext != NULL)
139      case GPG_ERR_BAD_SIGNATURE:s = "NO";    break;              attr = key.ext->uids->uid;
140      default:                   s = "ERROR"; break;      }
141      }      else
142      listview_add_sub_item( lv, 0, 1, s );          attr = uid->uid;
143        if (attr && strlen (attr)) {
144      switch (ks->sig_class) {          char *p = uid? m_strdup (attr) : indent_string (attr, 2);
145      case 0x10: strcpy (t, " "); break;          listview_add_sub_item (lv, pos, SL_COL_UID, p);
146      case 0x11: strcpy (t, "1"); break;          free_if_alloc (p);
147      case 0x12: strcpy (t, "2"); break;      }
148      case 0x13: strcpy (t, "3"); break;      else {
149      }          listview_add_sub_item (lv, pos, SL_COL_UID, _("  user ID not found"));
150                    no_uid = 1;
151      strcat (t, " ");      }
152      if (!ks->exportable)  
153          strcat (t, "L");      /* Return immediately for root items. */
154      /*if (key_attr & GPGME_SIGF_NREV)      if (uid)
155          strcat (t, "R");*/          return 0;
156      listview_add_sub_item (lv, 0, 2, t);  
157        /* TRANSLATORS: these strings should be in capital letters. */
158      key_attr = ks->timestamp;      switch (gpgme_err_code (ks->status)) {
159      if( key_attr ) {      case GPG_ERR_NO_ERROR:     s = _("YES");   break;
160          s = get_key_created( key_attr );      case GPG_ERR_NO_PUBKEY:    s = _("NOKEY"); break;
161          listview_add_sub_item( lv, 0, 3, s );      case GPG_ERR_BAD_SIGNATURE:s = _("NO");    break;
162      }      default:                   s = _("ERROR"); break;
163            }
164      attr = ks->keyid;      if (no_uid)
165      if( attr && strlen( attr ) == 16 ) {          s = _("NOKEY");
166          _snprintf( t, sizeof t -1, "0x%s", attr + 8 );      listview_add_sub_item (lv, pos, SL_COL_VALID, s);
167          listview_add_sub_item( lv, 0, 4, t );  
168      }      switch (ks->sig_class) {
169        case 0x10: strcpy (t, " "); break;
170      key_attr = ks->expires;      case 0x11: strcpy (t, "1"); break;
171      if (key_attr) {      case 0x12: strcpy (t, "2"); break;
172          s = get_key_created (key_attr);      case 0x13: strcpy (t, "3"); break;
173          listview_add_sub_item (lv, 0, 5, s);      }
174      }  
175        strcat (t, " ");
176      attr = get_key_pubalgo (ks->pubkey_algo);      if (!ks->exportable)
177      if( attr )          strcat (t, "L");
178          listview_add_sub_item( lv, 0, 6, (char *)attr );      /* XXX: if gpgme supports non-revocable status, add 'R' */
179            listview_add_sub_item (lv, pos, SL_COL_CLASS, t);
180      return 0;  
181  }      s = get_key_created (ks->timestamp);
182        listview_add_sub_item (lv, pos, SL_COL_CREATE, s);
183    
184  /* Load a signature list with the signatures of the key with      if (ks->keyid && strlen (ks->keyid) == 16) {
185     the keyID @keyid. The parent window is in @ctrl.          _snprintf (t, DIM (t) -1, "0x%s", ks->keyid + 8);
186     Return value is the handle to the listview control. */          listview_add_sub_item (lv, pos, SL_COL_KEYID, t);
187  listview_ctrl_t      }
188  siglist_load (HWND ctrl, const char *keyid)  
189  {          if (ks->expires > 0) {
190      gpgme_key_t key;          s = get_key_created (ks->expires);
191      gpgme_user_id_t u;          listview_add_sub_item (lv, pos, SL_COL_EXPIRE, s);
192      listview_ctrl_t lv;      }
193      int rc = 0, i;  
194        attr = get_key_pubalgo (ks->pubkey_algo);
195      if (siglist_build (&lv, ctrl))      if (attr)
196          BUG (NULL);          listview_add_sub_item (lv, pos, 6, (char *)attr);
197      rc = get_pubkey(keyid, &key);  
198      if (rc)      return 0;
199          BUG (NULL);  }
200    
201      for (u=key->uids; u; u = u->next) {      
202          rc = listview_add_item (lv, " ");  /* Load a signature list with the signatures of the key with
203          if( rc )             the keyID @keyid. The parent window is in @ctrl.
204              break;     Return value is the handle to the listview control. */
205          listview_add_sub_item (lv, 0, 0, u->uid);  listview_ctrl_t
206          for (i=0; i < count_uid_sigs (u); i++) {  siglist_load (HWND ctrl, const char *keyid)
207              rc = siglist_add_key( lv, u, i );  {    
208              if( rc )      gpgme_key_sig_t s;
209                  break;      struct native_uid_s *u;
210          }      winpt_key_s key;
211      }      listview_ctrl_t lv;
212      if( rc ) {      int pos = 0;
213          siglist_delete( lv );      int rc = 0;
214          lv = NULL;  
215      }      siglist_build (&lv, ctrl);
216      return lv;      memset (&key, 0, sizeof (key));
217  }      if (winpt_get_pubkey (keyid, &key))
218            BUG (NULL);
219    
220        for (u=key.ext->uids; u; u = u->next) {
221            siglist_add_key (lv, u, NULL, pos++);
222            for (s = u->signatures; s; s = s->next) {
223                if (!IS_UID_CERT (s->sig_class))
224                    continue;
225                rc = siglist_add_key (lv, NULL, s, pos++);
226                if (rc)
227                    break;
228            }
229        }
230        if (rc) {
231            siglist_delete (lv);
232            lv = NULL;
233        }
234        return lv;
235    }
236    
237    
238    /* Integer comparsion of @a and @b.
239       Return values: same as in strcmp. */
240    static inline int
241    int_cmp (int a, int b)
242    {
243        if (a == b) return 0;      
244        else if (a > b) return 1;
245        else return -1;
246        return 0;
247    }
248    
249    
250    /* Sorting callback for the signature list. */
251    static int CALLBACK
252    siglist_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
253    {
254        gpgme_key_sig_t a, b;
255        int cmpresult=0;
256    
257        a = (gpgme_key_sig_t)first;
258        b = (gpgme_key_sig_t)second;
259        if (!a || !b)
260            return -1; /* this indicates that one item is a root item. */
261    
262        switch (sortby) {
263        case KEY_SORT_KEYID:
264            cmpresult = strcmp (a->keyid, b->keyid);
265            break;
266    
267        case KEY_SORT_CREATED:
268            cmpresult = int_cmp (a->timestamp, b->timestamp);
269            break;
270    
271        case KEY_SORT_ALGO:
272            cmpresult = int_cmp (a->pubkey_algo, b->pubkey_algo);
273            break;
274    
275        case KEY_SORT_VALIDITY:
276            cmpresult = int_cmp (a->status, b->status);
277            break;
278    
279        case SIG_SORT_EXPIRE:
280            cmpresult = int_cmp (a->expires, a->expires);
281            break;
282    
283        case SIG_SORT_CLASS:
284            cmpresult = int_cmp (a->sig_class, b->sig_class);
285            break;
286        }
287        return cmpresult;
288    }
289    
290    
291    /* Sort the signature list @sigl by @sortby. */
292    void
293    siglist_sort (listview_ctrl_t sigl, int sortby)
294    {
295        listview_sort_items (sigl, sortby, siglist_cmp_cb);
296    }

Legend:
Removed from v.23  
changed lines
  Added in v.299

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26