aboutsummaryrefslogtreecommitdiffstats
path: root/matrix-e2e.c
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dave@treblig.org>2017-02-12 01:53:34 +0000
committerDr. David Alan Gilbert <dave@treblig.org>2018-02-25 02:08:49 +0000
commit86f665ed9dfc3503ff3d6c855ffade60737354d1 (patch)
tree8195ed85f6148413342098b4591e87d2cd4cf68f /matrix-e2e.c
parent22e9f6c194ffc3b223704d79526b1db94bff0224 (diff)
downloadpurple-matrix-86f665ed9dfc3503ff3d6c855ffade60737354d1.tar.gz
e2e: Restore OLM account state from Purple account data
Signed-off-by: Dr. David Alan Gilbert <dave@treblig.org>
Diffstat (limited to 'matrix-e2e.c')
-rw-r--r--matrix-e2e.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/matrix-e2e.c b/matrix-e2e.c
index 3d49e1c..dbd7dd1 100644
--- a/matrix-e2e.c
+++ b/matrix-e2e.c
@@ -141,6 +141,83 @@ static int matrix_store_e2e_account(MatrixConnectionData *conn)
return 0;
}
+/* Retrieve an Olm account from the Purple account data
+ * Returns: 1 on success
+ * 0 on no stored account
+ * -1 on error
+ */
+static int matrix_restore_e2e_account(MatrixConnectionData *conn)
+{
+ PurpleConnection *pc = conn->pc;
+ gchar *pickled_account = NULL;
+ const char *account_string = purple_account_get_string(pc->account,
+ PRPL_ACCOUNT_OPT_OLM_ACCOUNT_KEYS, NULL);
+ int ret = -1;
+ if (!account_string || !*account_string) {
+ return 0;
+ }
+ /* Deal with existing account string */
+ JsonParser *json_parser = json_parser_new();
+ const gchar *retrieved_device_id, *retrieved_hs, *retrieved_pickle;
+ GError *err = NULL;
+ if (!json_parser_load_from_data(json_parser,
+ account_string, strlen(account_string),
+ &err)) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Failed to parse stored account key");
+ purple_debug_info("matrixprpl",
+ "unable to parse account JSON: %s",
+ err->message);
+ g_error_free(err);
+ g_object_unref(json_parser);
+ ret = -1;
+ goto out;
+
+ }
+ JsonNode *settings_node = json_parser_get_root(json_parser);
+ JsonObject *settings_body = matrix_json_node_get_object(settings_node);
+ retrieved_device_id = matrix_json_object_get_string_member(settings_body, "device_id");
+ retrieved_hs = matrix_json_object_get_string_member(settings_body, "server");
+ retrieved_pickle = matrix_json_object_get_string_member(settings_body, "pickle");
+ if (!retrieved_device_id || !retrieved_hs || !retrieved_pickle) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Unable to retrieve part of the stored account key");
+ g_object_unref(json_parser);
+
+ ret = -1;
+ goto out;
+ }
+ if (strcmp(retrieved_device_id, conn->e2e->device_id) ||
+ strcmp(retrieved_hs, conn->homeserver)) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ "Device ID/HS doesn't matched for stored account key");
+ g_object_unref(json_parser);
+
+ ret = -1;
+ goto out;
+ }
+ pickled_account = g_strdup(retrieved_pickle);
+ if (olm_unpickle_account(conn->e2e->oa, "!", 1, pickled_account, strlen(retrieved_pickle)) ==
+ olm_error()) {
+ purple_connection_error_reason(pc,
+ PURPLE_CONNECTION_ERROR_OTHER_ERROR,
+ olm_account_last_error(conn->e2e->oa));
+ g_object_unref(json_parser);
+ ret = -1;
+ goto out;
+ }
+ g_object_unref(json_parser);
+ purple_debug_info("matrixprpl", "Succesfully unpickled account\n");
+ ret = 1;
+
+out:
+ g_free(pickled_account);
+ return ret;
+}
+
#else
/* ==== Stubs for when e2e is configured out of the build === */
#endif