privacy.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
  3. * Copyright (C) 1999-2006 Hiroyuki Yamamoto & the Claws Mail 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. #include <glib.h>
  20. #include <glib/gi18n.h>
  21. #include "privacy.h"
  22. #include "procmime.h"
  23. static GSList *systems = NULL;
  24. static gchar *privacy_last_error = NULL;
  25. void privacy_set_error(const gchar *format, ...)
  26. {
  27. va_list args;
  28. gchar buf[BUFSIZ];
  29. va_start(args, format);
  30. g_vsnprintf(buf, BUFSIZ, format, args);
  31. va_end(args);
  32. g_free(privacy_last_error);
  33. privacy_last_error = g_strdup(buf);
  34. }
  35. static gchar tmp_privacy_error[BUFSIZ];
  36. void privacy_reset_error(void)
  37. {
  38. g_free(privacy_last_error);
  39. privacy_last_error = NULL;
  40. }
  41. gboolean privacy_peek_error(void)
  42. {
  43. return (privacy_last_error != NULL);
  44. }
  45. const gchar *privacy_get_error (void)
  46. {
  47. if (privacy_last_error) {
  48. strncpy2(tmp_privacy_error, privacy_last_error, BUFSIZ-1);
  49. privacy_reset_error();
  50. return tmp_privacy_error;
  51. } else {
  52. return _("Unknown error");
  53. }
  54. }
  55. PrivacySystem *privacy_data_get_system(PrivacyData *data)
  56. {
  57. /* Make sure the cached system is still registered */
  58. if (data->system && g_slist_find(systems, data->system))
  59. return data->system;
  60. else
  61. return NULL;
  62. }
  63. /**
  64. * Register a new Privacy System
  65. *
  66. * \param system The Privacy System that should be registered
  67. */
  68. void privacy_register_system(PrivacySystem *system)
  69. {
  70. systems = g_slist_append(systems, system);
  71. }
  72. /**
  73. * Unregister a new Privacy System. The system must not be in
  74. * use anymore when it is unregistered.
  75. *
  76. * \param system The Privacy System that should be unregistered
  77. */
  78. void privacy_unregister_system(PrivacySystem *system)
  79. {
  80. systems = g_slist_remove(systems, system);
  81. }
  82. /**
  83. * Free a PrivacyData of a PrivacySystem
  84. *
  85. * \param privacydata The data to free
  86. */
  87. void privacy_free_privacydata(PrivacyData *privacydata)
  88. {
  89. PrivacySystem *system = NULL;
  90. g_return_if_fail(privacydata != NULL);
  91. system = privacy_data_get_system(privacydata);
  92. if (!system)
  93. return;
  94. system->free_privacydata(privacydata);
  95. }
  96. /**
  97. * Check if a MimeInfo is signed with one of the available
  98. * privacy system. If a privacydata is set in the MimeInfo
  99. * it will directory return the return value by the system
  100. * set in the privacy data or check all available privacy
  101. * systems otherwise.
  102. *
  103. * \return True if the MimeInfo has a signature
  104. */
  105. gboolean privacy_mimeinfo_is_signed(MimeInfo *mimeinfo)
  106. {
  107. GSList *cur;
  108. g_return_val_if_fail(mimeinfo != NULL, FALSE);
  109. if (mimeinfo->privacy != NULL) {
  110. PrivacySystem *system =
  111. privacy_data_get_system(mimeinfo->privacy);
  112. if (system == NULL) {
  113. mimeinfo->privacy = NULL;
  114. goto try_others;
  115. }
  116. if (system->is_signed != NULL)
  117. return system->is_signed(mimeinfo);
  118. else
  119. return FALSE;
  120. }
  121. try_others:
  122. for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
  123. PrivacySystem *system = (PrivacySystem *) cur->data;
  124. if(system->is_signed != NULL && system->is_signed(mimeinfo))
  125. return TRUE;
  126. }
  127. return FALSE;
  128. }
  129. /**
  130. * Check the signature of a MimeInfo. privacy_mimeinfo_is_signed
  131. * should be called before otherwise it is done by this function.
  132. * If the MimeInfo is not signed an error code will be returned.
  133. *
  134. * \return Error code indicating the result of the check,
  135. * < 0 if an error occured
  136. */
  137. gint privacy_mimeinfo_check_signature(MimeInfo *mimeinfo)
  138. {
  139. PrivacySystem *system;
  140. g_return_val_if_fail(mimeinfo != NULL, -1);
  141. if (mimeinfo->privacy == NULL)
  142. privacy_mimeinfo_is_signed(mimeinfo);
  143. if (mimeinfo->privacy == NULL)
  144. return -1;
  145. system = privacy_data_get_system(mimeinfo->privacy);
  146. if (system == NULL)
  147. return -1;
  148. if (system->check_signature == NULL)
  149. return -1;
  150. return system->check_signature(mimeinfo);
  151. }
  152. SignatureStatus privacy_mimeinfo_get_sig_status(MimeInfo *mimeinfo)
  153. {
  154. PrivacySystem *system;
  155. g_return_val_if_fail(mimeinfo != NULL, -1);
  156. if (mimeinfo->privacy == NULL)
  157. privacy_mimeinfo_is_signed(mimeinfo);
  158. if (mimeinfo->privacy == NULL)
  159. return SIGNATURE_UNCHECKED;
  160. system = privacy_data_get_system(mimeinfo->privacy);
  161. if (system == NULL)
  162. return SIGNATURE_UNCHECKED;
  163. if (system->get_sig_status == NULL)
  164. return SIGNATURE_UNCHECKED;
  165. return system->get_sig_status(mimeinfo);
  166. }
  167. gchar *privacy_mimeinfo_sig_info_short(MimeInfo *mimeinfo)
  168. {
  169. PrivacySystem *system;
  170. g_return_val_if_fail(mimeinfo != NULL, NULL);
  171. if (mimeinfo->privacy == NULL)
  172. privacy_mimeinfo_is_signed(mimeinfo);
  173. if (mimeinfo->privacy == NULL)
  174. return g_strdup(_("No signature found"));
  175. system = privacy_data_get_system(mimeinfo->privacy);
  176. if (system == NULL)
  177. return g_strdup(_("No signature found"));
  178. if (system->get_sig_info_short == NULL)
  179. return g_strdup(_("No information available"));
  180. return system->get_sig_info_short(mimeinfo);
  181. }
  182. gchar *privacy_mimeinfo_sig_info_full(MimeInfo *mimeinfo)
  183. {
  184. PrivacySystem *system;
  185. g_return_val_if_fail(mimeinfo != NULL, NULL);
  186. if (mimeinfo->privacy == NULL)
  187. privacy_mimeinfo_is_signed(mimeinfo);
  188. if (mimeinfo->privacy == NULL)
  189. return g_strdup(_("No signature found"));
  190. system = privacy_data_get_system(mimeinfo->privacy);
  191. if (system == NULL)
  192. return g_strdup(_("No signature found"));
  193. if (system->get_sig_info_full == NULL)
  194. return g_strdup(_("No information available"));
  195. return system->get_sig_info_full(mimeinfo);
  196. }
  197. gboolean privacy_mimeinfo_is_encrypted(MimeInfo *mimeinfo)
  198. {
  199. GSList *cur;
  200. g_return_val_if_fail(mimeinfo != NULL, FALSE);
  201. for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
  202. PrivacySystem *system = (PrivacySystem *) cur->data;
  203. if(system->is_encrypted != NULL && system->is_encrypted(mimeinfo))
  204. return TRUE;
  205. }
  206. return FALSE;
  207. }
  208. static gint decrypt(MimeInfo *mimeinfo, PrivacySystem *system)
  209. {
  210. MimeInfo *decryptedinfo, *parentinfo;
  211. gint childnumber;
  212. g_return_val_if_fail(system->decrypt != NULL, -1);
  213. decryptedinfo = system->decrypt(mimeinfo);
  214. if (decryptedinfo == NULL)
  215. return -1;
  216. parentinfo = procmime_mimeinfo_parent(mimeinfo);
  217. childnumber = g_node_child_index(parentinfo->node, mimeinfo);
  218. procmime_mimeinfo_free_all(mimeinfo);
  219. g_node_insert(parentinfo->node, childnumber, decryptedinfo->node);
  220. return 0;
  221. }
  222. gint privacy_mimeinfo_decrypt(MimeInfo *mimeinfo)
  223. {
  224. GSList *cur;
  225. g_return_val_if_fail(mimeinfo != NULL, FALSE);
  226. for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
  227. PrivacySystem *system = (PrivacySystem *) cur->data;
  228. if(system->is_encrypted != NULL && system->is_encrypted(mimeinfo))
  229. return decrypt(mimeinfo, system);
  230. }
  231. return -1;
  232. }
  233. GSList *privacy_get_system_ids()
  234. {
  235. GSList *cur;
  236. GSList *ret = NULL;
  237. for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
  238. PrivacySystem *system = (PrivacySystem *) cur->data;
  239. ret = g_slist_append(ret, g_strdup(system->id));
  240. }
  241. return ret;
  242. }
  243. static PrivacySystem *privacy_get_system(const gchar *id)
  244. {
  245. GSList *cur;
  246. g_return_val_if_fail(id != NULL, NULL);
  247. for(cur = systems; cur != NULL; cur = g_slist_next(cur)) {
  248. PrivacySystem *system = (PrivacySystem *) cur->data;
  249. if(strcmp(id, system->id) == 0)
  250. return system;
  251. }
  252. return NULL;
  253. }
  254. const gchar *privacy_system_get_name(const gchar *id)
  255. {
  256. PrivacySystem *system;
  257. g_return_val_if_fail(id != NULL, NULL);
  258. system = privacy_get_system(id);
  259. if (system == NULL)
  260. return NULL;
  261. return system->name;
  262. }
  263. gboolean privacy_system_can_sign(const gchar *id)
  264. {
  265. PrivacySystem *system;
  266. g_return_val_if_fail(id != NULL, FALSE);
  267. system = privacy_get_system(id);
  268. if (system == NULL)
  269. return FALSE;
  270. return system->can_sign;
  271. }
  272. gboolean privacy_system_can_encrypt(const gchar *id)
  273. {
  274. PrivacySystem *system;
  275. g_return_val_if_fail(id != NULL, FALSE);
  276. system = privacy_get_system(id);
  277. if (system == NULL)
  278. return FALSE;
  279. return system->can_encrypt;
  280. }
  281. gboolean privacy_sign(const gchar *id, MimeInfo *target, PrefsAccount *account)
  282. {
  283. PrivacySystem *system;
  284. g_return_val_if_fail(id != NULL, FALSE);
  285. g_return_val_if_fail(target != NULL, FALSE);
  286. system = privacy_get_system(id);
  287. if (system == NULL)
  288. return FALSE;
  289. if (!system->can_sign)
  290. return FALSE;
  291. if (system->sign == NULL)
  292. return FALSE;
  293. return system->sign(target, account);
  294. }
  295. gchar *privacy_get_encrypt_data(const gchar *id, GSList *recp_names)
  296. {
  297. PrivacySystem *system;
  298. g_return_val_if_fail(id != NULL, NULL);
  299. g_return_val_if_fail(recp_names != NULL, NULL);
  300. system = privacy_get_system(id);
  301. if (system == NULL)
  302. return NULL;
  303. if (!system->can_encrypt)
  304. return NULL;
  305. if (system->get_encrypt_data == NULL)
  306. return NULL;
  307. return system->get_encrypt_data(recp_names);
  308. }
  309. gboolean privacy_encrypt(const gchar *id, MimeInfo *mimeinfo, const gchar *encdata)
  310. {
  311. PrivacySystem *system;
  312. g_return_val_if_fail(id != NULL, FALSE);
  313. g_return_val_if_fail(mimeinfo != NULL, FALSE);
  314. if (encdata == NULL) {
  315. privacy_set_error(_("No recipient keys defined."));
  316. return FALSE;
  317. }
  318. system = privacy_get_system(id);
  319. if (system == NULL)
  320. return FALSE;
  321. if (!system->can_encrypt)
  322. return FALSE;
  323. if (system->encrypt == NULL)
  324. return FALSE;
  325. return system->encrypt(mimeinfo, encdata);
  326. }