/src/pigeonhole/src/testsuite/testsuite-message.c
Line | Count | Source |
1 | | /* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file |
2 | | */ |
3 | | |
4 | | #include "lib.h" |
5 | | #include "str.h" |
6 | | #include "istream.h" |
7 | | #include "smtp-params.h" |
8 | | #include "message-address.h" |
9 | | #include "mail-storage.h" |
10 | | #include "master-service.h" |
11 | | #include "mail-raw.h" |
12 | | |
13 | | #include "sieve-common.h" |
14 | | #include "sieve-address.h" |
15 | | #include "sieve-error.h" |
16 | | #include "sieve-message.h" |
17 | | #include "sieve-interpreter.h" |
18 | | |
19 | | #include "sieve-tool.h" |
20 | | |
21 | | #include "testsuite-common.h" |
22 | | #include "testsuite-message.h" |
23 | | |
24 | | /* |
25 | | * Testsuite message environment |
26 | | */ |
27 | | |
28 | | struct testsuite_message { |
29 | | struct testsuite_message *next; |
30 | | |
31 | | struct mail_raw *mail_raw; |
32 | | }; |
33 | | |
34 | | struct sieve_message_data testsuite_msgdata; |
35 | | static struct smtp_params_rcpt testsuite_rcpt_params; |
36 | | |
37 | | static struct testsuite_message *testsuite_msg; |
38 | | |
39 | | static const char *_default_message_data = |
40 | | "From: sender@example.com\n" |
41 | | "To: recipient@example.org\n" |
42 | | "Subject: Frop!\n" |
43 | | "\n" |
44 | | "Friep!\n"; |
45 | | |
46 | | static struct smtp_address *testsuite_env_mail_from = NULL; |
47 | | static struct smtp_address *testsuite_env_rcpt_to = NULL; |
48 | | static struct smtp_address *testsuite_env_orig_rcpt_to = NULL; |
49 | | static char *testsuite_env_auth = NULL; |
50 | | |
51 | | static pool_t testsuite_msg_pool; |
52 | | static string_t *testsuite_msg_default; |
53 | | static char *testsuite_msg_id = NULL; |
54 | | |
55 | | static const struct smtp_address * |
56 | | testsuite_message_get_address(struct mail *mail, const char *header) |
57 | 0 | { |
58 | 0 | struct message_address *addr; |
59 | 0 | struct smtp_address *smtp_addr; |
60 | 0 | const char *str; |
61 | |
|
62 | 0 | if (mail_get_first_header(mail, header, &str) <= 0) |
63 | 0 | return NULL; |
64 | 0 | addr = message_address_parse(pool_datastack_create(), |
65 | 0 | (const unsigned char *)str, |
66 | 0 | strlen(str), 1, 0); |
67 | 0 | if (addr == NULL || addr->mailbox == NULL || *addr->mailbox == '\0') |
68 | 0 | return NULL; |
69 | 0 | if (smtp_address_create_from_msg_temp(addr, &smtp_addr) < 0) |
70 | 0 | return NULL; |
71 | 0 | return smtp_addr; |
72 | 0 | } |
73 | | |
74 | | static void testsuite_message_set_data(struct mail *mail) |
75 | 0 | { |
76 | 0 | const struct smtp_address *recipient = NULL, *sender = NULL; |
77 | 0 | const char *msg_id; |
78 | |
|
79 | 0 | static const struct smtp_address default_recipient = { |
80 | 0 | .localpart = "recipient", |
81 | 0 | .domain = "example.com", |
82 | 0 | }; |
83 | 0 | static const struct smtp_address default_sender = { |
84 | 0 | .localpart = "sender", |
85 | 0 | .domain = "example.com", |
86 | 0 | }; |
87 | |
|
88 | 0 | i_free(testsuite_env_mail_from); |
89 | 0 | i_free(testsuite_env_rcpt_to); |
90 | 0 | i_free(testsuite_env_orig_rcpt_to); |
91 | 0 | i_free(testsuite_env_auth); |
92 | 0 | i_free(testsuite_msg_id); |
93 | | |
94 | | /* |
95 | | * Collect necessary message data |
96 | | */ |
97 | | |
98 | | /* Get recipient address */ |
99 | 0 | recipient = testsuite_message_get_address(mail, "Envelope-To"); |
100 | 0 | if (recipient == NULL) |
101 | 0 | recipient = testsuite_message_get_address(mail, "To"); |
102 | 0 | if (recipient == NULL) |
103 | 0 | recipient = &default_recipient; |
104 | | |
105 | | /* Get sender address */ |
106 | 0 | sender = testsuite_message_get_address(mail, "Return-path"); |
107 | 0 | if (sender == NULL) |
108 | 0 | sender = testsuite_message_get_address(mail, "Sender"); |
109 | 0 | if (sender == NULL) |
110 | 0 | sender = testsuite_message_get_address(mail, "From"); |
111 | 0 | if (sender == NULL) |
112 | 0 | sender = &default_sender; |
113 | |
|
114 | 0 | testsuite_env_mail_from = smtp_address_clone(default_pool, sender); |
115 | 0 | testsuite_env_rcpt_to = smtp_address_clone(default_pool, recipient); |
116 | 0 | testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, recipient); |
117 | |
|
118 | 0 | (void)mail_get_message_id(mail, &msg_id); |
119 | 0 | testsuite_msg_id = i_strdup(msg_id); |
120 | |
|
121 | 0 | i_zero(&testsuite_msgdata); |
122 | 0 | testsuite_msgdata.mail = mail; |
123 | 0 | testsuite_msgdata.auth_user = sieve_tool_get_username(sieve_tool); |
124 | 0 | testsuite_msgdata.envelope.mail_from = testsuite_env_mail_from; |
125 | 0 | testsuite_msgdata.envelope.rcpt_to = testsuite_env_rcpt_to; |
126 | 0 | testsuite_msgdata.id = testsuite_msg_id; |
127 | |
|
128 | 0 | i_zero(&testsuite_rcpt_params); |
129 | 0 | testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to; |
130 | |
|
131 | 0 | testsuite_msgdata.envelope.rcpt_params = &testsuite_rcpt_params; |
132 | 0 | } |
133 | | |
134 | | static struct testsuite_message *testsuite_message_new(void) |
135 | 0 | { |
136 | 0 | struct testsuite_message *msg; |
137 | |
|
138 | 0 | msg = i_new(struct testsuite_message, 1); |
139 | 0 | msg->next = testsuite_msg; |
140 | 0 | testsuite_msg = msg; |
141 | |
|
142 | 0 | return msg; |
143 | 0 | } |
144 | | |
145 | | static void testsuite_message_new_string(string_t *mail_str) |
146 | 0 | { |
147 | 0 | struct mail_user *mail_raw_user = |
148 | 0 | sieve_tool_get_mail_raw_user(sieve_tool); |
149 | 0 | struct testsuite_message *msg; |
150 | |
|
151 | 0 | msg = testsuite_message_new(); |
152 | 0 | msg->mail_raw = mail_raw_open_data(mail_raw_user, mail_str); |
153 | |
|
154 | 0 | testsuite_message_set_data(msg->mail_raw->mail); |
155 | 0 | } |
156 | | |
157 | | static void testsuite_message_new_file(const char *mail_path) |
158 | 0 | { |
159 | 0 | struct mail_user *mail_raw_user = |
160 | 0 | sieve_tool_get_mail_raw_user(sieve_tool); |
161 | 0 | struct testsuite_message *msg; |
162 | |
|
163 | 0 | msg = testsuite_message_new(); |
164 | 0 | msg->mail_raw = mail_raw_open_file(mail_raw_user, mail_path); |
165 | |
|
166 | 0 | testsuite_message_set_data(msg->mail_raw->mail); |
167 | 0 | } |
168 | | |
169 | | static void testsuite_message_free(bool all) |
170 | 0 | { |
171 | 0 | struct testsuite_message *msg; |
172 | |
|
173 | 0 | if (testsuite_msg == NULL) |
174 | 0 | return; |
175 | | |
176 | 0 | msg = (all ? testsuite_msg : testsuite_msg->next); |
177 | 0 | while (msg != NULL) { |
178 | 0 | struct testsuite_message *msg_next = msg->next; |
179 | |
|
180 | 0 | mail_raw_close(&msg->mail_raw); |
181 | 0 | i_free(msg); |
182 | |
|
183 | 0 | msg = msg_next; |
184 | 0 | } |
185 | 0 | if (all) |
186 | 0 | testsuite_msg = NULL; |
187 | 0 | else |
188 | 0 | testsuite_msg->next = NULL; |
189 | 0 | } |
190 | | |
191 | | void testsuite_message_flush(void) |
192 | 0 | { |
193 | 0 | testsuite_message_free(FALSE); |
194 | 0 | } |
195 | | |
196 | | void testsuite_message_init(void) |
197 | 0 | { |
198 | 0 | testsuite_msg_pool = pool_alloconly_create("testsuite_message", 6096); |
199 | |
|
200 | 0 | testsuite_msg_default = str_new(testsuite_msg_pool, 1024); |
201 | 0 | str_append(testsuite_msg_default, _default_message_data); |
202 | |
|
203 | 0 | testsuite_message_new_string(testsuite_msg_default); |
204 | 0 | } |
205 | | |
206 | | void testsuite_message_set_default(const struct sieve_runtime_env *renv) |
207 | 0 | { |
208 | 0 | sieve_message_context_reset(renv->msgctx); |
209 | |
|
210 | 0 | testsuite_message_new_string(testsuite_msg_default); |
211 | 0 | } |
212 | | |
213 | | void testsuite_message_set_string(const struct sieve_runtime_env *renv, |
214 | | string_t *message) |
215 | 0 | { |
216 | 0 | sieve_message_context_reset(renv->msgctx); |
217 | |
|
218 | 0 | testsuite_message_new_string(message); |
219 | 0 | } |
220 | | |
221 | | void testsuite_message_set_file(const struct sieve_runtime_env *renv, |
222 | | const char *file_path) |
223 | 0 | { |
224 | 0 | sieve_message_context_reset(renv->msgctx); |
225 | |
|
226 | 0 | testsuite_message_new_file(file_path); |
227 | 0 | } |
228 | | |
229 | | void testsuite_message_set_mail(const struct sieve_runtime_env *renv, |
230 | | struct mail *mail) |
231 | 0 | { |
232 | 0 | sieve_message_context_reset(renv->msgctx); |
233 | |
|
234 | 0 | testsuite_message_set_data(mail); |
235 | 0 | } |
236 | | |
237 | | void testsuite_message_deinit(void) |
238 | 0 | { |
239 | 0 | testsuite_message_free(TRUE); |
240 | |
|
241 | 0 | i_free(testsuite_env_mail_from); |
242 | 0 | i_free(testsuite_env_rcpt_to); |
243 | 0 | i_free(testsuite_env_orig_rcpt_to); |
244 | 0 | i_free(testsuite_env_auth); |
245 | 0 | pool_unref(&testsuite_msg_pool); |
246 | 0 | i_free(testsuite_msg_id); |
247 | 0 | } |
248 | | |
249 | | void testsuite_envelope_set_sender_address(const struct sieve_runtime_env *renv, |
250 | | const struct smtp_address *address) |
251 | 0 | { |
252 | 0 | sieve_message_context_reset(renv->msgctx); |
253 | |
|
254 | 0 | i_free(testsuite_env_mail_from); |
255 | |
|
256 | 0 | testsuite_env_mail_from = smtp_address_clone(default_pool, address); |
257 | 0 | testsuite_msgdata.envelope.mail_from = testsuite_env_mail_from; |
258 | 0 | } |
259 | | |
260 | | void testsuite_envelope_set_sender(const struct sieve_runtime_env *renv, |
261 | | const char *value) |
262 | 0 | { |
263 | 0 | struct smtp_address *address = NULL; |
264 | 0 | const char *error; |
265 | |
|
266 | 0 | if (smtp_address_parse_path(pool_datastack_create(), value, |
267 | 0 | (SMTP_ADDRESS_PARSE_FLAG_ALLOW_EMPTY | |
268 | 0 | SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL), |
269 | 0 | &address, &error) < 0) { |
270 | 0 | e_error(testsuite_sieve_instance->event, |
271 | 0 | "testsuite: envelope sender address " |
272 | 0 | "'%s' is invalid: %s", value, error); |
273 | 0 | } |
274 | 0 | testsuite_envelope_set_sender_address(renv, address); |
275 | 0 | } |
276 | | |
277 | | void testsuite_envelope_set_recipient_address( |
278 | | const struct sieve_runtime_env *renv, |
279 | | const struct smtp_address *address) |
280 | 0 | { |
281 | 0 | sieve_message_context_reset(renv->msgctx); |
282 | |
|
283 | 0 | i_free(testsuite_env_rcpt_to); |
284 | 0 | i_free(testsuite_env_orig_rcpt_to); |
285 | |
|
286 | 0 | testsuite_env_rcpt_to = smtp_address_clone(default_pool, address); |
287 | 0 | testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, address); |
288 | 0 | testsuite_msgdata.envelope.rcpt_to = testsuite_env_rcpt_to; |
289 | 0 | testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to; |
290 | 0 | } |
291 | | |
292 | | void testsuite_envelope_set_recipient(const struct sieve_runtime_env *renv, |
293 | | const char *value) |
294 | 0 | { |
295 | 0 | struct smtp_address *address = NULL; |
296 | 0 | const char *error; |
297 | |
|
298 | 0 | if (smtp_address_parse_path(pool_datastack_create(), value, |
299 | 0 | (SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART | |
300 | 0 | SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL), |
301 | 0 | &address, &error) < 0) { |
302 | 0 | e_error(testsuite_sieve_instance->event, |
303 | 0 | "testsuite: envelope recipient address " |
304 | 0 | "'%s' is invalid: %s", value, error); |
305 | 0 | } |
306 | 0 | testsuite_envelope_set_recipient_address(renv, address); |
307 | 0 | } |
308 | | |
309 | | void testsuite_envelope_set_orig_recipient_address( |
310 | | const struct sieve_runtime_env *renv, |
311 | | const struct smtp_address *address) |
312 | 0 | { |
313 | 0 | sieve_message_context_reset(renv->msgctx); |
314 | |
|
315 | 0 | i_free(testsuite_env_orig_rcpt_to); |
316 | |
|
317 | 0 | testsuite_env_orig_rcpt_to = smtp_address_clone(default_pool, address); |
318 | 0 | testsuite_rcpt_params.orcpt.addr = testsuite_env_orig_rcpt_to; |
319 | 0 | } |
320 | | |
321 | | void testsuite_envelope_set_orig_recipient(const struct sieve_runtime_env *renv, |
322 | | const char *value) |
323 | 0 | { |
324 | 0 | struct smtp_address *address = NULL; |
325 | 0 | const char *error; |
326 | |
|
327 | 0 | if (smtp_address_parse_path(pool_datastack_create(), value, |
328 | 0 | (SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART | |
329 | 0 | SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL), |
330 | 0 | &address, &error) < 0) { |
331 | 0 | e_error(testsuite_sieve_instance->event, |
332 | 0 | "testsuite: envelope recipient address " |
333 | 0 | "'%s' is invalid: %s", value, error); |
334 | 0 | } |
335 | 0 | testsuite_envelope_set_orig_recipient_address(renv, address); |
336 | 0 | } |
337 | | |
338 | | void testsuite_envelope_set_auth_user(const struct sieve_runtime_env *renv, |
339 | | const char *value) |
340 | 0 | { |
341 | 0 | sieve_message_context_reset(renv->msgctx); |
342 | |
|
343 | 0 | i_free(testsuite_env_auth); |
344 | |
|
345 | 0 | testsuite_env_auth = i_strdup(value); |
346 | 0 | testsuite_msgdata.auth_user = testsuite_env_auth; |
347 | 0 | } |