Bind encrypted manifests and request keys after verified download
This commit is contained in:
1 parent
41696b7e0b
commit
61d1561612
1 file changed
+33
-1
+33
-1
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "chat_core_priv.h"
|
||||
#include "chat_attachment.h"
|
||||
#include "chat_event.h"
|
||||
#include "chat_feedback.h"
|
||||
#include "chat_poll.h"
|
||||
@@ -266,6 +267,15 @@ static void on_media_registered(void* arg, int err, const struct media_index_res
|
||||
const char* filename = base ? base + 1 : mctx->media_dest;
|
||||
char attrs[1100]; snprintf(attrs, sizeof(attrs), "{\"st\":\"fl\",\"fp\":\"%s\"}", filename);
|
||||
|
||||
if (!strcmp(mctx->content_type, ENCRYPTED_ATTACHMENT_TYPE)) {
|
||||
uint8_t crypto_id[16], message_id[32];
|
||||
if (chat_attachment_identity(full_data, full_data_len, crypto_id) ||
|
||||
chat_message_id(db_sync_instance_group_id(si), ts, json_sig, message_id) ||
|
||||
chat_attachment_bind(mctx->inst, mctx->channel_id, crypto_id, message_id, result->content_hash)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted media: cannot publish without bound author key ch=%s", mctx->channel_id);
|
||||
u_free(sig_msg); u_free(json); u_free(full_data); media_submit_finish(mctx, 0); return;
|
||||
}
|
||||
}
|
||||
int ret = db_sync_insert_signed(si, json, strlen(json), json_sig, 64, ts, attrs);
|
||||
if (ret != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: media insert failed ret=%d", CC_ID, ret);
|
||||
@@ -680,6 +690,11 @@ static void md_download_done_cb(void* arg, int err) {
|
||||
struct md_done_ctx* ctx = (struct md_done_ctx*)arg;
|
||||
struct chat_core_ctx* cc = CC(ctx->inst);
|
||||
if (!err) {
|
||||
if (!strcmp(ctx->content_type, ENCRYPTED_ATTACHMENT_TYPE)) {
|
||||
uint8_t message[32];
|
||||
if (!chat_message_id(strtoull(ctx->channel_id, NULL, 10), ctx->ts, ctx->author_sig, message))
|
||||
chat_attachment_downloaded(ctx->inst, ctx->channel_id, message);
|
||||
}
|
||||
char attrs[1024];
|
||||
snprintf(attrs, sizeof(attrs), "{\"st\":\"fl\",\"fp\":\"%s\"}", ctx->dest_relpath);
|
||||
chat_core_update_local_attrs(ctx->inst, ctx->channel_id, ctx->ts, ctx->author_sig, attrs);
|
||||
@@ -783,7 +798,7 @@ static void extract_base_filename(const char* body, char* out, size_t out_sz) {
|
||||
/* Разбор тела "d" медиасообщения в media_index_result. Формат:
|
||||
* <name>|<file_size>|<block_size>|<num_blocks>|<media_id_hex>|<content_hash_hex>|<id_hex>,<sig_hex>,...
|
||||
* Выделяет result->block_ids/block_sigs (освобождать через media_index_result_free). */
|
||||
static int chat_msg_parse_media_body(const char* body, struct media_index_result* result) {
|
||||
int chat_msg_parse_media_body(const char* body, struct media_index_result* result) {
|
||||
memset(result, 0, sizeof(*result));
|
||||
if (!body) return -1;
|
||||
const char* p = body;
|
||||
@@ -917,6 +932,9 @@ void on_msg_inserted(struct DB_SYNC_INSTANCE* si, const uint8_t message_id[32],
|
||||
struct chat_core_ctx* cc = CC(inst);
|
||||
if (!cc) return;
|
||||
char ch_id[32]; snprintf(ch_id, sizeof(ch_id), "%llu", (unsigned long long)db_sync_instance_group_id(si));
|
||||
if (chat_attachment_observe(inst, ch_id, message_id, author, data, len)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "encrypted media: invalid manifest ch=%s", ch_id); return;
|
||||
}
|
||||
chat_feedback_check_message(inst, ch_id, message_id);
|
||||
uint8_t evt[73]; uint8_t cl = (uint8_t)strlen(ch_id); evt[0] = cl; memcpy(evt + 1, ch_id, cl);
|
||||
memcpy(evt + 1 + cl, &author, 8);
|
||||
@@ -1041,6 +1059,20 @@ void chat_core_attachment_download(struct UTUN_INSTANCE* inst, const char* chann
|
||||
uint8_t author_sig[64]; memcpy(author_sig, sig_blob, 64);
|
||||
sqlite3_finalize(st);
|
||||
|
||||
if (!strcmp(content_type, ENCRYPTED_ATTACHMENT_TYPE)) {
|
||||
uint8_t message[32];
|
||||
if (chat_message_id(strtoull(channel_id, NULL, 10), (uint64_t)db_ts, author_sig, message)) return;
|
||||
chat_attachment_want(inst, channel_id, message);
|
||||
sqlite3_stmt* encrypted = NULL;
|
||||
if (sqlite3_prepare_v2(cc->db, "SELECT cipher_path FROM attachment_keys WHERE channel=? AND message_id=? AND downloaded=1",
|
||||
-1, &encrypted, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_text(encrypted, 1, channel_id, -1, SQLITE_STATIC); sqlite3_bind_blob(encrypted, 2, message, 32, SQLITE_STATIC);
|
||||
int present = sqlite3_step(encrypted) == SQLITE_ROW && ma_file_size((const char*)sqlite3_column_text(encrypted, 0)) > 0;
|
||||
sqlite3_finalize(encrypted);
|
||||
if (present) { chat_attachment_downloaded(inst, channel_id, message); return; }
|
||||
} else DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "encrypted media: local file lookup failed: %s", sqlite3_errmsg(cc->db));
|
||||
}
|
||||
|
||||
/* сбрасываем пометку «файл есть»: файл мог быть вычищен кешем, а local_attrs ещё "fl".
|
||||
по завершении md_download_done_cb снова запишет st=fl (успех) или st=er (ошибка). */
|
||||
chat_core_update_local_attrs(inst, channel_id, (uint64_t)db_ts, author_sig, "{}");
|
||||
|
||||
Reference in new issue
Block a user