class.pop3.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <?php
  2. /*~ class.pop3.php
  3. .---------------------------------------------------------------------------.
  4. | Software: PHPMailer - PHP email class |
  5. | Version: 5.1 |
  6. | Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
  7. | Info: http://phpmailer.sourceforge.net |
  8. | Support: http://sourceforge.net/projects/phpmailer/ |
  9. | ------------------------------------------------------------------------- |
  10. | Admin: Andy Prevost (project admininistrator) |
  11. | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
  12. | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
  13. | Founder: Brent R. Matzelle (original founder) |
  14. | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
  15. | Copyright (c) 2001-2003, Brent R. Matzelle |
  16. | ------------------------------------------------------------------------- |
  17. | License: Distributed under the Lesser General Public License (LGPL) |
  18. | http://www.gnu.org/copyleft/lesser.html |
  19. | This program is distributed in the hope that it will be useful - WITHOUT |
  20. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
  21. | FITNESS FOR A PARTICULAR PURPOSE. |
  22. | ------------------------------------------------------------------------- |
  23. | We offer a number of paid services (www.codeworxtech.com): |
  24. | - Web Hosting on highly optimized fast and secure servers |
  25. | - Technology Consulting |
  26. | - Oursourcing (highly qualified programmers and graphic designers) |
  27. '---------------------------------------------------------------------------'
  28. */
  29. /**
  30. * PHPMailer - PHP POP Before SMTP Authentication Class
  31. * NOTE: Designed for use with PHP version 5 and up.
  32. *
  33. * @package PHPMailer
  34. *
  35. * @author Andy Prevost
  36. * @author Marcus Bointon
  37. * @copyright 2004 - 2009 Andy Prevost
  38. * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
  39. *
  40. * @version $Id: class.pop3.php 444 2009-05-05 11:22:26Z coolbru $
  41. */
  42. /**
  43. * POP Before SMTP Authentication Class
  44. * Version 5.0.0.
  45. *
  46. * Author: Richard Davey (rich@corephp.co.uk)
  47. * Modifications: Andy Prevost
  48. * License: LGPL, see PHPMailer License
  49. *
  50. * Specifically for PHPMailer to allow POP before SMTP authentication.
  51. * Does not yet work with APOP - if you have an APOP account, contact Richard Davey
  52. * and we can test changes to this script.
  53. *
  54. * This class is based on the structure of the SMTP class originally authored by Chris Ryan
  55. *
  56. * This class is rfc 1939 compliant and implements all the commands
  57. * required for POP3 connection, authentication and disconnection.
  58. *
  59. * @package PHPMailer
  60. *
  61. * @author Richard Davey
  62. */
  63. class POP3
  64. {
  65. /**
  66. * Default POP3 port.
  67. *
  68. * @var int
  69. */
  70. public $POP3_PORT = 110;
  71. /**
  72. * Default Timeout.
  73. *
  74. * @var int
  75. */
  76. public $POP3_TIMEOUT = 30;
  77. /**
  78. * POP3 Carriage Return + Line Feed.
  79. *
  80. * @var string
  81. */
  82. public $CRLF = "\r\n";
  83. /**
  84. * Displaying Debug warnings? (0 = now, 1+ = yes).
  85. *
  86. * @var int
  87. */
  88. public $do_debug = 2;
  89. /**
  90. * POP3 Mail Server.
  91. *
  92. * @var string
  93. */
  94. public $host;
  95. /**
  96. * POP3 Port.
  97. *
  98. * @var int
  99. */
  100. public $port;
  101. /**
  102. * POP3 Timeout Value.
  103. *
  104. * @var int
  105. */
  106. public $tval;
  107. /**
  108. * POP3 Username.
  109. *
  110. * @var string
  111. */
  112. public $username;
  113. /**
  114. * POP3 Password.
  115. *
  116. * @var string
  117. */
  118. public $password;
  119. /////////////////////////////////////////////////
  120. // PROPERTIES, PRIVATE AND PROTECTED
  121. /////////////////////////////////////////////////
  122. private $pop_conn;
  123. private $connected;
  124. private $error; // Error log array
  125. /**
  126. * Constructor, sets the initial values.
  127. *
  128. * @return POP3
  129. */
  130. public function __construct()
  131. {
  132. $this->pop_conn = 0;
  133. $this->connected = false;
  134. $this->error = null;
  135. }
  136. /**
  137. * Combination of public events - connect, login, disconnect.
  138. *
  139. * @param string $host
  140. * @param int $port
  141. * @param int $tval
  142. * @param string $username
  143. * @param string $password
  144. */
  145. public function Authorise($host, $port = false, $tval = false, $username, $password, $debug_level = 0)
  146. {
  147. $this->host = $host;
  148. // If no port value is passed, retrieve it
  149. if ($port == false) {
  150. $this->port = $this->POP3_PORT;
  151. } else {
  152. $this->port = $port;
  153. }
  154. // If no port value is passed, retrieve it
  155. if ($tval == false) {
  156. $this->tval = $this->POP3_TIMEOUT;
  157. } else {
  158. $this->tval = $tval;
  159. }
  160. $this->do_debug = $debug_level;
  161. $this->username = $username;
  162. $this->password = $password;
  163. // Refresh the error log
  164. $this->error = null;
  165. // Connect
  166. $result = $this->Connect($this->host, $this->port, $this->tval);
  167. if ($result) {
  168. $login_result = $this->Login($this->username, $this->password);
  169. if ($login_result) {
  170. $this->Disconnect();
  171. return true;
  172. }
  173. }
  174. // We need to disconnect regardless if the login succeeded
  175. $this->Disconnect();
  176. return false;
  177. }
  178. /**
  179. * Connect to the POP3 server.
  180. *
  181. * @param string $host
  182. * @param int $port
  183. * @param int $tval
  184. *
  185. * @return bool
  186. */
  187. public function Connect($host, $port = false, $tval = 30)
  188. {
  189. // Are we already connected?
  190. if ($this->connected) {
  191. return true;
  192. }
  193. /*
  194. On Windows this will raise a PHP Warning error if the hostname doesn't exist.
  195. Rather than supress it with @fsockopen, let's capture it cleanly instead
  196. */
  197. set_error_handler([&$this, 'catchWarning']);
  198. // Connect to the POP3 server
  199. $this->pop_conn = fsockopen($host, // POP3 Host
  200. $port, // Port #
  201. $errno, // Error Number
  202. $errstr, // Error Message
  203. $tval); // Timeout (seconds)
  204. // Restore the error handler
  205. restore_error_handler();
  206. // Does the Error Log now contain anything?
  207. if ($this->error && $this->do_debug >= 1) {
  208. $this->displayErrors();
  209. }
  210. // Did we connect?
  211. if ($this->pop_conn == false) {
  212. // It would appear not...
  213. $this->error = [
  214. 'error' => "Failed to connect to server $host on port $port",
  215. 'errno' => $errno,
  216. 'errstr' => $errstr,
  217. ];
  218. if ($this->do_debug >= 1) {
  219. $this->displayErrors();
  220. }
  221. return false;
  222. }
  223. // Increase the stream time-out
  224. // Check for PHP 4.3.0 or later
  225. if (version_compare(phpversion(), '5.0.0', 'ge')) {
  226. stream_set_timeout($this->pop_conn, $tval, 0);
  227. } else {
  228. // Does not work on Windows
  229. if (substr(PHP_OS, 0, 3) !== 'WIN') {
  230. socket_set_timeout($this->pop_conn, $tval, 0);
  231. }
  232. }
  233. // Get the POP3 server response
  234. $pop3_response = $this->getResponse();
  235. // Check for the +OK
  236. if ($this->checkResponse($pop3_response)) {
  237. // The connection is established and the POP3 server is talking
  238. $this->connected = true;
  239. return true;
  240. }
  241. }
  242. /**
  243. * Login to the POP3 server (does not support APOP yet).
  244. *
  245. * @param string $username
  246. * @param string $password
  247. *
  248. * @return bool
  249. */
  250. public function Login($username = '', $password = '')
  251. {
  252. if ($this->connected == false) {
  253. $this->error = 'Not connected to POP3 server';
  254. if ($this->do_debug >= 1) {
  255. $this->displayErrors();
  256. }
  257. }
  258. if (empty($username)) {
  259. $username = $this->username;
  260. }
  261. if (empty($password)) {
  262. $password = $this->password;
  263. }
  264. $pop_username = "USER $username".$this->CRLF;
  265. $pop_password = "PASS $password".$this->CRLF;
  266. // Send the Username
  267. $this->sendString($pop_username);
  268. $pop3_response = $this->getResponse();
  269. if ($this->checkResponse($pop3_response)) {
  270. // Send the Password
  271. $this->sendString($pop_password);
  272. $pop3_response = $this->getResponse();
  273. if ($this->checkResponse($pop3_response)) {
  274. return true;
  275. } else {
  276. return false;
  277. }
  278. } else {
  279. return false;
  280. }
  281. }
  282. /**
  283. * Disconnect from the POP3 server.
  284. */
  285. public function Disconnect()
  286. {
  287. $this->sendString('QUIT');
  288. fclose($this->pop_conn);
  289. }
  290. /////////////////////////////////////////////////
  291. // Private Methods
  292. /////////////////////////////////////////////////
  293. /**
  294. * Get the socket response back.
  295. * $size is the maximum number of bytes to retrieve.
  296. *
  297. * @param int $size
  298. *
  299. * @return string
  300. */
  301. private function getResponse($size = 128)
  302. {
  303. $pop3_response = fgets($this->pop_conn, $size);
  304. return $pop3_response;
  305. }
  306. /**
  307. * Send a string down the open socket connection to the POP3 server.
  308. *
  309. * @param string $string
  310. *
  311. * @return int
  312. */
  313. private function sendString($string)
  314. {
  315. $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
  316. return $bytes_sent;
  317. }
  318. /**
  319. * Checks the POP3 server response for +OK or -ERR.
  320. *
  321. * @param string $string
  322. *
  323. * @return bool
  324. */
  325. private function checkResponse($string)
  326. {
  327. if (substr($string, 0, 3) !== '+OK') {
  328. $this->error = [
  329. 'error' => "Server reported an error: $string",
  330. 'errno' => 0,
  331. 'errstr' => '',
  332. ];
  333. if ($this->do_debug >= 1) {
  334. $this->displayErrors();
  335. }
  336. return false;
  337. } else {
  338. return true;
  339. }
  340. }
  341. /**
  342. * If debug is enabled, display the error message array.
  343. */
  344. private function displayErrors()
  345. {
  346. echo '<pre>';
  347. foreach ($this->error as $single_error) {
  348. print_r($single_error);
  349. }
  350. echo '</pre>';
  351. }
  352. /**
  353. * Takes over from PHP for the socket warning handler.
  354. *
  355. * @param int $errno
  356. * @param string $errstr
  357. * @param string $errfile
  358. * @param int $errline
  359. */
  360. private function catchWarning($errno, $errstr, $errfile, $errline)
  361. {
  362. $this->error[] = [
  363. 'error' => "Connecting to the POP3 server raised a PHP warning: ",
  364. 'errno' => $errno,
  365. 'errstr' => $errstr,
  366. ];
  367. }
  368. // End of class
  369. }