您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef CFG_RCL_H_
  17. #define CFG_RCL_H_
  18. #include "config.h"
  19. #include "cfg_file.h"
  20. #include "ucl.h"
  21. #include "mem_pool.h"
  22. #define CFG_RCL_ERROR cfg_rcl_error_quark ()
  23. static inline GQuark
  24. cfg_rcl_error_quark (void)
  25. {
  26. return g_quark_from_static_string ("cfg-rcl-error-quark");
  27. }
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. struct rspamd_rcl_section;
  32. struct rspamd_config;
  33. struct rspamd_rcl_default_handler_data;
  34. enum rspamd_rcl_flag {
  35. RSPAMD_CL_FLAG_TIME_FLOAT = 0x1 << 0,
  36. RSPAMD_CL_FLAG_TIME_TIMEVAL = 0x1 << 1,
  37. RSPAMD_CL_FLAG_TIME_TIMESPEC = 0x1 << 2,
  38. RSPAMD_CL_FLAG_TIME_INTEGER = 0x1 << 3,
  39. RSPAMD_CL_FLAG_TIME_UINT_32 = 0x1 << 4,
  40. RSPAMD_CL_FLAG_INT_16 = 0x1 << 5,
  41. RSPAMD_CL_FLAG_INT_32 = 0x1 << 6,
  42. RSPAMD_CL_FLAG_INT_64 = 0x1 << 7,
  43. RSPAMD_CL_FLAG_UINT = 0x1 << 8,
  44. RSPAMD_CL_FLAG_INT_SIZE = 0x1 << 9,
  45. RSPAMD_CL_FLAG_STRING_PATH = 0x1 << 10,
  46. RSPAMD_CL_FLAG_BOOLEAN_INVERSE = 0x1 << 11,
  47. RSPAMD_CL_FLAG_STRING_LIST_HASH = 0x1 << 12,
  48. RSPAMD_CL_FLAG_MULTIPLE = 0x1 << 13,
  49. RSPAMD_CL_FLAG_SIGNKEY = 0x1 << 14,
  50. RSPAMD_CL_FLAG_NISTKEY = 0x1 << 15,
  51. };
  52. struct rspamd_rcl_struct_parser {
  53. struct rspamd_config *cfg;
  54. gpointer user_struct;
  55. goffset offset;
  56. enum rspamd_rcl_flag flags;
  57. };
  58. /**
  59. * Common handler type
  60. * @param cfg configuration
  61. * @param obj object to parse
  62. * @param ud user data (depends on section)
  63. * @param err error object
  64. * @return TRUE if a section has been parsed
  65. */
  66. typedef gboolean (*rspamd_rcl_handler_t) (rspamd_mempool_t *pool,
  67. const ucl_object_t *obj,
  68. const gchar *key,
  69. gpointer ud,
  70. struct rspamd_rcl_section *section,
  71. GError **err);
  72. typedef gboolean (*rspamd_rcl_default_handler_t) (rspamd_mempool_t *pool,
  73. const ucl_object_t *obj,
  74. gpointer ud,
  75. struct rspamd_rcl_section *section,
  76. GError **err);
  77. /**
  78. * A handler type that is called at the end of section parsing
  79. * @param cfg configuration
  80. * @param ud user data
  81. */
  82. typedef void (*rspamd_rcl_section_fin_t)(rspamd_mempool_t *pool, gpointer ud);
  83. /**
  84. * Add a default handler for a section
  85. * @param section section pointer
  86. * @param name name of param
  87. * @param handler handler of param
  88. * @param offset offset in a structure
  89. * @param flags flags for the parser
  90. * @return newly created structure
  91. */
  92. struct rspamd_rcl_default_handler_data *rspamd_rcl_add_default_handler (
  93. struct rspamd_rcl_section *section,
  94. const gchar *name,
  95. rspamd_rcl_default_handler_t handler,
  96. goffset offset,
  97. gint flags,
  98. const gchar *doc_string);
  99. /**
  100. * Add new section to the configuration
  101. * @param top top section
  102. * @param name the name of the section
  103. * @param key_attr name of the attribute that should be used as key attribute
  104. * @param handler handler function for all attributes
  105. * @param type type of object handled by a handler
  106. * @param required whether at least one of these sections is required
  107. * @param strict_type turn on strict check for types for this section
  108. * @return newly created structure
  109. */
  110. struct rspamd_rcl_section *rspamd_rcl_add_section (
  111. struct rspamd_rcl_section **top,
  112. const gchar *name, const gchar *key_attr,
  113. rspamd_rcl_handler_t handler,
  114. enum ucl_type type, gboolean required, gboolean strict_type);
  115. struct rspamd_rcl_section *rspamd_rcl_add_section_doc (
  116. struct rspamd_rcl_section **top,
  117. const gchar *name, const gchar *key_attr,
  118. rspamd_rcl_handler_t handler,
  119. enum ucl_type type, gboolean required,
  120. gboolean strict_type,
  121. ucl_object_t *doc_target,
  122. const gchar *doc_string);
  123. /**
  124. * Init common sections known to rspamd
  125. * @return top section
  126. */
  127. struct rspamd_rcl_section * rspamd_rcl_config_init (struct rspamd_config *cfg,
  128. GHashTable *skip_sections);
  129. /**
  130. * Get a section specified by path, it understand paths separated by '/' character
  131. * @param top top section
  132. * @param path '/' divided path
  133. * @return
  134. */
  135. struct rspamd_rcl_section * rspamd_rcl_config_get_section (
  136. struct rspamd_rcl_section *top,
  137. const char *path);
  138. /**
  139. * Parse configuration
  140. * @param top top section
  141. * @param cfg rspamd configuration
  142. * @param ptr pointer to the target
  143. * @param pool pool object
  144. * @param obj ucl object to parse
  145. * @param err error pointer
  146. * @return
  147. */
  148. gboolean rspamd_rcl_parse (struct rspamd_rcl_section *top,
  149. struct rspamd_config *cfg,
  150. gpointer ptr, rspamd_mempool_t *pool,
  151. const ucl_object_t *obj, GError **err);
  152. /**
  153. * Parse default structure for a section
  154. * @param section section
  155. * @param cfg config file
  156. * @param obj object to parse
  157. * @param ptr ptr to pass
  158. * @param err error ptr
  159. * @return TRUE if the object has been parsed
  160. */
  161. gboolean rspamd_rcl_section_parse_defaults (struct rspamd_config *cfg,
  162. struct rspamd_rcl_section *section,
  163. rspamd_mempool_t *pool, const ucl_object_t *obj, gpointer ptr,
  164. GError **err);
  165. /**
  166. * Here is a section of common handlers that accepts rcl_struct_parser
  167. * which itself contains a struct pointer and the offset of a member in a
  168. * specific structure
  169. */
  170. /**
  171. * Parse a string field of a structure
  172. * @param cfg config pointer
  173. * @param obj object to parse
  174. * @param ud struct_parser structure
  175. * @param section the current section
  176. * @param err error pointer
  177. * @return TRUE if a string value has been successfully parsed
  178. */
  179. gboolean rspamd_rcl_parse_struct_string (rspamd_mempool_t *pool,
  180. const ucl_object_t *obj,
  181. gpointer ud,
  182. struct rspamd_rcl_section *section,
  183. GError **err);
  184. /**
  185. * Parse an integer field of a structure
  186. * @param cfg config pointer
  187. * @param obj object to parse
  188. * @param ud struct_parser structure
  189. * @param section the current section
  190. * @param err error pointer
  191. * @return TRUE if a value has been successfully parsed
  192. */
  193. gboolean rspamd_rcl_parse_struct_integer (rspamd_mempool_t *pool,
  194. const ucl_object_t *obj,
  195. gpointer ud,
  196. struct rspamd_rcl_section *section,
  197. GError **err);
  198. /**
  199. * Parse a float field of a structure
  200. * @param cfg config pointer
  201. * @param obj object to parse
  202. * @param ud struct_parser structure
  203. * @param section the current section
  204. * @param err error pointer
  205. * @return TRUE if a value has been successfully parsed
  206. */
  207. gboolean rspamd_rcl_parse_struct_double (rspamd_mempool_t *pool,
  208. const ucl_object_t *obj,
  209. gpointer ud,
  210. struct rspamd_rcl_section *section,
  211. GError **err);
  212. /**
  213. * Parse a time field of a structure
  214. * @param cfg config pointer
  215. * @param obj object to parse
  216. * @param ud struct_parser structure (flags mean the exact structure used)
  217. * @param section the current section
  218. * @param err error pointer
  219. * @return TRUE if a value has been successfully parsed
  220. */
  221. gboolean rspamd_rcl_parse_struct_time (rspamd_mempool_t *pool,
  222. const ucl_object_t *obj,
  223. gpointer ud,
  224. struct rspamd_rcl_section *section,
  225. GError **err);
  226. /**
  227. * Parse a string list field of a structure presented by a GList* object
  228. * @param cfg config pointer
  229. * @param obj object to parse
  230. * @param ud struct_parser structure (flags mean the exact structure used)
  231. * @param section the current section
  232. * @param err error pointer
  233. * @return TRUE if a value has been successfully parsed
  234. */
  235. gboolean rspamd_rcl_parse_struct_string_list (rspamd_mempool_t *pool,
  236. const ucl_object_t *obj,
  237. gpointer ud,
  238. struct rspamd_rcl_section *section,
  239. GError **err);
  240. /**
  241. * Parse a boolean field of a structure
  242. * @param cfg config pointer
  243. * @param obj object to parse
  244. * @param ud struct_parser structure (flags mean the exact structure used)
  245. * @param section the current section
  246. * @param err error pointer
  247. * @return TRUE if a value has been successfully parsed
  248. */
  249. gboolean rspamd_rcl_parse_struct_boolean (rspamd_mempool_t *pool,
  250. const ucl_object_t *obj,
  251. gpointer ud,
  252. struct rspamd_rcl_section *section,
  253. GError **err);
  254. /**
  255. * Parse a keypair field of a structure
  256. * @param cfg config pointer
  257. * @param obj object to parse
  258. * @param ud struct_parser structure (flags mean the exact structure used)
  259. * @param section the current section
  260. * @param err error pointer
  261. * @return TRUE if a value has been successfully parsed
  262. */
  263. gboolean rspamd_rcl_parse_struct_keypair (rspamd_mempool_t *pool,
  264. const ucl_object_t *obj,
  265. gpointer ud,
  266. struct rspamd_rcl_section *section,
  267. GError **err);
  268. /**
  269. * Parse a pubkey field of a structure
  270. * @param cfg config pointer
  271. * @param obj object to parse
  272. * @param ud struct_parser structure (flags mean the exact structure used)
  273. * @param section the current section
  274. * @param err error pointer
  275. * @return TRUE if a value has been successfully parsed
  276. */
  277. gboolean rspamd_rcl_parse_struct_pubkey (rspamd_mempool_t *pool,
  278. const ucl_object_t *obj,
  279. gpointer ud,
  280. struct rspamd_rcl_section *section,
  281. GError **err);
  282. /**
  283. * Parse a inet addr field of a structure
  284. * @param cfg config pointer
  285. * @param obj object to parse
  286. * @param ud struct_parser structure (flags mean the exact structure used)
  287. * @param section the current section
  288. * @param err error pointer
  289. * @return TRUE if a value has been successfully parsed
  290. */
  291. gboolean rspamd_rcl_parse_struct_addr (rspamd_mempool_t *pool,
  292. const ucl_object_t *obj,
  293. gpointer ud,
  294. struct rspamd_rcl_section *section,
  295. GError **err);
  296. /**
  297. * Parse a gmime inet address field of a structure
  298. * @param cfg config pointer
  299. * @param obj object to parse
  300. * @param ud struct_parser structure (flags mean the exact structure used)
  301. * @param section the current section
  302. * @param err error pointer
  303. * @return TRUE if a value has been successfully parsed
  304. */
  305. gboolean rspamd_rcl_parse_struct_mime_addr (rspamd_mempool_t *pool,
  306. const ucl_object_t *obj,
  307. gpointer ud,
  308. struct rspamd_rcl_section *section,
  309. GError **err);
  310. /**
  311. * Parse a raw ucl object
  312. * @param cfg config pointer
  313. * @param obj object to parse
  314. * @param ud struct_parser structure (flags mean the exact structure used)
  315. * @param section the current section
  316. * @param err error pointer
  317. * @return TRUE if a value has been successfully parsed
  318. */
  319. gboolean rspamd_rcl_parse_struct_ucl (rspamd_mempool_t *pool,
  320. const ucl_object_t *obj,
  321. gpointer ud,
  322. struct rspamd_rcl_section *section,
  323. GError **err);
  324. /**
  325. * Utility functions
  326. */
  327. /**
  328. * Register new parser for a worker type of an option with the specified name
  329. * @param cfg config structure
  330. * @param type type of worker (GQuark)
  331. * @param name name of option
  332. * @param handler handler of option
  333. * @param target opaque target structure
  334. * @param offset offset inside a structure
  335. */
  336. void rspamd_rcl_register_worker_option (struct rspamd_config *cfg,
  337. GQuark type,
  338. const gchar *name,
  339. rspamd_rcl_default_handler_t handler,
  340. gpointer target,
  341. glong offset,
  342. gint flags,
  343. const gchar *doc_string);
  344. /**
  345. * Register a default parser for a worker
  346. * @param cfg config structure
  347. * @param type type of worker (GQuark)
  348. * @param func handler function
  349. * @param ud userdata for handler function
  350. */
  351. void rspamd_rcl_register_worker_parser (struct rspamd_config *cfg, gint type,
  352. gboolean (*func)(ucl_object_t *, gpointer), gpointer ud);
  353. /**
  354. * Adds new documentation object to the configuration
  355. * @param doc_target target object where to insert documentation (top object is used if this is NULL)
  356. * @param doc_object documentation object to insert
  357. */
  358. ucl_object_t *rspamd_rcl_add_doc_obj (ucl_object_t *doc_target,
  359. const char *doc_string,
  360. const char *doc_name,
  361. ucl_type_t type,
  362. rspamd_rcl_default_handler_t handler,
  363. gint flags,
  364. const char *default_value,
  365. gboolean required);
  366. /**
  367. * Adds new documentation option specified by path `doc_path` that should be
  368. * split by dots
  369. */
  370. ucl_object_t *rspamd_rcl_add_doc_by_path (struct rspamd_config *cfg,
  371. const gchar *doc_path,
  372. const char *doc_string,
  373. const char *doc_name,
  374. ucl_type_t type,
  375. rspamd_rcl_default_handler_t handler,
  376. gint flags,
  377. const char *default_value,
  378. gboolean required);
  379. /**
  380. * Parses example and adds documentation according to the example:
  381. *
  382. * ```
  383. * section {
  384. * param1 = value; # explanation
  385. * param2 = value; # explanation
  386. * }
  387. * ```
  388. *
  389. * will produce the following documentation strings:
  390. * section ->
  391. * section.param1 : explanation
  392. * section.param2 : explanation
  393. *
  394. * @param cfg
  395. * @param root_path
  396. * @param example_data
  397. * @param example_len
  398. * @return
  399. */
  400. ucl_object_t *rspamd_rcl_add_doc_by_example (struct rspamd_config *cfg,
  401. const gchar *root_path,
  402. const gchar *doc_string,
  403. const gchar *doc_name,
  404. const gchar *example_data, gsize example_len);
  405. /**
  406. * Add lua modules path
  407. * @param cfg
  408. * @param path
  409. * @param err
  410. * @return
  411. */
  412. gboolean rspamd_rcl_add_lua_plugins_path (struct rspamd_config *cfg,
  413. const gchar *path,
  414. gboolean main_path,
  415. GHashTable *modules_seen,
  416. GError **err);
  417. /**
  418. * Calls for an external lua function to apply potential config transformations
  419. * if needed. This function can change the cfg->rcl_obj.
  420. *
  421. * Example of transformation function:
  422. *
  423. * function(obj)
  424. * if obj.something == 'foo' then
  425. * obj.something = "bla"
  426. * return true, obj
  427. * end
  428. *
  429. * return false, nil
  430. * end
  431. *
  432. * If function returns 'false' then rcl_obj is not touched. Otherwise,
  433. * it is changed, then rcl_obj is imported from lua. Old config is dereferenced.
  434. * @param cfg
  435. */
  436. void rspamd_rcl_maybe_apply_lua_transform (struct rspamd_config *cfg);
  437. void rspamd_rcl_section_free (gpointer p);
  438. void rspamd_config_calculate_cksum (struct rspamd_config *cfg);
  439. /*
  440. * Read configuration file
  441. */
  442. gboolean rspamd_config_parse_ucl (struct rspamd_config *cfg,
  443. const gchar *filename,
  444. GHashTable *vars,
  445. ucl_include_trace_func_t inc_trace,
  446. void *trace_data,
  447. gboolean skip_jinja,
  448. GError **err);
  449. gboolean rspamd_config_read (struct rspamd_config *cfg,
  450. const gchar *filename,
  451. rspamd_rcl_section_fin_t logger_fin,
  452. gpointer logger_ud,
  453. GHashTable *vars,
  454. gboolean skip_jinja,
  455. gchar **lua_env);
  456. #ifdef __cplusplus
  457. }
  458. #endif
  459. #endif /* CFG_RCL_H_ */