/src/pigeonhole/src/lib-sieve/sieve-settings.c
Line | Count | Source |
1 | | /* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file |
2 | | */ |
3 | | |
4 | | #include "lib.h" |
5 | | #include "array.h" |
6 | | #include "settings.h" |
7 | | #include "settings-parser.h" |
8 | | |
9 | | #include "sieve-limits.h" |
10 | | #include "sieve-settings.h" |
11 | | |
12 | | #include <ctype.h> |
13 | | |
14 | | static bool sieve_settings_check(void *_set, pool_t pool, const char **error_r); |
15 | | |
16 | | #undef DEF |
17 | | #define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ |
18 | | "sieve_"#name, name, struct sieve_settings) |
19 | | |
20 | | static const struct setting_define sieve_setting_defines[] = { |
21 | | { .type = SET_FILTER_NAME, .key = "sieve_env_location_mda" }, |
22 | | { .type = SET_FILTER_NAME, .key = "sieve_env_location_mta" }, |
23 | | { .type = SET_FILTER_NAME, .key = "sieve_env_location_ms" }, |
24 | | |
25 | | DEF(BOOL, enabled), |
26 | | |
27 | | DEF(SIZE, max_script_size), |
28 | | DEF(UINT, max_actions), |
29 | | DEF(UINT, max_redirects), |
30 | | DEF(TIME, max_cpu_time), |
31 | | DEF(TIME, resource_usage_timeout), |
32 | | |
33 | | DEF(STR, redirect_envelope_from), |
34 | | DEF(UINT, redirect_duplicate_period), |
35 | | |
36 | | DEF(STR, user_email), |
37 | | DEF(STR, user_log_path), |
38 | | |
39 | | DEF(STR, trace_dir), |
40 | | DEF(ENUM, trace_level), |
41 | | DEF(BOOL, trace_debug), |
42 | | DEF(BOOL, trace_addresses), |
43 | | |
44 | | DEF(BOOLLIST, plugins), |
45 | | DEF(STR, plugin_dir), |
46 | | |
47 | | DEF(BOOLLIST, extensions), |
48 | | DEF(BOOLLIST, global_extensions), |
49 | | DEF(BOOLLIST, implicit_extensions), |
50 | | |
51 | | SETTING_DEFINE_LIST_END, |
52 | | }; |
53 | | |
54 | | const struct sieve_settings sieve_default_settings = { |
55 | | .enabled = TRUE, |
56 | | |
57 | | .max_script_size = (1 << 20), |
58 | | .max_actions = 32, |
59 | | .max_redirects = 4, |
60 | | .max_cpu_time = 0, |
61 | | |
62 | | .resource_usage_timeout = (60 * 60), |
63 | | .redirect_envelope_from = "", |
64 | | .redirect_duplicate_period = DEFAULT_REDIRECT_DUPLICATE_PERIOD, |
65 | | |
66 | | .user_email = "", |
67 | | .user_log_path = "", |
68 | | |
69 | | .trace_dir = "", |
70 | | .trace_level = "none:actions:commands:tests:matching", |
71 | | .trace_debug = FALSE, |
72 | | .trace_addresses = FALSE, |
73 | | |
74 | | .plugins = ARRAY_INIT, |
75 | | .plugin_dir = MODULEDIR"/sieve", |
76 | | |
77 | | .extensions = ARRAY_INIT, |
78 | | .global_extensions = ARRAY_INIT, |
79 | | .implicit_extensions = ARRAY_INIT, |
80 | | }; |
81 | | |
82 | | static const struct setting_keyvalue sieve_default_settings_keyvalue[] = { |
83 | | { "sieve_extensions", |
84 | | "fileinto reject envelope encoded-character vacation subaddress " |
85 | | "comparator-i;ascii-numeric relational regex imap4flags copy include " |
86 | | "body variables enotify environment mailbox date index ihave " |
87 | | "duplicate mime foreverypart extracttext" |
88 | | }, |
89 | | { "sieve_env_location_ms/sieve_max_cpu_time", "30s" }, |
90 | | { NULL, NULL } |
91 | | }; |
92 | | |
93 | | const struct setting_parser_info sieve_setting_parser_info = { |
94 | | .name = "sieve", |
95 | | |
96 | | .defines = sieve_setting_defines, |
97 | | .defaults = &sieve_default_settings, |
98 | | .default_settings = sieve_default_settings_keyvalue, |
99 | | |
100 | | .struct_size = sizeof(struct sieve_settings), |
101 | | |
102 | | .check_func = sieve_settings_check, |
103 | | |
104 | | .pool_offset1 = 1 + offsetof(struct sieve_settings, pool), |
105 | | }; |
106 | | |
107 | | /* <settings checks> */ |
108 | | static bool |
109 | | sieve_settings_check(void *_set, pool_t pool, const char **error_r) |
110 | 0 | { |
111 | 0 | struct sieve_settings *set = _set; |
112 | 0 | struct smtp_address *address = NULL; |
113 | 0 | const char *error; |
114 | |
|
115 | 0 | if (!sieve_address_source_parse( |
116 | 0 | pool, set->redirect_envelope_from, |
117 | 0 | &set->parsed.redirect_envelope_from)) { |
118 | 0 | *error_r = t_strdup_printf("sieve_redirect_envelope_from: " |
119 | 0 | "Invalid address source '%s'", |
120 | 0 | set->redirect_envelope_from); |
121 | 0 | return FALSE; |
122 | 0 | } |
123 | | |
124 | 0 | if (*set->user_email != '\0' && |
125 | 0 | smtp_address_parse_path(pool, set->user_email, |
126 | 0 | SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL, |
127 | 0 | &address, &error) < 0) { |
128 | 0 | *error_r = t_strdup_printf( |
129 | 0 | "sieve_user_email: Invalid SMTP address '%s': %s", |
130 | 0 | set->user_email, error); |
131 | 0 | return FALSE; |
132 | 0 | } |
133 | 0 | set->parsed.user_email = address; |
134 | |
|
135 | | #ifdef CONFIG_BINARY |
136 | | if (array_is_created(&set->plugins) && |
137 | | array_not_empty(&set->plugins) && |
138 | | faccessat(AT_FDCWD, set->plugin_dir, R_OK | X_OK, AT_EACCESS) < 0) { |
139 | | *error_r = t_strdup_printf( |
140 | | "sieve_plugin_dir: access(%s) failed: %m", |
141 | | set->plugin_dir); |
142 | | return FALSE; |
143 | | } |
144 | | #endif |
145 | 0 | return TRUE; |
146 | 0 | } |
147 | | /* </settings checks> */ |