4849a93b7d1fa7c6851f84edb336ec3e2b8c7cab
[claws.git] / src / privacy.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2003 Hiroyuki Yamamoto & the Sylpheed-Claws team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <glib.h>
21 #include <glib/gi18n.h>
22
23 #include "privacy.h"
24 #include "procmime.h"
25
26 static GSList *systems = NULL;
27
28 /**
29  * Register a new Privacy System
30  *
31  * \param system The Privacy System that should be registered
32  */
33 void privacy_register_system(PrivacySystem *system)
34 {
35         systems = g_slist_append(systems, system);
36 }
37
38 /**
39  * Unregister a new Privacy System. The system must not be in
40  * use anymore when it is unregistered.
41  *
42  * \param system The Privacy System that should be unregistered
43  */
44 void privacy_unregister_system(PrivacySystem *system)
45 {
46         systems = g_slist_remove(systems, system);
47 }
48
49 /**
50  * Free a PrivacyData of a PrivacySystem
51  *
52  * \param privacydata The data to free
53  */
54 void privacy_free_privacydata(PrivacyData *privacydata)
55 {
56         g_return_if_fail(privacydata != NULL);
57
58         privacydata->system->free_privacydata(privacydata);
59 }
60
61 /**
62  * Check if a MimeInfo is signed with one of the available
63  * privacy system. If a privacydata is set in the MimeInfo
64  * it will directory return the return value by the system
65  * set in the privacy data or check all available privacy
66  * systems otherwise.
67  *
68  * \return True if the MimeInfo has a signature
69  */
70 gboolean privacy_mimeinfo_is_signed(MimeInfo *mimeinfo)
71 {
72         GSList *cur;
73         g_return_val_if_fail(mimeinfo != NULL, FALSE);
74
75         if (mimeinfo->privacy != NULL) {
76                 PrivacySystem *system = mimeinfo->privacy->system;
77
78                 if (system->is_signed != NULL)
79                         return system->is_signed(mimeinfo);
80                 else
81                         return FALSE;
82         }
83
84         for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
85                 PrivacySystem *system = (PrivacySystem *) cur->data;
86
87                 if(system->is_signed != NULL && system->is_signed(mimeinfo))
88                         return TRUE;
89         }
90
91         return FALSE;
92 }
93
94 /**
95  * Check the signature of a MimeInfo. privacy_mimeinfo_is_signed
96  * should be called before otherwise it is done by this function.
97  * If the MimeInfo is not signed an error code will be returned.
98  *
99  * \return Error code indicating the result of the check,
100  *         < 0 if an error occured
101  */
102 gint privacy_mimeinfo_check_signature(MimeInfo *mimeinfo)
103 {
104         PrivacySystem *system;
105
106         g_return_val_if_fail(mimeinfo != NULL, -1);
107
108         if (mimeinfo->privacy == NULL)
109                 privacy_mimeinfo_is_signed(mimeinfo);
110         
111         if (mimeinfo->privacy == NULL)
112                 return -1;
113         
114         system = mimeinfo->privacy->system;
115         if (system->check_signature == NULL)
116                 return -1;
117         
118         return system->check_signature(mimeinfo);
119 }
120
121 SignatureStatus privacy_mimeinfo_get_sig_status(MimeInfo *mimeinfo)
122 {
123         PrivacySystem *system;
124
125         g_return_val_if_fail(mimeinfo != NULL, -1);
126
127         if (mimeinfo->privacy == NULL)
128                 privacy_mimeinfo_is_signed(mimeinfo);
129         
130         if (mimeinfo->privacy == NULL)
131                 return SIGNATURE_UNCHECKED;
132         
133         system = mimeinfo->privacy->system;
134         if (system->get_sig_status == NULL)
135                 return SIGNATURE_UNCHECKED;
136         
137         return system->get_sig_status(mimeinfo);
138 }
139
140 gchar *privacy_mimeinfo_sig_info_short(MimeInfo *mimeinfo)
141 {
142         PrivacySystem *system;
143
144         g_return_val_if_fail(mimeinfo != NULL, NULL);
145
146         if (mimeinfo->privacy == NULL)
147                 privacy_mimeinfo_is_signed(mimeinfo);
148         
149         if (mimeinfo->privacy == NULL)
150                 return g_strdup(_("No signature found"));
151         
152         system = mimeinfo->privacy->system;
153         if (system->get_sig_info_short == NULL)
154                 return g_strdup(_("No information available"));
155         
156         return system->get_sig_info_short(mimeinfo);
157 }
158
159 gchar *privacy_mimeinfo_sig_info_full(MimeInfo *mimeinfo)
160 {
161         PrivacySystem *system;
162
163         g_return_val_if_fail(mimeinfo != NULL, NULL);
164
165         if (mimeinfo->privacy == NULL)
166                 privacy_mimeinfo_is_signed(mimeinfo);
167         
168         if (mimeinfo->privacy == NULL)
169                 return g_strdup(_("No signature found"));
170         
171         system = mimeinfo->privacy->system;
172         if (system->get_sig_info_full == NULL)
173                 return g_strdup(_("No information available"));
174         
175         return system->get_sig_info_full(mimeinfo);
176 }
177
178 gboolean privacy_mimeinfo_is_encrypted(MimeInfo *mimeinfo)
179 {
180         GSList *cur;
181         g_return_val_if_fail(mimeinfo != NULL, FALSE);
182
183         for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
184                 PrivacySystem *system = (PrivacySystem *) cur->data;
185
186                 if(system->is_encrypted != NULL && system->is_encrypted(mimeinfo))
187                         return TRUE;
188         }
189
190         return FALSE;
191 }
192
193 static gint decrypt(MimeInfo *mimeinfo, PrivacySystem *system)
194 {
195         MimeInfo *decryptedinfo, *parentinfo;
196         gint childnumber;
197         
198         g_return_val_if_fail(system->decrypt != NULL, -1);
199         
200         decryptedinfo = system->decrypt(mimeinfo);
201         if (decryptedinfo == NULL)
202                 return -1;
203
204         parentinfo = procmime_mimeinfo_parent(mimeinfo);
205         childnumber = g_node_child_index(parentinfo->node, mimeinfo);
206         
207         procmime_mimeinfo_free_all(mimeinfo);
208
209         g_node_insert(parentinfo->node, childnumber, decryptedinfo->node);
210
211         return 0;
212 }
213
214 gint privacy_mimeinfo_decrypt(MimeInfo *mimeinfo)
215 {
216         GSList *cur;
217         g_return_val_if_fail(mimeinfo != NULL, FALSE);
218
219         for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
220                 PrivacySystem *system = (PrivacySystem *) cur->data;
221
222                 if(system->is_encrypted != NULL && system->is_encrypted(mimeinfo))
223                         return decrypt(mimeinfo, system);
224         }
225
226         return -1;
227 }
228
229 GSList *privacy_get_system_ids()
230 {
231         GSList *cur;
232         GSList *ret = NULL;
233
234         for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
235                 PrivacySystem *system = (PrivacySystem *) cur->data;
236
237                 ret = g_slist_append(ret, g_strdup(system->id));
238         }
239
240         return ret;
241 }
242
243 static PrivacySystem *privacy_get_system(const gchar *id)
244 {
245         GSList *cur;
246
247         g_return_val_if_fail(id != NULL, NULL);
248
249         for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
250                 PrivacySystem *system = (PrivacySystem *) cur->data;
251
252                 if(strcmp(id, system->id) == 0)
253                         return system;
254         }
255
256         return NULL;
257 }
258
259 const gchar *privacy_system_get_name(const gchar *id)
260 {
261         PrivacySystem *system;
262
263         g_return_val_if_fail(id != NULL, NULL);
264
265         system = privacy_get_system(id);
266         if (system == NULL)
267                 return NULL;
268
269         return system->name;
270 }
271
272 gboolean privacy_system_can_sign(const gchar *id)
273 {
274         PrivacySystem *system;
275
276         g_return_val_if_fail(id != NULL, FALSE);
277
278         system = privacy_get_system(id);
279         if (system == NULL)
280                 return FALSE;
281
282         return system->can_sign;
283 }
284
285 gboolean privacy_system_can_encrypt(const gchar *id)
286 {
287         PrivacySystem *system;
288
289         g_return_val_if_fail(id != NULL, FALSE);
290
291         system = privacy_get_system(id);
292         if (system == NULL)
293                 return FALSE;
294
295         return system->can_encrypt;
296 }
297
298 gboolean privacy_sign(const gchar *id, MimeInfo *target, PrefsAccount *account)
299 {
300         PrivacySystem *system;
301
302         g_return_val_if_fail(id != NULL, FALSE);
303         g_return_val_if_fail(target != NULL, FALSE);
304
305         system = privacy_get_system(id);
306         if (system == NULL)
307                 return FALSE;
308         if (!system->can_sign)
309                 return FALSE;
310         if (system->sign == NULL)
311                 return FALSE;
312
313         return system->sign(target, account);
314 }
315
316 gchar *privacy_get_encrypt_data(const gchar *id, GSList *recp_names)
317 {
318         PrivacySystem *system;
319
320         g_return_val_if_fail(id != NULL, NULL);
321         g_return_val_if_fail(recp_names != NULL, NULL);
322
323         system = privacy_get_system(id);
324         if (system == NULL)
325                 return NULL;
326         if (!system->can_encrypt)
327                 return NULL;
328         if (system->get_encrypt_data == NULL)
329                 return NULL;
330
331         return system->get_encrypt_data(recp_names);
332 }
333
334 gboolean privacy_encrypt(const gchar *id, MimeInfo *mimeinfo, const gchar *encdata)
335 {
336         PrivacySystem *system;
337
338         g_return_val_if_fail(id != NULL, FALSE);
339         g_return_val_if_fail(mimeinfo != NULL, FALSE);
340         g_return_val_if_fail(encdata != NULL, FALSE);
341
342         system = privacy_get_system(id);
343         if (system == NULL)
344                 return FALSE;
345         if (!system->can_encrypt)
346                 return FALSE;
347         if (system->encrypt == NULL)
348                 return FALSE;
349
350         return system->encrypt(mimeinfo, encdata);
351 }