[FIX] Remove HWIDProvider

This commit is contained in:
Gravita 2021-11-10 23:14:26 +07:00
parent ac1279ff5c
commit 50d8f12536
22 changed files with 39 additions and 677 deletions

View file

@ -3,9 +3,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launcher.managers.ConfigManager;
import pro.gravit.launcher.managers.GarbageManager;
import pro.gravit.launcher.modules.events.ClosePhase;
import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launchserver.auth.AuthProviderPair;
@ -166,7 +164,6 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La
config.init(ReloadType.FULL);
registerObject("launchServer", this);
GarbageManager.registerNeedGC(sessionManager);
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(commandHandler, this);
@ -411,9 +408,6 @@ public void registerObject(String name, Object object) {
if (object instanceof Reconfigurable) {
reconfigurableManager.registerReconfigurable(name, (Reconfigurable) object);
}
if (object instanceof NeedGarbageCollection) {
GarbageManager.registerNeedGC((NeedGarbageCollection) object);
}
}
@SuppressWarnings("deprecation")
@ -421,9 +415,6 @@ public void unregisterObject(String name, Object object) {
if (object instanceof Reconfigurable) {
reconfigurableManager.unregisterReconfigurable(name);
}
if (object instanceof NeedGarbageCollection) {
GarbageManager.unregisterNeedGC((NeedGarbageCollection) object);
}
}
public void fullyRestart() {

View file

@ -13,7 +13,6 @@
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
import pro.gravit.launchserver.auth.password.PasswordVerifier;
import pro.gravit.launchserver.auth.protect.ProtectHandler;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.auth.session.SessionStorage;
import pro.gravit.launchserver.auth.texture.TextureProvider;
import pro.gravit.launchserver.components.Component;
@ -204,7 +203,6 @@ public static void registerAll() {
WebSocketService.registerResponses();
AuthRequest.registerProviders();
GetAvailabilityAuthRequest.registerProviders();
HWIDProvider.registerProviders();
OptionalAction.registerProviders();
OptionalTrigger.registerProviders();
SessionStorage.registerProviders();

View file

@ -17,13 +17,11 @@
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportRegistration;
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.manangers.AuthManager;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.command.CommandException;
import pro.gravit.utils.command.SubCommand;
import java.io.IOException;
@ -251,7 +249,7 @@ public void invoke(String... args) throws Exception {
verifyArgs(args, 2);
HardwareReportRequest.HardwareInfo hardware1 = Launcher.gsonManager.gson.fromJson(args[0], HardwareReportRequest.HardwareInfo.class);
HardwareReportRequest.HardwareInfo hardware2 = Launcher.gsonManager.gson.fromJson(args[1], HardwareReportRequest.HardwareInfo.class);
HWIDProvider.HardwareInfoCompareResult result = instance.compareHardwareInfo(hardware1, hardware2);
AuthSupportHardware.HardwareInfoCompareResult result = instance.compareHardwareInfo(hardware1, hardware2);
if (result == null) {
logger.error("Method compareHardwareInfo return null");
return;

View file

@ -13,7 +13,6 @@
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
import pro.gravit.launchserver.auth.password.PasswordVerifier;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.manangers.AuthManager;
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import pro.gravit.utils.helper.IOHelper;
@ -272,7 +271,7 @@ public UserHardware getHardwareInfoByData(HardwareReportRequest.HardwareInfo inf
try (ResultSet set = s.executeQuery()) {
while (set.next()) {
MySQLUserHardware hw = fetchHardwareInfo(set);
HWIDProvider.HardwareInfoCompareResult result = compareHardwareInfo(hw.getHardwareInfo(), info);
HardwareInfoCompareResult result = compareHardwareInfo(hw.getHardwareInfo(), info);
if (result.compareLevel > criticalCompareLevel) {
return hw;
}

View file

@ -5,7 +5,6 @@
import pro.gravit.launchserver.auth.core.UserSession;
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.helper.DamerauHelper;
import java.util.Arrays;
@ -40,8 +39,8 @@ default void normalizeHardwareInfo(HardwareReportRequest.HardwareInfo hardwareIn
}
//Required normalize HardwareInfo
default HWIDProvider.HardwareInfoCompareResult compareHardwareInfo(HardwareReportRequest.HardwareInfo first, HardwareReportRequest.HardwareInfo second) {
HWIDProvider.HardwareInfoCompareResult result = new HWIDProvider.HardwareInfoCompareResult();
default HardwareInfoCompareResult compareHardwareInfo(HardwareReportRequest.HardwareInfo first, HardwareReportRequest.HardwareInfo second) {
HardwareInfoCompareResult result = new HardwareInfoCompareResult();
if (first.hwDiskId == null || first.hwDiskId.isEmpty()) result.firstSpoofingLevel += 0.9;
if (first.displayId == null || first.displayId.length < 4) result.firstSpoofingLevel += 0.3;
if (first.baseboardSerialNumber == null || first.baseboardSerialNumber.trim().isEmpty())
@ -95,4 +94,10 @@ default HWIDProvider.HardwareInfoCompareResult compareHardwareInfo(HardwareRepor
result.compareLevel += 0.05;
return result;
}
class HardwareInfoCompareResult {
public double firstSpoofingLevel = 0.0;
public double secondSpoofingLevel = 0.0;
public double compareLevel;
}
}

View file

@ -9,12 +9,9 @@
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
import pro.gravit.launchserver.auth.protect.hwid.HWIDException;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.auth.protect.interfaces.HardwareProtectHandler;
import pro.gravit.launchserver.auth.protect.interfaces.JoinServerProtectHandler;
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
@ -22,17 +19,13 @@
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import pro.gravit.launchserver.socket.response.auth.RestoreResponse;
import pro.gravit.launchserver.socket.response.secure.HardwareReportResponse;
import pro.gravit.utils.command.Command;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler, JoinServerProtectHandler, Reconfigurable {
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler, JoinServerProtectHandler {
private transient final Logger logger = LogManager.getLogger();
public boolean enableHardwareFeature;
public HWIDProvider provider;
private transient LaunchServer server;
@Override
@ -61,37 +54,28 @@ public void onHardwareReport(HardwareReportResponse response, Client client) {
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, response.hardware)));
return;
}
try {
if (!client.isAuth || client.trustLevel == null || client.trustLevel.publicKey == null) {
response.sendError("Access denied");
return;
}
logger.debug("HardwareInfo received");
{
var authSupportHardware = client.auth.isSupport(AuthSupportHardware.class);
if (authSupportHardware != null) {
UserHardware hardware = authSupportHardware.getHardwareInfoByData(response.hardware);
if (hardware == null) {
hardware = authSupportHardware.createHardwareInfo(response.hardware, client.trustLevel.publicKey);
} else {
authSupportHardware.addPublicKeyToHardwareInfo(hardware, client.trustLevel.publicKey);
}
authSupportHardware.connectUserAndHardware(client.sessionObject, hardware);
if (hardware.isBanned()) {
throw new SecurityException("Your hardware banned");
}
client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
if (!client.isAuth || client.trustLevel == null || client.trustLevel.publicKey == null) {
response.sendError("Access denied");
return;
}
logger.debug("HardwareInfo received");
{
var authSupportHardware = client.auth.isSupport(AuthSupportHardware.class);
if (authSupportHardware != null) {
UserHardware hardware = authSupportHardware.getHardwareInfoByData(response.hardware);
if (hardware == null) {
hardware = authSupportHardware.createHardwareInfo(response.hardware, client.trustLevel.publicKey);
} else {
provider.normalizeHardwareInfo(response.hardware);
boolean needCreate = !provider.addPublicKeyToHardwareInfo(response.hardware, client.trustLevel.publicKey, client);
logger.debug("HardwareInfo needCreate: {}", needCreate ? "true" : "false");
if (needCreate)
provider.createHardwareInfo(response.hardware, client.trustLevel.publicKey, client);
client.trustLevel.hardwareInfo = response.hardware;
authSupportHardware.addPublicKeyToHardwareInfo(hardware, client.trustLevel.publicKey);
}
authSupportHardware.connectUserAndHardware(client.sessionObject, hardware);
if (hardware.isBanned()) {
throw new SecurityException("Your hardware banned");
}
client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
} else {
logger.error("AuthCoreProvider not supported hardware");
}
} catch (HWIDException e) {
throw new SecurityException(e.getMessage());
}
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, response.hardware)));
}
@ -109,31 +93,14 @@ public VerifySecureLevelKeyRequestEvent onSuccessVerify(Client client) {
}
client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
authSupportHardware.connectUserAndHardware(client.sessionObject, hardware);
} else if (provider == null) {
logger.warn("HWIDProvider null. HardwareInfo not checked!");
} else {
try {
client.trustLevel.hardwareInfo = provider.findHardwareInfoByPublicKey(client.trustLevel.publicKey, client);
if (client.trustLevel.hardwareInfo == null) //HWID not found?
return new VerifySecureLevelKeyRequestEvent(true, false, createPublicKeyToken(client.username, client.trustLevel.publicKey));
} catch (HWIDException e) {
throw new SecurityException(e.getMessage()); //Show banned message
}
logger.warn("AuthCoreProvider not supported hardware. HardwareInfo not checked!");
}
return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey));
}
return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey));
}
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
if (provider instanceof Reconfigurable) {
commands.putAll(((Reconfigurable) provider).getCommands());
}
return commands;
}
@Override
public boolean onJoinServer(String serverID, String username, Client client) {
return !enableHardwareFeature || (client.trustLevel != null && client.trustLevel.hardwareInfo != null);
@ -141,17 +108,11 @@ public boolean onJoinServer(String serverID, String username, Client client) {
@Override
public void init(LaunchServer server) {
if (provider != null) {
provider.init(server);
logger.warn("HWIDProvider deprecated. Please use 'AuthSupportHardware' in AuthCoreProvider");
}
this.server = server;
}
@Override
public void close() {
if (provider != null)
provider.close();
}
public String createHardwareToken(String username, HardwareReportRequest.HardwareInfo info) {

View file

@ -1,22 +0,0 @@
package pro.gravit.launchserver.auth.protect.hwid;
public class HWIDException extends Exception {
public HWIDException() {
}
public HWIDException(String message) {
super(message);
}
public HWIDException(String message, Throwable cause) {
super(message, cause);
}
public HWIDException(Throwable cause) {
super(cause);
}
public HWIDException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -1,116 +0,0 @@
package pro.gravit.launchserver.auth.protect.hwid;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.helper.DamerauHelper;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.helper.SecurityHelper;
import java.util.Arrays;
public abstract class HWIDProvider {
public static final ProviderMap<HWIDProvider> providers = new ProviderMap<>("HWIDProvider");
private static boolean registredProv = false;
private final Logger logger = LogManager.getLogger();
public static void registerProviders() {
if (!registredProv) {
providers.register("memory", MemoryHWIDProvider.class);
providers.register("mysql", MysqlHWIDProvider.class);
providers.register("json", JsonHWIDProvider.class);
registredProv = true;
}
}
public abstract HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException;
public abstract void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException;
public abstract boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException;
public void normalizeHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo) {
if (hardwareInfo.baseboardSerialNumber != null)
hardwareInfo.baseboardSerialNumber = hardwareInfo.baseboardSerialNumber.trim();
if (hardwareInfo.hwDiskId != null) hardwareInfo.hwDiskId = hardwareInfo.hwDiskId.trim();
}
//Required normalize HardwareInfo
public HardwareInfoCompareResult compareHardwareInfo(HardwareReportRequest.HardwareInfo first, HardwareReportRequest.HardwareInfo second) {
HardwareInfoCompareResult result = new HardwareInfoCompareResult();
if (first.hwDiskId == null || first.hwDiskId.isEmpty()) result.firstSpoofingLevel += 0.9;
if (first.displayId == null || first.displayId.length < 4) result.firstSpoofingLevel += 0.3;
if (first.baseboardSerialNumber == null || first.baseboardSerialNumber.trim().isEmpty())
result.firstSpoofingLevel += 0.2;
if (second.hwDiskId == null || second.hwDiskId.trim().isEmpty()) result.secondSpoofingLevel += 0.9;
if (second.displayId == null || second.displayId.length < 4) result.secondSpoofingLevel += 0.3;
if (second.baseboardSerialNumber == null || second.baseboardSerialNumber.trim().isEmpty())
result.secondSpoofingLevel += 0.2;
if (first.hwDiskId != null && second.hwDiskId != null) {
int hwDIskIdRate = DamerauHelper.calculateDistance(first.hwDiskId.toLowerCase(), second.hwDiskId.toLowerCase());
if (hwDIskIdRate == 0) // 100% compare
{
result.compareLevel += 0.99;
} else if (hwDIskIdRate < 3) //Very small change
{
result.compareLevel += 0.85;
} else if (hwDIskIdRate < (first.hwDiskId.length() + second.hwDiskId.length()) / 4) {
double addLevel = hwDIskIdRate / ((double) (first.hwDiskId.length() + second.hwDiskId.length()) / 2.0);
if (addLevel > 0.0 && addLevel < 0.85) result.compareLevel += addLevel;
}
}
if (first.baseboardSerialNumber != null && second.baseboardSerialNumber != null) {
int baseboardSerialRate = DamerauHelper.calculateDistance(first.baseboardSerialNumber.toLowerCase(), second.baseboardSerialNumber.toLowerCase());
if (baseboardSerialRate == 0) // 100% compare
{
result.compareLevel += 0.3;
} else if (baseboardSerialRate < 3) //Very small change
{
result.compareLevel += 0.15;
}
}
if (first.displayId != null && second.displayId != null) {
if (Arrays.equals(first.displayId, second.displayId)) {
result.compareLevel += 0.75;
}
}
//Check statistic info
if (first.logicalProcessors == 0 || first.physicalProcessors == 0 || first.logicalProcessors < first.physicalProcessors) //WTF
result.firstSpoofingLevel += 0.9;
if (second.logicalProcessors == 0 || second.physicalProcessors == 0 || second.logicalProcessors < second.physicalProcessors) //WTF
result.secondSpoofingLevel += 0.9;
if (first.physicalProcessors == second.physicalProcessors && first.logicalProcessors == second.logicalProcessors)
result.compareLevel += 0.05;
if (first.battery != second.battery)
result.compareLevel -= 0.05;
if (first.processorMaxFreq == second.processorMaxFreq)
result.compareLevel += 0.1;
if (first.totalMemory == second.totalMemory)
result.compareLevel += 0.1;
if (Math.abs(first.totalMemory - second.totalMemory) < 32 * 1024)
result.compareLevel += 0.05;
return result;
}
protected void printHardwareInfo(HardwareReportRequest.HardwareInfo info) {
logger.info("[HardwareInfo] Processor: logical {} | physical {} | freq {} | bitness {}", info.logicalProcessors, info.physicalProcessors, info.processorMaxFreq, info.bitness);
logger.info("[HardwareInfo] Memory max: {} | battery {}", info.totalMemory, info.battery ? "true" : "false");
logger.info("[HardwareInfo] HWDiskID {} | baseboardSerialNumber {} | displayId hash: {}", info.hwDiskId, info.baseboardSerialNumber, SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, info.displayId)));
}
public void init(LaunchServer server) {
}
public void close() {
}
public static class HardwareInfoCompareResult {
public double firstSpoofingLevel = 0.0;
public double secondSpoofingLevel = 0.0;
public double compareLevel;
}
}

View file

@ -1,101 +0,0 @@
package pro.gravit.launchserver.auth.protect.hwid;
import pro.gravit.launcher.HTTPRequest;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.socket.Client;
import java.net.URL;
public class JsonHWIDProvider extends HWIDProvider {
public URL findHardwareInfoByPublicKeyRequest;
public URL createHardwareInfoRequest;
public URL addPublicKeyToHardwareInfoRequest;
public String apiKey;
@Override
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
try {
RequestFind req = new RequestFind();
req.publicKey = publicKey;
req.client = client;
req.apiKey = apiKey;
ResultFind r = Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(req), findHardwareInfoByPublicKeyRequest), ResultFind.class);
if (r.error != null) throw new HWIDException(r.error);
return r.info;
} catch (HWIDException t) {
throw t;
} catch (Throwable t) {
throw new HWIDException(t);
}
}
@Override
public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
try {
RequestCreate req = new RequestCreate();
req.publicKey = publicKey;
req.client = client;
req.hardwareInfo = hardwareInfo;
req.apiKey = apiKey;
ResultCreate r = Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(req), createHardwareInfoRequest), ResultCreate.class);
if (r.error != null) throw new HWIDException(r.error);
} catch (HWIDException t) {
throw t;
} catch (Throwable t) {
throw new HWIDException(t);
}
}
@Override
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
try {
RequestAddKey req = new RequestAddKey();
req.publicKey = publicKey;
req.client = client;
req.hardwareInfo = hardwareInfo;
req.apiKey = apiKey;
ResultAddKey r = Launcher.gsonManager.gson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.gson.toJsonTree(req), addPublicKeyToHardwareInfoRequest), ResultAddKey.class);
if (r.error != null) throw new HWIDException(r.error);
return r.success;
} catch (HWIDException t) {
throw t;
} catch (Throwable t) {
throw new HWIDException(t);
}
}
public static class RequestFind {
public byte[] publicKey;
public Client client;
public String apiKey;
}
public static class ResultFind {
public String error;
public HardwareReportRequest.HardwareInfo info;
}
public static class RequestCreate {
public byte[] publicKey;
public Client client;
public HardwareReportRequest.HardwareInfo hardwareInfo;
public String apiKey;
}
public static class ResultCreate {
public String error;
}
public static class RequestAddKey {
public byte[] publicKey;
public Client client;
public HardwareReportRequest.HardwareInfo hardwareInfo;
public String apiKey;
}
public static class ResultAddKey {
public String error;
public boolean success;
}
}

View file

@ -1,100 +0,0 @@
package pro.gravit.launchserver.auth.protect.hwid;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.SecurityHelper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class MemoryHWIDProvider extends HWIDProvider implements Reconfigurable {
private transient final Logger logger = LogManager.getLogger();
public double warningSpoofingLevel = -1.0;
public double criticalCompareLevel = 1.0;
public transient Set<MemoryHWIDEntity> db = ConcurrentHashMap.newKeySet();
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
commands.put("hardwarelist", new SubCommand() {
@Override
public void invoke(String... args) {
for (MemoryHWIDEntity e : db) {
printHardwareInfo(e.hardware);
logger.info("ID {} banned {}", e.id, e.banned ? "true" : "false");
logger.info("PublicKey Hash: {}", SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA1, e.publicKey)));
}
}
});
commands.put("hardwareban", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
long id = Long.parseLong(args[0]);
for (MemoryHWIDEntity e : db) {
if (e.id == id) {
e.banned = true;
logger.info("HardwareID {} banned", e.id);
}
}
}
});
return commands;
}
@Override
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
for (MemoryHWIDEntity e : db) {
if (Arrays.equals(e.publicKey, publicKey)) {
if (e.banned) throw new HWIDException("You HWID banned");
return e.hardware;
}
}
return null;
}
@Override
public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) {
db.add(new MemoryHWIDEntity(hardwareInfo, publicKey));
}
@Override
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
boolean isAlreadyWarning = false;
for (MemoryHWIDEntity e : db) {
HardwareInfoCompareResult result = compareHardwareInfo(e.hardware, hardwareInfo);
if (warningSpoofingLevel > 0 && result.firstSpoofingLevel > warningSpoofingLevel && !isAlreadyWarning) {
logger.warn("HardwareInfo spoofing level too high: {}", result.firstSpoofingLevel);
isAlreadyWarning = true;
}
if (result.compareLevel > criticalCompareLevel) {
logger.debug("HardwareInfo publicKey change: compareLevel {}", result.compareLevel);
if (e.banned) throw new HWIDException("You HWID banned");
e.publicKey = publicKey;
return true;
}
}
return false;
}
static class MemoryHWIDEntity {
public HardwareReportRequest.HardwareInfo hardware;
public byte[] publicKey;
public boolean banned;
public long id;
public MemoryHWIDEntity(HardwareReportRequest.HardwareInfo hardware, byte[] publicKey) {
this.hardware = hardware;
this.publicKey = publicKey;
this.id = SecurityHelper.newRandom().nextLong();
}
}
}

View file

@ -1,164 +0,0 @@
package pro.gravit.launchserver.auth.protect.hwid;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.request.secure.HardwareReportRequest;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.MySQLSourceConfig;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.helper.IOHelper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.sql.*;
public class MysqlHWIDProvider extends HWIDProvider {
private transient final Logger logger = LogManager.getLogger();
public MySQLSourceConfig mySQLHolder;
public double warningSpoofingLevel = -1.0;
public double criticalCompareLevel = 1.0;
public String tableHWID = "hwids";
public String tableHWIDLog = "hwidLog";
public String tableUsers;
public String usersNameColumn;
public String usersHWIDColumn;
private String sqlFindByPublicKey;
private String sqlFindByHardware;
private String sqlCreateHardware;
private String sqlCreateHWIDLog;
private String sqlUpdateHardware;
private String sqlUpdateUsers;
@Override
public void init(LaunchServer server) {
sqlFindByPublicKey = String.format("SELECT hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, banned FROM %s WHERE `publicKey` = ?", tableHWID);
sqlFindByHardware = String.format("SELECT hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, banned FROM %s", tableHWID);
sqlCreateHardware = String.format("INSERT INTO `%s` (`publickey`, `hwDiskId`, `baseboardSerialNumber`, `displayId`, `bitness`, `totalMemory`, `logicalProcessors`, `physicalProcessors`, `processorMaxFreq`, `battery`, `banned`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '0')", tableHWID);
sqlCreateHWIDLog = String.format("INSERT INTO %s (`hwidId`, `newPublicKey`) VALUES (?, ?)", tableHWIDLog);
sqlUpdateHardware = String.format("UPDATE %s SET `publicKey` = ? WHERE `id` = ?", tableHWID);
if (tableUsers != null && usersHWIDColumn != null && usersNameColumn != null) {
sqlUpdateUsers = String.format("UPDATE %s SET `%s` = ? WHERE `%s` = ?", tableUsers, usersHWIDColumn, usersNameColumn);
} else {
logger.warn("[MysqlHWIDProvider] Link to users table not configured");
}
}
@Override
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey, Client client) throws HWIDException {
try (Connection connection = mySQLHolder.getConnection()) {
PreparedStatement s = connection.prepareStatement(sqlFindByPublicKey);
s.setBlob(1, new ByteArrayInputStream(publicKey));
ResultSet set = s.executeQuery();
if (set.next()) {
if (set.getBoolean(11)) //isBanned
{
throw new HWIDException("You HWID banned");
}
long id = set.getLong(10);
setUserHardwareId(connection, client.username, id);
return fetchHardwareInfo(set);
} else {
return null;
}
} catch (SQLException | IOException throwables) {
logger.error(throwables);
throw new HWIDException("SQL error. Please try again later");
}
}
private HardwareReportRequest.HardwareInfo fetchHardwareInfo(ResultSet set) throws SQLException, IOException {
HardwareReportRequest.HardwareInfo hardwareInfo = new HardwareReportRequest.HardwareInfo();
hardwareInfo.hwDiskId = set.getString(1);
hardwareInfo.baseboardSerialNumber = set.getString(2);
Blob displayId = set.getBlob(3);
hardwareInfo.displayId = displayId == null ? null : IOHelper.read(displayId.getBinaryStream());
hardwareInfo.bitness = set.getInt(4);
hardwareInfo.totalMemory = set.getLong(5);
hardwareInfo.logicalProcessors = set.getInt(6);
hardwareInfo.physicalProcessors = set.getInt(7);
hardwareInfo.processorMaxFreq = set.getLong(8);
hardwareInfo.battery = set.getBoolean(9);
return hardwareInfo;
}
@Override
public void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
try (Connection connection = mySQLHolder.getConnection()) {
PreparedStatement s = connection.prepareStatement(sqlCreateHardware, Statement.RETURN_GENERATED_KEYS);
s.setBlob(1, new ByteArrayInputStream(publicKey));
s.setString(2, hardwareInfo.hwDiskId);
s.setString(3, hardwareInfo.baseboardSerialNumber);
s.setBlob(4, hardwareInfo.displayId == null ? null : new ByteArrayInputStream(hardwareInfo.displayId));
s.setInt(5, hardwareInfo.bitness);
s.setLong(6, hardwareInfo.totalMemory);
s.setInt(7, hardwareInfo.logicalProcessors);
s.setInt(8, hardwareInfo.physicalProcessors);
s.setLong(9, hardwareInfo.processorMaxFreq);
s.setBoolean(10, hardwareInfo.battery);
s.executeUpdate();
try (ResultSet generatedKeys = s.getGeneratedKeys()) {
if (generatedKeys.next()) {
writeHwidLog(connection, generatedKeys.getLong(1), publicKey);
setUserHardwareId(connection, client.username, generatedKeys.getLong(1));
}
}
} catch (SQLException throwables) {
logger.error(throwables);
throw new HWIDException("SQL error. Please try again later");
}
}
@Override
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, Client client) throws HWIDException {
try (Connection connection = mySQLHolder.getConnection()) {
PreparedStatement s = connection.prepareStatement(sqlFindByHardware);
ResultSet set = s.executeQuery();
while (set.next()) {
HardwareReportRequest.HardwareInfo hw = fetchHardwareInfo(set);
long id = set.getLong(10);
HardwareInfoCompareResult result = compareHardwareInfo(hw, hardwareInfo);
if (result.compareLevel > criticalCompareLevel) {
if (set.getBoolean(11)) //isBanned
{
throw new HWIDException("You HWID banned");
}
writeHwidLog(connection, id, publicKey);
changePublicKey(connection, id, publicKey);
setUserHardwareId(connection, client.username, id);
return true;
}
}
} catch (SQLException | IOException throwables) {
logger.error(throwables);
throw new HWIDException("SQL error. Please try again later");
}
return false;
}
private void changePublicKey(Connection connection, long id, byte[] publicKey) throws SQLException {
PreparedStatement s = connection.prepareStatement(sqlUpdateHardware);
s.setBlob(1, new ByteArrayInputStream(publicKey));
s.setLong(2, id);
s.executeUpdate();
}
private void writeHwidLog(Connection connection, long hwidId, byte[] newPublicKey) throws SQLException {
PreparedStatement s = connection.prepareStatement(sqlCreateHWIDLog);
s.setLong(1, hwidId);
s.setBlob(2, new ByteArrayInputStream(newPublicKey));
s.executeUpdate();
}
private void setUserHardwareId(Connection connection, String username, long hwidId) throws SQLException {
if (sqlUpdateUsers == null || username == null) return;
PreparedStatement s = connection.prepareStatement(sqlUpdateUsers);
s.setLong(1, hwidId);
s.setString(2, username);
s.executeUpdate();
}
@Override
public void close() {
mySQLHolder.close();
}
}

View file

@ -3,7 +3,6 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.utils.helper.IOHelper;
@ -12,14 +11,13 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
public class MemorySessionStorage extends SessionStorage implements NeedGarbageCollection, AutoCloseable {
public class MemorySessionStorage extends SessionStorage implements AutoCloseable {
private transient final Map<UUID, Entry> clientSet = new ConcurrentHashMap<>(128);
private transient final Map<UUID, Set<Entry>> uuidIndex = new ConcurrentHashMap<>(32);
@ -32,7 +30,6 @@ public void init(LaunchServer server) {
super.init(server);
if (autoDump) {
loadSessionsData();
garbageCollection();
}
}
@ -144,26 +141,9 @@ private void removeUuidFromIndexSet(Set<Entry> set, Entry e, UUID session) {
}
}
@Override
public void garbageCollection() {
long time = System.currentTimeMillis();
long session_timeout = server.config.netty.performance.sessionLifetimeMs;
Set<UUID> to_delete = new HashSet<>(32);
clientSet.forEach((uuid, entry) -> {
long timestamp = entry.timestamp;
if (timestamp + session_timeout < time)
to_delete.add(uuid);
});
for (UUID session : to_delete) {
deleteSession(session);
}
to_delete.clear();
}
@Override
public void close() {
if (autoDump) {
garbageCollection();
dumpSessionsData();
}
}

View file

@ -2,7 +2,6 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.command.SubCommand;
@ -12,7 +11,7 @@
import java.util.List;
import java.util.Map;
public abstract class AbstractLimiter<T> extends Component implements NeedGarbageCollection, Reconfigurable {
public abstract class AbstractLimiter<T> extends Component implements Reconfigurable {
public final List<T> exclude = new ArrayList<>();
protected final transient Map<T, LimitEntry> map = new HashMap<>();
private transient final Logger logger = LogManager.getLogger();
@ -64,7 +63,6 @@ public void invoke(String... args) {
protected abstract T getFromString(String str);
@Override
public void garbageCollection() {
long time = System.currentTimeMillis();
map.entrySet().removeIf((e) -> e.getValue().time + rateLimitMillis < time);

View file

@ -1,12 +1,11 @@
package pro.gravit.launchserver.components;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import pro.gravit.utils.HookException;
public class AuthLimiterComponent extends IPLimiter implements NeedGarbageCollection, AutoCloseable {
public class AuthLimiterComponent extends IPLimiter implements AutoCloseable {
public String message;
private transient LaunchServer srv;

View file

@ -1,6 +1,5 @@
package pro.gravit.launchserver.components;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
import pro.gravit.utils.HookException;
@ -8,7 +7,7 @@
import java.util.ArrayList;
import java.util.List;
public class RegLimiterComponent extends IPLimiter implements NeedGarbageCollection, AutoCloseable {
public class RegLimiterComponent extends IPLimiter implements AutoCloseable {
public transient LaunchServer launchServer;
public String message;

View file

@ -14,7 +14,6 @@
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
import pro.gravit.launchserver.auth.password.PasswordVerifier;
import pro.gravit.launchserver.auth.protect.ProtectHandler;
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
import pro.gravit.launchserver.auth.session.SessionStorage;
import pro.gravit.launchserver.auth.texture.TextureProvider;
import pro.gravit.launchserver.components.Component;
@ -44,7 +43,6 @@ public void registerAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
builder.registerTypeAdapter(GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails.class, new UniversalJsonAdapter<>(GetAvailabilityAuthRequest.providers));
builder.registerTypeAdapter(HWIDProvider.class, new UniversalJsonAdapter<>(HWIDProvider.providers));
builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers));
builder.registerTypeAdapter(OptionalTrigger.class, new UniversalJsonAdapter<>(OptionalTrigger.providers));
builder.registerTypeAdapter(SessionStorage.class, new UniversalJsonAdapter<>(SessionStorage.providers));

View file

@ -1,7 +1,6 @@
package pro.gravit.launchserver.manangers;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.HookSet;
@ -11,7 +10,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
public class SessionManager implements NeedGarbageCollection {
public class SessionManager {
private final LaunchServer server;
public HookSet<Client> clientRestoreHook = new HookSet<>();
@ -57,7 +56,6 @@ private Client restoreFromString(byte[] data) {
return result;
}
@Override
public void garbageCollection() {
}

View file

@ -314,7 +314,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
runMethod.invoke();
}
}
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
Launcher.LAUNCHED.set(true);
JVMHelper.fullGC();
// Invoke main method

View file

@ -1,10 +0,0 @@
package pro.gravit.launcher;
/**
* Determines whether this object requires periodic garbage collection by the gc command
* This interface has nothing to do with java garbage collection.
*/
@FunctionalInterface
public interface NeedGarbageCollection {
void garbageCollection();
}

View file

@ -1,48 +0,0 @@
package pro.gravit.launcher.managers;
import pro.gravit.launcher.NeedGarbageCollection;
import java.util.HashSet;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@Deprecated
public class GarbageManager {
private static final Timer timer = new Timer("GarbageTimer");
private static final Set<Entry> NEED_GARBARE_COLLECTION = new HashSet<>();
public static void gc() {
for (Entry gc : NEED_GARBARE_COLLECTION)
gc.invoke.garbageCollection();
}
public static void registerNeedGC(NeedGarbageCollection gc) {
NEED_GARBARE_COLLECTION.add(new Entry(gc, 0L));
}
public static void registerNeedGC(NeedGarbageCollection gc, long time) {
TimerTask task = new TimerTask() {
@Override
public void run() {
gc.garbageCollection();
}
};
timer.schedule(task, time);
NEED_GARBARE_COLLECTION.add(new Entry(gc, time));
}
public static void unregisterNeedGC(NeedGarbageCollection gc) {
NEED_GARBARE_COLLECTION.removeIf(e -> e.invoke == gc);
}
static class Entry {
final NeedGarbageCollection invoke;
final long timer;
public Entry(NeedGarbageCollection invoke, long timer) {
this.invoke = invoke;
this.timer = timer;
}
}
}

View file

@ -6,9 +6,9 @@ public final class Version implements Comparable<Version> {
public static final int MAJOR = 5;
public static final int MINOR = 2;
public static final int PATCH = 5;
public static final int PATCH = 6;
public static final int BUILD = 1;
public static final Version.Type RELEASE = Type.STABLE;
public static final Version.Type RELEASE = Type.DEV;
public final int major;
public final int minor;
public final int patch;

View file

@ -1,6 +1,5 @@
package pro.gravit.utils.command.basic;
import pro.gravit.launcher.managers.GarbageManager;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper;