libpurple/keyring.c

branch
soc.2008.masterpassword
changeset 33973
b193c0e9044b
parent 33972
b55f819a1239
child 33976
ff88d1340abe
equal deleted inserted replaced
33972:b55f819a1239 33973:b193c0e9044b
29 * - wrappers that will call the plugin 29 * - wrappers that will call the plugin
30 * - keyring managment stuff 30 * - keyring managment stuff
31 * - accessors 31 * - accessors
32 * 32 *
33 * TODO : 33 * TODO :
34 * - unregister
34 * - use accessors 35 * - use accessors
35 * - purple_keyring_init() 36 * - purple_keyring_init()
36 * - purple_keyring_set_inuse() needs to be async for error checking an reversability. 37 * - purple_keyring_set_inuse() needs to be async for error checking an reversability.
37 * 38 *
38 * Questions : 39 * Questions :
76 /*******************************/ 77 /*******************************/
77 78
78 /* manipulate keyring list, used by config interface */ 79 /* manipulate keyring list, used by config interface */
79 80
80 const GList * 81 const GList *
81 purple_keyring_get_keyringlist(void) 82 purple_keyring_get_keyringlist()
82 { 83 {
83 return purple_keyring_keyringlist; 84 return purple_keyring_keyringlist;
84 } 85 }
85 86
86 const PurpleKeyring * 87 const PurpleKeyring *
87 purple_keyring_get_inuse(void) 88 purple_keyring_get_inuse()
88 { 89 {
89 return purple_keyring_inuse; 90 return purple_keyring_inuse;
90 } 91 }
91 92
92 93
93 //typedef void (*PurpleKeyringSaveCallback)(const PurpleAccount * account, GError ** error, gpointer data); 94 /**
95 * If reading fails, export empty, issue warning, continue
96 * If writing fails, abort.
97 */
98 struct _PurpleKeyringChangeTracker
99 {
100 GError ** error; // could probably be dropped
101 PurpleKeyringSetInUseCb cb;
102 gpointer data;
103 PurpleKeyring * new;
104 PurpleKeyring * old; // we are done when : finished == TRUE && read_outstanding == 0
105 int read_outstanding;
106 gboolean finished;
107 gboolean abort;
108 };
109
94 void 110 void
95 purple_keyring_set_inuse_check_error_cb(const PurpleAccount * account, 111 purple_keyring_set_inuse_check_error_cb(const PurpleAccount * account,
96 GError ** error, 112 GError ** error,
97 gpointer data) 113 gpointer data)
98 { 114 {
99 115
100 const char * name; 116 const char * name;
117 PurpleKeyringClose close;
118 struct _PurpleKeyringChangeTracker * tracker;
119
120 tracker = (struct _PurpleKeyringChangeTracker *)data;
101 121
102 name = purple_account_get_username(account); 122 name = purple_account_get_username(account);
103 123
104 if ((error != NULL) && ((**error).domain == ERR_PIDGINKEYRING)) { 124 if ((error != NULL) && ((**error).domain == ERR_PIDGINKEYRING)) {
105 125
112 case ERR_NOACCOUNT : 132 case ERR_NOACCOUNT :
113 g_debug("No info on account %s found while changing keyring", name); 133 g_debug("No info on account %s found while changing keyring", name);
114 break; 134 break;
115 135
116 case ERR_NOCHANNEL : 136 case ERR_NOCHANNEL :
117 g_debug("Failed to communicate with backend while changing keyring for account %s", name); 137 g_debug("Failed to communicate with backend while changing keyring for account %s, aborting change.", name);
138 tracker->abort == TRUE;
118 break; 139 break;
119 /* FIXME : this should somehow abort the whole procedure */
120 140
121 default : 141 default :
142 // FIXME : display error string
122 g_debug("Unknown error while changing keyring for account %s", name); 143 g_debug("Unknown error while changing keyring for account %s", name);
123 break; 144 break;
124 } 145 }
125 } 146 }
126 147
127 return; 148 /* if this was the last one */
128 } 149 if (tracker->finished == TRUE) && (tracker->read_outstanding == 0)) {
129 150
130 //typedef void (*PurpleKeyringReadCallback)(const PurpleAccount * account, gchar * password, GError * error, gpointer data); 151 if (tracker->abort == TRUE) {
152
153 tracker->abort = TRUE;
154
155 close = purple_keyring_get_close_keyring(tracker->old);
156 close(error);
157
158 g_free(tracker);
159 return;
160 } else {
161 close = purple_keyring_get_close_keyring(tracker->new);
162 close(error);
163
164 tracker->cb(TRUE, error, tracker->data);
165 g_free(tracker);
166 return;
167 }
168
169 }
170 return;
171 }
172
173
131 void 174 void
132 purple_keyring_set_inuse_got_pw_cb(const PurpleAccount * account, 175 purple_keyring_set_inuse_got_pw_cb(const PurpleAccount * account,
133 gchar * password, 176 gchar * password,
134 GError ** error, 177 GError ** error,
135 gpointer data) 178 gpointer data)
136 { 179 {
137 PurpleKeyring * new; 180 PurpleKeyring * new;
138 PurpleKeyringSave save; 181 PurpleKeyringSave save;
139 new = (PurpleKeyring *)data; 182 struct _PurpleKeyringChangeTracker * tracker;
183
184
185 tracker = (struct _PurpleKeyringChangeTracker *)data;
186 new = tracker->new;
187
140 /* XXX check for read error or just forward ? */ 188 /* XXX check for read error or just forward ? */
141 189
142 /* XXX change to use accessor */ 190 tracker->read_outstanding--;
143 191
144 //typedef void (*PurpleKeyringSave)(const PurpleAccount * account, gchar * password, GError ** error, PurpleKeyringSaveCallback cb, gpointer data);
145
146 save = purple_keyring_get_save_password(new); 192 save = purple_keyring_get_save_password(new);
147 save(account, password, error, purple_keyring_set_inuse_check_error_cb, 193 save(account, password, error, purple_keyring_set_inuse_check_error_cb,
148 NULL); 194 tracker);
149 195
150 return; 196 return;
151 } 197 }
152 198
153 /* FIXME : needs to be async and cancelable */ 199 /* FIXME : needs to be async and cancelable */
200 /* PurpleKeyringSetInUseCb */
154 void 201 void
155 purple_keyring_set_inuse(PurpleKeyring * new, 202 purple_keyring_set_inuse(PurpleKeyring * new,
156 GError ** error) 203 GError ** error,
204 PurpleKeyringSetInUseCb cb,
205 gpointer data)
157 { 206 {
158 207
159 GList * cur; 208 GList * cur;
160 const PurpleKeyring * old; 209 const PurpleKeyring * old;
161 PurpleKeyringClose close;
162 PurpleKeyringRead read; 210 PurpleKeyringRead read;
211 struct _PurpleKeyringChangeTracker * tracker;
212
163 213
164 if (purple_keyring_inuse != NULL) { 214 if (purple_keyring_inuse != NULL) {
165 215
216 tracker = g_malloc(sizeof(struct _PurpleKeyringChangeTracker));
166 old = purple_keyring_get_inuse(); 217 old = purple_keyring_get_inuse();
167 218
168 for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next) 219 tracker->error = error;
220 tracker->cb = cb;
221 tracker->data = data;
222 tracker->new = new;
223 tracker->old = old;
224 tracker->read_outstanding = 0;
225 tracker->finished = FALSE;
226 tracker->abort = FALSE;
227
228 for (cur = purple_accounts_get_all();
229 (cur != NULL) && (tracker->abort != TRUE);
230 cur = cur->next)
169 { 231 {
232 tracker->read_outstanding++;
233
234 if (cur->next == NULL) {
235 tracker->finished = TRUE;
236 }
237
170 read = purple_keyring_get_read_password(old); 238 read = purple_keyring_get_read_password(old);
171 read(cur->data, NULL, purple_keyring_set_inuse_got_pw_cb, (void*)new); 239 read(cur->data, error, purple_keyring_set_inuse_got_pw_cb, tracker);
172 } 240 }
173 241
174 /* FIXME : 242 } else { /* no keyring was set before. */
175 * What happens if safe is closed before passwords have been successfully stored ? 243
176 */ 244 purple_keyring_inuse = new;
177 245 cb(data);
178 close = purple_keyring_get_close_keyring(old); 246 return;
179 close(error); /* should automatically free all passwords */ 247 }
180 }
181
182 purple_keyring_inuse = new;
183 return;
184 } 248 }
185 249
186 /* register a keyring plugin */ 250 /* register a keyring plugin */
187 /** 251 /**
188 * XXX : function to unregister a keyring ? 252 * XXX : function to unregister a keyring ?
232 * returned data must be g_free()'d 296 * returned data must be g_free()'d
233 */ 297 */
234 void 298 void
235 purple_keyring_export_password(PurpleAccount * account, 299 purple_keyring_export_password(PurpleAccount * account,
236 GError ** error, 300 GError ** error,
237 PurpleKeyringImportCallback cb, 301 PurpleKeyringExportCallback cb,
238 gpointer data) 302 gpointer data)
239 { 303 {
240 PurpleKeyringExportPassword export; 304 PurpleKeyringExportPassword export;
241 305
242 if (purple_keyring_inuse == NULL) { 306 if (purple_keyring_inuse == NULL) {
243 307
244 g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING, 308 g_set_error(error, ERR_PIDGINKEYRING, ERR_NOKEYRING,
245 "No Keyring configured."); 309 "No Keyring configured.");
246 cb(error, data); 310 cb(NULL, error, data);
247 311
248 } else { 312 } else {
249 export = purple_keyring_get_export_password(purple_keyring_inuse); 313 export = purple_keyring_get_export_password(purple_keyring_inuse);
250 export(account, error, cb, data); 314 export(account, error, cb, data);
251 } 315 }
412 476
413 477
414 /* PurpleKeyringPasswordNode */ 478 /* PurpleKeyringPasswordNode */
415 479
416 PurpleKeyringPasswordNode * 480 PurpleKeyringPasswordNode *
417 purple_keyring_password_node_new(void) 481 purple_keyring_password_node_new()
418 { 482 {
419 PurpleKeyringPasswordNode * ret; 483 PurpleKeyringPasswordNode * ret;
420 484
421 ret = g_malloc(sizeof(PurpleKeyringPasswordNode)); 485 ret = g_malloc(sizeof(PurpleKeyringPasswordNode));
422 return ret; 486 return ret;
485 info->data = data; 549 info->data = data;
486 return; 550 return;
487 } 551 }
488 552
489 GQuark 553 GQuark
490 purple_keyring_error_domain(void) 554 purple_keyring_error_domain()
491 { 555 {
492 return g_quark_from_static_string("Libpurple keyring"); 556 return g_quark_from_static_string("Libpurple keyring");
493 } 557 }
494 558
495 /** 559 /**

mercurial