Improve SMTPUTF8 support and fix relaxed email validation issues

pull/6116/head
Aleksander Machniak 7 years ago
parent 5665344673
commit 63a7d2313f

@ -226,6 +226,14 @@ class rcube_smtp
return false;
}
// prepare list of recipients
$recipients = $this->_parse_rfc822($recipients);
if (is_a($recipients, 'PEAR_Error')) {
$this->error = array('label' => 'smtprecipientserror');
$this->reset();
return false;
}
$exts = $this->conn->getServiceExtensions();
// RFC3461: Delivery Status Notification
@ -235,23 +243,20 @@ class rcube_smtp
$recipient_params = 'NOTIFY=SUCCESS,FAILURE';
}
}
//RFC6531: request smtputf8 if needed
if (
!mb_check_encoding($from,'ASCII') ||
!mb_check_encoding($recipients,'ASCII')
) {
// RFC6531: request SMTPUTF8 if needed
if (preg_match('/[^\x00-\x7F]/', $from . implode('', $recipients))) {
if (isset($exts['SMTPUTF8'])) {
if (!empty($from_params)) {
$from_params .= ' ';
}
$from_params .= 'SMTPUTF8';
}
else {
return false;
}
$from_params = ltrim($from_params . ' SMTPUTF8');
}
else {
$this->error = array('label' => 'smtputf8error');
$this->response[] = "SMTP server does not support unicode in email addresses";
$this->reset();
return false;
}
}
// RFC2298.3: remove envelope sender address
if (empty($opts['mdn_use_from'])
&& preg_match('/Content-Type: multipart\/report/', $text_headers)
@ -272,14 +277,6 @@ class rcube_smtp
return false;
}
// prepare list of recipients
$recipients = $this->_parse_rfc822($recipients);
if (is_a($recipients, 'PEAR_Error')) {
$this->error = array('label' => 'smtprecipientserror');
$this->reset();
return false;
}
// set mail recipients
foreach ($recipients as $recipient) {
$result = $this->conn->rcptTo($recipient, $recipient_params);

@ -63,7 +63,7 @@ class rcube_utils
*/
public static function check_email($email, $dns_check=true)
{
// Check for invalid characters
// Check for invalid (control) characters
if (preg_match('/\p{Cc}/u', $email)) {
return false;
}
@ -73,41 +73,28 @@ class rcube_utils
return false;
}
$email_array = explode('@', $email);
// Check that there's one @ symbol
if (count($email_array) < 2) {
return false;
}
$domain_part = array_pop($email_array);
$local_part = implode('@', $email_array);
// XXX RFC states that ".." is not allowed in a local-part
// of an email address, but apparently gmail allows it.
if(preg_match('/^\.|\.$/',$local_part)) {
$pos = strrpos($email, '@');
if (!$pos) {
return false;
}
$local_subparts;
preg_match_all('/"(?:\\\\.|[^\\\\"])*"|[^\.]+/',$local_part,$local_subparts);
$domain_part = substr($email, $pos + 1);
$local_part = substr($email, 0, $pos);
foreach ($local_subparts[0] as $l) {
if(substr($l,0,1) == '"') {
// quoted-string, make sure all backslashes and quotes are
// escaped
$local_quoted = preg_replace('/\\\\(\\\\|\")/','',substr($l,1,-1));
if(preg_match('/\\\\|"/',$local_quoted)) {
return false;
}
}
else {
// dot-atom portion, make sure there's no prohibited characters
if(preg_match('/[\\ ",:;<>@]/',$l)) {
return false;
}
// quoted-string, make sure all backslashes and quotes are
// escaped
if (substr($local_part,0,1) == '"') {
$local_quoted = preg_replace('/\\\\(\\\\|\")/','', substr($local_part, 1, -1));
if (preg_match('/\\\\|"/', $local_quoted)) {
return false;
}
}
// dot-atom portion, make sure there's no prohibited characters
else if (preg_match('/(^\.|\.\.|\.$)/', $local_part)
|| preg_match('/[\\ ",:;<>@]/', $local_part)
) {
return false;
}
// Validate domain part
if (preg_match('/^\[((IPv6:[0-9a-f:.]+)|([0-9.]+))\]$/i', $domain_part, $matches)) {

@ -167,6 +167,7 @@ $messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed.';
$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from" ($msg).';
$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to" ($msg).';
$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list.';
$messages['smtputf8error'] = 'SMTP Error: Server does not support unicode in email address.';
$messages['smtpsizeerror'] = 'SMTP Error: Message size exceeds server limit ($limit)';
$messages['smtperror'] = 'SMTP Error: $msg';
$messages['emailformaterror'] = 'Invalid email address: $email';

@ -30,6 +30,7 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
array('email@domain.co.jp', 'Dot in Top Level Domain name also considered valid (use co.jp as example here)'),
array('firstname-lastname@domain.com', 'Dash in address field is valid'),
array('test@xn--e1aaa0cbbbcacac.xn--p1ai', 'IDNA domain'),
array('あいうえお@domain.com', 'Unicode char as address'),
);
}
@ -48,7 +49,6 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
array('.email@domain.com', 'Leading dot in address is not allowed'),
array('email.@domain.com', 'Trailing dot in address is not allowed'),
array('email..email@domain.com', 'Multiple dots'),
array('あいうえお@domain.com', 'Unicode char as address'),
array('email@domain.com (Joe Smith)', 'Text followed email is not allowed'),
array('email@domain', 'Missing top level domain (.com/.net/.org/etc)'),
array('email@-domain.com', 'Leading dash in front of domain is invalid'),

Loading…
Cancel
Save