mfapi.h revision 261363
1/*
2 * Copyright (c) 1999-2004, 2006, 2008, 2012 Proofpoint, 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.83 2013/11/22 20:51:27 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# if _FFR_MDS_NEGOTIATE
22#  define SMFI_VERSION	0x01000002	/* libmilter version number */
23
24   /* first libmilter version that has MDS support */
25#  define SMFI_VERSION_MDS	0x01000002
26# else /* _FFR_MDS_NEGOTIATE */
27#  define SMFI_VERSION	0x01000001	/* libmilter version number */
28# endif /* _FFR_MDS_NEGOTIATE */
29#endif /* ! SMFI_VERSION */
30
31#define SM_LM_VRS_MAJOR(v)	(((v) & 0x7f000000) >> 24)
32#define SM_LM_VRS_MINOR(v)	(((v) & 0x007fff00) >> 8)
33#define SM_LM_VRS_PLVL(v)	((v) & 0x0000007f)
34
35# include <sys/types.h>
36# include <sys/socket.h>
37
38#include "libmilter/mfdef.h"
39
40# define LIBMILTER_API		extern
41
42
43/* Only need to export C interface if used by C++ source code */
44#ifdef __cplusplus
45extern "C" {
46#endif /* __cplusplus */
47
48#ifndef _SOCK_ADDR
49# define _SOCK_ADDR	struct sockaddr
50#endif /* ! _SOCK_ADDR */
51
52/*
53**  libmilter functions return one of the following to indicate
54**  success/failure(/continue):
55*/
56
57#define MI_SUCCESS	0
58#define MI_FAILURE	(-1)
59#if _FFR_WORKERS_POOL
60# define MI_CONTINUE	1
61#endif /* _FFR_WORKERS_POOL */
62
63/* "forward" declarations */
64typedef struct smfi_str SMFICTX;
65typedef struct smfi_str *SMFICTX_PTR;
66
67typedef struct smfiDesc smfiDesc_str;
68typedef struct smfiDesc	*smfiDesc_ptr;
69
70/*
71**  Type which callbacks should return to indicate message status.
72**  This may take on one of the SMFIS_* values listed below.
73*/
74
75typedef int	sfsistat;
76
77#if defined(__linux__) && defined(__GNUC__) && defined(__cplusplus) && __GNUC_MINOR__ >= 8
78# define SM__P(X)	__PMT(X)
79#else /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
80# define SM__P(X)	__P(X)
81#endif /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
82
83/* Some platforms don't define __P -- do it for them here: */
84#ifndef __P
85# ifdef __STDC__
86#  define __P(X) X
87# else /* __STDC__ */
88#  define __P(X) ()
89# endif /* __STDC__ */
90#endif /* __P */
91
92#if SM_CONF_STDBOOL_H
93# include <stdbool.h>
94#else /* SM_CONF_STDBOOL_H */
95# ifndef __cplusplus
96#  ifndef bool
97#   ifndef __bool_true_false_are_defined
98typedef int	bool;
99#    define false	0
100#    define true	1
101#    define __bool_true_false_are_defined	1
102#   endif /* ! __bool_true_false_are_defined */
103#  endif /* bool */
104# endif /* ! __cplusplus */
105#endif /* SM_CONF_STDBOOL_H */
106
107/*
108**  structure describing one milter
109*/
110
111struct smfiDesc
112{
113	char		*xxfi_name;	/* filter name */
114	int		xxfi_version;	/* version code -- do not change */
115	unsigned long	xxfi_flags;	/* flags */
116
117	/* connection info filter */
118	sfsistat	(*xxfi_connect) SM__P((SMFICTX *, char *, _SOCK_ADDR *));
119
120	/* SMTP HELO command filter */
121	sfsistat	(*xxfi_helo) SM__P((SMFICTX *, char *));
122
123	/* envelope sender filter */
124	sfsistat	(*xxfi_envfrom) SM__P((SMFICTX *, char **));
125
126	/* envelope recipient filter */
127	sfsistat	(*xxfi_envrcpt) SM__P((SMFICTX *, char **));
128
129	/* header filter */
130	sfsistat	(*xxfi_header) SM__P((SMFICTX *, char *, char *));
131
132	/* end of header */
133	sfsistat	(*xxfi_eoh) SM__P((SMFICTX *));
134
135	/* body block */
136	sfsistat	(*xxfi_body) SM__P((SMFICTX *, unsigned char *, size_t));
137
138	/* end of message */
139	sfsistat	(*xxfi_eom) SM__P((SMFICTX *));
140
141	/* message aborted */
142	sfsistat	(*xxfi_abort) SM__P((SMFICTX *));
143
144	/* connection cleanup */
145	sfsistat	(*xxfi_close) SM__P((SMFICTX *));
146
147	/* any unrecognized or unimplemented command filter */
148	sfsistat	(*xxfi_unknown) SM__P((SMFICTX *, const char *));
149
150	/* SMTP DATA command filter */
151	sfsistat	(*xxfi_data) SM__P((SMFICTX *));
152
153	/* negotiation callback */
154	sfsistat	(*xxfi_negotiate) SM__P((SMFICTX *,
155					unsigned long, unsigned long,
156					unsigned long, unsigned long,
157					unsigned long *, unsigned long *,
158					unsigned long *, unsigned long *));
159
160#if 0
161	/* signal handler callback, not yet implemented. */
162	int		(*xxfi_signal) SM__P((int));
163#endif
164
165};
166
167LIBMILTER_API int smfi_opensocket __P((bool));
168LIBMILTER_API int smfi_register __P((struct smfiDesc));
169LIBMILTER_API int smfi_main __P((void));
170LIBMILTER_API int smfi_setbacklog __P((int));
171LIBMILTER_API int smfi_setdbg __P((int));
172LIBMILTER_API int smfi_settimeout __P((int));
173LIBMILTER_API int smfi_setconn __P((char *));
174LIBMILTER_API int smfi_stop __P((void));
175LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
176LIBMILTER_API int smfi_version __P((unsigned int *, unsigned int *, 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_NOMACROS	(-1)	/* Do NOT use, internal only */
210#define SMFIM_FIRST	0	/* Do NOT use, internal marker only */
211#define SMFIM_CONNECT	0	/* connect */
212#define SMFIM_HELO	1	/* HELO/EHLO */
213#define SMFIM_ENVFROM	2	/* MAIL From */
214#define SMFIM_ENVRCPT	3	/* RCPT To */
215#define SMFIM_DATA	4	/* DATA */
216#define SMFIM_EOM	5	/* end of message (final dot) */
217#define SMFIM_EOH	6	/* end of header */
218#define SMFIM_LAST	6	/* Do NOT use, internal marker only */
219
220/*
221**  Continue processing message/connection.
222*/
223
224#define SMFIS_CONTINUE	0
225
226/*
227**  Reject the message/connection.
228**  No further routines will be called for this message
229**  (or connection, if returned from a connection-oriented routine).
230*/
231
232#define SMFIS_REJECT	1
233
234/*
235**  Accept the message,
236**  but silently discard the message.
237**  No further routines will be called for this message.
238**  This is only meaningful from message-oriented routines.
239*/
240
241#define SMFIS_DISCARD	2
242
243/*
244**  Accept the message/connection.
245**  No further routines will be called for this message
246**  (or connection, if returned from a connection-oriented routine;
247**  in this case, it causes all messages on this connection
248**  to be accepted without filtering).
249*/
250
251#define SMFIS_ACCEPT	3
252
253/*
254**  Return a temporary failure, i.e.,
255**  the corresponding SMTP command will return a 4xx status code.
256**  In some cases this may prevent further routines from
257**  being called on this message or connection,
258**  although in other cases (e.g., when processing an envelope
259**  recipient) processing of the message will continue.
260*/
261
262#define SMFIS_TEMPFAIL	4
263
264/*
265**  Do not send a reply to the MTA
266*/
267
268#define SMFIS_NOREPLY	7
269
270/*
271**  Skip over rest of same callbacks, e.g., body.
272*/
273
274#define SMFIS_SKIP	8
275
276/* xxfi_negotiate: use all existing protocol options/actions */
277#define SMFIS_ALL_OPTS	10
278
279#if 0
280/*
281**  Filter Routine Details
282*/
283
284/* connection info filter */
285extern sfsistat	xxfi_connect __P((SMFICTX *, char *, _SOCK_ADDR *));
286
287/*
288**  xxfi_connect(ctx, hostname, hostaddr) Invoked on each connection
289**
290**	char *hostname; Host domain name, as determined by a reverse lookup
291**		on the host address.
292**	_SOCK_ADDR *hostaddr; Host address, as determined by a getpeername
293**		call on the SMTP socket.
294*/
295
296/* SMTP HELO command filter */
297extern sfsistat	xxfi_helo __P((SMFICTX *, char *));
298
299/*
300**  xxfi_helo(ctx, helohost) Invoked on SMTP HELO/EHLO command
301**
302**	char *helohost; Value passed to HELO/EHLO command, which should be
303**		the domain name of the sending host (but is, in practice,
304**		anything the sending host wants to send).
305*/
306
307/* envelope sender filter */
308extern sfsistat	xxfi_envfrom __P((SMFICTX *, char **));
309
310/*
311**  xxfi_envfrom(ctx, argv) Invoked on envelope from
312**
313**	char **argv; Null-terminated SMTP command arguments;
314**		argv[0] is guaranteed to be the sender address.
315**		Later arguments are the ESMTP arguments.
316*/
317
318/* envelope recipient filter */
319extern sfsistat	xxfi_envrcpt __P((SMFICTX *, char **));
320
321/*
322**  xxfi_envrcpt(ctx, argv) Invoked on each envelope recipient
323**
324**	char **argv; Null-terminated SMTP command arguments;
325**		argv[0] is guaranteed to be the recipient address.
326**		Later arguments are the ESMTP arguments.
327*/
328
329/* unknown command filter */
330
331extern sfsistat	*xxfi_unknown __P((SMFICTX *, const char *));
332
333/*
334**  xxfi_unknown(ctx, arg) Invoked when SMTP command is not recognized or not
335**  implemented.
336**	const char *arg; Null-terminated SMTP command
337*/
338
339/* header filter */
340extern sfsistat	xxfi_header __P((SMFICTX *, char *, char *));
341
342/*
343**  xxfi_header(ctx, headerf, headerv) Invoked on each message header. The
344**  content of the header may have folded white space (that is, multiple
345**  lines with following white space) included.
346**
347**	char *headerf; Header field name
348**	char *headerv; Header field value
349*/
350
351/* end of header */
352extern sfsistat	xxfi_eoh __P((SMFICTX *));
353
354/*
355**  xxfi_eoh(ctx) Invoked at end of header
356*/
357
358/* body block */
359extern sfsistat	xxfi_body __P((SMFICTX *, unsigned char *, size_t));
360
361/*
362**  xxfi_body(ctx, bodyp, bodylen) Invoked for each body chunk. There may
363**  be multiple body chunks passed to the filter. End-of-lines are
364**  represented as received from SMTP (normally Carriage-Return/Line-Feed).
365**
366**	unsigned char *bodyp; Pointer to body data
367**	size_t bodylen; Length of body data
368*/
369
370/* end of message */
371extern sfsistat	xxfi_eom __P((SMFICTX *));
372
373/*
374**  xxfi_eom(ctx) Invoked at end of message. This routine can perform
375**  special operations such as modifying the message header, body, or
376**  envelope.
377*/
378
379/* message aborted */
380extern sfsistat	xxfi_abort __P((SMFICTX *));
381
382/*
383**  xxfi_abort(ctx) Invoked if message is aborted outside of the control of
384**  the filter, for example, if the SMTP sender issues an RSET command. If
385**  xxfi_abort is called, xxfi_eom will not be called and vice versa.
386*/
387
388/* connection cleanup */
389extern sfsistat	xxfi_close __P((SMFICTX *));
390
391/*
392**  xxfi_close(ctx) Invoked at end of the connection. This is called on
393**  close even if the previous mail transaction was aborted.
394*/
395#endif /* 0 */
396
397/*
398**  Additional information is passed in to the vendor filter routines using
399**  symbols. Symbols correspond closely to sendmail macros. The symbols
400**  defined depend on the context. The value of a symbol is accessed using:
401*/
402
403/* Return the value of a symbol. */
404LIBMILTER_API char * smfi_getsymval __P((SMFICTX *, char *));
405
406/*
407**  Return the value of a symbol.
408**
409**	SMFICTX *ctx; Opaque context structure
410**	char *symname; The name of the symbol to access.
411*/
412
413/*
414**  Vendor filter routines that want to pass additional information back to
415**  the MTA for use in SMTP replies may call smfi_setreply before returning.
416*/
417
418LIBMILTER_API int smfi_setreply __P((SMFICTX *, char *, char *, char *));
419
420/*
421**  Alternatively, smfi_setmlreply can be called if a multi-line SMTP reply
422**  is needed.
423*/
424
425LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, ...));
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
446LIBMILTER_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
458LIBMILTER_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
471LIBMILTER_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
484LIBMILTER_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
495LIBMILTER_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
504LIBMILTER_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
515LIBMILTER_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
524LIBMILTER_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
535LIBMILTER_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
559LIBMILTER_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
567LIBMILTER_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
576LIBMILTER_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
585LIBMILTER_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
596LIBMILTER_API int smfi_set_max_exec_time __P((unsigned int));
597#endif /* _FFR_THREAD_MONITOR */
598
599#ifdef __cplusplus
600}
601#endif /* __cplusplus */
602
603#endif /* ! _LIBMILTER_MFAPI_H */
604