]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3-20051222
authorWietse Venema <wietse@porcupine.org>
Thu, 22 Dec 2005 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:31:57 +0000 (06:31 +0000)
33 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/SASL_README
postfix/RELEASE_NOTES
postfix/html/SASL_README.html
postfix/html/postconf.1.html
postfix/html/postconf.5.html
postfix/html/trivial-rewrite.8.html
postfix/man/man1/postconf.1
postfix/man/man5/postconf.5
postfix/man/man8/trivial-rewrite.8
postfix/mantools/postlink
postfix/proto/SASL_README.html
postfix/proto/postconf.proto
postfix/src/dns/dns.h
postfix/src/dns/dns_lookup.c
postfix/src/dns/dns_rr.c
postfix/src/dns/dns_sa_to_rr.c
postfix/src/dns/test_dns_lookup.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postconf/postconf.c
postfix/src/smtpd/smtpd_check.c
postfix/src/trivial-rewrite/resolve.c
postfix/src/trivial-rewrite/trivial-rewrite.c
postfix/src/util/sys_defs.h
postfix/src/util/unescape.c
postfix/src/util/vstring.c
postfix/src/util/vstring.h
postfix/src/xsasl/Makefile.in
postfix/src/xsasl/xsasl_dovecot.h [new file with mode: 0644]
postfix/src/xsasl/xsasl_dovecot_server.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_server.c

index 785f167846ecba7c890eb316d1ff12f47908005f..77268881747d7fe985f8881f0fc8f0aa60791d06 100644 (file)
@@ -44,9 +44,6 @@
 -TCRYPTO_EX_DATA
 -TCTABLE
 -TCTABLE_ENTRY
--TXSASL_CYRUS_CLIENT
--TXSASL_CYRUS_ERROR_INFO
--TXSASL_CYRUS_SERVER
 -TDELIVER_ATTR
 -TDELIVER_REQUEST
 -TDELTA_TIME
 -TXSASL_CLIENT
 -TXSASL_CLIENT_IMPL
 -TXSASL_CLIENT_IMPL_INFO
+-TXSASL_CYRUS_CLIENT
+-TXSASL_CYRUS_ERROR_INFO
+-TXSASL_CYRUS_SERVER
+-TXSASL_DOVECOT_SERVER
+-TXSASL_DOVECOT_SERVER_IMPL
 -TXSASL_SERVER
 -TXSASL_SERVER_IMPL
 -TXSASL_SERVER_IMPL_INFO
index d11533737efd8aebedd0acd53c21b32957e112ab..1f6fbf838bad5e8844d1a82058a0d3fc2f974d7b 100644 (file)
@@ -11625,10 +11625,39 @@ Apologies for any names omitted.
        user" errors by "authentication failed" errors.  File:
        xsasl/xsasl_cyrus_server.c.
 
-Open problems:
+       Safety: the Postfix SMTP client no longer uses CNAME expanded
+       hostnames for logging, SASL password lookup, TLS policy
+       decisions, or TLS certificate verification.  Instead it
+       uses the name of the recipient domain, or the host or domain
+       name specified in Postfix configuration files. Of course
+       this won't prevent cheating with hostnames that appear in
+       MX lookup results. To avoid that you will have to suppress
+       MX lookups with explicit [hostname] entries in transport
+       maps. Files: dns/dns_lookup.c, dns/dns_rr.c.
+
+20051222
+
+       Feature: Dovecot SASL authentication (server side) plug-in
+       by Timo Sirainen. This builds without external library
+       dependencies and is therefore compiled in by default.
+       Files: xsasl/xsasl_dovecot_server.[hc].
+
+       Safety: set the default LANG=C, instead of deleting LANG
+       from the environment and assuming the right thing will
+       happen. File: global/mail_params.h.
+
+       Safety: always add the ISASCII() requirement to the ISXXX()
+       macros, because they are used for protocol and policy
+       enforcement.  File: util/sys_defs.h.
+
+       Bugfix: null pointer in the 20051219 policy delegation
+       crypto attributes.  File: smtpd/smtpd_check.c.
+
+       Compatibility: "resolve_numeric_domain = yes" will accept
+       addresses with numeric domains instead of rejecting them as
+       invalid. Files: trivial-rewrite/resolve.c, util/vstring.c.
 
-       Reject numeric domains only when strict envelope syntax is
-       turned on.
+Open problems:
 
        "postsuper -r" no longer resets the message arrival time,
        because pickup(8) no longer overrides queue file time stamp
index da0e31b7daf1a58d40cf9ba0c067e8169e5aa3e9..12ca1c6b3adc79a02a39795cc187e90f68a1e93b 100644 (file)
@@ -28,9 +28,12 @@ search its SASL password table by the sender email address.
 This document covers the following topics:
 
   * What SASL versions are supported
+  * Building Postfix with Dovecot SASL support
   * Building the Cyrus SASL library
   * Building Postfix with Cyrus SASL support
   * Enabling SASL authentication in the Postfix SMTP server
+  * Dovecot SASL configuration for the Postfix SMTP server
+  * Cyrus SASL configuration for the Postfix SMTP server
   * Testing SASL authentication in the Postfix SMTP server
   * Trouble shooting the SASL internals
   * Enabling SASL authentication in the Postfix SMTP client
@@ -38,10 +41,45 @@ This document covers the following topics:
 
 W\bWh\bha\bat\bt S\bSA\bAS\bSL\bL v\bve\ber\brs\bsi\bio\bon\bns\bs a\bar\bre\be s\bsu\bup\bpp\bpo\bor\brt\bte\bed\bd
 
-This document describes Postfix with Cyrus SASL version 1 and Cyrus SASL
-version 2. Postfix version 2.3 introduces has a plug-in mechanism for other
-SASL implementations. Support for other implementations is currently not part
-of the Postfix distribution and will be described elsewhere.
+This document describes Postfix with the following SASL implementations:
+
+  * Cyrus SASL version 1 (client and server).
+
+  * Cyrus SASL version 2 (client and server).
+
+  * Dovecot protocol version 1 (server only, Postfix version 2.3 and later)
+
+Postfix version 2.3 introduces a plug-in mechanism that provides support for
+multiple SASL implementations. To find out what implementations are built into
+Postfix, use the following commands:
+
+    % postconf -a (SASL support in the SMTP server)
+    % postconf -A (SASL support in the SMTP+LMTP client)
+
+Needless to say, these commands are not available in Postfix versions before
+2.3.
+
+B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh D\bDo\bov\bve\bec\bco\bot\bt S\bSA\bAS\bSL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
+
+Dovecot is available via http://www.dovecot.org/. It uses its own daemon
+process for authentication. Building Postfix with Dovecot SASL support is
+relatively easy, because there is no need to link extra libraries into Postfix.
+
+To generate the necessary Makefiles, execute the following in the Postfix top-
+level directory:
+
+% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SASL_SERVER=\"dovecot\"'
+
+Notes:
+
+  * The "-DDEF_SASL_SERVER" stuff is not necessary; it just makes Postfix
+    configuration a little more convenient because you don't have to specify
+    the SASL plug-in type in the Postfix main.cf file.
+
+  * If you also want support for LDAP or TLS, you will have to merge their
+    CCARGS and AUXLIBS into the above command line.
+
+  * After this, proceed with "make" as described in the INSTALL document.
 
 B\bBu\bui\bil\bld\bdi\bin\bng\bg t\bth\bhe\be C\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL l\bli\bib\bbr\bra\bar\bry\by
 
@@ -116,6 +154,36 @@ and later):
 
 Note: the SASL login names will be shared with the entire world.
 
+D\bDo\bov\bve\bec\bco\bot\bt S\bSA\bAS\bSL\bL c\bco\bon\bnf\bfi\big\bgu\bur\bra\bat\bti\bio\bon\bn f\bfo\bor\br t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP s\bse\ber\brv\bve\ber\br
+
+On the Postfix side you need to specify the location of the Dovecot
+authentication daemon socket. We use a pathname relative to the Postfix queue
+directory, so that it will work whether or not Postfix runs chrooted:
+
+    /etc/postfix/main.cf:
+        smtpd_sasl_type = dovecot
+        smtpd_sasl_path = private/auth
+
+On the Dovecot side you also need to specify the Dovecot authentication daemon
+socket. In this case we specify an absolute pathname. In the example we assume
+that the Postfix queue is under /var/spool/postfix/.
+
+    /some/where/dovecot.conf:
+        auth default {
+          ..
+          socket listen {
+       client {
+         path = /var/spool/postfix/private/auth
+         mode = 0666
+       }
+          }
+        }
+
+See the Dovecot documentation for how to configure the Dovecot authentication
+server.
+
+C\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL c\bco\bon\bnf\bfi\big\bgu\bur\bra\bat\bti\bio\bon\bn f\bfo\bor\br t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP s\bse\ber\brv\bve\ber\br
+
 In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or /usr/local/lib/
 sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to specify how the server
 should validate client passwords.
@@ -374,4 +442,6 @@ C\bCr\bre\bed\bdi\bit\bts\bs
     reject_unauthenticated_sender_login_mismatch, and revised the docs.
   * Wietse made another iteration through the code to add plug-in support for
     multiple implementations.
+  * The Dovecot plug-in was originally implemented by Timo Sirainen of
+    Procontrol, Finland.
 
index df9b5f944d2bf7c83903bd668f5bc6f1b7e1ae02..0554a708913c70ceeee45fd37bafc49007d7c9a9 100644 (file)
@@ -17,6 +17,16 @@ Incompatibility with Postfix 2.1 and earlier
 If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2
 before proceeding.
 
+Major changes with snapshot 20051222
+====================================
+
+Dovecot SASL support (SMTP server only). Details can be found
+in the SASL_README document.
+
+You can now use "resolve_numeric_address = yes" to stop Postfix
+from rejecting user@ipaddress as an invalid destination. It will
+deliver the mail to user@[ipaddress] instead.
+
 Incompatibility with snapshot 20051220
 ======================================
 
index 4a720afc995e2303b7791444181b3a3562f23dd4..98b848f459370499b251b7b0e8541f85bf2f0602 100644 (file)
@@ -49,6 +49,9 @@ sender email address. </p>
 
 <li><a href="#versions">What SASL versions are supported</a>
 
+<li><a href="#build_dovecot">Building Postfix with Dovecot SASL
+support</a></li>
+
 <li><a href="#build_sasl">Building the Cyrus SASL library</a>
 
 <li><a href="#build_postfix">Building Postfix with Cyrus SASL
@@ -57,6 +60,12 @@ support</a></li>
 <li><a href="#server_sasl">Enabling SASL authentication in the
 Postfix SMTP server</a></li>
 
+<li><a href="#server_dovecot">Dovecot SASL configuration for the Postfix
+SMTP server</a></li>
+
+<li><a href="#server_cyrus">Cyrus SASL configuration for the Postfix
+SMTP server</a></li>
+
 <li><a href="#server_test">Testing SASL authentication in the
 Postfix SMTP server</a></li>
 
@@ -71,11 +80,66 @@ Postfix SMTP client</a></li>
 
 <h2><a name="versions">What SASL versions are supported</a></h2>
 
-<p> This document describes Postfix with Cyrus SASL version 1 and
-Cyrus SASL version 2. Postfix version 2.3 introduces has a plug-in
-mechanism for other SASL implementations.  Support for other
-implementations is currently not part of the Postfix distribution
-and will be described elsewhere.  </p>
+<p> This document describes Postfix with the following SASL
+implementations: </p>
+
+<ul>
+
+<li> <p> Cyrus SASL version 1 (client and server). </p>
+
+<li> <p> Cyrus SASL version 2 (client and server). </p>
+
+<li> <p> Dovecot protocol version 1 (server only, Postfix version
+2.3 and later) </p>
+
+</ul>
+
+<p> Postfix version 2.3 introduces a plug-in mechanism that provides
+support for multiple SASL implementations.  To find out what
+implementations are built into Postfix, use the following commands:
+</p>
+
+<blockquote>
+<pre>
+% postconf -a (SASL support in the SMTP server)
+% postconf -A (SASL support in the SMTP+LMTP client)
+</pre>
+</blockquote>
+
+<p> Needless to say, these commands are not available in Postfix
+versions before 2.3. </p>
+
+<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
+support</a></h2>
+
+<p> Dovecot is available via <a href="http://www.dovecot.org/">http://www.dovecot.org/</a>. It uses its
+own daemon process for authentication. Building Postfix with Dovecot
+SASL support is relatively easy, because there is no need to link
+extra libraries into Postfix. </p>
+
+<p> To generate the necessary Makefiles, execute the following
+in the Postfix top-level directory: </p>
+
+<pre>
+% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SASL_SERVER=\"dovecot\"'
+</pre>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The "-DDEF_SASL_SERVER" stuff is not necessary; it just
+makes Postfix configuration a little more convenient because you
+don't have to specify the SASL plug-in type in the Postfix main.cf
+file.  </p>
+
+<li> <p> If you also want support for LDAP or TLS, you will have to merge
+their CCARGS and AUXLIBS into the above command line. </p>
+
+<li> <p> After this, proceed with "<tt>make</tt>" as described in the
+<a href="INSTALL.html">INSTALL</a> document. </p>
+
+</ul>
 
 <h2><a name="build_sasl">Building the Cyrus SASL library</a></h2>
 
@@ -186,6 +250,48 @@ SMTP server</a></h2>
 <p> Note: the SASL login names will be shared with the entire world.
 </p>
 
+<h2><a name="server_dovecot">Dovecot SASL configuration for the
+Postfix SMTP server</a></h2>
+
+<p> On the Postfix side you need to specify the location of the
+Dovecot authentication daemon socket. We use a pathname relative
+to the Postfix queue directory, so that it will work whether or not
+Postfix runs chrooted: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    <a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a> = dovecot
+    <a href="postconf.5.html#smtpd_sasl_path">smtpd_sasl_path</a> = private/auth
+</pre>
+</blockquote>
+
+<p> On the Dovecot side you also need to specify the Dovecot
+authentication daemon socket. In this case we specify an
+absolute pathname. In the example we assume that the 
+Postfix queue is under /var/spool/postfix/. </p>
+
+<blockquote>
+<pre>
+/some/where/dovecot.conf:
+    auth default {
+      ..
+      socket listen {
+       client {
+         path = /var/spool/postfix/private/auth
+         mode = 0666
+       }
+      }
+    }
+</pre>
+</blockquote>
+
+<p> See the Dovecot documentation for how to configure the Dovecot
+authentication server. </p>
+
+<h2><a name="server_cyrus">Cyrus SASL configuration for the Postfix
+SMTP server</a></h2>
+
 <p> In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or
 /usr/local/lib/sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to
 specify how the server should validate client passwords. </p>
@@ -562,6 +668,9 @@ of SuSE Rhein/Main AG.
 <li> Wietse made another iteration through the code to add
 plug-in support for multiple implementations.
 
+<li> The Dovecot plug-in was originally implemented by Timo Sirainen
+of Procontrol, Finland.
+
 </ul>
 
 </body>
index 7e4de63d225370730c9c20fea9c552d1218d0eb0..48139eb90341db0521710bce254df00aea738702 100644 (file)
@@ -28,87 +28,99 @@ POSTCONF(1)                                                        POSTCONF(1)
 
        <b>-a</b>     List the available SASL server plug-in types.   The
               SASL    plug-in   type   is   selected   with   the
-              <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b> configuration parameter.
+              <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b> configuration parameter by specify-
+              ing one of the names listed below.
 
-              This feature is  available  with  Postfix  2.3  and
+              This  feature  is  available  with  Postfix 2.3 and
               later.
 
-       <b>-A</b>     List  the available SASL client plug-in types.  The
-              SASL   plug-in   type   is   selected   with    the
-              <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>   or   <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b>  configuration
-              parameters.
+              <b>cyrus</b>  This server plug-in is available when  Post-
+                     fix is built with Cyrus SASL support.
+
+              <b>dovecot</b>
+                     This  server  plug-in  requires  the Dovecot
+                     authentication server.
+
+       <b>-A</b>     List the available SASL client plug-in types.   The
+              SASL    plug-in   type   is   selected   with   the
+              <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>  or   <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b>   configuration
+              parameters  by  specifying  one of the names listed
+              below.
 
               This feature is  available  with  Postfix  2.3  and
               later.
 
+              <b>cyrus</b>  This  client plug-in is available when Post-
+                     fix is built with Cyrus SASL support.
+
        <b>-b</b> [<i>template</i><b>_</b><i>file</i>]
               Display the message text that appears at the begin-
-              ning of delivery  status  notification  (DSN)  mes-
-              sages,  with  $<b>name</b>  expressions replaced by actual
-              values.  To override  the  built-in  message  text,
-              specify  a  template file at the end of the command
-              line, or specify a template file  in  main.cf  with
-              the   <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b>   parameter.   To  force
-              selection of the built-in message  text  templates,
-              specify  an empty template file name (in shell lan-
+              ning  of  delivery  status  notification (DSN) mes-
+              sages, with $<b>name</b> expressions  replaced  by  actual
+              values.   To  override  the  built-in message text,
+              specify a template file at the end of  the  command
+              line,  or  specify  a template file in main.cf with
+              the  <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b>  parameter.    To   force
+              selection  of  the built-in message text templates,
+              specify an empty template file name (in shell  lan-
               guage: "").
 
-              This feature is  available  with  Postfix  2.3  and
+              This  feature  is  available  with  Postfix 2.3 and
               later.
 
        <b>-c</b> <i>config</i><b>_</b><i>dir</i>
-              The  <b>main.cf</b>  configuration  file  is  in the named
+              The <b>main.cf</b> configuration  file  is  in  the  named
               directory  instead  of  the  default  configuration
               directory.
 
-       <b>-d</b>     Print  default parameter settings instead of actual
+       <b>-d</b>     Print default parameter settings instead of  actual
               settings.
 
-       <b>-e</b>     Edit the <b>main.cf</b> configuration file.  The  file  is
+       <b>-e</b>     Edit  the  <b>main.cf</b>  configuration file. The file is
               copied to a temporary file then renamed into place.
-              Parameters and values are specified on the  command
-              line.   Use   quotes  in  order  to  protect  shell
+              Parameters  and values are specified on the command
+              line.  Use  quotes  in  order  to   protect   shell
               metacharacters and whitespace.
 
-       <b>-h</b>     Show parameter values only, not  the  ``name  =  ''
+       <b>-h</b>     Show  parameter  values  only,  not the ``name = ''
               label that normally precedes the value.
 
-       <b>-l</b>     List  the  names  of  all supported mailbox locking
+       <b>-l</b>     List the names of  all  supported  mailbox  locking
               methods.  Postfix supports the following methods:
 
-              <b>flock</b>  A kernel-based advisory locking  method  for
-                     local  files  only.   This locking method is
-                     available on systems with a  BSD  compatible
+              <b>flock</b>  A  kernel-based  advisory locking method for
+                     local files only.  This  locking  method  is
+                     available  on  systems with a BSD compatible
                      library.
 
-              <b>fcntl</b>  A  kernel-based  advisory locking method for
+              <b>fcntl</b>  A kernel-based advisory locking  method  for
                      local and remote files.
 
               <b>dotlock</b>
-                     An  application-level  locking  method.   An
-                     application  locks  a file named <i>filename</i> by
-                     creating a file  named  <i>filename</i><b>.lock</b>.   The
-                     application  is  expected  to remove its own
-                     lock file, as well as stale lock files  that
+                     An   application-level  locking  method.  An
+                     application locks a file named  <i>filename</i>  by
+                     creating  a  file  named <i>filename</i><b>.lock</b>.  The
+                     application is expected to  remove  its  own
+                     lock  file, as well as stale lock files that
                      were left behind after abnormal termination.
 
        <b>-m</b>     List the names of all supported lookup table types.
-              In  Postfix  configuration files, lookup tables are
-              specified as <i>type</i><b>:</b><i>name</i>, where <i>type</i> is  one  of  the
-              types  listed  below. The table <i>name</i> syntax depends
-              on the lookup table type as described in the  <a href="DATABASE_README.html">DATA</a>-
+              In Postfix configuration files, lookup  tables  are
+              specified  as  <i>type</i><b>:</b><i>name</i>,  where <i>type</i> is one of the
+              types listed below. The table <i>name</i>  syntax  depends
+              on  the lookup table type as described in the <a href="DATABASE_README.html">DATA</a>-
               <a href="DATABASE_README.html">BASE_README</a> document.
 
-              <b>btree</b>  A  sorted, balanced tree structure.  This is
+              <b>btree</b>  A sorted, balanced tree structure.  This  is
                      available on systems with support for Berke-
                      ley DB databases.
 
-              <b>cdb</b>    A  read-optimized  structure with no support
-                     for incremental updates.  This is  available
+              <b>cdb</b>    A read-optimized structure with  no  support
+                     for  incremental updates.  This is available
                      on systems with support for CDB databases.
 
-              <b>cidr</b>   A  table  that associates values with Class-
-                     less Inter-Domain Routing  (CIDR)  patterns.
+              <b>cidr</b>   A table that associates values  with  Class-
+                     less  Inter-Domain  Routing (CIDR) patterns.
                      This is described in <a href="cidr_table.5.html"><b>cidr_table</b>(5)</a>.
 
               <b>dbm</b>    An indexed file type based on hashing.  This
@@ -117,75 +129,75 @@ POSTCONF(1)                                                        POSTCONF(1)
 
               <b>environ</b>
                      The  UNIX  process  environment  array.  The
-                     lookup key is the variable name.  Originally
-                     implemented  for  testing,  someone may find
+                     lookup  key is the variable name. Originally
+                     implemented for testing,  someone  may  find
                      this useful someday.
 
               <b>hash</b>   An indexed file type based on hashing.  This
-                     is  available  on  systems  with support for
+                     is available on  systems  with  support  for
                      Berkeley DB databases.
 
               <b>ldap</b> (read-only)
-                     Perform lookups  using  the  LDAP  protocol.
+                     Perform  lookups  using  the  LDAP protocol.
                      This is described in <a href="ldap_table.5.html"><b>ldap_table</b>(5)</a>.
 
               <b>mysql</b> (read-only)
-                     Perform  lookups  using  the MYSQL protocol.
+                     Perform lookups using  the  MYSQL  protocol.
                      This is described in <a href="mysql_table.5.html"><b>mysql_table</b>(5)</a>.
 
               <b>pcre</b> (read-only)
                      A lookup table based on Perl Compatible Reg-
-                     ular   Expressions.   The   file  format  is
+                     ular  Expressions.  The   file   format   is
                      described in <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
               <b>pgsql</b> (read-only)
-                     Perform lookups using the PostgreSQL  proto-
+                     Perform  lookups using the PostgreSQL proto-
                      col. This is described in <a href="pgsql_table.5.html"><b>pgsql_table</b>(5)</a>.
 
               <b>proxy</b> (read-only)
-                     A  lookup  table that is implemented via the
-                     Postfix <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table  name
+                     A lookup table that is implemented  via  the
+                     Postfix  <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table name
                      syntax is <i>type</i><b>:</b><i>name</i>.
 
               <b>regexp</b> (read-only)
                      A lookup table based on regular expressions.
-                     The file format is described  in  <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
+                     The  file  format is described in <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
                      <a href="regexp_table.5.html"><b>ble</b>(5)</a>.
 
               <b>sdbm</b>   An indexed file type based on hashing.  This
-                     is available on  systems  with  support  for
+                     is  available  on  systems  with support for
                      SDBM databases.
 
               <b>static</b> (read-only)
-                     A  table  that  always  returns  its name as
-                     lookup result.  For  example,  <b>static:foobar</b>
-                     always  returns  the string <b>foobar</b> as lookup
+                     A table that  always  returns  its  name  as
+                     lookup  result.  For  example, <b>static:foobar</b>
+                     always returns the string <b>foobar</b>  as  lookup
                      result.
 
               <b>tcp</b> (read-only)
                      Perform lookups using a simple request-reply
-                     protocol  that is described in <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
-                     This feature is not  included  with  Postfix
+                     protocol that is described in  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
+                     This  feature  is  not included with Postfix
                      2.2.
 
               <b>unix</b> (read-only)
-                     A  limited way to query the UNIX authentica-
+                     A limited way to query the UNIX  authentica-
                      tion  database.  The  following  tables  are
                      implemented:
 
                      <b>unix:passwd.byname</b>
-                            The  table is the UNIX password data-
-                            base. The key is a login  name.   The
-                            result  is  a  password file entry in
+                            The table is the UNIX password  data-
+                            base.  The  key is a login name.  The
+                            result is a password  file  entry  in
                             <b>passwd</b>(5) format.
 
                      <b>unix:group.byname</b>
                             The table is the UNIX group database.
-                            The  key is a group name.  The result
-                            is a group  file  entry  in  <b>group</b>(5)
+                            The key is a group name.  The  result
+                            is  a  group  file  entry in <b>group</b>(5)
                             format.
 
-              Other  table types may exist depending on how Post-
+              Other table types may exist depending on how  Post-
               fix was built.
 
        <b>-n</b>     Print parameter settings that are not left at their
@@ -194,18 +206,18 @@ POSTCONF(1)                                                        POSTCONF(1)
 
        <b>-t</b> [<i>template</i><b>_</b><i>file</i>]
               Display the templates for delivery status notifica-
-              tion  (DSN) messages. To override the built-in tem-
-              plates, specify a template file at the end  of  the
+              tion (DSN) messages. To override the built-in  tem-
+              plates,  specify  a template file at the end of the
               command line, or specify a template file in main.cf
-              with the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.  To  force
-              selection  of  the  built-in  templates, specify an
+              with  the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.  To force
+              selection of the  built-in  templates,  specify  an
               empty template file name (in shell language: "").
 
-              This feature is  available  with  Postfix  2.3  and
+              This  feature  is  available  with  Postfix 2.3 and
               later.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple <b>-v</b> options  make  the  software  increasingly
+              tiple  <b>-v</b>  options  make  the software increasingly
               verbose.
 
 <b>DIAGNOSTICS</b>
@@ -216,18 +228,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               Directory with Postfix configuration files.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <b>main.cf</b> parameters are especially relevant
+       The following <b>main.cf</b> parameters are  especially  relevant
        to this program.
 
-       The text below provides  only  a  parameter  summary.  See
+       The  text  below  provides  only  a parameter summary. See
        <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
+              The default location of  the  Postfix  main.cf  and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a> (empty)</b>
-              Pathname of a configuration file with  bounce  mes-
+              Pathname  of  a configuration file with bounce mes-
               sage templates.
 
 <b>FILES</b>
@@ -241,7 +253,7 @@ POSTCONF(1)                                                        POSTCONF(1)
        <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 03a5ec6c3eac2d5be061f72a949f4eccd82d05f8..eb78fb295e044e2707eb671329c980c9ac638d10 100644 (file)
@@ -6047,6 +6047,17 @@ or to addresses that end in the "@" null domain, and from addresses
 that rewrite into a form that ends in the "@" null domain.  </p>
 
 
+</DD>
+
+<DT><b><a name="resolve_numeric_domain">resolve_numeric_domain</a>
+(default: no)</b></DT><DD>
+
+<p> Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+rejecting the address as invalid.  </p>
+
+<p> This feature is available in Postfix 2.3 and later.
+
+
 </DD>
 
 <DT><b><a name="rewrite_service_name">rewrite_service_name</a>
index 6f62be23997a528d40d7ff04864fbd3c3aba9875..007e70dd7a8a98102fb2a0019082d464cb9aea84 100644 (file)
@@ -102,24 +102,28 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               as if the local hostname were specified, instead of
               rejecting the address as invalid.
 
+       <b><a href="postconf.5.html#resolve_numeric_domain">resolve_numeric_domain</a> (no)</b>
+              Resolve  "user@ipaddress"  as   "user@[ipaddress]",
+              instead of rejecting the address as invalid.
+
 <b>ADDRESS REWRITING CONTROLS</b>
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
               The domain name that locally-posted mail appears to
-              come  from,  and that locally posted mail is deliv-
+              come from, and that locally posted mail  is  deliv-
               ered to.
 
        <b><a href="postconf.5.html#allow_percent_hack">allow_percent_hack</a> (yes)</b>
-              Enable the rewriting of the form  "user%domain"  to
+              Enable  the  rewriting of the form "user%domain" to
               "user@domain".
 
        <b><a href="postconf.5.html#append_at_myorigin">append_at_myorigin</a> (yes)</b>
-              With  locally  submitted  mail,  append  the string
-              "@$<a href="postconf.5.html#myorigin">myorigin</a>"  to  mail  addresses  without   domain
+              With locally  submitted  mail,  append  the  string
+              "@$<a href="postconf.5.html#myorigin">myorigin</a>"   to  mail  addresses  without  domain
               information.
 
        <b><a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> (yes)</b>
-              With  locally  submitted  mail,  append  the string
-              ".$<a href="postconf.5.html#mydomain">mydomain</a>" to addresses that  have  no  ".domain"
+              With locally  submitted  mail,  append  the  string
+              ".$<a href="postconf.5.html#mydomain">mydomain</a>"  to  addresses  that have no ".domain"
               information.
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
@@ -127,75 +131,75 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               sions (user+foo).
 
        <b><a href="postconf.5.html#swap_bangpath">swap_bangpath</a> (yes)</b>
-              Enable   the   rewriting   of   "site!user"    into
+              Enable    the   rewriting   of   "site!user"   into
               "user@site".
 
        Available in Postfix 2.2 and later:
 
        <b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
-              Don't  rewrite  message headers from remote clients
+              Don't rewrite message headers from  remote  clients
               at all when this parameter is empty; otherwise, re-
-              write  message  headers  and  append  the specified
+              write message  headers  and  append  the  specified
               domain name to incomplete addresses.
 
 <b>ROUTING CONTROLS</b>
-       The following is applicable to  Postfix  version  2.0  and
-       later.   Earlier  versions  do  not have support for: <a href="postconf.5.html#virtual_transport">vir</a>-
-       <a href="postconf.5.html#virtual_transport">tual_transport</a>,  <a href="postconf.5.html#relay_transport">relay_transport</a>,   <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>,
+       The  following  is  applicable  to Postfix version 2.0 and
+       later.  Earlier versions do not  have  support  for:  <a href="postconf.5.html#virtual_transport">vir</a>-
+       <a href="postconf.5.html#virtual_transport">tual_transport</a>,   <a href="postconf.5.html#relay_transport">relay_transport</a>,  <a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>,
        <a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> or <a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
 
        <b><a href="postconf.5.html#local_transport">local_transport</a> (<a href="local.8.html">local</a>:$<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The  default  mail  delivery transport and next-hop
-              destination for final delivery  to  domains  listed
-              with  <a href="postconf.5.html#mydestination">mydestination</a>,  and  for [ipaddress] destina-
-              tions that match $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or  $<a href="postconf.5.html#proxy_interfaces">proxy_inter</a>-
+              The default mail delivery  transport  and  next-hop
+              destination  for  final  delivery to domains listed
+              with <a href="postconf.5.html#mydestination">mydestination</a>, and  for  [ipaddress]  destina-
+              tions  that match $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or $<a href="postconf.5.html#proxy_interfaces">proxy_inter</a>-
               <a href="postconf.5.html#proxy_interfaces">faces</a>.
 
        <b><a href="postconf.5.html#virtual_transport">virtual_transport</a> (virtual)</b>
-              The  default  mail  delivery transport and next-hop
-              destination for final delivery  to  domains  listed
+              The default mail delivery  transport  and  next-hop
+              destination  for  final  delivery to domains listed
               with $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>.
 
        <b><a href="postconf.5.html#relay_transport">relay_transport</a> (relay)</b>
-              The  default  mail  delivery transport and next-hop
-              destination for remote delivery to  domains  listed
+              The default mail delivery  transport  and  next-hop
+              destination  for  remote delivery to domains listed
               with $<a href="postconf.5.html#relay_domains">relay_domains</a>.
 
        <b><a href="postconf.5.html#default_transport">default_transport</a> (smtp)</b>
-              The  default  mail  delivery transport and next-hop
-              destination for  destinations  that  do  not  match
+              The default mail delivery  transport  and  next-hop
+              destination  for  destinations  that  do  not match
               $<a href="postconf.5.html#mydestination">mydestination</a>,   $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a>,   $<a href="postconf.5.html#proxy_interfaces">proxy_inter</a>-
               <a href="postconf.5.html#proxy_interfaces">faces</a>,    $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>,    $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mail-
               box_domains</a>, or $<a href="postconf.5.html#relay_domains">relay_domains</a>.
 
-       <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a>  (see  'postconf -d' out-</b>
+       <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf  -d'  out-</b>
        <b>put)</b>
               What   Postfix   features   match   subdomains   of
               "domain.tld" automatically, instead of requiring an
               explicit ".domain.tld" pattern.
 
        <b><a href="postconf.5.html#relayhost">relayhost</a> (empty)</b>
-              The  next-hop  destination of non-local mail; over-
+              The next-hop destination of non-local  mail;  over-
               rides non-<a href="ADDRESS_CLASS_README.html#local_domain_class">local domains</a> in recipient addresses.
 
        <b><a href="postconf.5.html#transport_maps">transport_maps</a> (empty)</b>
               Optional lookup tables with mappings from recipient
-              address  to  (message  delivery transport, next-hop
+              address to (message  delivery  transport,  next-hop
               destination).
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a> (empty)</b>
-              A sender-dependent override for the  global  <a href="postconf.5.html#relayhost">relay</a>-
+              A  sender-dependent  override for the global <a href="postconf.5.html#relayhost">relay</a>-
               <a href="postconf.5.html#relayhost">host</a> parameter setting.
 
 <b>ADDRESS VERIFICATION CONTROLS</b>
-       Postfix   version  2.1  introduces  sender  and  recipient
-       address verification.   This  feature  is  implemented  by
-       sending  probe email messages that are not actually deliv-
-       ered.  By default, address  verification  probes  use  the
-       same  route  as regular mail. To override specific aspects
-       of message routing for address verification probes,  spec-
+       Postfix  version  2.1  introduces  sender  and   recipient
+       address  verification.   This  feature  is  implemented by
+       sending probe email messages that are not actually  deliv-
+       ered.   By  default,  address  verification probes use the
+       same route as regular mail. To override  specific  aspects
+       of  message routing for address verification probes, spec-
        ify one or more of the following:
 
        <b><a href="postconf.5.html#address_verify_local_transport">address_verify_local_transport</a> ($<a href="postconf.5.html#local_transport">local_transport</a>)</b>
@@ -203,7 +207,7 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               address verification probes.
 
        <b><a href="postconf.5.html#address_verify_virtual_transport">address_verify_virtual_transport</a> ($<a href="postconf.5.html#virtual_transport">virtual_transport</a>)</b>
-              Overrides the <a href="postconf.5.html#virtual_transport">virtual_transport</a>  parameter  setting
+              Overrides  the  <a href="postconf.5.html#virtual_transport">virtual_transport</a> parameter setting
               for address verification probes.
 
        <b><a href="postconf.5.html#address_verify_relay_transport">address_verify_relay_transport</a> ($<a href="postconf.5.html#relay_transport">relay_transport</a>)</b>
@@ -211,35 +215,35 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               address verification probes.
 
        <b><a href="postconf.5.html#address_verify_default_transport">address_verify_default_transport</a> ($<a href="postconf.5.html#default_transport">default_transport</a>)</b>
-              Overrides the <a href="postconf.5.html#default_transport">default_transport</a>  parameter  setting
+              Overrides  the  <a href="postconf.5.html#default_transport">default_transport</a> parameter setting
               for address verification probes.
 
        <b><a href="postconf.5.html#address_verify_relayhost">address_verify_relayhost</a> ($<a href="postconf.5.html#relayhost">relayhost</a>)</b>
-              Overrides   the  <a href="postconf.5.html#relayhost">relayhost</a>  parameter  setting  for
+              Overrides  the  <a href="postconf.5.html#relayhost">relayhost</a>  parameter  setting   for
               address verification probes.
 
        <b><a href="postconf.5.html#address_verify_transport_maps">address_verify_transport_maps</a> ($<a href="postconf.5.html#transport_maps">transport_maps</a>)</b>
-              Overrides the <a href="postconf.5.html#transport_maps">transport_maps</a> parameter setting  for
+              Overrides  the <a href="postconf.5.html#transport_maps">transport_maps</a> parameter setting for
               address verification probes.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#address_verify_sender_dependent_relayhost_maps">address_verify_sender_dependent_relayhost_maps</a> (empty)</b>
               Overrides    the    <a href="postconf.5.html#sender_dependent_relayhost_maps">sender_dependent_relayhost_maps</a>
-              parameter setting for address verification  probes.
+              parameter  setting for address verification probes.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
+              The default location of  the  Postfix  main.cf  and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process may take  to
-              handle  a  request  before  it  is  terminated by a
+              How  much time a Postfix daemon process may take to
+              handle a request  before  it  is  terminated  by  a
               built-in watchdog timer.
 
        <b><a href="postconf.5.html#empty_address_recipient">empty_address_recipient</a> (MAILER-DAEMON)</b>
-              The  recipient  of  mail  addressed  to  the   null
+              The   recipient  of  mail  addressed  to  the  null
               address.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
@@ -247,12 +251,12 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               over an internal communication channel.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time  that  an  idle  Postfix
-              daemon  process  waits for the next service request
+              The  maximum  amount  of  time that an idle Postfix
+              daemon process waits for the next  service  request
               before exiting.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
-              The maximal number of connection requests before  a
+              The  maximal number of connection requests before a
               Postfix daemon process terminates.
 
        <b><a href="postconf.5.html#relocated_maps">relocated_maps</a> (empty)</b>
@@ -260,33 +264,33 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
               for users or domains that no longer exist.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The process ID  of  a  Postfix  command  or  daemon
+              The  process  ID  of  a  Postfix  command or daemon
               process.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The  process  name  of  a Postfix command or daemon
+              The process name of a  Postfix  command  or  daemon
               process.
 
        <b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
-              The location of the Postfix top-level queue  direc-
+              The  location of the Postfix top-level queue direc-
               tory.
 
        <b><a href="postconf.5.html#show_user_unknown_table_name">show_user_unknown_table_name</a> (yes)</b>
-              Display  the  name  of  the  recipient table in the
+              Display the name of  the  recipient  table  in  the
               "User unknown" responses.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
+              The  mail  system  name  that  is  prepended to the
+              process name in syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#helpful_warnings">helpful_warnings</a> (yes)</b>
-              Log warnings about problematic  configuration  set-
+              Log  warnings  about problematic configuration set-
               tings, and provide helpful suggestions.
 
 <b>SEE ALSO</b>
@@ -301,7 +305,7 @@ TRIVIAL-REWRITE(8)                                          TRIVIAL-REWRITE(8)
        <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VERIFICATION_README</a>, Postfix address verification
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 1b982d816b46d4e325987c5ee9dd62899300f334..06d43b7f71254906af9c0f220fb140a3f2be6543 100644 (file)
@@ -30,15 +30,30 @@ Options:
 .IP \fB-a\fR
 List the available SASL server plug-in types.  The SASL
 plug-in type is selected with the \fBsmtpd_sasl_type\fR
-configuration parameter.
+configuration parameter by specifying one of the names
+listed below.
 
 This feature is available with Postfix 2.3 and later.
+.RS
+.IP \fBcyrus\fR
+This server plug-in is available when Postfix is built with
+Cyrus SASL support.
+.IP \fBdovecot\fR
+This server plug-in requires the Dovecot authentication
+server.
+.RE
 .IP \fB-A\fR
 List the available SASL client plug-in types.  The SASL
 plug-in type is selected with the \fBsmtp_sasl_type\fR or
-\fBlmtp_sasl_type\fR configuration parameters.
+\fBlmtp_sasl_type\fR configuration parameters by specifying
+one of the names listed below.
 
 This feature is available with Postfix 2.3 and later.
+.RS
+.IP \fBcyrus\fR
+This client plug-in is available when Postfix is built with
+Cyrus SASL support.
+.RE
 .IP "\fB-b\fR [\fItemplate_file\fR]"
 Display the message text that appears at the beginning of
 delivery status notification (DSN) messages, with $\fBname\fR
index 97247d18b36e07e9f154de5bb72c0c91ff45de1c..192116ec4615b8cb2931eecb2508d481ddce4e71 100644 (file)
@@ -3362,6 +3362,11 @@ hostname.
 The Postfix SMTP server uses this feature to reject mail from
 or to addresses that end in the "@" null domain, and from addresses
 that rewrite into a form that ends in the "@" null domain.
+.SH resolve_numeric_domain (default: no)
+Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+rejecting the address as invalid.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH rewrite_service_name (default: rewrite)
 The name of the address rewriting service. This service rewrites
 addresses to standard form and resolves them to a (delivery method,
index b7123ee5056dd831890a47b6c56103e3fc491a85..396147f953f11462ae03f84cd352d32d74159a54 100644 (file)
@@ -105,6 +105,9 @@ looking inside quotes.
 Resolve an address that ends in the "@" null domain as if the
 local hostname were specified, instead of rejecting the address as
 invalid.
+.IP "\fBresolve_numeric_domain (no)\fR"
+Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+rejecting the address as invalid.
 .SH "ADDRESS REWRITING CONTROLS"
 .na
 .nf
index d57349ca932aa5f292dac20e79586e18aad4d2de..8301739627d804c7d3f89991363b38df31b235b6 100755 (executable)
@@ -371,6 +371,7 @@ while (<>) {
     s;\brelay_destination_concurrency_limit\b;<a href="postconf.5.html#relay_destination_concurrency_limit">$&</a>;g;
     s;\brelay_destination_recip[-</bB>]*\n* *[<bB>]*ient_limit\b;<a href="postconf.5.html#relay_destination_recipient_limit">$&</a>;g;
     s;\bresolve_null_domain\b;<a href="postconf.5.html#resolve_null_domain">$&</a>;g;
+    s;\bresolve_numeric_domain\b;<a href="postconf.5.html#resolve_numeric_domain">$&</a>;g;
     s;\bsmtp_destination_concurrency_limit\b;<a href="postconf.5.html#smtp_destination_concurrency_limit">$&</a>;g;
     s;\bsmtp_destination_recip[-</bB>]*\n* *[<bB>]*ient_limit\b;<a href="postconf.5.html#smtp_destination_recipient_limit">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_destination_concurrency_limit\b;<a href="postconf.5.html#virtual_destination_concurrency_limit">$&</a>;g;
index 90da1ee6e10549f429a9a4838c245c79eb41f9bd..a651a1ac8d747fda20ea45d1bcf642d7b773f900 100644 (file)
@@ -49,6 +49,9 @@ sender email address. </p>
 
 <li><a href="#versions">What SASL versions are supported</a>
 
+<li><a href="#build_dovecot">Building Postfix with Dovecot SASL
+support</a></li>
+
 <li><a href="#build_sasl">Building the Cyrus SASL library</a>
 
 <li><a href="#build_postfix">Building Postfix with Cyrus SASL
@@ -57,6 +60,12 @@ support</a></li>
 <li><a href="#server_sasl">Enabling SASL authentication in the
 Postfix SMTP server</a></li>
 
+<li><a href="#server_dovecot">Dovecot SASL configuration for the Postfix
+SMTP server</a></li>
+
+<li><a href="#server_cyrus">Cyrus SASL configuration for the Postfix
+SMTP server</a></li>
+
 <li><a href="#server_test">Testing SASL authentication in the
 Postfix SMTP server</a></li>
 
@@ -71,11 +80,66 @@ Postfix SMTP client</a></li>
 
 <h2><a name="versions">What SASL versions are supported</a></h2>
 
-<p> This document describes Postfix with Cyrus SASL version 1 and
-Cyrus SASL version 2. Postfix version 2.3 introduces has a plug-in
-mechanism for other SASL implementations.  Support for other
-implementations is currently not part of the Postfix distribution
-and will be described elsewhere.  </p>
+<p> This document describes Postfix with the following SASL
+implementations: </p>
+
+<ul>
+
+<li> <p> Cyrus SASL version 1 (client and server). </p>
+
+<li> <p> Cyrus SASL version 2 (client and server). </p>
+
+<li> <p> Dovecot protocol version 1 (server only, Postfix version
+2.3 and later) </p>
+
+</ul>
+
+<p> Postfix version 2.3 introduces a plug-in mechanism that provides
+support for multiple SASL implementations.  To find out what
+implementations are built into Postfix, use the following commands:
+</p>
+
+<blockquote>
+<pre>
+% postconf -a (SASL support in the SMTP server)
+% postconf -A (SASL support in the SMTP+LMTP client)
+</pre>
+</blockquote>
+
+<p> Needless to say, these commands are not available in Postfix
+versions before 2.3. </p>
+
+<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
+support</a></h2>
+
+<p> Dovecot is available via http://www.dovecot.org/. It uses its
+own daemon process for authentication. Building Postfix with Dovecot
+SASL support is relatively easy, because there is no need to link
+extra libraries into Postfix. </p>
+
+<p> To generate the necessary Makefiles, execute the following
+in the Postfix top-level directory: </p>
+
+<pre>
+% make makefiles CCARGS='-DUSE_SASL_AUTH -DDEF_SASL_SERVER=\"dovecot\"'
+</pre>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The "-DDEF_SASL_SERVER" stuff is not necessary; it just
+makes Postfix configuration a little more convenient because you
+don't have to specify the SASL plug-in type in the Postfix main.cf
+file.  </p>
+
+<li> <p> If you also want support for LDAP or TLS, you will have to merge
+their CCARGS and AUXLIBS into the above command line. </p>
+
+<li> <p> After this, proceed with "<tt>make</tt>" as described in the
+INSTALL document. </p>
+
+</ul>
 
 <h2><a name="build_sasl">Building the Cyrus SASL library</a></h2>
 
@@ -186,6 +250,48 @@ SMTP server</a></h2>
 <p> Note: the SASL login names will be shared with the entire world.
 </p>
 
+<h2><a name="server_dovecot">Dovecot SASL configuration for the
+Postfix SMTP server</a></h2>
+
+<p> On the Postfix side you need to specify the location of the
+Dovecot authentication daemon socket. We use a pathname relative
+to the Postfix queue directory, so that it will work whether or not
+Postfix runs chrooted: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    smtpd_sasl_type = dovecot
+    smtpd_sasl_path = private/auth
+</pre>
+</blockquote>
+
+<p> On the Dovecot side you also need to specify the Dovecot
+authentication daemon socket. In this case we specify an
+absolute pathname. In the example we assume that the 
+Postfix queue is under /var/spool/postfix/. </p>
+
+<blockquote>
+<pre>
+/some/where/dovecot.conf:
+    auth default {
+      ..
+      socket listen {
+       client {
+         path = /var/spool/postfix/private/auth
+         mode = 0666
+       }
+      }
+    }
+</pre>
+</blockquote>
+
+<p> See the Dovecot documentation for how to configure the Dovecot
+authentication server. </p>
+
+<h2><a name="server_cyrus">Cyrus SASL configuration for the Postfix
+SMTP server</a></h2>
+
 <p> In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or
 /usr/local/lib/sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to
 specify how the server should validate client passwords. </p>
@@ -562,6 +668,9 @@ reject_unauthenticated_sender_login_mismatch, and revised the docs.
 <li> Wietse made another iteration through the code to add
 plug-in support for multiple implementations.
 
+<li> The Dovecot plug-in was originally implemented by Timo Sirainen
+of Procontrol, Finland.
+
 </ul>
 
 </body>
index cc47868935b4c50639b74f3f6eda39b248641c71..3bcaa68b20fc6c89b3efef8a0659bf78d3018198 100644 (file)
@@ -9116,3 +9116,10 @@ is rejected by the <b>reject_plaintext_session</b> restriction.
 </p>
 
 <p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM resolve_numeric_domain no
+
+<p> Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+rejecting the address as invalid.  </p>
+
+<p> This feature is available in Postfix 2.3 and later.
index e84ce8abc2248bbdca6d65faaee83cc90742fcb3..415c4703bc7e1967f65be4460798f24bee2e2850 100644 (file)
@@ -81,6 +81,7 @@ typedef struct DNS_FIXED {
   */
 typedef struct DNS_RR {
     char   *name;                      /* name, mystrdup()ed */
+    char   *rname;                     /* reply name, mystrdup()ed */
     unsigned short type;               /* T_A, T_CNAME, etc. */
     unsigned short class;              /* C_IN, etc. */
     unsigned int ttl;                  /* always */
@@ -104,7 +105,8 @@ extern unsigned dns_type(const char *);
  /*
   * dns_rr.c
   */
-extern DNS_RR *dns_rr_create(const char *, ushort, ushort,
+extern DNS_RR *dns_rr_create(const char *, const char *,
+                                    ushort, ushort,
                                     unsigned, unsigned,
                                     const char *, size_t);
 extern void dns_rr_free(DNS_RR *);
index 5739947690f8eac37b1058f9989ecc79758be229..5ec5b8fe4533cef57a004ab22a052a5fcf7e107b 100644 (file)
@@ -349,8 +349,9 @@ static int valid_rr_name(const char *name, const char *location,
 
 /* dns_get_rr - extract resource record from name server reply */
 
-static int dns_get_rr(DNS_RR **list, DNS_REPLY *reply, unsigned char *pos,
-                             char *rr_name, DNS_FIXED *fixed)
+static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
+                             unsigned char *pos, char *rr_name,
+                             DNS_FIXED *fixed)
 {
     char    temp[DNS_NAME_LEN];
     ssize_t data_len;
@@ -423,8 +424,8 @@ static int dns_get_rr(DNS_RR **list, DNS_REPLY *reply, unsigned char *pos,
        *dst = 0;
        break;
     }
-    *list = dns_rr_create(rr_name, fixed->type, fixed->class, fixed->ttl,
-                         pref, temp, data_len);
+    *list = dns_rr_create(orig_name, rr_name, fixed->type, fixed->class,
+                         fixed->ttl, pref, temp, data_len);
     return (DNS_OK);
 }
 
@@ -444,7 +445,7 @@ static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
 
 /* dns_get_answer - extract answers from name server reply */
 
-static int dns_get_answer(DNS_REPLY *reply, int type,
+static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
                     DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len)
 {
     char    rr_name[DNS_NAME_LEN];
@@ -518,7 +519,8 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
            CORRUPT(DNS_RETRY);
        if (type == fixed.type || type == T_ANY) {      /* requested type */
            if (rrlist) {
-               if ((status = dns_get_rr(&rr, reply, pos, rr_name, &fixed)) == DNS_OK) {
+               if ((status = dns_get_rr(&rr, orig_name, reply, pos, rr_name,
+                                        &fixed)) == DNS_OK) {
                    resource_found++;
                    *rrlist = dns_rr_append(*rrlist, rr);
                } else if (not_found_status != DNS_RETRY)
@@ -556,6 +558,7 @@ int     dns_lookup(const char *name, unsigned type, unsigned flags,
     static DNS_REPLY reply;
     int     count;
     int     status;
+    const char *orig_name = name;
 
     /*
      * DJBDNS produces a bogus A record when given a numerical hostname.
@@ -597,7 +600,8 @@ int     dns_lookup(const char *name, unsigned type, unsigned flags,
         * Extract resource records of the requested type. Pick up CNAME
         * information just in case the requested data is not found.
         */
-       status = dns_get_answer(&reply, type, rrlist, fqdn, cname, c_len);
+       status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
+                               cname, c_len);
        switch (status) {
        default:
            if (why)
index 0063a201e1b823db717dad50bee3a95bd92451ff..e4dc0f85eaa88fcab6586ce1d35bff008ff49291 100644 (file)
@@ -6,9 +6,10 @@
 /* SYNOPSIS
 /*     #include <dns.h>
 /*
-/*     DNS_RR  *dns_rr_create(name, type, class, ttl, preference,
+/*     DNS_RR  *dns_rr_create(name, rname, type, class, ttl, preference,
 /*                             data, data_len)
 /*     const char *name;
+/*     const char *rname;
 /*     unsigned short type;
 /*     unsigned short class;
 /*     unsigned int ttl;
@@ -45,7 +46,8 @@
 /*     information, and maintain lists of DNS resource records.
 /*
 /*     dns_rr_create() creates and initializes one resource record.
-/*     The \fIname\fR record specifies the record name.
+/*     The \fIname\fR field specifies the query name.
+/*     The \fIrname\fR field specifies the reply name.
 /*     \fIpreference\fR is used for MX records; \fIdata\fR is a null
 /*     pointer or specifies optional resource-specific data;
 /*     \fIdata_len\fR is the amount of resource-specific data.
 
 /* dns_rr_create - fill in resource record structure */
 
-DNS_RR *dns_rr_create(const char *name, ushort type, ushort class,
+DNS_RR *dns_rr_create(const char *name, const char *rname,
+                             ushort type, ushort class,
                              unsigned int ttl, unsigned pref,
                              const char *data, size_t data_len)
 {
@@ -106,6 +109,7 @@ DNS_RR *dns_rr_create(const char *name, ushort type, ushort class,
 
     rr = (DNS_RR *) mymalloc(sizeof(*rr) + data_len - 1);
     rr->name = mystrdup(name);
+    rr->rname = mystrdup(rname);
     rr->type = type;
     rr->class = class;
     rr->ttl = ttl;
@@ -125,6 +129,7 @@ void    dns_rr_free(DNS_RR *rr)
        if (rr->next)
            dns_rr_free(rr->next);
        myfree(rr->name);
+       myfree(rr->rname);
        myfree((char *) rr);
     }
 }
@@ -142,6 +147,7 @@ DNS_RR *dns_rr_copy(DNS_RR *src)
     dst = (DNS_RR *) mymalloc(len);
     memcpy((char *) dst, (char *) src, len);
     dst->name = mystrdup(src->name);
+    dst->rname = mystrdup(src->rname);
     dst->next = 0;
     return (dst);
 }
index da8aa9e1d862181fb22b78891b557910d939cdc3..d8a8dc94cbceaca7338f833e90c249c29e431d82 100644 (file)
@@ -54,12 +54,12 @@ DNS_RR *dns_sa_to_rr(const char *hostname, unsigned pref, struct sockaddr * sa)
 #define DUMMY_TTL      0
 
     if (sa->sa_family == AF_INET) {
-       return (dns_rr_create(hostname, T_A, C_IN, DUMMY_TTL, pref,
+       return (dns_rr_create(hostname, hostname, T_A, C_IN, DUMMY_TTL, pref,
                              (char *) &SOCK_ADDR_IN_ADDR(sa),
                              sizeof(SOCK_ADDR_IN_ADDR(sa))));
 #ifdef HAS_IPV6
     } else if (sa->sa_family == AF_INET6) {
-       return (dns_rr_create(hostname, T_AAAA, C_IN, DUMMY_TTL, pref,
+       return (dns_rr_create(hostname, hostname, T_AAAA, C_IN, DUMMY_TTL, pref,
                              (char *) &SOCK_ADDR_IN6_ADDR(sa),
                              sizeof(SOCK_ADDR_IN6_ADDR(sa))));
 #endif
index e1350fd755b055b52449f9174b0d29a15aacbe07..ac61287ace6477480296eee2884ec2dfa080f88d 100644 (file)
@@ -45,7 +45,7 @@ static void print_rr(DNS_RR *rr)
     MAI_HOSTADDR_STR host;
 
     while (rr) {
-       printf("%s: ttl: %9d ", rr->name, rr->ttl);
+       printf("%s: ttl: %9d ", rr->rname, rr->ttl);
        switch (rr->type) {
        case T_A:
 #ifdef T_AAAA
index 2decd4cef49dfd3a05c5db7ef25f0a6eaa09bad1..685bf264763f432a2ddd5db03a1699be4c3654a8 100644 (file)
@@ -1926,11 +1926,11 @@ extern int var_fflush_refresh;
   * and what Postfix exports to the external world.
   */
 #define VAR_IMPORT_ENVIRON             "import_environment"
-#define DEF_IMPORT_ENVIRON             "MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY"
+#define DEF_IMPORT_ENVIRON             "MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C"
 extern char *var_import_environ;
 
 #define VAR_EXPORT_ENVIRON             "export_environment"
-#define DEF_EXPORT_ENVIRON             "TZ MAIL_CONFIG"
+#define DEF_EXPORT_ENVIRON             "TZ MAIL_CONFIG LANG"
 extern char *var_export_environ;
 
  /*
@@ -2124,6 +2124,10 @@ extern bool var_resolve_dequoted;
 #define DEF_RESOLVE_NULLDOM            0
 extern bool var_resolve_nulldom;
 
+#define VAR_RESOLVE_NUM_DOM            "resolve_numeric_domain"
+#define DEF_RESOLVE_NUM_DOM            0
+extern bool var_resolve_num_dom;
+
  /*
   * Service names. The transport (TCP, FIFO or UNIX-domain) type is frozen
   * because you cannot simply mix them, and accessibility (private/public) is
index 70e7badf789aab87eeed41a96148b40222dc280e..ede0171970ec24755f3562570b625b7a033bc794 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20051221"
+#define MAIL_RELEASE_DATE      "20051222"
 #define MAIL_VERSION_NUMBER    "2.3"
 
 #ifdef SNAPSHOT
index be948313fe06c00393166b7d831f56097dba3fa7..ad1c2a7262ef2df1062a07ba3d289830375bb67c 100644 (file)
 /* .IP \fB-a\fR
 /*     List the available SASL server plug-in types.  The SASL
 /*     plug-in type is selected with the \fBsmtpd_sasl_type\fR
-/*     configuration parameter.
+/*     configuration parameter by specifying one of the names
+/*     listed below.
 /*
 /*     This feature is available with Postfix 2.3 and later.
+/* .RS
+/* .IP \fBcyrus\fR
+/*     This server plug-in is available when Postfix is built with
+/*     Cyrus SASL support.
+/* .IP \fBdovecot\fR
+/*     This server plug-in requires the Dovecot authentication
+/*     server.
+/* .RE
 /* .IP \fB-A\fR
 /*     List the available SASL client plug-in types.  The SASL
 /*     plug-in type is selected with the \fBsmtp_sasl_type\fR or
-/*     \fBlmtp_sasl_type\fR configuration parameters.
+/*     \fBlmtp_sasl_type\fR configuration parameters by specifying
+/*     one of the names listed below.
 /*
 /*     This feature is available with Postfix 2.3 and later.
+/* .RS
+/* .IP \fBcyrus\fR
+/*     This client plug-in is available when Postfix is built with
+/*     Cyrus SASL support.
+/* .RE
 /* .IP "\fB-b\fR [\fItemplate_file\fR]"
 /*     Display the message text that appears at the beginning of
 /*     delivery status notification (DSN) messages, with $\fBname\fR
index ec1f603856ce25b55e425691f1b38c0cdf0f7d77..9cf948c3fb9fd12c1086cbc7ba2e9aacdbbb3801 100644 (file)
@@ -2484,7 +2484,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
                            (VSTRING *) 0, (VSTRING *) 0);
     if (dns_status == DNS_NOTFOUND && h_errno == NO_DATA) {
        if (type == T_MX) {
-           server_list = dns_rr_create(domain, type, C_IN, 0, 0,
+           server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
                                        domain, strlen(domain) + 1);
            dns_status = DNS_OK;
        } else if (type == T_NS) {
@@ -3301,13 +3301,13 @@ static int check_policy_service(SMTPD_STATE *state, const char *server,
                          IF_VERIFIED(state->tls_context->issuer_CN),
                          ATTR_TYPE_STR, MAIL_ATTR_CCERT_FINGERPRINT,
                          IF_VERIFIED(state->tls_context->peer_fingerprint),
-#define IF_ENCRYPTED(x) ((state->tls_context && ((x) != 0)) ? (x) : "")
+#define IF_ENCRYPTED(x, y) ((state->tls_context && ((x) != 0)) ? (x) : (y))
                          ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_PROTOCOL,
-                         IF_ENCRYPTED(state->tls_context->protocol),
+                         IF_ENCRYPTED(state->tls_context->protocol, ""),
                          ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_CIPHER,
-                         IF_ENCRYPTED(state->tls_context->cipher_name),
+                         IF_ENCRYPTED(state->tls_context->cipher_name, ""),
                          ATTR_TYPE_NUM, MAIL_ATTR_CRYPTO_KEYSIZE,
-                         state->tls_context->cipher_usebits,
+                         IF_ENCRYPTED(state->tls_context->cipher_usebits, 0),
 #endif
                          ATTR_TYPE_END,
                          ATTR_FLAG_MISSING,    /* Reply attributes. */
index 2ba518da99d57d504d9d61266d31ef8025e62d55..f961b011169260e3b49a62995805d080d6bcaa8f 100644 (file)
@@ -366,9 +366,20 @@ static void resolve_addr(RES_CONTEXT *rp, char *sender, char *addr,
      */
     tok822_internalize(nextrcpt, tree, TOK822_STR_DEFL);
     rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
-    if (*rcpt_domain == '[' ? !valid_mailhost_literal(rcpt_domain, DONT_GRIPE) :
-       !valid_hostname(rcpt_domain, DONT_GRIPE))
-       *flags |= RESOLVE_FLAG_ERROR;
+    if (*rcpt_domain == '[') {
+       if (!valid_mailhost_literal(rcpt_domain, DONT_GRIPE))
+           *flags |= RESOLVE_FLAG_ERROR;
+    } else if (!valid_hostname(rcpt_domain, DONT_GRIPE)) {
+       if (var_resolve_num_dom && valid_hostaddr(rcpt_domain, DONT_GRIPE)) {
+           vstring_insert(nextrcpt, rcpt_domain - STR(nextrcpt), "[", 1);
+           vstring_strcat(nextrcpt, "]");
+           rcpt_domain = strrchr(STR(nextrcpt), '@') + 1;
+           if (resolve_local(rcpt_domain))     /* XXX */
+               domain = 0;
+       } else {
+           *flags |= RESOLVE_FLAG_ERROR;
+       }
+    }
     tok822_free_tree(tree);
     tree = 0;
 
index 0ab6f46dcb635aca3003b5781d13b4361b3d8a21..9852dea32ba56df94f4c729cc81f50f37f002516 100644 (file)
@@ -87,6 +87,9 @@
 /*     Resolve an address that ends in the "@" null domain as if the
 /*     local hostname were specified, instead of rejecting the address as
 /*     invalid.
+/* .IP "\fBresolve_numeric_domain (no)\fR"
+/*     Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+/*     rejecting the address as invalid.
 /* ADDRESS REWRITING CONTROLS
 /* .ad
 /* .fi
@@ -311,6 +314,7 @@ int     var_show_unk_rcpt_table;
 int     var_resolve_nulldom;
 char   *var_remote_rwr_domain;
 char   *var_snd_relay_maps;
+int     var_resolve_num_dom;
 
  /*
   * Shadow personality for address verification.
@@ -557,6 +561,7 @@ int     main(int argc, char **argv)
        VAR_RESOLVE_DEQUOTED, DEF_RESOLVE_DEQUOTED, &var_resolve_dequoted,
        VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table,
        VAR_RESOLVE_NULLDOM, DEF_RESOLVE_NULLDOM, &var_resolve_nulldom,
+       VAR_RESOLVE_NUM_DOM, DEF_RESOLVE_NUM_DOM, &var_resolve_num_dom,
        0,
     };
 
index 17d7968cfe240ae7f7b23890f7fa38f5b8f98ae7..3665210918da842cdfcbe978d7009012aeacbdff 100644 (file)
@@ -1322,12 +1322,12 @@ typedef int pid_t;
 #endif
 
  /*
-  * Making the ctype.h macros not more expensive than necessary. On some
-  * systems, ctype.h misbehaves with non-ASCII and/or negative characters.
+  * Safety. On some systems, ctype.h misbehaves with non-ASCII or negative
+  * characters. More importantly, Postfix uses the ISXXX() macros to ensure
+  * protocol compliance, so we have to rule out non-ASCII characters.
   */
-#define _UCHAR_(c)     ((unsigned char)(c))
-#ifdef UNSAFE_CTYPE
 #define ISASCII(c)     isascii(_UCHAR_(c))
+#define _UCHAR_(c)     ((unsigned char)(c))
 #define ISALNUM(c)     (ISASCII(c) && isalnum(c))
 #define ISALPHA(c)     (ISASCII(c) && isalpha(c))
 #define ISCNTRL(c)     (ISASCII(c) && iscntrl(c))
@@ -1340,21 +1340,6 @@ typedef int pid_t;
 #define ISUPPER(c)     (ISASCII(c) && isupper(c))
 #define TOLOWER(c)     (ISUPPER(c) ? tolower(c) : (c))
 #define TOUPPER(c)     (ISLOWER(c) ? toupper(c) : (c))
-#else
-#define ISASCII(c)     isascii(_UCHAR_(c))
-#define ISALNUM(c)     isalnum(_UCHAR_(c))
-#define ISALPHA(c)     isalpha(_UCHAR_(c))
-#define ISCNTRL(c)     iscntrl(_UCHAR_(c))
-#define ISDIGIT(c)     isdigit(_UCHAR_(c))
-#define ISGRAPH(c)     isgraph(_UCHAR_(c))
-#define ISLOWER(c)     islower(_UCHAR_(c))
-#define ISPRINT(c)     isprint(_UCHAR_(c))
-#define ISPUNCT(c)     ispunct(_UCHAR_(c))
-#define ISSPACE(c)     isspace(_UCHAR_(c))
-#define ISUPPER(c)     isupper(_UCHAR_(c))
-#define TOLOWER(c)     tolower(_UCHAR_(c))
-#define TOUPPER(c)     toupper(_UCHAR_(c))
-#endif
 
  /*
   * Scaffolding. I don't want to lose messages while the program is under
index 14be31fa6d01936638f53c2b2bfe9174ab8bc10c..27d9d849fb24a4e22a8dcb3c959256d8bc606296 100644 (file)
@@ -144,29 +144,32 @@ VSTRING *escape(VSTRING *result, const char *data, ssize_t len)
                VSTRING_ADDCH(result, ch);
                continue;
            } else if (ch == '\a') {            /* \a -> audible bell */
-               vstring_strcat(result, "\a");
+               vstring_strcat(result, "\\a");
                continue;
            } else if (ch == '\b') {            /* \b -> backspace */
-               vstring_strcat(result, "\b");
+               vstring_strcat(result, "\\b");
                continue;
            } else if (ch == '\f') {            /* \f -> formfeed */
-               vstring_strcat(result, "\f");
+               vstring_strcat(result, "\\f");
                continue;
            } else if (ch == '\n') {            /* \n -> newline */
-               vstring_strcat(result, "\n");
+               vstring_strcat(result, "\\n");
                continue;
            } else if (ch == '\r') {            /* \r -> carriagereturn */
-               vstring_strcat(result, "\r");
+               vstring_strcat(result, "\\r");
                continue;
            } else if (ch == '\t') {            /* \t -> horizontal tab */
-               vstring_strcat(result, "\t");
+               vstring_strcat(result, "\\t");
                continue;
            } else if (ch == '\v') {            /* \v -> vertical tab */
-               vstring_strcat(result, "\v");
+               vstring_strcat(result, "\\v");
                continue;
            }
        }
-       vstring_sprintf_append(result, "\\%03d", ch);
+       if (ISDIGIT(*UCHAR(data)))
+           vstring_sprintf_append(result, "\\%03d", ch);
+       else
+           vstring_sprintf_append(result, "\\%d", ch);
     }
     VSTRING_TERMINATE(result);
     return (result);
@@ -175,16 +178,29 @@ VSTRING *escape(VSTRING *result, const char *data, ssize_t len)
 #ifdef TEST
 
 #include <stdlib.h>
+#include <string.h>
+#include <msg.h>
 #include <vstring_vstream.h>
 
-int     main(int unused_argc, char **unused_argv)
+int     main(int argc, char **argv)
 {
     VSTRING *in = vstring_alloc(10);
     VSTRING *out = vstring_alloc(10);
+    int     un_escape = 1;
 
-    while (vstring_fgets_nonl(in, VSTREAM_IN)) {
-       unescape(out, vstring_str(in));
-       vstream_fwrite(VSTREAM_OUT, vstring_str(out), VSTRING_LEN(out));
+    if (argc > 2 || (un_escape = strcmp(argv[1], "-e")) != 0)
+       msg_fatal("usage: %s [-e (escape)]", argv[0]);
+
+    if (un_escape) {
+       while (vstring_fgets_nonl(in, VSTREAM_IN)) {
+           unescape(out, vstring_str(in));
+           vstream_fwrite(VSTREAM_OUT, vstring_str(out), VSTRING_LEN(out));
+       }
+    } else {
+       while (vstring_fgets(in, VSTREAM_IN)) {
+           escape(out, vstring_str(in), VSTRING_LEN(in));
+           vstream_fwrite(VSTREAM_OUT, vstring_str(out), VSTRING_LEN(out));
+       }
     }
     vstream_fflush(VSTREAM_OUT);
     exit(0);
index b73983b36ca1c61ccf63e11dc77ee45c20f0d3ae..c050f6381f712dc55925965a08629f54112b27ae 100644 (file)
 /*     VSTRING *vp;
 /*     int     ch;
 /*
+/*     VSTRING *vstring_insert(vp, start, src, len)
+/*     VSTRING *vp;
+/*     ssize_t start;
+/*     const char *src;
+/*     ssize_t len;
+/*
 /*     VSTRING *vstring_prepend(vp, src, len)
 /*     VSTRING *vp;
 /*     const char *src;
 /*
 /*     vstring_memchr() locates a byte in a variable-length string.
 /*
+/*     vstring_insert() inserts a buffer content into a variable-length
+/*     string at the specified start position. The result is
+/*     null-terminated.
+/*
 /*     vstring_prepend() prepends a buffer content to a variable-length
 /*     string. The result is null-terminated.
 /*
@@ -477,6 +487,34 @@ char   *vstring_memchr(VSTRING *vp, int ch)
     return (0);
 }
 
+/* vstring_insert - insert text into string */
+
+VSTRING *vstring_insert(VSTRING *vp, ssize_t start, const char *buf, ssize_t len)
+{
+    const char *myname = "vstring_insert";
+    ssize_t new_len;
+
+    /*
+     * Sanity check.
+     */
+    if (start < 0 || start >= VSTRING_LEN(vp))
+       msg_panic("vstring_insert: bad start %ld", (long) start);
+    if (len < 0)
+       msg_panic("vstring_insert: bad length %ld", (long) len);
+
+    /*
+     * Move the existing content and copy the new content.
+     */
+    new_len = VSTRING_LEN(vp) + len;
+    VSTRING_SPACE(vp, len);
+    memmove(vstring_str(vp) + start + len, vstring_str(vp) + start,
+           VSTRING_LEN(vp) - start);
+    memcpy(vstring_str(vp) + start, buf, len);
+    VSTRING_AT_OFFSET(vp, new_len);
+    VSTRING_TERMINATE(vp);
+    return (vp);
+}
+
 /* vstring_prepend - prepend text to string */
 
 VSTRING *vstring_prepend(VSTRING *vp, const char *buf, ssize_t len)
index e031bbcf856488f12d4c92335f835ce82c9c0eac..30b463d1ec197cef2ddd4100c554acca016ff61d 100644 (file)
@@ -41,6 +41,7 @@ extern VSTRING *vstring_strncat(VSTRING *, const char *, ssize_t);
 extern VSTRING *vstring_memcpy(VSTRING *, const char *, ssize_t);
 extern VSTRING *vstring_memcat(VSTRING *, const char *, ssize_t);
 extern char *vstring_memchr(VSTRING *, int);
+extern VSTRING *vstring_insert(VSTRING *, ssize_t, const char *, ssize_t);
 extern VSTRING *vstring_prepend(VSTRING *, const char *, ssize_t);
 extern VSTRING *PRINTFLIKE(2, 3) vstring_sprintf(VSTRING *, const char *,...);
 extern VSTRING *PRINTFLIKE(2, 3) vstring_sprintf_append(VSTRING *, const char *,...);
index 0e45a12fe5a74e5592d16efe0fe208418a0e50c8..2a2d51c0b58b0dea14d5aa49f2b905b2e9449706 100644 (file)
@@ -1,8 +1,10 @@
 SHELL  = /bin/sh
 SRCS   = xsasl_server.c xsasl_cyrus_server.c xsasl_cyrus_log.c \
-       xsasl_cyrus_security.c xsasl_client.c xsasl_cyrus_client.c
+       xsasl_cyrus_security.c xsasl_client.c xsasl_cyrus_client.c \
+       xsasl_dovecot_server.c
 OBJS   = xsasl_server.o xsasl_cyrus_server.o xsasl_cyrus_log.o \
-       xsasl_cyrus_security.o xsasl_client.o xsasl_cyrus_client.o
+       xsasl_cyrus_security.o xsasl_client.o xsasl_cyrus_client.o \
+       xsasl_dovecot_server.o
 HDRS   = xsasl.h
 TESTSRC        = 
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
@@ -118,6 +120,22 @@ xsasl_cyrus_server.o: xsasl.h
 xsasl_cyrus_server.o: xsasl_cyrus.h
 xsasl_cyrus_server.o: xsasl_cyrus_common.h
 xsasl_cyrus_server.o: xsasl_cyrus_server.c
+xsasl_dovecot_server.o: ../../include/argv.h
+xsasl_dovecot_server.o: ../../include/connect.h
+xsasl_dovecot_server.o: ../../include/iostuff.h
+xsasl_dovecot_server.o: ../../include/mail_params.h
+xsasl_dovecot_server.o: ../../include/msg.h
+xsasl_dovecot_server.o: ../../include/mymalloc.h
+xsasl_dovecot_server.o: ../../include/split_at.h
+xsasl_dovecot_server.o: ../../include/stringops.h
+xsasl_dovecot_server.o: ../../include/sys_defs.h
+xsasl_dovecot_server.o: ../../include/vbuf.h
+xsasl_dovecot_server.o: ../../include/vstream.h
+xsasl_dovecot_server.o: ../../include/vstring.h
+xsasl_dovecot_server.o: ../../include/vstring_vstream.h
+xsasl_dovecot_server.o: xsasl.h
+xsasl_dovecot_server.o: xsasl_dovecot.h
+xsasl_dovecot_server.o: xsasl_dovecot_server.c
 xsasl_server.o: ../../include/argv.h
 xsasl_server.o: ../../include/msg.h
 xsasl_server.o: ../../include/mymalloc.h
@@ -127,4 +145,5 @@ xsasl_server.o: ../../include/vstream.h
 xsasl_server.o: ../../include/vstring.h
 xsasl_server.o: xsasl.h
 xsasl_server.o: xsasl_cyrus.h
+xsasl_server.o: xsasl_dovecot.h
 xsasl_server.o: xsasl_server.c
diff --git a/postfix/src/xsasl/xsasl_dovecot.h b/postfix/src/xsasl/xsasl_dovecot.h
new file mode 100644 (file)
index 0000000..f99850e
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _XSASL_DOVECOT_H_INCLUDED_
+#define _XSASL_DOVECOT_H_INCLUDED_
+
+/*++
+/* NAME
+/*     xsasl_dovecot 3h
+/* SUMMARY
+/*     Dovecot SASL plug-in
+/* SYNOPSIS
+/*     #include <xsasl_dovecot.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * XSASL library.
+  */
+#include <xsasl.h>
+
+#if defined(USE_SASL_AUTH)
+
+ /*
+  * SASL protocol interface
+  */
+#define XSASL_TYPE_DOVECOT "dovecot"
+
+extern XSASL_SERVER_IMPL *xsasl_dovecot_server_init(const char *, const char *);
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_dovecot_server.c b/postfix/src/xsasl/xsasl_dovecot_server.c
new file mode 100644 (file)
index 0000000..af2f0ce
--- /dev/null
@@ -0,0 +1,496 @@
+/*++
+/* NAME
+/*     xsasl_dovecot_server 3
+/* SUMMARY
+/*     Dovecot SASL server-side plug-in
+/* SYNOPSIS
+/*     XSASL_SERVER_IMPL *xsasl_dovecot_server_init(server_type, appl_name)
+/*     const char *server_type;
+/*     const char *appl_name;
+/* DESCRIPTION
+/*     This module implements the Dovecot SASL server-side authentication
+/*     plug-in.
+/*
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/*
+/*     Panic: interface violation.
+/*
+/*     Other: the routines log a warning and return an error result
+/*     as specified in xsasl_server(3).
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Initial implementation by:
+/*     Timo Sirainen
+/*     Procontrol
+/*     Finland
+/*
+/*     Adopted by:
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <connect.h>
+#include <split_at.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* Application-specific. */
+
+#include <xsasl.h>
+#include <xsasl_dovecot.h>
+
+#ifdef USE_SASL_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
+
+ /*
+  * Class variables.
+  */
+typedef struct {
+    XSASL_SERVER_IMPL xsasl;
+    VSTREAM *sasl_stream;
+    char   *socket_path;
+    char   *mechanism_list;            /* applicable mechanisms */
+    unsigned int request_id_counter;
+} XSASL_DOVECOT_SERVER_IMPL;
+
+ /*
+  * The XSASL_DOVECOT_SERVER object is derived from the generic XSASL_SERVER
+  * object.
+  */
+typedef struct {
+    XSASL_SERVER xsasl;                        /* generic members, must be first */
+    XSASL_DOVECOT_SERVER_IMPL *impl;
+    unsigned int last_request_id;
+    char   *service;
+    char   *username;                  /* authenticated user */
+    VSTRING *sasl_line;
+} XSASL_DOVECOT_SERVER;
+
+ /*
+  * Forward declarations.
+  */
+static void xsasl_dovecot_server_done(XSASL_SERVER_IMPL *);
+static XSASL_SERVER *xsasl_dovecot_server_create(XSASL_SERVER_IMPL *,
+                                                        VSTREAM *,
+                                                        const char *,
+                                                        const char *,
+                                                        const char *);
+static void xsasl_dovecot_server_free(XSASL_SERVER *);
+static int xsasl_dovecot_server_first(XSASL_SERVER *, const char *,
+                                             const char *, VSTRING *);
+static int xsasl_dovecot_server_next(XSASL_SERVER *, const char *, VSTRING *);
+static const char *xsasl_dovecot_server_get_mechanism_list(XSASL_SERVER *);
+static const char *xsasl_dovecot_server_get_username(XSASL_SERVER *);
+
+static int xsasl_dovecot_server_connect(XSASL_DOVECOT_SERVER_IMPL *xp)
+{
+    const char *myname = "xsasl_dovecot_server_connect";
+    VSTRING *line_str, *mechanisms_str;
+    VSTREAM *sasl_stream;
+    char   *line, *cmd, *mech_name;
+    unsigned int major_version, minor_version;
+    int     fd, success;
+
+    if (msg_verbose)
+       msg_info("%s: Connecting", myname);
+
+    if ((fd = unix_connect(xp->socket_path, BLOCKING, 0)) < 0) {
+       msg_warn("SASL: Connect to %s failed: %m", xp->socket_path);
+       return (-1);
+    }
+    sasl_stream = vstream_fdopen(fd, O_RDWR);
+    vstream_control(sasl_stream, VSTREAM_CTL_PATH,
+                   xp->socket_path, 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_warn("SASL: Couldn't send handshake: %m");
+       return (-1);
+    }
+    success = 0;
+    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_warn("SASL: Protocol version error");
+               break;
+           }
+           if (major_version != AUTH_PROTOCOL_MAJOR_VERSION) {
+               /* Major version is different from ours. */
+               msg_warn("SASL: Protocol version mismatch (%d vs. %d)",
+                        major_version, AUTH_PROTOCOL_MAJOR_VERSION);
+               break;
+           }
+       } 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. */
+           success = 1;
+           break;
+       } else {
+           /* ignore any unknown commands */
+       }
+    }
+    vstring_free(line_str);
+
+    if (!success) {
+       /* handshake failed */
+       vstring_free(mechanisms_str);
+       (void) vstream_fclose(sasl_stream);
+       return (-1);
+    }
+    xp->sasl_stream = sasl_stream;
+    xp->mechanism_list =
+       translit(vstring_export(mechanisms_str), "\t", " ");
+    if (msg_verbose)
+       msg_info("%s: Mechanisms: %s", myname, xp->mechanism_list);
+    return (0);
+}
+
+static void xsasl_dovecot_server_disconnect(XSASL_DOVECOT_SERVER_IMPL *xp)
+{
+    if (xp->sasl_stream) {
+       (void) vstream_fclose(xp->sasl_stream);
+       xp->sasl_stream = 0;
+    }
+    if (xp->mechanism_list) {
+       myfree(xp->mechanism_list);
+       xp->mechanism_list = 0;
+    }
+}
+
+/* xsasl_dovecot_server_init - create implementation handle */
+
+XSASL_SERVER_IMPL *xsasl_dovecot_server_init(const char *unused_server_type,
+                                                    const char *path_info)
+{
+    XSASL_DOVECOT_SERVER_IMPL *xp;
+
+    xp = (XSASL_DOVECOT_SERVER_IMPL *) mymalloc(sizeof(*xp));
+    xp->xsasl.create = xsasl_dovecot_server_create;
+    xp->xsasl.done = xsasl_dovecot_server_done;
+    xp->socket_path = mystrdup(path_info);
+    xp->sasl_stream = 0;
+    xp->mechanism_list = 0;
+    xp->request_id_counter = 0;
+    return (&xp->xsasl);
+}
+
+/* xsasl_dovecot_server_done - dispose of implementation */
+
+static void xsasl_dovecot_server_done(XSASL_SERVER_IMPL *impl)
+{
+    XSASL_DOVECOT_SERVER_IMPL *xp = (XSASL_DOVECOT_SERVER_IMPL *) impl;
+
+    xsasl_dovecot_server_disconnect(xp);
+    myfree(xp->socket_path);
+    myfree((char *) impl);
+}
+
+/* xsasl_dovecot_server_create - create server instance */
+
+static XSASL_SERVER *xsasl_dovecot_server_create(XSASL_SERVER_IMPL *impl,
+                                                    VSTREAM *unused_stream,
+                                                        const char *service,
+                                                        const char *realm,
+                                              const char *unused_sec_props)
+{
+    const char *myname = "xsasl_dovecot_server_create";
+    XSASL_DOVECOT_SERVER *server;
+
+    if (msg_verbose)
+       msg_info("%s: SASL service=%s, realm=%s",
+                myname, service, realm ? realm : "(null)");
+
+    /*
+     * Extend the XSASL_SERVER_IMPL object with our own data. We use
+     * long-lived conversion buffers rather than local variables to avoid
+     * memory leaks in case of read/write timeout or I/O error.
+     */
+    server = (XSASL_DOVECOT_SERVER *) mymalloc(sizeof(*server));
+    server->xsasl.free = xsasl_dovecot_server_free;
+    server->xsasl.first = xsasl_dovecot_server_first;
+    server->xsasl.next = xsasl_dovecot_server_next;
+    server->xsasl.get_mechanism_list = xsasl_dovecot_server_get_mechanism_list;
+    server->xsasl.get_username = xsasl_dovecot_server_get_username;
+    server->impl = (XSASL_DOVECOT_SERVER_IMPL *) impl;
+    server->sasl_line = vstring_alloc(256);
+    server->username = 0;
+    server->service = mystrdup(service);
+    server->last_request_id = 0;
+
+    return (&server->xsasl);
+}
+
+/* xsasl_dovecot_server_get_mechanism_list - get available mechanisms */
+
+static const char *xsasl_dovecot_server_get_mechanism_list(XSASL_SERVER *xp)
+{
+    XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
+
+    if (!server->impl->sasl_stream) {
+       if (xsasl_dovecot_server_connect(server->impl) < 0)
+           return (0);
+    }
+    return (server->impl->mechanism_list);
+}
+
+/* xsasl_dovecot_server_free - destroy server instance */
+
+static void xsasl_dovecot_server_free(XSASL_SERVER *xp)
+{
+    XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
+
+    vstring_free(server->sasl_line);
+    if (server->username)
+       myfree(server->username);
+    myfree(server->service);
+    myfree((char *) server);
+}
+
+/* xsasl_dovecot_server_auth_response - encode server first/next response */
+
+static int xsasl_dovecot_parse_reply(XSASL_DOVECOT_SERVER *server, char **line)
+{
+    char   *id;
+
+    if (*line == NULL) {
+       msg_warn("SASL: Protocol error");
+       return -1;
+    }
+    id = *line;
+    *line = split_at(*line, '\t');
+
+    if (strtoul(id, NULL, 0) != server->last_request_id) {
+       /* reply to another request, shouldn't really happen.. */
+       return -1;
+    }
+    return 0;
+}
+
+static void xsasl_dovecot_parse_reply_args(XSASL_DOVECOT_SERVER *server,
+                                                char *line, VSTRING *reply,
+                                                  int success)
+{
+    char   *next;
+
+    if (server->username) {
+       myfree(server->username);
+       server->username = 0;
+    }
+
+    /*
+     * Note: TAB is part of the Dovecot protocol and must not appear in
+     * legitimate Dovecot usernames, otherwise the protocol would break.
+     */
+    for (; line != NULL; line = next) {
+       next = split_at(line, '\t');
+       if (strncmp(line, "user=", 5) == 0) {
+           server->username = mystrdup(line + 5);
+           printable(server->username, '?');
+       } else if (strncmp(line, "reason=", 7) == 0) {
+           if (!success) {
+               printable(line + 7, '?');
+               vstring_strcpy(reply, line + 7);
+           }
+       }
+    }
+}
+
+/* xsasl_dovecot_handle_reply - receive and process auth reply */
+
+static int xsasl_dovecot_handle_reply(XSASL_DOVECOT_SERVER *server,
+                                             VSTRING *reply)
+{
+    char   *myname = "xsasl_dovecot_handle_reply";
+    char   *line, *cmd;
+
+    while (vstring_get_nonl(server->sasl_line,
+                           server->impl->sasl_stream) != VSTREAM_EOF) {
+       line = vstring_str(server->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 (xsasl_dovecot_parse_reply(server, &line) == 0) {
+               /* authentication successful */
+               xsasl_dovecot_parse_reply_args(server, line, reply, 1);
+               return XSASL_AUTH_DONE;
+           }
+       } else if (strcmp(cmd, "CONT") == 0) {
+           if (xsasl_dovecot_parse_reply(server, &line) == 0) {
+               vstring_strcpy(reply, line);
+               return XSASL_AUTH_MORE;
+           }
+       } else if (strcmp(cmd, "FAIL") == 0) {
+           if (xsasl_dovecot_parse_reply(server, &line) == 0) {
+               /* authentication failure */
+               xsasl_dovecot_parse_reply_args(server, line, reply, 0);
+               return XSASL_AUTH_FAIL;
+           }
+       } else {
+           /* ignore */
+       }
+    }
+
+    vstring_strcpy(reply, "Connection lost to authentication server");
+    return XSASL_AUTH_FAIL;
+}
+
+/* is_valid_base64 - input sanitized */
+
+static int is_valid_base64(const char *data)
+{
+
+    /*
+     * XXX Maybe use ISALNUM() (isascii && isalnum, i.e. locale independent).
+     */
+    for (; *data != '\0'; data++) {
+       if (!((*data >= '0' && *data <= '9') ||
+             (*data >= 'a' && *data <= 'z') ||
+             (*data >= 'A' && *data <= 'Z') ||
+             *data == '+' || *data == '/' || *data == '='))
+           return 0;
+    }
+    return 1;
+}
+
+/* xsasl_dovecot_server_first - per-session authentication */
+
+int     xsasl_dovecot_server_first(XSASL_SERVER *xp, const char *sasl_method,
+                                 const char *init_response, VSTRING *reply)
+{
+    char   *myname = "xsasl_dovecot_server_first";
+    XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
+    int     i;
+
+#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, ""));
+
+    if (init_response)
+       if (!is_valid_base64(init_response)) {
+           vstring_strcpy(reply, "Invalid base64 data in initial response");
+           return XSASL_AUTH_FAIL;
+       }
+    for (i = 0; i < 2; i++) {
+       if (!server->impl->sasl_stream) {
+           if (xsasl_dovecot_server_connect(server->impl) < 0)
+               return (0);
+       }
+       /* send the request */
+       server->last_request_id = ++server->impl->request_id_counter;
+       vstream_fprintf(server->impl->sasl_stream,
+                       "AUTH\t%u\t%s\tservice=%s",
+                       server->last_request_id, sasl_method,
+                       server->service);
+       if (init_response) {
+
+           /*
+            * initial response is already base64 encoded, so we can send it
+            * directly.
+            */
+           vstream_fprintf(server->impl->sasl_stream,
+                           "\tresp=%s", init_response);
+       }
+       VSTREAM_PUTC('\n', server->impl->sasl_stream);
+
+       if (vstream_fflush(server->impl->sasl_stream) != VSTREAM_EOF)
+           break;
+
+       if (i == 1) {
+           vstring_strcpy(reply, "Can't connect to authentication server");
+           return XSASL_AUTH_FAIL;
+       }
+
+       /*
+        * Reconnect and try again.
+        */
+       xsasl_dovecot_server_disconnect(server->impl);
+    }
+
+    return xsasl_dovecot_handle_reply(server, reply);
+}
+
+/* xsasl_dovecot_server_next - continue authentication */
+
+static int xsasl_dovecot_server_next(XSASL_SERVER *xp, const char *request,
+                                            VSTRING *reply)
+{
+    XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
+
+    if (!is_valid_base64(request)) {
+       vstring_strcpy(reply, "Invalid base64 data in continued response");
+       return XSASL_AUTH_FAIL;
+    }
+    vstream_fprintf(server->impl->sasl_stream,
+                   "CONT\t%u\t%s\n", server->last_request_id, request);
+    if (vstream_fflush(server->impl->sasl_stream) == VSTREAM_EOF) {
+       vstring_strcpy(reply, "Connection lost to authentication server");
+       return XSASL_AUTH_FAIL;
+    }
+    return xsasl_dovecot_handle_reply(server, reply);
+}
+
+/* xsasl_dovecot_server_get_username - get authenticated username */
+
+static const char *xsasl_dovecot_server_get_username(XSASL_SERVER *xp)
+{
+    XSASL_DOVECOT_SERVER *server = (XSASL_DOVECOT_SERVER *) xp;
+
+    return (server->username);
+}
+
+#endif
index 729cb46e6bd014bcf605f019ce94e1d74ab95dc3..23531cd4a7facbfe3dd6df828e45da46aba460ae 100644 (file)
 
 #include <xsasl.h>
 #include <xsasl_cyrus.h>
+#include <xsasl_dovecot.h>
 
  /*
   * Lookup table for available SASL server implementations.
@@ -196,9 +197,12 @@ typedef struct {
 
 static XSASL_SERVER_IMPL_INFO server_impl_info[] = {
 #ifdef XSASL_TYPE_CYRUS
-    XSASL_TYPE_CYRUS, xsasl_cyrus_server_init,
+    {XSASL_TYPE_CYRUS, xsasl_cyrus_server_init},
 #endif
-    0,
+#ifdef XSASL_TYPE_DOVECOT
+    {XSASL_TYPE_DOVECOT, xsasl_dovecot_server_init},
+#endif
+    {0, 0}
 };
 
 /* xsasl_server_init - look up server implementation by name */