From 033c33111a1572b2104916dc7e8ea32ea48067d0 Mon Sep 17 00:00:00 2001 From: Robert Wojciechowski Date: Thu, 13 Feb 2025 12:32:42 +0100 Subject: [PATCH] Format using clang-format --- .clang-format | 88 ++++ .pre-commit-config.yaml | 9 + src/modules/compliance/src/lib/Base64.cpp | 146 +++--- src/modules/compliance/src/lib/Base64.h | 5 +- .../src/lib/ComplianceInterface.cpp | 11 +- src/modules/compliance/src/lib/Engine.cpp | 479 +++++++++--------- src/modules/compliance/src/lib/Engine.h | 129 ++--- src/modules/compliance/src/lib/Evaluator.cpp | 30 +- src/modules/compliance/src/lib/Evaluator.h | 79 +-- .../compliance/src/lib/JsonWrapper.cpp | 16 +- src/modules/compliance/src/lib/JsonWrapper.h | 12 +- src/modules/compliance/src/lib/Optional.h | 182 +++---- src/modules/compliance/src/lib/Procedure.cpp | 143 +++--- src/modules/compliance/src/lib/Procedure.h | 53 +- .../compliance/src/lib/ProcedureMap.cpp | 10 +- src/modules/compliance/src/lib/Result.h | 371 +++++++------- src/modules/compliance/src/lib/TypeTraits.h | 20 +- src/modules/compliance/tests/Base64Test.cpp | 6 +- .../compliance/tests/ComplianceTest.cpp | 7 +- src/modules/compliance/tests/EngineTest.cpp | 7 +- .../compliance/tests/EvaluatorTest.cpp | 26 +- src/modules/compliance/tests/OptionalTest.cpp | 3 +- src/modules/compliance/tests/ResultTest.cpp | 5 +- 23 files changed, 996 insertions(+), 841 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..0a58c1319 --- /dev/null +++ b/.clang-format @@ -0,0 +1,88 @@ +--- +BasedOnStyle: Microsoft +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: BeforeColon +PackConstructorInitializers: Never +ColumnLimit: 152 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +IndentCaseLabels: true +IndentExternBlock: NoIndent +IndentWidth: 4 +IndentPPDirectives: AfterHash +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 100 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: CaseSensitive +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatementsExceptControlMacros +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseCRLF: false +UseTab: Never +IndentAccessModifiers: false +AccessModifierOffset: -4 +EmptyLineBeforeAccessModifier: Always +IncludeBlocks: Regroup diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8f735b6c..296937f96 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -41,3 +41,12 @@ repos: .*\.cmd| .*\.csrpoj )$ + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v14.0.6 + hooks: + - id: clang-format + files: | + (?x)( + ^src/modules/compliance/.*\.h$| + ^src/modules/compliance/.*\.cpp$ + ) diff --git a/src/modules/compliance/src/lib/Base64.cpp b/src/modules/compliance/src/lib/Base64.cpp index 9239f19c0..dd721fa5c 100644 --- a/src/modules/compliance/src/lib/Base64.cpp +++ b/src/modules/compliance/src/lib/Base64.cpp @@ -1,96 +1,98 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include -#include "Result.h" #include "Base64.h" +#include "Result.h" + +#include + namespace compliance { - static inline char Base64Char(const unsigned char c) +static inline char Base64Char(const unsigned char c) +{ + if (c >= 'A' && c <= 'Z') { - if (c >= 'A' && c <= 'Z') - { - return c - 'A'; - } - else if (c >= 'a' && c <= 'z') - { - return c - 'a' + 26; - } - else if (c >= '0' && c <= '9') - { - return c - '0' + 52; - } - else if (c == '+') - { - return 62; - } - else if (c == '/') - { - return 63; - } - else - { - return 0; - } + return c - 'A'; } - - static inline bool IsBase64(const unsigned char c) + else if (c >= 'a' && c <= 'z') + { + return c - 'a' + 26; + } + else if (c >= '0' && c <= '9') { - return (isalnum(c) || (c == '+') || (c == '/') || (c == '=')); + return c - '0' + 52; } + else if (c == '+') + { + return 62; + } + else if (c == '/') + { + return 63; + } + else + { + return 0; + } +} - Result Base64Decode(const std::string &input) +static inline bool IsBase64(const unsigned char c) +{ + return (isalnum(c) || (c == '+') || (c == '/') || (c == '=')); +} + +Result Base64Decode(const std::string& input) +{ + if (input.size() % 4 != 0) + { + return Error("Invalid base64 length", EINVAL); + } + for (const char c : input) { - if (input.size() % 4 != 0) + if (!IsBase64(c)) { - return Error("Invalid base64 length", EINVAL); - } - for (const char c : input) - { - if (!IsBase64(c)) - { - return Error("Invalid base64 character", EINVAL); - } + return Error("Invalid base64 character", EINVAL); } + } - std::string ret; - ret.reserve((input.size() * 3) / 4); + std::string ret; + ret.reserve((input.size() * 3) / 4); - for (size_t i = 0; i < input.size(); i += 4) - { - unsigned char enc[4]; + for (size_t i = 0; i < input.size(); i += 4) + { + unsigned char enc[4]; - int j = 0; - for (j = 0; j < 4; j++) + int j = 0; + for (j = 0; j < 4; j++) + { + if (input[i + j] == '=') { - if (input[i+j] == '=') - { - break; - } - enc[j] = Base64Char(input[i + j]); + break; } + enc[j] = Base64Char(input[i + j]); + } - if (j == 4) - { - ret += (enc[0] << 2) | (enc[1] >> 4); - ret += ((enc[1] & 0x0f) << 4) | (enc[2] >> 2); - ret += ((enc[2] & 0x03) << 6) | enc[3]; - } - else if (j == 3) - { - ret += (enc[0] << 2) | (enc[1] >> 4); - ret += ((enc[1] & 0x0f) << 4) | (enc[2] >> 2); - } - else if (j == 2) - { - ret += (enc[0] << 2) | (enc[1] >> 4); - } - else - { - return Error("Invalid base64", EINVAL); - } + if (j == 4) + { + ret += (enc[0] << 2) | (enc[1] >> 4); + ret += ((enc[1] & 0x0f) << 4) | (enc[2] >> 2); + ret += ((enc[2] & 0x03) << 6) | enc[3]; + } + else if (j == 3) + { + ret += (enc[0] << 2) | (enc[1] >> 4); + ret += ((enc[1] & 0x0f) << 4) | (enc[2] >> 2); + } + else if (j == 2) + { + ret += (enc[0] << 2) | (enc[1] >> 4); + } + else + { + return Error("Invalid base64", EINVAL); } - return ret; } + return ret; } +} // namespace compliance diff --git a/src/modules/compliance/src/lib/Base64.h b/src/modules/compliance/src/lib/Base64.h index 37ac04700..2d16ed526 100644 --- a/src/modules/compliance/src/lib/Base64.h +++ b/src/modules/compliance/src/lib/Base64.h @@ -1,12 +1,13 @@ #ifndef BASE64_H #define BASE64_H -#include #include "Result.h" +#include + namespace compliance { - Result Base64Decode(const std::string &input); +Result Base64Decode(const std::string& input); } #endif // BASE64_H diff --git a/src/modules/compliance/src/lib/ComplianceInterface.cpp b/src/modules/compliance/src/lib/ComplianceInterface.cpp index 0ff8d7fbd..a13e9f167 100644 --- a/src/modules/compliance/src/lib/ComplianceInterface.cpp +++ b/src/modules/compliance/src/lib/ComplianceInterface.cpp @@ -2,8 +2,16 @@ // Licensed under the MIT License. #include "ComplianceInterface.h" + #include "CommonUtils.h" #include "Engine.h" +#include "Logging.h" +#include "Mmi.h" + +#include +#include +#include +#include using compliance::Engine; @@ -126,7 +134,8 @@ int ComplianceMmiSet(MMI_HANDLE clientSession, const char* componentName, const return result.error().code; } - OsConfigLogInfo(engine.log(), "MmiSet(%p, %s, %s, %.*s, %d) returned %s", clientSession, componentName, objectName, payloadSizeBytes, payload, payloadSizeBytes, result.value() ? "true" : "false"); + OsConfigLogInfo(engine.log(), "MmiSet(%p, %s, %s, %.*s, %d) returned %s", clientSession, componentName, objectName, payloadSizeBytes, payload, + payloadSizeBytes, result.value() ? "true" : "false"); return MMI_OK; } catch (const std::exception& e) diff --git a/src/modules/compliance/src/lib/Engine.cpp b/src/modules/compliance/src/lib/Engine.cpp index 877c2dcf8..f7f35770b 100644 --- a/src/modules/compliance/src/lib/Engine.cpp +++ b/src/modules/compliance/src/lib/Engine.cpp @@ -3,323 +3,332 @@ #include "Engine.h" -#include -#include "Evaluator.h" #include "Base64.h" - -#include "parson.h" -#include -#include +#include "Evaluator.h" +#include "JsonWrapper.h" +#include "Logging.h" +#include "Optional.h" +#include "Procedure.h" +#include "Result.h" + +#include +#include #include -#include +#include +#include +#include +#include namespace compliance { - static constexpr const char* cLogFile = "/var/log/osconfig_compliance.log"; - static constexpr const char* cRolledLogFile = "/var/log/osconfig_compliance.bak"; - static constexpr const char* cModuleInfo = "{\"Name\": \"Compliance\"," - "\"Description\": \"Provides functionality to audit and remediate Security Baseline policies on device\"," - "\"Manufacturer\": \"Microsoft\"," - "\"VersionMajor\": 2," - "\"VersionMinor\": 0," - "\"VersionInfo\": \"Dilithium\"," - "\"Components\": [\"Compliance\"]," - "\"Lifetime\": 2," - "\"UserAccount\": 0}"; +static constexpr const char* cLogFile = "/var/log/osconfig_compliance.log"; +static constexpr const char* cRolledLogFile = "/var/log/osconfig_compliance.bak"; +static constexpr const char* cModuleInfo = "{\"Name\": \"Compliance\"," + "\"Description\": \"Provides functionality to audit and remediate Security Baseline policies on device\"," + "\"Manufacturer\": \"Microsoft\"," + "\"VersionMajor\": 2," + "\"VersionMinor\": 0," + "\"VersionInfo\": \"Dilithium\"," + "\"Components\": [\"Compliance\"]," + "\"Lifetime\": 2," + "\"UserAccount\": 0}"; + +Engine::Engine(void* log) noexcept + : mLog{log} +{ +} - Engine::Engine(void* log) noexcept : mLog{ log } - { - } +Engine::Engine() noexcept + : mLog{OpenLog(cLogFile, cRolledLogFile)}, + mLocalLog{true} +{ +} - Engine::Engine() noexcept : mLog{ OpenLog(cLogFile, cRolledLogFile) }, mLocalLog{ true } +Engine::~Engine() +{ + if (mLocalLog) { + CloseLog(&mLog); } +} + +void Engine::setMaxPayloadSize(unsigned int value) noexcept +{ + mMaxPayloadSize = value; +} + +unsigned int Engine::getMaxPayloadSize() const noexcept +{ + return mMaxPayloadSize; +} + +OSCONFIG_LOG_HANDLE Engine::log() const noexcept +{ + return mLog; +} + +const char* Engine::getModuleInfo() noexcept +{ + return cModuleInfo; +} - Engine::~Engine() +Result Engine::mmiGet(const char* objectName) +{ + if (nullptr == objectName) { - if(mLocalLog) - { - CloseLog(&mLog); - } + return Error("Invalid argument", EINVAL); } - void Engine::setMaxPayloadSize(unsigned int value) noexcept + OsConfigLogInfo(log(), "Engine::mmiGet(%s)", objectName); + auto result = AuditResult(); + auto ruleName = std::string(objectName); + constexpr const char* auditPrefix = "audit"; + if (ruleName.find(auditPrefix) != 0) { - mMaxPayloadSize = value; + return Error("Invalid object name", EINVAL); } - unsigned int Engine::getMaxPayloadSize() const noexcept + ruleName = ruleName.substr(strlen(auditPrefix)); + if (ruleName.empty()) { - return mMaxPayloadSize; + return Error("Rule name is empty", EINVAL); } - OSCONFIG_LOG_HANDLE Engine::log() const noexcept + auto it = mDatabase.find(ruleName); + if (it == mDatabase.end()) { - return mLog; + return Error("Rule not found", EINVAL); } - - const char* Engine::getModuleInfo() noexcept + const auto& procedure = it->second; + if (nullptr == procedure.audit()) { - return cModuleInfo; + return Error("Failed to get 'audit' object"); } - Result Engine::mmiGet(const char* objectName) + Evaluator evaluator(procedure.audit(), procedure.parameters(), log()); + auto rc = evaluator.ExecuteAudit(&result.payload, &result.payloadSize); + if (!rc.has_value()) { - if (nullptr == objectName) - { - return Error("Invalid argument", EINVAL); - } - - OsConfigLogInfo(log(), "Engine::mmiGet(%s)", objectName); - auto result = AuditResult(); - auto ruleName = std::string(objectName); - constexpr const char* auditPrefix = "audit"; - if (ruleName.find(auditPrefix) != 0) - { - return Error("Invalid object name", EINVAL); - } + return rc.error(); + } - ruleName = ruleName.substr(strlen(auditPrefix)); - if (ruleName.empty()) - { - return Error("Rule name is empty", EINVAL); - } + result.result = rc.value(); + return Result(std::move(result)); +} - auto it = mDatabase.find(ruleName); - if (it == mDatabase.end()) - { - return Error("Rule not found", EINVAL); - } - const auto& procedure = it->second; - if (nullptr == procedure.audit()) - { - return Error("Failed to get 'audit' object"); - } +Result Engine::decodeB64JSON(const char* input) const +{ + if (nullptr == input) + { + return Error("Input is null", EINVAL); + } + std::string inputStr(input); + if ((inputStr.length() > 2) && (inputStr[0] == '"') && (inputStr[inputStr.length() - 1] == '"')) + { + inputStr = inputStr.substr(1, inputStr.length() - 2); + } + auto decodedString = Base64Decode(inputStr); + if (!decodedString.has_value()) + { + return decodedString.error(); + } + auto result = json_parse_string(decodedString.value().c_str()); + if (nullptr == result) + { + return Error("Failed to parse JSON", EINVAL); + } - Evaluator evaluator(procedure.audit(), procedure.parameters(), log()); - auto rc = evaluator.ExecuteAudit(&result.payload, &result.payloadSize); - if (!rc.has_value()) - { - return rc.error(); - } + return JsonWrapper(result); +} - result.result = rc.value(); - return Result(std::move(result)); +Optional Engine::setProcedure(const std::string& ruleName, const char* payload, const int payloadSizeBytes) +{ + if (ruleName.empty()) + { + return Error("Rule name is empty", EINVAL); } - Result Engine::decodeB64JSON(const char* input) const + mDatabase.erase(ruleName); + auto ruleJSON = decodeB64JSON(std::string(payload, payloadSizeBytes).c_str()); + if (!ruleJSON.has_value()) { - if (nullptr == input) - { - return Error("Input is null", EINVAL); - } - std::string inputStr(input); - if ((inputStr.length() > 2) && (inputStr[0] == '"') && (inputStr[inputStr.length() - 1] == '"')) - { - inputStr = inputStr.substr(1, inputStr.length() - 2); - } - auto decodedString = Base64Decode(inputStr); - if (!decodedString.has_value()) - { - return decodedString.error(); - } - auto result = json_parse_string(decodedString.value().c_str()); - if (nullptr == result) - { - return Error("Failed to parse JSON", EINVAL); - } - - return JsonWrapper(result); + return ruleJSON.error(); } - Optional Engine::setProcedure(const std::string& ruleName, const char* payload, const int payloadSizeBytes) + auto object = json_value_get_object(ruleJSON.value().get()); + if (nullptr == object) { - if (ruleName.empty()) - { - return Error("Rule name is empty", EINVAL); - } + return Error("Failed to parse JSON object"); + } - mDatabase.erase(ruleName); - auto ruleJSON = decodeB64JSON(std::string(payload, payloadSizeBytes).c_str()); - if (!ruleJSON.has_value()) - { - return ruleJSON.error(); - } + auto jsonValue = json_object_get_value(object, "audit"); + if (nullptr == jsonValue) + { + return Error("Missing 'audit' object"); + } - auto object = json_value_get_object(ruleJSON.value().get()); - if (nullptr == object) - { - return Error("Failed to parse JSON object"); - } + if (json_value_get_type(jsonValue) != JSONObject) + { + return Error("The 'audit' value is not an object"); + } - auto jsonValue = json_object_get_value(object, "audit"); - if (nullptr == jsonValue) - { - return Error("Missing 'audit' object"); - } + auto procedure = Procedure{}; + auto error = procedure.setAudit(jsonValue); + if (error) + { + return error.value(); + } + if (nullptr == procedure.audit()) + { + OsConfigLogError(log(), "Failed to copy 'audit' object"); + return Error("Out of memory"); + } + jsonValue = json_object_get_value(object, "remediate"); + if (nullptr != jsonValue) + { if (json_value_get_type(jsonValue) != JSONObject) { - return Error("The 'audit' value is not an object"); + return Error("The 'remediate' value is not an object"); } - auto procedure = Procedure{}; - auto error = procedure.setAudit(jsonValue); + auto error = procedure.setRemediation(jsonValue); if (error) { return error.value(); } - if(nullptr == procedure.audit()) + if (nullptr == procedure.remediation()) { - OsConfigLogError(log(), "Failed to copy 'audit' object"); + OsConfigLogError(log(), "Failed to copy 'remediate' object"); return Error("Out of memory"); } + } - jsonValue = json_object_get_value(object, "remediate"); - if (nullptr != jsonValue) + jsonValue = json_object_get_value(object, "parameters"); + if (nullptr != jsonValue) + { + if (json_value_get_type(jsonValue) != JSONObject) { - if (json_value_get_type(jsonValue) != JSONObject) - { - return Error("The 'remediate' value is not an object"); - } - - auto error = procedure.setRemediation(jsonValue); - if (error) - { - return error.value(); - } - if (nullptr == procedure.remediation()) - { - OsConfigLogError(log(), "Failed to copy 'remediate' object"); - return Error("Out of memory"); - } + return Error("The 'parameters' value is not an object"); } - jsonValue = json_object_get_value(object, "parameters"); - if (nullptr != jsonValue) + auto paramsObj = json_value_get_object(jsonValue); + auto count = json_object_get_count(paramsObj); + for (decltype(count) i = 0; i < count; ++i) { - if (json_value_get_type(jsonValue) != JSONObject) + const char* key = json_object_get_name(paramsObj, i); + const char* val = json_object_get_string(paramsObj, key); + if ((nullptr == key) || (nullptr == val)) { - return Error("The 'parameters' value is not an object"); + OsConfigLogError(log(), "Failed to get parameter name and value"); + return Error("Failed to get parameter name and value"); } - auto paramsObj = json_value_get_object(jsonValue); - auto count = json_object_get_count(paramsObj); - for (decltype(count) i = 0; i < count; ++i) - { - const char* key = json_object_get_name(paramsObj, i); - const char* val = json_object_get_string(paramsObj, key); - if ((nullptr == key) || (nullptr == val)) - { - OsConfigLogError(log(), "Failed to get parameter name and value"); - return Error("Failed to get parameter name and value"); - } - - procedure.setParameter(key, val); - } + procedure.setParameter(key, val); } - mDatabase.emplace(std::move(ruleName), std::move(procedure)); - return Optional(); } + mDatabase.emplace(std::move(ruleName), std::move(procedure)); + return Optional(); +} - Optional Engine::initAudit(const std::string& ruleName, const char* payload, const int payloadSizeBytes) +Optional Engine::initAudit(const std::string& ruleName, const char* payload, const int payloadSizeBytes) +{ + if (ruleName.empty()) { - if (ruleName.empty()) - { - return Error("Rule name is empty", EINVAL); - } + return Error("Rule name is empty", EINVAL); + } - auto it = mDatabase.find(ruleName); - if (it == mDatabase.end()) - { - return Error("Out-of-order operation: procedure must be set first", EINVAL); - } + auto it = mDatabase.find(ruleName); + if (it == mDatabase.end()) + { + return Error("Out-of-order operation: procedure must be set first", EINVAL); + } - auto error = it->second.updateUserParameters(std::string(payload, payloadSizeBytes)); - if (error) - { - return error.value(); - } + auto error = it->second.updateUserParameters(std::string(payload, payloadSizeBytes)); + if (error) + { + return error.value(); + } - return Optional(); + return Optional(); +} + +Result Engine::executeRemediation(const std::string& ruleName, const char* payload, const int payloadSizeBytes) +{ + if (ruleName.empty()) + { + return Error("Rule name is empty", EINVAL); } - Result Engine::executeRemediation(const std::string& ruleName, const char* payload, const int payloadSizeBytes) + auto it = mDatabase.find(ruleName); + if (it == mDatabase.end()) { - if (ruleName.empty()) - { - return Error("Rule name is empty", EINVAL); - } + return Error("Out-of-order operation: procedure must be set first", EINVAL); + } + auto& procedure = it->second; + if (nullptr == procedure.remediation()) + { + return Error("Failed to get 'remediate' object"); + } - auto it = mDatabase.find(ruleName); - if (it == mDatabase.end()) - { - return Error("Out-of-order operation: procedure must be set first", EINVAL); - } - auto& procedure = it->second; - if (nullptr == procedure.remediation()) - { - return Error("Failed to get 'remediate' object"); - } + auto error = procedure.updateUserParameters(std::string(payload, payloadSizeBytes)); + if (error) + { + return error.value(); + } - auto error = procedure.updateUserParameters(std::string(payload, payloadSizeBytes)); - if (error) - { - return error.value(); - } + Evaluator evaluator(procedure.remediation(), procedure.parameters(), log()); + return evaluator.ExecuteRemediation(); +} - Evaluator evaluator(procedure.remediation(), procedure.parameters(), log()); - return evaluator.ExecuteRemediation(); +Result Engine::mmiSet(const char* objectName, const char* payload, const int payloadSizeBytes) +{ + if (nullptr == objectName) + { + OsConfigLogError(log(), "Object name is null"); + return Error("Invalid argument", EINVAL); } - Result Engine::mmiSet(const char* objectName, const char* payload, const int payloadSizeBytes) + if ((nullptr == payload) || (payloadSizeBytes < 0)) { - if (nullptr == objectName) - { - OsConfigLogError(log(), "Object name is null"); - return Error("Invalid argument", EINVAL); - } + OsConfigLogError(log(), "Invalid argument: payload is null or payloadSizeBytes is <= 0"); + return Error("Invalid argument", EINVAL); + } - if ((nullptr == payload) || (payloadSizeBytes < 0)) + OsConfigLogInfo(log(), "Engine::mmiSet(%s, %.*s)", objectName, payloadSizeBytes, payload); + constexpr const char* remediatePrefix = "remediate"; + constexpr const char* initPrefix = "init"; + constexpr const char* procedurePrefix = "procedure"; + auto ruleName = std::string(objectName); + if (ruleName.find(procedurePrefix) == 0) + { + auto error = setProcedure(ruleName.substr(strlen(procedurePrefix)), payload, payloadSizeBytes); + if (error) { - OsConfigLogError(log(), "Invalid argument: payload is null or payloadSizeBytes is <= 0"); - return Error("Invalid argument", EINVAL); + return error.value(); } - OsConfigLogInfo(log(), "Engine::mmiSet(%s, %.*s)", objectName, payloadSizeBytes, payload); - constexpr const char* remediatePrefix = "remediate"; - constexpr const char* initPrefix = "init"; - constexpr const char* procedurePrefix = "procedure"; - auto ruleName = std::string(objectName); - if (ruleName.find(procedurePrefix) == 0) - { - auto error = setProcedure(ruleName.substr(strlen(procedurePrefix)), payload, payloadSizeBytes); - if (error) - { - return error.value(); - } - - return true; - } + return true; + } - if (ruleName.find(initPrefix) == 0) + if (ruleName.find(initPrefix) == 0) + { + auto error = initAudit(ruleName.substr(strlen(initPrefix)), payload, payloadSizeBytes); + if (error) { - auto error = initAudit(ruleName.substr(strlen(initPrefix)), payload, payloadSizeBytes); - if(error) - { - OsConfigLogInfo(log(), "Failed to init audit: %s", error->message.c_str()); - return error.value(); - } - - return true; + OsConfigLogInfo(log(), "Failed to init audit: %s", error->message.c_str()); + return error.value(); } - if (ruleName.find(remediatePrefix) == 0) - { - return executeRemediation(ruleName.substr(strlen(remediatePrefix)), payload, payloadSizeBytes); - } + return true; + } - OsConfigLogError(log(), "Invalid object name: Must start with %s, %s or %s prefix", initPrefix, procedurePrefix, remediatePrefix); - return Error("Invalid object name"); + if (ruleName.find(remediatePrefix) == 0) + { + return executeRemediation(ruleName.substr(strlen(remediatePrefix)), payload, payloadSizeBytes); } + + OsConfigLogError(log(), "Invalid object name: Must start with %s, %s or %s prefix", initPrefix, procedurePrefix, remediatePrefix); + return Error("Invalid object name"); } +} // namespace compliance diff --git a/src/modules/compliance/src/lib/Engine.h b/src/modules/compliance/src/lib/Engine.h index 8885e5ea0..7058b71c1 100644 --- a/src/modules/compliance/src/lib/Engine.h +++ b/src/modules/compliance/src/lib/Engine.h @@ -4,88 +4,89 @@ #ifndef COMPLIANCE_ENGINE_H #define COMPLIANCE_ENGINE_H -#include +#include "JsonWrapper.h" #include "Logging.h" - -#include "Result.h" +#include "Mmi.h" #include "Optional.h" #include "Procedure.h" -#include "JsonWrapper.h" +#include "Result.h" +#include #include #include -#include struct json_object_t; namespace compliance { - class Engine +class Engine +{ +public: + struct AuditResult { - public: - struct AuditResult - { - bool result = false; - char* payload = nullptr; - int payloadSize = 0; + bool result = false; + char* payload = nullptr; + int payloadSize = 0; - AuditResult() = default; - ~AuditResult() - { - free(payload); - } + AuditResult() = default; + ~AuditResult() + { + free(payload); + } - AuditResult(const AuditResult&) = delete; - AuditResult(AuditResult&& other) noexcept - { - result = other.result; - payload = other.payload; - payloadSize = other.payloadSize; - other.payload = nullptr; - } + AuditResult(const AuditResult&) = delete; + AuditResult(AuditResult&& other) noexcept + { + result = other.result; + payload = other.payload; + payloadSize = other.payloadSize; + other.payload = nullptr; + } - AuditResult& operator=(const AuditResult&) = delete; - AuditResult& operator=(AuditResult&& other) noexcept + AuditResult& operator=(const AuditResult&) = delete; + AuditResult& operator=(AuditResult&& other) noexcept + { + if (this == &other) { - if (this == &other) - { - return *this; - } - - result = other.result; - free(payload); - payload = other.payload; - payloadSize = other.payloadSize; - other.payload = nullptr; return *this; } - }; - private: - OSCONFIG_LOG_HANDLE mLog = nullptr; - bool mLocalLog = false; - unsigned int mMaxPayloadSize = 0; - std::map mDatabase; - - Result decodeB64JSON(const char* input) const; - Optional setProcedure(const std::string& ruleName, const char* payload, const int payloadSizeBytes); - Optional initAudit(const std::string& ruleName, const char* payload, const int payloadSizeBytes); - Result executeRemediation(const std::string& ruleName, const char* payload, const int payloadSizeBytes); - public: - // Create engine with external log file - Engine(void* log) noexcept; - // Create engine with locally initialized log file - Engine() noexcept; - ~Engine(); - - void setMaxPayloadSize(unsigned int value) noexcept; - unsigned int getMaxPayloadSize() const noexcept; - OSCONFIG_LOG_HANDLE log() const noexcept; - - static const char* getModuleInfo() noexcept; - - Result mmiGet(const char* objectName); - Result mmiSet(const char* objectName, const char* payload, const int payloadSizeBytes); + + result = other.result; + free(payload); + payload = other.payload; + payloadSize = other.payloadSize; + other.payload = nullptr; + return *this; + } }; -} + +private: + OSCONFIG_LOG_HANDLE mLog = nullptr; + bool mLocalLog = false; + unsigned int mMaxPayloadSize = 0; + std::map mDatabase; + + Result decodeB64JSON(const char* input) const; + Optional setProcedure(const std::string& ruleName, const char* payload, const int payloadSizeBytes); + Optional initAudit(const std::string& ruleName, const char* payload, const int payloadSizeBytes); + Result executeRemediation(const std::string& ruleName, const char* payload, const int payloadSizeBytes); + +public: + // Create engine with external log file + Engine(void* log) noexcept; + // Create engine with locally initialized log file + Engine() noexcept; + ~Engine(); + + void setMaxPayloadSize(unsigned int value) noexcept; + unsigned int getMaxPayloadSize() const noexcept; + OSCONFIG_LOG_HANDLE log() const noexcept; + + static const char* getModuleInfo() noexcept; + + Result mmiGet(const char* objectName); + Result mmiSet(const char* objectName, const char* payload, const int payloadSizeBytes); +}; +} // namespace compliance #endif // COMPLIANCE_ENGINE_H diff --git a/src/modules/compliance/src/lib/Evaluator.cpp b/src/modules/compliance/src/lib/Evaluator.cpp index 13dce1006..14765a49b 100644 --- a/src/modules/compliance/src/lib/Evaluator.cpp +++ b/src/modules/compliance/src/lib/Evaluator.cpp @@ -1,18 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include -#include -#include -#include -#include -#include #include "Evaluator.h" + +#include "Logging.h" #include "Result.h" -#define lenof(str) (sizeof(str)-1) +#include +#include +#include +#include +#include +#include -namespace compliance { +namespace compliance +{ Result Evaluator::ExecuteAudit(char** payload, int* payloadSizeBytes) { @@ -29,7 +31,7 @@ Result Evaluator::ExecuteAudit(char** payload, int* payloadSizeBytes) return result.error(); } - std::string vlog = mLogstream.str().substr(0, cLogstreamMaxSize - (1 + lenof("PASS") + lenof("\"\""))); + std::string vlog = mLogstream.str().substr(0, cLogstreamMaxSize - (1 + strlen("PASS") + strlen("\"\""))); if (result.value() == true) { vlog = "\"PASS" + vlog + "\""; @@ -84,12 +86,12 @@ Result Evaluator::EvaluateProcedure(const JSON_Object* json, const Action OsConfigLogError(mLog, "anyOf value is not an array"); return Error("anyOf value is not an array"); } - JSON_Array *array = json_value_get_array(value); + JSON_Array* array = json_value_get_array(value); size_t count = json_array_get_count(array); mLogstream << "{ anyOf: ["; for (size_t i = 0; i < count; ++i) { - JSON_Object *subObject = json_array_get_object(array, i); + JSON_Object* subObject = json_array_get_object(array, i); auto result = EvaluateProcedure(subObject, action); if (!result.has_value()) { @@ -187,8 +189,8 @@ Result Evaluator::EvaluateProcedure(const JSON_Object* json, const Action size_t count = json_object_get_count(args_object); for (size_t i = 0; i < count; ++i) { - const char *key = json_object_get_name(args_object, i); - JSON_Value *val = json_object_get_value_at(args_object, i); + const char* key = json_object_get_name(args_object, i); + JSON_Value* val = json_object_get_value_at(args_object, i); if (json_value_get_type(val) != JSONString) { mLogstream << "ERROR: Argument type is not a string"; @@ -256,4 +258,4 @@ Result Evaluator::EvaluateProcedure(const JSON_Object* json, const Action return Error("Unreachable"); // unreachable } -} +} // namespace compliance diff --git a/src/modules/compliance/src/lib/Evaluator.h b/src/modules/compliance/src/lib/Evaluator.h index 06039375b..eae04441d 100644 --- a/src/modules/compliance/src/lib/Evaluator.h +++ b/src/modules/compliance/src/lib/Evaluator.h @@ -4,53 +4,58 @@ #ifndef COMPLIANCE_EVALUATOR_H #define COMPLIANCE_EVALUATOR_H +#include "Logging.h" +#include "Result.h" + #include -#include #include -#include "Result.h" -#include "Logging.h" +#include struct json_object_t; -#define AUDIT_FN(fn_name) \ - ::compliance::Result Audit_##fn_name(std::map args, std::ostringstream &logstream) +#define AUDIT_FN(fn_name) ::compliance::Result Audit_##fn_name(std::map args, std::ostringstream& logstream) -#define REMEDIATE_FN(fn_name) \ - ::compliance::Result Remediate_##fn_name(std::map args, std::ostringstream &logstream) +#define REMEDIATE_FN(fn_name) ::compliance::Result Remediate_##fn_name(std::map args, std::ostringstream& logstream) namespace compliance { - using ParameterMap = std::map; - using action_func_t = Result(*)(ParameterMap, std::ostringstream&); - using ProcedureMap = std::map>; - class Evaluator +using ParameterMap = std::map; +using action_func_t = Result (*)(ParameterMap, std::ostringstream&); +using ProcedureMap = std::map>; +class Evaluator +{ +public: + Evaluator(const struct json_object_t* json, const ParameterMap& parameters, OSCONFIG_LOG_HANDLE log) + : mJson(json), + mParameters(parameters), + mLog(log) + { + } + Evaluator(const Evaluator&) = delete; + Evaluator(Evaluator&&) = delete; + Evaluator& operator=(const Evaluator&) = delete; + Evaluator& operator=(Evaluator&&) = delete; + + Result ExecuteAudit(char** payload, int* payloadSizeBytes); + Result ExecuteRemediation(); + + void setProcedureMap(ProcedureMap procedureMap); + +private: + enum class Action { - public: - Evaluator(const struct json_object_t* json, const ParameterMap& parameters, OSCONFIG_LOG_HANDLE log) : mJson(json), mParameters(parameters), mLog(log) {} - Evaluator(const Evaluator&) = delete; - Evaluator(Evaluator&&) = delete; - Evaluator& operator=(const Evaluator&) = delete; - Evaluator& operator=(Evaluator&&) = delete; - - Result ExecuteAudit(char** payload, int* payloadSizeBytes); - Result ExecuteRemediation(); - - void setProcedureMap(ProcedureMap procedureMap); - private: - enum class Action - { - Audit, - Remediate - }; - Result EvaluateProcedure(const struct json_object_t *json, const Action action); - const struct json_object_t *mJson; - const ParameterMap &mParameters; - std::ostringstream mLogstream; - void *mLog; - // autogenerated, instantiated in ProcedureMap.cpp - static ProcedureMap mProcedureMap; - static const size_t cLogstreamMaxSize = 4096; + Audit, + Remediate }; -} + Result EvaluateProcedure(const struct json_object_t* json, const Action action); + const struct json_object_t* mJson; + const ParameterMap& mParameters; + std::ostringstream mLogstream; + void* mLog; + // autogenerated, instantiated in ProcedureMap.cpp + static ProcedureMap mProcedureMap; + static const size_t cLogstreamMaxSize = 4096; +}; +} // namespace compliance #endif // COMPLIANCE_EVALUATOR_H diff --git a/src/modules/compliance/src/lib/JsonWrapper.cpp b/src/modules/compliance/src/lib/JsonWrapper.cpp index e9e74814d..c7a5da700 100644 --- a/src/modules/compliance/src/lib/JsonWrapper.cpp +++ b/src/modules/compliance/src/lib/JsonWrapper.cpp @@ -7,13 +7,13 @@ namespace compliance { - void JsonWrapperDeleter::operator()(json_value_t* value) const - { - json_value_free(value); - } +void JsonWrapperDeleter::operator()(json_value_t* value) const +{ + json_value_free(value); +} - JsonWrapper parseJSON(const char* input) - { - return JsonWrapper(json_parse_string(input), JsonWrapperDeleter()); - } +JsonWrapper parseJSON(const char* input) +{ + return JsonWrapper(json_parse_string(input), JsonWrapperDeleter()); +} } // namespace compliance diff --git a/src/modules/compliance/src/lib/JsonWrapper.h b/src/modules/compliance/src/lib/JsonWrapper.h index 83ee5325c..1b3d8a986 100644 --- a/src/modules/compliance/src/lib/JsonWrapper.h +++ b/src/modules/compliance/src/lib/JsonWrapper.h @@ -10,13 +10,13 @@ struct json_value_t; namespace compliance { - struct JsonWrapperDeleter - { - void operator()(json_value_t* value) const; - }; - using JsonWrapper = std::unique_ptr; +struct JsonWrapperDeleter +{ + void operator()(json_value_t* value) const; +}; +using JsonWrapper = std::unique_ptr; - JsonWrapper parseJSON(const char* input); +JsonWrapper parseJSON(const char* input); } // namespace compliance #endif // COMPLIANCE_JSON_H diff --git a/src/modules/compliance/src/lib/Optional.h b/src/modules/compliance/src/lib/Optional.h index af2649043..30bd6c02d 100644 --- a/src/modules/compliance/src/lib/Optional.h +++ b/src/modules/compliance/src/lib/Optional.h @@ -5,131 +5,133 @@ #define COMPLIANCE_OPTIONAL_H #include "TypeTraits.h" + #include namespace compliance { - template - class Optional +template +class Optional +{ + std::unique_ptr mValue; + +public: + Optional() = default; + Optional(T value) { - std::unique_ptr mValue; - public: - Optional() = default; - Optional(T value) - { - mValue.reset(new T(std::move(value))); - } + mValue.reset(new T(std::move(value))); + } - Optional(const Optional& other) + Optional(const Optional& other) + { + if (other.mValue != nullptr) { - if (other.mValue != nullptr) - { - mValue.reset(new T(*other.mValue)); - } - else - { - mValue.reset(); - } + mValue.reset(new T(*other.mValue)); } - - Optional(Optional&& other) noexcept + else { - mValue = std::move(other.mValue); + mValue.reset(); } + } - Optional& operator=(const Optional& other) - { - if (this == &other) - { - return *this; - } - - if (other.mValue != nullptr) - { - mValue.reset(new T(*other.mValue)); - } - else - { - mValue.reset(); - } - - return *this; - } + Optional(Optional&& other) noexcept + { + mValue = std::move(other.mValue); + } - Optional& operator=(T value) + Optional& operator=(const Optional& other) + { + if (this == &other) { - if( mValue != nullptr ) - { - *mValue = std::move(value); - } - else - { - mValue.reset(new T(std::move(value))); - } return *this; } - Optional& operator=(Optional&& other) noexcept + if (other.mValue != nullptr) { - if (this == &other) - { - return *this; - } - - mValue = std::move(other.mValue); - return *this; + mValue.reset(new T(*other.mValue)); } - - bool has_value() const + else { - return mValue != nullptr; + mValue.reset(); } - T value_or(T default_value) const noexcept(noexcept_copyable()) - { - if (mValue == nullptr) - { - return default_value; - } - - return *mValue; - } + return *this; + } - const T& value() const& + Optional& operator=(T value) + { + if (mValue != nullptr) { - return *mValue; + *mValue = std::move(value); } - - T value() && noexcept(noexcept_movable()) + else { - return std::move(*mValue); + mValue.reset(new T(std::move(value))); } + return *this; + } - T& value() & + Optional& operator=(Optional&& other) noexcept + { + if (this == &other) { - return *mValue; + return *this; } - const T* operator->() const& - { - return mValue.get(); - } + mValue = std::move(other.mValue); + return *this; + } - T* operator->() & - { - return mValue.get(); - } + bool has_value() const + { + return mValue != nullptr; + } - operator bool() const noexcept + T value_or(T default_value) const noexcept(noexcept_copyable()) + { + if (mValue == nullptr) { - return has_value(); + return default_value; } - void reset() - { - mValue.reset(); - } - }; + return *mValue; + } + + const T& value() const& + { + return *mValue; + } + + T value() && noexcept(noexcept_movable()) + { + return std::move(*mValue); + } + + T& value() & + { + return *mValue; + } + + const T* operator->() const& + { + return mValue.get(); + } + + T* operator->() & + { + return mValue.get(); + } + + operator bool() const noexcept + { + return has_value(); + } + + void reset() + { + mValue.reset(); + } +}; } // namespace compliance #endif // COMPLIANCE_OPTIONAL_H diff --git a/src/modules/compliance/src/lib/Procedure.cpp b/src/modules/compliance/src/lib/Procedure.cpp index ba5fbc90e..0afda8e06 100644 --- a/src/modules/compliance/src/lib/Procedure.cpp +++ b/src/modules/compliance/src/lib/Procedure.cpp @@ -2,6 +2,7 @@ // Licensed under the MIT License. #include "Procedure.h" + #include "Logging.h" #include @@ -9,102 +10,104 @@ namespace compliance { - void Procedure::setParameter(const std::string& key, std::string value) - { - mParameters[key] = std::move(value); - } +void Procedure::setParameter(const std::string& key, std::string value) +{ + mParameters[key] = std::move(value); +} - Optional Procedure::updateUserParameters(const std::string &input) - { - std::istringstream stream(input); - std::string token; +Optional Procedure::updateUserParameters(const std::string& input) +{ + std::istringstream stream(input); + std::string token; - while (std::getline(stream, token, ' ')) + while (std::getline(stream, token, ' ')) + { + // In the non-NRP scenario the token is delimited by double quotes + if (token.size() >= 2 && token.front() == '"' && token.back() == '"') { - // In the non-NRP scenario the token is delimited by double quotes - if (token.size() >= 2 && token.front() == '"' && token.back() == '"') - { - token = token.substr(1, token.size() - 2); - } + token = token.substr(1, token.size() - 2); + } - size_t pos = token.find('='); - if (pos == std::string::npos) - { - continue; - } + size_t pos = token.find('='); + if (pos == std::string::npos) + { + continue; + } - std::string key = token.substr(0, pos); - std::string value = token.substr(pos + 1); + std::string key = token.substr(0, pos); + std::string value = token.substr(pos + 1); - if (!value.empty() && value[0] == '"') + if (!value.empty() && value[0] == '"') + { + value.erase(0, 1); + while (!value.empty() && value.back() == '\\') { - value.erase(0, 1); - while (!value.empty() && value.back() == '\\') + std::string nextToken; + if (std::getline(stream, nextToken, ' ')) { - std::string nextToken; - if (std::getline(stream, nextToken, ' ')) - { - value.pop_back(); - value += ' ' + nextToken; - } - else - { - break; - } + value.pop_back(); + value += ' ' + nextToken; } - if (!value.empty() && value.back() == '"') + else { - value.pop_back(); + break; } } - - auto it = mParameters.find(key); - if (it == mParameters.end()) + if (!value.empty() && value.back() == '"') { - return Error(std::string("User parameter '") + key + std::string("' not found")); + value.pop_back(); } - - it->second = value; } - return Optional(); - } - - Optional Procedure::setAudit(const json_value_t* rule) - { - if(mAuditRule != nullptr) + auto it = mParameters.find(key); + if (it == mParameters.end()) { - return Error("Audit rule already set"); + return Error(std::string("User parameter '") + key + std::string("' not found")); } - mAuditRule.reset(json_value_deep_copy(rule)); - return Optional(); + it->second = value; } - const JSON_Object* Procedure::audit() const noexcept { - if( mAuditRule == nullptr ) - { - return nullptr; - } - return json_value_get_object(mAuditRule.get()); + return Optional(); +} + +Optional Procedure::setAudit(const json_value_t* rule) +{ + if (mAuditRule != nullptr) + { + return Error("Audit rule already set"); } - Optional Procedure::setRemediation(const json_value_t* rule) + mAuditRule.reset(json_value_deep_copy(rule)); + return Optional(); +} + +const JSON_Object* Procedure::audit() const noexcept +{ + if (mAuditRule == nullptr) { - if (mRemediationRule != nullptr) - { - return Error("Remediation rule already set"); - } + return nullptr; + } + return json_value_get_object(mAuditRule.get()); +} - mRemediationRule.reset(json_value_deep_copy(rule)); - return Optional(); +Optional Procedure::setRemediation(const json_value_t* rule) +{ + if (mRemediationRule != nullptr) + { + return Error("Remediation rule already set"); } - const JSON_Object* Procedure::remediation() const noexcept { - if (mRemediationRule == nullptr) - { - return nullptr; - } - return json_value_get_object(mRemediationRule.get()); + mRemediationRule.reset(json_value_deep_copy(rule)); + return Optional(); +} + +const JSON_Object* Procedure::remediation() const noexcept +{ + if (mRemediationRule == nullptr) + { + return nullptr; } + return json_value_get_object(mRemediationRule.get()); +} } // namespace compliance diff --git a/src/modules/compliance/src/lib/Procedure.h b/src/modules/compliance/src/lib/Procedure.h index d5948d1b7..352378450 100644 --- a/src/modules/compliance/src/lib/Procedure.h +++ b/src/modules/compliance/src/lib/Procedure.h @@ -4,9 +4,9 @@ #ifndef PROCEDURE_HPP #define PROCEDURE_HPP -#include "Result.h" -#include "Optional.h" #include "JsonWrapper.h" +#include "Optional.h" +#include "Result.h" #include #include @@ -16,30 +16,33 @@ struct json_object_t; namespace compliance { - class Procedure +class Procedure +{ + std::map mParameters; + JsonWrapper mAuditRule; + JsonWrapper mRemediationRule; + +public: + Procedure() = default; + ~Procedure() = default; + + Procedure(const Procedure&) = delete; + Procedure& operator=(const Procedure&) = delete; + Procedure(Procedure&&) = default; + Procedure& operator=(Procedure&&) = default; + + const std::map& parameters() const noexcept { - std::map mParameters; - JsonWrapper mAuditRule; - JsonWrapper mRemediationRule; - - public: - Procedure() = default; - ~Procedure() = default; - - Procedure(const Procedure&) = delete; - Procedure& operator=(const Procedure&) = delete; - Procedure(Procedure&&) = default; - Procedure& operator=(Procedure&&) = default; - - const std::map& parameters() const noexcept { return mParameters; } - const json_object_t* audit() const noexcept; - const json_object_t* remediation() const noexcept; - - void setParameter(const std::string& key, std::string value); - Optional updateUserParameters(const std::string &userParameters); - Optional setAudit(const json_value_t *rule); - Optional setRemediation(const json_value_t* rule); - }; + return mParameters; + } + const json_object_t* audit() const noexcept; + const json_object_t* remediation() const noexcept; + + void setParameter(const std::string& key, std::string value); + Optional updateUserParameters(const std::string& userParameters); + Optional setAudit(const json_value_t* rule); + Optional setRemediation(const json_value_t* rule); +}; } // namespace compliance #endif // PROCEDURE_HPP diff --git a/src/modules/compliance/src/lib/ProcedureMap.cpp b/src/modules/compliance/src/lib/ProcedureMap.cpp index 7c524e3c9..e8b1e05f6 100644 --- a/src/modules/compliance/src/lib/ProcedureMap.cpp +++ b/src/modules/compliance/src/lib/ProcedureMap.cpp @@ -1,11 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include -#include -#include +#include "Evaluator.h" -namespace compliance { - ProcedureMap Evaluator::mProcedureMap = { - }; +namespace compliance +{ +ProcedureMap Evaluator::mProcedureMap = {}; } diff --git a/src/modules/compliance/src/lib/Result.h b/src/modules/compliance/src/lib/Result.h index f6060ceda..5cfe3e8ce 100644 --- a/src/modules/compliance/src/lib/Result.h +++ b/src/modules/compliance/src/lib/Result.h @@ -5,245 +5,266 @@ #define COMPLIANCE_RESULT_H #include "TypeTraits.h" + #include namespace compliance { - struct Error - { - int code = -1; - std::string message; +struct Error +{ + int code = -1; + std::string message; - Error(std::string message, int code) : code(code), message(std::move(message)) {} - Error(std::string message) : message(std::move(message)) {} - Error(const Error& other) : code(other.code), message(other.message) {} - Error(Error&& other) noexcept : code(other.code), message(std::move(other.message)) {} - Error& operator=(const Error& other) + Error(std::string message, int code) + : code(code), + message(std::move(message)) + { + } + Error(std::string message) + : message(std::move(message)) + { + } + Error(const Error& other) + : code(other.code), + message(other.message) + { + } + Error(Error&& other) noexcept + : code(other.code), + message(std::move(other.message)) + { + } + Error& operator=(const Error& other) + { + if (this == &other) { - if (this == &other) - { - return *this; - } - - code = other.code; - message = other.message; return *this; } - Error& operator=(Error&& other) noexcept - { - if (this == &other) - { - return *this; - } + code = other.code; + message = other.message; + return *this; + } - code = other.code; - message = std::move(other.message); + Error& operator=(Error&& other) noexcept + { + if (this == &other) + { return *this; } - ~Error() = default; + + code = other.code; + message = std::move(other.message); + return *this; + } + ~Error() = default; +}; + +template +class Result +{ + union Pointer + { + T* value; + Error* error; }; - template - class Result + enum class Tag { - union Pointer - { - T* value; - Error* error; - }; + Value, + Error + }; - enum class Tag - { - Value, - Error - }; + Tag mTag; + Pointer mPointer; + +public: + Result(T value) + : mTag(Tag::Value) + { + mPointer.value = new T(std::move(value)); + } + + Result(Error error) + : mTag(Tag::Error) + { + mPointer.error = new Error(std::move(error)); + } - Tag mTag; - Pointer mPointer; - public: - Result(T value) : mTag(Tag::Value) + Result(const Result& other) + : mTag(other.mTag) + { + if (mTag == Tag::Value) { - mPointer.value = new T(std::move(value)); + mPointer.value = new T(*other.mPointer.value); } - - Result(Error error) : mTag(Tag::Error) + else { - mPointer.error = new Error(std::move(error)); + mPointer.error = new Error(*other.mPointer.error); } + } - Result(const Result& other) : mTag(other.mTag) + Result(Result&& other) noexcept + : mTag(other.mTag) + { + if (mTag == Tag::Value) { - if (mTag == Tag::Value) - { - mPointer.value = new T(*other.mPointer.value); - } - else - { - mPointer.error = new Error(*other.mPointer.error); - } + mPointer.value = other.mPointer.value; } - - Result(Result&& other) noexcept : mTag(other.mTag) + else { - if(mTag == Tag::Value) - { - mPointer.value = other.mPointer.value; - } - else - { - mPointer.error = other.mPointer.error; - } - - other.mPointer.error = nullptr; - other.mTag = Tag::Error; + mPointer.error = other.mPointer.error; } - ~Result() + other.mPointer.error = nullptr; + other.mTag = Tag::Error; + } + + ~Result() + { + if (mTag == Tag::Value) { - if (mTag == Tag::Value) - { - delete mPointer.value; - } - else - { - delete mPointer.error; - } + delete mPointer.value; } - - Result& operator=(const Result& other) + else { - if (this == &other) - { - return *this; - } - - if (mTag == Tag::Value) - { - delete mPointer.value; - } - else - { - delete mPointer.error; - } - - mTag = other.mTag; - other.mTag = Tag::Error; - - if (mTag == Tag::Value) - { - mPointer.value = other.mPointer.value; - } - else - { - mPointer.error = other.mPointer.error; - } - - other.mPointer.error = nullptr; - return *this; + delete mPointer.error; } + } - Result& operator=(Result&& other) noexcept - { - if (this == &other) - { - return *this; - } - - if (mTag == Tag::Value) - { - delete mPointer.value; - } - else - { - delete mPointer.error; - } - - mTag = other.mTag; - if (mTag == Tag::Value) - { - mPointer.value = other.mPointer.value; - other.mPointer.value = nullptr; - } - else - { - mPointer.error = other.mPointer.error; - other.mPointer.error = nullptr; - } - + Result& operator=(const Result& other) + { + if (this == &other) + { return *this; } - bool has_value() const noexcept + if (mTag == Tag::Value) { - return mTag == Tag::Value; + delete mPointer.value; } - - operator bool() const noexcept + else { - return has_value(); + delete mPointer.error; } - T value_or(T default_value) const& noexcept(noexcept_copyable()) - { - if(mTag == Tag::Error) - { - return std::move(default_value); - } - - return *mPointer.value; - } + mTag = other.mTag; + other.mTag = Tag::Error; - T value_or(T default_value) && noexcept(noexcept_copyable()) + if (mTag == Tag::Value) { - if (mTag == Tag::Error) - { - return std::move(default_value); - } - - return std::move(*mPointer.value); + mPointer.value = other.mPointer.value; } - - const T& value() const& noexcept(noexcept_copyable()) + else { - return *mPointer.value; + mPointer.error = other.mPointer.error; } - T value() && noexcept(noexcept_movable()) + other.mPointer.error = nullptr; + return *this; + } + + Result& operator=(Result&& other) noexcept + { + if (this == &other) { - return std::move(*mPointer.value); + return *this; } - T& value() & + if (mTag == Tag::Value) { - return *mPointer.value; + delete mPointer.value; } - - const T* operator->() const& + else { - return mPointer.value; + delete mPointer.error; } - T* operator->()& + mTag = other.mTag; + if (mTag == Tag::Value) { - return mPointer.value; + mPointer.value = other.mPointer.value; + other.mPointer.value = nullptr; } - - const Error& error() const& + else { - return *mPointer.error; + mPointer.error = other.mPointer.error; + other.mPointer.error = nullptr; } - Error error() && + return *this; + } + + bool has_value() const noexcept + { + return mTag == Tag::Value; + } + + operator bool() const noexcept + { + return has_value(); + } + + T value_or(T default_value) const& noexcept(noexcept_copyable()) + { + if (mTag == Tag::Error) { - return std::move(*mPointer.error); + return std::move(default_value); } - Error& error() & + return *mPointer.value; + } + + T value_or(T default_value) && noexcept(noexcept_copyable()) + { + if (mTag == Tag::Error) { - return *mPointer.error; + return std::move(default_value); } - }; + + return std::move(*mPointer.value); + } + + const T& value() const& noexcept(noexcept_copyable()) + { + return *mPointer.value; + } + + T value() && noexcept(noexcept_movable()) + { + return std::move(*mPointer.value); + } + + T& value() & + { + return *mPointer.value; + } + + const T* operator->() const& + { + return mPointer.value; + } + + T* operator->() & + { + return mPointer.value; + } + + const Error& error() const& + { + return *mPointer.error; + } + + Error error() && + { + return std::move(*mPointer.error); + } + + Error& error() & + { + return *mPointer.error; + } +}; } // namespace compliance #endif // COMPLIANCE_RESULT_H diff --git a/src/modules/compliance/src/lib/TypeTraits.h b/src/modules/compliance/src/lib/TypeTraits.h index 381266e22..ac5fe291b 100644 --- a/src/modules/compliance/src/lib/TypeTraits.h +++ b/src/modules/compliance/src/lib/TypeTraits.h @@ -8,17 +8,17 @@ namespace compliance { - template - constexpr bool noexcept_copyable() noexcept - { - return noexcept(std::is_copy_constructible::value); - } +template +constexpr bool noexcept_copyable() noexcept +{ + return noexcept(std::is_copy_constructible::value); +} - template - constexpr bool noexcept_movable() noexcept - { - return noexcept(std::is_move_constructible::value); - } +template +constexpr bool noexcept_movable() noexcept +{ + return noexcept(std::is_move_constructible::value); +} } // namespace compliance #endif // COMPLIANCE_TYPE_TRAITS_H diff --git a/src/modules/compliance/tests/Base64Test.cpp b/src/modules/compliance/tests/Base64Test.cpp index 8236eea94..b8f9fefe8 100644 --- a/src/modules/compliance/tests/Base64Test.cpp +++ b/src/modules/compliance/tests/Base64Test.cpp @@ -1,13 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include #include "Base64.h" + #include "Result.h" +#include + using compliance::Base64Decode; -using compliance::Result; using compliance::Error; +using compliance::Result; class Base64Test : public ::testing::Test { diff --git a/src/modules/compliance/tests/ComplianceTest.cpp b/src/modules/compliance/tests/ComplianceTest.cpp index 2dce0697a..e74ecc99f 100644 --- a/src/modules/compliance/tests/ComplianceTest.cpp +++ b/src/modules/compliance/tests/ComplianceTest.cpp @@ -1,11 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#include "ComplianceInterface.h" + +#include +#include #include #include -#include -#include -#include "ComplianceInterface.h" using namespace std; diff --git a/src/modules/compliance/tests/EngineTest.cpp b/src/modules/compliance/tests/EngineTest.cpp index 890d11164..1023bd6fa 100644 --- a/src/modules/compliance/tests/EngineTest.cpp +++ b/src/modules/compliance/tests/EngineTest.cpp @@ -2,16 +2,17 @@ // Licensed under the MIT License. #include "Engine.h" + #include "Evaluator.h" #include "parson.h" #include -using compliance::Result; -using compliance::Error; +using compliance::action_func_t; using compliance::Engine; +using compliance::Error; using compliance::JsonWrapper; -using compliance::action_func_t; +using compliance::Result; static Result auditFailure(std::map, std::ostringstream&) { diff --git a/src/modules/compliance/tests/EvaluatorTest.cpp b/src/modules/compliance/tests/EvaluatorTest.cpp index 3c6abbc02..1d28c275d 100644 --- a/src/modules/compliance/tests/EvaluatorTest.cpp +++ b/src/modules/compliance/tests/EvaluatorTest.cpp @@ -2,17 +2,17 @@ // Licensed under the MIT License. #include "Evaluator.h" -#include "JsonWrapper.h" +#include "JsonWrapper.h" #include "parson.h" #include -using compliance::Result; +using compliance::action_func_t; using compliance::Error; using compliance::Evaluator; using compliance::JsonWrapper; -using compliance::action_func_t; +using compliance::Result; static Result remediationFailure(std::map, std::ostringstream&) { @@ -37,16 +37,16 @@ static Result auditSuccess(std::map, std::ostrin static Result remediationParametrized(std::map arguments, std::ostringstream&) { auto it = arguments.find("result"); - if(it == arguments.end()) + if (it == arguments.end()) { return Error("Missing 'result' parameter"); } - if(it->second == "success") + if (it->second == "success") { return true; } - else if(it->second == "failure") + else if (it->second == "failure") { return false; } @@ -62,13 +62,9 @@ class EvaluatorTest : public ::testing::Test void SetUp() override { - mProcedureMap = { - {"auditSuccess", {auditSuccess, nullptr}}, - {"auditFailure", {auditFailure, nullptr}}, - {"remediationSuccess", {nullptr, remediationSuccess}}, - {"remediationFailure", {nullptr, remediationFailure}}, - {"remediationParametrized", {nullptr, remediationParametrized}} - }; + mProcedureMap = {{"auditSuccess", {auditSuccess, nullptr}}, {"auditFailure", {auditFailure, nullptr}}, + {"remediationSuccess", {nullptr, remediationSuccess}}, {"remediationFailure", {nullptr, remediationFailure}}, + {"remediationParametrized", {nullptr, remediationParametrized}}}; } }; @@ -612,7 +608,7 @@ TEST_F(EvaluatorTest, ExecuteRemediation_Parameters_5) TEST_F(EvaluatorTest, ExecuteRemediation_Parameters_6) { - mParameters = { {"placeholder", "failure"} }; + mParameters = {{"placeholder", "failure"}}; auto json = compliance::parseJSON("{\"anyOf\":[{\"remediationParametrized\":{\"result\":\"$placeholder\"}}]}"); ASSERT_TRUE(json.get()); Evaluator evaluator1(json_value_get_object(json.get()), mParameters, nullptr); @@ -625,7 +621,7 @@ TEST_F(EvaluatorTest, ExecuteRemediation_Parameters_6) TEST_F(EvaluatorTest, ExecuteRemediation_Parameters_7) { - mParameters = { {"placeholder", "success"} }; + mParameters = {{"placeholder", "success"}}; auto json = compliance::parseJSON("{\"anyOf\":[{\"remediationParametrized\":{\"result\":\"$placeholder\"}}]}"); ASSERT_TRUE(json.get()); Evaluator evaluator1(json_value_get_object(json.get()), mParameters, nullptr); diff --git a/src/modules/compliance/tests/OptionalTest.cpp b/src/modules/compliance/tests/OptionalTest.cpp index 01dee709e..b46fe8360 100644 --- a/src/modules/compliance/tests/OptionalTest.cpp +++ b/src/modules/compliance/tests/OptionalTest.cpp @@ -1,9 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include #include "Optional.h" +#include + using compliance::Optional; class OptionalTest : public ::testing::Test diff --git a/src/modules/compliance/tests/ResultTest.cpp b/src/modules/compliance/tests/ResultTest.cpp index a2b0129a2..0e6e3930b 100644 --- a/src/modules/compliance/tests/ResultTest.cpp +++ b/src/modules/compliance/tests/ResultTest.cpp @@ -1,11 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include #include "Result.h" -using compliance::Result; +#include + using compliance::Error; +using compliance::Result; class ResultTest : public ::testing::Test {