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