Source for file functions.php

Documentation is available at functions.php

  1. <?php
  2.  
  3. /**
  4.  * mail_fetch/functions.php
  5.  *
  6.  * Functions for the mail_fetch plugin.
  7.  *
  8.  * Original code from LexZEUS <[email protected]>
  9.  * and [email protected] (extracted from php manual)
  10.  * Adapted for MailFetch by Philippe Mingo <[email protected]>
  11.  *
  12.  * @copyright 1999-2020 The SquirrelMail Project Team
  13.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  14.  * @version $Id: functions.php 14845 2020-01-07 08:09:34Z pdontthink $
  15.  * @package plugins
  16.  * @subpackage mail_fetch
  17.  */
  18.  
  19.  
  20. /** pop3 class */
  21. include_once (SM_PATH 'plugins/mail_fetch/constants.php');
  22. include_once (SM_PATH 'plugins/mail_fetch/class.mail_fetch.php');
  23.  
  24. /** declare plugin globals */
  25. global $mail_fetch_allow_unsubscribed$mail_fetch_allowable_ports,
  26.        $mail_fetch_block_server_pattern;
  27.  
  28. /**
  29.   * Add link to menu at top of content pane
  30.   *
  31.   * @return void 
  32.   *
  33.   */
  34. function mail_fetch_link_do({
  35.  
  36.     global $oTemplate$nbsp;
  37.     $output makeInternalLink('plugins/mail_fetch/fetch.php'_("Fetch")'')
  38.             . $nbsp $nbsp;
  39.     return array('menuline' => $output);
  40.  
  41. }
  42.  
  43. /**
  44.  * Controls use of unsubscribed folders in plugin
  45.  * @global boolean $mail_fetch_allow_unsubscribed 
  46.  * @since 1.5.1 and 1.4.5
  47.  */
  48. $mail_fetch_allow_unsubscribed false;
  49.  
  50. /** load site config */
  51. if (file_exists(SM_PATH 'config/mail_fetch_config.php')) {
  52.     include_once(SM_PATH 'config/mail_fetch_config.php');
  53. elseif (file_exists(SM_PATH 'plugins/mail_fetch/config.php')) {
  54.     include_once(SM_PATH 'plugins/mail_fetch/config.php');
  55. }
  56.  
  57. // hooked functions
  58.  
  59. /**
  60.  * Internal function used to fetch pop3 mails on login
  61.  * @since 1.5.1
  62.  * @private
  63.  */
  64.     include_once (SM_PATH 'functions/imap_general.php');
  65.  
  66.     global $username$data_dir$imapServerAddress$imapPort$imap_stream_options;
  67.  
  68.     $mailfetch_newlog getPref($data_dir$username'mailfetch_newlog');
  69.  
  70.     $outMsg '';
  71.  
  72.     $mailfetch_server_number getPref($data_dir$username'mailfetch_server_number');
  73.     if (!isset($mailfetch_server_number)) $mailfetch_server_number=0;
  74.     $mailfetch_cypher getPref($data_dir$username'mailfetch_cypher');
  75.     if ($mailfetch_server_number<1$mailfetch_server_number=0;
  76.  
  77.     for ($i_loop=0;$i_loop<$mailfetch_server_number;$i_loop++{
  78.  
  79.         $mailfetch_login_[$i_loopgetPref($data_dir$username"mailfetch_login_$i_loop");
  80.         $mailfetch_fref_[$i_loopgetPref($data_dir$username"mailfetch_fref_$i_loop");
  81.         $mailfetch_pass_[$i_loopgetPref($data_dir$username"mailfetch_pass_$i_loop");
  82.         if$mailfetch_cypher == 'on' {
  83.             $mailfetch_pass_[$i_loopdecrypt$mailfetch_pass_[$i_loop);
  84.         }
  85.  
  86.         if$mailfetch_pass_[$i_loop<> '' &&          // Empty passwords no allowed
  87.                 ( ( $mailfetch_login_[$i_loop== 'on' &&  $mailfetch_newlog == 'on' || $mailfetch_fref_[$i_loop== 'on' ) ) {
  88.  
  89.             // What the heck
  90.             $mailfetch_server_[$i_loopgetPref($data_dir$username"mailfetch_server_$i_loop");
  91.             $mailfetch_port_[$i_loopgetPref($data_dir$username "mailfetch_port_$i_loop");
  92.             $mailfetch_alias_[$i_loopgetPref($data_dir$username"mailfetch_alias_$i_loop");
  93.             $mailfetch_user_[$i_loopgetPref($data_dir$username"mailfetch_user_$i_loop");
  94.             $mailfetch_lmos_[$i_loopgetPref($data_dir$username"mailfetch_lmos_$i_loop");
  95.             $mailfetch_uidl_[$i_loopgetPref($data_dir$username"mailfetch_uidl_$i_loop");
  96.             $mailfetch_subfolder_[$i_loopgetPref($data_dir$username"mailfetch_subfolder_$i_loop");
  97.             $mailfetch_auth_[$i_loopgetPref($data_dir$username"mailfetch_auth_$i_loop",MAIL_FETCH_AUTH_USER);
  98.             $mailfetch_type_[$i_loopgetPref($data_dir$username"mailfetch_type_$i_loop",MAIL_FETCH_USE_PLAIN);
  99.  
  100.             $mailfetch_server=$mailfetch_server_[$i_loop];
  101.             $mailfetch_port=$mailfetch_port_[$i_loop];
  102.             $mailfetch_user=$mailfetch_user_[$i_loop];
  103.             $mailfetch_alias=$mailfetch_alias_[$i_loop];
  104.             $mailfetch_pass=$mailfetch_pass_[$i_loop];
  105.             $mailfetch_lmos=$mailfetch_lmos_[$i_loop];
  106.             $mailfetch_login=$mailfetch_login_[$i_loop];
  107.             $mailfetch_uidl=$mailfetch_uidl_[$i_loop];
  108.             $mailfetch_subfolder=$mailfetch_subfolder_[$i_loop];
  109.             $mailfetch_auth=$mailfetch_auth_[$i_loop];
  110.             $mailfetch_type=$mailfetch_type_[$i_loop];
  111.             // end of what the heck
  112.  
  113.  
  114.             // $outMsg .= "$mailfetch_alias checked<br />";
  115.  
  116.             // $outMsg .= "$mailfetch_alias_[$i_loop]<br />";
  117.  
  118.             // FIXME: duplicate code with different output destination.
  119.  
  120.             $pop3 new mail_fetch(array('host'    => $mailfetch_server,
  121.                                          'port'    => $mailfetch_port,
  122.                                          'auth'    => $mailfetch_auth,
  123.                                          'tls'     => $mailfetch_type,
  124.                                          'timeout' => 60));
  125.  
  126.             if (!empty($pop3->error)) {
  127.                 $outMsg .= _("Warning:"' ' $pop3->error;
  128.                 continue;
  129.             }
  130.  
  131.             $imap_stream sqimap_login($usernamefalse$imapServerAddress$imapPort10$imap_stream_options);
  132.  
  133.             /* log into pop server*/
  134.             if ($pop3->login($mailfetch_user$mailfetch_pass)) {
  135.                 $outMsg .= _("Login Failed:"' ' $pop3->error;
  136.                 continue;
  137.             }
  138.  
  139.             $aMsgStat $pop3->command_stat();
  140.             if (is_bool($aMsgStat)) {
  141.                 $outMsg .= _("Can't get mailbox status:"' ' sm_encode_html_special_chars($pop3->error);
  142.                 continue;
  143.             }
  144.  
  145.             $Count $aMsgStat['count'];
  146.  
  147.             $i 1;
  148.  
  149.             if ($Count>0{
  150.                 // If we leave messages on server, try using UIDL
  151.                 if ($mailfetch_lmos == 'on'{
  152.                     $msglist $pop3->command_uidl();
  153.                     if (is_bool($msglist)) {
  154.                         $outMsg .= _("Server does not support UIDL."' '.sm_encode_html_special_chars($pop3->error);
  155.                         // User asked to leave messages on server, but we can't do that.
  156.                         $pop3->command_quit();
  157.                         continue;
  158.                         // $mailfetch_lmos = 'off';
  159.                     else {
  160.                         // calculate number of new messages
  161.                         for ($j 1$j <= sizeof($msglist)$j++{
  162.                             // do strict comparison ('1111.10' should not be equal to '1111.100')
  163.                             if ($msglist[$j=== $mailfetch_uidl{
  164.                                 $i $j+1;
  165.                                 break;
  166.                             }
  167.                         }
  168.                     }
  169.                 }
  170.                 // fetch list of messages with LIST
  171.                 // we can use else control, but we can also set $mailfetch_lmos 
  172.                 // to off if server does not support UIDL.
  173.                 if ($mailfetch_lmos != 'on'{
  174.                     $msglist $pop3->command_list();
  175.                 }
  176.             }
  177.  
  178.             if ($Count $i{
  179.                 $pop3->command_quit();
  180.                 continue;
  181.             }
  182.             if ($Count == 0{
  183.                 $pop3->command_quit();
  184.                 continue;
  185.             }
  186.  
  187.             for ($i <= $Count$i++{
  188.                 if (!ini_get('safe_mode'))
  189.                     set_time_limit(20)// 20 seconds per message max
  190.                 $Message $pop3->command_retr($i);
  191.  
  192.                 if (is_bool($Message)) {
  193.                     $outMsg .= _("Warning:"' ' sm_encode_html_special_chars($pop3->error);
  194.                     continue;
  195.                 }
  196.  
  197.                 // check if mail folder is not null and subscribed (There is possible issue with /noselect mail folders)
  198.                 if ($mailfetch_subfolder=='' ||
  199.                     mail_fetch_check_folder($imap_stream,$mailfetch_subfolder)) {
  200.                     fputs($imap_stream"A3$i APPEND INBOX {strlen($Message"}\r\n");
  201.                 else {
  202.                     fputs($imap_stream"A3$i APPEND $mailfetch_subfolder {strlen($Message"}\r\n");
  203.                 }
  204.                 $Line fgets($imap_stream1024);
  205.                 if (substr($Line01== '+'{
  206.                     fputs($imap_stream$Message);
  207.                     fputs($imap_stream"\r\n");
  208.                     sqimap_read_data($imap_stream"A3$i"false$response$message);
  209.  
  210.                     // Check results of append command
  211.                     $response=(implode('',$response));
  212.                     $message=(implode('',$message));
  213.                     if ($response != 'OK'{
  214.                         $outMsg .= _("Error Appending Message!")." ".sm_encode_html_special_chars($message);
  215.  
  216.                         if ($mailfetch_lmos == 'on'{
  217.                             setPref($data_dir,$username,"mailfetch_uidl_$i_loop"$msglist[$i-1]);
  218.                         }
  219.                         // Destroy msg list in order to prevent UIDL update
  220.                         $msglist false;
  221.                         // if append fails, don't download other messages
  222.                         break;
  223.                     }
  224.  
  225.                     if ($mailfetch_lmos != 'on'{
  226.                         $pop3->command_dele($i);
  227.                     }
  228.                 else {
  229.                     echo "$Line";
  230.                     $outMsg .= _("Error Appending Message!");
  231.                 }
  232.             }
  233.  
  234.             $pop3->command_quit();
  235.             sqimap_logout($imap_stream);
  236.             if ($mailfetch_lmos == 'on' && is_array($msglist)) {
  237.                 setPref($data_dir,$username,"mailfetch_uidl_$i_loop"array_pop($msglist));
  238.             }
  239.         }
  240.     }
  241.  
  242.     iftrim$outMsg <> '' {
  243.         echo '<br /><font size="1">' _("Mail Fetch Result:""<br />$outMsg</font>";
  244.     }
  245.     if$mailfetch_newlog == 'on' {
  246.         setPref($data_dir$username'mailfetch_newlog''off');
  247.     }
  248. }
  249.  
  250. /**
  251.  * Internal function used to detect new logins
  252.  */
  253.     global $data_dir$username;
  254.  
  255.     setPref$data_dir$username'mailfetch_newlog''on' );
  256. }
  257.  
  258. /**
  259.  * Internal function used to register option block
  260.  * @since 1.5.1
  261.  * @private
  262.  */
  263.     global $optpage_blocks;
  264.  
  265.     $optpage_blocks[array(
  266.             'name' => _("POP3 Fetch Mail"),
  267.             'url'  => '../plugins/mail_fetch/options.php',
  268.             'desc' => _("This configures settings for downloading email from a POP3 mailbox to your account on this server."),
  269.             'js'   => false
  270.             );
  271. }
  272.  
  273. /**
  274.  * Internal function used to update mail_fetch settings
  275.  * when folders are renamed or deleted.
  276.  * @since 1.5.1
  277.  * @private
  278.  */
  279. function mail_fetch_folderact_function($args{
  280.     global $username$data_dir;
  281.  
  282.     if (empty($args|| !is_array($args)) {
  283.         return;
  284.     }
  285.  
  286.     /* Should be 3 ars, 1: old folder, 2: action, 3: new folder */
  287.     if (count($args!= 3{
  288.         return;
  289.     }
  290.  
  291.     list($old_folder$action$new_folder$args;
  292.  
  293.     $mailfetch_server_number getPref($data_dir$username'mailfetch_server_number');
  294.  
  295.     for ($i 0$i $mailfetch_server_number$i++{
  296.         $mailfetch_subfolder getPref($data_dir$username'mailfetch_subfolder_' $i);
  297.  
  298.         if ($mailfetch_subfolder != $old_folder{
  299.             continue;
  300.         }
  301.  
  302.         if ($action == 'delete'{
  303.             setPref($data_dir$username'mailfetch_subfolder_' $i'INBOX');
  304.         elseif ($action == 'rename'{
  305.             setPref($data_dir$username'mailfetch_subfolder_' $i$new_folder);
  306.         }
  307.     }
  308. }
  309. // end of hooked functions
  310.  
  311. /**
  312.  * hex2bin - convert a hexadecimal string into binary
  313.  * Exists since PHP 5.4.
  314.  */
  315. if function_exists('hex2bin') ) {
  316.     function hex2bin$data {
  317.  
  318.         /* Original code by [email protected] */
  319.  
  320.         $len strlen($data);
  321.         $newdata '';
  322.         for$i=0$i $len$i += {
  323.             $newdata .= pack"C"hexdecsubstr$data$i2) ) );
  324.         }
  325.         return $newdata;
  326.     }
  327. }
  328.  
  329. function mf_keyED$txt {
  330.  
  331.     global $MF_TIT;
  332.  
  333.     if!isset$MF_TIT ) ) {
  334.         $MF_TIT "MailFetch Secure for SquirrelMail 1.x";
  335.     }
  336.  
  337.     $encrypt_key md5$MF_TIT );
  338.     $ctr 0;
  339.     $tmp "";
  340.     for$i 0$i strlen$txt )$i++ {
  341.         if$ctr == strlen$encrypt_key ) ) $ctr=0;
  342.         $tmp.= substr$txt$isubstr$encrypt_key$ctr);
  343.         $ctr++;
  344.     }
  345.     return $tmp;
  346. }
  347.  
  348. function encrypt$txt {
  349.  
  350.     srand(double) microtime(1000000 );
  351.     $encrypt_key md5rand032000 ) );
  352.     $ctr 0;
  353.     $tmp "";
  354.     for$i 0$i strlen$txt )$i++ {
  355.         if ($ctr==strlen($encrypt_key)) $ctr=0;
  356.         $tmp.= substr($encrypt_key,$ctr,1.
  357.             (substr($txt,$i,1substr($encrypt_key,$ctr,1));
  358.         $ctr++;
  359.     }
  360.     return bin2hexmf_keyED$tmp ) );
  361.  
  362. }
  363.  
  364. function decrypt$txt {
  365.  
  366.     $txt mf_keyEDhex2bin$txt ) );
  367.     $tmp '';
  368.     for $i=0$i strlen$txt )$i++ {
  369.         $md5 substr$txt$i);
  370.         $i++;
  371.         $tmp.= substr$txt$i$md5 );
  372.     }
  373.     return $tmp;
  374. }
  375.  
  376. /**
  377.  * check mail folder
  378.  * @param stream $imap_stream imap connection resource
  379.  * @param string $imap_folder imap folder name
  380.  * @return boolean true, when folder can be used to store messages.
  381.  * @since 1.5.1 and 1.4.5
  382.  */
  383. function mail_fetch_check_folder($imap_stream,$imap_folder{
  384.  
  385.     // check if folder is subscribed or only exists.
  386.     if (sqimap_mailbox_is_subscribed($imap_stream,$imap_folder)) {
  387.         $ret true;
  388.     elseif ($mail_fetch_allow_unsubscribed && sqimap_mailbox_exists($imap_stream,$imap_folder)) {
  389.         $ret true;
  390.     else {
  391.         $ret false;
  392.     }
  393.  
  394.     // make sure that folder can store messages
  395.     if ($ret && mail_fetch_check_noselect($imap_stream,$imap_folder)) {
  396.         $ret false;
  397.     }
  398.  
  399.     return $ret;
  400. }
  401.  
  402. /**
  403.  * Checks if folder is noselect (can't store messages)
  404.  *
  405.  * Function does not check if folder subscribed.
  406.  * @param stream $imap_stream imap connection resource
  407.  * @param string $imap_folder imap folder name
  408.  * @return boolean true, when folder has noselect flag. false in any other case.
  409.  * @since 1.5.1 and 1.4.5
  410.  */
  411. function mail_fetch_check_noselect($imap_stream,$imap_folder{
  412.     $boxes=sqimap_mailbox_list($imap_stream);
  413.     foreach($boxes as $box{
  414.         if ($box['unformatted']==$imap_folder{
  415.             return (bool) check_is_noselect($box['raw']);
  416.         }
  417.     }
  418.     return false;
  419. }
  420.  
  421. /**
  422.   * Validate a requested POP3 port number
  423.   *
  424.   * Allowable port numbers are configured in config.php
  425.   * (see config_example.php for an example and more
  426.   * rules about how the list of allowable port numbers
  427.   * can be specified)
  428.   *
  429.   * @param int $requested_port The port number given by the user
  430.   *
  431.   * @return string An error string is returned if the port
  432.   *                 number is not allowable, otherwise an
  433.   *                 empty string is returned.
  434.   *
  435.   */
  436. function validate_mail_fetch_port_number($requested_port{
  437.     global $mail_fetch_allowable_ports;
  438.     if (empty($mail_fetch_allowable_ports))
  439.         $mail_fetch_allowable_ports array(110995);
  440.  
  441.     if (in_array('ALL'$mail_fetch_allowable_ports))
  442.         return '';
  443.  
  444.     if (!in_array($requested_port$mail_fetch_allowable_ports)) {
  445.         sq_change_text_domain('mail_fetch');
  446.         $error _("Sorry, that port number is not allowed");
  447.         sq_change_text_domain('squirrelmail');
  448.         return $error;
  449.     }
  450.  
  451.     return '';
  452. }
  453.  
  454. /**
  455.   * Validate a requested POP3 server address
  456.   *
  457.   * Blocked server addresses are configured in config.php
  458.   * (see config_example.php for more details)
  459.   *
  460.   * @param int $requested_address The server address given by the user
  461.   *
  462.   * @return string An error string is returned if the server
  463.   *                 address is not allowable, otherwise an
  464.   *                 empty string is returned.
  465.   *
  466.   */
  467. function validate_mail_fetch_server_address($requested_address{
  468.     global $mail_fetch_block_server_pattern;
  469.     if (empty($mail_fetch_block_server_pattern))
  470.         $mail_fetch_block_server_pattern '/(^10\.)|(^192\.)|(^127\.)|(^localhost)/';
  471.  
  472.     if ($mail_fetch_block_server_pattern == 'UNRESTRICTED')
  473.         return '';
  474.  
  475.     if (preg_match($mail_fetch_block_server_pattern$requested_address)) {
  476.         sq_change_text_domain('mail_fetch');
  477.         $error _("Sorry, that server address is not allowed");
  478.         sq_change_text_domain('squirrelmail');
  479.         return $error;
  480.     }
  481.  
  482.     return '';
  483. }

Documentation generated on Mon, 13 Jan 2020 04:22:34 +0100 by phpDocumentor 1.4.3