diff --git a/postfix/.indent.pro b/postfix/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/.indent.pro
+++ b/postfix/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 58fd9eb63..d627a1b85 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -3743,3 +3743,33 @@ Apologies for any names omitted.
The recipient counts provides an initial estimate for a
more advanced queue manager scheduling algorithm. Files:
cleanup/cleanup_envelope.c, cleanup/cleanup_extracted.c.
+
+20000311
+
+ Portability: HP-UX awk can't handle bare { in regexps
+ (Lamont Jones. HP). File: postconf/extract.awk.
+
+ Compatibility: sendmail now recognizes '.' as end of input.
+ File: sendmail/sendmail.c.
+
+20000313
+
+ Compatibility: dtcm (CDE desktop calendar manager) leaks
+ a file descriptor into its child process, and requires that
+ sendmail closes the descriptor, otherwise mail notification
+ will hang. These GUI programmers never figured out that
+ the child process must close the writing ed of a pipe.
+ File: sendmail/sendmail.c.
+
+20000314
+
+ Feature: SASL authentication in the SMTP server and client.
+ Based on code contributed by Till Franke, SuSE. Specify:
+ "smtpd_sasl_auth_enable = yes" and "smtp_sasl_auth_enable
+ = yes". The "permit_sasl_authenticated" UCE restriction
+ gives special treatment to authenticated clients.
+
+20000315
+
+ Workaround: added -blibpath option for AIX 4.x, to close
+ hole in case postdrop needs to be set-gid.
diff --git a/postfix/Makefile b/postfix/Makefile
index 424db7120..8d9e069d9 100644
--- a/postfix/Makefile
+++ b/postfix/Makefile
@@ -12,7 +12,7 @@ SHELL = /bin/sh
default: update
update depend printfck clean tidy depend_update: Makefiles
- $(MAKE) $@
+ $(MAKE) MAKELEVEL= $@
makefiles Makefiles:
- $(MAKE) -f Makefile.in Makefiles
+ $(MAKE) -f Makefile.in MAKELEVEL= Makefiles
diff --git a/postfix/Makefile.in b/postfix/Makefile.in
index ec3d76ba3..7bf601f1c 100644
--- a/postfix/Makefile.in
+++ b/postfix/Makefile.in
@@ -36,6 +36,14 @@ depend_update:
|| exit 1; \
done
+cleanmakefiles:
+ set -e; for i in $(DIRS); do \
+ (set -e; echo "[$$i]"; cd $$i; rm -f Makefile; \
+ ../cleanup_makefile.pl Makefile.in >Makefile.new; \
+ rm Makefile.in ; mv Makefile.new Makefile.in); \
+ done;
+ rm -f Makefile; (set -e; sh makedefs; cat Makefile.in) >Makefile
+
tidy: clean
rm -f Makefile */Makefile
cp Makefile.init Makefile
diff --git a/postfix/Makefile.init b/postfix/Makefile.init
index 424db7120..8d9e069d9 100644
--- a/postfix/Makefile.init
+++ b/postfix/Makefile.init
@@ -12,7 +12,7 @@ SHELL = /bin/sh
default: update
update depend printfck clean tidy depend_update: Makefiles
- $(MAKE) $@
+ $(MAKE) MAKELEVEL= $@
makefiles Makefiles:
- $(MAKE) -f Makefile.in Makefiles
+ $(MAKE) -f Makefile.in MAKELEVEL= Makefiles
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index c83265f39..bdcdaedc4 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -5,6 +5,10 @@ This release is mainly to have a reference point after reorganizing
the cleanup daemon, and before adding some major contributions from
other people.
+The sendmail command now treats a `.' line as end of input, for
+the sake of compatibility. To revert to past behavior, specify the
+`-i' or `-oi' command-line flags.
+
Major changes with snapshot-20000309
====================================
diff --git a/postfix/SASL_README b/postfix/SASL_README
new file mode 100644
index 000000000..de366bc49
--- /dev/null
+++ b/postfix/SASL_README
@@ -0,0 +1,74 @@
+Introduction
+============
+
+The Postfix SASL support according to RFC 2554 was originally
+implemented by Till Franke of SuSE Rhein/Main AG. The present code
+is a trimmed-down implementation of only the bare necessities for
+SMTP clients and servers. When receiving mail, Postfix logs the
+client-provided username and sender address to the maillog file,
+but does not include that information in message headers.
+
+Building the SASL library
+=========================
+
+Postfix appears to work with cyrus-sasl-1.5.5, which is available
+from:
+
+ ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
+
+Other SASL libraries may require some changes. All the library
+specific code is in smtp_sasl_glue.c and in smtpd_sasl_glue.c.
+
+Building Postfix with SASL authentication support
+=================================================
+
+To build Postfix with SASL authentication support, given that the
+SASL include files are in /usr/local/include, and that the SASL
+libraries are in /usr/local/lib:
+
+ % make makefiles CCARGS=-DUSE_SASL_AUTH" -I/usr/local/include" \
+ AUXLIBS="-L/usr/local/lib -lsasl"
+
+Enabling SASL authentication in the SMTP server
+===============================================
+
+See conf/sample-sasl.cf for examples.
+
+ /etc/postfix/main.cf:
+ smtpd_sasl_auth_enable = yes
+
+In order to allow mail relaying by authenticated clients:
+
+ /etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ permit_mynetworks permit_sasl_authenticated ...
+
+In usr/local/lib/sasl/smtpd.conf you need to specify what authentication
+mechanisms the server will support, for example:
+
+ pwcheck_method: {PAM, kerberos_v4, passwd, shadow, sasldb}
+
+/etc/sasldb is a db (dbm) database. IN order to make all this work
+with chrooted operation, you may have to copy files into chroot
+jail: password files, PAM libraries, etc.
+
+If PAM is used, the PAM service name is `smtp'. The SASL service
+name is `smtp', too.
+
+Enabling SASL authentication in the SMTP client
+===============================================
+
+Turn on client-side SASl authentication, and specify a table with
+per-host username and password information.
+
+ /etc/postfix/main.cf:
+ smtp_sasl_auth_enable = yes
+ smtp_sasl_passwd_maps = hash:/etc/postfix/sasl_passwd
+
+ /etc/postfix/sasl_passwd:
+ host.domain username:password
+ host.domain username
+
+The SASL password file is opened before the SMTP server enters the
+optional chroot jail, so there is no need to copy the sasl_passwd
+file.
diff --git a/postfix/bounce/.indent.pro b/postfix/bounce/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/bounce/.indent.pro
+++ b/postfix/bounce/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/bounce/Makefile.in b/postfix/bounce/Makefile.in
index 44d5b7ed2..1298eee45 100644
--- a/postfix/bounce/Makefile.in
+++ b/postfix/bounce/Makefile.in
@@ -53,7 +53,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
bounce.o: bounce.c
diff --git a/postfix/cleanup/.indent.pro b/postfix/cleanup/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/cleanup/.indent.pro
+++ b/postfix/cleanup/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/cleanup/Makefile.in b/postfix/cleanup/Makefile.in
index 073c93006..8b1da52c8 100644
--- a/postfix/cleanup/Makefile.in
+++ b/postfix/cleanup/Makefile.in
@@ -57,7 +57,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
cleanup.o: cleanup.c
diff --git a/postfix/cleanup/cleanup_message.c b/postfix/cleanup/cleanup_message.c
index c9a48f11c..2c6276357 100644
--- a/postfix/cleanup/cleanup_message.c
+++ b/postfix/cleanup/cleanup_message.c
@@ -375,6 +375,22 @@ static void cleanup_missing_headers(CLEANUP_STATE *state)
state->resent, vstring_str(state->temp1));
}
}
+#ifdef USE_AUTH
+ /*
+ * Add client and sender identity headers if configured
+ */
+ if (cleanup_auth_client_identity && *var_cleanup_auth_client_header) {
+ cleanup_out_format(REC_TYPE_NORM, "%s %s@%s",
+ var_cleanup_auth_client_header,
+ cleanup_auth_client_identity,
+ var_cleanup_auth_client_header_domain);
+ }
+ if (cleanup_auth_sender_identity && *var_cleanup_auth_sender_header) {
+ cleanup_out_format(REC_TYPE_NORM, "%s %s",
+ var_cleanup_auth_sender_header,
+ cleanup_auth_sender_identity);
+ }
+#endif
}
/* cleanup_message - initialize message content segment */
diff --git a/postfix/conf/sample-auth.cf b/postfix/conf/sample-auth.cf
new file mode 100644
index 000000000..412fc8134
--- /dev/null
+++ b/postfix/conf/sample-auth.cf
@@ -0,0 +1,72 @@
+# This file contains example settings of Postfix configuration
+# parameters that control SMTP authentication
+
+# The given example parameters are the default
+
+# smtpd options: incoming connections
+
+# The smtpd_auth_enable parameter controls whether authentication is
+# activated for Postfix as a server
+smtpd_auth_enable = yes
+
+# The smtpd_auth_require parameter controls whether authentication is
+# necessary for Postfix as a server
+# If it is set to 'no', the 'anonymous' mechanism is activated for all
+# clients, otherwise it is not offered, except for local clients if
+# smtpd_auth_mynetworks_anonymous is true.
+smtpd_auth_require = yes
+
+# TODO:
+# The smtpd_auth_mechanisms parameter controls which SASL mechanisms
+# are offered by the server
+# The default "" means that all available mechanisms are offered
+smtpd_auth_mechanisms = ""
+
+# TODO:
+# The smtpd_auth_mechanisms_weak parameter controls which SASL
+# mechanisms are considered too weak for specific purposes. This may
+# be used in the access checking rules.
+# The default "" means that all authentications are considered strong
+# enough.
+smtpd_auth_mechanisms_weak = ""
+
+
+# The smtpd_auth_mynetworks_anonymous controls whether the local nets
+# are allowed to authenticate anonymously and still be considered as
+# authenticated in the smtpd_check verifications. This has an
+# influence only if auth_required is set to "yes"
+smtpd_auth_mynetworks_anonymous = no
+
+# smtp options: outgoing connections
+
+# The smtp_auth_enable parameter controls whether authentication is
+# activated for Postfix as a client
+smtp_auth_enable=yes
+
+# The smtp_auth_anonymous parameter controls whether the client tries
+# to authenticate as anonymous if authentication with a password
+# failed (i.e. the client tries to authenticate a second time, with the
+# `anonymous' mechanism)
+smtp_auth_anonymous = yes
+
+# The smtp_auth_passwd_map parameter specifies the name of the map that
+# contains usernames and passwords for postfix to authenticate as a
+# client
+# The mapping is hostname -> username:password
+# where hostname is the name of the host requesting authentication
+smtp_auth_passwd_map = ""
+
+# The cleanup_auth_client_header is inserted after the received headers to
+# identify the relay. The default "" prevents the insertion of a header.
+cleanup_auth_client_header = ""
+
+# The cleanup_auth_client_header_domain can be used to append a domain
+# name to the auth_client_header, to identity the domain where the client
+# identity is valid. Default is $mydomain.
+cleanup_auth_client_header_domain = $mydomain
+
+
+# The cleanup_auth_sender_header is inserted after the received headers to
+# identify the sender. The default "" prevents the insertion of a header.
+cleanup_auth_sender_header = ""
+
diff --git a/postfix/conf/sample-tls.cf b/postfix/conf/sample-tls.cf
new file mode 100644
index 000000000..97444df4f
--- /dev/null
+++ b/postfix/conf/sample-tls.cf
@@ -0,0 +1,277 @@
+# This file contains example settings of Postfix configuration
+# parameters that control the behaviour of the TLS extensions.
+#
+# We strictly seperate between server side TLS (smtpd_) and client side
+# TLS (smtp_), as for practical reasons we might choose differently.
+
+# Section with SMTPD specific settings
+
+# To use TLS we do need a certificate and a private key. Both must be in
+# "pem" format, the private key must not be encrypted, that does mean:
+# it must be accessable without password. Both parts (certificate and
+# private key) may be in the same file.
+#
+# smtpd_tls_cert_file = /etc/postfix/server.pem
+# smtpd_tls_key_file = $tls_cert_file
+
+# The certificate was issued by a certification authority (CA), of which
+# the CA-cert must be available. This file may also contain the the
+# CA certificates of other trusted CAs. You must use this file for the
+# list of trusted CAs if you want to use chroot-mode.
+#
+# smtpd_tls_CAfile = /etc/postfix/CAcert.pem
+
+# To verify the peer certificate, we need to know the certificates of
+# certification authorities. These certificates in "pem" format are
+# collected in a directory. The same CAs are offered to clients for
+# client verification. Don't forget to create the necessary "hash"
+# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
+# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
+# no default and you explicitly have to set the value here!
+# This will not work in chroot mode, use the tls_CAfile instead.
+#
+smtpd_tls_CApath = /etc/postfix/certs
+
+# To get additional information during the TLS setup and negotiations
+# you can increase the loglevel from 0..4:
+# 0: No output about the TLS subsystem
+# 1: Printout startup and certificate information
+# 2: 1 + Printout of levels during negotiation
+# 3: 2 + Hex and ASCII dump of negotiation process
+# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
+# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
+# discouraged.
+#
+# smtpd_tls_loglevel = 0
+
+# To include information about the protocol and cipher used as well as the
+# client and issuer CommonName into the "Received:" header, set the
+# smtpd_tls_received_header variable to true. The default is no, as the
+# information is not necessarily authentic. Only the final destination
+# is reliable, since the headers might have been changed in between.
+#
+#smtpd_tls_received_header = true
+
+# By default TLS is disabled, so no difference to plain postfix is visible.
+# Explicitely switch it on here:
+#
+smtpd_use_tls = yes
+
+# You can ENFORCE the use of TLS, so that no commands (except QUIT of course)
+# are allowed without TLS. According to RFC2487 this MUST NOT be applied
+# in case of a publicly-referenced SMTP server. So this option is off
+# by default and should only seldom be used. Using this option implies
+# smtpd_use_tls = yes
+#
+# smtpd_enforce_tls = no
+
+# To receive a client certificate, the server must explicitly ask for one.
+# Hence netscape will either complain if no certificate is available (for
+# the list of CAs in /etc/postfix/certs) or will offer you client certificates
+# to choose from. This might be annoying, so this option is "off" by default.
+# You will however need the certificate if you want to to e.g. certificate
+# based relaying.
+#
+# smtpd_tls_ask_ccert = no
+
+# You may also decide to REQUIRE a client certificate to allow TLS connections.
+# I don't think it will be necessary often, it is however included here for
+# completeness. This option implies smtpd_tls_ask_ccert = yes
+#
+# smtpd_tls_req_ccert = no
+
+# The verification depth for client certificates. The default (1) is
+# sufficient, if the client certificate ist directly issued by a CA
+# listed under $tls_CApath
+#
+# smtpd_tls_ccert_vd = 1
+
+# One additional option has been added for relay control to the UCE rules:
+# check_relay_ccerts. If this option is added to smtpd_recipient_restrictions
+# postfix will relay if a valid client certificate is presented and in the
+# list of client certs (relay_clientcerts).
+#
+# smtpd_recipient_restrictions = check_relay_ccerts
+
+# The list of client certificates for which relaying will be allowed.
+# Unfortunately the routines for lists in postfix use whitespaces as
+# seperators and choke on special chars. So using the certificate
+# X509ONELINES is quite impractical. We will use the fingerprints at
+# this point, as they are difficult to fake but easy to use for lookup.
+# There is just one small problem: The colon ':' is interpreted as
+# seperator between database type and filename, so we must avoid it.
+# We use the underscore "_" instead.
+# As postmap (when using e.g. db) insists of having a pair of key and value,
+# but we only need the key, the value can be chosen freely, e.g. the name
+# of the user or host:
+# D7_04_2F_A7_0B_8C_A5_21_FA_31_77_E1_41_8A_EE_80 lutzpc.at.home
+#
+# relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+
+# Section with SMTP specific settings
+
+# During the startup negotiation we might present a certificate to the server.
+# Netscape is rather clever here and lets the user select between only those
+# certs that will match the CAs accepted from the server. As I simply use
+# the integrated "SSL_connect()" from the OpenSSL package, this is not
+# possible by now and we have to chose just one cert.
+# So for now the default is to use _no_ cert and key unless explictly
+# set here. It is possible to use the same key/cert pair as for the server.
+# If a cert is to be presented, it must be in "pem" format, the private key
+# must not be encrypted, that does mean: it must be accessable without
+# password. Both parts (certificate and # private key) may be in the
+# same file.
+#
+smtp_tls_cert_file = /etc/postfix/server.pem
+smtp_tls_key_file = $tls_cert_file
+
+# The certificate was issued by a certification authority (CA), of which
+# the CA-cert must be available. This file may also contain the the
+# CA certificates of other trusted CAs. You must use this file for the
+# list of trusted CAs if you want to use chroot-mode.
+# No default is supplied for this value as of now.
+#
+smtp_tls_CAfile = /etc/postfix/CAcert.pem
+
+# To verify the peer certificate, we need to know the certificates of
+# certification authorities. These certificates in "pem" format are
+# collected in a directory. Don't forget to create the necessary "hash"
+# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical
+# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is
+# no default and you explicitly have to set the value here!
+# This will not work in chroot mode, use the tls_CAfile instead.
+#
+smtp_tls_CApath = /etc/postfix/certs
+
+# To get additional information during the TLS setup and negotiations
+# you can increase the loglevel from 0..4:
+# 0: No output about the TLS subsystem
+# 1: Printout startup and certificate information
+# 2: 1 + Printout of levels during negotiation
+# 3: 2 + Hex and ASCII dump of negotiation process
+# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS
+# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly
+# discouraged.
+#
+smtp_tls_loglevel = 0
+
+# By default TLS is disabled, so no difference to plain postfix is visible.
+# If you enable TLS it will be used when offered by the server.
+# WARNING: I didn't have access to other software (except those explicitely
+# listed) to test the interaction. On corresponding mailing list
+# there was a discussion going on about MS exchange servers offering
+# STARTTLS even if it is not configured, so it might be wise to not
+# use this option on your central mail hub, as you don't know in advance
+# whether you are going to hit such host. Use the recipient/site specific
+# options instead.
+#
+# In case of failure, a "4xx" code is issued and the mail stays in the queue.
+#
+# Explicitely switch it on here, if you really wish it:
+#
+smtp_use_tls = yes
+
+# As generally trying TLS can be a bad idea (some hosts offer STARTTLS but
+# the negotiation will fail leading to unexplainable failures, it is a better
+# idea to decide based on the recipient or the mailhub to which you are
+# connecting.
+#
+# Recipient: The host/domain part of the recipients email address:
+# for "joe@dom.ain" the "dom.ain" is used for the 'recipient' matching.
+#
+# To try to use TLS whenever email is sent to somebody matching the recipient
+# domain "dom.ain", add it to the "use_tls_recipients" list. The STARTTLS
+# option is recognized and used regardless of the MX to which the smtp client
+# does connect.
+#
+smtp_use_tls_recipients = dom.ain, hash:/etc/postfix/use_tls_recipients
+#
+# Site: The name of the host the email is actually delivered to.
+#
+# To try to use TLS whenever a certain MX is used to deliver an email,
+# add it to the "use_tls_sites" list:
+#
+smtp_use_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/use_tls_sites
+#
+# The matching is done as a domain match, such that "some.where.else" will
+# match all hosts in the domain "some.where.else", e.g.
+# mailhost.some.where.else. For this reason, this option is named .._sites
+# and not .._hosts.
+#
+# These options will only use STARTTLS if it is offered. If it is not offered,
+# the mail will be delivered without encryption or authentication!! See also
+# the "enforce" options below.
+
+# You can ENFORCE the use of TLS, so that only connections with TLS will
+# be accepted. Additionally, the hostname of the receiving host is matched
+# against the CommonName in the certificate. Also, the certificate must
+# be verified "Ok", so that a CA trusted by the client must have issued
+# the certificate. If the certificate doesn't verify or the hostname doesn't
+# match, a "4xx" # will be issued and the mail stays in the queue.
+# The hostname used in the check is beyond question, as it must be the
+# principle hostname (no CNAME allowed here).
+#
+# This option is useful only if you are definitely sure that you will only
+# connect to servers supporting RFC2487 _and_ with valid certificates.
+# I use it for my clients which will only send email to one mailhub, which
+# does offer the necessary STARTTLS support.
+#
+# smtp_enforce_tls = no
+
+# For a per_site or per_recipient decision, use the corresponding lists.
+#
+# Recipient: The host/domain part of the recipients email address:
+# for "joe@dom.ain" the "dom.ain" is used for the 'recipient' matching.
+#
+# To enforce the use of TLS whenever email is sent to somebody matching the
+# recipient domain "dom.ain", add it to the "enforce_tls_recipients" list.
+# This way the email is only sent with encryption and authentication,
+# regardless of the MX to which the smtp client does connect. This way you
+# can assure that your email really is delivered to the correct MX; the
+# correctness of the MX nameserver record cannot be checked from postfix,
+# however.
+# Please note, that the authentication process requires that you recognize
+# the CA that issued the server certificate!
+#
+smtp_enforce_tls_recipients = dom.ain, hash:/etc/postfix/enforce_tls_recipients
+#
+# Site: The name of the host the email is actually delivered to.
+#
+# To enforce the use of TLS whenever a certain MX is used to deliver an email,
+# add it to the "enforce_tls_sites" list:
+#
+smtp_enforce_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/enforce_tls_sites
+#
+# The matching is done as a domain match, such that "some.where.else" will
+# match all hosts in the domain "some.where.else", e.g.
+# mailhost.some.where.else. For this reason, this option is named .._sites
+# and not .._hosts.
+
+# In case the client use of TLS is explicitely turned on, a list of
+# sites/hosts can be given for which no STARTTLS negotiation will be
+# started, e.g. because it is already known that it might fail for some
+# reason. It makes no sense for recipients, only receiving mail servers,
+# so only the "smtp_no_tls_sites" is offered, but not an equivalent
+# ".._recipients" option.
+#
+# HINT: This list is only checked when TLS usage is generally turned on
+# (usage or enforcement). If the recieving host/recipient is listed by the
+# specific "use/enforce_tls_sites/recipients" options, this setting has
+# precedence in any case and STARTTLS will be negotiated. No warning is given.
+#
+smtp_no_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/no_tls_sites
+
+# The verification depth for certificates. The default (1) is sufficient,
+# if the certificate ist directly issued by a CA listed under $tls_CApath
+#
+# smtp_tls_ccert_vd = 1
+
+# As we decide on a "per site" basis, wether to use TLS or not, it would be
+# good to have a list of sites, that offered "STARTTLS'. We can collect it
+# ourselves with this option.
+#
+# If activated and TLS is not already enabled for this host, a line is added
+# to the logfile:
+# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
+#
+smtp_tls_note_starttls_offer = yes
diff --git a/postfix/dns/.indent.pro b/postfix/dns/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/dns/.indent.pro
+++ b/postfix/dns/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/dns/Makefile.in b/postfix/dns/Makefile.in
index be767bef2..245fc77ee 100644
--- a/postfix/dns/Makefile.in
+++ b/postfix/dns/Makefile.in
@@ -65,7 +65,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
dns_lookup.o: dns_lookup.c
diff --git a/postfix/error/.indent.pro b/postfix/error/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/error/.indent.pro
+++ b/postfix/error/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/error/Makefile.in b/postfix/error/Makefile.in
index 5e0542b9c..7d43663d0 100644
--- a/postfix/error/Makefile.in
+++ b/postfix/error/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
error.o: error.c
diff --git a/postfix/fsstone/.indent.pro b/postfix/fsstone/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/fsstone/.indent.pro
+++ b/postfix/fsstone/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/fsstone/Makefile.in b/postfix/fsstone/Makefile.in
index 92dbdc3f6..a463020f8 100644
--- a/postfix/fsstone/Makefile.in
+++ b/postfix/fsstone/Makefile.in
@@ -51,7 +51,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
fsstone.o: fsstone.c
diff --git a/postfix/global/.indent.pro b/postfix/global/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/global/.indent.pro
+++ b/postfix/global/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/global/Makefile.in b/postfix/global/Makefile.in
index 1eefc0ee1..0b207fe35 100644
--- a/postfix/global/Makefile.in
+++ b/postfix/global/Makefile.in
@@ -217,7 +217,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
been_here.o: been_here.c
diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h
index e81bb0a62..aaf7468c0 100644
--- a/postfix/global/mail_params.h
+++ b/postfix/global/mail_params.h
@@ -631,6 +631,27 @@ extern int var_smtpd_hard_erlim;
#define DEF_SMTPD_ERR_SLEEP 5
extern int var_smtpd_err_sleep;
+ /*
+ * SASL authentication support.
+ */
+#ifdef USE_SASL_AUTH
+
+#define VAR_SMTPD_SASL_ENABLE "smtpd_sasl_auth_enable"
+#define DEF_SMTPD_SASL_ENABLE 0
+extern bool var_smtpd_sasl_enable;
+
+#define VAR_SMTP_SASL_ENABLE "smtp_sasl_auth_enable"
+#define DEF_SMTP_SASL_ENABLE 0
+extern bool var_smtp_sasl_enable;
+
+#define VAR_SMTP_SASL_PWD_MAPS "smtp_sasl_password_maps"
+#define DEF_SMTP_SASL_PWD_MAPS ""
+extern char *var_smtp_sasl_pwd_maps;
+
+#define PERMIT_SASL_AUTH "permit_sasl_authenticated"
+
+#endif
+
/*
* Cleanup service. Header info that exceeds $header_size_limit bytes forces
* the start of the message body.
diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h
index 7b9ffd13b..60a9586e9 100644
--- a/postfix/global/mail_version.h
+++ b/postfix/global/mail_version.h
@@ -15,7 +15,7 @@
* Version of this program.
*/
#define VAR_MAIL_VERSION "mail_version"
-#define DEF_MAIL_VERSION "Snapshot-20000309"
+#define DEF_MAIL_VERSION "Snapshot-20000316"
extern char *var_mail_version;
/* LICENSE
diff --git a/postfix/html/faq.html b/postfix/html/faq.html
index 8e582d89c..bff21f6ff 100644
--- a/postfix/html/faq.html
+++ b/postfix/html/faq.html
@@ -2311,12 +2311,51 @@ include directory and of the object library.
-One problem: older DB versions install a file
+When building with a third-party DB library you may into one of the
+following problems:
+
+
+
+
+
+- Older DB versions install a file
/usr/local/include/ndbm.h that is incompatible with
/usr/include/ndbm.h. Be sure to get rid of the bogus file.
See the FAQ entry titled "Undefined symbols:
dbm_pagfno, dbm_dirfno etc".
+
+
+
- With Sleepcat DB 3.0.55, the linker will complain that dbopen()
+is not found. To fix, apply the following patch to the DB 3.0.55
+db_185.h include file:
+
+
+
+*** db_185.h.orig Tue Mar 7 16:27:32 2000
+--- db_185.h Tue Mar 7 16:27:44 2000
+***************
+*** 166,173 ****
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+- #ifdef DB_LIBRARY_COMPATIBILITY_API
+ #define dbopen __db185_open
+ DB *__db185_open __P((const char *, int, int, DBTYPE, const void *));
+ #else
+ DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
+--- 166,173 ----
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+ #define dbopen __db185_open
++ #ifdef DB_LIBRARY_COMPATIBILITY_API
+ DB *__db185_open __P((const char *, int, int, DBTYPE, const void *));
+ #else
+ DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
+
+
+
Up one level | Postfix FAQ
diff --git a/postfix/local/.indent.pro b/postfix/local/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/local/.indent.pro
+++ b/postfix/local/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/local/Makefile.in b/postfix/local/Makefile.in
index e1c8d8b64..f367ef9c1 100644
--- a/postfix/local/Makefile.in
+++ b/postfix/local/Makefile.in
@@ -57,7 +57,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
alias.o: alias.c
diff --git a/postfix/makedefs b/postfix/makedefs
index c92a1b216..68bd3d8ac 100644
--- a/postfix/makedefs
+++ b/postfix/makedefs
@@ -143,7 +143,7 @@ case "$SYSTEM.$RELEASE" in
4) SYSTYPE=AIX4
# How embarrassing...
case "$CC" in
- cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w";;
+ cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w -blibpath:/usr/lib:/lib:/usr/local/lib";;
esac
CCARGS="$CCARGS -D_ALL_SOURCE"
;;
@@ -258,4 +258,5 @@ CC = $CC $CCARGS
OPT = $OPT
DEBUG = $DEBUG
AWK = $AWK
+EXPORT = AUXLIBS="$AUXLIBS" CCARGS="$CCARGS" OPT="$OPT" DEBUG="$DEBUG"
EOF
diff --git a/postfix/master/.indent.pro b/postfix/master/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/master/.indent.pro
+++ b/postfix/master/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/master/Makefile.in b/postfix/master/Makefile.in
index a499576de..31a0e36c4 100644
--- a/postfix/master/Makefile.in
+++ b/postfix/master/Makefile.in
@@ -75,7 +75,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
master.o: master.c
diff --git a/postfix/pickup/.indent.pro b/postfix/pickup/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/pickup/.indent.pro
+++ b/postfix/pickup/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/pickup/Makefile.in b/postfix/pickup/Makefile.in
index d3b0f35d9..1f20f1934 100644
--- a/postfix/pickup/Makefile.in
+++ b/postfix/pickup/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
pickup.o: pickup.c
diff --git a/postfix/pipe/.indent.pro b/postfix/pipe/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/pipe/.indent.pro
+++ b/postfix/pipe/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/pipe/Makefile.in b/postfix/pipe/Makefile.in
index aebfd7435..f6879fa0a 100644
--- a/postfix/pipe/Makefile.in
+++ b/postfix/pipe/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
pipe.o: pipe.c
diff --git a/postfix/postalias/.indent.pro b/postfix/postalias/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postalias/.indent.pro
+++ b/postfix/postalias/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postalias/Makefile.in b/postfix/postalias/Makefile.in
index 1304d7844..1ffd12352 100644
--- a/postfix/postalias/Makefile.in
+++ b/postfix/postalias/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postalias.o: postalias.c
diff --git a/postfix/postcat/.indent.pro b/postfix/postcat/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postcat/.indent.pro
+++ b/postfix/postcat/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postcat/Makefile.in b/postfix/postcat/Makefile.in
index 68175a8ba..09a495884 100644
--- a/postfix/postcat/Makefile.in
+++ b/postfix/postcat/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postcat.o: postcat.c
diff --git a/postfix/postconf/.indent.pro b/postfix/postconf/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postconf/.indent.pro
+++ b/postfix/postconf/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postconf/Makefile.in b/postfix/postconf/Makefile.in
index a0b8cd1a3..47aab60d0 100644
--- a/postfix/postconf/Makefile.in
+++ b/postfix/postconf/Makefile.in
@@ -61,7 +61,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postconf.o: postconf.c
diff --git a/postfix/postconf/extract.awk b/postfix/postconf/extract.awk
index 8cd8cfc09..ebe866e29 100644
--- a/postfix/postconf/extract.awk
+++ b/postfix/postconf/extract.awk
@@ -1,18 +1,18 @@
# Extract initialization tables from actual source code.
-/^(static| )*CONFIG_INT_TABLE .*{/,/};/ {
+/^(static| )*CONFIG_INT_TABLE .*\{/,/\};/ {
if ($1 ~ /VAR/) {
print "int " substr($3,2,length($3)-2) ";" > "int_vars.h"
print | "sed 's/[ ][ ]*/ /g' | sort -u >int_table.h"
}
}
-/^(static| )*CONFIG_STR_TABLE .*{/,/};/ {
+/^(static| )*CONFIG_STR_TABLE .*\{/,/\};/ {
if ($1 ~ /VAR/) {
print "char *" substr($3,2,length($3)-2) ";" > "str_vars.h"
print | "sed 's/[ ][ ]*/ /g' | sort -u >str_table.h"
}
}
-/^(static| )*CONFIG_BOOL_TABLE .*{/,/};/ {
+/^(static| )*CONFIG_BOOL_TABLE .*\{/,/\};/ {
if ($1 ~ /VAR/) {
print "int " substr($3,2,length($3)-2) ";" > "bool_vars.h"
print | "sed 's/[ ][ ]*/ /g' | sort -u >bool_table.h"
diff --git a/postfix/postdrop/.indent.pro b/postfix/postdrop/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postdrop/.indent.pro
+++ b/postfix/postdrop/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postdrop/Makefile.in b/postfix/postdrop/Makefile.in
index cb8ed7547..8f24b00c0 100644
--- a/postfix/postdrop/Makefile.in
+++ b/postfix/postdrop/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postdrop.o: postdrop.c
diff --git a/postfix/postfix/.indent.pro b/postfix/postfix/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postfix/.indent.pro
+++ b/postfix/postfix/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postfix/Makefile.in b/postfix/postfix/Makefile.in
index d807c878b..b1f63de7c 100644
--- a/postfix/postfix/Makefile.in
+++ b/postfix/postfix/Makefile.in
@@ -54,7 +54,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postfix.o: postfix.c
diff --git a/postfix/postkick/.indent.pro b/postfix/postkick/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postkick/.indent.pro
+++ b/postfix/postkick/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postkick/Makefile.in b/postfix/postkick/Makefile.in
index 9a0fd6b02..c846ca697 100644
--- a/postfix/postkick/Makefile.in
+++ b/postfix/postkick/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postkick.o: postkick.c
diff --git a/postfix/postlock/.indent.pro b/postfix/postlock/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postlock/.indent.pro
+++ b/postfix/postlock/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postlock/Makefile.in b/postfix/postlock/Makefile.in
index c2ee45d3c..0d194091b 100644
--- a/postfix/postlock/Makefile.in
+++ b/postfix/postlock/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postlock.o: postlock.c
diff --git a/postfix/postlog/.indent.pro b/postfix/postlog/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postlog/.indent.pro
+++ b/postfix/postlog/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postlog/Makefile.in b/postfix/postlog/Makefile.in
index fbfad473f..e3f00e469 100644
--- a/postfix/postlog/Makefile.in
+++ b/postfix/postlog/Makefile.in
@@ -54,7 +54,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postlog.o: postlog.c
diff --git a/postfix/postmap/.indent.pro b/postfix/postmap/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postmap/.indent.pro
+++ b/postfix/postmap/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postmap/Makefile.in b/postfix/postmap/Makefile.in
index 5cd483acd..db3a6bd5f 100644
--- a/postfix/postmap/Makefile.in
+++ b/postfix/postmap/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postmap.o: postmap.c
diff --git a/postfix/postsuper/.indent.pro b/postfix/postsuper/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/postsuper/.indent.pro
+++ b/postfix/postsuper/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/postsuper/Makefile.in b/postfix/postsuper/Makefile.in
index 1b58244f9..b5caf22cb 100644
--- a/postfix/postsuper/Makefile.in
+++ b/postfix/postsuper/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
postsuper.o: postsuper.c
diff --git a/postfix/qmgr/.indent.pro b/postfix/qmgr/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/qmgr/.indent.pro
+++ b/postfix/qmgr/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/qmgr/Makefile.in b/postfix/qmgr/Makefile.in
index 144e089f9..99ce9e6ef 100644
--- a/postfix/qmgr/Makefile.in
+++ b/postfix/qmgr/Makefile.in
@@ -55,7 +55,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
qmgr.o: qmgr.c
diff --git a/postfix/sendmail/.indent.pro b/postfix/sendmail/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/sendmail/.indent.pro
+++ b/postfix/sendmail/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/sendmail/Makefile.in b/postfix/sendmail/Makefile.in
index 9a71d3422..da946438b 100644
--- a/postfix/sendmail/Makefile.in
+++ b/postfix/sendmail/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
sendmail.o: sendmail.c
diff --git a/postfix/sendmail/sendmail.c b/postfix/sendmail/sendmail.c
index 90e27bcf1..311350544 100644
--- a/postfix/sendmail/sendmail.c
+++ b/postfix/sendmail/sendmail.c
@@ -18,6 +18,7 @@
/* Sendmail command-line options are recognized but silently ignored.
/*
/* By default, \fBsendmail\fR reads a message from standard input
+/* until EOF or until it reads a line with only a \fB.\fR character,
/* and arranges for delivery. \fBsendmail\fR attempts to create
/* a queue file in the \fBmaildrop\fR directory. If that directory
/* is not world-writable, the message is piped through the
@@ -95,8 +96,9 @@
/* .IP "\fB-h \fIhop_count\fR (ignored)"
/* Hop count limit. Use the \fBhopcount_limit\fR configuration
/* parameter instead.
-/* .IP "\fB-i\fR (ignored)"
-/* Lines beginning with "." get special treatment only with \fB-bs\fR.
+/* .IP "\fB-i\fR"
+/* When reading a message from standard input, don\'t treat a line
+/* with only a \fB.\fR character as the end of input.
/* .IP "\fB-m\fR (ignored)"
/* Backwards compatibility.
/* .IP "\fB-n\fR (ignored)"
@@ -109,6 +111,9 @@
/* .IP "\fB-o8\fR (ignored)"
/* The message body type. Currently, Postfix implements
/* \fBjust-send-eight\fR.
+/* .IP "\fB-oi\fR"
+/* When reading a message from standard input, don\'t treat a line
+/* with only a \fB.\fR character as the end of input.
/* .IP "\fB-om\fR (ignored)"
/* The sender is never eliminated from alias etc. expansions.
/* .IP "\fB-o \fIx value\fR (ignored)"
@@ -285,6 +290,13 @@
static char *sendmail_path;
static void sendmail_cleanup(void);
+ /*
+ * Flag parade.
+ */
+#define SM_FLAG_AEOF (1<<0) /* archaic EOF */
+
+#define SM_FLAG_DEFAULT (SM_FLAG_AEOF)
+
/*
* Silly little macros (SLMs).
*/
@@ -292,7 +304,8 @@ static void sendmail_cleanup(void);
/* enqueue - post one message */
-static void enqueue(const char *sender, const char *full_name, char **recipients)
+static void enqueue(const int flags, const char *sender, const char *full_name,
+ char **recipients)
{
VSTRING *buf;
VSTREAM *dst;
@@ -425,6 +438,8 @@ static void enqueue(const char *sender, const char *full_name, char **recipients
if (strip_cr == STRIP_CR_DO && type == REC_TYPE_NORM)
if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
vstring_truncate(buf, VSTRING_LEN(buf) - 1);
+ if ((flags & SM_FLAG_AEOF) && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
+ break;
if (REC_PUT_BUF(dst, type, buf) < 0)
msg_fatal("%s(%d): error writing queue file: %m", saved_sender, uid);
}
@@ -572,6 +587,7 @@ int main(int argc, char **argv)
int debug_me = 0;
int err;
int n;
+ int flags = SM_FLAG_DEFAULT;
/*
* Be consistent with file permissions.
@@ -588,6 +604,14 @@ int main(int argc, char **argv)
&& (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
msg_fatal("open /dev/null: %m");
+ /*
+ * The CDE desktop calendar manager leaks a parent file descriptor into
+ * the child process. For the sake of sendmail compatibility we have to
+ * close the file descriptor otherwise mail notification will hang.
+ */
+ for ( /* void */ ; fd < 100; fd++)
+ (void) close(fd);
+
/*
* Process environment options as early as we can. We might be called
* from a set-uid (set-gid) program, so be careful with importing
@@ -720,6 +744,9 @@ int main(int argc, char **argv)
case 'f':
sender = optarg;
break;
+ case 'i':
+ flags &= ~SM_FLAG_AEOF;
+ break;
case 'o':
switch (*optarg) {
default:
@@ -735,6 +762,10 @@ int main(int argc, char **argv)
break;
case '7':
case '8':
+ break;
+ case 'i':
+ flags &= ~SM_FLAG_AEOF;
+ break;
case 'm':
break;
}
@@ -780,7 +811,7 @@ int main(int argc, char **argv)
msg_panic("unknown operation mode: %d", mode);
/* NOTREACHED */
case SM_MODE_ENQUEUE:
- enqueue(sender, full_name, argv + OPTIND);
+ enqueue(flags, sender, full_name, argv + OPTIND);
exit(0);
break;
case SM_MODE_MAILQ:
diff --git a/postfix/showq/.indent.pro b/postfix/showq/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/showq/.indent.pro
+++ b/postfix/showq/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/showq/Makefile.in b/postfix/showq/Makefile.in
index 55a1e0879..ec75f8c9b 100644
--- a/postfix/showq/Makefile.in
+++ b/postfix/showq/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
showq.o: showq.c
diff --git a/postfix/smtp/.indent.pro b/postfix/smtp/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/smtp/.indent.pro
+++ b/postfix/smtp/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/smtp/Makefile.in b/postfix/smtp/Makefile.in
index c7163fdf4..4db9cb944 100644
--- a/postfix/smtp/Makefile.in
+++ b/postfix/smtp/Makefile.in
@@ -1,9 +1,11 @@
SHELL = /bin/sh
SRCS = smtp.c quote_821_local.c smtp_connect.c smtp_proto.c smtp_chat.c \
- smtp_session.c smtp_addr.c smtp_trouble.c smtp_unalias.c smtp_state.c
+ smtp_session.c smtp_addr.c smtp_trouble.c smtp_unalias.c smtp_state.c \
+ smtp_sasl_proto.c smtp_sasl_glue.c
OBJS = smtp.o quote_821_local.o smtp_connect.o smtp_proto.o smtp_chat.o \
- smtp_session.o smtp_addr.o smtp_trouble.o smtp_unalias.o smtp_state.o
-HDRS = smtp.h
+ smtp_session.o smtp_addr.o smtp_trouble.o smtp_unalias.o smtp_state.o \
+ smtp_sasl_proto.o smtp_sasl_glue.o
+HDRS = smtp.h smtp_sasl.h
TESTSRC =
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@@ -59,7 +61,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
quote_821_local.o: quote_821_local.c
@@ -88,6 +90,7 @@ smtp.o: ../include/mail_proto.h
smtp.o: ../include/iostuff.h
smtp.o: ../include/mail_server.h
smtp.o: smtp.h
+smtp.o: smtp_sasl.h
smtp_addr.o: smtp_addr.c
smtp_addr.o: ../include/sys_defs.h
smtp_addr.o: ../include/msg.h
@@ -167,6 +170,37 @@ smtp_proto.o: ../include/mark_corrupt.h
smtp_proto.o: smtp.h
smtp_proto.o: ../include/argv.h
smtp_proto.o: quote_821_local.h
+smtp_proto.o: smtp_sasl.h
+smtp_sasl_glue.o: smtp_sasl_glue.c
+smtp_sasl_glue.o: ../include/sys_defs.h
+smtp_sasl_glue.o: ../include/msg.h
+smtp_sasl_glue.o: ../include/mymalloc.h
+smtp_sasl_glue.o: ../include/stringops.h
+smtp_sasl_glue.o: ../include/split_at.h
+smtp_sasl_glue.o: ../include/mail_params.h
+smtp_sasl_glue.o: ../include/string_list.h
+smtp_sasl_glue.o: ../include/maps.h
+smtp_sasl_glue.o: ../include/dict.h
+smtp_sasl_glue.o: ../include/vstream.h
+smtp_sasl_glue.o: ../include/vbuf.h
+smtp_sasl_glue.o: ../include/argv.h
+smtp_sasl_glue.o: smtp.h
+smtp_sasl_glue.o: ../include/vstring.h
+smtp_sasl_glue.o: ../include/deliver_request.h
+smtp_sasl_glue.o: ../include/recipient_list.h
+smtp_sasl_glue.o: smtp_sasl.h
+smtp_sasl_proto.o: smtp_sasl_proto.c
+smtp_sasl_proto.o: ../include/sys_defs.h
+smtp_sasl_proto.o: ../include/msg.h
+smtp_sasl_proto.o: ../include/mymalloc.h
+smtp_sasl_proto.o: smtp.h
+smtp_sasl_proto.o: ../include/vstream.h
+smtp_sasl_proto.o: ../include/vbuf.h
+smtp_sasl_proto.o: ../include/vstring.h
+smtp_sasl_proto.o: ../include/argv.h
+smtp_sasl_proto.o: ../include/deliver_request.h
+smtp_sasl_proto.o: ../include/recipient_list.h
+smtp_sasl_proto.o: smtp_sasl.h
smtp_session.o: smtp_session.c
smtp_session.o: ../include/sys_defs.h
smtp_session.o: ../include/mymalloc.h
@@ -189,6 +223,7 @@ smtp_state.o: smtp.h
smtp_state.o: ../include/argv.h
smtp_state.o: ../include/deliver_request.h
smtp_state.o: ../include/recipient_list.h
+smtp_state.o: smtp_sasl.h
smtp_trouble.o: smtp_trouble.c
smtp_trouble.o: ../include/sys_defs.h
smtp_trouble.o: ../include/msg.h
diff --git a/postfix/smtp/smtp.c b/postfix/smtp/smtp.c
index 29dc70dab..95543bba3 100644
--- a/postfix/smtp/smtp.c
+++ b/postfix/smtp/smtp.c
@@ -185,6 +185,7 @@
/* Application-specific. */
#include "smtp.h"
+#include "smtp_sasl.h"
/*
* Tunable parameters. These have compiled-in defaults that can be overruled
@@ -211,6 +212,14 @@ char *var_bestmx_transp;
char *var_error_rcpt;
int var_smtp_always_ehlo;
+#ifdef USE_SASL_AUTH
+
+char *var_smtp_sasl_pwd_maps;
+bool var_smtp_sasl_enable;
+bool var_smtp_sasl_anon;
+
+#endif
+
/*
* Global variables. smtp_errno is set by the address lookup routines and by
* the connection management routines.
@@ -318,6 +327,11 @@ static void smtp_service(VSTREAM *client_stream, char *unused_service, char **ar
static void pre_init(char *unused_name, char **unused_argv)
{
debug_peer_init();
+
+#ifdef USE_SASL_AUTH
+ if (var_smtp_sasl_enable)
+ smtp_sasl_initialize();
+#endif
}
/* pre_accept - see if tables have changed */
@@ -340,6 +354,9 @@ int main(int argc, char **argv)
VAR_FALLBACK_RELAY, DEF_FALLBACK_RELAY, &var_fallback_relay, 0, 0,
VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
+#ifdef USE_SASL_AUTH
+ VAR_SMTP_SASL_PWD_MAPS, DEF_SMTP_SASL_PWD_MAPS, &var_smtp_sasl_pwd_maps, 0, 0,
+#endif
0,
};
static CONFIG_INT_TABLE int_table[] = {
@@ -360,6 +377,9 @@ int main(int argc, char **argv)
VAR_IGN_MX_LOOKUP_ERR, DEF_IGN_MX_LOOKUP_ERR, &var_ign_mx_lookup_err,
VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
+#ifdef USE_SASL_AUTH
+ VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+#endif
0,
};
diff --git a/postfix/smtp/smtp.h b/postfix/smtp/smtp.h
index e236d9a07..d73494871 100644
--- a/postfix/smtp/smtp.h
+++ b/postfix/smtp/smtp.h
@@ -8,6 +8,14 @@
/* DESCRIPTION
/* .nf
+ /*
+ * SASL library.
+ */
+#ifdef USE_SASL_AUTH
+#include
+#include
+#endif
+
/*
* Utility library.
*/
@@ -35,12 +43,23 @@ typedef struct SMTP_STATE {
int features; /* server features */
ARGV *history; /* transaction log */
int error_mask; /* error classes */
+#ifdef USE_SASL_AUTH
+ char *sasl_mechanism_list; /* server mechanism list */
+ char *sasl_username; /* client username */
+ char *sasl_passwd; /* client password */
+ sasl_conn_t *sasl_conn; /* SASL internal state */
+ VSTRING *sasl_encoded; /* encoding buffer */
+ VSTRING *sasl_decoded; /* decoding buffer */
+ sasl_callback_t *sasl_callbacks; /* stateful callbacks */
+#endif
} SMTP_STATE;
#define SMTP_FEATURE_ESMTP (1<<0)
#define SMTP_FEATURE_8BITMIME (1<<1)
#define SMTP_FEATURE_PIPELINING (1<<2)
#define SMTP_FEATURE_SIZE (1<<3)
+#define SMTP_FEATURE_STARTTLS (1<<4)
+#define SMTP_FEATURE_AUTH (1<<5)
/*
* smtp.c
diff --git a/postfix/smtp/smtp_proto.c b/postfix/smtp/smtp_proto.c
index 9be06bd45..8e0b7c8c2 100644
--- a/postfix/smtp/smtp_proto.c
+++ b/postfix/smtp/smtp_proto.c
@@ -103,6 +103,7 @@
#include "smtp.h"
#include "quote_821_local.h"
+#include "smtp_sasl.h"
/*
* Sender and receiver state. A session does not necessarily go through a
@@ -220,6 +221,10 @@ int smtp_helo(SMTP_STATE *state)
state->features |= SMTP_FEATURE_PIPELINING;
else if (strcasecmp(word, "SIZE") == 0)
state->features |= SMTP_FEATURE_SIZE;
+#ifdef USE_SASL_AUTH
+ else if (strcasecmp(word, "AUTH") == 0)
+ smtp_sasl_helo_auth(state, words);
+#endif
else if (strcasecmp(word, var_myhostname) == 0) {
msg_warn("host %s replied to HELO/EHLO with my own hostname %s",
session->namaddr, var_myhostname);
@@ -231,6 +236,12 @@ int smtp_helo(SMTP_STATE *state)
}
if (msg_verbose)
msg_info("server features: 0x%x", state->features);
+
+#ifdef USE_SASL_AUTH
+ if (state->features & SMTP_FEATURE_AUTH)
+ return (smtp_sasl_helo_login(state));
+#endif
+
return (0);
}
diff --git a/postfix/smtp/smtp_sasl.h b/postfix/smtp/smtp_sasl.h
new file mode 100644
index 000000000..1c6ec6f76
--- /dev/null
+++ b/postfix/smtp/smtp_sasl.h
@@ -0,0 +1,35 @@
+/*++
+/* NAME
+/* smtp_sasl 3h
+/* SUMMARY
+/* Postfix SASL interface for SMTP client
+/* SYNOPSIS
+/* #include "smtp_sasl.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * SASL protocol functions
+ */
+extern void smtp_sasl_initialize(void);
+extern void smtp_sasl_connect(SMTP_STATE *);
+extern void smtp_sasl_start(SMTP_STATE *);
+extern int smtp_sasl_authenticate(SMTP_STATE *, VSTRING *);
+extern void smtp_sasl_cleanup(SMTP_STATE *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
diff --git a/postfix/smtp/smtp_sasl_glue.c b/postfix/smtp/smtp_sasl_glue.c
new file mode 100644
index 000000000..5d87d1440
--- /dev/null
+++ b/postfix/smtp/smtp_sasl_glue.c
@@ -0,0 +1,461 @@
+/*++
+/* NAME
+/* smtp_sasl 3
+/* SUMMARY
+/* Postfix SASL interface for SMTP client
+/* SYNOPSIS
+/* #include smtp_sasl.h
+/*
+/* void smtp_sasl_initialize()
+/*
+/* void smtp_sasl_connect(state)
+/* SMTP_STATE *state;
+/*
+/* void smtp_sasl_start(state)
+/* SMTP_STATE *state;
+/*
+/* int smtp_sasl_authenticate(state, why)
+/* SMTP_STATE *state;
+/* VSTRING *why;
+/*
+/* void smtp_sasl_cleanup(state)
+/* SMTP_STATE *state;
+/* DESCRIPTION
+/* smtp_sasl_initialize() initializes the SASL library. This
+/* routine must be called once at process startup, before any
+/* chroot operations.
+/*
+/* smtp_sasl_connect() performs per-session initialization. This
+/* routine must be called once at the start of each connection.
+/*
+/* smtp_sasl_start() performs per-session initialization. This
+/* routine must be called once per session before doing any SASL
+/* authentication.
+/*
+/* smtp_sasl_authenticate() implements the SASL authentication
+/* dialog. The result is < 0 in case of protocol failure, zero in
+/* case of unsuccessful authentication, > 0 in case of success.
+/* The why argument is updated with a reason for failure.
+/*
+/* smtp_sasl_cleanup() cleans up. It must be called at the
+/* end of every SMTP session that uses SASL authentication.
+/* This routine is a noop for non-SASL sessions.
+/*
+/* Arguments:
+/* .IP state
+/* Session context.
+/* .IP mech_list
+/* String of SASL mechanisms (separated by blanks)
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Original author:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include
+#include
+#include
+#ifdef STRCASECMP_IN_STRINGS_H
+#include
+#endif
+
+ /*
+ * Utility library
+ */
+#include
+#include
+#include
+#include
+
+ /*
+ * Global library
+ */
+#include
+#include
+#include
+
+ /*
+ * Application-specific
+ */
+#include "smtp.h"
+#include "smtp_sasl.h"
+
+#ifdef USE_SASL_AUTH
+
+ /*
+ * Silly little macros.
+ */
+#define STR(x) vstring_str(x)
+
+ /*
+ * Per-host login/password information.
+ */
+static MAPS *smtp_sasl_passwd_map;
+
+/* smtp_sasl_log - logging call-back routine */
+
+static int smtp_sasl_log(void *unused_context, int priority,
+ const char *message)
+{
+ switch (priority) {
+ case SASL_LOG_ERR:
+ msg_fatal("%s", message);
+ break;
+ case SASL_LOG_WARNING:
+ msg_warn("%s", message);
+ break;
+ case SASL_LOG_INFO:
+ if (msg_verbose)
+ msg_info("%s", message);
+ break;
+ }
+ return (SASL_OK);
+}
+
+/* smtp_sasl_get_user - username lookup call-back routine */
+
+static int smtp_sasl_get_user(void *context, int unused_id, const char **result,
+ unsigned *len)
+{
+ SMTP_STATE *state = (SMTP_STATE *) context;
+
+ if (msg_verbose)
+ msg_info("smtp_sasl_get_user: %s", state->sasl_username);
+
+ *result = state->sasl_username;
+ if (len)
+ *len = strlen(state->sasl_username);
+ return (SASL_OK);
+}
+
+/* smtp_sasl_get_passwd - password lookup call-back routine */
+
+static int smtp_sasl_get_passwd(sasl_conn_t *conn, void *context,
+ int id, sasl_secret_t **psecret)
+{
+ SMTP_STATE *state = (SMTP_STATE *) context;
+ int len;
+
+ if (msg_verbose)
+ msg_info("smtp_sasl_get_passwd: %s", state->sasl_passwd);
+
+ /*
+ * Sanity check.
+ */
+ if (!conn || !psecret || id != SASL_CB_PASS)
+ return (SASL_BADPARAM);
+
+ /*
+ * Convert the password into a counted string.
+ */
+ len = strlen(state->sasl_passwd);
+ if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0)
+ return (SASL_NOMEM);
+ (*psecret)->len = len;
+ strcpy((*psecret)->data, state->sasl_passwd);
+
+ return (SASL_OK);
+}
+
+/* smtp_sasl_passwd_lookup - password lookup routine */
+
+static void smtp_sasl_passwd_lookup(SMTP_STATE *state)
+{
+ char *myname = "smtp_sasl_passwd_lookup";
+ const char *value;
+ char *passwd;
+
+ /*
+ * Sanity check.
+ */
+ if (smtp_sasl_passwd_map == 0)
+ msg_panic("%s: passwd map not initialized", myname);
+
+ /*
+ * Look up the per-server password information.
+ */
+
+ if ((value = maps_find(smtp_sasl_passwd_map, state->session->host, 0)) != 0) {
+ state->sasl_username = mystrdup(value);
+ passwd = split_at(state->sasl_username, ':');
+ state->sasl_passwd = mystrdup(passwd ? passwd : "");
+ } else {
+ state->sasl_username = mystrdup(var_myhostname);
+ state->sasl_passwd = mystrdup("");
+ }
+ if (msg_verbose)
+ msg_info("%s: host `%s' user `%s' pass `%s'",
+ myname, state->session->host,
+ state->sasl_username, state->sasl_passwd);
+}
+
+/* smtp_sasl_initialize - per-process initialization (pre jail) */
+
+void smtp_sasl_initialize(void)
+{
+
+ /*
+ * Global callbacks. These have no per-session context.
+ */
+ static sasl_callback_t callbacks[] = {
+ {SASL_CB_LOG, &smtp_sasl_log, 0},
+ {SASL_CB_LIST_END, 0, 0}
+ };
+
+ /*
+ * Sanity check.
+ */
+ if (smtp_sasl_passwd_map)
+ msg_panic("smtp_sasl_initialize: repeated call");
+ if (*var_smtp_sasl_pwd_maps == 0)
+ msg_fatal("specify password table via the `%s' configuration parameter",
+ VAR_SMTP_SASL_PWD_MAPS);
+
+ /*
+ * Open the per-host password table and initialize the SASL library. Use
+ * shared locks for reading, just in case someone updates the table.
+ */
+ smtp_sasl_passwd_map = maps_create("smtp_sasl_passwd",
+ var_smtp_sasl_pwd_maps, DICT_FLAG_LOCK);
+ if (sasl_client_init(callbacks) != SASL_OK)
+ msg_fatal("SASL library initialization");
+}
+
+/* smtp_sasl_connect - per-session client initialization */
+
+void smtp_sasl_connect(SMTP_STATE *state)
+{
+ state->sasl_mechanism_list = 0;
+ state->sasl_username = 0;
+ state->sasl_passwd = 0;
+ state->sasl_conn = 0;
+ state->sasl_encoded = 0;
+ state->sasl_decoded = 0;
+ state->sasl_callbacks = 0;
+}
+
+/* smtp_sasl_start - per-session SASL initialization */
+
+void smtp_sasl_start(SMTP_STATE *state)
+{
+ static sasl_callback_t callbacks[] = {
+ {SASL_CB_USER, &smtp_sasl_get_user, 0},
+ {SASL_CB_AUTHNAME, &smtp_sasl_get_user, 0},
+ {SASL_CB_PASS, &smtp_sasl_get_passwd, 0},
+ {SASL_CB_LIST_END, 0, 0}
+ };
+ sasl_callback_t *cp;
+ sasl_security_properties_t sec_props;
+
+ if (msg_verbose)
+ msg_info("starting new SASL client");
+
+ /*
+ * Per-session initialization. Provide each session with its own callback
+ * context.
+ */
+#define NULL_SECFLAGS 0
+
+ state->sasl_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks));
+ memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
+ for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
+ cp->context = (void *) state;
+ if (sasl_client_new("smtp", state->session->host, callbacks, NULL_SECFLAGS,
+ (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
+ msg_fatal("per-session SASL client initialization");
+ smtp_sasl_passwd_lookup(state);
+
+ /*
+ * Per-session security properties. XXX This routine is not sufficiently
+ * documented. What is the purpose of all this?
+ */
+ memset(&sec_props, 0L, sizeof(sec_props));
+ sec_props.min_ssf = 0;
+ sec_props.max_ssf = 1; /* don't allow real SASL
+ * security layer */
+ sec_props.security_flags = 0;
+ sec_props.maxbufsize = 0;
+ sec_props.property_names = 0;
+ sec_props.property_values = 0;
+ if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS,
+ &sec_props) != SASL_OK)
+ msg_fatal("set per-session SASL security properties");
+
+ /*
+ * We use long-lived conversion buffers rather than local variables in
+ * order to avoid memory leaks in case of read/write timeout or I/O
+ * error.
+ */
+ state->sasl_encoded = vstring_alloc(10);
+ state->sasl_decoded = vstring_alloc(10);
+}
+
+/* smtp_sasl_authenticate - run authentication protocol */
+
+int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why)
+{
+ char *myname = "smtp_sasl_authenticate";
+ unsigned enc_length;
+ unsigned enc_length_out;
+ char *clientout;
+ unsigned clientoutlen;
+ unsigned serverinlen;
+ SMTP_RESP *resp;
+ const char *mechanism;
+ int result;
+ char *line;
+
+#define NO_SASL_SECRET 0
+#define NO_SASL_INTERACTION 0
+
+ if (msg_verbose)
+ msg_info("%s: %s: SASL mechanisms %s",
+ myname, state->session->namaddr, state->sasl_mechanism_list);
+
+ /*
+ * Start the client side authentication protocol.
+ */
+ result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
+ state->sasl_mechanism_list,
+ NO_SASL_SECRET, NO_SASL_INTERACTION,
+ &clientout, &clientoutlen, &mechanism);
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ msg_fatal("%s: %s: client-side SASL authentication startup",
+ myname, state->session->namaddr);
+
+ /*
+ * Send the AUTH command and the optional initial client response.
+ * sasl_encode64() produces four bytes for each complete or incomplete
+ * triple of input bytes. Allocate an extra byte for string termination.
+ */
+#define ENCODE64_LENGTH(n) ((((n) + 2) / 3) * 4)
+
+ if (clientoutlen > 0) {
+ if (msg_verbose)
+ msg_info("%s: %s: uncoded initial reply: %.*s",
+ myname, state->session->namaddr, clientoutlen, clientout);
+ enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+ VSTRING_SPACE(state->sasl_encoded, enc_length);
+ if (sasl_encode64(clientout, clientoutlen,
+ STR(state->sasl_encoded), enc_length,
+ &enc_length_out) != SASL_OK)
+ msg_panic("%s: sasl_encode64 botch", myname);
+ free(clientout);
+ smtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
+ } else {
+ smtp_chat_cmd(state, "AUTH %s", mechanism);
+ }
+
+ /*
+ * Step through the authentication protocol until the server tells us
+ * that we are done.
+ */
+ while ((resp = smtp_chat_resp(state))->code % 100 == 3) {
+
+ /*
+ * Process a server challenge.
+ */
+ line = resp->str;
+ (void) mystrtok(&line, "- \t\n"); /* skip over result code */
+ serverinlen = strlen(line);
+ VSTRING_SPACE(state->sasl_decoded, serverinlen);
+ if (sasl_decode64(line, serverinlen,
+ STR(state->sasl_decoded), &enc_length) != SASL_OK) {
+ vstring_sprintf(why, "unable to decode SASL challenge from %s",
+ state->session->namaddr);
+ return (-1);
+ }
+ if (msg_verbose)
+ msg_info("%s: %s: decoded challenge: %.*s",
+ myname, state->session->namaddr,
+ enc_length, STR(state->sasl_decoded));
+ result = sasl_client_step((sasl_conn_t *) state->sasl_conn,
+ STR(state->sasl_decoded), enc_length,
+ NO_SASL_INTERACTION, &clientout, &clientoutlen);
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ msg_warn("%s: smtp SASL authentication step failed",
+ state->session->namaddr);
+
+ /*
+ * Send a client response.
+ */
+ if (clientoutlen > 0) {
+ if (msg_verbose)
+ msg_info("%s: %s: uncoded client response %.*s",
+ myname, state->session->namaddr, clientoutlen, clientout);
+ enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+ VSTRING_SPACE(state->sasl_encoded, enc_length);
+ if (sasl_encode64(clientout, clientoutlen,
+ STR(state->sasl_encoded), enc_length,
+ &enc_length_out) != SASL_OK)
+ msg_panic("%s: sasl_encode64 botch", myname);
+ free(clientout);
+ } else {
+ vstring_strcat(state->sasl_encoded, "");
+ }
+ smtp_chat_cmd(state, "%s", STR(state->sasl_encoded));
+ }
+
+ /*
+ * We completed the authentication protocol.
+ */
+ if (resp->code / 100 != 2) {
+ vstring_sprintf(why, "unable to SASL authenticate with %s",
+ state->session->namaddr);
+ return (0);
+ }
+ return (1);
+}
+
+/* smtp_sasl_cleanup - per-session cleanup */
+
+void smtp_sasl_cleanup(SMTP_STATE *state)
+{
+ if (state->sasl_username) {
+ myfree(state->sasl_username);
+ state->sasl_username = 0;
+ }
+ if (state->sasl_passwd) {
+ myfree(state->sasl_passwd);
+ state->sasl_passwd = 0;
+ }
+ if (state->sasl_mechanism_list) {
+ myfree(state->sasl_mechanism_list); /* allocated in smtp_helo */
+ state->sasl_mechanism_list = 0;
+ }
+ if (state->sasl_conn) {
+ if (msg_verbose)
+ msg_info("disposing SASL state information");
+ sasl_dispose(&state->sasl_conn);
+ }
+ if (state->sasl_callbacks) {
+ myfree((char *) state->sasl_callbacks);
+ state->sasl_callbacks = 0;
+ }
+ if (state->sasl_encoded) {
+ vstring_free(state->sasl_encoded);
+ state->sasl_encoded = 0;
+ }
+ if (state->sasl_decoded) {
+ vstring_free(state->sasl_decoded);
+ state->sasl_decoded = 0;
+ }
+}
+
+#endif
diff --git a/postfix/smtp/smtp_sasl_proto.c b/postfix/smtp/smtp_sasl_proto.c
new file mode 100644
index 000000000..ed34c3522
--- /dev/null
+++ b/postfix/smtp/smtp_sasl_proto.c
@@ -0,0 +1,113 @@
+/*++
+/* NAME
+/* smtp_sasl_proto 3
+/* SUMMARY
+/* Postfix SASL interface for SMTP client
+/* SYNOPSIS
+/* #include smtp_sasl.h
+/*
+/* void smtp_sasl_helo_auth(state, words)
+/* SMTP_STATE *state;
+/* const char *words;
+/*
+/* void smtp_sasl_helo_login(state)
+/* SMTP_STATE *state;
+/* DESCRIPTION
+/* This module contains random chunks of code that implement
+/* the SMTP protocol interface for SASL negotiation. The goal
+/* is to reduce clutter of the main SMTP client source code.
+/*
+/* smtp_sasl_helo_auth() processes the AUTH option in the
+/* SMTP server's EHLO response.
+/*
+/* smtp_sasl_helo_login() authenticates the SMTP client to the
+/* SMTP server, using the authentication mechanism information
+/* given by the server.
+/*
+/* Arguments:
+/* .IP state
+/* Session context.
+/* .IP words
+/* List of SASL authentication mechanisms (separated by blanks)
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Original author:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include
+
+/* Utility library. */
+
+#include
+#include
+
+/* Global library. */
+
+#include
+
+/* Application-specific. */
+
+#include "smtp.h"
+#include "smtp_sasl.h"
+
+#ifdef USE_SASL_AUTH
+
+/* smtp_sasl_helo_auth - handle AUTH option in EHLO reply */
+
+void smtp_sasl_helo_auth(SMTP_STATE *state, const char *words)
+{
+
+ /*
+ * XXX If the server offers a null list of authentication mechanisms,
+ * then pretend that the server doesn't support SASL authentication.
+ */
+ if (var_smtp_sasl_enable) {
+ if (state->sasl_mechanism_list) {
+ myfree(state->sasl_mechanism_list);
+ msg_warn("%s offered AUTH option multiple times",
+ state->session->namaddr);
+ state->sasl_mechanism_list = 0;
+ state->features &= ~SMTP_FEATURE_AUTH;
+ }
+ if (strlen(words) > 0) {
+ state->sasl_mechanism_list = mystrdup(words);
+ state->features |= SMTP_FEATURE_AUTH;
+ }
+ }
+}
+
+/* smtp_sasl_helo_login - perform SASL login */
+
+int smtp_sasl_helo_login(SMTP_STATE *state)
+{
+ VSTRING *why = vstring_alloc(10);
+ int ret;
+
+ /*
+ * XXX If authentication fails, should we try anonymous authentication?
+ */
+ smtp_sasl_start(state);
+ if (smtp_sasl_authenticate(state, why) <= 0)
+ ret = smtp_site_fail(state, 450, "Authentication failed: %s",
+ vstring_str(why));
+ vstring_free(why);
+ return (ret);
+}
+
+#endif
diff --git a/postfix/smtp/smtp_state.c b/postfix/smtp/smtp_state.c
index 1ab6a6f1d..07696dd91 100644
--- a/postfix/smtp/smtp_state.c
+++ b/postfix/smtp/smtp_state.c
@@ -15,10 +15,6 @@
/* memory for buffers etc.
/*
/* smtp_cleanup() destroys memory allocated by smtp_state_init().
-/* STANDARDS
-/* DIAGNOSTICS
-/* BUGS
-/* SEE ALSO
/* LICENSE
/* .ad
/* .fi
@@ -47,6 +43,7 @@
/* Application-specific. */
#include "smtp.h"
+#include "smtp_sasl.h"
/* smtp_state_alloc - initialize */
@@ -64,6 +61,9 @@ SMTP_STATE *smtp_state_alloc(void)
state->features = 0;
state->history = 0;
state->error_mask = 0;
+#ifdef USE_SASL_AUTH
+ smtp_sasl_connect(state);
+#endif
return (state);
}
@@ -74,5 +74,8 @@ void smtp_state_free(SMTP_STATE *state)
vstring_free(state->buffer);
vstring_free(state->scratch);
vstring_free(state->scratch2);
+#ifdef USE_AUTH
+ smtp_sasl_cleanup(state);
+#endif
myfree((char *) state);
}
diff --git a/postfix/smtpd/.indent.pro b/postfix/smtpd/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/smtpd/.indent.pro
+++ b/postfix/smtpd/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/smtpd/Makefile.in b/postfix/smtpd/Makefile.in
index 7203499fc..67b36092c 100644
--- a/postfix/smtpd/Makefile.in
+++ b/postfix/smtpd/Makefile.in
@@ -1,9 +1,10 @@
SHELL = /bin/sh
SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
- smtpd_peer.c
+ smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c
OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
- smtpd_peer.o
-HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h
+ smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o
+HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
+ smtpd_sasl_glue.h
TESTSRC = smtpd_token_test.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
@@ -64,7 +65,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
tests: smtpd_check_test smtpd_check_test2 smtpd_check_test3 smtpd_token_test
@@ -128,6 +129,8 @@ smtpd.o: smtpd_token.h
smtpd.o: smtpd.h
smtpd.o: smtpd_check.h
smtpd.o: smtpd_chat.h
+smtpd.o: smtpd_sasl_proto.h
+smtpd.o: smtpd_sasl_glue.h
smtpd_chat.o: smtpd_chat.c
smtpd_chat.o: ../include/sys_defs.h
smtpd_chat.o: ../include/msg.h
@@ -194,6 +197,40 @@ smtpd_peer.o: ../include/vbuf.h
smtpd_peer.o: ../include/vstring.h
smtpd_peer.o: ../include/argv.h
smtpd_peer.o: ../include/mail_stream.h
+smtpd_sasl_glue.o: smtpd_sasl_glue.c
+smtpd_sasl_glue.o: ../include/sys_defs.h
+smtpd_sasl_glue.o: ../include/msg.h
+smtpd_sasl_glue.o: ../include/mymalloc.h
+smtpd_sasl_glue.o: ../include/namadr_list.h
+smtpd_sasl_glue.o: ../include/mail_params.h
+smtpd_sasl_glue.o: ../include/smtp_stream.h
+smtpd_sasl_glue.o: ../include/vstring.h
+smtpd_sasl_glue.o: ../include/vbuf.h
+smtpd_sasl_glue.o: ../include/vstream.h
+smtpd_sasl_glue.o: smtpd.h
+smtpd_sasl_glue.o: ../include/argv.h
+smtpd_sasl_glue.o: ../include/mail_stream.h
+smtpd_sasl_glue.o: smtpd_sasl_glue.h
+smtpd_sasl_glue.o: smtpd_chat.h
+smtpd_sasl_proto.o: smtpd_sasl_proto.c
+smtpd_sasl_proto.o: ../include/sys_defs.h
+smtpd_sasl_proto.o: ../include/msg.h
+smtpd_sasl_proto.o: ../include/mymalloc.h
+smtpd_sasl_proto.o: ../include/mail_params.h
+smtpd_sasl_proto.o: ../include/mail_proto.h
+smtpd_sasl_proto.o: ../include/vstream.h
+smtpd_sasl_proto.o: ../include/vbuf.h
+smtpd_sasl_proto.o: ../include/iostuff.h
+smtpd_sasl_proto.o: ../include/mail_error.h
+smtpd_sasl_proto.o: ../include/name_mask.h
+smtpd_sasl_proto.o: smtpd.h
+smtpd_sasl_proto.o: ../include/vstring.h
+smtpd_sasl_proto.o: ../include/argv.h
+smtpd_sasl_proto.o: ../include/mail_stream.h
+smtpd_sasl_proto.o: smtpd_token.h
+smtpd_sasl_proto.o: smtpd_chat.h
+smtpd_sasl_proto.o: smtpd_sasl_proto.h
+smtpd_sasl_proto.o: smtpd_sasl_glue.h
smtpd_state.o: smtpd_state.c
smtpd_state.o: ../include/sys_defs.h
smtpd_state.o: ../include/events.h
@@ -201,6 +238,7 @@ smtpd_state.o: ../include/mymalloc.h
smtpd_state.o: ../include/vstream.h
smtpd_state.o: ../include/vbuf.h
smtpd_state.o: ../include/name_mask.h
+smtpd_state.o: ../include/msg.h
smtpd_state.o: ../include/cleanup_user.h
smtpd_state.o: ../include/mail_params.h
smtpd_state.o: ../include/mail_error.h
@@ -209,6 +247,7 @@ smtpd_state.o: ../include/vstring.h
smtpd_state.o: ../include/argv.h
smtpd_state.o: ../include/mail_stream.h
smtpd_state.o: smtpd_chat.h
+smtpd_state.o: smtpd_sasl_glue.h
smtpd_token.o: smtpd_token.c
smtpd_token.o: ../include/sys_defs.h
smtpd_token.o: ../include/mymalloc.h
diff --git a/postfix/smtpd/smtpd.c b/postfix/smtpd/smtpd.c
index 6887e0d8d..e076c4c3f 100644
--- a/postfix/smtpd/smtpd.c
+++ b/postfix/smtpd/smtpd.c
@@ -37,6 +37,7 @@
/* RFC 1854 (SMTP Pipelining)
/* RFC 1870 (Message Size Declaration)
/* RFC 1985 (ETRN command) (partial)
+/* RFC 2554 (AUTH command)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/*
@@ -58,6 +59,11 @@
/* .IP \fBstrict_rfc821_envelopes\fR
/* Disallow non-RFC 821 style addresses in envelopes. For example,
/* allow RFC822-style address forms with comments, like Sendmail does.
+/* .SH "Authenication controls"
+/* .IP \fBenable_sasl_authentication\fR
+/* Enable per-session authentication as per RFC 2554 (SASL).
+/* This functionality is available only when explicitly selected
+/* at program build time and explicitly enabled at runtime.
/* .SH Miscellaneous
/* .ad
/* .fi
@@ -257,6 +263,8 @@
#include "smtpd.h"
#include "smtpd_check.h"
#include "smtpd_chat.h"
+#include "smtpd_sasl_proto.h"
+#include "smtpd_sasl_glue.h"
/*
* Tunable parameters. Make sure that there is some bound on the length of
@@ -307,6 +315,11 @@ char *var_alias_maps;
char *var_local_rcpt_maps;
bool var_allow_untrust_route;
+#ifdef USE_SASL_AUTH
+bool var_smtpd_sasl_enable;
+
+#endif
+
/*
* Global state, for stand-alone mode queue file cleanup. When this is
* non-null at cleanup time, the named file is removed.
@@ -396,6 +409,10 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
else
smtpd_chat_reply(state, "250-SIZE");
smtpd_chat_reply(state, "250-ETRN");
+#ifdef USE_SASL_AUTH
+ if (var_smtpd_sasl_enable)
+ smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
+#endif
smtpd_chat_reply(state, "250 8BITMIME");
return (0);
}
@@ -592,6 +609,13 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
} else if (strncasecmp(arg, "SIZE=", 5) == 0) {
if ((state->msg_size = off_cvt_string(arg + 5)) < 0)
state->msg_size = 0;
+#ifdef USE_SASL_AUTH
+ } else if (strncasecmp(arg, "AUTH=", 5) == 0) {
+ if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
+ smtpd_chat_reply(state, "%s", err);
+ return (-1);
+ }
+#endif
} else {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "555 Unsupported option: %s", arg);
@@ -615,7 +639,13 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
* Open queue file or IPC stream.
*/
mail_open_stream(state);
+#ifdef USE_SASL_AUTH
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_mail_log(state);
+ else
+#else
msg_info("%s: client=%s[%s]", state->queue_id, state->name, state->addr);
+#endif
/*
* Record the time of arrival and the sender envelope address.
@@ -660,6 +690,9 @@ static void mail_reset(SMTPD_STATE *state)
myfree(state->sender);
state->sender = 0;
}
+#ifdef USE_SASL_AUTH
+ smtpd_sasl_mail_reset(state);
+#endif
}
/* rcpt_cmd - process RCPT TO command */
@@ -1061,6 +1094,11 @@ typedef struct SMTPD_CMD {
static SMTPD_CMD smtpd_cmd_table[] = {
"HELO", helo_cmd,
"EHLO", ehlo_cmd,
+
+#ifdef USE_SASL_AUTH
+ "AUTH", smtpd_sasl_auth_cmd,
+#endif
+
"MAIL", mail_cmd,
"RCPT", rcpt_cmd,
"DATA", data_cmd,
@@ -1182,6 +1220,9 @@ static void smtpd_proto(SMTPD_STATE *state)
* dialog.
*/
helo_reset(state);
+#ifdef USE_SASL_AUTH
+ smtpd_sasl_auth_reset(state);
+#endif
mail_reset(state);
rcpt_reset(state);
smtpd_chat_reset(state);
@@ -1304,6 +1345,11 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
smtpd_check_init();
debug_peer_init();
msg_cleanup(smtpd_cleanup);
+
+#ifdef USE_SASL_AUTH
+ if (var_smtpd_sasl_enable)
+ smtpd_sasl_initialize();
+#endif
}
/* main - the main program */
@@ -1335,6 +1381,9 @@ int main(int argc, char **argv)
VAR_STRICT_RFC821_ENV, DEF_STRICT_RFC821_ENV, &var_strict_rfc821_env,
VAR_DISABLE_VRFY_CMD, DEF_DISABLE_VRFY_CMD, &var_disable_vrfy_cmd,
VAR_ALLOW_UNTRUST_ROUTE, DEF_ALLOW_UNTRUST_ROUTE, &var_allow_untrust_route,
+#ifdef USE_SASL_AUTH
+ VAR_SMTPD_SASL_ENABLE, DEF_SMTPD_SASL_ENABLE, &var_smtpd_sasl_enable,
+#endif
0,
};
static CONFIG_STR_TABLE str_table[] = {
diff --git a/postfix/smtpd/smtpd.h b/postfix/smtpd/smtpd.h
index 13549faca..e64971f13 100644
--- a/postfix/smtpd/smtpd.h
+++ b/postfix/smtpd/smtpd.h
@@ -8,6 +8,14 @@
/* DESCRIPTION
/* .nf
+ /*
+ * SASL library.
+ */
+#ifdef USE_SASL_AUTH
+#include
+#include
+#endif
+
/*
* Utility library.
*/
@@ -53,6 +61,15 @@ typedef struct SMTPD_STATE {
char *where;
int recursion;
off_t msg_size;
+#ifdef USE_SASL_AUTH
+ char *sasl_mechanism_list;
+ char *sasl_method;
+ char *sasl_username;
+ char *sasl_sender;
+ sasl_conn_t *sasl_conn;
+ VSTRING *sasl_encoded;
+ VSTRING *sasl_decoded;
+#endif
} SMTPD_STATE;
extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c
index 5b63353a6..8677106dc 100644
--- a/postfix/smtpd/smtpd_check.c
+++ b/postfix/smtpd/smtpd_check.c
@@ -768,6 +768,19 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, char *name,
return (SMTPD_CHECK_DUNNO);
}
+#ifdef USE_SASL_AUTH
+
+/* permit_sasl_auth - OK for authenticated connection */
+
+static int permit_sasl_auth(SMTPD_STATE *state)
+{
+ if (state->sasl_username)
+ return (SMTPD_CHECK_OK);
+ return (SMTPD_CHECK_DUNNO);
+}
+
+#endif
+
/* check_relay_domains - OK/FAIL for message relaying */
static int check_relay_domains(SMTPD_STATE *state, char *recipient,
@@ -1665,6 +1678,10 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
if (cpp[1] != 0)
msg_warn("restriction `%s' after `%s' is ignored",
cpp[1], CHECK_RELAY_DOMAINS);
+#ifdef USE_SASL_AUTH
+ } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) {
+ status = permit_sasl_auth(state);
+#endif
} else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) {
if (state->recipient)
status = reject_unknown_address(state, state->recipient,
diff --git a/postfix/smtpd/smtpd_sasl_glue.c b/postfix/smtpd/smtpd_sasl_glue.c
new file mode 100644
index 000000000..e861fc22b
--- /dev/null
+++ b/postfix/smtpd/smtpd_sasl_glue.c
@@ -0,0 +1,370 @@
+/*++
+/* NAME
+/* smtpd_sasl_glue 3
+/* SUMMARY
+/* Postfix SMTP server, SASL support interface
+/* SYNOPSIS
+/* #include "smtpd_sasl_glue.h"
+/*
+/* void smtpd_sasl_initialize()
+/*
+/* void smtpd_sasl_connect(state)
+/* SMTPD_STATE *state;
+/*
+/* char *smtpd_sasl_authenticate(state, sasl_method, init_response)
+/* SMTPD_STATE *state;
+/* const char *sasl_method;
+/* const char *init_response;
+/*
+/* void smtpd_sasl_logout(state)
+/* SMTPD_STATE *state;
+/*
+/* void smtpd_sasl_disconnect(state)
+/* SMTPD_STATE *state;
+/* DESCRIPTION
+/* This module encapsulates most of the detail specific to SASL
+/* authentication.
+/*
+/* smtpd_sasl_initialize() initializes the SASL library. This
+/* routine should be called once at process start-up. It may
+/* need access to the file system for run-time loading of
+/* plug-in modules. There is no corresponding cleanup routine.
+/*
+/* smtpd_sasl_connect() performs per-connection initialization.
+/* This routine should be called once at the start of every
+/* connection.
+/*
+/* smtpd_sasl_authenticate() implements the authentication dialog.
+/* The result is a null pointer in case of success, an SMTP reply
+/* in case of failure. smtpd_sasl_authenticate() updates the
+/* following state structure members:
+/* .IP sasl_method
+/* The authentication method that was successfully applied.
+/* This member is a null pointer in the absence of successful
+/* authentication.
+/* .IP sasl_username
+/* The username that was successfully authenticated.
+/* This member is a null pointer in the absence of successful
+/* authentication.
+/* .PP
+/* smtpd_sasl_logout() cleant up after smtpd_sasl_authenticate().
+/* This routine exists for the sake of symmetry.
+/*
+/* smtpd_sasl_disconnect() performs per-connection cleanup.
+/* This routine should be called at the end of every connection.
+/*
+/* Arguments:
+/* .IP state
+/* SMTP session context.
+/* .IP sasl_method
+/* A SASL mechanism name
+/* .IP init_reply
+/* An optional initial client response.
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include
+#include
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+
+/* Global library. */
+
+#include
+#include
+
+/* Application-specific. */
+
+#include "smtpd.h"
+#include "smtpd_sasl_glue.h"
+#include "smtpd_chat.h"
+
+#ifdef USE_SASL_AUTH
+
+/*
+ * Silly little macros.
+ */
+#define STR(s) vstring_str(s)
+
+/* smtpd_sasl_log - SASL logging callback */
+
+static int smtpd_sasl_log(void *unused_context, int priority,
+ const char *message)
+{
+ switch (priority) {
+ case SASL_LOG_ERR:
+ msg_fatal("%s", message);
+ break;
+ case SASL_LOG_WARNING:
+ msg_warn("%s", message);
+ break;
+ case SASL_LOG_INFO:
+ if (msg_verbose)
+ msg_info("%s", message);
+ break;
+ }
+ return SASL_OK;
+}
+
+ /*
+ * SASL callback interface structure. These call-backs have no per-session
+ * context.
+ */
+#define NO_CALLBACK_CONTEXT 0
+
+static sasl_callback_t callbacks[] = {
+ {SASL_CB_LOG, &smtpd_sasl_log, NO_CALLBACK_CONTEXT},
+ {SASL_CB_LIST_END, 0, 0}
+};
+
+/* smtpd_sasl_initialize - per-process initialization */
+
+void smtpd_sasl_initialize(void)
+{
+
+ /*
+ * Initialize the library: load SASL plug-in routines, etc.
+ */
+ if (sasl_server_init(callbacks, "smtpd") != SASL_OK)
+ msg_fatal("SASL per-process initialization failed");
+}
+
+/* smtpd_sasl_connect - per-connection initialization */
+
+void smtpd_sasl_connect(SMTPD_STATE *state)
+{
+ int sasl_mechanism_count;
+ sasl_security_properties_t sec_props;
+
+ /*
+ * Initialize SASL-specific state variables. Use long-lived storage for
+ * base 64 conversion results, rather than local variables, to avoid
+ * memory leaks when a read or write routine returns abnormally after
+ * timeout or I/O error.
+ */
+ state->sasl_mechanism_list = 0;
+ state->sasl_username = 0;
+ state->sasl_sender = 0;
+ state->sasl_conn = 0;
+ state->sasl_decoded = vstring_alloc(10);
+ state->sasl_encoded = vstring_alloc(10);
+
+ /*
+ * Set up a new server context for this connection.
+ */
+#define DEFAULT_USER_REALM ((char *) 0)
+#define NO_SECURITY_LAYERS (0)
+#define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
+
+ if (sasl_server_new("smtp", var_myhostname, DEFAULT_USER_REALM,
+ NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
+ &state->sasl_conn) != SASL_OK)
+ msg_fatal("SASL per-connection server initialization");
+
+ /*
+ * Security options. XXX What exactly is this supposed to be doing? The
+ * cyrus-sasl-1.5.15 source code has no documentation at all about this
+ * routine.
+ */
+ memset(&sec_props, 0, sizeof(sec_props));
+ sec_props.min_ssf = 0;
+ sec_props.max_ssf = 1; /* don't allow real SASL
+ * security layer */
+ sec_props.security_flags = 0;
+ sec_props.maxbufsize = 0;
+ sec_props.property_names = 0;
+ sec_props.property_values = 0;
+
+ if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS,
+ &sec_props) != SASL_OK)
+ msg_fatal("SASL per-connection security setup");
+
+ /*
+ * Get the list of authentication mechanisms.
+ */
+#define UNSUPPORTED_USER ((char *) 0)
+#define IGNORE_MECHANISM_LEN ((unsigned *) 0)
+
+ if (sasl_listmech(state->sasl_conn, UNSUPPORTED_USER,
+ "250-AUTH ", " ", "",
+ &state->sasl_mechanism_list,
+ IGNORE_MECHANISM_LEN,
+ &sasl_mechanism_count) != SASL_OK
+ || sasl_mechanism_count <= 0)
+ msg_fatal("no SASL authentication mechanisms");
+}
+
+/* smtpd_sasl_disconnect - per-connection cleanup */
+
+void smtpd_sasl_disconnect(SMTPD_STATE *state)
+{
+ if (state->sasl_mechanism_list) {
+ free(state->sasl_mechanism_list);
+ state->sasl_mechanism_list = NULL;
+ }
+ if (state->sasl_conn) {
+ sasl_dispose(&state->sasl_conn);
+ state->sasl_conn = 0;
+ }
+ vstring_free(state->sasl_decoded);
+ vstring_free(state->sasl_encoded);
+}
+
+/* smtpd_sasl_authenticate - per-session authentication */
+
+char *smtpd_sasl_authenticate(SMTPD_STATE *state,
+ const char *sasl_method,
+ const char *init_response)
+{
+ char *myname = "smtpd_sasl_authenticate";
+ char *dec_buffer;
+ unsigned dec_length;
+ unsigned enc_length;
+ unsigned enc_length_out;
+ unsigned reply_len;
+ char *serverout;
+ unsigned serveroutlen;
+ int result;
+ const char *errstr = 0;
+
+#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
+#define LOG_IFSET(text,var) IFELSE((var),(text),""), IFELSE((var),(var),"")
+
+ if (msg_verbose)
+ msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
+ LOG_IFSET(", init_response ", init_response));
+
+ /*
+ * Sanity check.
+ */
+ if (state->sasl_username || state->sasl_method)
+ msg_panic("%s: already authenticated", myname);
+
+ /*
+ * SASL authentication protocol start-up. Process any initial client
+ * response that was sent along in the AUTH command.
+ */
+ if (init_response) {
+ reply_len = strlen(init_response);
+ VSTRING_SPACE(state->sasl_decoded, reply_len);
+ dec_buffer = STR(state->sasl_decoded);
+ if (sasl_decode64(init_response, reply_len,
+ dec_buffer, &dec_length) != SASL_OK)
+ return ("501 AUTH failed: malformed initial response");
+ if (msg_verbose)
+ msg_info("%s: decoded initial response %s", myname, dec_buffer);
+ } else {
+ dec_buffer = 0;
+ dec_length = 0;
+ }
+ result = sasl_server_start(state->sasl_conn, sasl_method, dec_buffer,
+ dec_length, &serverout, &serveroutlen, &errstr);
+
+ /*
+ * Repeat until done or until the client gives up.
+ */
+ while (result == SASL_CONTINUE) {
+
+ /*
+ * Send a server challenge. Avoid storing the challenge in a local
+ * variable, because we would leak memory when smtpd_chat_reply()
+ * does not return due to timeout or I/O error. sasl_encode64()
+ * null-terminates the result if the result buffer is large enough.
+ *
+ * Regarding the hairy expression below: output from sasl_encode64()
+ * comes in multiples of four bytes for each triple of input bytes,
+ * plus four bytes for any incomplete last triple, plus one byte for
+ * the null terminator.
+ */
+ if (msg_verbose)
+ msg_info("%s: uncoded challenge: %.*s",
+ myname, serveroutlen, serverout);
+ enc_length = ((serveroutlen + 2) / 3) * 4 + 1;
+ VSTRING_SPACE(state->sasl_encoded, enc_length);
+ if (sasl_encode64(serverout, serveroutlen, STR(state->sasl_encoded),
+ enc_length, &enc_length_out) != SASL_OK)
+ msg_panic("%s: sasl_encode64 botch", myname);
+ free(serverout);
+ smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
+
+ /*
+ * Receive the client response. "*" means that the client gives up.
+ * For now we ignore the fact that excessively long responses will be
+ * truncated. To handle such responses, we need to change
+ * smtpd_chat_query() so that it returns an error indication.
+ */
+ smtpd_chat_query(state);
+ if (strcmp(vstring_str(state->buffer), "*") == 0)
+ return ("501 Authentication aborted"); /* XXX */
+ reply_len = VSTRING_LEN(state->buffer);
+ VSTRING_SPACE(state->sasl_decoded, reply_len);
+ if (sasl_decode64(vstring_str(state->buffer), reply_len,
+ STR(state->sasl_decoded), &dec_length) != SASL_OK)
+ return ("501 Error: malformed authentication response");
+ if (msg_verbose)
+ msg_info("%s: decoded response: %.*s",
+ myname, dec_length, STR(state->sasl_decoded));
+ result = sasl_server_step(state->sasl_conn, STR(state->sasl_decoded),
+ dec_length, &serverout, &serveroutlen, &errstr);
+ }
+
+ /*
+ * The authentication protocol was completed.
+ */
+ if (result != SASL_OK)
+ return ("535 Error: authentication failed");
+
+ /*
+ * Authentication succeeded. Find out the login name for logging and for
+ * accounting purposes. For the sake of completeness we also record the
+ * authentication method that was used.
+ */
+ result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
+ (void **) &serverout);
+ if (result != SASL_OK || serverout == 0)
+ msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
+ state->sasl_username = mystrdup(serverout);
+ state->sasl_method = mystrdup(sasl_method);
+ free(serverout);
+
+ return (0);
+}
+
+/* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */
+
+void smtpd_sasl_logout(SMTPD_STATE *state)
+{
+ if (state->sasl_username) {
+ myfree(state->sasl_username);
+ state->sasl_username = 0;
+ }
+ if (state->sasl_method) {
+ myfree(state->sasl_method);
+ state->sasl_method = 0;
+ }
+}
+
+#endif
diff --git a/postfix/smtpd/smtpd_sasl_glue.h b/postfix/smtpd/smtpd_sasl_glue.h
new file mode 100644
index 000000000..89dce7643
--- /dev/null
+++ b/postfix/smtpd/smtpd_sasl_glue.h
@@ -0,0 +1,35 @@
+/*++
+/* NAME
+/* smtpd_sasl_glue 3h
+/* SUMMARY
+/* Postfix SMTP server, SASL support interface
+/* SYNOPSIS
+/* #include "smtpd_sasl.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * SASL protocol interface
+ */
+extern void smtpd_sasl_initialize(void);
+extern void smtpd_sasl_connect(SMTPD_STATE *);
+extern void smtpd_sasl_disconnect(SMTPD_STATE *);
+extern char *smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *);
+extern void smtpd_sasl_logout(SMTPD_STATE *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
diff --git a/postfix/smtpd/smtpd_sasl_proto.c b/postfix/smtpd/smtpd_sasl_proto.c
new file mode 100644
index 000000000..db5600a59
--- /dev/null
+++ b/postfix/smtpd/smtpd_sasl_proto.c
@@ -0,0 +1,198 @@
+/*++
+/* NAME
+/* smtpd_sasl_proto 3
+/* SUMMARY
+/* Postfix SMTP protocol support for SASL authentication
+/* SYNOPSIS
+/* #include "smtpd.h"
+/* #include "smtpd_sasl.h"
+/*
+/* void smtpd_sasl_auth_cmd(state, argc, argv)
+/* SMTPD_STATE *state;
+/* int argc;
+/* SMTPD_TOKEN *argv;
+/*
+/* void smtpd_sasl_auth_reset(state)
+/* SMTPD_STATE *state;
+/*
+/* char *smtpd_sasl_mail_opt(state, sender)
+/* SMTPD_STATE *state;
+/* const char *sender;
+/*
+/* void smtpd_sasl_mail_log(state)
+/* SMTPD_STATE *state;
+/*
+/* void smtpd_sasl_mail_reset(state)
+/* SMTPD_STATE *state;
+/* DESCRIPTION
+/* This module contains random chunks of code that implement
+/* the SMTP protocol interface for SASL negotiation. The goal
+/* is to reduce clutter of the main SMTP server source code.
+/*
+/* smtpd_sasl_auth_cmd() implements the AUTH command.
+/*
+/* smtpd_sasl_auth_reset() cleans up after the AUTH command.
+/*
+/* smtpd_sasl_mail_opt() implements the AUTH=sender option
+/* to the MAIL FROM command. The result is an error response
+/* in case of problems.
+/*
+/* smtpd_sasl_mail_log() logs the queue ID and client information.
+/*
+/* smtpd_sasl_mail_reset() cleans up after the AUTH=sender option.
+/*
+/* Arguments:
+/* .IP state
+/* SMTP session context.
+/* .IP argc
+/* Number of command line tokens.
+/* .IP argv
+/* The command line parsed into tokens.
+/* .IP sender
+/* Sender address from the AUTH=sender option in the MAIL FROM
+/* command.
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include
+#include
+
+/* Utility library. */
+
+#include
+#include
+
+/* Global library. */
+
+#include
+#include
+#include
+
+/* Application-specific. */
+
+#include "smtpd.h"
+#include "smtpd_token.h"
+#include "smtpd_chat.h"
+#include "smtpd_sasl_proto.h"
+#include "smtpd_sasl_glue.h"
+
+#ifdef USE_SASL_AUTH
+
+/* smtpd_sasl_auth_cmd - process AUTH command */
+
+int smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
+{
+ char *auth_mechanism;
+ char *initial_response;
+ char *err;
+
+ if (var_helo_required && state->helo_name == 0) {
+ state->error_mask |= MAIL_ERROR_POLICY;
+ smtpd_chat_reply(state, "503 Error: send HELO/EHLO first");
+ return (-1);
+ }
+ if (!var_smtpd_sasl_enable) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "503 Error: authentication not enabled");
+ return (-1);
+ }
+ if (state->sasl_username) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "503 Error: already authenticated");
+ return (-1);
+ }
+ if (argc < 2 || argc > 3) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 Syntax: AUTH mechanism");
+ return (-1);
+ }
+
+ /*
+ * All authentication failures shall be logged. The 5xx reply code
+ * triggers tar-pit delays in order to slow down password guessing
+ * attacks.
+ */
+ auth_mechanism = argv[1].strval;
+ initial_response = (argc == 3 ? argv[2].strval : 0);
+ err = smtpd_sasl_authenticate(state, auth_mechanism, initial_response);
+ if (err != 0) {
+ msg_warn("%s[%s]: SASL authentication failed",
+ state->name, state->addr);
+ smtpd_chat_reply(state, "%s", err);
+ return (-1);
+ }
+ smtpd_chat_reply(state, "235 Authentication successful");
+ return (0);
+}
+
+/* smtpd_sasl_auth_reset - clean up after AUTH command */
+
+void smtpd_sasl_auth_reset(SMTPD_STATE *state)
+{
+ smtpd_sasl_logout(state);
+}
+
+/* smtpd_sasl_mail_opt - SASL-specific AUTH=sender option */
+
+char *smtpd_sasl_mail_opt(SMTPD_STATE *state, const char *addr)
+{
+ if (!var_smtpd_sasl_enable) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ return ("503 Error: authentication disabled");
+ }
+ if (state->sasl_username == 0) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ return ("503 Error: send AUTH command first");
+ }
+ if (state->sasl_sender != 0) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ return ("503 Error: multiple AUTH= options");
+ }
+ if (strcmp(addr, "<>") != 0)
+ state->sasl_sender = mystrdup(addr);
+ return (0);
+}
+
+/* smtpd_sasl_mail_log - SASL-specific MAIL FROM command logging */
+
+void smtpd_sasl_mail_log(SMTPD_STATE *state)
+{
+#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
+#define LOG_IFSET(text,var) IFELSE((var),(text),""), IFELSE((var),(var),"")
+
+ msg_info("%s: client=%s[%s]%s%s%s%s",
+ state->queue_id, state->name, state->addr,
+ LOG_IFSET(", sasl_method=", state->sasl_method),
+ LOG_IFSET(", sasl_username=", state->sasl_username),
+ LOG_IFSET(", sasl_sender=", state->sasl_sender));
+}
+
+/* smtpd_sasl_mail_reset - SASL-specific MAIL FROM cleanup */
+
+void smtpd_sasl_mail_reset(SMTPD_STATE *state)
+{
+ if (state->sasl_sender) {
+ myfree(state->sasl_sender);
+ state->sasl_sender = 0;
+ }
+}
+
+#endif
diff --git a/postfix/smtpd/smtpd_sasl_proto.h b/postfix/smtpd/smtpd_sasl_proto.h
new file mode 100644
index 000000000..bd326be58
--- /dev/null
+++ b/postfix/smtpd/smtpd_sasl_proto.h
@@ -0,0 +1,35 @@
+/*++
+/* NAME
+/* smtpd_sasl_proto 3h
+/* SUMMARY
+/* Postfix SMTP protocol support for SASL authentication
+/* SYNOPSIS
+/* #include "smtpd_sasl_proto.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * SMTP protocol interface.
+ */
+extern int smtpd_sasl_auth_cmd(SMTPD_STATE *, int, SMTPD_TOKEN *);
+extern void smtpd_sasl_auth_reset(SMTPD_STATE *);
+extern char *smtpd_sasl_mail_opt(SMTPD_STATE *, const char *);
+extern void smtpd_sasl_mail_log(SMTPD_STATE *);
+extern void smtpd_sasl_mail_reset(SMTPD_STATE *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
diff --git a/postfix/smtpd/smtpd_state.c b/postfix/smtpd/smtpd_state.c
index a5d8c7dab..063f40506 100644
--- a/postfix/smtpd/smtpd_state.c
+++ b/postfix/smtpd/smtpd_state.c
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
/* Global library. */
@@ -56,6 +57,7 @@
#include "smtpd.h"
#include "smtpd_chat.h"
+#include "smtpd_sasl_glue.h"
/* smtpd_state_init - initialize after connection establishment */
@@ -88,6 +90,10 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
state->recursion = 0;
state->msg_size = 0;
+#ifdef USE_SASL_AUTH
+ smtpd_sasl_connect(state);
+#endif
+
/*
* Initialize peer information.
*/
@@ -112,4 +118,8 @@ void smtpd_state_reset(SMTPD_STATE *state)
if (state->buffer)
vstring_free(state->buffer);
smtpd_peer_reset(state);
+
+#ifdef USE_SASL_AUTH
+ smtpd_sasl_disconnect(state);
+#endif
}
diff --git a/postfix/smtpstone/.indent.pro b/postfix/smtpstone/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/smtpstone/.indent.pro
+++ b/postfix/smtpstone/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/smtpstone/Makefile.in b/postfix/smtpstone/Makefile.in
index 90cd11386..702f55cf6 100644
--- a/postfix/smtpstone/Makefile.in
+++ b/postfix/smtpstone/Makefile.in
@@ -58,7 +58,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
smtp-sink.o: smtp-sink.c
diff --git a/postfix/spawn/.indent.pro b/postfix/spawn/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/spawn/.indent.pro
+++ b/postfix/spawn/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/spawn/Makefile.in b/postfix/spawn/Makefile.in
index ecada6188..d535d6df0 100644
--- a/postfix/spawn/Makefile.in
+++ b/postfix/spawn/Makefile.in
@@ -50,7 +50,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
spawn.o: spawn.c
diff --git a/postfix/trivial-rewrite/.indent.pro b/postfix/trivial-rewrite/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/trivial-rewrite/.indent.pro
+++ b/postfix/trivial-rewrite/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/trivial-rewrite/Makefile.in b/postfix/trivial-rewrite/Makefile.in
index 8dcbb0c6b..a944bf153 100644
--- a/postfix/trivial-rewrite/Makefile.in
+++ b/postfix/trivial-rewrite/Makefile.in
@@ -56,7 +56,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make -f Makefile.in Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
resolve.o: resolve.c
diff --git a/postfix/util/.indent.pro b/postfix/util/.indent.pro
index 2cc95193a..f9b8f2287 100644
--- a/postfix/util/.indent.pro
+++ b/postfix/util/.indent.pro
@@ -64,7 +64,6 @@
-TNAMADR_LIST
-TNAME_MASK
-TPEER_NAME
--TPENDING
-TPICKUP_INFO
-TPIPE_ATTR
-TPIPE_PARAMS
@@ -110,3 +109,5 @@
-TWAIT_STATUS_T
-TWATCHDOG
-TWATCH_FD
+-Tsasl_conn_t
+-Tsasl_secret_t
diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in
index 6309d5342..349b29d43 100644
--- a/postfix/util/Makefile.in
+++ b/postfix/util/Makefile.in
@@ -255,7 +255,7 @@ depend: $(MAKES)
$(CC) -E $(DEFS) $(INCL) $$i | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' -e 'p' -e '}'; \
done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
- @make Makefile
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
stream_test: stream_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
diff --git a/postfix/util/dict_open.c b/postfix/util/dict_open.c
index 670550245..1eb2471ae 100644
--- a/postfix/util/dict_open.c
+++ b/postfix/util/dict_open.c
@@ -372,7 +372,7 @@ main(int argc, char **argv)
if ((cmd = mystrtok(&bufp, " ")) == 0)
continue;
key = mystrtok(&bufp, " =");
- value = mystrtok(&bufp, " ");
+ value = mystrtok(&bufp, " =");
if (strcmp(cmd, "del") == 0 && key && !value) {
if (dict_del(dict, key))
vstream_printf("%s: not found\n", key);