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