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