</instructions>
<instructions type="update" fromversion="5.3.*">
+ <!--
+tar cvf com.woltlab.wcf/files_pre.tar -C wcfsetup/install/files/ \
+ acp/update_com.woltlab.wcf_5.4_checkOwnerGroup.php \
+ acp/update_com.woltlab.wcf_5.4_session_1_cookies.php \
+ acp/update_com.woltlab.wcf_5.4_session_2_user_session.php \
+ lib/util/HeaderUtil.class.php \
+ lib/system/package/plugin/AbstractPackageInstallationPlugin.class.php \
+ lib/system/package/plugin/ScriptPackageInstallationPlugin.class.php \
+ lib/system/package/plugin/FilePackageInstallationPlugin.class.php
+ -->
+ <instruction type="file" run="standalone">files_pre.tar</instruction>
+
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_checkOwnerGroup.php</instruction>
- <instruction type="file" />
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_session_1_cookies.php</instruction>
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_session_2_user_session.php</instruction>
+
+ <instruction type="file" skipStyleUpdate="true" />
<instruction type="acpTemplate" />
<instruction type="template" />
- <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_removeFiles.php</instruction>
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php</instruction>
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php</instruction>
<instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_db.php</instruction>
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_removeFiles.php</instruction>
+
+ <instruction type="script" run="standalone">acp/update_com.woltlab.wcf_5.4_updateStyle.php</instruction>
+
<instruction type="objectTypeDefinition" />
<instruction type="option" />
</instructions>
--- /dev/null
+<?php
+/**
+ * Sets the new session cookies.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+use wcf\system\application\ApplicationHandler;
+use wcf\system\form\container\GroupFormElementContainer;
+use wcf\system\form\element\LabelFormElement;
+use wcf\system\form\FormDocument;
+use wcf\system\request\RouteHandler;
+use wcf\system\WCF;
+use wcf\util\CryptoUtil;
+use wcf\util\HeaderUtil;
+
+// 1) Check whether the cookies are already in place.
+$sessionIdOkay = false;
+if (!empty($_COOKIE[COOKIE_PREFIX."acp_session"])) {
+ $cookieValue = CryptoUtil::getValueFromSignedString($_COOKIE[COOKIE_PREFIX."acp_session"]);
+ if ($cookieValue) {
+ $sessionID = \bin2hex($cookieValue);
+ if ($sessionID === WCF::getSession()->sessionID) {
+ $sessionIdOkay = true;
+ }
+ }
+}
+
+$xsrfTokenOkay = false;
+if (!empty($_COOKIE['XSRF-TOKEN'])) {
+ if (CryptoUtil::validateSignedString($_COOKIE['XSRF-TOKEN'])) {
+ $xsrfTokenOkay = true;
+ }
+}
+
+if ($sessionIdOkay && $xsrfTokenOkay) {
+ // The process may continue;
+ return;
+}
+
+// 2) Set new session cookie.
+HeaderUtil::setCookie(
+ "acp_session",
+ CryptoUtil::createSignedString(
+ \hex2bin(WCF::getSession()->sessionID)
+ )
+);
+
+// 3) Set new XSRF-TOKEN cookie.
+$sameSite = $cookieDomain = '';
+if (ApplicationHandler::getInstance()->isMultiDomainSetup()) {
+ // We need to specify the cookieDomain in a multi domain set-up, because
+ // otherwise no cookies are sent to subdomains.
+ $cookieDomain = HeaderUtil::getCookieDomain();
+ $cookieDomain = ($cookieDomain !== null ? '; domain='.$cookieDomain : '');
+}
+else {
+ // SameSite=strict is not supported in a multi domain set-up, because
+ // it breaks cross-application requests.
+ $sameSite = '; SameSite=strict';
+}
+
+do {
+ $bytes = \bin2hex(\random_bytes(16));
+}
+while (strpos(base64_encode($bytes), '+') !== false);
+$xsrfToken = CryptoUtil::createSignedString($bytes);
+WCF::getSession()->register('__SECURITY_TOKEN', $xsrfToken);
+\header('set-cookie: XSRF-TOKEN='.\rawurlencode($xsrfToken).'; path=/'.$cookieDomain.(RouteHandler::secureConnection() ? '; secure' : '').$sameSite, false);
+
+// 4) Adjust the SECURITY_TOKEN.
+$container = new GroupFormElementContainer();
+$container->setLabel('Set Cookies'); // TODO
+$container->setDescription('Sets cookies');
+
+$label = new LabelFormElement($container);
+$label->setLabel('Set Cookies');
+$label->setDescription(
+<<<EOT
+<script>(function() {
+var oldToken = SECURITY_TOKEN;
+SECURITY_TOKEN = encodeURIComponent("$xsrfToken");
+var oldExecute = WCF.ACP.Package.Installation.prototype._executeStep;
+WCF.ACP.Package.Installation.prototype._executeStep = function (step, node, additionalData) {
+ var request = this._proxy._ajaxRequest;
+ request.setOption('url', request.getOption('url').replace(oldToken, SECURITY_TOKEN));
+
+ return oldExecute.call(this, step, node, additionalData);
+}
+})();
+</script>
+EOT
+);
+
+$container->appendChild($label);
+
+$document = new FormDocument("cookies_set");
+$document->appendContainer($container);
+
+return $document;
--- /dev/null
+<?php
+
+use wcf\system\database\table\column\CharDatabaseTableColumn;
+use wcf\system\database\table\column\IntDatabaseTableColumn;
+use wcf\system\database\table\column\MediumblobDatabaseTableColumn;
+use wcf\system\database\table\column\NotNullInt10DatabaseTableColumn;
+use wcf\system\database\table\column\NotNullVarchar255DatabaseTableColumn;
+use wcf\system\database\table\column\VarcharDatabaseTableColumn;
+use wcf\system\database\table\DatabaseTable;
+use wcf\system\database\table\DatabaseTableChangeProcessor;
+use wcf\system\database\table\index\DatabaseTableForeignKey;
+use wcf\system\database\table\index\DatabaseTableIndex;
+use wcf\system\WCF;
+
+/**
+ * Creates the user_session table.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+$tables = [
+ DatabaseTable::create('wcf1_user_session')
+ ->columns([
+ CharDatabaseTableColumn::create('sessionID')
+ ->length(40)
+ ->notNull(),
+ IntDatabaseTableColumn::create('userID')
+ ->length(10),
+ NotNullVarchar255DatabaseTableColumn::create('userAgent')
+ ->defaultValue(''),
+ VarcharDatabaseTableColumn::create('ipAddress')
+ ->length(39)
+ ->defaultValue(''),
+ NotNullInt10DatabaseTableColumn::create('lastActivityTime')
+ ->defaultValue(0),
+ MediumblobDatabaseTableColumn::create('sessionVariables'),
+ ])
+ ->indices([
+ DatabaseTableIndex::create()
+ ->type(DatabaseTableIndex::PRIMARY_TYPE)
+ ->columns(['sessionID']),
+ DatabaseTableIndex::create()
+ ->columns(['userID']),
+ DatabaseTableIndex::create()
+ ->columns(['lastActivityTime']),
+ ])
+ ->foreignKeys([
+ DatabaseTableForeignKey::create()
+ ->columns(['userID'])
+ ->referencedTable('wcf1_user')
+ ->referencedColumns(['userID'])
+ ->onDelete('CASCADE')
+ ]),
+];
+
+(new DatabaseTableChangeProcessor(
+/** @var ScriptPackageInstallationPlugin $this */
+ $this->installation->getPackage(),
+ $tables,
+ WCF::getDB()->getEditor())
+)->process();
--- /dev/null
+<?php
+
+use wcf\system\database\table\DatabaseTableChangeProcessor;
+use wcf\system\database\table\PartialDatabaseTable;
+use wcf\system\WCF;
+
+/**
+ * Removes the *_session_virtual tables.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+$tables = [
+ PartialDatabaseTable::create('wcf1_session_virtual')
+ ->drop(),
+ PartialDatabaseTable::create('wcf1_acp_session_virtual')
+ ->drop(),
+];
+
+(new DatabaseTableChangeProcessor(
+/** @var ScriptPackageInstallationPlugin $this */
+ $this->installation->getPackage(),
+ $tables,
+ WCF::getDB()->getEditor())
+)->process();
--- /dev/null
+<?php
+
+use wcf\system\database\table\column\MediumblobDatabaseTableColumn;
+use wcf\system\database\table\column\NotNullVarchar255DatabaseTableColumn;
+use wcf\system\database\table\column\VarcharDatabaseTableColumn;
+use wcf\system\database\table\DatabaseTableChangeProcessor;
+use wcf\system\database\table\index\DatabaseTableIndex;
+use wcf\system\database\table\PartialDatabaseTable;
+use wcf\system\WCF;
+
+/**
+ * Adjusts wcf1_acp_session and wcf1_acp_session_access_log.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+$tables = [
+ PartialDatabaseTable::create('wcf1_acp_session')
+ ->columns([
+ VarcharDatabaseTableColumn::create('requestURI')->drop(),
+ VarcharDatabaseTableColumn::create('requestMethod')->drop(),
+ MediumblobDatabaseTableColumn::create('sessionVariables'),
+ ])
+ ->indices([
+ DatabaseTableIndex::create()
+ ->columns(['userID']),
+ DatabaseTableIndex::create()
+ ->columns(['lastActivityTime']),
+ ]),
+ PartialDatabaseTable::create('wcf1_acp_session_access_log')
+ ->columns([
+ NotNullVarchar255DatabaseTableColumn::create('requestMethod')
+ ->defaultValue(''),
+ ])
+];
+
+(new DatabaseTableChangeProcessor(
+/** @var ScriptPackageInstallationPlugin $this */
+ $this->installation->getPackage(),
+ $tables,
+ WCF::getDB()->getEditor())
+)->process();
--- /dev/null
+<?php
+
+use wcf\util\StyleUtil;
+
+/**
+ * Runs the skipped style update.
+ *
+ * @author Tim Duesterhus
+ * @copyright 2001-2020 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core
+ */
+
+StyleUtil::updateStyleFile();