mcramer
2012-09-27 d6363ba9dd38e98c8f2d48085677c4bafdfdc7cd
Fixed: Added missing idn converts to mail functions
Added: Changed idn function to support multi-line fields (like mail forward)

9 files modified
172 ■■■■■ changed files
interface/lib/classes/functions.inc.php 88 ●●●● patch | view | raw | blame | history
interface/lib/classes/tform.inc.php 11 ●●●●● patch | view | raw | blame | history
interface/web/mail/form/mail_user.tform.php 7 ●●●●● patch | view | raw | blame | history
interface/web/mail/list/mail_user.list.php 3 ●●●●● patch | view | raw | blame | history
interface/web/mail/mail_alias_edit.php 10 ●●●●● patch | view | raw | blame | history
interface/web/mail/mail_aliasdomain_edit.php 15 ●●●● patch | view | raw | blame | history
interface/web/mail/mail_domain_catchall_edit.php 12 ●●●●● patch | view | raw | blame | history
interface/web/mail/mail_forward_edit.php 12 ●●●●● patch | view | raw | blame | history
interface/web/mail/mail_user_edit.php 14 ●●●●● patch | view | raw | blame | history
interface/lib/classes/functions.inc.php
@@ -315,7 +315,7 @@
    /** IDN converter wrapper.
     * all converter classes should be placed in ISPC_CLASS_PATH.'/idn/'
     */
    public function idn_encode($domain) {
    private function _idn_encode_decode($domain, $encode = true) {
        if($domain == '') return '';
        if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee encoded
        
@@ -326,56 +326,60 @@
            $domain = substr($domain, strrpos($domain, '@') + 1);
        }
        
        if(function_exists('idn_to_ascii')) {
            $domain = idn_to_ascii($domain);
        } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
             /* use idna class:
             * @author  Matthias Sommerfeld <mso@phlylabs.de>
             * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
             * @version 0.8.0 2011-03-11
             */
            if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
                include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
                $this->idn_converter = new idna_convert(array('idn_version' => 2008));
                $this->idn_converter_name = 'idna_convert.class';
        if($encode == true) {
            if(function_exists('idn_to_ascii')) {
                $domain = idn_to_ascii($domain);
            } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
                 /* use idna class:
                 * @author  Matthias Sommerfeld <mso@phlylabs.de>
                 * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
                 * @version 0.8.0 2011-03-11
                 */
                if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
                    include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
                    $this->idn_converter = new idna_convert(array('idn_version' => 2008));
                    $this->idn_converter_name = 'idna_convert.class';
                }
                $domain = $this->idn_converter->encode($domain);
            }
            $domain = $this->idn_converter->encode($domain);
        } else {
            if(function_exists('idn_to_utf8')) {
                $domain = idn_to_utf8($domain);
            } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
                 /* use idna class:
                 * @author  Matthias Sommerfeld <mso@phlylabs.de>
                 * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
                 * @version 0.8.0 2011-03-11
                 */
                if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
                    include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
                    $this->idn_converter = new idna_convert(array('idn_version' => 2008));
                    $this->idn_converter_name = 'idna_convert.class';
                }
                $domain = $this->idn_converter->decode($domain);
            }
        }
        
        if($user_part !== false) return $user_part . '@' . $domain;
        else return $domain;
    }
    public function idn_encode($domain) {
        $domains = explode("\n", $domain);
        for($d = 0; $d < count($domains); $d++) {
            $domains[$d] = $this->_idn_encode_decode($domains[$d], true);
        }
        return implode("\n", $domains);
    }
    
    public function idn_decode($domain) {
        if($domain == '') return '';
        if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee decoded
        // get domain and user part if it is an email
        $user_part = false;
        if(strpos($domain, '@') !== false) {
            $user_part = substr($domain, 0, strrpos($domain, '@'));
            $domain = substr($domain, strrpos($domain, '@') + 1);
        $domains = explode("\n", $domain);
        for($d = 0; $d < count($domains); $d++) {
            $domains[$d] = $this->_idn_encode_decode($domains[$d], false);
        }
        if(function_exists('idn_to_utf8')) {
            $domain = idn_to_utf8($domain);
        } elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
             /* use idna class:
             * @author  Matthias Sommerfeld <mso@phlylabs.de>
             * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
             * @version 0.8.0 2011-03-11
             */
            if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
                include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
                $this->idn_converter = new idna_convert(array('idn_version' => 2008));
                $this->idn_converter_name = 'idna_convert.class';
            }
            $domain = $this->idn_converter->decode($domain);
        }
        if($user_part !== false) return $user_part . '@' . $domain;
        else return $domain;
        return implode("\n", $domains);
    }
        
}
interface/lib/classes/tform.inc.php
@@ -276,6 +276,17 @@
                                $this->errorMessage .= "Custom datasource class or function is empty<br />\r\n";
                        }
                }
                if(isset($field['filters']) && is_array($field['filters'])) {
                    $new_values = array();
                    foreach($values as $index => $value) {
                        $new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
                        $new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
                    }
                    $values = $new_values;
                    unset($new_values);
                    unset($new_index);
                }
                return $values;
interface/web/mail/form/mail_user.tform.php
@@ -96,6 +96,13 @@
    'login' => array (
      'datatype'  => 'VARCHAR',
      'formtype'  => 'TEXT',
            'filters'   => array( 0 => array( 'event' => 'SAVE',
                                              'type' => 'IDNTOASCII'),
                                  1 => array( 'event' => 'SHOW',
                                              'type' => 'IDNTOUTF8'),
                                  2 => array( 'event' => 'SAVE',
                                              'type' => 'TOLOWER')
                                ),
      'validators'  => array (
                    0 => array (  'type'  => 'UNIQUE',
                            'errmsg'=> 'login_error_unique'),
interface/web/mail/list/mail_user.list.php
@@ -61,6 +61,9 @@
$liste["item"][] = array(   'field'     => "login",
                            'datatype'  => "VARCHAR",
                            'filters'   => array( 0 => array( 'event' => 'SHOW',
                                                              'type' => 'IDNTOUTF8')
                                                ),
                            'formtype'  => "TEXT",
                            'op'        => "like",
                            'prefix'    => "%",
interface/web/mail/mail_alias_edit.php
@@ -72,6 +72,7 @@
        $email = $this->dataRecord["source"];
        $email_parts = explode("@",$email);
        $app->tpl->setVar("email_local_part",$email_parts[0]);
        $email_parts[1] = $app->functions->idn_decode($email_parts[1]);
        
        // Getting Domains of the user
        // $sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
@@ -80,6 +81,7 @@
        $domain_select = '';
        if(is_array($domains)) {
            foreach( $domains as $domain) {
                $domain['domain'] = $app->functions->idn_decode($domain['domain']);
                $selected = ($domain["domain"] == @$email_parts[1])?'SELECTED':'';
                $domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
            }
@@ -93,8 +95,8 @@
        global $app, $conf;
        
        // Check if Domain belongs to user
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        
        // Check the client limits, if user is not the admin
        if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -114,7 +116,7 @@
        
                 
        // compose the email field
        $this->dataRecord["source"] = $_POST["email_local_part"]."@".$_POST["email_domain"];
        $this->dataRecord["source"] = $_POST["email_local_part"]."@".$app->functions->idn_encode($_POST["email_domain"]);
        // Set the server id of the mailbox = server ID of mail domain.
        $this->dataRecord["server_id"] = $domain["server_id"];
        
@@ -141,7 +143,7 @@
    function onAfterInsert() {
        global $app;
        
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        $app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
        
    }
interface/web/mail/mail_aliasdomain_edit.php
@@ -69,8 +69,8 @@
    function onShowEnd() {
        global $app, $conf;
        
        $source_domain = substr($this->dataRecord["source"],1);
        $destination_domain = substr($this->dataRecord["destination"],1);
        $source_domain = $app->functions->idn_decode(substr($this->dataRecord["source"],1));
        $destination_domain = $app->functions->idn_decode(substr($this->dataRecord["destination"],1));
        
        // Getting Domains of the user
        $sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
@@ -80,6 +80,7 @@
        $destination_select = '';
        if(is_array($domains)) {
            foreach( $domains as $domain) {
                $domain['domain'] = $app->functions->idn_decode($domain['domain']);
                $selected = ($domain["domain"] == @$source_domain)?'SELECTED':'';
                $source_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
                $selected = ($domain["domain"] == @$destination_domain)?'SELECTED':'';
@@ -96,12 +97,12 @@
        global $app, $conf;
        
        // Check if source Domain belongs to user
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["source"])."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $_POST["source"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["source"]))."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $app->functions->idn_encode($_POST["source"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        
        // Check if the destination domain belongs to the user
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["destination"])."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $_POST["destination"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["destination"]))."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $app->functions->idn_encode($_POST["destination"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        
        // Check the client limits, if user is not the admin
        if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -127,7 +128,7 @@
    function onAfterInsert() {
        global $app;
        
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["destination"])."' AND ".$app->tform->getAuthSQL('r'));
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["destination"]))."' AND ".$app->tform->getAuthSQL('r'));
        $app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
        
    }
interface/web/mail/mail_domain_catchall_edit.php
@@ -72,13 +72,15 @@
        $email = $this->dataRecord["source"];
        $email_parts = explode("@",$email);
        $app->tpl->setVar("email_local_part",$email_parts[0]);
        $email_parts[1] = $app->functions->idn_decode($email_parts[1]);
        // Getting Domains of the user
        $sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r');
        $domains = $app->db->queryAllRecords($sql);
        $domain_select = '';
        if(is_array($domains)) {
            foreach( $domains as $domain) {
                $domain['domain'] = $app->functions->idn_decode($domain['domain']);
                $selected = (isset($email_parts[1]) && $domain["domain"] == $email_parts[1])?'SELECTED':'';
                $domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
            }
@@ -92,8 +94,8 @@
        global $app, $conf;
        
        // Check if Domain belongs to user
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        
        // Check the client limits, if user is not the admin
        if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -112,7 +114,7 @@
        } // end if user is not admin
                 
        // compose the email field
        $this->dataRecord["source"] = "@".$_POST["email_domain"];
        $this->dataRecord["source"] = "@".$app->functions->idn_encode($_POST["email_domain"]);
        // Set the server id of the mailbox = server ID of mail domain.
        $this->dataRecord["server_id"] = $domain["server_id"];
        
@@ -125,7 +127,7 @@
    function onAfterInsert() {
        global $app;
        
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        $app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
        
    }
interface/web/mail/mail_forward_edit.php
@@ -72,13 +72,15 @@
        $email = $this->dataRecord["source"];
        $email_parts = explode("@",$email);
        $app->tpl->setVar("email_local_part",$email_parts[0]);
        $email_parts[1] = $app->functions->idn_decode($email_parts[1]);
        // Getting Domains of the user
        //$sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
        $sql = "SELECT domain FROM mail_domain WHERE domain NOT IN (SELECT SUBSTR(source,2) FROM mail_forwarding WHERE type = 'aliasdomain') AND ".$app->tform->getAuthSQL('r')." ORDER BY domain";
        $domains = $app->db->queryAllRecords($sql);
        $domain_select = '';
        foreach( $domains as $domain) {
            $domain['domain'] = $app->functions->idn_decode($domain['domain']);
            $selected = (isset($email_parts[1]) && $domain["domain"] == $email_parts[1])?'SELECTED':'';
            $domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
        }
@@ -91,8 +93,8 @@
        global $app, $conf;
        
        // Check if Domain belongs to user
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
        
        // Check the client limits, if user is not the admin
        if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -111,7 +113,7 @@
        } // end if user is not admin
                 
        // compose the email field
        $this->dataRecord["source"] = $_POST["email_local_part"]."@".$_POST["email_domain"];
        $this->dataRecord["source"] = $_POST["email_local_part"]."@".$app->functions->idn_encode($_POST["email_domain"]);
        // Set the server id of the mailbox = server ID of mail domain.
        $this->dataRecord["server_id"] = $domain["server_id"];
        
@@ -129,7 +131,7 @@
    function onAfterInsert() {
        global $app;
        
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        $domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        $app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
        
    }
interface/web/mail/mail_user_edit.php
@@ -73,7 +73,8 @@
        $email = $this->dataRecord["email"];
        $email_parts = explode("@",$email);
        $app->tpl->setVar("email_local_part",$email_parts[0]);
        $email_parts[1] = $app->functions->idn_decode($email_parts[1]);
        // Getting Domains of the user
        // $sql = "SELECT domain, server_id FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
        $sql = "SELECT domain, server_id FROM mail_domain WHERE domain NOT IN (SELECT SUBSTR(source,2) FROM mail_forwarding WHERE type = 'aliasdomain') AND ".$app->tform->getAuthSQL('r')." ORDER BY domain";
@@ -81,6 +82,7 @@
        $domain_select = '';
        if(is_array($domains)) {
            foreach( $domains as $domain) {
                $domain['domain'] = $app->functions->idn_decode($domain['domain']);
                $selected = ($domain["domain"] == @$email_parts[1])?'SELECTED':'';
                $domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
            }
@@ -131,8 +133,8 @@
        
        //* Check if Domain belongs to user
        if(isset($_POST["email_domain"])) {
            $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
            if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm");
            $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
            if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm");
        }
        
        
@@ -179,7 +181,7 @@
        
        //* compose the email field
        if(isset($_POST["email_local_part"]) && isset($_POST["email_domain"])) {
            $this->dataRecord["email"] = strtolower($_POST["email_local_part"]."@".$_POST["email_domain"]);
            $this->dataRecord["email"] = strtolower($_POST["email_local_part"]."@".$app->functions->idn_encode($_POST["email_domain"]));
        
            // Set the server id of the mailbox = server ID of mail domain.
            $this->dataRecord["server_id"] = $domain["server_id"];
@@ -225,7 +227,7 @@
        global $app, $conf;
        
        // Set the domain owner as mailbox owner
        $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
        $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
        $app->db->query("UPDATE mail_user SET sys_groupid = ".$domain["sys_groupid"]." WHERE mailuser_id = ".$this->id);
        
        // Spamfilter policy
@@ -261,7 +263,7 @@
        
        // Set the domain owner as mailbox owner
        if(isset($_POST["email_domain"])) {
            $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
            $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM mail_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["email_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
            $app->db->query("UPDATE mail_user SET sys_groupid = ".$domain["sys_groupid"]." WHERE mailuser_id = ".$this->id);
        
            // Spamfilter policy