| 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 |
|