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