diff options
Diffstat (limited to 'src/main/java/net/elytrium/limboauth/LimboAuth.java')
-rw-r--r-- | src/main/java/net/elytrium/limboauth/LimboAuth.java | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/src/main/java/net/elytrium/limboauth/LimboAuth.java b/src/main/java/net/elytrium/limboauth/LimboAuth.java index 9eaef13..e18b2bf 100644 --- a/src/main/java/net/elytrium/limboauth/LimboAuth.java +++ b/src/main/java/net/elytrium/limboauth/LimboAuth.java @@ -134,6 +134,7 @@ public class LimboAuth { private final Map<String, CachedSessionUser> cachedAuthChecks = new ConcurrentHashMap<>(); private final Map<String, CachedPremiumUser> premiumCache = new ConcurrentHashMap<>(); + private final Map<InetAddress, CachedBruteforceUser> bruteforceCache = new ConcurrentHashMap<>(); private final Map<UUID, Runnable> postLoginTasks = new ConcurrentHashMap<>(); private final Set<String> unsafePasswords = new HashSet<>(); private final Set<String> forcedPreviously = Collections.synchronizedSet(new HashSet<>()); @@ -157,10 +158,12 @@ public class LimboAuth { @Nullable private Title loginFloodgateTitle; private Component registrationsDisabledKick; + private Component bruteforceAttemptKick; private Component nicknameInvalidKick; private Component reconnectKick; private ScheduledTask purgeCacheTask; private ScheduledTask purgePremiumCacheTask; + private ScheduledTask purgeBruteforceCacheTask; private ConnectionSource connectionSource; private Dao<RegisteredPlayer, String> playerDao; @@ -253,6 +256,7 @@ public class LimboAuth { ); } + this.bruteforceAttemptKick = SERIALIZER.deserialize(Settings.IMP.MAIN.STRINGS.LOGIN_WRONG_PASSWORD_KICK); this.nicknameInvalidKick = SERIALIZER.deserialize(Settings.IMP.MAIN.STRINGS.NICKNAME_INVALID_KICK); this.reconnectKick = SERIALIZER.deserialize(Settings.IMP.MAIN.STRINGS.RECONNECT_KICK); this.registrationsDisabledKick = SERIALIZER.deserialize(Settings.IMP.MAIN.STRINGS.REGISTRATIONS_DISABLED_KICK); @@ -270,6 +274,8 @@ public class LimboAuth { } this.cachedAuthChecks.clear(); + this.premiumCache.clear(); + this.bruteforceCache.clear(); Settings.DATABASE dbConfig = Settings.IMP.DATABASE; DatabaseLibrary databaseLibrary = DatabaseLibrary.valueOf(dbConfig.STORAGE_TYPE.toUpperCase(Locale.ROOT)); @@ -383,6 +389,16 @@ public class LimboAuth { .repeat(Settings.IMP.MAIN.PURGE_PREMIUM_CACHE_MILLIS, TimeUnit.MILLISECONDS) .schedule(); + if (this.purgeBruteforceCacheTask != null) { + this.purgeBruteforceCacheTask.cancel(); + } + + this.purgeBruteforceCacheTask = this.server.getScheduler() + .buildTask(this, () -> this.checkCache(this.bruteforceCache, Settings.IMP.MAIN.PURGE_BRUTEFORCE_CACHE_MILLIS)) + .delay(Settings.IMP.MAIN.PURGE_BRUTEFORCE_CACHE_MILLIS, TimeUnit.MILLISECONDS) + .repeat(Settings.IMP.MAIN.PURGE_BRUTEFORCE_CACHE_MILLIS, TimeUnit.MILLISECONDS) + .schedule(); + eventManager.fireAndForget(new AuthPluginReloadEvent()); } @@ -390,7 +406,7 @@ public class LimboAuth { return commands.stream().filter(command -> command.startsWith("/")).map(command -> command.substring(1)).collect(Collectors.toList()); } - private void checkCache(Map<String, ? extends CachedUser> userMap, long time) { + private void checkCache(Map<?, ? extends CachedUser> userMap, long time) { userMap.entrySet().stream() .filter(userEntry -> userEntry.getValue().getCheckTime() + time <= System.currentTimeMillis()) .map(Map.Entry::getKey) @@ -480,6 +496,11 @@ public class LimboAuth { return; } + if (this.getBruteforceAttempts(player.getRemoteAddress().getAddress()) >= Settings.IMP.MAIN.BRUTEFORCE_MAX_ATTEMPTS) { + player.disconnect(this.bruteforceAttemptKick); + return; + } + boolean isFloodgate = !Settings.IMP.MAIN.FLOODGATE_NEED_AUTH && this.floodgateApi.isFloodgatePlayer(player.getUniqueId()); String nickname = player.getUsername(); if (!this.nicknameValidationPattern.matcher((isFloodgate) ? nickname.substring(this.floodgateApi.getPrefixLength()) : nickname).matches()) { @@ -788,6 +809,24 @@ public class LimboAuth { } } + public void incrementBruteforceAttempts(InetAddress address) { + this.bruteforceCache.get(address).incrementAttempts(); + } + + public int getBruteforceAttempts(InetAddress address) { + CachedBruteforceUser user = this.bruteforceCache.get(address); + if (user == null) { + user = new CachedBruteforceUser(System.currentTimeMillis()); + this.bruteforceCache.put(address, user); + } + + return user.getAttempts(); + } + + public void clearBruteforceAttempts(InetAddress address) { + this.bruteforceCache.remove(address); + } + public void saveForceOfflineMode(String nickname) { this.forcedPreviously.add(nickname); } @@ -881,6 +920,23 @@ public class LimboAuth { } } + private static class CachedBruteforceUser extends CachedUser { + + private int attempts; + + public CachedBruteforceUser(long checkTime) { + super(checkTime); + } + + public void incrementAttempts() { + this.attempts++; + } + + public int getAttempts() { + return this.attempts; + } + } + public static class PremiumResponse { private final PremiumState state; |