]> source.dussan.org Git - nextcloud-server.git/commitdiff
block DAV if 2FA challenge needs to be solved first
authorChristoph Wurst <christoph@owncloud.com>
Wed, 1 Jun 2016 08:42:38 +0000 (10:42 +0200)
committerChristoph Wurst <christoph@owncloud.com>
Wed, 1 Jun 2016 08:42:38 +0000 (10:42 +0200)
apps/dav/appinfo/v1/caldav.php
apps/dav/appinfo/v1/carddav.php
apps/dav/appinfo/v1/webdav.php
apps/dav/lib/Connector/Sabre/Auth.php
apps/dav/lib/Server.php
apps/dav/tests/unit/Connector/Sabre/AuthTest.php

index d3af714474533a8fd1c10d6242f0a97ed3cec900..50348a6020236eba51f4a773ed51fd873ee36458 100644 (file)
@@ -34,6 +34,7 @@ $authBackend = new Auth(
        \OC::$server->getSession(),
        \OC::$server->getUserSession(),
        \OC::$server->getRequest(),
+       \OC::$server->getTwoFactorAuthManager(),
        'principals/'
 );
 $principalBackend = new Principal(
index 7ef510689c26338114930e675c463b15706dc58a..88582d64ee517c2388c8d10db98bea419fa8b785 100644 (file)
@@ -35,6 +35,7 @@ $authBackend = new Auth(
        \OC::$server->getSession(),
        \OC::$server->getUserSession(),
        \OC::$server->getRequest(),
+       \OC::$server->getTwoFactorAuthManager(),
        'principals/'
 );
 $principalBackend = new Principal(
index 275849f618df531afbfb20c689d62c27f6782911..3b733c0fbd502afeb943bf323cf62a0ef4085696 100644 (file)
@@ -42,6 +42,7 @@ $authBackend = new \OCA\DAV\Connector\Sabre\Auth(
        \OC::$server->getSession(),
        \OC::$server->getUserSession(),
        \OC::$server->getRequest(),
+       \OC::$server->getTwoFactorAuthManager(),
        'principals/'
 );
 $requestUri = \OC::$server->getRequest()->getRequestUri();
index 8b9f86af1e79fe7731a59f524e29e6980d2b76e8..7b959a0d8992e34e10d5e39461b2a9ecc6874bdd 100644 (file)
@@ -31,9 +31,10 @@ namespace OCA\DAV\Connector\Sabre;
 
 use Exception;
 use OC\AppFramework\Http\Request;
+use OC\Authentication\TwoFactorAuth\Manager;
+use OC\User\Session;
 use OCP\IRequest;
 use OCP\ISession;
-use OC\User\Session;
 use Sabre\DAV\Auth\Backend\AbstractBasic;
 use Sabre\DAV\Exception\NotAuthenticated;
 use Sabre\DAV\Exception\ServiceUnavailable;
@@ -41,6 +42,8 @@ use Sabre\HTTP\RequestInterface;
 use Sabre\HTTP\ResponseInterface;
 
 class Auth extends AbstractBasic {
+
+
        const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
 
        /** @var ISession */
@@ -51,19 +54,24 @@ class Auth extends AbstractBasic {
        private $request;
        /** @var string */
        private $currentUser;
+       /** @var Manager */
+       private $twoFactorManager;
 
        /**
         * @param ISession $session
         * @param Session $userSession
         * @param IRequest $request
+        * @param Manager $twoFactorManager
         * @param string $principalPrefix
         */
        public function __construct(ISession $session,
                                                                Session $userSession,
                                                                IRequest $request,
+                                                               Manager $twoFactorManager,
                                                                $principalPrefix = 'principals/users/') {
                $this->session = $session;
                $this->userSession = $userSession;
+               $this->twoFactorManager = $twoFactorManager;
                $this->request = $request;
                $this->principalPrefix = $principalPrefix;
        }
@@ -197,6 +205,9 @@ class Auth extends AbstractBasic {
                if($forcedLogout) {
                        $this->userSession->logout();
                } else {
+                       if ($this->twoFactorManager->needsSecondFactor()) {
+                               throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
+                       }
                        if (\OC_User::handleApacheAuth() ||
                                //Fix for broken webdav clients
                                ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
index 2a9c36698b1b3d23e46f48aa5cf0dcd9b2f15d5b..179558e97ae5d604c8653cc63ff9345b05b6afc0 100644 (file)
@@ -25,7 +25,6 @@
 namespace OCA\DAV;
 
 use OCA\DAV\CalDAV\Schedule\IMipPlugin;
-use OCA\DAV\Connector\FedAuth;
 use OCA\DAV\Connector\Sabre\Auth;
 use OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin;
 use OCA\DAV\Connector\Sabre\DavAclPlugin;
@@ -57,7 +56,8 @@ class Server {
                $authBackend = new Auth(
                        \OC::$server->getSession(),
                        \OC::$server->getUserSession(),
-                       \OC::$server->getRequest()
+                       \OC::$server->getRequest(),
+                       \OC::$server->getTwoFactorAuthManager()
                );
 
                // Set URL explicitly due to reverse-proxy situations
index e5b5fe21b1f755744211fb45809a26591d6a5239..b3ab49a027e099b221f8ef51d13c2d8a4ace0f2a 100644 (file)
 
 namespace OCA\DAV\Tests\unit\Connector\Sabre;
 
+use OC\Authentication\TwoFactorAuth\Manager;
+use OC\User\Session;
 use OCP\IRequest;
+use OCP\ISession;
 use OCP\IUser;
 use Test\TestCase;
-use OCP\ISession;
-use OC\User\Session;
 
 /**
  * Class AuthTest
@@ -48,6 +49,8 @@ class AuthTest extends TestCase {
        private $userSession;
        /** @var IRequest */
        private $request;
+       /** @var Manager */
+       private $twoFactorManager;
 
        public function setUp() {
                parent::setUp();
@@ -57,10 +60,14 @@ class AuthTest extends TestCase {
                        ->disableOriginalConstructor()->getMock();
                $this->request = $this->getMockBuilder('\OCP\IRequest')
                        ->disableOriginalConstructor()->getMock();
+               $this->twoFactorManager = $this->getMockBuilder('\OC\Authentication\TwoFactorAuth\Manager')
+                       ->disableOriginalConstructor()
+                       ->getMock();
                $this->auth = new \OCA\DAV\Connector\Sabre\Auth(
                        $this->session,
                        $this->userSession,
-                       $this->request
+                       $this->request,
+                       $this->twoFactorManager
                );
        }
 
@@ -295,6 +302,59 @@ class AuthTest extends TestCase {
                $this->auth->check($request, $response);
        }
 
+       /**
+        * @expectedException \Sabre\DAV\Exception\NotAuthenticated
+        * @expectedExceptionMessage 2FA challenge not passed.
+        */
+       public function testAuthenticateAlreadyLoggedInWithoutTwoFactorChallengePassed() {
+               $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $this->userSession
+                       ->expects($this->any())
+                       ->method('isLoggedIn')
+                       ->willReturn(true);
+               $this->request
+                       ->expects($this->any())
+                       ->method('getMethod')
+                       ->willReturn('PROPFIND');
+               $this->request
+                       ->expects($this->any())
+                       ->method('isUserAgent')
+                       ->with([
+                               '/^Mozilla\/5\.0 \([A-Za-z ]+\) (mirall|csyncoC)\/.*$/',
+                               '/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/',
+                               '/^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/',
+                       ])
+                       ->willReturn(false);
+               $this->session
+                       ->expects($this->any())
+                       ->method('get')
+                       ->with('AUTHENTICATED_TO_DAV_BACKEND')
+                       ->will($this->returnValue('LoggedInUser'));
+               $user = $this->getMockBuilder('\OCP\IUser')
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $user->expects($this->any())
+                       ->method('getUID')
+                       ->will($this->returnValue('LoggedInUser'));
+               $this->userSession
+                       ->expects($this->any())
+                       ->method('getUser')
+                       ->will($this->returnValue($user));
+               $this->request
+                       ->expects($this->once())
+                       ->method('passesCSRFCheck')
+                       ->willReturn(true);
+               $this->twoFactorManager->expects($this->once())
+                       ->method('needsSecondFactor')
+                       ->will($this->returnValue(true));
+               $this->auth->check($request, $response);
+       }
+
        /**
         * @expectedException \Sabre\DAV\Exception\NotAuthenticated
         * @expectedExceptionMessage CSRF check not passed.