| OLD | NEW |
| 1 /* | 1 /* |
| 2 * | 2 * |
| 3 * Connection Manager | 3 * Connection Manager |
| 4 * | 4 * |
| 5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. | 5 * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. |
| 6 * | 6 * |
| 7 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
| 8 * it under the terms of the GNU General Public License version 2 as | 8 * it under the terms of the GNU General Public License version 2 as |
| 9 * published by the Free Software Foundation. | 9 * published by the Free Software Foundation. |
| 10 * | 10 * |
| 11 * This program is distributed in the hope that it will be useful, | 11 * This program is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 * GNU General Public License for more details. | 14 * GNU General Public License for more details. |
| 15 * | 15 * |
| 16 * You should have received a copy of the GNU General Public License | 16 * You should have received a copy of the GNU General Public License |
| 17 * along with this program; if not, write to the Free Software | 17 * along with this program; if not, write to the Free Software |
| 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 * | 19 * |
| 20 */ | 20 */ |
| 21 | 21 |
| 22 #ifdef HAVE_CONFIG_H | 22 #ifdef HAVE_CONFIG_H |
| 23 #include <config.h> | 23 #include <config.h> |
| 24 #endif | 24 #endif |
| 25 | 25 |
| 26 #include <stdio.h> |
| 26 #include <unistd.h> | 27 #include <unistd.h> |
| 27 | 28 |
| 28 #include "connman.h" | 29 #include "connman.h" |
| 29 | 30 |
| 30 #define _DBG_STORAGE(fmt, arg...) DBG(DBG_STORAGE, fmt, ## arg) | 31 #define _DBG_STORAGE(fmt, arg...) DBG(DBG_STORAGE, fmt, ## arg) |
| 31 | 32 |
| 32 static GSList *storage_list = NULL; | 33 static GSList *storage_list = NULL; |
| 33 | 34 |
| 34 static gint compare_priority(gconstpointer a, gconstpointer b) | 35 static gint compare_priority(gconstpointer a, gconstpointer b) |
| 35 { | 36 { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 64 * Remove a previously registered storage module | 65 * Remove a previously registered storage module |
| 65 */ | 66 */ |
| 66 void connman_storage_unregister(struct connman_storage *storage) | 67 void connman_storage_unregister(struct connman_storage *storage) |
| 67 { | 68 { |
| 68 _DBG_STORAGE("storage %p name %s", storage, storage->name); | 69 _DBG_STORAGE("storage %p name %s", storage, storage->name); |
| 69 | 70 |
| 70 storage_list = g_slist_remove(storage_list, storage); | 71 storage_list = g_slist_remove(storage_list, storage); |
| 71 } | 72 } |
| 72 | 73 |
| 73 void __connman_storage_set_encrypted_value(GKeyFile *keyfile, | 74 void __connman_storage_set_encrypted_value(GKeyFile *keyfile, |
| 74 const char *profile_name, const char *section, const char *key, | 75 const char *section, const char *key, const char *value) |
| 75 const char *value) | |
| 76 { | 76 { |
| 77 char *cryptvalue = __connman_crypto_encrypt_keyvalue( | 77 char *cryptvalue = __connman_crypto_encrypt_keyvalue(key, value); |
| 78 profile_name, key, value); | |
| 79 g_key_file_set_string(keyfile, section, key, cryptvalue); | 78 g_key_file_set_string(keyfile, section, key, cryptvalue); |
| 80 g_free(cryptvalue); | 79 g_free(cryptvalue); |
| 81 } | 80 } |
| 82 | 81 |
| 83 char *__connman_storage_get_encrypted_value(GKeyFile *keyfile, | 82 char *__connman_storage_get_encrypted_value(GKeyFile *keyfile, |
| 84 const char *profile_name, const char *section, const char *key) | 83 const char *section, const char *key) |
| 85 { | 84 { |
| 86 char *ciphertext = g_key_file_get_string(keyfile, section, key, NULL); | 85 char *ciphertext, *plaintext; |
| 86 |
| 87 ciphertext = g_key_file_get_string(keyfile, section, key, NULL); |
| 87 if (ciphertext == NULL) | 88 if (ciphertext == NULL) |
| 88 return NULL; | 89 return NULL; |
| 89 | 90 |
| 90 char *plaintext = __connman_crypto_decrypt_keyvalue( | 91 plaintext = __connman_crypto_decrypt_keyvalue(key, ciphertext); |
| 91 profile_name, key, ciphertext); | |
| 92 g_free(ciphertext); | 92 g_free(ciphertext); |
| 93 | 93 |
| 94 return plaintext; | 94 return plaintext; |
| 95 } | 95 } |
| 96 | 96 |
| 97 GKeyFile *__connman_storage_open(const char *ident) | 97 static const char *__getpath(const struct connman_storage_ident *ident) |
| 98 { |
| 99 » static char path[80]; |
| 100 |
| 101 » if (ident->user != NULL) { |
| 102 » » /* TODO(sleffler) worth using getpwnam & co? */ |
| 103 » » /* TODO(sleffler) at least use #define */ |
| 104 » » snprintf(path, sizeof(path), STORAGE_HOMEDIR "/%s.profile", |
| 105 » » ident->user, ident->ident); |
| 106 » } else { |
| 107 » » snprintf(path, sizeof(path), STORAGEDIR "/%s.profile", |
| 108 » » ident->ident); |
| 109 » } |
| 110 » return path; |
| 111 } |
| 112 |
| 113 static char *getpath(const struct connman_storage_ident *ident) |
| 114 { |
| 115 » if (ident->user != NULL) { |
| 116 » » /* TODO(sleffler) worth using getpwnam & co? */ |
| 117 » » /* TODO(sleffler) at least use #define */ |
| 118 » » return g_strdup_printf(STORAGE_HOMEDIR "/%s.profile", |
| 119 » » ident->user, ident->ident); |
| 120 » } else { |
| 121 » » return g_strdup_printf(STORAGEDIR "/%s.profile", ident->ident); |
| 122 » } |
| 123 } |
| 124 |
| 125 gboolean __connman_storage_exists(const struct connman_storage_ident *ident) |
| 126 { |
| 127 » gchar *pathname, *data = NULL; |
| 128 » gboolean result; |
| 129 » gsize length; |
| 130 |
| 131 » _DBG_STORAGE("ident %s", __getpath(ident)); |
| 132 |
| 133 » pathname = getpath(ident); |
| 134 » if (pathname == NULL) |
| 135 » » return FALSE; |
| 136 |
| 137 » result = g_file_get_contents(pathname, &data, &length, NULL); |
| 138 |
| 139 » g_free(pathname); |
| 140 » g_free(data); |
| 141 |
| 142 » return result; |
| 143 } |
| 144 |
| 145 GKeyFile *__connman_storage_open(const struct connman_storage_ident *ident) |
| 98 { | 146 { |
| 99 GKeyFile *keyfile; | 147 GKeyFile *keyfile; |
| 100 gchar *pathname, *data = NULL; | 148 gchar *pathname, *data = NULL; |
| 101 gboolean result; | 149 gboolean result; |
| 102 gsize length; | 150 gsize length; |
| 103 | 151 |
| 104 » _DBG_STORAGE("ident %s", ident); | 152 » _DBG_STORAGE("ident %s", __getpath(ident)); |
| 105 | 153 |
| 106 » pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident); | 154 » pathname = getpath(ident); |
| 107 if (pathname == NULL) | 155 if (pathname == NULL) |
| 108 return NULL; | 156 return NULL; |
| 109 | 157 |
| 110 result = g_file_get_contents(pathname, &data, &length, NULL); | 158 result = g_file_get_contents(pathname, &data, &length, NULL); |
| 111 | 159 |
| 112 g_free(pathname); | 160 g_free(pathname); |
| 113 | 161 |
| 114 keyfile = g_key_file_new(); | 162 keyfile = g_key_file_new(); |
| 115 | 163 |
| 116 if (result == FALSE) | 164 if (result == FALSE) |
| 117 goto done; | 165 goto done; |
| 118 | 166 |
| 119 if (length > 0) | 167 if (length > 0) |
| 120 g_key_file_load_from_data(keyfile, data, length, 0, NULL); | 168 g_key_file_load_from_data(keyfile, data, length, 0, NULL); |
| 121 | 169 |
| 122 g_free(data); | 170 g_free(data); |
| 123 | 171 |
| 124 done: | 172 done: |
| 125 _DBG_STORAGE("keyfile %p", keyfile); | 173 _DBG_STORAGE("keyfile %p", keyfile); |
| 126 | 174 |
| 127 return keyfile; | 175 return keyfile; |
| 128 } | 176 } |
| 129 | 177 |
| 130 void __connman_storage_close(const char *ident, | 178 void __connman_storage_close(const struct connman_storage_ident *ident, |
| 131 GKeyFile *keyfile, gboolean save) | 179 GKeyFile *keyfile, gboolean save) |
| 132 { | 180 { |
| 133 gchar *pathname, *data = NULL; | 181 gchar *pathname, *data = NULL; |
| 134 gsize length = 0; | 182 gsize length = 0; |
| 135 | 183 |
| 136 » _DBG_STORAGE("ident %s keyfile %p save %d", ident, keyfile, save); | 184 » _DBG_STORAGE("ident %s keyfile %p save %d", __getpath(ident), |
| 185 » keyfile, save); |
| 137 | 186 |
| 138 if (save == FALSE) { | 187 if (save == FALSE) { |
| 139 g_key_file_free(keyfile); | 188 g_key_file_free(keyfile); |
| 140 return; | 189 return; |
| 141 } | 190 } |
| 142 | 191 |
| 143 » pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident); | 192 » pathname = getpath(ident); |
| 144 if (pathname == NULL) | 193 if (pathname == NULL) |
| 145 return; | 194 return; |
| 146 | 195 |
| 147 data = g_key_file_to_data(keyfile, &length, NULL); | 196 data = g_key_file_to_data(keyfile, &length, NULL); |
| 148 | 197 |
| 149 if (g_file_set_contents(pathname, data, length, NULL) == FALSE) | 198 if (g_file_set_contents(pathname, data, length, NULL) == FALSE) |
| 150 » » connman_error("Failed to store information"); | 199 » » connman_error("%s: failed to store data for %s:%s", |
| 200 » » __func__, ident->user, ident->ident); |
| 151 | 201 |
| 152 g_free(data); | 202 g_free(data); |
| 153 | 203 |
| 154 g_free(pathname); | 204 g_free(pathname); |
| 155 | 205 |
| 156 g_key_file_free(keyfile); | 206 g_key_file_free(keyfile); |
| 157 } | 207 } |
| 158 | 208 |
| 159 void __connman_storage_delete(const char *ident) | 209 void __connman_storage_delete(const struct connman_storage_ident *ident) |
| 160 { | 210 { |
| 161 gchar *pathname; | 211 gchar *pathname; |
| 162 | 212 |
| 163 » _DBG_STORAGE("ident %s", ident); | 213 » _DBG_STORAGE("ident %s", __getpath(ident)); |
| 164 | 214 |
| 165 » pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident); | 215 » pathname = getpath(ident); |
| 166 if (pathname == NULL) | 216 if (pathname == NULL) |
| 167 return; | 217 return; |
| 168 | 218 |
| 169 if (unlink(pathname) < 0) | 219 if (unlink(pathname) < 0) |
| 170 connman_error("Failed to remove %s", pathname); | 220 connman_error("Failed to remove %s", pathname); |
| 221 |
| 222 g_free(pathname); |
| 171 } | 223 } |
| 172 | 224 |
| 173 int __connman_storage_init_profile(void) | 225 int __connman_storage_init_profile(void) |
| 174 { | 226 { |
| 175 GSList *list; | 227 GSList *list; |
| 176 | 228 |
| 177 _DBG_STORAGE(""); | 229 _DBG_STORAGE(""); |
| 178 | 230 |
| 179 for (list = storage_list; list; list = list->next) { | 231 for (list = storage_list; list; list = list->next) { |
| 180 struct connman_storage *storage = list->data; | 232 struct connman_storage *storage = list->data; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 269 |
| 218 if (storage->profile_save) { | 270 if (storage->profile_save) { |
| 219 if (storage->profile_save(profile) == 0) | 271 if (storage->profile_save(profile) == 0) |
| 220 return 0; | 272 return 0; |
| 221 } | 273 } |
| 222 } | 274 } |
| 223 | 275 |
| 224 return -ENOENT; | 276 return -ENOENT; |
| 225 } | 277 } |
| 226 | 278 |
| 227 int __connman_storage_load_service(struct connman_service *service) | 279 /* |
| 280 * Load/Save object support. Walk the list of registered |
| 281 * storage implementors until we find one that has a handler |
| 282 * for the object type. The storage implementor template |
| 283 * has per-object types (apparently) but these are not used |
| 284 * at the moment. |
| 285 */ |
| 286 #define»DOLOAD(func, arg, profile_ident) do {» » » » \ |
| 287 » int err;» » » » » » » \ |
| 288 » GKeyFile *keyfile = __connman_storage_open(profile_ident);» \ |
| 289 » if (keyfile == NULL)» » » » » » \ |
| 290 » » return -ENXIO;» » » » » » \ |
| 291 » err = func(arg, keyfile);» » » » » \ |
| 292 » __connman_storage_close(profile_ident, keyfile, FALSE);»» \ |
| 293 » return err;» » » » » » » \ |
| 294 } while (0) |
| 295 |
| 296 #define»DOSAVE(func, arg, profile_ident) do {» » » » \ |
| 297 » int err;» » » » » » » \ |
| 298 » GKeyFile *keyfile = __connman_storage_open(profile_ident);» \ |
| 299 » if (keyfile == NULL)» » » » » » \ |
| 300 » » return -ENXIO;» » » » » » \ |
| 301 » err = func(arg, keyfile);» » » » » \ |
| 302 » /* NB: always write-back for compatibility */» » » \ |
| 303 » __connman_storage_close(profile_ident, keyfile, TRUE);» » \ |
| 304 » return err;» » » » » » » \ |
| 305 } while (0) |
| 306 |
| 307 int __connman_storage_load_service(struct connman_service *service, |
| 308 const struct connman_storage_ident *profile_ident) |
| 228 { | 309 { |
| 229 GSList *list; | 310 GSList *list; |
| 230 | 311 |
| 231 _DBG_STORAGE("service %p", service); | 312 _DBG_STORAGE("service %p", service); |
| 232 | 313 |
| 233 for (list = storage_list; list; list = list->next) { | 314 for (list = storage_list; list; list = list->next) { |
| 234 struct connman_storage *storage = list->data; | 315 struct connman_storage *storage = list->data; |
| 235 | 316 |
| 236 » » if (storage->service_load) { | 317 » » if (storage->service_load) |
| 237 » » » if (storage->service_load(service) == 0) | 318 » » » DOLOAD(storage->service_load, service, profile_ident); |
| 238 » » » » return 0; | |
| 239 » » } | |
| 240 } | 319 } |
| 241 | |
| 242 return -ENOENT; | 320 return -ENOENT; |
| 243 } | 321 } |
| 244 | 322 |
| 245 int __connman_storage_save_service(struct connman_service *service) | 323 int __connman_storage_save_service(struct connman_service *service, |
| 324 const struct connman_storage_ident *profile_ident) |
| 246 { | 325 { |
| 247 GSList *list; | 326 GSList *list; |
| 248 | 327 |
| 249 _DBG_STORAGE("service %p", service); | 328 _DBG_STORAGE("service %p", service); |
| 250 | 329 |
| 251 for (list = storage_list; list; list = list->next) { | 330 for (list = storage_list; list; list = list->next) { |
| 252 struct connman_storage *storage = list->data; | 331 struct connman_storage *storage = list->data; |
| 253 | 332 |
| 254 » » if (storage->service_save) { | 333 » » if (storage->service_save) |
| 255 » » » if (storage->service_save(service) == 0) | 334 » » » DOSAVE(storage->service_save, service, profile_ident); |
| 256 » » » » return 0; | |
| 257 » » } | |
| 258 } | 335 } |
| 259 | |
| 260 return -ENOENT; | 336 return -ENOENT; |
| 261 } | 337 } |
| 262 | 338 |
| 263 int __connman_storage_load_device(struct connman_device *device) | 339 int __connman_storage_load_device(struct connman_device *device, |
| 340 const struct connman_storage_ident *profile_ident) |
| 264 { | 341 { |
| 265 GSList *list; | 342 GSList *list; |
| 266 | 343 |
| 267 _DBG_STORAGE("device %p", device); | 344 _DBG_STORAGE("device %p", device); |
| 268 | 345 |
| 269 for (list = storage_list; list; list = list->next) { | 346 for (list = storage_list; list; list = list->next) { |
| 270 struct connman_storage *storage = list->data; | 347 struct connman_storage *storage = list->data; |
| 271 | 348 |
| 272 » » if (storage->device_load) { | 349 » » if (storage->device_load) |
| 273 » » » if (storage->device_load(device) == 0) | 350 » » » DOLOAD(storage->device_load, device, profile_ident); |
| 274 » » » » return 0; | |
| 275 » » } | |
| 276 } | 351 } |
| 277 | |
| 278 return -ENOENT; | 352 return -ENOENT; |
| 279 } | 353 } |
| 280 | 354 |
| 281 int __connman_storage_save_device(struct connman_device *device) | 355 int __connman_storage_save_device(struct connman_device *device, |
| 356 const struct connman_storage_ident *profile_ident) |
| 282 { | 357 { |
| 283 GSList *list; | 358 GSList *list; |
| 284 | 359 |
| 285 _DBG_STORAGE("device %p", device); | 360 _DBG_STORAGE("device %p", device); |
| 286 | 361 |
| 287 for (list = storage_list; list; list = list->next) { | 362 for (list = storage_list; list; list = list->next) { |
| 288 struct connman_storage *storage = list->data; | 363 struct connman_storage *storage = list->data; |
| 289 | 364 |
| 290 » » if (storage->device_save) { | 365 » » if (storage->device_save) |
| 291 » » » if (storage->device_save(device) == 0) | 366 » » » DOSAVE(storage->device_save, device, profile_ident); |
| 292 » » » » return 0; | |
| 293 » » } | |
| 294 } | 367 } |
| 295 | |
| 296 return -ENOENT; | 368 return -ENOENT; |
| 297 } | 369 } |
| 298 | 370 |
| 299 int __connman_storage_load_ipconfig(struct connman_ipconfig *ipconfig) | 371 int __connman_storage_load_ipconfig(struct connman_ipconfig *ipconfig, |
| 372 const struct connman_storage_ident *profile_ident) |
| 300 { | 373 { |
| 301 GSList *list; | 374 GSList *list; |
| 302 | 375 |
| 303 _DBG_STORAGE("ipconfig %p", ipconfig); | 376 _DBG_STORAGE("ipconfig %p", ipconfig); |
| 304 | 377 |
| 305 for (list = storage_list; list; list = list->next) { | 378 for (list = storage_list; list; list = list->next) { |
| 306 struct connman_storage *storage = list->data; | 379 struct connman_storage *storage = list->data; |
| 307 | 380 |
| 308 » » if (storage->ipconfig_load) { | 381 » » if (storage->ipconfig_load) |
| 309 » » » if (storage->ipconfig_load(ipconfig) == 0) | 382 » » » DOLOAD(storage->ipconfig_load, ipconfig, profile_ident); |
| 310 » » » » return 0; | |
| 311 » » } | |
| 312 } | 383 } |
| 313 | |
| 314 return -ENOENT; | 384 return -ENOENT; |
| 315 } | 385 } |
| 316 | 386 |
| 317 int __connman_storage_save_ipconfig(const struct connman_ipconfig *ipconfig) | 387 int __connman_storage_save_ipconfig(const struct connman_ipconfig *ipconfig, |
| 388 const struct connman_storage_ident *profile_ident) |
| 318 { | 389 { |
| 319 GSList *list; | 390 GSList *list; |
| 320 | 391 |
| 321 _DBG_STORAGE("ipconfig %p", ipconfig); | 392 _DBG_STORAGE("ipconfig %p", ipconfig); |
| 322 | 393 |
| 323 for (list = storage_list; list; list = list->next) { | 394 for (list = storage_list; list; list = list->next) { |
| 324 struct connman_storage *storage = list->data; | 395 struct connman_storage *storage = list->data; |
| 325 | 396 |
| 326 » » if (storage->ipconfig_save) { | 397 » » if (storage->ipconfig_save) |
| 327 » » » if (storage->ipconfig_save(ipconfig) == 0) | 398 » » » DOSAVE(storage->ipconfig_save, ipconfig, profile_ident); |
| 328 » » » » return 0; | |
| 329 » » } | |
| 330 } | 399 } |
| 331 | |
| 332 return -ENOENT; | 400 return -ENOENT; |
| 333 } | 401 } |
| 334 | 402 |
| 335 int __connman_storage_init(void) | 403 int __connman_storage_init(void) |
| 336 { | 404 { |
| 337 _DBG_STORAGE(""); | 405 _DBG_STORAGE(""); |
| 338 | 406 |
| 339 return 0; | 407 return 0; |
| 340 } | 408 } |
| 341 | 409 |
| 342 void __connman_storage_cleanup(void) | 410 void __connman_storage_cleanup(void) |
| 343 { | 411 { |
| 344 _DBG_STORAGE(""); | 412 _DBG_STORAGE(""); |
| 345 } | 413 } |
| OLD | NEW |