On 2014-02-21 at 15:27 -0800, Paul O'Rorke wrote:
> I've defined in auth/30_exim4-config_examples:
>
> <snip>
> digest_md5_sasl_server:
> driver = cyrus_sasl
> public_name = DIGEST-MD5
> server_realm = chemainus.mjbrownloos.com
> server_set_id = $auth1
> </snip>
>
> and I can authenticate to cyrus for normal logins, get access to and
> work with mail boxes, receive and read mail etc but I cannot send. My
> MUA (Thunderbird) when querying the account on set up finds the IMAP and
> prompts to use and 'Encrypted password' but SMTP insists on using 'no
> encryption'.
Most of that tells us that Cyrus SASL is working with Cyrus IMAPd; the
only one there which is affected by Exim is the last one. I would start
digging into access controls and permissions around socket locations,
etc etc. Alternatively, using the `gsasl` authenticator aimed at the
sasldb2 file used by Cyrus can result in fewer moving parts, easier
debugging and only needing to make sure that the Exim run-time user has
access to read that DB.
There's an example of the last approach in The Exim Specification, with
the example authenticator named `gsasl_cyrusless_crammd5`.
I've also attached a debugging tool which I still use occasionally; to
use it, connect to a service (telnet, openssl s_client, whatever) and
issue the "AUTH CRAM-MD5" command in that window, while running this
tool in another window; copy/paste the challenge across, fill in user
code and password when prompted, copy/paste the response back into the
SMTP session. (You can abort a partial authentication with "*" on a
line on its own (no quotes)).
> <quote>
> If an authenticator is to be used for both server and client functions,
> a single definition, using both sets of options, is required. For example:
>
> cram:
> driver = cram_md5
> public_name = CRAM-MD5
> server_secret = ${if eq{$auth1}{ph10}{secret1}fail}
> client_name = ph10
> client_secret = secret2
>
> The server_ option is used when Exim is acting as a server, and the
> client_ options when it is acting as a client.
> </quote>
>
> Why would a user and password be hard coded into the authenticator? How
> does this use the user's name and password?
This is a different driver to the one above. Each authenticator has a
"driver" which knows how to get the data and what to send for the next
step. Some drivers look in files, some are configured in the Exim
config file with access to the credentials needed.
Note that the "name and password" are only in the "client_*" options,
which as stated, are used for Exim as a _client_ talking to another
server. Here you only care about Exim as a server. Remove the client_*
options, you don't typically want your central MTA trying to
SASL authenticate to other servers.
So the only option here which is dealing with credentials for
Exim-as-a-server is "server_secret", which for _this_ driver is used to
supply the secret, or password; in this example, it's using the offered
usercode to look up the correct password, and would typically use a file
or database lookup of some kind to get the result.
> Yet neither Thunderbird nor Outlook are responding to the TLS and only
> cyrus the encrypted password. So I can authenticate using DIGEST_MD5 for
> IMAP but not SMTP. I need to either get encrypted passwords working on
> SMTP or fix my TLS issue and use LOGIN. Any suggestions? What configs or
> logs entries would help troubleshoot this?
Use "gnutls-cli" to connect to the server; type STARTTLS after the EHLO,
when when prompted to continue, send an EOF (press Ctrl-D, once). This
will nudge gnutls-cli to start the handshake and you can see what's
happening, then continue with the rest of the session.
gnutls-cli --x509cafile "$SSL_CERT_FILE" --starttls --crlf \
--port 587 mail.example.org
You can run Exim on a different port, with much more debugging
information, via:
exim -d+tls -oX 26 -bd
Alternatively, you can turn on debugging in a Connect ACL, and do so
based upon source IP or the like; the results will appear in a debuglog
file in the same directory as your mainlog file.
> One thing I noticed is that while Exim is advertising TLS according to
> those tests, it is not reported in exim -bV:
> Support for: crypteq iconv() IPv6 PAM Perl Expand_dlfunc GnuTLS
GnuTLS provides TLS in this build of Exim; in other builds, it might be
OpenSSL.
> Authenticators: cram_md5 cyrus_sasl dovecot plaintext spa
> Does this mean I have something to do to make DIGEST-MD5 available for
> sending mail?
You should have DIGEST-MD5 via cyrus_sasl; you're running 4.80 so gsasl
support is in Exim's code-base but not in your binary. It's much easier
to get running with gsasl, but that will involve rebuilding Exim to add
support.
(Alternatively, with Expand_dlfunc there, it's possible that you do have
gsasl support in a plugin which won't load because of the missing
library; installing the gsasl library package for your OS might cause
Exim to start reporting gsasl support).
-Phil
#!/usr/bin/perl
#
# $HeadURL:
https://svn.spodhuis.org/ksvn/pdp-bincommon/cram_auth_calc $
# $Id: cram_auth_calc 12 2005-06-16 01:23:17Z pdp $
#
# CRAM-<HMAC-HASH> calculator for interactive logins.
# Assumes base64.
#
use strict;
use warnings;
use vars qw/ $progname $algorithm $algorithm_uc $hmac_func $do_hmac /;
BEGIN {
my %hmacs = ( # keys lower-case
md5 => [ 'Digest::HMAC_MD5', 'hmac_md5_hex' ],
sha1 => [ 'Digest::HMAC_SHA1', 'hmac_sha1_hex' ],
);
my $hmac_re = join('|', keys %hmacs);
($progname = $0) =~ s!^.*/!!;
if ($progname =~ /^(?:.*?[_.-])? ($hmac_re) (?:[_.-].*)?$/ix) {
$algorithm = lc $1;
} else {
$algorithm = undef;
}
unless (defined $algorithm) {
if (defined $ARGV[0] and exists $hmacs{lc $ARGV[0]}) {
$algorithm = lc $ARGV[0];
shift @ARGV;
}
}
unless (defined $algorithm) {
warn "No HMAC algorithm determined. Please supply one of:\n";
warn "\t" . join(' ', map {uc $_} sort keys %hmacs) . "\n";
exit 1;
}
$algorithm_uc = uc $algorithm;
$hmac_func = $hmacs{$algorithm};
my $hmac_module = $hmac_func->[0];
$hmac_module =~ s!::!/!g; $hmac_module .= '.pm';
require $hmac_module;
$do_hmac = \&{$hmac_func->[0] . '::' . $hmac_func->[1]};
}
use MIME::Base64;
use Term::ReadLine;
use Term::ReadPassword;
my $term = new Term::ReadLine "cram_auth_calc_$algorithm";
die "No terminal initialisation" unless defined $term;
$term->ornaments(0);
my $challenge = $term->readline("CRAM-$algorithm_uc Challenge (base64 encoded): ");
my $usercode = $term->readline('Usercode to authenticate as: ');
my $password = read_password('Password: ');
my $raw_challenge = decode_base64($challenge);
my $authdata = $do_hmac->($raw_challenge, $password);
my $raw_response = $usercode . ' ' . $authdata;
my $response = encode_base64($raw_response);
$response .= "\n" unless $response =~ /\n\z/;
print $response;