Skip to content

Commit a99fd29

Browse files
committed
Lua evaluator - take 1
1 parent cfc7d64 commit a99fd29

13 files changed

Lines changed: 1284 additions & 12 deletions

File tree

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "src/adapters/pnp/azure-iot-sdk-c"]
22
path = src/adapters/pnp/azure-iot-sdk-c
33
url = https://github.com/Azure/azure-iot-sdk-c
4+
[submodule "src/modules/complianceengine/lua/src"]
5+
path = src/modules/complianceengine/lua/src
6+
url = https://github.com/lua/lua

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"semaphore": "cpp",
8686
"charconv": "cpp",
8787
"format": "cpp",
88-
"span": "cpp"
88+
"span": "cpp",
89+
"unordered_set": "cpp"
8990
}
9091
}

src/modules/complianceengine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ add_subdirectory(src)
55
if (BUILD_TESTS)
66
add_subdirectory(tests)
77
endif()
8+
9+
add_subdirectory(lua)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
project(lualib)
2+
3+
4+
add_library(lualib STATIC
5+
src/lapi.c
6+
src/lcode.c
7+
src/lctype.c
8+
src/ldebug.c
9+
src/ldo.c
10+
src/ldump.c
11+
src/lfunc.c
12+
src/lgc.c
13+
src/llex.c
14+
src/lmem.c
15+
src/lobject.c
16+
src/lopcodes.c
17+
src/lparser.c
18+
src/lstate.c
19+
src/lstring.c
20+
src/ltable.c
21+
src/ltm.c
22+
src/lundump.c
23+
src/lvm.c
24+
src/lzio.c
25+
src/ltests.c
26+
src/lauxlib.c
27+
src/lbaselib.c
28+
src/ldblib.c
29+
src/liolib.c
30+
src/lmathlib.c
31+
src/loslib.c
32+
src/ltablib.c
33+
src/lstrlib.c
34+
src/lutf8lib.c
35+
src/loadlib.c
36+
src/lcorolib.c
37+
src/linit.c
38+
)
39+
40+
set_property(TARGET lualib PROPERTY POSITION_INDEPENDENT_CODE ON)
41+
42+
# POSIX, not Linux, as Linux implies libdl which we don't want.
43+
target_compile_options(lualib PRIVATE -DLUA_USE_POSIX -Wno-error=unused-const-variable=)
Submodule src added at e3716ee

src/modules/complianceengine/src/lib/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ add_library(complianceenginelib STATIC
131131
JsonWrapper.cpp
132132
KernelModuleTools.cpp
133133
ListValidShells.cpp
134+
LuaEvaluator.cpp
134135
NetworkTools.cpp
135136
PasswordEntriesIterator.cpp
136137
Procedure.cpp
@@ -156,8 +157,10 @@ target_link_libraries(complianceenginelib PRIVATE
156157
logging
157158
commonutils
158159
parsonlib
160+
lualib
159161
)
160162

161163
target_include_directories(complianceenginelib PUBLIC
162164
${MODULES_INC_DIR}
163-
${CMAKE_CURRENT_SOURCE_DIR})
165+
${CMAKE_CURRENT_SOURCE_DIR}
166+
${CMAKE_CURRENT_SOURCE_DIR}/../../lua/src)

src/modules/complianceengine/src/lib/Evaluator.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "JsonWrapper.h"
77
#include "Logging.h"
8+
#include "LuaEvaluator.h"
89
#include "Reasons.h"
910
#include "Result.h"
1011

@@ -25,11 +26,14 @@ using std::string;
2526
Evaluator::Evaluator(std::string ruleName, const struct json_object_t* json, const ParameterMap& parameters, ContextInterface& context)
2627
: mJson(json),
2728
mParameters(parameters),
28-
mContext(context)
29+
mContext(context),
30+
mLuaEvaluator(std::unique_ptr<LuaEvaluator>(new LuaEvaluator()))
2931
{
3032
mIndicators.Push(std::move(ruleName));
3133
}
3234

35+
Evaluator::~Evaluator() = default;
36+
3337
Result<AuditResult> Evaluator::ExecuteAudit(const PayloadFormatter& formatter)
3438
{
3539
auto result = EvaluateProcedure(mJson, Action::Audit);
@@ -109,6 +113,20 @@ Result<Status> Evaluator::EvaluateProcedure(const JSON_Object* object, const Act
109113
return result.Value();
110114
}
111115

116+
if (!strcmp(name, "lua"))
117+
{
118+
mIndicators.Push("lua");
119+
const auto result = EvaluateLua(value, action);
120+
if (!result.HasValue())
121+
{
122+
OsConfigLogError(mContext.GetLogHandle(), "Evaluation failed: %s", result.Error().message.c_str());
123+
return result;
124+
}
125+
mIndicators.Back().status = result.Value();
126+
mIndicators.Pop();
127+
return result.Value();
128+
}
129+
112130
mIndicators.Push(name);
113131
auto result = EvaluateBuiltinProcedure(name, value, action);
114132
if (!result.HasValue())
@@ -206,6 +224,49 @@ Result<Status> Evaluator::EvaluateNot(const json_value_t* value, const Action ac
206224
return Status::Compliant;
207225
}
208226

227+
Result<Status> Evaluator::EvaluateLua(const json_value_t* value, const Action action)
228+
{
229+
OsConfigLogDebug(mContext.GetLogHandle(), "Evaluating lua operator");
230+
231+
if (nullptr == value)
232+
{
233+
OsConfigLogError(mContext.GetLogHandle(), "invalid argument");
234+
return Error("invalid argument", EINVAL);
235+
}
236+
237+
if (json_value_get_type(value) != JSONObject)
238+
{
239+
OsConfigLogError(mContext.GetLogHandle(), "lua value is not an object");
240+
return Error("lua value is not an object", EINVAL);
241+
}
242+
243+
// Lua can be used for both audit and remediation
244+
// Get the arguments from the JSON object
245+
auto arguments = GetBuiltinProcedureArguments(value);
246+
if (!arguments.HasValue())
247+
{
248+
OsConfigLogError(mContext.GetLogHandle(), "Failed to get lua arguments: %s", arguments.Error().message.c_str());
249+
return arguments.Error();
250+
}
251+
252+
// Call the lua evaluation function using our LuaEvaluator instance
253+
auto scriptIt = arguments.Value().find("script");
254+
if (scriptIt == arguments.Value().end())
255+
{
256+
OsConfigLogError(mContext.GetLogHandle(), "No script content provided");
257+
return Error("No script content provided", EINVAL);
258+
}
259+
260+
auto result = mLuaEvaluator->Evaluate(scriptIt->second, mIndicators, mContext, action);
261+
if (!result.HasValue())
262+
{
263+
OsConfigLogError(mContext.GetLogHandle(), "Lua evaluation failed: %s", result.Error().message.c_str());
264+
return result.Error();
265+
}
266+
267+
return result.Value();
268+
}
269+
209270
Result<map<string, string>> Evaluator::GetBuiltinProcedureArguments(const json_value_t* value) const
210271
{
211272
map<string, string> result;

src/modules/complianceengine/src/lib/Evaluator.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <Optional.h>
1414
#include <map>
15+
#include <memory>
1516
#include <sstream>
1617
#include <string>
1718
#include <vector>
@@ -43,6 +44,16 @@ struct json_value_t;
4344
namespace ComplianceEngine
4445
{
4546

47+
// Define Action enum outside of class for forward declarations
48+
enum class Action
49+
{
50+
Audit,
51+
Remediate
52+
};
53+
54+
// Forward declaration
55+
class LuaEvaluator;
56+
4657
class PayloadFormatter
4758
{
4859
public:
@@ -113,7 +124,7 @@ class Evaluator
113124
{
114125
public:
115126
Evaluator(std::string ruleName, const struct json_object_t* json, const ParameterMap& parameters, ContextInterface& context);
116-
~Evaluator() = default;
127+
~Evaluator();
117128
Evaluator(const Evaluator&) = delete;
118129
Evaluator(Evaluator&&) = delete;
119130
Evaluator& operator=(const Evaluator&) = delete;
@@ -122,13 +133,10 @@ class Evaluator
122133
Result<AuditResult> ExecuteAudit(const PayloadFormatter& formatter);
123134
Result<Status> ExecuteRemediation();
124135

125-
private:
126-
enum class Action
127-
{
128-
Audit,
129-
Remediate
130-
};
136+
// Make procedure map public for access from Lua scripts
137+
static const ProcedureMap mProcedureMap;
131138

139+
private:
132140
enum class ListAction
133141
{
134142
AnyOf,
@@ -138,17 +146,19 @@ class Evaluator
138146
Result<Status> EvaluateProcedure(const struct json_object_t* object, Action action);
139147
Result<Status> EvaluateList(const struct json_value_t* value, Action action, ListAction listAction);
140148
Result<Status> EvaluateNot(const struct json_value_t* value, Action action);
149+
Result<Status> EvaluateLua(const struct json_value_t* value, Action action);
141150
Result<Status> EvaluateBuiltinProcedure(const std::string& procedureName, const struct json_value_t* value, Action action);
142151
Result<std::map<std::string, std::string>> GetBuiltinProcedureArguments(const json_value_t* value) const;
143152
const struct json_object_t* mJson;
144153
const ParameterMap& mParameters;
145154
ContextInterface& mContext;
146-
// autogenerated, instantiated in ProcedureMap.cpp
147-
static const ProcedureMap mProcedureMap;
148155
static const size_t cLogstreamMaxSize = 4096;
149156

150157
// List of indicators which determine the final state of the evaluation
151158
IndicatorsTree mIndicators;
159+
160+
// Lua evaluator instance for this evaluator
161+
std::unique_ptr<LuaEvaluator> mLuaEvaluator;
152162
};
153163
} // namespace ComplianceEngine
154164

0 commit comments

Comments
 (0)