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