ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
SMTP Class Reference
+ Collaboration diagram for SMTP:

Public Member Functions

 connect ($host, $port=null, $timeout=30, $options=array())
 Connect to an SMTP server. More...
 
 startTLS ()
 Initiate a TLS (encrypted) session. More...
 
 authenticate ( $username, $password, $authtype=null, $realm='', $workstation='', $OAuth=null)
 Perform SMTP authentication. More...
 
 connected ()
 Check connection state. More...
 
 close ()
 Close the socket and clean up the state of the class. More...
 
 data ($msg_data)
 Send an SMTP DATA command. More...
 
 hello ($host='')
 Send an SMTP HELO or EHLO command. More...
 
 mail ($from)
 Send an SMTP MAIL command. More...
 
 quit ($close_on_error=true)
 Send an SMTP QUIT command. More...
 
 recipient ($address)
 Send an SMTP RCPT command. More...
 
 reset ()
 Send an SMTP RSET command. More...
 
 sendAndMail ($from)
 Send an SMTP SAML command. More...
 
 verify ($name)
 Send an SMTP VRFY command. More...
 
 noop ()
 Send an SMTP NOOP command. More...
 
 turn ()
 Send an SMTP TURN command. More...
 
 client_send ($data)
 Send raw data to the server. More...
 
 getError ()
 Get the latest error. More...
 
 getServerExtList ()
 Get SMTP extensions available on the server @access public. More...
 
 getServerExt ($name)
 A multipurpose method The method works in three ways, dependent on argument value and current state. More...
 
 getLastReply ()
 Get the last reply from the server. More...
 
 setVerp ($enabled=false)
 Enable or disable VERP address generation. More...
 
 getVerp ()
 Get VERP address generation mode. More...
 
 setDebugOutput ($method='echo')
 Set debug output method. More...
 
 getDebugOutput ()
 Get debug output method. More...
 
 setDebugLevel ($level=0)
 Set debug output level. More...
 
 getDebugLevel ()
 Get debug output level. More...
 
 setTimeout ($timeout=0)
 Set SMTP timeout. More...
 
 getTimeout ()
 Get SMTP timeout. More...
 
 getLastTransactionID ()
 Will return the ID of the last smtp transaction based on a list of patterns provided in SMTP::$smtp_transaction_id_patterns. More...
 

Data Fields

const VERSION = '5.2.22'
 
const CRLF = "\r\n"
 
const DEFAULT_SMTP_PORT = 25
 
const MAX_LINE_LENGTH = 998
 
const DEBUG_OFF = 0
 Debug level for no output. More...
 
const DEBUG_CLIENT = 1
 Debug level to show client -> server messages. More...
 
const DEBUG_SERVER = 2
 Debug level to show client -> server and server -> client messages. More...
 
const DEBUG_CONNECTION = 3
 Debug level to show connection status, client -> server and server -> client messages. More...
 
const DEBUG_LOWLEVEL = 4
 Debug level to show all messages. More...
 
 $Version = '5.2.22'
 
 $SMTP_PORT = 25
 
 $CRLF = "\r\n"
 
 $do_debug = self::DEBUG_OFF
 
 $Debugoutput = 'echo'
 
 $do_verp = false
 
 $Timeout = 300
 
 $Timelimit = 300
 

Protected Member Functions

 edebug ($str, $level=0)
 Output debugging info via a user-selected method. More...
 
 hmac ($data, $key)
 Calculate an MD5 HMAC hash. More...
 
 sendHello ($hello, $host)
 Send an SMTP HELO or EHLO command. More...
 
 parseHelloFields ($type)
 Parse a reply to HELO/EHLO command to discover server extensions. More...
 
 sendCommand ($command, $commandstring, $expect)
 Send a command to an SMTP server and check its return code. More...
 
 get_lines ()
 Read the SMTP server's response. More...
 
 setError ($message, $detail='', $smtp_code='', $smtp_code_ex='')
 Set error messages and codes. More...
 
 errorHandler ($errno, $errmsg)
 Reports an error number and string. More...
 

Protected Attributes

 $smtp_transaction_id_patterns
 
 $smtp_conn
 
 $error
 
 $helo_rply = null
 
 $server_caps = null
 
 $last_reply = ''
 

Detailed Description

Definition at line 27 of file class.smtp.php.

Member Function Documentation

◆ authenticate()

SMTP::authenticate (   $username,
  $password,
  $authtype = null,
  $realm = '',
  $workstation = '',
  $OAuth = null 
)

Perform SMTP authentication.

Must be run after hello().

See also
hello()
Parameters
string$usernameThe user name
string$passwordThe password
string$authtypeThe auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)
string$realmThe auth realm for NTLM
string$workstationThe auth workstation for NTLM
null | OAuth$OAuthAn optional OAuth instance (
See also
PHPMailerOAuth)
Returns
bool True if successfully authenticated.* @access public

Definition at line 387 of file class.smtp.php.

394 {
395 if (!$this->server_caps) {
396 $this->setError('Authentication is not allowed before HELO/EHLO');
397 return false;
398 }
399
400 if (array_key_exists('EHLO', $this->server_caps)) {
401 // SMTP extensions are available. Let's try to find a proper authentication method
402
403 if (!array_key_exists('AUTH', $this->server_caps)) {
404 $this->setError('Authentication is not allowed at this stage');
405 // 'at this stage' means that auth may be allowed after the stage changes
406 // e.g. after STARTTLS
407 return false;
408 }
409
410 self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
412 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),
413 self::DEBUG_LOWLEVEL
414 );
415
416 if (empty($authtype)) {
417 foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {
418 if (in_array($method, $this->server_caps['AUTH'])) {
419 $authtype = $method;
420 break;
421 }
422 }
423 if (empty($authtype)) {
424 $this->setError('No supported authentication methods found');
425 return false;
426 }
427 self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL);
428 }
429
430 if (!in_array($authtype, $this->server_caps['AUTH'])) {
431 $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
432 return false;
433 }
434 } elseif (empty($authtype)) {
435 $authtype = 'LOGIN';
436 }
437 switch ($authtype) {
438 case 'PLAIN':
439 // Start authentication
440 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
441 return false;
442 }
443 // Send encoded username and password
444 if (!$this->sendCommand(
445 'User & Password',
446 base64_encode("\0" . $username . "\0" . $password),
447 235
448 )
449 ) {
450 return false;
451 }
452 break;
453 case 'LOGIN':
454 // Start authentication
455 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
456 return false;
457 }
458 if (!$this->sendCommand("Username", base64_encode($username), 334)) {
459 return false;
460 }
461 if (!$this->sendCommand("Password", base64_encode($password), 235)) {
462 return false;
463 }
464 break;
465 case 'XOAUTH2':
466 //If the OAuth Instance is not set. Can be a case when PHPMailer is used
467 //instead of PHPMailerOAuth
468 if (is_null($OAuth)) {
469 return false;
470 }
471 $oauth = $OAuth->getOauth64();
472
473 // Start authentication
474 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
475 return false;
476 }
477 break;
478 case 'NTLM':
479 /*
480 * ntlm_sasl_client.php
481 * Bundled with Permission
482 *
483 * How to telnet in windows:
484 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx
485 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication
486 */
487 require_once 'extras/ntlm_sasl_client.php';
488 $temp = new stdClass;
489 $ntlm_client = new ntlm_sasl_client_class;
490 //Check that functions are available
491 if (!$ntlm_client->initialize($temp)) {
492 $this->setError($temp->error);
493 $this->edebug(
494 'You need to enable some modules in your php.ini file: '
495 . $this->error['error'],
496 self::DEBUG_CLIENT
497 );
498 return false;
499 }
500 //msg1
501 $msg1 = $ntlm_client->typeMsg1($realm, $workstation); //msg1
502
503 if (!$this->sendCommand(
504 'AUTH NTLM',
505 'AUTH NTLM ' . base64_encode($msg1),
506 334
507 )
508 ) {
509 return false;
510 }
511 //Though 0 based, there is a white space after the 3 digit number
512 //msg2
513 $challenge = substr($this->last_reply, 3);
514 $challenge = base64_decode($challenge);
515 $ntlm_res = $ntlm_client->NTLMResponse(
516 substr($challenge, 24, 8),
517 $password
518 );
519 //msg3
520 $msg3 = $ntlm_client->typeMsg3(
521 $ntlm_res,
522 $username,
523 $realm,
524 $workstation
525 );
526 // send encoded username
527 return $this->sendCommand('Username', base64_encode($msg3), 235);
528 case 'CRAM-MD5':
529 // Start authentication
530 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
531 return false;
532 }
533 // Get the challenge
534 $challenge = base64_decode(substr($this->last_reply, 4));
535
536 // Build the response
537 $response = $username . ' ' . $this->hmac($challenge, $password);
538
539 // send encoded credentials
540 return $this->sendCommand('Username', base64_encode($response), 235);
541 default:
542 $this->setError("Authentication method \"$authtype\" is not supported");
543 return false;
544 }
545 return true;
546 }
setError($message, $detail='', $smtp_code='', $smtp_code_ex='')
Set error messages and codes.
hmac($data, $key)
Calculate an MD5 HMAC hash.
Definition: class.smtp.php:557
sendCommand($command, $commandstring, $expect)
Send a command to an SMTP server and check its return code.
Definition: class.smtp.php:875
edebug($str, $level=0)
Output debugging info via a user-selected method.
Definition: class.smtp.php:213
error($a_errmsg)
set error message @access public

References edebug(), error(), hmac(), sendCommand(), and setError().

+ Here is the call graph for this function:

◆ client_send()

SMTP::client_send (   $data)

Send raw data to the server.

Parameters
string$dataThe data to send @access public
Returns
integer|boolean The number of bytes sent to the server or false on error

Definition at line 989 of file class.smtp.php.

990 {
991 $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
992 return fwrite($this->smtp_conn, $data);
993 }
$data

References $data, and edebug().

Referenced by data(), and sendCommand().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ close()

SMTP::close ( )

Close the socket and clean up the state of the class.

Don't use this function without first trying to use QUIT.

See also
quit() @access User interface
Returns
void

Definition at line 614 of file class.smtp.php.

615 {
616 $this->setError('');
617 $this->server_caps = null;
618 $this->helo_rply = null;
619 if (is_resource($this->smtp_conn)) {
620 // close the connection and cleanup
621 fclose($this->smtp_conn);
622 $this->smtp_conn = null; //Makes for cleaner serialization
623 $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
624 }
625 }

References edebug(), and setError().

Referenced by connected(), and quit().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ connect()

SMTP::connect (   $host,
  $port = null,
  $timeout = 30,
  $options = array() 
)

Connect to an SMTP server.

Parameters
string$hostSMTP server IP or host name
integer$portThe port number to connect to
integer$timeoutHow long to wait for the connection to open
array$optionsAn array of options for stream_context_create() @access public
Returns
boolean

Definition at line 258 of file class.smtp.php.

259 {
260 static $streamok;
261 //This is enabled by default since 5.0.0 but some providers disable it
262 //Check this once and cache the result
263 if (is_null($streamok)) {
264 $streamok = function_exists('stream_socket_client');
265 }
266 // Clear errors to avoid confusion
267 $this->setError('');
268 // Make sure we are __not__ connected
269 if ($this->connected()) {
270 // Already connected, generate error
271 $this->setError('Already connected to a server');
272 return false;
273 }
274 if (empty($port)) {
276 }
277 // Connect to the SMTP server
278 $this->edebug(
279 "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true),
280 self::DEBUG_CONNECTION
281 );
282 $errno = 0;
283 $errstr = '';
284 if ($streamok) {
285 $socket_context = stream_context_create($options);
286 set_error_handler(array($this, 'errorHandler'));
287 $this->smtp_conn = stream_socket_client(
288 $host . ":" . $port,
289 $errno,
290 $errstr,
291 $timeout,
292 STREAM_CLIENT_CONNECT,
293 $socket_context
294 );
295 restore_error_handler();
296 } else {
297 //Fall back to fsockopen which should work in more places, but is missing some features
298 $this->edebug(
299 "Connection: stream_socket_client not available, falling back to fsockopen",
300 self::DEBUG_CONNECTION
301 );
302 set_error_handler(array($this, 'errorHandler'));
303 $this->smtp_conn = fsockopen(
304 $host,
305 $port,
306 $errno,
307 $errstr,
308 $timeout
309 );
310 restore_error_handler();
311 }
312 // Verify we connected properly
313 if (!is_resource($this->smtp_conn)) {
314 $this->setError(
315 'Failed to connect to server',
316 $errno,
317 $errstr
318 );
319 $this->edebug(
320 'SMTP ERROR: ' . $this->error['error']
321 . ": $errstr ($errno)",
322 self::DEBUG_CLIENT
323 );
324 return false;
325 }
326 $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
327 // SMTP server can take longer to respond, give longer timeout for first read
328 // Windows does not have support for this timeout function
329 if (substr(PHP_OS, 0, 3) != 'WIN') {
330 $max = ini_get('max_execution_time');
331 // Don't bother if unlimited
332 if ($max != 0 && $timeout > $max) {
333 @set_time_limit($timeout);
334 }
335 stream_set_timeout($this->smtp_conn, $timeout, 0);
336 }
337 // Get any announcement
338 $announce = $this->get_lines();
339 $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
340 return true;
341 }
connected()
Check connection state.
Definition: class.smtp.php:589
const DEFAULT_SMTP_PORT
Definition: class.smtp.php:45
get_lines()
Read the SMTP server's response.
if(!is_array($argv)) $options

References $options, connected(), DEFAULT_SMTP_PORT, edebug(), error(), get_lines(), and setError().

+ Here is the call graph for this function:

◆ connected()

SMTP::connected ( )

Check connection state.

@access public

Returns
boolean True if connected.

Definition at line 589 of file class.smtp.php.

590 {
591 if (is_resource($this->smtp_conn)) {
592 $sock_status = stream_get_meta_data($this->smtp_conn);
593 if ($sock_status['eof']) {
594 // The socket is valid but we are not connected
595 $this->edebug(
596 'SMTP NOTICE: EOF caught while checking if connected',
597 self::DEBUG_CLIENT
598 );
599 $this->close();
600 return false;
601 }
602 return true; // everything looks good
603 }
604 return false;
605 }
close()
Close the socket and clean up the state of the class.
Definition: class.smtp.php:614

References close(), and edebug().

Referenced by connect(), and sendCommand().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ data()

SMTP::data (   $msg_data)

Send an SMTP DATA command.

Issues a data command and sends the msg_data to the server, finializing the mail transaction. $msg_data is the message that is to be send with the headers. Each header needs to be on a single line followed by a <CRLF> with the message headers and the message body being separated by and additional <CRLF>. Implements rfc 821: DATA <CRLF>

Parameters
string$msg_dataMessage data to send @access public
Returns
boolean

Definition at line 639 of file class.smtp.php.

640 {
641 //This will use the standard timelimit
642 if (!$this->sendCommand('DATA', 'DATA', 354)) {
643 return false;
644 }
645
646 /* The server is ready to accept data!
647 * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)
648 * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into
649 * smaller lines to fit within the limit.
650 * We will also look for lines that start with a '.' and prepend an additional '.'.
651 * NOTE: this does not count towards line-length limit.
652 */
653
654 // Normalize line breaks before exploding
655 $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
656
657 /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
658 * of the first line (':' separated) does not contain a space then it _should_ be a header and we will
659 * process all lines before a blank line as headers.
660 */
661
662 $field = substr($lines[0], 0, strpos($lines[0], ':'));
663 $in_headers = false;
664 if (!empty($field) && strpos($field, ' ') === false) {
665 $in_headers = true;
666 }
667
668 foreach ($lines as $line) {
669 $lines_out = array();
670 if ($in_headers and $line == '') {
671 $in_headers = false;
672 }
673 //Break this line up into several smaller lines if it's too long
674 //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len),
675 while (isset($line[self::MAX_LINE_LENGTH])) {
676 //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on
677 //so as to avoid breaking in the middle of a word
678 $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
679 //Deliberately matches both false and 0
680 if (!$pos) {
681 //No nice break found, add a hard break
682 $pos = self::MAX_LINE_LENGTH - 1;
683 $lines_out[] = substr($line, 0, $pos);
684 $line = substr($line, $pos);
685 } else {
686 //Break at the found point
687 $lines_out[] = substr($line, 0, $pos);
688 //Move along by the amount we dealt with
689 $line = substr($line, $pos + 1);
690 }
691 //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1
692 if ($in_headers) {
693 $line = "\t" . $line;
694 }
695 }
696 $lines_out[] = $line;
697
698 //Send the lines to the server
699 foreach ($lines_out as $line_out) {
700 //RFC2821 section 4.5.2
701 if (!empty($line_out) and $line_out[0] == '.') {
702 $line_out = '.' . $line_out;
703 }
704 $this->client_send($line_out . self::CRLF);
705 }
706 }
707
708 //Message data has been sent, complete the command
709 //Increase timelimit for end of DATA command
710 $savetimelimit = $this->Timelimit;
711 $this->Timelimit = $this->Timelimit * 2;
712 $result = $this->sendCommand('DATA END', '.', 250);
713 //Restore timelimit
714 $this->Timelimit = $savetimelimit;
715 return $result;
716 }
$result
client_send($data)
Send raw data to the server.
Definition: class.smtp.php:989
$Timelimit
Definition: class.smtp.php:151

References $result, $Timelimit, client_send(), and sendCommand().

+ Here is the call graph for this function:

◆ edebug()

SMTP::edebug (   $str,
  $level = 0 
)
protected

Output debugging info via a user-selected method.

See also
SMTP::$Debugoutput
SMTP::$do_debug
Parameters
string$strDebug string to output
integer$levelThe debug level of this message; see DEBUG_* constants
Returns
void

Definition at line 213 of file class.smtp.php.

214 {
215 if ($level > $this->do_debug) {
216 return;
217 }
218 //Avoid clash with built-in function names
219 if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
220 call_user_func($this->Debugoutput, $str, $level);
221 return;
222 }
223 switch ($this->Debugoutput) {
224 case 'error_log':
225 //Don't output, just log
226 error_log($str);
227 break;
228 case 'html':
229 //Cleans up output a bit for a better looking, HTML-safe output
230 echo htmlentities(
231 preg_replace('/[\r\n]+/', '', $str),
232 ENT_QUOTES,
233 'UTF-8'
234 )
235 . "<br>\n";
236 break;
237 case 'echo':
238 default:
239 //Normalize line breaks
240 $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
241 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
242 "\n",
243 "\n \t ",
244 trim($str)
245 )."\n";
246 }
247 }

References Monolog\Handler\error_log().

Referenced by authenticate(), client_send(), close(), connect(), connected(), errorHandler(), get_lines(), sendCommand(), and turn().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ errorHandler()

SMTP::errorHandler (   $errno,
  $errmsg 
)
protected

Reports an error number and string.

Parameters
integer$errnoThe error number returned by PHP.
string$errmsgThe error message returned by PHP.

Definition at line 1212 of file class.smtp.php.

1213 {
1214 $notice = 'Connection: Failed to connect to server.';
1215 $this->setError(
1216 $notice,
1217 $errno,
1218 $errmsg
1219 );
1220 $this->edebug(
1221 $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg,
1222 self::DEBUG_CONNECTION
1223 );
1224 }

References edebug(), and setError().

+ Here is the call graph for this function:

◆ get_lines()

SMTP::get_lines ( )
protected

Read the SMTP server's response.

Either before eof or socket timeout occurs on the operation. With SMTP we can tell if we have more lines to read if the 4th character is '-' symbol. If it is a space then we don't need to read anything else. @access protected

Returns
string

Definition at line 1075 of file class.smtp.php.

1076 {
1077 // If the connection is bad, give up straight away
1078 if (!is_resource($this->smtp_conn)) {
1079 return '';
1080 }
1081 $data = '';
1082 $endtime = 0;
1083 stream_set_timeout($this->smtp_conn, $this->Timeout);
1084 if ($this->Timelimit > 0) {
1085 $endtime = time() + $this->Timelimit;
1086 }
1087 while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
1088 $str = @fgets($this->smtp_conn, 515);
1089 $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
1090 $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
1091 $data .= $str;
1092 // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
1093 if ((isset($str[3]) and $str[3] == ' ')) {
1094 break;
1095 }
1096 // Timed-out? Log and break
1097 $info = stream_get_meta_data($this->smtp_conn);
1098 if ($info['timed_out']) {
1099 $this->edebug(
1100 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',
1101 self::DEBUG_LOWLEVEL
1102 );
1103 break;
1104 }
1105 // Now check if reads took too long
1106 if ($endtime and time() > $endtime) {
1107 $this->edebug(
1108 'SMTP -> get_lines(): timelimit reached ('.
1109 $this->Timelimit . ' sec)',
1110 self::DEBUG_LOWLEVEL
1111 );
1112 break;
1113 }
1114 }
1115 return $data;
1116 }
$info
Definition: example_052.php:80

References $data, $info, $Timelimit, and edebug().

Referenced by connect(), and sendCommand().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDebugLevel()

SMTP::getDebugLevel ( )

Get debug output level.

Returns
integer

Definition at line 1184 of file class.smtp.php.

1185 {
1186 return $this->do_debug;
1187 }

References $do_debug.

◆ getDebugOutput()

SMTP::getDebugOutput ( )

Get debug output method.

Returns
string

Definition at line 1166 of file class.smtp.php.

1167 {
1168 return $this->Debugoutput;
1169 }
$Debugoutput
Definition: class.smtp.php:127

References $Debugoutput.

◆ getError()

SMTP::getError ( )

Get the latest error.

@access public

Returns
array

Definition at line 1000 of file class.smtp.php.

1001 {
1002 return $this->error;
1003 }

References $error.

◆ getLastReply()

SMTP::getLastReply ( )

Get the last reply from the server.

@access public

Returns
string

Definition at line 1061 of file class.smtp.php.

1062 {
1063 return $this->last_reply;
1064 }
$last_reply
Definition: class.smtp.php:203

References $last_reply.

Referenced by getLastTransactionID().

+ Here is the caller graph for this function:

◆ getLastTransactionID()

SMTP::getLastTransactionID ( )

Will return the ID of the last smtp transaction based on a list of patterns provided in SMTP::$smtp_transaction_id_patterns.

If no reply has been received yet, it will return null. If no pattern has been matched, it will return false.

Returns
bool|null|string

Definition at line 1233 of file class.smtp.php.

1234 {
1235 $reply = $this->getLastReply();
1236
1237 if (empty($reply)) {
1238 return null;
1239 }
1240
1241 foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
1242 if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
1243 return $matches[1];
1244 }
1245 }
1246
1247 return false;
1248 }
getLastReply()
Get the last reply from the server.

References getLastReply().

+ Here is the call graph for this function:

◆ getServerExt()

SMTP::getServerExt (   $name)

A multipurpose method The method works in three ways, dependent on argument value and current state.

  1. HELO/EHLO was not sent - returns null and set up $this->error
  2. HELO was sent $name = 'HELO': returns server name $name = 'EHLO': returns boolean false $name = any string: returns null and set up $this->error
  3. EHLO was sent $name = 'HELO'|'EHLO': returns server name $name = any string: if extension $name exists, returns boolean True or its options. Otherwise returns boolean False In other words, one can use this method to detect 3 conditions:

null returned: handshake was not or we don't know about ext (refer to $this->error)

  • false returned: the requested feature exactly not exists
  • positive value returned: the requested feature exists
    Parameters
    string$nameName of SMTP extension or 'HELO'|'EHLO'
    Returns
    mixed

Definition at line 1034 of file class.smtp.php.

1035 {
1036 if (!$this->server_caps) {
1037 $this->setError('No HELO/EHLO was sent');
1038 return null;
1039 }
1040
1041 // the tight logic knot ;)
1042 if (!array_key_exists($name, $this->server_caps)) {
1043 if ($name == 'HELO') {
1044 return $this->server_caps['EHLO'];
1045 }
1046 if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
1047 return false;
1048 }
1049 $this->setError('HELO handshake was used. Client knows nothing about server extensions');
1050 return null;
1051 }
1052
1053 return $this->server_caps[$name];
1054 }

References setError().

+ Here is the call graph for this function:

◆ getServerExtList()

SMTP::getServerExtList ( )

Get SMTP extensions available on the server @access public.

Returns
array|null

Definition at line 1010 of file class.smtp.php.

1011 {
1012 return $this->server_caps;
1013 }
$server_caps
Definition: class.smtp.php:197

References $server_caps.

◆ getTimeout()

SMTP::getTimeout ( )

Get SMTP timeout.

Returns
integer

Definition at line 1202 of file class.smtp.php.

1203 {
1204 return $this->Timeout;
1205 }

References $Timeout.

◆ getVerp()

SMTP::getVerp ( )

Get VERP address generation mode.

Returns
boolean

Definition at line 1131 of file class.smtp.php.

1132 {
1133 return $this->do_verp;
1134 }

References $do_verp.

◆ hello()

SMTP::hello (   $host = '')

Send an SMTP HELO or EHLO command.

Used to identify the sending server to the receiving server. This makes sure that client and server are in a known state. Implements RFC 821: HELO <SP> <domain> <CRLF> and RFC 2821 EHLO.

Parameters
string$hostThe host name or IP to connect to @access public
Returns
boolean

Definition at line 728 of file class.smtp.php.

729 {
730 //Try extended hello first (RFC 2821)
731 return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
732 }
sendHello($hello, $host)
Send an SMTP HELO or EHLO command.
Definition: class.smtp.php:743

References sendHello().

+ Here is the call graph for this function:

◆ hmac()

SMTP::hmac (   $data,
  $key 
)
protected

Calculate an MD5 HMAC hash.

Works like hash_hmac('md5', $data, $key) in case that function is not available

Parameters
string$dataThe data to hash
string$keyThe key to hash with @access protected
Returns
string

Definition at line 557 of file class.smtp.php.

558 {
559 if (function_exists('hash_hmac')) {
560 return hash_hmac('md5', $data, $key);
561 }
562
563 // The following borrowed from
564 // http://php.net/manual/en/function.mhash.php#27225
565
566 // RFC 2104 HMAC implementation for php.
567 // Creates an md5 HMAC.
568 // Eliminates the need to install mhash to compute a HMAC
569 // by Lance Rushing
570
571 $bytelen = 64; // byte length for md5
572 if (strlen($key) > $bytelen) {
573 $key = pack('H*', md5($key));
574 }
575 $key = str_pad($key, $bytelen, chr(0x00));
576 $ipad = str_pad('', $bytelen, chr(0x36));
577 $opad = str_pad('', $bytelen, chr(0x5c));
578 $k_ipad = $key ^ $ipad;
579 $k_opad = $key ^ $opad;
580
581 return md5($k_opad . pack('H*', md5($k_ipad . $data)));
582 }

References $data.

Referenced by authenticate().

+ Here is the caller graph for this function:

◆ mail()

SMTP::mail (   $from)

Send an SMTP MAIL command.

Starts a mail transaction from the email address specified in $from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more recipient commands may be called followed by a data command. Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>

Parameters
string$fromSource address of this message @access public
Returns
boolean

Definition at line 808 of file class.smtp.php.

809 {
810 $useVerp = ($this->do_verp ? ' XVERP' : '');
811 return $this->sendCommand(
812 'MAIL FROM',
813 'MAIL FROM:<' . $from . '>' . $useVerp,
814 250
815 );
816 }

References sendCommand().

+ Here is the call graph for this function:

◆ noop()

SMTP::noop ( )

Send an SMTP NOOP command.

Used to keep keep-alives alive, doesn't actually do anything @access public

Returns
boolean

Definition at line 962 of file class.smtp.php.

963 {
964 return $this->sendCommand('NOOP', 'NOOP', 250);
965 }

References sendCommand().

+ Here is the call graph for this function:

◆ parseHelloFields()

SMTP::parseHelloFields (   $type)
protected

Parse a reply to HELO/EHLO command to discover server extensions.

In case of HELO, the only parameter that can be discovered is a server name. @access protected

Parameters
string$type- 'HELO' or 'EHLO'

Definition at line 761 of file class.smtp.php.

762 {
763 $this->server_caps = array();
764 $lines = explode("\n", $this->helo_rply);
765
766 foreach ($lines as $n => $s) {
767 //First 4 chars contain response code followed by - or space
768 $s = trim(substr($s, 4));
769 if (empty($s)) {
770 continue;
771 }
772 $fields = explode(' ', $s);
773 if (!empty($fields)) {
774 if (!$n) {
775 $name = $type;
776 $fields = $fields[0];
777 } else {
778 $name = array_shift($fields);
779 switch ($name) {
780 case 'SIZE':
781 $fields = ($fields ? $fields[0] : 0);
782 break;
783 case 'AUTH':
784 if (!is_array($fields)) {
785 $fields = array();
786 }
787 break;
788 default:
789 $fields = true;
790 }
791 }
792 $this->server_caps[$name] = $fields;
793 }
794 }
795 }
$n
Definition: RandomTest.php:80

References $n.

Referenced by sendHello().

+ Here is the caller graph for this function:

◆ quit()

SMTP::quit (   $close_on_error = true)

Send an SMTP QUIT command.

Closes the socket if there is no error or the $close_on_error argument is true. Implements from rfc 821: QUIT <CRLF>

Parameters
boolean$close_on_errorShould the connection close if an error occurs? @access public
Returns
boolean

Definition at line 826 of file class.smtp.php.

827 {
828 $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
829 $err = $this->error; //Save any error
830 if ($noerror or $close_on_error) {
831 $this->close();
832 $this->error = $err; //Restore any error from the quit command
833 }
834 return $noerror;
835 }

References $error, close(), error(), and sendCommand().

+ Here is the call graph for this function:

◆ recipient()

SMTP::recipient (   $address)

Send an SMTP RCPT command.

Sets the TO argument to $toaddr. Returns true if the recipient was accepted false if it was rejected. Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>

Parameters
string$addressThe address the message is being sent to @access public
Returns
boolean

Definition at line 846 of file class.smtp.php.

847 {
848 return $this->sendCommand(
849 'RCPT TO',
850 'RCPT TO:<' . $address . '>',
851 array(250, 251)
852 );
853 }

References sendCommand().

+ Here is the call graph for this function:

◆ reset()

SMTP::reset ( )

Send an SMTP RSET command.

Abort any transaction that is currently in progress. Implements rfc 821: RSET <CRLF> @access public

Returns
boolean True on success.

Definition at line 862 of file class.smtp.php.

863 {
864 return $this->sendCommand('RSET', 'RSET', 250);
865 }

References sendCommand().

+ Here is the call graph for this function:

◆ sendAndMail()

SMTP::sendAndMail (   $from)

Send an SMTP SAML command.

Starts a mail transaction from the email address specified in $from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more recipient commands may be called followed by a data command. This command will send the message to the users terminal if they are logged in and send them an email. Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>

Parameters
string$fromThe address the message is from @access public
Returns
boolean

Definition at line 940 of file class.smtp.php.

941 {
942 return $this->sendCommand('SAML', "SAML FROM:$from", 250);
943 }

References sendCommand().

+ Here is the call graph for this function:

◆ sendCommand()

SMTP::sendCommand (   $command,
  $commandstring,
  $expect 
)
protected

Send a command to an SMTP server and check its return code.

Parameters
string$commandThe command name - not sent to the server
string$commandstringThe actual command to send
integer | array$expectOne or more expected integer success codes @access protected
Returns
boolean True on success.

Definition at line 875 of file class.smtp.php.

876 {
877 if (!$this->connected()) {
878 $this->setError("Called $command without being connected");
879 return false;
880 }
881 //Reject line breaks in all commands
882 if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
883 $this->setError("Command '$command' contained line breaks");
884 return false;
885 }
886 $this->client_send($commandstring . self::CRLF);
887
888 $this->last_reply = $this->get_lines();
889 // Fetch SMTP code and possible error code explanation
890 $matches = array();
891 if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
892 $code = $matches[1];
893 $code_ex = (count($matches) > 2 ? $matches[2] : null);
894 // Cut off error code from each response line
895 $detail = preg_replace(
896 "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m",
897 '',
898 $this->last_reply
899 );
900 } else {
901 // Fall back to simple parsing if regex fails
902 $code = substr($this->last_reply, 0, 3);
903 $code_ex = null;
904 $detail = substr($this->last_reply, 4);
905 }
906
907 $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
908
909 if (!in_array($code, (array)$expect)) {
910 $this->setError(
911 "$command command failed",
912 $detail,
913 $code,
914 $code_ex
915 );
916 $this->edebug(
917 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,
918 self::DEBUG_CLIENT
919 );
920 return false;
921 }
922
923 $this->setError('');
924 return true;
925 }
$code
Definition: example_050.php:99

References $code, client_send(), connected(), edebug(), error(), get_lines(), and setError().

Referenced by authenticate(), data(), mail(), noop(), quit(), recipient(), reset(), sendAndMail(), sendHello(), startTLS(), and verify().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sendHello()

SMTP::sendHello (   $hello,
  $host 
)
protected

Send an SMTP HELO or EHLO command.

Low-level implementation used by hello()

See also
hello()
Parameters
string$helloThe HELO string
string$hostThe hostname to say we are @access protected
Returns
boolean

Definition at line 743 of file class.smtp.php.

744 {
745 $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
746 $this->helo_rply = $this->last_reply;
747 if ($noerror) {
748 $this->parseHelloFields($hello);
749 } else {
750 $this->server_caps = null;
751 }
752 return $noerror;
753 }
parseHelloFields($type)
Parse a reply to HELO/EHLO command to discover server extensions.
Definition: class.smtp.php:761

References $last_reply, parseHelloFields(), and sendCommand().

Referenced by hello().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setDebugLevel()

SMTP::setDebugLevel (   $level = 0)

Set debug output level.

Parameters
integer$level

Definition at line 1175 of file class.smtp.php.

1176 {
1177 $this->do_debug = $level;
1178 }

◆ setDebugOutput()

SMTP::setDebugOutput (   $method = 'echo')

Set debug output method.

Parameters
string | callable$methodThe name of the mechanism to use for debugging output, or a callable to handle it.

Definition at line 1157 of file class.smtp.php.

1158 {
1159 $this->Debugoutput = $method;
1160 }

◆ setError()

SMTP::setError (   $message,
  $detail = '',
  $smtp_code = '',
  $smtp_code_ex = '' 
)
protected

Set error messages and codes.

Parameters
string$messageThe error message
string$detailFurther detail on the error
string$smtp_codeAn associated SMTP error code
string$smtp_code_exExtended SMTP code

Definition at line 1143 of file class.smtp.php.

1144 {
1145 $this->error = array(
1146 'error' => $message,
1147 'detail' => $detail,
1148 'smtp_code' => $smtp_code,
1149 'smtp_code_ex' => $smtp_code_ex
1150 );
1151 }

References error().

Referenced by authenticate(), close(), connect(), errorHandler(), getServerExt(), sendCommand(), and turn().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setTimeout()

SMTP::setTimeout (   $timeout = 0)

Set SMTP timeout.

Parameters
integer$timeout

Definition at line 1193 of file class.smtp.php.

1194 {
1195 $this->Timeout = $timeout;
1196 }

◆ setVerp()

SMTP::setVerp (   $enabled = false)

Enable or disable VERP address generation.

Parameters
boolean$enabled

Definition at line 1122 of file class.smtp.php.

1123 {
1124 $this->do_verp = $enabled;
1125 }

◆ startTLS()

SMTP::startTLS ( )

Initiate a TLS (encrypted) session.

@access public

Returns
boolean

Definition at line 348 of file class.smtp.php.

349 {
350 if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
351 return false;
352 }
353
354 //Allow the best TLS version(s) we can
355 $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
356
357 //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
358 //so add them back in manually if we can
359 if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
360 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
361 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
362 }
363
364 // Begin encrypted connection
365 if (!stream_socket_enable_crypto(
366 $this->smtp_conn,
367 true,
368 $crypto_method
369 )) {
370 return false;
371 }
372 return true;
373 }

References sendCommand().

+ Here is the call graph for this function:

◆ turn()

SMTP::turn ( )

Send an SMTP TURN command.

This is an optional command for SMTP that this class does not support. This method is here to make the RFC821 Definition complete for this class and may be implemented in future Implements from rfc 821: TURN <CRLF> @access public

Returns
boolean

Definition at line 976 of file class.smtp.php.

977 {
978 $this->setError('The SMTP TURN command is not implemented');
979 $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
980 return false;
981 }

References edebug(), error(), and setError().

+ Here is the call graph for this function:

◆ verify()

SMTP::verify (   $name)

Send an SMTP VRFY command.

Parameters
string$nameThe name to verify @access public
Returns
boolean

Definition at line 951 of file class.smtp.php.

952 {
953 return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
954 }

References sendCommand().

+ Here is the call graph for this function:

Field Documentation

◆ $CRLF

SMTP::$CRLF = "\r\n"

Definition at line 100 of file class.smtp.php.

◆ $Debugoutput

SMTP::$Debugoutput = 'echo'

Definition at line 127 of file class.smtp.php.

Referenced by getDebugOutput().

◆ $do_debug

SMTP::$do_debug = self::DEBUG_OFF

Definition at line 112 of file class.smtp.php.

Referenced by getDebugLevel().

◆ $do_verp

SMTP::$do_verp = false

Definition at line 135 of file class.smtp.php.

Referenced by getVerp().

◆ $error

SMTP::$error
protected
Initial value:
= array(
'error' => '',
'detail' => '',
'smtp_code' => '',
'smtp_code_ex' => ''
)

Definition at line 174 of file class.smtp.php.

Referenced by getError(), and quit().

◆ $helo_rply

SMTP::$helo_rply = null
protected

Definition at line 186 of file class.smtp.php.

◆ $last_reply

SMTP::$last_reply = ''
protected

Definition at line 203 of file class.smtp.php.

Referenced by getLastReply(), and sendHello().

◆ $server_caps

SMTP::$server_caps = null
protected

Definition at line 197 of file class.smtp.php.

Referenced by getServerExtList().

◆ $smtp_conn

SMTP::$smtp_conn
protected

Definition at line 168 of file class.smtp.php.

◆ $SMTP_PORT

SMTP::$SMTP_PORT = 25

Definition at line 92 of file class.smtp.php.

◆ $smtp_transaction_id_patterns

SMTP::$smtp_transaction_id_patterns
protected
Initial value:
= array(
'exim' => '/[0-9]{3} OK id=(.*)/',
'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
)

Definition at line 158 of file class.smtp.php.

◆ $Timelimit

SMTP::$Timelimit = 300

Definition at line 151 of file class.smtp.php.

Referenced by data(), and get_lines().

◆ $Timeout

SMTP::$Timeout = 300

Definition at line 144 of file class.smtp.php.

Referenced by getTimeout().

◆ $Version

SMTP::$Version = '5.2.22'

Definition at line 84 of file class.smtp.php.

◆ CRLF

const SMTP::CRLF = "\r\n"

Definition at line 39 of file class.smtp.php.

◆ DEBUG_CLIENT

const SMTP::DEBUG_CLIENT = 1

Debug level to show client -> server messages.

Definition at line 61 of file class.smtp.php.

◆ DEBUG_CONNECTION

const SMTP::DEBUG_CONNECTION = 3

Debug level to show connection status, client -> server and server -> client messages.

Definition at line 71 of file class.smtp.php.

◆ DEBUG_LOWLEVEL

const SMTP::DEBUG_LOWLEVEL = 4

Debug level to show all messages.

Definition at line 76 of file class.smtp.php.

◆ DEBUG_OFF

const SMTP::DEBUG_OFF = 0

Debug level for no output.

Definition at line 56 of file class.smtp.php.

◆ DEBUG_SERVER

const SMTP::DEBUG_SERVER = 2

Debug level to show client -> server and server -> client messages.

Definition at line 66 of file class.smtp.php.

◆ DEFAULT_SMTP_PORT

const SMTP::DEFAULT_SMTP_PORT = 25

Definition at line 45 of file class.smtp.php.

Referenced by connect().

◆ MAX_LINE_LENGTH

const SMTP::MAX_LINE_LENGTH = 998

Definition at line 51 of file class.smtp.php.

◆ VERSION

const SMTP::VERSION = '5.2.22'

Definition at line 33 of file class.smtp.php.


The documentation for this class was generated from the following file: