Support SMTPUTF8, relax email restrictions

If the FROM/TO portions of an email use non-ASCII characters,
check that the SMTP server supports the SMTPUTF8 extension.

Additionally, change some rules for parsing email addresses to
allow for more characters. Basically, SMTPUTF8 states that
nearly any printable character is a valid character in an
email address.
pull/5256/head
John Regan 9 years ago
parent 0b7e26c1bf
commit 0e809364e7

@ -223,15 +223,31 @@ class rcube_smtp
return false;
}
$exts = $this->conn->getServiceExtensions();
// RFC3461: Delivery Status Notification
if ($opts['dsn']) {
$exts = $this->conn->getServiceExtensions();
if (isset($exts['DSN'])) {
$from_params = 'RET=HDRS';
$recipient_params = 'NOTIFY=SUCCESS,FAILURE';
}
}
//RFC6531: request smtputf8 if needed
if (
!mb_check_encoding($from,'ASCII') ||
!mb_check_encoding($recipients,'ASCII')
) {
if (isset($exts['SMTPUTF8'])) {
if (!empty($from_params)) {
$from_params .= ' ';
}
$from_params .= 'SMTPUTF8';
}
else {
return false;
}
}
// RFC2298.3: remove envelope sender address
if (empty($opts['mdn_use_from'])

@ -61,7 +61,7 @@ class rcube_utils
public static function check_email($email, $dns_check=true)
{
// Check for invalid characters
if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email)) {
if (preg_match('/\p{Cc}/u', $email)) {
return false;
}
@ -80,16 +80,32 @@ class rcube_utils
$domain_part = array_pop($email_array);
$local_part = implode('@', $email_array);
// from PEAR::Validate
$regexp = '&^(?:
("\s*(?:[^"\f\n\r\t\v\b\s]+\s*)+")| #1 quoted name
([-\w!\#\$%\&\'*+~/^`|{}=]+(?:\.[-\w!\#\$%\&\'*+~/^`|{}=]+)*)) #2 OR dot-atom (RFC5322)
$&xi';
if (!preg_match($regexp, $local_part)) {
// 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)) {
return false;
}
$local_subparts;
preg_match_all('/"(?:\\\\.|[^\\\\"])*"|[^\.]+/',$local_part,$local_subparts);
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;
}
}
}
// Validate domain part
if (preg_match('/^\[((IPv6:[0-9a-f:.]+)|([0-9.]+))\]$/i', $domain_part, $matches)) {
return self::check_ip(preg_replace('/^IPv6:/i', '', $matches[1])); // valid IPv4 or IPv6 address

Loading…
Cancel
Save