[PATCH] notmuch-config: replace config reading function
Ioan-Adrian Ratiu
adi at adirat.com
Sat Nov 5 17:09:53 PDT 2016
Config files are currently read using glib's g_key_file_load_from_file
function which is very inconvenient because it's limited by design to read
only from "regular data files" in a filesystem. Because of this limitation
notmuch can't read configs from pipes, fifos, sockets, stdin, etc. Not even
"notmuch --config=/dev/stdin" works:
Error reading configuration file /dev/stdin: Not a regular file
So replace g_key_file_load_from_file with g_key_file_load_from_data which
gives us much more freedom to read configs from multiple sources.
This also helps the more security sensitive users: If someone has private
information in the config file, it can be encrypted on disk, then decrypted
in RAM and passed through a pipe directly to notmuch without the use of
intermediate plain text files.
Signed-off-by: Ioan-Adrian Ratiu <adi at adirat.com>
---
notmuch-config.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 4 deletions(-)
diff --git a/notmuch-config.c b/notmuch-config.c
index e5d42a0..8435815 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -202,6 +202,64 @@ get_username_from_passwd_file (void *ctx)
return name;
}
+static gboolean
+get_config_from_file (notmuch_config_t *config, GError **error)
+{
+ #define BUF_SIZE 4096
+ char buffer[BUF_SIZE];
+ size_t content_size = 1; // includes NULL
+
+ FILE *fp = fopen(config->filename, "r");
+ if (fp == NULL) {
+ *error = g_error_new(G_FILE_ERROR,
+ G_FILE_ERROR_NOENT,
+ "Couldn't open config file '%s': %s.\n",
+ config->filename,
+ strerror(errno));
+ return FALSE;
+ }
+
+ char *config_str = talloc_zero_array (config, char, BUF_SIZE);
+ if (config_str == NULL)
+ {
+ *error = g_error_new(G_FILE_ERROR,
+ G_FILE_ERROR_NOMEM,
+ "Out of memory while reading config.\n");
+ return FALSE;
+ }
+
+ while (fgets (buffer, BUF_SIZE, fp))
+ {
+ content_size += strlen(buffer);
+ config_str = talloc_realloc(config, config_str, char, content_size);
+ if (config_str == NULL)
+ {
+ *error = g_error_new(G_FILE_ERROR,
+ G_FILE_ERROR_NOMEM,
+ "Failed to reallocate config memory.\n");
+ return FALSE;
+ }
+ strcat (config_str, buffer);
+ }
+
+ if (ferror (fp))
+ {
+ *error = g_error_new(G_FILE_ERROR,
+ G_FILE_ERROR_IO,
+ "I/O error reading configuration from '%s'.\n",
+ config->filename);
+ return FALSE;
+ }
+
+ fclose(fp);
+
+ return g_key_file_load_from_data (config->key_file,
+ config_str,
+ strlen(config_str),
+ G_KEY_FILE_KEEP_COMMENTS,
+ error);
+}
+
/* Open the named notmuch configuration file. If the filename is NULL,
* the value of the environment variable $NOTMUCH_CONFIG will be used.
* If $NOTMUCH_CONFIG is unset, the default configuration file
@@ -289,10 +347,7 @@ notmuch_config_open (void *ctx,
config->search_exclude_tags_length = 0;
config->crypto_gpg_path = NULL;
- if (! g_key_file_load_from_file (config->key_file,
- config->filename,
- G_KEY_FILE_KEEP_COMMENTS,
- &error))
+ if (! get_config_from_file (config, &error))
{
if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT) {
/* If create_new is true, then the caller is prepared for a
--
2.10.2
More information about the notmuch
mailing list