Coverage Report

Created: 2026-04-12 07:00

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