/[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 24 by twoaday, Sat Oct 8 10:43:08 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-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *      Copyright (C) 2005 g10 Code GmbH   *      Copyright (C) 2005, 2006 g10 Code GmbH
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
6   *   *
7   * WinPT is free software; you can redistribute it and/or   * WinPT is free software; you can redistribute it and/or
8   * modify it under the terms of the GNU General Public License   * modify it under the terms of the GNU General Public License
9   * as published by the Free Software Foundation; either version 2   * as published by the Free Software Foundation; either version 2
10   * of the License, or (at your option) any later version.   * of the License, or (at your option) any later version.
11   *     *  
12   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * General Public License for more details.   * General Public License for more details.
16   *   */
17   * You should have received a copy of the GNU General Public License  
18   * along with WinPT; if not, write to the Free Software Foundation,  #ifdef HAVE_CONFIG_H
19   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  #include <config.h>
20   */  #endif
21    
22  #include <windows.h>  #include <windows.h>
23  #include <time.h>  #include <time.h>
24    
25  #include "wptGPG.h"  #include "resource.h"
26  #include "wptCommonCtl.h"  #include "wptGPG.h"
27  #include "wptKeylist.h"  #include "wptCommonCtl.h"
28  #include "wptNLS.h"  #include "wptKeylist.h"
29  #include "wptUTF8.h"  #include "wptNLS.h"
30  #include "wptErrors.h"  #include "wptErrors.h"
31  #include "wptTypes.h"  #include "wptTypes.h"
32  #include "wptW32API.h"  #include "wptW32API.h"
33    #include "wptVersion.h"
34    #include "wptContext.h"
35  /* Is the given signature an user-id signature? */  
36  #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)  
37    /* Is the given signature an user-id signature? */
38    #define IS_UID_CERT(_class) ((_class) >= 0x10 && (_class) <= 0x13)
39  /* Create a signature list control in @lv with the parent window  
40     given in @ctrl.  
41     Return value: 0 on success. */  /* Create a signature list control in @lv with the parent window
42  static int     given in @ctrl.
43  siglist_build (listview_ctrl_t * lv, HWND ctrl)     Return value: 0 on success. */
44  {  static void
45      struct listview_ctrl_s *c;  siglist_build (listview_ctrl_t *lv, HWND ctrl)
46      struct listview_column_s implist[] = {  {
47          {0, 240, (char *)_("User ID")},      listview_ctrl_t c;
48          {1,  50, (char *)_("Valid")},      struct listview_column_s implist[] = {
49          {2,  40, (char *)_("Class")},          {0, 240, (char *)_("User ID")},
50          {3,  68, (char *)_("Creation")},          {1,  50, (char *)_("Valid")},
51          {4,  80, (char *)_("Key ID")},          {2,  44, (char *)_("Class")},
52          {5,  68, (char *)_("Expiration")},          {3,  68, (char *)_("Creation")},
53          {6,  56, (char *)_("Algorithm")},          {4,  80, (char *)_("Key ID")},
54          {0,   0, NULL}          {5,  68, (char *)_("Expiration")},
55      };            {6,  56, (char *)_("Algorithm")},
56      int j, rc = 0;          {0,   0, NULL}
57            };
58      rc = listview_new (&c);      int j;
59      if (rc)  
60          return rc;      listview_new (&c, ctrl);
61      c->ctrl = ctrl;      for  (j=0; implist[j].fieldname != NULL; j++)
62      for ( j=0; implist[j].fieldname != NULL; j++ )          listview_add_column (c, &implist[j]);
63          listview_add_column( c, &implist[j] );      listview_set_ext_style (c);
64      listview_set_ext_style( c );      listview_del_all_items (c);
65      *lv = c;      *lv = c;
66      return 0;  }
67  }  
68    
69    /* Delete the signature control in @lv. */
70  /* Delete the signature control in @lv. */  void
71  void  siglist_delete (listview_ctrl_t lv)
72  siglist_delete( listview_ctrl_t lv )  {
73  {      if (lv) {
74      if( lv ) {          listview_release (lv);
75          listview_release( lv );      }
76      }  }
77  }  
78    
79    /* Indent the string in @old with the level @ilvl.
80  /* Indent the string in @old with the level @ilvl.      Return value: indented string. */
81      Return value: indented string. */  static char*
82  static char *  indent_string (const char *old, int ilvl)
83  indent_string (const char * old, int ilvl)  {
84  {      char *p;
85      char * p;      int i;
86      int i;  
87        p = new char[strlen (old) + 1 + ilvl];
88      p = new char[strlen (old) + 1 + ilvl];      if (!p)
89      if (!p)          BUG (NULL);
90          BUG (NULL);      for (i = 0; i < ilvl; i++)
91      for (i = 0; i < ilvl; i++)          p[i] = ' ';
92          p[i] = ' ';      strcpy (p+i, old);
93      strcpy (p+i, old);      return p;
94      return p;  }
95  }  
96    
97    /* Add an item at the given pos @pos with the opaque param @ks. */
98  /* Add an userid signature @ks from the userid @uid to the sig list  int
99     control @lv.  add_keysig_item (listview_ctrl_t ctx, int pos, gpgme_key_sig_t ks)
100     Return value: 0 on success. */  {
101  static int      LV_ITEM lvi;
102  siglist_add_key (listview_ctrl_t lv, gpgme_user_id_t uid, gpgme_key_sig_t ks)  
103  {      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;          return -1;
109        return 0;
110      if (ks && !IS_UID_CERT (ks->sig_class))  }
111          return 0;  
112    
113      rc = listview_add_item (lv, " ");  /* Add an userid signature @ks from the userid @uid to the sig list
114      if( rc )         control @lv.
115          return rc;     Return value: 0 on success. */
116    static int
117      attr = NULL;  siglist_add_key (listview_ctrl_t lv, struct native_uid_s *uid,
118      if (!uid) {                   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      }      const char *s;
123      else      char t[128];
124          attr = uid->uid;      int no_uid = 0;
125      if (attr && strlen (attr)) {      int rc;
126          char *uid_utf8 = utf8_to_wincp (attr, strlen (attr));  
127          char *p = uid? m_strdup (uid_utf8) : indent_string (uid_utf8, 2);      if (ks && !IS_UID_CERT (ks->sig_class))
128          listview_add_sub_item (lv, 0, 0, p);          return 0;
129          free (uid_utf8);      
130          free_if_alloc (p);      rc = add_keysig_item (lv, pos, ks);
131      }      if (rc)
132      else          return rc;
133          listview_add_sub_item (lv, 0, 0, _("  user ID not found"));  
134        attr = NULL;
135      if (uid)      if (!uid) {
136          return 0;          memset (&key, 0, sizeof (key));
137            winpt_get_pubkey (ks->keyid, &key);
138      switch (gpgme_err_code (ks->status)) {          if (key.ext != NULL)
139      case GPG_ERR_NO_ERROR:     s = "YES";   break;              attr = key.ext->uids->uid;
140      case GPG_ERR_NO_PUBKEY:    s = "NOKEY"; break;      }
141      case GPG_ERR_BAD_SIGNATURE:s = "NO";    break;      else
142      default:                   s = "ERROR"; break;          attr = uid->uid;
143      }      if (attr && strlen (attr)) {
144      listview_add_sub_item( lv, 0, 1, s );          char *p = uid? m_strdup (attr) : indent_string (attr, 2);
145            listview_add_sub_item (lv, pos, SL_COL_UID, p);
146      switch (ks->sig_class) {          free_if_alloc (p);
147      case 0x10: strcpy (t, " "); break;      }
148      case 0x11: strcpy (t, "1"); break;      else {
149      case 0x12: strcpy (t, "2"); break;          listview_add_sub_item (lv, pos, SL_COL_UID, _("  user ID not found"));
150      case 0x13: strcpy (t, "3"); break;          no_uid = 1;
151      }      }
152            
153      strcat (t, " ");      /* Return immediately for root items. */
154      if (!ks->exportable)      if (uid)
155          strcat (t, "L");          return 0;
156      /*if (key_attr & GPGME_SIGF_NREV)  
157          strcat (t, "R");*/      /* TRANSLATORS: these strings should be in capital letters. */
158      listview_add_sub_item (lv, 0, 2, t);      switch (gpgme_err_code (ks->status)) {
159        case GPG_ERR_NO_ERROR:     s = _("YES");   break;
160      key_attr = ks->timestamp;      case GPG_ERR_NO_PUBKEY:    s = _("NOKEY"); break;
161      if( key_attr ) {      case GPG_ERR_BAD_SIGNATURE:s = _("NO");    break;
162          s = get_key_created( key_attr );      default:                   s = _("ERROR"); break;
163          listview_add_sub_item( lv, 0, 3, s );      }
164      }      if (no_uid)
165                s = _("NOKEY");
166      attr = ks->keyid;      listview_add_sub_item (lv, pos, SL_COL_VALID, s);
167      if( attr && strlen( attr ) == 16 ) {  
168          _snprintf (t, sizeof t -1, "0x%s", attr + 8);      switch (ks->sig_class) {
169          listview_add_sub_item( lv, 0, 4, t );      case 0x10: strcpy (t, " "); break;
170      }      case 0x11: strcpy (t, "1"); break;
171        case 0x12: strcpy (t, "2"); break;
172      key_attr = ks->expires;      case 0x13: strcpy (t, "3"); break;
173      if (key_attr) {      }
174          s = get_key_created (key_attr);  
175          listview_add_sub_item (lv, 0, 5, s);      strcat (t, " ");
176      }      if (!ks->exportable)
177            strcat (t, "L");
178      attr = get_key_pubalgo (ks->pubkey_algo);      /* XXX: if gpgme supports non-revocable status, add 'R' */
179      if( attr )      listview_add_sub_item (lv, pos, SL_COL_CLASS, t);
180          listview_add_sub_item( lv, 0, 6, (char *)attr );  
181            s = get_key_created (ks->timestamp);
182      return 0;      listview_add_sub_item (lv, pos, SL_COL_CREATE, s);
183  }  
184        if (ks->keyid && strlen (ks->keyid) == 16) {
185            _snprintf (t, DIM (t) -1, "0x%s", ks->keyid + 8);
186  /* Load a signature list with the signatures of the key with          listview_add_sub_item (lv, pos, SL_COL_KEYID, t);
187     the keyID @keyid. The parent window is in @ctrl.      }
188     Return value is the handle to the listview control. */  
189  listview_ctrl_t      if (ks->expires > 0) {
190  siglist_load (HWND ctrl, const char *keyid)          s = get_key_created (ks->expires);
191  {              listview_add_sub_item (lv, pos, SL_COL_EXPIRE, s);
192      gpgme_key_t key;      }
193      gpgme_user_id_t u;  
194      gpgme_key_sig_t s;      attr = get_key_pubalgo (ks->pubkey_algo);
195      listview_ctrl_t lv;      if (attr)
196      int rc, i=0;          listview_add_sub_item (lv, pos, 6, (char *)attr);
197    
198      if (siglist_build (&lv, ctrl))      return 0;
199          BUG (NULL);  }
200      rc = get_pubkey(keyid, &key);  
201      if (rc)  
202          BUG (NULL);  /* Load a signature list with the signatures of the key with
203       the keyID @keyid. The parent window is in @ctrl.
204      /* XXX: the root item is at the end but should come first. */     Return value is the handle to the listview control. */
205      for (u=key->uids; u; u = u->next) {  listview_ctrl_t
206          siglist_add_key (lv, u, NULL);  siglist_load (HWND ctrl, const char *keyid)
207          for (s = u->signatures; s; s = s->next) {  {    
208              rc = siglist_add_key (lv, NULL, s);      gpgme_key_sig_t s;
209              if (rc)      struct native_uid_s *u;
210                  break;      winpt_key_s key;
211          }      listview_ctrl_t lv;
212      }      int pos = 0;
213      if (rc) {      int rc = 0;
214          siglist_delete (lv);  
215          lv = NULL;      siglist_build (&lv, ctrl);
216      }      memset (&key, 0, sizeof (key));
217      return lv;      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.24  
changed lines
  Added in v.299

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26