LDFL
LD_PRELOAD library rerule files & directories.
Loading...
Searching...
No Matches
ldfl-config-parser.h
Go to the documentation of this file.
1
2#include <jansson.h>
3#include <string.h>
4#include <stdlib.h>
5
6// Default Mapping
7ldfl_rule_t default_default[] = {
8 {"default noop rule", ".*", LDFL_OP_NOOP, NULL, LDFL_PATH_ABS, false, NULL},
9 {NULL, NULL, LDFL_OP_END, NULL, LDFL_PATH_ABS, NULL, NULL} // keep this last value
10};
11
12ldfl_rule_t *ldfl_rule = default_default;
13
14ldfl_setting_t ldfl_setting = {
16 .log_level = LOG_INFO,
17 .logger = ldfl_stderr_logger,
18};
19
20// Helper function to convert JSON string to operation type
21static ldfl_operation_t json_to_operation(const char *op_str) {
22 if (strcmp(op_str, "noop") == 0)
23 return LDFL_OP_NOOP;
24 if (strcmp(op_str, "path_redir") == 0)
25 return LDFL_OP_PATH_REDIR;
26 if (strcmp(op_str, "exec_redir") == 0)
27 return LDFL_OP_EXEC_REDIR;
28 if (strcmp(op_str, "mem_open") == 0)
29 return LDFL_OP_MEM_OPEN;
30 if (strcmp(op_str, "mem_data") == 0)
31 return LDFL_OP_MEM_DATA;
32 if (strcmp(op_str, "perm") == 0)
33 return LDFL_OP_PERM;
34 if (strcmp(op_str, "deny") == 0)
35 return LDFL_OP_DENY;
36 if (strcmp(op_str, "ro") == 0)
37 return LDFL_OP_RO;
38 return LDFL_OP_END;
39}
40
41// Helper function to convert JSON string to path type
42static ldfl_path_type_t json_to_path_type(const char *path_type_str) {
43 if (strcmp(path_type_str, "absolute") == 0)
44 return LDFL_PATH_ABS;
45 return LDFL_PATH_ORIG;
46}
47
48// Helper function to convert JSON string to log level
49static int json_to_log_level(const char *level_str) {
50 if (strcmp(level_str, "emerg") == 0)
51 return LOG_EMERG;
52 if (strcmp(level_str, "alert") == 0)
53 return LOG_ALERT;
54 if (strcmp(level_str, "crit") == 0)
55 return LOG_CRIT;
56 if (strcmp(level_str, "err") == 0)
57 return LOG_ERR;
58 if (strcmp(level_str, "warning") == 0)
59 return LOG_WARNING;
60 if (strcmp(level_str, "notice") == 0)
61 return LOG_NOTICE;
62 if (strcmp(level_str, "info") == 0)
63 return LOG_INFO;
64 if (strcmp(level_str, "debug") == 0)
65 return LOG_DEBUG;
66 return LOG_DEBUG; // Default to debug
67}
68
69// Helper function to convert JSON string to logger function
70static ldfl_logger_t json_to_logger(const char *logger_str) {
71 if (strcmp(logger_str, "syslog") == 0)
72 return ldfl_syslog_logger;
73 if (strcmp(logger_str, "stderr") == 0)
74 return ldfl_stderr_logger;
75 return ldfl_dummy_logger; // Default to dummy logger
76}
77
78// Helper function to convert JSON string to log mask
79static uint64_t json_to_log_mask(json_t *log_mask_array) {
80 uint64_t mask = 0;
81 size_t index;
82 json_t *value;
83
84 json_array_foreach(log_mask_array, index, value) {
85 const char *mask_str = json_string_value(value);
86 if (strcmp(mask_str, "rule_search") == 0)
88 if (strcmp(mask_str, "rule_apply") == 0)
89 mask |= LDFL_LOG_RULE_APPLY;
90 if (strcmp(mask_str, "rule_found") == 0)
91 mask |= LDFL_LOG_RULE_FOUND;
92 if (strcmp(mask_str, "fn_call") == 0)
93 mask |= LDFL_LOG_FN_CALL;
94 if (strcmp(mask_str, "init") == 0)
95 mask |= LDFL_LOG_INIT;
96 if (strcmp(mask_str, "fn_call_err") == 0)
98 if (strcmp(mask_str, "all") == 0)
99 mask |= LDFL_LOG_ALL;
100 }
101 return mask;
102}
103
104// Parse JSON configuration file
105int ldfl_parse_json_config(const char *config_file) {
106 json_error_t error;
107 json_t *root = json_load_file(config_file, 0, &error);
108 if (!root) {
109 fprintf(stderr, "Error parsing JSON config '%s': %s (line %d, column %d)\n", config_file, error.text, error.line, error.column);
110 return -1;
111 }
112
113 // Parse settings
114 json_t *settings = json_object_get(root, "settings");
115 if (settings) {
116 json_t *log_mask = json_object_get(settings, "log_mask");
117 if (log_mask && json_is_array(log_mask)) {
118 ldfl_setting.log_mask = json_to_log_mask(log_mask);
119 }
120
121 json_t *log_level = json_object_get(settings, "log_level");
122 if (log_level && json_is_string(log_level)) {
123 ldfl_setting.log_level = json_to_log_level(json_string_value(log_level));
124 }
125
126 json_t *logger = json_object_get(settings, "logger");
127 if (logger && json_is_string(logger)) {
128 ldfl_setting.logger = json_to_logger(json_string_value(logger));
129 }
130 }
131
132 // Parse rules
133 json_t *rules = json_object_get(root, "rules");
134 if (rules && json_is_array(rules)) {
135 size_t rule_count = json_array_size(rules);
136 ldfl_rule = calloc(rule_count + 1, sizeof(ldfl_rule_t)); // +1 for sentinel
137
138 size_t index;
139 json_t *rule;
140 json_array_foreach(rules, index, rule) {
141 json_t *name = json_object_get(rule, "name");
142 json_t *search_pattern = json_object_get(rule, "search_pattern");
143 json_t *operation = json_object_get(rule, "operation");
144 json_t *target = json_object_get(rule, "target");
145 json_t *path_transform = json_object_get(rule, "path_transform");
146 json_t *extra_options = json_object_get(rule, "extra_options");
147 json_t *final = json_object_get(rule, "final");
148
149 if (name && search_pattern && operation) {
150 ldfl_rule[index].name = strdup(json_string_value(name));
151 ldfl_rule[index].search_pattern = strdup(json_string_value(search_pattern));
152 ldfl_rule[index].operation = json_to_operation(json_string_value(operation));
153
154 if (target && !json_is_null(target)) {
155 ldfl_rule[index].target = strdup(json_string_value(target));
156 } else {
157 ldfl_rule[index].target = NULL;
158 }
159
160 if (path_transform) {
161 ldfl_rule[index].path_transform = json_to_path_type(json_string_value(path_transform));
162 } else {
163 ldfl_rule[index].path_transform = LDFL_PATH_ABS;
164 }
165
166 if (extra_options && !json_is_null(extra_options)) {
167 ldfl_rule[index].extra_options = strdup(json_string_value(extra_options));
168 } else {
169 ldfl_rule[index].extra_options = NULL;
170 }
171
172 if (final && json_is_boolean(final)) {
173 ldfl_rule[index].final = json_boolean_value(final);
174 } else {
175 ldfl_rule[index].final = false; // Default to false if not specified
176 }
177 }
178 }
179
180 // Add sentinel entry
181 ldfl_rule[rule_count].name = NULL;
182 ldfl_rule[rule_count].search_pattern = NULL;
183 ldfl_rule[rule_count].operation = LDFL_OP_END;
184 ldfl_rule[rule_count].target = NULL;
185 ldfl_rule[rule_count].path_transform = LDFL_PATH_ABS;
186 ldfl_rule[rule_count].extra_options = NULL;
187 ldfl_rule[rule_count].final = false;
188 }
189
190 json_decref(root);
191 return 0;
192}
193
194// Free allocated memory from JSON config
195void ldfl_free_json_config(void) {
196 if (ldfl_rule && ldfl_rule != default_default) {
197 for (int i = 0; ldfl_rule[i].operation != LDFL_OP_END; i++) {
198 free((void *)ldfl_rule[i].name);
199 free((void *)ldfl_rule[i].search_pattern);
200 free((void *)ldfl_rule[i].target);
201 free((void *)ldfl_rule[i].extra_options);
202 }
203 free(ldfl_rule);
204 ldfl_rule = NULL;
205 }
206}
ldfl_path_type_t
flag
Definition ldfl.c:47
@ LDFL_PATH_ORIG
Definition ldfl.c:48
@ LDFL_PATH_ABS
Definition ldfl.c:49
@ LDFL_LOG_RULE_APPLY
Definition ldfl.c:65
@ LDFL_LOG_FN_CALL_ERR
Definition ldfl.c:62
@ LDFL_LOG_ALL
Definition ldfl.c:67
@ LDFL_LOG_FN_CALL
Definition ldfl.c:61
@ LDFL_LOG_RULE_SEARCH
Definition ldfl.c:63
@ LDFL_LOG_INIT
Definition ldfl.c:66
@ LDFL_LOG_RULE_FOUND
Definition ldfl.c:64
ldfl_operation_t
enum for the type of operations
Definition ldfl.c:74
@ LDFL_OP_DENY
Definition ldfl.c:82
@ LDFL_OP_PATH_REDIR
Definition ldfl.c:76
@ LDFL_OP_PERM
Definition ldfl.c:80
@ LDFL_OP_MEM_OPEN
Definition ldfl.c:78
@ LDFL_OP_END
Definition ldfl.c:84
@ LDFL_OP_NOOP
Definition ldfl.c:75
@ LDFL_OP_MEM_DATA
Definition ldfl.c:79
@ LDFL_OP_EXEC_REDIR
Definition ldfl.c:77
@ LDFL_OP_RO
Definition ldfl.c:83
void(* ldfl_logger_t)(uint64_t mask, int priority, const char *fmt,...)
Variadic logger function type.
Definition ldfl.c:151
Represents matching + operation rule.
Definition ldfl.c:125
ldfl_path_type_t path_transform
Definition ldfl.c:130
ldfl_operation_t operation
Definition ldfl.c:128
const char * search_pattern
Definition ldfl.c:127
const char * name
Definition ldfl.c:126
const void * target
Definition ldfl.c:129
const char * extra_options
Definition ldfl.c:132
bool final
Definition ldfl.c:131
Represents the general settings.
Definition ldfl.c:158
uint64_t log_mask
Definition ldfl.c:161
int log_level
Definition ldfl.c:159
ldfl_logger_t logger
Definition ldfl.c:160