libpurple/plugins/keyrings/internalkeyring.c

branch
soc.2008.masterpassword
changeset 34128
0cbd558ab5e7
parent 34127
51c1bce7f52f
child 34129
52b91b4b8314
equal deleted inserted replaced
34127:51c1bce7f52f 34128:0cbd558ab5e7
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details. 23 * GNU General Public License for more details.
24 * 24 *
25 * You should have received a copy of the GNU General Public License 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 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 27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
28 */ 28 */
29 29
30 #include "internal.h" 30 #include "internal.h"
31 #include "account.h" 31 #include "account.h"
32 #include "debug.h" 32 #include "debug.h"
33 #include "keyring.h" 33 #include "keyring.h"
34 #include "plugin.h" 34 #include "plugin.h"
35 #include "version.h" 35 #include "version.h"
36 36
37 #define INTERNALKEYRING_NAME N_("Internal keyring") 37 #define INTERNALKEYRING_NAME N_("Internal keyring")
38 #define INTERNALKEYRING_DESCRIPTION N_("This plugin provides the default password storage behaviour for libpurple. Password will be stored unencrypted.") 38 #define INTERNALKEYRING_DESCRIPTION N_("This plugin provides the default" \
39 " password storage behaviour for libpurple. Password will be stored" \
40 " unencrypted.")
39 #define INTERNALKEYRING_AUTHOR "Scrouaf (scrouaf[at]soc.pidgin.im)" 41 #define INTERNALKEYRING_AUTHOR "Scrouaf (scrouaf[at]soc.pidgin.im)"
40 #define INTERNALKEYRING_ID PURPLE_DEFAULT_KEYRING 42 #define INTERNALKEYRING_ID PURPLE_DEFAULT_KEYRING
41 43
42 #define ACTIVATE() \ 44 static gboolean internal_keyring_opened = FALSE;
43 if (internal_keyring_passwords == NULL) \
44 internal_keyring_open();
45
46 static GHashTable *internal_keyring_passwords = NULL; 45 static GHashTable *internal_keyring_passwords = NULL;
47 static PurpleKeyring *keyring_handler = NULL; 46 static PurpleKeyring *keyring_handler = NULL;
48 47
49 /***********************************************/ 48 /***********************************************/
50 /* Keyring interface */ 49 /* Keyring interface */
51 /***********************************************/ 50 /***********************************************/
51
52 static void 52 static void
53 internal_keyring_open(void) 53 internal_keyring_open(void)
54 { 54 {
55 if (internal_keyring_opened)
56 return;
57 internal_keyring_opened = TRUE;
58
55 internal_keyring_passwords = g_hash_table_new_full(g_direct_hash, 59 internal_keyring_passwords = g_hash_table_new_full(g_direct_hash,
56 g_direct_equal, NULL, g_free); 60 g_direct_equal, NULL, g_free);
57 } 61 }
58 62
59 static void 63 static void
60 internal_keyring_read(PurpleAccount *account, 64 internal_keyring_read(PurpleAccount *account, PurpleKeyringReadCallback cb,
61 PurpleKeyringReadCallback cb, 65 gpointer data)
62 gpointer data)
63 { 66 {
64 const char *password; 67 const char *password;
65 GError *error; 68 GError *error;
66 69
67 ACTIVATE(); 70 internal_keyring_open();
68 71
69 password = g_hash_table_lookup(internal_keyring_passwords, account); 72 password = g_hash_table_lookup(internal_keyring_passwords, account);
70 73
71 if (password != NULL) { 74 if (password != NULL) {
72 purple_debug_misc("keyring-internal", 75 purple_debug_misc("keyring-internal",
87 g_error_free(error); 90 g_error_free(error);
88 } 91 }
89 } 92 }
90 93
91 static void 94 static void
92 internal_keyring_save(PurpleAccount *account, 95 internal_keyring_save(PurpleAccount *account, const gchar *password,
93 const gchar *password, 96 PurpleKeyringSaveCallback cb, gpointer data)
94 PurpleKeyringSaveCallback cb, 97 {
95 gpointer data) 98 internal_keyring_open();
96 {
97 ACTIVATE();
98
99 if (password[0] == '\0')
100 password = NULL;
101 99
102 if (password == NULL) 100 if (password == NULL)
103 g_hash_table_remove(internal_keyring_passwords, account); 101 g_hash_table_remove(internal_keyring_passwords, account);
104 else 102 else {
105 g_hash_table_replace(internal_keyring_passwords, account, g_strdup(password)); 103 g_hash_table_replace(internal_keyring_passwords, account,
104 g_strdup(password));
105 }
106 106
107 purple_debug_misc("keyring-internal", 107 purple_debug_misc("keyring-internal",
108 "Password %s for account %s (%s).\n", 108 "Password %s for account %s (%s).\n",
109 (password == NULL ? "removed" : "saved"), 109 (password == NULL ? "removed" : "saved"),
110 purple_account_get_username(account), 110 purple_account_get_username(account),
112 112
113 if (cb != NULL) 113 if (cb != NULL)
114 cb(account, NULL, data); 114 cb(account, NULL, data);
115 } 115 }
116 116
117
118 static void 117 static void
119 internal_keyring_close(GError **error) 118 internal_keyring_close(GError **error)
120 { 119 {
121 if (internal_keyring_passwords) 120 if (!internal_keyring_opened)
122 g_hash_table_destroy(internal_keyring_passwords); 121 return;
122 internal_keyring_opened = FALSE;
123
124 g_hash_table_destroy(internal_keyring_passwords);
123 internal_keyring_passwords = NULL; 125 internal_keyring_passwords = NULL;
124 } 126 }
125 127
126 static gboolean 128 static gboolean
127 internal_keyring_import_password(PurpleAccount *account, 129 internal_keyring_import_password(PurpleAccount *account, const char *mode,
128 const char *mode, 130 const char *data, GError **error)
129 const char *data, 131 {
130 GError **error) 132 g_return_val_if_fail(account != NULL, FALSE);
131 { 133 g_return_val_if_fail(data != NULL, FALSE);
132 g_return_if_fail(account != NULL); 134
133 g_return_if_fail(data != NULL); 135 internal_keyring_open();
134 136
135 ACTIVATE(); 137 if (mode == NULL)
136 138 mode = "cleartext";
137 if (mode == NULL || g_strcmp0(mode, "cleartext") == 0) { 139
138 g_hash_table_replace(internal_keyring_passwords, account, g_strdup(data)); 140 if (g_strcmp0(mode, "cleartext") == 0) {
141 g_hash_table_replace(internal_keyring_passwords, account,
142 g_strdup(data));
139 return TRUE; 143 return TRUE;
140 } else { 144 } else {
141 if (error != NULL) { 145 if (error != NULL) {
142 *error = g_error_new(PURPLE_KEYRING_ERROR, 146 *error = g_error_new(PURPLE_KEYRING_ERROR,
143 PURPLE_KEYRING_ERROR_WRONGFORMAT, 147 PURPLE_KEYRING_ERROR_WRONGFORMAT,
144 "invalid mode"); 148 "invalid mode");
145 } 149 }
146 return FALSE; 150 return FALSE;
147 } 151 }
148 152 }
149 return TRUE; 153
150 } 154 static gboolean
151 155 internal_keyring_export_password(PurpleAccount *account, const char **mode,
152 static gboolean 156 char **data, GError **error, GDestroyNotify *destroy)
153 internal_keyring_export_password(PurpleAccount *account,
154 const char **mode,
155 char **data,
156 GError **error,
157 GDestroyNotify *destroy)
158 { 157 {
159 gchar *password; 158 gchar *password;
160 159
161 ACTIVATE(); 160 internal_keyring_open();
162 161
163 password = g_hash_table_lookup(internal_keyring_passwords, account); 162 password = g_hash_table_lookup(internal_keyring_passwords, account);
164 163
165 if (password == NULL) { 164 if (password == NULL) {
166 return FALSE; 165 return FALSE;
170 *destroy = g_free; 169 *destroy = g_free;
171 return TRUE; 170 return TRUE;
172 } 171 }
173 } 172 }
174 173
175 static void 174 /***********************************************/
176 internal_keyring_init(void) 175 /* Plugin interface */
176 /***********************************************/
177
178 static gboolean
179 internal_keyring_load(PurplePlugin *plugin)
177 { 180 {
178 keyring_handler = purple_keyring_new(); 181 keyring_handler = purple_keyring_new();
179 182
180 purple_keyring_set_name(keyring_handler, INTERNALKEYRING_NAME); 183 purple_keyring_set_name(keyring_handler, INTERNALKEYRING_NAME);
181 purple_keyring_set_id(keyring_handler, INTERNALKEYRING_ID); 184 purple_keyring_set_id(keyring_handler, INTERNALKEYRING_ID);
182 purple_keyring_set_read_password(keyring_handler, internal_keyring_read); 185 purple_keyring_set_read_password(keyring_handler, internal_keyring_read);
183 purple_keyring_set_save_password(keyring_handler, internal_keyring_save); 186 purple_keyring_set_save_password(keyring_handler, internal_keyring_save);
184 purple_keyring_set_close_keyring(keyring_handler, internal_keyring_close); 187 purple_keyring_set_close_keyring(keyring_handler, internal_keyring_close);
185 purple_keyring_set_change_master(keyring_handler, NULL);
186 purple_keyring_set_import_password(keyring_handler, internal_keyring_import_password); 188 purple_keyring_set_import_password(keyring_handler, internal_keyring_import_password);
187 purple_keyring_set_export_password(keyring_handler, internal_keyring_export_password); 189 purple_keyring_set_export_password(keyring_handler, internal_keyring_export_password);
188 190
189 purple_keyring_register(keyring_handler); 191 purple_keyring_register(keyring_handler);
190 } 192
191 193 return TRUE;
192 static void 194 }
193 internal_keyring_uninit(void) 195
194 { 196 static gboolean
197 internal_keyring_unload(PurplePlugin *plugin)
198 {
199 if (purple_keyring_get_inuse() == keyring_handler) {
200 purple_debug_warning("keyring-internal",
201 "keyring in use, cannot unload\n");
202 return FALSE;
203 }
204
195 internal_keyring_close(NULL); 205 internal_keyring_close(NULL);
206
196 purple_keyring_unregister(keyring_handler); 207 purple_keyring_unregister(keyring_handler);
197
198 }
199
200 /***********************************************/
201 /* Plugin interface */
202 /***********************************************/
203
204 static gboolean
205 internal_keyring_load(PurplePlugin *plugin)
206 {
207 internal_keyring_init();
208 return TRUE;
209 }
210
211 static gboolean
212 internal_keyring_unload(PurplePlugin *plugin)
213 {
214 if (purple_keyring_get_inuse() == keyring_handler)
215 return FALSE;
216
217 internal_keyring_uninit();
218
219 purple_keyring_free(keyring_handler); 208 purple_keyring_free(keyring_handler);
220 keyring_handler = NULL; 209 keyring_handler = NULL;
221 210
222 return TRUE; 211 return TRUE;
223 } 212 }
224 213
225 PurplePluginInfo plugininfo = 214 PurplePluginInfo plugininfo =
226 { 215 {
227 PURPLE_PLUGIN_MAGIC, /* magic */ 216 PURPLE_PLUGIN_MAGIC, /* magic */
228 PURPLE_MAJOR_VERSION, /* major_version */ 217 PURPLE_MAJOR_VERSION, /* major_version */
229 PURPLE_MINOR_VERSION, /* minor_version */ 218 PURPLE_MINOR_VERSION, /* minor_version */
230 PURPLE_PLUGIN_STANDARD, /* type */ 219 PURPLE_PLUGIN_STANDARD, /* type */
231 NULL, /* ui_requirement */ 220 NULL, /* ui_requirement */
232 PURPLE_PLUGIN_FLAG_INVISIBLE, /* flags */ 221 PURPLE_PLUGIN_FLAG_INVISIBLE, /* flags */
233 NULL, /* dependencies */ 222 NULL, /* dependencies */
234 PURPLE_PRIORITY_DEFAULT, /* priority */ 223 PURPLE_PRIORITY_DEFAULT, /* priority */
235 INTERNALKEYRING_ID, /* id */ 224 INTERNALKEYRING_ID, /* id */
236 INTERNALKEYRING_NAME, /* name */ 225 INTERNALKEYRING_NAME, /* name */
237 DISPLAY_VERSION, /* version */ 226 DISPLAY_VERSION, /* version */
238 "Internal Keyring Plugin", /* summary */ 227 "Internal Keyring Plugin", /* summary */
239 INTERNALKEYRING_DESCRIPTION, /* description */ 228 INTERNALKEYRING_DESCRIPTION, /* description */
240 INTERNALKEYRING_AUTHOR, /* author */ 229 INTERNALKEYRING_AUTHOR, /* author */
241 PURPLE_WEBSITE, /* homepage */ 230 PURPLE_WEBSITE, /* homepage */
242 internal_keyring_load, /* load */ 231 internal_keyring_load, /* load */
243 internal_keyring_unload, /* unload */ 232 internal_keyring_unload, /* unload */
244 NULL, /* destroy */ 233 NULL, /* destroy */
245 NULL, /* ui_info */ 234 NULL, /* ui_info */
246 NULL, /* extra_info */ 235 NULL, /* extra_info */
247 NULL, /* prefs_info */ 236 NULL, /* prefs_info */
248 NULL, /* actions */ 237 NULL, /* actions */
249 NULL, /* padding... */ 238 NULL, NULL, NULL, NULL /* padding */
250 NULL,
251 NULL,
252 NULL,
253 }; 239 };
254 240
255 static void 241 static void
256 init_plugin(PurplePlugin *plugin) 242 init_plugin(PurplePlugin *plugin)
257 { 243 {
258 } 244 }
259 245
260 PURPLE_INIT_PLUGIN(internal_keyring, init_plugin, plugininfo) 246 PURPLE_INIT_PLUGIN(internal_keyring, init_plugin, plugininfo)
261

mercurial