1 /*
2 * e-source-smime.c
3 *
4 * This library is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 /**
19 * SECTION: e-source-smime
20 * @include: libedataserver/libedataserver.h
21 * @short_description: #ESource extension for S/MIME settings
22 *
23 * The #ESourceSMIME extension tracks Secure/Multipurpose Internet Mail
24 * Extensions (S/MIME) settings to be applied to outgoing mail messages.
25 *
26 * Access the extension as follows:
27 *
28 * |[
29 * #include <libedataserver/libedataserver.h>
30 *
31 * ESourceSMIME *extension;
32 *
33 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_SMIME);
34 * ]|
35 **/
36
37 #include "e-source-smime.h"
38
39 #include <libedataserver/e-data-server-util.h>
40
41 struct _ESourceSMIMEPrivate {
42 gchar *encryption_certificate;
43 gchar *signing_algorithm;
44 gchar *signing_certificate;
45
46 gboolean encrypt_by_default;
47 gboolean encrypt_to_self;
48 gboolean sign_by_default;
49 };
50
51 enum {
52 PROP_0,
53 PROP_ENCRYPTION_CERTIFICATE,
54 PROP_ENCRYPT_BY_DEFAULT,
55 PROP_ENCRYPT_TO_SELF,
56 PROP_SIGNING_ALGORITHM,
57 PROP_SIGNING_CERTIFICATE,
58 PROP_SIGN_BY_DEFAULT
59 };
60
G_DEFINE_TYPE_WITH_PRIVATE(ESourceSMIME,e_source_smime,E_TYPE_SOURCE_EXTENSION)61 G_DEFINE_TYPE_WITH_PRIVATE (
62 ESourceSMIME,
63 e_source_smime,
64 E_TYPE_SOURCE_EXTENSION)
65
66 static void
67 source_smime_set_property (GObject *object,
68 guint property_id,
69 const GValue *value,
70 GParamSpec *pspec)
71 {
72 switch (property_id) {
73 case PROP_ENCRYPTION_CERTIFICATE:
74 e_source_smime_set_encryption_certificate (
75 E_SOURCE_SMIME (object),
76 g_value_get_string (value));
77 return;
78
79 case PROP_ENCRYPT_BY_DEFAULT:
80 e_source_smime_set_encrypt_by_default (
81 E_SOURCE_SMIME (object),
82 g_value_get_boolean (value));
83 return;
84
85 case PROP_ENCRYPT_TO_SELF:
86 e_source_smime_set_encrypt_to_self (
87 E_SOURCE_SMIME (object),
88 g_value_get_boolean (value));
89 return;
90
91 case PROP_SIGNING_ALGORITHM:
92 e_source_smime_set_signing_algorithm (
93 E_SOURCE_SMIME (object),
94 g_value_get_string (value));
95 return;
96
97 case PROP_SIGNING_CERTIFICATE:
98 e_source_smime_set_signing_certificate (
99 E_SOURCE_SMIME (object),
100 g_value_get_string (value));
101 return;
102
103 case PROP_SIGN_BY_DEFAULT:
104 e_source_smime_set_sign_by_default (
105 E_SOURCE_SMIME (object),
106 g_value_get_boolean (value));
107 return;
108 }
109
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
111 }
112
113 static void
source_smime_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)114 source_smime_get_property (GObject *object,
115 guint property_id,
116 GValue *value,
117 GParamSpec *pspec)
118 {
119 switch (property_id) {
120 case PROP_ENCRYPTION_CERTIFICATE:
121 g_value_take_string (
122 value,
123 e_source_smime_dup_encryption_certificate (
124 E_SOURCE_SMIME (object)));
125 return;
126
127 case PROP_ENCRYPT_BY_DEFAULT:
128 g_value_set_boolean (
129 value,
130 e_source_smime_get_encrypt_by_default (
131 E_SOURCE_SMIME (object)));
132 return;
133
134 case PROP_ENCRYPT_TO_SELF:
135 g_value_set_boolean (
136 value,
137 e_source_smime_get_encrypt_to_self (
138 E_SOURCE_SMIME (object)));
139 return;
140
141 case PROP_SIGNING_ALGORITHM:
142 g_value_take_string (
143 value,
144 e_source_smime_dup_signing_algorithm (
145 E_SOURCE_SMIME (object)));
146 return;
147
148 case PROP_SIGNING_CERTIFICATE:
149 g_value_take_string (
150 value,
151 e_source_smime_dup_signing_certificate (
152 E_SOURCE_SMIME (object)));
153 return;
154
155 case PROP_SIGN_BY_DEFAULT:
156 g_value_set_boolean (
157 value,
158 e_source_smime_get_sign_by_default (
159 E_SOURCE_SMIME (object)));
160 return;
161 }
162
163 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
164 }
165
166 static void
source_smime_finalize(GObject * object)167 source_smime_finalize (GObject *object)
168 {
169 ESourceSMIMEPrivate *priv;
170
171 priv = E_SOURCE_SMIME (object)->priv;
172
173 g_free (priv->encryption_certificate);
174 g_free (priv->signing_algorithm);
175 g_free (priv->signing_certificate);
176
177 /* Chain up to parent's finalize() method. */
178 G_OBJECT_CLASS (e_source_smime_parent_class)->finalize (object);
179 }
180
181 static void
e_source_smime_class_init(ESourceSMIMEClass * class)182 e_source_smime_class_init (ESourceSMIMEClass *class)
183 {
184 GObjectClass *object_class;
185 ESourceExtensionClass *extension_class;
186
187 object_class = G_OBJECT_CLASS (class);
188 object_class->set_property = source_smime_set_property;
189 object_class->get_property = source_smime_get_property;
190 object_class->finalize = source_smime_finalize;
191
192 extension_class = E_SOURCE_EXTENSION_CLASS (class);
193 extension_class->name = E_SOURCE_EXTENSION_SMIME;
194
195 g_object_class_install_property (
196 object_class,
197 PROP_ENCRYPTION_CERTIFICATE,
198 g_param_spec_string (
199 "encryption-certificate",
200 "Encryption Certificate",
201 "S/MIME certificate for encrypting messages",
202 NULL,
203 G_PARAM_READWRITE |
204 G_PARAM_CONSTRUCT |
205 G_PARAM_EXPLICIT_NOTIFY |
206 G_PARAM_STATIC_STRINGS |
207 E_SOURCE_PARAM_SETTING));
208
209 g_object_class_install_property (
210 object_class,
211 PROP_ENCRYPT_BY_DEFAULT,
212 g_param_spec_boolean (
213 "encrypt-by-default",
214 "Encrypt By Default",
215 "Encrypt outgoing messages by default",
216 FALSE,
217 G_PARAM_READWRITE |
218 G_PARAM_CONSTRUCT |
219 G_PARAM_EXPLICIT_NOTIFY |
220 G_PARAM_STATIC_STRINGS |
221 E_SOURCE_PARAM_SETTING));
222
223 g_object_class_install_property (
224 object_class,
225 PROP_ENCRYPT_TO_SELF,
226 g_param_spec_boolean (
227 "encrypt-to-self",
228 "Encrypt To Self",
229 "Always encrypt to myself",
230 TRUE,
231 G_PARAM_READWRITE |
232 G_PARAM_CONSTRUCT |
233 G_PARAM_EXPLICIT_NOTIFY |
234 G_PARAM_STATIC_STRINGS |
235 E_SOURCE_PARAM_SETTING));
236
237 g_object_class_install_property (
238 object_class,
239 PROP_SIGNING_ALGORITHM,
240 g_param_spec_string (
241 "signing-algorithm",
242 "Signing Algorithm",
243 "Hash algorithm used to sign messages",
244 NULL,
245 G_PARAM_READWRITE |
246 G_PARAM_CONSTRUCT |
247 G_PARAM_EXPLICIT_NOTIFY |
248 G_PARAM_STATIC_STRINGS |
249 E_SOURCE_PARAM_SETTING));
250
251 g_object_class_install_property (
252 object_class,
253 PROP_SIGNING_CERTIFICATE,
254 g_param_spec_string (
255 "signing-certificate",
256 "Signing Certificate",
257 "S/MIME certificate for signing messages",
258 NULL,
259 G_PARAM_READWRITE |
260 G_PARAM_CONSTRUCT |
261 G_PARAM_EXPLICIT_NOTIFY |
262 G_PARAM_STATIC_STRINGS |
263 E_SOURCE_PARAM_SETTING));
264
265 g_object_class_install_property (
266 object_class,
267 PROP_SIGN_BY_DEFAULT,
268 g_param_spec_boolean (
269 "sign-by-default",
270 "Sign By Default",
271 "Sign outgoing messages by default",
272 FALSE,
273 G_PARAM_READWRITE |
274 G_PARAM_CONSTRUCT |
275 G_PARAM_EXPLICIT_NOTIFY |
276 G_PARAM_STATIC_STRINGS |
277 E_SOURCE_PARAM_SETTING));
278 }
279
280 static void
e_source_smime_init(ESourceSMIME * extension)281 e_source_smime_init (ESourceSMIME *extension)
282 {
283 extension->priv = e_source_smime_get_instance_private (extension);
284 }
285
286 /**
287 * e_source_smime_get_encryption_certificate:
288 * @extension: an #ESourceSMIME
289 *
290 * Returns the S/MIME certificate name used to encrypt messages.
291 *
292 * Returns: (nullable): the certificate name used to encrypt messages
293 *
294 * Since: 3.6
295 **/
296 const gchar *
e_source_smime_get_encryption_certificate(ESourceSMIME * extension)297 e_source_smime_get_encryption_certificate (ESourceSMIME *extension)
298 {
299 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
300
301 return extension->priv->encryption_certificate;
302 }
303
304 /**
305 * e_source_smime_dup_encryption_certificate:
306 * @extension: an #ESourceSMIME
307 *
308 * Thread-safe variation of e_source_smime_get_encryption_certificate().
309 * Use this function when accessing @extension from multiple threads.
310 *
311 * The returned string should be freed with g_free() when no longer needed.
312 *
313 * Returns: (nullable): a newly-allocated copy of #ESourceSMIME:encryption-certificate
314 *
315 * Since: 3.6
316 **/
317 gchar *
e_source_smime_dup_encryption_certificate(ESourceSMIME * extension)318 e_source_smime_dup_encryption_certificate (ESourceSMIME *extension)
319 {
320 const gchar *protected;
321 gchar *duplicate;
322
323 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
324
325 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
326
327 protected = e_source_smime_get_encryption_certificate (extension);
328 duplicate = g_strdup (protected);
329
330 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
331
332 return duplicate;
333 }
334
335 /**
336 * e_source_smime_set_encryption_certificate:
337 * @extension: an #ESourceSMIME
338 * @encryption_certificate: (nullable): the certificate name used to encrypt
339 * messages, or %NULL
340 *
341 * Sets the certificate name used to encrypt messages.
342 *
343 * If the @encryption_certificate string is empty, %NULL is set instead.
344 *
345 * Since: 3.6
346 **/
347 void
e_source_smime_set_encryption_certificate(ESourceSMIME * extension,const gchar * encryption_certificate)348 e_source_smime_set_encryption_certificate (ESourceSMIME *extension,
349 const gchar *encryption_certificate)
350 {
351 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
352
353 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
354
355 if (g_strcmp0 (
356 extension->priv->encryption_certificate,
357 encryption_certificate) == 0) {
358 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
359 return;
360 }
361
362 if (encryption_certificate && !*encryption_certificate)
363 encryption_certificate = NULL;
364
365 g_free (extension->priv->encryption_certificate);
366 extension->priv->encryption_certificate = g_strdup (encryption_certificate);
367
368 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
369
370 g_object_notify (G_OBJECT (extension), "encryption-certificate");
371 }
372
373 /**
374 * e_source_smime_get_encrypt_by_default:
375 * @extension: an #ESourceSMIME
376 *
377 * Returns whether to encrypt outgoing messages by default using S/MIME
378 * software such as Mozilla Network Security Services (NSS).
379 *
380 * Returns: whether to encrypt outgoing messages by default
381 *
382 * Since: 3.6
383 **/
384 gboolean
e_source_smime_get_encrypt_by_default(ESourceSMIME * extension)385 e_source_smime_get_encrypt_by_default (ESourceSMIME *extension)
386 {
387 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), FALSE);
388
389 return extension->priv->encrypt_by_default;
390 }
391
392 /**
393 * e_source_smime_set_encrypt_by_default:
394 * @extension: an #ESourceSMIME
395 * @encrypt_by_default: whether to encrypt outgoing messages by default
396 *
397 * Sets whether to encrypt outgoing messages by default using S/MIME
398 * software such as Mozilla Network Security Services (NSS).
399 *
400 * Since: 3.6
401 **/
402 void
e_source_smime_set_encrypt_by_default(ESourceSMIME * extension,gboolean encrypt_by_default)403 e_source_smime_set_encrypt_by_default (ESourceSMIME *extension,
404 gboolean encrypt_by_default)
405 {
406 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
407
408 if (extension->priv->encrypt_by_default == encrypt_by_default)
409 return;
410
411 extension->priv->encrypt_by_default = encrypt_by_default;
412
413 g_object_notify (G_OBJECT (extension), "encrypt-by-default");
414 }
415
416 /**
417 * e_source_smime_get_encrypt_to_self:
418 * @extension: an #ESourceSMIME
419 *
420 * Returns whether to "encrypt-to-self" when sending encrypted messages.
421 *
422 * Returns: whether to "encrypt-to-self"
423 *
424 * Since: 3.6
425 **/
426 gboolean
e_source_smime_get_encrypt_to_self(ESourceSMIME * extension)427 e_source_smime_get_encrypt_to_self (ESourceSMIME *extension)
428 {
429 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), FALSE);
430
431 return extension->priv->encrypt_to_self;
432 }
433
434 /**
435 * e_source_smime_set_encrypt_to_self:
436 * @extension: an #ESourceSMIME
437 * @encrypt_to_self: whether to "encrypt-to-self"
438 *
439 * Sets whether to "encrypt-to-self" when sending encrypted messages.
440 *
441 * Since: 3.6
442 **/
443 void
e_source_smime_set_encrypt_to_self(ESourceSMIME * extension,gboolean encrypt_to_self)444 e_source_smime_set_encrypt_to_self (ESourceSMIME *extension,
445 gboolean encrypt_to_self)
446 {
447 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
448
449 if (extension->priv->encrypt_to_self == encrypt_to_self)
450 return;
451
452 extension->priv->encrypt_to_self = encrypt_to_self;
453
454 g_object_notify (G_OBJECT (extension), "encrypt-to-self");
455 }
456
457 /**
458 * e_source_smime_get_signing_algorithm:
459 * @extension: an #ESourceSMIME
460 *
461 * Returns the name of the hash algorithm used to digitally sign outgoing
462 * messages.
463 *
464 * Returns: (nullable): the signing algorithm for outgoing messages
465 *
466 * Since: 3.6
467 **/
468 const gchar *
e_source_smime_get_signing_algorithm(ESourceSMIME * extension)469 e_source_smime_get_signing_algorithm (ESourceSMIME *extension)
470 {
471 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
472
473 return extension->priv->signing_algorithm;
474 }
475
476 /**
477 * e_source_smime_dup_signing_algorithm:
478 * @extension: an #ESourceSMIME
479 *
480 * Thread-safe variation of e_source_smime_get_signing_algorithm().
481 * Use this function when accessing @extension from multiple threads.
482 *
483 * The returned string should be freed with g_free() when no longer needed.
484 *
485 * Returns: (nullable): a newly-allocated copy of #ESourceSMIME:signing-algorithm
486 *
487 * Since: 3.6
488 **/
489 gchar *
e_source_smime_dup_signing_algorithm(ESourceSMIME * extension)490 e_source_smime_dup_signing_algorithm (ESourceSMIME *extension)
491 {
492 const gchar *protected;
493 gchar *duplicate;
494
495 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
496
497 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
498
499 protected = e_source_smime_get_signing_algorithm (extension);
500 duplicate = g_strdup (protected);
501
502 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
503
504 return duplicate;
505 }
506
507 /**
508 * e_source_smime_set_signing_algorithm:
509 * @extension: an #ESourceSMIME
510 * @signing_algorithm: (nullable): the signing algorithm for outgoing
511 * messages, or %NULL
512 *
513 * Sets the name of the hash algorithm used to digitally sign outgoing
514 * messages.
515 *
516 * The internal copy of @signing_algorithm is automatically stripped of
517 * leading and trailing whitespace. If the resulting string is empty,
518 * %NULL is set instead.
519 *
520 * Since: 3.6
521 **/
522 void
e_source_smime_set_signing_algorithm(ESourceSMIME * extension,const gchar * signing_algorithm)523 e_source_smime_set_signing_algorithm (ESourceSMIME *extension,
524 const gchar *signing_algorithm)
525 {
526 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
527
528 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
529
530 if (e_util_strcmp0 (extension->priv->signing_algorithm, signing_algorithm) == 0) {
531 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
532 return;
533 }
534
535 g_free (extension->priv->signing_algorithm);
536 extension->priv->signing_algorithm =
537 e_util_strdup_strip (signing_algorithm);
538
539 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
540
541 g_object_notify (G_OBJECT (extension), "signing-algorithm");
542 }
543
544 /**
545 * e_source_smime_get_signing_certificate:
546 * @extension: an #ESourceSMIME
547 *
548 * Returns the S/MIME certificate name used to sign messages.
549 *
550 * Returns: (nullable): the certificate name used to sign messages
551 *
552 * Since: 3.6
553 **/
554 const gchar *
e_source_smime_get_signing_certificate(ESourceSMIME * extension)555 e_source_smime_get_signing_certificate (ESourceSMIME *extension)
556 {
557 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
558
559 return extension->priv->signing_certificate;
560 }
561
562 /**
563 * e_source_smime_dup_signing_certificate:
564 * @extension: an #ESourceSMIME
565 *
566 * Thread-safe variation of e_source_smime_get_signing_certificate().
567 * Use this function when accessing @extension from multiple threads.
568 *
569 * The returned string should be freed with g_free() when no longer needed.
570 *
571 * Returns: (nullable): a newly-allocated copy of #ESourceSMIME:signing-certificate
572 *
573 * Since: 3.6
574 **/
575 gchar *
e_source_smime_dup_signing_certificate(ESourceSMIME * extension)576 e_source_smime_dup_signing_certificate (ESourceSMIME *extension)
577 {
578 const gchar *protected;
579 gchar *duplicate;
580
581 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), NULL);
582
583 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
584
585 protected = e_source_smime_get_signing_certificate (extension);
586 duplicate = g_strdup (protected);
587
588 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
589
590 return duplicate;
591 }
592
593 /**
594 * e_source_smime_set_signing_certificate:
595 * @extension: an #ESourceSMIME
596 * @signing_certificate: (nullable): the certificate name used to sign
597 * messages, or %NULL
598 *
599 * Sets the S/MIME certificate name used to sign messages.
600 *
601 * If the @signing_certificate string is empty, %NULL is set instead.
602 *
603 * Since: 3.6
604 **/
605 void
e_source_smime_set_signing_certificate(ESourceSMIME * extension,const gchar * signing_certificate)606 e_source_smime_set_signing_certificate (ESourceSMIME *extension,
607 const gchar *signing_certificate)
608 {
609 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
610
611 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
612
613 if (g_strcmp0 (extension->priv->signing_certificate, signing_certificate) == 0) {
614 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
615 return;
616 }
617
618 if (signing_certificate && !*signing_certificate)
619 signing_certificate = NULL;
620
621 g_free (extension->priv->signing_certificate);
622 extension->priv->signing_certificate = g_strdup (signing_certificate);
623
624 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
625
626 g_object_notify (G_OBJECT (extension), "signing-certificate");
627 }
628
629 /**
630 * e_source_smime_get_sign_by_default:
631 * @extension: an #ESourceSMIME
632 *
633 * Returns whether to digitally sign outgoing messages by default using
634 * S/MIME software such as Mozilla Network Security Services (NSS).
635 *
636 * Returns: whether to sign outgoing messages by default
637 *
638 * Since: 3.6
639 **/
640 gboolean
e_source_smime_get_sign_by_default(ESourceSMIME * extension)641 e_source_smime_get_sign_by_default (ESourceSMIME *extension)
642 {
643 g_return_val_if_fail (E_IS_SOURCE_SMIME (extension), FALSE);
644
645 return extension->priv->sign_by_default;
646 }
647
648 /**
649 * e_source_smime_set_sign_by_default:
650 * @extension: an #ESourceSMIME
651 * @sign_by_default: whether to sign outgoing messages by default
652 *
653 * Sets whether to digitally sign outgoing messages by default using
654 * S/MIME software such as Mozilla Network Security Services (NSS).
655 *
656 * Since: 3.6
657 **/
658 void
e_source_smime_set_sign_by_default(ESourceSMIME * extension,gboolean sign_by_default)659 e_source_smime_set_sign_by_default (ESourceSMIME *extension,
660 gboolean sign_by_default)
661 {
662 g_return_if_fail (E_IS_SOURCE_SMIME (extension));
663
664 if (extension->priv->sign_by_default == sign_by_default)
665 return;
666
667 extension->priv->sign_by_default = sign_by_default;
668
669 g_object_notify (G_OBJECT (extension), "sign-by-default");
670 }
671
672