xref: /openbsd-src/usr.sbin/smtpd/smtpd-api.h (revision 897fc685943471cf985a0fe38ba076ea6fe74fa5)
1 /*	$OpenBSD: smtpd-api.h,v 1.32 2017/09/08 16:51:22 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 struct mailaddr {
24 	char	user[SMTPD_MAXLOCALPARTSIZE];
25 	char	domain[SMTPD_MAXDOMAINPARTSIZE];
26 };
27 
28 SPLAY_HEAD(_dict, dictentry);
29 SPLAY_HEAD(_tree, treeentry);
30 
31 struct tree {
32 	struct _tree	tree;
33 	size_t		count;
34 };
35 
36 struct dict {
37 	struct _dict	dict;
38 	size_t		count;
39 };
40 
41 #define PROC_QUEUE_API_VERSION	2
42 
43 enum {
44 	PROC_QUEUE_OK,
45 	PROC_QUEUE_FAIL,
46 	PROC_QUEUE_INIT,
47 	PROC_QUEUE_CLOSE,
48 	PROC_QUEUE_MESSAGE_CREATE,
49 	PROC_QUEUE_MESSAGE_DELETE,
50 	PROC_QUEUE_MESSAGE_COMMIT,
51 	PROC_QUEUE_MESSAGE_FD_R,
52 	PROC_QUEUE_MESSAGE_CORRUPT,
53 	PROC_QUEUE_MESSAGE_UNCORRUPT,
54 	PROC_QUEUE_ENVELOPE_CREATE,
55 	PROC_QUEUE_ENVELOPE_DELETE,
56 	PROC_QUEUE_ENVELOPE_LOAD,
57 	PROC_QUEUE_ENVELOPE_UPDATE,
58 	PROC_QUEUE_ENVELOPE_WALK,
59 };
60 
61 #define PROC_SCHEDULER_API_VERSION	2
62 
63 struct scheduler_info;
64 
65 enum {
66 	PROC_SCHEDULER_OK,
67 	PROC_SCHEDULER_FAIL,
68 	PROC_SCHEDULER_INIT,
69 	PROC_SCHEDULER_INSERT,
70 	PROC_SCHEDULER_COMMIT,
71 	PROC_SCHEDULER_ROLLBACK,
72 	PROC_SCHEDULER_UPDATE,
73 	PROC_SCHEDULER_DELETE,
74 	PROC_SCHEDULER_HOLD,
75 	PROC_SCHEDULER_RELEASE,
76 	PROC_SCHEDULER_BATCH,
77 	PROC_SCHEDULER_MESSAGES,
78 	PROC_SCHEDULER_ENVELOPES,
79 	PROC_SCHEDULER_SCHEDULE,
80 	PROC_SCHEDULER_REMOVE,
81 	PROC_SCHEDULER_SUSPEND,
82 	PROC_SCHEDULER_RESUME,
83 };
84 
85 enum envelope_flags {
86 	EF_AUTHENTICATED	= 0x01,
87 	EF_BOUNCE		= 0x02,
88 	EF_INTERNAL		= 0x04, /* Internal expansion forward */
89 
90 	/* runstate, not saved on disk */
91 
92 	EF_PENDING		= 0x10,
93 	EF_INFLIGHT		= 0x20,
94 	EF_SUSPEND		= 0x40,
95 	EF_HOLD			= 0x80,
96 };
97 
98 struct evpstate {
99 	uint64_t		evpid;
100 	uint16_t		flags;
101 	uint16_t		retry;
102 	time_t			time;
103 };
104 
105 enum delivery_type {
106 	D_MDA,
107 	D_MTA,
108 	D_BOUNCE,
109 };
110 
111 struct scheduler_info {
112 	uint64_t		evpid;
113 	enum delivery_type	type;
114 	uint16_t		retry;
115 	time_t			creation;
116 	time_t			expire;
117 	time_t			lasttry;
118 	time_t			lastbounce;
119 	time_t			nexttry;
120 };
121 
122 #define SCHED_REMOVE		0x01
123 #define SCHED_EXPIRE		0x02
124 #define SCHED_UPDATE		0x04
125 #define SCHED_BOUNCE		0x08
126 #define SCHED_MDA		0x10
127 #define SCHED_MTA		0x20
128 
129 #define PROC_TABLE_API_VERSION	2
130 
131 struct table_open_params {
132 	uint32_t	version;
133 	char		name[LINE_MAX];
134 };
135 
136 enum table_service {
137 	K_NONE		= 0x000,
138 	K_ALIAS		= 0x001,	/* returns struct expand	*/
139 	K_DOMAIN	= 0x002,	/* returns struct destination	*/
140 	K_CREDENTIALS	= 0x004,	/* returns struct credentials	*/
141 	K_NETADDR	= 0x008,	/* returns struct netaddr	*/
142 	K_USERINFO	= 0x010,	/* returns struct userinfo	*/
143 	K_SOURCE	= 0x020,	/* returns struct source	*/
144 	K_MAILADDR	= 0x040,	/* returns struct mailaddr	*/
145 	K_ADDRNAME	= 0x080,	/* returns struct addrname	*/
146 	K_MAILADDRMAP	= 0x100,	/* returns struct maddrmap	*/
147 };
148 #define K_ANY		  0xfff
149 
150 enum {
151 	PROC_TABLE_OK,
152 	PROC_TABLE_FAIL,
153 	PROC_TABLE_OPEN,
154 	PROC_TABLE_CLOSE,
155 	PROC_TABLE_UPDATE,
156 	PROC_TABLE_CHECK,
157 	PROC_TABLE_LOOKUP,
158 	PROC_TABLE_FETCH,
159 };
160 
161 enum enhanced_status_code {
162 	/* 0.0 */
163 	ESC_OTHER_STATUS				= 00,
164 
165 	/* 1.x */
166 	ESC_OTHER_ADDRESS_STATUS			= 10,
167 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS		= 11,
168 	ESC_BAD_DESTINATION_SYSTEM_ADDRESS		= 12,
169 	ESC_BAD_DESTINATION_MAILBOX_ADDRESS_SYNTAX     	= 13,
170 	ESC_DESTINATION_MAILBOX_ADDRESS_AMBIGUOUS	= 14,
171 	ESC_DESTINATION_ADDRESS_VALID			= 15,
172 	ESC_DESTINATION_MAILBOX_HAS_MOVED      		= 16,
173 	ESC_BAD_SENDER_MAILBOX_ADDRESS_SYNTAX		= 17,
174 	ESC_BAD_SENDER_SYSTEM_ADDRESS			= 18,
175 
176 	/* 2.x */
177 	ESC_OTHER_MAILBOX_STATUS			= 20,
178 	ESC_MAILBOX_DISABLED				= 21,
179 	ESC_MAILBOX_FULL				= 22,
180 	ESC_MESSAGE_LENGTH_TOO_LARGE   			= 23,
181 	ESC_MAILING_LIST_EXPANSION_PROBLEM		= 24,
182 
183 	/* 3.x */
184 	ESC_OTHER_MAIL_SYSTEM_STATUS			= 30,
185 	ESC_MAIL_SYSTEM_FULL				= 31,
186 	ESC_SYSTEM_NOT_ACCEPTING_MESSAGES		= 32,
187 	ESC_SYSTEM_NOT_CAPABLE_OF_SELECTED_FEATURES    	= 33,
188 	ESC_MESSAGE_TOO_BIG_FOR_SYSTEM		    	= 34,
189 	ESC_SYSTEM_INCORRECTLY_CONFIGURED      	    	= 35,
190 
191 	/* 4.x */
192 	ESC_OTHER_NETWORK_ROUTING_STATUS      	    	= 40,
193 	ESC_NO_ANSWER_FROM_HOST		      	    	= 41,
194 	ESC_BAD_CONNECTION		      	    	= 42,
195 	ESC_DIRECTORY_SERVER_FAILURE   	      	    	= 43,
196 	ESC_UNABLE_TO_ROUTE	   	      	    	= 44,
197 	ESC_MAIL_SYSTEM_CONGESTION   	      	    	= 45,
198 	ESC_ROUTING_LOOP_DETECTED   	      	    	= 46,
199 	ESC_DELIVERY_TIME_EXPIRED   	      	    	= 47,
200 
201 	/* 5.x */
202 	ESC_INVALID_RECIPIENT   	      	    	= 50,
203 	ESC_INVALID_COMMAND	   	      	    	= 51,
204 	ESC_SYNTAX_ERROR	   	      	    	= 52,
205 	ESC_TOO_MANY_RECIPIENTS	   	      	    	= 53,
206 	ESC_INVALID_COMMAND_ARGUMENTS  	      	    	= 54,
207 	ESC_WRONG_PROTOCOL_VERSION  	      	    	= 55,
208 
209 	/* 6.x */
210 	ESC_OTHER_MEDIA_ERROR   	      	    	= 60,
211 	ESC_MEDIA_NOT_SUPPORTED   	      	    	= 61,
212 	ESC_CONVERSION_REQUIRED_AND_PROHIBITED		= 62,
213 	ESC_CONVERSION_REQUIRED_BUT_NOT_SUPPORTED      	= 63,
214 	ESC_CONVERSION_WITH_LOSS_PERFORMED	     	= 64,
215 	ESC_CONVERSION_FAILED			     	= 65,
216 
217 	/* 7.x */
218 	ESC_OTHER_SECURITY_STATUS      		     	= 70,
219 	ESC_DELIVERY_NOT_AUTHORIZED_MESSAGE_REFUSED	= 71,
220 	ESC_MAILING_LIST_EXPANSION_PROHIBITED		= 72,
221 	ESC_SECURITY_CONVERSION_REQUIRED_NOT_POSSIBLE  	= 73,
222 	ESC_SECURITY_FEATURES_NOT_SUPPORTED	  	= 74,
223 	ESC_CRYPTOGRAPHIC_FAILURE			= 75,
224 	ESC_CRYPTOGRAPHIC_ALGORITHM_NOT_SUPPORTED	= 76,
225 	ESC_MESSAGE_INTEGRITY_FAILURE			= 77,
226 };
227 
228 enum enhanced_status_class {
229 	ESC_STATUS_OK		= 2,
230 	ESC_STATUS_TEMPFAIL	= 4,
231 	ESC_STATUS_PERMFAIL	= 5,
232 };
233 
234 static inline uint32_t
235 evpid_to_msgid(uint64_t evpid)
236 {
237 	return (evpid >> 32);
238 }
239 
240 static inline uint64_t
241 msgid_to_evpid(uint32_t msgid)
242 {
243         return ((uint64_t)msgid << 32);
244 }
245 
246 /* dict.c */
247 #define dict_init(d) do { SPLAY_INIT(&((d)->dict)); (d)->count = 0; } while(0)
248 #define dict_empty(d) SPLAY_EMPTY(&((d)->dict))
249 #define dict_count(d) ((d)->count)
250 int dict_check(struct dict *, const char *);
251 void *dict_set(struct dict *, const char *, void *);
252 void dict_xset(struct dict *, const char *, void *);
253 void *dict_get(struct dict *, const char *);
254 void *dict_xget(struct dict *, const char *);
255 void *dict_pop(struct dict *, const char *);
256 void *dict_xpop(struct dict *, const char *);
257 int dict_poproot(struct dict *, void **);
258 int dict_root(struct dict *, const char **, void **);
259 int dict_iter(struct dict *, void **, const char **, void **);
260 int dict_iterfrom(struct dict *, void **, const char *, const char **, void **);
261 void dict_merge(struct dict *, struct dict *);
262 
263 
264 /* esc.c */
265 const char *esc_code(enum enhanced_status_class, enum enhanced_status_code);
266 const char *esc_description(enum enhanced_status_code);
267 
268 
269 /* queue */
270 void queue_api_on_close(int(*)(void));
271 void queue_api_on_message_create(int(*)(uint32_t *));
272 void queue_api_on_message_commit(int(*)(uint32_t, const char*));
273 void queue_api_on_message_delete(int(*)(uint32_t));
274 void queue_api_on_message_fd_r(int(*)(uint32_t));
275 void queue_api_on_message_corrupt(int(*)(uint32_t));
276 void queue_api_on_message_uncorrupt(int(*)(uint32_t));
277 void queue_api_on_envelope_create(int(*)(uint32_t, const char *, size_t, uint64_t *));
278 void queue_api_on_envelope_delete(int(*)(uint64_t));
279 void queue_api_on_envelope_update(int(*)(uint64_t, const char *, size_t));
280 void queue_api_on_envelope_load(int(*)(uint64_t, char *, size_t));
281 void queue_api_on_envelope_walk(int(*)(uint64_t *, char *, size_t));
282 void queue_api_on_message_walk(int(*)(uint64_t *, char *, size_t,
283     uint32_t, int *, void **));
284 void queue_api_no_chroot(void);
285 void queue_api_set_chroot(const char *);
286 void queue_api_set_user(const char *);
287 int queue_api_dispatch(void);
288 
289 /* scheduler */
290 void scheduler_api_on_init(int(*)(void));
291 void scheduler_api_on_insert(int(*)(struct scheduler_info *));
292 void scheduler_api_on_commit(size_t(*)(uint32_t));
293 void scheduler_api_on_rollback(size_t(*)(uint32_t));
294 void scheduler_api_on_update(int(*)(struct scheduler_info *));
295 void scheduler_api_on_delete(int(*)(uint64_t));
296 void scheduler_api_on_hold(int(*)(uint64_t, uint64_t));
297 void scheduler_api_on_release(int(*)(int, uint64_t, int));
298 void scheduler_api_on_batch(int(*)(int, int *, size_t *, uint64_t *, int *));
299 void scheduler_api_on_messages(size_t(*)(uint32_t, uint32_t *, size_t));
300 void scheduler_api_on_envelopes(size_t(*)(uint64_t, struct evpstate *, size_t));
301 void scheduler_api_on_schedule(int(*)(uint64_t));
302 void scheduler_api_on_remove(int(*)(uint64_t));
303 void scheduler_api_on_suspend(int(*)(uint64_t));
304 void scheduler_api_on_resume(int(*)(uint64_t));
305 void scheduler_api_no_chroot(void);
306 void scheduler_api_set_chroot(const char *);
307 void scheduler_api_set_user(const char *);
308 int scheduler_api_dispatch(void);
309 
310 /* table */
311 void table_api_on_update(int(*)(void));
312 void table_api_on_check(int(*)(int, struct dict *, const char *));
313 void table_api_on_lookup(int(*)(int, struct dict *, const char *, char *, size_t));
314 void table_api_on_fetch(int(*)(int, struct dict *, char *, size_t));
315 int table_api_dispatch(void);
316 const char *table_api_get_name(void);
317 
318 /* tree.c */
319 #define tree_init(t) do { SPLAY_INIT(&((t)->tree)); (t)->count = 0; } while(0)
320 #define tree_empty(t) SPLAY_EMPTY(&((t)->tree))
321 #define tree_count(t) ((t)->count)
322 int tree_check(struct tree *, uint64_t);
323 void *tree_set(struct tree *, uint64_t, void *);
324 void tree_xset(struct tree *, uint64_t, void *);
325 void *tree_get(struct tree *, uint64_t);
326 void *tree_xget(struct tree *, uint64_t);
327 void *tree_pop(struct tree *, uint64_t);
328 void *tree_xpop(struct tree *, uint64_t);
329 int tree_poproot(struct tree *, uint64_t *, void **);
330 int tree_root(struct tree *, uint64_t *, void **);
331 int tree_iter(struct tree *, void **, uint64_t *, void **);
332 int tree_iterfrom(struct tree *, void **, uint64_t, uint64_t *, void **);
333 void tree_merge(struct tree *, struct tree *);
334 
335 #endif
336