| [ Index ] |
PHP Cross Reference of MyBB 1.6.7 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id: smtp.php 5297 2010-12-28 22:01:14Z Tomm $ 10 */ 11 12 // Disallow direct access to this file for security reasons 13 if(!defined("IN_MYBB")) 14 { 15 die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined."); 16 } 17 18 /** 19 * SMTP mail handler class. 20 */ 21 22 if(!defined('MYBB_SSL')) 23 { 24 define('MYBB_SSL', 1); 25 } 26 27 if(!defined('MYBB_TLS')) 28 { 29 define('MYBB_TLS', 2); 30 } 31 32 class SmtpMail extends MailHandler 33 { 34 /** 35 * The SMTP connection. 36 * 37 * @var resource 38 */ 39 public $connection; 40 41 /** 42 * SMTP username. 43 * 44 * @var string 45 */ 46 public $username = ''; 47 48 /** 49 * SMTP password. 50 * 51 * @var string 52 */ 53 public $password = ''; 54 55 /** 56 * Hello string sent to the smtp server with either HELO or EHLO. 57 * 58 * @var string 59 */ 60 public $helo = 'localhost'; 61 62 /** 63 * User authenticated or not. 64 * 65 * @var boolean 66 */ 67 public $authenticated = false; 68 69 /** 70 * How long before timeout. 71 * 72 * @var integer 73 */ 74 public $timeout = 5; 75 76 /** 77 * SMTP status. 78 * 79 * @var integer 80 */ 81 public $status = 0; 82 83 /** 84 * SMTP default port. 85 * 86 * @var integer 87 */ 88 public $port = 25; 89 90 /** 91 * SMTP default secure port. 92 * 93 * @var integer 94 */ 95 public $secure_port = 465; 96 97 /** 98 * SMTP host. 99 * 100 * @var string 101 */ 102 public $host = ''; 103 104 /** 105 * The last received response from the SMTP server. 106 * 107 * @var string 108 */ 109 public $data = ''; 110 111 /** 112 * The last received response code from the SMTP server. 113 * 114 * @var string 115 */ 116 public $code = 0; 117 118 /** 119 * The last received error message from the SMTP server. 120 * 121 * @var string 122 */ 123 public $last_error = ''; 124 125 /** 126 * Are we keeping the connection to the SMTP server alive? 127 * 128 * @var boolean 129 */ 130 public $keep_alive = false; 131 132 function __construct() 133 { 134 global $mybb; 135 136 $protocol = ''; 137 switch($mybb->settings['secure_smtp']) 138 { 139 case MYBB_SSL: 140 $protocol = 'ssl://'; 141 break; 142 case MYBB_TLS: 143 $protocol = 'tls://'; 144 break; 145 } 146 147 if(empty($mybb->settings['smtp_host'])) 148 { 149 $this->host = @ini_get('SMTP'); 150 } 151 else 152 { 153 $this->host = $mybb->settings['smtp_host']; 154 } 155 156 $this->helo = $this->host; 157 158 $this->host = $protocol . $this->host; 159 160 if(empty($mybb->settings['smtp_port']) && !empty($protocol) && !@ini_get('smtp_port')) 161 { 162 $this->port = $this->secure_port; 163 } 164 else if(empty($mybb->settings['smtp_port']) && @ini_get('smtp_port')) 165 { 166 $this->port = @ini_get('smtp_port'); 167 } 168 else if(!empty($mybb->settings['smtp_port'])) 169 { 170 $this->port = $mybb->settings['smtp_port']; 171 } 172 173 $this->password = $mybb->settings['smtp_pass']; 174 $this->username = $mybb->settings['smtp_user']; 175 } 176 177 /** 178 * Sends the email. 179 * 180 * @return true/false whether or not the email got sent or not. 181 */ 182 function send() 183 { 184 global $lang, $mybb; 185 186 if(!$this->connected()) 187 { 188 $this->connect(); 189 } 190 191 if($this->connected()) 192 { 193 if(!$this->send_data('MAIL FROM:<'.$this->from.'>', '250')) 194 { 195 $this->fatal_error("The mail server does not understand the MAIL FROM command. Reason: ".$this->get_error()); 196 return false; 197 } 198 199 // Loop through recipients 200 $emails = explode(',', $this->to); 201 foreach($emails as $to) 202 { 203 $to = trim($to); 204 if(!$this->send_data('RCPT TO:<'.$to.'>', '250')) 205 { 206 $this->fatal_error("The mail server does not understand the RCPT TO command. Reason: ".$this->get_error()); 207 return false; 208 } 209 } 210 211 if($this->send_data('DATA', '354')) 212 { 213 $this->send_data('Date: ' . gmdate('r')); 214 $this->send_data('To: ' . $this->to); 215 216 $this->send_data('Subject: ' . $this->subject); 217 218 // Only send additional headers if we've got any 219 if(trim($this->headers)) 220 { 221 $this->send_data(trim($this->headers)); 222 } 223 224 $this->send_data(""); 225 226 // Queue the actual message 227 $this->message = str_replace("\n.", "\n..", $this->message); 228 $this->send_data($this->message); 229 } 230 else 231 { 232 $this->fatal_error("The mail server did not understand the DATA command"); 233 return false; 234 } 235 236 $this->send_data('.', '250'); 237 238 if(!$this->keep_alive) 239 { 240 $this->close(); 241 } 242 return true; 243 } 244 else 245 { 246 return false; 247 } 248 } 249 250 /** 251 * Connect to the SMTP server. 252 * 253 * @return boolean True if connection was successful 254 */ 255 function connect() 256 { 257 global $lang, $mybb; 258 259 $this->connection = @fsockopen($this->host, $this->port, $error_number, $error_string, $this->timeout); 260 261 // DIRECTORY_SEPARATOR checks if running windows 262 if(function_exists('stream_set_timeout') && DIRECTORY_SEPARATOR != '\\') 263 { 264 @stream_set_timeout($this->connection, $this->timeout, 0); 265 } 266 267 if(is_resource($this->connection)) 268 { 269 $this->status = 1; 270 $this->get_data(); 271 if(!$this->check_status('220')) 272 { 273 $this->fatal_error("The mail server is not ready, it did not respond with a 220 status message."); 274 return false; 275 } 276 277 if(!empty($this->username) && !empty($this->password)) 278 { 279 $data = $this->send_data('EHLO ' . $this->helo, '250'); 280 if(!$data) 281 { 282 $this->fatal_error("The server did not understand the EHLO command"); 283 return false; 284 } 285 preg_match("#250-AUTH( |=)(.+)$#mi", $data, $matches); 286 if(!$this->auth($matches[2])) 287 { 288 $this->fatal_error("MyBB was unable to authenticate you against the SMTP server"); 289 return false; 290 } 291 } 292 else 293 { 294 if(!$this->send_data('HELO ' . $this->helo, '250')) 295 { 296 $this->fatal_error("The server did not understand the HELO command"); 297 return false; 298 } 299 } 300 return true; 301 } 302 else 303 { 304 $this->fatal_error("Unable to connect to the mail server with the given details.<br /><br />{$error_number}: {$error_string}"); 305 return false; 306 } 307 } 308 309 /** 310 * Authenticate against the SMTP server. 311 * 312 * @param string A list of authentication methods supported by the server 313 * @return boolean True on success 314 */ 315 function auth($auth_methods) 316 { 317 global $lang, $mybb; 318 319 $auth_methods = explode(" ", $auth_methods); 320 321 if(in_array("LOGIN", $auth_methods)) 322 { 323 if(!$this->send_data("AUTH LOGIN", 334)) 324 { 325 if($this->code == 503) 326 { 327 return true; 328 } 329 $this->fatal_error("The SMTP server did not respond correctly to the AUTH LOGIN command"); 330 return false; 331 } 332 333 if(!$this->send_data(base64_encode($this->username), '334')) 334 { 335 $this->fatal_error("The SMTP server rejected the supplied SMTP username. Reason: ".$this->get_error()); 336 return false; 337 } 338 339 if(!$this->send_data(base64_encode($this->password), '235')) 340 { 341 $this->fatal_error("The SMTP server rejected the supplied SMTP password. Reason: ".$this->get_error()); 342 return false; 343 } 344 } 345 else if(in_array("PLAIN", $auth_methods)) 346 { 347 if(!$this->send_data("AUTH PLAIN", '334')) 348 { 349 if($this->code == 503) 350 { 351 return true; 352 } 353 $this->fatal_error("The SMTP server did not respond correctly to the AUTH PLAIN command"); 354 return false; 355 } 356 $auth = base64_encode(chr(0).$this->username.chr(0).$this->password); 357 if(!$this->send_data($auth, 235)) 358 { 359 $this->fatal_error("The SMTP server rejected the supplied login username and password. Reason: ".$this->get_error()); 360 return false; 361 } 362 } 363 else 364 { 365 $this->fatal_error("The SMTP server does not support any of the AUTH methods that MyBB supports"); 366 return false; 367 } 368 369 // Still here, we're authenticated 370 return true; 371 } 372 373 /** 374 * Fetch data from the SMTP server. 375 * 376 * @return string The data from the SMTP server 377 */ 378 function get_data() 379 { 380 $string = ''; 381 382 while((($line = fgets($this->connection, 515)) !== false)) 383 { 384 $string .= $line; 385 if(substr($line, 3, 1) == ' ') 386 { 387 break; 388 } 389 } 390 $this->data = $string; 391 $this->code = substr(trim($this->data), 0, 3); 392 return $string; 393 } 394 395 /** 396 * Check if we're currently connected to an SMTP server 397 * 398 * @return boolean true if connected 399 */ 400 function connected() 401 { 402 if($this->status == 1) 403 { 404 return true; 405 } 406 return false; 407 } 408 409 /** 410 * Send data through to the SMTP server. 411 * 412 * @param string The data to be sent 413 * @param int The response code expected back from the server (if we have one) 414 * @return boolean True on success 415 */ 416 function send_data($data, $status_num = false) 417 { 418 if($this->connected()) 419 { 420 if(fwrite($this->connection, $data."\r\n")) 421 { 422 if($status_num != false) 423 { 424 $rec = $this->get_data(); 425 if($this->check_status($status_num)) 426 { 427 return $rec; 428 } 429 else 430 { 431 $this->set_error($rec); 432 return false; 433 } 434 } 435 return true; 436 } 437 else 438 { 439 $this->fatal_error("Unable to send the data to the SMTP server"); 440 return false; 441 } 442 } 443 return false; 444 } 445 446 /** 447 * Checks if the received status code matches the one we expect. 448 * 449 * @param int The status code we expected back from the server 450 * @param boolean True if it matches 451 */ 452 function check_status($status_num) 453 { 454 if($this->code == $status_num) 455 { 456 return $this->data; 457 } 458 else 459 { 460 return false; 461 } 462 } 463 464 /** 465 * Close the connection to the SMTP server. 466 */ 467 function close() 468 { 469 if($this->status == 1) 470 { 471 $this->send_data('QUIT'); 472 fclose($this->connection); 473 $this->status = 0; 474 } 475 } 476 477 /** 478 * Get the last error message response from the SMTP server 479 * 480 * @return string The error message response from the SMTP server 481 */ 482 function get_error() 483 { 484 if(!$this->last_error) 485 { 486 $this->last_error = "N/A"; 487 } 488 489 return $this->last_error; 490 } 491 492 /** 493 * Set the last error message response from the SMTP server 494 * 495 * @param string The error message response 496 */ 497 function set_error($error) 498 { 499 $this->last_error = $error; 500 } 501 } 502 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Mar 31 17:55:03 2012 | Cross-referenced by PHPXref 0.7.1 |