Возможность передавать файлы была бы полезной функцией, чтобы включить осведомителей и т. Д.
Вау, это старая проблема. Пришло время сделать это. Поговорим о передаче файлов. Отчасти это запрос на обратную связь, отчасти попытка убедить себя, а отчасти - мозговую трепку, но, надеюсь, это полезно.
Я вижу два основных варианта использования передачи файлов. Активные пользователи отправляют и получают файлы во время разговоров и ожидают, что файл будет частью их разговора. Удаление файлов предназначено для значительного меньшинства пользователей Ricochet, которые хотят оставаться в сети и иметь возможность получать файлы в любое время, даже если они не активны в данный момент.
Как и большинство приложений для обмена сообщениями, мы хотим, чтобы передача файлов выполнялась во время разговора , и они не должны требовать использования какого-либо другого приложения (включая браузер).
Перетаскивание файла в беседу - это нормальный способ отправки файла. Возможно, таким способом легко случайно отправить файл. Это можно смягчить, перетащив файл в поле ввода сообщения и разрешив вводить сообщение перед отправкой или, что проще, с помощью обратного отсчета перед отправкой . Должен быть еще один видимый метод пользовательского интерфейса для отправки файлов, например, кнопка в заголовке беседы или рядом с вводом сообщения.
Срок действия предлагаемых файлов
Модель угроз Ricochet запрещает автоматическое сохранение данных разговоров (включая файлы). Модель угроз также рассматривает контакты как потенциальных злоумышленников, поэтому мы хотим сократить набор действий, которые контакт может инициировать без одобрения пользователя. Это говорит о том, что мы должны требовать явного принятия по умолчанию для передачи файлов. Пользователь должен явно выбрать, где сохранить каждый файл, если он не настроил расположение по умолчанию. Это нормально для варианта использования активного пользователя, но для удаления файлов нам понадобится
Активные предложения или переводы должны быть легко заметны обеим сторонам. Помимо отображения прогресса передачи в разговоре , должен быть прогресс в заголовке разговора (вкладка переводов?) И / или где-то в статусе глобальной передачи . Это особенно важно, потому что разговор может продолжаться, пока продолжаются переводы. Когда перевод закончится, его нужно переместить в конец разговора.
Завершенные переводы открываются щелчком с предупреждением, аналогичным предупреждению браузера.
Известно, что Tor ненадежен, поэтому возможность возобновления будет важна. Мы должны повторно подключаться и возобновлять автоматически, когда это возможно. Если прошло слишком много времени или один из клиентов потерял свою историю, возобновление должно быть возможно, сохранив существующий неполный файл .
Отображение изображений внутри разговоров - это стандартная функция обмена сообщениями. Это легко сделать, если у нас есть передача файлов, за исключением того, что я не доверяю декодерам изображений . Как только мы найдем надежный и безопасный для памяти декодер или кроссплатформенную песочницу в стиле seccomp, это стоит сделать.
Кто-то указал, что мы можем выполнить предварительную выборку файлов, по крайней мере, путем создания соединений и буферизации до некоторого предела в памяти, чтобы процесс передачи казался более быстрым.
Было бы неплохо разрешить передачу пакетов файлов или целых папок до некоторого разумного предела.
Было бы здорово иметь способ автоматической проверки хэша загруженного файла на отправляющем сервере.
Данные файла не могут быть отправлены через соединение по основному протоколу Ricochet. Несмотря на то, что мы упаковываем данные в пакеты, из-за свойств буферизации для потоков Tor очень большие объемы данных будут находиться в очередях при лавинной рассылке скрытых сервисных соединений. Это вызывает чрезмерную задержку (часто 30 с и более) для этого потока. Любая другая форма управления скоростью слишком сильно повлияет на скорость передачи.
Простой ответ - открыть дополнительные подключения к одноранговому сервису. Эти соединения будут мультиплексированы Tor в той же цепи, но поведение буферизации значительно лучше. При случайном тестировании не наблюдается значительного влияния на задержку сообщения при лавинной передаче данных в другой поток в той же цепи.
Мы также могли бы использовать параметры изоляции цепи, чтобы заставить Tor создавать новые цепи для передач. Неясно, будет ли это полезно для пропускной способности или задержки, и неясно, окажет ли создание дополнительных параллельных каналов значительное влияние на анонимность или анализ трафика.
Протокол Ricochet не допускает более одного аутентифицированного соединения для каждого контакта, потому что было бы неоднозначно, какое соединение следует использовать, и это могло бы нарушить ожидания по упорядочиванию сообщений. Если дополнительные соединения используют протокол Рикошета, им необходимо будет аутентифицироваться иначе, чтобы указать, что соединение используется только для передачи данных.
Поскольку передача данных происходит через вторичные соединения, мы не обязаны упаковывать данные с помощью протокола Ricochet. Здесь стоит продумать варианты.
Моей первоначальной мыслью было использовать протокол Ricochet для передачи файловых данных по дополнительным соединениям. Это не совсем просто.
Преимущества:
Минусы:
Есть несколько более старых работ о том, как это может выглядеть из ветки WIP в FileTransferChannel.proto и FileTransferDataChannel.proto .
Клиенты Ricochet могут предлагать файлы через HTTP, используя простой внутренний сервер и уникальные URL-адреса, аналогичные OnionShare . Этот сервер может быть на другом (возможно, случайном) порте той же скрытой службы, на новых эфемерных службах или даже использовать один и тот же порт с помощью обнаружения протокола.
Преимущества:
Минусы:
В Ricochet нет необходимости в полностью полнофункциональном и совместимом со спецификациями HTTP-клиенте, потому что здесь вариант использования очень минимален. Чтобы снизить вероятность ошибок, насколько это возможно, я бы ограничил реализацию функциями, которые нам _ нужны_, и не использовал бы (например) фрагментированное кодирование передачи или эзотерические параметры. Мы могли бы даже заставить Connection: close
если это будет полезно. В итоге получается довольно небольшой объем кода, доступного для сети, и, как правило, он совместим с другими клиентами и серверами.
Я предпочитаю разместить HTTP-сервер на случайном порте под той же скрытой службой. Создание новых сервисов иногда происходит медленно или ненадежно и включает в себя множество новых каналов и заметную сетевую активность. Это также означает, что нам может потребоваться одно и то же имя хоста .onion, что не позволяет одноранговым узлам принудительно устанавливать соединение с произвольным .onion.
Если сервер всегда работает, контакты и неконтакты могут быть найдены в любое время, хотя это не должно иметь никакого значения. Если сервер активен только тогда, когда есть активные предложения файлов, это состояние может быть обнаружено контактами или неконтактами, которые могут узнать порт.
Нет смысла или необходимости пытаться маскироваться под кого-либо, кроме клиента Ricochet. Все правильно сформированные запросы, которые не являются допустимыми файловыми запросами, должны отклоняться с общей ошибкой 404.
Я предлагаю следующие URL-адреса для скачивания:
http://[address].onion:[port]/ricochet/fetch/[uniqid]/[filename]
[address] must be the contact's ricochet connection address
[uniqid] is a large (>=128bit) random identifier
[filename] is the URL-encoded original name of the file
Only HTTP is permitted, no HTTPS. We do not want to require a TLS
implementation, and .onion makes it unnecessary.
Clients may refuse transfer URLs without a /ricochet/fetch/ prefix.
URL-адреса файлов относятся к конкретной передаче и предназначены для одноразового использования. Запросы диапазона должны поддерживаться, чтобы разрешить возобновление, и могут быть разрешены для параллельной загрузки. Серверы должны прекратить предлагать URL, как только они считают, что у получателя есть полная копия.
Мы можем упаковать предложение файла в расширенное сообщение чата:
message ChatMessage {
required string message_text = 1;
optional uint32 message_id = 2;
optional int64 time_delta = 3;
// Indicates a file transfer offer. message_text must begin with a valid
// file transfer URL, terminated by the first whitespace or end of message.
// The rest of message_text, if any, should be displayed as a user message
// along with the file.
optional FileInfo file_info = 4;
}
message FileInfo {
// required
optional string file_name = 1;
optional uint64 file_size = 2;
// optional
optional string content_type = 3;
}
message ChatAcknowledge {
optional uint32 message_id = 1;
optional bool accepted = 2 [default = true];
optional bool file_received = 3;
optional bool file_refused = 4;
}
Подтверждение этого сообщения также подтверждает предложение файла. URL-адрес может быть немедленно доступен для загрузки файла. В дополнение к обычному подтверждению сообщения получатель должен отправить дополнительный ChatAcknowledge
когда передача завершена или если она отклонена, с соответствующим набором полей. Отправители должны быть готовы к тому, что передача будет завершена только на основе переданных данных, и не полагаться на ChatAcknowledge
для поддержки старых клиентов или альтернативных загрузчиков.
У этого есть изящное свойство быть полностью совместимым с клиентами, которые не реализуют передачу файлов; пользователь увидит URL-адрес и сможет загрузить его в браузере. Однако это не имеет особого значения.
XXX. Здесь отправитель не определил способ указать отмену.
Я хотел бы продвинуться в этом довольно быстро, поэтому я собираюсь очень скоро закрепить протокол и основные решения UX.
Уже написан хороший фрагмент кода, но он нуждается в некоторых исправлениях и потребует изменений на основе решений, принятых здесь.
Есть предположения?
Мне это нравится. Я согласен с тем, что направление HTTP-сервера кажется правильным.
Пара мыслей - без определенного порядка и приоритета:
У этого есть изящное свойство быть полностью совместимым с клиентами, которые не реализуют передачу файлов; пользователь увидит URL-адрес и сможет загрузить его в браузере.
- Это открывает несколько упомянутых выше векторов атак, которых http-клиент с рикошетом может избежать, а браузер - нет. Уже есть предупреждения об открытии ссылок, но мне интересно, может ли обмен сообщениями и статус поддерживаемых функций передачи файлов открыть трещину для фишинга.
- Стоит ли обращать внимание на векторы атак без аутентификации клиента при загрузке? Я не могу придумать ничего, что могло бы иметь решающее значение для модели угроз ... но для протокола, вот некоторые вещи, которые пришли мне в голову:
Ну, есть аутентификация с использованием URL-адреса, уникального для получателя и файла. Проблема заключается в том, что он может быть передан: эта проверка подлинности не идентифицирует получателя никому, кроме отправителя (и это не криптографически), и не содержит секрета, который получатель может пожелать защитить.
- Существует ли вероятность атаки типа DoS / slowloris, когда злоумышленник заставляет жертву обслужить файл, а затем самого злоумышленника, или когда несколько человек открывают и заполняют пул соединений?
Я думаю, что варианта DoS нет, пока мы ограничиваем количество подключений для каждого предлагаемого файла. Поскольку цель состоит в том, чтобы один раз поделиться одним файлом с одним человеком (с учетом резюме и других проблем), мы можем быть строгими в этом отношении. Также для удобства использования может быть хорошей идеей установить минимальную скорость передачи.
- Существует ли атака атрибуции, при которой злоумышленник заставляет кого-то обслуживать файл, а затем он может доказать другому человеку, что он это делает?
Интересно! Мне нравится эта атака. Есть слабые средства защиты, связанные с изменением аутентификации клиента, но на самом деле они просто препятствуют совместному использованию URL-адресов. Мне также нравится, что эти URL-адреса не идентифицируют своего предполагаемого получателя, кроме отправителя, который их сгенерировал.
Чтобы фактически удалить криптографическую атрибуцию, нам пришлось бы обслуживать файлы в эфемерных службах. Я не уверен, требуется ли для этого одна временная услуга на _контакт_. Технически Боб может убедить Алису отправить опасный файл, Боб делится адресом с Кэрол, а затем Кэрол может отдельно заставить Алису отправить безобидный файл, чтобы Кэрол могла подтвердить, что опасный URL-адрес пришел от Алисы.
Самый безопасный ответ с точки зрения атрибуции - использовать уникальную временную службу для каждого контакта за сеанс. Меня беспокоит следующее: 1) задержка публикации службы; 2) требуется _много_ дополнительных цепей; 3) более четко проявляется при анализе трафика.
Я думаю, что я могу использовать одну временную службу для передачи всех файлов в сеансе. По крайней мере, он все еще отличается криптографически, уменьшает все эти воздействия, и случай, когда он терпит неудачу, является надуманным.
- Имя файла и тип содержимого, вероятно, подвержены тем же проблемам с Юникодом, что и в # 338.
Тип содержимого - это MIME-тип, поэтому проблем с Unicode здесь нет. Для очистки имен файлов я давно придумал несколько правил , над которыми нужно подумать. Там надо быть очень осторожным.
- Клиенты должны отклонять перенаправления HTTP и другие попытки перехватить поток HTTP.
Согласен.
- Я думаю, я бы сказал, что недействительные URL-адреса должны просто запускать закрытие соединения, а не 404.
Без ответа? Хм. Это делает более неоднозначным для рикошетного клиента определение наличия сбоя в сети или недействительности URL-адреса. В противном случае у меня нет проблем с этим, и я бы не хотел ничего отправлять обратно неавторизованным клиентам.
У этого есть изящное свойство быть полностью совместимым с клиентами, которые не реализуют передачу файлов; пользователь увидит URL-адрес и сможет загрузить его в браузере.
- Это открывает несколько упомянутых выше векторов атак, которых http-клиент с рикошетом может избежать, а браузер - нет. Уже есть предупреждения об открытии ссылок, но мне интересно, может ли обмен сообщениями и статус поддерживаемых функций передачи файлов открыть трещину для фишинга.
Меры предосторожности здесь должны быть такими же, как и при открытии любого URL-адреса. Я не думаю, что это обязательно тот вариант использования, для которого стоит разрабатывать - я не уверен, что в конечном итоге он останется в силе.
Неясно, какая реализация C ++ / Qt будет достаточно безопасной для использования
Возможно, он уже слишком велик для этого варианта использования, но написан с учетом требований безопасности: https://github.com/reyk/httpd
message FileInfo {
// required
optional string file_name = 1;
optional uint64 file_size = 2;
// optional
optional string content_type = 3;
}
Интересно, почему вы хотите сохранить дополнительный тип содержимого помимо видимого пользователем расширения имени файла? Может ли это привести к путанице на стороне получателя, технически в том, какую программу запускать, или нетехнически в том, чего ожидает пользователь?
XXX. Здесь отправитель не определил способ указать отмену.
Разве флаг bool file_refused
в сообщении ChatAcknowledge не является способом сделать это? Или вы имеете в виду после того, как файл был принят и находясь в процессе передачи?
Я думаю, я бы сказал, что недействительные URL-адреса должны просто запускать закрытие соединения, а не 404.
👍
Интересно! Мне нравится эта атака. Есть слабые средства защиты, связанные с изменением аутентификации клиента, но на самом деле они просто препятствуют совместному использованию URL-адресов. Мне также нравится, что эти URL-адреса не идентифицируют своего предполагаемого получателя, кроме отправителя, который их сгенерировал.
Возможно ли за счет совместимости клиента зашифровать содержимое файла открытым ключом получателя или чем-то вроде идентификатора сеанса?
Интересно, почему вы хотите сохранить дополнительный тип содержимого помимо видимого пользователем расширения имени файла? Может ли это привести к путанице на стороне получателя, технически в том, какую программу запускать, или нетехнически в том, чего ожидает пользователь?
Хм. Я имею в виду два применения:
Обнаружение их на основе расширения по крайней мере так же ненадежно, как и наличие (возможно, неправильного) типа содержимого. Вы правы в том, что на # 2 нужно быть осторожным, чтобы убедиться, что мы не показываем что-то как изображение, когда оно действительно открывается как исполняемый файл. Только по этой причине, возможно, лучше удалить тип содержимого и обнаруживать только по расширению. Хм..
XXX. Здесь отправитель не определил способ указать отмену.
Разве флаг bool file_refused в сообщении ChatAcknowledge не является способом сделать это? Или вы имеете в виду после того, как файл был принят и находясь в процессе передачи?
Отправлять ChatAcknowledge
для полученных вами сообщений - нет смысла подтверждать свои собственные сообщения. Таким образом, file_refused
предоставляет получателю возможность отменить, но я еще не определил эквивалент для отправителя, чтобы сказать «Я больше не предлагаю этот файл».
Возможно ли за счет совместимости клиента зашифровать содержимое файла открытым ключом получателя или чем-то вроде идентификатора сеанса?
Шифрование файла не решает проблему атрибуции @ s-rah: это означает лишь то, что вам нужно предоставить ключ дешифрования вместе с URL-адресом. Обычные способы шифрования открытого ключа получателя имеют ту же проблему, потому что обычно вы просто обертываете симметричный ключ шифрования, используемый для данных файла.
Было бы более полезно потребовать, чтобы получатель отказался от своего личного ключа идентификации, чтобы продемонстрировать, что отправитель предлагает файл. Для этого нам просто нужно аутентифицировать соединение с открытым ключом получателя перед обслуживанием файлов, но это плохо согласуется с HTTP (нет, без TLS). Это было бы аргументом в пользу использования другого протокола.
Совершенно другой подход состоит в том, чтобы сервер-получатель размещал сервер, а отправитель действовал как клиент для загрузки данных. Это может работать с HTTP или чем-то еще, но у него есть некоторые недостатки в гибкости. В этом случае проблем с атрибуцией не возникнет.
Когда мы реализуем встроенные изображения, нам понадобится способ узнать, какие файлы являются изображениями.
Хочу заявить, что полностью согласен с вашим предыдущим утверждением: I don't trust image decoders
.
нет смысла подтверждать свои собственные сообщения.
Плохо, я прочитал "получатель", хотя на самом деле указано "отправитель" :)
Было бы более полезно потребовать, чтобы получатель отказался от своего личного ключа идентификации, чтобы продемонстрировать, что отправитель предлагает файл. Для этого нам просто нужно аутентифицировать соединение с открытым ключом получателя перед обслуживанием файлов, но это плохо согласуется с HTTP (нет, без TLS).
Звучит интересно, у вас есть примеры, когда это делают другие протоколы? Или как это можно было настроить? Думаю, здесь может помочь структура Noise, как указано в https://github.com/ricochet-im/ricochet/issues/72#issuecomment -258894126.
Если кому-то это нужно как можно скорее, тогда вы должны использовать луковицу вместе с рикошетом.
----- НАЧАТЬ ПОДПИСАННОЕ СООБЩЕНИЕ PGP -----
Хеш: SHA512
Джон Брукс:
Разрешен только HTTP, без HTTPS. Мы не хотим требовать TLS
реализация, а .onion делает его ненужным.
Мне неясно, является ли это частью модели угроз Рикошета,
но в таких средах, как Whonix, клиент Tor может читать содержимое
трафика .onion, но не трафика TLS (поскольку TLS расшифровывается в
разные ВМ).
----- НАЧАТЬ ПОДПИСЬ PGP -----
iQIcBAEBCgAGBQJYKlGYAAoJELPy0WV4bWVwu / gQAI / 7bmPTKwbcsjEntuEjc03j
nQFKDvSMg05FXR9rljFym5E ++ pr1FEteKb2qAu0Gub9CbkxCWhibBYNQHi1aFgy5
wgO07yom0oJI4JxBXA185TNSJKE7 + LnDAqUCT0H1d0yCy5t4TZfFQHJFLdhOjdk +
GD + Lbuv3pH0GIInsK7iAFQlps0bQmI8aNrNAgoiuk3iWI9MqGFZ8BoXZlabMeGnF
O0OeaibMjtvtuvX4mRsgTFZdNzzUmSfmkoYsABHDK / He4rcnUg6LUetVz16YKzuo
i5Oxy + dQZ6FHHICsQq2Ajg35LfW95I27jcm0QBGFZ08tu3Igt7DFqw9Sq1Ydg5Hl
J / HckRIA5pIJJUcOUa4ynFyk2t / hA0fQEjSoy9C66GnH4Fzt6X / Izs0CDkPkZOQ /
+ Vo7wYkqyKcInn2uu7sb62lopX7L6QKHMORRiO / 5echUMCNCs5fVx7pDenIKvXew
88QcZ / UkR48N9RdKaNC + UdCt3a / vJzQhbzB65cgGuPtvJLhUPFay2IK / szP0 / Drw
gPXT + kwbCcBKqbmzkniPysn0Z62wXOlZAfiI / BJ5TqbqILNlhyR9HFSb9MIImiNL
Es + Q3vteUEm6pGVGPnqMZMm2dxVYmP5xx3pHhqq7GjaeGplNEi0ZwTsmSpfCztPB
Y6ksrSAXNDadT0ijrXfu
= TeTg
----- КОНЕЦ ПОДПИСЬ PGP -----
Возможный обходной путь : по крайней мере, в Windows и Linux есть gpg4usb (gpg4usb.org), автономная программа GPG, которая сохраняет все файлы в зашифрованном виде в виде текстовых файлов:
Интерфейс:
Вывод (откройте _data.docx.asc_ в блокноте):
Подводные камни:
Обновление: эта программа использует устаревшую версию GPG, поэтому, хотя она, вероятно, все еще работает в качестве временного решения, она может не работать с другими недавно обновленными инструментами, совместимыми с GPG.
1) Функция передачи файлов очень важна в реальной рабочей среде. По работе я часто бываю мобильным и вынужден обмениваться сообщениями и файлами с коллегами (редко изображениями, чаще всего .docx, xls и другие типы файлов). Конечно, мы должны быть уверены, что они перемещаются по безопасному и ЗАЩИЩЕННОМУ каналу.
Совершенно необходимо (запрос №1), чтобы файл не мог быть перехвачен или взят кем-либо, кроме предполагаемого получателя.
Поэтому я категорически и категорически против любого использования общедоступных URL-адресов (даже если они зашифрованы или что-то в этом роде), которые каким-либо образом видны или легко выводятся (и могут передаваться другим). Содержимое разговора, а также файл должны оставаться строго конфиденциальными для отправителя и получателя (чистый P2P, а не совместное использование вообще).
Тип «атаки», который следует учитывать, если использование «общедоступных» URL-адресов исходит от самого получателя.
Подумайте о не очень лояльном сотруднике, который знает об этом механизме и передает по другому каналу (может быть, даже второй чат Ricochet IM без каких-либо следов ...) URL-адрес третьей стороне, как только он его получил ... Третья сторона загружает файл, сотрудник тоже загружает его и делает вид, что не сделал ничего плохого ... В системе без каких-либо общедоступных / видимых / копируемых ссылок, в которой единственный вариант, который он получает в окне чата, - это загрузить файл на его ПК или откажитесь от него, он - единственный другой человек (кроме отправителя), имеющий доступ к этому файлу, и если он просочится, то нет никаких оправданий тому, что это связано с каким-либо «общедоступным URL-адресом http ....
2) Вы смотрели на другие решения для чата, которые предлагают передачу файлов P2P, чтобы получить представление о том, что что-то уже работает?
Ожидая появления этой опции, мы используем поле QTox, и у него есть работающая и приятная опция передачи файлов, полностью встроенная в чат.
(в прошлом я также использовал uVNC, и он легко передавал файлы через защищенные туннели p2p)
3) Моим старым чутьем было бы отказаться от любой идеи протокола http и начать работу над эффективной пакетизацией файлов в существующий проверенный, безопасный и надежный протокол рикошета (с необходимыми небольшими изменениями и, возможно, необязательным дополнительным уровнем простого шифрования) , как описано в вашем первом варианте.
Даже просто обернуть файл Mime64 + облегченное скремблирование (и сделать обратное при приеме) будет достаточно в качестве оболочки.
Я предпочитаю безопасность и уверенность в том, что мои файлы не могут попасть в руки конкурентов, а не более изящный и / или более быстрый механизм передачи.
4) Не забывайте, что большинство людей по-прежнему используют электронную почту (незашифрованное кодирование файлов вложений MIME-64) для отправки файлов ... медленно, неэффективно и определенно небезопасно.
Максимальная скорость не является критической частью передачи в реальной мобильной среде (а некоторые мобильные соединения, используемые удаленно, в любом случае даже не способны поддерживать огромные скорости ...).
Для меня более важно, чтобы у меня был индикатор статуса передачи моим сверстникам, чтобы иметь возможность `` приостановить / возобновить '' отправку длинных файлов и иметь механизм, обрабатывающий потерянные соединения (что часто происходит на поле) с текущими переводами.
Самый полезный комментарий
Вау, это старая проблема. Пришло время сделать это. Поговорим о передаче файлов. Отчасти это запрос на обратную связь, отчасти попытка убедить себя, а отчасти - мозговую трепку, но, надеюсь, это полезно.
UX
Я вижу два основных варианта использования передачи файлов. Активные пользователи отправляют и получают файлы во время разговоров и ожидают, что файл будет частью их разговора. Удаление файлов предназначено для значительного меньшинства пользователей Ricochet, которые хотят оставаться в сети и иметь возможность получать файлы в любое время, даже если они не активны в данный момент.
Как и большинство приложений для обмена сообщениями, мы хотим, чтобы передача файлов выполнялась во время разговора , и они не должны требовать использования какого-либо другого приложения (включая браузер).
Перетаскивание файла в беседу - это нормальный способ отправки файла. Возможно, таким способом легко случайно отправить файл. Это можно смягчить, перетащив файл в поле ввода сообщения и разрешив вводить сообщение перед отправкой или, что проще, с помощью обратного отсчета перед отправкой . Должен быть еще один видимый метод пользовательского интерфейса для отправки файлов, например, кнопка в заголовке беседы или рядом с вводом сообщения.
Срок действия предлагаемых файлов
Модель угроз Ricochet запрещает автоматическое сохранение данных разговоров (включая файлы). Модель угроз также рассматривает контакты как потенциальных злоумышленников, поэтому мы хотим сократить набор действий, которые контакт может инициировать без одобрения пользователя. Это говорит о том, что мы должны требовать явного принятия по умолчанию для передачи файлов. Пользователь должен явно выбрать, где сохранить каждый файл, если он не настроил расположение по умолчанию. Это нормально для варианта использования активного пользователя, но для удаления файлов нам понадобится
Активные предложения или переводы должны быть легко заметны обеим сторонам. Помимо отображения прогресса передачи в разговоре , должен быть прогресс в заголовке разговора (вкладка переводов?) И / или где-то в статусе глобальной передачи . Это особенно важно, потому что разговор может продолжаться, пока продолжаются переводы. Когда перевод закончится, его нужно переместить в конец разговора.
Завершенные переводы открываются щелчком с предупреждением, аналогичным предупреждению браузера.
Известно, что Tor ненадежен, поэтому возможность возобновления будет важна. Мы должны повторно подключаться и возобновлять автоматически, когда это возможно. Если прошло слишком много времени или один из клиентов потерял свою историю, возобновление должно быть возможно, сохранив существующий неполный файл .
UX будущего
Отображение изображений внутри разговоров - это стандартная функция обмена сообщениями. Это легко сделать, если у нас есть передача файлов, за исключением того, что я не доверяю декодерам изображений . Как только мы найдем надежный и безопасный для памяти декодер или кроссплатформенную песочницу в стиле seccomp, это стоит сделать.
Кто-то указал, что мы можем выполнить предварительную выборку файлов, по крайней мере, путем создания соединений и буферизации до некоторого предела в памяти, чтобы процесс передачи казался более быстрым.
Было бы неплохо разрешить передачу пакетов файлов или целых папок до некоторого разумного предела.
Было бы здорово иметь способ автоматической проверки хэша загруженного файла на отправляющем сервере.
Протокол
Подключения
Данные файла не могут быть отправлены через соединение по основному протоколу Ricochet. Несмотря на то, что мы упаковываем данные в пакеты, из-за свойств буферизации для потоков Tor очень большие объемы данных будут находиться в очередях при лавинной рассылке скрытых сервисных соединений. Это вызывает чрезмерную задержку (часто 30 с и более) для этого потока. Любая другая форма управления скоростью слишком сильно повлияет на скорость передачи.
Простой ответ - открыть дополнительные подключения к одноранговому сервису. Эти соединения будут мультиплексированы Tor в той же цепи, но поведение буферизации значительно лучше. При случайном тестировании не наблюдается значительного влияния на задержку сообщения при лавинной передаче данных в другой поток в той же цепи.
Мы также могли бы использовать параметры изоляции цепи, чтобы заставить Tor создавать новые цепи для передач. Неясно, будет ли это полезно для пропускной способности или задержки, и неясно, окажет ли создание дополнительных параллельных каналов значительное влияние на анонимность или анализ трафика.
Протокол Ricochet не допускает более одного аутентифицированного соединения для каждого контакта, потому что было бы неоднозначно, какое соединение следует использовать, и это могло бы нарушить ожидания по упорядочиванию сообщений. Если дополнительные соединения используют протокол Рикошета, им необходимо будет аутентифицироваться иначе, чтобы указать, что соединение используется только для передачи данных.
Поскольку передача данных происходит через вторичные соединения, мы не обязаны упаковывать данные с помощью протокола Ricochet. Здесь стоит продумать варианты.
Вариант 1: модифицированный протокол рикошета
Моей первоначальной мыслью было использовать протокол Ricochet для передачи файловых данных по дополнительным соединениям. Это не совсем просто.
Преимущества:
Минусы:
Есть несколько более старых работ о том, как это может выглядеть из ветки WIP в FileTransferChannel.proto и FileTransferDataChannel.proto .
Вариант 2: HTTP (мои текущие предпочтения)
Клиенты Ricochet могут предлагать файлы через HTTP, используя простой внутренний сервер и уникальные URL-адреса, аналогичные OnionShare . Этот сервер может быть на другом (возможно, случайном) порте той же скрытой службы, на новых эфемерных службах или даже использовать один и тот же порт с помощью обнаружения протокола.
Преимущества:
Минусы:
Реализация сервер / клиент
В Ricochet нет необходимости в полностью полнофункциональном и совместимом со спецификациями HTTP-клиенте, потому что здесь вариант использования очень минимален. Чтобы снизить вероятность ошибок, насколько это возможно, я бы ограничил реализацию функциями, которые нам _ нужны_, и не использовал бы (например) фрагментированное кодирование передачи или эзотерические параметры. Мы могли бы даже заставить
Connection: close
если это будет полезно. В итоге получается довольно небольшой объем кода, доступного для сети, и, как правило, он совместим с другими клиентами и серверами.Поведение сервера и формат URL
Я предпочитаю разместить HTTP-сервер на случайном порте под той же скрытой службой. Создание новых сервисов иногда происходит медленно или ненадежно и включает в себя множество новых каналов и заметную сетевую активность. Это также означает, что нам может потребоваться одно и то же имя хоста .onion, что не позволяет одноранговым узлам принудительно устанавливать соединение с произвольным .onion.
Если сервер всегда работает, контакты и неконтакты могут быть найдены в любое время, хотя это не должно иметь никакого значения. Если сервер активен только тогда, когда есть активные предложения файлов, это состояние может быть обнаружено контактами или неконтактами, которые могут узнать порт.
Нет смысла или необходимости пытаться маскироваться под кого-либо, кроме клиента Ricochet. Все правильно сформированные запросы, которые не являются допустимыми файловыми запросами, должны отклоняться с общей ошибкой 404.
Я предлагаю следующие URL-адреса для скачивания:
URL-адреса файлов относятся к конкретной передаче и предназначены для одноразового использования. Запросы диапазона должны поддерживаться, чтобы разрешить возобновление, и могут быть разрешены для параллельной загрузки. Серверы должны прекратить предлагать URL, как только они считают, что у получателя есть полная копия.
Протокол предложения файлов
Мы можем упаковать предложение файла в расширенное сообщение чата:
Подтверждение этого сообщения также подтверждает предложение файла. URL-адрес может быть немедленно доступен для загрузки файла. В дополнение к обычному подтверждению сообщения получатель должен отправить дополнительный
ChatAcknowledge
когда передача завершена или если она отклонена, с соответствующим набором полей. Отправители должны быть готовы к тому, что передача будет завершена только на основе переданных данных, и не полагаться наChatAcknowledge
для поддержки старых клиентов или альтернативных загрузчиков.У этого есть изящное свойство быть полностью совместимым с клиентами, которые не реализуют передачу файлов; пользователь увидит URL-адрес и сможет загрузить его в браузере. Однако это не имеет особого значения.
XXX. Здесь отправитель не определил способ указать отмену.
Следующие шаги
Я хотел бы продвинуться в этом довольно быстро, поэтому я собираюсь очень скоро закрепить протокол и основные решения UX.
Уже написан хороший фрагмент кода, но он нуждается в некоторых исправлениях и потребует изменений на основе решений, принятых здесь.
Есть предположения?