Browse Source

Validate PM attachment metadata before committing messages

master
evgeny 2 days ago
parent
commit
72d1d3f582
  1. 4
      src/Makefile.am
  2. 18
      src/dm/dm_core.c

4
src/Makefile.am

@ -65,6 +65,8 @@ utun_CORE_SOURCES = \
media_delivery/file_transfer.c \
media_delivery/file_transfer.h \
media_async/media_async.c \
media_async/attachment.c \
media_async/attachment.h \
video/video.c \
transport_layer/dummynet.c \
ntp_time.c \
@ -177,6 +179,8 @@ libutun_a_SOURCES = \
media_delivery/file_transfer.c \
media_delivery/file_transfer.h \
media_async/media_async.c \
media_async/attachment.c \
media_async/attachment.h \
video/video.c \
transport_layer/dummynet.c \
ntp_time.c \

18
src/dm/dm_core.c

@ -306,6 +306,8 @@ static int dm_build_body(struct dm_state* dm, const struct dm_conv* c, uint64_t
media = data;
data += DM_MEDIA_DESC_SIZE;
data_len -= DM_MEDIA_DESC_SIZE;
struct attachment_info info;
if (attachment_decode(data, data_len, &info)) return -1;
}
uint64_t conv_num = (uint64_t)strtoull(c->conv_id, NULL, 10);
uint8_t nonce[DM_NONCE_SIZE];
@ -465,6 +467,10 @@ int dm_accept_message(struct UTUN_INSTANCE* inst, const uint8_t* msg, size_t len
size_t plain_len = 0;
dm_build_nonce(conv, author, seq, nonce);
if (dm_decrypt(c.content_key, nonce, msg + 35 + msg[32], enc_len, plain, &plain_len) != 0) return -1;
if (dm_message_media(msg, len)) {
struct attachment_info info;
if (attachment_decode(plain, plain_len, &info)) return -1;
}
if (dm_exec(dm, "BEGIN IMMEDIATE") != 0) return -1;
int inserted = dm_store_message(dm, conv_id, 0, msg, len);
if (seq > c.last_in_seq) c.last_in_seq = seq; /* Только статистика; не курсор dedup. */
@ -939,6 +945,12 @@ int dm_list_messages_json(struct UTUN_INSTANCE* inst, const char* conv_id, int c
if (enc_len < DM_TAG_SIZE || enc_len > DM_DATA_MAX + DM_TAG_SIZE ||
dm_decrypt(c.content_key, nonce, enc, (size_t)enc_len, (uint8_t*)text, &plen)) goto fail;
text[plen] = '\0';
struct attachment_info attachment = {0};
int file = ct && !strcmp(ct, "file");
if (file) {
if (attachment_decode((const uint8_t*)text, plen, &attachment)) goto fail;
snprintf(text, sizeof(text), "%s", attachment.name);
}
int ready = sqlite3_column_int(st, 7), downloading = sqlite3_column_int(st, 8);
int delivered = sqlite3_column_bytes(st, 9) == DM_MEDIA_RECEIPT_SIZE;
const char* path = ready == 1 ? (const char*)sqlite3_column_text(st, 10) : "";
@ -948,10 +960,12 @@ int dm_list_messages_json(struct UTUN_INSTANCE* inst, const char* conv_id, int c
json_escape(ct ? ct : "", esc_ct, sizeof(esc_ct)); json_escape(text, esc_data, sizeof(esc_data));
json_escape(path, esc_path, sizeof(esc_path));
if (strbuf_addf(&sb, "%s{\"dir\":%d,\"seq\":%llu,\"ts\":%llu,\"author\":\"%llu\",\"ct\":\"%s\",\"data\":\"%s\","
"\"pending\":%s,\"media_status\":\"%s\",\"media_path\":\"%s\",\"media_size\":%llu}", first ? "" : ",", dir,
"\"pending\":%s,\"media_status\":\"%s\",\"media_path\":\"%s\",\"media_size\":%llu,"
"\"content_type\":\"%s\",\"duration_ms\":%u,\"width\":%u,\"height\":%u,\"waveform\":\"%s\"}", first ? "" : ",", dir,
(unsigned long long)seq, (unsigned long long)ts, (unsigned long long)author, esc_ct, esc_data,
sqlite3_column_int(st, 6) ? "true" : "false", status, esc_path,
(unsigned long long)sqlite3_column_int64(st, 11)) < 0) goto fail;
(unsigned long long)sqlite3_column_int64(st, 11), file ? attachment_content_type(attachment.kind) : "text/plain",
attachment.duration_ms, attachment.width, attachment.height, attachment.waveform) < 0) goto fail;
first = 0;
}
if (rc != SQLITE_DONE || strbuf_addf(&sb, "]") < 0 || sb.len + 1 > buf_size) goto fail;

Loading…
Cancel
Save