1 /* 2 * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 * 10 * $Id: mfapi.h,v 8.60 2004/08/20 21:24:14 ca Exp $ 11 */ 12 13 /* 14 * MFAPI.H -- Global definitions for mail filter library and mail filters. 15 */ 16 17 #ifndef _LIBMILTER_MFAPI_H 18 #define _LIBMILTER_MFAPI_H 19 20 #pragma ident "%Z%%M% %I% %E% SMI" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #ifndef SMFI_VERSION 27 #define SMFI_VERSION 2 /* version number */ 28 #endif /* ! SMFI_VERSION */ 29 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 33 #include <libmilter/mfdef.h> 34 35 #define LIBMILTER_API extern 36 37 #ifndef _SOCK_ADDR 38 #define _SOCK_ADDR struct sockaddr 39 #endif /* ! _SOCK_ADDR */ 40 41 /* 42 * libmilter functions return one of the following to indicate 43 * success/failure: 44 */ 45 46 #define MI_SUCCESS 0 47 #define MI_FAILURE (-1) 48 49 /* "forward" declarations */ 50 typedef struct smfi_str SMFICTX; 51 typedef struct smfi_str *SMFICTX_PTR; 52 53 typedef struct smfiDesc smfiDesc_str; 54 typedef struct smfiDesc *smfiDesc_ptr; 55 56 /* 57 * Type which callbacks should return to indicate message status. 58 * This may take on one of the SMFIS_* values listed below. 59 */ 60 61 typedef int sfsistat; 62 63 #if defined(__linux__) && defined(__GNUC__) && defined(__cplusplus) && \ 64 __GNUC_MINOR__ >= 8 65 #define SM__P(X) __PMT(X) 66 #else /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */ 67 #define SM__P(X) __P(X) 68 #endif /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */ 69 70 /* Some platforms don't define __P -- do it for them here: */ 71 #ifndef __P 72 #ifdef __STDC__ 73 #define __P(X) X 74 #else /* __STDC__ */ 75 #define __P(X) () 76 #endif /* __STDC__ */ 77 #endif /* __P */ 78 79 #if SM_CONF_STDBOOL_H 80 #include <stdbool.h> 81 #else /* SM_CONF_STDBOOL_H */ 82 #ifndef __cplusplus 83 #ifndef bool 84 #ifndef __bool_true_false_are_defined 85 typedef int bool; 86 #define __bool_true_false_are_defined 1 87 #endif /* ! __bool_true_false_are_defined */ 88 #endif /* bool */ 89 #endif /* ! __cplusplus */ 90 #endif /* SM_CONF_STDBOOL_H */ 91 92 /* 93 * structure describing one milter 94 */ 95 96 struct smfiDesc 97 { 98 char *xxfi_name; /* filter name */ 99 int xxfi_version; /* version code -- do not change */ 100 unsigned long xxfi_flags; /* flags */ 101 102 /* connection info filter */ 103 sfsistat (*xxfi_connect) SM__P((SMFICTX *, char *, 104 _SOCK_ADDR *)); 105 106 /* SMTP HELO command filter */ 107 sfsistat (*xxfi_helo) SM__P((SMFICTX *, char *)); 108 109 /* envelope sender filter */ 110 sfsistat (*xxfi_envfrom) SM__P((SMFICTX *, char **)); 111 112 /* envelope recipient filter */ 113 sfsistat (*xxfi_envrcpt) SM__P((SMFICTX *, char **)); 114 115 /* header filter */ 116 sfsistat (*xxfi_header) SM__P((SMFICTX *, char *, char *)); 117 118 /* end of header */ 119 sfsistat (*xxfi_eoh) SM__P((SMFICTX *)); 120 121 /* body block */ 122 sfsistat (*xxfi_body) SM__P((SMFICTX *, unsigned char *, 123 size_t)); 124 125 /* end of message */ 126 sfsistat (*xxfi_eom) SM__P((SMFICTX *)); 127 128 /* message aborted */ 129 sfsistat (*xxfi_abort) SM__P((SMFICTX *)); 130 131 /* connection cleanup */ 132 sfsistat (*xxfi_close) SM__P((SMFICTX *)); 133 134 #if SMFI_VERSION > 2 135 /* any unrecognized or unimplemented command filter */ 136 sfsistat (*xxfi_unknown) SM__P((SMFICTX *, char *)); 137 #endif /* SMFI_VERSION > 2 */ 138 139 #if SMFI_VERSION > 3 140 /* any unrecognized or unimplemented command filter */ 141 sfsistat (*xxfi_data) SM__P((SMFICTX *)); 142 #endif /* SMFI_VERSION > 3 */ 143 }; 144 145 LIBMILTER_API int smfi_opensocket __P((bool)); 146 LIBMILTER_API int smfi_register __P((struct smfiDesc)); 147 LIBMILTER_API int smfi_main __P((void)); 148 LIBMILTER_API int smfi_setbacklog __P((int)); 149 LIBMILTER_API int smfi_setdbg __P((int)); 150 LIBMILTER_API int smfi_settimeout __P((int)); 151 LIBMILTER_API int smfi_setconn __P((char *)); 152 LIBMILTER_API int smfi_stop __P((void)); 153 #if _FFR_MAXDATASIZE 154 LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t)); 155 #endif /* _FFR_MAXDATASIZE */ 156 157 /* 158 * What the filter might do -- values to be ORed together for 159 * smfiDesc.xxfi_flags. 160 */ 161 162 #define SMFIF_NONE 0x00000000L /* no flags */ 163 #define SMFIF_ADDHDRS 0x00000001L /* filter may add headers */ 164 #define SMFIF_CHGBODY 0x00000002L /* filter may replace body */ 165 #define SMFIF_MODBODY SMFIF_CHGBODY /* backwards compatible */ 166 #define SMFIF_ADDRCPT 0x00000004L /* filter may add recipients */ 167 #define SMFIF_DELRCPT 0x00000008L /* filter may delete recipients */ 168 #define SMFIF_CHGHDRS 0x00000010L /* filter may change/delete headers */ 169 #define SMFIF_QUARANTINE 0x00000020L /* filter may quarantine envelope */ 170 171 /* 172 * Continue processing message/connection. 173 */ 174 175 #define SMFIS_CONTINUE 0 176 177 /* 178 * Reject the message/connection. 179 * No further routines will be called for this message 180 * (or connection, if returned from a connection-oriented routine). 181 */ 182 183 #define SMFIS_REJECT 1 184 185 /* 186 * Accept the message, 187 * but silently discard the message. 188 * No further routines will be called for this message. 189 * This is only meaningful from message-oriented routines. 190 */ 191 192 #define SMFIS_DISCARD 2 193 194 /* 195 * Accept the message/connection. 196 * No further routines will be called for this message 197 * (or connection, if returned from a connection-oriented routine; 198 * in this case, it causes all messages on this connection 199 * to be accepted without filtering). 200 */ 201 202 #define SMFIS_ACCEPT 3 203 204 /* 205 * Return a temporary failure, i.e., 206 * the corresponding SMTP command will return a 4xx status code. 207 * In some cases this may prevent further routines from 208 * being called on this message or connection, 209 * although in other cases (e.g., when processing an envelope 210 * recipient) processing of the message will continue. 211 */ 212 213 #define SMFIS_TEMPFAIL 4 214 215 #if 0 216 /* 217 * Filter Routine Details 218 */ 219 220 /* connection info filter */ 221 extern sfsistat xxfi_connect __P((SMFICTX *, char *, _SOCK_ADDR *)); 222 223 /* 224 * xxfi_connect(ctx, hostname, hostaddr) Invoked on each connection 225 * 226 * char *hostname; Host domain name, as determined by a reverse lookup 227 * on the host address. 228 * _SOCK_ADDR *hostaddr; Host address, as determined by a getpeername 229 * call on the SMTP socket. 230 */ 231 232 /* SMTP HELO command filter */ 233 extern sfsistat xxfi_helo __P((SMFICTX *, char *)); 234 235 /* 236 * xxfi_helo(ctx, helohost) Invoked on SMTP HELO/EHLO command 237 * 238 * char *helohost; Value passed to HELO/EHLO command, which should be 239 * the domain name of the sending host (but is, in practice, 240 * anything the sending host wants to send). 241 */ 242 243 /* envelope sender filter */ 244 extern sfsistat xxfi_envfrom __P((SMFICTX *, char **)); 245 246 /* 247 * xxfi_envfrom(ctx, argv) Invoked on envelope from 248 * 249 * char **argv; Null-terminated SMTP command arguments; 250 * argv[0] is guaranteed to be the sender address. 251 * Later arguments are the ESMTP arguments. 252 */ 253 254 /* envelope recipient filter */ 255 extern sfsistat xxfi_envrcpt __P((SMFICTX *, char **)); 256 257 /* 258 * xxfi_envrcpt(ctx, argv) Invoked on each envelope recipient 259 * 260 * char **argv; Null-terminated SMTP command arguments; 261 * argv[0] is guaranteed to be the recipient address. 262 * Later arguments are the ESMTP arguments. 263 */ 264 265 /* unknown command filter */ 266 267 extern sfsistat *xxfi_unknown __P((SMFICTX *, char *)); 268 269 /* 270 * xxfi_unknown(ctx, arg) Invoked when SMTP command is not recognized or not 271 * implemented. 272 * char *arg; Null-terminated SMTP command 273 */ 274 275 /* header filter */ 276 extern sfsistat xxfi_header __P((SMFICTX *, char *, char *)); 277 278 /* 279 * xxfi_header(ctx, headerf, headerv) Invoked on each message header. The 280 * content of the header may have folded white space (that is, multiple 281 * lines with following white space) included. 282 * 283 * char *headerf; Header field name 284 * char *headerv; Header field value 285 */ 286 287 /* end of header */ 288 extern sfsistat xxfi_eoh __P((SMFICTX *)); 289 290 /* 291 * xxfi_eoh(ctx) Invoked at end of header 292 */ 293 294 /* body block */ 295 extern sfsistat xxfi_body __P((SMFICTX *, unsigned char *, size_t)); 296 297 /* 298 * xxfi_body(ctx, bodyp, bodylen) Invoked for each body chunk. There may 299 * be multiple body chunks passed to the filter. End-of-lines are 300 * represented as received from SMTP (normally Carriage-Return/Line-Feed). 301 * 302 * unsigned char *bodyp; Pointer to body data 303 * size_t bodylen; Length of body data 304 */ 305 306 /* end of message */ 307 extern sfsistat xxfi_eom __P((SMFICTX *)); 308 309 /* 310 * xxfi_eom(ctx) Invoked at end of message. This routine can perform 311 * special operations such as modifying the message header, body, or 312 * envelope. 313 */ 314 315 /* message aborted */ 316 extern sfsistat xxfi_abort __P((SMFICTX *)); 317 318 /* 319 * xxfi_abort(ctx) Invoked if message is aborted outside of the control of 320 * the filter, for example, if the SMTP sender issues an RSET command. If 321 * xxfi_abort is called, xxfi_eom will not be called and vice versa. 322 */ 323 324 /* connection cleanup */ 325 extern sfsistat xxfi_close __P((SMFICTX *)); 326 327 /* 328 * xxfi_close(ctx) Invoked at end of the connection. This is called on 329 * close even if the previous mail transaction was aborted. 330 */ 331 #endif /* 0 */ 332 333 /* 334 * Additional information is passed in to the vendor filter routines using 335 * symbols. Symbols correspond closely to sendmail macros. The symbols 336 * defined depend on the context. The value of a symbol is accessed using: 337 */ 338 339 /* Return the value of a symbol. */ 340 LIBMILTER_API char *smfi_getsymval __P((SMFICTX *, char *)); 341 342 /* 343 * Return the value of a symbol. 344 * 345 * SMFICTX *ctx; Opaque context structure 346 * char *symname; The name of the symbol to access. 347 */ 348 349 /* 350 * Vendor filter routines that want to pass additional information back to 351 * the MTA for use in SMTP replies may call smfi_setreply before returning. 352 */ 353 354 LIBMILTER_API int smfi_setreply __P((SMFICTX *, char *, char *, char *)); 355 356 /* 357 * Alternatively, smfi_setmlreply can be called if a multi-line SMTP reply 358 * is needed. 359 */ 360 361 LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, 362 ...)); 363 364 /* 365 * Set the specific reply code to be used in response to the active 366 * command. If not specified, a generic reply code is used. 367 * 368 * SMFICTX *ctx; Opaque context structure 369 * char *rcode; The three-digit (RFC 821) SMTP reply code to be 370 * returned, e.g., ``551''. 371 * char *xcode; The extended (RFC 2034) reply code, e.g., ``5.7.6''. 372 * char *message; The text part of the SMTP reply. 373 */ 374 375 /* 376 * The xxfi_eom routine is called at the end of a message (essentially, 377 * after the final DATA dot). This routine can call some special routines 378 * to modify the envelope, header, or body of the message before the 379 * message is enqueued. These routines must not be called from any vendor 380 * routine other than xxfi_eom. 381 */ 382 383 LIBMILTER_API int smfi_addheader __P((SMFICTX *, char *, char *)); 384 385 /* 386 * Add a header to the message. It is not checked for standards 387 * compliance; the mail filter must ensure that no protocols are violated 388 * as a result of adding this header. 389 * 390 * SMFICTX *ctx; Opaque context structure 391 * char *headerf; Header field name 392 * char *headerv; Header field value 393 */ 394 395 LIBMILTER_API int smfi_chgheader __P((SMFICTX *, char *, int, char *)); 396 397 /* 398 * Change/delete a header in the message. It is not checked for standards 399 * compliance; the mail filter must ensure that no protocols are violated 400 * as a result of adding this header. 401 * 402 * SMFICTX *ctx; Opaque context structure 403 * char *headerf; Header field name 404 * int index; The Nth occurence of header field name 405 * char *headerv; New header field value (empty for delete header) 406 */ 407 408 LIBMILTER_API int smfi_insheader __P((SMFICTX *, int, char *, char *)); 409 410 /* 411 * Insert a header into the message. It is not checked for standards 412 * compliance; the mail filter must ensure that no protocols are violated 413 * as a result of adding this header. 414 * 415 * SMFICTX *ctx; Opaque context structure 416 * int idx; index into the header list where the insertion should happen 417 * char *headerh; Header field name 418 * char *headerv; Header field value 419 */ 420 421 LIBMILTER_API int smfi_addrcpt __P((SMFICTX *, char *)); 422 423 /* 424 * Add a recipient to the envelope 425 * 426 * SMFICTX *ctx; Opaque context structure 427 * char *rcpt; Recipient to be added 428 */ 429 430 LIBMILTER_API int smfi_delrcpt __P((SMFICTX *, char *)); 431 432 /* 433 * Send a "no-op" up to the MTA to tell it we're still alive, so long 434 * milter-side operations don't time out. 435 * 436 * SMFICTX *ctx; Opaque context structure 437 */ 438 439 LIBMILTER_API int smfi_progress __P((SMFICTX *)); 440 441 /* 442 * Delete a recipient from the envelope 443 * 444 * SMFICTX *ctx; Opaque context structure 445 * char *rcpt; Envelope recipient to be deleted. This should be in 446 * exactly the form passed to xxfi_envrcpt or the address may 447 * not be deleted. 448 */ 449 450 LIBMILTER_API int smfi_replacebody __P((SMFICTX *, unsigned char *, int)); 451 452 /* 453 * Replace the body of the message. This routine may be called multiple 454 * times if the body is longer than convenient to send in one call. End of 455 * line should be represented as Carriage-Return/Line Feed. 456 * 457 * char *bodyp; Pointer to block of body information to insert 458 * int bodylen; Length of data pointed at by bodyp 459 */ 460 461 /* 462 * If the message is aborted (for example, if the SMTP sender sends the 463 * envelope but then does a QUIT or RSET before the data is sent), 464 * xxfi_abort is called. This can be used to reset state. 465 */ 466 467 /* 468 * Quarantine an envelope 469 * 470 * SMFICTX *ctx; Opaque context structure 471 * char *reason: explanation 472 */ 473 474 LIBMILTER_API int smfi_quarantine __P((SMFICTX *ctx, char *reason)); 475 476 /* 477 * Connection-private data (specific to an SMTP connection) can be 478 * allocated using the smfi_setpriv routine; routines can access private 479 * data using smfi_getpriv. 480 */ 481 482 LIBMILTER_API int smfi_setpriv __P((SMFICTX *, void *)); 483 484 /* 485 * Set the private data pointer 486 * 487 * SMFICTX *ctx; Opaque context structure 488 * void *privatedata; Pointer to private data area 489 */ 490 491 LIBMILTER_API void *smfi_getpriv __P((SMFICTX *)); 492 493 #ifdef __cplusplus 494 } 495 #endif 496 497 #endif /* !_LIBMILTER_MFAPI_H */ 498