Merge branch 'MDL-57531-master-phpmailer' of git://github.com/mudrd8mz/moodle

This commit is contained in:
Dan Poltawski 2017-01-04 13:29:10 +00:00
commit b6f5e57e45
6 changed files with 63 additions and 6 deletions

View file

@ -29,9 +29,9 @@ if ($primaryadmin) {
$primaryadminname = NULL; $primaryadminname = NULL;
} }
$temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'), $temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'),
new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS)); new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
$setting = new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'), $setting = new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'),
new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_NOTAGS); new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_EMAIL);
$setting->set_force_ltr(true); $setting->set_force_ltr(true);
$temp->add($setting); $temp->add($setting);
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'), new lang_string('configsupportpage', 'admin'), '', PARAM_URL)); $temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'), new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
@ -237,7 +237,7 @@ $temp->add(new admin_setting_configtext('smtpmaxbulk', new lang_string('smtpmaxb
$temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'), $temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'),
new lang_string('noreplydomaindetail', 'admin'))); new lang_string('noreplydomaindetail', 'admin')));
$temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'), $temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'),
new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_NOTAGS)); new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_EMAIL));
$temp->add(new admin_setting_configtextarea('allowedemaildomains', $temp->add(new admin_setting_configtextarea('allowedemaildomains',
new lang_string('allowedemaildomains', 'admin'), new lang_string('allowedemaildomains', 'admin'),
new lang_string('configallowedemaildomains', 'admin'), new lang_string('configallowedemaildomains', 'admin'),

View file

@ -5788,7 +5788,13 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
$tempreplyto = array(); $tempreplyto = array();
// Make sure that we fall back onto some reasonable no-reply address. // Make sure that we fall back onto some reasonable no-reply address.
$noreplyaddress = empty($CFG->noreplyaddress) ? 'noreply@' . get_host_from_url($CFG->wwwroot) : $CFG->noreplyaddress; $noreplyaddressdefault = 'noreply@' . get_host_from_url($CFG->wwwroot);
$noreplyaddress = empty($CFG->noreplyaddress) ? $noreplyaddressdefault : $CFG->noreplyaddress;
if (!validate_email($noreplyaddress)) {
debugging('email_to_user: Invalid noreply-email '.s($noreplyaddress));
$noreplyaddress = $noreplyaddressdefault;
}
// Make up an email address for handling bounces. // Make up an email address for handling bounces.
if (!empty($CFG->handlebounces)) { if (!empty($CFG->handlebounces)) {
@ -5798,6 +5804,12 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
$mail->Sender = $noreplyaddress; $mail->Sender = $noreplyaddress;
} }
// Make sure that the explicit replyto is valid, fall back to the implicit one.
if (!empty($replyto) && !validate_email($replyto)) {
debugging('email_to_user: Invalid replyto-email '.s($replyto));
$replyto = $noreplyaddress;
}
$alloweddomains = null; $alloweddomains = null;
if (!empty($CFG->allowedemaildomains)) { if (!empty($CFG->allowedemaildomains)) {
$alloweddomains = explode(PHP_EOL, $CFG->allowedemaildomains); $alloweddomains = explode(PHP_EOL, $CFG->allowedemaildomains);
@ -5815,6 +5827,11 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
// and that the senders email setting is either displayed to everyone, or display to only other users that are enrolled // and that the senders email setting is either displayed to everyone, or display to only other users that are enrolled
// in a course with the sender. // in a course with the sender.
} else if ($usetrueaddress && can_send_from_real_email_address($from, $user, $alloweddomains)) { } else if ($usetrueaddress && can_send_from_real_email_address($from, $user, $alloweddomains)) {
if (!validate_email($from->email)) {
debugging('email_to_user: Invalid from-email '.s($from->email).' - not sending');
// Better not to use $noreplyaddress in this case.
return false;
}
$mail->From = $from->email; $mail->From = $from->email;
$fromdetails = new stdClass(); $fromdetails = new stdClass();
$fromdetails->name = fullname($from); $fromdetails->name = fullname($from);

View file

@ -3425,4 +3425,27 @@ class core_moodlelib_testcase extends advanced_testcase {
'samecourse' => false, 'result' => false], 'samecourse' => false, 'result' => false],
]; ];
} }
/**
* Test that generate_email_processing_address() returns valid email address.
*/
public function test_generate_email_processing_address() {
global $CFG;
$this->resetAfterTest();
$data = (object)[
'id' => 42,
'email' => 'my.email+from_moodle@example.com',
];
$modargs = 'B'.base64_encode(pack('V', $data->id)).substr(md5($data->email), 0, 16);
$CFG->maildomain = 'example.com';
$CFG->mailprefix = 'mdl+';
$this->assertTrue(validate_email(generate_email_processing_address(0, $modargs)));
$CFG->maildomain = 'mail.example.com';
$CFG->mailprefix = 'mdl-';
$this->assertTrue(validate_email(generate_email_processing_address(23, $modargs)));
}
} }

View file

@ -665,4 +665,19 @@ EXPECTED;
); );
} }
/**
* Tests for validate_email() function.
*/
public function test_validate_email() {
$this->assertTrue(validate_email('moodle@example.com'));
$this->assertTrue(validate_email('moodle@localhost.local'));
$this->assertTrue(validate_email('verp_email+is=mighty@moodle.org'));
$this->assertTrue(validate_email("but_potentially'dangerous'too@example.org"));
$this->assertTrue(validate_email('posts+AAAAAAAAAAIAAAAAAAAGQQAAAAABFSXz1eM/P/lR2bYyljM+@posts.moodle.org'));
$this->assertFalse(validate_email('moodle@localhost'));
$this->assertFalse(validate_email('"attacker\\" -oQ/tmp/ -X/var/www/vhost/moodle/backdoor.php some"@email.com'));
$this->assertFalse(validate_email("moodle@example.com>\r\nRCPT TO:<victim@example.com"));
}
} }

View file

@ -2,10 +2,12 @@ This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers. information provided here is intended especially for developers.
=== 3.3 === === 3.3 ===
* YUI module moodle-core-formautosubmit has been removed, use jquery .change() instead (see lib/templates/url_select.mustache for * YUI module moodle-core-formautosubmit has been removed, use jquery .change() instead (see lib/templates/url_select.mustache for
an example) an example)
* $mform->init_javascript_enhancement() is deprecated and no longer does anything. Existing uses of smartselect enhancement * $mform->init_javascript_enhancement() is deprecated and no longer does anything. Existing uses of smartselect enhancement
should be switched to the searchableselector form element or other solutions. should be switched to the searchableselector form element or other solutions.
* Return value of the validate_email() is now proper boolean as documented. Previously the function could return 1, 0 or false.
=== 3.2 === === 3.2 ===

View file

@ -1088,12 +1088,12 @@ function page_get_doc_link_path(moodle_page $page) {
*/ */
function validate_email($address) { function validate_email($address) {
return (preg_match('#^[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+'. return (bool)preg_match('#^[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+'.
'(\.[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+)*'. '(\.[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+)*'.
'@'. '@'.
'[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'. '[-!\#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!\#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$#', '[-!\#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$#',
$address)); $address);
} }
/** /**