diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php index 09220fc759d..d9cd436d4ce 100644 --- a/auth/ldap/auth.php +++ b/auth/ldap/auth.php @@ -1498,7 +1498,7 @@ class auth_plugin_ldap extends auth_plugin_base { global $CFG, $SESSION; // HTTPS is potentially required - httpsrequired(); + //httpsrequired(); - this must be used before setting the URL, it is already done on the login/index.php if (($_SERVER['REQUEST_METHOD'] === 'GET' // Only on initial GET of loginpage || ($_SERVER['REQUEST_METHOD'] === 'POST' diff --git a/auth/ldap/ntlmsso_attempt.php b/auth/ldap/ntlmsso_attempt.php index 8d60cfebde6..8624b38b57d 100644 --- a/auth/ldap/ntlmsso_attempt.php +++ b/auth/ldap/ntlmsso_attempt.php @@ -2,8 +2,8 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); -// HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); $PAGE->set_url('/auth/ldap/ntlmsso_attempt.php'); $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); diff --git a/auth/ldap/ntlmsso_finish.php b/auth/ldap/ntlmsso_finish.php index c43b4beb878..0c1ad6f2e3b 100644 --- a/auth/ldap/ntlmsso_finish.php +++ b/auth/ldap/ntlmsso_finish.php @@ -2,8 +2,8 @@ require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); -// HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); $PAGE->set_url('/auth/ldap/ntlmsso_finish.php'); $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); diff --git a/auth/ldap/ntlmsso_magic.php b/auth/ldap/ntlmsso_magic.php index bf94978b903..9c74f87c93a 100644 --- a/auth/ldap/ntlmsso_magic.php +++ b/auth/ldap/ntlmsso_magic.php @@ -8,8 +8,9 @@ define('NO_MOODLE_COOKIES', true); require_once(dirname(dirname(dirname(__FILE__))).'/config.php'); -// HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); + $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); $authsequence = get_enabled_auth_plugins(true); // auths, in sequence diff --git a/auth/shibboleth/login.php b/auth/shibboleth/login.php index d33cbea002a..b06dd5d2ff8 100644 --- a/auth/shibboleth/login.php +++ b/auth/shibboleth/login.php @@ -15,8 +15,8 @@ } -//HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); /// Define variables used in page $site = get_site(); @@ -69,7 +69,7 @@ httpsrequired(); $PAGE->set_url('/auth/shibboleth/login.php'); $PAGE->navbar->add($loginsite); $PAGE->set_title("$site->fullname: $loginsite"); - $PAGE->set_heading($site->fullname); + $PAGE->set_heading($site->fullname); echo $OUTPUT->header(); include("index_form.html"); diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php index b10ed16aaca..15da1f93ed6 100644 --- a/lib/deprecatedlib.php +++ b/lib/deprecatedlib.php @@ -74,6 +74,19 @@ function filter_text($text, $courseid = NULL) { return filter_manager::instance()->filter_text($text, $context); } +/** + * This function indicates that current page requires the https + * when $CFG->loginhttps enabled. + * + * By using this function properly, we can ensure 100% https-ized pages + * at our entire discretion (login, forgot_password, change_password) + * @deprecated use $PAGE->https_required() instead + */ +function httpsrequired() { + global $PAGE; + $PAGE->https_required(); +} + /** * Given a physical path to a file, returns the URL through which it can be reached in Moodle. * @@ -85,7 +98,7 @@ function filter_text($text, $courseid = NULL) { * @return string URL to file */ function get_file_url($path, $options=null, $type='coursefile') { - global $CFG, $HTTPSPAGEREQUIRED; + global $CFG; $path = str_replace('//', '/', $path); $path = trim($path, '/'); // no leading and trailing slashes diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 64478ade12c..3591fac4fa6 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8621,19 +8621,6 @@ function address_in_subnet($addr, $subnetstr) { return false; } -/** - * This function sets the $HTTPSPAGEREQUIRED global - * (used in some parts of moodle to change some links) - * and calculate the proper wwwroot to be used - * - * By using this function properly, we can ensure 100% https-ized pages - * at our entire discretion (login, forgot_password, change_password) - */ -function httpsrequired() { - global $PAGE; - $PAGE->https_required(); -} - /** * For outputting debugging info * diff --git a/lib/pagelib.php b/lib/pagelib.php index ce75839349a..e80c8f94e99 100644 --- a/lib/pagelib.php +++ b/lib/pagelib.php @@ -223,6 +223,8 @@ class moodle_page { */ protected $_legacythemeinuse = false; + protected $_https_login_required = false; + /// Magic getter methods ============================================================= /// Due to the __get magic below, you normally do not call these as $PAGE->magic_get_x /// methods, but instead use the $PAGE->x syntax. @@ -1086,26 +1088,70 @@ class moodle_page { } /** - * This function sets the $HTTPSPAGEREQUIRED global - * (used in some parts of moodle to change some links) - * and calculate the proper wwwroot to be used + * This function indicates that current page requires the https + * when $CFG->loginhttps enabled. * * By using this function properly, we can ensure 100% https-ized pages * at our entire discretion (login, forgot_password, change_password) + * @return void */ public function https_required() { - global $CFG, $HTTPSPAGEREQUIRED; + global $CFG; + + if (!is_null($this->_url)) { + throw new coding_exception('https_required() must be used before setting page url!'); + } $this->ensure_theme_not_set(); + $this->_https_login_required = true; + if (!empty($CFG->loginhttps)) { - $HTTPSPAGEREQUIRED = true; $CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); } else { $CFG->httpswwwroot = $CFG->wwwroot; } } + /** + * Makes sure that page previously marked with https_required() + * is really using https://, if not it redirects to https:// + * + * @return void (may redirect to https://self) + */ + public function verify_https_required() { + global $CFG, $FULLME; + + if (is_null($this->_url)) { + throw new coding_exception('verify_https_required() must be called after setting page url!'); + } + + if (!$this->_https_login_required) { + throw new coding_exception('verify_https_required() must be called only after https_required()!'); + } + + if (empty($CFG->loginhttps)) { + // https not required, so stop checking + return; + } + + if (strpos($this->_url, 'https://')) { + // detect if incorrect PAGE->set_url() used, it is recommended to use root-relative paths there + throw new coding_exception('Invalid page url specified, it must start with https:// for pages that set https_required()!'); + } + + if (!empty($CFG->sslproxy)) { + // it does not make much sense to use sslproxy and loginhttps at the same time + return; + } + + // now the real test and redirect! + if (strpos($FULLME, 'https:') !== 0) { + // this may lead to infinite redirect on misconfigured sites, in that case use $CFG->loginhttps=0; in /config.php + redirect($this->_url); + } + } + /// Initialisation methods ===================================================== /// These set various things up in a default way. diff --git a/lib/setup.php b/lib/setup.php index 2bd76124a96..327f6b0276a 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -272,17 +272,6 @@ global $OUTPUT; */ global $MCACHE; -/** - * A global to define if the page being displayed must run under HTTPS. - * - * Its primary goal is to allow 100% HTTPS pages when $CFG->loginhttps is enabled. Default to false. - * Its enabled only by the $PAGE->https_required() function and used in some pages to update some URLs - * - * @global bool $HTTPSPAGEREQUIRED - * @name $HTTPSPAGEREQUIRED - */ -global $HTTPSPAGEREQUIRED; - /** * Full script path including all params, slash arguments, scheme and host. * @global string $FULLME diff --git a/login/change_password.php b/login/change_password.php index ab47e71bd2a..93d5090c06a 100644 --- a/login/change_password.php +++ b/login/change_password.php @@ -29,18 +29,19 @@ require_once('change_password_form.php'); $id = optional_param('id', SITEID, PARAM_INT); // current course -$url = new moodle_url('/login/change_password.php'); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); + +$uparams = array(); if ($id != SITEID) { - $url->param('id', $id); + $uparams['id'] = $id; } -$PAGE->set_url($url); +$PAGE->set_url('/login/change_password.php', $uparams); + $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); $strparticipants = get_string('participants'); -//HTTPS is potentially required in this page -httpsrequired(); - $systemcontext = get_context_instance(CONTEXT_SYSTEM); if (!$course = $DB->get_record('course', array('id'=>$id))) { @@ -127,6 +128,8 @@ if ($mform->is_cancelled()) { exit; } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); $strchangepassword = get_string('changepassword'); diff --git a/login/forgot_password.php b/login/forgot_password.php index dcf75154b38..cb55571c81d 100644 --- a/login/forgot_password.php +++ b/login/forgot_password.php @@ -32,10 +32,11 @@ require_once('forgot_password_form.php'); $p_secret = optional_param('p', false, PARAM_RAW); $p_username = optional_param('s', false, PARAM_RAW); -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); -$systemcontext = get_context_instance(CONTEXT_SYSTEM); $PAGE->set_url('/login/forgot_password.php'); +$systemcontext = get_context_instance(CONTEXT_SYSTEM); $PAGE->set_context($systemcontext); // setup text strings @@ -170,6 +171,9 @@ if ($mform->is_cancelled()) { die; // never reached } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); + /// DISPLAY FORM diff --git a/login/index.php b/login/index.php index 5c4071692d9..4953fa0bcf4 100644 --- a/login/index.php +++ b/login/index.php @@ -35,8 +35,8 @@ if ($cancel) { redirect(new moodle_url('/')); } -//HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); $context = get_context_instance(CONTEXT_SYSTEM); $PAGE->set_url("$CFG->httpswwwroot/login/index.php"); @@ -273,6 +273,8 @@ if (!empty($CFG->alternateloginurl)) { redirect($loginurl); } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); /// Generate the login page with forms @@ -311,14 +313,6 @@ foreach($authsequence as $authname) { $PAGE->set_title("$site->fullname: $loginsite"); $PAGE->set_heading("$site->fullname"); -// make sure we are on the https page when https login required -if (empty($CFG->sslproxy) and !empty($CFG->loginhttps)) { - if (strpos($FULLME, 'https:') !== 0) { - // this may lead to infinite redirect on misconfigured sites, in that case use $CFG->loginhttps=0; in /config.php - redirect(get_login_url()); - } -} - echo $OUTPUT->header(); if (isloggedin() and !isguestuser()) { diff --git a/login/signup.php b/login/signup.php index 176482f4d64..f3b83be65d3 100644 --- a/login/signup.php +++ b/login/signup.php @@ -37,8 +37,9 @@ if (!$authplugin->can_signup()) { print_error('notlocalisederrormessage', 'error', '', 'Sorry, you may not use this page.'); } -//HTTPS is potentially required in this page -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); + $PAGE->set_url('/login/signup.php'); $PAGE->set_context(get_context_instance(CONTEXT_SYSTEM)); @@ -60,6 +61,10 @@ if ($mform_signup->is_cancelled()) { exit; //never reached } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); + + $newaccount = get_string('newaccount'); $login = get_string('login'); diff --git a/user/edit.php b/user/edit.php index 5d2a02f3d76..5661a6aa619 100644 --- a/user/edit.php +++ b/user/edit.php @@ -29,17 +29,14 @@ require_once($CFG->dirroot.'/user/edit_form.php'); require_once($CFG->dirroot.'/user/editlib.php'); require_once($CFG->dirroot.'/user/profile/lib.php'); -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); $userid = optional_param('id', $USER->id, PARAM_INT); // user id $course = optional_param('course', SITEID, PARAM_INT); // course id (defaults to Site) -$cancelemailchange = optional_param('cancelemailchange', false, PARAM_INT); // course id (defaults to Site) +$cancelemailchange = optional_param('cancelemailchange', 0, PARAM_INT); // course id (defaults to Site) -$url = new moodle_url('/user/edit.php', array('course'=>$course)); -if ($userid !== $USER->id) { - $url->param('id', $userid); -} -$PAGE->set_url($url); +$PAGE->set_url('/user/edit.php', array('course'=>$course, 'id'=>$userid, 'cancelemailchange'=>$cancelemailchange)); if (!$course = $DB->get_record('course', array('id'=>$course))) { print_error('invalidcourseid'); @@ -260,6 +257,9 @@ if ($usernew = $userform->get_data()) { } } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); + /// Display page header $streditmyprofile = get_string('editmyprofile'); diff --git a/user/editadvanced.php b/user/editadvanced.php index 14c1b848588..6b58ca0d4fe 100644 --- a/user/editadvanced.php +++ b/user/editadvanced.php @@ -30,16 +30,13 @@ require_once($CFG->dirroot.'/user/editadvanced_form.php'); require_once($CFG->dirroot.'/user/editlib.php'); require_once($CFG->dirroot.'/user/profile/lib.php'); -httpsrequired(); +//HTTPS is required in this page when $CFG->loginhttps enabled +$PAGE->https_required(); $id = optional_param('id', $USER->id, PARAM_INT); // user id; -1 if creating new user $course = optional_param('course', SITEID, PARAM_INT); // course id (defaults to Site) -$url = new moodle_url('/user/editadvanced.php', array('course'=>$course)); -if ($id !== $USER->id) { - $url->param('id', $id); -} -$PAGE->set_url($url); +$PAGE->set_url('/user/editadvanced.php', array('course'=>$course, 'id'=>$id)); $course = $DB->get_record('course', array('id'=>$course), '*', MUST_EXIST); @@ -235,6 +232,9 @@ if ($usernew = $userform->get_data()) { //never reached } +// make sure we really are on the https page when https login required +$PAGE->verify_https_required(); + /// Display page header if ($user->id == -1 or ($user->id != $USER->id)) {