aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--matrix-e2e.c89
2 files changed, 90 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 37644c9..f914496 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
#!/usr/bin/make -f
CC=gcc
-LIBS=purple json-glib-1.0 glib-2.0
+LIBS=purple json-glib-1.0 glib-2.0 sqlite3
PKG_CONFIG=pkg-config
CFLAGS+=$(shell $(PKG_CONFIG) --cflags $(LIBS))
diff --git a/matrix-e2e.c b/matrix-e2e.c
index e7471fd..6d8918e 100644
--- a/matrix-e2e.c
+++ b/matrix-e2e.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
+#include <sqlite3.h>
#include "libmatrix.h"
#include "matrix-api.h"
#include "matrix-e2e.h"
@@ -36,6 +37,7 @@ struct _MatrixE2EData {
gchar *device_id;
gchar *curve25519_pubkey;
gchar *ed25519_pubkey;
+ sqlite3 *db;
};
static void key_upload_callback(MatrixConnectionData *conn,
@@ -482,6 +484,86 @@ static void key_upload_callback(MatrixConnectionData *conn,
matrix_e2e_handle_sync_key_counts(conn->pc, key_counts, !key_counts);
}
+static void close_e2e_db(MatrixConnectionData *conn)
+{
+ sqlite3_close(conn->e2e->db);
+ conn->e2e->db = NULL;
+}
+
+/* 'check' and 'create' are SQL statements; call check, if it returns no result
+ * then run 'create'.
+ * typically for checking for the existence of a table and creating it if it didn't
+ * exist.
+ */
+static int ensure_table(MatrixConnectionData *conn, const char *check, const char *create)
+{
+ PurpleConnection *pc = conn->pc;
+ int ret;
+ sqlite3_stmt *dbstmt;
+ ret = sqlite3_prepare_v2(conn->e2e->db, check, -1, &dbstmt, NULL);
+ if (ret != SQLITE_OK || !dbstmt) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Failed to check e2e db table list (prep)");
+ return -1;
+ }
+ ret = sqlite3_step(dbstmt);
+ sqlite3_finalize(dbstmt);
+ purple_debug_info("matrixprpl", "%s:db table query %d\n", __func__, ret);
+ if (ret == SQLITE_ROW) {
+ /* Already exists */
+ return 0;
+ }
+ ret = sqlite3_prepare_v2(conn->e2e->db, create, -1, &dbstmt, NULL);
+ if (ret != SQLITE_OK || !dbstmt) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Failed to create e2e db table (prep)");
+ return -1;
+ }
+ ret = sqlite3_step(dbstmt);
+ sqlite3_finalize(dbstmt);
+ if (ret != SQLITE_DONE) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Failed to create e2e db table (step)");
+ return -1;
+ }
+
+ return 0;
+}
+static int open_e2e_db(MatrixConnectionData *conn)
+{
+ PurpleConnection *pc = conn->pc;
+ int ret;
+ const char *purple_username =
+ purple_account_get_username(purple_connection_get_account(pc));
+ char *cfilename = g_strdup_printf("matrix-%s-%s.db", conn->user_id,
+ purple_username);
+ const char *escaped_filename = purple_escape_filename(cfilename);
+ g_free(cfilename);
+ char *full_path = g_strdup_printf("%s/%s", purple_user_dir(),
+ escaped_filename);
+ ret = sqlite3_open(full_path, &conn->e2e->db);
+ purple_debug_info("matrixprpl", "Opened e2e db at %s %d\n", full_path, ret);
+ g_free(full_path);
+ if (ret) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Failed to open e2e db");
+ return ret;
+ }
+
+ /* TODO: Add calls to ensure_table here */
+
+ if (ret) {
+ close_e2e_db(conn);
+ return ret;
+ }
+
+ return 0;
+}
+
/*
* Get a set of device keys for ourselves. Either by retreiving it from our store
* or by generating a new set.
@@ -539,6 +621,12 @@ int matrix_e2e_get_device_keys(MatrixConnectionData *conn, const gchar *device_i
}
}
+ /* Open the e2e db - an sqlite db held for the account */
+ ret = open_e2e_db(conn);
+ if (ret) {
+ goto out;
+ }
+
/* Form a device keys object for an upload,
* from https://matrix.org/speculator/spec/drafts%2Fe2e/client_server/unstable.html#post-matrix-client-unstable-keys-upload
*/
@@ -613,6 +701,7 @@ out:
void matrix_e2e_cleanup_connection(MatrixConnectionData *conn)
{
if (conn->e2e) {
+ close_e2e_db(conn);
g_free(conn->e2e->curve25519_pubkey);
g_free(conn->e2e->oa);
g_free(conn->e2e->device_id);