Route encrypted group preparation through key owner
This commit is contained in:
1 parent
e5a1fc5a48
commit
41696b7e0b
3 files changed
+15
-2
No files matched your search
@@ -76,6 +76,7 @@ static inline size_t b64_decode(const char* src, size_t src_len, uint8_t* dst, s
|
|||||||
/* ── Состояние одного экземпляра (создаётся в chat_core.c) ── */
|
/* ── Состояние одного экземпляра (создаётся в chat_core.c) ── */
|
||||||
|
|
||||||
struct ms_props_cbk; /* member_sync.c */
|
struct ms_props_cbk; /* member_sync.c */
|
||||||
|
struct media_index_result;
|
||||||
struct ms_apply_cbk; /* member_sync.c */
|
struct ms_apply_cbk; /* member_sync.c */
|
||||||
struct group_avatar;
|
struct group_avatar;
|
||||||
|
|
||||||
@@ -119,6 +120,8 @@ void si_register(struct UTUN_INSTANCE* inst, struct DB_SYNC_INSTANCE* si, const
|
|||||||
|
|
||||||
void on_msg_inserted(struct DB_SYNC_INSTANCE* si, const uint8_t message_id[32], uint64_t record_ts,
|
void on_msg_inserted(struct DB_SYNC_INSTANCE* si, const uint8_t message_id[32], uint64_t record_ts,
|
||||||
const char* data, size_t len, uint64_t author, int initial_sync, void* arg);
|
const char* data, size_t len, uint64_t author, int initial_sync, void* arg);
|
||||||
|
/* Разобрать подписанный manifest канального медиа; result освобождается media_index_result_free. */
|
||||||
|
int chat_msg_parse_media_body(const char* body, struct media_index_result* result);
|
||||||
|
|
||||||
/* ── применить настройку group_autoconnect ко всем CHAT-группам (chat_channel.c) ── */
|
/* ── применить настройку group_autoconnect ко всем CHAT-группам (chat_channel.c) ── */
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "../utun_instance.h"
|
#include "../utun_instance.h"
|
||||||
#include "../chat/chat_core.h"
|
#include "../chat/chat_core.h"
|
||||||
#include "../chat/chat_event.h"
|
#include "../chat/chat_event.h"
|
||||||
|
#include "../chat/chat_attachment.h"
|
||||||
#include "../dm/dm_media.h"
|
#include "../dm/dm_media.h"
|
||||||
#include "../dm/dm_history.h"
|
#include "../dm/dm_history.h"
|
||||||
#include "../video/video.h"
|
#include "../video/video.h"
|
||||||
@@ -85,7 +86,13 @@ static void attachment_publish(struct attachment_send_req* req, int error) {
|
|||||||
chat_event_attachment(req->inst, req->is_dm, req->target, req->id, 1);
|
chat_event_attachment(req->inst, req->is_dm, req->target, req->id, 1);
|
||||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "attachment: prepared target=%s pm=%d kind=%d duration=%u dimensions=%ux%u",
|
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "attachment: prepared target=%s pm=%d kind=%d duration=%u dimensions=%ux%u",
|
||||||
req->target, req->is_dm, req->info.kind, req->info.duration_ms, req->info.width, req->info.height);
|
req->target, req->is_dm, req->info.kind, req->info.duration_ms, req->info.width, req->info.height);
|
||||||
if (req->is_dm) {
|
if (req->encrypted && !req->is_dm) {
|
||||||
|
const char* type = req->content_type[0] ? req->content_type : attachment_content_type(req->info.kind);
|
||||||
|
if (chat_attachment_send(req->inst, req->target, req->output, &req->info, type, req->reply_to, req->request_id)) {
|
||||||
|
chat_event_submitted(req->inst, req->request_id, 0);
|
||||||
|
if (remove(req->output) && errno != ENOENT) DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "attachment: encrypted source cleanup failed");
|
||||||
|
}
|
||||||
|
} else if (req->is_dm) {
|
||||||
struct dm_file_req* file = u_calloc(1, sizeof(*file));
|
struct dm_file_req* file = u_calloc(1, sizeof(*file));
|
||||||
if (file) {
|
if (file) {
|
||||||
file->inst = req->inst; file->info = req->info; file->remove_source = 1;
|
file->inst = req->inst; file->info = req->info; file->remove_source = 1;
|
||||||
@@ -164,7 +171,8 @@ void attachment_send_trampoline(void* arg) {
|
|||||||
for (unsigned i = 0; i < 16; i++) snprintf(hex + 2 * i, 3, "%02x", uuid[i]);
|
for (unsigned i = 0; i < 16; i++) snprintf(hex + 2 * i, 3, "%02x", uuid[i]);
|
||||||
memcpy(req->id, uuid, sizeof(req->id));
|
memcpy(req->id, uuid, sizeof(req->id));
|
||||||
const char* base = req->inst->config->global.db_path;
|
const char* base = req->inst->config->global.db_path;
|
||||||
int n = snprintf(req->output, sizeof(req->output), "%s/media/%s/%s.%s", base[0] ? base : ".",
|
int n = snprintf(req->output, sizeof(req->output), "%s/%s/%s/%s.%s", base[0] ? base : ".",
|
||||||
|
req->encrypted && !req->is_dm ? "encrypted-prepared" : "media",
|
||||||
req->is_dm ? "pm-prepared" : req->target, hex, req->info.kind == ATTACHMENT_VOICE ? "opus" : "mp4");
|
req->is_dm ? "pm-prepared" : req->target, hex, req->info.kind == ATTACHMENT_VOICE ? "opus" : "mp4");
|
||||||
if (n < 0 || (size_t)n >= sizeof(req->output)) {
|
if (n < 0 || (size_t)n >= sizeof(req->output)) {
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment: output path too long"); req->output[0] = 0; attachment_publish(req, -1); return;
|
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment: output path too long"); req->output[0] = 0; attachment_publish(req, -1); return;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ struct attachment_send_req {
|
|||||||
struct UTUN_INSTANCE* inst;
|
struct UTUN_INSTANCE* inst;
|
||||||
char target[64]; /* Десятичный channel_id либо conv_id без префикса dm:, зафиксированный до подготовки. */
|
char target[64]; /* Десятичный channel_id либо conv_id без префикса dm:, зафиксированный до подготовки. */
|
||||||
int is_dm;
|
int is_dm;
|
||||||
|
int encrypted; /* Отдельный случайный ключ группового вложения с ручной выдачей. */
|
||||||
|
char content_type[32]; /* Необязательный исходный MIME (например image/png). */
|
||||||
uint64_t dm_generation; /* Захватывается до подготовки и сохраняется во всех её стадиях. */
|
uint64_t dm_generation; /* Захватывается до подготовки и сохраняется во всех её стадиях. */
|
||||||
unsigned dm_paths_held;
|
unsigned dm_paths_held;
|
||||||
uint8_t reply_to[32]; /* Оригинал канального ответа, зафиксированный до подготовки. */
|
uint8_t reply_to[32]; /* Оригинал канального ответа, зафиксированный до подготовки. */
|
||||||
|
|||||||
Reference in new issue
Block a user