mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
[FEATURE] AuthLimiter теперь компонент
This commit is contained in:
parent
3eabd1e38e
commit
694c994807
7 changed files with 59 additions and 55 deletions
|
@ -8,7 +8,7 @@
|
||||||
import ru.gravit.launcher.managers.GarbageManager;
|
import ru.gravit.launcher.managers.GarbageManager;
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
import ru.gravit.launcher.profiles.ClientProfile;
|
||||||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||||
import ru.gravit.launchserver.auth.AuthLimiter;
|
import ru.gravit.launchserver.components.AuthLimiterComponent;
|
||||||
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import ru.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
import ru.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
||||||
import ru.gravit.launchserver.auth.hwid.AcceptHWIDHandler;
|
import ru.gravit.launchserver.auth.hwid.AcceptHWIDHandler;
|
||||||
|
@ -33,7 +33,6 @@
|
||||||
import ru.gravit.launchserver.texture.RequestTextureProvider;
|
import ru.gravit.launchserver.texture.RequestTextureProvider;
|
||||||
import ru.gravit.launchserver.texture.TextureProvider;
|
import ru.gravit.launchserver.texture.TextureProvider;
|
||||||
import ru.gravit.utils.helper.*;
|
import ru.gravit.utils.helper.*;
|
||||||
import sun.nio.cs.ext.COMPOUND_TEXT;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
|
@ -48,8 +47,6 @@
|
||||||
import java.security.interfaces.RSAPrivateKey;
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
@ -111,14 +108,6 @@ public static final class Config {
|
||||||
|
|
||||||
public boolean compress;
|
public boolean compress;
|
||||||
|
|
||||||
public int authRateLimit;
|
|
||||||
|
|
||||||
public int authRateLimitMilis;
|
|
||||||
|
|
||||||
public String[] authLimitExclusions;
|
|
||||||
|
|
||||||
public String authRejectString;
|
|
||||||
|
|
||||||
public String whitelistRejectString;
|
public String whitelistRejectString;
|
||||||
|
|
||||||
public boolean genMappings;
|
public boolean genMappings;
|
||||||
|
@ -329,8 +318,6 @@ public static void main(String... args) throws Throwable {
|
||||||
public final LauncherBinary launcherEXEBinary;
|
public final LauncherBinary launcherEXEBinary;
|
||||||
// HWID ban + anti-brutforce
|
// HWID ban + anti-brutforce
|
||||||
|
|
||||||
public final AuthLimiter limiter;
|
|
||||||
|
|
||||||
public final SessionManager sessionManager;
|
public final SessionManager sessionManager;
|
||||||
|
|
||||||
public final SocketHookManager socketHookManager;
|
public final SocketHookManager socketHookManager;
|
||||||
|
@ -463,7 +450,6 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
||||||
|
|
||||||
// build hooks, anti-brutforce and other
|
// build hooks, anti-brutforce and other
|
||||||
buildHookManager = new BuildHookManager();
|
buildHookManager = new BuildHookManager();
|
||||||
limiter = new AuthLimiter(this);
|
|
||||||
proguardConf = new ProguardConf(this);
|
proguardConf = new ProguardConf(this);
|
||||||
sessionManager = new SessionManager();
|
sessionManager = new SessionManager();
|
||||||
mirrorManager = new MirrorManager();
|
mirrorManager = new MirrorManager();
|
||||||
|
@ -472,7 +458,6 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
||||||
socketHookManager = new SocketHookManager();
|
socketHookManager = new SocketHookManager();
|
||||||
authHookManager = new AuthHookManager();
|
authHookManager = new AuthHookManager();
|
||||||
GarbageManager.registerNeedGC(sessionManager);
|
GarbageManager.registerNeedGC(sessionManager);
|
||||||
GarbageManager.registerNeedGC(limiter);
|
|
||||||
reloadManager.registerReloadable("launchServer", this);
|
reloadManager.registerReloadable("launchServer", this);
|
||||||
if (config.permissionsHandler instanceof Reloadable)
|
if (config.permissionsHandler instanceof Reloadable)
|
||||||
reloadManager.registerReloadable("permissionsHandler", (Reloadable) config.permissionsHandler);
|
reloadManager.registerReloadable("permissionsHandler", (Reloadable) config.permissionsHandler);
|
||||||
|
@ -632,7 +617,6 @@ private void generateConfigIfNotExists() throws IOException {
|
||||||
newConfig.permissionsHandler = new JsonFilePermissionsHandler();
|
newConfig.permissionsHandler = new JsonFilePermissionsHandler();
|
||||||
newConfig.port = 7240;
|
newConfig.port = 7240;
|
||||||
newConfig.bindAddress = "0.0.0.0";
|
newConfig.bindAddress = "0.0.0.0";
|
||||||
newConfig.authRejectString = "Превышен лимит авторизаций";
|
|
||||||
newConfig.binaryName = "Launcher";
|
newConfig.binaryName = "Launcher";
|
||||||
newConfig.whitelistRejectString = "Вас нет в белом списке";
|
newConfig.whitelistRejectString = "Вас нет в белом списке";
|
||||||
|
|
||||||
|
@ -649,6 +633,13 @@ private void generateConfigIfNotExists() throws IOException {
|
||||||
newConfig.deleteTempFiles = true;
|
newConfig.deleteTempFiles = true;
|
||||||
newConfig.isWarningMissArchJava = true;
|
newConfig.isWarningMissArchJava = true;
|
||||||
|
|
||||||
|
newConfig.components = new HashMap<>();
|
||||||
|
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
||||||
|
authLimiterComponent.rateLimit = 3;
|
||||||
|
authLimiterComponent.rateLimitMilis = 8000;
|
||||||
|
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||||
|
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||||
|
|
||||||
// Set server address
|
// Set server address
|
||||||
System.out.println("LaunchServer address: ");
|
System.out.println("LaunchServer address: ");
|
||||||
newConfig.setAddress(commandHandler.readLine());
|
newConfig.setAddress(commandHandler.readLine());
|
||||||
|
|
|
@ -1,14 +1,42 @@
|
||||||
package ru.gravit.launchserver.auth;
|
package ru.gravit.launchserver.components;
|
||||||
|
|
||||||
import ru.gravit.launcher.NeedGarbageCollection;
|
import ru.gravit.launcher.NeedGarbageCollection;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
|
import ru.gravit.launchserver.auth.AuthException;
|
||||||
|
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
|
import ru.gravit.launchserver.components.Component;
|
||||||
|
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AuthLimiter implements NeedGarbageCollection {
|
public class AuthLimiterComponent extends Component implements NeedGarbageCollection {
|
||||||
|
private LaunchServer server;
|
||||||
|
@Override
|
||||||
|
public void preInit(LaunchServer launchServer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(LaunchServer launchServer) {
|
||||||
|
server = launchServer;
|
||||||
|
launchServer.authHookManager.registerPreHook(this::preAuthHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(LaunchServer launchServer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
public void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||||
|
if(isLimit(context.ip))
|
||||||
|
{
|
||||||
|
AuthProvider.authError(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class AuthEntry {
|
static class AuthEntry {
|
||||||
public int value;
|
public int value;
|
||||||
|
|
||||||
|
@ -50,20 +78,12 @@ public String toString() {
|
||||||
|
|
||||||
|
|
||||||
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
|
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
|
||||||
public final int rateLimit;
|
public int rateLimit;
|
||||||
public final int rateLimitMilis;
|
public int rateLimitMilis;
|
||||||
|
public String message;
|
||||||
|
|
||||||
private final HashMap<String, AuthEntry> map;
|
public transient HashMap<String, AuthEntry> map;
|
||||||
private final List<String> excludeIps;
|
public List<String> excludeIps;
|
||||||
|
|
||||||
public AuthLimiter(LaunchServer srv) {
|
|
||||||
map = new HashMap<>();
|
|
||||||
excludeIps = new ArrayList<>();
|
|
||||||
if (srv.config.authLimitExclusions != null)
|
|
||||||
excludeIps.addAll(Arrays.asList(srv.config.authLimitExclusions));
|
|
||||||
rateLimit = srv.config.authRateLimit;
|
|
||||||
rateLimitMilis = srv.config.authRateLimitMilis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void garbageCollection() {
|
public void garbageCollection() {
|
|
@ -30,6 +30,7 @@ public static String getComponentName(Class<Component> clazz) {
|
||||||
|
|
||||||
public static void registerComponents() {
|
public static void registerComponents() {
|
||||||
if (!registredComp) {
|
if (!registredComp) {
|
||||||
|
registerComponent("authLimiter", AuthLimiterComponent.class);
|
||||||
registredComp = true;
|
registredComp = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ru.gravit.launchserver.manangers.hook;
|
package ru.gravit.launchserver.manangers.hook;
|
||||||
|
|
||||||
|
import ru.gravit.launcher.request.RequestException;
|
||||||
|
import ru.gravit.launchserver.auth.AuthException;
|
||||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
|
@ -14,22 +16,22 @@ public class AuthHookManager {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface AuthPreHook {
|
public interface AuthPreHook {
|
||||||
void preAuthHook(AuthResponse.AuthContext context, Client client);
|
void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface AuthPostHook {
|
public interface AuthPostHook {
|
||||||
void postAuthHook(AuthResponse.AuthContext context, Client client);
|
void postAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface CheckServerHook {
|
public interface CheckServerHook {
|
||||||
void checkServerHook(String username, String serverID);
|
void checkServerHook(String username, String serverID) throws AuthException;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface JoinServerHook {
|
public interface JoinServerHook {
|
||||||
void joinServerHook(String username, String accessToken, String serverID);
|
void joinServerHook(String username, String accessToken, String serverID) throws AuthException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerPostHook(AuthPostHook hook) {
|
public void registerPostHook(AuthPostHook hook) {
|
||||||
|
@ -48,25 +50,25 @@ public void registerPreHook(AuthPreHook hook) {
|
||||||
PRE_HOOKS.add(hook);
|
PRE_HOOKS.add(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preHook(AuthResponse.AuthContext context, Client client) {
|
public void preHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||||
for (AuthPreHook preHook : PRE_HOOKS) {
|
for (AuthPreHook preHook : PRE_HOOKS) {
|
||||||
preHook.preAuthHook(context, client);
|
preHook.preAuthHook(context, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkServerHook(String username, String serverID) {
|
public void checkServerHook(String username, String serverID) throws AuthException {
|
||||||
for (CheckServerHook hook : CHECKSERVER_HOOKS) {
|
for (CheckServerHook hook : CHECKSERVER_HOOKS) {
|
||||||
hook.checkServerHook(username, serverID);
|
hook.checkServerHook(username, serverID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void joinServerHook(String username, String accessToken, String serverID) {
|
public void joinServerHook(String username, String accessToken, String serverID) throws AuthException {
|
||||||
for (JoinServerHook hook : JOINSERVER_HOOKS) {
|
for (JoinServerHook hook : JOINSERVER_HOOKS) {
|
||||||
hook.joinServerHook(username, accessToken, serverID);
|
hook.joinServerHook(username, accessToken, serverID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postHook(AuthResponse.AuthContext context, Client client) {
|
public void postHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||||
for (AuthPostHook postHook : POST_HOOKS) {
|
for (AuthPostHook postHook : POST_HOOKS) {
|
||||||
postHook.postAuthHook(context, client);
|
postHook.postAuthHook(context, client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,14 @@ public AuthResponse(LaunchServer server, long session, HInput input, HOutput out
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthContext {
|
public static class AuthContext {
|
||||||
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, boolean isServerAuth) {
|
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.login = login;
|
this.login = login;
|
||||||
this.password_lenght = password_lenght;
|
this.password_lenght = password_lenght;
|
||||||
this.customText = customText;
|
this.customText = customText;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.hwid = hwid;
|
this.hwid = hwid;
|
||||||
|
this.ip = ip;
|
||||||
this.isServerAuth = isServerAuth;
|
this.isServerAuth = isServerAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ public AuthContext(long session, String login, int password_lenght, String custo
|
||||||
public String client;
|
public String client;
|
||||||
public String hwid;
|
public String hwid;
|
||||||
public String customText;
|
public String customText;
|
||||||
|
public String ip;
|
||||||
public boolean isServerAuth;
|
public boolean isServerAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,13 +84,9 @@ public void reply() throws Exception {
|
||||||
AuthProviderResult result;
|
AuthProviderResult result;
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
clientData.type = Client.Type.USER;
|
clientData.type = Client.Type.USER;
|
||||||
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, false);
|
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, ip, false);
|
||||||
try {
|
try {
|
||||||
server.authHookManager.preHook(context, clientData);
|
server.authHookManager.preHook(context, clientData);
|
||||||
if (server.limiter.isLimit(ip)) {
|
|
||||||
AuthProvider.authError(server.config.authRejectString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!clientData.checkSign) {
|
if (!clientData.checkSign) {
|
||||||
throw new AuthException("You must using checkLauncher");
|
throw new AuthException("You must using checkLauncher");
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,6 @@ public void reply() throws Exception {
|
||||||
AuthProviderResult result;
|
AuthProviderResult result;
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
try {
|
try {
|
||||||
if (server.limiter.isLimit(ip)) {
|
|
||||||
AuthProvider.authError(server.config.authRejectString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
result = provider.auth(login, password, ip);
|
result = provider.auth(login, password, ip);
|
||||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
if (!VerifyHelper.isValidUsername(result.username)) {
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
||||||
|
|
|
@ -56,10 +56,6 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
try {
|
try {
|
||||||
AuthRequestEvent result = new AuthRequestEvent();
|
AuthRequestEvent result = new AuthRequestEvent();
|
||||||
String ip = IOHelper.getIP(ctx.channel().remoteAddress());
|
String ip = IOHelper.getIP(ctx.channel().remoteAddress());
|
||||||
if (LaunchServer.server.limiter.isLimit(ip)) {
|
|
||||||
AuthProvider.authError(LaunchServer.server.config.authRejectString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((authType == null || authType == ConnectTypes.CLIENT) &&!clientData.checkSign) {
|
if ((authType == null || authType == ConnectTypes.CLIENT) &&!clientData.checkSign) {
|
||||||
AuthProvider.authError("Don't skip Launcher Update");
|
AuthProvider.authError("Don't skip Launcher Update");
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +78,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
{
|
{
|
||||||
AuthProvider.authError("authType: SERVER not allowed for this account");
|
AuthProvider.authError("authType: SERVER not allowed for this account");
|
||||||
}
|
}
|
||||||
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(),customText, client, null, false);
|
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(),customText, client, ip, null, false);
|
||||||
AuthProvider provider = LaunchServer.server.config.authProvider[authid];
|
AuthProvider provider = LaunchServer.server.config.authProvider[authid];
|
||||||
LaunchServer.server.authHookManager.preHook(context, clientData);
|
LaunchServer.server.authHookManager.preHook(context, clientData);
|
||||||
provider.preAuth(login,password,customText,ip);
|
provider.preAuth(login,password,customText,ip);
|
||||||
|
|
Loading…
Reference in a new issue