diff -ruN postfix-2.1.5/postfix-2.1.5-dovecot-auth.patch postfix-2.1.5-dovecot/postfix-2.1.5-dovecot-auth.patch --- postfix-2.1.5/postfix-2.1.5-dovecot-auth.patch 1970-01-01 02:00:00.000000000 +0200 +++ postfix-2.1.5-dovecot/postfix-2.1.5-dovecot-auth.patch 2005-01-22 22:01:57.000000000 +0200 @@ -0,0 +1,1039 @@ +diff -ruN postfix-2.1.5/src/global/mail_params.h postfix-2.1.5-dovecot/src/global/mail_params.h +--- postfix-2.1.5/src/global/mail_params.h 2004-04-21 21:56:04.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/global/mail_params.h 2005-01-22 22:00:58.000000000 +0200 +@@ -908,6 +908,10 @@ + #define DEF_SMTPD_SASL_ENABLE 0 + extern bool var_smtpd_sasl_enable; + ++#define VAR_SMTPD_SASL_SOCKET "smtpd_sasl_auth_socket" ++#define DEF_SMTPD_SASL_SOCKET "" ++extern char *var_smtpd_sasl_socket; ++ + #define VAR_SMTPD_SASL_OPTS "smtpd_sasl_security_options" + #define DEF_SMTPD_SASL_OPTS "noanonymous" + extern char *var_smtpd_sasl_opts; +diff -ruN postfix-2.1.5/src/lmtp/lmtp.c postfix-2.1.5-dovecot/src/lmtp/lmtp.c +--- postfix-2.1.5/src/lmtp/lmtp.c 2004-06-20 02:06:39.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp.c 2005-01-22 22:00:58.000000000 +0200 +@@ -354,7 +354,7 @@ + lmtp_quit(state); + lmtp_chat_reset(state); + state->session = lmtp_session_free(state->session); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable) + lmtp_sasl_cleanup(state); + #endif +@@ -367,7 +367,7 @@ + else if (lmtp_rset(state) != 0) { + lmtp_chat_reset(state); + state->session = lmtp_session_free(state->session); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable) + lmtp_sasl_cleanup(state); + #endif +@@ -405,7 +405,7 @@ + */ + else if (lmtp_lhlo(state) != 0) { + state->session = lmtp_session_free(state->session); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable) + lmtp_sasl_cleanup(state); + #endif +@@ -501,7 +501,7 @@ + { + debug_peer_init(); + if (var_lmtp_sasl_enable) +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + lmtp_sasl_initialize(); + #else + msg_warn("%s is true, but SASL support is not compiled in", +@@ -526,7 +526,7 @@ + msg_info("cleanup: just closed down session"); + } + lmtp_state_free(state); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable) + sasl_done(); + #endif +diff -ruN postfix-2.1.5/src/lmtp/lmtp.h postfix-2.1.5-dovecot/src/lmtp/lmtp.h +--- postfix-2.1.5/src/lmtp/lmtp.h 2003-12-16 03:21:54.000000000 +0200 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp.h 2005-01-22 22:00:58.000000000 +0200 +@@ -11,7 +11,7 @@ + /* + * SASL library. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + #include + #include + #endif +@@ -43,7 +43,7 @@ + int features; /* server features */ + ARGV *history; /* transaction log */ + int error_mask; /* error classes */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + char *sasl_mechanism_list; /* server mechanism list */ + char *sasl_username; /* client username */ + char *sasl_passwd; /* client password */ +diff -ruN postfix-2.1.5/src/lmtp/lmtp_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c +--- postfix-2.1.5/src/lmtp/lmtp_proto.c 2004-04-14 23:02:37.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c 2005-01-22 22:00:58.000000000 +0200 +@@ -259,7 +259,7 @@ + NAME_CODE_FLAG_NONE, word); + else if (strcasecmp(word, "SIZE") == 0) + state->features |= LMTP_FEATURE_SIZE; +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0) + lmtp_sasl_helo_auth(state, words); + #endif +@@ -293,7 +293,7 @@ + } else + state->sndbufsize = 0; + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH)) + return (lmtp_sasl_helo_login(state)); + #endif +@@ -444,7 +444,7 @@ + /* + * We authenticate the local MTA only, but not the sender. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_lmtp_sasl_enable + && (state->features & LMTP_FEATURE_AUTH) + && state->sasl_passwd) +diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c +--- postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c 2003-09-12 21:46:58.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c 2005-01-22 22:00:58.000000000 +0200 +@@ -108,7 +108,7 @@ + #include "lmtp.h" + #include "lmtp_sasl.h" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + + /* + * Authentication security options. +diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c +--- postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c 2003-07-07 21:01:17.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c 2005-01-22 22:00:58.000000000 +0200 +@@ -71,7 +71,7 @@ + #include "lmtp.h" + #include "lmtp_sasl.h" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + + /* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */ + +diff -ruN postfix-2.1.5/src/lmtp/lmtp_state.c postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c +--- postfix-2.1.5/src/lmtp/lmtp_state.c 2003-09-12 21:42:55.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c 2005-01-22 22:00:58.000000000 +0200 +@@ -76,7 +76,7 @@ + state->features = 0; + state->history = 0; + state->error_mask = 0; +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + lmtp_sasl_connect(state); + #endif + state->sndbufsize = 0; +@@ -91,7 +91,7 @@ + vstring_free(state->buffer); + vstring_free(state->scratch); + vstring_free(state->scratch2); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + lmtp_sasl_cleanup(state); + #endif + myfree((char *) state); +diff -ruN postfix-2.1.5/src/smtp/smtp.c postfix-2.1.5-dovecot/src/smtp/smtp.c +--- postfix-2.1.5/src/smtp/smtp.c 2004-04-14 17:25:42.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtp/smtp.c 2005-01-22 22:00:58.000000000 +0200 +@@ -447,7 +447,7 @@ + * SASL initialization. + */ + if (var_smtp_sasl_enable) +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + smtp_sasl_initialize(); + #else + msg_warn("%s is true, but SASL support is not compiled in", +@@ -476,7 +476,7 @@ + + static void pre_exit(void) + { +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_smtp_sasl_enable) + sasl_done(); + #endif +diff -ruN postfix-2.1.5/src/smtp/smtp.h postfix-2.1.5-dovecot/src/smtp/smtp.h +--- postfix-2.1.5/src/smtp/smtp.h 2003-12-26 21:17:29.000000000 +0200 ++++ postfix-2.1.5-dovecot/src/smtp/smtp.h 2005-01-22 22:00:58.000000000 +0200 +@@ -11,7 +11,7 @@ + /* + * SASL library. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + #include + #include + #endif +@@ -43,7 +43,7 @@ + int features; /* server features */ + ARGV *history; /* transaction log */ + int error_mask; /* error classes */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + char *sasl_mechanism_list; /* server mechanism list */ + char *sasl_username; /* client username */ + char *sasl_passwd; /* client password */ +diff -ruN postfix-2.1.5/src/smtp/smtp_connect.c postfix-2.1.5-dovecot/src/smtp/smtp_connect.c +--- postfix-2.1.5/src/smtp/smtp_connect.c 2004-06-19 19:23:33.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtp/smtp_connect.c 2005-01-22 22:00:58.000000000 +0200 +@@ -368,7 +368,7 @@ + /* XXX smtp_xfer() may abort in the middle of DATA. */ + smtp_session_free(state->session); + state->session = 0; +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + smtp_sasl_cleanup(state); + #endif + debug_peer_restore(); +diff -ruN postfix-2.1.5/src/smtp/smtp_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_proto.c +--- postfix-2.1.5/src/smtp/smtp_proto.c 2004-04-14 23:02:20.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtp/smtp_proto.c 2005-01-22 22:00:58.000000000 +0200 +@@ -288,7 +288,7 @@ + state->size_limit = off_cvt_string(word); + } + } +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0) + smtp_sasl_helo_auth(state, words); + #endif +@@ -307,7 +307,7 @@ + msg_info("server features: 0x%x size %.0f", + state->features, (double) state->size_limit); + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH)) + return (smtp_sasl_helo_login(state)); + #endif +@@ -610,7 +610,7 @@ + /* + * We authenticate the local MTA only, but not the sender. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + if (var_smtp_sasl_enable + && (state->features & SMTP_FEATURE_AUTH) + && state->sasl_passwd) +diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_glue.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c +--- postfix-2.1.5/src/smtp/smtp_sasl_glue.c 2003-07-14 21:03:20.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c 2005-01-22 22:00:58.000000000 +0200 +@@ -108,7 +108,7 @@ + #include "smtp.h" + #include "smtp_sasl.h" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + + /* + * Authentication security options. +diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c +--- postfix-2.1.5/src/smtp/smtp_sasl_proto.c 2003-07-07 21:01:32.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c 2005-01-22 22:00:58.000000000 +0200 +@@ -71,7 +71,7 @@ + #include "smtp.h" + #include "smtp_sasl.h" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + + /* smtp_sasl_helo_auth - handle AUTH option in EHLO reply */ + +diff -ruN postfix-2.1.5/src/smtp/smtp_state.c postfix-2.1.5-dovecot/src/smtp/smtp_state.c +--- postfix-2.1.5/src/smtp/smtp_state.c 2003-12-21 04:10:50.000000000 +0200 ++++ postfix-2.1.5-dovecot/src/smtp/smtp_state.c 2005-01-22 22:00:58.000000000 +0200 +@@ -66,7 +66,7 @@ + state->features = 0; + state->history = 0; + state->error_mask = 0; +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + smtp_sasl_connect(state); + #endif + state->size_limit = 0; +@@ -82,7 +82,7 @@ + vstring_free(state->buffer); + vstring_free(state->scratch); + vstring_free(state->scratch2); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_CLIENT_AUTH + smtp_sasl_cleanup(state); + #endif + if (state->mime_state) +diff -ruN postfix-2.1.5/src/smtpd/Makefile.in postfix-2.1.5-dovecot/src/smtpd/Makefile.in +--- postfix-2.1.5/src/smtpd/Makefile.in 2004-04-22 22:37:39.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/Makefile.in 2005-01-22 22:00:58.000000000 +0200 +@@ -1,10 +1,10 @@ + SHELL = /bin/sh + SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \ +- smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \ +- smtpd_xforward.c ++ smtpd_peer.c smtpd_sasl.c smtpd_sasl_proto.c smtpd_sasl_glue.c \ ++ smtpd_proxy.c smtpd_xforward.c + OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \ +- smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \ +- smtpd_xforward.o ++ smtpd_peer.o smtpd_sasl.o smtpd_sasl_proto.o smtpd_sasl_glue.o \ ++ smtpd_proxy.o smtpd_xforward.o + HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \ + smtpd_sasl_glue.h smtpd_proxy.h + TESTSRC = smtpd_token_test.c +@@ -272,6 +272,26 @@ + smtpd_proxy.o: ../../include/argv.h + smtpd_proxy.o: ../../include/mail_stream.h + smtpd_proxy.o: smtpd_proxy.h ++smtpd_sasl.o: smtpd_sasl.c ++smtpd_sasl.o: ../../include/sys_defs.h ++smtpd_sasl.o: ../../include/base64_code.h ++smtpd_sasl.o: ../../include/vstring.h ++smtpd_sasl.o: ../../include/vbuf.h ++smtpd_sasl.o: ../../include/connect.h ++smtpd_sasl.o: ../../include/iostuff.h ++smtpd_sasl.o: ../../include/msg.h ++smtpd_sasl.o: ../../include/mymalloc.h ++smtpd_sasl.o: ../../include/split_at.h ++smtpd_sasl.o: ../../include/stringops.h ++smtpd_sasl.o: ../../include/vstring_vstream.h ++smtpd_sasl.o: ../../include/vstream.h ++smtpd_sasl.o: ../../include/mail_params.h ++smtpd_sasl.o: ../../include/smtp_stream.h ++smtpd_sasl.o: smtpd.h ++smtpd_sasl.o: ../../include/argv.h ++smtpd_sasl.o: ../../include/mail_stream.h ++smtpd_sasl.o: smtpd_sasl_glue.h ++smtpd_sasl.o: smtpd_chat.h + smtpd_sasl_glue.o: smtpd_sasl_glue.c + smtpd_sasl_glue.o: ../../include/sys_defs.h + smtpd_sasl_glue.o: ../../include/msg.h +diff -ruN postfix-2.1.5/src/smtpd/smtpd.c postfix-2.1.5-dovecot/src/smtpd/smtpd.c +--- postfix-2.1.5/src/smtpd/smtpd.c 2004-08-14 01:28:41.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd.c 2005-01-22 22:00:58.000000000 +0200 +@@ -717,6 +717,7 @@ + int var_smtpd_junk_cmd_limit; + int var_smtpd_rcpt_overlim; + bool var_smtpd_sasl_enable; ++char *var_smtpd_sasl_socket; + char *var_smtpd_sasl_opts; + char *var_smtpd_sasl_appname; + char *var_smtpd_sasl_realm; +@@ -816,7 +817,7 @@ + */ + #define NEUTER_CHARACTERS " <>()\\\";:@" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + + /* + * SASL exceptions. +@@ -943,7 +944,7 @@ + if (var_disable_vrfy_cmd == 0) + smtpd_chat_reply(state, "250-VRFY"); + smtpd_chat_reply(state, "250-ETRN"); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable && !sasl_client_exception(state)) { + smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list); + if (var_broken_auth_clients) +@@ -1246,7 +1247,7 @@ + state->error_mask |= MAIL_ERROR_POLICY; + return (-1); + } +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) { + if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) { + smtpd_chat_reply(state, "%s", err); +@@ -1354,7 +1355,7 @@ + state->saved_redirect = 0; + } + state->saved_flags = 0; +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) + smtpd_sasl_mail_reset(state); + #endif +@@ -1455,7 +1456,7 @@ + /* + * Log the queue ID with the message origin. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) + smtpd_sasl_mail_log(state); + else +@@ -2328,7 +2329,7 @@ + "HELO", helo_cmd, SMTPD_CMD_FLAG_LIMIT, + "EHLO", ehlo_cmd, SMTPD_CMD_FLAG_LIMIT, + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + "AUTH", smtpd_sasl_auth_cmd, 0, + #endif + +@@ -2531,7 +2532,7 @@ + * dialog. + */ + helo_reset(state); +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) + smtpd_sasl_auth_reset(state); + #endif +@@ -2628,7 +2629,7 @@ + debug_peer_init(); + + if (var_smtpd_sasl_enable) +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + smtpd_sasl_initialize(); + + if (*var_smtpd_sasl_exceptions_networks) +@@ -2757,6 +2758,7 @@ + VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0, + VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0, + VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0, ++ VAR_SMTPD_SASL_SOCKET, DEF_SMTPD_SASL_SOCKET, &var_smtpd_sasl_socket, 0, 0, + VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0, + VAR_SMTPD_SASL_APPNAME, DEF_SMTPD_SASL_APPNAME, &var_smtpd_sasl_appname, 1, 0, + VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0, +diff -ruN postfix-2.1.5/src/smtpd/smtpd.h postfix-2.1.5-dovecot/src/smtpd/smtpd.h +--- postfix-2.1.5/src/smtpd/smtpd.h 2004-04-21 21:23:33.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd.h 2005-01-22 22:00:58.000000000 +0200 +@@ -16,7 +16,7 @@ + /* + * SASL library. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_CYRUS_SASL + #include + #include + #endif +@@ -90,7 +90,7 @@ + /* + * SASL specific. + */ +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + #if SASL_VERSION_MAJOR >= 2 + const char *sasl_mechanism_list; + #else +@@ -99,10 +99,15 @@ + char *sasl_method; + char *sasl_username; + char *sasl_sender; ++ unsigned int sasl_id; ++ VSTRING *sasl_line; ++ ++#ifdef USE_CYRUS_SASL + sasl_conn_t *sasl_conn; + VSTRING *sasl_encoded; + VSTRING *sasl_decoded; + #endif ++#endif + + /* + * Specific to smtpd access checks. +diff -ruN postfix-2.1.5/src/smtpd/smtpd_check.c postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c +--- postfix-2.1.5/src/smtpd/smtpd_check.c 2004-08-02 00:08:32.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c 2005-01-22 22:00:58.000000000 +0200 +@@ -2762,7 +2762,7 @@ + return (result); + } + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + + /* reject_auth_sender_login_mismatch - logged in client must own sender address */ + +@@ -2868,7 +2868,7 @@ + STR(state->instance), + ATTR_TYPE_LONG, MAIL_ATTR_SIZE, + (unsigned long) state->msg_size, +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, + var_smtpd_sasl_enable && state->sasl_method ? + state->sasl_method : "", +@@ -3162,7 +3162,7 @@ + status = reject_non_fqdn_address(state, state->sender, + state->sender, SMTPD_NAME_SENDER); + } else if (strcasecmp(name, REJECT_AUTH_SENDER_LOGIN_MISMATCH) == 0) { +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) { + if (state->sender && *state->sender) + status = reject_auth_sender_login_mismatch(state, state->sender); +@@ -3170,7 +3170,7 @@ + #endif + msg_warn("restriction `%s' ignored: no SASL support", name); + } else if (strcasecmp(name, REJECT_UNAUTH_SENDER_LOGIN_MISMATCH) == 0) { +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) { + if (state->sender && *state->sender) + status = reject_unauth_sender_login_mismatch(state, state->sender); +@@ -3232,7 +3232,7 @@ + cpp[1], CHECK_RELAY_DOMAINS); + } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) { + if (var_smtpd_sasl_enable) +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + status = permit_sasl_auth(state, + SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO); + #else +@@ -4209,7 +4209,7 @@ + + bool var_smtpd_sasl_enable = 0; + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + + /* smtpd_sasl_connect - stub */ + +diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c +--- postfix-2.1.5/src/smtpd/smtpd_sasl.c 1970-01-01 02:00:00.000000000 +0200 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c 2005-01-22 22:01:20.000000000 +0200 +@@ -0,0 +1,409 @@ ++/*++ ++/* NAME ++/* smtpd_sasl_glue 3 ++/* SUMMARY ++/* Postfix SMTP server, SASL support interface ++/* SYNOPSIS ++/* #include "smtpd_sasl_glue.h" ++/* ++/* void smtpd_sasl_initialize() ++/* ++/* void smtpd_sasl_connect(state, sasl_opts_name, sasl_opts_val) ++/* SMTPD_STATE *state; ++/* ++/* char *smtpd_sasl_authenticate(state, sasl_method, init_response) ++/* SMTPD_STATE *state; ++/* const char *sasl_method; ++/* const char *init_response; ++/* ++/* void smtpd_sasl_logout(state) ++/* SMTPD_STATE *state; ++/* ++/* void smtpd_sasl_disconnect(state) ++/* SMTPD_STATE *state; ++/* DESCRIPTION ++/* This module encapsulates most of the detail specific to SASL ++/* authentication. ++/* ++/* smtpd_sasl_initialize() initializes the SASL library. This ++/* routine should be called once at process start-up. It may ++/* need access to the file system for run-time loading of ++/* plug-in modules. There is no corresponding cleanup routine. ++/* ++/* smtpd_sasl_connect() performs per-connection initialization. ++/* This routine should be called once at the start of every ++/* connection. The sasl_opts_name and sasl_opts_val parameters ++/* are the postfix configuration parameters setting the security ++/* policy of the SASL authentication. ++/* ++/* smtpd_sasl_authenticate() implements the authentication dialog. ++/* The result is a null pointer in case of success, an SMTP reply ++/* in case of failure. smtpd_sasl_authenticate() updates the ++/* following state structure members: ++/* .IP sasl_method ++/* The authentication method that was successfully applied. ++/* This member is a null pointer in the absence of successful ++/* authentication. ++/* .IP sasl_username ++/* The username that was successfully authenticated. ++/* This member is a null pointer in the absence of successful ++/* authentication. ++/* .PP ++/* smtpd_sasl_logout() cleans up after smtpd_sasl_authenticate(). ++/* This routine exists for the sake of symmetry. ++/* ++/* smtpd_sasl_disconnect() performs per-connection cleanup. ++/* This routine should be called at the end of every connection. ++/* ++/* Arguments: ++/* .IP state ++/* SMTP session context. ++/* .IP sasl_method ++/* A SASL mechanism name ++/* .IP init_reply ++/* An optional initial client response. ++/* DIAGNOSTICS ++/* All errors are fatal. ++/* LICENSE ++/* .ad ++/* .fi ++/* The Secure Mailer license must be distributed with this software. ++/* AUTHOR(S) ++/* Initial implementation by: ++/* Till Franke ++/* SuSE Rhein/Main AG ++/* 65760 Eschborn, Germany ++/* ++/* Adopted by: ++/* Wietse Venema ++/* IBM T.J. Watson Research ++/* P.O. Box 704 ++/* Yorktown Heights, NY 10598, USA ++/*--*/ ++ ++/* System library. */ ++ ++#include ++#include ++#include ++#include ++ ++/* Utility library. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global library. */ ++ ++#include ++#include ++ ++/* Application-specific. */ ++ ++#include "smtpd.h" ++#include "smtpd_sasl_glue.h" ++#include "smtpd_chat.h" ++ ++#ifdef USE_SASL_SERVER_AUTH ++ ++/* Major version changes are not backwards compatible, ++ minor version numbers can be ignored. */ ++#define AUTH_PROTOCOL_MAJOR_VERSION 1 ++#define AUTH_PROTOCOL_MINOR_VERSION 0 ++ ++static unsigned int sasl_id = 0; ++static VSTREAM *sasl_stream = 0; ++static char *sasl_mechanism_list = 0; ++ ++/* smtpd_sasl_initialize - per-process initialization */ ++ ++void smtpd_sasl_initialize(void) ++{ ++#ifdef USE_CYRUS_SASL ++ if (*var_smtpd_sasl_socket == '\0') ++ smtpd_cyrus_sasl_initialize(); ++#endif ++} ++ ++static void smtpd_sasl_connect_server(void) ++{ ++ char *myname = "smtpd_sasl_connect_server"; ++ VSTRING *line_str, *mechanisms_str; ++ char *line, *cmd, *mech_name; ++ unsigned int major_version, minor_version; ++ int fd; ++ ++ if ((fd = unix_connect(var_smtpd_sasl_socket, BLOCKING, 0)) < 0) ++ msg_fatal("SASL: connect failed: %m"); ++ ++ sasl_stream = vstream_fdopen(fd, O_RDWR); ++ vstream_control(sasl_stream, VSTREAM_CTL_PATH, ++ var_smtpd_sasl_socket, VSTREAM_CTL_END); ++ ++ vstream_fprintf(sasl_stream, ++ "VERSION\t%u\t%u\n" ++ "SERVICE\tsmtp\n" ++ "CPID\t%u\n", ++ AUTH_PROTOCOL_MAJOR_VERSION, ++ AUTH_PROTOCOL_MINOR_VERSION, ++ (unsigned int)getpid()); ++ if (vstream_fflush(sasl_stream) == VSTREAM_EOF) ++ msg_fatal("SASL: couldn't send handshake: %m"); ++ ++ line_str = vstring_alloc(256); ++ mechanisms_str = vstring_alloc(128); ++ while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) { ++ line = vstring_str(line_str); ++ ++ if (msg_verbose) ++ msg_info("%s: auth reply: %s", myname, line); ++ ++ cmd = line; ++ line = split_at(line, '\t'); ++ ++ if (strcmp(cmd, "VERSION") == 0) { ++ if (sscanf(line, "%u\t%u", &major_version, &minor_version) != 2) ++ msg_fatal("SASL: Protocol version error"); ++ ++ if (major_version != AUTH_PROTOCOL_MAJOR_VERSION) { ++ /* Major version is different from ours. */ ++ msg_fatal("SASL: Protocol version mismatch (%d vs. %d)", ++ major_version, AUTH_PROTOCOL_MAJOR_VERSION); ++ } ++ } else if (strcmp(cmd, "MECH") == 0 && line != NULL) { ++ mech_name = line; ++ line = split_at(line, '\t'); ++ ++ if (VSTRING_LEN(mechanisms_str) > 0) ++ VSTRING_ADDCH(mechanisms_str, ' '); ++ vstring_strcat(mechanisms_str, mech_name); ++ } else if (strcmp(cmd, "DONE") == 0) { ++ /* Handshake finished. */ ++ break; ++ } else { ++ /* ignore any unknown commands */ ++ } ++ } ++ vstring_free(line_str); ++ ++ if (sasl_mechanism_list) ++ myfree(sasl_mechanism_list); ++ sasl_mechanism_list = ++ translit(vstring_export(mechanisms_str), "\t", " "); ++} ++ ++static void smtpd_sasl_disconnect_server(void) ++{ ++ (void) vstream_fclose(sasl_stream); ++ sasl_stream = 0; ++ ++ myfree(sasl_mechanism_list); ++ sasl_mechanism_list = 0; ++} ++ ++/* smtpd_sasl_connect - per-connection initialization */ ++ ++void smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, ++ const char *sasl_opts_val) ++{ ++#ifdef USE_CYRUS_SASL ++ if (*var_smtpd_sasl_socket == '\0') { ++ smtpd_cyrus_sasl_connect(state, sasl_opts_name, sasl_opts_val); ++ return; ++ } ++#endif ++ ++ state->sasl_username = 0; ++ state->sasl_method = 0; ++ state->sasl_sender = 0; ++ state->sasl_line = vstring_alloc(512); ++ ++ if (!sasl_stream) ++ smtpd_sasl_connect_server(); ++ state->sasl_mechanism_list = mystrdup(sasl_mechanism_list); ++} ++ ++/* smtpd_sasl_disconnect - per-connection cleanup */ ++ ++void smtpd_sasl_disconnect(SMTPD_STATE *state) ++{ ++#ifdef USE_CYRUS_SASL ++ if (*var_smtpd_sasl_socket == '\0') { ++ smtpd_cyrus_sasl_disconnect(state); ++ return; ++ } ++#endif ++ ++ vstring_free(state->sasl_line); ++ state->sasl_line = 0; ++ myfree(state->sasl_mechanism_list); ++ state->sasl_mechanism_list = 0; ++} ++ ++static int smtpd_sasl_parse_reply(SMTPD_STATE *state, char **line) ++{ ++ char *id; ++ ++ if (*line == NULL) ++ msg_fatal("SASL: Protocol error"); ++ ++ id = *line; ++ *line = split_at(*line, '\t'); ++ ++ if (strtoul(id, NULL, 0) != state->sasl_id) { ++ /* reply to another request, shouldn't really happen.. */ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++ ++/* smtpd_sasl_authenticate - per-session authentication */ ++ ++char *smtpd_sasl_authenticate(SMTPD_STATE *state, ++ const char *sasl_method, ++ const char *init_response) ++{ ++ char *myname = "smtpd_sasl_authenticate"; ++ char *line, *cmd; ++ int i, success; ++ ++#ifdef USE_CYRUS_SASL ++ if (*var_smtpd_sasl_socket == '\0') ++ return smtpd_cyrus_sasl_authenticate(state, sasl_method, init_response); ++#endif ++ ++#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3)) ++ ++ if (msg_verbose) ++ msg_info("%s: sasl_method %s%s%s", myname, sasl_method, ++ IFELSE(init_response, ", init_response ", ""), ++ IFELSE(init_response, init_response, "")); ++ ++ for (i = 0; i < 2; i++) { ++ state->sasl_id = ++sasl_id; ++ vstream_fprintf(sasl_stream, "AUTH\t%u\t%s", ++ state->sasl_id, sasl_method); ++ if (init_response) ++ vstream_fprintf(sasl_stream, "\tresp=%s", init_response); ++ VSTREAM_PUTC('\n', sasl_stream); ++ ++ if (vstream_fflush(sasl_stream) != VSTREAM_EOF) ++ break; ++ ++ if (i == 1) ++ return ("454 Temporary authentication failure"); ++ ++ /* ++ * Reconnect. ++ */ ++ smtpd_sasl_disconnect_server(); ++ smtpd_sasl_connect_server(); ++ } ++ ++ /* ++ * Sanity check. ++ */ ++ if (state->sasl_username || state->sasl_method) ++ msg_panic("%s: already authenticated", myname); ++ ++ success = 0; ++ while (vstring_get_nonl(state->sasl_line, sasl_stream) != VSTREAM_EOF) { ++ line = vstring_str(state->sasl_line); ++ ++ if (msg_verbose) ++ msg_info("%s: auth reply: %s", myname, line); ++ ++ cmd = line; ++ line = split_at(line, '\t'); ++ ++ if (strcmp(cmd, "OK") == 0) { ++ if (!smtpd_sasl_parse_reply(state, &line)) ++ continue; ++ ++ /* authentication successful */ ++ success = 1; ++ break; ++ } else if (strcmp(cmd, "CONT") == 0) { ++ if (!smtpd_sasl_parse_reply(state, &line)) ++ continue; ++ ++ /* ++ * Receive the client response. "*" means that the client gives up. ++ * XXX For now we ignore the fact that excessively long responses ++ * will be truncated. To handle such responses, we need to change ++ * smtpd_chat_query() so that it returns an error indication. ++ */ ++ smtpd_chat_reply(state, "334 %s", line); ++ ++ smtpd_chat_query(state); ++ if (strcmp(vstring_str(state->buffer), "*") == 0) ++ return ("501 Authentication aborted"); ++ ++ vstream_fprintf(sasl_stream, "CONT\t%u\t", state->sasl_id); ++ vstream_fputs(vstring_str(state->buffer), sasl_stream); ++ VSTREAM_PUTC('\n', sasl_stream); ++ ++ if (vstream_fflush(sasl_stream) == VSTREAM_EOF) ++ break; ++ } else if (strcmp(cmd, "FAIL") == 0) { ++ if (!smtpd_sasl_parse_reply(state, &line)) ++ continue; ++ ++ return ("535 Error: authentication failed"); ++ } else { ++ /* ignore */ ++ } ++ } ++ ++ if (!success) { ++ /* connection lost to auth server */ ++ return ("454 Temporary authentication failure"); ++ } ++ ++ while (line != NULL && strncmp(line, "user=", 5) != 0) ++ line = split_at(line, '\t'); ++ ++ if (line == NULL) ++ state->sasl_username = mystrdup("?"); ++ else { ++ line += 5; ++ (void) split_at(line, '\t'); ++ state->sasl_username = mystrdup(line); ++ } ++ printable(state->sasl_username, '?'); ++ ++ state->sasl_method = mystrdup(sasl_method); ++ printable(state->sasl_method, '?'); ++ ++ return (0); ++} ++ ++/* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */ ++ ++void smtpd_sasl_logout(SMTPD_STATE *state) ++{ ++#ifdef USE_CYRUS_SASL ++ if (*var_smtpd_sasl_socket == '\0') { ++ smtpd_cyrus_sasl_logout(state); ++ return; ++ } ++#endif ++ ++ if (state->sasl_username) { ++ myfree(state->sasl_username); ++ state->sasl_username = 0; ++ } ++ if (state->sasl_method) { ++ myfree(state->sasl_method); ++ state->sasl_method = 0; ++ } ++} ++ ++#endif +diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c +--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c 2004-02-01 20:44:55.000000000 +0200 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c 2005-01-22 22:00:58.000000000 +0200 +@@ -105,7 +105,7 @@ + #include "smtpd_sasl_glue.h" + #include "smtpd_chat.h" + +-#ifdef USE_SASL_AUTH ++#if defined(USE_SASL_SERVER_AUTH) && defined(USE_CYRUS_SASL) + + /* + * Silly little macros. +@@ -205,7 +205,7 @@ + + /* smtpd_sasl_initialize - per-process initialization */ + +-void smtpd_sasl_initialize(void) ++void smtpd_cyrus_sasl_initialize(void) + { + + /* +@@ -221,7 +221,7 @@ + + /* smtpd_sasl_connect - per-connection initialization */ + +-void smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, ++void smtpd_cyrus_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, + const char *sasl_opts_val) + { + #if SASL_VERSION_MAJOR < 2 +@@ -318,7 +318,7 @@ + + /* smtpd_sasl_disconnect - per-connection cleanup */ + +-void smtpd_sasl_disconnect(SMTPD_STATE *state) ++void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *state) + { + if (state->sasl_mechanism_list) { + #if SASL_VERSION_MAJOR < 2 +@@ -337,7 +337,7 @@ + + /* smtpd_sasl_authenticate - per-session authentication */ + +-char *smtpd_sasl_authenticate(SMTPD_STATE *state, ++char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *state, + const char *sasl_method, + const char *init_response) + { +@@ -490,7 +490,7 @@ + + /* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */ + +-void smtpd_sasl_logout(SMTPD_STATE *state) ++void smtpd_cyrus_sasl_logout(SMTPD_STATE *state) + { + if (state->sasl_username) { + myfree(state->sasl_username); +diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h +--- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h 2003-07-07 21:01:45.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h 2005-01-22 22:00:58.000000000 +0200 +@@ -18,6 +18,15 @@ + extern void smtpd_sasl_logout(SMTPD_STATE *); + extern int permit_sasl_auth(SMTPD_STATE *, int, int); + ++#ifdef USE_CYRUS_SASL ++extern void smtpd_cyrus_sasl_initialize(void); ++extern void smtpd_cyrus_sasl_connect(SMTPD_STATE *, const char *, const char *); ++extern void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *); ++extern char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *, const char *, ++ const char *); ++extern void smtpd_cyrus_sasl_logout(SMTPD_STATE *); ++#endif ++ + /* LICENSE + /* .ad + /* .fi +diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c +--- postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c 2004-03-29 22:40:52.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c 2005-01-22 22:00:58.000000000 +0200 +@@ -109,7 +109,7 @@ + #include "smtpd_sasl_proto.h" + #include "smtpd_sasl_glue.h" + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + + /* smtpd_sasl_auth_cmd - process AUTH command */ + +diff -ruN postfix-2.1.5/src/smtpd/smtpd_state.c postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c +--- postfix-2.1.5/src/smtpd/smtpd_state.c 2004-04-21 21:23:49.000000000 +0300 ++++ postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c 2005-01-22 22:00:58.000000000 +0200 +@@ -112,7 +112,7 @@ + state->instance = vstring_alloc(10); + state->seqno = 0; + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (SMTPD_STAND_ALONE(state)) + var_smtpd_sasl_enable = 0; + if (var_smtpd_sasl_enable) +@@ -166,7 +166,7 @@ + if (state->instance) + vstring_free(state->instance); + +-#ifdef USE_SASL_AUTH ++#ifdef USE_SASL_SERVER_AUTH + if (var_smtpd_sasl_enable) + smtpd_sasl_disconnect(state); + #endif diff -ruN postfix-2.1.5/src/global/mail_params.h postfix-2.1.5-dovecot/src/global/mail_params.h --- postfix-2.1.5/src/global/mail_params.h 2004-04-21 21:56:04.000000000 +0300 +++ postfix-2.1.5-dovecot/src/global/mail_params.h 2005-03-25 14:12:56.709298387 +0200 @@ -908,6 +908,10 @@ #define DEF_SMTPD_SASL_ENABLE 0 extern bool var_smtpd_sasl_enable; +#define VAR_SMTPD_SASL_SOCKET "smtpd_sasl_auth_socket" +#define DEF_SMTPD_SASL_SOCKET "" +extern char *var_smtpd_sasl_socket; + #define VAR_SMTPD_SASL_OPTS "smtpd_sasl_security_options" #define DEF_SMTPD_SASL_OPTS "noanonymous" extern char *var_smtpd_sasl_opts; diff -ruN postfix-2.1.5/src/lmtp/lmtp.c postfix-2.1.5-dovecot/src/lmtp/lmtp.c --- postfix-2.1.5/src/lmtp/lmtp.c 2004-06-20 02:06:39.000000000 +0300 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp.c 2005-03-25 14:12:56.710298199 +0200 @@ -354,7 +354,7 @@ lmtp_quit(state); lmtp_chat_reset(state); state->session = lmtp_session_free(state->session); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable) lmtp_sasl_cleanup(state); #endif @@ -367,7 +367,7 @@ else if (lmtp_rset(state) != 0) { lmtp_chat_reset(state); state->session = lmtp_session_free(state->session); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable) lmtp_sasl_cleanup(state); #endif @@ -405,7 +405,7 @@ */ else if (lmtp_lhlo(state) != 0) { state->session = lmtp_session_free(state->session); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable) lmtp_sasl_cleanup(state); #endif @@ -501,7 +501,7 @@ { debug_peer_init(); if (var_lmtp_sasl_enable) -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH lmtp_sasl_initialize(); #else msg_warn("%s is true, but SASL support is not compiled in", @@ -526,7 +526,7 @@ msg_info("cleanup: just closed down session"); } lmtp_state_free(state); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable) sasl_done(); #endif diff -ruN postfix-2.1.5/src/lmtp/lmtp.h postfix-2.1.5-dovecot/src/lmtp/lmtp.h --- postfix-2.1.5/src/lmtp/lmtp.h 2003-12-16 03:21:54.000000000 +0200 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp.h 2005-03-25 14:12:56.710298199 +0200 @@ -11,7 +11,7 @@ /* * SASL library. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH #include #include #endif @@ -43,7 +43,7 @@ int features; /* server features */ ARGV *history; /* transaction log */ int error_mask; /* error classes */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH char *sasl_mechanism_list; /* server mechanism list */ char *sasl_username; /* client username */ char *sasl_passwd; /* client password */ diff -ruN postfix-2.1.5/src/lmtp/lmtp_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c --- postfix-2.1.5/src/lmtp/lmtp_proto.c 2004-04-14 23:02:37.000000000 +0300 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp_proto.c 2005-03-25 14:12:56.712297822 +0200 @@ -259,7 +259,7 @@ NAME_CODE_FLAG_NONE, word); else if (strcasecmp(word, "SIZE") == 0) state->features |= LMTP_FEATURE_SIZE; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH else if (var_lmtp_sasl_enable && strcasecmp(word, "AUTH") == 0) lmtp_sasl_helo_auth(state, words); #endif @@ -293,7 +293,7 @@ } else state->sndbufsize = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH)) return (lmtp_sasl_helo_login(state)); #endif @@ -444,7 +444,7 @@ /* * We authenticate the local MTA only, but not the sender. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH) && state->sasl_passwd) diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c --- postfix-2.1.5/src/lmtp/lmtp_sasl_glue.c 2003-09-12 21:46:58.000000000 +0300 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_glue.c 2005-03-25 14:12:56.712297822 +0200 @@ -108,7 +108,7 @@ #include "lmtp.h" #include "lmtp_sasl.h" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH /* * Authentication security options. diff -ruN postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c --- postfix-2.1.5/src/lmtp/lmtp_sasl_proto.c 2003-07-07 21:01:17.000000000 +0300 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp_sasl_proto.c 2005-03-25 14:12:56.713297633 +0200 @@ -71,7 +71,7 @@ #include "lmtp.h" #include "lmtp_sasl.h" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH /* lmtp_sasl_helo_auth - handle AUTH option in EHLO reply */ diff -ruN postfix-2.1.5/src/lmtp/lmtp_state.c postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c --- postfix-2.1.5/src/lmtp/lmtp_state.c 2003-09-12 21:42:55.000000000 +0300 +++ postfix-2.1.5-dovecot/src/lmtp/lmtp_state.c 2005-03-25 14:12:56.713297633 +0200 @@ -76,7 +76,7 @@ state->features = 0; state->history = 0; state->error_mask = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH lmtp_sasl_connect(state); #endif state->sndbufsize = 0; @@ -91,7 +91,7 @@ vstring_free(state->buffer); vstring_free(state->scratch); vstring_free(state->scratch2); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH lmtp_sasl_cleanup(state); #endif myfree((char *) state); diff -ruN postfix-2.1.5/src/smtp/smtp.c postfix-2.1.5-dovecot/src/smtp/smtp.c --- postfix-2.1.5/src/smtp/smtp.c 2004-04-14 17:25:42.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtp/smtp.c 2005-03-25 14:12:56.714297445 +0200 @@ -447,7 +447,7 @@ * SASL initialization. */ if (var_smtp_sasl_enable) -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH smtp_sasl_initialize(); #else msg_warn("%s is true, but SASL support is not compiled in", @@ -476,7 +476,7 @@ static void pre_exit(void) { -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_smtp_sasl_enable) sasl_done(); #endif diff -ruN postfix-2.1.5/src/smtp/smtp.h postfix-2.1.5-dovecot/src/smtp/smtp.h --- postfix-2.1.5/src/smtp/smtp.h 2003-12-26 21:17:29.000000000 +0200 +++ postfix-2.1.5-dovecot/src/smtp/smtp.h 2005-03-25 14:12:56.715297256 +0200 @@ -11,7 +11,7 @@ /* * SASL library. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH #include #include #endif @@ -43,7 +43,7 @@ int features; /* server features */ ARGV *history; /* transaction log */ int error_mask; /* error classes */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH char *sasl_mechanism_list; /* server mechanism list */ char *sasl_username; /* client username */ char *sasl_passwd; /* client password */ diff -ruN postfix-2.1.5/src/smtp/smtp_connect.c postfix-2.1.5-dovecot/src/smtp/smtp_connect.c --- postfix-2.1.5/src/smtp/smtp_connect.c 2004-06-19 19:23:33.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtp/smtp_connect.c 2005-03-25 14:12:56.717296879 +0200 @@ -368,7 +368,7 @@ /* XXX smtp_xfer() may abort in the middle of DATA. */ smtp_session_free(state->session); state->session = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH smtp_sasl_cleanup(state); #endif debug_peer_restore(); diff -ruN postfix-2.1.5/src/smtp/smtp_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_proto.c --- postfix-2.1.5/src/smtp/smtp_proto.c 2004-04-14 23:02:20.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtp/smtp_proto.c 2005-03-25 14:12:56.719296502 +0200 @@ -288,7 +288,7 @@ state->size_limit = off_cvt_string(word); } } -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH else if (var_smtp_sasl_enable && strcasecmp(word, "AUTH") == 0) smtp_sasl_helo_auth(state, words); #endif @@ -307,7 +307,7 @@ msg_info("server features: 0x%x size %.0f", state->features, (double) state->size_limit); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH)) return (smtp_sasl_helo_login(state)); #endif @@ -610,7 +610,7 @@ /* * We authenticate the local MTA only, but not the sender. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH if (var_smtp_sasl_enable && (state->features & SMTP_FEATURE_AUTH) && state->sasl_passwd) diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_glue.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c --- postfix-2.1.5/src/smtp/smtp_sasl_glue.c 2003-07-14 21:03:20.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_glue.c 2005-03-25 14:12:56.720296314 +0200 @@ -108,7 +108,7 @@ #include "smtp.h" #include "smtp_sasl.h" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH /* * Authentication security options. diff -ruN postfix-2.1.5/src/smtp/smtp_sasl_proto.c postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c --- postfix-2.1.5/src/smtp/smtp_sasl_proto.c 2003-07-07 21:01:32.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtp/smtp_sasl_proto.c 2005-03-25 14:12:56.721296126 +0200 @@ -71,7 +71,7 @@ #include "smtp.h" #include "smtp_sasl.h" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH /* smtp_sasl_helo_auth - handle AUTH option in EHLO reply */ diff -ruN postfix-2.1.5/src/smtp/smtp_state.c postfix-2.1.5-dovecot/src/smtp/smtp_state.c --- postfix-2.1.5/src/smtp/smtp_state.c 2003-12-21 04:10:50.000000000 +0200 +++ postfix-2.1.5-dovecot/src/smtp/smtp_state.c 2005-03-25 14:12:56.723295749 +0200 @@ -66,7 +66,7 @@ state->features = 0; state->history = 0; state->error_mask = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH smtp_sasl_connect(state); #endif state->size_limit = 0; @@ -82,7 +82,7 @@ vstring_free(state->buffer); vstring_free(state->scratch); vstring_free(state->scratch2); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_CLIENT_AUTH smtp_sasl_cleanup(state); #endif if (state->mime_state) diff -ruN postfix-2.1.5/src/smtpd/Makefile.in postfix-2.1.5-dovecot/src/smtpd/Makefile.in --- postfix-2.1.5/src/smtpd/Makefile.in 2004-04-22 22:37:39.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/Makefile.in 2005-03-25 14:12:56.724295560 +0200 @@ -1,10 +1,10 @@ SHELL = /bin/sh SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \ - smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \ - smtpd_xforward.c + smtpd_peer.c smtpd_sasl.c smtpd_sasl_proto.c smtpd_sasl_glue.c \ + smtpd_proxy.c smtpd_xforward.c OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \ - smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \ - smtpd_xforward.o + smtpd_peer.o smtpd_sasl.o smtpd_sasl_proto.o smtpd_sasl_glue.o \ + smtpd_proxy.o smtpd_xforward.o HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \ smtpd_sasl_glue.h smtpd_proxy.h TESTSRC = smtpd_token_test.c @@ -272,6 +272,26 @@ smtpd_proxy.o: ../../include/argv.h smtpd_proxy.o: ../../include/mail_stream.h smtpd_proxy.o: smtpd_proxy.h +smtpd_sasl.o: smtpd_sasl.c +smtpd_sasl.o: ../../include/sys_defs.h +smtpd_sasl.o: ../../include/base64_code.h +smtpd_sasl.o: ../../include/vstring.h +smtpd_sasl.o: ../../include/vbuf.h +smtpd_sasl.o: ../../include/connect.h +smtpd_sasl.o: ../../include/iostuff.h +smtpd_sasl.o: ../../include/msg.h +smtpd_sasl.o: ../../include/mymalloc.h +smtpd_sasl.o: ../../include/split_at.h +smtpd_sasl.o: ../../include/stringops.h +smtpd_sasl.o: ../../include/vstring_vstream.h +smtpd_sasl.o: ../../include/vstream.h +smtpd_sasl.o: ../../include/mail_params.h +smtpd_sasl.o: ../../include/smtp_stream.h +smtpd_sasl.o: smtpd.h +smtpd_sasl.o: ../../include/argv.h +smtpd_sasl.o: ../../include/mail_stream.h +smtpd_sasl.o: smtpd_sasl_glue.h +smtpd_sasl.o: smtpd_chat.h smtpd_sasl_glue.o: smtpd_sasl_glue.c smtpd_sasl_glue.o: ../../include/sys_defs.h smtpd_sasl_glue.o: ../../include/msg.h diff -ruN postfix-2.1.5/src/smtpd/smtpd.c postfix-2.1.5-dovecot/src/smtpd/smtpd.c --- postfix-2.1.5/src/smtpd/smtpd.c 2004-08-14 01:28:41.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd.c 2005-03-25 14:12:56.727294995 +0200 @@ -717,6 +717,7 @@ int var_smtpd_junk_cmd_limit; int var_smtpd_rcpt_overlim; bool var_smtpd_sasl_enable; +char *var_smtpd_sasl_socket; char *var_smtpd_sasl_opts; char *var_smtpd_sasl_appname; char *var_smtpd_sasl_realm; @@ -816,7 +817,7 @@ */ #define NEUTER_CHARACTERS " <>()\\\";:@" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH /* * SASL exceptions. @@ -943,7 +944,7 @@ if (var_disable_vrfy_cmd == 0) smtpd_chat_reply(state, "250-VRFY"); smtpd_chat_reply(state, "250-ETRN"); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable && !sasl_client_exception(state)) { smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list); if (var_broken_auth_clients) @@ -1246,7 +1247,7 @@ state->error_mask |= MAIL_ERROR_POLICY; return (-1); } -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) { if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) { smtpd_chat_reply(state, "%s", err); @@ -1354,7 +1355,7 @@ state->saved_redirect = 0; } state->saved_flags = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) smtpd_sasl_mail_reset(state); #endif @@ -1455,7 +1456,7 @@ /* * Log the queue ID with the message origin. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) smtpd_sasl_mail_log(state); else @@ -2328,7 +2329,7 @@ "HELO", helo_cmd, SMTPD_CMD_FLAG_LIMIT, "EHLO", ehlo_cmd, SMTPD_CMD_FLAG_LIMIT, -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH "AUTH", smtpd_sasl_auth_cmd, 0, #endif @@ -2531,7 +2532,7 @@ * dialog. */ helo_reset(state); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) smtpd_sasl_auth_reset(state); #endif @@ -2628,7 +2629,7 @@ debug_peer_init(); if (var_smtpd_sasl_enable) -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH smtpd_sasl_initialize(); if (*var_smtpd_sasl_exceptions_networks) @@ -2757,6 +2758,7 @@ VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0, VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0, VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0, + VAR_SMTPD_SASL_SOCKET, DEF_SMTPD_SASL_SOCKET, &var_smtpd_sasl_socket, 0, 0, VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0, VAR_SMTPD_SASL_APPNAME, DEF_SMTPD_SASL_APPNAME, &var_smtpd_sasl_appname, 1, 0, VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0, diff -ruN postfix-2.1.5/src/smtpd/smtpd.h postfix-2.1.5-dovecot/src/smtpd/smtpd.h --- postfix-2.1.5/src/smtpd/smtpd.h 2004-04-21 21:23:33.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd.h 2005-03-25 14:12:56.729294618 +0200 @@ -16,7 +16,7 @@ /* * SASL library. */ -#ifdef USE_SASL_AUTH +#ifdef USE_CYRUS_SASL #include #include #endif @@ -90,7 +90,7 @@ /* * SASL specific. */ -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH #if SASL_VERSION_MAJOR >= 2 const char *sasl_mechanism_list; #else @@ -99,10 +99,15 @@ char *sasl_method; char *sasl_username; char *sasl_sender; + unsigned int sasl_id; + VSTRING *sasl_line; + +#ifdef USE_CYRUS_SASL sasl_conn_t *sasl_conn; VSTRING *sasl_encoded; VSTRING *sasl_decoded; #endif +#endif /* * Specific to smtpd access checks. diff -ruN postfix-2.1.5/src/smtpd/smtpd_check.c postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c --- postfix-2.1.5/src/smtpd/smtpd_check.c 2004-08-02 00:08:32.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_check.c 2005-03-25 14:12:56.732294052 +0200 @@ -2762,7 +2762,7 @@ return (result); } -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH /* reject_auth_sender_login_mismatch - logged in client must own sender address */ @@ -2868,7 +2868,7 @@ STR(state->instance), ATTR_TYPE_LONG, MAIL_ATTR_SIZE, (unsigned long) state->msg_size, -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH ATTR_TYPE_STR, MAIL_ATTR_SASL_METHOD, var_smtpd_sasl_enable && state->sasl_method ? state->sasl_method : "", @@ -3162,7 +3162,7 @@ status = reject_non_fqdn_address(state, state->sender, state->sender, SMTPD_NAME_SENDER); } else if (strcasecmp(name, REJECT_AUTH_SENDER_LOGIN_MISMATCH) == 0) { -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) { if (state->sender && *state->sender) status = reject_auth_sender_login_mismatch(state, state->sender); @@ -3170,7 +3170,7 @@ #endif msg_warn("restriction `%s' ignored: no SASL support", name); } else if (strcasecmp(name, REJECT_UNAUTH_SENDER_LOGIN_MISMATCH) == 0) { -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) { if (state->sender && *state->sender) status = reject_unauth_sender_login_mismatch(state, state->sender); @@ -3232,7 +3232,7 @@ cpp[1], CHECK_RELAY_DOMAINS); } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) { if (var_smtpd_sasl_enable) -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH status = permit_sasl_auth(state, SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO); #else @@ -4209,7 +4209,7 @@ bool var_smtpd_sasl_enable = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH /* smtpd_sasl_connect - stub */ diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c --- postfix-2.1.5/src/smtpd/smtpd_sasl.c 1970-01-01 02:00:00.000000000 +0200 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl.c 2005-03-25 14:13:16.856500665 +0200 @@ -0,0 +1,408 @@ +/*++ +/* NAME +/* smtpd_sasl_glue 3 +/* SUMMARY +/* Postfix SMTP server, SASL support interface +/* SYNOPSIS +/* #include "smtpd_sasl_glue.h" +/* +/* void smtpd_sasl_initialize() +/* +/* void smtpd_sasl_connect(state, sasl_opts_name, sasl_opts_val) +/* SMTPD_STATE *state; +/* +/* char *smtpd_sasl_authenticate(state, sasl_method, init_response) +/* SMTPD_STATE *state; +/* const char *sasl_method; +/* const char *init_response; +/* +/* void smtpd_sasl_logout(state) +/* SMTPD_STATE *state; +/* +/* void smtpd_sasl_disconnect(state) +/* SMTPD_STATE *state; +/* DESCRIPTION +/* This module encapsulates most of the detail specific to SASL +/* authentication. +/* +/* smtpd_sasl_initialize() initializes the SASL library. This +/* routine should be called once at process start-up. It may +/* need access to the file system for run-time loading of +/* plug-in modules. There is no corresponding cleanup routine. +/* +/* smtpd_sasl_connect() performs per-connection initialization. +/* This routine should be called once at the start of every +/* connection. The sasl_opts_name and sasl_opts_val parameters +/* are the postfix configuration parameters setting the security +/* policy of the SASL authentication. +/* +/* smtpd_sasl_authenticate() implements the authentication dialog. +/* The result is a null pointer in case of success, an SMTP reply +/* in case of failure. smtpd_sasl_authenticate() updates the +/* following state structure members: +/* .IP sasl_method +/* The authentication method that was successfully applied. +/* This member is a null pointer in the absence of successful +/* authentication. +/* .IP sasl_username +/* The username that was successfully authenticated. +/* This member is a null pointer in the absence of successful +/* authentication. +/* .PP +/* smtpd_sasl_logout() cleans up after smtpd_sasl_authenticate(). +/* This routine exists for the sake of symmetry. +/* +/* smtpd_sasl_disconnect() performs per-connection cleanup. +/* This routine should be called at the end of every connection. +/* +/* Arguments: +/* .IP state +/* SMTP session context. +/* .IP sasl_method +/* A SASL mechanism name +/* .IP init_reply +/* An optional initial client response. +/* DIAGNOSTICS +/* All errors are fatal. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Initial implementation by: +/* Till Franke +/* SuSE Rhein/Main AG +/* 65760 Eschborn, Germany +/* +/* Adopted by: +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include +#include +#include + +/* Utility library. */ + +#include +#include +#include +#include +#include +#include +#include + +/* Global library. */ + +#include +#include + +/* Application-specific. */ + +#include "smtpd.h" +#include "smtpd_sasl_glue.h" +#include "smtpd_chat.h" + +#ifdef USE_SASL_SERVER_AUTH + +/* Major version changes are not backwards compatible, + minor version numbers can be ignored. */ +#define AUTH_PROTOCOL_MAJOR_VERSION 1 +#define AUTH_PROTOCOL_MINOR_VERSION 0 + +static unsigned int sasl_id = 0; +static VSTREAM *sasl_stream = 0; +static char *sasl_mechanism_list = 0; + +/* smtpd_sasl_initialize - per-process initialization */ + +void smtpd_sasl_initialize(void) +{ +#ifdef USE_CYRUS_SASL + if (*var_smtpd_sasl_socket == '\0') + smtpd_cyrus_sasl_initialize(); +#endif +} + +static void smtpd_sasl_connect_server(void) +{ + char *myname = "smtpd_sasl_connect_server"; + VSTRING *line_str, *mechanisms_str; + char *line, *cmd, *mech_name; + unsigned int major_version, minor_version; + int fd; + + if ((fd = unix_connect(var_smtpd_sasl_socket, BLOCKING, 0)) < 0) + msg_fatal("SASL: connect failed: %m"); + + sasl_stream = vstream_fdopen(fd, O_RDWR); + vstream_control(sasl_stream, VSTREAM_CTL_PATH, + var_smtpd_sasl_socket, VSTREAM_CTL_END); + + vstream_fprintf(sasl_stream, + "VERSION\t%u\t%u\n" + "CPID\t%u\n", + AUTH_PROTOCOL_MAJOR_VERSION, + AUTH_PROTOCOL_MINOR_VERSION, + (unsigned int)getpid()); + if (vstream_fflush(sasl_stream) == VSTREAM_EOF) + msg_fatal("SASL: couldn't send handshake: %m"); + + line_str = vstring_alloc(256); + mechanisms_str = vstring_alloc(128); + while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) { + line = vstring_str(line_str); + + if (msg_verbose) + msg_info("%s: auth reply: %s", myname, line); + + cmd = line; + line = split_at(line, '\t'); + + if (strcmp(cmd, "VERSION") == 0) { + if (sscanf(line, "%u\t%u", &major_version, &minor_version) != 2) + msg_fatal("SASL: Protocol version error"); + + if (major_version != AUTH_PROTOCOL_MAJOR_VERSION) { + /* Major version is different from ours. */ + msg_fatal("SASL: Protocol version mismatch (%d vs. %d)", + major_version, AUTH_PROTOCOL_MAJOR_VERSION); + } + } else if (strcmp(cmd, "MECH") == 0 && line != NULL) { + mech_name = line; + line = split_at(line, '\t'); + + if (VSTRING_LEN(mechanisms_str) > 0) + VSTRING_ADDCH(mechanisms_str, ' '); + vstring_strcat(mechanisms_str, mech_name); + } else if (strcmp(cmd, "DONE") == 0) { + /* Handshake finished. */ + break; + } else { + /* ignore any unknown commands */ + } + } + vstring_free(line_str); + + if (sasl_mechanism_list) + myfree(sasl_mechanism_list); + sasl_mechanism_list = + translit(vstring_export(mechanisms_str), "\t", " "); +} + +static void smtpd_sasl_disconnect_server(void) +{ + (void) vstream_fclose(sasl_stream); + sasl_stream = 0; + + myfree(sasl_mechanism_list); + sasl_mechanism_list = 0; +} + +/* smtpd_sasl_connect - per-connection initialization */ + +void smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, + const char *sasl_opts_val) +{ +#ifdef USE_CYRUS_SASL + if (*var_smtpd_sasl_socket == '\0') { + smtpd_cyrus_sasl_connect(state, sasl_opts_name, sasl_opts_val); + return; + } +#endif + + state->sasl_username = 0; + state->sasl_method = 0; + state->sasl_sender = 0; + state->sasl_line = vstring_alloc(512); + + if (!sasl_stream) + smtpd_sasl_connect_server(); + state->sasl_mechanism_list = mystrdup(sasl_mechanism_list); +} + +/* smtpd_sasl_disconnect - per-connection cleanup */ + +void smtpd_sasl_disconnect(SMTPD_STATE *state) +{ +#ifdef USE_CYRUS_SASL + if (*var_smtpd_sasl_socket == '\0') { + smtpd_cyrus_sasl_disconnect(state); + return; + } +#endif + + vstring_free(state->sasl_line); + state->sasl_line = 0; + myfree(state->sasl_mechanism_list); + state->sasl_mechanism_list = 0; +} + +static int smtpd_sasl_parse_reply(SMTPD_STATE *state, char **line) +{ + char *id; + + if (*line == NULL) + msg_fatal("SASL: Protocol error"); + + id = *line; + *line = split_at(*line, '\t'); + + if (strtoul(id, NULL, 0) != state->sasl_id) { + /* reply to another request, shouldn't really happen.. */ + return 0; + } + + return 1; +} + + +/* smtpd_sasl_authenticate - per-session authentication */ + +char *smtpd_sasl_authenticate(SMTPD_STATE *state, + const char *sasl_method, + const char *init_response) +{ + char *myname = "smtpd_sasl_authenticate"; + char *line, *cmd; + int i, success; + +#ifdef USE_CYRUS_SASL + if (*var_smtpd_sasl_socket == '\0') + return smtpd_cyrus_sasl_authenticate(state, sasl_method, init_response); +#endif + +#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3)) + + if (msg_verbose) + msg_info("%s: sasl_method %s%s%s", myname, sasl_method, + IFELSE(init_response, ", init_response ", ""), + IFELSE(init_response, init_response, "")); + + for (i = 0; i < 2; i++) { + state->sasl_id = ++sasl_id; + vstream_fprintf(sasl_stream, "AUTH\t%u\t%s\tservice=smtp", + state->sasl_id, sasl_method); + if (init_response) + vstream_fprintf(sasl_stream, "\tresp=%s", init_response); + VSTREAM_PUTC('\n', sasl_stream); + + if (vstream_fflush(sasl_stream) != VSTREAM_EOF) + break; + + if (i == 1) + return ("454 Temporary authentication failure"); + + /* + * Reconnect. + */ + smtpd_sasl_disconnect_server(); + smtpd_sasl_connect_server(); + } + + /* + * Sanity check. + */ + if (state->sasl_username || state->sasl_method) + msg_panic("%s: already authenticated", myname); + + success = 0; + while (vstring_get_nonl(state->sasl_line, sasl_stream) != VSTREAM_EOF) { + line = vstring_str(state->sasl_line); + + if (msg_verbose) + msg_info("%s: auth reply: %s", myname, line); + + cmd = line; + line = split_at(line, '\t'); + + if (strcmp(cmd, "OK") == 0) { + if (!smtpd_sasl_parse_reply(state, &line)) + continue; + + /* authentication successful */ + success = 1; + break; + } else if (strcmp(cmd, "CONT") == 0) { + if (!smtpd_sasl_parse_reply(state, &line)) + continue; + + /* + * Receive the client response. "*" means that the client gives up. + * XXX For now we ignore the fact that excessively long responses + * will be truncated. To handle such responses, we need to change + * smtpd_chat_query() so that it returns an error indication. + */ + smtpd_chat_reply(state, "334 %s", line); + + smtpd_chat_query(state); + if (strcmp(vstring_str(state->buffer), "*") == 0) + return ("501 Authentication aborted"); + + vstream_fprintf(sasl_stream, "CONT\t%u\t", state->sasl_id); + vstream_fputs(vstring_str(state->buffer), sasl_stream); + VSTREAM_PUTC('\n', sasl_stream); + + if (vstream_fflush(sasl_stream) == VSTREAM_EOF) + break; + } else if (strcmp(cmd, "FAIL") == 0) { + if (!smtpd_sasl_parse_reply(state, &line)) + continue; + + return ("535 Error: authentication failed"); + } else { + /* ignore */ + } + } + + if (!success) { + /* connection lost to auth server */ + return ("454 Temporary authentication failure"); + } + + while (line != NULL && strncmp(line, "user=", 5) != 0) + line = split_at(line, '\t'); + + if (line == NULL) + state->sasl_username = mystrdup("?"); + else { + line += 5; + (void) split_at(line, '\t'); + state->sasl_username = mystrdup(line); + } + printable(state->sasl_username, '?'); + + state->sasl_method = mystrdup(sasl_method); + printable(state->sasl_method, '?'); + + return (0); +} + +/* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */ + +void smtpd_sasl_logout(SMTPD_STATE *state) +{ +#ifdef USE_CYRUS_SASL + if (*var_smtpd_sasl_socket == '\0') { + smtpd_cyrus_sasl_logout(state); + return; + } +#endif + + if (state->sasl_username) { + myfree(state->sasl_username); + state->sasl_username = 0; + } + if (state->sasl_method) { + myfree(state->sasl_method); + state->sasl_method = 0; + } +} + +#endif diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c --- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.c 2004-02-01 20:44:55.000000000 +0200 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.c 2005-03-25 14:12:56.736293299 +0200 @@ -105,7 +105,7 @@ #include "smtpd_sasl_glue.h" #include "smtpd_chat.h" -#ifdef USE_SASL_AUTH +#if defined(USE_SASL_SERVER_AUTH) && defined(USE_CYRUS_SASL) /* * Silly little macros. @@ -205,7 +205,7 @@ /* smtpd_sasl_initialize - per-process initialization */ -void smtpd_sasl_initialize(void) +void smtpd_cyrus_sasl_initialize(void) { /* @@ -221,7 +221,7 @@ /* smtpd_sasl_connect - per-connection initialization */ -void smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, +void smtpd_cyrus_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name, const char *sasl_opts_val) { #if SASL_VERSION_MAJOR < 2 @@ -318,7 +318,7 @@ /* smtpd_sasl_disconnect - per-connection cleanup */ -void smtpd_sasl_disconnect(SMTPD_STATE *state) +void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *state) { if (state->sasl_mechanism_list) { #if SASL_VERSION_MAJOR < 2 @@ -337,7 +337,7 @@ /* smtpd_sasl_authenticate - per-session authentication */ -char *smtpd_sasl_authenticate(SMTPD_STATE *state, +char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *state, const char *sasl_method, const char *init_response) { @@ -490,7 +490,7 @@ /* smtpd_sasl_logout - clean up after smtpd_sasl_authenticate */ -void smtpd_sasl_logout(SMTPD_STATE *state) +void smtpd_cyrus_sasl_logout(SMTPD_STATE *state) { if (state->sasl_username) { myfree(state->sasl_username); diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h --- postfix-2.1.5/src/smtpd/smtpd_sasl_glue.h 2003-07-07 21:01:45.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_glue.h 2005-03-25 14:12:56.737293110 +0200 @@ -18,6 +18,15 @@ extern void smtpd_sasl_logout(SMTPD_STATE *); extern int permit_sasl_auth(SMTPD_STATE *, int, int); +#ifdef USE_CYRUS_SASL +extern void smtpd_cyrus_sasl_initialize(void); +extern void smtpd_cyrus_sasl_connect(SMTPD_STATE *, const char *, const char *); +extern void smtpd_cyrus_sasl_disconnect(SMTPD_STATE *); +extern char *smtpd_cyrus_sasl_authenticate(SMTPD_STATE *, const char *, + const char *); +extern void smtpd_cyrus_sasl_logout(SMTPD_STATE *); +#endif + /* LICENSE /* .ad /* .fi diff -ruN postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c --- postfix-2.1.5/src/smtpd/smtpd_sasl_proto.c 2004-03-29 22:40:52.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_sasl_proto.c 2005-03-25 14:12:56.739292733 +0200 @@ -109,7 +109,7 @@ #include "smtpd_sasl_proto.h" #include "smtpd_sasl_glue.h" -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH /* smtpd_sasl_auth_cmd - process AUTH command */ diff -ruN postfix-2.1.5/src/smtpd/smtpd_state.c postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c --- postfix-2.1.5/src/smtpd/smtpd_state.c 2004-04-21 21:23:49.000000000 +0300 +++ postfix-2.1.5-dovecot/src/smtpd/smtpd_state.c 2005-03-25 14:12:56.740292545 +0200 @@ -112,7 +112,7 @@ state->instance = vstring_alloc(10); state->seqno = 0; -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (SMTPD_STAND_ALONE(state)) var_smtpd_sasl_enable = 0; if (var_smtpd_sasl_enable) @@ -166,7 +166,7 @@ if (state->instance) vstring_free(state->instance); -#ifdef USE_SASL_AUTH +#ifdef USE_SASL_SERVER_AUTH if (var_smtpd_sasl_enable) smtpd_sasl_disconnect(state); #endif