diff --git a/admin/index.php b/admin/index.php index 71df7d6..3da3fcd 100644 --- a/admin/index.php +++ b/admin/index.php @@ -31,6 +31,7 @@ $agreelicense = optional_param('agreelicense', 0, PARAM_BOOL); $autopilot = optional_param('autopilot', 0, PARAM_BOOL); $ignoreupgradewarning = optional_param('ignoreupgradewarning', 0, PARAM_BOOL); + $datarootconfirmsecure = optional_param('datarootconfirmsecure', 0, PARAM_BOOL); /// check upgrade status first if ($ignoreupgradewarning and !empty($_SESSION['upgraderunning'])) { @@ -531,6 +532,11 @@ /// Everything should now be set up, and the user is an admin +/// Move this check befor the call to admin_get_root(). + if (empty($CFG->datarootconfirmsecure) && !empty($datarootconfirmsecure)) { + set_config('datarootconfirmsecure',true); + } + /// Print default admin page with notifications. $adminroot = admin_get_root(); @@ -551,8 +557,15 @@ print_box(get_string('globalswarning', 'admin'), 'generalbox adminwarning'); } - if (is_dataroot_insecure()) { - print_box(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot), 'generalbox adminwarning'); + if (empty($CFG->datarootconfirmsecure) && ($datarooturl = is_dataroot_insecure())) { + print_box_start('generalbox adminwarning'); + print_string('datarootsecuritywarning', 'admin', $datarooturl); + $options = array(); + $options['sesskey'] = $USER->sesskey; + $options['datarootconfirmsecure'] = 1; + print_single_button('index.php', $options, get_string('datarootconfirmsecure', 'admin'), + 'post', '', '', '', '', get_string('confirmverifieddataroot', 'admin')); + print_box_end(); } if (defined('WARN_DISPLAY_ERRORS_ENABLED')) { diff --git a/admin/settings/top.php b/admin/settings/top.php index e538b68..c48c0f2 100644 --- a/admin/settings/top.php +++ b/admin/settings/top.php @@ -5,7 +5,11 @@ // since they need to exist *before* settingpages and externalpages // are added to them. -$ADMIN->add('root', new admin_externalpage('adminnotifications', get_string('notifications'), "$CFG->wwwroot/$CFG->admin/index.php")); +$adminnotifications = get_string('notifications'); +if (empty($CFG->datarootconfirmsecure) && is_dataroot_insecure()) { + $adminnotifications .= get_string('securitywarningspending', 'admin'); +} +$ADMIN->add('root', new admin_externalpage('adminnotifications', $adminnotifications, "$CFG->wwwroot/$CFG->admin/index.php")); // hidden upgrade script $ADMIN->add('root', new admin_externalpage('upgradesettings', get_string('upgradesettings', 'admin'), "$CFG->wwwroot/$CFG->admin/upgradesettings.php", 'moodle/site:config', true)); diff --git a/install.php b/install.php index 4e64f7c..affc56d 100644 --- a/install.php +++ b/install.php @@ -225,6 +225,13 @@ if (isset($_GET['download'])) { /// Check the directory settings +if (($nextstage == DIRECTORY)) { + // Each time we are going to visit the directory settings page, clear the + // insecure dataroot confirmation flag (so the user needs to confirm it + // again) just in case. + unset($INSTALL['datarootconfirmsecure']); +} + if ($INSTALL['stage'] == DIRECTORY) { error_reporting(0); @@ -250,7 +257,14 @@ if ($INSTALL['stage'] == DIRECTORY) { if (make_upload_directory('sessions', false) === false ) { $errormsg .= get_string('datarooterror', 'install').'
'; } - if ($fh) fclose($fh); + $CFG->wwwroot = $INSTALL['wwwroot']; // We need wwwroot inside is_dataroot_insecure. + if (($datarooturl = is_dataroot_insecure()) && (empty($INSTALL['datarootconfirmsecure']))) { + if (empty($errormsg)) { + // We don't touch $errormsg here, as the error message is printed inside the form_table + // function, but we need to make sure we stay in the stage. + $nextstage = DIRECTORY; + } + } if (!empty($errormsg)) $nextstage = DIRECTORY; @@ -712,7 +726,7 @@ if ($nextstage == SAVE) { //==========================================================================// function form_table($nextstage = WELCOME, $formaction = "install.php") { - global $INSTALL, $db; + global $INSTALL, $db, $CFG; /// Print the standard form if we aren't in the DOWNLOADLANG page /// because it has its own form. @@ -766,6 +780,15 @@ function form_table($nextstage = WELCOME, $formaction = "install.php") { break; case DIRECTORY: /// Directory settings + if (!empty($INSTALL['wwwrootform'])) { + $CFG->wwwroot = $INSTALL['wwwrootform']; + if (($datarooturl = is_dataroot_insecure()) && (empty($INSTALL['datarootconfirmsecure']))) { + $errormsg = get_string('datarootinsecureerror', 'install', $datarooturl); + echo "

$errormsg

\n"; + echo '
'. + get_string('datarootconfirmsecure', 'install').'

'; + } + } ?> diff --git a/install/lang/en_utf8/installer.php b/install/lang/en_utf8/installer.php index d1c12eb..f5af6c8 100644 --- a/install/lang/en_utf8/installer.php +++ b/install/lang/en_utf8/installer.php @@ -131,6 +131,8 @@ $string['databasesettingssub_postgres7'] = 'Type: PostgreSQL
Tables Prefix: prefix to use for all table names (mandatory)'; $string['dataroot'] = 'Data Directory'; $string['datarooterror'] = 'The \'Data Directory\' you specified could not be found or created. Either correct the path or create that directory manually.'; +$string['datarootinsecureerror'] = 'SECURITY ALERT!: The \'Data Directory\' you specified could be insecure! Please, click on the following link ($a) and make really sure you get an Access Denied error. Otherwise all of your contents will be available from the web to anyone, and anyone could impersonate any user account in your system (including the admin account!). If you are really sure the \'Data Directory\' you specified is secure, tick the \'Yes, I have verified it.\' checkbox to continue the installation'; +$string['datarootconfirmsecure'] = 'Yes, I have verified it.'; $string['dbconnectionerror'] = 'We could not connect to the database you specified. Please check your database settings.'; $string['dbcreationerror'] = 'Database creation error. Could not create the given database name with the settings provided'; $string['dbhost'] = 'Host Server'; diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php index a9447d3..2a27d5e 100644 --- a/lang/en_utf8/admin.php +++ b/lang/en_utf8/admin.php @@ -202,6 +202,7 @@ $string['configwarning'] = 'Be careful modifying these settings - strange values $string['configzip'] = 'Indicate the location of your zip program (Unix only, optional). If specified, this will be used to create zip archives on the server. If you leave this blank, then Moodle will use internal routines.'; $string['confirmation'] = 'Confirmation'; $string['confirminstall'] = 'You are about to install language pack ($a), are you sure?'; +$string['confirmverifieddataroot'] = 'If you have really verified your Data Directory is sure, click OK. Otherwise click Cancel.'; $string['country'] = 'Default country'; $string['coursemanager'] = 'Course managers'; $string['coursemgmt'] = 'Add/edit courses'; @@ -219,7 +220,8 @@ $string['curlrecommended'] = 'Installing the optional Curl library is highly rec $string['ctyperecommended'] = 'Installing the optional ctype PHP extension is highly recommended in order to improve site performance, particularly if your site is supporting non-latin languages.'; $string['ctyperequired'] = 'The ctype PHP extension is now required by Moodle, in order to improve site performance and to offer multilingual compatibility.'; $string['customcheck'] = 'Other Checks'; -$string['datarootsecuritywarning'] = 'Your site configuration might not be secure. Please make sure that your dataroot directory ($a) is not directly accessible via web.'; +$string['datarootsecuritywarning'] = 'SECURITY ALERT!: The \'Data Directory\' you are using could be insecure! Please, click on the following link ($a) and make really sure you get an Access Denied error. Otherwise all of your contents will be available from the web to anyone, and anyone could impersonate any user account in your system (including the admin account!). If you are really sure the \'Data Directory\' you are using is secure, click on the \'Yes, I have verified it.\' button to remove this security warning.'; +$string['datarootconfirmsecure'] = 'Yes, I have verified it.'; $string['dbmigrate'] = 'Moodle Database Migration'; $string['dbmigrateconnecerror'] = 'Could not connect to the database specified.'; $string['dbmigrateencodingerror'] = 'The database specified has encoding $a rather than required UNICODE/UTF8.
Please specify another.'; @@ -512,6 +514,7 @@ $string['searchinsettings'] = 'Search in settings'; $string['sectionerror'] = 'Section Error!'; $string['secureforms'] = 'Use additional form security'; $string['security'] = 'Security'; +$string['securitywarningspending'] = ' [Security warnings pending! Click here to see them]'; $string['server'] = 'Server'; $string['serverchecks'] = 'Server Checks'; $string['sessioncookie'] = 'Cookie prefix'; diff --git a/lib/adminlib.php b/lib/adminlib.php index c17f627..20c2afa 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -665,7 +665,11 @@ function is_dataroot_insecure() { $dataroot = str_replace('\\', '/', $CFG->dataroot.'/'); if (strpos($dataroot, $siteroot) === 0) { - return true; + $httpdocroot = str_replace('\\', '/', strrev($CFG->dirroot.'/')); + preg_match ('|(https?://[^/]+)|i', $CFG->wwwroot, $matches); + $httpdocroot = $matches[1]; + $datarooturl = $httpdocroot.'/'. substr($dataroot, strlen($siteroot)); + return $datarooturl; } return false; }