diff options
author | Björn Schießle <bjoern@schiessle.org> | 2015-11-19 11:48:21 +0100 |
---|---|---|
committer | Björn Schießle <bjoern@schiessle.org> | 2015-11-19 18:07:33 +0100 |
commit | 6f7aa3392f4ec47d03164a9732842ec034aeae48 (patch) | |
tree | 3a277311f8eb5d00cfbea92014cb5de8e818c419 | |
parent | 2754afc0747950591b3ddca37248d363c6ab64f3 (diff) | |
download | nextcloud-server-6f7aa3392f4ec47d03164a9732842ec034aeae48.tar.gz nextcloud-server-6f7aa3392f4ec47d03164a9732842ec034aeae48.zip |
make sure that both server don't try to exchange the shared secret in parallel
-rw-r--r-- | apps/federation/api/ocsauthapi.php | 9 | ||||
-rw-r--r-- | apps/federation/backgroundjob/getsharedsecret.php | 54 | ||||
-rw-r--r-- | apps/federation/backgroundjob/requestsharedsecret.php | 48 |
3 files changed, 79 insertions, 32 deletions
diff --git a/apps/federation/api/ocsauthapi.php b/apps/federation/api/ocsauthapi.php index 7965e6f2140..3279ae1dd7b 100644 --- a/apps/federation/api/ocsauthapi.php +++ b/apps/federation/api/ocsauthapi.php @@ -91,6 +91,13 @@ class OCSAuthAPI { return new \OC_OCS_Result(null, HTTP::STATUS_FORBIDDEN); } + // if both server initiated the exchange of the shared secret the greater + // token wins + $localToken = $this->dbHandler->getToken($url); + if (strcmp($localToken, $token) > 0) { + return new \OC_OCS_Result(null, HTTP::STATUS_FORBIDDEN); + } + $this->jobList->add( 'OCA\Federation\BackgroundJob\GetSharedSecret', [ @@ -123,6 +130,8 @@ class OCSAuthAPI { $sharedSecret = $this->secureRandom->getMediumStrengthGenerator()->generate(32); $this->trustedServers->addSharedSecret($url, $sharedSecret); + // reset token after the exchange of the shared secret was successful + $this->dbHandler->addToken($url, ''); return new \OC_OCS_Result(['sharedSecret' => $sharedSecret], Http::STATUS_OK); diff --git a/apps/federation/backgroundjob/getsharedsecret.php b/apps/federation/backgroundjob/getsharedsecret.php index 3e8597cd78b..dd095ed117a 100644 --- a/apps/federation/backgroundjob/getsharedsecret.php +++ b/apps/federation/backgroundjob/getsharedsecret.php @@ -22,6 +22,7 @@ namespace OCA\Federation\BackgroundJob; +use GuzzleHttp\Exception\ClientException; use OC\BackgroundJob\QueuedJob; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; @@ -52,6 +53,9 @@ class GetSharedSecret extends QueuedJob{ /** @var TrustedServers */ private $trustedServers; + /** @var DbHandler */ + private $dbHandler; + /** @var ILogger */ private $logger; @@ -65,23 +69,26 @@ class GetSharedSecret extends QueuedJob{ * @param IJobList $jobList * @param TrustedServers $trustedServers * @param ILogger $logger + * @param DbHandler $dbHandler */ public function __construct( IClient $httpClient = null, IURLGenerator $urlGenerator = null, IJobList $jobList = null, TrustedServers $trustedServers = null, - ILogger $logger = null + ILogger $logger = null, + dbHandler $dbHandler = null ) { $this->logger = $logger ? $logger : \OC::$server->getLogger(); $this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient(); $this->jobList = $jobList ? $jobList : \OC::$server->getJobList(); $this->urlGenerator = $urlGenerator ? $urlGenerator : \OC::$server->getURLGenerator(); + $this->dbHandler = $dbHandler ? $dbHandler : new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation')); if ($trustedServers) { $this->trustedServers = $trustedServers; } else { $this->trustedServers = new TrustedServers( - new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation')), + $this->dbHandler, \OC::$server->getHTTPClientService(), \OC::$server->getLogger(), $this->jobList, @@ -112,20 +119,25 @@ class GetSharedSecret extends QueuedJob{ $source = rtrim($source, '/'); $token = $argument['token']; - $result = $this->httpClient->get( - $target . $this->endPoint, - [ - 'query' => - [ - 'url' => $source, - 'token' => $token - ], - 'timeout' => 3, - 'connect_timeout' => 3, - ] - ); - - $status = $result->getStatusCode(); + try { + $result = $this->httpClient->get( + $target . $this->endPoint, + [ + 'query' => + [ + 'url' => $source, + 'token' => $token + ], + 'timeout' => 3, + 'connect_timeout' => 3, + ] + ); + + $status = $result->getStatusCode(); + + } catch (ClientException $e) { + $status = $e->getCode(); + } // if we received a unexpected response we try again later if ( @@ -133,10 +145,15 @@ class GetSharedSecret extends QueuedJob{ && $status !== Http::STATUS_FORBIDDEN ) { $this->jobList->add( - 'OCA\Federation\Backgroundjob\RequestSharedSecret', + 'OCA\Federation\Backgroundjob\GetSharedSecret', $argument ); - } elseif ($status === Http::STATUS_OK) { + } else { + // reset token if we received a valid response + $this->dbHandler->addToken($target, ''); + } + + if ($status === Http::STATUS_OK) { $body = $result->getBody(); $result = json_decode($body, true); if (isset($result['ocs']['data']['sharedSecret'])) { @@ -152,5 +169,6 @@ class GetSharedSecret extends QueuedJob{ $this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE); } } + } } diff --git a/apps/federation/backgroundjob/requestsharedsecret.php b/apps/federation/backgroundjob/requestsharedsecret.php index b73b620b4b7..c945757818d 100644 --- a/apps/federation/backgroundjob/requestsharedsecret.php +++ b/apps/federation/backgroundjob/requestsharedsecret.php @@ -23,6 +23,7 @@ namespace OCA\Federation\BackgroundJob; +use GuzzleHttp\Exception\ClientException; use OC\BackgroundJob\QueuedJob; use OCA\Federation\DbHandler; use OCA\Federation\TrustedServers; @@ -50,6 +51,12 @@ class RequestSharedSecret extends QueuedJob { /** @var IURLGenerator */ private $urlGenerator; + /** @var DbHandler */ + private $dbHandler; + + /** @var TrustedServers */ + private $trustedServers; + private $endPoint = '/ocs/v2.php/apps/federation/api/v1/request-shared-secret?format=json'; /** @@ -59,21 +66,24 @@ class RequestSharedSecret extends QueuedJob { * @param IURLGenerator $urlGenerator * @param IJobList $jobList * @param TrustedServers $trustedServers + * @param DbHandler $dbHandler */ public function __construct( IClient $httpClient = null, IURLGenerator $urlGenerator = null, IJobList $jobList = null, - TrustedServers $trustedServers = null + TrustedServers $trustedServers = null, + dbHandler $dbHandler = null ) { $this->httpClient = $httpClient ? $httpClient : \OC::$server->getHTTPClientService()->newClient(); $this->jobList = $jobList ? $jobList : \OC::$server->getJobList(); $this->urlGenerator = $urlGenerator ? $urlGenerator : \OC::$server->getURLGenerator(); + $this->dbHandler = $dbHandler ? $dbHandler : new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation')); if ($trustedServers) { $this->trustedServers = $trustedServers; } else { $this->trustedServers = new TrustedServers( - new DbHandler(\OC::$server->getDatabaseConnection(), \OC::$server->getL10N('federation')), + $this->dbHandler, \OC::$server->getHTTPClientService(), \OC::$server->getLogger(), $this->jobList, @@ -106,19 +116,24 @@ class RequestSharedSecret extends QueuedJob { $source = rtrim($source, '/'); $token = $argument['token']; - $result = $this->httpClient->post( - $target . $this->endPoint, - [ - 'body' => [ - 'url' => $source, - 'token' => $token, - ], - 'timeout' => 3, - 'connect_timeout' => 3, - ] - ); + try { + $result = $this->httpClient->post( + $target . $this->endPoint, + [ + 'body' => [ + 'url' => $source, + 'token' => $token, + ], + 'timeout' => 3, + 'connect_timeout' => 3, + ] + ); - $status = $result->getStatusCode(); + $status = $result->getStatusCode(); + + } catch (ClientException $e) { + $status = $e->getCode(); + } // if we received a unexpected response we try again later if ( @@ -131,5 +146,10 @@ class RequestSharedSecret extends QueuedJob { ); } + if ($status === Http::STATUS_FORBIDDEN) { + // clear token if remote server refuses to ask for shared secret + $this->dbHandler->addToken($target, ''); + } + } } |