diff --git a/LaunchServer/LaunchServer.iml b/LaunchServer/LaunchServer.iml index da32c08..0c1bb78 100644 --- a/LaunchServer/LaunchServer.iml +++ b/LaunchServer/LaunchServer.iml @@ -60,5 +60,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/LaunchServer/source/auth/provider/AuthProvider.java b/LaunchServer/source/auth/provider/AuthProvider.java index 7f0da4b..8cfe8de 100644 --- a/LaunchServer/source/auth/provider/AuthProvider.java +++ b/LaunchServer/source/auth/provider/AuthProvider.java @@ -53,6 +53,7 @@ registerProvider("file", FileAuthProvider::new); registerProvider("mojang", MojangAuthProvider::new); registerProvider("mysql", MySQLAuthProvider::new); + registerProvider("mysql-bcrypt", MySQLBcryptAuthProvider::new); registerProvider("request", RequestAuthProvider::new); } } diff --git a/LaunchServer/source/auth/provider/MySQLBcryptAuthProvider.java b/LaunchServer/source/auth/provider/MySQLBcryptAuthProvider.java new file mode 100644 index 0000000..d2d6052 --- /dev/null +++ b/LaunchServer/source/auth/provider/MySQLBcryptAuthProvider.java @@ -0,0 +1,60 @@ +package launchserver.auth.provider; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.mindrot.jbcrypt.BCrypt; + +import launcher.helper.CommonHelper; +import launcher.helper.SecurityHelper; +import launcher.helper.VerifyHelper; +import launcher.serialize.config.entry.BlockConfigEntry; +import launcher.serialize.config.entry.ListConfigEntry; +import launcher.serialize.config.entry.StringConfigEntry; +import launchserver.auth.AuthException; +import launchserver.auth.MySQLSourceConfig; + +public final class MySQLBcryptAuthProvider extends AuthProvider +{ + private final MySQLSourceConfig mySQLHolder; + private final String query; + private final String[] queryParams; + + public MySQLBcryptAuthProvider(BlockConfigEntry block) + { + super(block); + mySQLHolder = new MySQLSourceConfig("authProviderPool", block); + + query = VerifyHelper.verify(block.getEntryValue("query", StringConfigEntry.class), + VerifyHelper.NOT_EMPTY, "MySQL query can't be empty"); + queryParams = block.getEntry("queryParams", ListConfigEntry.class). + stream(StringConfigEntry.class).toArray(String[]::new); + } + + @Override + public AuthProviderResult auth(String login, String password, String ip) throws SQLException, AuthException + { + try (Connection c = mySQLHolder.getConnection(); PreparedStatement s = c.prepareStatement(query)) + { + String[] replaceParams = { "login", login, "password", password, "ip", ip }; + for (int i = 0; i < queryParams.length; i++) + { + s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams)); + } + + // Execute SQL query + s.setQueryTimeout(MySQLSourceConfig.TIMEOUT); + try (ResultSet set = s.executeQuery()) + { + return set.next() ? BCrypt.checkpw(password, "$2a" + set.getString(1).substring(3)) ? new AuthProviderResult(set.getString(2), SecurityHelper.randomStringToken()) : authError("Incorrect username or password") : authError("Incorrect username or password"); + } + } + } + + @Override + public void close() { + mySQLHolder.close(); + } +} diff --git a/build/libraries/jbcrypt.jar b/build/libraries/jbcrypt.jar new file mode 100644 index 0000000..ccace8b --- /dev/null +++ b/build/libraries/jbcrypt.jar Binary files differ