libpurple/plugins/internalkeyring.c

branch
soc.2008.masterpassword
changeset 33988
4ac83e1786bf
parent 33987
9beebdbf44d6
child 33990
8cef8a764ab9
equal deleted inserted replaced
33987:9beebdbf44d6 33988:4ac83e1786bf
1 /**
2 * @file internalkeyring.c internal keyring
3 * @ingroup plugins
4 *
5 * @todo
6 * cleanup error handling and reporting
7 */
8
9 /* purple
10 *
11 * Purple is the legal property of its developers, whose names are too numerous
12 * to list here. Please refer to the COPYRIGHT file distributed with this
13 * source distribution.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program ; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #ifndef PURPLE_PLUGINS
35 # define PURPLE_PLUGINS
36 #endif
37
38 #include <glib.h>
39
40 #ifndef G_GNUC_NULL_TERMINATED
41 # if __GNUC__ >= 4
42 # define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
43 # else
44 # define G_GNUC_NULL_TERMINATED
45 # endif
46 #endif
47
48 #include "account.h"
49 #include "version.h"
50 #include "keyring.h"
51 #include "debug.h"
52 #include "plugin.h"
53
54 #define INTERNALKEYRING_NAME "Internal keyring"
55 #define INTERNALKEYRING_VERSION "0.7"
56 #define INTERNALKEYRING_DESCRIPTION "This plugin provides the default password storage behaviour for libpurple."
57 #define INTERNALKEYRING_AUTHOR "Scrouaf (scrouaf[at]soc.pidgin.im)"
58 #define INTERNALKEYRING_ID FALLBACK_KEYRING
59
60
61 #define GET_PASSWORD(account) \
62 g_hash_table_lookup (internal_keyring_passwords, account)
63 #define SET_PASSWORD(account, password) \
64 g_hash_table_replace(internal_keyring_passwords, account, password)
65
66
67 GHashTable * internal_keyring_passwords = NULL;
68 static PurpleKeyring * keyring_handler = NULL;
69
70 /* a few prototypes : */
71 static void internal_keyring_read(const PurpleAccount *, PurpleKeyringReadCallback, gpointer);
72 static void internal_keyring_save(const PurpleAccount *, gchar *, GDestroyNotify, PurpleKeyringSaveCallback, gpointer);
73 static const char * internal_keyring_read_sync(const PurpleAccount *);
74 static void internal_keyring_save_sync(PurpleAccount *, const gchar *);
75 static void internal_keyring_close(GError **);
76 static gboolean internal_keyring_import_password(PurpleAccount *, char *, char *, GError **);
77 static gboolean internal_keyring_export_password(PurpleAccount *, const char **, char **, GError **, GDestroyNotify *);
78 static void internal_keyring_init(void);
79 static void internal_keyring_uninit(void);
80 static gboolean internal_keyring_load(PurplePlugin *);
81 static gboolean internal_keyring_unload(PurplePlugin *);
82 static void internal_keyring_destroy(PurplePlugin *);
83
84 /***********************************************/
85 /* Keyring interface */
86 /***********************************************/
87 static void
88 internal_keyring_read(const PurpleAccount * account,
89 PurpleKeyringReadCallback cb,
90 gpointer data)
91 {
92 char * password;
93 GError * error;
94
95 password = GET_PASSWORD(account);
96
97 if (password != NULL) {
98 cb(account, password, NULL, data);
99 } else {
100 error = g_error_new(ERR_PIDGINKEYRING,
101 ERR_NOPASSWD, "password not found");
102 cb(account, NULL, error, data);
103 g_error_free(error);
104 }
105 return;
106 }
107
108 static void
109 internal_keyring_save(const PurpleAccount * account,
110 gchar * password,
111 GDestroyNotify destroy,
112 PurpleKeyringSaveCallback cb,
113 gpointer data)
114 {
115 gchar * copy;
116
117 if (password == NULL) {
118 g_hash_table_remove(internal_keyring_passwords, account);
119 } else {
120 copy = g_strdup(password);
121 SET_PASSWORD((void *)account, copy); /* cast prevents warning because account is const */
122 }
123
124 if(destroy != NULL)
125 destroy(password);
126
127 cb(account, NULL, data);
128 return;
129 }
130
131
132 static const char *
133 internal_keyring_read_sync(const PurpleAccount * account)
134 {
135 purple_debug_info("keyring", "password was read\n");
136 return GET_PASSWORD(account);
137 }
138
139 static void
140 internal_keyring_save_sync(PurpleAccount * account,
141 const char * password)
142 {
143 gchar * copy;
144
145 if (password == NULL) {
146 g_hash_table_remove(internal_keyring_passwords, account);
147 } else {
148 copy = g_strdup(password);
149 SET_PASSWORD(account, copy);
150 }
151 purple_debug_info("keyring", "password was set\n");
152 return;
153 }
154
155 static void
156 internal_keyring_close(GError ** error)
157 {
158 internal_keyring_uninit();
159 }
160
161 static gboolean
162 internal_keyring_import_password(PurpleAccount * account,
163 char * mode,
164 char * data,
165 GError ** error)
166 {
167 gchar * copy;
168
169 if (account != NULL &&
170 data != NULL &&
171 (mode == NULL || g_strcmp0(mode, "cleartext") == 0)) {
172
173 copy = g_strdup(data);
174 SET_PASSWORD(account, copy);
175 return TRUE;
176
177 } else {
178
179 *error = g_error_new(ERR_PIDGINKEYRING, ERR_NOPASSWD, "no password for account");
180 return FALSE;
181
182 }
183 }
184
185 static gboolean
186 internal_keyring_export_password(PurpleAccount * account,
187 const char ** mode,
188 char ** data,
189 GError ** error,
190 GDestroyNotify * destroy)
191 {
192 gchar * password;
193
194 password = GET_PASSWORD(account);
195
196 if (password == NULL) {
197 return FALSE;
198 } else {
199 *mode = "cleartext";
200 *data = g_strdup(password);
201 *destroy = g_free;
202 return TRUE;
203 }
204 }
205
206
207
208
209 static void
210 internal_keyring_init()
211 {
212 keyring_handler = purple_keyring_new();
213
214 purple_keyring_set_name(keyring_handler, INTERNALKEYRING_NAME);
215 purple_keyring_set_id(keyring_handler, INTERNALKEYRING_ID);
216 purple_keyring_set_read_sync(keyring_handler, internal_keyring_read_sync);
217 purple_keyring_set_save_sync(keyring_handler, internal_keyring_save_sync);
218 purple_keyring_set_read_password(keyring_handler, internal_keyring_read);
219 purple_keyring_set_save_password(keyring_handler, internal_keyring_save);
220 purple_keyring_set_close_keyring(keyring_handler, internal_keyring_close);
221 purple_keyring_set_change_master(keyring_handler, NULL);
222 purple_keyring_set_import_password(keyring_handler, internal_keyring_import_password);
223 purple_keyring_set_export_password(keyring_handler, internal_keyring_export_password);
224
225 purple_keyring_register(keyring_handler);
226
227 internal_keyring_passwords = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
228 }
229
230 static void
231 internal_keyring_uninit()
232 {
233 purple_keyring_free(keyring_handler);
234 keyring_handler = NULL;
235
236 g_hash_table_destroy(internal_keyring_passwords);
237 internal_keyring_passwords = NULL;
238 }
239
240
241
242 /***********************************************/
243 /* Plugin interface */
244 /***********************************************/
245
246 static gboolean
247 internal_keyring_load(PurplePlugin *plugin)
248 {
249 internal_keyring_init();
250 return TRUE;
251 }
252
253 static gboolean
254 internal_keyring_unload(PurplePlugin *plugin)
255 {
256 internal_keyring_uninit();
257 return TRUE;
258 }
259
260 static void
261 internal_keyring_destroy(PurplePlugin *plugin)
262 {
263 internal_keyring_uninit();
264 return;
265 }
266
267 PurplePluginInfo plugininfo =
268 {
269 PURPLE_PLUGIN_MAGIC, /* magic */
270 PURPLE_MAJOR_VERSION, /* major_version */
271 PURPLE_MINOR_VERSION, /* minor_version */
272 PURPLE_PLUGIN_STANDARD, /* type */
273 NULL, /* ui_requirement */
274 PURPLE_PLUGIN_FLAG_INVISIBLE|PURPLE_PLUGIN_FLAG_AUTOLOAD, /* flags */
275 NULL, /* dependencies */
276 PURPLE_PRIORITY_DEFAULT, /* priority */
277 INTERNALKEYRING_ID, /* id */
278 INTERNALKEYRING_NAME, /* name */
279 INTERNALKEYRING_VERSION, /* version */
280 "Internal Keyring Plugin", /* summary */
281 INTERNALKEYRING_DESCRIPTION, /* description */
282 INTERNALKEYRING_AUTHOR, /* author */
283 "N/A", /* homepage */
284 internal_keyring_load, /* load */
285 internal_keyring_unload, /* unload */
286 internal_keyring_destroy, /* destroy */
287 NULL, /* ui_info */
288 NULL, /* extra_info */
289 NULL, /* prefs_info */
290 NULL, /* actions */
291 NULL, /* padding... */
292 NULL,
293 NULL,
294 NULL,
295 };
296
297 static void
298 init_plugin(PurplePlugin *plugin)
299 {
300 purple_debug_info("internalkeyring", "init plugin called.\n");
301 }
302
303 PURPLE_INIT_PLUGIN(internal_keyring, init_plugin, plugininfo)
304

mercurial