Coverage Report

Created: 2026-08-08 06:43

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