Explorar el Código

With a little help from Marc (ok, a lot), CRAM-MD5 and DIGEST-MD5 no longer require the mhash extension. If present, mhash will be used.

tassium hace 22 años
padre
commit
1fc6f1eced

+ 1 - 2
class/deliver/Deliver_SMTP.class.php

@@ -51,8 +51,7 @@ class Deliver_SMTP extends Deliver {
 	}
     
 	/* Lets introduce ourselves */
-	if ((( $smtp_auth_mech == 'cram-md5') or ( $smtp_auth_mech == 'digest-md5' )) and (extension_loaded('mhash')))
-	{
+	if (( $smtp_auth_mech == 'cram-md5') or ( $smtp_auth_mech == 'digest-md5' )) {
 	  // Doing some form of non-plain auth
 	  fputs($stream, "EHLO $domain\r\n");
 	  $tmp = fgets($stream,1024);

+ 4 - 4
config/conf.pl

@@ -1152,8 +1152,8 @@ sub command112a {
 	} 
 	  print "\nWhat authentication mechanism do you want to use for IMAP connections?\n\n";
 	  print $WHT . "plain" . $NRM . " - Plaintext. If you can do better, you probably should.\n";
-	  print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext. (Requires PHP mhash extension)\n";
-	  print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5.  (Requires PHP mhash extension)\n";
+	  print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext.\n";
+	  print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5.\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 \"plain\"\n\n";
 	  print "plain, cram-md5, or digest-md5 [$WHT$imap_auth_mech$NRM]: $WHT";
@@ -1245,8 +1245,8 @@ sub command112b {
     print "\tWhat authentication mechanism do you want to use for SMTP connections?\n";
     print $WHT . "none" . $NRM . " - Your SMTP server does not require authorization.\n";
     print $WHT . "plain" . $NRM . " - Plaintext. If you can do better, you probably should.\n";
-    print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext. (Requires PHP mhash extension)\n";
-    print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5. (Requires PHP mhash extension)\n";
+    print $WHT . "cram-md5" . $NRM . " - Slightly better than plaintext.\n";
+    print $WHT . "digest-md5" . $NRM . " - Privacy protection - better than cram-md5.\n";
     print "\n*** YOUR SMTP SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE HERE ***\n";
     print "If you don't understand or are unsure, you probably want \"none\"\n\n";
     print "none, plain, cram-md5, or digest-md5 [$WHT$smtp_auth_mech$NRM]: $WHT";

+ 4 - 3
doc/authentication.txt

@@ -1,6 +1,6 @@
 **********************************************
 IMAP AND SMTP AUTHENTICATION WITH SQUIRRELMAIL
-Preliminary documentation - 20 Nov 2002
+Preliminary documentation - 6 Dec 2002
 Chris Hilts chilts@birdbrained.org
 **********************************************
 
@@ -17,8 +17,9 @@ REQUIREMENTS
 
 CRAM/DIGEST-MD5
 * SquirrelMail 1.3.3 or higher
-* The mhash extension for PHP. (Debian users: You're lucky.  Type 'apt-get
-  install php4-mhash' and you're done.)
+* If you have the mhash extension to PHP, it will automatically
+  be used, which may help performance on heavily loaded servers.
+  ** NOTE: mhash is optional and no longer a requirement **
 
 TLS
 * SquirrelMail 1.3.3 or higher

+ 32 - 7
functions/auth.php

@@ -59,10 +59,9 @@ function cram_md5_response ($username,$password,$challenge) {
 
 /* Given the challenge from the server, supply the response using
    cram-md5 (See RFC 2195 for details)
-   NOTE: Requires mhash extension to PHP
 */
 $challenge=base64_decode($challenge);
-$hash=bin2hex(mhash(MHASH_MD5,$challenge,$password));
+$hash=bin2hex(hmac($challenge,$password));
 $response=base64_encode($username . " " . $hash) . "\r\n";
 return $response;
 }
@@ -78,7 +77,7 @@ function digest_md5_response ($username,$password,$challenge,$service,$host) {
     // rfc2831: client MUST fail if no qop methods supported
    // return false;
   //}
-  $cnonce = base64_encode(bin2hex(mhash(MHASH_MD5, microtime())));
+  $cnonce = base64_encode(bin2hex(hmac(microtime())));
   $ncount = "00000001";
 
   /* This can be auth (authentication only), auth-int (integrity protection), or
@@ -93,18 +92,18 @@ function digest_md5_response ($username,$password,$challenge,$service,$host) {
   $string_a1 = utf8_encode($username).":";
   $string_a1 .= utf8_encode($result['realm']).":";
   $string_a1 .= utf8_encode($password);
-  $string_a1 = mhash(MHASH_MD5, $string_a1);
+  $string_a1 = hmac($string_a1);
   $A1 = $string_a1 . ":" . $result['nonce'] . ":" . $cnonce;
-  $A1 = bin2hex(mhash(MHASH_MD5, $A1));
+  $A1 = bin2hex(hmac($A1));
   $A2 = "AUTHENTICATE:$digest_uri_value";
   // If qop is auth-int or auth-conf, A2 gets a little extra
   if ($qop_value != 'auth') {
     $A2 .= ':00000000000000000000000000000000';
   }
-  $A2 = bin2hex(mhash(MHASH_MD5, $A2));
+  $A2 = bin2hex(hmac($A2));
 
   $string_response = $result['nonce'] . ':' . $ncount . ':' . $cnonce . ':' . $qop_value;
-  $response_value = bin2hex(mhash(MHASH_MD5, $A1.":".$string_response.":".$A2));
+  $response_value = bin2hex(hmac($A1.":".$string_response.":".$A2));
 
   $reply = 'charset=utf-8,username="' . $username . '",realm="' . $result["realm"] . '",';
   $reply .= 'nonce="' . $result['nonce'] . '",nc=' . $ncount . ',cnonce="' . $cnonce . '",';
@@ -154,4 +153,30 @@ function digest_md5_parse_challenge($challenge) {
   return $parsed;
 }
 
+function hmac($data, $key='') {
+    // Creates a HMAC digest that can be used for auth purposes
+    // See RFCs 2104, 2617, 2831
+    // Uses mhash() extension if available
+    if (extension_loaded('mhash')) {
+      if ($key== '') {
+        $mhash=mhash(MHASH_MD5,$data);
+      } else {
+        $mhash=mhash(MHASH_MD5,$data,$key);
+      }
+      return $mhash;
+    }
+    if (!$key) {
+         return pack('H*',md5($data));
+    }
+    $key = str_pad($key,64,chr(0x00));
+    if (strlen($key) > 64) {
+        $key = pack("H*",md5($key));
+    }
+    $k_ipad =  $key ^ str_repeat(chr(0x36), 64) ;
+    $k_opad =  $key ^ str_repeat(chr(0x5c), 64) ;
+    /* Heh, let's get re-entrant. PHP is so kinky */
+    $hmac=hmac($k_opad . pack("H*",md5($k_ipad . $data)) );
+    return $hmac;
+}
+
 ?>

+ 1 - 1
functions/imap_general.php

@@ -237,7 +237,7 @@ function sqimap_login ($username, $password, $imap_server_address, $imap_port, $
     /* Decrypt the password */
     $password = OneTimePadDecrypt($password, $onetimepad);
 
-	if ((($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) AND (extension_loaded('mhash')))  {
+	if (($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) {
       // We're using some sort of authentication OTHER than plain
 	  $tag=sqimap_session_id(false);
 	  if ($imap_auth_mech == 'digest-md5') {