stadium-proto/OVERVIEW.md

12 KiB
Raw Blame History

Спецификация Marafon Protocol (MFP) v1.0

Marafon Protocol это протокол логического уровня общего назначения и работает поверх любого транспортного. Также является базой для одноимённого ("Marafon") полнофункционального мессенджера.

Здесь описана спецификация базового протокола; спецификация версии протокола используемая в мессенджере будет размещена в другом репозитории.

Основной фокус при работе над сим проектом идёт на:

  • Снижение оверхэдов, по сравнению с классическими решениями (Matrix, Discord, WhatsApp, пр. (Reject HTML+JSON, return to binary.)).
  • Устойчивость к цензуре.
  • Федеративность.
  • Поддержка сквозного шифрования.
  • Совместимость со всеми мажорными оверлейными сетями (Tor, I2P и yggdrasil).
  • Расширяемость.

Поведение сервера и клиента

Сервер обязан:

  1. Оповещать клиент о всех ошибках, возникших во время его запроса, кроме:
    • Связанных с безопасностью
  2. Оповещать сервер в федерации о всех ошибках, возникших во время его запроса, кроме:
    • Связанных с безопасностью
    • Связанных с внутренними неполадками
  3. По умолчанию отклонять все события, содержащие ложную подпись.
  4. Отдавать предпочтение данным других серверов, нежели клиентов.
  5. Отдавать предпочтение сетевым настройкам входящих соединений, нежели локальным (не считая лимиты).

Клиент обязан:

  1. Не сообщать серверу ни о каких ошибках на своей (клиентской) стороне.
  2. По умолчанию блокировать до решения юзера все события, содержащие ложную подпись.
  3. Явно уведомлять юзера при возникновении проблем с безопасностью, как минимум по умолчанию.

События, пакеты и их структура

Существует три уровня категорий событий:

  1. Надкатегория: Client2Server, Server2Client, Server2Server.
  2. Категория: например "Authentication", "User", "Message", т.д.
  3. Подкатегория: например "Login", "Create", "Delete", т.д.

Надкатегория никак не указывается в пакете, зависит от контекста и при упоминании - чаще всего опускается. Она также определяет структуру некоторых событий, которая может меняться в конкретных случаях. Остальные две являются шестнадцатеричными числами размерности указанной при хэндшейке.

Все категории вместе являются типом события. Значение типа - это шестнадцатеричное число, которое указывается в начале пакета.

Пакеты с событиями всех категорий, кроме явно оговорённых или принадлежащих к надкатегории Server2Client, содержат идентификатор серверной сессии, являющийся четырёхбайтным числом без знака (uint32_t).

Пакеты с событиями всех категорий из надкатегории Client2Server, кроме явно оговорённых, содержат хэш полезной нагрузки, зашифрованный с помощью закрытого ключа подписи клиента.

Пакеты с событиями всех категорий, кроме явно оговорённых, содержат формат полезной нагрузки, занимающий ровно 1 байт (uint8_t):

  • 0x01: фиксированная схема.
  • 0x02: "ячеистая" структура.
  • Остальные значения зарезервированы.

Данные (AKA "полезная нагрузка") могут быть представлены в формате фиксированной схемы или в виде ячеек, которые являются расположенными последовательно парами "ключ-значение" и могут быть расположены в произвольном порядке относительно друг-друга. Все неизвестные ключи при парсинге игнорируются. Одна пара (AKA "ячейка") имеет следующий вид:

[key][data length][data]

Следовательно, полезная нагрузка в данном формате имеет вид:

[cell_1][cell_2][cell_3]...[cell_n]

Ключ и длинна данных являются шестнадцатеричными числами, размерность которых задаётся на этапе хэндшейка. Полезная нагрузка не может отсутствовать полностью (кроме особо-оговорённых случаев), а ключ не может являться нулём. Если значение конкретной пары пусто, то его длинна должна быть нулём.

Исходя из всего вышеописанного, итоговая примерная структура пакета выглядит следующим образом:

[category][subcategory][server session: 4B][payload hash: ?B][payload type: 1B][payload: >0B]

Размер пакета не нормирован и ответственность за его менеджмент остаётся на транспортном уровне. (Эталонная реализация MFP будет использовать общий универсальный интерфейс, который, в свою очередь, заворачивает все данные в релевантный протокол транспортного уровня)

Зарезервированные события

Некоторые категории событий зарезервированы под нужды базового протокола или просто для событий определённого рода. Второе носит рекомендательный характер; вы также можете использовать другие диапазоны для тех-же целей.

Все из зарезервированных типов помещаются в минимальную размерность типа события (т.е. по одному байту на категорию и подкатегорию). Ниже приведены диапазоны зарезервированных значений.

Зарезервировано для нужд протокола и запрещено к использованию в частных реализациях:

  • Категория 0x01
    • Все субкатегории: выделены для событий общей направленности.
  • Категория 0x11
    • Все субкатегории: выделены для событий ошибок и предупреждений протокольного уровня.

Рекомендуется к использованию при определённых случаях:

  • Категории 0x12-0x1F (включительно)
    • Все субкатегории: для событий ошибок и предупреждений.

Зарезервированные ключи ячеек

Скоро.

Соединение, аутентификация и сессии

Первичное подключение к серверу может выполнятся разными способами, в том числе подразумевающими маскировку траффика под существующие протоколы, но при использовании вне локальных сетей - должно сводиться к установке защищённого соединения.

Рукопожатие

См. файл HANDSHAKE.md.

Аутентификация

Описываемый протокол предполагает наличие базовых механизмов аутентификации. Все они сводятся к проверке как цели, так и запрашивающего на предмет релевантного доступа.

Сессии и подпись

Каждый принятый сервером пакет, содержащий хэш полезной нагрузки, должен проверяться на соответствие подписи. Если сервер обнаруживает, что подпись неверна - сервер отвечает ошибкой, соединение разрывается, а администратор сервера и владелец учётной записи уведомляются об инциденте.

Каждый принятый клиентом пакет, содержащий хэш полезной нагрузки, может быть проверен на соответствие подписи. Если клиент обнаруживает, что подпись неверна - он должен оповестить пользователя.

Полезная нагрузка пакета может быть проверена на целостность сервером или клиентом с использованием подписанного хеша, но данная проверка может быть отключена, по усмотрению владельца сервера или пользователя клиента.

Если при проверке ID серверной сессии обнаруживается несоответствие - сервер отвечает ошибкой, соединение разрывается.