123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863 |
- <?php
- class SMTP
- {
-
- public $SMTP_PORT = 25;
-
- public $CRLF = "\r\n";
-
- public $do_debug;
-
- public $do_verp = false;
-
-
-
- private $smtp_conn;
- private $error;
- private $helo_rply;
-
- public function __construct()
- {
- $this->smtp_conn = 0;
- $this->error = null;
- $this->helo_rply = null;
- $this->do_debug = false;
- }
-
-
-
-
- public function Connect($host, $port = 0, $tval = 30)
- {
-
- $this->error = null;
-
- if ($this->connected()) {
-
- $this->error = ["error" => "Already connected to a server"];
- return false;
- }
- if (empty($port)) {
- $port = $this->SMTP_PORT;
- }
-
- $this->smtp_conn = @fsockopen($host,
- $port,
- $errno,
- $errstr,
- $tval);
-
- if (empty($this->smtp_conn)) {
- $this->error = ["error" => "Failed to connect to server",
- "errno" => $errno,
- "errstr" => $errstr, ];
- if ($this->do_debug >= 1) {
- echo "SMTP -> ERROR: ".$this->error["error"].": $errstr ($errno)".$this->CRLF.'<br />';
- }
- return false;
- }
-
-
- if (substr(PHP_OS, 0, 3) != "WIN") {
- socket_set_timeout($this->smtp_conn, $tval, 0);
- }
-
- $announce = $this->get_lines();
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$announce.$this->CRLF.'<br />';
- }
- return true;
- }
-
- public function StartTLS()
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = ["error" => "Called StartTLS() without being connected"];
- return false;
- }
- fputs($this->smtp_conn, "STARTTLS".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 220) {
- $this->error =
- ["error" => "STARTTLS 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;
- }
-
- if (!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- return false;
- }
- return true;
- }
-
- public function Authenticate($username, $password)
- {
-
- fputs($this->smtp_conn, "AUTH LOGIN".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($code != 334) {
- $this->error =
- ["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;
- }
-
- fputs($this->smtp_conn, base64_encode($username).$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($code != 334) {
- $this->error =
- ["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;
- }
-
- fputs($this->smtp_conn, base64_encode($password).$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($code != 235) {
- $this->error =
- ["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;
- }
- return true;
- }
-
- public function Connected()
- {
- if (!empty($this->smtp_conn)) {
- $sock_status = socket_get_status($this->smtp_conn);
- if ($sock_status["eof"]) {
-
- if ($this->do_debug >= 1) {
- echo "SMTP -> NOTICE:".$this->CRLF."EOF caught while checking if connected";
- }
- $this->Close();
- return false;
- }
- return true;
- }
- return false;
- }
-
- public function Close()
- {
- $this->error = null;
- $this->helo_rply = null;
- if (!empty($this->smtp_conn)) {
-
- fclose($this->smtp_conn);
- $this->smtp_conn = 0;
- }
- }
-
-
-
-
- public function Data($msg_data)
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Data() without being connected", ];
- return false;
- }
- fputs($this->smtp_conn, "DATA".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 354) {
- $this->error =
- ["error" => "DATA command 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;
- }
-
-
- $msg_data = str_replace("\r\n", "\n", $msg_data);
- $msg_data = str_replace("\r", "\n", $msg_data);
- $lines = explode("\n", $msg_data);
-
- $field = substr($lines[0], 0, strpos($lines[0], ":"));
- $in_headers = false;
- if (!empty($field) && !strstr($field, " ")) {
- $in_headers = true;
- }
- $max_line_length = 998;
- while (list(, $line) = @each($lines)) {
- $lines_out = null;
- if ($line == "" && $in_headers) {
- $in_headers = false;
- }
-
- while (strlen($line) > $max_line_length) {
- $pos = strrpos(substr($line, 0, $max_line_length), " ");
-
- if (!$pos) {
- $pos = $max_line_length - 1;
- $lines_out[] = substr($line, 0, $pos);
- $line = substr($line, $pos);
- } else {
- $lines_out[] = substr($line, 0, $pos);
- $line = substr($line, $pos + 1);
- }
-
- if ($in_headers) {
- $line = "\t".$line;
- }
- }
- $lines_out[] = $line;
-
- while (list(, $line_out) = @each($lines_out)) {
- if (strlen($line_out) > 0) {
- if (substr($line_out, 0, 1) == ".") {
- $line_out = ".".$line_out;
- }
- }
- fputs($this->smtp_conn, $line_out.$this->CRLF);
- }
- }
-
- fputs($this->smtp_conn, $this->CRLF.".".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 250) {
- $this->error =
- ["error" => "DATA 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;
- }
- return true;
- }
-
- public function Hello($host = '')
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Hello() without being connected", ];
- return false;
- }
-
- if (empty($host)) {
-
- $host = "localhost";
- }
-
- if (!$this->SendHello("EHLO", $host)) {
- if (!$this->SendHello("HELO", $host)) {
- return false;
- }
- }
- return true;
- }
-
- public function Mail($from)
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Mail() without being connected", ];
- return false;
- }
- $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 />';
- }
- if ($code != 250) {
- $this->error =
- ["error" => "MAIL 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;
- }
- return true;
- }
-
- public function Quit($close_on_error = true)
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Quit() without being connected", ];
- return false;
- }
-
- fputs($this->smtp_conn, "quit".$this->CRLF);
-
- $byemsg = $this->get_lines();
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$byemsg.$this->CRLF.'<br />';
- }
- $rval = true;
- $e = null;
- $code = substr($byemsg, 0, 3);
- if ($code != 221) {
-
- $e = ["error" => "SMTP server rejected quit command",
- "smtp_code" => $code,
- "smtp_rply" => substr($byemsg, 4), ];
- $rval = false;
- if ($this->do_debug >= 1) {
- echo "SMTP -> ERROR: ".$e["error"].": ".$byemsg.$this->CRLF.'<br />';
- }
- }
- if (empty($e) || $close_on_error) {
- $this->Close();
- }
- return $rval;
- }
-
- public function Recipient($to)
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Recipient() without being connected", ];
- return false;
- }
- fputs($this->smtp_conn, "RCPT TO:<".$to.">".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 250 && $code != 251) {
- $this->error =
- ["error" => "RCPT 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;
- }
- return true;
- }
-
- public function Reset()
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called Reset() without being connected", ];
- return false;
- }
- fputs($this->smtp_conn, "RSET".$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 250) {
- $this->error =
- ["error" => "RSET failed",
- "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;
- }
- return true;
- }
-
- public function SendAndMail($from)
- {
- $this->error = null;
- if (!$this->connected()) {
- $this->error = [
- "error" => "Called SendAndMail() without being connected", ];
- return false;
- }
- fputs($this->smtp_conn, "SAML FROM:".$from.$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:".$rply.$this->CRLF.'<br />';
- }
- if ($code != 250) {
- $this->error =
- ["error" => "SAML 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;
- }
- return true;
- }
-
- public function Turn()
- {
- $this->error = ["error" => "This method, TURN, of the SMTP ".
- "is not implemented", ];
- if ($this->do_debug >= 1) {
- echo "SMTP -> NOTICE: ".$this->error["error"].$this->CRLF.'<br />';
- }
- return false;
- }
-
- public function getError()
- {
- return $this->error;
- }
-
- private function SendHello($hello, $host)
- {
- fputs($this->smtp_conn, $hello." ".$host.$this->CRLF);
- $rply = $this->get_lines();
- $code = substr($rply, 0, 3);
- if ($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER: ".$rply.$this->CRLF.'<br />';
- }
- if ($code != 250) {
- $this->error =
- ["error" => $hello." 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;
- }
- $this->helo_rply = $rply;
- return true;
- }
-
-
-
-
- private function get_lines()
- {
- $data = "";
- while ($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 />';
- }
- $data .= $str;
- if ($this->do_debug >= 4) {
- echo "SMTP -> get_lines(): \$data is \"$data\"".$this->CRLF.'<br />';
- }
-
- if (substr($str, 3, 1) == " ") {
- break;
- }
- }
- return $data;
- }
- }
|