Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2011 Collabora Ltd.
3 : : *
4 : : * This program is free software; you can redistribute it and/or modify
5 : : * it under the terms of the GNU Lesser General Public License as
6 : : * published by the Free Software Foundation; either version 2.1 of
7 : : * the License, or (at your option) any later version.
8 : : *
9 : : * This program is distributed in the hope that it will be useful, but
10 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : : * Lesser General Public License for more details.
13 : : *
14 : : * You should have received a copy of the GNU Lesser General Public
15 : : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
16 : : *
17 : : * Author: Stef Walter <stefw@collabora.co.uk>
18 : : */
19 : :
20 : : #include "config.h"
21 : :
22 : : #include "gcr-gnupg-key.h"
23 : : #include "gcr-gnupg-records.h"
24 : : #include "gcr-record.h"
25 : :
26 : : #include "gck/gck.h"
27 : :
28 : : #include <glib/gi18n-lib.h>
29 : :
30 : : enum {
31 : : PROP_0,
32 : : PROP_KEYID,
33 : : PROP_PUBLIC_RECORDS,
34 : : PROP_SECRET_RECORDS,
35 : : PROP_LABEL,
36 : : PROP_MARKUP,
37 : : PROP_DESCRIPTION,
38 : : PROP_SHORT_KEYID,
39 : : N_PROPS
40 : : };
41 : :
42 : : struct _GcrGnupgKeyPrivate {
43 : : GPtrArray *public_records;
44 : : GPtrArray *secret_records;
45 : : };
46 : :
47 [ + + + - : 94 : G_DEFINE_TYPE_WITH_PRIVATE (GcrGnupgKey, _gcr_gnupg_key, G_TYPE_OBJECT);
+ + ]
48 : :
49 : : static gchar *
50 : 2 : calculate_name (GcrGnupgKey *self)
51 : : {
52 : : GcrRecord* record;
53 : :
54 : 2 : record = _gcr_records_find (self->pv->public_records, GCR_RECORD_SCHEMA_UID);
55 [ - + ]: 2 : g_return_val_if_fail (record, NULL);
56 : :
57 : 2 : return _gcr_record_get_string (record, GCR_RECORD_UID_USERID);
58 : : }
59 : :
60 : : static gchar *
61 : 1 : calculate_markup (GcrGnupgKey *self)
62 : : {
63 : 1 : gchar *markup = NULL;
64 : : gchar *uid, *name, *email, *comment;
65 : :
66 : 1 : uid = calculate_name (self);
67 [ - + ]: 1 : if (uid == NULL)
68 : 0 : return NULL;
69 : :
70 : 1 : _gcr_gnupg_records_parse_user_id (uid, &name, &email, &comment);
71 [ - + - - ]: 1 : if (comment != NULL && comment[0] != '\0')
72 : 0 : markup = g_markup_printf_escaped ("%s\n<small>%s \'%s\'</small>", name, email, comment);
73 : : else
74 : 1 : markup = g_markup_printf_escaped ("%s\n<small>%s</small>", name, email);
75 : 1 : g_free (name);
76 : 1 : g_free (email);
77 : 1 : g_free (comment);
78 : 1 : g_free (uid);
79 : :
80 : 1 : return markup;
81 : : }
82 : :
83 : : static void
84 : 11 : _gcr_gnupg_key_init (GcrGnupgKey *self)
85 : : {
86 : 11 : self->pv = _gcr_gnupg_key_get_instance_private (self);
87 : 11 : }
88 : :
89 : : static void
90 : 11 : _gcr_gnupg_key_finalize (GObject *obj)
91 : : {
92 : 11 : GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
93 : :
94 [ + - ]: 11 : if (self->pv->public_records)
95 : 11 : g_ptr_array_unref (self->pv->public_records);
96 [ + + ]: 11 : if (self->pv->secret_records)
97 : 1 : g_ptr_array_unref (self->pv->secret_records);
98 : :
99 : 11 : G_OBJECT_CLASS (_gcr_gnupg_key_parent_class)->finalize (obj);
100 : 11 : }
101 : :
102 : : static void
103 : 23 : _gcr_gnupg_key_set_property (GObject *obj, guint prop_id, const GValue *value,
104 : : GParamSpec *pspec)
105 : : {
106 : 23 : GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
107 : :
108 [ + + - ]: 23 : switch (prop_id) {
109 : 11 : case PROP_PUBLIC_RECORDS:
110 : 11 : _gcr_gnupg_key_set_public_records (self, g_value_get_boxed (value));
111 : 11 : break;
112 : 12 : case PROP_SECRET_RECORDS:
113 : 12 : _gcr_gnupg_key_set_secret_records (self, g_value_get_boxed (value));
114 : 12 : break;
115 : 0 : default:
116 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
117 : 0 : break;
118 : : }
119 : 23 : }
120 : :
121 : : static void
122 : 7 : _gcr_gnupg_key_get_property (GObject *obj, guint prop_id, GValue *value,
123 : : GParamSpec *pspec)
124 : : {
125 : 7 : GcrGnupgKey *self = GCR_GNUPG_KEY (obj);
126 : :
127 [ + + + + : 7 : switch (prop_id) {
+ + + - ]
128 : 1 : case PROP_PUBLIC_RECORDS:
129 : 1 : g_value_set_boxed (value, self->pv->public_records);
130 : 1 : break;
131 : 1 : case PROP_SECRET_RECORDS:
132 : 1 : g_value_set_boxed (value, self->pv->secret_records);
133 : 1 : break;
134 : 1 : case PROP_KEYID:
135 : 1 : g_value_set_string (value, _gcr_gnupg_key_get_keyid (self));
136 : 1 : break;
137 : 1 : case PROP_LABEL:
138 : 1 : g_value_take_string (value, calculate_name (self));
139 : 1 : break;
140 : 1 : case PROP_DESCRIPTION:
141 : 1 : g_value_set_string (value, _("PGP Key"));
142 : 1 : break;
143 : 1 : case PROP_MARKUP:
144 : 1 : g_value_take_string (value, calculate_markup (self));
145 : 1 : break;
146 : 1 : case PROP_SHORT_KEYID:
147 : 1 : g_value_set_string (value, _gcr_gnupg_records_get_short_keyid (self->pv->public_records));
148 : 1 : break;
149 : 0 : default:
150 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
151 : 0 : break;
152 : : }
153 : 7 : }
154 : :
155 : : static void
156 : 1 : _gcr_gnupg_key_class_init (GcrGnupgKeyClass *klass)
157 : : {
158 : 1 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
159 : :
160 : 1 : _gcr_gnupg_key_parent_class = g_type_class_peek_parent (klass);
161 : :
162 : 1 : gobject_class->finalize = _gcr_gnupg_key_finalize;
163 : 1 : gobject_class->set_property = _gcr_gnupg_key_set_property;
164 : 1 : gobject_class->get_property = _gcr_gnupg_key_get_property;
165 : :
166 : : /**
167 : : * GcrGnupgKey:public-records:
168 : : *
169 : : * Public key data. Should always be present.
170 : : */
171 : 1 : g_object_class_install_property (gobject_class, PROP_PUBLIC_RECORDS,
172 : : g_param_spec_boxed ("public-records", "Public Records", "Public Key Colon Records",
173 : : G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
174 : :
175 : : /**
176 : : * GcrGnupgKey:secret-records:
177 : : *
178 : : * Secret key data. The keyid of this data must match public-dataset.
179 : : * If present, this key represents a secret key.
180 : : */
181 : 1 : g_object_class_install_property (gobject_class, PROP_SECRET_RECORDS,
182 : : g_param_spec_boxed ("secret-records", "Secret Records", "Secret Key Colon Records",
183 : : G_TYPE_PTR_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
184 : :
185 : : /**
186 : : * GcrGnupgKey:keyid:
187 : : *
188 : : * Key identifier.
189 : : */
190 : 1 : g_object_class_install_property (gobject_class, PROP_KEYID,
191 : : g_param_spec_string ("keyid", "Key ID", "Key identifier",
192 : : "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
193 : :
194 : : /**
195 : : * GcrGnupgKey:label:
196 : : *
197 : : * User readable label for this key.
198 : : */
199 : 1 : g_object_class_install_property (gobject_class, PROP_LABEL,
200 : : g_param_spec_string ("label", "Label", "Key label",
201 : : "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
202 : :
203 : : /**
204 : : * GcrGnupgKey::description:
205 : : *
206 : : * Description of type of key.
207 : : */
208 : 1 : g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
209 : : g_param_spec_string ("description", "Description", "Description of object type",
210 : : "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
211 : :
212 : : /**
213 : : * GcrGnupgKey:markup:
214 : : *
215 : : * User readable markup which contains key label.
216 : : */
217 : 1 : g_object_class_install_property (gobject_class, PROP_MARKUP,
218 : : g_param_spec_string ("markup", "Markup", "Markup which describes key",
219 : : "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
220 : :
221 : : /**
222 : : * GcrGnupgKey:short-keyid:
223 : : *
224 : : * User readable key identifier.
225 : : */
226 : 1 : g_object_class_install_property (gobject_class, PROP_SHORT_KEYID,
227 : : g_param_spec_string ("short-keyid", "Short Key ID", "Display key identifier",
228 : : "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
229 : 1 : }
230 : :
231 : : /**
232 : : * _gcr_gnupg_key_new:
233 : : * @pubset: array of GcrRecord* representing public part of key
234 : : * @secset: (nullable): array of GcrRecord* representing secret part of key.
235 : : *
236 : : * Create a new GcrGnupgKey for the record data passed. If the secret part
237 : : * of the key is set, then this represents a secret key; otherwise it represents
238 : : * a public key.
239 : : *
240 : : * Returns: (transfer full): A newly allocated key.
241 : : */
242 : : GcrGnupgKey*
243 : 11 : _gcr_gnupg_key_new (GPtrArray *pubset, GPtrArray *secset)
244 : : {
245 [ - + ]: 11 : g_return_val_if_fail (pubset, NULL);
246 : 11 : return g_object_new (GCR_TYPE_GNUPG_KEY,
247 : : "public-records", pubset,
248 : : "secret-records", secset,
249 : : NULL);
250 : : }
251 : :
252 : : /**
253 : : * _gcr_gnupg_key_get_public_records:
254 : : * @self: The key
255 : : *
256 : : * Get the record data this key is based on.
257 : : *
258 : : * Returns: (transfer none): An array of GcrRecord*.
259 : : */
260 : : GPtrArray*
261 : 1 : _gcr_gnupg_key_get_public_records (GcrGnupgKey *self)
262 : : {
263 [ - + + - : 1 : g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
+ - - + ]
264 : 1 : return self->pv->public_records;
265 : : }
266 : :
267 : : /**
268 : : * _gcr_gnupg_key_set_public_records:
269 : : * @self: The key
270 : : * @records: The new array of GcrRecord*
271 : : *
272 : : * Change the record data that this key is based on.
273 : : */
274 : : void
275 : 12 : _gcr_gnupg_key_set_public_records (GcrGnupgKey *self, GPtrArray *records)
276 : : {
277 : : GObject *obj;
278 : :
279 [ - + + - : 12 : g_return_if_fail (GCR_IS_GNUPG_KEY (self));
+ - - + ]
280 [ - + ]: 12 : g_return_if_fail (records);
281 : :
282 : : /* Check that it matches previous */
283 [ + + ]: 12 : if (self->pv->public_records) {
284 : 1 : const gchar *old_keyid = _gcr_gnupg_records_get_keyid (self->pv->public_records);
285 : 1 : const gchar *new_keyid = _gcr_gnupg_records_get_keyid (records);
286 : :
287 [ - + ]: 1 : if (g_strcmp0 (old_keyid, new_keyid) != 0) {
288 : 0 : g_warning ("it is an error to change a gnupg key so that the "
289 : : "fingerprint is no longer the same: %s != %s",
290 : : old_keyid, new_keyid);
291 : 0 : return;
292 : : }
293 : : }
294 : :
295 : 12 : g_ptr_array_ref (records);
296 [ + + ]: 12 : if (self->pv->public_records)
297 : 1 : g_ptr_array_unref (self->pv->public_records);
298 : 12 : self->pv->public_records = records;
299 : :
300 : 12 : obj = G_OBJECT (self);
301 : 12 : g_object_freeze_notify (obj);
302 : 12 : g_object_notify (obj, "public-records");
303 : 12 : g_object_notify (obj, "label");
304 : 12 : g_object_notify (obj, "markup");
305 : 12 : g_object_thaw_notify (obj);
306 : : }
307 : :
308 : : /**
309 : : * _gcr_gnupg_key_get_secret_records:
310 : : * @self: The key
311 : : *
312 : : * Get the record secret data this key is based on. %NULL if a public key.
313 : : *
314 : : * Returns: (transfer none) (nullable): An array of GcrColons*.
315 : : */
316 : : GPtrArray*
317 : 1 : _gcr_gnupg_key_get_secret_records (GcrGnupgKey *self)
318 : : {
319 [ - + + - : 1 : g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
+ - - + ]
320 : 1 : return self->pv->secret_records;
321 : : }
322 : :
323 : : /**
324 : : * _gcr_gnupg_key_set_secret_records:
325 : : * @self: The key
326 : : * @records: (nullable): The new array of GcrRecord*
327 : : *
328 : : * Set the secret data for this key. %NULL if public key.
329 : : */
330 : : void
331 : 12 : _gcr_gnupg_key_set_secret_records (GcrGnupgKey *self, GPtrArray *records)
332 : : {
333 : : GObject *obj;
334 : :
335 [ - + + - : 12 : g_return_if_fail (GCR_IS_GNUPG_KEY (self));
+ - - + ]
336 : :
337 : : /* Check that it matches public key */
338 [ + - + + ]: 12 : if (self->pv->public_records && records) {
339 : 2 : const gchar *pub_keyid = _gcr_gnupg_records_get_keyid (self->pv->public_records);
340 : 2 : const gchar *sec_keyid = _gcr_gnupg_records_get_keyid (records);
341 : :
342 [ - + ]: 2 : if (g_strcmp0 (pub_keyid, sec_keyid) != 0) {
343 : 0 : g_warning ("it is an error to create a gnupg key so that the "
344 : : "fingerprint of thet pub and sec parts are not the same: %s != %s",
345 : : pub_keyid, sec_keyid);
346 : 0 : return;
347 : : }
348 : : }
349 : :
350 [ + + ]: 12 : if (records)
351 : 2 : g_ptr_array_ref (records);
352 [ + + ]: 12 : if (self->pv->secret_records)
353 : 1 : g_ptr_array_unref (self->pv->secret_records);
354 : 12 : self->pv->secret_records = records;
355 : :
356 : 12 : obj = G_OBJECT (self);
357 : 12 : g_object_freeze_notify (obj);
358 : 12 : g_object_notify (obj, "secret-records");
359 : 12 : g_object_thaw_notify (obj);
360 : : }
361 : :
362 : : /**
363 : : * _gcr_gnupg_key_get_keyid:
364 : : * @self: The key
365 : : *
366 : : * Get the keyid for this key.
367 : : *
368 : : * Returns: (transfer none): The keyid.
369 : : */
370 : : const gchar*
371 : 2 : _gcr_gnupg_key_get_keyid (GcrGnupgKey *self)
372 : : {
373 [ - + + - : 2 : g_return_val_if_fail (GCR_IS_GNUPG_KEY (self), NULL);
+ - - + ]
374 : 2 : return _gcr_gnupg_records_get_keyid (self->pv->public_records);
375 : : }
|