diff --git a/LaunchServer/source/auth/provider/AcceptAuthProvider.java b/LaunchServer/source/auth/provider/AcceptAuthProvider.java index 65c40f1..c6f39d3 100644 --- a/LaunchServer/source/auth/provider/AcceptAuthProvider.java +++ b/LaunchServer/source/auth/provider/AcceptAuthProvider.java @@ -8,7 +8,7 @@ } @Override - public String auth(String login, String password) { + public String auth(String login, String password, String ip) { return login; // Same as login } diff --git a/LaunchServer/source/auth/provider/AuthProvider.java b/LaunchServer/source/auth/provider/AuthProvider.java index 76837af..10b1314 100644 --- a/LaunchServer/source/auth/provider/AuthProvider.java +++ b/LaunchServer/source/auth/provider/AuthProvider.java @@ -23,7 +23,7 @@ public abstract void close() throws IOException; @LauncherAPI - public abstract String auth(String login, String password) throws Exception; + public abstract String auth(String login, String password, String ip) throws Exception; @LauncherAPI public static String authError(String message) throws AuthException { diff --git a/LaunchServer/source/auth/provider/FileAuthProvider.java b/LaunchServer/source/auth/provider/FileAuthProvider.java index 4f46378..0489d90 100644 --- a/LaunchServer/source/auth/provider/FileAuthProvider.java +++ b/LaunchServer/source/auth/provider/FileAuthProvider.java @@ -40,7 +40,7 @@ } @Override - public String auth(String login, String password) throws IOException { + public String auth(String login, String password, String ip) throws IOException { Entry entry; synchronized (cacheLock) { updateCache(); @@ -49,6 +49,9 @@ // Verify digest and return true username verifyDigest(entry == null ? null : entry.password, password); + if (entry == null || ip != null && !entry.ip.equals(ip)) { + authError("Authentication from this IP is not allowed"); + } return entry.username; } @@ -91,12 +94,15 @@ private static final class Entry extends ConfigObject { private final String username; private final String password; + private final String ip; private Entry(BlockConfigEntry block) { super(block); username = VerifyHelper.verifyUsername(block.getEntryValue("username", StringConfigEntry.class)); password = VerifyHelper.verify(block.getEntryValue("password", StringConfigEntry.class), VerifyHelper.NOT_EMPTY, String.format("Password can't be empty: '%s'", username)); + ip = block.hasEntry("ip") ? VerifyHelper.verify(block.getEntryValue("ip", StringConfigEntry.class), + VerifyHelper.NOT_EMPTY, String.format("IP can't be empty: '%s'", username)) : null; } } } diff --git a/LaunchServer/source/auth/provider/MySQLAuthProvider.java b/LaunchServer/source/auth/provider/MySQLAuthProvider.java index 63dfbf5..4d7bb5f 100644 --- a/LaunchServer/source/auth/provider/MySQLAuthProvider.java +++ b/LaunchServer/source/auth/provider/MySQLAuthProvider.java @@ -30,9 +30,9 @@ } @Override - public String auth(String login, String password) throws SQLException, AuthException { + public String 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 }; + 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)); } diff --git a/LaunchServer/source/auth/provider/NullAuthProvider.java b/LaunchServer/source/auth/provider/NullAuthProvider.java index 6701085..5c5aa81 100644 --- a/LaunchServer/source/auth/provider/NullAuthProvider.java +++ b/LaunchServer/source/auth/provider/NullAuthProvider.java @@ -15,8 +15,8 @@ } @Override - public String auth(String login, String password) throws Exception { - return getProvider().auth(login, password); + public String auth(String login, String password, String ip) throws Exception { + return getProvider().auth(login, password, ip); } @Override diff --git a/LaunchServer/source/auth/provider/RejectAuthProvider.java b/LaunchServer/source/auth/provider/RejectAuthProvider.java index 74eced1..8a08b08 100644 --- a/LaunchServer/source/auth/provider/RejectAuthProvider.java +++ b/LaunchServer/source/auth/provider/RejectAuthProvider.java @@ -15,7 +15,7 @@ } @Override - public String auth(String login, String password) throws AuthException { + public String auth(String login, String password, String ip) throws AuthException { return authError(message); } diff --git a/LaunchServer/source/auth/provider/RequestAuthProvider.java b/LaunchServer/source/auth/provider/RequestAuthProvider.java index 88539fb..5fb9a3f 100644 --- a/LaunchServer/source/auth/provider/RequestAuthProvider.java +++ b/LaunchServer/source/auth/provider/RequestAuthProvider.java @@ -20,12 +20,12 @@ response = Pattern.compile(block.getEntryValue("response", StringConfigEntry.class)); // Verify is valid URL - IOHelper.verifyURL(getFormattedURL("urlAuthLogin", "urlAuthPassword")); + IOHelper.verifyURL(getFormattedURL("urlAuthLogin", "urlAuthPassword", "urlAuthIP")); } @Override - public String auth(String login, String password) throws IOException { - String currentResponse = IOHelper.request(new URL(getFormattedURL(login, password))); + public String auth(String login, String password, String ip) throws IOException { + String currentResponse = IOHelper.request(new URL(getFormattedURL(login, password, ip))); // Match username Matcher matcher = response.matcher(currentResponse); @@ -38,7 +38,7 @@ // Do nothing } - private String getFormattedURL(String login, String password) { - return CommonHelper.replace(url, "login", IOHelper.urlEncode(login), "password", IOHelper.urlEncode(password)); + private String getFormattedURL(String login, String password, String ip) { + return CommonHelper.replace(url, "login", IOHelper.urlEncode(login), "password", IOHelper.urlEncode(password), "ip", IOHelper.urlEncode(ip)); } } diff --git a/LaunchServer/source/command/auth/AuthCommand.java b/LaunchServer/source/command/auth/AuthCommand.java index 9a6bb1a..0c5f371 100644 --- a/LaunchServer/source/command/auth/AuthCommand.java +++ b/LaunchServer/source/command/auth/AuthCommand.java @@ -29,7 +29,7 @@ String password = args[1]; // Authenticate - String username = server.config.authProvider.auth(login, password); + String username = server.config.authProvider.auth(login, password, "127.0.0.1"); // Authenticate on server (and get UUID) String accessToken = SecurityHelper.randomStringToken(); diff --git a/LaunchServer/source/response/ResponseThread.java b/LaunchServer/source/response/ResponseThread.java index 0f3c4c3..691d2e8 100644 --- a/LaunchServer/source/response/ResponseThread.java +++ b/LaunchServer/source/response/ResponseThread.java @@ -125,7 +125,7 @@ response = new PingResponse(server, id, input, output); break; case AUTH: - response = new AuthResponse(server, id, input, output); + response = new AuthResponse(server, id, input, output, IOHelper.getIP(socket.getRemoteSocketAddress())); break; case JOIN_SERVER: response = new JoinServerResponse(server, id, input, output); diff --git a/LaunchServer/source/response/auth/AuthResponse.java b/LaunchServer/source/response/auth/AuthResponse.java index 06fcc35..32ff8e3 100644 --- a/LaunchServer/source/response/auth/AuthResponse.java +++ b/LaunchServer/source/response/auth/AuthResponse.java @@ -18,8 +18,11 @@ import launchserver.response.profile.ProfileByUUIDResponse; public final class AuthResponse extends Response { - public AuthResponse(LaunchServer server, long id, HInput input, HOutput output) { + private final String ip; + + public AuthResponse(LaunchServer server, long id, HInput input, HOutput output, String ip) { super(server, id, input, output); + this.ip = ip; } @Override @@ -41,7 +44,7 @@ debug("Login: '%s', Password: '%s'", login, echo(password.length())); String username; try { - username = server.config.authProvider.auth(login, password); + username = server.config.authProvider.auth(login, password, ip); if (!VerifyHelper.isValidUsername(username)) { AuthProvider.authError(String.format("Illegal username: '%s'", username)); return;