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:
rtm516 2020-08-15 21:06:50 +01:00 committed by GitHub
parent 4bcf44638e
commit 4af17df46f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 28 deletions

View file

@ -33,10 +33,12 @@ import org.geysermc.connector.common.ChatColor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.common.serializer.AsteriskSerializer;
import org.geysermc.connector.dump.DumpInfo;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.connector.utils.WebUtils;
import java.io.FileOutputStream;
import java.io.IOException;
public class DumpCommand extends GeyserCommand {
@ -49,43 +51,80 @@ public class DumpCommand extends GeyserCommand {
super(name, description, permission);
this.connector = connector;
final SimpleFilterProvider filter = new SimpleFilterProvider();
filter.addFilter("dump_user_auth", SimpleBeanPropertyFilter.serializeAllExcept(new String[] {"password"}));
MAPPER.setFilterProvider(filter);
}
@Override
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"));
String dumpData = "";
try {
dumpData = MAPPER.writeValueAsString(new DumpInfo());
if (offlineDump) {
dumpData = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(new DumpInfo());
} else {
dumpData = MAPPER.writeValueAsString(new DumpInfo());
}
} catch (IOException e) {
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error"));
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
return;
}
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;
String uploadedDumpUrl = "";
if (offlineDump) {
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.writing"));
try {
FileOutputStream outputStream = new FileOutputStream(GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("dump.json").toFile());
outputStream.write(dumpData.getBytes());
outputStream.close();
} 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);
if (!sender.isConsole()) {
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), uploadedDumpUrl));

View file

@ -42,34 +42,46 @@ import java.lang.annotation.Target;
import java.util.Optional;
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
public static boolean showSensitive = false;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = AsteriskSerializer.class)
public @interface Asterisk {
String value() default "***";
boolean sensitive() default false;
}
String asterisk;
boolean sensitive;
public AsteriskSerializer() {
super(Object.class);
}
public AsteriskSerializer(String asterisk) {
public AsteriskSerializer(String asterisk, boolean sensitive) {
super(Object.class);
this.asterisk = asterisk;
this.sensitive = sensitive;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
Optional<Asterisk> anno = Optional.ofNullable(property)
.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
public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
if (sensitive && showSensitive) {
gen.writeObject(obj);
return;
}
gen.writeString(asterisk);
}
}

View file

@ -98,6 +98,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
@Getter
public static class BedrockConfiguration implements IBedrockConfiguration {
@AsteriskSerializer.Asterisk(sensitive = true)
private String address;
@Setter
@ -114,6 +115,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
public static class RemoteConfiguration implements IRemoteConfiguration {
@Setter
@AsteriskSerializer.Asterisk(sensitive = true)
private String address;
@Setter

@ -1 +1 @@
Subproject commit 57e5986bd99bf3d81d67c75299ea3dde67d53554
Subproject commit 2641db5aa9100cdbe21b4493489e9be19092a600