forked from GeyserMC/Geyser
Add support for sensitive data in dumps (#1149)
* Add sensitive dumps * Add better arg handling and offline dumps * Add sensitive parameters for plugin IPs * Add sensitive property to the Bedrock remote address Co-authored-by: Camotoy <20743703+DoctorMacc@users.noreply.github.com>
This commit is contained in:
parent
4bcf44638e
commit
4af17df46f
7 changed files with 98 additions and 28 deletions
|
@ -28,6 +28,7 @@ package org.geysermc.platform.bungeecord;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -52,7 +53,13 @@ public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
||||||
this.plugins = new ArrayList<>();
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
|
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
|
||||||
this.listeners.add(new ListenerInfo(listener.getHost().getHostString(), listener.getHost().getPort()));
|
String hostname;
|
||||||
|
if (AsteriskSerializer.showSensitive || (listener.getHost().getHostString().equals("") || listener.getHost().getHostString().equals("0.0.0.0"))) {
|
||||||
|
hostname = listener.getHost().getHostString();
|
||||||
|
} else {
|
||||||
|
hostname = "***";
|
||||||
|
}
|
||||||
|
this.listeners.add(new ListenerInfo(hostname, listener.getHost().getPort()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.platform.spigot;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -50,7 +51,11 @@ public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
||||||
this.platformVersion = Bukkit.getVersion();
|
this.platformVersion = Bukkit.getVersion();
|
||||||
this.platformAPIVersion = Bukkit.getBukkitVersion();
|
this.platformAPIVersion = Bukkit.getBukkitVersion();
|
||||||
this.onlineMode = Bukkit.getOnlineMode();
|
this.onlineMode = Bukkit.getOnlineMode();
|
||||||
this.serverIP = Bukkit.getIp();
|
if (AsteriskSerializer.showSensitive || (Bukkit.getIp().equals("") || Bukkit.getIp().equals("0.0.0.0"))) {
|
||||||
|
this.serverIP = Bukkit.getIp();
|
||||||
|
} else {
|
||||||
|
this.serverIP = "***";
|
||||||
|
}
|
||||||
this.serverPort = Bukkit.getPort();
|
this.serverPort = Bukkit.getPort();
|
||||||
this.plugins = new ArrayList<>();
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ package org.geysermc.platform.velocity;
|
||||||
import com.velocitypowered.api.plugin.PluginContainer;
|
import com.velocitypowered.api.plugin.PluginContainer;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -50,7 +51,11 @@ public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
||||||
this.platformVersion = proxy.getVersion().getVersion();
|
this.platformVersion = proxy.getVersion().getVersion();
|
||||||
this.platformVendor = proxy.getVersion().getVendor();
|
this.platformVendor = proxy.getVersion().getVendor();
|
||||||
this.onlineMode = proxy.getConfiguration().isOnlineMode();
|
this.onlineMode = proxy.getConfiguration().isOnlineMode();
|
||||||
this.serverIP = proxy.getBoundAddress().getHostString();
|
if (AsteriskSerializer.showSensitive || (proxy.getBoundAddress().getHostString().equals("") || proxy.getBoundAddress().getHostString().equals("0.0.0.0"))) {
|
||||||
|
this.serverIP = proxy.getBoundAddress().getHostString();
|
||||||
|
} else {
|
||||||
|
this.serverIP = "***";
|
||||||
|
}
|
||||||
this.serverPort = proxy.getBoundAddress().getPort();
|
this.serverPort = proxy.getBoundAddress().getPort();
|
||||||
this.plugins = new ArrayList<>();
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,12 @@ import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
import org.geysermc.connector.dump.DumpInfo;
|
import org.geysermc.connector.dump.DumpInfo;
|
||||||
import org.geysermc.connector.utils.LanguageUtils;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.connector.utils.WebUtils;
|
import org.geysermc.connector.utils.WebUtils;
|
||||||
|
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class DumpCommand extends GeyserCommand {
|
public class DumpCommand extends GeyserCommand {
|
||||||
|
@ -49,43 +51,80 @@ public class DumpCommand extends GeyserCommand {
|
||||||
super(name, description, permission);
|
super(name, description, permission);
|
||||||
|
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
|
|
||||||
final SimpleFilterProvider filter = new SimpleFilterProvider();
|
|
||||||
filter.addFilter("dump_user_auth", SimpleBeanPropertyFilter.serializeAllExcept(new String[] {"password"}));
|
|
||||||
|
|
||||||
MAPPER.setFilterProvider(filter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
boolean showSensitive = false;
|
||||||
|
boolean offlineDump = false;
|
||||||
|
if (args.length >= 1) {
|
||||||
|
for (String arg : args) {
|
||||||
|
switch (arg) {
|
||||||
|
case "full":
|
||||||
|
showSensitive = true;
|
||||||
|
break;
|
||||||
|
case "offline":
|
||||||
|
offlineDump = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AsteriskSerializer.showSensitive = showSensitive;
|
||||||
|
|
||||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collecting"));
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collecting"));
|
||||||
String dumpData = "";
|
String dumpData = "";
|
||||||
try {
|
try {
|
||||||
dumpData = MAPPER.writeValueAsString(new DumpInfo());
|
if (offlineDump) {
|
||||||
|
dumpData = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(new DumpInfo());
|
||||||
|
} else {
|
||||||
|
dumpData = MAPPER.writeValueAsString(new DumpInfo());
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error"));
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error"));
|
||||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.uploading"));
|
String uploadedDumpUrl = "";
|
||||||
String response;
|
|
||||||
JsonNode responseNode;
|
if (offlineDump) {
|
||||||
try {
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.writing"));
|
||||||
response = WebUtils.post(DUMP_URL + "documents", dumpData);
|
|
||||||
responseNode = MAPPER.readTree(response);
|
try {
|
||||||
} catch (IOException e) {
|
FileOutputStream outputStream = new FileOutputStream(GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("dump.json").toFile());
|
||||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error"));
|
outputStream.write(dumpData.getBytes());
|
||||||
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e);
|
outputStream.close();
|
||||||
return;
|
} catch (IOException e) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.write_error"));
|
||||||
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.write_error_short"), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadedDumpUrl = "dump.json";
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.uploading"));
|
||||||
|
|
||||||
|
String response;
|
||||||
|
JsonNode responseNode;
|
||||||
|
try {
|
||||||
|
response = WebUtils.post(DUMP_URL + "documents", dumpData);
|
||||||
|
responseNode = MAPPER.readTree(response);
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error"));
|
||||||
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!responseNode.has("key")) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short") + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!responseNode.has("key")) {
|
|
||||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short") + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
|
|
||||||
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.message") + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.message") + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
|
||||||
if (!sender.isConsole()) {
|
if (!sender.isConsole()) {
|
||||||
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), uploadedDumpUrl));
|
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), uploadedDumpUrl));
|
||||||
|
|
|
@ -42,34 +42,46 @@ import java.lang.annotation.Target;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
|
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
|
||||||
|
|
||||||
|
public static boolean showSensitive = false;
|
||||||
|
|
||||||
@Target({ElementType.FIELD})
|
@Target({ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@JacksonAnnotationsInside
|
@JacksonAnnotationsInside
|
||||||
@JsonSerialize(using = AsteriskSerializer.class)
|
@JsonSerialize(using = AsteriskSerializer.class)
|
||||||
public @interface Asterisk {
|
public @interface Asterisk {
|
||||||
String value() default "***";
|
String value() default "***";
|
||||||
|
boolean sensitive() default false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String asterisk;
|
String asterisk;
|
||||||
|
boolean sensitive;
|
||||||
|
|
||||||
public AsteriskSerializer() {
|
public AsteriskSerializer() {
|
||||||
super(Object.class);
|
super(Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsteriskSerializer(String asterisk) {
|
public AsteriskSerializer(String asterisk, boolean sensitive) {
|
||||||
super(Object.class);
|
super(Object.class);
|
||||||
this.asterisk = asterisk;
|
this.asterisk = asterisk;
|
||||||
|
this.sensitive = sensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
|
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
|
||||||
Optional<Asterisk> anno = Optional.ofNullable(property)
|
Optional<Asterisk> anno = Optional.ofNullable(property)
|
||||||
.map(prop -> prop.getAnnotation(Asterisk.class));
|
.map(prop -> prop.getAnnotation(Asterisk.class));
|
||||||
return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null));
|
|
||||||
|
return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null), anno.map(Asterisk::sensitive).orElse(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
|
public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
|
||||||
|
if (sensitive && showSensitive) {
|
||||||
|
gen.writeObject(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gen.writeString(asterisk);
|
gen.writeString(asterisk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||||
@Getter
|
@Getter
|
||||||
public static class BedrockConfiguration implements IBedrockConfiguration {
|
public static class BedrockConfiguration implements IBedrockConfiguration {
|
||||||
|
|
||||||
|
@AsteriskSerializer.Asterisk(sensitive = true)
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -114,6 +115,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||||
public static class RemoteConfiguration implements IRemoteConfiguration {
|
public static class RemoteConfiguration implements IRemoteConfiguration {
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
@AsteriskSerializer.Asterisk(sensitive = true)
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 57e5986bd99bf3d81d67c75299ea3dde67d53554
|
Subproject commit 2641db5aa9100cdbe21b4493489e9be19092a600
|
Loading…
Reference in a new issue