[FEATURE] LaunchServerRuntimeConfig

This commit is contained in:
Gravit 2019-04-12 04:58:45 +07:00
parent ab57e7d2d7
commit 3c0de3727d
12 changed files with 158 additions and 7 deletions

View file

@ -25,6 +25,7 @@
import ru.gravit.launchserver.binary.*; import ru.gravit.launchserver.binary.*;
import ru.gravit.launchserver.components.AuthLimiterComponent; import ru.gravit.launchserver.components.AuthLimiterComponent;
import ru.gravit.launchserver.components.Component; import ru.gravit.launchserver.components.Component;
import ru.gravit.launchserver.config.LaunchServerRuntimeConfig;
import ru.gravit.launchserver.config.adapter.*; import ru.gravit.launchserver.config.adapter.*;
import ru.gravit.launchserver.manangers.*; import ru.gravit.launchserver.manangers.*;
import ru.gravit.launchserver.manangers.hook.AuthHookManager; import ru.gravit.launchserver.manangers.hook.AuthHookManager;
@ -41,10 +42,7 @@
import ru.gravit.utils.config.JsonConfigurable; import ru.gravit.utils.config.JsonConfigurable;
import ru.gravit.utils.helper.*; import ru.gravit.utils.helper.*;
import java.io.BufferedReader; import java.io.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect; import java.lang.ProcessBuilder.Redirect;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -336,6 +334,7 @@ public static void main(String... args) throws Throwable {
public final List<String> args; public final List<String> args;
public final Path configFile; public final Path configFile;
public final Path runtimeConfigFile;
public final Path publicKeyFile; public final Path publicKeyFile;
@ -349,6 +348,7 @@ public static void main(String... args) throws Throwable {
// Server config // Server config
public Config config; public Config config;
public LaunchServerRuntimeConfig runtime;
public final RSAPublicKey publicKey; public final RSAPublicKey publicKey;
@ -413,6 +413,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
launcherLibrariesCompile = dir.resolve("launcher-libraries-compile"); launcherLibrariesCompile = dir.resolve("launcher-libraries-compile");
this.args = Arrays.asList(args); this.args = Arrays.asList(args);
configFile = dir.resolve("LaunchServer.conf"); configFile = dir.resolve("LaunchServer.conf");
runtimeConfigFile = dir.resolve("RuntimeLaunchServer.conf");
publicKeyFile = dir.resolve("public.key"); publicKeyFile = dir.resolve("public.key");
privateKeyFile = dir.resolve("private.key"); privateKeyFile = dir.resolve("private.key");
updatesDir = dir.resolve("updates"); updatesDir = dir.resolve("updates");
@ -486,6 +487,20 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
try (BufferedReader reader = IOHelper.newReader(configFile)) { try (BufferedReader reader = IOHelper.newReader(configFile)) {
config = Launcher.gson.fromJson(reader, Config.class); config = Launcher.gson.fromJson(reader, Config.class);
} }
if(!Files.exists(runtimeConfigFile))
{
LogHelper.info("Reset LaunchServer runtime config file");
runtime = new LaunchServerRuntimeConfig();
runtime.reset();
}
else
{
LogHelper.info("Reading LaunchServer runtime config file");
try (BufferedReader reader = IOHelper.newReader(runtimeConfigFile)) {
runtime = Launcher.gson.fromJson(reader, LaunchServerRuntimeConfig.class);
}
}
runtime.verify();
config.verify(); config.verify();
Launcher.applyLauncherEnv(config.env); Launcher.applyLauncherEnv(config.env);
for (AuthProviderPair provider : config.auth) { for (AuthProviderPair provider : config.auth) {
@ -633,6 +648,18 @@ public void close() {
// Close handlers & providers // Close handlers & providers
config.close(); config.close();
modulesManager.close(); modulesManager.close();
LogHelper.info("Save LaunchServer runtime config");
try(Writer writer = IOHelper.newWriter(runtimeConfigFile))
{
if(LaunchServer.gson != null)
{
LaunchServer.gson.toJson(runtime, writer);
} else {
LogHelper.error("Error writing LaunchServer runtime config file. Gson is null");
}
} catch (IOException e) {
LogHelper.error(e);
}
// Print last message before death :( // Print last message before death :(
LogHelper.info("LaunchServer stopped"); LogHelper.info("LaunchServer stopped");
} }

View file

@ -9,6 +9,21 @@ public String generateSecureToken(AuthResponse.AuthContext context) {
return SecurityHelper.randomStringToken(); return SecurityHelper.randomStringToken();
} }
@Override
public String generateClientSecureToken() {
return SecurityHelper.randomStringToken();
}
@Override
public boolean verifyClientSecureToken(String token) {
return true;
}
@Override
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
return true;
}
@Override @Override
public void checkLaunchServerLicense() { public void checkLaunchServerLicense() {
// None // None

View file

@ -38,6 +38,10 @@ public static void registerHandlers() {
public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface
public abstract String generateClientSecureToken();
public abstract boolean verifyClientSecureToken(String token);
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии
//public abstract //public abstract
} }

View file

@ -0,0 +1,16 @@
package ru.gravit.launchserver.config;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.SecurityHelper;
public class LaunchServerRuntimeConfig {
public String clientToken;
public void verify()
{
if(clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
}
public void reset()
{
clientToken = SecurityHelper.randomStringToken();
}
}

View file

@ -14,6 +14,7 @@ public class Client {
public ClientProfile profile; public ClientProfile profile;
public boolean isAuth; public boolean isAuth;
public boolean checkSign; public boolean checkSign;
public boolean isSecure;
public ClientPermissions permissions; public ClientPermissions permissions;
public String username; public String username;
public LogHelper.OutputEnity logOutput; public LogHelper.OutputEnity logOutput;

View file

@ -22,6 +22,8 @@
import ru.gravit.launchserver.websocket.json.profile.BatchProfileByUsername; import ru.gravit.launchserver.websocket.json.profile.BatchProfileByUsername;
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse; import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
import ru.gravit.launchserver.websocket.json.profile.ProfileByUsername; import ru.gravit.launchserver.websocket.json.profile.ProfileByUsername;
import ru.gravit.launchserver.websocket.json.secure.GetSecureTokenResponse;
import ru.gravit.launchserver.websocket.json.secure.VerifySecureTokenResponse;
import ru.gravit.launchserver.websocket.json.update.LauncherResponse; import ru.gravit.launchserver.websocket.json.update.LauncherResponse;
import ru.gravit.launchserver.websocket.json.update.UpdateListResponse; import ru.gravit.launchserver.websocket.json.update.UpdateListResponse;
import ru.gravit.launchserver.websocket.json.update.UpdateResponse; import ru.gravit.launchserver.websocket.json.update.UpdateResponse;
@ -88,6 +90,8 @@ public void registerResponses() {
registerResponse("batchProfileByUsername", BatchProfileByUsername.class); registerResponse("batchProfileByUsername", BatchProfileByUsername.class);
registerResponse("profileByUsername", ProfileByUsername.class); registerResponse("profileByUsername", ProfileByUsername.class);
registerResponse("profileByUUID", ProfileByUUIDResponse.class); registerResponse("profileByUUID", ProfileByUUIDResponse.class);
registerResponse("getSecureToken", GetSecureTokenResponse.class);
registerResponse("verifySecureToken", VerifySecureTokenResponse.class);
} }
public void sendObject(ChannelHandlerContext ctx, Object obj) { public void sendObject(ChannelHandlerContext ctx, Object obj) {

View file

@ -105,7 +105,6 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
//if (clientData.profile == null) { //if (clientData.profile == null) {
// throw new AuthException("You profile not found"); // throw new AuthException("You profile not found");
//} //}
UUID uuid = pair.handler.auth(aresult);
if (authType == ConnectTypes.CLIENT) if (authType == ConnectTypes.CLIENT)
LaunchServer.server.config.hwidHandler.check(hwid, aresult.username); LaunchServer.server.config.hwidHandler.check(hwid, aresult.username);
LaunchServer.server.authHookManager.postHook(context, clientData); LaunchServer.server.authHookManager.postHook(context, clientData);
@ -121,8 +120,12 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
LaunchServer.server.sessionManager.addClient(clientData); LaunchServer.server.sessionManager.addClient(clientData);
result.session = clientData.session; result.session = clientData.session;
} }
if(LaunchServer.server.config.protectHandler.allowGetAccessToken(context))
{
UUID uuid = pair.handler.auth(aresult);
result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, aresult.username, client, clientData.auth.textureProvider); result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, aresult.username, client, clientData.auth.textureProvider);
LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString()); LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString());
}
service.sendObject(ctx, result); service.sendObject(ctx, result);
} catch (AuthException | HWIDException e) { } catch (AuthException | HWIDException e) {
service.sendObject(ctx, new ErrorRequestEvent(e.getMessage())); service.sendObject(ctx, new ErrorRequestEvent(e.getMessage()));

View file

@ -0,0 +1,21 @@
package ru.gravit.launchserver.websocket.json.secure;
import io.netty.channel.ChannelHandlerContext;
import ru.gravit.launcher.events.request.GetSecureTokenRequestEvent;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.WebSocketService;
import ru.gravit.launchserver.websocket.json.JsonResponseInterface;
public class GetSecureTokenResponse implements JsonResponseInterface {
@Override
public String getType() {
return "getSecureToken";
}
@Override
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
String secureToken = LaunchServer.server.config.protectHandler.generateClientSecureToken();
service.sendObject(ctx, new GetSecureTokenRequestEvent(secureToken));
}
}

View file

@ -0,0 +1,24 @@
package ru.gravit.launchserver.websocket.json.secure;
import io.netty.channel.ChannelHandlerContext;
import ru.gravit.launcher.events.request.VerifySecureTokenRequestEvent;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.WebSocketService;
import ru.gravit.launchserver.websocket.json.JsonResponseInterface;
public class VerifySecureTokenResponse implements JsonResponseInterface {
public String secureToken;
@Override
public String getType() {
return "verifySecureToken";
}
@Override
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
boolean success = LaunchServer.server.config.protectHandler.verifyClientSecureToken(secureToken);
if(success) client.isSecure = true;
service.sendObject(ctx, new VerifySecureTokenRequestEvent(success));
}
}

View file

@ -111,6 +111,8 @@ public void registerResults() {
registerResult("error", ErrorRequestEvent.class); registerResult("error", ErrorRequestEvent.class);
registerResult("update", UpdateRequestEvent.class); registerResult("update", UpdateRequestEvent.class);
registerResult("restoreSession", RestoreSessionRequestEvent.class); registerResult("restoreSession", RestoreSessionRequestEvent.class);
registerResult("getSecureToken", GetSecureTokenRequestEvent.class);
registerResult("verifySecureToken", VerifySecureTokenRequestEvent.class);
} }
public void registerHandler(EventHandler eventHandler) { public void registerHandler(EventHandler eventHandler) {

View file

@ -0,0 +1,17 @@
package ru.gravit.launcher.events.request;
import ru.gravit.launcher.LauncherNetworkAPI;
import ru.gravit.launcher.request.ResultInterface;
public class GetSecureTokenRequestEvent implements ResultInterface {
@LauncherNetworkAPI
public String secureToken;
@Override
public String getType() {
return "GetSecureToken";
}
public GetSecureTokenRequestEvent(String secureToken) {
this.secureToken = secureToken;
}
}

View file

@ -0,0 +1,17 @@
package ru.gravit.launcher.events.request;
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.request.ResultInterface;
public class VerifySecureTokenRequestEvent implements ResultInterface {
@LauncherAPI
public boolean success;
@Override
public String getType() {
return "verifySecureToken";
}
public VerifySecureTokenRequestEvent(boolean success) {
this.success = success;
}
}