Files
moonwell-client/LAUNCHER_AUTH.md
T
2026-08-17 20:24:00 +04:00

6.4 KiB
Raw Blame History

Авторизация MoonWell через лаунчер

Клиентская часть не принимает логин и пароль в Release-сборке. Лаунчер передаёт игре короткоживущую учётную сессию через environment block дочернего процесса, а GlueXML сразу запускает стандартный SRP-вход и не показывает форму логина.

Контракт запуска клиента

Перед CreateProcess лаунчер должен добавить в environment block только запускаемого Wow.exe:

MOONWELL_LAUNCH_ACCOUNT=<account name>
MOONWELL_LAUNCH_TICKET=<single-use SRP password>

Обе переменные обязательны. Нативный модуль читает и удаляет их из окружения процесса до загрузки GlueXML. Значения не должны передаваться в аргументах командной строки, писаться в файл, лог или реестр.

Ограничения значений:

  • account: печатный ASCII без пробелов, не более 320 байт;
  • ticket: ровно 16 символов из A-Z0-9 (около 82 бит при равномерной генерации);
  • ticket должен быть криптографически случайным, одноразовым и жить не более 60 секунд;
  • выпуск нового ticket должен отзывать предыдущий активный ticket этого аккаунта.

Пример Win32-последовательности лаунчера:

  1. Пользователь авторизуется в лаунчере.
  2. Лаунчер запрашивает у backend одноразовый game ticket.
  3. Лаунчер создаёт отдельный environment block с двумя переменными выше.
  4. Лаунчер запускает Wow.exe через CreateProcessW.
  5. Лаунчер сразу затирает ticket в своей памяти.

Кнопка «Авторизоваться» сначала ищет MoonWell.exe или MoonWellLauncher.exe рядом с Wow.exe. Если файла нет, она открывает URI moonwell://authorize?source=client. Установщик лаунчера должен зарегистрировать схему moonwell для текущего пользователя.

Обязательное изменение auth-сервера

Скрытие полей в GlueXML не является серверной защитой: пользователь контролирует свой клиент. Чтобы вход действительно был возможен только через лаунчер, auth-сервер обязан для обычных аккаунтов отказаться от постоянного password verifier и принимать только активный launcher ticket.

Для совместимости с неизменённым SRP-клиентом ticket используется как временный пароль:

  1. Backend хранит для аккаунта один активный ticket либо подготовленные из него временные SRP salt и verifier.
  2. На CMD_AUTH_LOGON_CHALLENGE auth-сервер ищет активный непросроченный ticket аккаунта. Если ticket отсутствует, сервер отклоняет вход до выполнения обычной password-проверки.
  3. SRP challenge строится по временному verifier.
  4. После успешного CMD_AUTH_LOGON_PROOF ticket атомарно помечается использованным.
  5. Повторный proof, повторный запуск и истёкший ticket отклоняются.

Поскольку challenge содержит аккаунт, но не сам ticket, одновременно должен существовать не более одного активного ticket на аккаунт.

Рекомендуется дополнительно привязать ticket к версии клиента и идентификатору launcher-сессии, ограничить частоту выпуска и не возвращать его ни в какие аналитические события.

Режим разработчика

Ручной логин компилируется только в Debug-варианте MoonWell.dll. Для локального запуска:

.\run.ps1 -Env local -DeveloperLogin

Authserver должен независимо разрешить тот же аккаунт записью в launcher_dev_account с точным allowed_ip и enabled = 1. Один только Debug-режим клиента никогда не обходит серверную проверку.

Скрипт собирает Debug runtime и передаёт MOONWELL_DEV_LOGIN=1 только запускаемому процессу. Переменная одноразово удаляется нативным модулем. В Release-сборке она игнорируется.

Auth-сервер также должен отдельно разрешать постоянный SRP verifier только dev-аккаунтам — лучше по allowlist аккаунтов вместе с VPN/IP-ограничением. Нельзя считать Debug-флаг клиента границей безопасности и нельзя распространять Debug DLL игрокам.

Поведение интерфейса

  • валидная launcher-сессия: AccountLoginUI скрывается и сразу вызывается DefaultServerLogin(account, ticket);
  • прямой Release-запуск: поля логина, пароля и параметры сохранения скрыты, основная кнопка открывает лаунчер;
  • Debug + MOONWELL_DEV_LOGIN=1: показывается прежняя форма ручного входа;
  • сохранённые ранее логин и пароль удаляются при любом не-dev запуске.