summaryrefslogtreecommitdiffstats
path: root/autocrypt
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2019-07-06 14:01:13 -0700
committerKevin McCarthy <kevin@8t8.us>2019-08-03 14:08:09 -0700
commitbe89dc7b3c3af202cfb770550fdf0083ee6ac253 (patch)
treed75bb9a3eb293222fcb1251640c0088b2541fba0 /autocrypt
parente966890252fac950a53189b6b928bfa4cd35e93c (diff)
Add database and schema initialization.
Add mutt_mkdir() library function supporting recursive mkdir.
Diffstat (limited to 'autocrypt')
-rw-r--r--autocrypt/Makefile.am3
-rw-r--r--autocrypt/autocrypt.c57
-rw-r--r--autocrypt/autocrypt.h6
-rw-r--r--autocrypt/autocrypt_db.c94
-rw-r--r--autocrypt/autocrypt_private.h29
-rw-r--r--autocrypt/autocrypt_schema.c129
6 files changed, 315 insertions, 3 deletions
diff --git a/autocrypt/Makefile.am b/autocrypt/Makefile.am
index 235c43c2..a874a3d1 100644
--- a/autocrypt/Makefile.am
+++ b/autocrypt/Makefile.am
@@ -7,4 +7,5 @@ AM_CPPFLAGS = -I$(top_srcdir) -I../intl
noinst_LIBRARIES = libautocrypt.a
-libautocrypt_a_SOURCES = autocrypt.c autocrypt.h
+libautocrypt_a_SOURCES = autocrypt.c autocrypt.h autocrypt_db.c autocrypt_private.h \
+ autocrypt_schema.c
diff --git a/autocrypt/autocrypt.c b/autocrypt/autocrypt.c
index 6aecf6fe..fe40b613 100644
--- a/autocrypt/autocrypt.c
+++ b/autocrypt/autocrypt.c
@@ -22,13 +22,68 @@
#include "mutt.h"
#include "autocrypt.h"
+#include "autocrypt_private.h"
-void mutt_autocrypt_init (void)
+#include <errno.h>
+
+static int autocrypt_dir_init (int can_create)
{
+ int rv = 0;
+ struct stat sb;
+ BUFFER *prompt = NULL;
+
+ if (!stat (AutocryptDir, &sb))
+ return 0;
+
+ if (!can_create)
+ return -1;
+
+ prompt = mutt_buffer_pool_get ();
+ mutt_buffer_printf (prompt, _("%s does not exist. Create it?"), AutocryptDir);
+ if (mutt_yesorno (mutt_b2s (prompt), MUTT_YES) == MUTT_YES)
+ {
+ if (mutt_mkdir (AutocryptDir, 0700) < 0)
+ {
+ mutt_error ( _("Can't create %s: %s."), AutocryptDir, strerror (errno));
+ mutt_sleep (0);
+ rv = -1;
+ }
+ }
+
+ mutt_buffer_pool_release (&prompt);
+ return rv;
+}
+
+int mutt_autocrypt_init (int can_create)
+{
+ if (AutocryptDB)
+ return 0;
+
+ if (!option (OPTAUTOCRYPT) || !AutocryptDir)
+ return -1;
+
+ if (autocrypt_dir_init (can_create))
+ goto bail;
+
+ if (mutt_autocrypt_db_init (can_create))
+ goto bail;
+
+ /* mutt_autocrypt_gpgme_init()
+ * - init gpgme
+ * - create key if doesn't exist
+ * - perhaps should query account table and if empty do that?
+ */
dprint (1, (debugfile, "In mutt_autocrypt_init()\n"));
+ return 0;
+
+bail:
+ unset_option (OPTAUTOCRYPT);
+ mutt_autocrypt_db_close ();
+ return -1;
}
void mutt_autocrypt_cleanup (void)
{
+ mutt_autocrypt_db_close ();
dprint (1, (debugfile, "In mutt_autocrypt_cleanup()\n"));
}
diff --git a/autocrypt/autocrypt.h b/autocrypt/autocrypt.h
index f866e76b..2429539e 100644
--- a/autocrypt/autocrypt.h
+++ b/autocrypt/autocrypt.h
@@ -19,7 +19,11 @@
#ifndef _AUTOCRYPT_H
#define _AUTOCRYPT_H 1
-void mutt_autocrypt_init (void);
+#include <sqlite3.h>
+
+WHERE sqlite3 *AutocryptDB;
+
+int mutt_autocrypt_init (int);
void mutt_autocrypt_cleanup (void);
#endif
diff --git a/autocrypt/autocrypt_db.c b/autocrypt/autocrypt_db.c
new file mode 100644
index 00000000..e7baa603
--- /dev/null
+++ b/autocrypt/autocrypt_db.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "mutt.h"
+#include "autocrypt.h"
+#include "autocrypt_private.h"
+
+static int autocrypt_db_create (const char *db_path)
+{
+ if (sqlite3_open_v2 (db_path,
+ &AutocryptDB,
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE,
+ NULL) != SQLITE_OK)
+ {
+ mutt_error (_("Unable to open autocrypt database %s"), db_path);
+ mutt_sleep (0);
+ return -1;
+ }
+ return mutt_autocrypt_schema_init ();
+}
+
+int mutt_autocrypt_db_init (int can_create)
+{
+ int rv = -1;
+ BUFFER *db_path = NULL;
+ struct stat sb;
+
+ if (AutocryptDB)
+ return 0;
+
+ if (!option (OPTAUTOCRYPT) || !AutocryptDir)
+ return -1;
+
+ db_path = mutt_buffer_pool_get ();
+ mutt_buffer_concat_path (db_path, AutocryptDir, "autocrypt.db");
+ if (stat (mutt_b2s (db_path), &sb))
+ {
+ if (!can_create || autocrypt_db_create (mutt_b2s (db_path)))
+ goto cleanup;
+ }
+ else
+ {
+ if (sqlite3_open_v2 (mutt_b2s (db_path),
+ &AutocryptDB,
+ SQLITE_OPEN_READWRITE,
+ NULL) != SQLITE_OK)
+ {
+ mutt_error (_("Unable to open autocrypt database %s"), mutt_b2s (db_path));
+ mutt_sleep (0);
+ goto cleanup;
+ }
+ }
+
+ if (mutt_autocrypt_schema_update ())
+ goto cleanup;
+
+ rv = 0;
+
+cleanup:
+ mutt_buffer_pool_release (&db_path);
+ return rv;
+}
+
+void mutt_autocrypt_db_close (void)
+{
+ if (!AutocryptDB)
+ return;
+
+ /* TODO:
+ * call sqlite3_finalize () for each prepared statement
+ */
+
+ sqlite3_close_v2 (AutocryptDB);
+ AutocryptDB = NULL;
+}
diff --git a/autocrypt/autocrypt_private.h b/autocrypt/autocrypt_private.h
new file mode 100644
index 00000000..56f0dda3
--- /dev/null
+++ b/autocrypt/autocrypt_private.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _AUTOCRYPT_PRIVATE_H
+#define _AUTOCRYPT_PRIVATE_H 1
+
+int mutt_autocrypt_db_init (int can_create);
+void mutt_autocrypt_db_close (void);
+
+int mutt_autocrypt_schema_init (void);
+int mutt_autocrypt_schema_update (void);
+
+
+#endif
diff --git a/autocrypt/autocrypt_schema.c b/autocrypt/autocrypt_schema.c
new file mode 100644
index 00000000..cb9d63d6
--- /dev/null
+++ b/autocrypt/autocrypt_schema.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "mutt.h"
+#include "autocrypt.h"
+#include "autocrypt_private.h"
+
+int mutt_autocrypt_schema_init (void)
+{
+ const char *schema;
+ char *errmsg = NULL;
+
+ schema =
+ "BEGIN TRANSACTION; "
+
+ "CREATE TABLE account ("
+ "email_addr text primary key not null, "
+ "keyid text, "
+ "keydata text, "
+ "prefer_encrypt int, "
+ "enabled int);"
+
+ "CREATE TABLE peer ("
+ "email_addr text primary key not null, "
+ "last_seen int, "
+ "autocrypt_timestamp int, "
+ "keyid text, "
+ "keydata text, "
+ "prefer_encrypt int, "
+ "gossip_timestamp int, "
+ "gossip_keyid text, "
+ "gossip_keydata text);"
+
+ "CREATE TABLE peer_history ("
+ "peer_email_addr text not null, "
+ "email_msgid text, "
+ "timestamp int, "
+ "keydata text);"
+
+ "CREATE INDEX peer_history_email "
+ "ON peer_history ("
+ "peer_email_addr);"
+
+ "CREATE TABLE gossip_history ("
+ "peer_email_addr text not null, "
+ "sender_email_addr text, "
+ "email_msgid text, "
+ "timestamp int, "
+ "gossip_keydata text);"
+
+ "CREATE INDEX gossip_history_email "
+ "ON gossip_history ("
+ "peer_email_addr);"
+
+ "CREATE TABLE schema ("
+ "version int);"
+
+ "INSERT into schema (version) values (1);"
+
+ "COMMIT TRANSACTION";
+
+ if (sqlite3_exec (AutocryptDB, schema, NULL, NULL, &errmsg) != SQLITE_OK)
+ {
+ dprint (1, (debugfile, "mutt_autocrypt_schema_init() returned %s\n", errmsg));
+ sqlite3_free (errmsg);
+ return -1;
+ }
+ return 0;
+}
+
+int mutt_autocrypt_schema_update (void)
+{
+ sqlite3_stmt *stmt = NULL;
+ int rv = -1, version;
+
+ if (sqlite3_prepare_v2 (
+ AutocryptDB,
+ "SELECT version FROM schema;",
+ -1,
+ &stmt,
+ NULL) != SQLITE_OK)
+ goto cleanup;
+
+ if (sqlite3_step (stmt) != SQLITE_ROW)
+ goto cleanup;
+
+ version = sqlite3_column_int (stmt, 0);
+
+ if (version > 1)
+ {
+ /* L10N:
+ The autocrypt database keeps track of schema version numbers.
+ This error occurs if the version number is too high.
+ Presumably because this is an old version of mutt and the
+ database was upgraded by a future version.
+ */
+ mutt_error _("Autocrypt database version is too new");
+ mutt_sleep (0);
+ goto cleanup;
+ }
+
+ /* TODO: schema version upgrades go here.
+ * Bump one by one, each update inside a transaction. */
+
+ rv = 0;
+
+cleanup:
+ sqlite3_finalize (stmt);
+ return rv;
+}