]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/class-smtp.php
Wordpress 3.6-scripts
[autoinstalls/wordpress.git] / wp-includes / class-smtp.php
index 6977bffad14745086a1effac05c7ced3806da154..72361bbbbb0b725fc095ffe677c74147137c1009 100644 (file)
@@ -2,7 +2,7 @@
 /*~ class.smtp.php
 .---------------------------------------------------------------------------.
 |  Software: PHPMailer - PHP email class                                    |
-|   Version: 5.2.1                                                          |
+|   Version: 5.2.4                                                          |
 |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
 | ------------------------------------------------------------------------- |
 |     Admin: Jim Jagielski (project admininistrator)                        |
  * @author Jim Jagielski
  * @copyright 2010 - 2012 Jim Jagielski
  * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
- * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $
  */
 
 /**
- * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
- * commands except TURN which will always return a not implemented
- * error. SMTP also provides some utility methods for sending mail
- * to an SMTP server.
- * original author: Chris Ryan
+ * PHP RFC821 SMTP client
+ *
+ * Implements all the RFC 821 SMTP commands except TURN which will always return a not implemented error.
+ * SMTP also provides some utility methods for sending mail to an SMTP server.
+ * @author Chris Ryan
+ * @package PHPMailer
  */
 
 class SMTP {
@@ -51,7 +51,7 @@ class SMTP {
   public $SMTP_PORT = 25;
 
   /**
-   *  SMTP reply line ending
+   *  SMTP reply line ending (don't change)
    *  @var string
    */
   public $CRLF = "\r\n";
@@ -62,30 +62,70 @@ class SMTP {
    */
   public $do_debug;       // the level of debug to perform
 
+  /**
+   * Sets the function/method to use for debugging output.
+   * Right now we only honor "echo" or "error_log"
+   * @var string
+   */
+  public $Debugoutput     = "echo";
+
   /**
    *  Sets VERP use on/off (default is off)
    *  @var bool
    */
   public $do_verp = false;
 
+  /**
+   * Sets the SMTP timeout value for reads, in seconds
+   * @var int
+   */
+  public $Timeout         = 15;
+
+  /**
+   * Sets the SMTP timelimit value for reads, in seconds
+   * @var int
+   */
+  public $Timelimit       = 30;
+
   /**
    * Sets the SMTP PHPMailer Version number
    * @var string
    */
-  public $Version         = '5.2.1';
+  public $Version         = '5.2.4';
 
   /////////////////////////////////////////////////
   // PROPERTIES, PRIVATE AND PROTECTED
   /////////////////////////////////////////////////
 
-  private $smtp_conn; // the socket to the server
-  private $error;     // error if any on the last call
-  private $helo_rply; // the reply the server sent to us for HELO
+  /**
+   * @var resource The socket to the server
+   */
+  private $smtp_conn;
+  /**
+   * @var string Error message, if any, for the last call
+   */
+  private $error;
+  /**
+   * @var string The reply the server sent to us for HELO
+   */
+  private $helo_rply;
+
+  /**
+   * Outputs debugging info via user-defined method
+   * @param string $str
+   */
+  private function edebug($str) {
+    if ($this->Debugoutput == "error_log") {
+        error_log($str);
+    } else {
+        echo $str;
+    }
+  }
 
   /**
    * Initialize the class so that the data is in a known state.
    * @access public
-   * @return void
+   * @return SMTP
    */
   public function __construct() {
     $this->smtp_conn = 0;
@@ -110,6 +150,9 @@ class SMTP {
    * SMTP CODE SUCCESS: 220
    * SMTP CODE FAILURE: 421
    * @access public
+   * @param string $host
+   * @param int $port
+   * @param int $tval
    * @return bool
    */
   public function Connect($host, $port = 0, $tval = 30) {
@@ -139,21 +182,26 @@ class SMTP {
                            "errno" => $errno,
                            "errstr" => $errstr);
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />');
       }
       return false;
     }
 
     // SMTP server can take longer to respond, give longer timeout for first read
     // Windows does not have support for this timeout function
-    if(substr(PHP_OS, 0, 3) != "WIN")
-     socket_set_timeout($this->smtp_conn, $tval, 0);
+    if(substr(PHP_OS, 0, 3) != "WIN") {
+     $max = ini_get('max_execution_time');
+     if ($max != 0 && $tval > $max) { // don't bother if unlimited
+      @set_time_limit($tval);
+     }
+     stream_set_timeout($this->smtp_conn, $tval, 0);
+    }
 
     // get any announcement
     $announce = $this->get_lines();
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />');
     }
 
     return true;
@@ -182,7 +230,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 220) {
@@ -191,7 +239,7 @@ class SMTP {
                "smtp_code" => $code,
                "smtp_msg"  => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -208,60 +256,164 @@ class SMTP {
    * Performs SMTP authentication.  Must be run after running the
    * Hello() method.  Returns true if successfully authenticated.
    * @access public
+   * @param string $username
+   * @param string $password
+   * @param string $authtype
+   * @param string $realm
+   * @param string $workstation
    * @return bool
    */
-  public function Authenticate($username, $password) {
-    // Start authentication
-    fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
-
-    $rply = $this->get_lines();
-    $code = substr($rply,0,3);
-
-    if($code != 334) {
-      $this->error =
-        array("error" => "AUTH not accepted from server",
-              "smtp_code" => $code,
-              "smtp_msg" => substr($rply,4));
-      if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
-      }
-      return false;
-    }
-
-    // Send encoded username
-    fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
-
-    $rply = $this->get_lines();
-    $code = substr($rply,0,3);
-
-    if($code != 334) {
-      $this->error =
-        array("error" => "Username not accepted from server",
-              "smtp_code" => $code,
-              "smtp_msg" => substr($rply,4));
-      if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
-      }
-      return false;
-    }
-
-    // Send encoded password
-    fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
-
-    $rply = $this->get_lines();
-    $code = substr($rply,0,3);
-
-    if($code != 235) {
-      $this->error =
-        array("error" => "Password not accepted from server",
-              "smtp_code" => $code,
-              "smtp_msg" => substr($rply,4));
-      if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
-      }
-      return false;
+  public function Authenticate($username, $password, $authtype='LOGIN', $realm='', $workstation='') {
+    if (empty($authtype)) {
+      $authtype = 'LOGIN';
+    }
+
+    switch ($authtype) {
+      case 'PLAIN':
+        // Start authentication
+        fputs($this->smtp_conn,"AUTH PLAIN" . $this->CRLF);
+    
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+    
+        if($code != 334) {
+          $this->error =
+            array("error" => "AUTH not accepted from server",
+                  "smtp_code" => $code,
+                  "smtp_msg" => substr($rply,4));
+          if($this->do_debug >= 1) {
+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
+          }
+          return false;
+        }
+        // Send encoded username and password
+        fputs($this->smtp_conn, base64_encode("\0".$username."\0".$password) . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+    
+        if($code != 235) {
+          $this->error =
+            array("error" => "Authentication not accepted from server",
+                  "smtp_code" => $code,
+                  "smtp_msg" => substr($rply,4));
+          if($this->do_debug >= 1) {
+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
+          }
+          return false;
+        }
+        break;
+      case 'LOGIN':
+        // Start authentication
+        fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
+    
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+    
+        if($code != 334) {
+          $this->error =
+            array("error" => "AUTH not accepted from server",
+                  "smtp_code" => $code,
+                  "smtp_msg" => substr($rply,4));
+          if($this->do_debug >= 1) {
+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
+          }
+          return false;
+        }
+    
+        // Send encoded username
+        fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
+    
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+    
+        if($code != 334) {
+          $this->error =
+            array("error" => "Username not accepted from server",
+                  "smtp_code" => $code,
+                  "smtp_msg" => substr($rply,4));
+          if($this->do_debug >= 1) {
+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
+          }
+          return false;
+        }
+    
+        // Send encoded password
+        fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
+    
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+    
+        if($code != 235) {
+          $this->error =
+            array("error" => "Password not accepted from server",
+                  "smtp_code" => $code,
+                  "smtp_msg" => substr($rply,4));
+          if($this->do_debug >= 1) {
+            $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
+          }
+          return false;
+        }
+        break;
+      case 'NTLM':
+        /*
+         * ntlm_sasl_client.php
+         ** Bundled with Permission
+         **
+         ** How to telnet in windows: http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
+         ** PROTOCOL Documentation http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
+         */
+        require_once('ntlm_sasl_client.php');
+        $temp = new stdClass();
+        $ntlm_client = new ntlm_sasl_client_class;
+        if(! $ntlm_client->Initialize($temp)){//let's test if every function its available
+            $this->error = array("error" => $temp->error);
+            if($this->do_debug >= 1) {
+                $this->edebug("You need to enable some modules in your php.ini file: " . $this->error["error"] . $this->CRLF);
+            }
+            return false;
+        }
+        $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);//msg1
+        
+        fputs($this->smtp_conn,"AUTH NTLM " . base64_encode($msg1) . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+        
+
+        if($code != 334) {
+            $this->error =
+                array("error" => "AUTH not accepted from server",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
+            }
+            return false;
+        }
+        
+        $challange = substr($rply,3);//though 0 based, there is a white space after the 3 digit number....//msg2
+        $challange = base64_decode($challange);
+        $ntlm_res = $ntlm_client->NTLMResponse(substr($challange,24,8),$password);
+        $msg3 = $ntlm_client->TypeMsg3($ntlm_res,$username,$realm,$workstation);//msg3
+        // Send encoded username
+        fputs($this->smtp_conn, base64_encode($msg3) . $this->CRLF);
+
+        $rply = $this->get_lines();
+        $code = substr($rply,0,3);
+
+        if($code != 235) {
+            $this->error =
+                array("error" => "Could not authenticate",
+                      "smtp_code" => $code,
+                      "smtp_msg" => substr($rply,4));
+            if($this->do_debug >= 1) {
+                $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF);
+            }
+            return false;
+        }
+        break;
     }
-
     return true;
   }
 
@@ -276,7 +428,7 @@ class SMTP {
       if($sock_status["eof"]) {
         // the socket is valid but we are not connected
         if($this->do_debug >= 1) {
-            echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
+            $this->edebug("SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected");
         }
         $this->Close();
         return false;
@@ -324,6 +476,7 @@ class SMTP {
    * SMTP CODE FAILURE: 451,554
    * SMTP CODE ERROR  : 500,501,503,421
    * @access public
+   * @param string $msg_data
    * @return bool
    */
   public function Data($msg_data) {
@@ -341,7 +494,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 354) {
@@ -350,7 +503,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -435,7 +588,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250) {
@@ -444,7 +597,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -461,6 +614,7 @@ class SMTP {
    * SMTP CODE SUCCESS: 250
    * SMTP CODE ERROR  : 500, 501, 504, 421
    * @access public
+   * @param string $host
    * @return bool
    */
   public function Hello($host = '') {
@@ -491,6 +645,8 @@ class SMTP {
   /**
    * Sends a HELO/EHLO command.
    * @access private
+   * @param string $hello
+   * @param string $host
    * @return bool
    */
   private function SendHello($hello, $host) {
@@ -500,7 +656,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250) {
@@ -509,7 +665,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -531,6 +687,7 @@ class SMTP {
    * SMTP CODE SUCCESS: 552,451,452
    * SMTP CODE SUCCESS: 500,501,421
    * @access public
+   * @param string $from
    * @return bool
    */
   public function Mail($from) {
@@ -542,14 +699,14 @@ class SMTP {
       return false;
     }
 
-    $useVerp = ($this->do_verp ? "XVERP" : "");
+    $useVerp = ($this->do_verp ? " XVERP" : "");
     fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
 
     $rply = $this->get_lines();
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250) {
@@ -558,7 +715,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -574,6 +731,7 @@ class SMTP {
    * SMTP CODE SUCCESS: 221
    * SMTP CODE ERROR  : 500
    * @access public
+   * @param bool $close_on_error
    * @return bool
    */
   public function Quit($close_on_error = true) {
@@ -592,7 +750,7 @@ class SMTP {
     $byemsg = $this->get_lines();
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />');
     }
 
     $rval = true;
@@ -606,7 +764,7 @@ class SMTP {
                  "smtp_rply" => substr($byemsg,4));
       $rval = false;
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />');
       }
     }
 
@@ -627,6 +785,7 @@ class SMTP {
    * SMTP CODE FAILURE: 550,551,552,553,450,451,452
    * SMTP CODE ERROR  : 500,501,503,421
    * @access public
+   * @param string $to
    * @return bool
    */
   public function Recipient($to) {
@@ -644,7 +803,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250 && $code != 251) {
@@ -653,7 +812,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -687,7 +846,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250) {
@@ -696,7 +855,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -718,6 +877,7 @@ class SMTP {
    * SMTP CODE SUCCESS: 552,451,452
    * SMTP CODE SUCCESS: 500,501,502,421
    * @access public
+   * @param string $from
    * @return bool
    */
   public function SendAndMail($from) {
@@ -735,7 +895,7 @@ class SMTP {
     $code = substr($rply,0,3);
 
     if($this->do_debug >= 2) {
-      echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />');
     }
 
     if($code != 250) {
@@ -744,7 +904,7 @@ class SMTP {
               "smtp_code" => $code,
               "smtp_msg" => substr($rply,4));
       if($this->do_debug >= 1) {
-        echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />');
       }
       return false;
     }
@@ -768,7 +928,7 @@ class SMTP {
     $this->error = array("error" => "This method, TURN, of the SMTP ".
                                     "is not implemented");
     if($this->do_debug >= 1) {
-      echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
+      $this->edebug("SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />');
     }
     return false;
   }
@@ -797,22 +957,47 @@ class SMTP {
    */
   private function get_lines() {
     $data = "";
-    while(!feof($this->smtp_conn)) {
+    $endtime = 0;
+    /* If for some reason the fp is bad, don't inf loop */
+    if (!is_resource($this->smtp_conn)) {
+      return $data;
+    }
+    stream_set_timeout($this->smtp_conn, $this->Timeout);
+    if ($this->Timelimit > 0) {
+      $endtime = time() + $this->Timelimit;
+    }
+    while(is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
       $str = @fgets($this->smtp_conn,515);
       if($this->do_debug >= 4) {
-        echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
-        echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />');
+        $this->edebug("SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />');
       }
       $data .= $str;
       if($this->do_debug >= 4) {
-        echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
+        $this->edebug("SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />');
       }
       // if 4th character is a space, we are done reading, break the loop
       if(substr($str,3,1) == " ") { break; }
+      // Timed-out? Log and break
+      $info = stream_get_meta_data($this->smtp_conn);
+      if ($info['timed_out']) {
+        if($this->do_debug >= 4) {
+          $this->edebug("SMTP -> get_lines(): timed-out (" . $this->Timeout . " seconds) <br />");
+        }
+        break;
+      }
+      // Now check if reads took too long
+      if ($endtime) {
+        if (time() > $endtime) {
+          if($this->do_debug >= 4) {
+            $this->edebug("SMTP -> get_lines(): timelimit reached (" . $this->Timelimit . " seconds) <br />");
+          }
+          break;
+        }
+      }
     }
     return $data;
   }
 
 }
-
 ?>