88 lines
6.4 KiB
Markdown
88 lines
6.4 KiB
Markdown
# Авторизация MoonWell через лаунчер
|
||
|
||
Клиентская часть не принимает логин и пароль в Release-сборке. Лаунчер передаёт игре
|
||
короткоживущую учётную сессию через environment block дочернего процесса, а GlueXML сразу
|
||
запускает стандартный SRP-вход и не показывает форму логина.
|
||
|
||
## Контракт запуска клиента
|
||
|
||
Перед `CreateProcess` лаунчер должен добавить в environment block только запускаемого `Wow.exe`:
|
||
|
||
```text
|
||
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`. Для локального запуска:
|
||
|
||
```powershell
|
||
.\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 запуске.
|