i have now spent 4 hours doing some more security++ and also it launches now and communicates with the loader :3

This commit is contained in:
Daniella / Tove 2023-09-28 19:19:44 +02:00
parent e9a912c3db
commit 4a02fac307
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
13 changed files with 321 additions and 122 deletions

Binary file not shown.

View file

@ -7,6 +7,7 @@ import com.baseband.client.event.FMLEventProcessor;
import com.baseband.client.module.Module;
import com.baseband.client.module.modules.*;
import de.tudbut.tools.Registry;
import de.tudbut.tools.Tools;
import net.minecraft.client.Minecraft;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.common.MinecraftForge;
@ -20,20 +21,24 @@ import de.tudbut.tools.Lock;
import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.function.Consumer;
@Mod(modid = "baseband")
public class BaseBand {
public static int majorVersion = 1;
public static int buildNumber = 269;
public static String hash = "8c1ab03377ef905c";
public static int buildNumber = 313;
public static String hash = "0259cd1df4fa6209";
public static String name = "BaseBand";
public long timeOfCompile = 1695869277858L;
public long timeOfCompile = 1695921315991L;
public CommandManager commandRegistry;
public EventBus eventBus;
public ArrayList<Module> modules = new ArrayList<>();
@ -69,12 +74,50 @@ public class BaseBand {
public void onInit() {
Utils.check();
try {
Object keeper = BaseBand.class.getClassLoader().getClass().getFields()[1].get(BaseBand.class.getClassLoader());
Method access = keeper.getClass().getMethods()[1];
access.invoke(keeper, (Consumer<Object>) accessor -> {
try {
Object registry = accessor.getClass().getMethods()[0].invoke(accessor);
for (Method save : registry.getClass().getMethods()) {
if(save.getParameterCount() == 0 && save.getReturnType() == Void.TYPE && save.getDeclaringClass() == registry.getClass()) {
save.invoke(registry); // registry save
System.out.println("Registry saved!!");
}
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
Utils.crash();
}
});
} catch (Exception e) {
e.printStackTrace();
Utils.crash();
}
try {
Registry = new Registry("BaseBand.registry");
} catch(Exception e) {
throw new RuntimeException(e);
registryData = Registry.register("*");
} catch (Exception e) {
// tamper detected
Utils.crash();
}
// cant be a normal if statement because it might be null
if (registryData.getBoolean("LoaderPresent") == Boolean.TRUE) {
String key = registryData.getString("Key");
TCN data = TCN.readMap(Tools.stringToMap(new Key(key).decryptString(registryData.getString("Data"))));
registryData.set("Key", null);
registryData.set("Data", null);
this.level = data.getInteger("level");
} else {
// do other stuff here later?
log.info("No loader present, but able to start anyway ==> Debug environment detected.");
}
// unset so this won't be discovered and manipulated
registryData.set("LoaderPresent", null);
Registry.save();
commandRegistry = new CommandManager();

View file

@ -7,8 +7,6 @@ import com.baseband.client.module.modules.ChatCrypt;
import de.tudbut.tools.Hasher;
import java.util.Arrays;
public class GenericSetCommand extends Command {
@Override
@ -33,7 +31,7 @@ public class GenericSetCommand extends Command {
}
if(args[0].equalsIgnoreCase("cryptkey") && args.length==2) {
ChatCrypt.key = Hasher.sha512hex(Hasher.sha512hex(args[0]));
ChatCrypt.chatKey = Hasher.sha512hex(Hasher.sha512hex(args[0]));
return "OK";
}

View file

@ -30,12 +30,12 @@ public class ChatCrypt extends Module {
}
@Save
public static String key = "default";
public static String chatKey = "default";
private SecretKey secretKey() {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), key.getBytes(), 100, 128);
KeySpec spec = new PBEKeySpec(chatKey.toCharArray(), chatKey.getBytes(), 100, 128);
SecretKey tmp = factory.generateSecret(spec);
return new SecretKeySpec(tmp.getEncoded(), "AES");
} catch (Exception ignored) {

View file

@ -46,6 +46,8 @@ public class DataKeeper<T> {
if(!permissionManager.checkCaller(strictness)) {
if(permissionManager.showErrors())
throw new IllegalAccessError("The active PermissionManager does not allow you to access this DataKeeper.");
else
return;
}
Lock waitLock = new Lock(true);
nextFunctionToRun.add(new DoubleTypedObject<>(accessor, waitLock));
@ -92,13 +94,6 @@ public class DataKeeper<T> {
value = data;
}
public T setValue(T newValue) {
// check is in getValue
T old = getValue();
value.set(newValue);
return old;
}
public T getValue() {
if(permissionManager.checkCaller(strictness))
return value.get();
@ -116,5 +111,12 @@ public class DataKeeper<T> {
return (T) value.get().getClass().cast(new Object());
}
}
public T setValue(T newValue) {
// check is in getValue
T old = getValue();
value.set(newValue);
return old;
}
}
}

View file

@ -2,7 +2,10 @@ package de.tudbut.security.permissionmanager;
import de.tudbut.security.PermissionManager;
import de.tudbut.security.Strictness;
import de.tudbut.tools.ReflectUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@ -17,14 +20,14 @@ import java.util.Set;
* allowlist pass, instead of allowing the allowed classes to call "through" others.
*/
public class ClassLoaderRestriction extends Restriction {
private final Set<Class<?>> allow;
private final Set<ClassLoader> allow;
public ClassLoaderRestriction(PermissionManager parent, Class<?>... allowFromClassLoaders) {
public ClassLoaderRestriction(PermissionManager parent, ClassLoader... allowFromClassLoaders) {
super(parent);
this.allow = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowFromClassLoaders)));
}
public ClassLoaderRestriction(Class<?>... allowFromClassLoaders) {
public ClassLoaderRestriction(ClassLoader... allowFromClassLoaders) {
this(null, allowFromClassLoaders);
}
@ -44,9 +47,9 @@ public class ClassLoaderRestriction extends Restriction {
boolean isCalledByAllowed = false;
for (StackTraceElement element : st) {
try {
Class<?> cls = Class.forName(element.getClassName());
// is the call the classloader or loaded by it?
if(allow.contains(cls) || allow.contains(cls.getClassLoader().getClass())) {
Class<?> cls = getClassObject(element.getClassName());
// is the classloader or loaded by it?
if(allow.stream().anyMatch(x -> x.getClass() == cls) || allow.contains(cls.getClassLoader())) {
isCalledByAllowed = true;
break;
}
@ -57,27 +60,44 @@ public class ClassLoaderRestriction extends Restriction {
return isCalledByAllowed && super.checkCaller(strictnessLevel);
}
private Class<?> getClassObject(String className) throws ClassNotFoundException {
try {
Method findLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
ReflectUtil.forceAccessible(findLoadedClass);
for (ClassLoader allowed : allow) {
Class<?> clazz = (Class<?>) findLoadedClass.invoke(allowed, className);
if(clazz != null) {
return clazz;
}
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
return Class.forName(className);
}
@Override
public <T> boolean checkLambda(Strictness strictnessLevel, T lambda) {
boolean b = true;
if(strictnessLevel.getBoolProperty("Restriction.ClassLoader.RestrictLambda")) {
// might get more complex soon.
// is classloader, inner class of it, or loaded by it?
b = allow.contains(lambda.getClass())
|| allow.contains(lambda.getClass().getClassLoader().getClass());
//noinspection SuspiciousMethodCalls
b = allow.contains(lambda)
|| allow.contains(lambda.getClass().getClassLoader());
// is enclosed class (e.g. anonymous class)
Class<?> enclosingClass = lambda.getClass().getEnclosingClass();
if (enclosingClass != null)
b = b || allow.contains(enclosingClass);
b = b || allow.stream().anyMatch(x -> x.getClass() == enclosingClass);
// is lambda in allowed class?
String name = lambda.getClass().getName().replaceAll("\\$\\$Lambda.*$", "");
for (Class<?> clazz : allow) {
if (clazz.getName().equals(name)) {
b = true;
break;
}
}
b = b || allow.stream().anyMatch(x -> x.getClass().getName().equals(name)); // is lambda in classloader
try {
b = b || allow.contains(Class.forName(name).getClassLoader().getClass());
b = b || allow.contains(getClassObject(name).getClassLoader()); // is lambda in classloader-loaded class
} catch (Exception e) {
// it'll just stay false
}

View file

@ -1,19 +1,23 @@
package de.tudbut.tools;
import com.sun.org.apache.xpath.internal.operations.Mod;
import de.tudbut.io.CLSPrintWriter;
import de.tudbut.parsing.TCN;
import sun.misc.Unsafe;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class ReflectUtil {
public static boolean hasAnnotation(Field field, Class<? extends Annotation> clazz) {
return field.getDeclaredAnnotation(clazz) != null;
}
public static <T> T getPrivateFieldByTypeIndex(Class<?> clazz, CLSPrintWriter o, Class<? extends T> type, int index) {
public static <T> T getPrivateFieldByTypeIndex(Class<?> clazz, Object o, Class<? extends T> type, int index) {
int idx = 0;
for (Field field : clazz.getDeclaredFields()) {
if(field.getType() == type) {
@ -30,7 +34,7 @@ public class ReflectUtil {
}
throw new NullPointerException();
}
public static <T> T setPrivateFieldByTypeIndex(Class<?> clazz, CLSPrintWriter o, Class<? extends T> type, int index, T t) {
public static <T> T setPrivateFieldByTypeIndex(Class<?> clazz, Object o, Class<? extends T> type, int index, T t) {
int idx = 0;
for (Field field : clazz.getDeclaredFields()) {
if(field.getType() == type) {
@ -54,10 +58,70 @@ public class ReflectUtil {
return (T) t.getClass().getDeclaredMethod("clone").invoke(t);
}
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
throw new RuntimeException(ignored);
throw new IllegalArgumentException();
}
}
else
return (T) new Object();
}
static Unsafe theSafe;
static {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
theSafe = (Unsafe) f.get(null);
} catch (Throwable e) {
throw new Error(e); // Don't recover.
}
}
// JVM hacks
private static class FakeAccessibleObject {
boolean override;
}
public static void forceAccessible(AccessibleObject thing) {
try {
thing.setAccessible(true);
if(!thing.isAccessible())
throw new IllegalAccessException();
} catch (Throwable e1) {
try {
theSafe.putBoolean(thing, theSafe.objectFieldOffset(AccessibleObject.class.getDeclaredField("override")), true);
if(!thing.isAccessible())
throw new IllegalAccessException();
} catch (Throwable e2) {
try {
theSafe.putBoolean(thing, theSafe.objectFieldOffset(FakeAccessibleObject.class.getDeclaredField("override")), true);
if(!thing.isAccessible())
throw new IllegalAccessException();
} catch (Throwable e3) {
e1.printStackTrace();
e2.printStackTrace();
e3.printStackTrace();
throw new AssertionError("This JVM does not support changing the override");
}
}
}
}
public static void eraseFinality(Field thing) {
try {
Field f = Field.class.getDeclaredField("modifiers");
forceAccessible(f);
f.set(thing, f.getInt(thing) & ~Modifier.FINAL);
if((thing.getModifiers() & Modifier.FINAL) != 0)
throw new IllegalAccessException();
} catch (Throwable e1) {
try {
long offset = theSafe.objectFieldOffset(Field.class.getDeclaredField("modifiers"));
theSafe.putInt(thing, offset, theSafe.getInt(thing, offset) & ~Modifier.FINAL); // EZ
if((thing.getModifiers() & Modifier.FINAL) != 0)
throw new IllegalAccessException();
} catch (Throwable e2) {
throw new AssertionError("This JVM does not support changing field modifiers");
}
}
}
}

View file

@ -10,14 +10,13 @@ package org.baseband.launcher.classloader;
import de.tudbut.security.*;
import de.tudbut.security.permissionmanager.CallClassRestriction;
import de.tudbut.security.permissionmanager.HideErrorRestriction;
import de.tudbut.security.permissionmanager.PermissionOR;
import net.minecraft.launchwrapper.Launch;
import org.baseband.launcher.launch.Loader;
import org.baseband.launcher.util.BBPermissionManager;
import org.baseband.launcher.util.DynamicPermissionManager;
import org.baseband.launcher.util.MixinRestriction;
import org.spongepowered.asm.service.MixinService;
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
import sun.misc.Unsafe;
import java.io.IOException;
import java.lang.reflect.Field;
@ -26,14 +25,17 @@ import java.util.HashMap;
public class CustomClassloader extends ClassLoader {
public CustomClassloader INSTANCE;
public static Class<?> customMixinServerClass = CustomMixinServer.class;
private static final DataKeeper<HashMap<String, byte[]>> encryptedClasses;
public static final DataKeeper<Object> registryTransfer;
static {
encryptedClasses = initSecurity();
encryptedClasses = init1();
registryTransfer = init2();
}
private static DataKeeper<HashMap<String, byte[]>> initSecurity() {
private static DataKeeper<HashMap<String, byte[]>> init1() {
AccessKiller.killReflectionFor(CustomClassloader.class, CustomMixinServer.class);
return new DataKeeper<>(
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, CustomMixinServer.class))),
@ -42,6 +44,14 @@ public class CustomClassloader extends ClassLoader {
);
}
private static DataKeeper<Object> init2() {
return new DataKeeper<>(
Loader.dynamicPermissionManager,
Loader.defaultStrictness,
null
);
}
public static void ensureInit() {
}
@ -104,8 +114,6 @@ public class CustomClassloader extends ClassLoader {
}
}
public static Class<?> customMixinServerClass = CustomMixinServer.class;
private static class CustomMixinServer extends MixinServiceLaunchWrapper {
private CustomMixinServer() {}

View file

@ -17,6 +17,8 @@ import net.minecraft.launchwrapper.Launch;
import org.baseband.launcher.Tweaker;
import org.baseband.launcher.util.BBPermissionManager;
import org.baseband.launcher.classloader.CustomClassloader;
import org.baseband.launcher.util.BaseBandSecurityManager;
import org.baseband.launcher.util.DynamicPermissionManager;
import org.baseband.launcher.util.Key;
import sun.misc.Unsafe;
import de.tudbut.parsing.TCN;
@ -30,6 +32,7 @@ import java.lang.reflect.Modifier;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -38,33 +41,47 @@ public class Loader {
public static DataKeeper<Key> classKey;
public static DataKeeper<Key> objectKey;
public static DataKeeper<PermissionManager> permissionManager;
public static final Strictness defaultStrictness = StrictnessBuilder.create()
.property("Restriction.CallClass.MaxDistance", 10)
.property("Restriction.ClassLoader.MaxDistance", 10)
.property("Restriction.Mixin.MaxDistance", 10)
.property("Restriction.CallClass.RestrictLambda", true) // only allow immediate calls
.property("Restriction.ClassLoader.RestrictLambda", true)
.build();
public static final Strictness defaultStrictness;
public static final DataKeeper<PermissionManager> permissionManager;
public static final PermissionManager dynamicPermissionManager = new DynamicPermissionManager();
static {
defaultStrictness = init1();
permissionManager = init2();
}
private static Strictness init1() {
AccessKiller.killFieldAccess(Loader.class, "defaultStrictness");
return StrictnessBuilder.create()
.property("Restriction.CallClass.MaxDistance", 10)
.property("Restriction.ClassLoader.MaxDistance", 15)
.property("Restriction.Mixin.MaxDistance", 10)
.property("Restriction.CallClass.RestrictLambda", true) // only allow immediate calls
.property("Restriction.ClassLoader.RestrictLambda", true)
.build();
}
private static DataKeeper<PermissionManager> init2() {
AccessKiller.killFieldAccess(Loader.class, "permissionManager");
PermissionManager manager =
new HideErrorRestriction(
new BBPermissionManager(
new CallClassRestriction(Loader.class, CustomClassloader.class, CustomClassloader.customMixinServerClass)));
return new DataKeeper<>(manager, defaultStrictness, manager);
}
public static PermissionManager getPermissionManager() {
AtomicReference<PermissionManager> manager = new AtomicReference<>();
permissionManager.access(x -> manager.set(x.getValue()));
return manager.get();
}
public static void initiate() {
boolean dump = dumpDetected();
PermissionManager mainPermissionManager =
new HideErrorRestriction(
new BBPermissionManager(
new PermissionOR(
new CallClassRestriction(Loader.class, CustomClassloader.class, CustomClassloader.customMixinServerClass),
new ClassLoaderRestriction(CustomClassloader.class))));
permissionManager = new DataKeeper<>(mainPermissionManager, defaultStrictness, mainPermissionManager);
classKey = new DataKeeper<>(mainPermissionManager, defaultStrictness, new Key());
objectKey = new DataKeeper<>(mainPermissionManager, defaultStrictness, new Key());
classKey = new DataKeeper<>(getPermissionManager() /*atm this is the CallClass-only one*/, defaultStrictness, new Key());
objectKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key());
try {
Socket socket = new Socket("127.0.0.1", 31212);
@ -111,13 +128,11 @@ public class Loader {
Key communicationKey = new Key(ticket);
outputF.writeUTF("loader");
outputF.writeUTF(communicationKey.encryptString(username));
outputF.writeUTF(communicationKey.encryptString(password));
outputF.writeUTF(communicationKey.encryptString(generate()));
boolean dump = dumpDetected();
outputF.writeBoolean(dump);
outputF.writeUTF("reason"); //TODO: make this return reason
@ -166,21 +181,23 @@ public class Loader {
}
}
String key = getRandomTicket();
/*
Registry baseBandRegistry = MCRegistry.registerMod("baseband");
TCN tcn = baseBandRegistry.register("*");
tcn.set("LoaderPresent", true);
tcn.set("Key", key);
TCN data = new TCN();
data.set("level", responseCode);
data.set("username", username);
tcn.set("Data", new Key(key).encryptString(Tools.mapToString(data.toMap())));
// this is not the real mod, therefore unregister so the actual client can register it
baseBandRegistry.unregister("*", tcn);
MCRegistry.unregisterMod("baseband", baseBandRegistry);
MCRegistry.GlobalRegistry.save();
*/
try {
Registry Registry = new Registry("BaseBand.registry");
TCN tcn = Registry.register("*");
tcn.set("LoaderPresent", true);
tcn.set("Key", key);
TCN data = new TCN();
data.set("level", responseCode);
data.set("username", username);
tcn.set("Data", new Key(key).encryptString(Tools.mapToString(data.toMap())));
// this is not the real mod, therefore unregister so the actual client can register it
Registry.unregister("*", tcn);
CustomClassloader.registryTransfer.access(x -> x.setValue(Registry));
} catch (Exception e) {
throw new RuntimeException(e);
}
Map<String, byte[]> classCache = new HashMap<>();
@ -203,7 +220,6 @@ public class Loader {
//Yep!
try (ZipInputStream zipStream = new ZipInputStream(input)) {
ZipEntry zipEntry;
while ((zipEntry = zipStream.getNextEntry()) != null) {
@ -252,7 +268,17 @@ public class Loader {
}
}
new CustomClassloader(classCache);
CustomClassloader customCL = new CustomClassloader(classCache);
permissionManager.access(x -> x.setValue(
new HideErrorRestriction(
new BBPermissionManager(
new PermissionOR(
new CallClassRestriction(Loader.class, CustomClassloader.class, CustomClassloader.customMixinServerClass),
new ClassLoaderRestriction(customCL)
)
)
)
));
Tweaker.log(String.format("Loaded. (Took %s milliseconds.)", System.nanoTime() / 1000000L - startTime));
@ -338,48 +364,44 @@ public class Loader {
return true;
}
try {
SecurityManager currentSecurityManager = System.getSecurityManager();
//// TudbuT // this is a VERY bad idea. it will overwrite any data that bytewise-matches
//// TudbuT // the security manager. this is so unsafe it might overwrite random data
//// TudbuT // that isnt even a security manager with one. if you really need a security
//// TudbuT // manager despite AccessKiller's existence, ask me and ill make a better setter.
// try {
// SecurityManager currentSecurityManager = System.getSecurityManager();
if (currentSecurityManager != null) {
Field b = Unsafe.class.getDeclaredField("theUnsafe");
boolean a = b.isAccessible();
b.setAccessible(true);
Unsafe unsafe = (Unsafe) b.get(null);
b.setAccessible(a);
Object base = null;
Field[] fields = System.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
base = unsafe.staticFieldBase(field);
break;
}
}
// if (currentSecurityManager != null) {
// Field b = Unsafe.class.getDeclaredField("theUnsafe");
// boolean a = b.isAccessible();
// b.setAccessible(true);
// Unsafe unsafe = (Unsafe)b.get(null);
// b.setAccessible(a);
// Object base = null;
// Field[] fields = System.class.getDeclaredFields();
// for (Field field : fields) {
// if (Modifier.isStatic(field.getModifiers())) {
// base = unsafe.staticFieldBase(field);
// break;
// }
// }
long offset = 0L;
// long offset = 0L;
while (true) {
Object object = unsafe.getObject(base, offset);
if (object == currentSecurityManager) {
unsafe.putObject(base, offset, new BaseBandSecurityManager());
return false;
}
// while (true) {
// Object object = unsafe.getObject(base, offset);
// if (object == currentSecurityManager) {
// unsafe.putObject(base, offset, new BaseBandSecurityManager());
// return false;
// }
offset += 4L;
}
} else {
System.setSecurityManager(new BaseBandSecurityManager());
return false;
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
// offset += 4L;
// }
// } else {
// System.setSecurityManager(new BaseBandSecurityManager());
// return false;
// }
// } catch (Exception e) {
// return true;
// }
return false;
//return false if it's fine, return true if it broke
}
@ -419,6 +441,7 @@ public class Loader {
Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class);
exitMethod.setAccessible(true);
exitMethod.invoke(null, 1);
} catch (Exception ignored) {}
} catch (Exception ignored) {
}
}
}

View file

@ -65,8 +65,10 @@ public class BBPermissionManager extends Restriction {
@Override
public boolean checkCaller(Strictness strictnessLevel) {
/*if(!(System.getSecurityManager() instanceof BaseBandSecurityManager)) {
System.out.println("No security?");
return false;
}*/
}
*/
//// TudbuT // Are you sure this is this a good idea? it will be called a LOT.

View file

@ -16,6 +16,12 @@ public class BaseBandSecurityManager extends SecurityManager {
public void checkPermission(Permission permission) {
String permissionName = (permission.getName() != null) ? permission.getName() : "null";
//noinspection DuplicateCondition
if (permissionName.equals("setSecurityManager")) {
//Loader.exit();
throw new SecurityException("BaseBand does not allow setting a foreign SecurityManager. Please contact basebandsec@mail.tudbut.de or @tudbut on Discord.");
}
//noinspection ConstantValue,DuplicateCondition
if (permissionName.equals("setSecurityManager")) {
Loader.exit();
}
@ -24,6 +30,7 @@ public class BaseBandSecurityManager extends SecurityManager {
Class<?>[] classContext = this.getClassContext();
String callerClassName = (classContext.length > 4) ? classContext[4].getName() : null;
String parentClassName = (classContext.length > 5) ? classContext[5].getName() : null;
System.out.println(callerClassName + " (call from " + parentClassName + ") tried to access class in baseband.");
if (callerClassName != null && !callerClassName.startsWith("com.baseband.")) {
if (parentClassName == null || !parentClassName.startsWith("com.baseband.")) {

View file

@ -0,0 +1,32 @@
package org.baseband.launcher.util;
import de.tudbut.security.PermissionManager;
import de.tudbut.security.Strictness;
import org.baseband.launcher.launch.Loader;
public class DynamicPermissionManager implements PermissionManager {
@Override
public boolean checkCaller(Strictness strictnessLevel) {
return Loader.getPermissionManager().checkCaller(strictnessLevel);
}
@Override
public <T> boolean checkLambda(Strictness strictnessLevel, T lambda) {
return Loader.getPermissionManager().checkLambda(strictnessLevel, lambda);
}
@Override
public void crash(Strictness strictnessLevel) {
Loader.getPermissionManager().crash(strictnessLevel);
}
@Override
public boolean showErrors() {
return Loader.getPermissionManager().showErrors();
}
@Override
public void killReflection() {
Loader.getPermissionManager().killReflection();
}
}

View file

@ -47,7 +47,7 @@ public class ClientHandler extends Thread {
int result;
// TODO MUST ALWAYS BE FALSE
if(false) {
if(true) {
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!");
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!! Granting access due to debug mode");
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!");