xref: /openbsd-src/usr.sbin/smtpd/smtpd-api.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: smtpd-api.h,v 1.31 2016/09/03 16:06:26 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2013 Eric Faurot <eric@openbsd.org>
5  * Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef	_SMTPD_API_H_
21 #define	_SMTPD_API_H_
22 
23 #define	FILTER_API_VERSION	 52
24 
25 struct mailaddr {
26 	char	user[SMTPD_MAXLOCALPARTSIZE];
27 	char	domain[SMTPD_MAXDOMAINPARTSIZE];
28 };
29 
30 SPLAY_HEAD(_dict, dictentry);
31 SPLAY_HEAD(_tree, treeentry);
32 
33 struct tree {
34 	struct _tree	tree;
35 	size_t		count;
36 };
37 
38 struct dict {
39 	struct _dict	dict;
40 	size_t		count;
41 };
42 
43 enum filter_status {
44 	FILTER_OK,
45 	FILTER_FAIL,
46 	FILTER_CLOSE,
47 };
48 
49 enum filter_imsg {
50 	IMSG_FILTER_REGISTER,
51 	IMSG_FILTER_EVENT,
52 	IMSG_FILTER_QUERY,
53 	IMSG_FILTER_PIPE,
54 	IMSG_FILTER_RESPONSE
55 };
56 
57 /* XXX - server side requires mfa_session.c update on filter_event */
58 enum filter_event_type {
59 	EVENT_CONNECT,
60 	EVENT_RESET,
61 	EVENT_DISCONNECT,
62 	EVENT_TX_BEGIN,
63 	EVENT_TX_COMMIT,
64 	EVENT_TX_ROLLBACK,
65 };
66 
67 /* XXX - server side requires mfa_session.c update on filter_hook changes */
68 enum filter_query_type {
69 	QUERY_CONNECT,
70 	QUERY_HELO,
71 	QUERY_MAIL,
72 	QUERY_RCPT,
73 	QUERY_DATA,
74 	QUERY_EOM,
75 	QUERY_DATALINE,
76 };
77 
78 /* XXX - server side requires mfa_session.c update on filter_hook changes */
79 enum filter_hook_type {
80 	HOOK_CONNECT		= 1 << 0,
81 	HOOK_HELO		= 1 << 1,
82 	HOOK_MAIL		= 1 << 2,
83 	HOOK_RCPT		= 1 << 3,
84 	HOOK_DATA		= 1 << 4,
85 	HOOK_EOM		= 1 << 5,
86 	HOOK_RESET		= 1 << 6,
87 	HOOK_DISCONNECT		= 1 << 7,
88 	HOOK_COMMIT		= 1 << 8,
89 	HOOK_ROLLBACK		= 1 << 9,
90 	HOOK_DATALINE		= 1 << 10,
91 };
92 
93 struct filter_connect {
94 	struct sockaddr_storage	 local;
95 	struct sockaddr_storage	 remote;
96 	const char		*hostname;
97 };
98 
99 #define PROC_QUEUE_API_VERSION	2
100 
101 enum {
102 	PROC_QUEUE_OK,
103 	PROC_QUEUE_FAIL,
104 	PROC_QUEUE_INIT,
105 	PROC_QUEUE_CLOSE,
106 	PROC_QUEUE_MESSAGE_CREATE,
107 	PROC_QUEUE_MESSAGE_DELETE,
108 	PROC_QUEUE_MESSAGE_COMMIT,
109 	PROC_QUEUE_MESSAGE_FD_R,
110 	PROC_QUEUE_MESSAGE_CORRUPT,
111 	PROC_QUEUE_MESSAGE_UNCORRUPT,
112 	PROC_QUEUE_ENVELOPE_CREATE,
113 	PROC_QUEUE_ENVELOPE_DELETE,
114 	PROC_QUEUE_ENVELOPE_LOAD,
115 	PROC_QUEUE_ENVELOPE_UPDATE,
116 	PROC_QUEUE_ENVELOPE_WALK,
117 };
118 
119 #define PROC_SCHEDULER_API_VERSION	2
120 
121 struct scheduler_info;
122 
123 enum {
124 	PROC_SCHEDULER_OK,
125 	PROC_SCHEDULER_FAIL,
126 	PROC_SCHEDULER_INIT,
127 	PROC_SCHEDULER_INSERT,
128 	PROC_SCHEDULER_COMMIT,
129 	PROC_SCHEDULER_ROLLBACK,
130 	PROC_SCHEDULER_UPDATE,
131 	PROC_SCHEDULER_DELETE,
132 	PROC_SCHEDULER_HOLD,
133 	PROC_SCHEDULER_RELEASE,
134 	PROC_SCHEDULER_BATCH,
135 	PROC_SCHEDULER_MESSAGES,
136 	PROC_SCHEDULER_ENVELOPES,
137 	PROC_SCHEDULER_SCHEDULE,
138 	PROC_SCHEDULER_REMOVE,
139 	PROC_SCHEDULER_SUSPEND,
140 	PROC_SCHEDULER_RESUME,
141 };
142 
143 enum envelope_flags {
144 	EF_AUTHENTICATED	= 0x01,
145 	EF_BOUNCE		= 0x02,
146 	EF_INTERNAL		= 0x04, /* Internal expansion forward */
147 
148 	/* runstate, not saved on disk */
149 
150 	EF_PENDING		= 0x10,
151 	EF_INFLIGHT		= 0x20,
152 	EF_SUSPEND		= 0x40,
153 	EF_HOLD			= 0x80,
154 };
155 
156 struct evpstate {
157 	uint64_t		evpid;
158 	uint16_t		flags;
159 	uint16_t		retry;
160 	time_t			time;
161 };
162 
163 enum delivery_type {
164 	D_MDA,
165 	D_MTA,
166 	D_BOUNCE,
167 };
168 
169 struct scheduler_info {
170 	uint64_t		evpid;
171 	enum delivery_type	type;
172 	uint16_t		retry;
173 	time_t			creation;
174 	time_t			expire;
175 	time_t			lasttry;
176 	time_t			lastbounce;
177 	time_t			nexttry;
178 };
179 
180 #define SCHED_REMOVE		0x01
181 #define SCHED_EXPIRE		0x02
182 #define SCHED_UPDATE		0x04
183 #define SCHED_BOUNCE		0x08
184 #define SCHED_MDA		0x10
185 #define SCHED_MTA		0x20
186 
187 #define PROC_TABLE_API_VERSION	2
188 
189 struct table_open_params {
190 	uint32_t	version;
191 	char		name[LINE_MAX];
192 };
193 
194 enum table_service {
195 	K_NONE		= 0x000,
196 	K_ALIAS		= 0x001,	/* returns struct expand	*/
197 	K_DOMAIN	= 0x002,	/* returns struct destination	*/
198 	K_CREDENTIALS	= 0x004,	/* returns struct credentials	*/
199 	K_NETADDR	= 0x008,	/* returns struct netaddr	*/
200 	K_USERINFO	= 0x010,	/* returns struct userinfo	*/
201 	K_SOURCE	= 0x020,	/* returns struct source	*/
202 	K_MAILADDR	= 0x040,	/* returns struct mailaddr	*/
203 	K_ADDRNAME	= 0x080,	/* returns struct addrname	*/
204 	K_MAILADDRMAP	= 0x100,	/* returns struct maddrmap	*/
205 };
206 #define K_ANY		  0xfff
207 
208 enum {
209 	PROC_TABLE_OK,
210 	PROC_TABLE_FAIL,
211 	PROC_TABLE_OPEN,
212 	PROC_TABLE_CLOSE,
213 	PROC_TABLE_UPDATE,
214 	PROC_TABLE_CHECK,
215 	PROC_TABLE_LOOKUP,
216 	PROC_TABLE_FETCH,
217 };
218 
219 enum enhanced_status_code {
220 	/* 0.0 */
221 	ESC_OTHER_STATUS				= 00,
222 
223 	/* 1.x */
224 	ESC_OTHER_ADDRESS_STATUS			= 10,
225 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS		= 11,
226 	ESC_BAD_DESTINATION_SYSTEM_ADDRESS		= 12,
227 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX     	= 13,
228 	ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS	= 14,
229 	ESC_DESTINATION_ADDRESS_VALID			= 15,
230 	ESC_DESTINATION_MAILBOX_HAS_MOVED      		= 16,
231 	ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX		= 17,
232 	ESC_BAD_SENDER_SYSTEM_ADDRESS			= 18,
233 
234 	/* 2.x */
235 	ESC_OTHER_MAILBOX_STATUS			= 20,
236 	ESC_MAILBOX_DISABLED				= 21,
237 	ESC_MAILBOX_FULL				= 22,
238 	ESC_MESSAGE_LENGTH_TOO_LARGE   			= 23,
239 	ESC_MAILING_LIST_EXPANSION_PROBLEM		= 24,
240 
241 	/* 3.x */
242 	ESC_OTHER_MAIL_SYSTEM_STATUS			= 30,
243 	ESC_MAIL_SYSTEM_FULL				= 31,
244 	ESC_SYSTEM_NOT_ACCEPTING_MESSAGES		= 32,
245 	ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES    	= 33,
246 	ESC_MESSAGE_TOO_BIG_FOR_SYSTEM		    	= 34,
247 	ESC_SYSTEM_INCORRECTLY_CONFIGURED      	    	= 35,
248 
249 	/* 4.x */
250 	ESC_OTHER_NETWORK_ROUTING_STATUS      	    	= 40,
251 	ESC_NO_ANSWER_FROM_HOST		      	    	= 41,
252 	ESC_BAD_CONNECTION		      	    	= 42,
253 	ESC_DIRECTORY_SERVER_FAILURE   	      	    	= 43,
254 	ESC_UNABLE_TO_ROUTE	   	      	    	= 44,
255 	ESC_MAIL_SYSTEM_CONGESTION   	      	    	= 45,
256 	ESC_ROUTING_LOOP_DETECTED   	      	    	= 46,
257 	ESC_DELIVERY_TIME_EXPIRED   	      	    	= 47,
258 
259 	/* 5.x */
260 	ESC_INVALID_RECIPIENT   	      	    	= 50,
261 	ESC_INVALID_COMMAND	   	      	    	= 51,
262 	ESC_SYNTAX_ERROR	   	      	    	= 52,
263 	ESC_TOO_MANY_RECIPIENTS	   	      	    	= 53,
264 	ESC_INVALID_COMMAND_ARGUMENTS  	      	    	= 54,
265 	ESC_WRONG_PROTOCOL_VERSION  	      	    	= 55,
266 
267 	/* 6.x */
268 	ESC_OTHER_MEDIA_ERROR   	      	    	= 60,
269 	ESC_MEDIA_NOT_SUPPORTED   	      	    	= 61,
270 	ESC_CONVERSION_REQUIRED_AND_PROHIBITED		= 62,
271 	ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED      	= 63,
272 	ESC_CONVERSION_WITH_LOSS_PERFORMED	     	= 64,
273 	ESC_CONVERSION_FAILED			     	= 65,
274 
275 	/* 7.x */
276 	ESC_OTHER_SECURITY_STATUS      		     	= 70,
277 	ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED	= 71,
278 	ESC_MAILING_LIST_EXPANSION_PROHIBITED		= 72,
279 	ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE  	= 73,
280 	ESC_SECURITY_FEATURES_NOT_SUPPORTED	  	= 74,
281 	ESC_CRYPTOGRAPHIC_FAILURE			= 75,
282 	ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED	= 76,
283 	ESC_MESSAGE_INTEGRITY_FAILURE			= 77,
284 };
285 
286 enum enhanced_status_class {
287 	ESC_STATUS_OK		= 2,
288 	ESC_STATUS_TEMPFAIL	= 4,
289 	ESC_STATUS_PERMFAIL	= 5,
290 };
291 
292 static inline uint32_t
293 evpid_to_msgid(uint64_t evpid)
294 {
295 	return (evpid >> 32);
296 }
297 
298 static inline uint64_t
299 msgid_to_evpid(uint32_t msgid)
300 {
301         return ((uint64_t)msgid << 32);
302 }
303 
304 /* dict.c */
305 #define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0)
306 #define dict_empty(d) SPLAY_EMPTY(&((d)->dict))
307 #define dict_count(d) ((d)->count)
308 int dict_check(struct dict *, const char *);
309 void *dict_set(struct dict *, const char *, void *);
310 void dict_xset(struct dict *, const char *, void *);
311 void *dict_get(struct dict *, const char *);
312 void *dict_xget(struct dict *, const char *);
313 void *dict_pop(struct dict *, const char *);
314 void *dict_xpop(struct dict *, const char *);
315 int dict_poproot(struct dict *, void **);
316 int dict_root(struct dict *, const char **, void **);
317 int dict_iter(struct dict *, void **, const char **, void **);
318 int dict_iterfrom(struct dict *, void **, const char *, const char **, void **);
319 void dict_merge(struct dict *, struct dict *);
320 
321 
322 /* esc.c */
323 const char *esc_code(enum enhanced_status_class, enum enhanced_status_code);
324 const char *esc_description(enum enhanced_status_code);
325 
326 
327 /* filter_api.c */
328 void filter_api_setugid(uid_t, gid_t);
329 void filter_api_set_chroot(const char *);
330 void filter_api_no_chroot(void);
331 void filter_api_set_udata(uint64_t, void *);
332 void *filter_api_get_udata(uint64_t);
333 
334 void filter_api_loop(void);
335 int filter_api_accept(uint64_t);
336 int filter_api_reject(uint64_t, enum filter_status);
337 int filter_api_reject_code(uint64_t, enum filter_status, uint32_t,
338     const char *);
339 void filter_api_writeln(uint64_t, const char *);
340 const char *filter_api_sockaddr_to_text(const struct sockaddr *);
341 const char *filter_api_mailaddr_to_text(const struct mailaddr *);
342 
343 void filter_api_on_connect(int(*)(uint64_t, struct filter_connect *));
344 void filter_api_on_helo(int(*)(uint64_t, const char *));
345 void filter_api_on_mail(int(*)(uint64_t, struct mailaddr *));
346 void filter_api_on_rcpt(int(*)(uint64_t, struct mailaddr *));
347 void filter_api_on_data(int(*)(uint64_t));
348 void filter_api_on_dataline(void(*)(uint64_t, const char *));
349 void filter_api_on_eom(int(*)(uint64_t, size_t));
350 void filter_api_on_reset(void(*)(uint64_t));
351 void filter_api_on_disconnect(void(*)(uint64_t));
352 void filter_api_on_commit(void(*)(uint64_t));
353 void filter_api_on_rollback(void(*)(uint64_t));
354 
355 /* queue */
356 void queue_api_on_close(int(*)(void));
357 void queue_api_on_message_create(int(*)(uint32_t *));
358 void queue_api_on_message_commit(int(*)(uint32_t, const char*));
359 void queue_api_on_message_delete(int(*)(uint32_t));
360 void queue_api_on_message_fd_r(int(*)(uint32_t));
361 void queue_api_on_message_corrupt(int(*)(uint32_t));
362 void queue_api_on_message_uncorrupt(int(*)(uint32_t));
363 void queue_api_on_envelope_create(int(*)(uint32_t, const char *, size_t, uint64_t *));
364 void queue_api_on_envelope_delete(int(*)(uint64_t));
365 void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t));
366 void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t));
367 void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t));
368 void queue_api_on_message_walk(int(*)(uint64_t *, char *, size_t,
369     uint32_t, int *, void **));
370 void queue_api_no_chroot(void);
371 void queue_api_set_chroot(const char *);
372 void queue_api_set_user(const char *);
373 int queue_api_dispatch(void);
374 
375 /* scheduler */
376 void scheduler_api_on_init(int(*)(void));
377 void scheduler_api_on_insert(int(*)(struct scheduler_info *));
378 void scheduler_api_on_commit(size_t(*)(uint32_t));
379 void scheduler_api_on_rollback(size_t(*)(uint32_t));
380 void scheduler_api_on_update(int(*)(struct scheduler_info *));
381 void scheduler_api_on_delete(int(*)(uint64_t));
382 void scheduler_api_on_hold(int(*)(uint64_t, uint64_t));
383 void scheduler_api_on_release(int(*)(int, uint64_t, int));
384 void scheduler_api_on_batch(int(*)(int, int *, size_t *, uint64_t *, int *));
385 void scheduler_api_on_messages(size_t(*)(uint32_t, uint32_t *, size_t));
386 void scheduler_api_on_envelopes(size_t(*)(uint64_t, struct evpstate *, size_t));
387 void scheduler_api_on_schedule(int(*)(uint64_t));
388 void scheduler_api_on_remove(int(*)(uint64_t));
389 void scheduler_api_on_suspend(int(*)(uint64_t));
390 void scheduler_api_on_resume(int(*)(uint64_t));
391 void scheduler_api_no_chroot(void);
392 void scheduler_api_set_chroot(const char *);
393 void scheduler_api_set_user(const char *);
394 int scheduler_api_dispatch(void);
395 
396 /* table */
397 void table_api_on_update(int(*)(void));
398 void table_api_on_check(int(*)(int, struct dict *, const char *));
399 void table_api_on_lookup(int(*)(int, struct dict *, const char *, char *, size_t));
400 void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t));
401 int table_api_dispatch(void);
402 const char *table_api_get_name(void);
403 
404 /* tree.c */
405 #define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0)
406 #define tree_empty(t) SPLAY_EMPTY(&((t)->tree))
407 #define tree_count(t) ((t)->count)
408 int tree_check(struct tree *, uint64_t);
409 void *tree_set(struct tree *, uint64_t, void *);
410 void tree_xset(struct tree *, uint64_t, void *);
411 void *tree_get(struct tree *, uint64_t);
412 void *tree_xget(struct tree *, uint64_t);
413 void *tree_pop(struct tree *, uint64_t);
414 void *tree_xpop(struct tree *, uint64_t);
415 int tree_poproot(struct tree *, uint64_t *, void **);
416 int tree_root(struct tree *, uint64_t *, void **);
417 int tree_iter(struct tree *, void **, uint64_t *, void **);
418 int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **);
419 void tree_merge(struct tree *, struct tree *);
420 
421 #endif
422