# File: libspf-1.0.0/patches/Postfix/2.1.x/postfix-2.1.4-libspf-1.0.0-RC6.diff
# Date: 09/15/04
# Desc: Patch for libSPF v1.0 against Postfix v2.1.4
#
# Patch coder: Travis Anderson <tanderson@codeshare.ca>
# Diff author: James Couzens <jcouzens@codeshare.ca>
#
# Contents:
#
# diff -rpN -C4 postfix-2.1.4/include/mail_params.h postfix-2.1.4.libspf/include/mail_params.h >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/global/mail_params.h postfix-2.1.4.libspf/src/global/mail_params.h >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/smtpd/smtpd.c postfix-2.1.4.libspf/src/smtpd/smtpd.c >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/smtpd/smtpd_check.c postfix-2.1.4.libspf/src/smtpd/smtpd_check.c >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/smtpd/smtpd_state.c postfix-2.1.4.libspf/src/smtpd/smtpd_state.c >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/smtpd/Makefile postfix-2.1.4.libspf/src/smtpd/Makefile >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/src/smtpd/smtpd.h postfix-2.1.4.libspf/src/smtpd/smtpd.h >> postfix-2.1.4-libspf-1.0-RC6.diff
# diff -rpN -C4 postfix-2.1.4/conf/spf.cf.example postfix-2.1.4.libspf/conf/spf.cf.example >> postfix-2.1.4-libspf-1.0-RC6.diff
*** postfix-2.1.4/include/mail_params.h Wed Sep 15 08:52:07 2004
--- postfix-2.1.4.libspf/include/mail_params.h Wed Sep 15 08:33:42 2004
*************** extern char *var_syslog_facility;
*** 274,282 ****
extern char *var_always_bcc;
/*
* What to put in the To: header when no recipients were disclosed.
! *
* XXX 2822: When no recipient headers remain, a system should insert a Bcc:
* header without additional information. That is not so great given that
* MTAs routinely strip Bcc: headers from message headers.
*/
--- 274,282 ----
extern char *var_always_bcc;
/*
* What to put in the To: header when no recipients were disclosed.
! *
* XXX 2822: When no recipient headers remain, a system should insert a Bcc:
* header without additional information. That is not so great given that
* MTAs routinely strip Bcc: headers from message headers.
*/
*************** extern int var_hash_queue_depth;
*** 747,755 ****
* SMTP client. Timeouts inspired by RFC 1123. The SMTP recipient limit
* determines how many recipient addresses the SMTP client sends along with
* each message. Unfortunately, some mailers misbehave and disconnect (smap)
* when given more recipients than they are willing to handle.
! *
* XXX 2821: A mail system is supposed to use EHLO instead of HELO, and to fall
* back to HELO if EHLO is not supported.
*/
#define VAR_BESTMX_TRANSP "best_mx_transport"
--- 747,755 ----
* SMTP client. Timeouts inspired by RFC 1123. The SMTP recipient limit
* determines how many recipient addresses the SMTP client sends along with
* each message. Unfortunately, some mailers misbehave and disconnect (smap)
* when given more recipients than they are willing to handle.
! *
* XXX 2821: A mail system is supposed to use EHLO instead of HELO, and to fall
* back to HELO if EHLO is not supported.
*/
#define VAR_BESTMX_TRANSP "best_mx_transport"
*************** extern char *var_smtp_sasl_passwd;
*** 944,951 ****
--- 944,988 ----
#define VAR_SMTP_SASL_OPTS "smtp_sasl_security_options"
#define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_smtp_sasl_opts;
+ /*
+ * LIBSPF support
+ */
+ #define REJECT_SPF "reject_spf"
+
+ #define VAR_SPF_ACTION "spf_action"
+ #define DEF_SPF_ACTION 1
+ extern int var_spf_action;
+
+ #define VAR_SPF_DO_PREPEND_HEADER "spf_do_prepend_header"
+ #define DEF_SPF_DO_PREPEND_HEADER 1
+ extern bool var_spf_do_prepend_header;
+
+ #define VAR_SPF_DO_EXPLAIN "spf_do_explain"
+ #define DEF_SPF_DO_EXPLAIN 0
+ extern bool var_spf_do_explain;
+
+ #define VAR_SPF_DO_USE_BEST_GUESS_RECORD "spf_do_use_best_guess_record"
+ #define DEF_SPF_DO_USE_BEST_GUESS_RECORD 0
+ extern bool var_spf_do_use_best_guess_record;
+
+ #define VAR_SPF_DO_USE_TRUSTED_FORWARDER "spf_do_use_trusted_forwarder"
+ #define DEF_SPF_DO_USE_TRUSTED_FORWARDER 0
+ extern bool var_spf_do_use_trusted_forwarder;
+
+ #define VAR_SPF_CUSTOM_EXPLANATION "spf_custom_explanation"
+ #define DEF_SPF_CUSTOM_EXPLANATION ""
+ extern char *var_spf_custom_explanation;
+
+ #define VAR_SPF_CUSTOM_BEST_GUESS_RECORD "spf_custom_best_guess_record"
+ #define DEF_SPF_CUSTOM_BEST_GUESS_RECORD ""
+ extern char *var_spf_custom_best_guess_record;
+
+ #define VAR_SPF_CUSTOM_TRUSTED_FORWARDER "spf_custom_trusted_forwarder"
+ #define DEF_SPF_CUSTOM_TRUSTED_FORWARDER ""
+ extern char *var_spf_custom_trusted_forwarder;
+
/*
* LMTP server. The soft error limit determines how many errors an LMTP
* client may make before we start to slow down; the hard error limit
* determines after how many client errors we disconnect.
*** postfix-2.1.4/src/global/mail_params.h Wed Apr 21 11:56:04 2004
--- postfix-2.1.4.libspf/src/global/mail_params.h Wed Sep 15 08:19:42 2004
*************** extern char *var_syslog_facility;
*** 274,282 ****
extern char *var_always_bcc;
/*
* What to put in the To: header when no recipients were disclosed.
! *
* XXX 2822: When no recipient headers remain, a system should insert a Bcc:
* header without additional information. That is not so great given that
* MTAs routinely strip Bcc: headers from message headers.
*/
--- 274,282 ----
extern char *var_always_bcc;
/*
* What to put in the To: header when no recipients were disclosed.
! *
* XXX 2822: When no recipient headers remain, a system should insert a Bcc:
* header without additional information. That is not so great given that
* MTAs routinely strip Bcc: headers from message headers.
*/
*************** extern int var_hash_queue_depth;
*** 747,755 ****
* SMTP client. Timeouts inspired by RFC 1123. The SMTP recipient limit
* determines how many recipient addresses the SMTP client sends along with
* each message. Unfortunately, some mailers misbehave and disconnect (smap)
* when given more recipients than they are willing to handle.
! *
* XXX 2821: A mail system is supposed to use EHLO instead of HELO, and to fall
* back to HELO if EHLO is not supported.
*/
#define VAR_BESTMX_TRANSP "best_mx_transport"
--- 747,755 ----
* SMTP client. Timeouts inspired by RFC 1123. The SMTP recipient limit
* determines how many recipient addresses the SMTP client sends along with
* each message. Unfortunately, some mailers misbehave and disconnect (smap)
* when given more recipients than they are willing to handle.
! *
* XXX 2821: A mail system is supposed to use EHLO instead of HELO, and to fall
* back to HELO if EHLO is not supported.
*/
#define VAR_BESTMX_TRANSP "best_mx_transport"
*************** extern char *var_smtp_sasl_passwd;
*** 944,951 ****
--- 944,988 ----
#define VAR_SMTP_SASL_OPTS "smtp_sasl_security_options"
#define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_smtp_sasl_opts;
+ /*
+ * LIBSPF support
+ */
+ #define REJECT_SPF "reject_spf"
+
+ #define VAR_SPF_ACTION "spf_action"
+ #define DEF_SPF_ACTION 1
+ extern int var_spf_action;
+
+ #define VAR_SPF_DO_PREPEND_HEADER "spf_do_prepend_header"
+ #define DEF_SPF_DO_PREPEND_HEADER 1
+ extern bool var_spf_do_prepend_header;
+
+ #define VAR_SPF_DO_EXPLAIN "spf_do_explain"
+ #define DEF_SPF_DO_EXPLAIN 0
+ extern bool var_spf_do_explain;
+
+ #define VAR_SPF_DO_USE_BEST_GUESS_RECORD "spf_do_use_best_guess_record"
+ #define DEF_SPF_DO_USE_BEST_GUESS_RECORD 0
+ extern bool var_spf_do_use_best_guess;
+
+ #define VAR_SPF_DO_USE_TRUSTED_FORWARDER "spf_do_use_trusted_forwarder"
+ #define DEF_SPF_DO_USE_TRUSTED_FORWARDER 0
+ extern bool var_spf_do_use_trusted_forwarder;
+
+ #define VAR_SPF_CUSTOM_EXPLANATION "spf_custom_explanation"
+ #define DEF_SPF_CUSTOM_EXPLANATION ""
+ extern char *var_spf_custom_explanation;
+
+ #define VAR_SPF_CUSTOM_BEST_GUESS_RECORD "spf_custom_best_guess_record"
+ #define DEF_SPF_CUSTOM_BEST_GUESS_RECORD ""
+ extern char *var_spf_custom_guess_record;
+
+ #define VAR_SPF_CUSTOM_TRUSTED_FORWARDER "spf_custom_trusted_forwarder"
+ #define DEF_SPF_CUSTOM_TRUSTED_FORWARDER ""
+ extern char *var_spf_custom_trusted_forwarder;
+
/*
* LMTP server. The soft error limit determines how many errors an LMTP
* client may make before we start to slow down; the hard error limit
* determines after how many client errors we disconnect.
*** postfix-2.1.4/src/smtpd/smtpd.c Wed Jun 16 15:40:36 2004
--- postfix-2.1.4.libspf/src/smtpd/smtpd.c Sat Sep 11 12:48:53 2004
*************** char *var_xclient_hosts;
*** 754,761 ****
--- 754,771 ----
char *var_xforward_hosts;
bool var_smtpd_rej_unl_from;
bool var_smtpd_rej_unl_rcpt;
+ /* LibSPF vars */
+ int var_spf_action;
+ bool var_spf_do_prepend_header;
+ bool var_spf_do_explain;
+ bool var_spf_do_use_best_guess_record;
+ bool var_spf_do_use_trusted_forwarder;
+ char *var_spf_custom_explanation;
+ char *var_spf_custom_best_guess_record;
+ char *var_spf_custom_trusted_forwarder;
+
#ifdef SNAPSHOT
int var_smtpd_crate_limit;
int var_smtpd_cconn_limit;
char *var_smtpd_hoggers;
*************** static void mail_open_stream(SMTPD_STATE
*** 984,992 ****
/*
* XXX 2821: An SMTP server is not allowed to "clean up" mail except in
* the case of original submissions. Presently, Postfix always runs all
* mail through the cleanup server.
! *
* We could approximate the RFC as follows: Postfix rewrites mail if it
* comes from a source that we are willing to relay for. This way, we
* avoid rewriting most mail that comes from elsewhere. However, that
* requires moving functionality away from the cleanup daemon elsewhere,
--- 994,1002 ----
/*
* XXX 2821: An SMTP server is not allowed to "clean up" mail except in
* the case of original submissions. Presently, Postfix always runs all
* mail through the cleanup server.
! *
* We could approximate the RFC as follows: Postfix rewrites mail if it
* comes from a source that we are willing to relay for. This way, we
* avoid rewriting most mail that comes from elsewhere. However, that
* requires moving functionality away from the cleanup daemon elsewhere,
*************** static char *extract_addr(SMTPD_STATE *s
*** 1092,1104 ****
/*
* Some mailers send RFC822-style address forms (with comments and such)
* in SMTP envelopes. We cannot blame users for this: the blame is with
* programmers violating the RFC, and with sendmail for being permissive.
! *
* XXX The SMTP command tokenizer must leave the address in externalized
* (quoted) form, so that the address parser can correctly extract the
* address from surrounding junk.
! *
* XXX We have only one address parser, written according to the rules of
* RFC 822. That standard differs subtly from RFC 821.
*/
if (msg_verbose)
--- 1102,1114 ----
/*
* Some mailers send RFC822-style address forms (with comments and such)
* in SMTP envelopes. We cannot blame users for this: the blame is with
* programmers violating the RFC, and with sendmail for being permissive.
! *
* XXX The SMTP command tokenizer must leave the address in externalized
* (quoted) form, so that the address parser can correctly extract the
* address from surrounding junk.
! *
* XXX We have only one address parser, written according to the rules of
* RFC 822. That standard differs subtly from RFC 821.
*/
if (msg_verbose)
*************** static int mail_cmd(SMTPD_STATE *state,
*** 1191,1199 ****
state->encoding = 0;
/*
* Sanity checks.
! *
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
* which there are no other reasons for rejection, MUST reject that
* command with a 501 response. So much for the principle of "be liberal
--- 1201,1209 ----
state->encoding = 0;
/*
* Sanity checks.
! *
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
* which there are no other reasons for rejection, MUST reject that
* command with a 501 response. So much for the principle of "be liberal
*************** static int rcpt_cmd(SMTPD_STATE *state,
*** 1385,1393 ****
char *arg;
/*
* Sanity checks.
! *
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
* which there are no other reasons for rejection, MUST reject that
* command with a 501 response. So much for the principle of "be liberal
--- 1395,1403 ----
char *arg;
/*
* Sanity checks.
! *
* XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a
* command in which invalid character codes have been employed, and for
* which there are no other reasons for rejection, MUST reject that
* command with a 501 response. So much for the principle of "be liberal
*************** static int rcpt_cmd(SMTPD_STATE *state,
*** 1476,1484 ****
}
/*
* Store the recipient. Remember the first one.
! *
* Flush recipients to maintain a stiffer coupling with the next stage and
* to better utilize parallelism.
*/
state->rcpt_count++;
--- 1486,1494 ----
}
/*
* Store the recipient. Remember the first one.
! *
* Flush recipients to maintain a stiffer coupling with the next stage and
* to better utilize parallelism.
*/
state->rcpt_count++;
*************** static int data_cmd(SMTPD_STATE *state,
*** 1572,1580 ****
/*
* Flush out any access table actions that are delegated to the cleanup
* server, and that may trigger before we accept the first valid
* recipient.
! *
* Terminate the message envelope segment. Start the message content
* segment, and prepend our own Received: header. If there is only one
* recipient, list the recipient address.
*/
--- 1582,1590 ----
/*
* Flush out any access table actions that are delegated to the cleanup
* server, and that may trigger before we accept the first valid
* recipient.
! *
* Terminate the message envelope segment. Start the message content
* segment, and prepend our own Received: header. If there is only one
* recipient, list the recipient address.
*/
*************** static int data_cmd(SMTPD_STATE *state,
*** 1633,1645 ****
/*
* Copy the message content. If the cleanup process has a problem, keep
* reading until the remote stops sending, then complain. Produce typed
* records from the SMTP stream so we can handle data that spans buffers.
! *
* XXX Force an empty record when the queue file content begins with
* whitespace, so that it won't be considered as being part of our own
* Received: header. What an ugly Kluge.
! *
* XXX Deal with UNIX-style From_ lines at the start of message content
* because sendmail permits it.
*/
for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type) {
--- 1643,1655 ----
/*
* Copy the message content. If the cleanup process has a problem, keep
* reading until the remote stops sending, then complain. Produce typed
* records from the SMTP stream so we can handle data that spans buffers.
! *
* XXX Force an empty record when the queue file content begins with
* whitespace, so that it won't be considered as being part of our own
* Received: header. What an ugly Kluge.
! *
* XXX Deal with UNIX-style From_ lines at the start of message content
* because sendmail permits it.
*/
for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type) {
*************** static int data_cmd(SMTPD_STATE *state,
*** 1652,1659 ****
--- 1662,1683 ----
if (first) {
if (strncmp(start + strspn(start, ">"), "From ", 5) == 0) {
out_fprintf(out_stream, curr_rec_type,
"X-Mailbox-Line: %s", start);
+
+ #ifdef USE_LIBSPF
+ /* LibSPF: If we're giving an explanation, we want to output
+ it at the very start of DATA
+ */
+ if (state->spf_explanation != NULL) {
+ out_fprintf(out_stream, curr_rec_type,
+ state->spf_explanation);
+
+ /* make sure we leave nothing behind */
+ free(state->spf_explanation);
+ state->spf_explanation = NULL;
+ }
+ #endif
continue;
}
first = 0;
if (len > 0 && IS_SPACE_TAB(start[0]))
*************** static int data_cmd(SMTPD_STATE *state,
*** 1669,1677 ****
/*
* Send the end of DATA and finish the proxy connection. Set the
* CLEANUP_STAT_PROXY error flag in case of trouble.
! *
* XXX The low-level proxy output routines should set "state" error
* attributes. This requires making "state" a context attribute of the
* VSTREAM.
*/
--- 1693,1701 ----
/*
* Send the end of DATA and finish the proxy connection. Set the
* CLEANUP_STAT_PROXY error flag in case of trouble.
! *
* XXX The low-level proxy output routines should set "state" error
* attributes. This requires making "state" a context attribute of the
* VSTREAM.
*/
*************** static int data_cmd(SMTPD_STATE *state,
*** 1711,1719 ****
/*
* Handle any errors. One message may suffer from multiple errors, so
* complain only about the most severe error. Forgive any previous client
* errors when a message was received successfully.
! *
* See also: qmqpd.c
*/
if (state->err == CLEANUP_STAT_OK) {
state->error_count = 0;
--- 1735,1743 ----
/*
* Handle any errors. One message may suffer from multiple errors, so
* complain only about the most severe error. Forgive any previous client
* errors when a message was received successfully.
! *
* See also: qmqpd.c
*/
if (state->err == CLEANUP_STAT_OK) {
state->error_count = 0;
*************** static int noop_cmd(SMTPD_STATE *state,
*** 1800,1808 ****
/*
* XXX 2821 incompatibility: Section 4.1.1.9 says that NOOP can have a
* parameter string which is to be ignored. NOOP instructions with
* parameters? Go figure.
! *
* RFC 2821 violates RFC 821, which says that NOOP takes no parameters.
*/
#ifdef RFC821_SYNTAX
--- 1824,1832 ----
/*
* XXX 2821 incompatibility: Section 4.1.1.9 says that NOOP can have a
* parameter string which is to be ignored. NOOP instructions with
* parameters? Go figure.
! *
* RFC 2821 violates RFC 821, which says that NOOP takes no parameters.
*/
#ifdef RFC821_SYNTAX
*************** static int vrfy_cmd(SMTPD_STATE *state,
*** 1828,1847 ****
/*
* The SMTP standard (RFC 821) disallows unquoted special characters in
* the VRFY argument. Common practice violates the standard, however.
* Postfix accomodates common practice where it violates the standard.
! *
* XXX Impedance mismatch! The SMTP command tokenizer preserves quoting,
* whereas the recipient restrictions checks expect unquoted (internal)
* address forms. Therefore we must parse out the address, or we must
* stop doing recipient restriction checks and lose the opportunity to
* say "user unknown" at the SMTP port.
! *
* XXX 2821 incompatibility and brain damage: Section 4.5.1 requires that
* VRFY is implemented. RFC 821 specifies that VRFY is optional. It gets
* even worse: section 3.5.3 says that a 502 (command recognized but not
* implemented) reply is not fully compliant.
! *
* Thus, an RFC 2821 compliant implementation cannot refuse to supply
* information in reply to VRFY queries. That is simply bogus. The only
* reply we could supply is a generic 252 reply. This causes spammers to
* add tons of bogus addresses to their mailing lists (spam harvesting by
--- 1852,1871 ----
/*
* The SMTP standard (RFC 821) disallows unquoted special characters in
* the VRFY argument. Common practice violates the standard, however.
* Postfix accomodates common practice where it violates the standard.
! *
* XXX Impedance mismatch! The SMTP command tokenizer preserves quoting,
* whereas the recipient restrictions checks expect unquoted (internal)
* address forms. Therefore we must parse out the address, or we must
* stop doing recipient restriction checks and lose the opportunity to
* say "user unknown" at the SMTP port.
! *
* XXX 2821 incompatibility and brain damage: Section 4.5.1 requires that
* VRFY is implemented. RFC 821 specifies that VRFY is optional. It gets
* even worse: section 3.5.3 says that a 502 (command recognized but not
* implemented) reply is not fully compliant.
! *
* Thus, an RFC 2821 compliant implementation cannot refuse to supply
* information in reply to VRFY queries. That is simply bogus. The only
* reply we could supply is a generic 252 reply. This causes spammers to
* add tons of bogus addresses to their mailing lists (spam harvesting by
*************** static int vrfy_cmd(SMTPD_STATE *state,
*** 1876,1884 ****
* XXX 2821 new feature: Section 3.5.1 requires that the VRFY response is
* either "full name <user@domain>" or "user@domain". Postfix replies
* with the address that was provided by the client, whether or not it is
* in fully qualified domain form or not.
! *
* Reply code 250 is reserved for the case where the address is verified;
* reply code 252 should be used when no definitive certainty exists.
*/
smtpd_chat_reply(state, "252 %s", argv[1].strval);
--- 1900,1908 ----
* XXX 2821 new feature: Section 3.5.1 requires that the VRFY response is
* either "full name <user@domain>" or "user@domain". Postfix replies
* with the address that was provided by the client, whether or not it is
* in fully qualified domain form or not.
! *
* Reply code 250 is reserved for the case where the address is verified;
* reply code 252 should be used when no definitive certainty exists.
*/
smtpd_chat_reply(state, "252 %s", argv[1].strval);
*************** static void smtpd_proto(SMTPD_STATE *sta
*** 2368,2382 ****
* Print a greeting banner and run the state machine. Read SMTP commands
* one line at a time. According to the standard, a sender or recipient
* address could contain an escaped newline. I think this is perverse,
* and anyone depending on this is really asking for trouble.
! *
* In case of mail protocol trouble, the program jumps back to this place,
* so that it can perform the necessary cleanup before talking to the
* next client. The setjmp/longjmp primitives are like a sharp tool: use
* with care. I would certainly recommend against the use of
* setjmp/longjmp in programs that change privilege levels.
! *
* In case of file system trouble the program terminates after logging the
* error and after informing the client. In all other cases (out of
* memory, panic) the error is logged, and the msg_cleanup() exit handler
* cleans up, but no attempt is made to inform the client of the nature
--- 2392,2406 ----
* Print a greeting banner and run the state machine. Read SMTP commands
* one line at a time. According to the standard, a sender or recipient
* address could contain an escaped newline. I think this is perverse,
* and anyone depending on this is really asking for trouble.
! *
* In case of mail protocol trouble, the program jumps back to this place,
* so that it can perform the necessary cleanup before talking to the
* next client. The setjmp/longjmp primitives are like a sharp tool: use
* with care. I would certainly recommend against the use of
* setjmp/longjmp in programs that change privilege levels.
! *
* In case of file system trouble the program terminates after logging the
* error and after informing the client. In all other cases (out of
* memory, panic) the error is logged, and the msg_cleanup() exit handler
* cleans up, but no attempt is made to inform the client of the nature
*************** static void smtpd_service(VSTREAM *strea
*** 2552,2560 ****
/*
* This routine runs when a client has connected to our network port, or
* when the smtp server is run in stand-alone mode (input from pipe).
! *
* Look up and sanitize the peer name, then initialize some connection-
* specific state. When the name service is hosed, hostname lookup will
* take a while. This is why I always run a local name server on critical
* machines.
--- 2576,2584 ----
/*
* This routine runs when a client has connected to our network port, or
* when the smtp server is run in stand-alone mode (input from pipe).
! *
* Look up and sanitize the peer name, then initialize some connection-
* specific state. When the name service is hosed, hostname lookup will
* take a while. This is why I always run a local name server on critical
* machines.
*************** int main(int argc, char **argv)
*** 2706,2713 ****
--- 2730,2741 ----
VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code, 0, 0,
VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0,
VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0,
VAR_VERIFY_POLL_COUNT, DEF_VERIFY_POLL_COUNT, &var_verify_poll_count, 1, 0,
+
+ /* LibSPF vars */
+ VAR_SPF_ACTION, DEF_SPF_ACTION, &var_spf_action, 0, 7,
+
#ifdef SNAPSHOT
VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0,
VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
#endif
*************** int main(int argc, char **argv)
*** 2733,2740 ****
--- 2761,2774 ----
VAR_BROKEN_AUTH_CLNTS, DEF_BROKEN_AUTH_CLNTS, &var_broken_auth_clients,
VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table,
VAR_SMTPD_REJ_UNL_FROM, DEF_SMTPD_REJ_UNL_FROM, &var_smtpd_rej_unl_from,
VAR_SMTPD_REJ_UNL_RCPT, DEF_SMTPD_REJ_UNL_RCPT, &var_smtpd_rej_unl_rcpt,
+
+ /* LibSPF vars */
+ VAR_SPF_DO_PREPEND_HEADER, DEF_SPF_DO_PREPEND_HEADER, &var_spf_do_prepend_header,
+ VAR_SPF_DO_EXPLAIN, DEF_SPF_DO_EXPLAIN, &var_spf_do_explain,
+ VAR_SPF_DO_USE_BEST_GUESS_RECORD, DEF_SPF_DO_USE_BEST_GUESS_RECORD, &var_spf_do_use_best_guess_record,
+ VAR_SPF_DO_USE_TRUSTED_FORWARDER, DEF_SPF_DO_USE_TRUSTED_FORWARDER, &var_spf_do_use_trusted_forwarder,
0,
};
static CONFIG_STR_TABLE str_table[] = {
VAR_SMTPD_BANNER, DEF_SMTPD_BANNER, &var_smtpd_banner, 1, 0,
*************** int main(int argc, char **argv)
*** 2771,2778 ****
--- 2805,2818 ----
VAR_SMTPD_PROXY_EHLO, DEF_SMTPD_PROXY_EHLO, &var_smtpd_proxy_ehlo, 0, 0,
VAR_INPUT_TRANSP, DEF_INPUT_TRANSP, &var_input_transp, 0, 0,
VAR_XCLIENT_HOSTS, DEF_XCLIENT_HOSTS, &var_xclient_hosts, 0, 0,
VAR_XFORWARD_HOSTS, DEF_XFORWARD_HOSTS, &var_xforward_hosts, 0, 0,
+
+ /* LibSPF vars */
+ VAR_SPF_CUSTOM_EXPLANATION, DEF_SPF_CUSTOM_EXPLANATION, &var_spf_custom_explanation, 0, 0,
+ VAR_SPF_CUSTOM_BEST_GUESS_RECORD, DEF_SPF_CUSTOM_BEST_GUESS_RECORD, &var_spf_custom_best_guess_record, 0, 0,
+ VAR_SPF_CUSTOM_TRUSTED_FORWARDER, DEF_SPF_CUSTOM_TRUSTED_FORWARDER, &var_spf_custom_trusted_forwarder, 0, 0,
+
#ifdef SNAPSHOT
VAR_SMTPD_HOGGERS, DEF_SMTPD_HOGGERS, &var_smtpd_hoggers, 0, 0,
#endif
0,
*** postfix-2.1.4/src/smtpd/smtpd_check.c Mon May 3 08:40:13 2004
--- postfix-2.1.4.libspf/src/smtpd/smtpd_check.c Sat Sep 11 12:47:17 2004
***************
*** 207,214 ****
--- 207,218 ----
#include <is_header.h>
/* Application-specific. */
+ #ifdef USE_LIBSPF
+ #include <spf.h>
+ #endif /* USE_LIBSPF */
+
#include "smtpd.h"
#include "smtpd_sasl_glue.h"
#include "smtpd_check.h"
*************** static int check_rcpt_maps(SMTPD_STATE *
*** 324,348 ****
/*
* If some decision can't be made due to a temporary error, then change
* other decisions into deferrals.
! *
* XXX Deferrals can be postponed only with restrictions that are based on
* client-specified information: this restricts their use to parameters
* given in HELO, MAIL FROM, RCPT TO commands.
! *
* XXX Deferrals must not be postponed after client hostname lookup failure.
* The reason is that the effect of access tables may depend on whether a
* client hostname is available or not. Thus, the reject_unknown_client
* restriction must defer immediately when lookup fails, otherwise incorrect
* results happen with:
! *
* reject_unknown_client, hostname-based white-list, reject
! *
* XXX With warn_if_reject, don't raise the defer_if_permit flag when a
* reject-style restriction fails. Instead, log the warning for the
* resulting defer message.
! *
* XXX With warn_if_reject, do raise the defer_if_reject flag when a
* permit-style restriction fails. Otherwise, we could reject legitimate
* mail.
*/
--- 328,352 ----
/*
* If some decision can't be made due to a temporary error, then change
* other decisions into deferrals.
! *
* XXX Deferrals can be postponed only with restrictions that are based on
* client-specified information: this restricts their use to parameters
* given in HELO, MAIL FROM, RCPT TO commands.
! *
* XXX Deferrals must not be postponed after client hostname lookup failure.
* The reason is that the effect of access tables may depend on whether a
* client hostname is available or not. Thus, the reject_unknown_client
* restriction must defer immediately when lookup fails, otherwise incorrect
* results happen with:
! *
* reject_unknown_client, hostname-based white-list, reject
! *
* XXX With warn_if_reject, don't raise the defer_if_permit flag when a
* reject-style restriction fails. Instead, log the warning for the
* resulting defer message.
! *
* XXX With warn_if_reject, do raise the defer_if_reject flag when a
* permit-style restriction fails. Otherwise, we could reject legitimate
* mail.
*/
*************** static int smtpd_check_reject(SMTPD_STAT
*** 757,776 ****
}
/*
* Soft bounce safety net.
! *
* XXX The code below also appears in the Postfix SMTP server reply output
* routine. It is duplicated here in order to avoid discrepancies between
* the reply codes that are shown in "reject" logging and the reply codes
* that are actually sent to the SMTP client.
! *
* Implementing the soft_bounce safety net in the SMTP server reply output
* routine has the advantage that it covers all 5xx replies, including
* SMTP protocol or syntax errors, which makes soft_bounce great for
* non-destructive tests (especially by people who are paranoid about
* losing mail).
! *
* We could eliminate the code duplication and implement the soft_bounce
* safety net only in the code below. But then the safety net would cover
* the UCE restrictions only. This would be at odds with documentation
* which says soft_bounce changes all 5xx replies into 4xx ones.
--- 761,780 ----
}
/*
* Soft bounce safety net.
! *
* XXX The code below also appears in the Postfix SMTP server reply output
* routine. It is duplicated here in order to avoid discrepancies between
* the reply codes that are shown in "reject" logging and the reply codes
* that are actually sent to the SMTP client.
! *
* Implementing the soft_bounce safety net in the SMTP server reply output
* routine has the advantage that it covers all 5xx replies, including
* SMTP protocol or syntax errors, which makes soft_bounce great for
* non-destructive tests (especially by people who are paranoid about
* losing mail).
! *
* We could eliminate the code duplication and implement the soft_bounce
* safety net only in the code below. But then the safety net would cover
* the UCE restrictions only. This would be at odds with documentation
* which says soft_bounce changes all 5xx replies into 4xx ones.
*************** static char *dup_if_truncate(char *name)
*** 874,882 ****
char *result;
/*
* Truncate hostnames ending in dot but not dot-dot.
! *
* XXX This should not be distributed all over the code. Problem is,
* addresses can enter the system via multiple paths: networks, local
* forward/alias/include files, even as the result of address rewriting.
*/
--- 878,886 ----
char *result;
/*
* Truncate hostnames ending in dot but not dot-dot.
! *
* XXX This should not be distributed all over the code. Problem is,
* addresses can enter the system via multiple paths: networks, local
* forward/alias/include files, even as the result of address rewriting.
*/
*************** static int not_in_client_helo(SMTPD_STAT
*** 1644,1652 ****
* immediately, outside any particular mail transaction context. For
* example, rejecting HELO does not affect subsequent mail deliveries.
* Thus, if delay_reject=no, client and helo actions such as FILTER or
* HOLD also should not affect subsequent mail deliveries. Hmm...
! *
* XXX If the MAIL FROM command is rejected then we have to reset access
* map side effects such as FILTER.
*/
if (state->sender == 0) {
--- 1648,1656 ----
* immediately, outside any particular mail transaction context. For
* example, rejecting HELO does not affect subsequent mail deliveries.
* Thus, if delay_reject=no, client and helo actions such as FILTER or
* HOLD also should not affect subsequent mail deliveries. Hmm...
! *
* XXX If the MAIL FROM command is rejected then we have to reset access
* map side effects such as FILTER.
*/
if (state->sender == 0) {
*************** static int check_table_result(SMTPD_STAT
*** 1878,1886 ****
* Unfortunately, maps must be declared ahead of time so they can be
* opened before we go to jail. We could insist that the RHS can only
* contain a pre-defined restriction class name, but that would be too
* restrictive. Instead we warn if an access table references any map.
! *
* XXX Don't use passwd files or address rewriting maps as access tables.
*/
if (strchr(value, ':') != 0) {
msg_warn("SMTPD access map %s has entry with lookup table: %s",
--- 1882,1890 ----
* Unfortunately, maps must be declared ahead of time so they can be
* opened before we go to jail. We could insist that the RHS can only
* contain a pre-defined restriction class name, but that would be too
* restrictive. Instead we warn if an access table references any map.
! *
* XXX Don't use passwd files or address rewriting maps as access tables.
*/
if (strchr(value, ':') != 0) {
msg_warn("SMTPD access map %s has entry with lookup table: %s",
*************** static int check_table_result(SMTPD_STAT
*** 1904,1912 ****
/*
* Recursively evaluate the restrictions given in the right-hand side. In
* the dark ages, an empty right-hand side meant OK. Make some
* discouraging comments.
! *
* XXX Jump some hoops to avoid a minute memory leak in case of a file
* configuration error.
*/
#define ADDROF(x) ((char *) &(x))
--- 1908,1916 ----
/*
* Recursively evaluate the restrictions given in the right-hand side. In
* the dark ages, an empty right-hand side meant OK. Make some
* discouraging comments.
! *
* XXX Jump some hoops to avoid a minute memory leak in case of a file
* configuration error.
*/
#define ADDROF(x) ((char *) &(x))
*************** static int check_domain_access(SMTPD_STA
*** 1985,1993 ****
msg_info("%s: %s", myname, domain);
/*
* Try the name and its parent domains. Including top-level domains.
! *
* Helo names can end in ".". The test below avoids lookups of the empty
* key, because Berkeley DB cannot deal with it. [Victor Duchovni, Morgan
* Stanley].
*/
--- 1989,1997 ----
msg_info("%s: %s", myname, domain);
/*
* Try the name and its parent domains. Including top-level domains.
! *
* Helo names can end in ".". The test below avoids lookups of the empty
* key, because Berkeley DB cannot deal with it. [Victor Duchovni, Morgan
* Stanley].
*/
*************** static int check_server_access(SMTPD_STA
*** 2136,2147 ****
domain = name;
/*
* If the domain name does not exist then we apply no restriction.
! *
* If the domain name exists but no MX record exists, fabricate an MX record
* that points to the domain name itself.
! *
* If the domain name exists but no NS record exists, look up parent domain
* NS records.
*/
dns_status = dns_lookup(domain, type, 0, &server_list,
--- 2140,2151 ----
domain = name;
/*
* If the domain name does not exist then we apply no restriction.
! *
* If the domain name exists but no MX record exists, fabricate an MX record
* that points to the domain name itself.
! *
* If the domain name exists but no NS record exists, look up parent domain
* NS records.
*/
dns_status = dns_lookup(domain, type, 0, &server_list,
*************** static const char *smtpd_expand_lookup(c
*** 2432,2440 ****
/*
* Don't query main.cf parameters, as the result of expansion could
* reveal system-internal information in server replies.
! *
* Return NULL only for non-existent names.
*/
if (STREQ(name, MAIL_ATTR_CLIENT)) {
return (state->namaddr);
--- 2436,2444 ----
/*
* Don't query main.cf parameters, as the result of expansion could
* reveal system-internal information in server replies.
! *
* Return NULL only for non-existent names.
*/
if (STREQ(name, MAIL_ATTR_CLIENT)) {
return (state->namaddr);
*************** static int reject_unauth_sender_login_mi
*** 2825,2832 ****
--- 2829,2960 ----
}
#endif
+ #ifdef USE_LIBSPF
+
+ /* reject spf - checks if the sender+client_addr passes an SPF check */
+
+ /*
+ TODO
+ -test config file settings
+ -document config file settings
+ -add debug info
+ -write comments
+ */
+
+ static int reject_spf(SMTPD_STATE *state, const char *sender, const char *client_addr)
+ {
+ int pass = 0;
+ SPF_RESULT res = 0;
+ char *client_helo = NULL;
+ char *recieved_spf = NULL;
+
+ char *spf_explain = NULL;
+ char *spf_trusted_forwarder = NULL;
+ char *spf_best_guess = NULL;
+
+ char *header_response = NULL;
+ VSTRING *vstr_header_response = NULL;
+ char *header_response_full = NULL;
+
+ peer_info_t *pi = NULL;
+
+ if (var_spf_action > 0)
+ {
+ recieved_spf = "Recieved-SPF: ";
+
+ if (state->helo_name && *state->helo_name) {
+ client_helo = state->helo_name;
+ }
+
+ if (var_spf_custom_explanation != NULL && *var_spf_custom_explanation) {
+ spf_explain = var_spf_custom_explanation;
+ }
+
+ if (var_spf_custom_trusted_forwarder != NULL && *var_spf_custom_trusted_forwarder) {
+ spf_trusted_forwarder = var_spf_custom_trusted_forwarder;
+ }
+
+ if (var_spf_custom_best_guess_record != NULL && *var_spf_custom_best_guess_record) {
+ spf_best_guess = var_spf_custom_best_guess_record;
+ }
+
+ pi = SPF_init(var_myhostname, client_addr, spf_explain, spf_trusted_forwarder,
+ spf_best_guess, var_spf_do_use_trusted_forwarder,
+ var_spf_do_use_best_guess_record);
+
+ if (pi == NULL) {
+ msg_fatal("SPF: Could not allocate peer_info_t structure");
+ return (SMTPD_CHECK_DUNNO);
+ }
+
+ SPF_smtp_helo(pi, client_helo);
+
+ if (SPF_smtp_from(pi, sender) == 0) {
+ msg_error("SPF: Bad address: %s", sender);
+ SPF_close(pi);
+
+ return(SMTPD_CHECK_DUNNO);
+ }
+
+ res = SPF_policy_main(pi);
+
+ if (var_spf_action > 1) {
+ switch (res) {
+ case SPF_H_FAIL: pass = (var_spf_action > 1 ? 0 : 1); break;
+ case SPF_S_FAIL: pass = (var_spf_action > 2 ? 0 : 1); break;
+ case SPF_NEUTRAL: pass = (var_spf_action > 3 ? 0 : 1); break;
+ case SPF_NONE: pass = (var_spf_action > 4 ? 0 : 1); break;
+ case SPF_ERROR: pass = (var_spf_action > 5 ? 0 : 1); break;
+ case SPF_UNKNOWN: pass = (var_spf_action > 6 ? 0 : 1); break;
+ default: pass = 1; break;
+ }
+ } else {
+ pass = 1;
+ }
+
+ if (!pass) {
+ SPF_close(pi);
+
+ return(smtpd_check_reject(state, MAIL_ERROR_POLICY,
+ "553: Sender address rejected: SPF check failed"));
+ } else {
+ if (var_spf_do_explain) {
+ state->spf_explanation = SPF_get_explain(pi);
+ }
+
+ if (var_spf_do_prepend_header) {
+ header_response = SPF_build_header(pi);
+ }
+
+ if (header_response != NULL) {
+ vstr_header_response = vstring_alloc(strlen(recieved_spf) + strlen(header_response) + 1);
+ vstring_strcat(vstr_header_response, recieved_spf);
+ vstring_strcat(vstr_header_response, header_response);
+ header_response_full = vstring_export(vstr_header_response);
+
+ if (state->prepend == 0) {
+ state->prepend = argv_alloc(1);
+ }
+
+ argv_add(state->prepend, header_response_full, (char *) 0);
+
+ free(header_response);
+ free(header_response_full);
+ }
+
+ SPF_close(pi);
+
+ return(SMTPD_CHECK_DUNNO);
+ }
+ }
+
+ return(SMTPD_CHECK_DUNNO);
+ }
+
+ #endif /* USE_LIBSPF */
+
/* check_policy_service - check delegated policy service */
static int check_policy_service(SMTPD_STATE *state, const char *server,
const char *reply_name, const char *reply_class,
*************** static int generic_checks(SMTPD_STATE *s
*** 3176,3183 ****
--- 3304,3318 ----
status = reject_unauth_sender_login_mismatch(state, state->sender);
} else
#endif
msg_warn("restriction `%s' ignored: no SASL support", name);
+ } else if (strcasecmp(name, REJECT_SPF) == 0) {
+ #ifdef USE_LIBSPF
+ if (state->sender && *state->sender && state->addr) {
+ status = reject_spf(state, state->sender, state->addr);
+ } else
+ #endif /* USE_LIBSPF */
+ msg_warn("restriction `%s' ignored: no SPF support", name);
} else if (is_map_command(state, name, CHECK_SENDER_NS_ACL, &cpp)) {
if (state->sender && *state->sender) {
status = check_server_access(state, *cpp, state->sender,
T_NS, state->sender,
*************** static int generic_checks(SMTPD_STATE *s
*** 3303,3310 ****
--- 3438,3446 ----
status = generic_checks(state, list, reply_name,
reply_class, def_acl);
}
+
/*
* Error: undefined restriction name.
*/
else {
*************** static int check_rcpt_maps(SMTPD_STATE *
*** 3738,3746 ****
/*
* At this point, anything that resolves to the error mailer is known to
* be undeliverable.
! *
* XXX Until the address resolver does final address resolution, known and
* unknown recipients in virtual alias domains will both resolve to
* "error:user unknown".
*/
--- 3874,3882 ----
/*
* At this point, anything that resolves to the error mailer is known to
* be undeliverable.
! *
* XXX Until the address resolver does final address resolution, known and
* unknown recipients in virtual alias domains will both resolve to
* "error:user unknown".
*/
*************** static int check_rcpt_maps(SMTPD_STATE *
*** 3753,3765 ****
STR(reply->nexthop)));
/*
* Search the recipient lookup tables of the respective address class.
! *
* XXX Use the less expensive maps_find() (case is already folded) instead
* of the baroque mail_addr_find(). But then we have to strip the domain
* and deal with address extensions ourselves.
! *
* XXX But that would break sites that use the virtual delivery agent for
* local delivery, because the virtual delivery agent requires
* user@domain style addresses in its user database.
*/
--- 3889,3901 ----
STR(reply->nexthop)));
/*
* Search the recipient lookup tables of the respective address class.
! *
* XXX Use the less expensive maps_find() (case is already folded) instead
* of the baroque mail_addr_find(). But then we have to strip the domain
* and deal with address extensions ourselves.
! *
* XXX But that would break sites that use the virtual delivery agent for
* local delivery, because the virtual delivery agent requires
* user@domain style addresses in its user database.
*/
*************** char *smtpd_check_data(SMTPD_STATE *st
*** 3895,3903 ****
state->defer_if_permit.active = 0;
/*
* Apply restrictions in the order as specified.
! *
* XXX We cannot specify a default target for a bare access map.
*/
SMTPD_CHECK_RESET();
status = setjmp(smtpd_check_buf);
--- 4031,4039 ----
state->defer_if_permit.active = 0;
/*
* Apply restrictions in the order as specified.
! *
* XXX We cannot specify a default target for a bare access map.
*/
SMTPD_CHECK_RESET();
status = setjmp(smtpd_check_buf);
*** postfix-2.1.4/src/smtpd/smtpd_state.c Wed Apr 21 11:23:49 2004
--- postfix-2.1.4.libspf/src/smtpd/smtpd_state.c Sat Sep 11 10:15:11 2004
*************** void smtpd_state_init(SMTPD_STATE *st
*** 118,125 ****
--- 118,129 ----
if (var_smtpd_sasl_enable)
smtpd_sasl_connect(state, VAR_SMTPD_SASL_OPTS, var_smtpd_sasl_opts);
#endif
+ #ifdef USE_LIBSPF
+ state->spf_explanation = NULL;
+ #endif
+
/*
* Initialize peer information.
*/
smtpd_peer_init(state);
*** postfix-2.1.4/src/smtpd/Makefile Wed Sep 15 08:51:49 2004
--- postfix-2.1.4.libspf/src/smtpd/Makefile Sat Sep 11 06:30:32 2004
*************** OBJS = smtpd.o smtpd_token.o smtpd_check
*** 22,35 ****
smtpd_xforward.o
HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
smtpd_sasl_glue.h smtpd_proxy.h
TESTSRC = smtpd_token_test.c
! DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG= smtpd_token smtpd_check
PROG = smtpd
INC_DIR = ../../include
! LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libdns.a ../../lib/libutil.a
.c.o:; $(CC) $(CFLAGS) -c $*.c
$(PROG): $(OBJS) $(LIBS)
--- 22,35 ----
smtpd_xforward.o
HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
smtpd_sasl_glue.h smtpd_proxy.h
TESTSRC = smtpd_token_test.c
! DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) -DUSE_LIBSPF
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
TESTPROG= smtpd_token smtpd_check
PROG = smtpd
INC_DIR = ../../include
! LIBS = ../../lib/libmaster.a ../../lib/libglobal.a ../../lib/libdns.a ../../lib/libutil.a /usr/local/lib/libspf.so
.c.o:; $(CC) $(CFLAGS) -c $*.c
$(PROG): $(OBJS) $(LIBS)
*** postfix-2.1.4/src/smtpd/smtpd.h Wed Apr 21 11:23:33 2004
--- postfix-2.1.4.libspf/src/smtpd/smtpd.h Sat Sep 11 10:03:17 2004
*************** typedef struct SMTPD_STATE {
*** 104,111 ****
--- 104,118 ----
VSTRING *sasl_decoded;
#endif
/*
+ * LibSPF specific
+ */
+ #ifdef USE_LIBSPF
+ char *spf_explanation;
+ #endif
+
+ /*
* Specific to smtpd access checks.
*/
int sender_rcptmap_checked; /* sender validated against maps */
int recipient_rcptmap_checked; /* recipient validated against maps */
*************** extern void smtpd_peer_reset(SMTPD_STATE
*** 207,225 ****
#define SMTPD_PEER_CODE_PERM 5
/*
* Choose between normal or forwarded attributes.
! *
* Note 1: inside the SMTP server, forwarded attributes must have the exact
* same representation as normal attributes: unknown string values are
* "unknown", except for HELO which defaults to null. This is better than
* having to change every piece of code that accesses a possibly forwarded
* attribute.
! *
* Note 2: outside the SMTP server, the representation of unknown/known
* attribute values is different in queue files, in queue manager delivery
* requests, and in over-the-network XFORWARD commands.
! *
* Note 3: if forwarding client information, don't mix information from the
* current SMTP session with forwarded information from an up-stream
* session.
*/
--- 214,232 ----
#define SMTPD_PEER_CODE_PERM 5
/*
* Choose between normal or forwarded attributes.
! *
* Note 1: inside the SMTP server, forwarded attributes must have the exact
* same representation as normal attributes: unknown string values are
* "unknown", except for HELO which defaults to null. This is better than
* having to change every piece of code that accesses a possibly forwarded
* attribute.
! *
* Note 2: outside the SMTP server, the representation of unknown/known
* attribute values is different in queue files, in queue manager delivery
* requests, and in over-the-network XFORWARD commands.
! *
* Note 3: if forwarding client information, don't mix information from the
* current SMTP session with forwarded information from an up-stream
* session.
*/
*** postfix-2.1.4/conf/spf.cf.example Wed Dec 31 16:00:00 1969
--- postfix-2.1.4.libspf/conf/spf.cf.example Sat Sep 11 12:55:49 2004
***************
*** 0 ****
--- 1,98 ----
+ # SPF ACTION
+ #
+ # Describes the action to take (i.e., accept or reject) based on the SPF
+ # result.
+ #
+ # 0: SPF checking disabled
+ # 1+: SPF checks enabled; all mail is accepted regardless of result.
+ # 2: messages with a result of 'fail' are rejected;
+ # all other result types accepted
+ # 3: rejected: fail, softfail; accepted: all others
+ # 4: rejected: fail, softfail, neutral; accepted: all others
+ # 5: rejected: fail, softfail, neutral, none; accepted: all others
+ # 6: rejected: fail, softfail, neutral, none, error; accepted: all others
+ # 7: rejected: fail, softfail, neutral, none, error, unknown;
+ # accepted: all others (only pass at this point)
+ #
+ #spf_action = 1
+
+ # PREPEND SPF HEADER
+ #
+ # Add the Recieved-SPF: header to SPF-checked messages
+ #
+ #spf_do_prepend_header = yes
+
+ # ADD EXPLANATIONS TO DATA
+ #
+ # Prepends a string explaining the SPF result (except if result is PASS)
+ # to DATA.
+ #
+ # Note: LibSPF has a built-in default explanation; this setting
+ # may be turned on without modifying spf_custom_explanation. The
+ # default LibSPF values are given as examples for their respective
+ # spf_custom_* conf vars.
+ #
+ # See also: spf_custom_explanation
+ #
+ #spf_do_explain = no
+
+ # USE A TRUSTED FORWARDER
+ #
+ # For domains that do not publish SPF records, try to use a trusted forwarder
+ # instead.
+ #
+ # Note: LibSPF has a built-in default trusted forwarder record; this setting
+ # may be turned on without modifying spf_custom_trusted_forwarder. The
+ # default LibSPF values are given as examples for their respective
+ # spf_custom_* conf vars.
+ #
+ # See also: spf_custom_trusted_forwarder
+ #
+ #spf_do_use_trusted_forwarder = no
+
+ # USE A BEST GUESS RECORD
+ #
+ # Apply a "best guess" generic record for domains who do not publish SPF and
+ # did not pass with a trusted forwarder.
+ #
+ # Note: LibSPF has a built-in default best guess record; this setting
+ # may be turned on without modifying spf_custom_best_guess_record. The
+ # default LibSPF values are given as examples for their respective
+ # spf_custom_* conf vars.
+ #
+ # See also: spf_custom_best_guess_record
+ #
+ #spf_do_use_best_guess_record = no
+
+ # SET CUSTOM EXPLANATION
+ #
+ # Set a custom SPF result explanation that is prepended to DATA whenever the
+ # result is anything other than PASS.
+ #
+ # Note: Is not used unless spf_do_explain = yes
+ #
+ # Ex: See http://spf.pobox.com/why.html?sender=%{S}&ip=%{I}&receiver=%{xR}
+ #
+ #spf_custom_explanation =
+
+ # SET CUSTOM TRUSTED FORWARDER
+ #
+ # Set a custom trusted forwarder that is used when considering a domain which
+ # does not publish SPF records.
+ #
+ # Note: Is not used unless spf_do_use_trusted_forwarder = yes
+ #
+ # Ex: v=spf1 include:spf.trusted-forwarder.org
+ #
+ #spf_custom_trusted_forwarder =
+
+ # SET CUSTOM BEST GUESS RECORD
+ #
+ # Set a custom best guess record that is applied to domains who do not publish
+ # SPF and did not pass with a trusted forwarder.
+ #
+ # Note: Is not used unless spf_do_use_best_guess_record = yes
+ #
+ # Ex: v=spf1 a/24 mx/24 ptr
+ #
+ #spf_custom_best_guess_record =
syntax highlighted by Code2HTML, v. 0.9.1