phpgroupware-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Phpgroupware-tracker] [bugs #3304] Sending mail is impossible with Qmai


From: Dr. Christian Böttger
Subject: [Phpgroupware-tracker] [bugs #3304] Sending mail is impossible with Qmail system
Date: Wed, 21 Apr 2004 03:39:43 -0400
User-agent: Mozilla/5.0 (compatible; Konqueror/3.2; Linux 2.4.21-202-default; X11; i686; de, address@hidden) (KHTML, like Gecko)

This mail is an automated notification from the bugs tracker
 of the project: phpGroupWare.

/**************************************************************************/
[bugs #3304] Latest Modifications:

Changes by: 
                Dr. Christian Böttger <address@hidden>
'Date: 
                Wed 04/21/04 at 07:39 (Europe/Berlin)

            What     | Removed                   | Added
---------------------------------------------------------------------------
         Assigned to | None                      | angles







/**************************************************************************/
[bugs #3304] Full Item Snapshot:

URL: <http://savannah.gnu.org/bugs/?func=detailitem&item_id=3304>
Project: phpGroupWare
Submitted by: yann
On: Tue 04/22/03 at 16:17

Category:  email
Item Group:  None
Severity:  5 - Average
Priority:  5 - Normal
Resolution:  None
Assigned to:  angles
Status:  Open
Component Version:  None
Platform Version:  GNU/Linux - RedHat/Fedora
Reproducibility:  Every Time


Summary:  Sending mail is impossible with Qmail system

Original Submission:  My server is installed on linux with the mail system 
Qmail (and not sendmail...). I can read mailboxes but it's impossible to send 
mail. I try also with the module felamail. It doesn't work.



Note: I have tested with the success to send a mail with my own script php so 
my config is ok. 

Follow-up Comments
------------------


-------------------------------------------------------
Date: Fri 06/27/03 at 15:46         By: cw
ah, which doesn't allow for proper multipart mime mail forwarding so it's not 
an option.

is the qmail on the same host as the web server, and do you access it via 
localhost or the full name or IP? 

-------------------------------------------------------
Date: Fri 06/27/03 at 15:13         By: yannator
I can feel your frustation :-) but I did'nt succeed to catch more information 
from the Qmail server (it failed during the first connexion).
The class which work is on the site (email_message.php)
I don't have written. I take it on phpclasses.org. It prepares the body and 
headers etc... then it uses simply the php function mail() (line 141)
and... it works ! 


-------------------------------------------------------
Date: Fri 06/27/03 at 14:38         By: cw
*sigh*

alright then, exacly how does the class that work make the connection?

i hope you can see my frustration here.  you keep saying "it's broke" and "but 
this other thing works" but you won't tell us what this other thing does 
differently!



-------------------------------------------------------
Date: Fri 06/27/03 at 14:28         By: yannator
As I said in a previous message, the bug happens
 in /email/inc/class.mail_send.inc.php in the function msg2socket at it's first 
call when the connection is established with Qmail. Qmail closes immediatly the 
connection. The groupware error was:
"error 420
lost connection
lost connection to smtp server ". there is no way to catch Qmail error.
I have no more information. 
The question of the headers is my own hypothesis. If I knew exactly what was 
wrong, I would have correct it by myself. With the other class, it works....

-------------------------------------------------------
Date: Fri 06/27/03 at 14:09         By: cw
well then this doesn't help at all bcause we don't have that file!

you send way too much extranious data, please only post the sections of code 
that apply to the problem, which we still don't know of because you just say 
"qmail has stricter rules for smtp" which is confusing because our class 
follows the protocol to the letter.  

what exactly does qmail want? (not that this is the problem, just an example)  
example answer:

currently sends:
MAIL FROM: address@hidden

needs to send:
MAIL FROM: <address@hidden>

(using <> is optional according to RFC so this better not be the problem. :P )



-------------------------------------------------------
Date: Fri 06/27/03 at 13:47         By: yannator
If you read the code of the function smail_2822,all the old code is in comment. 
I use instead the class email_message.php.
See below, i have removed the comments

                // ===== [ main function: smail_2822() ] =======

                function smail_2822($mail_out)
                {
                 

                  require_once 
PHPGW_SERVER_ROOT."/phpgwapi/inc/email_message.php";
                  $email_message=new email_message_class;

                  $from_name=getenv("USERNAME");
                  $from_address= $mail_out[from][0][plain];
                  $reply_name=$from_name;
                  $reply_address=$from_address;
                  $reply_address=$from_address;
                  $error_delivery_name=$from_name;
                  $error_delivery_address=$from_address;

                  $subject = $mail_out[subject];
                  if(!$subject){
                    $subject ="none";
                  }
                  $body = $email_message->WrapText($mail_out[body_string]);
                  
        
                  
$email_message->SetEncodedEmailHeader("From",$from_address,$from_name);
                  
$email_message->SetEncodedEmailHeader("Reply-To",$reply_address,$reply_name);
                  /*
                   *  Set the Return-Path header to define the envelope sender 
address to which bounced messages are delivered.
                   *  If you are using Windows, you need to use the 
smtp_message_class to set the return-path address.
                   */
                  if(defined("PHP_OS")
                     && strcmp(substr(PHP_OS,0,3),"WIN"))
                    
$email_message->SetHeader("Return-Path",$error_delivery_address);
                  
$email_message->SetEncodedEmailHeader("Errors-To",$error_delivery_address,$error_delivery_name);
                  $email_message->SetEncodedHeader("Subject",$subject);

                  /* If you are not going to personalize the message body for 
each recipient,
                   * set the cache_body flag to 1 to reduce the time that the 
class will take
                   * to regenerate the message to send to each recipient */
                  $email_message->cache_body=1;
                  
$email_message->AddQuotedPrintableTextPart($email_message->WrapText($body));

                  // pieces jointes
                  if ($mail_out['is_multipart'] == True){
                    foreach($mail_out[attachment_file] as $ind => $tabFile){
                      $email_message->AddFilePart($tabFile);
                    }
                  }

                  /* Iterate personalization for each recipient. */
                  $tab=array('to','cc','bcc');
                  foreach($tab as $ind => $arrayName){
                    $tabAddress = $mail_out[$arrayName];
                    if(is_array($tabAddress) && count($tabAddress) >= 1){
                     
                      
for($recipient=0;$recipient<count($tabAddress);$recipient++)
                        {
                          
                          /* Personalize the recipient address. */
                          $to_address=$tabAddress[$recipient]["plain"];
                          $to_name=$tabAddress[$recipient]["personal"];
                          //print "to_address=$to_address<br>";
                          
$email_message->SetEncodedEmailHeader("To",$to_address,$to_name);
                          
                          /* Do we really need to personalize the message body?
                           * If not, let the class reuse the message body 
defined for the first recipient above.
                           */
                         
                          /* Send the message checking for eventually 
acumulated errors */
                          $error=$email_message->Send();
                          if(strlen($error))
                            break;
                        }
                    }
                  }
                  if(strlen($error)) {
                    echo "Error: $errorn";
                  }
                  else{
                    return true;
                  }
                }
                
        // end of class
        }

-------------------------------------------------------
Date: Fri 06/27/03 at 13:40         By: cw
can you narrow this down to exactly the smtp chat changes?  i'm not seeing the 
difference.


-------------------------------------------------------
Date: Fri 06/27/03 at 08:10         By: None
My job is really dirty: i used an other email class and I have forced the code 
to use it. You can send mail with joined files  and that's all. (no forward or 
Cc, etc...)
 

I have change in /email/inc/class.mail_send.inc.php the function smail_2822().
        // ===== [ main function: smail_2822() ] =======

                function smail_2822($mail_out)
                {
                  /*print "<pre>";
                  print_r($mail_out);
                  print "</pre><hr>";*/

                  require_once 
PHPGW_SERVER_ROOT."/phpgwapi/inc/email_message.php";
                  $email_message=new email_message_class;

                  $from_name=getenv("USERNAME");
                  $from_address= $mail_out[from][0][plain];
                  $reply_name=$from_name;
                  $reply_address=$from_address;
                  $reply_address=$from_address;
                  $error_delivery_name=$from_name;
                  $error_delivery_address=$from_address;

                  $subject = $mail_out[subject];
                  if(!$subject){
                    $subject ="none";
                  }
                  $body = $email_message->WrapText($mail_out[body_string]);
                  
        
                  
$email_message->SetEncodedEmailHeader("From",$from_address,$from_name);
                  
$email_message->SetEncodedEmailHeader("Reply-To",$reply_address,$reply_name);
                  /*
                   *  Set the Return-Path header to define the envelope sender 
address to which bounced messages are delivered.
                   *  If you are using Windows, you need to use the 
smtp_message_class to set the return-path address.
                   */
                  if(defined("PHP_OS")
                     && strcmp(substr(PHP_OS,0,3),"WIN"))
                    
$email_message->SetHeader("Return-Path",$error_delivery_address);
                  
$email_message->SetEncodedEmailHeader("Errors-To",$error_delivery_address,$error_delivery_name);
                  $email_message->SetEncodedHeader("Subject",$subject);

                  /* If you are not going to personalize the message body for 
each recipient,
                   * set the cache_body flag to 1 to reduce the time that the 
class will take
                   * to regenerate the message to send to each recipient */
                  $email_message->cache_body=1;
                  
$email_message->AddQuotedPrintableTextPart($email_message->WrapText($body));

                  // pieces jointes
                  if ($mail_out['is_multipart'] == True){
                    foreach($mail_out[attachment_file] as $ind => $tabFile){
                      $email_message->AddFilePart($tabFile);
                    }
                  }

                  /* Iterate personalization for each recipient. */
                  $tab=array('to','cc','bcc');
                  foreach($tab as $ind => $arrayName){
                    $tabAddress = $mail_out[$arrayName];
                    if(is_array($tabAddress) && count($tabAddress) >= 1){
                      /*print "<pre>";
                  print_r($tabAddress);
                  print "</pre>";*/
                      
for($recipient=0;$recipient<count($tabAddress);$recipient++)
                        {
                          
                          /* Personalize the recipient address. */
                          $to_address=$tabAddress[$recipient]["plain"];
                          $to_name=$tabAddress[$recipient]["personal"];
                          //print "to_address=$to_address<br>";
                          
$email_message->SetEncodedEmailHeader("To",$to_address,$to_name);
                          
                          /* Do we really need to personalize the message body?
                           * If not, let the class reuse the message body 
defined for the first recipient above.
                           */
                          /*  print "<pre>";
                          print_r($email_message);
                          print "</pre>";*/
                          
                          /* Send the message checking for eventually 
acumulated errors */
                          $error=$email_message->Send();
                          if(strlen($error))
                            break;
                        }
                    }
                  }
                  if(strlen($error)) {
                    echo "Error: $errorn";
                  }
                  else{
                    return true;
                  }






                  /*    // don't start retaining the email copy until after the 
MTA handshake
                        $this->retain_copy_ignore = True;
                        
                        // error code and message of failed connection
                        $errcode = '';
                        $errmsg = '';
                        // timeout in secs
                        $timeout = 5;
                        
                        if ($this->debug_fake_send)
                        {
                                // arbitrary number, no significance
                                // we do not actually communicate with the SMTP 
server for a fake send
                                $socket = 41;
                                // announce the fact this is echo'd debug 
output, not an actual session
                                echo '<html><body><h2>FAKE SEND DEBUG:</h2> 
<h3>this is what the client *would* send to the SMTP server were this an actual 
send</h3>';
                        }
                        else
                        {
                                $smtp_server = 
$GLOBALS['phpgw_info']['server']['smtp_server'];
                                $smtp_port = 
$GLOBALS['phpgw_info']['server']['smtp_port'];
                                // some people do not set this up correctly in 
the site-wide admin for email
                                if (empty($smtp_port))
                                {
                                        $smtp_port = $this->default_smtp_port;
                                }
                                
                                // OPEN SOCKET - now we try to open the socket 
and check, if any smtp server responds
                                $socket = 
fsockopen($smtp_server,$smtp_port,$errcode,$errmsg,$timeout);
                                $this->err['server_chat'] .= 
htmlspecialchars('c->s: 
fsockopen('.$smtp_server.','.$smtp_port.','.$errcode.','.$errmsg.','.$timeout.')
 ; returned: '.$socket )."rn";

                        }
                        if (!$socket)
                        {
                                $this->err['code'] = '420';
                                $this->err['msg']  = $errcode.':'.$errmsg;
                                $this->err['desc'] = 'Connection to 
'.$GLOBALS['phpgw_info']['server']['smtp_server'].':'.$GLOBALS['phpgw_info']['server']['smtp_port'].'
 failed - could not open socket.';
                                return false;
                        }
                        else
                        {
                                $rrc = $this->socket2msg($socket);
                        }
                        
                        $mymachine = $mail_out['mta_elho_mymachine'];
                        $fromuser = $mail_out['mta_from'];
                        // START SMTP SESSION - now we can send our message. 
1st we identify ourselves and the sender
                        $cmds = array (
                                "$src = $this->msg2socket($socket,"EHLO 
$mymachinern");",
                                "$rrc = $this->socket2msg($socket);",
                                "$src = $this->msg2socket($socket,"MAIL 
FROM:$fromuserrn");",
                                "$rrc = $this->socket2msg($socket);"
                        );
                        if ($this->debug_fake_send)
                        {
                                echo '<pre>';
                        }
                        for ($src=true,$rrc=true,$i=0; $i<count($cmds);$i++)
                        {
                                eval ($cmds[$i]);
                                if (!$src || !$rrc)
                                {
                                        return false;
                                }
                        }
                        
                        // RCPT TO - now we've got to feed the to's and cc's
                        for ($i=0; $i<count($mail_out['mta_to']); $i++)
                        {
                                $src = $this->msg2socket($socket,'RCPT 
TO:'.$mail_out['mta_to'][$i]."rn");
                                $rrc = $this->socket2msg($socket);
                                // for lateron validation
                                $this->to_res[$i][addr] = 
$mail_out['mta_to'][$i];
                                $this->to_res[$i][code] = $this->err['code'];
                                $this->to_res[$i][msg]  = $this->err['msg'];
                                $this->to_res[$i][desc] = $this->err['desc'];
                        }
                        
                        if (!$this->debug_fake_send)
                        {
                                //now we have to make sure that at least one 
$to-address was accepted
                                $stop = 1;
                                for ($i=0;$i<count($this->to_res);$i++)
                                {
                                        $rc = 
substr($this->to_res[$i][code],0,1);
                                        if ($rc == 2)
                                        {
                                                // at least to this address we 
can deliver
                                                $stop = 0;
                                        }
                                }
                                if ($stop)
                                {
                                        // no address found we can deliver to
                                        return false;
                                }
                        }
                        
                        // HEADERS - now we can go to deliver the headers!
                        if (!$this->msg2socket($socket,"DATArn"))
                        {
                                return false;
                        }
                        if (!$this->socket2msg($socket))
                        {
                                return false;
                        }
                        
                        // READY TO SEND MAIL: start retaining the email copy 
(if necessary)
                        $this->retain_copy_ignore = False;
                        
                        // BEGIN THE DATA SEND
                        for ($i=0; $i<count($mail_out['main_headers']); $i++)
                        {
                                if 
(!$this->msg2socket($socket,$mail_out['main_headers'][$i]."rn"))
                                {
                                        return false;
                                }
                        }
                        // HEADERS TERMINATION - this CRLF terminates the 
header, signals the body will follow next (ONE CRLF ONLY)
                        if (!$this->msg2socket($socket,"rn"))
                        {
                                return false;
                        }
                        // BODY - now we can go to deliver the body!
                        for ($part_num=0; $part_num<count($mail_out['body']); 
$part_num++)
                        {
                                // mime headers for this mime part (if any)
                                if (($mail_out['is_multipart'] == True)
                                || ($mail_out['is_forward'] == True))
                                {
                                        for ($i=0; 
$i<count($mail_out['body'][$part_num]['mime_headers']); $i++)
                                        {
                                                $this_line = rtrim($this_line = 
$mail_out['body'][$part_num]['mime_headers'][$i])."rn";
                                                if 
(!$this->msg2socket($socket,$this_line))
                                                {
                                                        return false;
                                                }
                                        }
                                        // a space needs to seperate the mime 
part headers from the mime part content
                                        if (!$this->msg2socket($socket,"rn"))
                                        {
                                                return false;
                                        }
                                }
                                // the part itself
                                for ($i=0; 
$i<count($mail_out['body'][$part_num]['mime_body']); $i++)
                                {
                                        $this_line = 
rtrim($mail_out['body'][$part_num]['mime_body'][$i])."rn";
                                        // TRANSPARENCY - rfc2821 sect 4.5.2 - 
any line beginning with a dot, add another dot
                                        if ((strlen($this_line) > 0)
                                        && ($this_line[0] == '.'))
                                        {
                                                // rfc2821 add another dot to 
the begining of this line
                                                $this_line = '.' .$this_line;
                                        }
                                        if 
(!$this->msg2socket($socket,$this_line))
                                        {
                                                return false;
                                        }
                                }
                                // this space will seperate this part from any 
following parts that may be coming
                                if (!$this->msg2socket($socket,"rn"))
                                {
                                        return false;
                                }
                        }
                        // FINAL BOUNDARY - at the end of a multipart email, we 
need to add the "final" boundary
                        if (($mail_out['is_multipart'] == True)
                        || ($mail_out['is_forward'] == True))
                        {
                                // attachments / parts have their own boundary 
preceeding them in their mime headers
                                // this is: "--"boundary
                                // all boundary strings are have 2 dashes "--" 
added to their begining
                                // and the FINAL boundary string (after all 
other parts) ALSO has 
                                // 2 dashes "--" tacked on tho the end of it, 
very important !! 
                                //   the first or last rn is *probably* not 
necessary
                                $final_boundary = '--' 
.$mail_out['boundary'].'--'."rn";
                                if (!$this->msg2socket($socket,$final_boundary))
                                {
                                        return false;
                                }
                                // another blank line
                                if (!$this->msg2socket($socket,"rn"))
                                {
                                        return false;
                                }
                        }
                        
                        // stop retaining the email copy, the message is over, 
only MTA closing handshake remainse
                        $this->retain_copy_ignore = True;
                        
                        // DATA END - special string "DOTCRLF" signals the end 
of the body
                        if (!$this->msg2socket($socket,".rn"))
                        {
                                return false;
                        }
                        if (!$this->socket2msg($socket))
                        {
                                return false;
                        }
                        // QUIT
                        if (!$this->msg2socket($socket,"QUITrn"))
                        {
                                return false;
                        }
                        
                        if ($this->debug_fake_send)
                        {
                                echo '</pre><h3>end of Fake 
Send</h3></body></html>';
                        }
                        
                        if (!$this->debug_fake_send)
                        {
                                do
                                {
                                        $closing = $this->socket2msg($socket);
                                }
                                while ($closing);
                        }
                        return true;*/
                }
                


-------------------------------------------------------
Date: Fri 06/27/03 at 02:39         By: cw
the RFC is pretty specific and mail_send follows it, can you at least outline 
your modified SMTP chat?

-------------------------------------------------------
Date: Tue 06/03/03 at 07:01         By: yannator
The error was:
error 420
lost connection
lost connection to smtp server

the bug is in /email/inc/class.mail_send.inc.php in the function msg2socket. It 
opens a socket with success but after, when you try to send headers, the Qmail 
server closes the socket.
I am not sure but I think that the syntax of the headers are not perfect. a 
smtp server is less restrictive than a Qmail server. I have changed the code 
with an other email class (which work) But it is a very dirty job so I prefer 
not send it to you.

-------------------------------------------------------
Date: Mon 06/02/03 at 22:19         By: skwashd
and what is the error you receive?

-------------------------------------------------------
Date: Mon 06/02/03 at 14:25         By: yannator
More Informations:
OS = linux Red Hat 6.3
Apache = 1.3.27
Php Version = 4.2.3
Php groupware Version = 0.9.14.000



-------------------------------------------------------
Date: Thu 05/29/03 at 01:18         By: skwashd
You have not provided enough information for us to diagnose this
problem.  See http://phpgroupware.org/bugs for a list information
that we require in a bug report.






File Attachments
-------------------

-------------------------------------------------------
Date: Fri 06/27/03 at 08:10  Name: email_message.php  Size: 35KB   By: None
The email class I really use to send mail
http://savannah.gnu.org/bugs/download.php?item_id=3304&amp;item_file_id=498






For detailed info, follow this link:
<http://savannah.gnu.org/bugs/?func=detailitem&item_id=3304>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/







reply via email to

[Prev in Thread] Current Thread [Next in Thread]