Merge branch 'sasl_fixes'
authorPhil Pennock <pdp@exim.org>
Sat, 18 Feb 2012 16:20:18 +0000 (11:20 -0500)
committerPhil Pennock <pdp@exim.org>
Sat, 18 Feb 2012 16:20:18 +0000 (11:20 -0500)
1  2 
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/globals.h
src/src/tls-gnu.c

index 8afccbf1d2266d989919bca2b06f52e7252873b8,5ae4f76498b4c8cd0d37812cff7cc054c2fa990c..9c39b4aa204f1202116d9207c60d22eeb319b71d
@@@ -1868,14 -1868,6 +1868,14 @@@ SUPPORT_TLS=ye
  TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto
  TLS_INCLUDE=-I/usr/local/openssl/include/
  .endd
 +.new
 +.cindex "pkg-config" "OpenSSL"
 +If you have &'pkg-config'& available, then instead you can just use:
 +.code
 +SUPPORT_TLS=yes
 +USE_OPENSSL_PC=openssl
 +.endd
 +.wen
  .cindex "USE_GNUTLS"
  If GnuTLS is installed, you should set
  .code
@@@ -1891,16 -1883,6 +1891,16 @@@ USE_GNUTLS=ye
  TLS_LIBS=-L/usr/gnu/lib -lgnutls -ltasn1 -lgcrypt
  TLS_INCLUDE=-I/usr/gnu/include
  .endd
 +.new
 +.cindex "pkg-config" "GnuTLS"
 +If you have &'pkg-config'& available, then instead you can just use:
 +.code
 +SUPPORT_TLS=yes
 +USE_GNUTLS=yes
 +USE_GNUTLS_PC=gnutls
 +.endd
 +.wen
 +
  You do not need to set TLS_INCLUDE if the relevant directory is already
  specified in INCLUDE. Details of how to configure Exim to make use of TLS are
  given in chapter &<<CHAPTLS>>&.
@@@ -2128,28 -2110,6 +2128,28 @@@ files or libraries are required. When 
  binary, attempts to configure Exim to use it cause run time configuration
  errors.
  
 +.new
 +.cindex "pkg-config" "lookups"
 +.cindex "pkg-config" "authenticators"
 +Many systems now use a tool called &'pkg-config'& to encapsulate information
 +about how to compile against a library; Exim has some initial support for
 +being able to use pkg-config for lookups and authenticators.  For any given
 +makefile variable which starts &`LOOKUP_`& or &`AUTH_`&, you can add a new
 +variable with the &`_PC`& suffix in the name and assign as the value the
 +name of the package to be queried.  The results of querying via the
 +&'pkg-config'& command will be added to the appropriate Makefile variables
 +with &`+=`& directives, so your version of &'make'& will need to support that
 +syntax.  For instance:
 +.code
 +LOOKUP_SQLITE=yes
 +LOOKUP_SQLITE_PC=sqlite3
 +AUTH_GSASL=yes
 +AUTH_GSASL_PC=libgsasl
 +AUTH_HEIMDAL_GSSAPI=yes
 +AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi
 +.endd
 +.wen
 +
  .cindex "Perl" "including support for"
  Exim can be linked with an embedded Perl interpreter, allowing Perl
  subroutines to be called during string expansion. To enable this facility,
@@@ -11824,6 -11784,16 +11824,16 @@@ command in a filter file. Its use is ex
  command, which can be found in the separate document entitled &'Exim's
  interfaces to mail filtering'&.
  
+ .new
+ .vitem &$tls_bits$&
+ .vindex "&$tls_bits$&"
+ Contains an approximation of the TLS cipher's bit-strength; the meaning of
+ this depends upon the TLS implementation used.
+ If TLS has not been negotiated, the value will be 0.
+ The value of this is automatically fed into the Cyrus SASL authenticator
+ when acting as a server, to specify the "external SSF" (a SASL term).
+ .wen
  .vitem &$tls_certificate_verified$&
  .vindex "&$tls_certificate_verified$&"
  This variable is set to &"1"& if a TLS certificate was verified when the
@@@ -23436,29 -23406,15 +23446,29 @@@ included by settin
  .code
  AUTH_CRAM_MD5=yes
  AUTH_CYRUS_SASL=yes
 +.new
 +AUTH_DOVECOT=yes
 +AUTH_GSASL=yes
 +AUTH_HEIMDAL_GSSAPI=yes
 +.wen
  AUTH_PLAINTEXT=yes
  AUTH_SPA=yes
  .endd
  in &_Local/Makefile_&, respectively. The first of these supports the CRAM-MD5
  authentication mechanism (RFC 2195), and the second provides an interface to
 -the Cyrus SASL authentication library. The third can be configured to support
 +the Cyrus SASL authentication library.
 +.new
 +The third is an interface to Dovecot's authentication system, delegating the
 +work via a socket interface.
 +The fourth provides an interface to the GNU SASL authentication library, which
 +provides mechanisms but typically not data sources.
 +The fifth provides direct access to Heimdal GSSAPI, geared for Kerberos, but
 +supporting setting a server keytab.
 +The sixth can be configured to support
  the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
 -not formally documented, but used by several MUAs. The fourth authenticator
 +not formally documented, but used by several MUAs. The seventh authenticator
  supports Microsoft's &'Secure Password Authentication'& mechanism.
 +.wen
  
  The authenticators are configured using the same syntax as other drivers (see
  section &<<SECTfordricon>>&). If no authenticators are required, no
@@@ -23490,30 -23446,6 +23500,30 @@@ The remainder of this chapter covers th
  authenticators, followed by general discussion of the way authentication works
  in Exim.
  
 +.new
 +&*Beware:*& the meaning of &$auth1$&, &$auth2$&, ... varies on a per-driver and
 +per-mechanism basis.  Please read carefully to determine which variables hold
 +account labels such as usercodes and which hold passwords or other
 +authenticating data.
 +
 +Note that some mechanisms support two different identifiers for accounts: the
 +&'authentication id'& and the &'authorization id'&.  The contractions &'authn'&
 +and &'authz'& are commonly encountered.  The American spelling is standard here.
 +Conceptually, authentication data such as passwords are tied to the identifier
 +used to authenticate; servers may have rules to permit one user to act as a
 +second user, so that after login the session is treated as though that second
 +user had logged in.  That second user is the &'authorization id'&.  A robust
 +configuration might confirm that the &'authz'& field is empty or matches the
 +&'authn'& field.  Often this is just ignored.  The &'authn'& can be considered
 +as verified data, the &'authz'& as an unverified request which the server might
 +choose to honour.
 +
 +A &'realm'& is a text string, typically a domain name, presented by a server
 +to a client to help it select an account and credentials to use.  In some
 +mechanisms, the client and server provably agree on the realm, but clients
 +typically can not treat the realm as secure data to be blindly trusted.
 +.wen
 +
  
  
  .section "Generic options for authenticators" "SECID168"
@@@ -23560,11 -23492,6 +23570,11 @@@ This option must be set for a &%plainte
  is used directly to control authentication. See section &<<SECTplainserver>>&
  for details.
  
 +.new
 +For the &(gsasl)& authenticator, this option is required for various
 +mechanisms; see chapter &<<CHAPgsasl>>& for details.
 +.wen
 +
  For the other authenticators, &%server_condition%& can be used as an additional
  authentication or authorization mechanism that is applied after the other
  authenticator conditions succeed. If it is set, it is expanded when the
@@@ -24242,17 -24169,10 +24252,17 @@@ be set in &_exim.conf_& in your SASL di
  Kerberos, note that because of limitations in the GSSAPI interface,
  changing the server keytab might need to be communicated down to the Kerberos
  layer independently. The mechanism for doing so is dependent upon the Kerberos
 -implementation. For example, for Heimdal, the environment variable KRB5_KTNAME
 +implementation.
 +.new
 +For example, for older releases of Heimdal, the environment variable KRB5_KTNAME
  may be set to point to an alternative keytab file. Exim will pass this
  variable through from its own inherited environment when started as root or the
  Exim user. The keytab file needs to be readable by the Exim user.
 +With newer releases of Heimdal, a setuid Exim may cause Heimdal to discard the
 +environment variable.  In practice, for those releases, the Cyrus authenticator
 +is not a suitable interface for GSSAPI (Kerberos) support.  Instead, consider
 +the &(heimdal_gssapi)& authenticator, described in chapter &<<CHAPheimdalgss>>&
 +.wen
  
  
  .section "Using cyrus_sasl as a server" "SECID178"
@@@ -24355,202 -24275,6 +24365,202 @@@ who authenticated is placed in &$auth1$
  .ecindex IIDdcotauth2
  
  
 +. ////////////////////////////////////////////////////////////////////////////
 +. ////////////////////////////////////////////////////////////////////////////
 +.new
 +.chapter "The gsasl authenticator" "CHAPgsasl"
 +.scindex IIDgsaslauth1 "&(gsasl)& authenticator"
 +.scindex IIDgsaslauth2 "authenticators" "&(gsasl)&"
 +.cindex "authentication" "GNU SASL"
 +.cindex "authentication" "SASL"
 +.cindex "authentication" "EXTERNAL"
 +.cindex "authentication" "ANONYMOUS"
 +.cindex "authentication" "PLAIN"
 +.cindex "authentication" "LOGIN"
 +.cindex "authentication" "DIGEST-MD5"
 +.cindex "authentication" "CRAM-MD5"
 +.cindex "authentication" "SCRAM-SHA-1"
 +The &(gsasl)& authenticator provides server integration for the GNU SASL
 +library and the mechanisms it provides.  This is new as of the 4.78 release
 +and there are a few areas where the library does not let Exim smoothly
 +scale to handle future authentication mechanisms, so no guarantee can be
 +made that any particular new authentication mechanism will be supported
 +without code changes in Exim.
 +
 +
 +.option server_channelbinding gsasl bool false
 +Some authentication mechanisms are able to use external context at both ends
 +of the session to bind the authentication to that context, and fail the
 +authentication process if that context differs.  Specifically, some TLS
 +ciphersuites can provide identifying information about the cryptographic
 +context.
 +
 +This means that certificate identity and verification becomes a non-issue,
 +as a man-in-the-middle attack will cause the correct client and server to
 +see different identifiers and authentication will fail.
 +
 +This is currently only supported when using the GnuTLS library.  This is
 +only usable by mechanisms which support "channel binding"; at time of
 +writing, that's the SCRAM family.
 +
 +This defaults off to ensure smooth upgrade across Exim releases, in case
 +this option causes some clients to start failing.  Some future release
 +of Exim may switch the default to be true.
 +
 +
 +.option server_hostname gsasl string&!! "see below"
 +This option selects the hostname that is used when communicating with the
 +library. The default value is &`$primary_hostname`&.
 +Some mechanisms will use this data.
 +
 +
 +.option server_mech gsasl string "see below"
 +This option selects the authentication mechanism this driver should use. The
 +default is the value of the generic &%public_name%& option. This option allows
 +you to use a different underlying mechanism from the advertised name. For
 +example:
 +.code
 +sasl:
 +  driver = gsasl
 +  public_name = X-ANYTHING
 +  server_mech = CRAM-MD5
 +  server_set_id = $auth1
 +.endd
 +
 +
 +.option server_password gsasl string&!! unset
 +Various mechanisms need access to the cleartext password on the server, so
 +that proof-of-possession can be demonstrated on the wire, without sending
 +the password itself.
 +
 +The data available for lookup varies per mechanism.
 +In all cases, &$auth1$& is set to the &'authentication id'&.
 +The &$auth2$& variable will always be the &'authorization id'& (&'authz'&)
 +if available, else the empty string.
 +The &$auth3$& variable will always be the &'realm'& if available,
 +else the empty string.
 +
 +A forced failure will cause authentication to defer.
 +
 +If using this option, it may make sense to set the &%server_condition%&
 +option to be simply "true".
 +
 +
 +.option server_realm gsasl string&!! unset
 +This specifies the SASL realm that the server claims to be in.
 +Some mechanisms will use this data.
 +
 +
 +.option server_scram_iter gsasl string&!! unset
 +This option provides data for the SCRAM family of mechanisms.
 +&$auth1$& is not available at evaluation time.
 +(This may change, as we receive feedback on use)
 +
 +
 +.option server_scram_salt gsasl string&!! unset
 +This option provides data for the SCRAM family of mechanisms.
 +&$auth1$& is not available at evaluation time.
 +(This may change, as we receive feedback on use)
 +
 +
 +.option server_service gsasl string &`smtp`&
 +This is the SASL service that the server claims to implement.
 +Some mechanisms will use this data.
 +
 +
 +.section "&(gsasl)& auth variables" "SECTgsaslauthvar"
 +.vindex "&$auth1$&, &$auth2$&, etc"
 +These may be set when evaluating specific options, as detailed above.
 +They will also be set when evaluating &%server_condition%&.
 +
 +Unless otherwise stated below, the &(gsasl)& integration will use the following
 +meanings for these variables:
 +
 +.ilist
 +.vindex "&$auth1$&"
 +&$auth1$&: the &'authentication id'&
 +.next
 +.vindex "&$auth2$&"
 +&$auth2$&: the &'authorization id'&
 +.next
 +.vindex "&$auth3$&"
 +&$auth3$&: the &'realm'&
 +.endlist
 +
 +On a per-mechanism basis:
 +
 +.ilist
 +.cindex "authentication" "EXTERNAL"
 +EXTERNAL: only &$auth1$& is set, to the possibly empty &'authorization id'&;
 +the &%server_condition%& option must be present.
 +.next
 +.cindex "authentication" "ANONYMOUS"
 +ANONYMOUS: only &$auth1$& is set, to the possibly empty &'anonymous token'&;
 +the &%server_condition%& option must be present.
 +.next
 +.cindex "authentication" "GSSAPI"
 +GSSAPI: &$auth1$& will be set to the &'GSSAPI Display Name'&;
 +&$auth2$& will be set to the &'authorization id'&,
 +the &%server_condition%& option must be present.
 +.endlist
 +
 +An &'anonymous token'& is something passed along as an unauthenticated
 +identifier; this is analogous to FTP anonymous authentication passing an
 +email address, or software-identifier@, as the "password".
 +
 +.wen
 +
 +. ////////////////////////////////////////////////////////////////////////////
 +. ////////////////////////////////////////////////////////////////////////////
 +
 +.new
 +.chapter "The heimdal_gssapi authenticator" "CHAPheimdalgss"
 +.scindex IIDheimdalgssauth1 "&(heimdal_gssapi)& authenticator"
 +.scindex IIDheimdalgssauth2 "authenticators" "&(heimdal_gssapi)&"
 +.cindex "authentication" "GSSAPI"
 +.cindex "authentication" "Kerberos"
 +The &(heimdal_gssapi)& authenticator provides server integration for the
 +Heimdal GSSAPI/Kerberos library, permitting Exim to set a keytab pathname
 +reliably.
 +
 +.option server_hostname heimdal_gssapi string&!! "see below"
 +This option selects the hostname that is used, with &%server_service%&,
 +for constructing the GSS server name, as a &'GSS_C_NT_HOSTBASED_SERVICE'&
 +identifier.  The default value is &`$primary_hostname`&.
 +
 +.option server_keytab heimdal_gssapi string&!! unset
 +If set, then Heimdal will not use the system default keytab (typically
 +&_/etc/krb5.keytab_&) but instead the pathname given in this option.
 +The value should be a pathname, with no &"file:"& prefix.
 +
 +.option server_service heimdal_gssapi string&!! "smtp"
 +This option specifies the service identifier used, in conjunction with
 +&%server_hostname%&, for building the identifer for finding credentials
 +from the keytab.
 +
 +
 +.section "&(heimdal_gssapi)& auth variables" "SECTheimdalgssauthvar"
 +Beware that these variables will typically include a realm, thus will appear
 +to be roughly like an email address already.  The &'authzid'& in &$auth2$& is
 +not verified, so a malicious client can set it to anything.
 +
 +The &$auth1$& field should be safely trustable as a value from the Key
 +Distribution Center.  Note that these are not quite email addresses.
 +Each identifier is for a role, and so the left-hand-side may include a
 +role suffix.  For instance, &"joe/admin@EXAMPLE.ORG"&.
 +
 +.vindex "&$auth1$&, &$auth2$&, etc"
 +.ilist
 +.vindex "&$auth1$&"
 +&$auth1$&: the &'authentication id'&, set to the GSS Display Name.
 +.next
 +.vindex "&$auth2$&"
 +&$auth2$&: the &'authorization id'&, sent within SASL encapsulation after
 +authentication.
 +.endlist
 +
 +.wen
 +
  . ////////////////////////////////////////////////////////////////////////////
  . ////////////////////////////////////////////////////////////////////////////
  
diff --combined doc/doc-txt/ChangeLog
index 699da323cf1dc636fa5c8c87165d333dcae1b185,0212a51ae99e39c79be11b2fc30801e2ba1f6677..3f43ef83da0b369150c9bfd0a3c492c56dfdeabc
@@@ -15,19 -15,10 +15,23 @@@ NM/02 Bugzilla 1093 - eximstats DATA re
  
  NM/03 Bugzilla 1169 - primary_hostname spelling was incorrect in docs.
  
 -PP/02 New expansion variable $tls_bits; Cyrus SASL server connection
 +PP/02 Implemented gsasl authenticator.
 +
 +PP/03 Implemented heimdal_gssapi authenticator with "server_keytab" option.
 +
 +PP/04 Local/Makefile support for (AUTH|LOOKUP)_*_PC=foo to use
 +      `pkg-config foo` for cflags/libs.
 +
 +PP/05 Swapped $auth1/$auth2 for gsasl GSSAPI mechanism, to be more consistent
 +      with rest of GSASL and with heimdal_gssapi.
 +
 +PP/06 Local/Makefile support for USE_(GNUTLS|OPENSSL)_PC=foo to use
 +      `pkg-config foo` for cflags/libs for the TLS implementation.
 +
++PP/07 New expansion variable $tls_bits; Cyrus SASL server connection
+       properties get this fed in as external SSF.  A number of robustness
+       and debugging improvements to the cyrus_sasl authenticator.
  
  Exim version 4.77
  -----------------
diff --combined doc/doc-txt/NewStuff
index 487ce30b347c73f53ab6e0edcf06be45621501e5,fdbb07488ea7e3eb97d97c7baa8a3a1b6ce848cc..057656c24186fece32d366cf4ced54482a091955
@@@ -7,28 -7,9 +7,30 @@@ test from the snapshots or the CVS befo
  the documentation is updated, this file is reduced to a short list.
  
  Version 4.78
 +------------
 +
 + 1. New authenticator driver, "gsasl".  Server-only (at present).
 +    This is a SASL interface, licensed under GPL, which can be found at
 +    http://www.gnu.org/software/gsasl/.
 +    This system does not provide sources of data for authentication, so
 +    careful use needs to be made of the conditions in Exim.  Note that
 +    this can not yet be used as a drop-in replacement for Cyrus SASL, as
 +    Exim is currently unable to construct strings with embedded NULs for
 +    use as keys in lookups against sasldb2.
 +
 + 2. New authenticator driver, "heimdal_gssapi".  Server-only.
 +    A replacement for using cyrus_sasl with Heimdal, now that $KRB5_KTNAME
 +    is no longer honoured for setuid programs by Heimdal.  Use the
 +    "server_keytab" option to point to the keytab.
 +
 + 3. The "pkg-config" system can now be used when building Exim to reference
 +    cflags and library information for lookups and authenticators, rather
 +    than having to update "CFLAGS", "AUTH_LIBS", "LOOKUP_INCLUDE" and
 +    "LOOKUP_LIBS" directly.  Similarly for handling the TLS library support
 +    without adjusting "TLS_INCLUDE" and "TLS_LIBS".
  
 - 1. New expansion variable $tls_bits.
++ 4. New expansion variable $tls_bits.
  
  Version 4.77
  ------------
diff --combined src/src/globals.h
index 58fdb0a0cc7a9ffbcae5eb5e7bf6737c676d4e45,869a23e63dfa71f4b1454ea5326a50c566179e9c..a51e3bc50657475312548f3efbd7bf035541798a
@@@ -75,6 -75,7 +75,7 @@@ cluttered in several places (e.g. durin
  them. Also, the tls_ variables are now always visible. */
  
  extern int     tls_active;             /* fd/socket when in a TLS session */
+ extern int     tls_bits;               /* bits used in TLS session */
  extern BOOL    tls_certificate_verified; /* Client certificate verified */
  extern uschar *tls_cipher;             /* Cipher used */
  extern BOOL    tls_on_connect;         /* For older MTAs that don't STARTTLS */
@@@ -90,7 -91,6 +91,7 @@@ extern uschar *openssl_options;        
  extern const pcre *regex_STARTTLS;     /* For recognizing STARTTLS settings */
  extern uschar *tls_advertise_hosts;    /* host for which TLS is advertised */
  extern uschar *tls_certificate;        /* Certificate file */
 +extern uschar *tls_channelbinding_b64; /* string of base64 channel binding */
  extern uschar *tls_crl;                /* CRL File */
  extern uschar *tls_dhparam;            /* DH param file */
  extern BOOL    tls_offered;            /* Server offered TLS */
diff --combined src/src/tls-gnu.c
index 2d1a327dea80307939e2fc23b0c9d5714fa2ae5c,dc09d4720d9df0962feee5357e4723a315010f5d..2f952e47b3aeef121f294ae8e6d521f46fa57841
@@@ -854,41 -854,24 +854,43 @@@ construct_cipher_name(gnutls_session se
  {
  static uschar cipherbuf[256];
  uschar *ver;
- int bits, c, kx, mac, rc;
+ int c, kx, mac;
 +#ifdef GNUTLS_CB_TLS_UNIQUE
++int rc;
 +gnutls_datum_t channel;
 +#endif
  
  ver = string_copy(
    US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
  if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-';   /* Don't want space */
  
  c = gnutls_cipher_get(session);
- bits = gnutls_cipher_get_key_size(c);
+ /* returns size in "bytes" */
+ tls_bits = gnutls_cipher_get_key_size(c) * 8;
  
  mac = gnutls_mac_get(session);
  kx = gnutls_kx_get(session);
  
  string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
-   gnutls_cipher_suite_get_name(kx, c, mac), bits);
+   gnutls_cipher_suite_get_name(kx, c, mac), tls_bits);
  tls_cipher = cipherbuf;
  
  DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
 +
 +if (tls_channelbinding_b64)
 +  free(tls_channelbinding_b64);
 +tls_channelbinding_b64 = NULL;
 +
 +#ifdef GNUTLS_CB_TLS_UNIQUE
 +channel = { NULL, 0 };
 +rc = gnutls_session_channel_binding(session, GNUTLS_CB_TLS_UNIQUE, &channel);
 +if (rc) {
 +  DEBUG(D_tls) debug_printf("Channel binding error: %s\n", gnutls_strerror(rc));
 +} else {
 +  tls_channelbinding_b64 = auth_b64encode(channel.data, (int)channel.size);
 +  DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage.\n");
 +}
 +#endif
  }