Browse Source

add SASL2 support

master
parent
commit
9f7da5ec5a
  1. 715
      postfix/postfix-sasl2.patch
  2. 20
      postfix/postfix.spec

715
postfix/postfix-sasl2.patch

@ -0,0 +1,715 @@
diff -ru postfix-1.1.4-orig/README_FILES/SASL_README postfix-1.1.4/README_FILES/SASL_README
--- postfix-1.1.4-orig/README_FILES/SASL_README Sat May 26 11:32:47 2001
+++ postfix-1.1.4/README_FILES/SASL_README Mon Mar 11 14:04:58 2002
@@ -26,6 +26,14 @@
Note that this seems to be related to the auto_transition switch in
SASL. Note also that the Cyrus SASL documentation says that it is
pointless to enable that if you use "sasldb" for "pwcheck_method".
+Later versions of the SASL 1.5.x series should also work.
+
+Postfix+SASL 2.1.1 appears to work on Mandrake Linux 8.1 (pwcheck_method
+set to saslauthd or auxprop). Note that the 'auxprop' pwcheck_method
+replaces the 'sasldb' method from SASL 1.5.x. Postfix may need
+write access to /etc/sasldb2 if you are using the auto_transition
+feature, or if you are using an authentication mechanism such as OTP
+that needs to update secrets in the database.
Introduction
============
@@ -50,20 +58,22 @@
Building the SASL library
=========================
-Postfix appears to work with cyrus-sasl-1.5.5, which is available
-from:
+Postfix appears to work with cyrus-sasl-1.5.5 or cyrus-sasl-2.1.1,
+which are available from:
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
IMPORTANT: if you install the Cyrus SASL libraries as per the default,
-you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
+you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl for
+version 1.5.5 or /usr/lib/sasl2 -> /usr/local/lib/sasl2 for version 2.1.1.
Reportedly, Microsoft Internet Explorer version 5 requires the
non-standard SASL LOGIN authentication method. To enable this
authentication method, specify ``./configure --enable-login''.
If you install the Cyrus SASL libraries as per the default, you
-will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
+will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl for version 1.5.5
+or symlink /usr/lib/sasl2 -> /usr/local/lib/sasl2 for version 2.1.1.
Building Postfix with SASL authentication support
=================================================
@@ -72,19 +82,33 @@
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:
+On some systems this generates the necessary Makefile definitions for
+Cyrus SASL 1.5.5:
% make tidy # if you have left-over files from a previous build
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
AUXLIBS="-L/usr/local/lib -lsasl"
+On some systems this generates the necessary Makefile definitions for
+Cyrus SASL 2.1.1:
+
+ % make tidy # if you have left-over files from a previous build
+ % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
+ AUXLIBS="-L/usr/local/lib -lsasl2"
+
On Solaris 2.x you need to specify run-time link information,
otherwise ld.so will not find the SASL shared library:
+(for version 1.5.5):
% make tidy # if you have left-over files from a previous build
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
+(for version 2.1.1):
+ % make tidy # if you have left-over files from a previous build
+ % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
+ AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl2"
+
Enabling SASL authentication in the Postfix SMTP server
=======================================================
@@ -101,23 +125,41 @@
smtpd_recipient_restrictions =
permit_mynetworks permit_sasl_authenticated ...
-In /usr/local/lib/sasl/smtpd.conf you need to specify how the server
-should validate client passwords.
+In /usr/local/lib/sasl/smtpd.conf (for version 1.5.5) or
+/usr/local/lib/sasl2/smtpd.conf (for version 2.1.1) you need to
+specify how the server should validate client passwords.
In order to authenticate against the UNIX password database, try:
/usr/local/lib/sasl/smtpd.conf:
pwcheck_method: pwcheck
+ (use /usr/local/lib/sasl2/smtpd.conf with version 2.1.1)
The pwcheck daemon is contained in the cyrus-sasl source tarball.
-In order to authenticate against SASL's own password database:
+Alternately, in SASL 1.5.27 and later (including 2.1.1), try:
+
+ /usr/local/lib/sasl/smtpd.conf:
+ pwcheck_method: saslauthd
+ (use /usr/local/lib/sasl2/smtpd.conf with version 2.1.1)
+
+The saslauthd daemon is also contained in the cyrus-sasl source tarball.
+It is more flexible than the pwcheck daemon, in that it can authenticate
+against PAM and various other sources.
+
+In order to authenticate against SASL's own password database in version 1.5.5:
/usr/local/lib/sasl/smtpd.conf:
pwcheck_method: sasldb
-This will use the SASL password file (default: /etc/sasldb), which
-is maintained with the saslpasswd command (part of the Cyrus SASL
+or in version 2.1.1:
+
+ /usr/local/lib/sasl2/smtpd.conf:
+ pwcheck_method: auxprop
+
+This will use the SASL password file (default: /etc/sasldb in
+version 1.5.5, or /etc/sasldb2 in version 2.1.1), which is maintained
+with the saslpasswd or saslpasswd2 command (part of the Cyrus SASL
software). On some poorly-supported systems the saslpasswd command
needs to be run multiple times before it stops complaining. The
Postfix SMTP server needs read access to the sasldb file - you may
diff -ru postfix-1.1.4-orig/conf/sample-auth.cf postfix-1.1.4/conf/sample-auth.cf
--- postfix-1.1.4-orig/conf/sample-auth.cf Mon Mar 11 00:44:43 2002
+++ postfix-1.1.4/conf/sample-auth.cf Mon Mar 11 17:36:22 2002
@@ -23,6 +23,7 @@
#
# In order to enable server-side authentication, build Postfix with
# SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf
+# (for SASL version 1) or /usr/lib/sasl2/smtpd.conf (for SASL version 2)
# with as contents, for example,
#
# pwcheck_method: sasldb
@@ -51,6 +52,10 @@
# nodictionary: disallow methods subject to passive (dictionary) attack
# noanonymous: disallow methods that allow anonymous authentication
#
+# An additional options is available in SASL version 2:
+#
+# mutual_auth: only allow methods that provide mutual authentication
+#
# By default, the Postfix SMTP server accepts plaintext passwords but
# not anonymous logins.
#
@@ -104,6 +109,10 @@
# nodictionary: disallow methods subject to passive (dictionary) attack
# noanonymous: disallow methods that allow anonymous authentication
#
+# An additional options is available in SASL version 2:
+#
+# mutual_auth: only allow methods that provide mutual authentication
+#
# By default, the Postfix SMTP client will not use plaintext passwords.
#
#smtp_sasl_security_options =
diff -ru postfix-1.1.4-orig/src/lmtp/lmtp_sasl_glue.c postfix-1.1.4/src/lmtp/lmtp_sasl_glue.c
--- postfix-1.1.4-orig/src/lmtp/lmtp_sasl_glue.c Fri Jan 19 15:46:44 2001
+++ postfix-1.1.4/src/lmtp/lmtp_sasl_glue.c Mon Mar 11 17:35:33 2002
@@ -116,6 +116,9 @@
"noactive", SASL_SEC_NOACTIVE,
"nodictionary", SASL_SEC_NODICTIONARY,
"noanonymous", SASL_SEC_NOANONYMOUS,
+#if SASL_VERSION_MAJOR >= 2
+ "mutual_auth", SASL_SEC_MUTUAL_AUTH,
+#endif
0,
};
@@ -127,6 +130,44 @@
#define STR(x) vstring_str(x)
/*
+ * Macros to handle API differences between SASLv1 and SASLv2.
+ * Specifics:
+ * The SASL_LOG_* constants were renamed in SASLv2.
+ * SASLv2's sasl_client_new takes two new parameters to specify local
+ * and remote IP addresses for auth mechs that use them.
+ * SASLv2's sasl_client_start function no longer takes the secret parameter.
+ * SASLv2's sasl_decode64 function takes an extra parameter for the
+ * length of the output buffer.
+ *
+ * The other major change is that SASLv2 now takes more responsibility for
+ * deallocating memory that it allocates internally. Thus, some of the
+ * function parameters are now 'const', to make sure we don't try to free
+ * them too. This is dealt with in the code later on.
+ */
+
+#if SASL_VERSION_MAJOR < 2
+/* SASL version 1.x */
+#define SASL_LOG_WARN SASL_LOG_WARNING
+#define SASL_LOG_NOTE SASL_LOG_INFO
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+ sasl_client_new(srv, fqdn, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+ sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outlen)
+#endif
+
+#if SASL_VERSION_MAJOR >= 2
+/* SASL version > 2.x */
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+ sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+ sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outmaxlen, outlen)
+#endif
+
+ /*
* Per-host login/password information.
*/
static MAPS *lmtp_sasl_passwd_map;
@@ -137,14 +178,18 @@
const char *message)
{
switch (priority) {
- case SASL_LOG_ERR:
- case SASL_LOG_WARNING:
- msg_warn("%s", message);
+ case SASL_LOG_ERR: /* unusual errors */
+ case SASL_LOG_WARN: /* non-fatal warnings */
+ msg_warn("SASL authentication problem: %s", message);
break;
- case SASL_LOG_INFO:
+ case SASL_LOG_NOTE: /* other info */
if (msg_verbose)
- msg_info("%s", message);
+ msg_info("SASL authentication info: %s", message);
break;
+#if SASL_VERSION_MAJOR >= 2
+ case SASL_LOG_FAIL: /* authentication failures - SASLv2 only */
+ msg_warn("SASL authentication failure: %s", message);
+#endif
}
return (SASL_OK);
}
@@ -317,7 +362,9 @@
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,
+
+ if (SASL_CLIENT_NEW("smtp", state->session->host,
+ NULL, NULL,
state->sasl_callbacks, NULL_SECFLAGS,
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)
msg_fatal("per-session SASL client initialization");
@@ -354,7 +401,11 @@
char *myname = "lmtp_sasl_authenticate";
unsigned enc_length;
unsigned enc_length_out;
+#if SASL_VERSION_MAJOR >= 2
+ const char *clientout;
+#else
char *clientout;
+#endif
unsigned clientoutlen;
unsigned serverinlen;
LMTP_RESP *resp;
@@ -374,7 +425,7 @@
/*
* Start the client side authentication protocol.
*/
- result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
+ result = SASL_CLIENT_START((sasl_conn_t *) state->sasl_conn,
state->sasl_mechanism_list,
NO_SASL_SECRET, NO_SASL_INTERACTION,
&clientout, &clientoutlen, &mechanism);
@@ -404,7 +455,10 @@
STR(state->sasl_encoded), enc_length,
&enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(clientout);
+#endif
lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
} else {
lmtp_chat_cmd(state, "AUTH %s", mechanism);
@@ -423,8 +477,8 @@
(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) {
+ if (SASL_DECODE64(line, serverinlen, STR(state->sasl_decoded),
+ serverinlen, &enc_length) != SASL_OK) {
vstring_sprintf(why, "malformed SASL challenge from server %s",
state->session->namaddr);
return (-1);
@@ -456,7 +510,10 @@
STR(state->sasl_encoded), enc_length,
&enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(clientout);
+#endif
} else {
vstring_strcat(state->sasl_encoded, "");
}
@@ -487,7 +544,8 @@
state->sasl_passwd = 0;
}
if (state->sasl_mechanism_list) {
- myfree(state->sasl_mechanism_list); /* allocated in lmtp_helo */
+ /* state->sasl_mechanism_list is allocated in lmtp_sasl_helo_auth */
+ myfree(state->sasl_mechanism_list);
state->sasl_mechanism_list = 0;
}
if (state->sasl_conn) {
diff -ru postfix-1.1.4-orig/src/smtp/smtp_sasl_glue.c postfix-1.1.4/src/smtp/smtp_sasl_glue.c
--- postfix-1.1.4-orig/src/smtp/smtp_sasl_glue.c Mon Jul 2 14:12:54 2001
+++ postfix-1.1.4/src/smtp/smtp_sasl_glue.c Mon Mar 11 17:35:41 2002
@@ -116,6 +116,9 @@
"noactive", SASL_SEC_NOACTIVE,
"nodictionary", SASL_SEC_NODICTIONARY,
"noanonymous", SASL_SEC_NOANONYMOUS,
+#if SASL_VERSION_MAJOR >= 2
+ "mutual_auth", SASL_SEC_MUTUAL_AUTH,
+#endif
0,
};
@@ -127,6 +130,44 @@
#define STR(x) vstring_str(x)
/*
+ * Macros to handle API differences between SASLv1 and SASLv2.
+ * Specifics:
+ * The SASL_LOG_* constants were renamed in SASLv2.
+ * SASLv2's sasl_client_new takes two new parameters to specify local
+ * and remote IP addresses for auth mechs that use them.
+ * SASLv2's sasl_client_start function no longer takes the secret parameter.
+ * SASLv2's sasl_decode64 function takes an extra parameter for the
+ * length of the output buffer.
+ *
+ * The other major change is that SASLv2 now takes more responsibility for
+ * deallocating memory that it allocates internally. Thus, some of the
+ * function parameters are now 'const', to make sure we don't try to free
+ * them too. This is dealt with in the code later on.
+ */
+
+#if SASL_VERSION_MAJOR < 2
+/* SASL version 1.x */
+#define SASL_LOG_WARN SASL_LOG_WARNING
+#define SASL_LOG_NOTE SASL_LOG_INFO
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+ sasl_client_new(srv, fqdn, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+ sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outlen)
+#endif
+
+#if SASL_VERSION_MAJOR >= 2
+/* SASL version > 2.x */
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+ sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+ sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outmaxlen, outlen)
+#endif
+
+ /*
* Per-host login/password information.
*/
static MAPS *smtp_sasl_passwd_map;
@@ -137,14 +178,18 @@
const char *message)
{
switch (priority) {
- case SASL_LOG_ERR:
- case SASL_LOG_WARNING:
+ case SASL_LOG_ERR: /* unusual errors */
+ case SASL_LOG_WARN: /* non-fatal warnings */
msg_warn("SASL authentication problem: %s", message);
break;
- case SASL_LOG_INFO:
+ case SASL_LOG_NOTE: /* other info */
if (msg_verbose)
msg_info("SASL authentication info: %s", message);
break;
+#if SASL_VERSION_MAJOR >= 2
+ case SASL_LOG_FAIL: /* authentication failures - SASLv2 only */
+ msg_warn("SASL authentication failure: %s", message);
+#endif
}
return (SASL_OK);
}
@@ -317,7 +362,9 @@
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,
+
+ if (SASL_CLIENT_NEW("smtp", state->session->host,
+ NULL, NULL,
state->sasl_callbacks, NULL_SECFLAGS,
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)
msg_fatal("per-session SASL client initialization");
@@ -354,7 +401,11 @@
char *myname = "smtp_sasl_authenticate";
unsigned enc_length;
unsigned enc_length_out;
+#if SASL_VERSION_MAJOR >= 2
+ const char *clientout;
+#else
char *clientout;
+#endif
unsigned clientoutlen;
unsigned serverinlen;
SMTP_RESP *resp;
@@ -374,7 +425,7 @@
/*
* Start the client side authentication protocol.
*/
- result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
+ result = SASL_CLIENT_START((sasl_conn_t *) state->sasl_conn,
state->sasl_mechanism_list,
NO_SASL_SECRET, NO_SASL_INTERACTION,
&clientout, &clientoutlen, &mechanism);
@@ -404,7 +455,10 @@
STR(state->sasl_encoded), enc_length,
&enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(clientout);
+#endif
smtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
} else {
smtp_chat_cmd(state, "AUTH %s", mechanism);
@@ -423,8 +477,8 @@
(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) {
+ if (SASL_DECODE64(line, serverinlen, STR(state->sasl_decoded),
+ serverinlen, &enc_length) != SASL_OK) {
vstring_sprintf(why, "malformed SASL challenge from server %s",
state->session->namaddr);
return (-1);
@@ -456,7 +510,10 @@
STR(state->sasl_encoded), enc_length,
&enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(clientout);
+#endif
} else {
vstring_strcat(state->sasl_encoded, "");
}
@@ -487,7 +544,8 @@
state->sasl_passwd = 0;
}
if (state->sasl_mechanism_list) {
- myfree(state->sasl_mechanism_list); /* allocated in smtp_helo */
+ /* state->sasl_mechanism_list is allocated in smtp_sasl_helo_auth */
+ myfree(state->sasl_mechanism_list);
state->sasl_mechanism_list = 0;
}
if (state->sasl_conn) {
diff -ru postfix-1.1.4-orig/src/smtpd/smtpd.h postfix-1.1.4/src/smtpd/smtpd.h
--- postfix-1.1.4-orig/src/smtpd/smtpd.h Mon Mar 11 00:44:45 2002
+++ postfix-1.1.4/src/smtpd/smtpd.h Mon Mar 11 14:04:58 2002
@@ -69,7 +69,11 @@
off_t msg_size;
int junk_cmds;
#ifdef USE_SASL_AUTH
+# if SASL_VERSION_MAJOR >= 2
+ const char *sasl_mechanism_list;
+# else
char *sasl_mechanism_list;
+# endif
char *sasl_method;
char *sasl_username;
char *sasl_sender;
diff -ru postfix-1.1.4-orig/src/smtpd/smtpd_sasl_glue.c postfix-1.1.4/src/smtpd/smtpd_sasl_glue.c
--- postfix-1.1.4-orig/src/smtpd/smtpd_sasl_glue.c Sun Nov 25 18:14:01 2001
+++ postfix-1.1.4/src/smtpd/smtpd_sasl_glue.c Mon Mar 11 17:35:37 2002
@@ -110,20 +110,69 @@
*/
#define STR(s) vstring_str(s)
+ /*
+ * Macros to handle API differences between SASLv1 and SASLv2.
+ * Specifics:
+ * The SASL_LOG_* constants were renamed in SASLv2.
+ * SASLv2's sasl_server_new takes two new parameters to specify local
+ * and remote IP addresses for auth mechs that use them.
+ * SASLv2's sasl_server_start and sasl_server_step no longer have the
+ * errstr parameter.
+ * SASLv2's sasl_decode64 function takes an extra parameter for the
+ * length of the output buffer.
+ *
+ * The other major change is that SASLv2 now takes more responsibility for
+ * deallocating memory that it allocates internally. Thus, some of the
+ * function parameters are now 'const', to make sure we don't try to free
+ * them too. This is dealt with in the code later on.
+ */
+
+#if SASL_VERSION_MAJOR < 2
+/* SASL version 1.x */
+#define SASL_LOG_WARN SASL_LOG_WARNING
+#define SASL_LOG_NOTE SASL_LOG_INFO
+#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
+ sasl_server_new(srv, fqdn, rlm, cb, secflags, pconn)
+#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
+ sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen, err)
+#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
+ sasl_server_step(conn, clin, clinlen, srvout, srvoutlen, err)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outlen)
+#endif
+
+#if SASL_VERSION_MAJOR >= 2
+/* SASL version > 2.x */
+#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
+ sasl_server_new(srv, fqdn, rlm, lport, rport, cb, secflags, pconn)
+#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
+ sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen)
+#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
+ sasl_server_step(conn, clin, clinlen, srvout, srvoutlen)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+ sasl_decode64(in, inlen, out, outmaxlen, outlen)
+#endif
+
/* 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:
- case SASL_LOG_WARNING:
+ case SASL_LOG_ERR:
+ case SASL_LOG_WARN:
msg_warn("SASL authentication problem: %s", message);
break;
- case SASL_LOG_INFO:
+ case SASL_LOG_NOTE:
if (msg_verbose)
msg_info("SASL authentication info: %s", message);
break;
+#if SASL_VERSION_MAJOR >= 2
+ case SASL_LOG_FAIL:
+ if (msg_verbose)
+ msg_info("SASL authentication failure: %s", message);
+ break;
+#endif
}
return SASL_OK;
}
@@ -144,6 +193,9 @@
"noactive", SASL_SEC_NOACTIVE,
"nodictionary", SASL_SEC_NODICTIONARY,
"noanonymous", SASL_SEC_NOANONYMOUS,
+#if SASL_VERSION_MAJOR >= 2
+ "mutual_auth", SASL_SEC_MUTUAL_AUTH,
+#endif
0,
};
@@ -174,6 +226,9 @@
{
unsigned sasl_mechanism_count;
sasl_security_properties_t sec_props;
+ char *iplocal;
+ char *ipremote;
+
/*
* Initialize SASL-specific state variables. Use long-lived storage for
@@ -195,11 +250,24 @@
#define NO_SECURITY_LAYERS (0)
#define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
- if (sasl_server_new("smtp", var_myhostname, var_smtpd_sasl_realm,
+
+#if SASL_VERSION_MAJOR >= 2 && defined(USE_SASL_IP_AUTH)
+ /* Get IP addresses of local and remote hosts to pass to SASL. */
+
+#else
+ /* Don't give any IP information to SASL. SASLv1 doesn't use it, and
+ * in SASLv2 this will disable any mechs that do.
+ */
+ iplocal = NULL;
+ ipremote = NULL;
+#endif
+
+ if (SASL_SERVER_NEW("smtp", var_myhostname, var_smtpd_sasl_realm,
+ iplocal, ipremote,
NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
&state->sasl_conn) != SASL_OK)
msg_fatal("SASL per-connection server initialization");
-
+
/*
* Security options. Some information can be found in the sasl.h include
* file. Disallow anonymous authentication; this is because the
@@ -239,7 +307,10 @@
void smtpd_sasl_disconnect(SMTPD_STATE *state)
{
if (state->sasl_mechanism_list) {
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(state->sasl_mechanism_list);
+#endif
state->sasl_mechanism_list = 0;
}
if (state->sasl_conn) {
@@ -262,10 +333,18 @@
unsigned enc_length;
unsigned enc_length_out;
unsigned reply_len;
- char *serverout = 0;
unsigned serveroutlen;
int result;
+
+#if SASL_VERSION_MAJOR < 2
+ char *serverout = 0;
+#else
+ const char *serverout = 0;
+#endif
+
+#if SASL_VERSION_MAJOR < 2
const char *errstr = 0;
+#endif
#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
@@ -288,8 +367,8 @@
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)
+ if (SASL_DECODE64(init_response, reply_len,
+ dec_buffer, reply_len, &dec_length) != SASL_OK)
return ("501 Authentication failed: malformed initial response");
if (msg_verbose)
msg_info("%s: decoded initial response %s", myname, dec_buffer);
@@ -297,7 +376,7 @@
dec_buffer = 0;
dec_length = 0;
}
- result = sasl_server_start(state->sasl_conn, sasl_method, dec_buffer,
+ result = SASL_SERVER_START(state->sasl_conn, sasl_method, dec_buffer,
dec_length, &serverout, &serveroutlen, &errstr);
/*
@@ -327,7 +406,10 @@
if (sasl_encode64(serverout, serveroutlen, STR(state->sasl_encoded),
enc_length, &enc_length_out) != SASL_OK)
msg_panic("%s: sasl_encode64 botch", myname);
+#if SASL_VERSION_MAJOR < 2
+ /* SASL version 1 doesn't free memory that it allocates. */
free(serverout);
+#endif
serverout = 0;
smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
@@ -342,21 +424,24 @@
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)
+ if (SASL_DECODE64(vstring_str(state->buffer), reply_len,
+ STR(state->sasl_decoded), reply_len,
+ &dec_length) != SASL_OK)
return ("501 Error: malformed authentication response");
if (msg_verbose)
msg_info("%s: decoded response: %.*s",
myname, (int) dec_length, STR(state->sasl_decoded));
- result = sasl_server_step(state->sasl_conn, STR(state->sasl_decoded),
+ result = SASL_SERVER_STEP(state->sasl_conn, STR(state->sasl_decoded),
dec_length, &serverout, &serveroutlen, &errstr);
}
+#if SASL_VERSION_MAJOR < 2
/*
* Cleanup. What an awful interface.
*/
if (serverout)
free(serverout);
+#endif
/*
* The authentication protocol was completed.
@@ -369,8 +454,13 @@
* accounting purposes. For the sake of completeness we also record the
* authentication method that was used. XXX Do not free(serverout).
*/
+#if SASL_VERSION_MAJOR >= 2
+ result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
+ (const void **) &serverout);
+#else
result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
(void **) &serverout);
+#endif
if (result != SASL_OK || serverout == 0)
msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
state->sasl_username = mystrdup(serverout);

20
postfix/postfix.spec

@ -32,6 +32,9 @@
%ifndef with_tls
%define with_tls no
%endif
%ifndef with_sasl
%define with_sasl no
%endif
# package information
Name: postfix
@ -43,7 +46,7 @@ Distribution: OpenPKG [REL]
Group: Mail
License: IPL
Version: %{V_postfix}
Release: 20020615
Release: 20020705
# list of sources
Source0: ftp://ftp.porcupine.org/mirrors/postfix-release/official/postfix-%{V_postfix}.tar.gz
@ -52,6 +55,7 @@ Source2: fakesyslog.tar.gz
Source3: etc.tar
Source4: http://jimsun.linxnet.com/downloads/pflogsumm-%{V_pflogsumm}.pl
Source5: rc.postfix
Source6: postfix-sasl2.patch
# build information
Prefix: %{l_prefix}
@ -62,6 +66,10 @@ BuildPreReq: db, pcre
%if "%{with_tls}" == "yes"
BuildPreReq: openssl, patch
%endif
%if "%{with_sasl}" == "yes"
BuildPreReq: sasl
PreReq: sasl
%endif
AutoReq: no
AutoReqProv: no
Provides: MTA
@ -77,8 +85,9 @@ Provides: MTA
o Optional STARTTLS support
o Optional Berkeley-DB lookup table support
o Optional PCRE matching support
o Optional SASL2 authentication support
Options: with_tls=%{with_tls}
Options: with_tls=%{with_tls} with_sasl=%{with_sasl}
%prep
%setup0 -q -c -a 0
@ -90,6 +99,9 @@ Provides: MTA
cd postfix-%{V_postfix}
%if "%{with_tls}" == "yes"
%{l_patch} -p1 < ../pfixtls-%{V_tls}/pfixtls.diff
%endif
%if "%{with_sasl}" == "yes"
%{l_patch} -p1 < %{SOURCE postfix-sasl2.patch}
%endif
%{l_shtool} subst \
-e 's/var_config_dir, /var_command_dir, /' \
@ -134,6 +146,10 @@ Provides: MTA
%if "%{with_tls}" == "yes"
CCARGS="$CCARGS -DHAS_SSL"
AUXLIBS="$AUXLIBS -lssl -lcrypto"
%endif
%if "%{with_sasl}" == "yes"
CCARGS="$CCARGS -DUSE_SASL_AUTH -I%{l_prefix}/include/sasl"
AUXLIBS="$AUXLIBS -lsasl2"
%endif
AUXLIBS="$AUXLIBS -L$fakesyslogdir -lfakesyslog"
%{l_make} %{l_mflags} makefiles \

Loading…
Cancel
Save