From 639c716482e432f35b6f8e3aeb4802562a3824c1 Mon Sep 17 00:00:00 2001 From: tassium Date: Sat, 7 Dec 2002 04:02:05 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@4220 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- class/deliver/Deliver_SMTP.class.php | 3 +-- config/conf.pl | 8 +++--- doc/authentication.txt | 7 ++--- functions/auth.php | 39 +++++++++++++++++++++++----- functions/imap_general.php | 2 +- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/class/deliver/Deliver_SMTP.class.php b/class/deliver/Deliver_SMTP.class.php index 4c8e49a0..d3670782 100644 --- a/class/deliver/Deliver_SMTP.class.php +++ b/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); diff --git a/config/conf.pl b/config/conf.pl index eaa2a589..ad1ff4f3 100755 --- a/config/conf.pl +++ b/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"; diff --git a/doc/authentication.txt b/doc/authentication.txt index 73d1ed69..48d46a83 100644 --- a/doc/authentication.txt +++ b/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 diff --git a/functions/auth.php b/functions/auth.php index b00efd43..cb149dad 100644 --- a/functions/auth.php +++ b/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; +} + ?> diff --git a/functions/imap_general.php b/functions/imap_general.php index ab732315..1268831c 100755 --- a/functions/imap_general.php +++ b/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') { -- 2.25.1