diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | matrix-e2e.c | 89 |
2 files changed, 90 insertions, 1 deletions
@@ -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); |