1 #ifndef SIEVE_TYPES_H
2 #define SIEVE_TYPES_H
3 
4 #include "lib.h"
5 #include "smtp-address.h"
6 
7 #include <stdio.h>
8 
9 /*
10  * Forward declarations
11  */
12 
13 struct smtp_params_mail;
14 struct smtp_params_rcpt;
15 
16 struct sieve_instance;
17 struct sieve_callbacks;
18 
19 struct sieve_script;
20 struct sieve_binary;
21 
22 struct sieve_message_data;
23 struct sieve_script_env;
24 struct sieve_exec_status;
25 struct sieve_trace_log;
26 
27 /*
28  * System environment
29  */
30 
31 enum sieve_flag {
32 	/* Relative paths are resolved to HOME */
33 	SIEVE_FLAG_HOME_RELATIVE = (1 << 0)
34 };
35 
36 /* Sieve evaluation can be performed at various different points as messages
37    are processed. */
38 enum sieve_env_location {
39 	/* Unknown */
40 	SIEVE_ENV_LOCATION_UNKNOWN = 0,
41 	/* "MDA" - evaluation is being performed by a Mail Delivery Agent */
42 	SIEVE_ENV_LOCATION_MDA,
43 	/* "MTA" - the Sieve script is being evaluated by a Message Transfer Agent */
44 	SIEVE_ENV_LOCATION_MTA,
45 	/* "MS"  - evaluation is being performed by a Message Store */
46 	SIEVE_ENV_LOCATION_MS
47 };
48 
49 /* The point relative to final delivery where the Sieve script is being
50    evaluated. */
51 enum sieve_delivery_phase {
52 	SIEVE_DELIVERY_PHASE_UNKNOWN = 0,
53 	SIEVE_DELIVERY_PHASE_PRE,
54 	SIEVE_DELIVERY_PHASE_DURING,
55 	SIEVE_DELIVERY_PHASE_POST,
56 };
57 
58 struct sieve_environment {
59 	const char *hostname;
60 	const char *domainname;
61 
62 	const char *base_dir;
63 	const char *username;
64 	const char *home_dir;
65 	const char *temp_dir;
66 
67 	struct event *event_parent;
68 
69 	enum sieve_flag flags;
70 	enum sieve_env_location location;
71 	enum sieve_delivery_phase delivery_phase;
72 };
73 
74 /*
75  * Callbacks
76  */
77 
78 struct sieve_callbacks {
79 	const char *(*get_homedir)(void *context);
80 	const char *(*get_setting)(void *context, const char *identifier);
81 };
82 
83 /*
84  * Errors
85  */
86 
87 enum sieve_error {
88 	SIEVE_ERROR_NONE = 0,
89 
90 	/* Temporary internal error */
91 	SIEVE_ERROR_TEMP_FAILURE,
92 	/* It's not possible to do the wanted operation */
93 	SIEVE_ERROR_NOT_POSSIBLE,
94 	/* Invalid parameters (eg. script name not valid) */
95 	SIEVE_ERROR_BAD_PARAMS,
96 	/* No permission to do the request */
97 	SIEVE_ERROR_NO_PERMISSION,
98 	/* Out of disk space */
99 	SIEVE_ERROR_NO_QUOTA,
100 	/* Item (e.g. script or binary) cannot be found */
101 	SIEVE_ERROR_NOT_FOUND,
102 	/* Item (e.g. script or binary) already exists */
103 	SIEVE_ERROR_EXISTS,
104 	/* Referenced item (e.g. script or binary) is not valid or currupt */
105 	SIEVE_ERROR_NOT_VALID,
106 	/* Not allowed to perform the operation because the item is in active use */
107 	SIEVE_ERROR_ACTIVE,
108 	/* Operation exceeds resource limit */
109 	SIEVE_ERROR_RESOURCE_LIMIT,
110 };
111 
112 /*
113  * Compile flags
114  */
115 
116 enum sieve_compile_flags {
117 	/* No global extensions are allowed
118 	 *  (as marked by sieve_global_extensions setting)
119 	 */
120 	SIEVE_COMPILE_FLAG_NOGLOBAL = (1<<0),
121 	/* Script is being uploaded (usually through ManageSieve) */
122 	SIEVE_COMPILE_FLAG_UPLOADED = (1<<1),
123 	/* Script is being activated (usually through ManageSieve) */
124 	SIEVE_COMPILE_FLAG_ACTIVATED = (1<<2),
125 	/* Compiled for environment with no access to envelope */
126 	SIEVE_COMPILE_FLAG_NO_ENVELOPE = (1<<3)
127 };
128 
129 /*
130  * Message data
131  *
132  * - The mail message + envelope data
133  */
134 
135 struct sieve_message_data {
136 	struct mail *mail;
137 
138 	const char *auth_user;
139 	const char *id;
140 
141 	struct {
142 		const struct smtp_address *mail_from;
143 		const struct smtp_params_mail *mail_params;
144 
145 		const struct smtp_address *rcpt_to;
146 		const struct smtp_params_rcpt *rcpt_params;
147 	} envelope;
148 };
149 
150 /*
151  * Runtime flags
152  */
153 
154 enum sieve_execute_flags {
155 	/* No global extensions are allowed
156 	 *  (as marked by sieve_global_extensions setting)
157 	 */
158 	SIEVE_EXECUTE_FLAG_NOGLOBAL = (1<<0),
159 	/* Do not execute (implicit keep) at the end */
160 	SIEVE_EXECUTE_FLAG_DEFER_KEEP = (1<<1),
161 	/* There is no envelope */
162 	SIEVE_EXECUTE_FLAG_NO_ENVELOPE = (1<<2),
163 	/* Skip sending responses */
164 	SIEVE_EXECUTE_FLAG_SKIP_RESPONSES = (1<<3),
165 	/* Log result as info (when absent, only debug logging is performed) */
166 	SIEVE_EXECUTE_FLAG_LOG_RESULT = (1<<4),
167 };
168 
169 /*
170  * Runtime trace settings
171  */
172 
173 typedef enum {
174 	SIEVE_TRLVL_NONE = 0,
175 	SIEVE_TRLVL_ACTIONS,
176 	SIEVE_TRLVL_COMMANDS,
177 	SIEVE_TRLVL_TESTS,
178 	SIEVE_TRLVL_MATCHING
179 } sieve_trace_level_t;
180 
181 enum {
182 	SIEVE_TRFLG_DEBUG = (1 << 0),
183 	SIEVE_TRFLG_ADDRESSES = (1 << 1)
184 };
185 
186 struct sieve_trace_config {
187 	sieve_trace_level_t level;
188 	unsigned int flags;
189 };
190 
191 /*
192  * Duplicate checking
193  */
194 
195 enum sieve_duplicate_check_result {
196 	SIEVE_DUPLICATE_CHECK_RESULT_EXISTS = 1,
197 	SIEVE_DUPLICATE_CHECK_RESULT_NOT_FOUND = 0,
198 	SIEVE_DUPLICATE_CHECK_RESULT_FAILURE = -1,
199 	SIEVE_DUPLICATE_CHECK_RESULT_TEMP_FAILURE = -2,
200 };
201 
202 /*
203  * Script environment
204  *
205  * - Environment for currently executing script
206  */
207 
208 struct sieve_script_env {
209 	/* Mail-related */
210 	struct mail_user *user;
211 	const struct message_address *postmaster_address;
212 	const char *default_mailbox;
213 	bool mailbox_autocreate;
214 	bool mailbox_autosubscribe;
215 
216 	/* External context data */
217 
218 	void *script_context;
219 
220 	/* Callbacks */
221 
222 	/* Interface for sending mail */
223 	void *(*smtp_start)
224 		(const struct sieve_script_env *senv,
225 			const struct smtp_address *mail_from);
226 	/* Add a new recipient */
227 	void (*smtp_add_rcpt)
228 		(const struct sieve_script_env *senv, void *handle,
229 			const struct smtp_address *rcpt_to);
230 	/* Get an output stream where the message can be written to. The recipients
231 	   must already be added before calling this. */
232 	struct ostream *(*smtp_send)
233 		(const struct sieve_script_env *senv, void *handle);
234 	/* Abort the SMTP transaction after smtp_send() is already issued */
235 	void (*smtp_abort)
236 		(const struct sieve_script_env *senv, void *handle);
237 	/* Returns 1 on success, 0 on permanent failure, -1 on temporary failure. */
238 	int (*smtp_finish)
239 		(const struct sieve_script_env *senv, void *handle,
240 			const char **error_r);
241 
242 	/* Interface for marking and checking duplicates */
243 	void *(*duplicate_transaction_begin)(
244 		const struct sieve_script_env *senv);
245 	void (*duplicate_transaction_commit)(void **_dup_trans);
246 	void (*duplicate_transaction_rollback)(void **_dup_trans);
247 
248 	enum sieve_duplicate_check_result
249 	(*duplicate_check)(void *dup_trans, const struct sieve_script_env *senv,
250 			   const void *id, size_t id_size);
251 	void (*duplicate_mark)(void *dup_trans,
252 			       const struct sieve_script_env *senv,
253 			       const void *id, size_t id_size, time_t time);
254 
255 	/* Interface for rejecting mail */
256 	int (*reject_mail)(const struct sieve_script_env *senv,
257 		const struct smtp_address *recipient, const char *reason);
258 
259 	/* Interface for amending result messages */
260 	const char *
261 	(*result_amend_log_message)(const struct sieve_script_env *senv,
262 				    enum log_type log_type,
263 				    const char *message);
264 
265 	/* Execution status record */
266 	struct sieve_exec_status *exec_status;
267 
268 	/* Runtime trace*/
269 	struct sieve_trace_log *trace_log;
270 	struct sieve_trace_config trace_config;
271 };
272 
273 #define SIEVE_SCRIPT_DEFAULT_MAILBOX(senv) \
274 	(senv->default_mailbox == NULL ? "INBOX" : senv->default_mailbox )
275 
276 /*
277  * Resource usage
278  */
279 
280 struct sieve_resource_usage {
281 	/* The total amount of system + user CPU time consumed while executing
282 	   the Sieve script. */
283 	unsigned int cpu_time_msecs;
284 };
285 
286 /*
287  * Script execution status
288  */
289 
290 struct sieve_exec_status {
291 	struct mail_storage *last_storage;
292 
293 	struct sieve_resource_usage resource_usage;
294 
295 	bool message_saved:1;
296 	bool message_forwarded:1;
297 	bool tried_default_save:1;
298 	bool keep_original:1;
299 	bool store_failed:1;
300 	bool significant_action_executed:1;
301 };
302 
303 /*
304  * Execution exit codes
305  */
306 
307 enum sieve_execution_exitcode {
308 	SIEVE_EXEC_OK         	        = 1,
309 	SIEVE_EXEC_FAILURE              = 0,
310 	SIEVE_EXEC_TEMP_FAILURE         = -1,
311 	SIEVE_EXEC_BIN_CORRUPT          = -2,
312 	SIEVE_EXEC_KEEP_FAILED          = -3,
313 	SIEVE_EXEC_RESOURCE_LIMIT       = -4,
314 };
315 
316 #endif
317