From 07dd7bcfc86368adb40b71f8a9c6c951bd68a01c Mon Sep 17 00:00:00 2001 From: Gravit Date: Mon, 1 Jul 2019 16:07:33 +0700 Subject: [PATCH] [FEATURE] RegLimiterComponent --- .../pro/gravit/launchserver/LaunchServer.java | 6 ++ .../auth/provider/HibernateAuthProvider.java | 11 ++- .../launchserver/components/Component.java | 1 + .../components/RegLimiterComponent.java | 76 +++++++++++++++++++ .../manangers/hook/AuthHookManager.java | 15 ++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 47446b42..ca37d17e 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -62,6 +62,7 @@ import pro.gravit.launchserver.binary.ProguardConf; import pro.gravit.launchserver.components.AuthLimiterComponent; import pro.gravit.launchserver.components.Component; +import pro.gravit.launchserver.components.RegLimiterComponent; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; import pro.gravit.launchserver.dao.UserService; import pro.gravit.launchserver.dao.provider.DaoProvider; @@ -761,6 +762,11 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException { authLimiterComponent.rateLimitMilis = 8000; authLimiterComponent.message = "Превышен лимит авторизаций"; newConfig.components.put("authLimiter", authLimiterComponent); + RegLimiterComponent regLimiterComponent = new RegLimiterComponent(); + regLimiterComponent.rateLimit = 3; + regLimiterComponent.rateLimitMilis = 1000 * 60 * 60 * 10; //Блок на 10 часов + regLimiterComponent.message = "Превышен лимит регистраций"; + newConfig.components.put("regLimiter", regLimiterComponent); // Set server address String address; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java index 4f878b27..f29ffc63 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java @@ -4,6 +4,7 @@ import pro.gravit.launchserver.auth.AuthException; import pro.gravit.launchserver.dao.User; +import pro.gravit.launchserver.manangers.hook.AuthHookManager; import pro.gravit.utils.helper.SecurityHelper; public class HibernateAuthProvider extends AuthProvider { @@ -13,7 +14,15 @@ public AuthProviderResult auth(String login, String password, String ip) throws User user = srv.config.dao.userService.findUserByUsername(login); if(user == null && autoReg) { - user = srv.config.dao.userService.registerNewUser(login, password); + AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, password, ip, false); + if(AuthHookManager.registraion.hook(context)) + { + user = srv.config.dao.userService.registerNewUser(login, password); + } + else + { + throw new AuthException("Registration canceled. Try again later"); + } } if(user == null || !user.verifyPassword(password)) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/Component.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/Component.java index f19ebe1e..b4789057 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/components/Component.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/Component.java @@ -10,6 +10,7 @@ public abstract class Component { public static void registerComponents() { if (!registredComp) { providers.register("authLimiter", AuthLimiterComponent.class); + providers.register("regLimiter", RegLimiterComponent.class); providers.register("commandRemover", CommandRemoverComponent.class); registredComp = true; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java new file mode 100644 index 00000000..2cef6770 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java @@ -0,0 +1,76 @@ +package pro.gravit.launchserver.components; + +import pro.gravit.launcher.NeedGarbageCollection; +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.manangers.hook.AuthHookManager; +import pro.gravit.utils.HookException; +import pro.gravit.utils.HookSet; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable { + + public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов + public transient LaunchServer launchServer; + public int rateLimit; + public int rateLimitMilis; + public String message; + public transient HookSet.Hook hook; + + public transient HashMap map = new HashMap<>(); + public List excludeIps = new ArrayList<>(); + + @Override + public void preInit(LaunchServer launchServer) { + this.launchServer = launchServer; + } + + @Override + public void init(LaunchServer launchServer) { + + } + + @Override + public void postInit(LaunchServer launchServer) { + launchServer.authHookManager.registraion.registerHook(context -> { + if (isLimit(context.ip)) { + throw new HookException(message); + } + return false; + }); + } + + @Override + public void garbageCollection() { + long time = System.currentTimeMillis(); + long max_timeout = Math.max(rateLimitMilis, TIMEOUT); + map.entrySet().removeIf(e -> e.getValue().ts + max_timeout < time); + } + + public boolean isLimit(String ip) { + if (excludeIps.contains(ip)) return false; + if (map.containsKey(ip)) { + AuthLimiterComponent.AuthEntry rate = map.get(ip); + long currenttime = System.currentTimeMillis(); + if (rate.ts + rateLimitMilis < currenttime) rate.value = 0; + if (rate.value >= rateLimit && rateLimit > 0) { + rate.value++; + rate.ts = currenttime; + return true; + } + rate.value++; + rate.ts = currenttime; + return false; + } + map.put(ip, new AuthLimiterComponent.AuthEntry(1, System.currentTimeMillis())); + return false; + } + + @Override + public void close() throws Exception { + if(hook != null) + launchServer.authHookManager.registraion.unregisterHook(hook); + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/hook/AuthHookManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/hook/AuthHookManager.java index ef181c2f..31a7d451 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/hook/AuthHookManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/hook/AuthHookManager.java @@ -6,6 +6,7 @@ import pro.gravit.launchserver.socket.response.auth.JoinServerResponse; import pro.gravit.launchserver.socket.response.auth.SetProfileResponse; import pro.gravit.utils.BiHookSet; +import pro.gravit.utils.HookSet; public class AuthHookManager { public BiHookSet preHook = new BiHookSet<>(); @@ -13,4 +14,18 @@ public class AuthHookManager { public BiHookSet checkServerHook = new BiHookSet<>(); public BiHookSet joinServerHook = new BiHookSet<>(); public BiHookSet setProfileHook = new BiHookSet<>(); + public static class RegContext + { + public String login; + public String password; + public String ip; + public boolean trustContext; + public RegContext(String login, String password, String ip, boolean trustContext) { + this.login = login; + this.password = password; + this.ip = ip; + this.trustContext = trustContext; + } + } + public HookSet registraion; }