summaryrefslogtreecommitdiffstats
path: root/src/lib-smtp/smtp-params.h
blob: 34568ce070570f182b79a031b27eaa68716ac8ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#ifndef SMTP_PARAMS_H
#define SMTP_PARAMS_H

#include "array-decl.h"

#include "smtp-common.h"

struct smtp_param;

ARRAY_DEFINE_TYPE(smtp_param, struct smtp_param);

enum smtp_param_mail_body_type {
	SMTP_PARAM_MAIL_BODY_TYPE_UNSPECIFIED = 0,
	SMTP_PARAM_MAIL_BODY_TYPE_7BIT,
	SMTP_PARAM_MAIL_BODY_TYPE_8BITMIME,
	SMTP_PARAM_MAIL_BODY_TYPE_BINARYMIME,
	SMTP_PARAM_MAIL_BODY_TYPE_EXTENSION
};

enum smtp_param_mail_ret {
	SMTP_PARAM_MAIL_RET_UNSPECIFIED = 0,
	SMTP_PARAM_MAIL_RET_HDRS,
	SMTP_PARAM_MAIL_RET_FULL,
};

enum smtp_param_rcpt_notify {
	SMTP_PARAM_RCPT_NOTIFY_UNSPECIFIED = 0x00,
	SMTP_PARAM_RCPT_NOTIFY_SUCCESS   	 = 0x01,
	SMTP_PARAM_RCPT_NOTIFY_FAILURE     = 0x02,
	SMTP_PARAM_RCPT_NOTIFY_DELAY       = 0x04,
	SMTP_PARAM_RCPT_NOTIFY_NEVER       = 0x80
};

struct smtp_param {
	const char *keyword;
	const char *value;
};

struct smtp_params_mail {
	/* AUTH: RFC 4954 */
	const struct smtp_address *auth;
	/* BODY: RFC 6152 */
	struct {
		enum smtp_param_mail_body_type type;
		const char *ext;
	} body;
	/* ENVID: RFC 3461, Section 4.4 */
	const char *envid;
	/* RET: RFC 3461, Section 4.3 */
	enum smtp_param_mail_ret ret;
	/* SIZE: RFC 1870 */
	uoff_t size;
	/* extra parameters */
	ARRAY_TYPE(smtp_param) extra_params;
};

struct smtp_params_rcpt {
	/* ORCPT: RFC 3461, Section 4.2 */
	struct {
		const char *addr_type;
		/* addr_type=rfc822 */
		const struct smtp_address *addr;
		/* raw value */
		const char *addr_raw;
	} orcpt;
	/* NOTIFY: RFC 3461, Section 4.1 */
	enum smtp_param_rcpt_notify notify;
	/* extra parameters */
	ARRAY_TYPE(smtp_param) extra_params;
};

enum smtp_param_parse_error {
	SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX = 0,
	SMTP_PARAM_PARSE_ERROR_NOT_SUPPORTED
};

/*
 * Common
 */

/* parse */

int smtp_param_parse(pool_t pool, const char *text,
		     struct smtp_param *param_r, const char **error_r);

/* manipulate */

void smtp_params_copy(pool_t pool, ARRAY_TYPE(smtp_param) *dst,
		      const ARRAY_TYPE(smtp_param) *src) ATTR_NULL(3);

void smtp_params_add_one(ARRAY_TYPE(smtp_param) *params, pool_t pool,
			 const char *keyword, const char *value);
void smtp_params_add_encoded(ARRAY_TYPE(smtp_param) *params, pool_t pool,
			     const char *keyword, const unsigned char *value,
			     size_t value_len);

bool smtp_params_drop_one(ARRAY_TYPE(smtp_param) *params, const char *keyword,
			  const char **value_r);

/* write */

void smtp_param_write(string_t *out, const struct smtp_param *param);

/* evaluate */

const struct smtp_param *
smtp_params_get_param(const ARRAY_TYPE(smtp_param) *params,
		      const char *keyword);
int smtp_params_decode_param(const ARRAY_TYPE(smtp_param) *params,
			     const char *keyword, string_t **value_r,
			     bool allow_nul, const char **error_r);

bool smtp_params_equal(const ARRAY_TYPE(smtp_param) *params1,
		       const ARRAY_TYPE(smtp_param) *params2);

/*
 * MAIL parameters
 */

/* parse */

int smtp_params_mail_parse(pool_t pool, const char *args,
			   enum smtp_capability caps,
			   const char *const *param_extensions,
			   const char *const *body_param_extensions,
			   struct smtp_params_mail *params_r,
			   enum smtp_param_parse_error *error_code_r,
			   const char **error_r) ATTR_NULL(4, 5);

/* manipulate */

void smtp_params_mail_copy(pool_t pool, struct smtp_params_mail *dst,
			   const struct smtp_params_mail *src);

void smtp_params_mail_add_extra(struct smtp_params_mail *params, pool_t pool,
				const char *keyword, const char *value)
				ATTR_NULL(4);
void smtp_params_mail_encode_extra(struct smtp_params_mail *params, pool_t pool,
				   const char *keyword,
				   const unsigned char *value,
				   size_t value_len);
bool smtp_params_mail_drop_extra(struct smtp_params_mail *params,
				 const char *keyword, const char **value_r)
				 ATTR_NULL(3);

/* write */

void smtp_params_mail_write(string_t *buffer, enum smtp_capability caps,
			    const char *const *extra_params,
			    const struct smtp_params_mail *params) ATTR_NULL(3);

/* evaluate */

const struct smtp_param *
smtp_params_mail_get_extra(const struct smtp_params_mail *params,
			   const char *keyword);
int smtp_params_mail_decode_extra(const struct smtp_params_mail *params,
				  const char *keyword, string_t **value_r,
				  bool allow_nul, const char **error_r);

/* events */

void smtp_params_mail_add_to_event(const struct smtp_params_mail *params,
				   struct event *event);

/*
 * RCPT parameters
 */

/* parse */

enum smtp_param_rcpt_parse_flags {
	/* Allow address values without a domain part */
	SMTP_PARAM_RCPT_FLAG_ORCPT_ALLOW_LOCALPART = BIT(0),
};

int smtp_params_rcpt_parse(pool_t pool, const char *args,
			   enum smtp_param_rcpt_parse_flags flags,
			   enum smtp_capability caps,
			   const char *const *param_extensions,
			   struct smtp_params_rcpt *params_r,
			   enum smtp_param_parse_error *error_code_r,
			   const char **error_r) ATTR_NULL(4);

/* manipulate */

void smtp_params_rcpt_copy(pool_t pool, struct smtp_params_rcpt *dst,
			   const struct smtp_params_rcpt *src) ATTR_NULL(3);

void smtp_params_rcpt_add_extra(struct smtp_params_rcpt *params, pool_t pool,
				const char *keyword, const char *value)
				ATTR_NULL(4);
void smtp_params_rcpt_encode_extra(struct smtp_params_rcpt *params, pool_t pool,
				   const char *keyword,
				   const unsigned char *value,
				   size_t value_len);
bool smtp_params_rcpt_drop_extra(struct smtp_params_rcpt *params,
				 const char *keyword, const char **value_r)
				 ATTR_NULL(3);

void smtp_params_rcpt_set_orcpt(struct smtp_params_rcpt *params, pool_t pool,
				struct smtp_address *rcpt);

/* write */

void smtp_params_rcpt_write(string_t *buffer, enum smtp_capability caps,
			    const char *const *extra_params,
			    const struct smtp_params_rcpt *params) ATTR_NULL(3);

/* evaluate */

const struct smtp_param *
smtp_params_rcpt_get_extra(const struct smtp_params_rcpt *params,
			   const char *keyword);
int smtp_params_rcpt_decode_extra(const struct smtp_params_rcpt *params,
				  const char *keyword, string_t **value_r,
				  bool allow_nul, const char **error_r);

bool smtp_params_rcpt_equal(const struct smtp_params_rcpt *params1,
			    const struct smtp_params_rcpt *params2);

static inline bool
smtp_params_rcpt_has_orcpt(const struct smtp_params_rcpt *params)
{
	return (params->orcpt.addr_type != NULL);
}

/* events */

void smtp_params_rcpt_add_to_event(const struct smtp_params_rcpt *params,
				   struct event *event);

#endif