Skip to content

Commit

Permalink
Merge branch 'branches/rudder/8.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
clarktsiory committed Dec 13, 2024
2 parents e797c19 + 53daa05 commit 3e7ce6f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 62 deletions.
3 changes: 0 additions & 3 deletions openscap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ target/openscap_technique.zip: target/rudderc
target/remove_configuration:
cp packaging/remove_configuration target/remove_configuration

target/openscap.properties:
cp src/main/resources/openscap.properties target/openscap.properties

clean:
rm -f $(FULL_NAME)-*.rpkg pom.xml
rm -rf target
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@

package bootstrap.rudder.plugin

import bootstrap.liftweb.ClassPathResource
import bootstrap.liftweb.FileSystemResource
import bootstrap.liftweb.RudderConfig
import com.normation.plugins.RudderPluginModule
import com.normation.plugins.openscappolicies.CheckRudderPluginEnableImpl
Expand All @@ -47,55 +45,11 @@ import com.normation.plugins.openscappolicies.api.OpenScapApiImpl
import com.normation.plugins.openscappolicies.extension.OpenScapNodeDetailsExtension
import com.normation.plugins.openscappolicies.services.GetActiveTechniqueIds
import com.normation.plugins.openscappolicies.services.OpenScapReportReader
import com.normation.rudder.domain.logger.ApplicationLogger
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import java.io.File

object OpenScapProperties {
val CONFIG_FILE_KEY = "rudder.plugin.openScapPolicies.config"
val DEFAULT_CONFIG_FILE_NAME = "openscap.properties"

val configResource = System.getProperty(CONFIG_FILE_KEY) match {
case null | "" => // use default location in classpath
ApplicationLogger.info(s"JVM property -D${CONFIG_FILE_KEY} is not defined, use configuration file in classpath")
ClassPathResource(DEFAULT_CONFIG_FILE_NAME)
case x => // so, it should be a full path, check it
val config = new File(x)
if (config.exists && config.canRead) {
ApplicationLogger.info(s"Use configuration file defined by JVM property -D${CONFIG_FILE_KEY} : ${config.toURI.getPath}")
FileSystemResource(config)
} else {
ApplicationLogger.error(s"Can not find configuration file specified by JVM property ${CONFIG_FILE_KEY} ${x} ; abort")
throw new IllegalArgumentException("Configuration file not found: %s".format(config.toURI.getPath))
}
}

val config: Config = {
(configResource match {
case ClassPathResource(name) => ConfigFactory.load(name)
case FileSystemResource(file) => ConfigFactory.load(ConfigFactory.parseFile(file))
})
}
}

/*
* Actual configuration of the plugin logic
*/
object OpenscapPoliciesConf extends RudderPluginModule {
import OpenScapProperties.*

val SANITIZATION_PROPERTY = "sanitization.file"
val POLICY_SANITIZATION_FILE = config.getString(SANITIZATION_PROPERTY)

// check if sanitization file exists. If it doesn't, then it will silently block the start of Rudder
val policy_sanitization_file = new File(POLICY_SANITIZATION_FILE)
if (!policy_sanitization_file.exists()) {
ApplicationLogger.error(
s"Can not find sanitization file specified by configuration property ${SANITIZATION_PROPERTY}: ${POLICY_SANITIZATION_FILE}; abort"
)
throw new IllegalArgumentException(s"OpenSCAP sanitization file not found: ${POLICY_SANITIZATION_FILE}")
}

lazy val pluginStatusService = new CheckRudderPluginEnableImpl(RudderConfig.nodeFactRepository)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

package com.normation.plugins.openscappolicies.api

import com.normation.errors.SystemError
import com.normation.inventory.domain.NodeId
import com.normation.plugins.openscappolicies.OpenscapPoliciesLogger
import com.normation.plugins.openscappolicies.services.OpenScapReportReader
Expand All @@ -56,6 +57,7 @@ import com.normation.rudder.rest.lift.LiftApiModule
import com.normation.rudder.rest.lift.LiftApiModuleProvider
import com.normation.zio.*
import enumeratum.*
import java.io.IOException
import net.liftweb.http.InMemoryResponse
import net.liftweb.http.LiftResponse
import net.liftweb.http.Req
Expand Down Expand Up @@ -127,13 +129,20 @@ class OpenScapApiImpl(
case Right(None) =>
logger.trace("No report found")
InMemoryResponse(
s"No OpenSCAP report found for node '${nodeId}''".getBytes(),
s"No OpenSCAP report found for node '${nodeId.value}'".getBytes(),
("Content-Type" -> "text/txt") :: Nil,
Nil,
404
)
case Left(err) =>
val errorMessage = s"Could not get the OpenSCAP report for node ${nodeId.value}: ${err.fullMsg}"
val errorMessage = {
val prefix = s"Could not get the OpenSCAP report for node ${nodeId.value}: "
prefix ++ (err match {
// we don't want to get a stack trace for file errors
case SystemError(msg, ex: IOException) => s"${msg}; cause was: ${ex.getMessage}"
case _ => err.fullMsg
})
}
logger.info(errorMessage) // this is info level, because it can be expected errors like "no report"
InMemoryResponse(errorMessage.getBytes(), Nil, Nil, 500)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,25 @@ class OpenScapReportReader(
*/
def getOpenScapReportFile(nodeId: NodeId)(implicit qc: QueryContext): IOResult[Option[(String, File)]] = {
for {
nodeInfo <- nodeFactRepo.get(nodeId).notOptional(s"Node with id ${nodeId.value} does not exist")
path = computePathFromNodeId(nodeInfo.id)
reportFile = File(path)
exists <- IOResult.attempt(reportFile.exists())
res <- if (!exists) {
None.succeed
} else {
OpenscapPoliciesLoggerPure.debug(s"OpenSCAP report for node '${nodeId.value}' exists at ${path}") *>
Some((nodeInfo.fqdn, reportFile)).succeed
}
nodeInfo <- nodeFactRepo.get(nodeId).notOptional(s"Node with id ${nodeId.value} does not exist")
path = computePathFromNodeId(nodeInfo.id)
reportFile = File(path)
exists <- IOResult.attempt(reportFile.exists())
isFile <- IOResult.attempt(reportFile.isRegularFile)
isReadable <- IOResult.attempt(reportFile.isReadable)
res <- if (!exists) {
None.succeed
} else if (!isFile || !isReadable) {
OpenscapPoliciesLoggerPure
.warn(s"OpenSCAP report for node '${nodeId.value}' is not a file or is not readable at ${path}")
.as(None)
} else {
OpenscapPoliciesLoggerPure
.debug(s"OpenSCAP report for node '${nodeId.value}' exists at ${path}")
.as(
Some((nodeInfo.fqdn, reportFile))
)
}
} yield res
}

Expand All @@ -143,7 +152,9 @@ class OpenScapReportReader(
*/
def getOpenScapReportContent(nodeId: NodeId, hostname: String, file: File): IOResult[OpenScapReport] = {
for {
content <- IOResult.attempt(s"Error when retrieving report content")(file.contentAsString(StandardCharsets.UTF_8))
content <- IOResult.attempt(s"Error when retrieving content of report file ${file.name}")(
file.contentAsString(StandardCharsets.UTF_8)
)
} yield OpenScapReport(nodeId, hostname, content)
}
}
Expand Down
9 changes: 9 additions & 0 deletions openscap/src/test/resources/openscap_api/api_openscap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,12 @@ response:
type: text
content: >-
Could not get the OpenSCAP report for node node_void123: Inconsistency: Node with id node_void123 does not exist
---
description: Get OpenSCAP report for a node with file reading issue
method: GET
url: /api/latest/openscap/report/root
response:
code: 404
type: text
content: >-
No OpenSCAP report found for node 'root'
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class OpenScapApiTest extends ZIOSpecDefault {
"""<script>bad js</script><a href="https://example.com">not a trap!</a><div onMouseover="bad things;">content</div>"""
)

val rootReportFile = openScapReportDir
.createChild("root/", asDirectory = true)
// create a directory instead of a file, attempting to read the content should throw an exception
.createChild(OpenScapReportReader.OPENSCAP_REPORT_FILENAME, asDirectory = true)

val mockNodes = new MockNodes()
val openScapReportReader = new OpenScapReportReader(
mockNodes.nodeFactRepo,
Expand Down

0 comments on commit 3e7ce6f

Please sign in to comment.