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