1 /* gpa-tofu-list.c - A list to show TOFU information.
2 * Copyright (C) 2016 g10 Code GmbH
3 *
4 * This file is part of GPA
5 *
6 * GPA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPA is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21
22 #include "gpa.h"
23 #include "convert.h"
24 #include "gtktools.h"
25 #include "keytable.h"
26 #include "gpa-tofu-list.h"
27
28 #ifdef ENABLE_TOFU_INFO
29
30 static gboolean tofu_list_query_tooltip_cb (GtkWidget *wdiget, int x, int y,
31 gboolean keyboard_mode,
32 GtkTooltip *tooltip,
33 gpointer user_data);
34
35
36
37 typedef enum
38 {
39 TOFU_ADDRESS,
40 TOFU_VALIDITY,
41 TOFU_POLICY,
42 TOFU_COUNT,
43 TOFU_FIRSTSIGN,
44 TOFU_LASTSIGN,
45 TOFU_FIRSTENCR,
46 TOFU_LASTENCR,
47 TOFU_N_COLUMNS
48 } SubkeyListColumn;
49
50
51 /* Create a new subkey list. */
52 GtkWidget *
gpa_tofu_list_new(void)53 gpa_tofu_list_new (void)
54 {
55 GtkListStore *store;
56 GtkWidget *list;
57 GtkTreeViewColumn *column;
58 GtkCellRenderer *renderer;
59
60 /* Init the model */
61 store = gtk_list_store_new (TOFU_N_COLUMNS,
62 G_TYPE_STRING, /* address */
63 G_TYPE_STRING, /* validity */
64 G_TYPE_STRING, /* policy */
65 G_TYPE_STRING, /* count */
66 G_TYPE_STRING, /* firstsign */
67 G_TYPE_STRING, /* lastsign */
68 G_TYPE_STRING, /* firstencr */
69 G_TYPE_STRING /* lastencr */
70 );
71
72 /* The view */
73 list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
74 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE);
75
76 /* Add the columns */
77 renderer = gtk_cell_renderer_text_new ();
78 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
79 "text", TOFU_ADDRESS,
80 NULL);
81 gpa_set_column_title (column, _("Address"),
82 _("The mail address."));
83 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
84
85 renderer = gtk_cell_renderer_text_new ();
86 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
87 "text", TOFU_VALIDITY,
88 NULL);
89 gpa_set_column_title (column, _("Validity"),
90 _("The TOFU validity of the mail address:\n"
91 " Minimal = Only little history available\n"));
92 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
93
94 renderer = gtk_cell_renderer_text_new ();
95 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
96 "text", TOFU_POLICY,
97 NULL);
98 gpa_set_column_title (column, _("Policy"),
99 _("The TOFU policy set for this mail address."));
100 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
101
102 renderer = gtk_cell_renderer_text_new ();
103 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
104 "text", TOFU_COUNT,
105 NULL);
106 gpa_set_column_title (column, _("Count"),
107 _("The number of signatures seen for this address\n"
108 "and the number of encryption done to this address.")
109 );
110 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
111
112 renderer = gtk_cell_renderer_text_new ();
113 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
114 "text", TOFU_FIRSTSIGN,
115 NULL);
116 gpa_set_column_title (column, _("First Sig"),
117 _("The date the first signature was verified."));
118 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
119
120 renderer = gtk_cell_renderer_text_new ();
121 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
122 "text", TOFU_LASTSIGN,
123 NULL);
124 gpa_set_column_title (column, _("Last Sig"),
125 _("The most recent date a signature was verified."));
126 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
127
128 renderer = gtk_cell_renderer_text_new ();
129 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
130 "text", TOFU_FIRSTENCR,
131 NULL);
132 gpa_set_column_title (column, _("First Enc"),
133 _("The date the first encrypted mail was sent."));
134 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
135
136 renderer = gtk_cell_renderer_text_new ();
137 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
138 "text", TOFU_LASTENCR,
139 NULL);
140 gpa_set_column_title (column, _("Last Enc"),
141 _("The most recent date an encrypted mail was sent."));
142 gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
143
144 g_object_set (list, "has-tooltip", TRUE, NULL);
145 g_signal_connect (list, "query-tooltip",
146 G_CALLBACK (tofu_list_query_tooltip_cb), list);
147
148 return list;
149 }
150
151
152 static const gchar *
tofu_validity_str(gpgme_tofu_info_t tofu)153 tofu_validity_str (gpgme_tofu_info_t tofu)
154 {
155 switch (tofu->validity)
156 {
157 case 0: return _("Conflict");
158 case 1: return _("Unknown");
159 case 2: return _("Minimal");
160 case 3: return _("Basic");
161 case 4: return _("Full");
162 default: return "?";
163 }
164 }
165
166
167 static const gchar *
tofu_policy_str(gpgme_tofu_info_t tofu)168 tofu_policy_str (gpgme_tofu_info_t tofu)
169 {
170 switch (tofu->policy)
171 {
172 case GPGME_TOFU_POLICY_NONE: return _("None");
173 case GPGME_TOFU_POLICY_AUTO: return _("Auto");
174 case GPGME_TOFU_POLICY_GOOD: return _("Good");
175 case GPGME_TOFU_POLICY_UNKNOWN: return _("Unknown");
176 case GPGME_TOFU_POLICY_BAD: return _("Bad");
177 case GPGME_TOFU_POLICY_ASK: return _("Ask");
178 }
179 return "?";
180 }
181
182
183 /* Set the key whose subkeys should be displayed. */
184 void
gpa_tofu_list_set_key(GtkWidget * list,gpgme_key_t key)185 gpa_tofu_list_set_key (GtkWidget *list, gpgme_key_t key)
186 {
187 GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model
188 (GTK_TREE_VIEW (list)));
189 GtkTreeIter iter;
190 gpgme_user_id_t uid;
191 gpgme_tofu_info_t tofu;
192 char *countstr, *firstsign, *lastsign, *firstencr, *lastencr;
193
194 /* Empty the list */
195 gtk_list_store_clear (store);
196
197 if (!key || !key->uids)
198 return;
199
200 for (uid = key->uids; uid; uid = uid->next)
201 {
202 if (!uid->address || !uid->tofu)
203 continue; /* No address or tofu info. */
204 tofu = uid->tofu;
205
206 /* Note that we do not need to filter ADDRESS like we do with
207 * user ids because GPGME checked that it is a valid mail
208 * address. */
209 countstr = g_strdup_printf ("%hu/%hu", tofu->signcount, tofu->encrcount);
210 firstsign = gpa_date_string (tofu->signfirst);
211 lastsign = gpa_date_string (tofu->signlast);
212 firstencr = gpa_date_string (tofu->encrfirst);
213 lastencr = gpa_date_string (tofu->encrlast);
214
215 gtk_list_store_append (store, &iter);
216 gtk_list_store_set
217 (store, &iter,
218 TOFU_ADDRESS, uid->address,
219 TOFU_VALIDITY, tofu_validity_str (tofu),
220 TOFU_POLICY, tofu_policy_str (tofu),
221 TOFU_COUNT, countstr,
222 TOFU_FIRSTSIGN,firstsign,
223 TOFU_LASTSIGN, lastsign,
224 TOFU_FIRSTENCR,firstencr,
225 TOFU_LASTENCR, lastencr,
226 -1);
227
228 g_free (countstr);
229 g_free (firstsign);
230 g_free (lastsign);
231 g_free (firstencr);
232 g_free (lastencr);
233 }
234
235 }
236
237
238 /* Tooltip display callback. */
239 static gboolean
tofu_list_query_tooltip_cb(GtkWidget * widget,int x,int y,gboolean keyboard_tip,GtkTooltip * tooltip,gpointer user_data)240 tofu_list_query_tooltip_cb (GtkWidget *widget, int x, int y,
241 gboolean keyboard_tip,
242 GtkTooltip *tooltip, gpointer user_data)
243 {
244 GtkTreeView *tv = GTK_TREE_VIEW (widget);
245 GtkTreeViewColumn *column;
246 char *text;
247
248 (void)user_data;
249
250 if (!gtk_tree_view_get_tooltip_context (tv, &x, &y, keyboard_tip,
251 NULL, NULL, NULL))
252 return FALSE; /* Not at a row - do not show a tooltip. */
253 if (!gtk_tree_view_get_path_at_pos (tv, x, y, NULL, &column, NULL, NULL))
254 return FALSE;
255
256 widget = gtk_tree_view_column_get_widget (column);
257 text = widget? gtk_widget_get_tooltip_text (widget) : NULL;
258 if (!text)
259 return FALSE; /* No tooltip desired. */
260
261 gtk_tooltip_set_text (tooltip, text);
262 g_free (text);
263
264 return TRUE; /* Show tooltip. */
265 }
266 #endif /*ENABLE_TOFU_INFO*/
267