postfix-sasl2.patch 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. diff -ru postfix-1.1.4-orig/README_FILES/SASL_README postfix-1.1.4/README_FILES/SASL_README
  2. --- postfix-1.1.4-orig/README_FILES/SASL_README Sat May 26 11:32:47 2001
  3. +++ postfix-1.1.4/README_FILES/SASL_README Mon Mar 11 14:04:58 2002
  4. @@ -26,6 +26,14 @@
  5. Note that this seems to be related to the auto_transition switch in
  6. SASL. Note also that the Cyrus SASL documentation says that it is
  7. pointless to enable that if you use "sasldb" for "pwcheck_method".
  8. +Later versions of the SASL 1.5.x series should also work.
  9. +
  10. +Postfix+SASL 2.1.1 appears to work on Mandrake Linux 8.1 (pwcheck_method
  11. +set to saslauthd or auxprop). Note that the 'auxprop' pwcheck_method
  12. +replaces the 'sasldb' method from SASL 1.5.x. Postfix may need
  13. +write access to /etc/sasldb2 if you are using the auto_transition
  14. +feature, or if you are using an authentication mechanism such as OTP
  15. +that needs to update secrets in the database.
  16. Introduction
  17. ============
  18. @@ -50,20 +58,22 @@
  19. Building the SASL library
  20. =========================
  21. -Postfix appears to work with cyrus-sasl-1.5.5, which is available
  22. -from:
  23. +Postfix appears to work with cyrus-sasl-1.5.5 or cyrus-sasl-2.1.1,
  24. +which are available from:
  25. ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
  26. IMPORTANT: if you install the Cyrus SASL libraries as per the default,
  27. -you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
  28. +you will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl for
  29. +version 1.5.5 or /usr/lib/sasl2 -> /usr/local/lib/sasl2 for version 2.1.1.
  30. Reportedly, Microsoft Internet Explorer version 5 requires the
  31. non-standard SASL LOGIN authentication method. To enable this
  32. authentication method, specify ``./configure --enable-login''.
  33. If you install the Cyrus SASL libraries as per the default, you
  34. -will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl.
  35. +will have to symlink /usr/lib/sasl -> /usr/local/lib/sasl for version 1.5.5
  36. +or symlink /usr/lib/sasl2 -> /usr/local/lib/sasl2 for version 2.1.1.
  37. Building Postfix with SASL authentication support
  38. =================================================
  39. @@ -72,19 +82,33 @@
  40. assumes that the Cyrus SASL include files are in /usr/local/include,
  41. and that the Cyrus SASL libraries are in /usr/local/lib.
  42. -On some systems this generates the necessary Makefile definitions:
  43. +On some systems this generates the necessary Makefile definitions for
  44. +Cyrus SASL 1.5.5:
  45. % make tidy # if you have left-over files from a previous build
  46. % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
  47. AUXLIBS="-L/usr/local/lib -lsasl"
  48. +On some systems this generates the necessary Makefile definitions for
  49. +Cyrus SASL 2.1.1:
  50. +
  51. + % make tidy # if you have left-over files from a previous build
  52. + % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
  53. + AUXLIBS="-L/usr/local/lib -lsasl2"
  54. +
  55. On Solaris 2.x you need to specify run-time link information,
  56. otherwise ld.so will not find the SASL shared library:
  57. +(for version 1.5.5):
  58. % make tidy # if you have left-over files from a previous build
  59. % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
  60. AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
  61. +(for version 2.1.1):
  62. + % make tidy # if you have left-over files from a previous build
  63. + % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
  64. + AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl2"
  65. +
  66. Enabling SASL authentication in the Postfix SMTP server
  67. =======================================================
  68. @@ -101,23 +125,41 @@
  69. smtpd_recipient_restrictions =
  70. permit_mynetworks permit_sasl_authenticated ...
  71. -In /usr/local/lib/sasl/smtpd.conf you need to specify how the server
  72. -should validate client passwords.
  73. +In /usr/local/lib/sasl/smtpd.conf (for version 1.5.5) or
  74. +/usr/local/lib/sasl2/smtpd.conf (for version 2.1.1) you need to
  75. +specify how the server should validate client passwords.
  76. In order to authenticate against the UNIX password database, try:
  77. /usr/local/lib/sasl/smtpd.conf:
  78. pwcheck_method: pwcheck
  79. + (use /usr/local/lib/sasl2/smtpd.conf with version 2.1.1)
  80. The pwcheck daemon is contained in the cyrus-sasl source tarball.
  81. -In order to authenticate against SASL's own password database:
  82. +Alternately, in SASL 1.5.27 and later (including 2.1.1), try:
  83. +
  84. + /usr/local/lib/sasl/smtpd.conf:
  85. + pwcheck_method: saslauthd
  86. + (use /usr/local/lib/sasl2/smtpd.conf with version 2.1.1)
  87. +
  88. +The saslauthd daemon is also contained in the cyrus-sasl source tarball.
  89. +It is more flexible than the pwcheck daemon, in that it can authenticate
  90. +against PAM and various other sources.
  91. +
  92. +In order to authenticate against SASL's own password database in version 1.5.5:
  93. /usr/local/lib/sasl/smtpd.conf:
  94. pwcheck_method: sasldb
  95. -This will use the SASL password file (default: /etc/sasldb), which
  96. -is maintained with the saslpasswd command (part of the Cyrus SASL
  97. +or in version 2.1.1:
  98. +
  99. + /usr/local/lib/sasl2/smtpd.conf:
  100. + pwcheck_method: auxprop
  101. +
  102. +This will use the SASL password file (default: /etc/sasldb in
  103. +version 1.5.5, or /etc/sasldb2 in version 2.1.1), which is maintained
  104. +with the saslpasswd or saslpasswd2 command (part of the Cyrus SASL
  105. software). On some poorly-supported systems the saslpasswd command
  106. needs to be run multiple times before it stops complaining. The
  107. Postfix SMTP server needs read access to the sasldb file - you may
  108. diff -ru postfix-1.1.4-orig/conf/sample-auth.cf postfix-1.1.4/conf/sample-auth.cf
  109. --- postfix-1.1.4-orig/conf/sample-auth.cf Mon Mar 11 00:44:43 2002
  110. +++ postfix-1.1.4/conf/sample-auth.cf Mon Mar 11 17:36:22 2002
  111. @@ -23,6 +23,7 @@
  112. #
  113. # In order to enable server-side authentication, build Postfix with
  114. # SASL support, and install a configuration file /usr/lib/sasl/smtpd.conf
  115. +# (for SASL version 1) or /usr/lib/sasl2/smtpd.conf (for SASL version 2)
  116. # with as contents, for example,
  117. #
  118. # pwcheck_method: sasldb
  119. @@ -51,6 +52,10 @@
  120. # nodictionary: disallow methods subject to passive (dictionary) attack
  121. # noanonymous: disallow methods that allow anonymous authentication
  122. #
  123. +# An additional options is available in SASL version 2:
  124. +#
  125. +# mutual_auth: only allow methods that provide mutual authentication
  126. +#
  127. # By default, the Postfix SMTP server accepts plaintext passwords but
  128. # not anonymous logins.
  129. #
  130. @@ -104,6 +109,10 @@
  131. # nodictionary: disallow methods subject to passive (dictionary) attack
  132. # noanonymous: disallow methods that allow anonymous authentication
  133. #
  134. +# An additional options is available in SASL version 2:
  135. +#
  136. +# mutual_auth: only allow methods that provide mutual authentication
  137. +#
  138. # By default, the Postfix SMTP client will not use plaintext passwords.
  139. #
  140. #smtp_sasl_security_options =
  141. diff -ru postfix-1.1.4-orig/src/lmtp/lmtp_sasl_glue.c postfix-1.1.4/src/lmtp/lmtp_sasl_glue.c
  142. --- postfix-1.1.4-orig/src/lmtp/lmtp_sasl_glue.c Fri Jan 19 15:46:44 2001
  143. +++ postfix-1.1.4/src/lmtp/lmtp_sasl_glue.c Mon Mar 11 17:35:33 2002
  144. @@ -116,6 +116,9 @@
  145. "noactive", SASL_SEC_NOACTIVE,
  146. "nodictionary", SASL_SEC_NODICTIONARY,
  147. "noanonymous", SASL_SEC_NOANONYMOUS,
  148. +#if SASL_VERSION_MAJOR >= 2
  149. + "mutual_auth", SASL_SEC_MUTUAL_AUTH,
  150. +#endif
  151. 0,
  152. };
  153. @@ -127,6 +130,44 @@
  154. #define STR(x) vstring_str(x)
  155. /*
  156. + * Macros to handle API differences between SASLv1 and SASLv2.
  157. + * Specifics:
  158. + * The SASL_LOG_* constants were renamed in SASLv2.
  159. + * SASLv2's sasl_client_new takes two new parameters to specify local
  160. + * and remote IP addresses for auth mechs that use them.
  161. + * SASLv2's sasl_client_start function no longer takes the secret parameter.
  162. + * SASLv2's sasl_decode64 function takes an extra parameter for the
  163. + * length of the output buffer.
  164. + *
  165. + * The other major change is that SASLv2 now takes more responsibility for
  166. + * deallocating memory that it allocates internally. Thus, some of the
  167. + * function parameters are now 'const', to make sure we don't try to free
  168. + * them too. This is dealt with in the code later on.
  169. + */
  170. +
  171. +#if SASL_VERSION_MAJOR < 2
  172. +/* SASL version 1.x */
  173. +#define SASL_LOG_WARN SASL_LOG_WARNING
  174. +#define SASL_LOG_NOTE SASL_LOG_INFO
  175. +#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
  176. + sasl_client_new(srv, fqdn, prompt, secflags, pconn)
  177. +#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
  178. + sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
  179. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  180. + sasl_decode64(in, inlen, out, outlen)
  181. +#endif
  182. +
  183. +#if SASL_VERSION_MAJOR >= 2
  184. +/* SASL version > 2.x */
  185. +#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
  186. + sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
  187. +#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
  188. + sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
  189. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  190. + sasl_decode64(in, inlen, out, outmaxlen, outlen)
  191. +#endif
  192. +
  193. + /*
  194. * Per-host login/password information.
  195. */
  196. static MAPS *lmtp_sasl_passwd_map;
  197. @@ -137,14 +178,18 @@
  198. const char *message)
  199. {
  200. switch (priority) {
  201. - case SASL_LOG_ERR:
  202. - case SASL_LOG_WARNING:
  203. - msg_warn("%s", message);
  204. + case SASL_LOG_ERR: /* unusual errors */
  205. + case SASL_LOG_WARN: /* non-fatal warnings */
  206. + msg_warn("SASL authentication problem: %s", message);
  207. break;
  208. - case SASL_LOG_INFO:
  209. + case SASL_LOG_NOTE: /* other info */
  210. if (msg_verbose)
  211. - msg_info("%s", message);
  212. + msg_info("SASL authentication info: %s", message);
  213. break;
  214. +#if SASL_VERSION_MAJOR >= 2
  215. + case SASL_LOG_FAIL: /* authentication failures - SASLv2 only */
  216. + msg_warn("SASL authentication failure: %s", message);
  217. +#endif
  218. }
  219. return (SASL_OK);
  220. }
  221. @@ -317,7 +362,9 @@
  222. memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
  223. for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
  224. cp->context = (void *) state;
  225. - if (sasl_client_new("smtp", state->session->host,
  226. +
  227. + if (SASL_CLIENT_NEW("smtp", state->session->host,
  228. + NULL, NULL,
  229. state->sasl_callbacks, NULL_SECFLAGS,
  230. (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
  231. msg_fatal("per-session SASL client initialization");
  232. @@ -354,7 +401,11 @@
  233. char *myname = "lmtp_sasl_authenticate";
  234. unsigned enc_length;
  235. unsigned enc_length_out;
  236. +#if SASL_VERSION_MAJOR >= 2
  237. + const char *clientout;
  238. +#else
  239. char *clientout;
  240. +#endif
  241. unsigned clientoutlen;
  242. unsigned serverinlen;
  243. LMTP_RESP *resp;
  244. @@ -374,7 +425,7 @@
  245. /*
  246. * Start the client side authentication protocol.
  247. */
  248. - result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
  249. + result = SASL_CLIENT_START((sasl_conn_t *) state->sasl_conn,
  250. state->sasl_mechanism_list,
  251. NO_SASL_SECRET, NO_SASL_INTERACTION,
  252. &clientout, &clientoutlen, &mechanism);
  253. @@ -404,7 +455,10 @@
  254. STR(state->sasl_encoded), enc_length,
  255. &enc_length_out) != SASL_OK)
  256. msg_panic("%s: sasl_encode64 botch", myname);
  257. +#if SASL_VERSION_MAJOR < 2
  258. + /* SASL version 1 doesn't free memory that it allocates. */
  259. free(clientout);
  260. +#endif
  261. lmtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
  262. } else {
  263. lmtp_chat_cmd(state, "AUTH %s", mechanism);
  264. @@ -423,8 +477,8 @@
  265. (void) mystrtok(&line, "- \t\n"); /* skip over result code */
  266. serverinlen = strlen(line);
  267. VSTRING_SPACE(state->sasl_decoded, serverinlen);
  268. - if (sasl_decode64(line, serverinlen,
  269. - STR(state->sasl_decoded), &enc_length) != SASL_OK) {
  270. + if (SASL_DECODE64(line, serverinlen, STR(state->sasl_decoded),
  271. + serverinlen, &enc_length) != SASL_OK) {
  272. vstring_sprintf(why, "malformed SASL challenge from server %s",
  273. state->session->namaddr);
  274. return (-1);
  275. @@ -456,7 +510,10 @@
  276. STR(state->sasl_encoded), enc_length,
  277. &enc_length_out) != SASL_OK)
  278. msg_panic("%s: sasl_encode64 botch", myname);
  279. +#if SASL_VERSION_MAJOR < 2
  280. + /* SASL version 1 doesn't free memory that it allocates. */
  281. free(clientout);
  282. +#endif
  283. } else {
  284. vstring_strcat(state->sasl_encoded, "");
  285. }
  286. @@ -487,7 +544,8 @@
  287. state->sasl_passwd = 0;
  288. }
  289. if (state->sasl_mechanism_list) {
  290. - myfree(state->sasl_mechanism_list); /* allocated in lmtp_helo */
  291. + /* state->sasl_mechanism_list is allocated in lmtp_sasl_helo_auth */
  292. + myfree(state->sasl_mechanism_list);
  293. state->sasl_mechanism_list = 0;
  294. }
  295. if (state->sasl_conn) {
  296. diff -ru postfix-1.1.4-orig/src/smtp/smtp_sasl_glue.c postfix-1.1.4/src/smtp/smtp_sasl_glue.c
  297. --- postfix-1.1.4-orig/src/smtp/smtp_sasl_glue.c Mon Jul 2 14:12:54 2001
  298. +++ postfix-1.1.4/src/smtp/smtp_sasl_glue.c Mon Mar 11 17:35:41 2002
  299. @@ -116,6 +116,9 @@
  300. "noactive", SASL_SEC_NOACTIVE,
  301. "nodictionary", SASL_SEC_NODICTIONARY,
  302. "noanonymous", SASL_SEC_NOANONYMOUS,
  303. +#if SASL_VERSION_MAJOR >= 2
  304. + "mutual_auth", SASL_SEC_MUTUAL_AUTH,
  305. +#endif
  306. 0,
  307. };
  308. @@ -127,6 +130,44 @@
  309. #define STR(x) vstring_str(x)
  310. /*
  311. + * Macros to handle API differences between SASLv1 and SASLv2.
  312. + * Specifics:
  313. + * The SASL_LOG_* constants were renamed in SASLv2.
  314. + * SASLv2's sasl_client_new takes two new parameters to specify local
  315. + * and remote IP addresses for auth mechs that use them.
  316. + * SASLv2's sasl_client_start function no longer takes the secret parameter.
  317. + * SASLv2's sasl_decode64 function takes an extra parameter for the
  318. + * length of the output buffer.
  319. + *
  320. + * The other major change is that SASLv2 now takes more responsibility for
  321. + * deallocating memory that it allocates internally. Thus, some of the
  322. + * function parameters are now 'const', to make sure we don't try to free
  323. + * them too. This is dealt with in the code later on.
  324. + */
  325. +
  326. +#if SASL_VERSION_MAJOR < 2
  327. +/* SASL version 1.x */
  328. +#define SASL_LOG_WARN SASL_LOG_WARNING
  329. +#define SASL_LOG_NOTE SASL_LOG_INFO
  330. +#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
  331. + sasl_client_new(srv, fqdn, prompt, secflags, pconn)
  332. +#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
  333. + sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
  334. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  335. + sasl_decode64(in, inlen, out, outlen)
  336. +#endif
  337. +
  338. +#if SASL_VERSION_MAJOR >= 2
  339. +/* SASL version > 2.x */
  340. +#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
  341. + sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
  342. +#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
  343. + sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
  344. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  345. + sasl_decode64(in, inlen, out, outmaxlen, outlen)
  346. +#endif
  347. +
  348. + /*
  349. * Per-host login/password information.
  350. */
  351. static MAPS *smtp_sasl_passwd_map;
  352. @@ -137,14 +178,18 @@
  353. const char *message)
  354. {
  355. switch (priority) {
  356. - case SASL_LOG_ERR:
  357. - case SASL_LOG_WARNING:
  358. + case SASL_LOG_ERR: /* unusual errors */
  359. + case SASL_LOG_WARN: /* non-fatal warnings */
  360. msg_warn("SASL authentication problem: %s", message);
  361. break;
  362. - case SASL_LOG_INFO:
  363. + case SASL_LOG_NOTE: /* other info */
  364. if (msg_verbose)
  365. msg_info("SASL authentication info: %s", message);
  366. break;
  367. +#if SASL_VERSION_MAJOR >= 2
  368. + case SASL_LOG_FAIL: /* authentication failures - SASLv2 only */
  369. + msg_warn("SASL authentication failure: %s", message);
  370. +#endif
  371. }
  372. return (SASL_OK);
  373. }
  374. @@ -317,7 +362,9 @@
  375. memcpy((char *) state->sasl_callbacks, callbacks, sizeof(callbacks));
  376. for (cp = state->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
  377. cp->context = (void *) state;
  378. - if (sasl_client_new("smtp", state->session->host,
  379. +
  380. + if (SASL_CLIENT_NEW("smtp", state->session->host,
  381. + NULL, NULL,
  382. state->sasl_callbacks, NULL_SECFLAGS,
  383. (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
  384. msg_fatal("per-session SASL client initialization");
  385. @@ -354,7 +401,11 @@
  386. char *myname = "smtp_sasl_authenticate";
  387. unsigned enc_length;
  388. unsigned enc_length_out;
  389. +#if SASL_VERSION_MAJOR >= 2
  390. + const char *clientout;
  391. +#else
  392. char *clientout;
  393. +#endif
  394. unsigned clientoutlen;
  395. unsigned serverinlen;
  396. SMTP_RESP *resp;
  397. @@ -374,7 +425,7 @@
  398. /*
  399. * Start the client side authentication protocol.
  400. */
  401. - result = sasl_client_start((sasl_conn_t *) state->sasl_conn,
  402. + result = SASL_CLIENT_START((sasl_conn_t *) state->sasl_conn,
  403. state->sasl_mechanism_list,
  404. NO_SASL_SECRET, NO_SASL_INTERACTION,
  405. &clientout, &clientoutlen, &mechanism);
  406. @@ -404,7 +455,10 @@
  407. STR(state->sasl_encoded), enc_length,
  408. &enc_length_out) != SASL_OK)
  409. msg_panic("%s: sasl_encode64 botch", myname);
  410. +#if SASL_VERSION_MAJOR < 2
  411. + /* SASL version 1 doesn't free memory that it allocates. */
  412. free(clientout);
  413. +#endif
  414. smtp_chat_cmd(state, "AUTH %s %s", mechanism, STR(state->sasl_encoded));
  415. } else {
  416. smtp_chat_cmd(state, "AUTH %s", mechanism);
  417. @@ -423,8 +477,8 @@
  418. (void) mystrtok(&line, "- \t\n"); /* skip over result code */
  419. serverinlen = strlen(line);
  420. VSTRING_SPACE(state->sasl_decoded, serverinlen);
  421. - if (sasl_decode64(line, serverinlen,
  422. - STR(state->sasl_decoded), &enc_length) != SASL_OK) {
  423. + if (SASL_DECODE64(line, serverinlen, STR(state->sasl_decoded),
  424. + serverinlen, &enc_length) != SASL_OK) {
  425. vstring_sprintf(why, "malformed SASL challenge from server %s",
  426. state->session->namaddr);
  427. return (-1);
  428. @@ -456,7 +510,10 @@
  429. STR(state->sasl_encoded), enc_length,
  430. &enc_length_out) != SASL_OK)
  431. msg_panic("%s: sasl_encode64 botch", myname);
  432. +#if SASL_VERSION_MAJOR < 2
  433. + /* SASL version 1 doesn't free memory that it allocates. */
  434. free(clientout);
  435. +#endif
  436. } else {
  437. vstring_strcat(state->sasl_encoded, "");
  438. }
  439. @@ -487,7 +544,8 @@
  440. state->sasl_passwd = 0;
  441. }
  442. if (state->sasl_mechanism_list) {
  443. - myfree(state->sasl_mechanism_list); /* allocated in smtp_helo */
  444. + /* state->sasl_mechanism_list is allocated in smtp_sasl_helo_auth */
  445. + myfree(state->sasl_mechanism_list);
  446. state->sasl_mechanism_list = 0;
  447. }
  448. if (state->sasl_conn) {
  449. diff -ru postfix-1.1.4-orig/src/smtpd/smtpd.h postfix-1.1.4/src/smtpd/smtpd.h
  450. --- postfix-1.1.4-orig/src/smtpd/smtpd.h Mon Mar 11 00:44:45 2002
  451. +++ postfix-1.1.4/src/smtpd/smtpd.h Mon Mar 11 14:04:58 2002
  452. @@ -69,7 +69,11 @@
  453. off_t msg_size;
  454. int junk_cmds;
  455. #ifdef USE_SASL_AUTH
  456. +# if SASL_VERSION_MAJOR >= 2
  457. + const char *sasl_mechanism_list;
  458. +# else
  459. char *sasl_mechanism_list;
  460. +# endif
  461. char *sasl_method;
  462. char *sasl_username;
  463. char *sasl_sender;
  464. diff -ru postfix-1.1.4-orig/src/smtpd/smtpd_sasl_glue.c postfix-1.1.4/src/smtpd/smtpd_sasl_glue.c
  465. --- postfix-1.1.4-orig/src/smtpd/smtpd_sasl_glue.c Sun Nov 25 18:14:01 2001
  466. +++ postfix-1.1.4/src/smtpd/smtpd_sasl_glue.c Mon Mar 11 17:35:37 2002
  467. @@ -110,20 +110,69 @@
  468. */
  469. #define STR(s) vstring_str(s)
  470. + /*
  471. + * Macros to handle API differences between SASLv1 and SASLv2.
  472. + * Specifics:
  473. + * The SASL_LOG_* constants were renamed in SASLv2.
  474. + * SASLv2's sasl_server_new takes two new parameters to specify local
  475. + * and remote IP addresses for auth mechs that use them.
  476. + * SASLv2's sasl_server_start and sasl_server_step no longer have the
  477. + * errstr parameter.
  478. + * SASLv2's sasl_decode64 function takes an extra parameter for the
  479. + * length of the output buffer.
  480. + *
  481. + * The other major change is that SASLv2 now takes more responsibility for
  482. + * deallocating memory that it allocates internally. Thus, some of the
  483. + * function parameters are now 'const', to make sure we don't try to free
  484. + * them too. This is dealt with in the code later on.
  485. + */
  486. +
  487. +#if SASL_VERSION_MAJOR < 2
  488. +/* SASL version 1.x */
  489. +#define SASL_LOG_WARN SASL_LOG_WARNING
  490. +#define SASL_LOG_NOTE SASL_LOG_INFO
  491. +#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
  492. + sasl_server_new(srv, fqdn, rlm, cb, secflags, pconn)
  493. +#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
  494. + sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen, err)
  495. +#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
  496. + sasl_server_step(conn, clin, clinlen, srvout, srvoutlen, err)
  497. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  498. + sasl_decode64(in, inlen, out, outlen)
  499. +#endif
  500. +
  501. +#if SASL_VERSION_MAJOR >= 2
  502. +/* SASL version > 2.x */
  503. +#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
  504. + sasl_server_new(srv, fqdn, rlm, lport, rport, cb, secflags, pconn)
  505. +#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
  506. + sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen)
  507. +#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
  508. + sasl_server_step(conn, clin, clinlen, srvout, srvoutlen)
  509. +#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
  510. + sasl_decode64(in, inlen, out, outmaxlen, outlen)
  511. +#endif
  512. +
  513. /* smtpd_sasl_log - SASL logging callback */
  514. static int smtpd_sasl_log(void *unused_context, int priority,
  515. const char *message)
  516. {
  517. switch (priority) {
  518. - case SASL_LOG_ERR:
  519. - case SASL_LOG_WARNING:
  520. + case SASL_LOG_ERR:
  521. + case SASL_LOG_WARN:
  522. msg_warn("SASL authentication problem: %s", message);
  523. break;
  524. - case SASL_LOG_INFO:
  525. + case SASL_LOG_NOTE:
  526. if (msg_verbose)
  527. msg_info("SASL authentication info: %s", message);
  528. break;
  529. +#if SASL_VERSION_MAJOR >= 2
  530. + case SASL_LOG_FAIL:
  531. + if (msg_verbose)
  532. + msg_info("SASL authentication failure: %s", message);
  533. + break;
  534. +#endif
  535. }
  536. return SASL_OK;
  537. }
  538. @@ -144,6 +193,9 @@
  539. "noactive", SASL_SEC_NOACTIVE,
  540. "nodictionary", SASL_SEC_NODICTIONARY,
  541. "noanonymous", SASL_SEC_NOANONYMOUS,
  542. +#if SASL_VERSION_MAJOR >= 2
  543. + "mutual_auth", SASL_SEC_MUTUAL_AUTH,
  544. +#endif
  545. 0,
  546. };
  547. @@ -174,6 +226,9 @@
  548. {
  549. unsigned sasl_mechanism_count;
  550. sasl_security_properties_t sec_props;
  551. + char *iplocal;
  552. + char *ipremote;
  553. +
  554. /*
  555. * Initialize SASL-specific state variables. Use long-lived storage for
  556. @@ -195,11 +250,24 @@
  557. #define NO_SECURITY_LAYERS (0)
  558. #define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
  559. - if (sasl_server_new("smtp", var_myhostname, var_smtpd_sasl_realm,
  560. +
  561. +#if SASL_VERSION_MAJOR >= 2 && defined(USE_SASL_IP_AUTH)
  562. + /* Get IP addresses of local and remote hosts to pass to SASL. */
  563. +
  564. +#else
  565. + /* Don't give any IP information to SASL. SASLv1 doesn't use it, and
  566. + * in SASLv2 this will disable any mechs that do.
  567. + */
  568. + iplocal = NULL;
  569. + ipremote = NULL;
  570. +#endif
  571. +
  572. + if (SASL_SERVER_NEW("smtp", var_myhostname, var_smtpd_sasl_realm,
  573. + iplocal, ipremote,
  574. NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
  575. &state->sasl_conn) != SASL_OK)
  576. msg_fatal("SASL per-connection server initialization");
  577. -
  578. +
  579. /*
  580. * Security options. Some information can be found in the sasl.h include
  581. * file. Disallow anonymous authentication; this is because the
  582. @@ -239,7 +307,10 @@
  583. void smtpd_sasl_disconnect(SMTPD_STATE *state)
  584. {
  585. if (state->sasl_mechanism_list) {
  586. +#if SASL_VERSION_MAJOR < 2
  587. + /* SASL version 1 doesn't free memory that it allocates. */
  588. free(state->sasl_mechanism_list);
  589. +#endif
  590. state->sasl_mechanism_list = 0;
  591. }
  592. if (state->sasl_conn) {
  593. @@ -262,10 +333,18 @@
  594. unsigned enc_length;
  595. unsigned enc_length_out;
  596. unsigned reply_len;
  597. - char *serverout = 0;
  598. unsigned serveroutlen;
  599. int result;
  600. +
  601. +#if SASL_VERSION_MAJOR < 2
  602. + char *serverout = 0;
  603. +#else
  604. + const char *serverout = 0;
  605. +#endif
  606. +
  607. +#if SASL_VERSION_MAJOR < 2
  608. const char *errstr = 0;
  609. +#endif
  610. #define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
  611. @@ -288,8 +367,8 @@
  612. reply_len = strlen(init_response);
  613. VSTRING_SPACE(state->sasl_decoded, reply_len);
  614. dec_buffer = STR(state->sasl_decoded);
  615. - if (sasl_decode64(init_response, reply_len,
  616. - dec_buffer, &dec_length) != SASL_OK)
  617. + if (SASL_DECODE64(init_response, reply_len,
  618. + dec_buffer, reply_len, &dec_length) != SASL_OK)
  619. return ("501 Authentication failed: malformed initial response");
  620. if (msg_verbose)
  621. msg_info("%s: decoded initial response %s", myname, dec_buffer);
  622. @@ -297,7 +376,7 @@
  623. dec_buffer = 0;
  624. dec_length = 0;
  625. }
  626. - result = sasl_server_start(state->sasl_conn, sasl_method, dec_buffer,
  627. + result = SASL_SERVER_START(state->sasl_conn, sasl_method, dec_buffer,
  628. dec_length, &serverout, &serveroutlen, &errstr);
  629. /*
  630. @@ -327,7 +406,10 @@
  631. if (sasl_encode64(serverout, serveroutlen, STR(state->sasl_encoded),
  632. enc_length, &enc_length_out) != SASL_OK)
  633. msg_panic("%s: sasl_encode64 botch", myname);
  634. +#if SASL_VERSION_MAJOR < 2
  635. + /* SASL version 1 doesn't free memory that it allocates. */
  636. free(serverout);
  637. +#endif
  638. serverout = 0;
  639. smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
  640. @@ -342,21 +424,24 @@
  641. return ("501 Authentication aborted"); /* XXX */
  642. reply_len = VSTRING_LEN(state->buffer);
  643. VSTRING_SPACE(state->sasl_decoded, reply_len);
  644. - if (sasl_decode64(vstring_str(state->buffer), reply_len,
  645. - STR(state->sasl_decoded), &dec_length) != SASL_OK)
  646. + if (SASL_DECODE64(vstring_str(state->buffer), reply_len,
  647. + STR(state->sasl_decoded), reply_len,
  648. + &dec_length) != SASL_OK)
  649. return ("501 Error: malformed authentication response");
  650. if (msg_verbose)
  651. msg_info("%s: decoded response: %.*s",
  652. myname, (int) dec_length, STR(state->sasl_decoded));
  653. - result = sasl_server_step(state->sasl_conn, STR(state->sasl_decoded),
  654. + result = SASL_SERVER_STEP(state->sasl_conn, STR(state->sasl_decoded),
  655. dec_length, &serverout, &serveroutlen, &errstr);
  656. }
  657. +#if SASL_VERSION_MAJOR < 2
  658. /*
  659. * Cleanup. What an awful interface.
  660. */
  661. if (serverout)
  662. free(serverout);
  663. +#endif
  664. /*
  665. * The authentication protocol was completed.
  666. @@ -369,8 +454,13 @@
  667. * accounting purposes. For the sake of completeness we also record the
  668. * authentication method that was used. XXX Do not free(serverout).
  669. */
  670. +#if SASL_VERSION_MAJOR >= 2
  671. + result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
  672. + (const void **) &serverout);
  673. +#else
  674. result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
  675. (void **) &serverout);
  676. +#endif
  677. if (result != SASL_OK || serverout == 0)
  678. msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
  679. state->sasl_username = mystrdup(serverout);