Merge pull request #15683 from owncloud/block-legacy-clients

Block old legacy clients
This commit is contained in:
Lukas Reschke 2015-04-24 18:21:10 +02:00
commit b9df932e3c
4 changed files with 220 additions and 0 deletions

View File

@ -43,6 +43,7 @@ $server->setBaseUri($baseuri);
// Load plugins
$defaults = new OC_Defaults();
$server->addPlugin(new \OC\Connector\Sabre\BlockLegacyClientPlugin(\OC::$server->getConfig()));
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, $defaults->getName()));
// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
$server->addPlugin(new \OC\Connector\Sabre\DummyGetResponsePlugin());

View File

@ -799,6 +799,17 @@ $CONFIG = array(
*/
'cipher' => 'AES-256-CFB',
/**
* The minimum ownCloud desktop client version that will be allowed to sync with
* this server instance. All connections made from earlier clients will be denied
* by the server. Defaults to the minimum officially supported ownCloud version at
* the time of release of this server version.
*
* When changing this, note that older unsupported versions of the ownCloud desktop
* client may not function as expected, and could lead to permanent data loss for
* clients or other unexpected results.
*/
'minimum.supported.desktop.version' => '1.7.0',
/**
* Memory caching backend configuration

View File

@ -0,0 +1,79 @@
<?php
/**
* @author Lukas Reschke <lukas@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Connector\Sabre;
use OCP\IConfig;
use Sabre\HTTP\RequestInterface;
use Sabre\DAV\ServerPlugin;
use Sabre\DAV\Exception;
/**
* Class BlockLegacyClientPlugin is used to detect old legacy sync clients and
* returns a 403 status to those clients
*
* @package OC\Connector\Sabre
*/
class BlockLegacyClientPlugin extends ServerPlugin {
/** @var \Sabre\DAV\Server */
protected $server;
/** @var IConfig */
protected $config;
/**
* @param IConfig $config
*/
public function __construct(IConfig $config) {
$this->config = $config;
}
/**
* @param \Sabre\DAV\Server $server
* @return void
*/
public function initialize(\Sabre\DAV\Server $server) {
$this->server = $server;
$this->server->on('beforeMethod', [$this, 'beforeHandler'], 200);
}
/**
* Detects all unsupported clients and throws a \Sabre\DAV\Exception\Forbidden
* exception which will result in a 403 to them.
* @param RequestInterface $request
* @throws \Sabre\DAV\Exception\Forbidden If the client version is not supported
*/
public function beforeHandler(RequestInterface $request) {
$userAgent = $request->getHeader('User-Agent');
if($userAgent === null) {
return;
}
$minimumSupportedDesktopVersion = $this->config->getSystemValue('minimum.supported.desktop.version', '1.7.0');
// Match on the mirall version which is in scheme "Mozilla/5.0 (%1) mirall/%2" or
// "mirall/%1" for older releases
preg_match("/(?:mirall\\/)([\d.]+)/i", $userAgent, $versionMatches);
if(isset($versionMatches[1]) &&
version_compare($versionMatches[1], $minimumSupportedDesktopVersion) === -1) {
throw new \Sabre\DAV\Exception\Forbidden('Unsupported client version.');
}
}
}

View File

@ -0,0 +1,129 @@
<?php
/**
* @author Lukas Reschke <lukas@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace Test\Connector\Sabre;
use OC\Connector\Sabre\BlockLegacyClientPlugin;
use Test\TestCase;
use OCP\IConfig;
/**
* Class BlockLegacyClientPluginTest
*
* @package Test\Connector\Sabre
*/
class BlockLegacyClientPluginTest extends TestCase {
/** @var IConfig */
private $config;
/** @var BlockLegacyClientPlugin */
private $blockLegacyClientVersionPlugin;
public function setUp() {
parent::setUp();
$this->config = $this->getMock('\OCP\IConfig');
$this->blockLegacyClientVersionPlugin = new BlockLegacyClientPlugin($this->config);
}
/**
* @return array
*/
public function oldDesktopClientProvider() {
return [
['Mozilla/5.0 (1.5.0) mirall/1.5.0'],
['mirall/1.5.0'],
['mirall/1.5.4'],
['mirall/1.6.0'],
['Mozilla/5.0 (Bogus Text) mirall/1.6.9'],
];
}
/**
* @dataProvider oldDesktopClientProvider
* @param string $userAgent
* @expectedException \Sabre\DAV\Exception\Forbidden
* @expectedExceptionMessage Unsupported client version.
*/
public function testBeforeHandlerException($userAgent) {
/** @var \Sabre\HTTP\RequestInterface $request */
$request = $this->getMock('\Sabre\HTTP\RequestInterface');
$request
->expects($this->once())
->method('getHeader')
->with('User-Agent')
->will($this->returnValue($userAgent));
$this->config
->expects($this->once())
->method('getSystemValue')
->with('minimum.supported.desktop.version', '1.7.0')
->will($this->returnValue('1.7.0'));
$this->blockLegacyClientVersionPlugin->beforeHandler($request);
}
/**
* @return array
*/
public function newAndAlternateDesktopClientProvider() {
return [
['Mozilla/5.0 (1.7.0) mirall/1.7.0'],
['mirall/1.8.3'],
['mirall/1.7.2'],
['mirall/1.7.0'],
['Mozilla/5.0 (Bogus Text) mirall/1.9.3'],
];
}
/**
* @dataProvider newAndAlternateDesktopClientProvider
* @param string $userAgent
*/
public function testBeforeHandlerSuccess($userAgent) {
/** @var \Sabre\HTTP\RequestInterface $request */
$request = $this->getMock('\Sabre\HTTP\RequestInterface');
$request
->expects($this->once())
->method('getHeader')
->with('User-Agent')
->will($this->returnValue($userAgent));
$this->config
->expects($this->once())
->method('getSystemValue')
->with('minimum.supported.desktop.version', '1.7.0')
->will($this->returnValue('1.7.0'));
$this->blockLegacyClientVersionPlugin->beforeHandler($request);
}
public function testBeforeHandlerNoUserAgent() {
/** @var \Sabre\HTTP\RequestInterface $request */
$request = $this->getMock('\Sabre\HTTP\RequestInterface');
$request
->expects($this->once())
->method('getHeader')
->with('User-Agent')
->will($this->returnValue(null));
$this->blockLegacyClientVersionPlugin->beforeHandler($request);
}
}