xref: /freebsd/contrib/sendmail/include/libmilter/mfapi.h (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * Copyright (c) 1999-2004, 2006 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.77 2006/11/02 02:44:07 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	1
19 
20 #ifndef SMFI_VERSION
21 # define SMFI_VERSION	0x01000000	/* libmilter version number */
22 #endif /* ! SMFI_VERSION */
23 
24 #define SM_LM_VRS_MAJOR(v)	(((v) & 0x7f000000) >> 24)
25 #define SM_LM_VRS_MINOR(v)	(((v) & 0x007fff00) >> 8)
26 #define SM_LM_VRS_PLVL(v)	((v) & 0x0000007f)
27 
28 # include <sys/types.h>
29 # include <sys/socket.h>
30 
31 #include "libmilter/mfdef.h"
32 
33 # define LIBMILTER_API		extern
34 
35 
36 /* Only need to export C interface if used by C++ source code */
37 #ifdef __cplusplus
38 extern "C" {
39 #endif /* __cplusplus */
40 
41 #ifndef _SOCK_ADDR
42 # define _SOCK_ADDR	struct sockaddr
43 #endif /* ! _SOCK_ADDR */
44 
45 /*
46 **  libmilter functions return one of the following to indicate
47 **  success/failure(/continue):
48 */
49 
50 #define MI_SUCCESS	0
51 #define MI_FAILURE	(-1)
52 #if _FFR_WORKERS_POOL
53 # define MI_CONTINUE	1
54 #endif /* _FFR_WORKERS_POOL */
55 
56 /* "forward" declarations */
57 typedef struct smfi_str SMFICTX;
58 typedef struct smfi_str *SMFICTX_PTR;
59 
60 typedef struct smfiDesc smfiDesc_str;
61 typedef struct smfiDesc	*smfiDesc_ptr;
62 
63 /*
64 **  Type which callbacks should return to indicate message status.
65 **  This may take on one of the SMFIS_* values listed below.
66 */
67 
68 typedef int	sfsistat;
69 
70 #if defined(__linux__) && defined(__GNUC__) && defined(__cplusplus) && __GNUC_MINOR__ >= 8
71 # define SM__P(X)	__PMT(X)
72 #else /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
73 # define SM__P(X)	__P(X)
74 #endif /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
75 
76 /* Some platforms don't define __P -- do it for them here: */
77 #ifndef __P
78 # ifdef __STDC__
79 #  define __P(X) X
80 # else /* __STDC__ */
81 #  define __P(X) ()
82 # endif /* __STDC__ */
83 #endif /* __P */
84 
85 #if SM_CONF_STDBOOL_H
86 # include <stdbool.h>
87 #else /* SM_CONF_STDBOOL_H */
88 # ifndef __cplusplus
89 #  ifndef bool
90 #   ifndef __bool_true_false_are_defined
91 typedef int	bool;
92 #    define __bool_true_false_are_defined	1
93 #   endif /* ! __bool_true_false_are_defined */
94 #  endif /* bool */
95 # endif /* ! __cplusplus */
96 #endif /* SM_CONF_STDBOOL_H */
97 
98 /*
99 **  structure describing one milter
100 */
101 
102 struct smfiDesc
103 {
104 	char		*xxfi_name;	/* filter name */
105 	int		xxfi_version;	/* version code -- do not change */
106 	unsigned long	xxfi_flags;	/* flags */
107 
108 	/* connection info filter */
109 	sfsistat	(*xxfi_connect) SM__P((SMFICTX *, char *, _SOCK_ADDR *));
110 
111 	/* SMTP HELO command filter */
112 	sfsistat	(*xxfi_helo) SM__P((SMFICTX *, char *));
113 
114 	/* envelope sender filter */
115 	sfsistat	(*xxfi_envfrom) SM__P((SMFICTX *, char **));
116 
117 	/* envelope recipient filter */
118 	sfsistat	(*xxfi_envrcpt) SM__P((SMFICTX *, char **));
119 
120 	/* header filter */
121 	sfsistat	(*xxfi_header) SM__P((SMFICTX *, char *, char *));
122 
123 	/* end of header */
124 	sfsistat	(*xxfi_eoh) SM__P((SMFICTX *));
125 
126 	/* body block */
127 	sfsistat	(*xxfi_body) SM__P((SMFICTX *, unsigned char *, size_t));
128 
129 	/* end of message */
130 	sfsistat	(*xxfi_eom) SM__P((SMFICTX *));
131 
132 	/* message aborted */
133 	sfsistat	(*xxfi_abort) SM__P((SMFICTX *));
134 
135 	/* connection cleanup */
136 	sfsistat	(*xxfi_close) SM__P((SMFICTX *));
137 
138 	/* any unrecognized or unimplemented command filter */
139 	sfsistat	(*xxfi_unknown) SM__P((SMFICTX *, const char *));
140 
141 	/* SMTP DATA command filter */
142 	sfsistat	(*xxfi_data) SM__P((SMFICTX *));
143 
144 	/* negotiation callback */
145 	sfsistat	(*xxfi_negotiate) SM__P((SMFICTX *,
146 					unsigned long, unsigned long,
147 					unsigned long, unsigned long,
148 					unsigned long *, unsigned long *,
149 					unsigned long *, unsigned long *));
150 
151 #if 0
152 	/* signal handler callback, not yet implemented. */
153 	int		(*xxfi_signal) SM__P((int));
154 #endif
155 
156 };
157 
158 LIBMILTER_API int smfi_opensocket __P((bool));
159 LIBMILTER_API int smfi_register __P((struct smfiDesc));
160 LIBMILTER_API int smfi_main __P((void));
161 LIBMILTER_API int smfi_setbacklog __P((int));
162 LIBMILTER_API int smfi_setdbg __P((int));
163 LIBMILTER_API int smfi_settimeout __P((int));
164 LIBMILTER_API int smfi_setconn __P((char *));
165 LIBMILTER_API int smfi_stop __P((void));
166 #if _FFR_MAXDATASIZE
167 LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
168 #endif /* _FFR_MAXDATASIZE */
169 LIBMILTER_API int smfi_version __P((unsigned int *, unsigned int *, unsigned int *));
170 
171 /*
172 **  What the filter might do -- values to be ORed together for
173 **  smfiDesc.xxfi_flags.
174 */
175 
176 #define SMFIF_NONE	0x00000000L	/* no flags */
177 #define SMFIF_ADDHDRS	0x00000001L	/* filter may add headers */
178 #define SMFIF_CHGBODY	0x00000002L	/* filter may replace body */
179 #define SMFIF_MODBODY	SMFIF_CHGBODY	/* backwards compatible */
180 #define SMFIF_ADDRCPT	0x00000004L	/* filter may add recipients */
181 #define SMFIF_DELRCPT	0x00000008L	/* filter may delete recipients */
182 #define SMFIF_CHGHDRS	0x00000010L	/* filter may change/delete headers */
183 #define SMFIF_QUARANTINE 0x00000020L	/* filter may quarantine envelope */
184 
185 /* filter may change "from" (envelope sender) */
186 #define SMFIF_CHGFROM	0x00000040L
187 #define SMFIF_ADDRCPT_PAR	0x00000080L	/* add recipients incl. args */
188 
189 /* filter can send set of symbols (macros) that it wants */
190 #define SMFIF_SETSYMLIST	0x00000100L
191 
192 
193 /*
194 **  Macro "places";
195 **  Notes:
196 **  - must be coordinated with libmilter/engine.c and sendmail/milter.c
197 **  - the order MUST NOT be changed as it would break compatibility between
198 **	different versions. It's ok to append new entries however
199 **	(hence the list is not sorted by the SMT protocol steps).
200 */
201 
202 #define SMFIM_FIRST	0	/* Do NOT use, internal marker only */
203 #define SMFIM_CONNECT	0	/* connect */
204 #define SMFIM_HELO	1	/* HELO/EHLO */
205 #define SMFIM_ENVFROM	2	/* MAIL From */
206 #define SMFIM_ENVRCPT	3	/* RCPT To */
207 #define SMFIM_DATA	4	/* DATA */
208 #define SMFIM_EOM	5	/* end of message (final dot) */
209 #define SMFIM_EOH	6	/* end of header */
210 #define SMFIM_LAST	6	/* Do NOT use, internal marker only */
211 
212 /*
213 **  Continue processing message/connection.
214 */
215 
216 #define SMFIS_CONTINUE	0
217 
218 /*
219 **  Reject the message/connection.
220 **  No further routines will be called for this message
221 **  (or connection, if returned from a connection-oriented routine).
222 */
223 
224 #define SMFIS_REJECT	1
225 
226 /*
227 **  Accept the message,
228 **  but silently discard the message.
229 **  No further routines will be called for this message.
230 **  This is only meaningful from message-oriented routines.
231 */
232 
233 #define SMFIS_DISCARD	2
234 
235 /*
236 **  Accept the message/connection.
237 **  No further routines will be called for this message
238 **  (or connection, if returned from a connection-oriented routine;
239 **  in this case, it causes all messages on this connection
240 **  to be accepted without filtering).
241 */
242 
243 #define SMFIS_ACCEPT	3
244 
245 /*
246 **  Return a temporary failure, i.e.,
247 **  the corresponding SMTP command will return a 4xx status code.
248 **  In some cases this may prevent further routines from
249 **  being called on this message or connection,
250 **  although in other cases (e.g., when processing an envelope
251 **  recipient) processing of the message will continue.
252 */
253 
254 #define SMFIS_TEMPFAIL	4
255 
256 /*
257 **  Do not send a reply to the MTA
258 */
259 
260 #define SMFIS_NOREPLY	7
261 
262 /*
263 **  Skip over rest of same callbacks, e.g., body.
264 */
265 
266 #define SMFIS_SKIP	8
267 
268 /* xxfi_negotiate: use all existing protocol options/actions */
269 #define SMFIS_ALL_OPTS	10
270 
271 #if 0
272 /*
273 **  Filter Routine Details
274 */
275 
276 /* connection info filter */
277 extern sfsistat	xxfi_connect __P((SMFICTX *, char *, _SOCK_ADDR *));
278 
279 /*
280 **  xxfi_connect(ctx, hostname, hostaddr) Invoked on each connection
281 **
282 **	char *hostname; Host domain name, as determined by a reverse lookup
283 **		on the host address.
284 **	_SOCK_ADDR *hostaddr; Host address, as determined by a getpeername
285 **		call on the SMTP socket.
286 */
287 
288 /* SMTP HELO command filter */
289 extern sfsistat	xxfi_helo __P((SMFICTX *, char *));
290 
291 /*
292 **  xxfi_helo(ctx, helohost) Invoked on SMTP HELO/EHLO command
293 **
294 **	char *helohost; Value passed to HELO/EHLO command, which should be
295 **		the domain name of the sending host (but is, in practice,
296 **		anything the sending host wants to send).
297 */
298 
299 /* envelope sender filter */
300 extern sfsistat	xxfi_envfrom __P((SMFICTX *, char **));
301 
302 /*
303 **  xxfi_envfrom(ctx, argv) Invoked on envelope from
304 **
305 **	char **argv; Null-terminated SMTP command arguments;
306 **		argv[0] is guaranteed to be the sender address.
307 **		Later arguments are the ESMTP arguments.
308 */
309 
310 /* envelope recipient filter */
311 extern sfsistat	xxfi_envrcpt __P((SMFICTX *, char **));
312 
313 /*
314 **  xxfi_envrcpt(ctx, argv) Invoked on each envelope recipient
315 **
316 **	char **argv; Null-terminated SMTP command arguments;
317 **		argv[0] is guaranteed to be the recipient address.
318 **		Later arguments are the ESMTP arguments.
319 */
320 
321 /* unknown command filter */
322 
323 extern sfsistat	*xxfi_unknown __P((SMFICTX *, const char *));
324 
325 /*
326 **  xxfi_unknown(ctx, arg) Invoked when SMTP command is not recognized or not
327 **  implemented.
328 **	const char *arg; Null-terminated SMTP command
329 */
330 
331 /* header filter */
332 extern sfsistat	xxfi_header __P((SMFICTX *, char *, char *));
333 
334 /*
335 **  xxfi_header(ctx, headerf, headerv) Invoked on each message header. The
336 **  content of the header may have folded white space (that is, multiple
337 **  lines with following white space) included.
338 **
339 **	char *headerf; Header field name
340 **	char *headerv; Header field value
341 */
342 
343 /* end of header */
344 extern sfsistat	xxfi_eoh __P((SMFICTX *));
345 
346 /*
347 **  xxfi_eoh(ctx) Invoked at end of header
348 */
349 
350 /* body block */
351 extern sfsistat	xxfi_body __P((SMFICTX *, unsigned char *, size_t));
352 
353 /*
354 **  xxfi_body(ctx, bodyp, bodylen) Invoked for each body chunk. There may
355 **  be multiple body chunks passed to the filter. End-of-lines are
356 **  represented as received from SMTP (normally Carriage-Return/Line-Feed).
357 **
358 **	unsigned char *bodyp; Pointer to body data
359 **	size_t bodylen; Length of body data
360 */
361 
362 /* end of message */
363 extern sfsistat	xxfi_eom __P((SMFICTX *));
364 
365 /*
366 **  xxfi_eom(ctx) Invoked at end of message. This routine can perform
367 **  special operations such as modifying the message header, body, or
368 **  envelope.
369 */
370 
371 /* message aborted */
372 extern sfsistat	xxfi_abort __P((SMFICTX *));
373 
374 /*
375 **  xxfi_abort(ctx) Invoked if message is aborted outside of the control of
376 **  the filter, for example, if the SMTP sender issues an RSET command. If
377 **  xxfi_abort is called, xxfi_eom will not be called and vice versa.
378 */
379 
380 /* connection cleanup */
381 extern sfsistat	xxfi_close __P((SMFICTX *));
382 
383 /*
384 **  xxfi_close(ctx) Invoked at end of the connection. This is called on
385 **  close even if the previous mail transaction was aborted.
386 */
387 #endif /* 0 */
388 
389 /*
390 **  Additional information is passed in to the vendor filter routines using
391 **  symbols. Symbols correspond closely to sendmail macros. The symbols
392 **  defined depend on the context. The value of a symbol is accessed using:
393 */
394 
395 /* Return the value of a symbol. */
396 LIBMILTER_API char * smfi_getsymval __P((SMFICTX *, char *));
397 
398 /*
399 **  Return the value of a symbol.
400 **
401 **	SMFICTX *ctx; Opaque context structure
402 **	char *symname; The name of the symbol to access.
403 */
404 
405 /*
406 **  Vendor filter routines that want to pass additional information back to
407 **  the MTA for use in SMTP replies may call smfi_setreply before returning.
408 */
409 
410 LIBMILTER_API int smfi_setreply __P((SMFICTX *, char *, char *, char *));
411 
412 /*
413 **  Alternatively, smfi_setmlreply can be called if a multi-line SMTP reply
414 **  is needed.
415 */
416 
417 LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, ...));
418 
419 /*
420 **  Set the specific reply code to be used in response to the active
421 **  command. If not specified, a generic reply code is used.
422 **
423 **	SMFICTX *ctx; Opaque context structure
424 **	char *rcode; The three-digit (RFC 821) SMTP reply code to be
425 **		returned, e.g., ``551''.
426 **	char *xcode; The extended (RFC 2034) reply code, e.g., ``5.7.6''.
427 **	char *message; The text part of the SMTP reply.
428 */
429 
430 /*
431 **  The xxfi_eom routine is called at the end of a message (essentially,
432 **  after the final DATA dot). This routine can call some special routines
433 **  to modify the envelope, header, or body of the message before the
434 **  message is enqueued. These routines must not be called from any vendor
435 **  routine other than xxfi_eom.
436 */
437 
438 LIBMILTER_API int smfi_addheader __P((SMFICTX *, char *, char *));
439 
440 /*
441 **  Add a header to the message. It is not checked for standards
442 **  compliance; the mail filter must ensure that no protocols are violated
443 **  as a result of adding this header.
444 **
445 **	SMFICTX *ctx; Opaque context structure
446 **	char *headerf; Header field name
447 **	char *headerv; Header field value
448 */
449 
450 LIBMILTER_API int smfi_chgheader __P((SMFICTX *, char *, int, char *));
451 
452 /*
453 **  Change/delete a header in the message.  It is not checked for standards
454 **  compliance; the mail filter must ensure that no protocols are violated
455 **  as a result of adding this header.
456 **
457 **	SMFICTX *ctx; Opaque context structure
458 **	char *headerf; Header field name
459 **	int index; The Nth occurence of header field name
460 **	char *headerv; New header field value (empty for delete header)
461 */
462 
463 LIBMILTER_API int smfi_insheader __P((SMFICTX *, int, char *, char *));
464 
465 /*
466 **  Insert a header into the message.  It is not checked for standards
467 **  compliance; the mail filter must ensure that no protocols are violated
468 **  as a result of adding this header.
469 **
470 **	SMFICTX *ctx; Opaque context structure
471 **  	int idx; index into the header list where the insertion should happen
472 **	char *headerh; Header field name
473 **	char *headerv; Header field value
474 */
475 
476 LIBMILTER_API int smfi_chgfrom __P((SMFICTX *, char *, char *));
477 
478 /*
479 **  Modify envelope sender address
480 **
481 **	SMFICTX *ctx; Opaque context structure
482 **	char *mail; New envelope sender address
483 **	char *args; ESMTP arguments
484 */
485 
486 
487 LIBMILTER_API int smfi_addrcpt __P((SMFICTX *, char *));
488 
489 /*
490 **  Add a recipient to the envelope
491 **
492 **	SMFICTX *ctx; Opaque context structure
493 **	char *rcpt; Recipient to be added
494 */
495 
496 LIBMILTER_API int smfi_addrcpt_par __P((SMFICTX *, char *, char *));
497 
498 /*
499 **  Add a recipient to the envelope
500 **
501 **	SMFICTX *ctx; Opaque context structure
502 **	char *rcpt; Recipient to be added
503 **	char *args; ESMTP arguments
504 */
505 
506 
507 LIBMILTER_API int smfi_delrcpt __P((SMFICTX *, char *));
508 
509 /*
510 **  Send a "no-op" up to the MTA to tell it we're still alive, so long
511 **  milter-side operations don't time out.
512 **
513 **	SMFICTX *ctx; Opaque context structure
514 */
515 
516 LIBMILTER_API int smfi_progress __P((SMFICTX *));
517 
518 /*
519 **  Delete a recipient from the envelope
520 **
521 **	SMFICTX *ctx; Opaque context structure
522 **	char *rcpt; Envelope recipient to be deleted. This should be in
523 **		exactly the form passed to xxfi_envrcpt or the address may
524 **		not be deleted.
525 */
526 
527 LIBMILTER_API int smfi_replacebody __P((SMFICTX *, unsigned char *, int));
528 
529 /*
530 **  Replace the body of the message. This routine may be called multiple
531 **  times if the body is longer than convenient to send in one call. End of
532 **  line should be represented as Carriage-Return/Line Feed.
533 **
534 **	char *bodyp; Pointer to block of body information to insert
535 **	int bodylen; Length of data pointed at by bodyp
536 */
537 
538 /*
539 **  If the message is aborted (for example, if the SMTP sender sends the
540 **  envelope but then does a QUIT or RSET before the data is sent),
541 **  xxfi_abort is called. This can be used to reset state.
542 */
543 
544 /*
545 **  Quarantine an envelope
546 **
547 **	SMFICTX *ctx; Opaque context structure
548 **	char *reason: explanation
549 */
550 
551 LIBMILTER_API int smfi_quarantine __P((SMFICTX *ctx, char *reason));
552 
553 /*
554 **  Connection-private data (specific to an SMTP connection) can be
555 **  allocated using the smfi_setpriv routine; routines can access private
556 **  data using smfi_getpriv.
557 */
558 
559 LIBMILTER_API int smfi_setpriv __P((SMFICTX *, void *));
560 
561 /*
562 **  Set the private data pointer
563 **
564 **	SMFICTX *ctx; Opaque context structure
565 **	void *privatedata; Pointer to private data area
566 */
567 
568 LIBMILTER_API void *smfi_getpriv __P((SMFICTX *));
569 
570 /*
571 **  Get the private data pointer
572 **
573 **	SMFICTX *ctx; Opaque context structure
574 **	void *privatedata; Pointer to private data area
575 */
576 
577 LIBMILTER_API int smfi_setsymlist __P((SMFICTX *, int, char *));
578 
579 /*
580 **  Set list of symbols (macros) to receive
581 **
582 **	SMFICTX *ctx; Opaque context structure
583 **	int where; where in the SMTP dialogue should the macros be sent
584 **	char *macros; list of macros (space separated)
585 */
586 
587 #if _FFR_THREAD_MONITOR
588 LIBMILTER_API int smfi_set_max_exec_time __P((unsigned int));
589 #endif /* _FFR_THREAD_MONITOR */
590 
591 #ifdef __cplusplus
592 }
593 #endif /* __cplusplus */
594 
595 #endif /* ! _LIBMILTER_MFAPI_H */
596