bugphpGroupWare - Bugs: bug #3304, Sending mail is impossible with...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #3304: Sending mail is impossible with Qmail system

Submitter:  Invalid User ID <#18331>
Submitted:  Tue 22 Apr 2003 04:17:30 PM UTC
   
 
Category:  email Item Group:  None
Severity:  3 - Normal Priority:  5 - Normal
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  None Operating System:  GNU/Linux - RedHat/Fedora
Reproducibility:  Every Time Planned Release:  None
Fixed Release: 

Jump to the original submission

Wed 21 Apr 2004 02:02:59 PM UTC, comment #15: 

Yann, if you would to try to make this work again please try 0.9.16 which has many improvements in the email program and other places too.  It's worth looking at.

cboettger: I typicaly act as an in-between for email and anglemail when it's pratical.

Since this was for .14 and I didn't get answers to the last questions I'm closing this one.

Chris Weiss <cw>
Group administrator
Wed 21 Apr 2004 08:51:25 AM UTC, comment #14: 

no email application maintainer available

Dr. Christian Böttger <cboettger>
Fri 27 Jun 2003 03:46:53 PM UTC, comment #13: 

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?

Chris Weiss <cw>
Group administrator
Fri 27 Jun 2003 03:13:03 PM UTC, comment #12: 

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 !

Invalid User ID <#18331>
Fri 27 Jun 2003 02:38:30 PM UTC, comment #11: 

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!


Chris Weiss <cw>
Group administrator
Fri 27 Jun 2003 02:28:46 PM UTC, comment #10: 

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....

Invalid User ID <#18331>
Fri 27 Jun 2003 02:09:36 PM UTC, comment #9: 

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: email@domain

needs to send:
MAIL FROM: <email@domain>

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


Chris Weiss <cw>
Group administrator
Fri 27 Jun 2003 01:47:33 PM UTC, comment #8: 

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: $error\n";
                  }
                  else{
                    return true;
                  }
}

// end of class
}

Invalid User ID <#18331>
Fri 27 Jun 2003 01:40:13 PM UTC, comment #7: 

can you narrow this down to exactly the smtp chat changes?  i'm not seeing the difference.

Chris Weiss <cw>
Group administrator
Fri 27 Jun 2003 08:10:08 AM UTC, comment #6: 

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: $error\n";
                  }
                  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 )."\r\n";

}
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 \$mymachine\r\n\");",
"\$rrc = \$this->socket2msg(\$socket);",
"\$src = \$this->msg2socket(\$socket,\"MAIL FROM:\$fromuser\r\n\");",
"\$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]."\r\n");
$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,"DATA\r\n"))
{
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]."\r\n"))
{
return false;
}
}
// HEADERS TERMINATION - this CRLF terminates the header, signals the body will follow next (ONE CRLF ONLY)
if (!$this->msg2socket($socket,"\r\n"))
{
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])."\r\n";
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,"\r\n"))
{
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])."\r\n";
// 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,"\r\n"))
{
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 \r\n is probably not necessary
$final_boundary = '--' .$mail_out['boundary'].'--'."\r\n";
if (!$this->msg2socket($socket,$final_boundary))
{
return false;
}
// another blank line
if (!$this->msg2socket($socket,"\r\n"))
{
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,".\r\n"))
{
return false;
}
if (!$this->socket2msg($socket))
{
return false;
}
// QUIT
if (!$this->msg2socket($socket,"QUIT\r\n"))
{
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;*/
}


Anonymous
Fri 27 Jun 2003 02:39:00 AM UTC, comment #5: 

the RFC is pretty specific and mail_send follows it, can you at least outline your modified SMTP chat?

Chris Weiss <cw>
Group administrator
Tue 03 Jun 2003 07:01:48 AM UTC, comment #4: 

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.

Invalid User ID <#18331>
Mon 02 Jun 2003 10:19:44 PM UTC, comment #3: 

and what is the error you receive?

Dave Hall <skwashd>
Group administrator
Mon 02 Jun 2003 02:25:04 PM UTC, comment #2: 

More Informations:
OS = linux Red Hat 6.3
Apache = 1.3.27
Php Version = 4.2.3
Php groupware Version = 0.9.14.000


Invalid User ID <#18331>
Thu 29 May 2003 01:18:54 AM UTC, comment #1: 

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.

Dave Hall <skwashd>
Group administrator
Tue 22 Apr 2003 04:17:30 PM UTC, 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.

Invalid User ID <#18331>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #495:  email_message.php added by None (36KiB - application/octet-stream - The email class I really use to send mail)

 

Depends on the following items: None found

Items that depend on this one: None found

 

CC list is empty

 

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

 

Follow 3 latest changes.

Date Changed by Updated Field Previous Value => Replaced by
2004-04-21 cw Open/ClosedOpen Closed
2004-04-21 cboettger Assigned toangles None
2004-04-21 cboettger Assigned toNone angles

Back to the top

Powered by Savane 3.13-f8d8.
Corresponding source code