Add secure mode config toggles

This commit is contained in:
Lorenzune
2026-04-24 15:55:39 +02:00
parent 585af846c4
commit f51617d092
3 changed files with 22 additions and 0 deletions
@@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class NitroSecureApiHandler extends ChannelDuplexHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(NitroSecureApiHandler.class);
private static final String ENABLED_CONFIG = "nitro.secure.api.enabled";
private static final String API_PREFIX = "/api/";
private static final AttributeKey<Deque<SecureApiContext>> SECURE_CONTEXTS =
AttributeKey.valueOf("nitroSecureApiContexts");
@@ -39,6 +40,11 @@ public class NitroSecureApiHandler extends ChannelDuplexHandler {
String path = new QueryStringDecoder(req.uri()).path();
if (!secureApiEnabled()) {
super.channelRead(ctx, msg);
return;
}
if (!path.startsWith(API_PREFIX)) {
super.channelRead(ctx, msg);
return;
@@ -163,6 +169,10 @@ public class NitroSecureApiHandler extends ChannelDuplexHandler {
return "1".equals(req.headers().get("X-Nitro-Api"));
}
private static boolean secureApiEnabled() {
return com.eu.habbo.Emulator.getConfig().getBoolean(ENABLED_CONFIG, true);
}
private static byte[] unwrapEnvelope(byte[] clear, FullHttpRequest req, SecureApiContext secureContext) {
if (!requiresReplayEnvelope(req.method())) return clear;
@@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class NitroSecureAssetHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(NitroSecureAssetHandler.class);
private static final String MASTER_KEY_CONFIG = "nitro.secure.master_key";
private static final String ENABLED_CONFIG = "nitro.secure.assets.enabled";
private static final String BOOTSTRAP_PATH = "/nitro-sec/bootstrap";
private static final String FILE_PATH = "/nitro-sec/file";
private static final int MAX_BOOTSTRAP_BODY_BYTES = 4096;
@@ -48,6 +49,11 @@ public class NitroSecureAssetHandler extends ChannelInboundHandlerAdapter {
String path = new QueryStringDecoder(req.uri()).path();
if (!secureAssetsEnabled()) {
super.channelRead(ctx, msg);
return;
}
if (!path.equals(BOOTSTRAP_PATH) && !path.equals(FILE_PATH)) {
super.channelRead(ctx, msg);
return;
@@ -184,6 +190,10 @@ public class NitroSecureAssetHandler extends ChannelInboundHandlerAdapter {
return Path.of(fallback).toAbsolutePath().normalize();
}
private static boolean secureAssetsEnabled() {
return Emulator.getConfig().getBoolean(ENABLED_CONFIG, true);
}
static SecretKey deriveSessionKey(byte[] clientPublicEncoded) throws Exception {
KeyFactory factory = KeyFactory.getInstance("EC");
PublicKey clientPublic = factory.generatePublic(new X509EncodedKeySpec(clientPublicEncoded));
@@ -43,6 +43,8 @@ enc.n=86851dd364d5c5cece3c883171cc6ddc5760779b992482bd1e20dd296888df91b33b936a7b
enc.d=59ae13e243392e89ded305764bdd9e92e4eafa67bb6dac7e1415e8c645b0950bccd26246fd0d4af37145af5fa026c0ec3a94853013eaae5ff1888360f4f9449ee023762ec195dff3f30ca0b08b8c947e3859877b5d7dced5c8715c58b53740b84e11fbc71349a27c31745fcefeeea57cff291099205e230e0c7c27e8e1c0512b
# Nitro secure runtime assets. JSON files are read live from disk.
nitro.secure.assets.enabled=true
nitro.secure.api.enabled=true
nitro.secure.config.root=
nitro.secure.gamedata.root=
# Set a persistent secret when using Cloudflare / multiple backend requests.