This commit is contained in:
crschnick
2026-08-19 18:16:18 +00:00
parent 288d2cf380
commit 7283f38aa3
9 changed files with 83 additions and 13 deletions
@@ -106,13 +106,18 @@ public class BeaconRequestHandler<T> implements HttpHandler {
return;
}
var sync = beaconInterface.getSynchronizationObject();
if (sync != null) {
synchronized (sync) {
try {
var sync = beaconInterface.getSynchronizationObject();
if (sync != null) {
synchronized (sync) {
response = beaconInterface.handle(exchange, object);
}
} else {
response = beaconInterface.handle(exchange, object);
}
} else {
response = beaconInterface.handle(exchange, object);
} catch (IOException ioe) {
// Prevent IO exception from being interpreted as beacon connection issue
throw new BeaconServerException(ioe);
}
} catch (BeaconClientException clientException) {
ErrorEventFactory.fromThrowable(clientException).omit().expected().handle();
@@ -33,8 +33,12 @@ public class FsReadExchange extends BeaconInterface<FsReadExchange.Request> {
var shell = AppBeaconServer.get().getCache().getShellSession(msg.getStore());
var fs = new ShellFileSystem(shell.getControl());
if (!msg.getPath().isAbsolute()) {
throw new BeaconClientException("File path " + msg.getPath() + " is not absolute");
}
if (!fs.fileExists(msg.getPath())) {
throw new BeaconClientException("File does not exist");
throw new BeaconClientException("File " + msg.getPath() + " does not exist");
}
var size = fs.getFileSize(msg.getPath());
@@ -31,7 +31,6 @@ public class FsScriptExchange extends BeaconInterface<FsScriptExchange.Request>
try (var in = BlobManager.get().getBlob(msg.getBlob())) {
data = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
data = shell.getControl().getShellDialect().prepareScriptContent(shell.getControl(), data);
var file = ScriptHelper.createExecScript(shell.getControl(), data);
return Response.builder().path(file).build();
}
@@ -1,6 +1,7 @@
package io.xpipe.app.beacon.api;
import io.xpipe.app.beacon.AppBeaconServer;
import io.xpipe.app.beacon.BeaconClientException;
import io.xpipe.app.beacon.BeaconInterface;
import io.xpipe.app.beacon.BlobManager;
import io.xpipe.app.fs.ShellFileSystem;
@@ -27,6 +28,15 @@ public class FsWriteExchange extends BeaconInterface<FsWriteExchange.Request> {
public Object handle(HttpExchange exchange, Request msg) {
var shell = AppBeaconServer.get().getCache().getShellSession(msg.getStore());
var fs = new ShellFileSystem(shell.getControl());
if (!msg.getPath().isAbsolute()) {
throw new BeaconClientException("File path " + msg.getPath() + " is not absolute");
}
if (!fs.directoryExists(msg.getPath().getParent())) {
throw new BeaconClientException("Directory " + msg.getPath().getParent() + " does not exist");
}
try (var in = BlobManager.get().getBlob(msg.getBlob());
var os = fs.openOutput(msg.getPath(), BlobManager.get().getSize(msg.getBlob()))) {
in.transferTo(os);
@@ -16,9 +16,7 @@ import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
@JsonTypeName("internal")
@SuperBuilder
@Jacksonized
@EqualsAndHashCode(callSuper = true)
public class InPlaceSecretValue extends AesSecretValue {
@@ -23,6 +23,7 @@ import tools.jackson.core.JsonParser;
import tools.jackson.core.TokenStreamLocation;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.*;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.annotation.JsonSerialize;
import tools.jackson.databind.jsontype.NamedType;
import tools.jackson.databind.jsontype.TypeDeserializer;
@@ -32,6 +33,7 @@ import tools.jackson.databind.module.SimpleModule;
import tools.jackson.databind.node.JsonNodeFactory;
import java.io.CharArrayReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
@@ -70,6 +72,9 @@ public class AppJacksonModule extends SimpleModule {
registerSubtypes(ExternalSpiceClient.getClasses());
registerSubtypes(SecretRetrievalStrategy.getClasses());
addSerializer(InPlaceSecretValue.class, new InPlaceSecretValueSerializer());
addDeserializer(InPlaceSecretValue.class, new InPlaceSecretValueDeserializer());
addSerializer(DataStoreEntryRef.class, new DataStoreEntryRefSerializer());
addDeserializer(DataStoreEntryRef.class, new DataStoreEntryRefDeserializer());
@@ -118,6 +123,57 @@ public class AppJacksonModule extends SimpleModule {
super.setupModule(context);
}
public static class InPlaceSecretValueSerializer extends ValueSerializer<InPlaceSecretValue> {
@Override
public void serializeWithType(InPlaceSecretValue value, JsonGenerator gen, SerializationContext ctxt, TypeSerializer typeSer) throws
JacksonException {
serialize(value, gen, ctxt);
}
@Override
public void serialize(InPlaceSecretValue value, JsonGenerator jgen, SerializationContext context) {
if (value == null) {
jgen.writeNull();
return;
}
var tree = JsonNodeFactory.instance.objectNode();
tree.put("type", "internal");
tree.put("encryptedValue", value.getEncryptedValue());
jgen.writeTree(tree);
}
}
public static class InPlaceSecretValueDeserializer extends ValueDeserializer<InPlaceSecretValue> {
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws JacksonException {
return deserialize(p, ctxt);
}
@Override
public InPlaceSecretValue deserialize(JsonParser p, DeserializationContext ctxt) throws
JacksonException {
JsonNode tree = JacksonMapper.getDefault().readTree(p);
if (tree.isString()) {
return InPlaceSecretValue.of(tree.stringValue());
}
var type = tree.get("type");
if (type == null || !type.asString().equals("internal")) {
return null;
}
var enc = tree.get("encryptedValue");
if (enc == null) {
return null;
}
return InPlaceSecretValue.builder().encryptedValue(enc.stringValue()).build();
}
}
public static class EncryptionTokenSerializer extends ValueSerializer<EncryptionToken> {
@Override
@@ -31,8 +31,6 @@ public class ScriptStore implements SelfReferentialStore, StatefulDataStore<Enab
@Singular
List<DataStoreEntryRef<ScriptStore>> scripts;
String description;
ScriptTextSource textSource;
boolean initScript;
boolean shellScript;
@@ -162,7 +162,6 @@ public class ScriptStoreProvider implements DataStoreProvider {
return ScriptStore.builder()
.textSource(textSource.get())
.scripts(new ArrayList<>(others.get()))
.description(st.getDescription())
.initScript(selectedExecTypes.contains(0))
.runnableScript(selectedExecTypes.contains(1))
.fileScript(selectedExecTypes.contains(2))
+2 -1
View File
@@ -1982,7 +1982,8 @@ keePassXcOpenSshAgent=Use OpenSSH agent
keePassXcPageant=Use Pageant
passwordManagerSshAgentSocket=SSH agent socket
passwordManagerSshAgentSocketDescription=The socket that should be used to communicate with the agent.
passwordManagerSshKeysNotSupported=The current password manager configuration does not support retrieving SSH keys via an agent
#force
passwordManagerSshKeysNotSupported=The current password manager configuration does not support retrieving SSH keys
passwordManagerAdditionalKey=Additional SSH key
passwordManagerAdditionalKeyDescription=The SSH key to use in addition to the credentials from the password manager
multiIdentity.displayName=Multi identity