Advertisement
Guest User

Untitled

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