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