Add SCRAM Support

Close #1
This commit is contained in:
Andy 2019-11-06 23:30:26 -08:00
parent 8b0201f117
commit f1e95758e1
No known key found for this signature in database
GPG key ID: 0B7C73813443493A
12 changed files with 450 additions and 17 deletions

View file

@ -245,6 +245,71 @@ class Deliver_SMTP extends Deliver {
);
if (boolean_hook_function('smtp_authenticate', $smtp_auth_args, 1)) {
// authentication succeeded
} else if ( substr($smtp_auth_mech, 0, 6) == 'scram-' ) {
// Doing SCRAM
$hAlg = scram_supports(substr($smtp_auth_mech, 6));
if ($hAlg === false) {
return(0);
}
fputs($stream, 'AUTH '.strtoupper($smtp_auth_args)."\r\n");
$tmp = fgets($stream,1024);
if ($this->errorCheck($tmp,$stream)) {
return(0);
}
// At this point, $tmp should hold "334 "
// No Channel Binding support...
$cbf = 'n';
// Generate 20 random bytes
$cliNonce = scram_nonce();
// Build SCRAM request
$scram_request = scram_request($user, $cbf, $cliNonce);
fputs($stream, $scram_request."\r\n");
// Get SCRAM response
$tmp = fgets($stream,1024);
if ($this->errorCheck($tmp,$stream)) {
return(0);
}
// At this point, $tmp should hold "334 <challenge string>"
$chall = substr($tmp,4);
$serData = scram_parse_challenge($chall, $cliNonce);
if ($serData === false) {
return(0);
}
$scram_response = scram_response($hAlg, $user, $cbf, $cliNonce, $serData['r'], $pass, $serData['s'], $serData['i']);
fputs($stream, $scram_response."\r\n");
// Get SCRAM validation
$tmp = fgets($stream,1024);
if ($this->errorCheck($tmp,$stream)) {
return(0);
}
// At this point, $tmp should hold "334 <server verification string>"
$serVer = substr($tmp,4);
$valid = scram_verify($hAlg, $user, $cbf, $cliNonce, $serData['r'], $pass, $serData['s'], $serData['i'], $serVer);
if ($valid === false) {
return(0);
}
// TODO: For compatibility, this may need to either be blank or NOOP. Find out which!!!
fputs($stream, "\r\n");
// Just to make sure we're really logged in
$tmp = fgets($stream,1024);
if ($this->errorCheck($tmp,$stream)) {
return(0);
}
// SCRAM code ends here
} else if (( $smtp_auth_mech == 'cram-md5') or ( $smtp_auth_mech == 'digest-md5' )) {
// Doing some form of non-plain auth
if ($smtp_auth_mech == 'cram-md5') {

View file

@ -1492,7 +1492,7 @@ sub command111 {
return $new_optional_delimiter;
}
# IMAP authentication type
# Possible values: login, plain, cram-md5, digest-md5
# Possible values: login, plain, cram-md5, digest-md5, scram-[digest-algo]
# Now offers to detect supported mechs, assuming server & port are set correctly
sub command112a {
@ -1504,7 +1504,7 @@ sub command112a {
} else {
print "If you have already set the hostname and port number, I can try to\n";
print "detect the mechanisms your IMAP server supports.\n";
print "I will try to detect CRAM-MD5 and DIGEST-MD5 support. I can't test\n";
print "I will try to detect SCRAM, CRAM-MD5, and DIGEST-MD5 support. I can't test\n";
print "for \"login\" or \"plain\" without knowing a username and password.\n";
print "Auto-detecting is optional - you can safely say \"n\" here.\n";
print "\nTry to detect supported mechanisms? [y/N]: ";
@ -1514,6 +1514,30 @@ sub command112a {
# Yes, let's try to detect.
print "Trying to detect IMAP capabilities...\n";
my $host = $imapServerAddress . ':'. $imapPort;
print "SCRAM-SHA-1:\t";
my $tmp = detect_auth_support('IMAP',$host,'SCRAM-SHA-1');
if (defined($tmp)) {
if ($tmp eq 'YES') {
print "$WHT SUPPORTED$NRM\n";
} else {
print "$WHT NOT SUPPORTED$NRM\n";
}
} else {
print $WHT . " ERROR DETECTING$NRM\n";
}
print "SCRAM-SHA-256:\t";
my $tmp = detect_auth_support('IMAP',$host,'SCRAM-SHA-256');
if (defined($tmp)) {
if ($tmp eq 'YES') {
print "$WHT SUPPORTED$NRM\n";
} else {
print "$WHT NOT SUPPORTED$NRM\n";
}
} else {
print $WHT . " ERROR DETECTING$NRM\n";
}
print "CRAM-MD5:\t";
my $tmp = detect_auth_support('IMAP',$host,'CRAM-MD5');
if (defined($tmp)) {
@ -1545,12 +1569,15 @@ sub command112a {
print $WHT . "plain" . $NRM . " - SASL PLAIN. If you need this, you already know it.\n";
print $WHT . "cram-md5" . $NRM . " - Historic. No longer considered secure.\n";
print $WHT . "digest-md5" . $NRM . " - Historic. No longer considered secure.\n";
print $WHT . "scram-sha-1" . $NRM . " - Salted and hashed. Security contested.\n";
print $WHT . "scram-sha-256" . $NRM . " - Salted and hashed. Safer than sha-1.\n";
print "\n*** YOUR IMAP SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE HERE ***\n";
print "If you don't understand or are unsure, you probably want \"login\"\n\n";
print "login, plain, cram-md5, or digest-md5 [$WHT$imap_auth_mech$NRM]: $WHT";
print "login, plain, cram-md5, digest-md5, scram-* [$WHT$imap_auth_mech$NRM]: $WHT";
$inval=<STDIN>;
chomp($inval);
if ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) || ($inval =~ /^login\b/i) || ($inval =~ /^plain\b/i)) {
if ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) || ($inval =~ /^scram-.+\b/i) ||
($inval =~ /^login\b/i) || ($inval =~ /^plain\b/i)) {
return lc($inval);
} else {
# user entered garbage or default value so nothing needs to be set
@ -1560,7 +1587,7 @@ sub command112a {
# SMTP authentication type
# Possible choices: none, login, plain, cram-md5, digest-md5
# Possible choices: none, login, plain, cram-md5, digest-md5, scram-[digest-algo]
sub command112b {
if ($use_smtp_tls ne "0") {
print "Auto-detection of login methods is unavailable when using TLS or STARTTLS.\n";
@ -1641,7 +1668,6 @@ sub command112b {
print $WHT . "ERROR DETECTING$NRM\n";
}
print "Testing DIGEST-MD5:\t";
$tmp=detect_auth_support('SMTP',$host,'DIGEST-MD5');
if (defined($tmp)) {
@ -1653,6 +1679,32 @@ sub command112b {
} else {
print $WHT . "ERROR DETECTING$NRM\n";
}
# Try SCRAM-SHA-1
print "Testing SCRAM-SHA-1:\t";
$tmp=detect_auth_support('SMTP',$host,'SCRAM-SHA-1');
if (defined($tmp)) {
if ($tmp eq 'YES') {
print $WHT . "SUPPORTED$NRM\n";
} else {
print $WHT . "NOT SUPPORTED$NRM\n";
}
} else {
print $WHT . "ERROR DETECTING$NRM\n";
}
# Try SCRAM-SHA-256
print "Testing SCRAM-SHA-256:\t";
$tmp=detect_auth_support('SMTP',$host,'SCRAM-SHA-256');
if (defined($tmp)) {
if ($tmp eq 'YES') {
print $WHT . "SUPPORTED$NRM\n";
} else {
print $WHT . "NOT SUPPORTED$NRM\n";
}
} else {
print $WHT . "ERROR DETECTING$NRM\n";
}
}
}
print "\nWhat authentication mechanism do you want to use for SMTP connections?\n";
@ -1661,9 +1713,11 @@ sub command112b {
print $WHT . "plain" . $NRM . " - SASL PLAIN. Plaintext. If you can do better, you probably should.\n";
print $WHT . "cram-md5" . $NRM . " - Historic. No longer considered secure.\n";
print $WHT . "digest-md5" . $NRM . " - Historic. No longer considered secure.\n";
print $WHT . "scram-sha-1" . $NRM . " - Salted and hashed. Security contested.\n";
print $WHT . "scram-sha-256" . $NRM . " - Salted and hashed. Safer than sha-1.\n";
print $WHT . "\n*** YOUR SMTP SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE HERE ***\n" . $NRM;
print "If you don't understand or are unsure, you probably want \"none\"\n\n";
print "none, login, plain, cram-md5, or digest-md5 [$WHT$smtp_auth_mech$NRM]: $WHT";
print "none, login, plain, cram-md5, digest-md5, scram-* [$WHT$smtp_auth_mech$NRM]: $WHT";
$inval=<STDIN>;
chomp($inval);
if ($inval =~ /^none\b/i) {
@ -1672,7 +1726,7 @@ sub command112b {
$smtp_sitewide_pass = '';
# SMTP doesn't necessarily require logins
return "none";
} elsif ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) ||
} elsif ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) || ($inval =~ /^scram-.+\b/i) ||
($inval =~ /^login\b/i) || ($inval =~/^plain\b/i)) {
command_smtp_sitewide_userpass($inval);
return lc($inval);

View file

@ -263,7 +263,10 @@ $use_smtp_tls = 0;
/**
* SMTP authentication mechanism
*
* auth_mech can be either 'none', 'login','plain', 'cram-md5', or 'digest-md5'
* auth_mech can be either 'none', 'login', 'plain', 'cram-md5', 'digest-md5',
* or 'scram-*'. For SCRAM, any algorithm your PHP install supports for both
* the hash and hash_hmac functions is supported.
* Note that CRAM-MD5 & DIGEST-MD5 are historic and no longer considered safe.
* @global string $smtp_auth_mech
*/
$smtp_auth_mech = 'none';
@ -293,7 +296,10 @@ $smtp_sitewide_pass = '';
/**
* IMAP authentication mechanism
*
* auth_mech can be either 'login','plain', 'cram-md5', or 'digest-md5'
* auth_mech can be either 'login', 'plain', 'cram-md5', 'digest-md5', or
* 'scram-*'. For SCRAM, any algorithm your PHP install supports for both the
* hash and hash_hmac functions is supported.
* Note that CRAM-MD5 & DIGEST-MD5 are historic and no longer considered safe.
* @global string $imap_auth_mech
*/
$imap_auth_mech = 'login';

View file

@ -431,6 +431,8 @@ Version 1.5.2 - SVN
(see notes in config/config_local.example.php for more details)
- Added handling for RCDATA and RAWTEXT elements in HTML sanitizer
[CVE-2019-12970]
- Added SCRAM authentication support (RFC5802) (RFC7677) for IMAP
and SMTP
Version 1.5.1 (branched on 2006-02-12)
--------------------------------------

View file

@ -2,6 +2,7 @@
IMAP AND SMTP AUTHENTICATION WITH SQUIRRELMAIL
$Id$
Chris Hilts tassium@squirrelmail.org
Andrew Sachen webmaster@realityripple.com
**********************************************
Prior to SquirrelMail 1.4.0, only plaintext logins for IMAP and SMTP were
@ -12,6 +13,13 @@ SMTP. TLS is able to be enabled on a per-service basis as well.
Unless the administrator changes the authentication methods, SquirrelMail
will default to the "classic" plaintext methods, without TLS.
As of 1.5.2, the SCRAM auth mechanism has also been added. This supercedes the
now deprecated CRAM-MD5 and DIGEST-MD5 with a salted hash, typically with SHA-1
or SHA-256. While SHA-1 is potentially insecure, HMAC makes things much safer,
so SCRAM-SHA-1 is still considered functionally secure. If your mail server
supports SCRAM, please consider using it, especially if it doesn't support TLS
or you aren't using it. More especially if you're still using MD5.
Note: There is no point in using TLS if your IMAP server is localhost. You need
root to sniff the loopback interface, and if you don't trust root, or an attacker
already has root, the game is over. You've got a lot more to worry about beyond
@ -20,6 +28,10 @@ having the loopback interface sniffed.
REQUIREMENTS
------------
SCRAM-SHA-1/SCRAM-SHA-256
* SquirrelMail 1.5.2 or higher
* PHP 7.0 or higher (random_int() function for nonce generation)
CRAM/DIGEST-MD5
* SquirrelMail 1.4.0 or higher
* If you have the mhash extension to PHP, it will automatically
@ -108,7 +120,7 @@ configuration utility.
These configuration variables will be used to connect to the SMTP server as long
as the authentication mechanism is something besides 'none', i.e. 'login',
'plain', 'cram-md5', or 'digest-md5'.
'plain', 'cram-md5', 'digest-md5', 'scram-sha-1', or 'scram-sha-256'.
DEBUGGING SSL ERROR MESSAGES
----------------------------

View file

@ -41,8 +41,9 @@ on our wiki. Links to all these manuals and wikis can be found on our
<dt><a href="authentication.txt">Authentication</a></dt>
<dd>
SquirrelMail allows you to log in to your IMAP and SMTP servers using
plaintext, CRAM-MD5 or DIGEST-MD5, as well as use SSL for extra security.
This document describes how to use this new code, and the requirements.
plaintext, SCRAM, CRAM-MD5 or DIGEST-MD5, as well as use SSL/TLS for
extra security. This document describes how to use this new code,
and the requirements.
</dd>
<dt><a href="presets.txt">Specific IMAP server setups</a></dt>

View file

@ -136,6 +136,224 @@ function sqauth_save_password($pass) {
return $key;
}
/**
* Determine if an algorithm is supported by hash() and hash_hmac()
*
* @param string $algo Algorithm to find.
*
* @return string Functional $algo as used by hash() and hash_hmac()
* or boolean FALSE
*
* @since 1.5.2
*/
function scram_supports($algo) {
$HASHs = hash_algos();
if (check_php_version(7,2)) {
$HMACs = hash_hmac_algos();
$HASHs = array_values(array_intersect($HASHs, $HMACs));
}
$fAlgo = strtolower(str_replace('-', '', $algo));
if (in_array($fAlgo, $HASHs))
return $fAlgo;
return false;
}
/**
* Build client nonce for SCRAM (See RFC 5802 for details)
*
* @return string A set of twenty random printable ASCII characters
*
* @since 1.5.2
*/
function scram_nonce () {
// All printable ASCII characters except commas are OK
// (For simplicity, we're just going to use letters and numbers, though)
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$max = strlen($chars) - 1;
$nonce = '';
for($i = 0; $i < 20; $i++) {
$rndChr = random_int(0, $max);
$nonce.= $chars[$rndChr];
}
return $nonce;
}
/**
* Build client request for SCRAM (See RFC 5802 for details)
*
* @param string $username User ID
* @param string $cbf Channel Binding Flag ('n', 'y', or 'p=tls-unique'/'p=tls-server-end-point')
* @param string $nonce Client's random nonce data
*
* @return string The response to be sent to the server (base64 encoded)
*
* @since 1.5.2
*/
function scram_request ($username,$cbf,$nonce) {
return base64_encode($cbf.',,n='.$username.',r='.$nonce);
}
/**
* Parse SCRAM challenge.
* This function parses the challenge sent during SCRAM authentication and
* returns an array. See the RFC for details on what's in the challenge string.
*
* @param string $challenge SCRAM Challenge
* @param string $nonce Client's random nonce data
*
* @return array SCRAM challenge decoded data
* or boolean FALSE
*
* @since 1.5.2
*/
function scram_parse_challenge ($challenge,$nonce) {
$chall = base64_decode($challenge, true);
if ($chall === false) {
// The challenge must be base64 encoded
return false;
}
// Chall should now be r=NONCE,s=SALT,i=ITER
$sReq = explode(',', $chall);
$serNonce = '';
$serSalt = '';
$serIter = 0;
for($i = 0; $i < count($sReq); $i++) {
switch(substr($sReq[$i], 0, 2)) {
case 'r=':
$serNonce = substr($sReq[$i], 2);
break;
case 's=':
$serSalt = substr($sReq[$i], 2);
break;
case 'i=':
$serIter = substr($sReq[$i], 2);
break;
}
}
if (strlen($serNonce) <= strlen($nonce)) {
//the server 'r' value must be bigger than the client 'r' value
return false;
}
if (substr($serNonce, 0, strlen($nonce)) !== $nonce) {
// The server 'r' value must begin with the client 'r' value
return false;
}
if (is_numeric($serIter)) {
$serIter = intval($serIter);
} else {
// The iteration value must be a number
return false;
}
$serSaltV = base64_decode($serSalt, true);
if ($serSaltV === false) {
// The salt must be base64-encoded
return false;
}
$parsed = array();
$parsed['r'] = $serNonce;
$parsed['s'] = $serSaltV;
$parsed['i'] = $serIter;
return $parsed;
}
/**
* Build SCRAM response to challenge.
* This function hashes the heck out of the password and all previous communications
* to create a proof value which is then sent to the server as authentication.
*
* @param string $alg Hash algorithm to use ('sha1' or 'sha256')
* @param string $username User ID
* @param string $cbf Channel Binding Flag ('n', 'y', or 'p=tls-unique'/'p=tls-server-end-point')
* @param string $cli_nonce Client's random nonce data
* @param string $ser_nonce Client + Server's random nonce data
* @param string $password User password supplied by User
* @param string $salt Raw binary salt data, supplied by the server challenge
* @param string $iter PBKDF2 iterations, supplied by the server challenge
*
* @return string The response to be sent to the server (base64 encoded)
*
* @since 1.5.2
*/
function scram_response ($alg,$username,$cbf,$cli_nonce,$ser_nonce,$password,$salt,$iter) {
// salt and hash password
$salted_pass = hash_pbkdf2($alg, $password, $salt, $iter, 0, true);
$cli_hash = hash_hmac($alg, 'Client Key', $salted_pass, true);
$cli_key = hash($alg, $cli_hash, true);
$c = base64_encode($cbf.',,');
//generate unproofed communications
$cli_request = 'n='.$username.',r='.$cli_nonce;
$ser_challenge = 'r='.$ser_nonce.',s='.base64_encode($salt).',i='.$iter;
$cli_response_unp = 'c='.$c.',r='.$ser_nonce;
$comm_unp = $cli_request.','.$ser_challenge.','.$cli_response_unp;
//hash unproofed communications
$cli_sig = hash_hmac($alg, $comm_unp, $cli_key, true);
$cli_proof = $cli_hash ^ $cli_sig;
//generate proofed response
$cli_response = $cli_response_unp.',p='.base64_encode($cli_proof);
return base64_encode($cli_response);
}
/**
* Verify SCRAM server response.
* The final step in SCRAM is to make sure the server isn't just faking validation.
* This is done by hashing the unproofed communications with a 'Server Key'
* version of the hashed password, and comparing it with the server's final SCRAM message.
*
* @param string $alg Hash algorithm to use ('sha1' or 'sha256')
* @param string $username User ID
* @param string $cbf Channel Binding Flag ('n', 'y', or 'p=tls-unique'/'p=tls-server-end-point')
* @param string $cli_nonce Client's random nonce data
* @param string $ser_nonce Client + Server's random nonce data
* @param string $password User password supplied by User
* @param string $salt Raw binary salt data, supplied by the server challenge
* @param string $iter PBKDF2 iterations, supplied by the server challenge
* @param string $proof The server's final SCRAM message (base64 encoded)
*
* @return boolean Success or failure
*
* @since 1.5.2
*/
function scram_verify ($alg,$username,$cbf,$cli_nonce,$ser_nonce,$password,$salt,$iter,$proof) {
$proof = base64_decode($proof, true);
if ($proof === false) {
// The proof must be base64 encoded
return false;
}
if (substr($proof, 0, 2) !== 'v=') {
// The proof was not provided correctly
return false;
}
$proof = substr($proof, 2);
$proof = base64_decode($proof, true);
if ($proof === false) {
// The proof v value must be base64 encoded
return false;
}
// salt and hash password
$salted_pass = hash_pbkdf2($alg, $password, $salt, $iter, 0, true);
$cli_hash = hash_hmac($alg, 'Client Key', $salted_pass, true);
$cli_key = hash($alg, $cli_hash, true);
$c = base64_encode($cbf.',,');
//generate unproofed communications
$cli_request = 'n='.$username.',r='.$cli_nonce;
$ser_challenge = 'r='.$ser_nonce.',s='.base64_encode($salt).',i='.$iter;
$cli_response_unp = 'c='.$c.',r='.$ser_nonce;
$comm_unp = $cli_request.','.$ser_challenge.','.$cli_response_unp;
//hash for server
$ser_hash = hash_hmac($alg, 'Server Key', $salted_pass, true);
$ser_proof = hash_hmac($alg, $comm_unp, $ser_hash, true);
return $ser_proof === $proof;
}
/**
* Given the challenge from the server, supply the response using cram-md5 (See
* RFC 2195 for details)

View file

@ -879,7 +879,78 @@ function sqimap_login ($username, $password, $imap_server_address,
$imap_stream = sqimap_create_stream($imap_server_address,$imap_port,$use_imap_tls,$stream_options);
if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
if (substr($imap_auth_mech, 0, 6) == 'scram-') {
// Doing SCRAM
$hAlg = scram_supports(substr($imap_auth_mech, 6));
if ($hAlg === false) {
$response="BAD";
$message='PHP server does not appear to support the authentication method selected.';
$message .= ' Please contact your system administrator.';
} else {
$tag=sqimap_session_id(false);
fputs($imap_stream, $tag.' AUTHENTICATE '.strtoupper($imap_auth_mech)."\r\n");
$tmp = sqimap_fgets($imap_stream);
if ($tmp[0] !== '+') {
$response="BAD";
$message='IMAP server does not appear to support the authentication method selected.';
$message .= ' Please contact your system administrator.';
} else {
// No Channel Binding support...
$cbf = 'n';
// Generate 20 random bytes
$cliNonce = scram_nonce();
// Build SCRAM request
$scram_request = scram_request($username, $cbf, $cliNonce);
fputs($imap_stream, $scram_request."\r\n");
// Get SCRAM response
$tmp = sqimap_fgets($imap_stream);
if ($tmp[0] !== '+'){
$tmp = explode(' ', $tmp, 3);
$response=$tmp[1];
$message=$tmp[2];
} else {
// At this point, $tmp should hold "+ <challenge string>"
$chall = substr($tmp,2);
$serData = scram_parse_challenge($chall, $cliNonce);
if ($serData === false) {
$response="BAD";
$message='IMAP server challenge could not be parsed.';
$message .= ' Please contact your system administrator.';
} else {
$scram_response = scram_response($hAlg, $username, $cbf, $cliNonce, $serData['r'], $password, $serData['s'], $serData['i']);
fputs($imap_stream, $scram_response."\r\n");
// Get SCRAM validation
$tmp = sqimap_fgets($imap_stream);
if ($tmp[0] !== '+'){
$tmp = explode(' ', $tmp, 3);
$response=$tmp[1];
$message=$tmp[2];
} else {
// At this point, $tmp should hold "+ <server verification string>"
$serVer = substr($tmp,2);
$valid = scram_verify($hAlg, $username, $cbf, $cliNonce, $serData['r'], $password, $serData['s'], $serData['i'], $serVer);
if ($valid === false) {
$response="BAD";
$message='IMAP server challenge response could not be verified.';
$message .= ' Please contact your system administrator.';
} else {
fputs($imap_stream, "\r\n");
// Just to make sure we're really logged in
$tmp = sqimap_fgets($imap_stream);
$tmp = explode(' ', $tmp, 3);
$response=$tmp[1];
$message=$tmp[2];
}
}
}
}
}
}
// SCRAM code ends here
} else if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
// We're using some sort of authentication OTHER than plain or login
$tag=sqimap_session_id(false);
if ($imap_auth_mech == 'digest-md5') {

View file

@ -138,6 +138,8 @@ $defcfg = array( '$config_version' => array( 'name' => _("Config File Version"),
'$imap_auth_mech' => array( 'name' => _("IMAP Authentication Type"),
'type' => SMOPT_TYPE_STRLIST,
'posvals' => array('login' => _("IMAP login"),
'scram-sha-1' => 'SCRAM-SHA-1',
'scram-sha-256' => 'SCRAM-SHA-256',
'cram-md5' => 'CRAM-MD5',
'digest-md5' => 'DIGEST-MD5'),
'default' => 'login' ),
@ -166,6 +168,8 @@ $defcfg = array( '$config_version' => array( 'name' => _("Config File Version"),
'type' => SMOPT_TYPE_STRLIST,
'posvals' => array('none' => _("No SMTP auth"),
'login' => _("Login (plain text)"),
'scram-sha-1' => 'SCRAM-SHA-1',
'scram-sha-256' => 'SCRAM-SHA-256',
'cram-md5' => 'CRAM-MD5',
'digest-md5' => 'DIGEST-MD5'),
'default' => 'none'),

View file

@ -243,7 +243,7 @@ msgstr ""
msgid "The IMAP server is reporting that plain text logins are disabled."
msgstr ""
msgid "Using CRAM-MD5 or DIGEST-MD5 authentication instead may work."
msgid "Using SCRAM, CRAM-MD5, or DIGEST-MD5 authentication instead may work."
msgstr ""
msgid "Also, the use of TLS may allow SquirrelMail to login."

View file

@ -804,7 +804,7 @@ echo $IND . 'Capabilities: <tt>'.sm_encode_html_special_chars($capline)."</tt><b
if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
do_err('Your server doesn\'t allow plaintext logins. '.
'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
'Try enabling another authentication mechanism like SCRAM, CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
'in the SquirrelMail configuration.', FALSE);
}

View file

@ -46,7 +46,7 @@ if($imap_auth_mech == 'login') {
sqimap_logout($imap);
if ($logindisabled) {
$string = _("The IMAP server is reporting that plain text logins are disabled.").'<br />'.
_("Using CRAM-MD5 or DIGEST-MD5 authentication instead may work.").'<br />';
_("Using SCRAM, CRAM-MD5, or DIGEST-MD5 authentication instead may work.").'<br />';
if (!$use_imap_tls) {
$string .= _("Also, the use of TLS may allow SquirrelMail to login.").'<br />';
}