Skip to content

Commit d6363ba

Browse files
author
mcramer
committed
Fixed: Added missing idn converts to mail functions
Added: Changed idn function to support multi-line fields (like mail forward)
1 parent 8c1761c commit d6363ba

File tree

9 files changed

+103
-69
lines changed

9 files changed

+103
-69
lines changed

interface/lib/classes/functions.inc.php

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ public function intval($string, $force_numeric = false) {
315315
/** IDN converter wrapper.
316316
* all converter classes should be placed in ISPC_CLASS_PATH.'/idn/'
317317
*/
318-
public function idn_encode($domain) {
318+
private function _idn_encode_decode($domain, $encode = true) {
319319
if($domain == '') return '';
320320
if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee encoded
321321

@@ -326,56 +326,60 @@ public function idn_encode($domain) {
326326
$domain = substr($domain, strrpos($domain, '@') + 1);
327327
}
328328

329-
if(function_exists('idn_to_ascii')) {
330-
$domain = idn_to_ascii($domain);
331-
} elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
332-
/* use idna class:
333-
* @author Matthias Sommerfeld <mso@phlylabs.de>
334-
* @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
335-
* @version 0.8.0 2011-03-11
336-
*/
337-
338-
if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
339-
include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
340-
$this->idn_converter = new idna_convert(array('idn_version' => 2008));
341-
$this->idn_converter_name = 'idna_convert.class';
329+
if($encode == true) {
330+
if(function_exists('idn_to_ascii')) {
331+
$domain = idn_to_ascii($domain);
332+
} elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
333+
/* use idna class:
334+
* @author Matthias Sommerfeld <mso@phlylabs.de>
335+
* @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
336+
* @version 0.8.0 2011-03-11
337+
*/
338+
339+
if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
340+
include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
341+
$this->idn_converter = new idna_convert(array('idn_version' => 2008));
342+
$this->idn_converter_name = 'idna_convert.class';
343+
}
344+
$domain = $this->idn_converter->encode($domain);
345+
}
346+
} else {
347+
if(function_exists('idn_to_utf8')) {
348+
$domain = idn_to_utf8($domain);
349+
} elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
350+
/* use idna class:
351+
* @author Matthias Sommerfeld <mso@phlylabs.de>
352+
* @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
353+
* @version 0.8.0 2011-03-11
354+
*/
355+
356+
if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
357+
include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
358+
$this->idn_converter = new idna_convert(array('idn_version' => 2008));
359+
$this->idn_converter_name = 'idna_convert.class';
360+
}
361+
$domain = $this->idn_converter->decode($domain);
342362
}
343-
$domain = $this->idn_converter->encode($domain);
344363
}
345364

346365
if($user_part !== false) return $user_part . '@' . $domain;
347366
else return $domain;
348367
}
368+
369+
public function idn_encode($domain) {
370+
$domains = explode("\n", $domain);
371+
for($d = 0; $d < count($domains); $d++) {
372+
$domains[$d] = $this->_idn_encode_decode($domains[$d], true);
373+
}
374+
return implode("\n", $domains);
375+
}
349376

350377
public function idn_decode($domain) {
351-
if($domain == '') return '';
352-
if(preg_match('/^[0-9\.]+$/', $domain)) return $domain; // may be an ip address - anyway does not need to bee decoded
353-
354-
// get domain and user part if it is an email
355-
$user_part = false;
356-
if(strpos($domain, '@') !== false) {
357-
$user_part = substr($domain, 0, strrpos($domain, '@'));
358-
$domain = substr($domain, strrpos($domain, '@') + 1);
378+
$domains = explode("\n", $domain);
379+
for($d = 0; $d < count($domains); $d++) {
380+
$domains[$d] = $this->_idn_encode_decode($domains[$d], false);
359381
}
360-
if(function_exists('idn_to_utf8')) {
361-
$domain = idn_to_utf8($domain);
362-
} elseif(file_exists(ISPC_CLASS_PATH.'/idn/idna_convert.class.php')) {
363-
/* use idna class:
364-
* @author Matthias Sommerfeld <mso@phlylabs.de>
365-
* @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
366-
* @version 0.8.0 2011-03-11
367-
*/
368-
369-
if(!is_object($this->idn_converter) || $this->idn_converter_name != 'idna_convert.class') {
370-
include_once(ISPC_CLASS_PATH.'/idn/idna_convert.class.php');
371-
$this->idn_converter = new idna_convert(array('idn_version' => 2008));
372-
$this->idn_converter_name = 'idna_convert.class';
373-
}
374-
$domain = $this->idn_converter->decode($domain);
375-
}
376-
377-
if($user_part !== false) return $user_part . '@' . $domain;
378-
else return $domain;
382+
return implode("\n", $domains);
379383
}
380384

381385
}

interface/lib/classes/tform.inc.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,17 @@ function getDatasourceData($field, $record) {
276276
$this->errorMessage .= "Custom datasource class or function is empty<br />\r\n";
277277
}
278278
}
279+
280+
if(isset($field['filters']) && is_array($field['filters'])) {
281+
$new_values = array();
282+
foreach($values as $index => $value) {
283+
$new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
284+
$new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
285+
}
286+
$values = $new_values;
287+
unset($new_values);
288+
unset($new_index);
289+
}
279290

280291
return $values;
281292

interface/web/mail/form/mail_user.tform.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@
9696
'login' => array (
9797
'datatype' => 'VARCHAR',
9898
'formtype' => 'TEXT',
99+
'filters' => array( 0 => array( 'event' => 'SAVE',
100+
'type' => 'IDNTOASCII'),
101+
1 => array( 'event' => 'SHOW',
102+
'type' => 'IDNTOUTF8'),
103+
2 => array( 'event' => 'SAVE',
104+
'type' => 'TOLOWER')
105+
),
99106
'validators' => array (
100107
0 => array ( 'type' => 'UNIQUE',
101108
'errmsg'=> 'login_error_unique'),

interface/web/mail/list/mail_user.list.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161

6262
$liste["item"][] = array( 'field' => "login",
6363
'datatype' => "VARCHAR",
64+
'filters' => array( 0 => array( 'event' => 'SHOW',
65+
'type' => 'IDNTOUTF8')
66+
),
6467
'formtype' => "TEXT",
6568
'op' => "like",
6669
'prefix' => "%",

interface/web/mail/mail_alias_edit.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ function onShowEnd() {
7272
$email = $this->dataRecord["source"];
7373
$email_parts = explode("@",$email);
7474
$app->tpl->setVar("email_local_part",$email_parts[0]);
75+
$email_parts[1] = $app->functions->idn_decode($email_parts[1]);
7576

7677
// Getting Domains of the user
7778
// $sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
@@ -80,6 +81,7 @@ function onShowEnd() {
8081
$domain_select = '';
8182
if(is_array($domains)) {
8283
foreach( $domains as $domain) {
84+
$domain['domain'] = $app->functions->idn_decode($domain['domain']);
8385
$selected = ($domain["domain"] == @$email_parts[1])?'SELECTED':'';
8486
$domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
8587
}
@@ -93,8 +95,8 @@ function onSubmit() {
9395
global $app, $conf;
9496

9597
// Check if Domain belongs to user
96-
$domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
97-
if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
98+
$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'));
99+
if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
98100

99101
// Check the client limits, if user is not the admin
100102
if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -114,7 +116,7 @@ function onSubmit() {
114116

115117

116118
// compose the email field
117-
$this->dataRecord["source"] = $_POST["email_local_part"]."@".$_POST["email_domain"];
119+
$this->dataRecord["source"] = $_POST["email_local_part"]."@".$app->functions->idn_encode($_POST["email_domain"]);
118120
// Set the server id of the mailbox = server ID of mail domain.
119121
$this->dataRecord["server_id"] = $domain["server_id"];
120122

@@ -141,7 +143,7 @@ function onSubmit() {
141143
function onAfterInsert() {
142144
global $app;
143145

144-
$domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
146+
$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'));
145147
$app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
146148

147149
}

interface/web/mail/mail_aliasdomain_edit.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ function onShowNew() {
6969
function onShowEnd() {
7070
global $app, $conf;
7171

72-
$source_domain = substr($this->dataRecord["source"],1);
73-
$destination_domain = substr($this->dataRecord["destination"],1);
72+
$source_domain = $app->functions->idn_decode(substr($this->dataRecord["source"],1));
73+
$destination_domain = $app->functions->idn_decode(substr($this->dataRecord["destination"],1));
7474

7575
// Getting Domains of the user
7676
$sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
@@ -80,6 +80,7 @@ function onShowEnd() {
8080
$destination_select = '';
8181
if(is_array($domains)) {
8282
foreach( $domains as $domain) {
83+
$domain['domain'] = $app->functions->idn_decode($domain['domain']);
8384
$selected = ($domain["domain"] == @$source_domain)?'SELECTED':'';
8485
$source_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
8586
$selected = ($domain["domain"] == @$destination_domain)?'SELECTED':'';
@@ -96,12 +97,12 @@ function onSubmit() {
9697
global $app, $conf;
9798

9899
// Check if source Domain belongs to user
99-
$domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["source"])."' AND ".$app->tform->getAuthSQL('r'));
100-
if($domain["domain"] != $_POST["source"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
100+
$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'));
101+
if($domain["domain"] != $app->functions->idn_encode($_POST["source"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
101102

102103
// Check if the destination domain belongs to the user
103-
$domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["destination"])."' AND ".$app->tform->getAuthSQL('r'));
104-
if($domain["domain"] != $_POST["destination"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
104+
$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'));
105+
if($domain["domain"] != $app->functions->idn_encode($_POST["destination"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
105106

106107
// Check the client limits, if user is not the admin
107108
if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -127,7 +128,7 @@ function onSubmit() {
127128
function onAfterInsert() {
128129
global $app;
129130

130-
$domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["destination"])."' AND ".$app->tform->getAuthSQL('r'));
131+
$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'));
131132
$app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
132133

133134
}

interface/web/mail/mail_domain_catchall_edit.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ function onShowEnd() {
7272
$email = $this->dataRecord["source"];
7373
$email_parts = explode("@",$email);
7474
$app->tpl->setVar("email_local_part",$email_parts[0]);
75-
75+
$email_parts[1] = $app->functions->idn_decode($email_parts[1]);
76+
7677
// Getting Domains of the user
7778
$sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r');
7879
$domains = $app->db->queryAllRecords($sql);
7980
$domain_select = '';
8081
if(is_array($domains)) {
8182
foreach( $domains as $domain) {
83+
$domain['domain'] = $app->functions->idn_decode($domain['domain']);
8284
$selected = (isset($email_parts[1]) && $domain["domain"] == $email_parts[1])?'SELECTED':'';
8385
$domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
8486
}
@@ -92,8 +94,8 @@ function onSubmit() {
9294
global $app, $conf;
9395

9496
// Check if Domain belongs to user
95-
$domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
96-
if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
97+
$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'));
98+
if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
9799

98100
// Check the client limits, if user is not the admin
99101
if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -112,7 +114,7 @@ function onSubmit() {
112114
} // end if user is not admin
113115

114116
// compose the email field
115-
$this->dataRecord["source"] = "@".$_POST["email_domain"];
117+
$this->dataRecord["source"] = "@".$app->functions->idn_encode($_POST["email_domain"]);
116118
// Set the server id of the mailbox = server ID of mail domain.
117119
$this->dataRecord["server_id"] = $domain["server_id"];
118120

@@ -125,7 +127,7 @@ function onSubmit() {
125127
function onAfterInsert() {
126128
global $app;
127129

128-
$domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
130+
$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'));
129131
$app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
130132

131133
}

interface/web/mail/mail_forward_edit.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ function onShowEnd() {
7272
$email = $this->dataRecord["source"];
7373
$email_parts = explode("@",$email);
7474
$app->tpl->setVar("email_local_part",$email_parts[0]);
75-
75+
$email_parts[1] = $app->functions->idn_decode($email_parts[1]);
76+
7677
// Getting Domains of the user
7778
//$sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain';
7879
$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";
7980
$domains = $app->db->queryAllRecords($sql);
8081
$domain_select = '';
8182
foreach( $domains as $domain) {
83+
$domain['domain'] = $app->functions->idn_decode($domain['domain']);
8284
$selected = (isset($email_parts[1]) && $domain["domain"] == $email_parts[1])?'SELECTED':'';
8385
$domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
8486
}
@@ -91,8 +93,8 @@ function onSubmit() {
9193
global $app, $conf;
9294

9395
// Check if Domain belongs to user
94-
$domain = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
95-
if($domain["domain"] != $_POST["email_domain"]) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
96+
$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'));
97+
if($domain["domain"] != $app->functions->idn_encode($_POST["email_domain"])) $app->tform->errorMessage .= $app->tform->wordbook["no_domain_perm"];
9698

9799
// Check the client limits, if user is not the admin
98100
if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
@@ -111,7 +113,7 @@ function onSubmit() {
111113
} // end if user is not admin
112114

113115
// compose the email field
114-
$this->dataRecord["source"] = $_POST["email_local_part"]."@".$_POST["email_domain"];
116+
$this->dataRecord["source"] = $_POST["email_local_part"]."@".$app->functions->idn_encode($_POST["email_domain"]);
115117
// Set the server id of the mailbox = server ID of mail domain.
116118
$this->dataRecord["server_id"] = $domain["server_id"];
117119

@@ -129,7 +131,7 @@ function onSubmit() {
129131
function onAfterInsert() {
130132
global $app;
131133

132-
$domain = $app->db->queryOneRecord("SELECT sys_groupid FROM mail_domain WHERE domain = '".$app->db->quote($_POST["email_domain"])."' AND ".$app->tform->getAuthSQL('r'));
134+
$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'));
133135
$app->db->query("update mail_forwarding SET sys_groupid = ".$domain['sys_groupid']." WHERE forwarding_id = ".$this->id);
134136

135137
}

0 commit comments

Comments
 (0)