102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
import asyncio
|
|
import aiomysql
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
import hashlib
|
|
import binascii
|
|
import time
|
|
|
|
@dataclass
|
|
class AuthResult:
|
|
success: bool
|
|
message: str
|
|
account_id: Optional[int] = None
|
|
username: Optional[str] = None
|
|
gmlevel: Optional[int] = 0
|
|
|
|
class AuthAPI:
|
|
def __init__(self):
|
|
self.db_config = {
|
|
'host': '192.168.1.42',
|
|
'port': 3306,
|
|
'user': 'launcher_ro',
|
|
'password': 'rPIisIhn46',
|
|
'db': 'acore_auth'
|
|
}
|
|
# Константы для SRP6
|
|
self.N = 0x894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7
|
|
self.g = 7
|
|
|
|
def _calculate_verifier(self, username: str, password: str, salt: bytes) -> bytes:
|
|
"""
|
|
Вычисляет верификатор для SRP6
|
|
"""
|
|
# 1. Вычисляем h1 = SHA1("USERNAME:PASSWORD")
|
|
username = username.upper()
|
|
password = password.upper()
|
|
h1 = hashlib.sha1(f"{username}:{password}".encode()).digest()
|
|
|
|
# 2. Вычисляем h2 = SHA1(salt || h1)
|
|
h2 = int.from_bytes(
|
|
hashlib.sha1(salt + h1).digest(),
|
|
byteorder='little'
|
|
)
|
|
|
|
# 3. Вычисляем (g^h2) % N используя встроенную функцию pow
|
|
verifier = pow(self.g, h2, self.N)
|
|
|
|
# 4. Конвертируем в байты в little-endian порядке
|
|
return verifier.to_bytes(32, byteorder='little')
|
|
|
|
async def login(self, username: str, password: str) -> AuthResult:
|
|
try:
|
|
async with aiomysql.connect(**self.db_config) as conn:
|
|
async with conn.cursor() as cur:
|
|
# Получаем данные аккаунта
|
|
await cur.execute("""
|
|
SELECT id, username, salt, verifier, locked
|
|
FROM account
|
|
WHERE username = %s
|
|
""", (username.upper(),))
|
|
|
|
result = await cur.fetchone()
|
|
|
|
if not result:
|
|
return AuthResult(
|
|
success=False,
|
|
message="Неверное имя пользователя или пароль"
|
|
)
|
|
|
|
account_id, db_username, salt, stored_verifier, locked = result
|
|
|
|
# Проверяем блокировку
|
|
if locked:
|
|
return AuthResult(
|
|
success=False,
|
|
message="Аккаунт заблокирован"
|
|
)
|
|
|
|
# Вычисляем верификатор
|
|
calculated_verifier = self._calculate_verifier(username, password, salt)
|
|
|
|
# Сравниваем верификаторы
|
|
if calculated_verifier != stored_verifier:
|
|
return AuthResult(
|
|
success=False,
|
|
message="Неверное имя пользователя или пароль"
|
|
)
|
|
|
|
return AuthResult(
|
|
success=True,
|
|
message="Успешная авторизация",
|
|
account_id=account_id,
|
|
username=db_username,
|
|
gmlevel=0
|
|
)
|
|
|
|
except Exception as e:
|
|
print(f"Error during login: {e}")
|
|
return AuthResult(
|
|
success=False,
|
|
message="Ошибка при авторизации"
|
|
) |