}
function initStream($message, $domain, $length=0, $host='', $port='', $user='', $pass='', $authpop=false) {
-
- if ($authpop) {
- $this->authPop($host, '', $user, $pass);
+ global $use_smtp_tls,$smtp_auth_mech,$username,$key,$onetimepad;
+
+ if ($authpop) {
+ $this->authPop($host, '', $username, $pass);
}
-
- $rfc822_header = $message->rfc822_header;
+
+ $rfc822_header = $message->rfc822_header;
$from = $rfc822_header->from[0];
$to = $rfc822_header->to;
$cc = $rfc822_header->cc;
- $bcc = $rfc822_header->bcc;
+ $bcc = $rfc822_header->bcc;
+
+ if (($use_smtp_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) {
+ $stream = fsockopen('tls://' . $host, $port, $errorNumber, $errorString);
+ } else {
+ $stream = fsockopen($host, $port, $errorNumber, $errorString);
+ }
- $stream = fsockopen($host, $port, $errorNumber, $errorString);
if (!$stream) {
$this->dlv_msg = $errorString;
$this->dlv_ret_nr = $errorNumber;
}
/* Lets introduce ourselves */
- if (! isset ($use_authenticated_smtp)
- || $use_authenticated_smtp == false) {
- fputs($stream, "HELO $domain\r\n");
- $tmp = fgets($stream, 1024);
- if ($this->errorCheck($tmp, $stream)) {
- return(0);
- }
- } else {
- fputs($stream, "EHLO $domain\r\n");
- $tmp = fgets($stream, 1024);
- if ($this->errorCheck($tmp, $stream)) {
- return(0);
- }
- fputs($stream, "AUTH LOGIN\r\n");
- $tmp = fgets($stream, 1024);
+ if ((( $smtp_auth_mech == 'cram-md5') or ( $smtp_auth_mech == 'digest-md5' )) and (extension_loaded('mhash')))
+ {
+ // Doing some form of non-plain auth
+ fputs($stream, "EHLO $domain\r\n");
+ $tmp = fgets($stream,1024);
+ if ($this->errorCheck($tmp,$stream)) {
+ return(0);
+ }
+ if ($smtp_auth_mech == 'cram-md5') {
+ fputs($stream, "AUTH CRAM-MD5\r\n");
+ } elseif ($smtp_auth_mech == 'digest-md5') {
+ fputs($stream, "AUTH DIGEST-MD5\r\n");
+ }
+ $tmp = fgets($stream,1024);
+
+ if ($this->errorCheck($tmp,$stream)) {
+ return(0);
+ }
+
+ // At this point, $tmp should hold "334 <challenge string>"
+ $chall = substr($tmp,4);
+ // Depending on mechanism, generate response string
+ if ($smtp_auth_mech == 'cram-md5') {
+ $response = cram_md5_response($username,$pass,$chall);
+ } elseif ($smtp_auth_mech == 'digest-md5') {
+ $response = digest_md5_response($username,$pass,$chall,'smtp',$host);
+ }
+ fputs($stream, $response);
+
+ // Let's see what the server had to say about that
+ $tmp = fgets($stream,1024);
+ if ($this->errorCheck($tmp,$stream)) {
+ return(0);
+ }
+
+ // CRAM-MD5 is done at this point. If DIGEST-MD5, there's a bit more to go
+ if ($smtp_auth_mech == 'digest-md5')
+ {
+ // $tmp contains rspauth, but I don't store that yet. (No need yet)
+ fputs($stream,"\r\n");
+ $tmp = fgets($stream,1024);
+
+ if ($this->errorCheck($tmp,$stream)) {
+ return(0);
+ }
+ }
+ // CRAM-MD5 and DIGEST-MD5 code ends here
+ } elseif ($smtp_auth_mech == 'none') {
+ // No auth at all, just send helo and then send the mail
+ fputs($stream, "HELO $domain\r\n");
+ $tmp = fgets($stream, 1024);
+ if ($this->errorCheck($tmp, $stream)) {
+ return(0);
+ }
+ } elseif ($smtp_auth_mech == 'plain') {
+ // The plain LOGIN method
+ fputs($stream, "EHLO $domain\r\n");
+ $tmp = fgets($stream, 1024);
+ if ($this->errorCheck($tmp, $stream)) {
+ return(0);
+ }
+ fputs($stream, "AUTH LOGIN\r\n");
+ $tmp = fgets($stream, 1024);
- if ($this->errorCheck($tmp, $stream)) {
- return(0);
- }
- fputs($stream, base64_encode ($user) . "\r\n");
- $tmp = fgets($stream, 1024);
- if ($this->errorCheck($tmp, $stream)) {
- return(0);
- }
+ if ($this->errorCheck($tmp, $stream)) {
+ return(0);
+ }
+ fputs($stream, base64_encode ($username) . "\r\n");
+ $tmp = fgets($stream, 1024);
+ if ($this->errorCheck($tmp, $stream)) {
+ return(0);
+ }
- fputs($stream, base64_encode($pass) . "\r\n");
- $tmp = fgets($stream, 1024);
- if ($this->errorCheck($tmp, $stream)) {
- return(0);
- }
+ fputs($stream, base64_encode($pass) . "\r\n");
+ $tmp = fgets($stream, 1024);
+ if ($this->errorCheck($tmp, $stream)) {
+ return(0);
+ }
}
/* Ok, who is sending the message? */
function errorCheck($line, $smtpConnection) {
global $color, $compose_new_win;
-
+
/* Read new lines on a multiline response */
$lines = $line;
while(ereg("^[0-9]+-", $line)) {
case 221: $message = 'Service closing transmission channel';
$status = 5;
break;
- case 421: $message = 'Service not available, closing chanel';
+ case 421: $message = 'Service not available, closing channel';
$status = 0;
break;
- case 235: return(5);
- break;
+ case 235: $message = 'Authentication successful';
+ $status = 5;
+ break;
case 250: $message = 'Requested mail action okay, completed';
$status = 5;
break;
case 251: $message = 'User not local; will forward';
$status = 5;
break;
- case 334: return(5); break;
+ case 334: $message = 'OK - continue request';
+ $status = 5;
+ break;
case 450: $message = 'Requested mail action not taken: mailbox unavailable';
$status = 0;
break;
$status = 0;
break;
/* end RFC2554 */
+ case 535: $message = 'Authentication failed';
+ $status = 0;
+ break;
default: $message = 'Unknown response: '. nl2br(htmlspecialchars($lines));
$status = 0;
$err_num = '001';
if ( !$optional_delimiter ) {
$optional_delimiter = "detect";
}
-if ( !$use_authenticated_smtp ) {
- $use_authenticated_smtp = "false";
-}
if ( !$auto_create_special ) {
$auto_create_special = "false";
}
$prefs_val_field = 'prefval';
}
+if ( !$use_smtp_tls) {
+ $use_smtp_tls= 'false';
+}
+
+if ( !$smtp_auth_mech ) {
+ $smtp_auth_mech = 'none';
+}
+
+if ( !$use_imap_tls ) {
+ $use_imap_tls = 'false';
+}
+
+if ( !$imap_auth_mech ) {
+ $imap_auth_mech = 'plain';
+}
+
if ( $ARGV[0] eq '--install-plugin' ) {
print "Activating plugin " . $ARGV[1] . "\n";
push @plugins, $ARGV[1];
print "\n";
print "R Return to Main Menu\n";
} elsif ( $menu == 2 ) {
- print $WHT. "Server Settings\n" . $NRM;
- print "1. Domain : $WHT$domain$NRM\n";
- print "2. IMAP Server : $WHT$imapServerAddress$NRM\n";
- print "3. IMAP Port : $WHT$imapPort$NRM\n";
- print "4. Use Sendmail/SMTP : $WHT";
+ print $WHT. "Server Settings\n\n" . $NRM;
+ print $WHT . "General" . $NRM . "\n";
+ print "-------\n";
+ print "1. Domain : $WHT$domain$NRM\n";
+ print "2. Invert Time : $WHT$invert_time$NRM\n";
+ print "3. Sendmail or SMTP : $WHT";
if ( lc($useSendmail) eq "true" ) {
print "Sendmail";
} else {
print "SMTP";
}
print "$NRM\n";
- if ( lc($useSendmail) eq "true" ) {
- print "5. Sendmail Path : $WHT$sendmail_path$NRM\n";
- } else {
- print "6. SMTP Server : $WHT$smtpServerAddress$NRM\n";
- print "7. SMTP Port : $WHT$smtpPort$NRM\n";
- print "8. Authenticated SMTP : $WHT$use_authenticated_smtp$NRM\n";
- print "9. POP Before SMTP : $WHT$pop_before_smtp$NRM\n";
+ print "\n";
+
+ if ( $show_imap_settings ) {
+ print $WHT . "IMAP Settings". $NRM . "\n--------------\n";
+ print "4. IMAP Server : $WHT$imapServerAddress$NRM\n";
+ print "5. IMAP Port : $WHT$imapPort$NRM\n";
+ print "6. Authentication type : $WHT$imap_auth_mech$NRM\n";
+ print "7. Secure IMAP (TLS) : $WHT$use_imap_tls$NRM\n";
+ print "8. Server software : $WHT$imap_server_type$NRM\n";
+ print "9. Delimiter : $WHT$optional_delimiter$NRM\n";
+ print "\n";
+ } elsif ( $show_smtp_settings ) {
+ if ( lc($useSendmail) eq "true" ) {
+ print $WHT . "Sendmail" . $NRM . "\n--------\n";
+ print "4. Sendmail Path : $WHT$sendmail_path$NRM\n";
+ print "\n";
+ } else {
+ print $WHT . "SMTP Settings" . $NRM . "\n-------------\n";
+ print "4. SMTP Server : $WHT$smtpServerAddress$NRM\n";
+ print "5. SMTP Port : $WHT$smtpPort$NRM\n";
+ print "6. POP before SMTP : $WHT$pop_before_smtp$NRM\n";
+ print "7. SMTP Authentication : $WHT$smtp_auth_mech$NRM\n";
+ print "8. Secure SMTP (TLS) : $WHT$use_smtp_tls$NRM\n";
+ print "\n";
+ }
}
- print "10. Server : $WHT$imap_server_type$NRM\n";
- print "11. Invert Time : $WHT$invert_time$NRM\n";
- print "12. Delimiter : $WHT$optional_delimiter$NRM\n";
+
+ if ($show_imap_settings == 0) {
+ print "A. Update IMAP Settings : ";
+ print "$WHT$imapServerAddress$NRM:";
+ print "$WHT$imapPort$NRM ";
+ print "($WHT$imap_server_type$NRM)\n";
+ }
+ if ($show_smtp_settings == 0) {
+ if ( lc($useSendmail) eq "true" ) {
+ print "B. Change Sendmail Config : $WHT$sendmail_path$NRM\n";
+ } else {
+ print "B. Update SMTP Settings : ";
+ print "$WHT$smtpServerAddress$NRM:";
+ print "$WHT$smtpPort$NRM\n";
+ }
+ }
+ if ( $show_smtp_settings || $show_imap_settings )
+ {
+ print "H. Hide " .
+ ($show_imap_settings ? "IMAP Server" :
+ (lc($useSendmail) eq "true") ? "Sendmail" : "SMTP") . " Settings\n";
+ }
+
print "\n";
print "R Return to Main Menu\n";
} elsif ( $menu == 3 ) {
elsif ( $command == 9 ) { $provider_name = command8(); }
} elsif ( $menu == 2 ) {
- if ( $command == 1 ) { $domain = command11(); }
- elsif ( $command == 2 ) { $imapServerAddress = command12(); }
- elsif ( $command == 3 ) { $imapPort = command13(); }
- elsif ( $command == 4 ) { $useSendmail = command14(); }
- elsif ( $command == 5 ) { $sendmail_path = command15(); }
- elsif ( $command == 6 ) { $smtpServerAddress = command16(); }
- elsif ( $command == 7 ) { $smtpPort = command17(); }
- elsif ( $command == 8 ) { $use_authenticated_smtp = command18(); }
- elsif ( $command == 9 ) { $pop_before_smtp = command18a(); }
- elsif ( $command == 10 ) { $imap_server_type = command19(); }
- elsif ( $command == 11 ) { $invert_time = command110(); }
- elsif ( $command == 12 ) { $optional_delimiter = command111(); }
+ if ( $command eq "a" ) { $show_imap_settings = 1; $show_smtp_settings = 0; }
+ elsif ( $command eq "b" ) { $show_imap_settings = 0; $show_smtp_settings = 1; }
+ elsif ( $command eq "h" ) { $show_imap_settings = 0; $show_smtp_settings = 0; }
+ elsif ( $command <= 3 ) {
+ if ( $command == 1 ) { $domain = command11(); }
+ elsif ( $command == 2 ) { $invert_time = command110(); }
+ elsif ( $command == 3 ) { $useSendmail = command14(); }
+ $show_imap_settings = 0; $show_smtp_settings = 0;
+ } elsif ( $show_imap_settings ) {
+ if ( $command == 4 ) { $imapServerAddress = command12(); }
+ elsif ( $command == 5 ) { $imapPort = command13(); }
+ elsif ( $command == 6 ) { $imap_auth_mech = command112("IMAP",$imap_auth_mech); }
+ elsif ( $command == 7 ) { $use_imap_tls = command113("IMAP",$use_imap_tls); }
+ elsif ( $command == 8 ) { $imap_server_type = command19(); }
+ elsif ( $command == 9 ) { $optional_delimiter = command111(); }
+ } elsif ( $show_smtp_settings && lc($useSendmail) eq "true" ) {
+ if ( $command == 4 ) { $sendmail_path = command15(); }
+ } elsif ( $show_smtp_settings ) {
+ if ( $command == 4 ) { $smtpServerAddress = command16(); }
+ elsif ( $command == 5 ) { $smtpPort = command17(); }
+ elsif ( $command == 6 ) { $pop_before_smtp = command18a(); }
+ elsif ( $command == 7 ) { $smtp_auth_mech = command112("SMTP",$smtp_auth_mech); }
+ elsif ( $command == 8 ) { $use_smtp_tls = command113("SMTP",$use_smtp_tls); }
+ }
} elsif ( $menu == 3 ) {
if ( $command == 1 ) { $default_folder_prefix = command21(); }
elsif ( $command == 2 ) { $show_prefix_option = command22(); }
# imapServerAddress
sub command12 {
- print "This is the address where your IMAP server resides.\n";
+ print "This is the hostname where your IMAP server can be contacted.\n";
print "[$WHT$imapServerAddress$NRM]: $WHT";
$new_imapServerAddress = <STDIN>;
if ( $new_imapServerAddress eq "\n" ) {
# smtpServerAddress
sub command16 {
- print "This is the location of your SMTP server.\n";
+ print "This is the hostname of your SMTP server.\n";
print "[$WHT$smtpServerAddress$NRM]: $WHT";
$new_smtpServerAddress = <STDIN>;
if ( $new_smtpServerAddress eq "\n" ) {
# authenticated server
sub command18 {
+ return;
+ # This sub disabled by tassium - it has been replaced with smtp_auth_mech
print "Do you wish to use an authenticated SMTP server? Your server must\n";
print "support this in order for SquirrelMail to work with it. We implemented\n";
print "it according to RFC 2554.\n";
return $new_optional_delimiter;
}
+# authentication type
+# This sub gets reused for IMAP and SMTP, so pass in the server type as an arg
+# Second arg is the default value to use
+# Possible choices: plain, cram-md5, digest-md5
+# SMTP also can be disabled with 'none'
+sub command112 {
+ my($default_val,$service,$inval);
+ $service=$_[0];
+ $default_val=$_[1];
+ print "What authentication mechanism do you want to use for " . $service . " logins?\n";
+ if ($service eq "SMTP") {
+ 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 "\n*** YOUR " . $service . " SERVER MUST SUPPORT THE MECHANISM YOU CHOOSE ***\n";
+ print "If you don't understand or are unsure, you probably want \"plain\"\n\n";
+ if ($service eq "SMTP") {
+ print "none, ";
+ }
+ print "plain, cram-md5, or digest-md5 [$WHT$default_val$NRM]: $WHT";
+ $inval=<STDIN>;
+ chomp($inval);
+ if ( ($service eq "SMTP") && ($inval =~ /^none\b/i) ) {
+ # SMTP doesn't necessarily require logins
+ return "none";
+ }
+ if ( ($inval =~ /^cram-md5\b/i) || ($inval =~ /^digest-md5\b/i) ||
+ ($inval =~ /^plain\b/i)) {
+ return lc($inval);
+ } else {
+ return $default_val;
+ }
+}
+
+# TLS
+# This sub is reused for IMAP and SMTP
+# Args: service name, default value
+sub command113 {
+ my($default_val,$service,$inval);
+ $service=$_[0];
+ $default_val=$_[1];
+ print "TLS (Transport Layer Security) encrypts the traffic between server and client.\n";
+ print "If you're familiar with SSL, you get the idea.\n";
+ print "To use this feature, your " . $service . " server must offer TLS\n";
+ print "capability, plus PHP 4.3.x with OpenSSL support.\n";
+ print "\nIf your " . $service . " server is localhost, you can safely disable this.\n";
+ print "If it is remote, you may wish to seriously consider enabling this.\n";
+ print "Enable TLS (y/n) [$WHT";
+ if ($default_val eq "true") {
+ print "y";
+ } else {
+ print "n";
+ }
+ print "$NRM]: $WHT";
+ $inval=<STDIN>;
+ $inval =~ tr/yn//cd;
+ return "true" if ( $inval eq "y" );
+ return "false" if ( $inval eq "n" );
+ return $default_val;
+
+
+}
+
+
# MOTD
sub command71 {
print "\nYou can now create the welcome message that is displayed\n";
# string
print CF "\$sendmail_path = '$sendmail_path';\n";
# boolean
- print CF "\$use_authenticated_smtp = $use_authenticated_smtp;\n";
+# print CF "\$use_authenticated_smtp = $use_authenticated_smtp;\n";
# boolean
print CF "\$pop_before_smtp = $pop_before_smtp;\n";
# string
print CF "\$prefs_val_field = '$prefs_val_field';\n";
# boolean
print CF "\$no_list_for_subscribe = $no_list_for_subscribe;\n";
+
+ # string
+ print CF "\$smtp_auth_mech = '$smtp_auth_mech';\n";
+ print CF "\$imap_auth_mech = '$imap_auth_mech';\n";
+ # boolean
+ print CF "\$use_imap_tls = $use_imap_tls;\n";
+ print CF "\$use_smtp_tls = $use_smtp_tls;\n";
+
print CF "\n";
print CF "/**\n";
# If the path is absolute, don't bother.
return "\'" . $old_path . "\'" if ( $old_path eq '');
return "\'" . $old_path . "\'" if ( $old_path =~ /^\// );
+ return $old_path if ( $old_path =~ /^\$/);
return $old_path if ( $old_path =~ /^SM_PATH/ );
# For relative paths, split on '../'
my $new_path = '';
return $old_path if ( $old_path eq '');
+ return $old_path if ( $old_path =~ /^\$/ );
return $old_path if ( $old_path =~ /^\// );
return $old_path if ( $old_path =~ /^\.\./ );
global $no_list_for_subscribe;
$no_list_for_subscribe = false;
+/**
+ * Advanced authentication options
+ * CRAM-MD5, DIGEST-MD5, Plain, and TLS
+ * Set reasonable defaults - you'd never know this was there unless you ask for it
+ */
+global $use_imap_tls;
+global $use_smtp_tls;
+$use_imap_tls = false;
+$use_smtp_tls = false;
+
+/* auth_mech can be either 'plain', 'cram-md5', or 'digest-md5'
+ SMTP can also be 'none'
+*/
+global $smtp_auth_mech;
+global $imap_auth_mech;
+$smtp_auth_mech = 'none';
+$imap_auth_mech = 'plain';
+
/**
* Make sure there are no characters after the PHP closing
* tag below (including newline characters and whitespace).
RFC 1730 IMAP version 4
RFC 2060 IMAP version 4rev1
RFC 2183 Content-Disposition MIME header
+RFC 2195 IMAP/POP AUTHorize Extension for Simple Challenge/Response
RFC 2298 Details return receipts
RFC 2342 The IMAP4 NAMESPACE command
RFC 2616 HTTP/1.1
RFC 2683 IMAP4 Implementation Recommendations
RFC 2822 Format of an email message (sendmail)
+RFC 2831 Using Digest Authentication as a SASL Mechanism (digest-md5)
* $Id$
*/
+/* Put in a safety net here, in case a naughty admin didn't run conf.pl when they upgraded */
+
+if (! isset($smtp_auth_mech)) {
+ $smtp_auth_mech = 'none';
+}
+
+if (! isset($imap_auth_mech)) {
+ $imap_auth_mech = 'plain';
+}
+
+if (! isset($use_imap_tls)) {
+ $use_imap_tls = false;
+}
+
+if (! isset($use_smtp_tls)) {
+ $use_smtp_tls = false;
+}
+
function is_logged_in() {
if ( sqsession_is_registered('user_is_logged_in') ) {
}
}
+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));
+$response=base64_encode($username . " " . $hash) . "\r\n";
+return $response;
+}
+
+function digest_md5_response ($username,$password,$challenge,$service,$host) {
+/* Given the challenge from the server, calculate and return the response-string
+ for digest-md5 authentication. (See RFC 2831 for more details) */
+ $result=digest_md5_parse_challenge($challenge);
+
+// verify server supports qop=auth
+ $qop = explode(",",$result['qop']);
+ //if (!in_array("auth",$qop)) {
+ // rfc2831: client MUST fail if no qop methods supported
+ // return false;
+ //}
+ $cnonce = base64_encode(bin2hex(mhash(MHASH_MD5, microtime())));
+ $ncount = "00000001";
+
+ /* This can be auth (authentication only), auth-int (integrity protection), or
+ auth-conf (confidentiality protection). Right now only auth is supported.
+ DO NOT CHANGE THIS VALUE */
+ $qop_value = "auth";
+
+ $digest_uri_value = $service . '/' . $host;
+
+ // build the $response_value
+ //FIXME This will probably break badly if a server sends more than one realm
+ $string_a1 = utf8_encode($username).":";
+ $string_a1 .= utf8_encode($result['realm']).":";
+ $string_a1 .= utf8_encode($password);
+ $string_a1 = mhash(MHASH_MD5, $string_a1);
+ $A1 = $string_a1 . ":" . $result['nonce'] . ":" . $cnonce;
+ $A1 = bin2hex(mhash(MHASH_MD5, $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));
+
+ $string_response = $result['nonce'] . ':' . $ncount . ':' . $cnonce . ':' . $qop_value;
+ $response_value = bin2hex(mhash(MHASH_MD5, $A1.":".$string_response.":".$A2));
+
+ $reply = 'charset=utf-8,username="' . $username . '",realm="' . $result["realm"] . '",';
+ $reply .= 'nonce="' . $result['nonce'] . '",nc=' . $ncount . ',cnonce="' . $cnonce . '",';
+ $reply .= "digest-uri=\"$digest_uri_value\",response=$response_value";
+ $reply .= ',qop=' . $qop_value;
+ $reply = base64_encode($reply);
+ return $reply . "\r\n";
+
+}
+
+function digest_md5_parse_challenge($challenge) {
+/* This function parses the challenge sent during DIGEST-MD5 authentication and
+ returns an array. See the RFC for details on what's in the challenge string.
+*/
+ $challenge=base64_decode($challenge);
+ while (strlen($challenge)) {
+ if ($challenge{0} == ',') { // First char is a comma, must not be 1st time through loop
+ $challenge=substr($challenge,1);
+ }
+ $key=explode('=',$challenge,2);
+ $challenge=$key[1];
+ $key=$key[0];
+ if ($challenge{0} == '"') {
+ // We're in a quoted value
+ // Drop the first quote, since we don't care about it
+ $challenge=substr($challenge,1);
+ // Now explode() to the next quote, which is the end of our value
+ $val=explode('"',$challenge,2);
+ $challenge=$val[1]; // The rest of the challenge, work on it in next iteration of loop
+ $value=explode(',',$val[0]);
+ // Now, for those quoted values that are only 1 piece..
+ if (sizeof($value) == 1) {
+ $value=$value[0]; // Convert to non-array
+ }
+ } else {
+ // We're in a "simple" value - explode to next comma
+ $val=explode(',',$challenge,2);
+ $challenge=$val[1];
+ $value=$val[0];
+ }
+ $parsed["$key"]=$value;
+ } // End of while loop
+ return $parsed;
+}
+
?>
*/
require_once(SM_PATH . 'functions/page_header.php');
+require_once(SM_PATH . 'functions/auth.php');
+
global $sqimap_session_id;
$sqimap_session_id = 1;
* will be displayed. This function returns the imap connection handle.
*/
function sqimap_login ($username, $password, $imap_server_address, $imap_port, $hide) {
- global $color, $squirrelmail_language, $onetimepad;
+ global $color, $squirrelmail_language, $onetimepad, $use_imap_tls, $imap_auth_mech;
$imap_server_address = sqimap_get_user_server($imap_server_address, $username);
-
+ $host=$imap_server_address;
+
+ if (($use_imap_tls == true) and (check_php_version(4,3)) and (extension_loaded('openssl'))) {
+ /* Use TLS by prefixing "tls://" to the hostname */
+ $imap_server_address = 'tls://' . $imap_server_address;
+ }
+
$imap_stream = fsockopen ( $imap_server_address, $imap_port, $error_number, $error_string, 15);
/* Do some error correction */
/* Decrypt the password */
$password = OneTimePadDecrypt($password, $onetimepad);
- $query = 'LOGIN "' . quoteIMAP($username) . '" "' . quoteIMAP($password) . '"';
- $read = sqimap_run_command ($imap_stream, $query, false, $response, $message);
-
- /* If the connection was not successful, lets see why */
+ if ((($imap_auth_mech == 'cram-md5') OR ($imap_auth_mech == 'digest-md5')) AND (extension_loaded('mhash'))) {
+ // We're using some sort of authentication OTHER than plain
+ $tag=sqimap_session_id(false);
+ if ($imap_auth_mech == 'digest-md5') {
+ $query = $tag . " AUTHENTICATE DIGEST-MD5\r\n";
+ } elseif ($imap_auth_mech == 'cram-md5') {
+ $query = $tag . " AUTHENTICATE CRAM-MD5\r\n";
+ }
+ fputs($imap_stream,$query);
+ $answer=sqimap_fgets($imap_stream);
+ // Trim the "+ " off the front
+ $response=explode(" ",$answer,3);
+ if ($response[0] == '+') {
+ // Got a challenge back
+ $challenge=$response[1];
+ if ($imap_auth_mech == 'digest-md5') {
+ $reply = digest_md5_response($username,$password,$challenge,'imap',$host);
+ } elseif ($imap_auth_mech == 'cram-md5') {
+ $reply = cram_md5_response($username,$password,$challenge);
+ }
+ fputs($imap_stream,$reply);
+ $read=sqimap_fgets($imap_stream);
+ if ($imap_auth_mech == 'digest-md5') {
+ // DIGEST-MD5 has an extra step..
+ if (substr($read,0,1) == '+') { // OK so far..
+ fputs($imap_stream,"\r\n");
+ $read=sqimap_fgets($imap_stream);
+ }
+ }
+ $results=explode(" ",$read,3);
+ $response=$results[1];
+ $message=$results[2];
+ } else {
+ // Fake the response, so the error trap at the bottom will work
+ $response="BAD";
+ $message='IMAP server does not appear to support the authentication method selected.';
+ $message .= ' Please contact your system administrator.';
+ }
+ } else {
+ // Original PLAIN login code
+ $query = 'LOGIN "' . quoteIMAP($username) . '" "' . quoteIMAP($password) . '"';
+ $read = sqimap_run_command ($imap_stream, $query, false, $response, $message);
+ }
+
+ /* If the connection was not successful, lets see why */
if ($response != 'OK') {
if (!$hide) {
if ($response != 'NO') {
if (!$useSendmail && !$draft) {
require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
$deliver = new Deliver_SMTP();
- global $smtpServerAddress, $smtpPort, $use_authenticated_smtp, $pop_before_smtp;
- if ($use_authenticated_smtp) {
- global $key, $onetimepad;
- $user = $username;
- $pass = OneTimePadDecrypt($key, $onetimepad);
+ global $smtpServerAddress, $smtpPort, $pop_before_smtp, $smtp_auth_mech;
+
+ if ($smtp_auth_mech == 'none') {
+ $user = '';
+ $pass = '';
} else {
- $user = '';
- $pass = '';
+ global $key, $onetimepad;
+ $user = $username;
+ $pass = OneTimePadDecrypt($key, $onetimepad);
}
+
$authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
$stream = $deliver->initStream($composeMessage,$domain,0,
$smtpServerAddress, $smtpPort, $user, $pass, $authPop);
} else {
require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
$deliver = new Deliver_SMTP();
- global $smtpServerAddress, $smtpPort, $use_authenticated_smtp, $pop_before_smtp;
- if ($use_authenticated_smtp) {
+ global $smtpServerAddress, $smtpPort, $smtp_auth_mech, $pop_before_smtp;
+ if ($smtp_auth_mech == 'none') {
+ $user = '';
+ $pass = '';
+ } else {
global $key, $onetimepad;
$user = $username;
$pass = OneTimePadDecrypt($key, $onetimepad);
- } else {
- $user = '';
- $pass = '';
}
$authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
$stream = $deliver->initStream($composeMessage,$domain,0,