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