summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayanth Othayoth <ojayanth@in.ibm.com>2018-03-29 10:25:50 -0500
committerJayanth Othayoth <ojayanth@in.ibm.com>2018-04-30 01:21:46 -0500
commit11271fb7d2740cf87d4c93ad483511c022aa2670 (patch)
tree43965deedc9ee67c0ad3cf1026d8e8f683d478f5
parent207469f901a9cd3ea791e9a7bec4d8c697ac479c (diff)
downloadopenpower-pnor-code-mgmt-11271fb7d2740cf87d4c93ad483511c022aa2670.tar.gz
openpower-pnor-code-mgmt-11271fb7d2740cf87d4c93ad483511c022aa2670.zip
PNOR Signature validation failure handling based on field mode
Added support to stop the codeupdate only for the fieldmode enabled systems, for signature validation failures. Resolves openbmc/openbmc#3047 Change-Id: Idf47b122a60d5d14e6e7f134d8067d20e09e7c76 Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
-rwxr-xr-xactivation.cpp108
-rwxr-xr-xactivation.hpp38
2 files changed, 134 insertions, 12 deletions
diff --git a/activation.cpp b/activation.cpp
index b7cdb51fa..87e5d2bd1 100755
--- a/activation.cpp
+++ b/activation.cpp
@@ -6,11 +6,11 @@
#include <phosphor-logging/log.hpp>
#ifdef WANT_SIGNATURE_VERIFY
+#include <sdbusplus/server.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include "image_verify.hpp"
-#include "config.h"
#endif
namespace openpower
@@ -28,6 +28,10 @@ using namespace phosphor::logging;
#ifdef WANT_SIGNATURE_VERIFY
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+// Field mode path and interface.
+constexpr auto FIELDMODE_PATH("/xyz/openbmc_project/software");
+constexpr auto FIELDMODE_INTERFACE("xyz.openbmc_project.Control.FieldMode");
#endif
constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
@@ -120,24 +124,17 @@ auto Activation::activation(Activations value) -> Activations
{
#ifdef WANT_SIGNATURE_VERIFY
- using Signature = openpower::software::image::Signature;
-
- fs::path imagePath(IMG_DIR);
-
- Signature signature(imagePath / versionId,
- PNOR_SIGNED_IMAGE_CONF_PATH);
-
// Validate the signed image.
- if (!signature.verify())
+ if (!validateSignature())
{
- log<level::ERR>("Error occurred during image validation");
- report<InternalFailure>();
+ // Cleanup
+ activationBlocksTransition.reset(nullptr);
+ activationProgress.reset(nullptr);
return softwareServer::Activation::activation(
softwareServer::Activation::Activations::Failed);
}
#endif
-
Activation::startActivation();
return softwareServer::Activation::activation(value);
}
@@ -276,6 +273,93 @@ void Activation::unitStateChange(sdbusplus::message::message& msg)
return;
}
+#ifdef WANT_SIGNATURE_VERIFY
+inline bool Activation::validateSignature()
+{
+ using Signature = openpower::software::image::Signature;
+ fs::path imageDir(IMG_DIR);
+
+ Signature signature(imageDir / versionId, PNOR_SIGNED_IMAGE_CONF_PATH);
+
+ // Validate the signed image.
+ if (signature.verify())
+ {
+ return true;
+ }
+ // Log error and continue activation process, if field mode disabled.
+ log<level::ERR>("Error occurred during image validation");
+ report<InternalFailure>();
+
+ try
+ {
+ if (!fieldModeEnabled())
+ {
+ return true;
+ }
+ }
+ catch (const InternalFailure& e)
+ {
+ report<InternalFailure>();
+ }
+ return false;
+}
+
+bool Activation::fieldModeEnabled()
+{
+ auto fieldModeSvc = getService(bus, FIELDMODE_PATH, FIELDMODE_INTERFACE);
+
+ auto method = bus.new_method_call(fieldModeSvc.c_str(), FIELDMODE_PATH,
+ "org.freedesktop.DBus.Properties", "Get");
+
+ method.append(FIELDMODE_INTERFACE, "FieldModeEnabled");
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Error in fieldModeEnabled getValue");
+ elog<InternalFailure>();
+ }
+ sdbusplus::message::variant<bool> fieldMode;
+ reply.read(fieldMode);
+
+ return (fieldMode.get<bool>());
+}
+
+std::string Activation::getService(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ const std::string& intf)
+{
+ auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
+ MAPPER_INTERFACE, "GetObject");
+
+ mapperCall.append(path);
+ mapperCall.append(std::vector<std::string>({intf}));
+
+ auto mapperResponseMsg = bus.call(mapperCall);
+
+ if (mapperResponseMsg.is_method_error())
+ {
+ log<level::ERR>("ERROR in getting service",
+ entry("PATH=%s", path.c_str()),
+ entry("INTERFACE=%s", intf.c_str()));
+
+ elog<InternalFailure>();
+ }
+
+ std::map<std::string, std::vector<std::string>> mapperResponse;
+ mapperResponseMsg.read(mapperResponse);
+
+ if (mapperResponse.begin() == mapperResponse.end())
+ {
+ log<level::ERR>("ERROR reading mapper response",
+ entry("PATH=%s", path.c_str()),
+ entry("INTERFACE=%s", intf.c_str()));
+
+ elog<InternalFailure>();
+ }
+ return mapperResponse.begin()->first;
+}
+#endif
+
} // namespace updater
} // namespace software
} // namespace openpower
diff --git a/activation.hpp b/activation.hpp
index 2edbca5c0..1a600cc0d 100755
--- a/activation.hpp
+++ b/activation.hpp
@@ -7,6 +7,7 @@
#include "xyz/openbmc_project/Software/RedundancyPriority/server.hpp"
#include "xyz/openbmc_project/Software/ActivationProgress/server.hpp"
#include "org/openbmc/Associations/server.hpp"
+#include "config.h"
namespace openpower
{
@@ -300,6 +301,43 @@ class Activation : public ActivationInherit
/** @brief Member function for clarity & brevity at activation end */
void finishActivation();
+
+#ifdef WANT_SIGNATURE_VERIFY
+ /**
+ * @brief Wrapper function for the signature verify function.
+ * Signature class verify function used for validating
+ * signed image. Also added additional logic to continue
+ * update process in lab environment by checking the
+ * fieldModeEnabled property.
+ *
+ * @return true if successful signature validation or field
+ * mode is disabled.
+ * false for unsuccessful signature validation or
+ * any internal failure during the mapper call.
+ */
+ inline bool validateSignature();
+
+ /**
+ * @brief Gets the fieldModeEnabled property value.
+ *
+ * @return fieldModeEnabled property value
+ * @error InternalFailure exception thrown
+ */
+ bool fieldModeEnabled();
+
+ /**
+ * @brief Gets the D-Bus Service name for the input D-Bus path
+ *
+ * @param[in] bus - Bus handler
+ * @param[in] path - Object Path
+ * @param[in] intf - Interface
+ *
+ * @return Service name
+ * @error InternalFailure exception thrown
+ */
+ std::string getService(sdbusplus::bus::bus& bus, const std::string& path,
+ const std::string& intf);
+#endif
};
} // namespace updater
OpenPOWER on IntegriCloud