1 /* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
2
3 #include "lib.h"
4 #include "settings-parser.h"
5 #include "mail-storage-settings.h"
6 #include "imapc-settings.h"
7
8 #include <stddef.h>
9
10 #undef DEF
11 #define DEF(type, name) \
12 SETTING_DEFINE_STRUCT_##type(#name, name, struct imapc_settings)
13
14 static bool imapc_settings_check(void *_set, pool_t pool, const char **error_r);
15
16 static const struct setting_define imapc_setting_defines[] = {
17 DEF(STR, imapc_host),
18 DEF(IN_PORT, imapc_port),
19
20 DEF(STR_VARS, imapc_user),
21 DEF(STR_VARS, imapc_master_user),
22 DEF(STR, imapc_password),
23 DEF(STR, imapc_sasl_mechanisms),
24
25 DEF(ENUM, imapc_ssl),
26 DEF(BOOL, imapc_ssl_verify),
27
28 DEF(STR, imapc_features),
29 DEF(STR, imapc_rawlog_dir),
30 DEF(STR, imapc_list_prefix),
31 DEF(TIME, imapc_cmd_timeout),
32 DEF(TIME, imapc_max_idle_time),
33 DEF(UINT, imapc_connection_retry_count),
34 DEF(TIME_MSECS, imapc_connection_retry_interval),
35 DEF(SIZE, imapc_max_line_length),
36
37 DEF(STR, pop3_deleted_flag),
38
39 SETTING_DEFINE_LIST_END
40 };
41
42 static const struct imapc_settings imapc_default_settings = {
43 .imapc_host = "",
44 .imapc_port = 143,
45
46 .imapc_user = "",
47 .imapc_master_user = "",
48 .imapc_password = "",
49 .imapc_sasl_mechanisms = "",
50
51 .imapc_ssl = "no:imaps:starttls",
52 .imapc_ssl_verify = TRUE,
53
54 .imapc_features = "",
55 .imapc_rawlog_dir = "",
56 .imapc_list_prefix = "",
57 .imapc_cmd_timeout = 5*60,
58 .imapc_max_idle_time = 60*29,
59 .imapc_connection_retry_count = 1,
60 .imapc_connection_retry_interval = 1000,
61 .imapc_max_line_length = 0,
62
63 .pop3_deleted_flag = ""
64 };
65
66 static const struct setting_parser_info imapc_setting_parser_info = {
67 .module_name = "imapc",
68 .defines = imapc_setting_defines,
69 .defaults = &imapc_default_settings,
70
71 .type_offset = SIZE_MAX,
72 .struct_size = sizeof(struct imapc_settings),
73
74 .parent_offset = SIZE_MAX,
75 .parent = &mail_user_setting_parser_info,
76
77 .check_func = imapc_settings_check
78 };
79
imapc_get_setting_parser_info(void)80 const struct setting_parser_info *imapc_get_setting_parser_info(void)
81 {
82 return &imapc_setting_parser_info;
83 }
84
85 /* <settings checks> */
86 struct imapc_feature_list {
87 const char *name;
88 enum imapc_features num;
89 };
90
91 static const struct imapc_feature_list imapc_feature_list[] = {
92 { "rfc822.size", IMAPC_FEATURE_RFC822_SIZE },
93 { "guid-forced", IMAPC_FEATURE_GUID_FORCED },
94 { "fetch-headers", IMAPC_FEATURE_FETCH_HEADERS },
95 { "gmail-migration", IMAPC_FEATURE_GMAIL_MIGRATION },
96 { "search", IMAPC_FEATURE_SEARCH },
97 { "zimbra-workarounds", IMAPC_FEATURE_ZIMBRA_WORKAROUNDS },
98 { "no-examine", IMAPC_FEATURE_NO_EXAMINE },
99 { "proxyauth", IMAPC_FEATURE_PROXYAUTH },
100 { "fetch-msn-workarounds", IMAPC_FEATURE_FETCH_MSN_WORKAROUNDS },
101 { "fetch-fix-broken-mails", IMAPC_FEATURE_FETCH_FIX_BROKEN_MAILS },
102 { "modseq", IMAPC_FEATURE_MODSEQ },
103 { "delay-login", IMAPC_FEATURE_DELAY_LOGIN },
104 { "fetch-bodystructure", IMAPC_FEATURE_FETCH_BODYSTRUCTURE },
105 { "send-id", IMAPC_FEATURE_SEND_ID },
106 { "fetch-empty-is-expunged", IMAPC_FEATURE_FETCH_EMPTY_IS_EXPUNGED },
107 { "no-msn-updates", IMAPC_FEATURE_NO_MSN_UPDATES },
108 { "acl", IMAPC_FEATURE_ACL },
109 { NULL, 0 }
110 };
111
112 static int
imapc_settings_parse_throttle(struct imapc_settings * set,const char * throttle_str,const char ** error_r)113 imapc_settings_parse_throttle(struct imapc_settings *set,
114 const char *throttle_str, const char **error_r)
115 {
116 const char *const *tmp;
117
118 tmp = t_strsplit(throttle_str, ":");
119 if (str_array_length(tmp) != 3 ||
120 str_to_uint(tmp[0], &set->throttle_init_msecs) < 0 ||
121 str_to_uint(tmp[1], &set->throttle_max_msecs) < 0 ||
122 str_to_uint(tmp[2], &set->throttle_shrink_min_msecs) < 0) {
123 *error_r = "imapc_features: Invalid throttle settings";
124 return -1;
125 }
126 return 0;
127 }
128
129 static int
imapc_settings_parse_features(struct imapc_settings * set,const char ** error_r)130 imapc_settings_parse_features(struct imapc_settings *set,
131 const char **error_r)
132 {
133 enum imapc_features features = 0;
134 const struct imapc_feature_list *list;
135 const char *const *str;
136
137 str = t_strsplit_spaces(set->imapc_features, " ,");
138 for (; *str != NULL; str++) {
139 list = imapc_feature_list;
140 for (; list->name != NULL; list++) {
141 if (strcasecmp(*str, list->name) == 0) {
142 features |= list->num;
143 break;
144 }
145 }
146 if (strncasecmp(*str, "throttle:", 9) == 0) {
147 if (imapc_settings_parse_throttle(set, *str + 9, error_r) < 0)
148 return -1;
149 continue;
150 }
151 if (list->name == NULL) {
152 *error_r = t_strdup_printf("imapc_features: "
153 "Unknown feature: %s", *str);
154 return -1;
155 }
156 }
157 set->parsed_features = features;
158 return 0;
159 }
160
imapc_settings_check(void * _set,pool_t pool ATTR_UNUSED,const char ** error_r)161 static bool imapc_settings_check(void *_set, pool_t pool ATTR_UNUSED,
162 const char **error_r)
163 {
164 struct imapc_settings *set = _set;
165
166 if (set->imapc_max_idle_time == 0) {
167 *error_r = "imapc_max_idle_time must not be 0";
168 return FALSE;
169 }
170 if (imapc_settings_parse_features(set, error_r) < 0)
171 return FALSE;
172 return TRUE;
173 }
174