2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

snapshot-20000316

This commit is contained in:
Wietse Venema 2000-03-16 00:00:00 +00:00
parent a68548b175
commit bb268b56ef
90 changed files with 2154 additions and 84 deletions

3
postfix/.indent.pro vendored
View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
====================================

74
postfix/SASL_README Normal file
View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 = ""

277
postfix/conf/sample-tls.cf Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -2311,12 +2311,51 @@ include directory and of the object library.
<p>
One problem: older DB versions install a file
When building with a third-party DB library you may into one of the
following problems:
<p>
<ul>
<li> Older DB versions install a file
<b>/usr/local/include/ndbm.h</b> that is incompatible with
<b>/usr/include/ndbm.h</b>. Be sure to get rid of the bogus file.
See the FAQ entry titled "<a href="#dbm_dirfno">Undefined symbols:
dbm_pagfno, dbm_dirfno etc</a>".
<p>
<li>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:
<p>
<pre>
*** 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 *));
</pre>
</ul>
<hr>
<a href="index.html">Up one level</a> | Postfix FAQ

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -8,6 +8,14 @@
/* DESCRIPTION
/* .nf
/*
* SASL library.
*/
#ifdef USE_SASL_AUTH
#include <sasl.h>
#include <saslutil.h>
#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

View File

@ -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);
}

35
postfix/smtp/smtp_sasl.h Normal file
View File

@ -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
/*--*/

View File

@ -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 <sys_defs.h>
#include <stdlib.h>
#include <string.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
#endif
/*
* Utility library
*/
#include <msg.h>
#include <mymalloc.h>
#include <stringops.h>
#include <split_at.h>
/*
* Global library
*/
#include <mail_params.h>
#include <string_list.h>
#include <maps.h>
/*
* 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

View File

@ -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 <sys_defs.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
/* Global library. */
#include <mail_params.h>
/* 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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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[] = {

View File

@ -8,6 +8,14 @@
/* DESCRIPTION
/* .nf
/*
* SASL library.
*/
#ifdef USE_SASL_AUTH
#include <sasl.h>
#include <saslutil.h>
#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 *);

View File

@ -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,

View File

@ -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 <sys_defs.h>
#include <stdlib.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <namadr_list.h>
/* Global library. */
#include <mail_params.h>
#include <smtp_stream.h>
/* 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

View File

@ -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
/*--*/

View File

@ -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 <sys_defs.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
/* Global library. */
#include <mail_params.h>
#include <mail_proto.h>
#include <mail_error.h>
/* 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

View File

@ -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
/*--*/

View File

@ -45,6 +45,7 @@
#include <mymalloc.h>
#include <vstream.h>
#include <name_mask.h>
#include <msg.h>
/* 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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);