diff options
author | Jayanth Othayoth <ojayanth@in.ibm.com> | 2018-03-29 10:25:50 -0500 |
---|---|---|
committer | Jayanth Othayoth <ojayanth@in.ibm.com> | 2018-04-30 01:21:46 -0500 |
commit | 11271fb7d2740cf87d4c93ad483511c022aa2670 (patch) | |
tree | 43965deedc9ee67c0ad3cf1026d8e8f683d478f5 | |
parent | 207469f901a9cd3ea791e9a7bec4d8c697ac479c (diff) | |
download | openpower-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-x | activation.cpp | 108 | ||||
-rwxr-xr-x | activation.hpp | 38 |
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 |