1 #ifndef SMTP_PARAMS_H
2 #define SMTP_PARAMS_H
3 
4 #include "array-decl.h"
5 
6 #include "smtp-common.h"
7 
8 struct smtp_param;
9 
10 ARRAY_DEFINE_TYPE(smtp_param, struct smtp_param);
11 
12 enum smtp_param_mail_body_type {
13 	SMTP_PARAM_MAIL_BODY_TYPE_UNSPECIFIED = 0,
14 	SMTP_PARAM_MAIL_BODY_TYPE_7BIT,
15 	SMTP_PARAM_MAIL_BODY_TYPE_8BITMIME,
16 	SMTP_PARAM_MAIL_BODY_TYPE_BINARYMIME,
17 	SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION
18 };
19 
20 enum smtp_param_mail_ret {
21 	SMTP_PARAM_MAIL_RET_UNSPECIFIED = 0,
22 	SMTP_PARAM_MAIL_RET_HDRS,
23 	SMTP_PARAM_MAIL_RET_FULL,
24 };
25 
26 enum smtp_param_rcpt_notify {
27 	SMTP_PARAM_RCPT_NOTIFY_UNSPECIFIED = 0x00,
28 	SMTP_PARAM_RCPT_NOTIFY_SUCCESS   	 = 0x01,
29 	SMTP_PARAM_RCPT_NOTIFY_FAILURE     = 0x02,
30 	SMTP_PARAM_RCPT_NOTIFY_DELAY       = 0x04,
31 	SMTP_PARAM_RCPT_NOTIFY_NEVER       = 0x80
32 };
33 
34 struct smtp_param {
35 	const char *keyword;
36 	const char *value;
37 };
38 
39 struct smtp_params_mail {
40 	/* AUTH: RFC 4954 */
41 	const struct smtp_address *auth;
42 	/* BODY: RFC 6152 */
43 	struct {
44 		enum smtp_param_mail_body_type type;
45 		const char *ext;
46 	} body;
47 	/* ENVID: RFC 3461, Section 4.4 */
48 	const char *envid;
49 	/* RET: RFC 3461, Section 4.3 */
50 	enum smtp_param_mail_ret ret;
51 	/* SIZE: RFC 1870 */
52 	uoff_t size;
53 	/* extra parameters */
54 	ARRAY_TYPE(smtp_param) extra_params;
55 };
56 
57 struct smtp_params_rcpt {
58 	/* ORCPT: RFC 3461, Section 4.2 */
59 	struct {
60 		const char *addr_type;
61 		/* addr_type=rfc822 */
62 		const struct smtp_address *addr;
63 		/* raw value */
64 		const char *addr_raw;
65 	} orcpt;
66 	/* NOTIFY: RFC 3461, Section 4.1 */
67 	enum smtp_param_rcpt_notify notify;
68 	/* extra parameters */
69 	ARRAY_TYPE(smtp_param) extra_params;
70 };
71 
72 enum smtp_param_parse_error {
73 	SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX = 0,
74 	SMTP_PARAM_PARSE_ERROR_NOT_SUPPORTED
75 };
76 
77 /*
78  * Common
79  */
80 
81 /* parse */
82 
83 int smtp_param_parse(pool_t pool, const char *text,
84 		     struct smtp_param *param_r, const char **error_r);
85 
86 /* manipulate */
87 
88 void smtp_params_copy(pool_t pool, ARRAY_TYPE(smtp_param) *dst,
89 		      const ARRAY_TYPE(smtp_param) *src) ATTR_NULL(3);
90 
91 void smtp_params_add_one(ARRAY_TYPE(smtp_param) *params, pool_t pool,
92 			 const char *keyword, const char *value);
93 void smtp_params_add_encoded(ARRAY_TYPE(smtp_param) *params, pool_t pool,
94 			     const char *keyword, const unsigned char *value,
95 			     size_t value_len);
96 
97 bool smtp_params_drop_one(ARRAY_TYPE(smtp_param) *params, const char *keyword,
98 			  const char **value_r);
99 
100 /* write */
101 
102 void smtp_param_write(string_t *out, const struct smtp_param *param);
103 
104 /* evaluate */
105 
106 const struct smtp_param *
107 smtp_params_get_param(const ARRAY_TYPE(smtp_param) *params,
108 		      const char *keyword);
109 int smtp_params_decode_param(const ARRAY_TYPE(smtp_param) *params,
110 			     const char *keyword, string_t **value_r,
111 			     bool allow_nul, const char **error_r);
112 
113 bool smtp_params_equal(const ARRAY_TYPE(smtp_param) *params1,
114 		       const ARRAY_TYPE(smtp_param) *params2);
115 
116 /*
117  * MAIL parameters
118  */
119 
120 /* parse */
121 
122 int smtp_params_mail_parse(pool_t pool, const char *args,
123 			   enum smtp_capability caps,
124 			   const char *const *param_extensions,
125 			   const char *const *body_param_extensions,
126 			   struct smtp_params_mail *params_r,
127 			   enum smtp_param_parse_error *error_code_r,
128 			   const char **error_r) ATTR_NULL(4, 5);
129 
130 /* manipulate */
131 
132 void smtp_params_mail_copy(pool_t pool, struct smtp_params_mail *dst,
133 			   const struct smtp_params_mail *src);
134 
135 void smtp_params_mail_add_extra(struct smtp_params_mail *params, pool_t pool,
136 				const char *keyword, const char *value)
137 				ATTR_NULL(4);
138 void smtp_params_mail_encode_extra(struct smtp_params_mail *params, pool_t pool,
139 				   const char *keyword,
140 				   const unsigned char *value,
141 				   size_t value_len);
142 bool smtp_params_mail_drop_extra(struct smtp_params_mail *params,
143 				 const char *keyword, const char **value_r)
144 				 ATTR_NULL(3);
145 
146 /* write */
147 
148 void smtp_params_mail_write(string_t *buffer, enum smtp_capability caps,
149 			    const char *const *extra_params,
150 			    const struct smtp_params_mail *params) ATTR_NULL(3);
151 
152 /* evaluate */
153 
154 const struct smtp_param *
155 smtp_params_mail_get_extra(const struct smtp_params_mail *params,
156 			   const char *keyword);
157 int smtp_params_mail_decode_extra(const struct smtp_params_mail *params,
158 				  const char *keyword, string_t **value_r,
159 				  bool allow_nul, const char **error_r);
160 
161 /* events */
162 
163 void smtp_params_mail_add_to_event(const struct smtp_params_mail *params,
164 				   struct event *event);
165 
166 /*
167  * RCPT parameters
168  */
169 
170 /* parse */
171 
172 enum smtp_param_rcpt_parse_flags {
173 	/* Allow address values without a domain part */
174 	SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART = BIT(0),
175 };
176 
177 int smtp_params_rcpt_parse(pool_t pool, const char *args,
178 			   enum smtp_param_rcpt_parse_flags flags,
179 			   enum smtp_capability caps,
180 			   const char *const *param_extensions,
181 			   struct smtp_params_rcpt *params_r,
182 			   enum smtp_param_parse_error *error_code_r,
183 			   const char **error_r) ATTR_NULL(4);
184 
185 /* manipulate */
186 
187 void smtp_params_rcpt_copy(pool_t pool, struct smtp_params_rcpt *dst,
188 			   const struct smtp_params_rcpt *src) ATTR_NULL(3);
189 
190 void smtp_params_rcpt_add_extra(struct smtp_params_rcpt *params, pool_t pool,
191 				const char *keyword, const char *value)
192 				ATTR_NULL(4);
193 void smtp_params_rcpt_encode_extra(struct smtp_params_rcpt *params, pool_t pool,
194 				   const char *keyword,
195 				   const unsigned char *value,
196 				   size_t value_len);
197 bool smtp_params_rcpt_drop_extra(struct smtp_params_rcpt *params,
198 				 const char *keyword, const char **value_r)
199 				 ATTR_NULL(3);
200 
201 void smtp_params_rcpt_set_orcpt(struct smtp_params_rcpt *params, pool_t pool,
202 				struct smtp_address *rcpt);
203 
204 /* write */
205 
206 void smtp_params_rcpt_write(string_t *buffer, enum smtp_capability caps,
207 			    const char *const *extra_params,
208 			    const struct smtp_params_rcpt *params) ATTR_NULL(3);
209 
210 /* evaluate */
211 
212 const struct smtp_param *
213 smtp_params_rcpt_get_extra(const struct smtp_params_rcpt *params,
214 			   const char *keyword);
215 int smtp_params_rcpt_decode_extra(const struct smtp_params_rcpt *params,
216 				  const char *keyword, string_t **value_r,
217 				  bool allow_nul, const char **error_r);
218 
219 bool smtp_params_rcpt_equal(const struct smtp_params_rcpt *params1,
220 			    const struct smtp_params_rcpt *params2);
221 
222 static inline bool
smtp_params_rcpt_has_orcpt(const struct smtp_params_rcpt * params)223 smtp_params_rcpt_has_orcpt(const struct smtp_params_rcpt *params)
224 {
225 	return (params->orcpt.addr_type != NULL);
226 }
227 
228 /* events */
229 
230 void smtp_params_rcpt_add_to_event(const struct smtp_params_rcpt *params,
231 				   struct event *event);
232 
233 #endif
234