From 4583f9195f276aeb4e480a3d0707be6bd3469cf1 Mon Sep 17 00:00:00 2001 From: Arda Date: Sat, 31 Aug 2024 15:39:46 +0300 Subject: [PATCH 1/4] Added option to disable user registering with leaked passwords. --- .../net/elytrium/limboauth/LimboAuth.java | 35 +++++++++++++++++-- .../java/net/elytrium/limboauth/Settings.java | 2 ++ .../limboauth/handler/AuthSessionHandler.java | 20 ++++++++++- .../limboauth/model/UnsafePlayer.java | 21 +++++++++++ src/main/resources/unsafe_pass_user_set.txt | 3 ++ 5 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java create mode 100644 src/main/resources/unsafe_pass_user_set.txt diff --git a/src/main/java/net/elytrium/limboauth/LimboAuth.java b/src/main/java/net/elytrium/limboauth/LimboAuth.java index e48e1c85..c40288a2 100644 --- a/src/main/java/net/elytrium/limboauth/LimboAuth.java +++ b/src/main/java/net/elytrium/limboauth/LimboAuth.java @@ -110,6 +110,7 @@ import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.listener.AuthListener; import net.elytrium.limboauth.listener.BackendEndpointsListener; +import net.elytrium.limboauth.model.UnsafePlayer; import net.elytrium.limboauth.model.RegisteredPlayer; import net.elytrium.limboauth.model.SQLRuntimeException; import net.kyori.adventure.text.Component; @@ -153,6 +154,7 @@ public class LimboAuth { private final Map bruteforceCache = new ConcurrentHashMap<>(); private final Map postLoginTasks = new ConcurrentHashMap<>(); private final Set unsafePasswords = new HashSet<>(); + private final Set unsafePlayerPassSet = new HashSet<>(); private final Set forcedPreviously = Collections.synchronizedSet(new HashSet<>()); private final Set pendingLogins = ConcurrentHashMap.newKeySet(); @@ -309,6 +311,30 @@ public void reload() { } } + try { + this.unsafePlayerPassSet.clear(); + Path craftrisePath = Paths.get(this.dataDirectoryFile.getAbsolutePath(), Settings.IMP.MAIN.UNSAFE_SET_PASSWORDS_FILE); + if (!craftrisePath.toFile().exists()) { + Files.copy(Objects.requireNonNull(this.getClass().getResourceAsStream("/unsafe_pass_user_set.txt")), craftrisePath); + } + + List stream = Files.readAllLines(craftrisePath); + stream.forEach(account -> { + String[] parts = account.split(":"); + if (parts.length == 2) { + String username = parts[0]; + String password = parts[1]; + UnsafePlayer unsafePlayer = new UnsafePlayer(username, password); + unsafePlayerPassSet.add(unsafePlayer); + } + }); + + this.server.sendMessage(Component.text("Loadded " + unsafePlayerPassSet.size() + " unsafe user & password set!")); + + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + this.cachedAuthChecks.clear(); this.premiumCache.clear(); this.bruteforceCache.clear(); @@ -934,9 +960,12 @@ public Map getPostLoginTasks() { return this.postLoginTasks; } - public Set getUnsafePasswords() { - return this.unsafePasswords; - } + public Set getUnsafePasswords() { + return this.unsafePasswords; + } + public Set getUnsafePlayerPassSet() { + return this.unsafePlayerPassSet; + } public ProxyServer getServer() { return this.server; diff --git a/src/main/java/net/elytrium/limboauth/Settings.java b/src/main/java/net/elytrium/limboauth/Settings.java index 540c9fe9..349a5ae2 100644 --- a/src/main/java/net/elytrium/limboauth/Settings.java +++ b/src/main/java/net/elytrium/limboauth/Settings.java @@ -73,6 +73,7 @@ public static class MAIN { @Comment("Max password length for the BCrypt hashing algorithm, which is used in this plugin, can't be higher than 71. You can set a lower value than 71.") public int MAX_PASSWORD_LENGTH = 71; public boolean CHECK_PASSWORD_STRENGTH = true; + public String UNSAFE_SET_PASSWORDS_FILE = "unsafe_pass_user_set.txt"; public String UNSAFE_PASSWORDS_FILE = "unsafe_passwords.txt"; @Comment({ "Players with premium nicknames should register/auth if this option is enabled", @@ -436,6 +437,7 @@ public static class STRINGS { public String REGISTER_PASSWORD_TOO_SHORT = "{PRFX} &cYou entered a too short password, use a different one!"; public String REGISTER_PASSWORD_TOO_LONG = "{PRFX} &cYou entered a too long password, use a different one!"; public String REGISTER_PASSWORD_UNSAFE = "{PRFX} &cYour password is unsafe, use a different one!"; + public String REGISTER_PASSWORD_UNSAFE_PASS_USER_SET = "{PRFX} &cYour password found in a database leak. You need to change your password to play in this server!"; public String REGISTER_SUCCESSFUL = "{PRFX} &aSuccessfully registered!"; @Comment(value = "Can be empty.", at = Comment.At.SAME_LINE) public String REGISTER_TITLE = "{PRFX}"; diff --git a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java index fd32fdd6..aee2e1ca 100644 --- a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java +++ b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java @@ -33,6 +33,7 @@ import java.text.MessageFormat; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -47,6 +48,7 @@ import net.elytrium.limboauth.event.PostRegisterEvent; import net.elytrium.limboauth.event.TaskEvent; import net.elytrium.limboauth.migration.MigrationHash; +import net.elytrium.limboauth.model.UnsafePlayer; import net.elytrium.limboauth.model.RegisteredPlayer; import net.elytrium.limboauth.model.SQLRuntimeException; import net.kyori.adventure.bossbar.BossBar; @@ -85,6 +87,7 @@ public class AuthSessionHandler implements LimboSessionHandler { private static Component registerPasswordTooLong; private static Component registerPasswordTooShort; private static Component registerPasswordUnsafe; + private static Component registerPasswordUnsafeUserPassSet; private static Component loginSuccessful; private static Component sessionExpired; @Nullable @@ -212,7 +215,8 @@ public void onChat(String message) { Command command = Command.parse(args[0]); if (command == Command.REGISTER && !this.totpState && this.playerInfo == null) { String password = args[1]; - if (this.checkPasswordsRepeat(args) && this.checkPasswordLength(password) && this.checkPasswordStrength(password)) { + if (this.checkPasswordsRepeat(args) && this.checkPasswordLength(password) + && this.checkPasswordStrength(password) && this.checkUnsafePassSet(this.proxyPlayer.getUsername(), password)) { this.saveTempPassword(password); RegisteredPlayer registeredPlayer = new RegisteredPlayer(this.proxyPlayer).setPassword(password); @@ -408,6 +412,19 @@ private boolean checkPasswordStrength(String password) { } } + private boolean checkUnsafePassSet(String username, String password) { + Set unsafePlayers = this.plugin.getUnsafePlayerPassSet(); + + for (UnsafePlayer risePlayer : unsafePlayers) { + if (username.equalsIgnoreCase(risePlayer.getUsername()) && risePlayer.getPassword().equalsIgnoreCase(password)) { + this.proxyPlayer.sendMessage(registerPasswordUnsafeUserPassSet); + return false; + } + } + + return true; + } + public void finishLogin() { this.proxyPlayer.sendMessage(loginSuccessful); if (loginSuccessfulTitle != null) { @@ -511,6 +528,7 @@ public static void reload() { registerPasswordTooLong = serializer.deserialize(Settings.IMP.MAIN.STRINGS.REGISTER_PASSWORD_TOO_LONG); registerPasswordTooShort = serializer.deserialize(Settings.IMP.MAIN.STRINGS.REGISTER_PASSWORD_TOO_SHORT); registerPasswordUnsafe = serializer.deserialize(Settings.IMP.MAIN.STRINGS.REGISTER_PASSWORD_UNSAFE); + registerPasswordUnsafeUserPassSet = serializer.deserialize(Settings.IMP.MAIN.STRINGS.REGISTER_PASSWORD_UNSAFE_PASS_USER_SET); loginSuccessful = serializer.deserialize(Settings.IMP.MAIN.STRINGS.LOGIN_SUCCESSFUL); sessionExpired = serializer.deserialize(Settings.IMP.MAIN.STRINGS.MOD_SESSION_EXPIRED); if (Settings.IMP.MAIN.STRINGS.LOGIN_SUCCESSFUL_TITLE.isEmpty() && Settings.IMP.MAIN.STRINGS.LOGIN_SUCCESSFUL_SUBTITLE.isEmpty()) { diff --git a/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java new file mode 100644 index 00000000..f2148c66 --- /dev/null +++ b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java @@ -0,0 +1,21 @@ +package net.elytrium.limboauth.model; + +public class UnsafePlayer { + + private final String username; + private final String password; + + public UnsafePlayer(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + +} diff --git a/src/main/resources/unsafe_pass_user_set.txt b/src/main/resources/unsafe_pass_user_set.txt new file mode 100644 index 00000000..0e8e9bd2 --- /dev/null +++ b/src/main/resources/unsafe_pass_user_set.txt @@ -0,0 +1,3 @@ +testUsername:TestPassword! +testUsername2:TestPassword1233 +testUsername3:TestPassword123 \ No newline at end of file From 2bc07ce2a8d8d316ca67e58e759890b8e12b59d7 Mon Sep 17 00:00:00 2001 From: Arda Date: Sat, 31 Aug 2024 15:40:26 +0300 Subject: [PATCH 2/4] Changed name of the variable --- .../net/elytrium/limboauth/handler/AuthSessionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java index aee2e1ca..f3b4e578 100644 --- a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java +++ b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java @@ -415,8 +415,8 @@ private boolean checkPasswordStrength(String password) { private boolean checkUnsafePassSet(String username, String password) { Set unsafePlayers = this.plugin.getUnsafePlayerPassSet(); - for (UnsafePlayer risePlayer : unsafePlayers) { - if (username.equalsIgnoreCase(risePlayer.getUsername()) && risePlayer.getPassword().equalsIgnoreCase(password)) { + for (UnsafePlayer unsafePlayer : unsafePlayers) { + if (username.equalsIgnoreCase(unsafePlayer.getUsername()) && unsafePlayer.getPassword().equalsIgnoreCase(password)) { this.proxyPlayer.sendMessage(registerPasswordUnsafeUserPassSet); return false; } From 4ce8ec64bb18d1505089bf098a11d17181509d35 Mon Sep 17 00:00:00 2001 From: Arda Date: Sat, 31 Aug 2024 15:43:27 +0300 Subject: [PATCH 3/4] Added license in UnsafePlayer class --- .../elytrium/limboauth/model/UnsafePlayer.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java index f2148c66..ea0dbe2c 100644 --- a/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java +++ b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2021 - 2024 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + package net.elytrium.limboauth.model; public class UnsafePlayer { From 9baf2d7012bc37154dc2693e83a45dbe0f84332c Mon Sep 17 00:00:00 2001 From: Arda Date: Sat, 31 Aug 2024 15:47:06 +0300 Subject: [PATCH 4/4] Fixed indents and order --- .../net/elytrium/limboauth/LimboAuth.java | 19 ++++++++------- .../limboauth/handler/AuthSessionHandler.java | 2 +- .../limboauth/model/UnsafePlayer.java | 24 +++++++++---------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/elytrium/limboauth/LimboAuth.java b/src/main/java/net/elytrium/limboauth/LimboAuth.java index c40288a2..c57b442d 100644 --- a/src/main/java/net/elytrium/limboauth/LimboAuth.java +++ b/src/main/java/net/elytrium/limboauth/LimboAuth.java @@ -110,9 +110,9 @@ import net.elytrium.limboauth.handler.AuthSessionHandler; import net.elytrium.limboauth.listener.AuthListener; import net.elytrium.limboauth.listener.BackendEndpointsListener; -import net.elytrium.limboauth.model.UnsafePlayer; import net.elytrium.limboauth.model.RegisteredPlayer; import net.elytrium.limboauth.model.SQLRuntimeException; +import net.elytrium.limboauth.model.UnsafePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.title.Title; @@ -325,11 +325,11 @@ public void reload() { String username = parts[0]; String password = parts[1]; UnsafePlayer unsafePlayer = new UnsafePlayer(username, password); - unsafePlayerPassSet.add(unsafePlayer); + this.unsafePlayerPassSet.add(unsafePlayer); } }); - this.server.sendMessage(Component.text("Loadded " + unsafePlayerPassSet.size() + " unsafe user & password set!")); + this.server.sendMessage(Component.text("Loadded " + this.unsafePlayerPassSet.size() + " unsafe user & password set!")); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -960,12 +960,13 @@ public Map getPostLoginTasks() { return this.postLoginTasks; } - public Set getUnsafePasswords() { - return this.unsafePasswords; - } - public Set getUnsafePlayerPassSet() { - return this.unsafePlayerPassSet; - } + public Set getUnsafePasswords() { + return this.unsafePasswords; + } + + public Set getUnsafePlayerPassSet() { + return this.unsafePlayerPassSet; + } public ProxyServer getServer() { return this.server; diff --git a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java index f3b4e578..fe92ef96 100644 --- a/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java +++ b/src/main/java/net/elytrium/limboauth/handler/AuthSessionHandler.java @@ -48,9 +48,9 @@ import net.elytrium.limboauth.event.PostRegisterEvent; import net.elytrium.limboauth.event.TaskEvent; import net.elytrium.limboauth.migration.MigrationHash; -import net.elytrium.limboauth.model.UnsafePlayer; import net.elytrium.limboauth.model.RegisteredPlayer; import net.elytrium.limboauth.model.SQLRuntimeException; +import net.elytrium.limboauth.model.UnsafePlayer; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.text.Component; import net.kyori.adventure.title.Title; diff --git a/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java index ea0dbe2c..0ced362b 100644 --- a/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java +++ b/src/main/java/net/elytrium/limboauth/model/UnsafePlayer.java @@ -20,20 +20,20 @@ public class UnsafePlayer { - private final String username; - private final String password; + private final String username; + private final String password; - public UnsafePlayer(String username, String password) { - this.username = username; - this.password = password; - } + public UnsafePlayer(String username, String password) { + this.username = username; + this.password = password; + } - public String getUsername() { - return username; - } + public String getUsername() { + return this.username; + } - public String getPassword() { - return password; - } + public String getPassword() { + return this.password; + } }