Fix memory leak in password store reading.
[claws.git] / src / passwordstore.c
index 8e3942a314f37303b47a676b597503dbc3236c81..95946efd9748a1d4fcfd7a6279bc2ddf96853264 100644 (file)
@@ -107,6 +107,7 @@ gboolean passwd_store_set(PasswordBlockType block_type,
                const gchar *password,
                gboolean encrypted)
 {
+       const gchar *p;
        PasswordBlock *block;
        gchar *encrypted_password;
 
@@ -115,20 +116,32 @@ gboolean passwd_store_set(PasswordBlockType block_type,
        g_return_val_if_fail(block_name != NULL, FALSE);
        g_return_val_if_fail(password_id != NULL, FALSE);
 
+       /* Empty password string equals null password for us. */
+       if (password == NULL || strlen(password) == 0)
+               p = NULL;
+       else
+               p = password;
+
        debug_print("%s password '%s' in block (%d/%s)%s\n",
-                       (password == NULL ? "Deleting" : "Storing"),
+                       (p == NULL ? "Deleting" : "Storing"),
                        password_id, block_type, block_name,
                        (encrypted ? ", already encrypted" : "") );
 
        // find correct block (create if needed)
-       if ((block = _get_block(block_type, block_name)) == NULL &&
-                       (block = _new_block(block_type, block_name)) == NULL) {
-               debug_print("Could not create password block (%d/%s)\n",
-                               block_type, block_name);
-               return FALSE;
+       if ((block = _get_block(block_type, block_name)) == NULL) {
+               /* If caller wants to delete a password, and even its block
+                * doesn't exist, we're done. */
+               if (p == NULL)
+                       return TRUE;
+
+               if ((block = _new_block(block_type, block_name)) == NULL) {
+                       debug_print("Could not create password block (%d/%s)\n",
+                                       block_type, block_name);
+                       return FALSE;
+               }
        }
 
-       if (password == NULL) {
+       if (p == NULL) {
                /* NULL password was passed to us, so delete the entry with
                 * corresponding id */
                g_hash_table_remove(block->entries, password_id);
@@ -136,14 +149,14 @@ gboolean passwd_store_set(PasswordBlockType block_type,
                if (!encrypted) {
                        /* encrypt password before saving it */
                        if ((encrypted_password =
-                                               password_encrypt(password, NULL)) == NULL) {
+                                               password_encrypt(p, NULL)) == NULL) {
                                debug_print("Could not encrypt password '%s' for block (%d/%s).\n",
                                                password_id, block_type, block_name);
                                return FALSE;
                        }
                } else {
                        /* password is already in encrypted form already */
-                       encrypted_password = g_strdup(password);
+                       encrypted_password = g_strdup(p);
                }
 
                // add encrypted password to the block
@@ -197,6 +210,49 @@ gchar *passwd_store_get(PasswordBlockType block_type,
        return password;
 }
 
+gboolean passwd_store_delete_block(PasswordBlockType block_type,
+               const gchar *block_name)
+{
+       PasswordBlock *block;
+
+       g_return_val_if_fail(block_type >= 0 && block_type < NUM_PWS_TYPES,
+                       FALSE);
+       g_return_val_if_fail(block_name != NULL, FALSE);
+
+       debug_print("Deleting block (%d/%s)\n", block_type, block_name);
+
+       // find correct block
+       if ((block = _get_block(block_type, block_name)) == NULL) {
+               debug_print("Block (%d/%s) not found.\n", block_type, block_name);
+               return FALSE;
+       }
+
+       g_hash_table_destroy(block->entries);
+       block->entries = NULL;
+       return TRUE;
+}
+
+gboolean passwd_store_set_account(gint account_id,
+               const gchar *password_id,
+               const gchar *password,
+               gboolean encrypted)
+{
+       gchar *uid = g_strdup_printf("%d", account_id);
+       gboolean ret = passwd_store_set(PWS_ACCOUNT, uid,
+                       password_id, password, encrypted);
+       g_free(uid);
+       return ret;
+}
+
+gchar *passwd_store_get_account(gint account_id,
+               const gchar *password_id)
+{
+       gchar *uid = g_strdup_printf("%d", account_id);
+       gchar *ret = passwd_store_get(PWS_ACCOUNT, uid, password_id);
+       g_free(uid);
+       return ret;
+}
+
 /* Reencrypts all stored passwords. */
 void passwd_store_reencrypt_all(const gchar *old_mpwd,
                const gchar *new_mpwd)
@@ -353,7 +409,7 @@ void passwd_store_read_config(void)
                        PASSWORD_STORE_RC, NULL);
 
        if (!g_file_get_contents(rcpath, &contents, NULL, &error)) {
-               g_warning("couldn't read password store from file: %s\n", error->message);
+               g_warning("couldn't read password store from file: %s", error->message);
                g_error_free(error);
                g_free(rcpath);
                return;
@@ -362,6 +418,8 @@ void passwd_store_read_config(void)
 
        lines = g_strsplit(contents, "\n", -1);
 
+       g_free(contents);
+
        while (lines[i] != NULL) {
                if (*lines[i] == '[') {
                        /* Beginning of a new block */
@@ -379,7 +437,7 @@ void passwd_store_read_config(void)
                                } else if (!strcmp(typestr, "plugin")) {
                                        type = PWS_PLUGIN;
                                } else {
-                                       debug_print("Uknown password block type: '%s'\n", typestr);
+                                       debug_print("Unknown password block type: '%s'\n", typestr);
                                        g_strfreev(line);
                                        i++; continue;
                                }