PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/wp-includes/class-pop3.php

https://gitlab.com/VTTE/sitios-vtte
PHP | 662 lines | 486 code | 81 blank | 95 comment | 99 complexity | 55e4f4d2ed9124899a8917433b47c270 MD5 | raw file
  1. <?php
  2. /**
  3. * mail_fetch/setup.php
  4. *
  5. * Copyright (c) 1999-2011 CDI (cdi@thewebmasters.net) All Rights Reserved
  6. * Modified by Philippe Mingo 2001-2009 mingo@rotedic.com
  7. * An RFC 1939 compliant wrapper class for the POP3 protocol.
  8. *
  9. * Licensed under the GNU GPL. For full terms see the file COPYING.
  10. *
  11. * POP3 class
  12. *
  13. * @copyright 1999-2011 The SquirrelMail Project Team
  14. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  15. * @package plugins
  16. * @subpackage mail_fetch
  17. */
  18. class POP3 {
  19. var $ERROR = ''; // Error string.
  20. var $TIMEOUT = 60; // Default timeout before giving up on a
  21. // network operation.
  22. var $COUNT = -1; // Mailbox msg count
  23. var $BUFFER = 512; // Socket buffer for socket fgets() calls.
  24. // Per RFC 1939 the returned line a POP3
  25. // server can send is 512 bytes.
  26. var $FP = ''; // The connection to the server's
  27. // file descriptor
  28. var $MAILSERVER = ''; // Set this to hard code the server name
  29. var $DEBUG = FALSE; // set to true to echo pop3
  30. // commands and responses to error_log
  31. // this WILL log passwords!
  32. var $BANNER = ''; // Holds the banner returned by the
  33. // pop server - used for apop()
  34. var $ALLOWAPOP = FALSE; // Allow or disallow apop()
  35. // This must be set to true
  36. // manually
  37. /**
  38. * PHP5 constructor.
  39. */
  40. function __construct ( $server = '', $timeout = '' ) {
  41. settype($this->BUFFER,"integer");
  42. if( !empty($server) ) {
  43. // Do not allow programs to alter MAILSERVER
  44. // if it is already specified. They can get around
  45. // this if they -really- want to, so don't count on it.
  46. if(empty($this->MAILSERVER))
  47. $this->MAILSERVER = $server;
  48. }
  49. if(!empty($timeout)) {
  50. settype($timeout,"integer");
  51. $this->TIMEOUT = $timeout;
  52. if (!ini_get('safe_mode'))
  53. set_time_limit($timeout);
  54. }
  55. return true;
  56. }
  57. /**
  58. * PHP4 constructor.
  59. */
  60. public function POP3( $server = '', $timeout = '' ) {
  61. self::__construct( $server, $timeout );
  62. }
  63. function update_timer () {
  64. if (!ini_get('safe_mode'))
  65. set_time_limit($this->TIMEOUT);
  66. return true;
  67. }
  68. function connect ($server, $port = 110) {
  69. // Opens a socket to the specified server. Unless overridden,
  70. // port defaults to 110. Returns true on success, false on fail
  71. // If MAILSERVER is set, override $server with its value.
  72. if (!isset($port) || !$port) {$port = 110;}
  73. if(!empty($this->MAILSERVER))
  74. $server = $this->MAILSERVER;
  75. if(empty($server)){
  76. $this->ERROR = "POP3 connect: " . _("No server specified");
  77. unset($this->FP);
  78. return false;
  79. }
  80. $fp = @fsockopen("$server", $port, $errno, $errstr);
  81. if(!$fp) {
  82. $this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";
  83. unset($this->FP);
  84. return false;
  85. }
  86. socket_set_blocking($fp,-1);
  87. $this->update_timer();
  88. $reply = fgets($fp,$this->BUFFER);
  89. $reply = $this->strip_clf($reply);
  90. if($this->DEBUG)
  91. error_log("POP3 SEND [connect: $server] GOT [$reply]",0);
  92. if(!$this->is_ok($reply)) {
  93. $this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]";
  94. unset($this->FP);
  95. return false;
  96. }
  97. $this->FP = $fp;
  98. $this->BANNER = $this->parse_banner($reply);
  99. return true;
  100. }
  101. function user ($user = "") {
  102. // Sends the USER command, returns true or false
  103. if( empty($user) ) {
  104. $this->ERROR = "POP3 user: " . _("no login ID submitted");
  105. return false;
  106. } elseif(!isset($this->FP)) {
  107. $this->ERROR = "POP3 user: " . _("connection not established");
  108. return false;
  109. } else {
  110. $reply = $this->send_cmd("USER $user");
  111. if(!$this->is_ok($reply)) {
  112. $this->ERROR = "POP3 user: " . _("Error ") . "[$reply]";
  113. return false;
  114. } else
  115. return true;
  116. }
  117. }
  118. function pass ($pass = "") {
  119. // Sends the PASS command, returns # of msgs in mailbox,
  120. // returns false (undef) on Auth failure
  121. if(empty($pass)) {
  122. $this->ERROR = "POP3 pass: " . _("No password submitted");
  123. return false;
  124. } elseif(!isset($this->FP)) {
  125. $this->ERROR = "POP3 pass: " . _("connection not established");
  126. return false;
  127. } else {
  128. $reply = $this->send_cmd("PASS $pass");
  129. if(!$this->is_ok($reply)) {
  130. $this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]";
  131. $this->quit();
  132. return false;
  133. } else {
  134. // Auth successful.
  135. $count = $this->last("count");
  136. $this->COUNT = $count;
  137. return $count;
  138. }
  139. }
  140. }
  141. function apop ($login,$pass) {
  142. // Attempts an APOP login. If this fails, it'll
  143. // try a standard login. YOUR SERVER MUST SUPPORT
  144. // THE USE OF THE APOP COMMAND!
  145. // (apop is optional per rfc1939)
  146. if(!isset($this->FP)) {
  147. $this->ERROR = "POP3 apop: " . _("No connection to server");
  148. return false;
  149. } elseif(!$this->ALLOWAPOP) {
  150. $retVal = $this->login($login,$pass);
  151. return $retVal;
  152. } elseif(empty($login)) {
  153. $this->ERROR = "POP3 apop: " . _("No login ID submitted");
  154. return false;
  155. } elseif(empty($pass)) {
  156. $this->ERROR = "POP3 apop: " . _("No password submitted");
  157. return false;
  158. } else {
  159. $banner = $this->BANNER;
  160. if( (!$banner) or (empty($banner)) ) {
  161. $this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort");
  162. $retVal = $this->login($login,$pass);
  163. return $retVal;
  164. } else {
  165. $AuthString = $banner;
  166. $AuthString .= $pass;
  167. $APOPString = md5($AuthString);
  168. $cmd = "APOP $login $APOPString";
  169. $reply = $this->send_cmd($cmd);
  170. if(!$this->is_ok($reply)) {
  171. $this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort");
  172. $retVal = $this->login($login,$pass);
  173. return $retVal;
  174. } else {
  175. // Auth successful.
  176. $count = $this->last("count");
  177. $this->COUNT = $count;
  178. return $count;
  179. }
  180. }
  181. }
  182. }
  183. function login ($login = "", $pass = "") {
  184. // Sends both user and pass. Returns # of msgs in mailbox or
  185. // false on failure (or -1, if the error occurs while getting
  186. // the number of messages.)
  187. if( !isset($this->FP) ) {
  188. $this->ERROR = "POP3 login: " . _("No connection to server");
  189. return false;
  190. } else {
  191. $fp = $this->FP;
  192. if( !$this->user( $login ) ) {
  193. // Preserve the error generated by user()
  194. return false;
  195. } else {
  196. $count = $this->pass($pass);
  197. if( (!$count) || ($count == -1) ) {
  198. // Preserve the error generated by last() and pass()
  199. return false;
  200. } else
  201. return $count;
  202. }
  203. }
  204. }
  205. function top ($msgNum, $numLines = "0") {
  206. // Gets the header and first $numLines of the msg body
  207. // returns data in an array with each returned line being
  208. // an array element. If $numLines is empty, returns
  209. // only the header information, and none of the body.
  210. if(!isset($this->FP)) {
  211. $this->ERROR = "POP3 top: " . _("No connection to server");
  212. return false;
  213. }
  214. $this->update_timer();
  215. $fp = $this->FP;
  216. $buffer = $this->BUFFER;
  217. $cmd = "TOP $msgNum $numLines";
  218. fwrite($fp, "TOP $msgNum $numLines\r\n");
  219. $reply = fgets($fp, $buffer);
  220. $reply = $this->strip_clf($reply);
  221. if($this->DEBUG) {
  222. @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
  223. }
  224. if(!$this->is_ok($reply))
  225. {
  226. $this->ERROR = "POP3 top: " . _("Error ") . "[$reply]";
  227. return false;
  228. }
  229. $count = 0;
  230. $MsgArray = array();
  231. $line = fgets($fp,$buffer);
  232. while ( !preg_match('/^\.\r\n/',$line))
  233. {
  234. $MsgArray[$count] = $line;
  235. $count++;
  236. $line = fgets($fp,$buffer);
  237. if(empty($line)) { break; }
  238. }
  239. return $MsgArray;
  240. }
  241. function pop_list ($msgNum = "") {
  242. // If called with an argument, returns that msgs' size in octets
  243. // No argument returns an associative array of undeleted
  244. // msg numbers and their sizes in octets
  245. if(!isset($this->FP))
  246. {
  247. $this->ERROR = "POP3 pop_list: " . _("No connection to server");
  248. return false;
  249. }
  250. $fp = $this->FP;
  251. $Total = $this->COUNT;
  252. if( (!$Total) or ($Total == -1) )
  253. {
  254. return false;
  255. }
  256. if($Total == 0)
  257. {
  258. return array("0","0");
  259. // return -1; // mailbox empty
  260. }
  261. $this->update_timer();
  262. if(!empty($msgNum))
  263. {
  264. $cmd = "LIST $msgNum";
  265. fwrite($fp,"$cmd\r\n");
  266. $reply = fgets($fp,$this->BUFFER);
  267. $reply = $this->strip_clf($reply);
  268. if($this->DEBUG) {
  269. @error_log("POP3 SEND [$cmd] GOT [$reply]",0);
  270. }
  271. if(!$this->is_ok($reply))
  272. {
  273. $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
  274. return false;
  275. }
  276. list($junk,$num,$size) = preg_split('/\s+/',$reply);
  277. return $size;
  278. }
  279. $cmd = "LIST";
  280. $reply = $this->send_cmd($cmd);
  281. if(!$this->is_ok($reply))
  282. {
  283. $reply = $this->strip_clf($reply);
  284. $this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
  285. return false;
  286. }
  287. $MsgArray = array();
  288. $MsgArray[0] = $Total;
  289. for($msgC=1;$msgC <= $Total; $msgC++)
  290. {
  291. if($msgC > $Total) { break; }
  292. $line = fgets($fp,$this->BUFFER);
  293. $line = $this->strip_clf($line);
  294. if(strpos($line, '.') === 0)
  295. {
  296. $this->ERROR = "POP3 pop_list: " . _("Premature end of list");
  297. return false;
  298. }
  299. list($thisMsg,$msgSize) = preg_split('/\s+/',$line);
  300. settype($thisMsg,"integer");
  301. if($thisMsg != $msgC)
  302. {
  303. $MsgArray[$msgC] = "deleted";
  304. }
  305. else
  306. {
  307. $MsgArray[$msgC] = $msgSize;
  308. }
  309. }
  310. return $MsgArray;
  311. }
  312. function get ($msgNum) {
  313. // Retrieve the specified msg number. Returns an array
  314. // where each line of the msg is an array element.
  315. if(!isset($this->FP))
  316. {
  317. $this->ERROR = "POP3 get: " . _("No connection to server");
  318. return false;
  319. }
  320. $this->update_timer();
  321. $fp = $this->FP;
  322. $buffer = $this->BUFFER;
  323. $cmd = "RETR $msgNum";
  324. $reply = $this->send_cmd($cmd);
  325. if(!$this->is_ok($reply))
  326. {
  327. $this->ERROR = "POP3 get: " . _("Error ") . "[$reply]";
  328. return false;
  329. }
  330. $count = 0;
  331. $MsgArray = array();
  332. $line = fgets($fp,$buffer);
  333. while ( !preg_match('/^\.\r\n/',$line))
  334. {
  335. if ( $line[0] == '.' ) { $line = substr($line,1); }
  336. $MsgArray[$count] = $line;
  337. $count++;
  338. $line = fgets($fp,$buffer);
  339. if(empty($line)) { break; }
  340. }
  341. return $MsgArray;
  342. }
  343. function last ( $type = "count" ) {
  344. // Returns the highest msg number in the mailbox.
  345. // returns -1 on error, 0+ on success, if type != count
  346. // results in a popstat() call (2 element array returned)
  347. $last = -1;
  348. if(!isset($this->FP))
  349. {
  350. $this->ERROR = "POP3 last: " . _("No connection to server");
  351. return $last;
  352. }
  353. $reply = $this->send_cmd("STAT");
  354. if(!$this->is_ok($reply))
  355. {
  356. $this->ERROR = "POP3 last: " . _("Error ") . "[$reply]";
  357. return $last;
  358. }
  359. $Vars = preg_split('/\s+/',$reply);
  360. $count = $Vars[1];
  361. $size = $Vars[2];
  362. settype($count,"integer");
  363. settype($size,"integer");
  364. if($type != "count")
  365. {
  366. return array($count,$size);
  367. }
  368. return $count;
  369. }
  370. function reset () {
  371. // Resets the status of the remote server. This includes
  372. // resetting the status of ALL msgs to not be deleted.
  373. // This method automatically closes the connection to the server.
  374. if(!isset($this->FP))
  375. {
  376. $this->ERROR = "POP3 reset: " . _("No connection to server");
  377. return false;
  378. }
  379. $reply = $this->send_cmd("RSET");
  380. if(!$this->is_ok($reply))
  381. {
  382. // The POP3 RSET command -never- gives a -ERR
  383. // response - if it ever does, something truly
  384. // wild is going on.
  385. $this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]";
  386. @error_log("POP3 reset: ERROR [$reply]",0);
  387. }
  388. $this->quit();
  389. return true;
  390. }
  391. function send_cmd ( $cmd = "" )
  392. {
  393. // Sends a user defined command string to the
  394. // POP server and returns the results. Useful for
  395. // non-compliant or custom POP servers.
  396. // Do NOT includ the \r\n as part of your command
  397. // string - it will be appended automatically.
  398. // The return value is a standard fgets() call, which
  399. // will read up to $this->BUFFER bytes of data, until it
  400. // encounters a new line, or EOF, whichever happens first.
  401. // This method works best if $cmd responds with only
  402. // one line of data.
  403. if(!isset($this->FP))
  404. {
  405. $this->ERROR = "POP3 send_cmd: " . _("No connection to server");
  406. return false;
  407. }
  408. if(empty($cmd))
  409. {
  410. $this->ERROR = "POP3 send_cmd: " . _("Empty command string");
  411. return "";
  412. }
  413. $fp = $this->FP;
  414. $buffer = $this->BUFFER;
  415. $this->update_timer();
  416. fwrite($fp,"$cmd\r\n");
  417. $reply = fgets($fp,$buffer);
  418. $reply = $this->strip_clf($reply);
  419. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
  420. return $reply;
  421. }
  422. function quit() {
  423. // Closes the connection to the POP3 server, deleting
  424. // any msgs marked as deleted.
  425. if(!isset($this->FP))
  426. {
  427. $this->ERROR = "POP3 quit: " . _("connection does not exist");
  428. return false;
  429. }
  430. $fp = $this->FP;
  431. $cmd = "QUIT";
  432. fwrite($fp,"$cmd\r\n");
  433. $reply = fgets($fp,$this->BUFFER);
  434. $reply = $this->strip_clf($reply);
  435. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
  436. fclose($fp);
  437. unset($this->FP);
  438. return true;
  439. }
  440. function popstat () {
  441. // Returns an array of 2 elements. The number of undeleted
  442. // msgs in the mailbox, and the size of the mbox in octets.
  443. $PopArray = $this->last("array");
  444. if($PopArray == -1) { return false; }
  445. if( (!$PopArray) or (empty($PopArray)) )
  446. {
  447. return false;
  448. }
  449. return $PopArray;
  450. }
  451. function uidl ($msgNum = "")
  452. {
  453. // Returns the UIDL of the msg specified. If called with
  454. // no arguments, returns an associative array where each
  455. // undeleted msg num is a key, and the msg's uidl is the element
  456. // Array element 0 will contain the total number of msgs
  457. if(!isset($this->FP)) {
  458. $this->ERROR = "POP3 uidl: " . _("No connection to server");
  459. return false;
  460. }
  461. $fp = $this->FP;
  462. $buffer = $this->BUFFER;
  463. if(!empty($msgNum)) {
  464. $cmd = "UIDL $msgNum";
  465. $reply = $this->send_cmd($cmd);
  466. if(!$this->is_ok($reply))
  467. {
  468. $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
  469. return false;
  470. }
  471. list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);
  472. return $myUidl;
  473. } else {
  474. $this->update_timer();
  475. $UIDLArray = array();
  476. $Total = $this->COUNT;
  477. $UIDLArray[0] = $Total;
  478. if ($Total < 1)
  479. {
  480. return $UIDLArray;
  481. }
  482. $cmd = "UIDL";
  483. fwrite($fp, "UIDL\r\n");
  484. $reply = fgets($fp, $buffer);
  485. $reply = $this->strip_clf($reply);
  486. if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
  487. if(!$this->is_ok($reply))
  488. {
  489. $this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
  490. return false;
  491. }
  492. $line = "";
  493. $count = 1;
  494. $line = fgets($fp,$buffer);
  495. while ( !preg_match('/^\.\r\n/',$line)) {
  496. list ($msg,$msgUidl) = preg_split('/\s+/',$line);
  497. $msgUidl = $this->strip_clf($msgUidl);
  498. if($count == $msg) {
  499. $UIDLArray[$msg] = $msgUidl;
  500. }
  501. else
  502. {
  503. $UIDLArray[$count] = 'deleted';
  504. }
  505. $count++;
  506. $line = fgets($fp,$buffer);
  507. }
  508. }
  509. return $UIDLArray;
  510. }
  511. function delete ($msgNum = "") {
  512. // Flags a specified msg as deleted. The msg will not
  513. // be deleted until a quit() method is called.
  514. if(!isset($this->FP))
  515. {
  516. $this->ERROR = "POP3 delete: " . _("No connection to server");
  517. return false;
  518. }
  519. if(empty($msgNum))
  520. {
  521. $this->ERROR = "POP3 delete: " . _("No msg number submitted");
  522. return false;
  523. }
  524. $reply = $this->send_cmd("DELE $msgNum");
  525. if(!$this->is_ok($reply))
  526. {
  527. $this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]";
  528. return false;
  529. }
  530. return true;
  531. }
  532. // *********************************************************
  533. // The following methods are internal to the class.
  534. function is_ok ($cmd = "") {
  535. // Return true or false on +OK or -ERR
  536. if( empty($cmd) )
  537. return false;
  538. else
  539. return( stripos($cmd, '+OK') !== false );
  540. }
  541. function strip_clf ($text = "") {
  542. // Strips \r\n from server responses
  543. if(empty($text))
  544. return $text;
  545. else {
  546. $stripped = str_replace(array("\r","\n"),'',$text);
  547. return $stripped;
  548. }
  549. }
  550. function parse_banner ( $server_text ) {
  551. $outside = true;
  552. $banner = "";
  553. $length = strlen($server_text);
  554. for($count =0; $count < $length; $count++)
  555. {
  556. $digit = substr($server_text,$count,1);
  557. if(!empty($digit)) {
  558. if( (!$outside) && ($digit != '<') && ($digit != '>') )
  559. {
  560. $banner .= $digit;
  561. }
  562. if ($digit == '<')
  563. {
  564. $outside = false;
  565. }
  566. if($digit == '>')
  567. {
  568. $outside = true;
  569. }
  570. }
  571. }
  572. $banner = $this->strip_clf($banner); // Just in case
  573. return "<$banner>";
  574. }
  575. } // End class
  576. // For php4 compatibility
  577. if (!function_exists("stripos")) {
  578. function stripos($haystack, $needle){
  579. return strpos($haystack, stristr( $haystack, $needle ));
  580. }
  581. }