Coverage Report

Created: 2026-03-15 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}