// Store (key,value) pairs from a GHashTable in the kwallet. // Every 'slot' has to take care of it's own data. gboolean dt_pwstorage_kwallet_set(const gchar* slot, GHashTable* table) { _context = (backend_kwallet_context_t*)(darktable.pwstorage->backend_context); GArray* byte_array = g_array_new(FALSE, FALSE, sizeof(gchar)); GHashTableIter iter; g_hash_table_iter_init (&iter, table); gpointer key, value; guint size = g_hash_table_size(table); size = GINT_TO_BE(size); g_array_append_vals(byte_array, &size, sizeof(guint)/sizeof(gchar)); while (g_hash_table_iter_next (&iter, &key, &value)) { dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_set] storing (%s, %s)\n",(gchar*)key, (gchar*)value); gsize length; gchar* new_key = char2qstring(key, &length); if(new_key == NULL) return FALSE; g_array_append_vals(byte_array, new_key, length); g_free(new_key); new_key = NULL; gchar* new_value = char2qstring(value, &length); if(new_value == NULL) return FALSE; g_array_append_vals(byte_array, new_value, length); g_free(new_value); new_value = NULL; } int wallet_handle = get_wallet_handle(); int ret = 0; GError* error = NULL; dbus_g_proxy_call(_context->proxy, "writeMap", &error, G_TYPE_INT, wallet_handle, // handle G_TYPE_STRING, kwallet_folder, // folder G_TYPE_STRING, slot, // key DBUS_TYPE_G_UCHAR_ARRAY, byte_array, // value G_TYPE_STRING, app_id, // appid G_TYPE_INVALID, G_TYPE_INT, &ret, G_TYPE_INVALID); g_array_free(byte_array, TRUE); if (CheckError(error)) return FALSE; if (ret != 0) dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_set] Warning: bad return code %d from kwallet\n", ret); return ret == 0; }
// Get the (key,value) pairs back from KWallet. GHashTable* dt_pwstorage_kwallet_get(const backend_kwallet_context_t *context, const gchar* slot) { GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal); GError* error = NULL; // Is there an entry in the wallet? gboolean has_entry = FALSE; int wallet_handle = get_wallet_handle(context); /* signature: * * in i handle, * in s folder, * in s key, * in s appid, * * out b arg_0 */ GVariant *ret = g_dbus_proxy_call_sync(context->proxy, "hasEntry", g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if(check_error(error)) { g_variant_unref(ret); return table; } GVariant *child = g_variant_get_child_value(ret, 0); has_entry = g_variant_get_boolean(child); g_variant_unref(child); g_variant_unref(ret); if(!has_entry) return table; /* signature: * * in i handle, * in s folder, * in s key, * in s appid, * * out a{sv} arg_0) */ ret = g_dbus_proxy_call_sync(context->proxy, "readMapList", g_variant_new("(isss)", wallet_handle, kwallet_folder, slot, app_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if(check_error(error)) { g_variant_unref(ret); return table; } child = g_variant_get_child_value(ret, 0); // we are only interested in the first child. i am not even sure that there can legally be more than one if(g_variant_n_children(child)<1) { g_variant_unref(child); g_variant_unref(ret); return table; } GVariant *element = g_variant_get_child_value(child, 0); GVariant *v = NULL; g_variant_get(element, "{sv}", NULL, &v); const gchar *byte_array = g_variant_get_data(v); if(!byte_array) { g_variant_unref(v); g_variant_unref(element); g_variant_unref(child); g_variant_unref(ret); return table; } int entries = GINT_FROM_BE(*((int*)byte_array)); byte_array += sizeof(gint); for(int i=0; i<entries; i++) { guint length; gchar* key = array2string(byte_array, &length); byte_array += length; gchar* value = array2string(byte_array, &length); byte_array += length; dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_get] reading (%s, %s)\n",(gchar*)key, (gchar*)value); g_hash_table_insert(table, key, value); } g_variant_unref(v); g_variant_unref(element); g_variant_unref(child); g_variant_unref(ret); return table; }
// Store (key,value) pairs from a GHashTable in the kwallet. // Every 'slot' has to take care of it's own data. gboolean dt_pwstorage_kwallet_set(const backend_kwallet_context_t *context, const gchar* slot, GHashTable* table) { printf("slot %s\n", slot); GArray* byte_array = g_array_new(FALSE, FALSE, sizeof(gchar)); GHashTableIter iter; g_hash_table_iter_init (&iter, table); gpointer key, value; guint size = g_hash_table_size(table); size = GINT_TO_BE(size); g_array_append_vals(byte_array, &size, sizeof(guint)/sizeof(gchar)); while (g_hash_table_iter_next (&iter, &key, &value)) { dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_set] storing (%s, %s)\n",(gchar*)key, (gchar*)value); gsize length; gchar* new_key = char2qstring(key, &length); if(new_key == NULL) { g_free(g_array_free(byte_array, FALSE)); return FALSE; } g_array_append_vals(byte_array, new_key, length); g_free(new_key); gchar* new_value = char2qstring(value, &length); if(new_value == NULL) { g_free(g_array_free(byte_array, FALSE)); return FALSE; } g_array_append_vals(byte_array, new_value, length); g_free(new_value); } int wallet_handle = get_wallet_handle(context); GError* error = NULL; /* signature: * * in i handle, * in s folder, * in s key, * in ay value, * in s appid, * * out i arg_0 */ GVariant *ret = g_dbus_proxy_call_sync(context->proxy, "writeMap", g_variant_new("(iss@ays)", wallet_handle, kwallet_folder, slot, g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING, byte_array->data, byte_array->len, TRUE, g_free, byte_array->data), app_id), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_array_free(byte_array, FALSE); if(check_error(error)) { g_variant_unref(ret); return FALSE; } GVariant *child = g_variant_get_child_value(ret, 0); int return_code = g_variant_get_int32(child); g_variant_unref(child); g_variant_unref(ret); if (return_code != 0) dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_set] Warning: bad return code %d from kwallet\n", return_code); return return_code == 0; }
// Get the (key,value) pairs back from KWallet. GHashTable* dt_pwstorage_kwallet_get(const gchar* slot) { _context = (backend_kwallet_context_t*)(darktable.pwstorage->backend_context); GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal); GError* error = NULL; // Is there an entry in the wallet? gboolean has_entry = FALSE; int wallet_handle = get_wallet_handle(); dbus_g_proxy_call(_context->proxy, "hasEntry", &error, G_TYPE_INT, wallet_handle, // handle G_TYPE_STRING, kwallet_folder, // folder G_TYPE_STRING, slot, // key G_TYPE_STRING, app_id, // appid G_TYPE_INVALID, G_TYPE_BOOLEAN, &has_entry, G_TYPE_INVALID); if (CheckError(error) || !has_entry) return table; GArray* byte_array = NULL; dbus_g_proxy_call(_context->proxy, "readMap", &error, G_TYPE_INT, wallet_handle, // handle G_TYPE_STRING, kwallet_folder, // folder G_TYPE_STRING, slot, // key G_TYPE_STRING, app_id, // appid G_TYPE_INVALID, DBUS_TYPE_G_UCHAR_ARRAY, &byte_array, G_TYPE_INVALID); if (CheckError(error) || !byte_array || !byte_array->len) return table; gint entries; memcpy(&entries, byte_array->data, sizeof(gint)); entries = GINT_FROM_BE(entries); gchar* pos = byte_array->data + sizeof(gint); gint i; for(i=0; i<entries; ++i) { guint length; gchar* key = array2string(pos, &length); pos += length; gchar* value = array2string(pos, &length); pos += length; dt_print(DT_DEBUG_PWSTORAGE,"[pwstorage_kwallet_get] reading (%s, %s)\n",(gchar*)key, (gchar*)value); g_hash_table_insert(table, key, value); } g_array_free(byte_array, TRUE); return table; }