mostly make loader work, mixins still broken (causing a crash)
This commit is contained in:
parent
9d0d39df03
commit
1a9d14ef10
38 changed files with 728 additions and 355 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@
|
|||
|
||||
valid_hashes.txt
|
||||
Obf.tar
|
||||
/Server/run/
|
||||
|
|
50
.run/BaseBandRewrite [build-full].run.xml
Normal file
50
.run/BaseBandRewrite [build-full].run.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="BaseBandRewrite [build-full]" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="build" />
|
||||
<option value="proguard" />
|
||||
<option value="proguardRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="false" name="BaseBandRewrite [build-full]" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="build" />
|
||||
<option value="proguard" />
|
||||
<option value="proguardRelease" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
32
.run/mobf.run.xml
Normal file
32
.run/mobf.run.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="mobf" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/mobf.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="*/build/proguard/BaseBand-*.jar" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/fish" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="false" name="mobf" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="bash mobf.sh */build/proguard/BaseBand-*.jar" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/mobf.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="*/build/proguard/BaseBand-*.jar" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/bash" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
32
.run/push_local.run.xml
Normal file
32
.run/push_local.run.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="push_local" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/push_local.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/bash" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration default="false" name="push_local" type="ShConfigurationType">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/push_local.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
||||
<option name="INTERPRETER_PATH" value="/bin/bash" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
Binary file not shown.
|
@ -11,15 +11,24 @@
|
|||
-obfuscationdictionary dictionary.txt
|
||||
-classobfuscationdictionary dictionary.txt
|
||||
-packageobfuscationdictionary dictionary.txt
|
||||
-repackageclasses org.baseband.prod
|
||||
-repackageclasses com.baseband.prod
|
||||
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,*Annotation*,Synthetic,EnclosingMethod
|
||||
-ignorewarnings
|
||||
-overloadaggressively
|
||||
|
||||
# keep things meant to exist in prod
|
||||
-keep class com.baseband.prod.** { *; }
|
||||
-keep class com.baseband.client.mixins.** { *; }
|
||||
-keep class com.baseband.client.DevStub {
|
||||
public <methods>;
|
||||
}
|
||||
-keep class com.baseband.launcher.Tweaker {
|
||||
public <methods>;
|
||||
}
|
||||
|
||||
# jna
|
||||
-keep class com.sun.** { *; }
|
||||
-keep class oshi.** { *; }
|
||||
|
||||
# spongepowered
|
||||
-keep class org.** { *; }
|
||||
|
|
|
@ -23,7 +23,7 @@ public class BaseBand {
|
|||
public static final Logger LOGGER = LogManager.getLogger("BaseBand");
|
||||
public static final SecureRandom RANDOM = new SecureRandom();
|
||||
|
||||
public static BaseBand INSTANCE; { INSTANCE = this; }
|
||||
public static BaseBand INSTANCE = new BaseBand();
|
||||
|
||||
public static String buildString = "Broadway";
|
||||
public static final EventManager eventManager = new EventManager(LOGGER::error);
|
||||
|
|
|
@ -26,7 +26,7 @@ public class DevStub implements IFMLLoadingPlugin {
|
|||
@Mod.EventHandler
|
||||
public void onInit(FMLPostInitializationEvent event) {
|
||||
BaseBand.buildString = "Dark Side of the Moon";
|
||||
new BaseBand().onInit();
|
||||
BaseBand.INSTANCE.onInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
15
Client/src/main/java/com/baseband/prod/LoadHandler.java
Normal file
15
Client/src/main/java/com/baseband/prod/LoadHandler.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package com.baseband.prod;
|
||||
|
||||
import com.baseband.client.BaseBand;
|
||||
|
||||
public class LoadHandler {
|
||||
|
||||
public static void loaded() {
|
||||
BaseBand.LOGGER.info("We have been loaded!");
|
||||
try {
|
||||
Class.forName("com.baseband.launcher.Tweaker").getDeclaredMethod("loaded", Class.class).invoke(null, BaseBand.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,7 +76,7 @@ dependencies {
|
|||
|
||||
jarLibs(fileTree(dir: "lib", include: "*.jar"));
|
||||
|
||||
jarLibs(group: 'com.github.oshi', name: 'oshi-core', version: '6.5.0');
|
||||
//jarLibs(group: 'com.github.oshi', name: 'oshi-core', version: '1.+');
|
||||
|
||||
annotationProcessor('org.spongepowered:mixin:0.8.5:processor') {
|
||||
exclude module: 'gson'
|
||||
|
@ -111,7 +111,7 @@ jar {
|
|||
|
||||
manifest {
|
||||
attributes(
|
||||
'TweakClass': 'org.baseband.launcher.Tweaker',
|
||||
'TweakClass': 'com.baseband.launcher.Tweaker',
|
||||
'TweakOrder': 0,
|
||||
'FMLCorePluginContainsFMLMod': 'true',
|
||||
'ForceLoadAsMod': 'true'
|
||||
|
|
Binary file not shown.
Binary file not shown.
1
Loader/lib/TuddyLIB.jar
Symbolic link
1
Loader/lib/TuddyLIB.jar
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../Client/libs/TuddyLIB.jar
|
153
Loader/src/main/java/com/baseband/launcher/Loader.java
Normal file
153
Loader/src/main/java/com/baseband/launcher/Loader.java
Normal file
|
@ -0,0 +1,153 @@
|
|||
package com.baseband.launcher;
|
||||
|
||||
import de.tudbut.io.TypedInputStream;
|
||||
import de.tudbut.io.TypedOutputStream;
|
||||
import de.tudbut.parsing.JSON;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.tools.Hasher;
|
||||
import de.tudbut.tools.Tools;
|
||||
import de.tudbut.tools.encryption.Key;
|
||||
import com.baseband.launcher.classloader.CustomClassLoader;
|
||||
import com.baseband.launcher.util.RSAKey;
|
||||
import com.baseband.launcher.util.Util;
|
||||
import de.tudbut.tools.encryption.RawKey;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.Processor;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Loader implements Util {
|
||||
|
||||
public static Class<?> baseBandClass;
|
||||
public static Object baseBand;
|
||||
|
||||
public enum Response {
|
||||
OK,
|
||||
FORBIDDEN,
|
||||
OUTDATED,
|
||||
BANNED,
|
||||
RESET,
|
||||
SERVER_ERROR,
|
||||
SERVER_DOWN,
|
||||
HWID_INVALID,
|
||||
LOGIN_LOCKOUT,
|
||||
}
|
||||
|
||||
private static final SystemInfo systemInfo = new SystemInfo();
|
||||
|
||||
private static CustomClassLoader classLoader;
|
||||
|
||||
public Loader() {
|
||||
try(Socket client = new Socket("baseband.lol", 40000)) {
|
||||
TypedInputStream inputStream = new TypedInputStream(client.getInputStream());
|
||||
TypedOutputStream outputStream = new TypedOutputStream(client.getOutputStream());
|
||||
|
||||
RSAKey rsaKey = new RSAKey(inputStream.readString()); //get publickey
|
||||
Key key = new Key();
|
||||
outputStream.writeString(rsaKey.rsaEnc(key.toString().getBytes(StandardCharsets.ISO_8859_1)));
|
||||
outputStream.writeString(key.encryptString(Tools.mapToString(getData().toMap())));
|
||||
|
||||
Response status = Response.values()[inputStream.readInt()];
|
||||
|
||||
if(status == Response.OK) {
|
||||
try {
|
||||
HashMap<String, byte[]> data = new HashMap<>();
|
||||
RawKey rk = new RawKey(key.toBytes());
|
||||
int n = inputStream.readInt();
|
||||
for (int i = 0; i < n; i++) {
|
||||
data.put(rk.decryptString(inputStream.readString()), rk.decryptBytes(inputStream.readByteArray()));
|
||||
}
|
||||
LOGGER.info("BaseBand downloaded: " + data.size() + " classes.");
|
||||
classLoader = new CustomClassLoader(data);
|
||||
classLoader.inject();
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal("BaseBand failed to (down)load.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGGER.fatal("Server refused.");
|
||||
LOGGER.error(status.ordinal());
|
||||
exit();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal("Failed to connect to Server-side.");
|
||||
LOGGER.fatal(e.getMessage());
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void informClient() {
|
||||
classLoader.informClient();
|
||||
}
|
||||
|
||||
public static void loaded(Class<?> baseBandClass) {
|
||||
LOGGER.info("BaseBand was loaded successfully.");
|
||||
Loader.baseBandClass = baseBandClass;
|
||||
try {
|
||||
baseBand = Arrays.stream(baseBandClass.getDeclaredFields()).filter(x -> x.getType() == baseBandClass).findFirst().get().get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onInit() {
|
||||
try {
|
||||
Arrays.stream(baseBandClass.getDeclaredMethods()).filter(x -> (x.getModifiers() & Modifier.STATIC) == 0).findFirst().get().invoke(baseBand);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static TCN getData() throws Exception {
|
||||
File file = new File("baseband.login");
|
||||
|
||||
Key key = new Key(Hasher.sha256hex(getToken())); //We encrypt using the hwid
|
||||
System.out.println(key);
|
||||
|
||||
if (file.exists()) {
|
||||
TCN tcn = new TCN();
|
||||
FileReader fileReader = new FileReader(file);
|
||||
BufferedReader reader = new BufferedReader(fileReader);
|
||||
|
||||
tcn.set("username", key.decryptString(reader.readLine()));
|
||||
tcn.set("password", key.decryptString(reader.readLine()));
|
||||
tcn.set("hardware-id", getToken());
|
||||
LOGGER.info("MAGIC " + Base64.getEncoder().encodeToString(key.encryptString("Logging in with " + JSON.write(tcn)).getBytes()));
|
||||
return tcn;
|
||||
}
|
||||
|
||||
exit();
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
private static String getToken() {
|
||||
String string = //this is intellij's fault I wanted a string-builder
|
||||
Arrays.stream(systemInfo.getHardware().getProcessors()).map(Processor::getIdentifier).collect(Collectors.joining(";;")) +
|
||||
systemInfo.getOperatingSystem().toString();
|
||||
|
||||
return Hasher.sha512hex(string);
|
||||
}
|
||||
|
||||
|
||||
public static void exit() {
|
||||
try {
|
||||
//Cleanly exit
|
||||
Class<?> shutdownClass = Class.forName("java.lang.Shutdown");
|
||||
Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class);
|
||||
exitMethod.setAccessible(true);
|
||||
exitMethod.invoke(null, 1);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,21 +3,38 @@
|
|||
* Unauthorized copying of this file via any medium is Strictly Prohibited.
|
||||
*/
|
||||
|
||||
package org.baseband.launcher;
|
||||
package com.baseband.launcher;
|
||||
|
||||
import net.minecraft.launchwrapper.ITweaker;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import org.spongepowered.asm.launch.MixinTweaker;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Mod(modid = "baseband")
|
||||
public class Tweaker implements ITweaker {
|
||||
public static CountDownLatch latch;
|
||||
|
||||
public static void loaded(Class<?> baseBandClass) {
|
||||
Loader.loaded(baseBandClass);
|
||||
}
|
||||
|
||||
private final MixinTweaker wrapped;
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onPreInit(FMLPreInitializationEvent event) {
|
||||
Loader.informClient();
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onInit(FMLPostInitializationEvent event) {
|
||||
Loader.onInit();
|
||||
}
|
||||
|
||||
public Tweaker() {
|
||||
wrapped = new MixinTweaker();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.baseband.launcher.classloader;
|
||||
package com.baseband.launcher.classloader;
|
||||
|
||||
import com.baseband.launcher.url.URLWrapper;
|
||||
import de.tudbut.security.DataKeeper;
|
||||
import de.tudbut.security.PermissionManager;
|
||||
import de.tudbut.security.StrictnessBuilder;
|
||||
|
@ -7,10 +8,9 @@ import de.tudbut.security.permissionmanager.CallClassRestriction;
|
|||
import de.tudbut.security.permissionmanager.ClassLoaderRestriction;
|
||||
import de.tudbut.security.permissionmanager.PermissionOR;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import org.baseband.launcher.Loader;
|
||||
import org.baseband.launcher.url.URLWrapper;
|
||||
import org.baseband.launcher.util.Util;
|
||||
import com.baseband.launcher.util.Util;
|
||||
import org.spongepowered.asm.mixin.transformer.MixinTransformer;
|
||||
import org.spongepowered.asm.service.MixinService;
|
||||
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -18,22 +18,25 @@ import java.lang.reflect.Field;
|
|||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.baseband.launcher.Loader.exit;
|
||||
|
||||
public class CustomClassLoader extends ClassLoader implements Util {
|
||||
private final DataKeeper<Map<String, byte[]>> binaryKeeper;
|
||||
private final DataKeeper<PermissionManager> mixinPermissionManager;
|
||||
|
||||
public CustomClassLoader(Map<String, byte[]> resources) {
|
||||
public CustomClassLoader(Map<String, byte[]> data) {
|
||||
this.binaryKeeper = new DataKeeper<>(
|
||||
new PermissionOR(new ClassLoaderRestriction(this), new CallClassRestriction(CustomClassLoader.class, CustomClassLoader.class)),
|
||||
StrictnessBuilder.create()
|
||||
.property("Restriction.ClassLoader.RestrictLambda", true)
|
||||
.property("Restriction.ClassLoader.MaxDistance", 3)
|
||||
.property("Restriction.ClassLoader.MaxDistance", 5)
|
||||
.property("Restriction.CallClass.RestrictLambda", true)
|
||||
.property("Restriction.CallClass.MaxDistance", 3)
|
||||
.property("Restriction.CallClass.MaxDistance", 5)
|
||||
.build(),
|
||||
resources
|
||||
data
|
||||
);
|
||||
PermissionManager mixinRestriction = new CallClassRestriction(MixinTransformer.class);
|
||||
mixinRestriction.killReflection();
|
||||
|
@ -48,15 +51,18 @@ public class CustomClassLoader extends ClassLoader implements Util {
|
|||
|
||||
public void inject() {
|
||||
try {
|
||||
CustomMixinServer customService = new CustomMixinServer();
|
||||
CustomMixinServer customService = new CustomMixinServer(this);
|
||||
Class<?> mixinServiceClass = Class.forName("org.spongepowered.asm.service.MixinService");
|
||||
Method instanceField = mixinServiceClass.getDeclaredMethod("getInstance");
|
||||
instanceField.setAccessible(true);
|
||||
Object serviceInstance = instanceField.invoke(null);
|
||||
Method instanceMethod = mixinServiceClass.getDeclaredMethod("getInstance");
|
||||
instanceMethod.setAccessible(true);
|
||||
Object serviceInstance = instanceMethod.invoke(null);
|
||||
Field serviceField = mixinServiceClass.getDeclaredField("service");
|
||||
serviceField.setAccessible(true);
|
||||
serviceField.set(serviceInstance, customService);
|
||||
LOGGER.debug("Injected Mixin Service.");
|
||||
LOGGER.info("Injected Mixin Service.");
|
||||
if (MixinService.getService() != customService) {
|
||||
throw new IllegalStateException(MixinService.getService().getClass().toString());
|
||||
}
|
||||
|
||||
Field parent = ClassLoader.class.getDeclaredField("parent");
|
||||
parent.setAccessible(true);
|
||||
|
@ -65,7 +71,16 @@ public class CustomClassLoader extends ClassLoader implements Util {
|
|||
LOGGER.debug("Set parent of Launch.classLoader.");
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
Loader.exit();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
public void informClient() {
|
||||
LOGGER.info("Informing client that it has been loaded.");
|
||||
try {
|
||||
this.loadClass("com.baseband.prod.LoadHandler").getDeclaredMethod("loaded").invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +100,7 @@ public class CustomClassLoader extends ClassLoader implements Util {
|
|||
binaryKeeper.access(m -> data[0] = m.getValue().get(name));
|
||||
|
||||
if (data[0] == null) {
|
||||
return Launch.classLoader.findResource(name);
|
||||
return super.findResource(name);
|
||||
}
|
||||
try {
|
||||
return URLWrapper.wrap(name, data[0]);
|
||||
|
@ -96,17 +111,48 @@ public class CustomClassLoader extends ClassLoader implements Util {
|
|||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
Set<ClassLoader> uniqueClassLoaders = Thread.getAllStackTraces().keySet().stream()
|
||||
.map(Thread::getContextClassLoader)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (ClassLoader classLoader : uniqueClassLoaders) {
|
||||
try {
|
||||
Field librariesField = ClassLoader.class.getDeclaredField("loadedLibraryNames");
|
||||
librariesField.setAccessible(true);
|
||||
Vector<String> libraries = (Vector<String>) librariesField.get(classLoader);
|
||||
|
||||
for(String s : libraries) {
|
||||
// TODO: add more protection
|
||||
if(s.equals("instrument")) // instrument is the name of the only lib that has instrumentation
|
||||
exit();
|
||||
if(s.contains("dump")) // hell nah if this triggers i don't even know wtf is happening
|
||||
exit();
|
||||
if(s.contains("hook")) //Maybe?
|
||||
exit();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
exit();
|
||||
}
|
||||
}
|
||||
final byte[][] bytes = {null};
|
||||
binaryKeeper.access(m -> bytes[0] = m.getValue().get(name));
|
||||
binaryKeeper.access(m -> bytes[0] = m.getValue().get(name.replace('.', '/') + ".class"));
|
||||
if (bytes[0] != null) {
|
||||
return defineClass(name, bytes[0], 0, bytes[0].length);
|
||||
}
|
||||
return super.findClass(name);
|
||||
try {
|
||||
return Launch.classLoader.findClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return super.findClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomMixinServer extends MixinServiceLaunchWrapper {
|
||||
public static class CustomMixinServer extends MixinServiceLaunchWrapper {
|
||||
private final CustomClassLoader parent;
|
||||
|
||||
public CustomMixinServer() {
|
||||
public CustomMixinServer(CustomClassLoader parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -123,12 +169,12 @@ public class CustomClassLoader extends ClassLoader implements Util {
|
|||
|
||||
private byte[] getBytes(String name) {
|
||||
PermissionManager[] pm = new PermissionManager[1];
|
||||
mixinPermissionManager.access(x -> pm[0] = x.getValue());
|
||||
if(!name.startsWith("com/baseband/client/mixins") || !pm[0].checkCaller(mixinPermissionManager.getStrictness()))
|
||||
parent.mixinPermissionManager.access(x -> pm[0] = x.getValue());
|
||||
if(!name.startsWith("com/baseband/client/mixins") || !pm[0].checkCaller(parent.mixinPermissionManager.getStrictness()))
|
||||
return null;
|
||||
|
||||
final byte[][] bytes = {null};
|
||||
binaryKeeper.access(m -> bytes[0] = m.getValue().get(name));
|
||||
parent.binaryKeeper.access(m -> bytes[0] = m.getValue().get(name));
|
||||
return bytes[0];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baseband.launcher.security;
|
||||
|
||||
import com.baseband.launcher.util.Util;
|
||||
|
||||
public interface SecurityImpl extends Util {
|
||||
void run();
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package org.baseband.launcher.security.impl;
|
||||
package com.baseband.launcher.security.impl;
|
||||
|
||||
import org.baseband.launcher.security.SecurityImpl;
|
||||
import com.baseband.launcher.security.SecurityImpl;
|
||||
|
||||
public class TestImpl implements SecurityImpl {
|
||||
@Override
|
|
@ -1,4 +1,4 @@
|
|||
package org.baseband.launcher.url;
|
||||
package com.baseband.launcher.url;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
|
@ -1,4 +1,4 @@
|
|||
package org.baseband.launcher.url;
|
||||
package com.baseband.launcher.url;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
|
@ -1,4 +1,4 @@
|
|||
package org.baseband.launcher.url;
|
||||
package com.baseband.launcher.url;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
|
@ -1,7 +1,10 @@
|
|||
package org.baseband.launcher.util;
|
||||
package com.baseband.launcher.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
|
@ -12,21 +15,24 @@ public class RSAKey implements Util {
|
|||
PrivateKey privateKey;
|
||||
|
||||
public RSAKey(String publicKey) {
|
||||
this.publicKey = decodeBase64ToPublicKey(publicKey);
|
||||
this.publicKey = decodePublicKey(publicKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public RSAKey() {
|
||||
KeyPair keyPair = generateKeyPair();
|
||||
this.publicKey = keyPair.getPublic();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
}
|
||||
|
||||
public RSAKey(KeyPair keyPair) {
|
||||
this.publicKey = keyPair.getPublic();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
}
|
||||
|
||||
private KeyPair generateKeyPair() {
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(4096);
|
||||
keyPairGenerator.initialize(1024 * 9);
|
||||
return keyPairGenerator.generateKeyPair();
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
|
@ -34,35 +40,34 @@ public class RSAKey implements Util {
|
|||
}
|
||||
}
|
||||
|
||||
public String rsaEnc(String plainText) {
|
||||
public String rsaEnc(byte[] plainText) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes()));
|
||||
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText));
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String rsaDec(String encryptedBytesInBase64) {
|
||||
public byte[] rsaDec(String encryptedBytesInBase64) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedBytesInBase64));
|
||||
return new String(decryptedBytes);
|
||||
return cipher.doFinal(Base64.getDecoder().decode(encryptedBytesInBase64));
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public PublicKey decodeBase64ToPublicKey(String base64PublicKey) {
|
||||
public static RSAPublicKey decodePublicKey(String b64) {
|
||||
try {
|
||||
byte[] publicKeyBytes = Base64.getDecoder().decode(base64PublicKey);
|
||||
byte[] bytes = Base64.getDecoder().decode(b64);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||
return keyFactory.generatePublic(keySpec);
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
|
||||
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
|
@ -73,4 +78,21 @@ public class RSAKey implements Util {
|
|||
byte[] publicKeyBytes = publicKey.getEncoded();
|
||||
return Base64.getEncoder().encodeToString(publicKeyBytes);
|
||||
}
|
||||
|
||||
public static RSAPrivateKey decodePrivateKey(String b64) {
|
||||
try {
|
||||
byte[] bytes = Base64.getDecoder().decode(b64);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String encodePrivateKeyToBase64() {
|
||||
byte[] publicKeyBytes = privateKey.getEncoded();
|
||||
return Base64.getEncoder().encodeToString(publicKeyBytes);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.baseband.launcher.util;
|
||||
package com.baseband.launcher.util;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
|
@ -1,86 +0,0 @@
|
|||
package org.baseband.launcher;
|
||||
|
||||
import de.tudbut.net.ws.Client;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.tools.Hasher;
|
||||
import de.tudbut.tools.encryption.Key;
|
||||
import org.baseband.launcher.classloader.CustomClassLoader;
|
||||
import org.baseband.launcher.util.RSAKey;
|
||||
import org.baseband.launcher.util.Util;
|
||||
import oshi.SystemInfo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
|
||||
public class Loader implements Util {
|
||||
|
||||
private static final SystemInfo systemInfo = new SystemInfo();
|
||||
|
||||
private static CustomClassLoader classLoader;
|
||||
|
||||
public Loader() {
|
||||
try {
|
||||
Client client = new Client("later", 40000);
|
||||
|
||||
RSAKey rsaKey = new RSAKey(client.receive()); //get publickey
|
||||
|
||||
Key key = new Key();
|
||||
|
||||
client.send(rsaKey.rsaEnc(key.toString()));
|
||||
|
||||
client.send(key.encryptObject(getData()));
|
||||
|
||||
classLoader = new CustomClassLoader(key.decryptObject(client.receive()));
|
||||
|
||||
classLoader.inject();
|
||||
} catch (Exception e) {
|
||||
LOGGER.fatal("Failed to connect to Server-side.");
|
||||
LOGGER.fatal(e.getMessage());
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static TCN getData() throws Exception {
|
||||
File file = new File("baseband.login");
|
||||
TCN tcn = new TCN();
|
||||
if (file.exists()) {
|
||||
FileReader fileReader = new FileReader(file);
|
||||
BufferedReader reader = new BufferedReader(fileReader);
|
||||
|
||||
Key key = new Key(getToken()); //We encrypt using the hwid
|
||||
|
||||
tcn.set("Username", key.decryptString(reader.readLine()));
|
||||
tcn.set("Password", key.decryptString(reader.readLine()));
|
||||
tcn.set("Hardware-ID", getToken());
|
||||
return tcn;
|
||||
}
|
||||
|
||||
exit();
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getToken() {
|
||||
String string = //this is intellij's fault I wanted a string-builder
|
||||
systemInfo.getHardware().getComputerSystem().getSerialNumber() +
|
||||
systemInfo.getOperatingSystem().getVersionInfo().toString();
|
||||
|
||||
return Hasher.sha512hex(string);
|
||||
}
|
||||
|
||||
|
||||
public static void exit() {
|
||||
try {
|
||||
//Cleanly exit
|
||||
Class<?> shutdownClass = Class.forName("java.lang.Shutdown");
|
||||
Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class);
|
||||
exitMethod.setAccessible(true);
|
||||
exitMethod.invoke(null, 1);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package org.baseband.launcher.security;
|
||||
|
||||
import org.baseband.launcher.util.Util;
|
||||
|
||||
public interface SecurityImpl extends Util {
|
||||
void run();
|
||||
}
|
|
@ -31,7 +31,7 @@ jar {
|
|||
}
|
||||
manifest {
|
||||
attributes(
|
||||
'Main-Class': 'dev.baseband.server.Main'
|
||||
'Main-Class': 'com.baseband.server.Main'
|
||||
)
|
||||
}
|
||||
baseName = 'BaseBand'
|
||||
|
|
Binary file not shown.
1
Server/lib/TuddyLIB.jar
Symbolic link
1
Server/lib/TuddyLIB.jar
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../Client/libs/TuddyLIB.jar
|
|
@ -1,4 +1,4 @@
|
|||
package dev.baseband.server;
|
||||
package com.baseband.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
38
Server/src/main/java/com/baseband/server/LoaderHandler.java
Normal file
38
Server/src/main/java/com/baseband/server/LoaderHandler.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package com.baseband.server;
|
||||
|
||||
import de.tudbut.io.TypedInputStream;
|
||||
import de.tudbut.io.TypedOutputStream;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.tools.Tools;
|
||||
import de.tudbut.tools.encryption.Key;
|
||||
import de.tudbut.tools.encryption.RawKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
|
||||
public class LoaderHandler {
|
||||
|
||||
public static void handle(Socket connection) throws IOException {
|
||||
TypedInputStream inputStream = new TypedInputStream(connection.getInputStream());
|
||||
TypedOutputStream outputStream = new TypedOutputStream(connection.getOutputStream());
|
||||
|
||||
outputStream.writeString(Main.rsaKey.encodePublicKeyToBase64());
|
||||
Key key = new Key(Main.rsaKey.rsaDec(inputStream.readString()));
|
||||
|
||||
TCN userData = TCN.readMap(Tools.stringToMap(key.decryptString(inputStream.readString())));
|
||||
|
||||
int response = UserHandler.isValid(userData);
|
||||
outputStream.writeInt(response);
|
||||
if(response == UserHandler.Response.OK.ordinal()) {
|
||||
RawKey rk = new RawKey(key.toBytes());
|
||||
outputStream.writeInt(Main.classes.size());
|
||||
for (Map.Entry<String, byte[]> entry : Main.classes.entrySet()) {
|
||||
outputStream.writeString(rk.encryptString(entry.getKey()));
|
||||
outputStream.writeByteArray(rk.encryptBytes(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
connection.close();
|
||||
}
|
||||
}
|
118
Server/src/main/java/com/baseband/server/Main.java
Normal file
118
Server/src/main/java/com/baseband/server/Main.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved.
|
||||
* Unauthorized copying of this file via any medium is Strictly Prohibited.
|
||||
*/
|
||||
|
||||
package com.baseband.server;
|
||||
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import de.tudbut.io.StreamReader;
|
||||
import de.tudbut.io.TypedInputStream;
|
||||
import de.tudbut.io.TypedOutputStream;
|
||||
import de.tudbut.parsing.JSON;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.parsing.TCNArray;
|
||||
import de.tudbut.tools.Hasher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.nio.file.Files;
|
||||
import java.security.KeyPair;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static RSAKey rsaKey;
|
||||
|
||||
public static boolean denyAll = false;
|
||||
public static Map<String, byte[]> classes;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File key = new File("baseband.key");
|
||||
if(key.exists()) {
|
||||
TypedInputStream stream = new TypedInputStream(new FileInputStream(key));
|
||||
rsaKey = new RSAKey(new KeyPair(
|
||||
RSAKey.decodePublicKey(stream.readString()),
|
||||
RSAKey.decodePrivateKey(stream.readString())
|
||||
));
|
||||
}
|
||||
else {
|
||||
System.out.println("Generating private key...");
|
||||
key.createNewFile();
|
||||
rsaKey = new RSAKey();
|
||||
TypedOutputStream stream = new TypedOutputStream(new FileOutputStream(key));
|
||||
stream.writeString(rsaKey.encodePublicKeyToBase64());
|
||||
stream.writeString(rsaKey.encodePrivateKeyToBase64());
|
||||
stream.getStream().close();
|
||||
}
|
||||
//Loader
|
||||
File db = new File("baseband.db");
|
||||
if(db.exists()) {
|
||||
UserHandler.users = TCNArray.fromTCN(JSON.read(new StreamReader(Files.newInputStream(db.toPath())).readAllAsString()));
|
||||
} else {
|
||||
db.createNewFile();
|
||||
TCN tcn = new TCN();
|
||||
|
||||
tcn.set("username", "root");
|
||||
tcn.set("password", BCrypt.withDefaults().hashToString(4, "test".toCharArray()));
|
||||
tcn.set("hardware-id", Hasher.sha512hex("hardware-id"));
|
||||
tcn.set("hardware-id-reset", true);
|
||||
tcn.set("disabled", false);
|
||||
|
||||
UserHandler.users.add(tcn);
|
||||
}
|
||||
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(db)) {
|
||||
fileOutputStream.write(JSON.writeReadable(UserHandler.users.toTCN(), 4).getBytes());
|
||||
fileOutputStream.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
System.out.println("Indexing...");
|
||||
classes = new HashMap<>();
|
||||
ZipInputStream jar = new ZipInputStream(new FileInputStream("BaseBand-Broadway.jar"));
|
||||
ZipEntry entry;
|
||||
while ((entry = jar.getNextEntry()) != null) {
|
||||
byte[] bytes = new StreamReader(jar).readAllAsBytes();
|
||||
classes.put(entry.getName(), bytes);
|
||||
System.out.println(entry.getName() + ": " + bytes.length);
|
||||
jar.closeEntry();
|
||||
}
|
||||
System.out.println("Listening!");
|
||||
|
||||
ServerSocket server = new ServerSocket(40000);
|
||||
Socket client;
|
||||
while ((client = server.accept()) != null) {
|
||||
client.setSoTimeout(1000);
|
||||
Socket thisClient = client;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
LoaderHandler.handle(thisClient);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
//WebServices
|
||||
//Server webServiceServer = new Server(40001);
|
||||
//webServiceServer.addHandler(new WebServiceHandler());
|
||||
//webServiceServer.run();
|
||||
}
|
||||
|
||||
|
||||
}
|
98
Server/src/main/java/com/baseband/server/RSAKey.java
Normal file
98
Server/src/main/java/com/baseband/server/RSAKey.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
package com.baseband.server;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class RSAKey {
|
||||
|
||||
final PublicKey publicKey;
|
||||
|
||||
PrivateKey privateKey;
|
||||
|
||||
public RSAKey(String publicKey) {
|
||||
this.publicKey = decodePublicKey(publicKey);
|
||||
}
|
||||
|
||||
public RSAKey() {
|
||||
KeyPair keyPair = generateKeyPair();
|
||||
this.publicKey = keyPair.getPublic();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
}
|
||||
|
||||
public RSAKey(KeyPair keyPair) {
|
||||
this.publicKey = keyPair.getPublic();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
}
|
||||
|
||||
private KeyPair generateKeyPair() {
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(1024 * 9);
|
||||
return keyPairGenerator.generateKeyPair();
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String rsaEnc(byte[] plainText) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText));
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] rsaDec(String encryptedBytesInBase64) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
return cipher.doFinal(Base64.getDecoder().decode(encryptedBytesInBase64));
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static RSAPublicKey decodePublicKey(String b64) {
|
||||
try {
|
||||
byte[] bytes = Base64.getDecoder().decode(b64);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
|
||||
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String encodePublicKeyToBase64() {
|
||||
byte[] publicKeyBytes = publicKey.getEncoded();
|
||||
return Base64.getEncoder().encodeToString(publicKeyBytes);
|
||||
}
|
||||
|
||||
public static RSAPrivateKey decodePrivateKey(String b64) {
|
||||
try {
|
||||
byte[] bytes = Base64.getDecoder().decode(b64);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String encodePrivateKeyToBase64() {
|
||||
byte[] publicKeyBytes = privateKey.getEncoded();
|
||||
return Base64.getEncoder().encodeToString(publicKeyBytes);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.baseband.server;
|
||||
package com.baseband.server;
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import de.tudbut.parsing.TCN;
|
||||
|
@ -9,7 +9,7 @@ public class UserHandler {
|
|||
|
||||
public static int isValid(TCN remoteTCN) {
|
||||
if(CheckNull.isNull(remoteTCN.get("username"))) {
|
||||
return RESPONSE.FORBIDDEN.getValue();
|
||||
return Response.FORBIDDEN.ordinal();
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -24,57 +24,49 @@ public class UserHandler {
|
|||
boolean isDisabled = localTCN.getBoolean("disabled");
|
||||
|
||||
if(isDisabled) { //if they're banned we're not even looking at their TCN
|
||||
return RESPONSE.BANNED.getValue();
|
||||
return Response.BANNED.ordinal();
|
||||
}
|
||||
|
||||
String remotePassword = remoteTCN.getString("password");
|
||||
String remoteHardwareID = remoteTCN.getString("hardware-id");
|
||||
|
||||
if(CheckNull.isNull(remotePassword, remoteHardwareID)) {
|
||||
return RESPONSE.SERVER_ERROR.getValue();
|
||||
return Response.SERVER_ERROR.ordinal();
|
||||
}
|
||||
|
||||
if (isReset) {
|
||||
localTCN.set("hardware-id-reset", false);
|
||||
localTCN.set("hardware-id", remoteHardwareID);
|
||||
return RESPONSE.RESET.getValue();
|
||||
return Response.RESET.ordinal();
|
||||
}
|
||||
|
||||
if(!localHardwareID.equals(remoteTCN.getString("hardware-id"))) {
|
||||
return RESPONSE.HWID_INVALID.getValue();
|
||||
return Response.HWID_INVALID.ordinal();
|
||||
}
|
||||
|
||||
if(BCrypt.verifyer().verify(remotePassword.toCharArray(), localPassword.toCharArray()).verified) {
|
||||
return RESPONSE.OK.getValue();
|
||||
return Response.OK.ordinal();
|
||||
}
|
||||
}
|
||||
|
||||
//LOL
|
||||
return RESPONSE.FORBIDDEN.getValue();
|
||||
return Response.FORBIDDEN.ordinal();
|
||||
} catch(Exception e) {
|
||||
return RESPONSE.SERVER_ERROR.getValue();
|
||||
return Response.SERVER_ERROR.ordinal();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum RESPONSE {
|
||||
OK(0),
|
||||
FORBIDDEN(1),
|
||||
OUTDATED(2),
|
||||
BANNED(3),
|
||||
RESET(4),
|
||||
SERVER_ERROR(5),
|
||||
SERVER_DOWN(6),
|
||||
HWID_INVALID(7),
|
||||
LOGIN_LOCKOUT(8);
|
||||
|
||||
private final int value;
|
||||
|
||||
RESPONSE(final int newValue) {
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
public int getValue() { return value; }
|
||||
public enum Response {
|
||||
OK,
|
||||
FORBIDDEN,
|
||||
OUTDATED,
|
||||
BANNED,
|
||||
RESET,
|
||||
SERVER_ERROR,
|
||||
SERVER_DOWN,
|
||||
HWID_INVALID,
|
||||
LOGIN_LOCKOUT,
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.baseband.server;
|
||||
package com.baseband.server;
|
||||
|
||||
import de.tudbut.net.ws.Connection;
|
||||
import de.tudbut.net.ws.ConnectionHandler;
|
|
@ -1,38 +0,0 @@
|
|||
package dev.baseband.server;
|
||||
|
||||
import de.tudbut.net.ws.Connection;
|
||||
import de.tudbut.net.ws.ConnectionHandler;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.tools.encryption.Key;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LoaderHandler implements ConnectionHandler {
|
||||
|
||||
@Override
|
||||
public void run(Connection connection) throws IOException {
|
||||
//TODO: no auth but otherwise "fully functional"
|
||||
connection.send(Main.rsaKey.encodePublicKeyToBase64());
|
||||
|
||||
Key key = new Key(Main.rsaKey.rsaDec(connection.receive()));
|
||||
|
||||
Object userData = key.decryptObject(connection.receive());
|
||||
|
||||
if(!(userData instanceof TCN)) {
|
||||
connection.send(String.valueOf(UserHandler.RESPONSE.SERVER_ERROR.getValue()));
|
||||
return;
|
||||
}
|
||||
|
||||
int response = UserHandler.isValid((TCN) userData);
|
||||
|
||||
connection.send(String.valueOf(response));
|
||||
|
||||
if(response == 0) {
|
||||
Map<String, byte[]> classes = new HashMap<>();
|
||||
|
||||
connection.send(key.encryptObject(classes));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved.
|
||||
* Unauthorized copying of this file via any medium is Strictly Prohibited.
|
||||
*/
|
||||
|
||||
package dev.baseband.server;
|
||||
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import de.tudbut.io.StreamReader;
|
||||
import de.tudbut.net.ws.Server;
|
||||
import de.tudbut.parsing.JSON;
|
||||
import de.tudbut.parsing.TCN;
|
||||
import de.tudbut.parsing.TCNArray;
|
||||
import de.tudbut.tools.Hasher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static final RSAKey rsaKey = new RSAKey();
|
||||
|
||||
public static boolean denyAll = false;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
//Loader
|
||||
File db = new File("baseband.db");
|
||||
if(db.exists()) {
|
||||
UserHandler.users = TCNArray.fromTCN(JSON.read(new StreamReader(Files.newInputStream(db.toPath())).readAllAsString()));
|
||||
} else {
|
||||
db.createNewFile();
|
||||
TCN tcn = new TCN();
|
||||
|
||||
tcn.set("username", "root");
|
||||
tcn.set("password", BCrypt.withDefaults().hashToString(4, "test".toCharArray()));
|
||||
tcn.set("hardware-id", Hasher.sha512hex("hardware-id"));
|
||||
tcn.set("hardware-id-reset", false);
|
||||
tcn.set("disabled", false);
|
||||
|
||||
UserHandler.users.add(tcn);
|
||||
}
|
||||
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
try {
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(db)) {
|
||||
fileOutputStream.write(JSON.writeReadable(UserHandler.users.toTCN(), 4).getBytes());
|
||||
fileOutputStream.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}));
|
||||
Server loaderServer = new Server(40000);
|
||||
loaderServer.addHandler(new LoaderHandler());
|
||||
loaderServer.run();
|
||||
|
||||
//WebServices
|
||||
//Server webServiceServer = new Server(40001);
|
||||
//webServiceServer.addHandler(new WebServiceHandler());
|
||||
//webServiceServer.run();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package dev.baseband.server;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.*;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
public class RSAKey {
|
||||
|
||||
PublicKey publicKey;
|
||||
|
||||
PrivateKey privateKey;
|
||||
|
||||
public RSAKey(String publicKey) {
|
||||
this.publicKey = decodeBase64ToPublicKey(publicKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public RSAKey() {
|
||||
KeyPair keyPair = generateKeyPair();
|
||||
assert keyPair != null; //thanks intellij
|
||||
this.publicKey = keyPair.getPublic();
|
||||
this.privateKey = keyPair.getPrivate();
|
||||
}
|
||||
|
||||
private KeyPair generateKeyPair() {
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(4096);
|
||||
return keyPairGenerator.generateKeyPair();
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String rsaEnc(String plainText) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes()));
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String rsaDec(String encryptedBytesInBase64) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedBytesInBase64));
|
||||
return new String(decryptedBytes);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public PublicKey decodeBase64ToPublicKey(String base64PublicKey) {
|
||||
try {
|
||||
byte[] publicKeyBytes = Base64.getDecoder().decode(base64PublicKey);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||
return keyFactory.generatePublic(keySpec);
|
||||
} catch (Exception e) {
|
||||
//LOGGER.fatal(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String encodePublicKeyToBase64() {
|
||||
byte[] publicKeyBytes = publicKey.getEncoded();
|
||||
return Base64.getEncoder().encodeToString(publicKeyBytes);
|
||||
}
|
||||
}
|
7
mobf.sh
Executable file
7
mobf.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
curl https://data.tudbut.de/mobf.jar > mobf.jar
|
||||
for file in "$@" ; do
|
||||
echo "$file"
|
||||
java -jar mobf.jar !mixin !org/ !spotify !google !sun !oshi -k "$file" || exit 1
|
||||
done
|
0
push_file.sh
Normal file → Executable file
0
push_file.sh
Normal file → Executable file
10
push_local.sh
Executable file
10
push_local.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
export SSH_PRIVATEKEY="$(cat ~/.ssh/upload_key)"
|
||||
export BB_HOST=baseband.lol
|
||||
export BB_PORT=22
|
||||
export BB_PATH="$PWD/Server/run"
|
||||
|
||||
bash push_file.sh Server/build/libs/BaseBand-Server.jar
|
||||
bash push_file.sh Client/build/proguard/BaseBand-Broadway.jar
|
||||
bash push_file.sh Loader/build/proguard/BaseBand-Loader.jar
|
Loading…
Add table
Reference in a new issue