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