From: Wietse Venema Date: Mon, 17 Apr 2000 00:00:00 +0000 (+0000) Subject: snapshot-20000417 X-Git-Tag: v20010228~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1656957b3c88b56ff38a888983af1615846aa26a;p=thirdparty%2Fpostfix.git snapshot-20000417 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 71be58c3c..bab37d87a 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -3815,3 +3815,8 @@ Apologies for any names omitted. 20000416 Workaround: allow <(comment)> as SMTP MAIL FROM address. + +20000417 + + The SASL authentication in the SMTP server and client works, + but only on Linux and Solaris. diff --git a/postfix/INSTALL.sh b/postfix/INSTALL.sh index 9ee2aff27..545dbb934 100644 --- a/postfix/INSTALL.sh +++ b/postfix/INSTALL.sh @@ -46,7 +46,7 @@ EOF # in order to not disturb running programs. compare_or_replace() { - cmp $2 $3 >/dev/null 2>&1 || { + (cmp $2 $3 >/dev/null 2>&1 && echo Skipping $3...) || { echo Updating $3... rm -f $tempdir/junk || exit 1 cp $2 $tempdir/junk || exit 1 @@ -57,7 +57,7 @@ compare_or_replace() { } compare_or_symlink() { - cmp $1 $2 >/dev/null 2>&1 || { + (cmp $1 $2 >/dev/null 2>&1 && echo Skipping $2...) || { echo Updating $2... rm -f $tempdir/junk || exit 1 dest=`echo $1 | sed ' @@ -86,7 +86,7 @@ compare_or_symlink() { } compare_or_move() { - cmp $2 $3 >/dev/null 2>&1 || { + (cmp $2 $3 >/dev/null 2>&1 && echo Skipping $3...) || { echo Updating $3... mv -f $2 $3 || exit 1 chmod $1 $3 || exit 1 @@ -334,7 +334,8 @@ no) ;; done for file in man?/* do - (test -f $MANPAGES/$file && cmp -s $file $MANPAGES/$file) || { + (test -f $MANPAGES/$file && cmp -s $file $MANPAGES/$file && + echo Skipping $MANPAGES/$file...) || { echo Updating $MANPAGES/$file... rm -f $MANPAGES/$file cp $file $MANPAGES/$file || exit 1 diff --git a/postfix/SASL_README b/postfix/SASL_README index 3582305a9..7a9926c99 100644 --- a/postfix/SASL_README +++ b/postfix/SASL_README @@ -1,28 +1,33 @@ WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING =============================================================== -Do not use this code. In its present form, the cyrus SASL library -software is light years away from production quality - not enough -documentation to figure out how the software is supposed to work, -and not enough error checking to find out why it fails. That is -unacceptable for a security-sensitive application. +Do not use this code. The Postfix SASL support is based on the +Cyrus SASL library, which is light years away from production +quality. There is not enough documentation to figure out how the +software is supposed to work. -Contrary to expectation, this code works only LINUX. If you build -Postfix+SASL on other systems, the software builds without trouble, -but crashes in mysterious ways when you attempt to use it, and can -be made to work only with a considerable amount of tweaking. +The SASL library code works only on LINUX and Solaris. If you +build Postfix+SASL on other systems, the software builds without +trouble but fails at runtime due to no available authentication +mechanisms. It can be made to work with considerable tweaking. 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 much 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. -It is no-one's business what username and authentication method -the poster was using in order to access the mail server. +The Postfix SASL support (RFC 2554) was originally implemented by +Till Franke of SuSE Rhein/Main AG. The present code is a trimmed-down +version with only the bare necessities. + +When receiving mail, Postfix logs the client-provided username and +sender address to the maillog file, and optionally grants mail +relay access to authenticated clients. SASL authentication information +is not passed on via message headers or via SMTP. It is no-one's +business what username and authentication method the poster was +using in order to access the mail server. + +When sending mail, Postfix looks up the server hostname and if +a username/password is known, it will use that to authenticate +to the server. Building the SASL library ========================= @@ -32,15 +37,15 @@ from: ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/ -IMPORTANT: if you install the sasl libraries as per the default, +IMPORTANT: if you install the Cyrus SASL libraries as per the default, you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl. Building Postfix with SASL authentication support ================================================= To build Postfix with SASL authentication support, the following -assumes that the SASL include files are in /usr/local/include, and -that the SASL libraries are in /usr/local/lib. +assumes that the Cyrus SASL include files are in /usr/local/include, +and that the Cyrus SASL libraries are in /usr/local/lib. On some systems this generates the necessary Makefile definitions: @@ -56,8 +61,13 @@ otherwise ld.so will not find the SASL shared library: Enabling SASL authentication in the SMTP server =============================================== +If you installed the Cyrus SASL libraries as per the default, you +will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl. + See conf/sample-sasl.cf for examples. +In order to enable SASL support in the SMTP server: + /etc/postfix/main.cf: smtpd_sasl_auth_enable = yes @@ -72,12 +82,18 @@ mechanism the server will support, for example: pwcheck_method: shadow -This will use the Linux shadow passwd file, which is in fact the -only way that I was able to test, but which is undesirable from a -security point of view because it uses clear-text passwords. +This will use the Linux or Solaris shadow passwd file, which is +the only way that I was able to test, but which is undesirable +because it uses plaintext passwords. + +If you wish to use the system shadow password file, the Postfix +SMTP server can't run chrooted (see master.cf), and the postfix +user or group needs read access to the shadow passwd file. + +To run chrooted with SASL support is an interesting exercise. -To test, connect to the SMTP server, and you should be able to have -a conversation like this: +To test the whole mess, connect to the SMTP server, and you should +be able to have a conversation like this: 220 server.host.name ESMTP Postfix EHLO client.host.name @@ -91,8 +107,8 @@ a conversation like this: 235 Authentication successful Instead of dGVzdAB0ZXN0AHRlc3RwYXNz, specify the base64 encoded -form of username\0username\0password. The example above is for a -user named test with password testpass. +form of username\0username\0password (the \0 is a null byte). The +example above is for a user named `test' with password `testpass'. Enabling SASL authentication in the SMTP client =============================================== @@ -110,4 +126,4 @@ per-host username and password information. 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 into /var/spool/postfix/etc/postfix. +DB or DBM file into /var/spool/postfix/etc/postfix. diff --git a/postfix/conf/sample-auth.cf b/postfix/conf/sample-auth.cf index 412fc8134..a9b8f7c17 100644 --- a/postfix/conf/sample-auth.cf +++ b/postfix/conf/sample-auth.cf @@ -1,72 +1,43 @@ +# DO NOT EDIT THIS FILE. EDIT THE MAIN.CF FILE INSTEAD. THE STUFF +# HERE JUST SERVES AS AN EXAMPLE. +# # 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 = "" - +# As of now, SASL authentication support uses the Cyrus SASL library +# which is known to work on Linux and Solaris. + +# The smtpd_sasl_auth_enable parameter controls whether authentication +# is enabled in the Postfix SMTP server. +# +# If a client is authenticated, then it matches the permit_sasl_authenticated +# UCE restriction, which can be used to grant mail relay access. +# +# In order to enable server-side authentication, build Postfix with +# SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf +# with as contents, for example, +# +# pwcheck_method: PAM +# +# or whatever is suitable for your environment. The PAM service name +# for SASL authentication is "smtp". +# +# If you run your SMTP server chrooted, then you need to copy the +# PAM and SASL support libraries and data files into the chroot jail. +# +smtpd_sasl_auth_enable = yes + +# The smtp_sasl_auth_enable parameter controls whether authentication +# is enabled in the Postfix SMTP client. +# +smtp_sasl_auth_enable = yes + +# The smtp_sasl_password_maps parameter specifies the names of lookup +# tables with one username:password entry per remote hostname. If a +# remote host has no username:password entry, then Postfix will not +# attempt to authenticate to the host. +# +# The Postifx SMTP client opens the lookup table before going to +# chroot jail, so you can keep the password file in /etc/postfix. +# +smtp_auth_passwd_map = hash:/etc/postfix/saslpass diff --git a/postfix/conf/sample-tls.cf b/postfix/conf/sample-tls.cf deleted file mode 100644 index 97444df4f..000000000 --- a/postfix/conf/sample-tls.cf +++ /dev/null @@ -1,277 +0,0 @@ -# This file contains example settings of Postfix configuration -# parameters that control the behaviour of the TLS extensions. -# -# We strictly seperate between server side TLS (smtpd_) and client side -# TLS (smtp_), as for practical reasons we might choose differently. - -# Section with SMTPD specific settings - -# To use TLS we do need a certificate and a private key. Both must be in -# "pem" format, the private key must not be encrypted, that does mean: -# it must be accessable without password. Both parts (certificate and -# private key) may be in the same file. -# -# smtpd_tls_cert_file = /etc/postfix/server.pem -# smtpd_tls_key_file = $tls_cert_file - -# The certificate was issued by a certification authority (CA), of which -# the CA-cert must be available. This file may also contain the the -# CA certificates of other trusted CAs. You must use this file for the -# list of trusted CAs if you want to use chroot-mode. -# -# smtpd_tls_CAfile = /etc/postfix/CAcert.pem - -# To verify the peer certificate, we need to know the certificates of -# certification authorities. These certificates in "pem" format are -# collected in a directory. The same CAs are offered to clients for -# client verification. Don't forget to create the necessary "hash" -# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical -# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is -# no default and you explicitly have to set the value here! -# This will not work in chroot mode, use the tls_CAfile instead. -# -smtpd_tls_CApath = /etc/postfix/certs - -# To get additional information during the TLS setup and negotiations -# you can increase the loglevel from 0..4: -# 0: No output about the TLS subsystem -# 1: Printout startup and certificate information -# 2: 1 + Printout of levels during negotiation -# 3: 2 + Hex and ASCII dump of negotiation process -# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS -# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly -# discouraged. -# -# smtpd_tls_loglevel = 0 - -# To include information about the protocol and cipher used as well as the -# client and issuer CommonName into the "Received:" header, set the -# smtpd_tls_received_header variable to true. The default is no, as the -# information is not necessarily authentic. Only the final destination -# is reliable, since the headers might have been changed in between. -# -#smtpd_tls_received_header = true - -# By default TLS is disabled, so no difference to plain postfix is visible. -# Explicitely switch it on here: -# -smtpd_use_tls = yes - -# You can ENFORCE the use of TLS, so that no commands (except QUIT of course) -# are allowed without TLS. According to RFC2487 this MUST NOT be applied -# in case of a publicly-referenced SMTP server. So this option is off -# by default and should only seldom be used. Using this option implies -# smtpd_use_tls = yes -# -# smtpd_enforce_tls = no - -# To receive a client certificate, the server must explicitly ask for one. -# Hence netscape will either complain if no certificate is available (for -# the list of CAs in /etc/postfix/certs) or will offer you client certificates -# to choose from. This might be annoying, so this option is "off" by default. -# You will however need the certificate if you want to to e.g. certificate -# based relaying. -# -# smtpd_tls_ask_ccert = no - -# You may also decide to REQUIRE a client certificate to allow TLS connections. -# I don't think it will be necessary often, it is however included here for -# completeness. This option implies smtpd_tls_ask_ccert = yes -# -# smtpd_tls_req_ccert = no - -# The verification depth for client certificates. The default (1) is -# sufficient, if the client certificate ist directly issued by a CA -# listed under $tls_CApath -# -# smtpd_tls_ccert_vd = 1 - -# One additional option has been added for relay control to the UCE rules: -# check_relay_ccerts. If this option is added to smtpd_recipient_restrictions -# postfix will relay if a valid client certificate is presented and in the -# list of client certs (relay_clientcerts). -# -# smtpd_recipient_restrictions = check_relay_ccerts - -# The list of client certificates for which relaying will be allowed. -# Unfortunately the routines for lists in postfix use whitespaces as -# seperators and choke on special chars. So using the certificate -# X509ONELINES is quite impractical. We will use the fingerprints at -# this point, as they are difficult to fake but easy to use for lookup. -# There is just one small problem: The colon ':' is interpreted as -# seperator between database type and filename, so we must avoid it. -# We use the underscore "_" instead. -# As postmap (when using e.g. db) insists of having a pair of key and value, -# but we only need the key, the value can be chosen freely, e.g. the name -# of the user or host: -# D7_04_2F_A7_0B_8C_A5_21_FA_31_77_E1_41_8A_EE_80 lutzpc.at.home -# -# relay_clientcerts = hash:/etc/postfix/relay_clientcerts - -# Section with SMTP specific settings - -# During the startup negotiation we might present a certificate to the server. -# Netscape is rather clever here and lets the user select between only those -# certs that will match the CAs accepted from the server. As I simply use -# the integrated "SSL_connect()" from the OpenSSL package, this is not -# possible by now and we have to chose just one cert. -# So for now the default is to use _no_ cert and key unless explictly -# set here. It is possible to use the same key/cert pair as for the server. -# If a cert is to be presented, it must be in "pem" format, the private key -# must not be encrypted, that does mean: it must be accessable without -# password. Both parts (certificate and # private key) may be in the -# same file. -# -smtp_tls_cert_file = /etc/postfix/server.pem -smtp_tls_key_file = $tls_cert_file - -# The certificate was issued by a certification authority (CA), of which -# the CA-cert must be available. This file may also contain the the -# CA certificates of other trusted CAs. You must use this file for the -# list of trusted CAs if you want to use chroot-mode. -# No default is supplied for this value as of now. -# -smtp_tls_CAfile = /etc/postfix/CAcert.pem - -# To verify the peer certificate, we need to know the certificates of -# certification authorities. These certificates in "pem" format are -# collected in a directory. Don't forget to create the necessary "hash" -# links with $OPENSSL_HOME/bin/c_rehash /etc/postfix/certs. A typical -# place for the CA-certs may also be $OPENSSL_HOME/certs, so there is -# no default and you explicitly have to set the value here! -# This will not work in chroot mode, use the tls_CAfile instead. -# -smtp_tls_CApath = /etc/postfix/certs - -# To get additional information during the TLS setup and negotiations -# you can increase the loglevel from 0..4: -# 0: No output about the TLS subsystem -# 1: Printout startup and certificate information -# 2: 1 + Printout of levels during negotiation -# 3: 2 + Hex and ASCII dump of negotiation process -# 4: 3 + Hex and ASCII dump of complete transmission after STARTTLS -# Use loglevel 3 only in case of problems. Use of loglevel 4 is strongly -# discouraged. -# -smtp_tls_loglevel = 0 - -# By default TLS is disabled, so no difference to plain postfix is visible. -# If you enable TLS it will be used when offered by the server. -# WARNING: I didn't have access to other software (except those explicitely -# listed) to test the interaction. On corresponding mailing list -# there was a discussion going on about MS exchange servers offering -# STARTTLS even if it is not configured, so it might be wise to not -# use this option on your central mail hub, as you don't know in advance -# whether you are going to hit such host. Use the recipient/site specific -# options instead. -# -# In case of failure, a "4xx" code is issued and the mail stays in the queue. -# -# Explicitely switch it on here, if you really wish it: -# -smtp_use_tls = yes - -# As generally trying TLS can be a bad idea (some hosts offer STARTTLS but -# the negotiation will fail leading to unexplainable failures, it is a better -# idea to decide based on the recipient or the mailhub to which you are -# connecting. -# -# Recipient: The host/domain part of the recipients email address: -# for "joe@dom.ain" the "dom.ain" is used for the 'recipient' matching. -# -# To try to use TLS whenever email is sent to somebody matching the recipient -# domain "dom.ain", add it to the "use_tls_recipients" list. The STARTTLS -# option is recognized and used regardless of the MX to which the smtp client -# does connect. -# -smtp_use_tls_recipients = dom.ain, hash:/etc/postfix/use_tls_recipients -# -# Site: The name of the host the email is actually delivered to. -# -# To try to use TLS whenever a certain MX is used to deliver an email, -# add it to the "use_tls_sites" list: -# -smtp_use_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/use_tls_sites -# -# The matching is done as a domain match, such that "some.where.else" will -# match all hosts in the domain "some.where.else", e.g. -# mailhost.some.where.else. For this reason, this option is named .._sites -# and not .._hosts. -# -# These options will only use STARTTLS if it is offered. If it is not offered, -# the mail will be delivered without encryption or authentication!! See also -# the "enforce" options below. - -# You can ENFORCE the use of TLS, so that only connections with TLS will -# be accepted. Additionally, the hostname of the receiving host is matched -# against the CommonName in the certificate. Also, the certificate must -# be verified "Ok", so that a CA trusted by the client must have issued -# the certificate. If the certificate doesn't verify or the hostname doesn't -# match, a "4xx" # will be issued and the mail stays in the queue. -# The hostname used in the check is beyond question, as it must be the -# principle hostname (no CNAME allowed here). -# -# This option is useful only if you are definitely sure that you will only -# connect to servers supporting RFC2487 _and_ with valid certificates. -# I use it for my clients which will only send email to one mailhub, which -# does offer the necessary STARTTLS support. -# -# smtp_enforce_tls = no - -# For a per_site or per_recipient decision, use the corresponding lists. -# -# Recipient: The host/domain part of the recipients email address: -# for "joe@dom.ain" the "dom.ain" is used for the 'recipient' matching. -# -# To enforce the use of TLS whenever email is sent to somebody matching the -# recipient domain "dom.ain", add it to the "enforce_tls_recipients" list. -# This way the email is only sent with encryption and authentication, -# regardless of the MX to which the smtp client does connect. This way you -# can assure that your email really is delivered to the correct MX; the -# correctness of the MX nameserver record cannot be checked from postfix, -# however. -# Please note, that the authentication process requires that you recognize -# the CA that issued the server certificate! -# -smtp_enforce_tls_recipients = dom.ain, hash:/etc/postfix/enforce_tls_recipients -# -# Site: The name of the host the email is actually delivered to. -# -# To enforce the use of TLS whenever a certain MX is used to deliver an email, -# add it to the "enforce_tls_sites" list: -# -smtp_enforce_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/enforce_tls_sites -# -# The matching is done as a domain match, such that "some.where.else" will -# match all hosts in the domain "some.where.else", e.g. -# mailhost.some.where.else. For this reason, this option is named .._sites -# and not .._hosts. - -# In case the client use of TLS is explicitely turned on, a list of -# sites/hosts can be given for which no STARTTLS negotiation will be -# started, e.g. because it is already known that it might fail for some -# reason. It makes no sense for recipients, only receiving mail servers, -# so only the "smtp_no_tls_sites" is offered, but not an equivalent -# ".._recipients" option. -# -# HINT: This list is only checked when TLS usage is generally turned on -# (usage or enforcement). If the recieving host/recipient is listed by the -# specific "use/enforce_tls_sites/recipients" options, this setting has -# precedence in any case and STARTTLS will be negotiated. No warning is given. -# -smtp_no_tls_sites = mailhost.some.where, some.where.else, hash:/etc/postfix/no_tls_sites - -# The verification depth for certificates. The default (1) is sufficient, -# if the certificate ist directly issued by a CA listed under $tls_CApath -# -# smtp_tls_ccert_vd = 1 - -# As we decide on a "per site" basis, wether to use TLS or not, it would be -# good to have a list of sites, that offered "STARTTLS'. We can collect it -# ourselves with this option. -# -# If activated and TLS is not already enabled for this host, a line is added -# to the logfile: -# postfix/smtp[pid]: Host offered STARTTLS: [name.of.host] -# -smtp_tls_note_starttls_offer = yes diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index dac3dd1cb..3be0516b4 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20000416" +#define DEF_MAIL_VERSION "Snapshot-20000417" extern char *var_mail_version; /* LICENSE diff --git a/postfix/smtp/smtp.c b/postfix/smtp/smtp.c index f3091afad..00d5ac1f7 100644 --- a/postfix/smtp/smtp.c +++ b/postfix/smtp/smtp.c @@ -36,6 +36,7 @@ /* RFC 1651 (SMTP service extensions) /* RFC 1870 (Message Size Declaration) /* RFC 2197 (Pipelining) +/* RFC 2554 (AUTH command) /* DIAGNOSTICS /* Problems and transactions are logged to \fBsyslogd\fR(8). /* Corrupted message files are marked so that the queue manager can @@ -93,6 +94,12 @@ /* Skip servers that greet us with a 5xx status code. /* .IP \fBsmtp_skip_quit_response\fR /* Do not wait for the server response after sending QUIT. +/* .SH "Authentication controls" +/* .IP \fBsmtp_enable_sasl_auth\fR +/* Enable per-session authentication as per RFC 2554 (SASL). +/* .IP \fBsmtp_sasl_password_maps\fR +/* Lookup tables with per-host \fIname\fR:\fIpassword\fR entries. +/* No entry for a host means no attempt to authenticate. /* .SH "Resource controls" /* .ad /* .fi @@ -343,6 +350,16 @@ static void pre_accept(char *unused_name, char **unused_argv) } } +/* pre_exit - pre-exit cleanup */ + +static void pre_exit(void) +{ +#ifdef USE_SASL_AUTH + if (var_smtp_sasl_enable) + sasl_done(); +#endif +} + /* main - pass control to the single-threaded skeleton */ int main(int argc, char **argv) @@ -388,5 +405,6 @@ int main(int argc, char **argv) MAIL_SERVER_BOOL_TABLE, bool_table, MAIL_SERVER_PRE_INIT, pre_init, MAIL_SERVER_PRE_ACCEPT, pre_accept, + MAIL_SERVER_EXIT, pre_exit, 0); } diff --git a/postfix/smtp/smtp_proto.c b/postfix/smtp/smtp_proto.c index 8e0b7c8c2..600280160 100644 --- a/postfix/smtp/smtp_proto.c +++ b/postfix/smtp/smtp_proto.c @@ -222,7 +222,7 @@ int smtp_helo(SMTP_STATE *state) else if (strcasecmp(word, "SIZE") == 0) state->features |= SMTP_FEATURE_SIZE; #ifdef USE_SASL_AUTH - else if (strcasecmp(word, "AUTH") == 0) + else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0) smtp_sasl_helo_auth(state, words); #endif else if (strcasecmp(word, var_myhostname) == 0) { @@ -238,7 +238,7 @@ int smtp_helo(SMTP_STATE *state) msg_info("server features: 0x%x", state->features); #ifdef USE_SASL_AUTH - if (state->features & SMTP_FEATURE_AUTH) + if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH)) return (smtp_sasl_helo_login(state)); #endif diff --git a/postfix/smtp/smtp_sasl.h b/postfix/smtp/smtp_sasl.h index 1c6ec6f76..43c721006 100644 --- a/postfix/smtp/smtp_sasl.h +++ b/postfix/smtp/smtp_sasl.h @@ -13,10 +13,14 @@ */ extern void smtp_sasl_initialize(void); extern void smtp_sasl_connect(SMTP_STATE *); +extern int smtp_sasl_passwd_lookup(SMTP_STATE *); extern void smtp_sasl_start(SMTP_STATE *); extern int smtp_sasl_authenticate(SMTP_STATE *, VSTRING *); extern void smtp_sasl_cleanup(SMTP_STATE *); +extern void smtp_sasl_helo_auth(SMTP_STATE *, const char *); +extern int smtp_sasl_helo_login(SMTP_STATE *); + /* LICENSE /* .ad /* .fi diff --git a/postfix/smtp/smtp_sasl_glue.c b/postfix/smtp/smtp_sasl_glue.c index 5d87d1440..105904379 100644 --- a/postfix/smtp/smtp_sasl_glue.c +++ b/postfix/smtp/smtp_sasl_glue.c @@ -14,6 +14,9 @@ /* void smtp_sasl_start(state) /* SMTP_STATE *state; /* +/* int smtp_sasl_passwd_lookup(state) +/* SMTP_STATE *state; +/* /* int smtp_sasl_authenticate(state, why) /* SMTP_STATE *state; /* VSTRING *why; @@ -32,10 +35,16 @@ /* routine must be called once per session before doing any SASL /* authentication. /* +/* smtp_sasl_passwd_lookup() looks up the username/password +/* for the current SMTP server. The result is zero in case +/* of failure. +/* /* 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. +/* This routine must be called only when smtp_sasl_passwd_lookup() +/* suceeds. /* /* smtp_sasl_cleanup() cleans up. It must be called at the /* end of every SMTP session that uses SASL authentication. @@ -175,7 +184,7 @@ static int smtp_sasl_get_passwd(sasl_conn_t *conn, void *context, /* smtp_sasl_passwd_lookup - password lookup routine */ -static void smtp_sasl_passwd_lookup(SMTP_STATE *state) +int smtp_sasl_passwd_lookup(SMTP_STATE *state) { char *myname = "smtp_sasl_passwd_lookup"; const char *value; @@ -190,19 +199,21 @@ static void smtp_sasl_passwd_lookup(SMTP_STATE *state) /* * 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 : ""); + if (msg_verbose) + msg_info("%s: host `%s' user `%s' pass `%s'", + myname, state->session->host, + state->sasl_username, state->sasl_passwd); + return(1); } else { - state->sasl_username = mystrdup(var_myhostname); - state->sasl_passwd = mystrdup(""); + if (msg_verbose) + msg_info("%s: host `%s' no auth info found", + myname, state->session->host); + return(0); } - 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) */ @@ -276,7 +287,8 @@ void smtp_sasl_start(SMTP_STATE *state) 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, + if (sasl_client_new("smtp", state->session->host, + state->sasl_callbacks, NULL_SECFLAGS, (sasl_conn_t **) &state->sasl_conn) != SASL_OK) msg_fatal("per-session SASL client initialization"); smtp_sasl_passwd_lookup(state); @@ -323,6 +335,8 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why) #define NO_SASL_SECRET 0 #define NO_SASL_INTERACTION 0 +#define NO_SASL_LANGLIST ((const char *) 0) +#define NO_SASL_OUTLANG ((const char **) 0) if (msg_verbose) msg_info("%s: %s: SASL mechanisms %s", @@ -335,9 +349,13 @@ int smtp_sasl_authenticate(SMTP_STATE *state, VSTRING *why) 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); + if (result != SASL_OK && result != SASL_CONTINUE) { + vstring_sprintf(why, "cannot SASL authenticate to server %s: %s", + state->session->namaddr, + sasl_errstring(result, NO_SASL_LANGLIST, + NO_SASL_OUTLANG)); + return (-1); + } /* * Send the AUTH command and the optional initial client response. diff --git a/postfix/smtp/smtp_sasl_proto.c b/postfix/smtp/smtp_sasl_proto.c index ecc9b76cf..2b17e47fc 100644 --- a/postfix/smtp/smtp_sasl_proto.c +++ b/postfix/smtp/smtp_sasl_proto.c @@ -10,7 +10,7 @@ /* SMTP_STATE *state; /* const char *words; /* -/* void smtp_sasl_helo_login(state) +/* int smtp_sasl_helo_login(state) /* SMTP_STATE *state; /* DESCRIPTION /* This module contains random chunks of code that implement @@ -22,7 +22,8 @@ /* /* smtp_sasl_helo_login() authenticates the SMTP client to the /* SMTP server, using the authentication mechanism information -/* given by the server. +/* given by the server. The result is a Postfix delivery status +/* code in case of trouble. /* /* Arguments: /* .IP state @@ -77,18 +78,16 @@ 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; - } + 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; } } @@ -97,15 +96,19 @@ void smtp_sasl_helo_auth(SMTP_STATE *state, const char *words) int smtp_sasl_helo_login(SMTP_STATE *state) { VSTRING *why = vstring_alloc(10); - int ret; + int ret = 0; /* - * XXX If authentication fails, should we try anonymous authentication? + * Skip authentication when we have no authentication info for this + * server. In that case it should simply treat us like any stranger. + * Otherwise, if authentication fails assume the error is recoverable. */ - smtp_sasl_start(state); - if (smtp_sasl_authenticate(state, why) <= 0) - ret = smtp_site_fail(state, 450, "Authentication failed: %s", - vstring_str(why)); + if (smtp_sasl_passwd_lookup(state) != 0) { + 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); }