From 155a0bf4485d748a00aa40e0d4e5117bcf7c2f5d Mon Sep 17 00:00:00 2001 From: Stephanya Casanova Date: Mon, 9 Sep 2024 09:15:19 +0200 Subject: [PATCH] [backend] Add elevation required attribute --- .../V3_33__Add_column_requires_elevation.java | 18 +++++++++ .../rest/payload/form/PayloadCreateInput.java | 7 +++- .../rest/payload/form/PayloadUpdateInput.java | 3 ++ .../rest/payload/form/PayloadUpsertInput.java | 3 ++ .../io/openbas/asset/EndpointService.java | 10 ++++- .../io/openbas/config/OpenBASAgentConfig.java | 40 +++++++++++++++++++ .../OpenBASExecutorContextService.java | 16 +++++--- .../openbas/database/model/AssetAgentJob.java | 19 +++++---- .../io/openbas/database/model/Payload.java | 11 +++-- 9 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 openbas-api/src/main/java/io/openbas/migration/V3_33__Add_column_requires_elevation.java create mode 100644 openbas-framework/src/main/java/io/openbas/config/OpenBASAgentConfig.java diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_33__Add_column_requires_elevation.java b/openbas-api/src/main/java/io/openbas/migration/V3_33__Add_column_requires_elevation.java new file mode 100644 index 0000000000..cc52d5c903 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/migration/V3_33__Add_column_requires_elevation.java @@ -0,0 +1,18 @@ +package io.openbas.migration; + +import org.flywaydb.core.api.migration.BaseJavaMigration; +import org.flywaydb.core.api.migration.Context; +import org.springframework.stereotype.Component; + +import java.sql.Statement; + +@Component +public class V3_33__Add_column_requires_elevation extends BaseJavaMigration { + + @Override + public void migrate(final Context context) throws Exception { + final Statement select = context.getConnection().createStatement(); + select.execute("ALTER TABLE asset_agent_jobs ADD asset_agent_elevation_required bool default false;"); + select.execute("ALTER TABLE payloads ADD payload_elevation_required bool default false;"); + } +} diff --git a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadCreateInput.java b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadCreateInput.java index 7083cad651..66509e032d 100644 --- a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadCreateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadCreateInput.java @@ -1,7 +1,7 @@ package io.openbas.rest.payload.form; import com.fasterxml.jackson.annotation.JsonProperty; -import io.openbas.database.model.Endpoint.PLATFORM_TYPE; +import io.openbas.database.model.Endpoint; import io.openbas.database.model.PayloadArgument; import io.openbas.database.model.PayloadPrerequisite; import jakarta.validation.constraints.NotBlank; @@ -36,7 +36,7 @@ public class PayloadCreateInput { @NotEmpty(message = MANDATORY_MESSAGE) @JsonProperty("payload_platforms") - private PLATFORM_TYPE[] platforms; + private Endpoint.PLATFORM_TYPE[] platforms; @JsonProperty("payload_description") private String description; @@ -73,6 +73,9 @@ public class PayloadCreateInput { @JsonProperty("payload_attack_patterns") private List attackPatternsIds = new ArrayList<>(); + + @JsonProperty("payload_elevation_required") + private boolean elevationRequired; } diff --git a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpdateInput.java index da3bb24ddc..572212249c 100644 --- a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpdateInput.java @@ -58,6 +58,9 @@ public class PayloadUpdateInput { @JsonProperty("payload_attack_patterns") private List attackPatternsIds = new ArrayList<>(); + + @JsonProperty("payload_elevation_required") + private boolean elevationRequired; } diff --git a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpsertInput.java b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpsertInput.java index f4c4a1a899..f59d5326b3 100644 --- a/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpsertInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/payload/form/PayloadUpsertInput.java @@ -76,6 +76,9 @@ public class PayloadUpsertInput { @JsonProperty("payload_attack_patterns") private List attackPatternsExternalIds = new ArrayList<>(); + + @JsonProperty("payload_elevation_required") + private boolean elevationRequired; } diff --git a/openbas-framework/src/main/java/io/openbas/asset/EndpointService.java b/openbas-framework/src/main/java/io/openbas/asset/EndpointService.java index 6252443368..aaa69baec2 100644 --- a/openbas-framework/src/main/java/io/openbas/asset/EndpointService.java +++ b/openbas-framework/src/main/java/io/openbas/asset/EndpointService.java @@ -1,5 +1,6 @@ package io.openbas.asset; +import io.openbas.config.OpenBASAgentConfig; import io.openbas.config.OpenBASConfig; import io.openbas.database.model.Endpoint; import io.openbas.database.repository.EndpointRepository; @@ -33,6 +34,9 @@ public class EndpointService { @Resource private OpenBASConfig openBASConfig; + @Resource + private OpenBASAgentConfig openBASAgentConfig; + @Value("${openbas.admin.token:#{null}}") private String adminToken; @@ -103,13 +107,15 @@ public String getFileOrDownloadFromJfrog(String platform, String file, String ad String filename = file + "-" + version + "." + extension; String resourcePath = "/openbas-agent/" + platform.toLowerCase() + "/"; InputStream in = getClass().getResourceAsStream("/agents" + resourcePath + filename); - if (in == null) { // Dev mode, get from artifactory + if (null == in) { // Dev mode, get from artifactory filename = file + "-latest." + extension; in = new BufferedInputStream(new URL(JFROG_BASE + resourcePath + filename).openStream()); } return IOUtils.toString(in, StandardCharsets.UTF_8) .replace("${OPENBAS_URL}", openBASConfig.getBaseUrl()) - .replace("${OPENBAS_TOKEN}", adminToken); + .replace("${OPENBAS_TOKEN}", adminToken) + .replace("${NON_SYSTEM_USER}", openBASAgentConfig.getNonSystemUser()) + .replace("${NON_SYSTEM_PWD}", openBASAgentConfig.getNonSystemPwd()); } public String generateInstallCommand(String platform, String token) throws IOException { diff --git a/openbas-framework/src/main/java/io/openbas/config/OpenBASAgentConfig.java b/openbas-framework/src/main/java/io/openbas/config/OpenBASAgentConfig.java new file mode 100644 index 0000000000..0d4beb7efd --- /dev/null +++ b/openbas-framework/src/main/java/io/openbas/config/OpenBASAgentConfig.java @@ -0,0 +1,40 @@ +package io.openbas.config; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "openbas.rabbitmq") +@Data +public class RabbitmqConfig { + + @JsonProperty("rabbitmq_prefix") + private String prefix; + + @JsonProperty("rabbitmq_hostname") + private String hostname; + + @JsonProperty("rabbitmq_vhost") + private String vhost; + + @JsonProperty("rabbitmq_ssl") + private boolean ssl; + + @JsonProperty("rabbitmq_port") + private int port; + + @JsonProperty("rabbitmq_management-port") + private int managementPort; + + @JsonProperty("rabbitmq_user") + private String user; + + @JsonProperty("rabbitmq_pass") + private String pass; + + @JsonProperty("rabbitmq_queue-type") + private String queueType; + +} diff --git a/openbas-framework/src/main/java/io/openbas/executors/openbas/service/OpenBASExecutorContextService.java b/openbas-framework/src/main/java/io/openbas/executors/openbas/service/OpenBASExecutorContextService.java index 04a0efd08f..2dad38d356 100644 --- a/openbas-framework/src/main/java/io/openbas/executors/openbas/service/OpenBASExecutorContextService.java +++ b/openbas-framework/src/main/java/io/openbas/executors/openbas/service/OpenBASExecutorContextService.java @@ -27,15 +27,15 @@ private String computeCommand(@NotNull final Inject inject, Endpoint.PLATFORM_TY .orElseThrow(() -> new UnsupportedOperationException("Inject does not have a contract")); switch (platform) { - case Endpoint.PLATFORM_TYPE.Windows -> { + case Windows -> { return injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.Windows.name() + "." + arch.name()) .replace("#{inject}", inject.getId()); } - case Endpoint.PLATFORM_TYPE.Linux -> { + case Linux -> { return injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.Linux.name() + "." + arch.name()) .replace("#{inject}", inject.getId()); } - case Endpoint.PLATFORM_TYPE.MacOS -> { + case MacOS -> { return injector.getExecutorCommands().get(Endpoint.PLATFORM_TYPE.MacOS.name() + "." + arch.name()) .replace("#{inject}", inject.getId()); } @@ -46,17 +46,23 @@ private String computeCommand(@NotNull final Inject inject, Endpoint.PLATFORM_TY public void launchExecutorSubprocess(@NotNull final Inject inject, @NotNull final Asset asset) { Endpoint.PLATFORM_TYPE platform = Objects.equals(asset.getType(), "Endpoint") ? ((Endpoint) Hibernate.unproxy(asset)).getPlatform() : null; Endpoint.PLATFORM_ARCH arch = Objects.equals(asset.getType(), "Endpoint") ? ((Endpoint) Hibernate.unproxy(asset)).getArch() : null; - if (platform == null) { + if (null == platform) { throw new RuntimeException("Unsupported null platform"); } AssetAgentJob assetAgentJob = new AssetAgentJob(); assetAgentJob.setCommand(computeCommand(inject, platform, arch)); assetAgentJob.setAsset(asset); assetAgentJob.setInject(inject); - assetAgentJobRepository.save(assetAgentJob); + assetAgentJob.setElevationRequired(this.isElevationRequired(inject)); + assetAgentJobRepository.save(assetAgentJob); } public void launchExecutorClear(@NotNull final Injector injector, @NotNull final Asset asset) { // TODO } + + private boolean isElevationRequired(final Inject inject) { + // Fix me add also for caldera + return inject.getInjectorContract().map(injectorContract -> injectorContract.getPayload().isElevationRequired()).orElse(false).booleanValue(); + } } diff --git a/openbas-model/src/main/java/io/openbas/database/model/AssetAgentJob.java b/openbas-model/src/main/java/io/openbas/database/model/AssetAgentJob.java index b4d7f9c445..e049be8541 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/AssetAgentJob.java +++ b/openbas-model/src/main/java/io/openbas/database/model/AssetAgentJob.java @@ -46,26 +46,31 @@ public class AssetAgentJob implements Base { @NotBlank private String command; + @Getter + @Column(name = "asset_agent_elevation_required") + @JsonProperty("asset_agent_elevation_required") + private boolean elevationRequired; + @Override public String toString() { - return id; + return this.id; } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) return true; - if (o == null || !Base.class.isAssignableFrom(o.getClass())) return false; - Base base = (Base) o; - return id.equals(base.getId()); + if (null == o || !Base.class.isAssignableFrom(o.getClass())) return false; + final Base base = (Base) o; + return this.id.equals(base.getId()); } @Override public int hashCode() { - return Objects.hash(id); + return Objects.hash(this.id); } @Override public String getId() { - return id; + return this.id; } } diff --git a/openbas-model/src/main/java/io/openbas/database/model/Payload.java b/openbas-model/src/main/java/io/openbas/database/model/Payload.java index b43e2cba14..f4bdee081b 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Payload.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Payload.java @@ -6,7 +6,6 @@ import io.hypersistence.utils.hibernate.type.json.JsonType; import io.openbas.annotation.Queryable; import io.openbas.database.audit.ModelBaseListener; -import io.openbas.database.model.Endpoint.PLATFORM_TYPE; import io.openbas.helper.MonoIdDeserializer; import io.openbas.helper.MultiIdListDeserializer; import io.openbas.helper.MultiIdSetDeserializer; @@ -14,6 +13,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; +import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.Type; import org.hibernate.annotations.UuidGenerator; @@ -72,7 +72,7 @@ public enum PAYLOAD_STATUS { @Type(StringArrayType.class) @Column(name = "payload_platforms", columnDefinition = "text[]") @JsonProperty("payload_platforms") - private PLATFORM_TYPE[] platforms = new PLATFORM_TYPE[0]; + private Endpoint.PLATFORM_TYPE[] platforms = new Endpoint.PLATFORM_TYPE[0]; @Setter @ManyToMany(fetch = FetchType.EAGER) @@ -94,6 +94,11 @@ public enum PAYLOAD_STATUS { @JsonProperty("payload_cleanup_command") private String cleanupCommand; + @Getter + @Column(name = "payload_elevation_required") + @JsonProperty("payload_elevation_required") + private boolean elevationRequired; + @Setter @Type(JsonType.class) @Column(name = "payload_arguments") @@ -159,7 +164,7 @@ public enum PAYLOAD_STATUS { @JsonProperty("payload_collector_type") private String getCollectorType() { - return this.getCollector() != null ? this.getCollector().getType() : null; + return null != collector ? this.collector.getType() : null; } @Override