diff options
Diffstat (limited to 'contrib/sendmail/libmilter')
47 files changed, 4319 insertions, 269 deletions
diff --git a/contrib/sendmail/libmilter/Makefile.m4 b/contrib/sendmail/libmilter/Makefile.m4 index 19381a4..f767441 100644 --- a/contrib/sendmail/libmilter/Makefile.m4 +++ b/contrib/sendmail/libmilter/Makefile.m4 @@ -1,5 +1,7 @@ include(confBUILDTOOLSDIR`/M4/switch.m4') +dnl only required for compilation of EXTRAS +define(`confREQUIRE_LIBSM', `true') define(`confMT', `true') # sendmail dir @@ -8,17 +10,29 @@ PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ') bldPRODUCT_START(`library', `libmilter') define(`bldINSTALLABLE', `true') -define(`bldSOURCES', `main.c engine.c listener.c handler.c comm.c smfi.c signal.c sm_gethost.c ') -bldPUSH_SMLIB(`smutil') +define(`LIBMILTER_EXTRAS', `errstring.c strl.c') +APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL -Dsm_snprintf=snprintf') +define(`bldSOURCES', `main.c engine.c listener.c handler.c comm.c smfi.c signal.c sm_gethost.c LIBMILTER_EXTRAS ') +define(`confBEFORE', `LIBMILTER_EXTRAS') bldPUSH_INSTALL_TARGET(`install-mfapi') bldPRODUCT_END -APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL') + +PUSHDIVERT(3) +errstring.c: + ${LN} ${LNOPTS} ${SRCDIR}/libsm/errstring.c . + +strl.c: + ${LN} ${LNOPTS} ${SRCDIR}/libsm/strl.c . +POPDIVERT + divert(bldTARGETS_SECTION) -# Install the API header file +# Install the API header files MFAPI= ${SRCDIR}/inc`'lude/libmilter/mfapi.h +MFDEF= ${SRCDIR}/inc`'lude/libmilter/mfdef.h install-mfapi: ${MFAPI} ${INSTALL} -c -o ${INCOWN} -g ${INCGRP} -m ${INCMODE} ${MFAPI} ${DESTDIR}${INCLUDEDIR} + ${INSTALL} -c -o ${INCOWN} -g ${INCGRP} -m ${INCMODE} ${MFDEF} ${DESTDIR}${INCLUDEDIR} divert(0) bldFINISH diff --git a/contrib/sendmail/libmilter/README b/contrib/sendmail/libmilter/README index 3eae861..f38f68a 100644 --- a/contrib/sendmail/libmilter/README +++ b/contrib/sendmail/libmilter/README @@ -9,17 +9,27 @@ through reference to a sample filter which is attached at the end of this file. It is necessary to first build libmilter.a, which can be done by issuing the './Build' command in SRCDIR/libmilter . -NOTE: Both libmilter and the callouts in sendmail are marked as an FFR (For -Future Release). If you intend to use them in 8.11.X, you must compiled -both libmilter and sendmail with -D_FFR_MILTER defined. You can do this by -adding the following to your devtools/Site/site.config.m4 file: +NOTE: If you intend to use filters in sendmail, you must compile sendmail +with -DMILTER defined. You can do this by adding the following to +your devtools/Site/site.config.m4 file: - dnl Milter - APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_MILTER=1') - APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER=1') + APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') + ++----------------+ +| SECURITY HINTS | ++----------------+ + +Note: we strongly recommend not to run any milter as root. Libmilter +does not need root access to communicate with sendmail. It is a +good security practice to run a program only with root privileges +if really necessary. A milter should probably check first whether +it runs as root and refuse to start in that case. There is a +compile time option _FFR_MILTER_ROOT_UNSAFE which keeps libmilter +from unlinking a socket when running as root. It is recommended +to turn on this option: + + APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER_ROOT_UNSAFE ') -You will also need to define _FFR_MILTER when building your .cf file using -m4. +-------------------+ | BUILDING A FILTER | @@ -29,14 +39,14 @@ The following command presumes that the sample code from the end of this README is saved to a file named 'sample.c' and built in the local platform- specific build subdirectory (SRCDIR/obj.*/libmilter). - cc -I../../sendmail -I../../include -o sample sample.c libmilter.a ../libsmutil/libsmutil.a -pthread + cc -I../../sendmail -I../../include -o sample sample.c libmilter.a ../libsm/libsm.a -pthread It is recommended that you build your filters in a location outside of the sendmail source tree. Modify the compiler include references (-I) and the library locations accordingly. Also, some operating systems may require additional libraries. For example, SunOS 5.X requires '-lresolv --lsocket -lnsl'. Depending on your OS you may need a library instead -of the option -pthread, e.g., -lpthread. +-lsocket -lnsl'. Depending on your operating system you may need a library +instead of the option -pthread, e.g., -lpthread. Filters must be thread-safe! Many operating systems now provide support for POSIX threads in the standard C libraries. The compiler flag to link with @@ -77,13 +87,13 @@ IPv4 socket on port 3333 of localhost. The current flags (F=) are: T Temporary fail connection if filter unavailable If neither F=R nor F=T is specified, the message is passed through sendmail -as if the filter were not present. +in case of filter errors as if the failing filters were not present. Finally, you can override the default timeouts used by sendmail when talking to the filters using the T= equate. There are four fields inside of the T= equate: -Letter Meaning +Letter Meaning C Timeout for connecting to a filter (if 0, use system timeout) S Timeout for sending information from the MTA to a filter R Timeout for reading reply from the filter @@ -94,7 +104,7 @@ Note the separator between each is a ';' as a ',' already separates equates and therefore can't separate timeouts. The default values (if not set in the config) are: -T=C:0m;S:10s;R:10s;E:5m +T=C:5m;S:10s;R:10s;E:5m where 's' is seconds and 'm' is minutes. @@ -182,6 +192,30 @@ the logging level of sendmail can be raised with the LogLevel option. See the sendmail(8) manual page for more information. ++--------------+ +| REQUIREMENTS | ++--------------+ + +libmilter requires pthread support in the operating system. Moreover, it +requires that the library functions it uses are thread safe; which is true +for the operating systems libmilter has been developed and tested on. On +some operating systems this requires special compile time options (e.g., +not just -pthread). libmilter is currently known to work on (modulo problems +in the pthread support of some specific versions): + +FreeBSD 3.x, 4.x +SunOS 5.x (x >= 5) +AIX 4.3.x +HP UX 11.x +Linux (recent versions/distributions) + +libmilter is currently not supported on: + +IRIX 6.x +Ultrix + +Feedback about problems (and possible fixes) is welcome. + +--------------------------+ | SOURCE FOR SAMPLE FILTER | +--------------------------+ @@ -201,14 +235,11 @@ below to verify the functions are thread safe. #include "libmilter/mfapi.h" +#ifndef true typedef int bool; - -#ifndef FALSE -# define FALSE 0 -#endif /* ! FALSE*/ -#ifndef TRUE -# define TRUE 1 -#endif /* ! TRUE*/ +# define false 0 +# define true 1 +#endif /* ! true */ struct mlfiPriv { @@ -295,7 +326,7 @@ mlfi_body(ctx, bodyp, bodylen) if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0) { /* write failed */ - (void) mlfi_cleanup(ctx, FALSE); + (void) mlfi_cleanup(ctx, false); return SMFIS_TEMPFAIL; } @@ -307,7 +338,7 @@ sfsistat mlfi_eom(ctx) SMFICTX *ctx; { - return mlfi_cleanup(ctx, TRUE); + return mlfi_cleanup(ctx, true); } sfsistat @@ -321,7 +352,7 @@ sfsistat mlfi_abort(ctx) SMFICTX *ctx; { - return mlfi_cleanup(ctx, FALSE); + return mlfi_cleanup(ctx, false); } sfsistat @@ -349,7 +380,7 @@ mlfi_cleanup(ctx, ok) { /* add a header to the message announcing our presence */ if (gethostname(host, sizeof host) < 0) - strlcpy(host, "localhost", sizeof host); + snprintf(host, sizeof host, "localhost"); p = strrchr(priv->mlfi_fname, '/'); if (p == NULL) p = priv->mlfi_fname; @@ -426,4 +457,4 @@ main(argc, argv) /* eof */ -$Revision: 8.9.2.1.2.19 $, Last updated $Date: 2001/06/28 22:25:14 $ +$Revision: 8.35 $, Last updated $Date: 2002/01/07 21:29:20 $ diff --git a/contrib/sendmail/libmilter/comm.c b/contrib/sendmail/libmilter/comm.c index af1ee6d..3347808 100644 --- a/contrib/sendmail/libmilter/comm.c +++ b/contrib/sendmail/libmilter/comm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,17 +8,16 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: comm.c,v 8.30.4.6 2000/10/05 22:44:01 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: comm.c,v 8.48 2001/11/07 17:43:04 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" +#include <sm/errstring.h> -#define FD_Z FD_ZERO(&readset); \ - FD_SET((u_int) sd, &readset); \ - FD_ZERO(&excset); \ - FD_SET((u_int) sd, &excset) +#define FD_Z FD_ZERO(&readset); \ + FD_SET((unsigned int) sd, &readset); \ + FD_ZERO(&excset); \ + FD_SET((unsigned int) sd, &excset) /* ** MI_RD_CMD -- read a command @@ -73,11 +72,13 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) *cmd = SMFIC_SELECT; return NULL; } - if ((len = MI_SOCK_READ(sd, data + i, sizeof data - i)) < 0) + + len = MI_SOCK_READ(sd, data + i, sizeof data - i); + if (MI_SOCK_READ_FAIL(len)) { smi_log(SMI_LOG_ERR, "%s, mi_rd_cmd: read returned %d: %s", - name, len, strerror(errno)); + name, len, sm_errstring(errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -100,7 +101,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: select returned %d: %s", - name, ret, strerror(errno)); + name, ret, sm_errstring(errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -116,7 +117,11 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) *cmd = SMFIC_TOOBIG; return NULL; } +#if _FFR_ADD_NULL + buf = malloc(expl + 1); +#else /* _FFR_ADD_NULL */ buf = malloc(expl); +#endif /* _FFR_ADD_NULL */ if (buf == NULL) { *cmd = SMFIC_MALLOC; @@ -133,11 +138,12 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) free(buf); return NULL; } - if ((len = MI_SOCK_READ(sd, buf + i, expl - i)) < 0) + len = MI_SOCK_READ(sd, buf + i, expl - i); + if (MI_SOCK_READ_FAIL(len)) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: read returned %d: %s", - name, len, strerror(errno)); + name, len, sm_errstring(errno)); ret = -1; break; } @@ -156,6 +162,10 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) if (len >= expl - i) { *rlen = expl; +#if _FFR_ADD_NULL + /* makes life simpler for common string routines */ + buf[expl] = '\0'; +#endif /* _FFR_ADD_NULL */ return buf; } i += len; @@ -175,14 +185,14 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: select returned %d: %s", - name, ret, strerror(save_errno)); + name, ret, sm_errstring(save_errno)); *cmd = SMFIC_RECVERR; return NULL; } *cmd = SMFIC_UNKNERR; return NULL; } -/* +/* ** MI_WR_CMD -- write a cmd to sd ** ** Parameters: @@ -222,7 +232,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) do { FD_ZERO(&wrtset); - FD_SET((u_int) sd, &wrtset); + FD_SET((unsigned int) sd, &wrtset); if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0) return MI_FAILURE; } while (ret < 0 && errno == EINTR); @@ -248,7 +258,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) do { FD_ZERO(&wrtset); - FD_SET((u_int) sd, &wrtset); + FD_SET((unsigned int) sd, &wrtset); if ((ret = select(sd + 1, NULL, &wrtset, NULL, timeout)) == 0) return MI_FAILURE; } while (ret < 0 && errno == EINTR); @@ -264,4 +274,3 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) } return MI_SUCCESS; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/docs/api.html b/contrib/sendmail/libmilter/docs/api.html new file mode 100644 index 0000000..af714ef --- /dev/null +++ b/contrib/sendmail/libmilter/docs/api.html @@ -0,0 +1,194 @@ +<html> +<head><title>Milter API</title></head> +<body> +<h1>Milter API</h1> + +<h2>Contents</h2> +<ul> + <li>Library Control Functions + <li>Data Access Functions + <li>Message Modification Functions + <li>Callbacks +</ul> + +<h2>Library Control Functions</h2> + +Before handing control to libmilter (by calling <a +href="smfi_main.html">smfi_main</a>), a filter may call the following +functions to set libmilter parameters. In particular, the filter must +call <a href="smfi_register.html">smfi_register</a> to register its +callbacks. Each function will return either MI_SUCCESS or MI_FAILURE to +indicate the status of the operation. +<p> +None of these functions communicate with the MTA. All alter the +library's state, some of which is communicated to the MTA inside <a +href="smfi_main.html">smfi_main</a>. +<p> +<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr> + +<tr><td><a href="smfi_register.html">smfi_register</a></td><td>Register a filter.</td></tr> + +<tr><td><a href="smfi_setconn.html">smfi_setconn</a></td><td>Specify socket to use.</td></tr> + +<tr><td><a href="smfi_settimeout.html">smfi_settimeout</a></td><td>Set timeout.</td></tr> + +<tr><td><a href="smfi_main.html">smfi_main</a></td><td>Hand control to libmilter.</td></tr> + +</table> + +<h2>Data Access Functions</h2> + +The following functions may be called from within the filter-defined callbacks +to access information about the current connection or message. +<p> +<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr> +<tr><td><a href="smfi_getsymval.html">smfi_getsymval</a></td><td>Return the value +of a symbol.</td></tr> + +<tr><td><a href="smfi_getpriv.html">smfi_getpriv</a></td><td>Get the private data +pointer.</td></tr> + +<tr><td><a href="smfi_setpriv.html">smfi_setpriv</a></td><td>Set the private data +pointer.</td></tr> + +<tr><td><a href="smfi_setreply.html">smfi_setreply</a></td><td>Set the specific +reply code to be used.</td></tr> + +</table> + +<h2>Message Modification Functions</h2> + +The following functions change a message's contents and attributes. +<b>They may only be called in <a href="xxfi_eom.html">xxfi_eom</a></b>. +All of these functions may invoke additional communication with the MTA. +They will return either MI_SUCCESS or MI_FAILURE to indicate the status of +the operation. + +<p> +A filter must have set the appropriate flag (listed below) in the +description passed to <a href="smfi_register.html">smfi_register</a> +to call any message modification function. Failure to do so will +cause the MTA to treat a call to the function as a failure of the +filter, terminating its connection. + +<p> +Note that the status returned indicates only whether or not the +filter's message was successfully sent to the MTA, not whether or not +the MTA performed the requested operation. For example, <a +href="smfi_addheader.html">smfi_addheader</a>, when called with an +illegal header name, will return MI_SUCCESS even though the MTA may +later refuse to add the illegal header. +<p> +<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th><th>SMFIF_* flag</tr> +<tr><td><a href="smfi_addheader.html">smfi_addheader</a></td><td>Add a header to +the message.</td><td>SMFIF_ADDHDRS</td></tr> + +<tr><td><a href="smfi_chgheader.html">smfi_chgheader</a></td><td>Change or delete a header.</td><td>SMFIF_CHGHDRS</td></tr> + +<tr><td><a href="smfi_addrcpt.html">smfi_addrcpt</a></td><td>Add a recipient to +the envelope.</td><td>SMFIF_ADDRCPT</td></tr> + +<tr><td><a href="smfi_delrcpt.html">smfi_delrcpt</a></td><td>Delete a recipient +from the envelope.</td><td>SMFIF_DELRCPT</td></tr> + +<tr><td><a href="smfi_replacebody.html">smfi_replacebody</a></td><td>Replace the +body of the message.</td><td>SMFIF_CHGBODY</td></tr> + +</table> + +<h2>Callbacks</h2> + +The filter should implement one or more of the following callbacks, +which are registered via <a href="smfi_register.html">smfi_register</a>: +<p> +<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr> + +<tr><td><a href="xxfi_connect.html">xxfi_connect</a></td><td>connection info</td></tr> + +<tr><td><a href="xxfi_helo.html">xxfi_helo</a></td><td>SMTP HELO/EHLO command</td></tr> + +<tr><td><a href="xxfi_envfrom.html">xxfi_envfrom</a></td><td>envelope sender</td></tr> + +<tr><td><a href="xxfi_envrcpt.html">xxfi_envrcpt</a></td><td>envelope recipient</td></tr> + +<tr><td><a href="xxfi_header.html">xxfi_header</a></td><td>header</td></tr> + +<tr><td><a href="xxfi_eoh.html">xxfi_eoh</a></td><td>end of header</td></tr> + +<tr><td><a href="xxfi_body.html">xxfi_body</a></td><td>body block</td></tr> + +<tr><td><a href="xxfi_eom.html">xxfi_eom</a></td><td>end of message</td></tr> + +<tr><td><a href="xxfi_abort.html">xxfi_abort</a></td><td>message aborted</td></tr> + +<tr><td><a href="xxfi_close.html">xxfi_close</a></td><td>connection cleanup</td></tr> + +</table> + +<p> +The above callbacks should all return one of the following return values, +having the indicated meanings. Any return other than one of the below +values constitutes an error, and will cause sendmail to terminate its +connection to the offending filter. + +<p><a name="conn-spec"></a>Milter distinguishes between recipient-, +message-, and connection-oriented routines. Recipient-oriented +callbacks may affect the processing of a single message recipient; +message-oriented callbacks, a single message; connection-oriented +callbacks, an entire connection (during which multiple messages may be +delivered to multiple sets of recipients). +<a href="xxfi_envrcpt.html">xxfi_envrcpt</a> is recipient-oriented. +<a href="xxfi_connect.html">xxfi_connect</a>, +<a href="xxfi_helo.html">xxfi_helo</a> and +<a href="xxfi_close.html">xxfi_close</a> are connection-oriented. All +other callbacks are message-oriented. + +<p> +<table border="1" cellspacing=0 cellpadding=2> + <tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr> + <tr valign="top"> + <td>SMFIS_CONTINUE</td> + <td>Continue processing the current connection, message, or recipient. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_REJECT</td> + <td>For a connection-oriented routine, reject this connection; call <a href="xxfi_close.html">xxfi_close</a>.<br> + For a message-oriented routine (except + <a href="xxfi_eom.html">xxfi_eom</a> or + <a href="xxfi_abort.html">xxfi_abort</a>), reject this message.<br> + For a recipient-oriented routine, reject the current recipient (but continue processing the current message). + </td> + </tr> + <tr valign="top"> + <td>SMFIS_DISCARD</td> + <td>For a message- or recipient-oriented routine, accept this message, but silently discard it.<br> + SMFIS_DISCARD should not be returned by a connection-oriented routine. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_ACCEPT</td> + <td>For a connection-oriented routine, accept this connection without further filter processing; call <a href="xxfi_close.html">xxfi_close</a>.<br> + For a message- or recipient-oriented routine, accept this message without further filtering.<br> + </td> + </tr> + <tr valign="top"> + <td>SMFIS_TEMPFAIL</td> + <td>Return a temporary failure, i.e., the corresponding SMTP command will return an appropriate 4xx status code. + For a message-oriented routine (except <a href="xxfi_envfrom.html">xxfi_envfrom</a>), fail for this message. <br> + For a connection-oriented routine, fail for this connection; call <a href="xxfi_close.html">xxfi_close</a>. <br> + For a recipient-oriented routine, only fail for the current recipient; continue message processing. + </td> + </tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/design.html b/contrib/sendmail/libmilter/docs/design.html new file mode 100644 index 0000000..fbc74e6 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/design.html @@ -0,0 +1,144 @@ +<html> +<head> +<title>Architecture</title> +</head> +<body> + +<h1>Architecture</h1> + +<h2>Contents</h2> + +<ul> + <li>Design Goals + <li>Implementing Filtering Policies + <li>MTA - Filter Communication +</ul> + +<h2>Goals</h2> + +The Sendmail Content Management API (Milter) provides an interface for +third-party software to validate and modify messages as they pass +through the mail transport system. Filters can process messages' +connection (IP) information, envelope protocol elements, message +headers, and/or message body contents, and modify a message's +recipients, headers, and body. The MTA configuration file specifies +which filters are to be applied, and in what order, allowing an +administrator to combine multiple independently-developed filters. + +<p> +We expect to see both vendor-supplied, configurable mail filtering +applications and a multiplicity of script-like filters designed by and +for MTA administrators. A certain degree of coding sophistication and +domain knowledge on the part of the filter provider is assumed. This +allows filters to exercise fine-grained control at the SMTP level. +However, as will be seen in the example, many filtering applications +can be written with relatively little protocol knowledge. + +<p> +Given these expectations, the API is designed to achieve the following +goals: + +<OL> + <LI>Safety/security. + Filter processes should not need to run as root + (of course, they can if required, but that is a local issue); + this will simplify coding + and limit the impact of security flaws in the filter program. +<p> + <LI>Reliability. + Coding failures in a Milter process that cause that process + to hang or core-dump + should not stop mail delivery. + Faced with such a failure, + sendmail should use a default mechanism, + either behaving as if the filter were not present + or as if a required resource were unavailable. + The latter failure mode will generally have sendmail return + a 4xx SMTP code (although in later phases of the SMTP protocol + it may cause the mail to be queued for later processing). +<p> + <LI>Simplicity. + The API should make implementation of a new filter + no more difficult than absolutely necessary. + Subgoals include: + <UL> + <LI>Encourage good thread practice + by defining thread-clean interfaces including local data hooks. + <LI>Provide all interfaces required + while avoiding unnecessary pedanticism. + </UL> +<p> + <LI>Performance. + Simple filters should not seriously impact overall MTA performance. +</OL> + +<h2>Implementing Filtering Policies</h2> + +Milter is designed to allow a server administrator to combine +third-party filters to implement a desired mail filtering policy. For +example, if a site wished to scan incoming mail for viruses on several +platforms, eliminate unsolicited commercial email, and append a mandated +footer to selected incoming messages, the administrator could configure +the MTA to filter messages first through a server based anti-virus +engine, then via a large-scale spam-catching service, and finally +append the desired footer if the message still met requisite criteria. +Any of these filters could be added or changed independently. + +<p> +Thus the site administrator, not the filter writer, controls the +overall mail filtering environment. In particular, he/she must decide +which filters are run, in what order they are run, and how they +communicate with the MTA. These parameters, as well as the +actions to be taken if a filter becomes unavailable, are selectable +during MTA configuration. <a href="installation.html">Further +details</a> are available later in this document. + +<h2>MTA - Filter communication</h2> + +Filters run as separate processes, outside of the sendmail address +space. The benefits of this are threefold: + +<OL> + <LI>The filter need not run with "root" permissions, thereby + avoiding a large family of potential security problems.</LI> + + <LI>Failures in a particular filter will not affect the MTA or + other filters.</LI> + + <LI>The filter can potentially have higher performance because of + the parallelism inherent in multiple processes.</LI> +</OL> + +<p> +Each filter may communicate with multiple MTAs at the same time over +local or remote connections, using multiple threads of execution. <a +href="#figure-1">Figure 1</a> illustrates a possible network of +communication channels between a site's filters, its MTAs, and other +MTAs on the network: +</p> +<div align="center"> +<a name="figure-1"><img src="figure1.jpg" ALT=""></A><br> +<b>Figure 1: A set of MTA's interacting with a set of filters.</b> +</div> +<p> +The Milter library (libmilter) implements the communication protocol. +It accepts connections from various MTAs, passes the relevant data to +the filter through callbacks, then makes appropriate responses based +on return codes. A filter may also send data to the MTA as a result +of library calls. <a href="#figure-2">Figure 2</a> shows a single +filter process processing messages from two MTAs: +</p> +<div align="center"> +<img src="figure2.jpg" ALT=""><br> +<b>Figure 2: A filter handling simultaneous requests from two MTA's.</b> +</div> +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/figure1.fig b/contrib/sendmail/libmilter/docs/figure1.fig new file mode 100644 index 0000000..e0cbdc8 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure1.fig @@ -0,0 +1,56 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +6 975 225 5025 3375 +6 1500 1275 2700 2025 +2 2 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 5 + 1650 1425 2550 1425 2550 1875 1650 1875 1650 1425 +4 0 1 50 0 0 20 0.0000 4 195 645 1800 1725 MTA\001 +-6 +6 1950 2625 3150 3375 +2 2 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 5 + 2100 2775 3000 2775 3000 3225 2100 3225 2100 2775 +4 0 4 50 0 0 20 0.0000 4 195 645 2250 3075 MTA\001 +-6 +6 1050 225 2250 975 +2 2 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 5 + 1200 375 2100 375 2100 825 1200 825 1200 375 +4 0 14 50 0 0 20 0.0000 4 195 645 1350 675 MTA\001 +-6 +2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 + 2550 1575 3750 2625 +2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 + 2550 1575 3750 1575 +2 1 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 2 + 2550 1575 3750 825 +2 1 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 2 + 3000 2925 3750 2625 +2 1 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 2 + 2100 525 3750 825 +2 1 0 2 14 7 50 0 -1 0.000 0 0 7 0 0 2 + 2100 525 3750 2625 +2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 + 1050 3075 2100 3075 +2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 + 1050 1725 1650 1725 +2 1 0 4 0 7 50 0 -1 0.000 0 0 7 0 0 2 + 1050 675 1200 675 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3750 2475 4950 2475 4950 2925 3750 2925 3750 2475 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3750 1425 4950 1425 4950 1875 3750 1875 3750 1425 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3750 525 4950 525 4950 975 3750 975 3750 525 +4 0 0 50 0 1 20 0.0000 4 210 795 3900 2775 Filter 3\001 +4 0 0 50 0 1 20 0.0000 4 210 795 3900 1725 Filter 2\001 +4 0 0 50 0 1 20 0.0000 4 210 795 3900 825 Filter 1\001 +-6 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 300 525 1050 525 1050 3225 300 3225 300 525 +4 0 0 50 0 2 24 1.5708 4 255 1950 825 2850 INTERNET\001 diff --git a/contrib/sendmail/libmilter/docs/figure1.jpg b/contrib/sendmail/libmilter/docs/figure1.jpg Binary files differnew file mode 100644 index 0000000..1a5f1de --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure1.jpg diff --git a/contrib/sendmail/libmilter/docs/figure1.ps b/contrib/sendmail/libmilter/docs/figure1.ps new file mode 100644 index 0000000..ae31760 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure1.ps @@ -0,0 +1,173 @@ +%!PS-Adobe-2.0 +%%Title: figure1.fig +%%Creator: fig2dev Version 3.2.3 Patchlevel +%%CreationDate: Tue Jun 6 14:00:04 2000 +%%For: sean@host232.Sendmail.COM (Sean O'rourke,5400) +%%Orientation: Landscape +%%Pages: 1 +%%BoundingBox: 0 0 612 792 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 792 moveto 0 0 lineto 612 0 lineto 612 792 lineto closepath clip newpath +198.0 238.0 translate + 90 rotate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +%%Page: 1 1 +/Times-Bold ff 360.00 scf sf +825 2850 m +gs 1 -1 sc 90.0 rot (INTERNET) col0 sh gr +/Times-Roman ff 300.00 scf sf +1800 1725 m +gs 1 -1 sc (MTA) col1 sh gr +% Polyline +15.000 slw +n 2100 2775 m 3000 2775 l 3000 3225 l 2100 3225 l + cp gs col4 s gr +/Times-Roman ff 300.00 scf sf +2250 3075 m +gs 1 -1 sc (MTA) col4 sh gr +% Polyline +n 1200 375 m 2100 375 l 2100 825 l 1200 825 l + cp gs col14 s gr +/Times-Roman ff 300.00 scf sf +1350 675 m +gs 1 -1 sc (MTA) col14 sh gr +% Polyline +n 2550 1575 m + 3750 2625 l gs col1 s gr +% Polyline +n 2550 1575 m + 3750 1575 l gs col1 s gr +% Polyline +n 2550 1575 m + 3750 825 l gs col1 s gr +% Polyline +n 3000 2925 m + 3750 2625 l gs col4 s gr +% Polyline +n 2100 525 m + 3750 825 l gs col14 s gr +% Polyline +n 2100 525 m + 3750 2625 l gs col14 s gr +% Polyline +45.000 slw +n 1050 3075 m + 2100 3075 l gs col0 s gr +% Polyline +n 1050 1725 m + 1650 1725 l gs col0 s gr +% Polyline +n 1050 675 m + 1200 675 l gs col0 s gr +% Polyline +15.000 slw +n 3750 2475 m 4950 2475 l 4950 2925 l 3750 2925 l + cp gs col0 s gr +% Polyline +n 3750 1425 m 4950 1425 l 4950 1875 l 3750 1875 l + cp gs col0 s gr +% Polyline +n 3750 525 m 4950 525 l 4950 975 l 3750 975 l + cp gs col0 s gr +/Times-Italic ff 300.00 scf sf +3900 2775 m +gs 1 -1 sc (Filter 3) col0 sh gr +/Times-Italic ff 300.00 scf sf +3900 1725 m +gs 1 -1 sc (Filter 2) col0 sh gr +/Times-Italic ff 300.00 scf sf +3900 825 m +gs 1 -1 sc (Filter 1) col0 sh gr +% Polyline +7.500 slw +n 300 525 m 1050 525 l 1050 3225 l 300 3225 l + cp gs col0 s gr +% Polyline +15.000 slw +n 1650 1425 m 2550 1425 l 2550 1875 l 1650 1875 l + cp gs col1 s gr +$F2psEnd +rs +showpage diff --git a/contrib/sendmail/libmilter/docs/figure2.fig b/contrib/sendmail/libmilter/docs/figure2.fig new file mode 100644 index 0000000..c93bfe3 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure2.fig @@ -0,0 +1,67 @@ +#FIG 3.2 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 0 -1 0.000 0 0 1 0 2981.250 1200.000 2700 1050 3300 1200 2700 1350 + 1 1 1.00 60.00 120.00 +6 4200 900 6450 1350 +2 2 0 1 1 7 50 0 -1 0.000 0 0 7 0 0 5 + 4200 900 6450 900 6450 1350 4200 1350 4200 900 +4 0 1 50 0 0 16 0.0000 4 195 2040 4350 1200 xxfi_header callback\001 +-6 +6 4200 2250 6450 2700 +2 2 0 1 4 7 50 0 -1 0.000 0 0 7 0 0 5 + 4200 2250 6450 2250 6450 2700 4200 2700 4200 2250 +4 0 4 50 0 0 16 0.0000 4 195 2040 4350 2550 xxfi_header callback\001 +-6 +6 600 2100 1800 2850 +2 2 0 2 4 7 50 0 -1 0.000 0 0 7 0 0 5 + 750 2250 1650 2250 1650 2700 750 2700 750 2250 +4 0 4 50 0 0 20 0.0000 4 195 645 900 2550 MTA\001 +-6 +6 600 750 1800 1500 +2 2 0 2 1 7 50 0 -1 0.000 0 0 7 0 0 5 + 750 900 1650 900 1650 1350 750 1350 750 900 +4 0 1 50 0 0 20 0.0000 4 195 645 900 1200 MTA\001 +-6 +2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 4200 1200 3600 1200 +2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 3450 900 4050 900 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2400 300 6600 300 6600 3300 2400 3300 2400 300 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2550 750 3450 750 3450 2700 2550 2700 2550 750 +2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 3450 2700 4050 2700 +2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 4200 2400 3600 2400 +2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 1650 2700 2250 2700 +2 1 0 2 4 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 2400 2400 1800 2400 +2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 1650 900 2250 900 +2 1 0 2 1 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 2400 1200 1800 1200 +4 0 0 50 0 0 20 0.0000 4 195 630 3900 600 Filter\001 +4 0 4 50 0 0 12 0.0000 4 180 1620 3450 3000 callback (arguments)\001 +4 0 4 50 0 0 12 0.0000 4 180 1575 3900 1950 optional library calls,\001 +4 0 4 50 0 0 12 0.0000 4 135 855 3900 2175 return code\001 +4 0 4 50 0 0 12 0.0000 4 135 780 1500 2100 responses\001 +4 0 0 50 0 0 16 0.0000 4 165 645 2700 2085 Milter\001 +4 0 0 50 0 0 16 0.0000 4 225 675 2700 2400 library\001 +4 0 4 50 0 0 12 0.0000 4 135 510 1500 3000 header\001 diff --git a/contrib/sendmail/libmilter/docs/figure2.jpg b/contrib/sendmail/libmilter/docs/figure2.jpg Binary files differnew file mode 100644 index 0000000..8b11485 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure2.jpg diff --git a/contrib/sendmail/libmilter/docs/figure2.ps b/contrib/sendmail/libmilter/docs/figure2.ps new file mode 100644 index 0000000..861a193 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/figure2.ps @@ -0,0 +1,242 @@ +%!PS-Adobe-2.0 +%%Title: figure2.fig +%%Creator: fig2dev Version 3.2.3 Patchlevel +%%CreationDate: Tue Jun 6 13:57:47 2000 +%%For: sean@host232.Sendmail.COM (Sean O'rourke,5400) +%%Orientation: Landscape +%%Pages: 1 +%%BoundingBox: 0 0 612 792 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%Magnification: 1.5000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 792 moveto 0 0 lineto 612 0 lineto 612 792 lineto closepath clip newpath +144.0 65.5 translate + 90 rotate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.09000 0.09000 sc +%%Page: 1 1 +/Times-Roman ff 180.00 scf sf +1500 3000 m +gs 1 -1 sc (header) col4 sh gr +/Times-Roman ff 240.00 scf sf +4350 1200 m +gs 1 -1 sc (xxfi_header callback) col1 sh gr +% Polyline +7.500 slw +n 4200 2250 m 6450 2250 l 6450 2700 l 4200 2700 l + cp gs col4 s gr +/Times-Roman ff 240.00 scf sf +4350 2550 m +gs 1 -1 sc (xxfi_header callback) col4 sh gr +% Polyline +15.000 slw +n 750 2250 m 1650 2250 l 1650 2700 l 750 2700 l + cp gs col4 s gr +/Times-Roman ff 300.00 scf sf +900 2550 m +gs 1 -1 sc (MTA) col4 sh gr +% Polyline +n 750 900 m 1650 900 l 1650 1350 l 750 1350 l + cp gs col1 s gr +/Times-Roman ff 300.00 scf sf +900 1200 m +gs 1 -1 sc (MTA) col1 sh gr +% Arc +7.500 slw +gs clippath +2713 1319 m 2667 1357 l 2761 1475 l 2710 1363 l 2808 1437 l cp +eoclip +n 2981.2 1200.0 318.8 -151.9 151.9 arc +gs col0 s gr + gr + +% arrowhead +n 2808 1437 m 2710 1363 l 2761 1475 l 2808 1437 l cp gs 0.00 setgray ef gr col0 s +% Polyline +15.000 slw +gs clippath +3585 1140 m 3585 1260 l 3872 1260 l 3632 1200 l 3872 1140 l cp +eoclip +n 4200 1200 m + 3600 1200 l gs col1 s gr gr + +% arrowhead +n 3872 1140 m 3632 1200 l 3872 1260 l 3872 1140 l cp gs col1 1.00 shd ef gr col1 s +% Polyline +gs clippath +4065 960 m 4065 840 l 3778 840 l 4018 900 l 3778 960 l cp +eoclip +n 3450 900 m + 4050 900 l gs col1 s gr gr + +% arrowhead +n 3778 960 m 4018 900 l 3778 840 l 3778 960 l cp gs col1 1.00 shd ef gr col1 s +% Polyline +n 2400 300 m 6600 300 l 6600 3300 l 2400 3300 l + cp gs col0 s gr +% Polyline +7.500 slw +n 2550 750 m 3450 750 l 3450 2700 l 2550 2700 l + cp gs col0 s gr +% Polyline +15.000 slw +gs clippath +4065 2760 m 4065 2640 l 3778 2640 l 4018 2700 l 3778 2760 l cp +eoclip +n 3450 2700 m + 4050 2700 l gs col4 s gr gr + +% arrowhead +n 3778 2760 m 4018 2700 l 3778 2640 l 3778 2760 l cp gs col4 1.00 shd ef gr col4 s +% Polyline +gs clippath +3585 2340 m 3585 2460 l 3872 2460 l 3632 2400 l 3872 2340 l cp +eoclip +n 4200 2400 m + 3600 2400 l gs col4 s gr gr + +% arrowhead +n 3872 2340 m 3632 2400 l 3872 2460 l 3872 2340 l cp gs col4 1.00 shd ef gr col4 s +% Polyline +gs clippath +2265 2760 m 2265 2640 l 1978 2640 l 2218 2700 l 1978 2760 l cp +eoclip +n 1650 2700 m + 2250 2700 l gs col4 s gr gr + +% arrowhead +n 1978 2760 m 2218 2700 l 1978 2640 l 1978 2760 l cp gs col4 1.00 shd ef gr col4 s +% Polyline +gs clippath +1785 2340 m 1785 2460 l 2072 2460 l 1832 2400 l 2072 2340 l cp +eoclip +n 2400 2400 m + 1800 2400 l gs col4 s gr gr + +% arrowhead +n 2072 2340 m 1832 2400 l 2072 2460 l 2072 2340 l cp gs col4 1.00 shd ef gr col4 s +% Polyline +gs clippath +2265 960 m 2265 840 l 1978 840 l 2218 900 l 1978 960 l cp +eoclip +n 1650 900 m + 2250 900 l gs col1 s gr gr + +% arrowhead +n 1978 960 m 2218 900 l 1978 840 l 1978 960 l cp gs col1 1.00 shd ef gr col1 s +% Polyline +gs clippath +1785 1140 m 1785 1260 l 2072 1260 l 1832 1200 l 2072 1140 l cp +eoclip +n 2400 1200 m + 1800 1200 l gs col1 s gr gr + +% arrowhead +n 2072 1140 m 1832 1200 l 2072 1260 l 2072 1140 l cp gs col1 1.00 shd ef gr col1 s +/Times-Roman ff 300.00 scf sf +3900 600 m +gs 1 -1 sc (Filter) col0 sh gr +/Times-Roman ff 180.00 scf sf +3450 3000 m +gs 1 -1 sc (callback \(arguments\)) col4 sh gr +/Times-Roman ff 180.00 scf sf +3900 1950 m +gs 1 -1 sc (optional library calls,) col4 sh gr +/Times-Roman ff 180.00 scf sf +3900 2175 m +gs 1 -1 sc (return code) col4 sh gr +/Times-Roman ff 180.00 scf sf +1500 2100 m +gs 1 -1 sc (responses) col4 sh gr +/Times-Roman ff 240.00 scf sf +2700 2085 m +gs 1 -1 sc (Milter) col0 sh gr +/Times-Roman ff 240.00 scf sf +2700 2400 m +gs 1 -1 sc (library) col0 sh gr +% Polyline +7.500 slw +n 4200 900 m 6450 900 l 6450 1350 l 4200 1350 l + cp gs col1 s gr +$F2psEnd +rs +showpage diff --git a/contrib/sendmail/libmilter/docs/index.html b/contrib/sendmail/libmilter/docs/index.html new file mode 100644 index 0000000..44c5f90 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/index.html @@ -0,0 +1,92 @@ +<html> +<head> +<title>Filtering Mail with Sendmail</title> +</head> +<body> +<!-- +$Id: index.html,v 1.10 2001/06/01 00:05:03 ca Exp $ +--> + +<h1>Filtering Mail with Sendmail</h1> + +<!-- +<P><b>Disclaimer</b>: +This preliminary API description is provided for review only. This +specification may change based on feedback from reviewers, and does +not bind Sendmail to offer this functionality in any release. +--> + +<h2>Introduction</h2> + +<P> +Sendmail's Content Management API (milter) provides third-party +programs to access mail messages as they are being processed by the +Mail Transfer Agent (MTA), allowing them to examine and modify message +content and meta-information. Filtering policies implemented by +Milter-conformant filters may then be centrally configured and +composed in an end-user's MTA configuration file. + +<p> +Possible uses for filters include spam rejection, virus +filtering, and content control. In general, Milter seeks to address +site-wide filtering concerns in a scalable way. Individual users' mail +filtering needs (e.g. sorting messages by subject) are left to +client-level programs such as <a href="http://www.procmail.org">Procmail</a>. + +<P> +This document is a technical introduction intended for those +interested in developing Milter filters. It includes: +<ul> +<li>A description of Milter's design goals. + +<li>An explanation of Milter application architecture, including +interactions between the support library and user code, and between +filters and the MTA. + +<li>A specification of the C application programming interface. +<li>An example of a simple Milter filter. +</ul> + +<h2>Contents</h2> + +<ul> +<li><a href="design.html">Architecture</a> +<ul> + <li>Design Goals + <li>Implementing Filtering Policies + <li>MTA - Filter communication +</ul> +<li><a href="overview.html">Technical Overview</a> +<ul> + <li>Initialization + <li>Control flow + <li>Multithreading + <li>Resource Management + <li>Signal Handling +</ul> +<li><a href="api.html">API Documentation</a> +<ul> + <li>Library Control Functions + <li>Data Access Functions + <li>Message Modification Functions + <li>Callbacks +</ul> +<li><a href="installation.html">Installation and Configuration</a> +<ul> + <li>Compiling and Installing Your Filter + <li>Configuring Sendmail +</ul> +<li><a href="sample.html">A Sample Filter</a> +<!-- <li><a href="other.html">Other Sources of Information</a> --> +</ul> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000, 2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/installation.html b/contrib/sendmail/libmilter/docs/installation.html new file mode 100644 index 0000000..8ebe4ee --- /dev/null +++ b/contrib/sendmail/libmilter/docs/installation.html @@ -0,0 +1,169 @@ +<html> +<head><title>Installation and Configuration</title> +</head> +<body> +<h1>Installation</h1> +<h2>Contents</h2> +<ul> + <li><a href="#compile">Compiling and Installing Your Filter</a> + <li><a href="#config">Configuring Sendmail</a> +</ul> + +<h2><a name="compile">Compiling and Installing Your Filter</A></h2> + +To compile a filter, modify the Makefile provided with the sample program, or: +<ul> + <li>Put the include and Sendmail directories in your include path + (e.g. -I/path/to/include -I/path/to/sendmail). + + <li>Make sure libmilter.so is in your library path, and link your + application with it (e.g. "-lmilter"). + + <li>Compile with pthreads, either by using -pthread for gcc, or + linking with a pthreads support library (-lpthread). +</ul> +Your compile command line will look like +<pre> +cc -I/path/to/include -I/path/to/sendmail -c myfile.c +</pre> +and your linking command line will look something like +<pre> +cc -o myfilter [object-files] -L[library-location] -lmilter -pthread +</pre> + +<p> +To run the filter, the Milter shared library must be available to the +run-time linker. + +<H2><a name="config">Configuring Sendmail</A></H2> + +First, you must compile sendmail versions before 8.12 with _FFR_MILTER +defined. To do this, add the following lines to your build +configuration file (devtools/Site/config.site.m4) +<pre> +APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_MILTER=1') +APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER=1') +</pre> + +then type <code>./Build -c</code> in your sendmail directory. + +<P> +Next, you must add the desired filters to your sendmail configuration +(.mc) file. With versions before 8.12, the file must then be +processed with _FFR_MILTER defined. Mail filters have three equates: +The required <code>S=</code> equate specifies the socket where +sendmail should look for the filter; The optional <code>F=</code> and +<code>T=</code> equates specify flags and timeouts, respectively. All +equates names, equate field names, and flag values are case sensitive. + +<P> +The current flags (<code>F=</code>) are: +<p> +<table cellspacing="1" cellpadding=4 border=1> +<tr bgcolor="#dddddd" align=left valign=top> +<th>Flag</TH> <th align="center">Meaning</TH> +</TR> +<tr align="left" valign=top> +<TD>R</TD> <TD>Reject connection if filter unavailable</TD> +</TR> +<tr align="left" valign=top> +<TD>T</TD> <TD>Temporary fail connection if filter unavailable</TD> +</TR> +</TABLE> + +If a filter is unavailable or unresponsive and no flags have been +specified, the MTA will continue normal handling of the current +connection. The MTA will try to contact the filter again on each new +connection. + +<P> +There are three fields inside of the <code>T=</code> equate: S, R, and +E. Note the separator between each is a ";" (semicolon), as "," +(comma) already separates equates. The value of each field is a +decimal number followed by a single letter designating the units ("s" +for seconds, "m" for minutes). The fields have the following +meanings: +<p> +<TABLE cellspacing="1" cellpadding=4 border=1> +<TR bgcolor="#dddddd" align=left valign=top> +<TH>Flag</TH> <TH align="center">Meaning</TH> +</TR> +<TR align="left" valign=top> +<TD>C</TD> <TD>Timeout for connecting to a filter. If set to 0, the + system's <CODE>connect()</CODE> timeout will be used. + Default: 5m</TD> +</TR> +<TR align="left" valign=top> +<TD>S</TD> <TD>Timeout for sending information from the MTA to a + filter. Default: 10s</TD> +</TR> +<TR align="left" valign=top> +<TD>R</TD> <TD>Timeout for reading reply from the filter. Default: 10s</TD> +</TR> +<TR align="left" valign=top> +<TD>E</TD> <TD>Overall timeout between sending end-of-message to + filter and waiting for the final acknowledgment. Default: 5m</TD> +</TR> +</TABLE> + +<p> +The following sendmail.mc example specifies three filters. The first +two rendezvous on Unix-domain sockets in the /var/run directory; the +third uses an IP socket on port 999. +<pre> + INPUT_MAIL_FILTER(`filter1', `S=unix:/var/run/f1.sock, F=R') + INPUT_MAIL_FILTER(`filter2', `S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m') + INPUT_MAIL_FILTER(`filter3', `S=inet:999@localhost, T=C:2m') + + define(`confINPUT_MAIL_FILTERS', `filter2,filter1,filter3') +<hr width="30%"> + m4 <b>-D_FFR_MILTER</b> ../m4/cf.m4 myconfig.mc > myconfig.cf +</pre> +By default, the filters would be run in the order declared, +i.e. "filter1, filter2, filter3"; however, since +<code>confINPUT_MAIL_FILTERS</code> is defined, the filters will be +run "filter2, filter1, filter3". Also note that a filter can be +defined without adding it to the input filter list by using +MAIL_FILTER() instead of INPUT_MAIL_FILTER(). + +<p> +The above macros will result in the following lines being added to +your .cf file: +<PRE> + Xfilter1, S=unix:/var/run/f1.sock, F=R + Xfilter2, S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m + Xfilter3, S=inet:999@localhost, T=C:2m + + O InputMailFilters=filter2,filter1,filter3 +</PRE> +<p> +Finally, the sendmail macros accessible via <a +href="smfi_getsymval.html">smfi_getsymval</a> can be configured by +defining the following m4 variables (or cf options): +<table cellspacing="1" cellpadding=4 border=1> +<tr bgcolor="#dddddd" align=left valign=top> +<th align="center">In .mc file</th> <th align="center">In .cf file</TH> +<th align="center">Default Value</th> +</tr> +<tr><td>confMILTER_MACROS_CONNECT</td><td>Milter.macros.connect</td> +<td><code>j, _, {daemon_name}, {if_name}, {if_addr}</code></td></tr> +<tr><td>confMILTER_MACROS_HELO</td><td>Milter.macros.helo</td> +<td><code>{tls_version}, {cipher}, {cipher_bits}, {cert_subject}, +{cert_issuer}</code></td></tr> +<tr><td>confMILTER_MACROS_ENVFROM</td><td>Milter.macros.envfrom</td> +<td><code>i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author}, +{mail_mailer}, {mail_host}, {mail_addr}</code></td></tr> +<tr><td>confMILTER_MACROS_ENVRCPT</td><td>Milter.macros.envrcpt</td> +<td><code>{rcpt_mailer}, {rcpt_host}, {rcpt_addr}</code></td></tr> +</table> +For information about available macros and their meanings, please +consult the sendmail documentation. +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> </html> diff --git a/contrib/sendmail/libmilter/docs/other.html b/contrib/sendmail/libmilter/docs/other.html new file mode 100644 index 0000000..8ec9ffd --- /dev/null +++ b/contrib/sendmail/libmilter/docs/other.html @@ -0,0 +1,15 @@ +<html> +<head><title>Other Resources</title> +</head> +<body> +FAQ? Mailing list? More sample filters? +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/overview.html b/contrib/sendmail/libmilter/docs/overview.html new file mode 100644 index 0000000..7f1c036 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/overview.html @@ -0,0 +1,194 @@ +<html> +<head> +<title>Technical Overview</title> +</head> +<body> +<!-- +$Id: overview.html,v 1.12 2001/06/01 00:05:03 ca Exp $ +--> + +<h1>Technical Overview</h1> + +<h2>Contents</h2> + +<ul> + <li>Initialization + <li>Control flow + <li>Multithreading + <li>Resource Management + <li>Signal Handling +</ul> + +<h2>Initialization</h2> + +In addition to its own initialization, libmilter expects a filter to initialize several parameters before calling <a href="smfi_main.html">smfi_main</a>: +<ul> + <li>The callbacks the filter wishes to be called, and the types of + message modification it intends to perform (required, see <a + href="smfi_register.html">smfi_register</a>). + + <li>The socket address to be used when communicating with the MTA + (required, see <a href="smfi_setconn.html">smfi_setconn</a>). + + <li>The number of seconds to wait for MTA connections before + timing out (optional, see <a + href="smfi_settimeout.html">smfi_settimeout</a>). +</ul> +<p> +If the filter fails to initialize libmilter, or if one or more of the +parameters it has passed are invalid, a subsequent call to smfi_main +will fail. + +<h2>Control flow</h2> + +<p> +The following pseudocode describes the filtering process from the +perspective of a set of <code>N</code> MTA's, each corresponding to a +connection. Callbacks are shown beside the processing stages in which +they are invoked; if no callbacks are defined for a particular stage, +that stage may be bypassed. Though it is not shown, processing may be +aborted at any time during a message, in which case the <a +href="xxfi_abort.html">xxfi_abort</a> callback is invoked and control +returns to <code>MESSAGE</code>. +<p> +<pre> +For each of N connections +{ + For each filter + process connection/helo (<a href="xxfi_connect.html">xxfi_connect</a>, <a href="xxfi_helo.html">xxfi_helo</a>) +MESSAGE:For each message in this connection (sequentially) + { + For each filter + process sender (<a href="xxfi_envfrom.html">xxfi_envfrom</a>) + For each recipient + { + For each filter + process recipient (<a href="xxfi_envrcpt.html">xxfi_envrcpt</a>) + } + For each filter + { + For each header + process header (<a href="xxfi_header.html">xxfi_header</a>) + process end of headers (<a href="xxfi_eoh.html">xxfi_eoh</a>) + For each body block + process this body block (<a href="xxfi_body.html">xxfi_body</a>) + process end of message (<a href="xxfi_eom.html">xxfi_eom</a>) + } + } + For each filter + process end of connection (<a href="xxfi_close.html">xxfi_close</a>) +} +</pre> + +<P>Note: Filters are contacted in order defined in config file.</P> + +<P> +To write a filter, a vendor supplies callbacks to process relevant +parts of a message transaction. The library then controls all +sequencing, threading, and protocol exchange with the MTA. <a +href="#figure-3">Figure 3</a> outlines control flow for a filter +process, showing where different callbacks are invoked. +</p> +<div align="center"><a name="figure-3"></a> +<table border=1 cellspacing=0 cellpadding=2 width="70%"> +<tr bgcolor="#dddddd"><th>SMTP Commands</th><th>Milter Callbacks</th></tr> +<tr><td>(open SMTP connection)</td><td>xxfi_connect</td></tr> +<tr><td>HELO ...</td><td>xxfi_helo</td></tr> +<tr><td>MAIL From: ...</td><td>xxfi_envfrom</td></tr> +<tr><td>RCPT To: ...</td><td>xxfi_envrcpt</td></tr> +<tr><td>[more RCPTs]</td><td>[xxfi_envrcpt]</td></tr> +<tr><td>DATA</td><td> </td></tr> +<tr><td>Header: ...</td><td>xxfi_header</td></tr> +<tr><td>[more headers]</td><td>[xxfi_header]</td></tr> +<tr><td> </td><td>xxfi_eoh</td></tr> +<tr><td>body... </td><td>xxfi_body</td></tr> +<tr><td>[more body...]</td><td>[xxfi_body]</td></tr> +<tr><td>.</td><td>xxfi_eom</td></tr> +<tr><td>QUIT</td><td>xxfi_close</td></tr> +<tr><td>(close SMTP connection)</td><td> </td></tr> +</table> +<b>Figure 3: Milter callbacks related to an SMTP transaction.</b> +</div> +<p> +Note that although only a single message is shown above, multiple +messages may be sent in a single connection. Note also that a message +and/or connection may be aborted by either the remote host or the MTA +at any point during the SMTP transaction. If this occurs during a +message (between the MAIL command and the final "."), the filter's <a +href="xxfi_abort.html">xxfi_abort</a> routine will be called. <a +href="xxfi_close.html">xxfi_close</a> is called any time the +connection closes. + +<h2>Multithreading</h2> + +<p> +A single filter process may handle any number of connections +simultaneously. All filtering callbacks must therefore be reentrant, +and use some appropriate external synchronization methods to access +global data. Furthermore, since there is not a one-to-one +correspondence between threads and connections (N connections mapped +onto M threads, M <= N), connection-specific data must be accessed +through the handles provided by the Milter library. The programmer +cannot rely on library-supplied thread-specific data blocks +(e.g. pthread_getspecific()) to store connection-specific data. See +the API documentation for <a +href="smfi_setpriv.html">smfi_setpriv</a> and <a +href="smfi_getpriv.html">smfi_getpriv</a> for details. + +<h2>Resource management</h2> + +Since filters are likely to be long-lived, and to handle many +connections, proper deallocation of per-connection resources is +important. The lifetime of a connection is bracketed by calls to the +callbacks <a href="xxfi_connect.html">xxfi_connect</a> and <a +href="xxfi_close.html">xxfi_close</a>. Therefore connection-specific +resources (accessed via <a href="smfi_getpriv.html">smfi_getpriv</a> +and <a href="smfi_setpriv.html">smfi_setpriv</a>) may be allocated in +<a href="xxfi_connect.html">xxfi_connect</a>, and should be freed in +<a href="xxfi_close.html">xxfi_close</a>. For further information see +the <a href="api.html#conn-msg">discussion</a> of message- versus +connection-oriented routines. In particular, note that there is only +one connection-specific data pointer per connection. +<p> + +Each message is bracketed by calls to <a +href="xxfi_envfrom.html">xxfi_envfrom</a> and <a +href="xxfi_eom.html">xxfi_eom</a> (or <a +href="xxfi_abort.html">xxfi_abort</a>), implying that message-specific +resources can be allocated and reclaimed in these routines. Since the +messages in a connection are processed sequentially by each filter, +there will be only one active message associated with a given +connection and filter (and connection-private data block). These +resources must still be accessed through <a +href="smfi_getpriv.html">smfi_getpriv</a> and <a +href="smfi_setpriv.html">smfi_setpriv</a>, and must be reclaimed +in <a href="xxfi_abort.html">xxfi_abort</a>. + +<h2>Signal Handling</h2> + +libmilter takes care of signal handling, the filters are +not influenced directly by signals. +There are basically two types of signal handlers: + +<ol> +<li><TT>Stop</TT>: no new connections from the MTA will be accepted, +but existing connections are allowed to continue. +<li><TT>Abort</TT>: all filters will be stopped as soon as the next +communication with the MTA happens. +</ol> + +Filters are not terminated asynchronously (except by +signals that can't be caught). +In the case of <TT>Abort</TT> the +<a href="xxfi_abort.html">xxfi_abort</a> callback is invoked. + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000, 2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/sample.html b/contrib/sendmail/libmilter/docs/sample.html new file mode 100644 index 0000000..7e99704 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/sample.html @@ -0,0 +1,426 @@ +<html> +<head><title>A Sample Filter</title></head> +<body> +<h1>A Sample Filter</h1> + +The following sample logs each message to a separate temporary file, +adds a recipient given with the -a flag, and rejects a disallowed +recipient address given with the -r flag. It recognizes the following +options: +<p> +<center> +<table border="1" cellpadding=2 cellspacing=1> +<tr><td><code>-p port</code></td><td>The port through which the MTA will connect to the filter.</td></tr> +<tr><td><code>-t sec</code></td><td>The timeout value.</td></tr> +<tr><td><code>-r addr</code></td><td>A recipient to reject.</td></tr> +<tr><td><code>-a addr</code></td><td>A recipient to add.</td></tr> +</table> +</center> +<hr> +<pre> +#include "mfapi.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sysexits.h> +#include <unistd.h> +#ifndef bool +#define bool char +#define TRUE 1 +#define FALSE 0 +#endif + +extern int errno; + + +struct mlfiPriv +{ + char *mlfi_fname; + char *mlfi_connectfrom; + char *mlfi_helofrom; + FILE *mlfi_fp; +}; + +#define MLFIPRIV ((struct mlfiPriv *) <a href="smfi_getpriv.html">smfi_getpriv</a>(ctx)) + +extern sfsistat mlfi_cleanup(SMFICTX *, bool); +/* recipients to add and reject (set with -a and -r options) */ +char *add, *reject; + +sfsistat +<a href="xxfi_connect.html">mlfi_connect</a>(ctx, hostname, hostaddr) + SMFICTX *ctx; + char *hostname; + _SOCK_ADDR *hostaddr; +{ + struct mlfiPriv *priv; + char *ident; + + /* allocate some private memory */ + priv = malloc(sizeof *priv); + if (priv == NULL) + { + /* can't accept this message right now */ + return SMFIS_TEMPFAIL; + } + memset(priv, '\0', sizeof *priv); + + /* save the private data */ + <a href="smfi_setpriv.html">smfi_setpriv</a>(ctx, priv); + + ident = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "_"); + if(!ident) ident = "???"; + if(!(priv->mlfi_connectfrom = strdup(ident))) { + return SMFIS_TEMPFAIL; + } + /* Continue processing. */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_helo.html">mlfi_helo</a>(ctx, helohost) + SMFICTX *ctx; + char *helohost; +{ + char *tls; + char *buf; + struct mlfiPriv *priv = MLFIPRIV; + tls = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{tls_version}"); + if(!tls) tls = "No TLS"; + if(!helohost) helohost = "???"; + if(!(buf = (char*)malloc(strlen(tls) + strlen(helohost) + 3))) { + return SMFIS_TEMPFAIL; + } + sprintf(buf, "%s, %s", helohost, tls); + if(priv->mlfi_helofrom) + free(priv->mlfi_helofrom); + priv->mlfi_helofrom = buf; + /* Continue processing. */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_envfrom.html">mlfi_envfrom</a>(ctx, argv) + SMFICTX *ctx; + char **argv; +{ + struct mlfiPriv *priv = MLFIPRIV; + char *mailaddr = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{mail_addr}"); + int argc = 0; + + /* open a file to store this message */ + priv->mlfi_fname = strdup("/tmp/msg.XXXXXX"); + mkstemp(priv->mlfi_fname); + if (priv->mlfi_fname == NULL) + return SMFIS_TEMPFAIL; + if ((priv->mlfi_fp = fopen(priv->mlfi_fname, "w+")) == NULL) + { + free(priv->mlfi_fname); + return SMFIS_TEMPFAIL; + } + + /* count the arguments */ + while(*argv++) ++argc; + /* log the connection information we stored earlier: */ + if(fprintf(priv->mlfi_fp, "Connect from %s (%s)\n\n", + priv->mlfi_helofrom, priv->mlfi_connectfrom) == EOF) { + (void) mlfi_cleanup(ctx, FALSE); + return SMFIS_TEMPFAIL; + } + /* log the sender */ + if(fprintf(priv->mlfi_fp, "FROM %s (%d argument%s)\n", + mailaddr?mailaddr:"???", argc, + (argc == 1)?"":"s") + == EOF) { + (void) mlfi_cleanup(ctx, FALSE); + return SMFIS_TEMPFAIL; + } + /* continue processing */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_envrcpt.html">mlfi_envrcpt</a>(ctx, argv) + SMFICTX *ctx; + char **argv; +{ + struct mlfiPriv *priv = MLFIPRIV; + char *rcptaddr = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{rcpt_addr}"); + int argc = 0; + /* count the arguments */ + while(*argv++) ++argc; + /* log this recipient */ + if(reject && rcptaddr && (strcmp(rcptaddr, reject) == 0)) { + if(fprintf(priv->mlfi_fp, "RCPT %s -- REJECTED\n", rcptaddr) + == EOF) { + (void) mlfi_cleanup(ctx, FALSE); + return SMFIS_TEMPFAIL; + } + return SMFIS_REJECT; + } + if(fprintf(priv->mlfi_fp, "RCPT %s (%d argument%s)\n", + rcptaddr?rcptaddr:"???", argc, + (argc == 1)?"":"s") + == EOF) { + (void) mlfi_cleanup(ctx, FALSE); + return SMFIS_TEMPFAIL; + } + /* continue processing */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_header.html">mlfi_header</a>(ctx, headerf, headerv) + SMFICTX *ctx; + char *headerf; + unsigned char *headerv; +{ + /* write the header to the log file */ + fprintf(MLFIPRIV->mlfi_fp, "%s: %s\n", headerf, headerv); + + /* continue processing */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_eoh.html">mlfi_eoh</a>(ctx) + SMFICTX *ctx; +{ + /* output the blank line between the header and the body */ + fprintf(MLFIPRIV->mlfi_fp, "\n"); + + /* continue processing */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_body.html">mlfi_body</a>(ctx, bodyp, bodylen) + SMFICTX *ctx; + unsigned char *bodyp; + size_t bodylen; +{ + /* output body block to log file */ + int nwritten; + if ((nwritten = fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp)) != 1) + { + /* write failed */ + perror("error logging body"); + (void) mlfi_cleanup(ctx, FALSE); + return SMFIS_TEMPFAIL; + } + + /* continue processing */ + return SMFIS_CONTINUE; +} + +sfsistat +<a href="xxfi_eom.html">mlfi_eom</a>(ctx) + SMFICTX *ctx; +{ + bool ok = TRUE; + /* change recipients, if requested */ + if(add) + ok = ok && (<a href="smfi_addrcpt.html">smfi_addrcpt</a>(ctx, add) == MI_SUCCESS); + return mlfi_cleanup(ctx, ok); +} + +sfsistat +<a href="xxfi_abort.html">mlfi_abort</a>(ctx) + SMFICTX *ctx; +{ + return mlfi_cleanup(ctx, FALSE); +} + +sfsistat +mlfi_cleanup(ctx, ok) + SMFICTX *ctx; + bool ok; +{ + sfsistat rstat = SMFIS_CONTINUE; + struct mlfiPriv *priv = MLFIPRIV; + char *p; + char host[512]; + char hbuf[1024]; + + if (priv == NULL) + return rstat; + + /* close the archive file */ + if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF) + { + /* failed; we have to wait until later */ + fprintf(stderr, "Couldn't close archive file %s: %s\n", + priv->mlfi_fname, strerror(errno)); + rstat = SMFIS_TEMPFAIL; + (void) unlink(priv->mlfi_fname); + } + else if (ok) + { + /* add a header to the message announcing our presence */ + if (gethostname(host, sizeof host) < 0) + strncpy(host, "localhost", sizeof host); + p = strrchr(priv->mlfi_fname, '/'); + if (p == NULL) + p = priv->mlfi_fname; + else + p++; + snprintf(hbuf, sizeof hbuf, "%s@%s", p, host); + <a href="smfi_addheader.html">smfi_addheader</a>(ctx, "X-Archived", hbuf); + } + else + { + /* message was aborted -- delete the archive file */ + fprintf(stderr, "Message aborted. Removing %s\n", + priv->mlfi_fname); + rstat = SMFIS_TEMPFAIL; + (void) unlink(priv->mlfi_fname); + } + + /* release private memory */ + free(priv->mlfi_fname); + + /* return status */ + return rstat; +} + +sfsistat +<a href="xxfi_close.html">mlfi_close</a>(ctx) + SMFICTX *ctx; +{ + struct mlfiPriv *priv = MLFIPRIV; + if(priv->mlfi_connectfrom) + free(priv->mlfi_connectfrom); + if(priv->mlfi_helofrom) + free(priv->mlfi_helofrom); + free(priv); + <a href="smfi_setpriv.html">smfi_setpriv</a>(ctx, NULL); + return SMFIS_CONTINUE; +} + +struct smfiDesc smfilter = +{ + "SampleFilter", /* filter name */ + SMFI_VERSION, /* version code -- do not change */ + SMFIF_ADDHDRS, /* flags */ + <a href="xxfi_connect.html">mlfi_connect</a>, /* connection info filter */ + <a href="xxfi_helo.html">mlfi_helo</a>, /* SMTP HELO command filter */ + <a href="xxfi_envfrom.html">mlfi_envfrom</a>, /* envelope sender filter */ + <a href="xxfi_envrcpt.html">mlfi_envrcpt</a>, /* envelope recipient filter */ + <a href="xxfi_header.html">mlfi_header</a>, /* header filter */ + <a href="xxfi_eoh.html">mlfi_eoh</a>, /* end of header */ + <a href="xxfi_body.html">mlfi_body</a>, /* body block filter */ + <a href="xxfi_eom.html">mlfi_eom</a>, /* end of message */ + <a href="xxfi_abort.html">mlfi_abort</a>, /* message aborted */ + <a href="xxfi_close.html">mlfi_close</a>, /* connection cleanup */ +}; + +static void +usage() +{ + fprintf(stderr, + "Usage: sample [-p socket-addr] [-t timeout] [-r reject-addr] \n\ +\t[-a accept-addr]\n"); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int retval; + char c; + const char *args = "p:t:r:a:h"; + extern char *optarg; + + /* Process command line options */ + while ((c = getopt(argc, argv, args)) != (char)EOF) + { + switch (c) + { + case 'p': + if (optarg == NULL || *optarg == '\0') + { + (void) fprintf(stderr, "Illegal conn: %s\n", + optarg); + exit(EX_USAGE); + } + if(<a href="smfi_setconn.html">smfi_setconn</a>(optarg) == MI_FAILURE) + { + (void) fputs("smfi_setconn failed", stderr); + exit(EX_SOFTWARE); + } + /* + ** If we're using a local socket, make sure it doesn't + ** already exist. + */ + if(strncmp(optarg, "unix:", 5) == 0) + unlink(optarg + 5); + else if(strncmp(optarg, "local:", 6) == 0) + unlink(optarg + 6); + break; + + case 't': + if (optarg == NULL || *optarg == '\0') + { + (void) fprintf(stderr, "Illegal timeout: %s\n", + optarg); + exit(EX_USAGE); + } + if(<a href="smfi_settimeout.html">smfi_settimeout</a>(atoi(optarg)) == MI_FAILURE) + { + (void) fputs("smfi_settimeout failed", stderr); + exit(EX_SOFTWARE); + } + break; + + case 'r': + if (optarg == NULL) + { + (void) fprintf(stderr, "Illegal reject rcpt: %s\n", + optarg); + exit(EX_USAGE); + } + reject = optarg; + break; + + case 'a': + if (optarg == NULL) + { + (void) fprintf(stderr, "Illegal add rcpt: %s\n", + optarg); + exit(EX_USAGE); + } + add = optarg; + smfilter.xxfi_flags |= SMFIF_ADDRCPT; + break; + case 'h': + default: + usage(); + exit(0); + } + } + if (<a href="smfi_register.html">smfi_register</a>(smfilter) == MI_FAILURE) + { + fprintf(stderr, "smfi_register failed\n"); + exit(EX_UNAVAILABLE); + } + retval = <a href="smfi_main.html">smfi_main</a>(); + return retval; +} + +/* eof */ + +</pre> +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_addheader.html b/contrib/sendmail/libmilter/docs/smfi_addheader.html new file mode 100644 index 0000000..c6417e2 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_addheader.html @@ -0,0 +1,94 @@ +<html> +<head><title>smfi_addheader</title></head> +<body> +<h1>smfi_addheader</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_addheader( + SMFICTX *ctx, + char *headerf, + char *headerv +); +</pre> +Add a header to the current message. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Adds a header to the current message.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>headerf</td> + <td>The header name, a non-NULL, null-terminated string. + </td></tr> + <tr valign="top"><td>headerv</td> + <td>The header value to be added, a non-NULL, null-terminated string. This may be the empty string. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_addheader returns MI_FAILURE if: +<ul><li>headerf or headerv is NULL. + <li>Adding headers in the current connection state is invalid. + <li>Memory allocation fails. + <li>A network error occurs. + <li>SMFIF_ADDHDRS was not set when <a href="smfi_register.html">smfi_register</a> was called. +</ul> +Otherwise, it returns MI_SUCCESS. +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +<ul><li>smfi_addheader does not change a message's existing headers. +To change a header's current value, use <a +href="smfi_chgheader.html">smfi_chgheader</a>. + <li>A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to <a href="smfi_register.html">smfi_register</a>. + <li>For smfi_chgheader, filter order is important. <b>Later filters will see the header changes made by earlier ones.</b> + <li>Neither the name nor the value of the header is checked for + standards compliance. However, each line of the header must be under + 2048 characters and should be under 998 characters. If longer headers + are needed, make them multiline. + <b>It is the filter writer's responsibility to ensure that no standards + are violated.</b> +</ul> +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html new file mode 100644 index 0000000..d0a5963 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html @@ -0,0 +1,80 @@ +<html> +<head><title>smfi_addrcpt</title></head> +<body> +<h1>smfi_addrcpt</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_addrcpt( + SMFICTX *ctx, + char *rcpt +); +</pre> +Add a recipient for the current message. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Add a recipient to the message envelope.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>rcpt</td> + <td>The new recipient's address. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_addrcpt will fail and return MI_FAILURE if: +<ul><li>rcpt is NULL. + <li>Adding headers in the current connection state is invalid. + <li>A network error occurs. + <li>SMFIF_ADDRCPT was not set when <a href="smfi_register.html">smfi_register</a> was called. +</ul> +Otherwise, it will return MI_SUCCESS. +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT flag +in the smfiDesc_str passed to +<a href="smfi_register.html">smfi_register</a>. +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_chgheader.html b/contrib/sendmail/libmilter/docs/smfi_chgheader.html new file mode 100644 index 0000000..4969674 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_chgheader.html @@ -0,0 +1,96 @@ +<html> +<head><title>smfi_chgheader</title></head> +<body> +<h1>smfi_chgheader</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_chgheader( + SMFICTX *ctx, + char *headerf, + mi_int32 hdridx, + char *headerv +); +</pre> +Change or delete a message header. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Changes a header's value for the current message.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>headerf</td> + <td>The header name, a non-NULL, null-terminated string. + </td></tr> + <tr valign="top"><td>hdridx</td> + <td>Header index value (1-based). A hdridx value of 1 will modify the first occurrence of a header named headerf. If hdridx is greater than the number of times headerf appears, a new copy of headerf will be added. + </td></tr> + <tr valign="top"><td>headerv</td> + <td>The new value of the given header. headerv == NULL implies that the header should be deleted. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td> +smfi_chgheader will return MI_FAILURE if +<ul><li>headerf is NULL + <li>Modifying headers in the current connection state is invalid. + <li>Memory allocation fails. + <li>A network error occurs. + <li>SMFIF_CHGHDRS was not set when <a href="smfi_register.html">smfi_register</a> was called. +</ul> +Otherwise, it returns MI_SUCCESS. +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +<ul><li>While smfi_chgheader may be used to add new headers, it is more efficient and far safer to use <a href="smfi_addheader.html">smfi_addheader</a>. + <li>A filter which calls smfi_chgheader must have set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to <a href="smfi_register.html">smfi_register</a>. + <li>For smfi_chgheader, filter order is important. <b>Later filters will see the header changes made by earlier ones.</b> + <li>Neither the name nor the value of the header is checked for + standards compliance. However, each line of the header must be under + 2048 characters and should be under 998 characters. If longer headers + are needed, make them multiline. + <b>It is the filter writer's responsibility to ensure that no standards + are violated.</b> +</ul> +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html new file mode 100644 index 0000000..f86fd2e --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html @@ -0,0 +1,79 @@ +<html> +<head><title>smfi_delrcpt</title></head> +<body> +<h1>smfi_delrcpt</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_delrcpt( + SMFICTX *ctx; + char *rcpt; +); +</pre> +Remove a recipient from the current message's envelope. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>smfi_delrcpt removes the named recipient from the current message's envelope.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>rcpt</td> + <td>The recipient address to be removed, a non-NULL, null-terminated string. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_delrcpt will fail and return MI_FAILURE if: +<ul> + <li>rcpt is NULL. + <li>Adding headers in the current connection state is invalid. + <li>A network error occurs. + <li>SMFIF_DELRCPT was not set when <a href="smfi_register.html">smfi_register</a> was called. +</ul> +Otherwise, it will return MI_SUCCESS +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +The addresses to be removed must match exactly. For example, an address and its expanded form do not match. +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_getpriv.html b/contrib/sendmail/libmilter/docs/smfi_getpriv.html new file mode 100644 index 0000000..8bb6efa --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_getpriv.html @@ -0,0 +1,59 @@ +<html> +<head><title>smfi_getpriv</title></head> +<body> +<h1>smfi_getpriv</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +void* smfi_getpriv( + SMFICTX *ctx +); +</pre> +Get the connection-specific data pointer for this connection. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_getpriv may be called in any of the xxfi_* callbacks.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>None.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_getpriv returns the private data pointer stored by a prior call to <a href="smfi_setpriv.html">smfi_setpriv</a>, or NULL if none has been set.</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_getsymval.html b/contrib/sendmail/libmilter/docs/smfi_getsymval.html new file mode 100644 index 0000000..d8a3304 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_getsymval.html @@ -0,0 +1,92 @@ +<html> +<head><title>smfi_getsymval</title></head> +<body> +<h1>smfi_getsymval</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +char* smfi_getsymval( + SMFICTX *ctx, + char *symname +); +</pre> +Get the value of a sendmail macro. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_getsymval may be called from within any of the xxfi_* callbacks. Which macros are defined will depend on when it is called.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>None.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>The opaque context structure. + </td></tr> + <tr valign="top"><td>symname</td> + <td>The name of a sendmail macro, optinally enclosed in braces ("{" and "}"). <a href="#notes">See below</a> for default macros. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_getsymval returns the value of the given macro as a null-terminated string, or NULL if the macro is not defined.</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th><a name="notes">NOTES</A></th> +<td> +By default, the following macros are valid in the given contexts: + +<table border="1" cellspacing=0> +<tr bgcolor="#dddddd"><th>Sent With</th><th>Macros</th></tr> +<tr><td>xxfi_connect</td> <td>daemon_name, if_name, if_addr, j, _</td></tr> +<tr><td>xxfi_helo</td> <td>tls_version, cipher, cipher_bits, cert_subject, cert_issuer</td></tr> +<tr><td>xxfi_envfrom</td> <td>i, auth_type, auth_authen, auth_ssf, auth_author, + mail_mailer, mail_host, mail_addr</td></tr> +<tr><td>xxfi_envrcpt</td> <td>rcpt_mailer, rcpt_host, rcpt_addr</td></tr> +</table> +<p> +All macros stay in effect from the point they are received until the +end of the connection for the first two sets, the end of the message +for the third (xxfi_envfrom), and just for each recipient for the +final set (xxfi_envrcpt). +<p> +The macro list can be changed using the confMILTER_MACROS_* options in +sendmail.mc. The scopes of such macros will be determined by when +they are set by sendmail. For descriptions of macros' values, please +see the "Sendmail Installation and Operation Guide" provided with your +sendmail distribution. + +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_main.html b/contrib/sendmail/libmilter/docs/smfi_main.html new file mode 100644 index 0000000..9652eaa --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_main.html @@ -0,0 +1,48 @@ +<html> +<head><title>smfi_main</title></head> +<body> +<h1>smfi_main</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_main( +); +</pre> +Hand control to libmilter event loop. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_main is called after a filter's initialization is complete.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>smfi_main hands control to the Milter event loop.</td> +</tr> +</table> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_main will return MI_FAILURE if it fails to establish a connection. This may occur for any of a variety of reasons (e.g. invalid address passed to <a href="smfi_setconn.html">smfi_setconn</a>). The reason for the failure will be logged. Otherwise, smfi_main will return MI_SUCCESS.</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_register.html b/contrib/sendmail/libmilter/docs/smfi_register.html new file mode 100644 index 0000000..705b3a4 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_register.html @@ -0,0 +1,160 @@ +<html> +<head><title>smfi_register</title></head> +<body> +<h1>smfi_register</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_register( + smfiDesc_str descr +); +</pre> +Register a set of filter callbacks. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=1> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_register must be called before smfi_main</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>smfi_register creates a filter using the information given in the +smfiDesc_str argument. Multiple calls to smfi_register within a +single process are not allowed.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>descr</td> + <td> +A filter descriptor of type smfiDesc_str describing the filter's +functions. The structure has the following members: +<pre> +struct smfiDesc +{ + char *xxfi_name; /* filter name */ + int xxfi_version; /* version code -- do not change */ + unsigned long xxfi_flags; /* <a href="#flags">flags</a> */ + + /* connection info filter */ + sfsistat (*<a href="xxfi_connect.html">xxfi_connect</a>)(SMFICTX *, char *, _SOCK_ADDR *); + /* SMTP HELO command filter */ + sfsistat (*<a href="xxfi_helo.html">xxfi_helo</a>)(SMFICTX *, char *); + /* envelope sender filter */ + sfsistat (*<a href="xxfi_envfrom.html">xxfi_envfrom</a>)(SMFICTX *, char **); + /* envelope recipient filter */ + sfsistat (*<a href="xxfi_envrcpt.html">xxfi_envrcpt</a>)(SMFICTX *, char **); + /* header filter */ + sfsistat (*<a href="xxfi_header.html">xxfi_header</a>)(SMFICTX *, char *, char *); + /* end of header */ + sfsistat (*<a href="xxfi_eoh.html">xxfi_eoh</a>)(SMFICTX *); + /* body block */ + sfsistat (*<a href="xxfi_body.html">xxfi_body</a>)(SMFICTX *, unsigned char *, size_t); + /* end of message */ + sfsistat (*<a href="xxfi_eom.html">xxfi_eom</a>)(SMFICTX *); + /* message aborted */ + sfsistat (*<a href="xxfi_abort.html">xxfi_abort</a>)(SMFICTX *); + /* connection cleanup */ + sfsistat (*<a href="xxfi_close.html">xxfi_close</a>)(SMFICTX *); +}; +</pre> + +A NULL value for any callback function indicates that the filter does +not wish to process the given type of information, simply returning +SMFIS_CONTINUE. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td> +smfi_register may return MI_FAILURE for any of the following reasons: +<ul> +<li>memory allocation failed. +<li>incompatible version or illegal flags value. +</ul> + +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> + +<a name="flags"></A> +The xxfi_flags field should contain the bitwise OR of zero or more of +the following values, describing the actions the filter may take: +<TABLE BORDER CELLPADDING="1" cellspacing=1> +<tr valign="top" bgcolor="#dddddd"><th align="left">Flag</th><th align="center">Description</th></tr> + <TR align="left" valign=top> + <TD> + SMFIF_ADDHDRS + </TD> + <TD> + This filter may add headers. + </TD> + </TR> + <TR align="left" valign=top> + <TD> + SMFIF_CHGHDRS + </TD> + <TD> + This filter may change and/or delete headers. + </TD> + </TR> + <TR align="left" valign=top> + <TD VALIGN="TOP"> + SMFIF_CHGBODY + </TD> + <TD> + This filter may replace the body during filtering. + This may have significant performance impact + if other filters do body filtering after this filter. + </TD> + </TR> + <TR> + <TD VALIGN="TOP"> + SMFIF_ADDRCPT + </TD> + <TD> + This filter may add recipients to the message. + </TD> + </TR> + <TR> + <TD VALIGN="TOP"> + SMFIF_DELRCPT + </TD> + <TD> + This filter may remove recipients from the message. + </TD> + </TR> +</TABLE> + +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_replacebody.html b/contrib/sendmail/libmilter/docs/smfi_replacebody.html new file mode 100644 index 0000000..204c2dc --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_replacebody.html @@ -0,0 +1,90 @@ +<html> +<head><title>smfi_replacebody</title></head> +<body> +<h1>smfi_replacebody</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_replacebody( + SMFICTX *ctx, + unsigned char *bodyp, + int bodylen +); +</pre> +Replace message-body data. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>. smfi_replacebody may be called more than once.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>smfi_replacebody replaces the body of the current message. If called +more than once, subsequent calls result in data being appended to the new +body. +</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>bodyp</td> + <td>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CR/LF form. + </td></tr> + <tr valign="top"><td>bodylen</td> + <td>The number of data bytes pointed to by bodyp. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_replacebody fails and returns MI_FAILURE if: +<ul> + <li>bodyp == NULL and bodylen > 0. + <li>Changing the body in the current connection state is invalid. + <li>A network error occurs. + <li>SMFIF_CHGBODY was not set when <a href="smfi_register.html">smfi_register</a> was called. +</ul> +Otherwise, it will return MI_SUCCESS. +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +<ul> + <li>Since the message body may be very large, setting SMFIF_CHGBODY may significantly affect filter performance. + <li>If a filter sets SMFIF_CHGBODY but does not call smfi_replacebody, the original body remains unchanged. + <li>For smfi_replacebody, filter order is important. <b>Later filters will see the new body contents created by earlier ones.</b> +</ul> +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_setconn.html b/contrib/sendmail/libmilter/docs/smfi_setconn.html new file mode 100644 index 0000000..0d46a5b --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_setconn.html @@ -0,0 +1,77 @@ +<html> +<head><title>smfi_setconn</title></head> +<body> +<h1>smfi_setconn</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_setconn( + char *oconn; +); +</pre> +Set the socket through which this filter should communicate with sendmail. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_setconn must be called once before <a href="smfi_main.html">smfi_main</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Sets the socket through which the filter communicates with sendmail.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>oconn</td> + <td>The address of the desired communication socket. + The address should be a NULL-terminated string in "proto:address" + format: + <ul> + <li><code>{unix|local}:/path/to/file</code> -- A named pipe. + <li><code>inet:port@{hostname|ip-address}</code> -- An IPV4 socket. + <li><code>inet6:port@{hostname|ip-address}</code> -- An IPV6 socket. + </ul> + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_setconn will not fail on an invalid address. The failure will +only be detected in <a href="smfi_main.html">smfi_main</a></td> +</tr> + +<tr> +<th valign="top" align=left>NOTES</th> + +<td> +<ul><li>If possible, filters should not run as root when communicating over unix/local domain sockets. + <li>Unix/local sockets should have their permissions set to 0600 (read/write permission only for the socket's owner). +</ul> +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_setpriv.html b/contrib/sendmail/libmilter/docs/smfi_setpriv.html new file mode 100644 index 0000000..e800cc8 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_setpriv.html @@ -0,0 +1,77 @@ +<html> +<head><title>smfi_setpriv</title></head> +<body> +<h1>smfi_setpriv</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_setpriv( + SMFICTX *ctx, + void *privatedata +); +</pre> +Set the private data pointer for this connection. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_setpriv may be called in any of the xxfi_* callbacks.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Sets the private data pointer for the context ctx.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>privatedata</td> + <td>Pointer to private data. This value will be returned by subsequent calls to <a href="smfi_getpriv.html">smfi_getpriv</a> using ctx. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_setpriv returns MI_FAILURE if ctx is an invalid context. +Otherwise, it returns MI_SUCCESS.</td> +</tr> + +<tr> +<th valign="top" align=left>NOTES</th> + +<td>There is only one private data pointer per connection; multiple +calls to smfi_setpriv with different values will cause previous values +to be lost. +<P> +Before a filter terminates it should release the private data +and set the pointer to NULL. +</td> + +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_setreply.html b/contrib/sendmail/libmilter/docs/smfi_setreply.html new file mode 100644 index 0000000..962f167 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_setreply.html @@ -0,0 +1,92 @@ +<html> +<head><title>smfi_setreply</title></head> +<body> +<h1>smfi_setreply</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_setreply( + SMFICTX *ctx, + char *rcode, + char *xcode, + char *message +); +</pre> +Set the default SMTP error reply code. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_setreply may be called from any of the xxfi_ callbacks.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Directly set the SMTP error reply code for this connection. This code +will be used on subsequent error replies resulting from actions taken by +this filter.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>rcode</td> + <td>The three-digit (RFC 821) SMTP reply code, as a null-terminated string. rcode cannot be NULL, and must be a valid reply code. + </td></tr> + <tr valign="top"><td>xcode</td> + <td>The extended (RFC 2034) reply code. If xcode is NULL, no extended code is used. Otherwise, xcode must conform to RFC 2034. + </td></tr> + <tr valign="top"><td>message</td> + <td>The text part of the SMTP reply. If message is NULL, an empty message is used. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_setreply will fail and return MI_FAILURE if: +<ul> + <li>The rcode or xcode argument is invalid. + <li>A memory-allocation failure occurs. +</ul> +Otherwise, it return MI_SUCCESS. +</td> +</tr> + +<!----------- Notes ----------> +<tr align="left" valign=top> +<th>NOTES</th> +<td> +<ul> +<li>Values passed to smfi_setreply are not checked for standards compliance. +<li>For details about reply codes and their meanings, please see RFC's +<a href="http://www.cis.ohio-state.edu/htbin/rfc/rfc821.html">821</a> +and <a href="http://www.cis.ohio-state.edu/htbin/rfc/rfc2034.html">2034</a>. +</ul> +</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/smfi_settimeout.html b/contrib/sendmail/libmilter/docs/smfi_settimeout.html new file mode 100644 index 0000000..a9e870a --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_settimeout.html @@ -0,0 +1,60 @@ +<html> +<head><title>smfi_settimeout</title></head> +<body> +<h1>smfi_settimeout</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +int smfi_settimeout( + int otimeout +); +</pre> +Set the filter's connection timeout value. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>smfi_settimeout should only be called before <a href="smfi_main.html">smfi_main</a>.</td> +</tr> +<tr align="left" valign=top> +<th width="80">Effects</th> +<td>Sets the number of seconds libmilter will wait for an MTA connection before timing out a socket. If smfi_settimeout is not called, a default timeout of 1800 seconds is used.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>otimeout</td> + <td>The number of seconds to wait before timing out (> 0). Zero means +no wait, <b>not</b> "wait forever". + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>RETURN VALUES</th> + +<td>smfi_settimeout always returns MI_SUCCESS.</td> +</tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_abort.html b/contrib/sendmail/libmilter/docs/xxfi_abort.html new file mode 100644 index 0000000..aeddf6f --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_abort.html @@ -0,0 +1,80 @@ +<html> +<head><title>xxfi_abort</title></head> +<body> +<h1>xxfi_abort</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_abort)( + SMFICTX * ctx +); +</pre> +Handle the current message's being aborted. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_abort may be called at any time during message processing (i.e. between some message-oriented routine and <a href="xxfi_eom.html">xxfi_eom</a>).</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + </table> +</td></tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td> +<ul> +<li>xxfi_abort must reclaim any resources allocated on a per-message +basis, and must be tolerant of being called between any two +message-oriented callbacks. + +<li>Calls to xxfi_abort and <a href="xxfi_eom.html">xxfi_eom</a> are +mutually exclusive. + +<li>xxfi_abort is not responsible for reclaiming connection-specific +data, since <a href="xxfi_close.html">xxfi_close</a> is always called +when a connection is closed. + +<li>Since the current message is already being aborted, the return +value is currently ignored. + +<li>xxfi_abort is only called if the message is aborted outside the +filter's control <b>and</b> the filter has not completed its +message-oriented processing. For example, if a filter has already +returned SMFIS_ACCEPT, SMFIS_REJECT, or SMFIS_DISCARD from a +message-oriented routine, xxfi_abort will not be called even if the +message is later aborted outside its control. +</ul> +</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_body.html b/contrib/sendmail/libmilter/docs/xxfi_body.html new file mode 100644 index 0000000..b19e0d4 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_body.html @@ -0,0 +1,80 @@ +<html> +<head><title>xxfi_body</title></head> +<body> +<h1>xxfi_body</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_body)( + SMFICTX * ctx, + unsigned char * bodyp, + size_t len +); +</pre> +Handle a piece of a message's body. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_body is called zero or more times between xxfi_eoh and xxfi_eom.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>bodyp</td> + <td>Pointer to the start of this block of body data. bodyp is not valid outside this call to xxfi_body. + </td></tr> + <tr valign="top"><td>len</td> + <td>The amount of data pointed to by bodyp. + </td></tr> + </table> +</td></tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td> +<ul> +<li>bodyp points to a sequence of bytes. +It is <em>not</em> a C string (a sequence of characters that is terminated by '\0'). +Therefore, do not use the usual C string functions like strlen() on this byte block. +Moreover, the byte sequence may contain '\0' characters inside the block. +Hence even if a trailing '\0' is added, C string functions may still fail +to work as expected. +<li>Since message bodies can be very large, defining xxfi_body can +significantly impact filter performance. +<li>End-of-lines are represented as received from SMTP (normally CR/LF). +<li>Later filters will see body changes made by earlier ones. +<li>Message bodies may be sent in multiple chunks, with one call to + xxfi_body per chunk. +</ul> +</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_close.html b/contrib/sendmail/libmilter/docs/xxfi_close.html new file mode 100644 index 0000000..07742be --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_close.html @@ -0,0 +1,66 @@ +<html> +<head><title>xxfi_close</title></head> +<body> +<h1>xxfi_close</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_close)( + SMFICTX * ctx +); +</pre> +The current connection is being closed. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_close is always called once at the end of each connection.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + </table> +</td></tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td> +<ul> +<li>xxfi_close is called on close even if the previous mail +transaction was aborted. +<li>xxfi_close is responsible for freeing any resources allocated on a +per-connection basis. +<li>Since the connection is already closing, the return value is +currently ignored. +</ul> +</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_connect.html b/contrib/sendmail/libmilter/docs/xxfi_connect.html new file mode 100644 index 0000000..1710285 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_connect.html @@ -0,0 +1,90 @@ +<html> +<head><title>xxfi_connect</title></head> +<body> +<h1>xxfi_connect</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_connect)( + SMFICTX *ctx, + char *hostname, + _SOCK_ADDR *hostaddr); +</pre> +</td></tr> +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr> +<th valign="top" align=left width=80>Called When</th> +<td>Once, at the start of each SMTP connection.</td> +</tr> +<tr> +<th valign="top" align=left width=80>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> +<!-- +This callback function is invoked on each connection to the mail +filter program. The callback is to be implemented by the Milter +application developers. The name of the callback can be any valid +function name. The function pointer is to be assigned to the +smfiDesc.xxfi_connect and the pointer to the smfiDesc structure +is passed to smfi_register(). +</td></tr> +--> +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr><td>ctx</td> + <td>the opaque context structure. + </td></tr> + <tr><td>hostname</td> + <td>the host name of the message sender, as determined by a + reverse lookup on the host address. If the reverse lookup + fails, hostname will contain the message sender's IP + address enclosed in square brackets (e.g. `[a.b.c.d]'). + </td></tr> + <tr><td>hostaddr</td> + <td>the host address, as determined by a getpeername() call on the SMTP socket. + NULL if the type is not supported in the current version or if + the SMTP connection is made via stdin. + </td></tr> + </table> +</td></tr> +<!----------- Return values ----------> +<!-- +<tr> +<th valign="top" align=left>SPECIAL RETURN VALUES</th> +<td><table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr> + <tr valign="top"> + <td>SMFIS_DISCARD</td> + <td>Not meaningful, as + this is only meaningful from message-oriented routines. + </td> + </tr> +</table> +</tr> +--> +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td>If an earlier filter rejects the connection in its xxfi_connect() +routine, this filter's xxfi_connect() will not be called.</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html new file mode 100644 index 0000000..d023c40 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html @@ -0,0 +1,92 @@ +<html> +<head><title>xxfi_envfrom</title></head> +<body> +<h1>xxfi_envfrom</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_envfrom)( + SMFICTX * ctx, + char ** argv +); +</pre> +Handle the envelope FROM command. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_envfrom is called once at the beginning of each message, before xxfi_envrcpt.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>argv</td> + <td>Null-terminated SMTP command arguments; + argv[0] is guaranteed to be the sender address. + Later arguments are the ESMTP arguments. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>SPECIAL RETURN VALUES</th> +<td><table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr> + <tr valign="top"> + <td>SMFIS_TEMPFAIL</td> + <td>Reject this sender and message with a temporary error; a new sender (and hence a new message) may subsequently be specified. <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_REJECT</td> + <td>Reject this sender and message; a new sender/message may be specified. <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_DISCARD</td> + <td>Accept and silently discard this message. <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_ACCEPT</td> + <td>Accept this message. <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> +</table> +</tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td>For more details on ESTMP responses, please see RFC +<a href="http://www.cis.ohio-state.edu/rfc/rfc1869.txt">1869</a>.</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html new file mode 100644 index 0000000..f13626a --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html @@ -0,0 +1,94 @@ +<html> +<head><title>xxfi_envrcpt</title></head> +<body> +<h1>xxfi_envrcpt</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_envrcpt)( + SMFICTX * ctx, + char ** argv +); +</pre> +Handle the envelope RCPT command. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_envrcpt is called once per recipient, hence one or more times per message, immediately after xxfi_envfrom.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>argv</td> + <td>Null-terminated SMTP command arguments; + argv[0] is guaranteed to be the recipient address. + Later arguments are the ESMTP arguments. + </td></tr> + </table> +</td></tr> + +<!----------- Return values ----------> +<tr> +<th valign="top" align=left>SPECIAL RETURN VALUES</th> +<td><table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr> + <tr valign="top"> + <td>SMFIS_TEMPFAIL</td> + <td>Temporarily fail for this particular recipient; further recipients + maystill be sent. <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_REJECT</td> + <td>Reject this particular recipient; further recipients maystill be sent. + <a href="xxfi_abort.html">xxfi_abort</a> is not called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_DISCARD</td> + <td>Accept and discard the message. <a href="xxfi_abort.html">xxfi_abort</a> will be called. + </td> + </tr> + <tr valign="top"> + <td>SMFIS_ACCEPT</td> + <td>Accept recipient. <a href="xxfi_abort.html">xxfi_abort</a> will not be called. + </td> + </tr> +</table> +</tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td>For more details on ESTMP responses, please see RFC +<a href="http://www.cis.ohio-state.edu/rfc/rfc1869.txt">1869</a>.</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_eoh.html b/contrib/sendmail/libmilter/docs/xxfi_eoh.html new file mode 100644 index 0000000..46c7925 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_eoh.html @@ -0,0 +1,53 @@ +<html> +<head><title>xxfi_eoh</title></head> +<body> +<h1>xxfi_eoh</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_eoh)( + SMFICTX * ctx +); +</pre> +Handle the end of message headers. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_eoh is called once after all headers have been sent and processed. +</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + </table> +</td></tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_eom.html b/contrib/sendmail/libmilter/docs/xxfi_eom.html new file mode 100644 index 0000000..40f6dee --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_eom.html @@ -0,0 +1,58 @@ +<html> +<head><title>xxfi_eom</title></head> +<body> +<h1>xxfi_eom</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_eom)( + SMFICTX * ctx +); +</pre> +End of a message. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_eom is called once after all calls to <a href="xxfi_body.html">xxfi_body</a> for a given message.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + </table> +</td></tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td>A filter is required to make all its modifications to the message headers, body, and envelope in xxfi_eom. Modifications are made via the smfi_* routines. +</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_header.html b/contrib/sendmail/libmilter/docs/xxfi_header.html new file mode 100644 index 0000000..a6c6322 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_header.html @@ -0,0 +1,74 @@ +<html> +<head><title>xxfi_header</title></head> +<body> +<h1>xxfi_header</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_header)( + SMFICTX * ctx, + char * headerf, + char * headerv +); +</pre> +Handle a message header. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> +<td>xxfi_header is called zero or more times between xxfi_envrcpt and xxfi_eoh, once per message header.</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>headerf</td> + <td> Header field name. + </td></tr> + <tr valign="top"><td>headerv</td> + <td>Header field value. The + content of the header may include folded white space (i.e. multiple + lines with following white space). The trailing line terminator (CR/LF) + is removed. + </td></tr> + </table> +</td></tr> + +<!----------- Notes ----------> +<tr> +<th valign="top" align=left>NOTES</th> +<td> +<ul> +<li>Later filters will see header changes/additions made by earlier ones. +<li>For much more detail about header format, please see +RFC <a href="http://www.cis.ohio-state.edu/htbin/rfc/rfc822.html">822</a> +</ul> +</td> +</tr> +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/docs/xxfi_helo.html b/contrib/sendmail/libmilter/docs/xxfi_helo.html new file mode 100644 index 0000000..b1aa9e9 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/xxfi_helo.html @@ -0,0 +1,59 @@ +<html> +<head><title>xxfi_helo</title></head> +<body> +<h1>xxfi_helo</h1> + +<table border="0" cellspacing=4 cellpadding=4> +<!---------- Synopsis -----------> +<tr><th valign="top" align=left width=150>SYNOPSIS</th><td> +<pre> +#include <libmilter/mfapi.h> +sfsistat (*xxfi_helo)( + SMFICTX * ctx, + char * helohost +); +</pre> +Handle the HELO/EHLO command. +</td></tr> + +<!----------- Description ----------> +<tr><th valign="top" align=left>DESCRIPTION</th><td> +<table border="1" cellspacing=1 cellpadding=4> +<tr align="left" valign=top> +<th width="80">Called When</th> <td>xxfi_helo is called whenever the client +sends a HELO/EHLO command. It may therefore be called between zero and +three times</td> +</tr> +<tr align="left" valign=top> +<th>Default Behavior</th> +<td>Do nothing; return SMFIS_CONTINUE.</td> +</tr> +</table> + +<!----------- Arguments ----------> +<tr><th valign="top" align=left>ARGUMENTS</th><td> + <table border="1" cellspacing=0> + <tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr> + <tr valign="top"><td>ctx</td> + <td>Opaque context structure. + </td></tr> + <tr valign="top"><td>helohost</td> + <td>Value passed to HELO/EHLO command, which should be + the domain name of the sending host (but is, in practice, + anything the sending host wants to send). + </td></tr> + </table> +</td></tr> + +</table> + +<hr size="1"> +<font size="-1"> +Copyright (c) 2000 Sendmail, Inc. and its suppliers. +All rights reserved. +<br> +By using this file, you agree to the terms and conditions set +forth in the <a href="LICENSE.txt">LICENSE</a>. +</font> +</body> +</html> diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c index 0fd48eb..aabfe6c 100644 --- a/contrib/sendmail/libmilter/engine.c +++ b/contrib/sendmail/libmilter/engine.c @@ -8,13 +8,10 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: engine.c,v 8.67.4.17 2001/01/22 19:00:16 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: engine.c,v 8.102 2001/12/13 17:10:00 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" -#include "sendmail/useful.h" #if NETINET || NETINET6 # include <arpa/inet.h> @@ -118,13 +115,16 @@ static int dec_arg2 __P((char *, size_t, char **, char **)); ** is set in the NX_* value ** this function is coded in trans_ok(), see below. */ + #define MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ #define NX_INIT (MASK(ST_OPTS)) #define NX_OPTS (MASK(ST_CONN)) #define NX_CONN (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_HELO (MASK(ST_HELO) | MASK(ST_MAIL)) #define NX_MAIL (MASK(ST_RCPT) | MASK(ST_ABRT)) -#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | MASK(ST_RCPT) | MASK(ST_ABRT)) +#define NX_RCPT (MASK(ST_HDRS) | MASK(ST_EOHS) | \ + MASK(ST_BODY) | MASK(ST_ENDM) | \ + MASK(ST_RCPT) | MASK(ST_ABRT)) #define NX_HDRS (MASK(ST_EOHS) | MASK(ST_HDRS) | MASK(ST_ABRT)) #define NX_EOHS (MASK(ST_BODY) | MASK(ST_ENDM) | MASK(ST_ABRT)) #define NX_BODY (MASK(ST_ENDM) | MASK(ST_BODY) | MASK(ST_ABRT)) @@ -172,8 +172,9 @@ static cmdfct cmds[] = #define _SMFIS_OPTIONS 22 #define _SMFIS_NOREPLY 23 #define _SMFIS_FAIL (-1) +#define _SMFIS_NONE (-2) -/* +/* ** MI_ENGINE -- receive commands and process them ** ** Parameters: @@ -208,6 +209,7 @@ mi_engine(ctx) fi_abort = ctx->ctx_smfi->xxfi_abort; mi_clr_macros(ctx, 0); fix_stm(ctx); + r = _SMFIS_NONE; do { /* call abort only if in a mail transaction */ @@ -217,17 +219,29 @@ mi_engine(ctx) if (mi_stop() == MILTER_ABRT) { if (ctx->ctx_dbg > 3) - dprintf("[%d] milter_abort\n", + sm_dprintf("[%d] milter_abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; } + + /* + ** Notice: buf is allocated by mi_rd_cmd() and it will + ** usually be free()d after it has been used in f(). + ** However, if the function returns _SMFIS_KEEP then buf + ** contains macros and will not be free()d. + ** Hence r must be set to _SMFIS_NONE if a new buf is + ** allocated to avoid problem with housekeeping, esp. + ** if the code "break"s out of the loop. + */ + + r = _SMFIS_NONE; if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len, ctx->ctx_smfi->xxfi_name)) == NULL && cmd < SMFIC_VALIDCMD) { if (ctx->ctx_dbg > 5) - dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", + sm_dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", (int) ctx->ctx_id, (int) cmd); /* @@ -240,7 +254,7 @@ mi_engine(ctx) break; } if (ctx->ctx_dbg > 4) - dprintf("[%d] got cmd '%c' len %d\n", + sm_dprintf("[%d] got cmd '%c' len %d\n", (int) ctx->ctx_id, cmd, len); for (i = 0; i < ncmds; i++) { @@ -251,7 +265,7 @@ mi_engine(ctx) { /* unknown command */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' unknown\n", + sm_dprintf("[%d] cmd '%c' unknown\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -260,7 +274,7 @@ mi_engine(ctx) { /* stop for now */ if (ctx->ctx_dbg > 1) - dprintf("[%d] cmd '%c' not impl\n", + sm_dprintf("[%d] cmd '%c' not impl\n", (int) ctx->ctx_id, cmd); ret = MI_FAILURE; break; @@ -269,14 +283,14 @@ mi_engine(ctx) /* is new state ok? */ newstate = cmds[i].cm_next; if (ctx->ctx_dbg > 5) - dprintf("[%d] cur %x new %x nextmask %x\n", + sm_dprintf("[%d] cur %x new %x nextmask %x\n", (int) ctx->ctx_id, curstate, newstate, next_states[curstate]); if (newstate != ST_NONE && !trans_ok(curstate, newstate)) { if (ctx->ctx_dbg > 1) - dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", + sm_dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", (int) ctx->ctx_id, curstate, MASK(curstate), newstate, MASK(newstate), @@ -293,7 +307,11 @@ mi_engine(ctx) curstate = ST_HELO; if (!trans_ok(curstate, newstate)) + { + free(buf); + buf = NULL; continue; + } } arg.a_len = len; arg.a_buf = buf; @@ -337,7 +355,7 @@ mi_engine(ctx) else if (r == _SMFIS_ABORT) { if (ctx->ctx_dbg > 5) - dprintf("[%d] function returned abort\n", + sm_dprintf("[%d] function returned abort\n", (int) ctx->ctx_id); ret = MI_FAILURE; break; @@ -354,12 +372,12 @@ mi_engine(ctx) /* close must always be called */ if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) (void) (*fi_close)(ctx); - if (buf != NULL) + if (r != _SMFIS_KEEP && buf != NULL) free(buf); mi_clr_macros(ctx, 0); return ret; } -/* +/* ** SENDREPLY -- send a reply to the MTA ** ** Parameters: @@ -462,7 +480,7 @@ mi_clr_macros(ctx, m) } } } -/* +/* ** ST_OPTIONNEG -- negotiate options ** ** Parameters: @@ -543,7 +561,7 @@ st_optionneg(g) return _SMFIS_OPTIONS; } -/* +/* ** ST_CONNECTINFO -- receive connection information ** ** Parameters: @@ -560,7 +578,7 @@ st_connectinfo(g) size_t l; size_t i; char *s, family; - u_short port = 0; + unsigned short port = 0; _SOCK_ADDR sockaddr; sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *)); @@ -617,11 +635,11 @@ st_connectinfo(g) # if NETINET6 if (family == SMFIA_INET6) { - if (inet_pton(AF_INET6, s + i, - &sockaddr.sin6.sin6_addr) != 1) + if (mi_inet_pton(AF_INET6, s + i, + &sockaddr.sin6.sin6_addr) != 1) { smi_log(SMI_LOG_ERR, - "%s: connect[%d]: inet_pton failed", + "%s: connect[%d]: mi_inet_pton failed", g->a_ctx->ctx_smfi->xxfi_name, (int) g->a_ctx->ctx_id); return _SMFIS_ABORT; @@ -635,7 +653,7 @@ st_connectinfo(g) # if NETUNIX if (family == SMFIA_UNIX) { - if (strlcpy(sockaddr.sunix.sun_path, s + i, + if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, sizeof sockaddr.sunix.sun_path) >= sizeof sockaddr.sunix.sun_path) { @@ -660,7 +678,7 @@ st_connectinfo(g) return (*fi_connect)(g->a_ctx, g->a_buf, family != SMFIA_UNKNOWN ? &sockaddr : NULL); } -/* +/* ** ST_EOH -- end of headers ** ** Parameters: @@ -683,7 +701,7 @@ st_eoh(g) return (*fi_eoh)(g->a_ctx); return SMFIS_CONTINUE; } -/* +/* ** ST_HELO -- helo/ehlo command ** ** Parameters: @@ -706,7 +724,7 @@ st_helo(g) return (*fi_helo)(g->a_ctx, g->a_buf); return SMFIS_CONTINUE; } -/* +/* ** ST_HEADER -- header line ** ** Parameters: @@ -734,24 +752,24 @@ st_header(g) return _SMFIS_ABORT; } -#define ARGV_FCT(lf, rf, idx) \ - char **argv; \ - sfsistat (*lf) __P((SMFICTX *, char **)); \ - int r; \ - \ - if (g == NULL) \ - return _SMFIS_ABORT; \ - mi_clr_macros(g->a_ctx, g->a_idx + 1); \ - if (g->a_ctx->ctx_smfi == NULL || \ - (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ - return SMFIS_CONTINUE; \ +#define ARGV_FCT(lf, rf, idx) \ + char **argv; \ + sfsistat (*lf) __P((SMFICTX *, char **)); \ + int r; \ + \ + if (g == NULL) \ + return _SMFIS_ABORT; \ + mi_clr_macros(g->a_ctx, g->a_idx + 1); \ + if (g->a_ctx->ctx_smfi == NULL || \ + (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ + return SMFIS_CONTINUE; \ if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL) \ - return _SMFIS_ABORT; \ - r = (*lf)(g->a_ctx, argv); \ - free(argv); \ + return _SMFIS_ABORT; \ + r = (*lf)(g->a_ctx, argv); \ + free(argv); \ return r; -/* +/* ** ST_SENDER -- MAIL FROM command ** ** Parameters: @@ -767,7 +785,7 @@ st_sender(g) { ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL) } -/* +/* ** ST_RCPT -- RCPT TO command ** ** Parameters: @@ -783,7 +801,7 @@ st_rcpt(g) { ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT) } -/* +/* ** ST_MACROS -- deal with macros received from the MTA ** ** Parameters: @@ -833,7 +851,7 @@ st_macros(g) g->a_ctx->ctx_mac_buf[i] = g->a_buf; return _SMFIS_KEEP; } -/* +/* ** ST_QUIT -- quit command ** ** Parameters: @@ -849,7 +867,7 @@ st_quit(g) { return _SMFIS_NOREPLY; } -/* +/* ** ST_BODYCHUNK -- deal with a piece of the mail body ** ** Parameters: @@ -863,16 +881,17 @@ static int st_bodychunk(g) genarg *g; { - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); if (g == NULL) return _SMFIS_ABORT; if (g->a_ctx->ctx_smfi != NULL && (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL) - return (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); return SMFIS_CONTINUE; } -/* +/* ** ST_BODYEND -- deal with the last piece of the mail body ** ** Parameters: @@ -890,7 +909,7 @@ st_bodyend(g) genarg *g; { sfsistat r; - sfsistat (*fi_body) __P((SMFICTX *, u_char *, size_t)); + sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); sfsistat (*fi_eom) __P((SMFICTX *)); if (g == NULL) @@ -907,7 +926,8 @@ st_bodyend(g) timeout.tv_sec = g->a_ctx->ctx_timeout; timeout.tv_usec = 0; sd = g->a_ctx->ctx_sd; - r = (*fi_body)(g->a_ctx, (u_char *)g->a_buf, g->a_len); + r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, + g->a_len); if (r != SMFIS_CONTINUE && sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS) return _SMFIS_ABORT; @@ -918,7 +938,7 @@ st_bodyend(g) return (*fi_eom)(g->a_ctx); return r; } -/* +/* ** ST_ABORTFCT -- deal with aborts ** ** Parameters: @@ -941,7 +961,7 @@ st_abortfct(g) (void) (*fi_abort)(g->a_ctx); return _SMFIS_NOREPLY; } -/* +/* ** TRANS_OK -- is the state transition ok? ** ** Parameters: @@ -963,13 +983,14 @@ trans_ok(old, new) { /* is this state transition allowed? */ if ((MASK(new) & next_states[s]) != 0) - return TRUE; + return true; /* ** no: try next state; ** this works since the relevant states are ordered ** strict sequentially */ + n = s + 1; /* @@ -977,14 +998,15 @@ trans_ok(old, new) ** see fix_stm() which sets this bit for those ** states which the filter program is not interested in */ + if (bitset(NX_SKIP, next_states[n])) s = n; else - return FALSE; + return false; } while (s <= ST_LAST); - return FALSE; + return false; } -/* +/* ** FIX_STM -- add "skip" bits to the state transition table ** ** Parameters: @@ -1001,7 +1023,7 @@ static void fix_stm(ctx) SMFICTX_PTR ctx; { - u_long fl; + unsigned long fl; if (ctx == NULL || ctx->ctx_smfi == NULL) return; @@ -1021,7 +1043,7 @@ fix_stm(ctx) if (bitset(SMFIP_NOBODY, fl)) next_states[ST_BODY] |= NX_SKIP; } -/* +/* ** DEC_ARGV -- split a buffer into a list of strings, NULL terminated ** ** Parameters: @@ -1065,7 +1087,7 @@ dec_argv(buf, len) s[elem] = NULL; return s; } -/* +/* ** DEC_ARG2 -- split a buffer into two strings ** ** Parameters: @@ -1094,7 +1116,7 @@ dec_arg2(buf, len, s1, s2) *s2 = buf + i + 1; return MI_SUCCESS; } -/* +/* ** SENDOK -- is it ok for the filter to send stuff to the MTA? ** ** Parameters: @@ -1111,9 +1133,12 @@ mi_sendok(ctx, flag) int flag; { if (ctx == NULL || ctx->ctx_smfi == NULL) - return FALSE; + return false; + + /* did the milter request this operation? */ if (flag != 0 && !bitset(flag, ctx->ctx_smfi->xxfi_flags)) - return FALSE; + return false; + + /* are we in the correct state? It must be "End of Message". */ return ctx->ctx_state == ST_ENDM; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c index 2ee5203..29ea446 100644 --- a/contrib/sendmail/libmilter/handler.c +++ b/contrib/sendmail/libmilter/handler.c @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: handler.c,v 8.19.4.3 2000/12/29 19:45:39 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: handler.c,v 8.29 2001/11/15 00:17:15 msk Exp $") -#if _FFR_MILTER #include "libmilter.h" @@ -45,7 +43,7 @@ mi_handle_session(ctx) ret = mi_engine(ctx); if (ValidSocket(ctx->ctx_sd)) { - (void) close(ctx->ctx_sd); + (void) closesocket(ctx->ctx_sd); ctx->ctx_sd = INVALID_SOCKET; } if (ctx->ctx_reply != NULL) @@ -64,4 +62,3 @@ mi_handle_session(ctx) ctx = NULL; return ret; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h index 49ac70f..d135aab 100644 --- a/contrib/sendmail/libmilter/libmilter.h +++ b/contrib/sendmail/libmilter/libmilter.h @@ -13,12 +13,13 @@ #ifndef _LIBMILTER_H # define _LIBMILTER_H 1 + +#include <sm/gen.h> + #ifdef _DEFINE # define EXTERN # define INIT(x) = x -# ifndef lint -static char MilterlId[] = "@(#)$Id: libmilter.h,v 8.3.6.16 2001/06/07 23:21:35 geir Exp $"; -# endif /* ! lint */ +SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.32 2001/11/29 02:21:02 ca Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -31,15 +32,12 @@ static char MilterlId[] = "@(#)$Id: libmilter.h,v 8.3.6.16 2001/06/07 23:21:35 g #include "libmilter/milter.h" -#ifndef __P -# include "sendmail/cdefs.h" -#endif /* ! __P */ -#include "sendmail/useful.h" - # define ValidSocket(sd) ((sd) >= 0) -# define INVALID_SOCKET -1 -# define MI_SOCK_READ(s, b, l) (read(s, b, l)) -# define MI_SOCK_WRITE(s, b, l) (write(s, b, l)) +# define INVALID_SOCKET (-1) +# define closesocket close +# define MI_SOCK_READ(s, b, l) read(s, b, l) +# define MI_SOCK_READ_FAIL(x) ((x) < 0) +# define MI_SOCK_WRITE(s, b, l) write(s, b, l) # define thread_create(ptid,wr,arg) pthread_create(ptid, NULL, wr, arg) # define sthread_get_id() pthread_self() @@ -61,16 +59,19 @@ typedef pthread_mutex_t smutex_t; #define MI_TIMEOUT 7210 /* default timeout for read/write */ #define MI_CHK_TIME 5 /* checking whether to terminate */ -#if SOMAXCONN > 20 -# define MI_SOMAXCONN SOMAXCONN -#else /* SOMAXCONN */ -# define MI_SOMAXCONN 20 -#endif /* SOMAXCONN */ +#ifndef MI_SOMAXCONN +# if SOMAXCONN > 20 +# define MI_SOMAXCONN SOMAXCONN +# else /* SOMAXCONN */ +# define MI_SOMAXCONN 20 +# endif /* SOMAXCONN */ +#endif /* ! MI_SOMAXCONN */ /* maximum number of repeated failures in mi_listener() */ #define MAX_FAILS_M 16 /* malloc() */ #define MAX_FAILS_T 16 /* thread creation */ #define MAX_FAILS_A 16 /* accept() */ +#define MAX_FAILS_S 16 /* select() */ /* internal "commands", i.e., error codes */ #define SMFIC_TIMEOUT ((char) 1) /* timeout */ @@ -84,6 +85,7 @@ typedef pthread_mutex_t smutex_t; /* hack */ #define smi_log syslog +#define sm_dprintf printf #define milter_ret int #define SMI_LOG_ERR LOG_ERR #define SMI_LOG_FATAL LOG_ERR @@ -106,6 +108,7 @@ extern int mi_control_startup __P((char *)); extern void mi_stop_milters __P((int)); extern void mi_clean_signals __P((void)); extern struct hostent *mi_gethostbyname __P((char *, int)); +extern int mi_inet_pton __P((int, const char *, void *)); extern void mi_closener __P((void)); /* communication functions */ @@ -113,4 +116,5 @@ extern char *mi_rd_cmd __P((socket_t, struct timeval *, char *, size_t *, char * extern int mi_wr_cmd __P((socket_t, struct timeval *, int, char *, size_t)); extern bool mi_sendok __P((SMFICTX_PTR, int)); + #endif /* !_LIBMILTER_H */ diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c index 6a59955..9b75ce0 100644 --- a/contrib/sendmail/libmilter/listener.c +++ b/contrib/sendmail/libmilter/listener.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,22 +8,24 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:58 ca Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: listener.c,v 8.81 2002/01/08 23:14:23 ca Exp $") -#if _FFR_MILTER /* ** listener.c -- threaded network listener */ #include "libmilter.h" +#include <sm/errstring.h> # if NETINET || NETINET6 # include <arpa/inet.h> # endif /* NETINET || NETINET6 */ -/* + +static smutex_t L_Mutex; + +/* ** MI_MILTEROPEN -- setup socket to listen on ** ** Parameters: @@ -35,8 +37,15 @@ static char id[] = "@(#)$Id: listener.c,v 8.38.2.1.2.22 2001/05/16 17:15:58 ca E ** ** Returns: ** socket upon success, error code otherwise. +** +** Side effect: +** sets sockpath if UNIX socket. */ +#if NETUNIX +static char *sockpath = NULL; +#endif /* NETUNIX */ + static socket_t mi_milteropen(conn, backlog, socksize, family, name) char *conn; @@ -47,6 +56,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { socket_t sock; int sockopt = 1; + size_t len = 0; char *p; char *colon; char *at; @@ -157,15 +167,16 @@ mi_milteropen(conn, backlog, socksize, family, name) # endif /* 0 */ at = colon; - if (strlcpy(addr.sunix.sun_path, colon, - sizeof addr.sunix.sun_path) >= - sizeof addr.sunix.sun_path) + len = strlen(colon) + 1; + if (len >= sizeof addr.sunix.sun_path) { errno = EINVAL; smi_log(SMI_LOG_ERR, "%s: UNIX socket name %s too long", name, colon); return INVALID_SOCKET; } + (void) sm_strlcpy(addr.sunix.sun_path, colon, + sizeof addr.sunix.sun_path); # if 0 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, S_IRUSR|S_IWUSR, NULL); @@ -179,7 +190,6 @@ mi_milteropen(conn, backlog, socksize, family, name) return INVALID_SOCKET; } # endif /* 0 */ - } #endif /* NETUNIX */ @@ -196,7 +206,7 @@ mi_milteropen(conn, backlog, socksize, family, name) # endif /* NETINET6 */ ) { - u_short port; + unsigned short port; /* Parse port@host */ at = strchr(colon, '@'); @@ -221,7 +231,7 @@ mi_milteropen(conn, backlog, socksize, family, name) *at = '\0'; if (isascii(*colon) && isdigit(*colon)) - port = htons((u_short) atoi(colon)); + port = htons((unsigned short) atoi(colon)); else { # ifdef NO_GETSERVBYNAME @@ -252,7 +262,7 @@ mi_milteropen(conn, backlog, socksize, family, name) end = strchr(at, ']'); if (end != NULL) { - bool found = FALSE; + bool found = false; # if NETINET unsigned long hid = INADDR_NONE; # endif /* NETINET */ @@ -263,23 +273,22 @@ mi_milteropen(conn, backlog, socksize, family, name) *end = '\0'; # if NETINET if (addr.sa.sa_family == AF_INET && - (hid = inet_addr(&at[1])) != - INADDR_NONE) + (hid = inet_addr(&at[1])) != INADDR_NONE) { addr.sin.sin_addr.s_addr = hid; addr.sin.sin_port = port; - found = TRUE; + found = true; } # endif /* NETINET */ # if NETINET6 (void) memset(&hid6, '\0', sizeof hid6); if (addr.sa.sa_family == AF_INET6 && - inet_pton(AF_INET6, &at[1], - &hid6.sin6_addr) == 1) + mi_inet_pton(AF_INET6, &at[1], + &hid6.sin6_addr) == 1) { addr.sin6.sin6_addr = hid6.sin6_addr; addr.sin6.sin6_port = port; - found = TRUE; + found = true; } # endif /* NETINET6 */ *end = ']'; @@ -338,9 +347,9 @@ mi_milteropen(conn, backlog, socksize, family, name) name, at, hp->h_addrtype); return INVALID_SOCKET; } -# if _FFR_FREEHOSTENT && NETINET6 +# if NETINET6 freehostent(hp); -# endif /* _FFR_FREEHOSTENT && NETINET6 */ +# endif /* NETINET6 */ } } else @@ -367,7 +376,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { smi_log(SMI_LOG_ERR, "%s: Unable to create new socket: %s", - name, strerror(errno)); + name, sm_errstring(errno)); return INVALID_SOCKET; } @@ -375,8 +384,9 @@ mi_milteropen(conn, backlog, socksize, family, name) sizeof(sockopt)) == -1) { smi_log(SMI_LOG_ERR, - "%s: Unable to setsockopt: %s", name, strerror(errno)); - (void) close(sock); + "%s: Unable to setsockopt: %s", name, + sm_errstring(errno)); + (void) closesocket(sock); return INVALID_SOCKET; } @@ -384,22 +394,45 @@ mi_milteropen(conn, backlog, socksize, family, name) { smi_log(SMI_LOG_ERR, "%s: Unable to bind to port %s: %s", - name, conn, strerror(errno)); - (void) close(sock); + name, conn, sm_errstring(errno)); + (void) closesocket(sock); return INVALID_SOCKET; } if (listen(sock, backlog) < 0) { smi_log(SMI_LOG_ERR, - "%s: listen call failed: %s", name, strerror(errno)); - (void) close(sock); + "%s: listen call failed: %s", name, + sm_errstring(errno)); + (void) closesocket(sock); return INVALID_SOCKET; } + +#if NETUNIX + if (addr.sa.sa_family == AF_UNIX && len > 0) + { + /* + ** Set global variable sockpath so the UNIX socket can be + ** unlink()ed at exit. + */ + + sockpath = (char *) malloc(len); + if (sockpath != NULL) + (void) sm_strlcpy(sockpath, colon, len); + else + { + smi_log(SMI_LOG_ERR, + "%s: can't malloc(%d) for sockpath: %s", + name, len, sm_errstring(errno)); + (void) closesocket(sock); + return INVALID_SOCKET; + } + } +#endif /* NETUNIX */ *family = addr.sa.sa_family; return sock; } -/* +/* ** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session ** ** Parameters: @@ -418,11 +451,12 @@ mi_thread_handle_wrapper(arg) static socket_t listenfd = INVALID_SOCKET; -static smutex_t L_Mutex; - -/* +/* ** MI_CLOSENER -- close listen socket ** +** NOTE: It is assumed that this function is called from a +** function that has a mutex lock (currently mi_stop_milters()). +** ** Parameters: ** none. ** @@ -436,13 +470,54 @@ mi_closener() (void) smutex_lock(&L_Mutex); if (ValidSocket(listenfd)) { - (void) close(listenfd); +#if NETUNIX + bool removable; + struct stat sockinfo; + struct stat fileinfo; + + removable = sockpath != NULL && +#if _FFR_MILTER_ROOT_UNSAFE + geteuid() != 0 && +#endif /* _FFR_MILTER_ROOT_UNSAFE */ + fstat(listenfd, &sockinfo) == 0 && + (S_ISFIFO(sockinfo.st_mode) +# ifdef S_ISSOCK + || S_ISSOCK(sockinfo.st_mode) +# endif /* S_ISSOCK */ + ); +#endif /* NETUNIX */ + + (void) closesocket(listenfd); listenfd = INVALID_SOCKET; + +#if NETUNIX + /* XXX sleep() some time before doing this? */ + if (sockpath != NULL) + { + if (removable && + stat(sockpath, &fileinfo) == 0 && + ((fileinfo.st_dev == sockinfo.st_dev && + fileinfo.st_ino == sockinfo.st_ino) +# ifdef S_ISSOCK + || S_ISSOCK(fileinfo.st_mode) +# endif /* S_ISSOCK */ + ) + && + (S_ISFIFO(fileinfo.st_mode) +# ifdef S_ISSOCK + || S_ISSOCK(fileinfo.st_mode) +# endif /* S_ISSOCK */ + )) + (void) unlink(sockpath); + free(sockpath); + sockpath = NULL; + } +#endif /* NETUNIX */ } (void) smutex_unlock(&L_Mutex); } -/* +/* ** MI_LISTENER -- Generic listener harness ** ** Open up listen port @@ -460,7 +535,7 @@ mi_closener() ** MI_FAILURE -- Network initialization failed. */ -# if BROKEN_PTHREAD_SLEEP +#if BROKEN_PTHREAD_SLEEP /* ** Solaris 2.6, perhaps others, gets an internal threads library panic @@ -480,7 +555,7 @@ mi_closener() ** 0 */ -# define MI_SLEEP(s) \ +# define MI_SLEEP(s) \ { \ int rs = 0; \ struct timeval st; \ @@ -496,9 +571,9 @@ mi_closener() rs, errno); \ } \ } -# else /* BROKEN_PTHREAD_SLEEP */ -# define MI_SLEEP(s) sleep((s)) -# endif /* BROKEN_PTHREAD_SLEEP */ +#else /* BROKEN_PTHREAD_SLEEP */ +# define MI_SLEEP(s) sleep((s)) +#endif /* BROKEN_PTHREAD_SLEEP */ int mi_listener(conn, dbg, smfi, timeout, backlog) @@ -513,9 +588,10 @@ mi_listener(conn, dbg, smfi, timeout, backlog) int sockopt = 1; int r; int ret = MI_SUCCESS; - int mcnt = 0; - int tcnt = 0; - int acnt = 0; + int mcnt = 0; /* error count for malloc() failures */ + int tcnt = 0; /* error count for thread_create() failures */ + int acnt = 0; /* error count for accept() failures */ + int scnt = 0; /* error count for select() failures */ int save_errno = 0; sthread_t thread_id; _SOCK_ADDR cliaddr; @@ -564,8 +640,8 @@ mi_listener(conn, dbg, smfi, timeout, backlog) /* select on interface ports */ FD_ZERO(&readset); FD_ZERO(&excset); - FD_SET((u_int) listenfd, &readset); - FD_SET((u_int) listenfd, &excset); + FD_SET((unsigned int) listenfd, &readset); + FD_SET((unsigned int) listenfd, &excset); chktime.tv_sec = MI_CHK_TIME; chktime.tv_usec = 0; r = select(listenfd + 1, &readset, NULL, &excset, &chktime); @@ -580,16 +656,30 @@ mi_listener(conn, dbg, smfi, timeout, backlog) (void) smutex_unlock(&L_Mutex); if (save_errno == EINTR) continue; - ret = MI_FAILURE; - break; + scnt++; + smi_log(SMI_LOG_ERR, + "%s: select() failed (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + scnt >= MAX_FAILS_S ? "abort" : "try again"); + MI_SLEEP(scnt); + if (scnt >= MAX_FAILS_S) + { + ret = MI_FAILURE; + break; + } + continue; } if (!FD_ISSET(listenfd, &readset)) { /* some error: just stop for now... */ ret = MI_FAILURE; (void) smutex_unlock(&L_Mutex); + smi_log(SMI_LOG_ERR, + "%s: select() returned exception for socket, abort", + smfi->xxfi_name); break; } + scnt = 0; /* reset error counter for select() */ memset(&cliaddr, '\0', sizeof cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, @@ -610,19 +700,20 @@ mi_listener(conn, dbg, smfi, timeout, backlog) # endif /* BSD4_4_SOCKADDR */ cliaddr.sa.sa_family != family)) { - (void) close(connfd); + (void) closesocket(connfd); connfd = INVALID_SOCKET; save_errno = EINVAL; } if (!ValidSocket(connfd)) { - smi_log(SMI_LOG_ERR, - "%s: accept() returned invalid socket (%s)", - smfi->xxfi_name, strerror(save_errno)); if (save_errno == EINTR) continue; acnt++; + smi_log(SMI_LOG_ERR, + "%s: accept() returned invalid socket (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + acnt >= MAX_FAILS_A ? "abort" : "try again"); MI_SLEEP(acnt); if (acnt >= MAX_FAILS_A) { @@ -631,20 +722,22 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } continue; } + acnt = 0; /* reset error counter for accept() */ if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, (void *) &sockopt, sizeof sockopt) < 0) { - smi_log(SMI_LOG_WARN, "%s: setsockopt() failed", - smfi->xxfi_name); + smi_log(SMI_LOG_WARN, "%s: setsockopt() failed (%s)", + smfi->xxfi_name, sm_errstring(errno)); /* XXX: continue? */ } if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) { - (void) close(connfd); - smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed", - smfi->xxfi_name); + (void) closesocket(connfd); mcnt++; + smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed (%s), %s", + smfi->xxfi_name, sm_errstring(save_errno), + mcnt >= MAX_FAILS_M ? "abort" : "try again"); MI_SLEEP(mcnt); if (mcnt >= MAX_FAILS_M) { @@ -653,8 +746,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } continue; } - mcnt = 0; - acnt = 0; + mcnt = 0; /* reset error counter for malloc() */ memset(ctx, '\0', sizeof *ctx); ctx->ctx_sd = connfd; ctx->ctx_dbg = dbg; @@ -685,12 +777,13 @@ mi_listener(conn, dbg, smfi, timeout, backlog) mi_thread_handle_wrapper, (void *) ctx)) != 0) { - smi_log(SMI_LOG_ERR, - "%s: thread_create() failed: %d", - smfi->xxfi_name, r); tcnt++; + smi_log(SMI_LOG_ERR, + "%s: thread_create() failed: %d, %s", + smfi->xxfi_name, r, + tcnt >= MAX_FAILS_T ? "abort" : "try again"); MI_SLEEP(tcnt); - (void) close(connfd); + (void) closesocket(connfd); free(ctx); if (tcnt >= MAX_FAILS_T) { @@ -708,4 +801,3 @@ mi_listener(conn, dbg, smfi, timeout, backlog) (void) smutex_destroy(&L_Mutex); return ret; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c index 6afebdb..ee440e3 100644 --- a/contrib/sendmail/libmilter/main.c +++ b/contrib/sendmail/libmilter/main.c @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: main.c,v 8.34.4.11 2001/05/07 22:06:37 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: main.c,v 8.53 2001/11/29 02:21:02 ca Exp $") -#if _FFR_MILTER #define _DEFINE 1 #include "libmilter.h" #include <fcntl.h> @@ -51,7 +49,7 @@ smfi_register(smfilter) smfi->xxfi_name = (char *) malloc(len); if (smfi->xxfi_name == NULL) return MI_FAILURE; - (void) strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); + (void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); /* compare milter version with hard coded version */ if (smfi->xxfi_version != SMFI_VERSION) @@ -61,13 +59,16 @@ smfi_register(smfilter) "%s: smfi_register: version mismatch application: %d != milter: %d", smfi->xxfi_name, smfi->xxfi_version, (int) SMFI_VERSION); + + /* XXX how about smfi? */ + free(smfi->xxfi_name); return MI_FAILURE; } return MI_SUCCESS; } -/* +/* ** SMFI_STOP -- stop milter ** ** Parameters: @@ -84,11 +85,26 @@ smfi_stop() return MI_SUCCESS; } +/* +** default values for some variables. +** Most of these can be changed with the functions below. +*/ + static int dbg = 0; static char *conn = NULL; static int timeout = MI_TIMEOUT; static int backlog= MI_SOMAXCONN; +/* +** SMFI_SETDBG -- set debug level. +** +** Parameters: +** odbg -- new debug level. +** +** Returns: +** MI_SUCCESS +*/ + int smfi_setdbg(odbg) int odbg; @@ -97,6 +113,16 @@ smfi_setdbg(odbg) return MI_SUCCESS; } +/* +** SMFI_SETTIMEOUT -- set timeout (for read/write). +** +** Parameters: +** otimeout -- new timeout. +** +** Returns: +** MI_SUCCESS +*/ + int smfi_settimeout(otimeout) int otimeout; @@ -105,6 +131,16 @@ smfi_settimeout(otimeout) return MI_SUCCESS; } +/* +** SMFI_SETCONN -- set connection information (socket description) +** +** Parameters: +** oconn -- new connection information. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + int smfi_setconn(oconn) char *oconn; @@ -116,11 +152,21 @@ smfi_setconn(oconn) l = strlen(oconn) + 1; if ((conn = (char *) malloc(l)) == NULL) return MI_FAILURE; - if (strlcpy(conn, oconn, l) >= l) + if (sm_strlcpy(conn, oconn, l) >= l) return MI_FAILURE; return MI_SUCCESS; } +/* +** SMFI_SETBACKLOG -- set backlog +** +** Parameters: +** odbg -- new backlog. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + int smfi_setbacklog(obacklog) int obacklog; @@ -132,11 +178,22 @@ smfi_setbacklog(obacklog) } +/* +** SMFI_MAIN -- setup milter connnection and start listener. +** +** Parameters: +** none. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + int smfi_main() { + int r; - signal(SIGPIPE, SIG_IGN); + (void) signal(SIGPIPE, SIG_IGN); if (conn == NULL) { smi_log(SMI_LOG_FATAL, "%s: missing connection information", @@ -152,12 +209,11 @@ smfi_main() smfi->xxfi_name); return MI_FAILURE; } - + r = MI_SUCCESS; /* Startup the listener */ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) - return MI_FAILURE; + r = MI_FAILURE; - return MI_SUCCESS; + return r; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/signal.c b/contrib/sendmail/libmilter/signal.c index 0bc5081..b160f5d 100644 --- a/contrib/sendmail/libmilter/signal.c +++ b/contrib/sendmail/libmilter/signal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,11 +8,9 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: signal.c,v 8.10.4.8 2000/11/20 21:15:37 ca Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: signal.c,v 8.35 2002/01/10 01:34:55 ca Exp $") -#if _FFR_MILTER #include "libmilter.h" /* @@ -23,7 +21,7 @@ static smutex_t M_Mutex; static int MilterStop = MILTER_CONT; -/* +/* ** MI_STOP -- return value of MilterStop ** ** Parameters: @@ -38,7 +36,7 @@ mi_stop() { return MilterStop; } -/* +/* ** MI_STOP_MILTERS -- set value of MilterStop ** ** Parameters: @@ -60,7 +58,7 @@ mi_stop_milters(v) mi_closener(); (void) smutex_unlock(&M_Mutex); } -/* +/* ** MI_CLEAN_SIGNALS -- clean up signal handler thread ** ** Parameters: @@ -75,7 +73,7 @@ mi_clean_signals() { (void) smutex_destroy(&M_Mutex); } -/* +/* ** MI_SIGNAL_THREAD -- thread to deal with signals ** ** Parameters: @@ -100,18 +98,18 @@ mi_signal_thread(name) sigaddset(&set, SIGINT); errs = 0; - while (TRUE) + while (true) { sig = 0; -#ifdef SOLARIS +#if defined(SOLARIS) || defined(__svr5__) if ((sig = sigwait(&set)) < 0) -#else /* SOLARIS */ +#else /* defined(SOLARIS) || defined(__svr5__) */ if (sigwait(&set, &sig) != 0) -#endif /* SOLARIS */ +#endif /* defined(SOLARIS) || defined(__svr5__) */ { smi_log(SMI_LOG_ERR, - "%s: sigwait returned error: %s", - (char *)name, strerror(errno)); + "%s: sigwait returned error: %d", + (char *)name, errno); if (++errs > MAX_FAILS_T) { mi_stop_milters(MILTER_ABRT); @@ -138,7 +136,7 @@ mi_signal_thread(name) } } } -/* +/* ** MI_SPAWN_SIGNAL_THREAD -- spawn thread to handle signals ** ** Parameters: @@ -153,6 +151,7 @@ mi_spawn_signal_thread(name) char *name; { sthread_t tid; + int r; sigset_t set; /* Mask HUP and KILL signals */ @@ -167,16 +166,17 @@ mi_spawn_signal_thread(name) "%s: Couldn't mask HUP and KILL signals", name); return MI_FAILURE; } - if (thread_create(&tid, mi_signal_thread, - (void *)name) != MI_SUCCESS) + r = thread_create(&tid, mi_signal_thread, (void *)name); + if (r != 0) { smi_log(SMI_LOG_ERR, - "%s: Couldn't start signal thread", name); + "%s: Couldn't start signal thread: %d", + name, r); return MI_FAILURE; } return MI_SUCCESS; } -/* +/* ** MI_CONTROL_STARTUP -- startup for thread to handle signals ** ** Parameters: @@ -212,4 +212,3 @@ mi_control_startup(name) } return MI_SUCCESS; } -#endif /* _FFR_MILTER */ diff --git a/contrib/sendmail/libmilter/sm_gethost.c b/contrib/sendmail/libmilter/sm_gethost.c index c1e80b1..1714741 100644 --- a/contrib/sendmail/libmilter/sm_gethost.c +++ b/contrib/sendmail/libmilter/sm_gethost.c @@ -8,17 +8,15 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: sm_gethost.c,v 8.7.8.11 2001/07/21 00:10:23 gshapiro Exp $"; -#endif /* ! lint */ +#include <sm/gen.h> +SM_RCSID("@(#)$Id: sm_gethost.c,v 8.26 2001/09/11 04:04:45 gshapiro Exp $") -#if _FFR_MILTER #include <sendmail.h> #if NETINET || NETINET6 # include <arpa/inet.h> #endif /* NETINET || NETINET6 */ -/* +/* ** MI_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX ** ** Some operating systems have wierd problems with the gethostbyXXX @@ -48,7 +46,7 @@ getipnodebyname(name, family, flags, err) int flags; int *err; { - bool resv6 = TRUE; + bool resv6 = true; struct hostent *h; if (family == AF_INET6) @@ -59,13 +57,12 @@ getipnodebyname(name, family, flags, err) } SM_SET_H_ERRNO(0); h = gethostbyname(name); - *err = h_errno; if (family == AF_INET6 && !resv6) _res.options &= ~RES_USE_INET6; + *err = h_errno; return h; } -# if _FFR_FREEHOSTENT void freehostent(h) struct hostent *h; @@ -77,7 +74,6 @@ freehostent(h) return; } -# endif /* _FFR_FREEHOSTENT */ #endif /* NEEDSGETIPNODE && NETINET6 */ struct hostent * @@ -117,4 +113,33 @@ mi_gethostbyname(name, family) #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) || (defined(sony_news) && defined(__svr4)) */ return h; } -#endif /* _FFR_MILTER */ + +#if NETINET6 +/* +** MI_INET_PTON -- convert printed form to network address. +** +** Wrapper for inet_pton() which handles IPv6: labels. +** +** Parameters: +** family -- address family +** src -- string +** dst -- destination address structure +** +** Returns: +** 1 if the address was valid +** 0 if the address wasn't parseable +** -1 if error +*/ + +int +mi_inet_pton(family, src, dst) + int family; + const char *src; + void *dst; +{ + if (family == AF_INET6 && + strncasecmp(src, "IPv6:", 5) == 0) + src += 5; + return inet_pton(family, src, dst); +} +#endif /* NETINET6 */ diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c index e034aa8..fd564d5 100644 --- a/contrib/sendmail/libmilter/smfi.c +++ b/contrib/sendmail/libmilter/smfi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,13 +8,14 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: smfi.c,v 8.28.4.6 2000/06/28 23:48:56 gshapiro Exp $"; -#endif /* ! lint */ - -#if _FFR_MILTER +#include <sm/gen.h> +SM_RCSID("@(#)$Id: smfi.c,v 8.57 2001/11/20 18:47:49 ca Exp $") +#include <sm/varargs.h> #include "libmilter.h" -#include "sendmail/useful.h" + +/* for smfi_set{ml}reply, let's be generous. 256/16 should be sufficient */ +#define MAXREPLYLEN 980 /* max. length of a reply string */ +#define MAXREPLIES 32 /* max. number of reply strings */ /* ** SMFI_ADDHEADER -- send a new header to the MTA @@ -110,7 +111,7 @@ smfi_chgheader(ctx, headerf, hdridx, headerv) free(buf); return r; } -/* +/* ** SMFI_ADDRCPT -- send an additional recipient to the MTA ** ** Parameters: @@ -138,7 +139,7 @@ smfi_addrcpt(ctx, rcpt) len = strlen(rcpt) + 1; return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDRCPT, rcpt, len); } -/* +/* ** SMFI_DELRCPT -- send a recipient to be removed to the MTA ** ** Parameters: @@ -166,7 +167,7 @@ smfi_delrcpt(ctx, rcpt) len = strlen(rcpt) + 1; return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_DELRCPT, rcpt, len); } -/* +/* ** SMFI_REPLACEBODY -- send a body chunk to the MTA ** ** Parameters: @@ -181,13 +182,14 @@ smfi_delrcpt(ctx, rcpt) int smfi_replacebody(ctx, bodyp, bodylen) SMFICTX *ctx; - u_char *bodyp; + unsigned char *bodyp; int bodylen; { int len, off, r; struct timeval timeout; - if (bodyp == NULL && bodylen > 0) + if (bodylen < 0 || + (bodyp == NULL && bodylen > 0)) return MI_FAILURE; if (!mi_sendok(ctx, SMFIF_CHGBODY)) return MI_FAILURE; @@ -208,7 +210,46 @@ smfi_replacebody(ctx, bodyp, bodylen) } return MI_SUCCESS; } -/* +#if _FFR_QUARANTINE +/* +** SMFI_QUARANTINE -- quarantine an envelope +** +** Parameters: +** ctx -- Opaque context structure +** reason -- why? +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +smfi_quarantine(ctx, reason) + SMFICTX *ctx; + char *reason; +{ + size_t len; + int r; + char *buf; + struct timeval timeout; + + if (reason == NULL || *reason == '\0') + return MI_FAILURE; + if (!mi_sendok(ctx, SMFIF_QUARANTINE)) + return MI_FAILURE; + timeout.tv_sec = ctx->ctx_timeout; + timeout.tv_usec = 0; + len = strlen(reason) + 1; + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; + (void) memcpy(buf, reason, len); + r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_QUARANTINE, buf, len); + free(buf); + return r; +} +#endif /* _FFR_QUARANTINE */ + +/* ** MYISENHSC -- check whether a string contains an enhanced status code ** ** Parameters: @@ -247,7 +288,8 @@ myisenhsc(s, delim) return 0; return l + h; } -/* + +/* ** SMFI_SETREPLY -- set the reply code for the next reply to the MTA ** ** Parameters: @@ -267,35 +309,170 @@ smfi_setreply(ctx, rcode, xcode, message) char *xcode; char *message; { - size_t len, l1, l2, l3; + size_t len; char *buf; if (rcode == NULL || ctx == NULL) return MI_FAILURE; - l1 = strlen(rcode) + 1; - if (l1 != 4) + + /* ### <sp> \0 */ + len = strlen(rcode) + 2; + if (len != 5) return MI_FAILURE; if ((rcode[0] != '4' && rcode[0] != '5') || !isascii(rcode[1]) || !isdigit(rcode[1]) || !isascii(rcode[2]) || !isdigit(rcode[2])) return MI_FAILURE; - l2 = xcode == NULL ? 1 : strlen(xcode) + 1; - if (xcode != NULL && !myisenhsc(xcode, '\0')) + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + len += strlen(xcode) + 1; + } + if (message != NULL) + { + size_t ml; + + /* XXX check also for unprintable chars? */ + if (strpbrk(message, "\r\n") != NULL) + return MI_FAILURE; + ml = strlen(message); + if (ml > MAXREPLYLEN) + return MI_FAILURE; + len += ml + 1; + } + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; /* oops */ + (void) sm_strlcpy(buf, rcode, len); + (void) sm_strlcat(buf, " ", len); + if (xcode != NULL) + (void) sm_strlcat(buf, xcode, len); + if (message != NULL) + { + if (xcode != NULL) + (void) sm_strlcat(buf, " ", len); + (void) sm_strlcat(buf, message, len); + } + if (ctx->ctx_reply != NULL) + free(ctx->ctx_reply); + ctx->ctx_reply = buf; + return MI_SUCCESS; +} + +#if _FFR_MULTILINE +/* +** SMFI_SETMLREPLY -- set multiline reply code for the next reply to the MTA +** +** Parameters: +** ctx -- Opaque context structure +** rcode -- The three-digit (RFC 821) SMTP reply code. +** xcode -- The extended (RFC 2034) reply code. +** txt, ... -- The text part of the SMTP reply, +** MUST be terminated with NULL. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +#if SM_VA_STD +smfi_setmlreply(SMFICTX *ctx, const char *rcode, const char *xcode, ...) +#else /* SM_VA_STD */ +smfi_setmlreply(ctx, rcode, xcode, va_alist) + SMFICTX *ctx; + const char *rcode; + const char *xcode; + va_dcl +#endif /* SM_VA_STD */ +{ + size_t len; + size_t rlen; + int args; + char *buf, *txt; + const char *xc; + char repl[16]; + SM_VA_LOCAL_DECL + + if (rcode == NULL || ctx == NULL) + return MI_FAILURE; + + /* ### <sp> */ + len = strlen(rcode) + 1; + if (len != 4) return MI_FAILURE; - l3 = message == NULL ? 1 : strlen(message) + 1; - len = l1 + l2 + l3; + if ((rcode[0] != '4' && rcode[0] != '5') || + !isascii(rcode[1]) || !isdigit(rcode[1]) || + !isascii(rcode[2]) || !isdigit(rcode[2])) + return MI_FAILURE; + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + xc = xcode; + } + else + { + if (rcode[0] == '4') + xc = "4.0.0"; + else + xc = "5.0.0"; + } + + /* add trailing space */ + len += strlen(xc) + 1; + rlen = len; + args = 0; + SM_VA_START(ap, xcode); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + size_t tl; + + tl = strlen(txt); + if (tl > MAXREPLYLEN) + return MI_FAILURE; + + /* this text, reply codes, \r\n */ + len += tl + 2 + rlen; + if (++args > MAXREPLIES) + return MI_FAILURE; + + /* XXX check also for unprintable chars? */ + if (strpbrk(txt, "\r\n") != NULL) + return MI_FAILURE; + } + SM_VA_END(ap); + + /* trailing '\0' */ + ++len; buf = malloc(len); if (buf == NULL) return MI_FAILURE; /* oops */ - (void) snprintf(buf, len, "%s %s %s", rcode, - xcode == NULL ? "" : xcode, - message == NULL ? "" : message); + (void) sm_strlcpyn(buf, len, 3, rcode, args == 1 ? " " : "-", xc); + (void) sm_strlcpyn(repl, sizeof repl, 4, rcode, args == 1 ? " " : "-", + xc, " "); + SM_VA_START(ap, xcode); + txt = SM_VA_ARG(ap, char *); + if (txt != NULL) + { + (void) sm_strlcat2(buf, " ", txt, len); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + if (--args <= 1) + repl[3] = ' '; + (void) sm_strlcat2(buf, "\r\n", repl, len); + (void) sm_strlcat(buf, txt, len); + } + } if (ctx->ctx_reply != NULL) free(ctx->ctx_reply); ctx->ctx_reply = buf; + SM_VA_END(ap); return MI_SUCCESS; } -/* +#endif /* _FFR_MULTILINE */ + +/* ** SMFI_SETPRIV -- set private data ** ** Parameters: @@ -316,7 +493,7 @@ smfi_setpriv(ctx, privatedata) ctx->ctx_privdata = privatedata; return MI_SUCCESS; } -/* +/* ** SMFI_GETPRIV -- get private data ** ** Parameters: @@ -334,7 +511,7 @@ smfi_getpriv(ctx) return NULL; return ctx->ctx_privdata; } -/* +/* ** SMFI_GETSYMVAL -- get the value of a macro ** ** See explanation in mfapi.h about layout of the structures. @@ -397,4 +574,3 @@ smfi_getsymval(ctx, symname) } return NULL; } -#endif /* _FFR_MILTER */ |