diff options
author | Björn Schießle <bjoern@schiessle.org> | 2015-11-10 10:50:59 +0100 |
---|---|---|
committer | Björn Schießle <bjoern@schiessle.org> | 2015-11-19 18:06:51 +0100 |
commit | 698100d279fdd8c8bc086e729833705d1a31c018 (patch) | |
tree | 3e38110373da82a5a89dbbe1a84708b6208b7d51 /apps/federation/lib | |
parent | ed039ee5ebdba6778b245f249fe206d2423a6a36 (diff) | |
download | nextcloud-server-698100d279fdd8c8bc086e729833705d1a31c018.tar.gz nextcloud-server-698100d279fdd8c8bc086e729833705d1a31c018.zip |
exchange shared secret
Diffstat (limited to 'apps/federation/lib')
-rw-r--r-- | apps/federation/lib/dbhandler.php | 182 | ||||
-rw-r--r-- | apps/federation/lib/trustedservers.php | 105 |
2 files changed, 237 insertions, 50 deletions
diff --git a/apps/federation/lib/dbhandler.php b/apps/federation/lib/dbhandler.php index 1100875cc23..58cf0f7f3b9 100644 --- a/apps/federation/lib/dbhandler.php +++ b/apps/federation/lib/dbhandler.php @@ -23,10 +23,19 @@ namespace OCA\Federation; +use OC\Files\Filesystem; use OC\HintException; use OCP\IDBConnection; use OCP\IL10N; +/** + * Class DbHandler + * + * handles all database calls for the federation app + * + * @group DB + * @package OCA\Federation + */ class DbHandler { /** @var IDBConnection */ @@ -53,12 +62,12 @@ class DbHandler { /** * add server to the list of trusted ownCloud servers * - * @param $url + * @param string $url * @return int * @throws HintException */ - public function add($url) { - $hash = md5($url); + public function addServer($url) { + $hash = $this->hash($url); $query = $this->connection->getQueryBuilder(); $query->insert($this->dbTable) ->values( @@ -73,14 +82,7 @@ class DbHandler { $result = $query->execute(); if ($result) { - $id = $this->connection->lastInsertId(); - // Fallback, if lastInterId() doesn't work we need to perform a select - // to get the ID (seems to happen sometimes on Oracle) - if (!$id) { - $server = $this->get($url); - $id = $server['id']; - } - return $id; + return $this->connection->lastInsertId($this->dbTable); } else { $message = 'Internal failure, Could not add ownCloud as trusted server: ' . $url; $message_t = $this->l->t('Could not add server'); @@ -93,7 +95,7 @@ class DbHandler { * * @param int $id */ - public function remove($id) { + public function removeServer($id) { $query = $this->connection->getQueryBuilder(); $query->delete($this->dbTable) ->where($query->expr()->eq('id', $query->createParameter('id'))) @@ -102,26 +104,11 @@ class DbHandler { } /** - * get trusted server from database - * - * @param $url - * @return mixed - */ - public function get($url) { - $query = $this->connection->getQueryBuilder(); - $query->select('url', 'id')->from($this->dbTable) - ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) - ->setParameter('url_hash', md5($url)); - - return $query->execute()->fetch(); - } - - /** * get all trusted servers * * @return array */ - public function getAll() { + public function getAllServer() { $query = $this->connection->getQueryBuilder(); $query->select('url', 'id')->from($this->dbTable); $result = $query->execute()->fetchAll(); @@ -134,14 +121,149 @@ class DbHandler { * @param string $url * @return bool */ - public function exists($url) { + public function serverExists($url) { + $hash = $this->hash($url); $query = $this->connection->getQueryBuilder(); $query->select('url')->from($this->dbTable) ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) - ->setParameter('url_hash', md5($url)); + ->setParameter('url_hash', $hash); $result = $query->execute()->fetchAll(); return !empty($result); } + /** + * write token to database. Token is used to exchange the secret + * + * @param string $url + * @param string $token + */ + public function addToken($url, $token) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->update($this->dbTable) + ->set('token', $query->createParameter('token')) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash) + ->setParameter('token', $token); + $query->execute(); + } + + /** + * get token stored in database + * + * @param string $url + * @return string + */ + public function getToken($url) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->select('token')->from($this->dbTable) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash); + + $result = $query->execute()->fetch(); + return $result['token']; + } + + /** + * add shared Secret to database + * + * @param string $url + * @param string $sharedSecret + */ + public function addSharedSecret($url, $sharedSecret) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->update($this->dbTable) + ->set('shared_secret', $query->createParameter('sharedSecret')) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash) + ->setParameter('sharedSecret', $sharedSecret); + $query->execute(); + } + + /** + * get shared secret from database + * + * @param string $url + * @return string + */ + public function getSharedSecret($url) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->select('shared_secret')->from($this->dbTable) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash); + + $result = $query->execute()->fetch(); + return $result['shared_secret']; + } + + /** + * set server status + * + * @param string $url + * @param int $status + */ + public function setServerStatus($url, $status) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->update($this->dbTable) + ->set('status', $query->createParameter('status')) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash) + ->setParameter('status', $status); + $query->execute(); + } + + /** + * get server status + * + * @param string $url + * @return int + */ + public function getServerStatus($url) { + $hash = $this->hash($url); + $query = $this->connection->getQueryBuilder(); + $query->select('status')->from($this->dbTable) + ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash'))) + ->setParameter('url_hash', $hash); + + $result = $query->execute()->fetch(); + return $result['status']; + } + + /** + * create hash from URL + * + * @param string $url + * @return string + */ + protected function hash($url) { + $normalized = $this->normalizeUrl($url); + return md5($normalized); + } + + /** + * normalize URL, used to create the md5 hash + * + * @param string $url + * @return string + */ + protected function normalizeUrl($url) { + $normalized = $url; + + if (strpos($url, 'https://') === 0) { + $normalized = substr($url, strlen('https://')); + } else if (strpos($url, 'http://') === 0) { + $normalized = substr($url, strlen('http://')); + } + + $normalized = Filesystem::normalizePath($normalized); + $normalized = trim($normalized, '/'); + + return $normalized; + } + } diff --git a/apps/federation/lib/trustedservers.php b/apps/federation/lib/trustedservers.php index bf31277b2a8..f3ac6e24fc6 100644 --- a/apps/federation/lib/trustedservers.php +++ b/apps/federation/lib/trustedservers.php @@ -22,15 +22,21 @@ namespace OCA\Federation; - -use OC\Files\Filesystem; use OCP\AppFramework\Http; +use OCP\BackgroundJob\IJobList; use OCP\Http\Client\IClientService; -use OCP\IDBConnection; use OCP\ILogger; +use OCP\Security\ISecureRandom; class TrustedServers { + /** after a user list was exchanged at least once successfully */ + const STATUS_OK = 1; + /** waiting for shared secret or initial user list exchange */ + const STATUS_PENDING = 2; + /** something went wrong, misconfigured server, software bug,... user interaction needed */ + const STATUS_FAILURE = 3; + /** @var dbHandler */ private $dbHandler; @@ -40,21 +46,31 @@ class TrustedServers { /** @var ILogger */ private $logger; - private $dbTable = 'trusted_servers'; + /** @var IJobList */ + private $jobList; + + /** @var ISecureRandom */ + private $secureRandom; /** * @param DbHandler $dbHandler * @param IClientService $httpClientService * @param ILogger $logger + * @param IJobList $jobList + * @param ISecureRandom $secureRandom */ public function __construct( DbHandler $dbHandler, IClientService $httpClientService, - ILogger $logger + ILogger $logger, + IJobList $jobList, + ISecureRandom $secureRandom ) { $this->dbHandler = $dbHandler; $this->httpClientService = $httpClientService; $this->logger = $logger; + $this->jobList = $jobList; + $this->secureRandom = $secureRandom; } /** @@ -64,7 +80,41 @@ class TrustedServers { * @return int server id */ public function addServer($url) { - return $this->dbHandler->add($this->normalizeUrl($url)); + $url = $this->updateProtocol($url); + $result = $this->dbHandler->addServer($url); + if ($result) { + $token = $this->secureRandom->getMediumStrengthGenerator()->generate(16); + $this->dbHandler->addToken($url, $token); + $this->jobList->add( + 'OCA\Federation\BackgroundJob\RequestSharedSecret', + [ + 'url' => $url, + 'token' => $token + ] + ); + } + + return $result; + } + + /** + * get shared secret for the given server + * + * @param string $url + * @return string + */ + public function getSharedSecret($url) { + return $this->dbHandler->getSharedSecret($url); + } + + /** + * add shared secret for the given server + * + * @param string $url + * @param $sharedSecret + */ + public function addSharedSecret($url, $sharedSecret) { + $this->dbHandler->addSharedSecret($url, $sharedSecret); } /** @@ -73,7 +123,7 @@ class TrustedServers { * @param int $id */ public function removeServer($id) { - $this->dbHandler->remove($id); + $this->dbHandler->removeServer($id); } /** @@ -82,7 +132,7 @@ class TrustedServers { * @return array */ public function getServers() { - return $this->dbHandler->getAll(); + return $this->dbHandler->getAllServer(); } /** @@ -92,7 +142,25 @@ class TrustedServers { * @return bool */ public function isTrustedServer($url) { - return $this->dbHandler->exists($this->normalizeUrl($url)); + return $this->dbHandler->serverExists($url); + } + + /** + * set server status + * + * @param string $url + * @param int $status + */ + public function setServerStatus($url, $status) { + $this->dbHandler->setServerStatus($url, $status); + } + + /** + * @param string $url + * @return int + */ + public function getServerStatus($url) { + return $this->dbHandler->getServerStatus($url); } /** @@ -137,24 +205,21 @@ class TrustedServers { } /** - * normalize URL + * check if the URL contain a protocol, if not add https * * @param string $url * @return string */ - protected function normalizeUrl($url) { + protected function updateProtocol($url) { + if ( + strpos($url, 'https://') === 0 + || strpos($url, 'http://') === 0 + ) { - $normalized = $url; + return $url; - if (strpos($url, 'https://') === 0) { - $normalized = substr($url, strlen('https://')); - } else if (strpos($url, 'http://') === 0) { - $normalized = substr($url, strlen('http://')); } - $normalized = Filesystem::normalizePath($normalized); - $normalized = trim($normalized, '/'); - - return $normalized; + return 'https://' . $url; } } |