Re: Improvement suggestions for mail() delivery

From: Date: Thu, 16 May 2002 15:58:35 +0000
Subject: Re: Improvement suggestions for mail() delivery
References: 1 2 3 4 5 6  Groups: php.qa 
Request: Send a blank email to php-qa+get-5432@lists.php.net to get a copy of this message
Hello, On 05/16/2002 02:40 AM, Markus Fischer wrote:
"verbose error return message" - I just did that for the win32/sendmail implementation (to a certain degree at least). It's still a mess, but testers are welcome. Anyway, I'm not going to do more work on that topic, so every contributor is welcome.
I don't use Windows, so I can't test it. Anyway, if you make the error messages show the actual SMTP status code and status message where it is failing, that is already an improvement. Later we will realize that there needs to be a way to specify authentication credentials (user, password and realm) because more and more people are using services that require authentication.
    Of course. I've already seen requests for it. But I'm not
    familiar with this topic.
It is not hard. I know how to do it in pure PHP. You may want to check this class that does it already for AUTH methods LOGIN and PLAIN. http://www.phpclasses.org/smtpclass Anyway, all you need to do is to switch to ESMTP by doing EHLO instead of HELO. The server should return a multi-line response listing all extensions that it supports. If it supports authentication it should return an extension response named AUTH followed by all the methods of authentication that it supports, like for instance: PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5, NTLM, etc... You don't need to support all types of authentication. Usually supporting AUTH LOGIN will do. It is not as secure as some other methods because it sends passwords just encoded with base64, but usually that is not a big problem because the passwords only go from a Web server machine to the machine that has a SMTP relay server. Here follows the relevant PHP code of my class that handles authentication: $success=0; if($this->VerifyResultLines("220",$responses)>0) { if($this->esmtp || strlen($this->user)) {
    if($this->PutLine("EHLO $localhost")
    && $this->VerifyResultLines("250",$responses)>0)
    {
      $this->esmtp_host=$this->Tokenize($responses[0]," ");
      for($response=1;$response<count($responses);$response++)
      {
        $extension=strtoupper($this->Tokenize($responses[$response]," "));
        $this->esmtp_extensions[$extension]=$this->Tokenize("");
      }
      $success=1;
    }
} if(!$success && strlen($this->user)==0 && $this->PutLine("HELO $localhost") && $this->VerifyResultLines("250",$responses)>0)
    $success=1;
if($success && strlen($this->user)) {
    if(!IsSet($this->esmtp_extensions["AUTH"]))
    {
      $this->error="server does not require authentication";
      $success=0;
    }
    else
    {
for($authentication=$this->Tokenize($this->esmtp_extensions["AUTH"]," ");strlen($authentication);$authentication=$this->Tokenize(" "))
      {
        switch($authentication)
        {
          case "PLAIN":
            $success=($this->PutLine("AUTH PLAIN")
            && $this->VerifyResultLines("334",$responses)
            && $this->PutLine(base64_encode($this->user.chr(0).$this->user."@".$this->realm.chr(0).$this->password))
            && $this->VerifyResultLines("235",$responses));
            break 2;
          case "LOGIN":
            $success=($this->PutLine("AUTH LOGIN")
            && $this->VerifyResultLines("334",$responses)
            && $this->PutLine(base64_encode($this->user.(strlen($this->realm) ? "@".$this->realm : "")))
            && $this->VerifyResultLines("334",$responses)
            && $this->PutLine(base64_encode($this->password))
            && $this->VerifyResultLines("235",$responses));
            break 2;
        }
      }
      if($success
      && strlen($authentication)==0)
      {
        $this->error="the server does not require a supported authentication method";
        $success=0;
      }
    }
} } -- Regards, Manuel Lemos

« previous php.qa (#5432) next »