From 78696e3ed7dc42190810ffd0bfac390e9a33cb91 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Mon, 25 Oct 2010 23:18:47 +0000 Subject: [PATCH] (bug 198: Easy, secure in-place upgrade) Introduce new $wgUpgradeKey. When set in LocalSettings, it allows the user to unlock the installer/upgrader with a hidden key. The days of having to move LocalSettings.php in order to perform an upgrade are gone. The key is the only thing loaded by the installer, you still have to provide the SQL information yourself (as an extra layer of sanity to keep unauthorized users from running it) --- RELEASE-NOTES | 2 + includes/DefaultSettings.php | 8 +++- includes/installer/CoreInstaller.php | 2 + includes/installer/Installer.i18n.php | 6 ++- includes/installer/Installer.php | 9 +++-- includes/installer/WebInstaller.php | 18 +++++---- includes/installer/WebInstallerPage.php | 50 +++++++++++++++++++++++++ 7 files changed, 81 insertions(+), 14 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index a48505045f..41c28b62f6 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -75,6 +75,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN available as input for other configuration items, either. * Remove $wgRemoteUploads. It was not well supported and superseded by $wgUploadNavigationUrl. +* $wgUpgradeKey allows unlocking the web installer for upgrades without having + to move LocalSettings.php === New features in 1.17 === * (bug 10183) Users can now add personal styles and scripts to all skins via diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index f71ddd13a7..7bc6ab361b 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -3988,7 +3988,7 @@ $wgMaintenanceScripts = array(); */ $wgReadOnly = null; -/*** +/** * If this lock file exists (size > 0), the wiki will be forced into read-only mode. * Its contents will be shown to users as part of the read-only warning * message. @@ -3997,6 +3997,12 @@ $wgReadOnly = null; */ $wgReadOnlyFile = false; +/** + * If this is set to some string, this opens up config/index.php for upgrades + * when needed. You will need to provide this key to use it + */ +$wgUpgradeKey = false; + /** @} */ # End of maintenance } /************************************************************************//** diff --git a/includes/installer/CoreInstaller.php b/includes/installer/CoreInstaller.php index 201b612d28..ca10131c35 100644 --- a/includes/installer/CoreInstaller.php +++ b/includes/installer/CoreInstaller.php @@ -83,6 +83,8 @@ abstract class CoreInstaller extends Installer { '_Extensions' => array(), '_MemCachedServers' => '', '_ExternalHTTP' => false, + '_LocalSettingsLocked' => true, + '_UpgradeKey' => '', ); /** diff --git a/includes/installer/Installer.i18n.php b/includes/installer/Installer.i18n.php index 099526ad9e..54d5177124 100644 --- a/includes/installer/Installer.i18n.php +++ b/includes/installer/Installer.i18n.php @@ -16,8 +16,9 @@ $messages['en'] = array( 'config-title' => 'MediaWiki $1 installation', 'config-information' => 'Information', 'config-localsettings-upgrade' => "'''Warning''': A LocalSettings.php file has been detected. -Your software is able to upgrade. -Please move LocalSettings.php to somewhere safe and then run the installer again.", +Your software is able to upgrade. Please fill in the value of \$wgUpgradeKey.php in the box", + 'config-localsettings-key' => 'Upgrade key:', + 'config-localsettings-badkey' => 'The key you provided is incorrect', 'config-localsettings-noupgrade' => "'''Error''': A LocalSettings.php file has been detected. Your software is not able to upgrade at this time. The installer has been disabled for security reasons.", @@ -51,6 +52,7 @@ Check your php.ini and make sure session.save_path is set to an app 'config-page-releasenotes' => 'Release notes', 'config-page-copying' => 'Copying', 'config-page-upgradedoc' => 'Upgrading', + 'config-page-locked' => 'Permission denied', 'config-help-restart' => 'Do you want to clear all saved data that you have entered and restart the installation process?', 'config-restart' => 'Yes, restart it', 'config-welcome' => "=== Environmental checks === diff --git a/includes/installer/Installer.php b/includes/installer/Installer.php index e17131e217..7bc71f3f96 100644 --- a/includes/installer/Installer.php +++ b/includes/installer/Installer.php @@ -230,10 +230,13 @@ abstract class Installer { wfRestoreWarnings(); if( $ls ) { - if( $this->getDBInstaller()->needsUpgrade() ) { + $wgCacheEpoch = $wgCommandLineMode = false; + require_once( "$IP/LocalSettings.php" ); + $vars = get_defined_vars(); + if( isset( $vars['wgUpgradeKey'] ) && $vars['wgUpgradeKey'] ) { $status->warning( 'config-localsettings-upgrade' ); - } - else { + $this->setVar( '_UpgradeKey', $vars['wgUpgradeKey' ] ); + } else { $status->fatal( 'config-localsettings-noupgrade' ); } } diff --git a/includes/installer/WebInstaller.php b/includes/installer/WebInstaller.php index 208f5ea667..861ea1d13b 100644 --- a/includes/installer/WebInstaller.php +++ b/includes/installer/WebInstaller.php @@ -163,7 +163,15 @@ class WebInstaller extends CoreInstaller { # Get the page name. $pageName = $this->request->getVal( 'page' ); - if ( in_array( $pageName, $this->otherPages ) ) { + # Check LocalSettings status + $localSettings = $this->getLocalSettingsStatus(); + + if( !$localSettings->isGood() && $this->getVar( '_LocalSettingsLocked' ) ) { + $pageName = 'Locked'; + $pageId = false; + $page = $this->getPageByName( $pageName ); + $page->setLocalSettingsStatus( $localSettings ); + } elseif ( in_array( $pageName, $this->otherPages ) ) { # Out of sequence $pageId = false; $page = $this->getPageByName( $pageName ); @@ -212,14 +220,8 @@ class WebInstaller extends CoreInstaller { # Execute the page. $this->currentPageName = $page->getName(); $this->startPageWrapper( $pageName ); - $localSettings = $this->getLocalSettingsStatus(); - if( !$localSettings->isGood() ) { - $this->showStatusBox( $localSettings ); - $result = 'output'; - } else { - $result = $page->execute(); - } + $result = $page->execute(); $this->endPageWrapper(); diff --git a/includes/installer/WebInstallerPage.php b/includes/installer/WebInstallerPage.php index b3738f6bfb..060009500c 100644 --- a/includes/installer/WebInstallerPage.php +++ b/includes/installer/WebInstallerPage.php @@ -102,6 +102,56 @@ abstract class WebInstallerPage { } +class WebInstaller_Locked extends WebInstallerPage { + + // The status of Installer::getLocalSettingsStatus() + private $status; + + public function setLocalSettingsStatus( Status $s ) { + $this->status = $s; + } + + public function execute() { + $r = $this->parent->request; + if( !$r->wasPosted() || !$this->status->isOK() ) { + $this->display(); + return 'output'; + } else { + $key = $r->getText( 'config_wpUpgradeKey' ); + if( !$key || $key !== $this->getVar( '_UpgradeKey' ) ) { + $this->display( true ); + return 'output'; + } else { + $this->setVar( '_LocalSettingsLocked', false ); + return 'continue'; + } + } + } + + /** + * Display stuff to the end user + * @param $badKey bool Whether the key input by the user was bad + */ + private function display( $badKey = false ) { + $this->startForm(); + if( $this->status->isOK() && !$this->status->isGood() ) { + if( $badKey ) { + $this->parent->showError( 'config-localsettings-badkey' ); + } + $this->parent->output->addWikiText( wfMsg( 'config-localsettings-upgrade' ) ); + $this->addHTML( "
" . + $this->parent->getTextBox( array( + 'var' => 'wpUpgradeKey', + 'label' => 'config-localsettings-key', + ) ) + ); + } else { + $this->parent->showStatusBox( $this->status ); + } + $this->endForm(); + } +} + class WebInstaller_Language extends WebInstallerPage { public function execute() { -- 2.20.1