mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
[FEATURE] HWIDProvider
This commit is contained in:
parent
a180673b26
commit
3baffcafb5
12 changed files with 339 additions and 5 deletions
|
@ -7,6 +7,7 @@
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
|
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
|
@ -211,6 +212,7 @@ public static void registerAll() {
|
||||||
WebSocketService.registerResponses();
|
WebSocketService.registerResponses();
|
||||||
DaoProvider.registerProviders();
|
DaoProvider.registerProviders();
|
||||||
AuthRequest.registerProviders();
|
AuthRequest.registerProviders();
|
||||||
|
HWIDProvider.registerProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateConfigIfNotExists(Path configFile, CommandHandler commandHandler, LaunchServer.LaunchServerEnv env) throws IOException {
|
public static void generateConfigIfNotExists(Path configFile, CommandHandler commandHandler, LaunchServer.LaunchServerEnv env) throws IOException {
|
||||||
|
|
|
@ -3,14 +3,25 @@
|
||||||
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
import pro.gravit.launcher.events.request.GetSecureLevelInfoRequestEvent;
|
||||||
import pro.gravit.launcher.events.request.HardwareReportRequestEvent;
|
import pro.gravit.launcher.events.request.HardwareReportRequestEvent;
|
||||||
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
|
import pro.gravit.launcher.events.request.VerifySecureLevelKeyRequestEvent;
|
||||||
|
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||||
|
import pro.gravit.launchserver.Reconfigurable;
|
||||||
|
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.HardwareProtectHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler;
|
||||||
import pro.gravit.launchserver.socket.Client;
|
import pro.gravit.launchserver.socket.Client;
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
import pro.gravit.launchserver.socket.response.secure.HardwareReportResponse;
|
import pro.gravit.launchserver.socket.response.secure.HardwareReportResponse;
|
||||||
|
import pro.gravit.utils.command.Command;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler {
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler, Reconfigurable {
|
||||||
public boolean enableHardwareFeature;
|
public boolean enableHardwareFeature;
|
||||||
|
public HWIDProvider provider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
public boolean allowGetAccessToken(AuthResponse.AuthContext context) {
|
||||||
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign;
|
||||||
|
@ -38,7 +49,16 @@ public void onHardwareReport(HardwareReportResponse response, Client client) {
|
||||||
response.sendResult(new HardwareReportRequestEvent());
|
response.sendResult(new HardwareReportRequestEvent());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
provider.normalizeHardwareInfo(response.hardware);
|
||||||
|
LogHelper.debug("[HardwareInfo] HardwareInfo received");
|
||||||
|
boolean needCreate = !provider.addPublicKeyToHardwareInfo(response.hardware, client.trustLevel.publicKey);
|
||||||
|
LogHelper.debug("[HardwareInfo] HardwareInfo needCreate: %s", needCreate ? "true" : "false");
|
||||||
|
if(needCreate)
|
||||||
|
provider.createHardwareInfo(response.hardware, client.trustLevel.publicKey);
|
||||||
|
} catch (HWIDException e) {
|
||||||
|
throw new SecurityException(e.getMessage());
|
||||||
|
}
|
||||||
response.sendResult(new HardwareReportRequestEvent());
|
response.sendResult(new HardwareReportRequestEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +66,32 @@ public void onHardwareReport(HardwareReportResponse response, Client client) {
|
||||||
public VerifySecureLevelKeyRequestEvent onSuccessVerify(Client client) {
|
public VerifySecureLevelKeyRequestEvent onSuccessVerify(Client client) {
|
||||||
if(enableHardwareFeature)
|
if(enableHardwareFeature)
|
||||||
{
|
{
|
||||||
|
if(provider == null)
|
||||||
|
{
|
||||||
|
LogHelper.warning("HWIDProvider null. HardwareInfo not checked!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
client.trustLevel.hardwareInfo = provider.findHardwareInfoByPublicKey(client.trustLevel.publicKey);
|
||||||
|
if(client.trustLevel.hardwareInfo == null) //HWID not found?
|
||||||
return new VerifySecureLevelKeyRequestEvent(true);
|
return new VerifySecureLevelKeyRequestEvent(true);
|
||||||
|
} catch (HWIDException e) {
|
||||||
|
throw new SecurityException(e.getMessage()); //Show banned message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new VerifySecureLevelKeyRequestEvent(false);
|
||||||
}
|
}
|
||||||
return new VerifySecureLevelKeyRequestEvent();
|
return new VerifySecureLevelKeyRequestEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Command> getCommands() {
|
||||||
|
Map<String, Command> commands = new HashMap<>();
|
||||||
|
if(provider instanceof Reconfigurable)
|
||||||
|
{
|
||||||
|
commands.putAll(((Reconfigurable) provider).getCommands());
|
||||||
|
}
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
package pro.gravit.launchserver.auth.protect.hwid;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||||
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
|
import pro.gravit.launchserver.helper.DamerauHelper;
|
||||||
|
import pro.gravit.utils.ProviderMap;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
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;
|
||||||
|
public static void registerProviders() {
|
||||||
|
if(!registredProv)
|
||||||
|
{
|
||||||
|
providers.register("memory", MemoryHWIDProvider.class);
|
||||||
|
registredProv = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public abstract HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey) throws HWIDException;
|
||||||
|
public abstract void createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey) throws HWIDException;
|
||||||
|
public abstract boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey) 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();
|
||||||
|
}
|
||||||
|
public static class HardwareInfoCompareResult
|
||||||
|
{
|
||||||
|
public double firstSpoofingLevel = 0.0;
|
||||||
|
public double secondSpoofingLevel = 0.0;
|
||||||
|
public double compareLevel;
|
||||||
|
}
|
||||||
|
//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(LogHelper.Level logLevel, HardwareReportRequest.HardwareInfo info)
|
||||||
|
{
|
||||||
|
LogHelper.log(logLevel, String.format("[HardwareInfo] Processor: logical %d | physical %d | freq %d | bitness %d", info.logicalProcessors, info.physicalProcessors, info.processorMaxFreq, info.bitness) , false);
|
||||||
|
LogHelper.log(logLevel, String.format("[HardwareInfo] Memory max: %d | battery %s", info.totalMemory, info.battery ? "true" : "false") , false);
|
||||||
|
LogHelper.log(logLevel, String.format("[HardwareInfo] HWDiskID %s | baseboardSerialNumber %s | displayId hash: %s", info.hwDiskId, info.baseboardSerialNumber, SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, info.displayId))) , false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package pro.gravit.launchserver.auth.protect.hwid;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||||
|
import pro.gravit.launchserver.Reconfigurable;
|
||||||
|
import pro.gravit.utils.command.Command;
|
||||||
|
import pro.gravit.utils.command.SubCommand;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
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 {
|
||||||
|
public double warningSpoofingLevel = -1.0;
|
||||||
|
public double criticalCompareLevel = 1.0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Command> getCommands() {
|
||||||
|
Map<String, Command> commands = new HashMap<>();
|
||||||
|
commands.put("hardwarelist", new SubCommand() {
|
||||||
|
@Override
|
||||||
|
public void invoke(String... args) throws Exception {
|
||||||
|
for(MemoryHWIDEntity e : db)
|
||||||
|
{
|
||||||
|
printHardwareInfo(LogHelper.Level.INFO, e.hardware);
|
||||||
|
LogHelper.info("ID %d banned %s", e.id, e.banned ? "true" : "false");
|
||||||
|
LogHelper.info("PublicKey Hash: %s", 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;
|
||||||
|
LogHelper.info("HardwareID %d banned", e.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Set<MemoryHWIDEntity> db = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HardwareReportRequest.HardwareInfo findHardwareInfoByPublicKey(byte[] publicKey) 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) throws HWIDException {
|
||||||
|
db.add(new MemoryHWIDEntity(hardwareInfo, publicKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey) throws HWIDException {
|
||||||
|
boolean isAlreadyWarning = false;
|
||||||
|
for(MemoryHWIDEntity e : db) {
|
||||||
|
HardwareInfoCompareResult result = compareHardwareInfo(e.hardware, hardwareInfo);
|
||||||
|
if(warningSpoofingLevel > 0 && result.firstSpoofingLevel > warningSpoofingLevel && !isAlreadyWarning)
|
||||||
|
{
|
||||||
|
LogHelper.warning("HardwareInfo spoofing level too high: %d", result.firstSpoofingLevel);
|
||||||
|
isAlreadyWarning = true;
|
||||||
|
}
|
||||||
|
if(result.compareLevel > criticalCompareLevel)
|
||||||
|
{
|
||||||
|
LogHelper.debug("HardwareInfo publicKey change: compareLevel %d", result.compareLevel);
|
||||||
|
e.publicKey = publicKey;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -183,6 +183,7 @@ public void init(LaunchServer.ReloadType type) {
|
||||||
dao.init(server);
|
dao.init(server);
|
||||||
}
|
}
|
||||||
if (protectHandler != null) {
|
if (protectHandler != null) {
|
||||||
|
server.registerObject("protectHandler", protectHandler);
|
||||||
protectHandler.checkLaunchServerLicense();
|
protectHandler.checkLaunchServerLicense();
|
||||||
}
|
}
|
||||||
if (components != null) {
|
if (components != null) {
|
||||||
|
@ -223,6 +224,9 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
if (protectHandler != null) {
|
||||||
|
server.unregisterObject("protectHandler", protectHandler);
|
||||||
|
}
|
||||||
if (dao != null) {
|
if (dao != null) {
|
||||||
server.unregisterObject("dao", dao);
|
server.unregisterObject("dao", dao);
|
||||||
if (dao instanceof AutoCloseable) {
|
if (dao instanceof AutoCloseable) {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package pro.gravit.launchserver.helper;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class DamerauHelper {
|
||||||
|
//Расстояние Дамерау — Левенштейна. GitHub https://github.com/crwohlfeil/damerau-levenshtein
|
||||||
|
public static int calculateDistance(CharSequence source, CharSequence target) {
|
||||||
|
if (source == null || target == null) {
|
||||||
|
throw new IllegalArgumentException("Parameter must not be null");
|
||||||
|
}
|
||||||
|
int sourceLength = source.length();
|
||||||
|
int targetLength = target.length();
|
||||||
|
if (sourceLength == 0) return targetLength;
|
||||||
|
if (targetLength == 0) return sourceLength;
|
||||||
|
int[][] dist = new int[sourceLength + 1][targetLength + 1];
|
||||||
|
for (int i = 0; i < sourceLength + 1; i++) {
|
||||||
|
dist[i][0] = i;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < targetLength + 1; j++) {
|
||||||
|
dist[0][j] = j;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < sourceLength + 1; i++) {
|
||||||
|
for (int j = 1; j < targetLength + 1; j++) {
|
||||||
|
int cost = source.charAt(i - 1) == target.charAt(j - 1) ? 0 : 1;
|
||||||
|
dist[i][j] = Math.min(Math.min(dist[i - 1][j] + 1, dist[i][j - 1] + 1), dist[i - 1][j - 1] + cost);
|
||||||
|
if (i > 1 &&
|
||||||
|
j > 1 &&
|
||||||
|
source.charAt(i - 1) == target.charAt(j - 2) &&
|
||||||
|
source.charAt(i - 2) == target.charAt(j - 1)) {
|
||||||
|
dist[i][j] = Math.min(dist[i][j], dist[i - 2][j - 2] + cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dist[sourceLength][targetLength];
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
import pro.gravit.launcher.request.auth.AuthRequest;
|
import pro.gravit.launcher.request.auth.AuthRequest;
|
||||||
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
import pro.gravit.launchserver.auth.handler.AuthHandler;
|
||||||
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
import pro.gravit.launchserver.auth.protect.ProtectHandler;
|
||||||
|
import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider;
|
||||||
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
import pro.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
import pro.gravit.launchserver.auth.texture.TextureProvider;
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
|
@ -36,6 +37,7 @@ public void registerAdapters(GsonBuilder builder) {
|
||||||
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers));
|
builder.registerTypeAdapter(WebSocketServerResponse.class, new UniversalJsonAdapter<>(WebSocketService.providers));
|
||||||
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
builder.registerTypeAdapter(WebSocketEvent.class, new JsonResultSerializeAdapter());
|
||||||
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
|
||||||
|
builder.registerTypeAdapter(HWIDProvider.class, new UniversalJsonAdapter<>(HWIDProvider.providers));
|
||||||
modulesManager.invokeEvent(new PreGsonPhase(builder));
|
modulesManager.invokeEvent(new PreGsonPhase(builder));
|
||||||
//ClientWebSocketService.appendTypeAdapters(builder);
|
//ClientWebSocketService.appendTypeAdapters(builder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import pro.gravit.launcher.request.secure.HardwareReportRequest;
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
|
@ -52,5 +53,6 @@ public static class TrustLevel {
|
||||||
public byte[] verifySecureKey;
|
public byte[] verifySecureKey;
|
||||||
public boolean keyChecked;
|
public boolean keyChecked;
|
||||||
public byte[] publicKey;
|
public byte[] publicKey;
|
||||||
|
public HardwareReportRequest.HardwareInfo hardwareInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,12 @@ public String getType() {
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if(server.config.protectHandler instanceof HardwareProtectHandler)
|
if(server.config.protectHandler instanceof HardwareProtectHandler)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
((HardwareProtectHandler) server.config.protectHandler).onHardwareReport(this, client);
|
((HardwareProtectHandler) server.config.protectHandler).onHardwareReport(this, client);
|
||||||
|
} catch (SecurityException e)
|
||||||
|
{
|
||||||
|
sendError(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,12 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
}
|
}
|
||||||
client.trustLevel.keyChecked = true;
|
client.trustLevel.keyChecked = true;
|
||||||
client.trustLevel.publicKey = publicKey;
|
client.trustLevel.publicKey = publicKey;
|
||||||
|
try {
|
||||||
sendResult(secureProtectHandler.onSuccessVerify(client));
|
sendResult(secureProtectHandler.onSuccessVerify(client));
|
||||||
|
} catch (SecurityException e)
|
||||||
|
{
|
||||||
|
sendError(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
public class VerifySecureLevelKeyRequestEvent extends RequestEvent {
|
public class VerifySecureLevelKeyRequestEvent extends RequestEvent {
|
||||||
public boolean needHardwareInfo;
|
public boolean needHardwareInfo;
|
||||||
|
public boolean onlyStatisticInfo;
|
||||||
|
|
||||||
public VerifySecureLevelKeyRequestEvent() {
|
public VerifySecureLevelKeyRequestEvent() {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue