Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/lookup-server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Schiessle <bjoern@schiessle.org>2017-04-28 14:08:25 +0300
committerBjoern Schiessle <bjoern@schiessle.org>2017-04-28 15:53:28 +0300
commite4f43f4930e3f5b8be625f636badf79aa59b3154 (patch)
treebad77ec53d04e6b5f95cd326ad1862f131975aba
parente46a8d2acbed6c61ce0568a3b5bedfba0a69efe2 (diff)
make it more modular
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
-rw-r--r--server/lib/SignatureHandler.php88
-rw-r--r--server/lib/UserManager.php121
-rw-r--r--server/lib/Validator/Website.php91
-rw-r--r--server/src/dependencies.php9
-rw-r--r--server/vendor/composer/autoload_classmap.php2
-rw-r--r--server/vendor/composer/autoload_static.php2
6 files changed, 221 insertions, 92 deletions
diff --git a/server/lib/SignatureHandler.php b/server/lib/SignatureHandler.php
new file mode 100644
index 0000000..bf308d4
--- /dev/null
+++ b/server/lib/SignatureHandler.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer;
+
+use GuzzleHttp\Client;
+
+class SignatureHandler {
+
+ /**
+ * check signature of incoming request
+ *
+ * @param string $cloudId
+ * @param string $message
+ * @param string $signature
+ * @return bool
+ * @throws \Exception
+ */
+ public function verify($cloudId, $message, $signature) {
+ // Get fed id
+ list($user, $host) = $this->splitCloudId($cloudId);
+
+ // Retrieve public key && store
+ $ocsreq = new \GuzzleHttp\Psr7\Request(
+ 'GET',
+ 'http://'.$host . '/ocs/v2.php/identityproof/key/' . $user,
+ [
+ 'OCS-APIREQUEST' => 'true',
+ 'Accept' => 'application/json',
+ ]);
+
+ $client = new Client();
+ $ocsresponse = $client->send($ocsreq, ['timeout' => 10]);
+
+ $ocsresponse = json_decode($ocsresponse->getBody(), true);
+
+ if ($ocsresponse === null || !isset($ocsresponse['ocs']) ||
+ !isset($ocsresponse['ocs']['data']) || !isset($ocsresponse['ocs']['data']['public'])) {
+ throw new \BadMethodCallException();
+ }
+
+ $key = $ocsresponse['ocs']['data']['public'];
+
+ // verify message
+ $message = json_encode($message);
+ $signature= base64_decode($signature);
+
+ $res = openssl_verify($message, $signature, $key, OPENSSL_ALGO_SHA512);
+
+ return $res === 1;
+
+ }
+
+ /**
+ * Split a cloud id in a user and host post
+ *
+ * @param $cloudId
+ * @return string[]
+ */
+ private function splitCloudId($cloudId) {
+ $loc = strrpos($cloudId, '@');
+
+ $user = substr($cloudId, 0, $loc);
+ $host = substr($cloudId, $loc+1);
+ return [$user, $host];
+ }
+
+
+}
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php
index e6d2cbe..bf984c8 100644
--- a/server/lib/UserManager.php
+++ b/server/lib/UserManager.php
@@ -2,8 +2,8 @@
namespace LookupServer;
-use GuzzleHttp\Client;
use LookupServer\Validator\Email;
+use LookupServer\Validator\Website;
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
@@ -15,9 +15,28 @@ class UserManager {
/** @var Email */
private $emailValidator;
- public function __construct(\PDO $db, Email $emailValidator) {
+ /** @var Website */
+ private $websiteValidator;
+
+ /** @var SignatureHandler */
+ private $signatureHandler;
+
+ /**
+ * UserManager constructor.
+ *
+ * @param \PDO $db
+ * @param Email $emailValidator
+ * @param Website $websiteValidator
+ * @param SignatureHandler $signatureHandler
+ */
+ public function __construct(\PDO $db,
+ Email $emailValidator,
+ Website $websiteValidator,
+ SignatureHandler $signatureHandler) {
$this->db = $db;
$this->emailValidator = $emailValidator;
+ $this->websiteValidator = $websiteValidator;
+ $this->signatureHandler = $signatureHandler;
}
public function search(Request $request, Response $response) {
@@ -258,7 +277,7 @@ LIMIT 50');
$cloudId = $body['message']['data']['federationId'];
try {
- $verified = $this->verifyRequest($cloudId, $body['message'], $body['signature']);
+ $verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
} catch(\Exception $e) {
$response->withStatus(400);
return $response;
@@ -290,7 +309,7 @@ LIMIT 50');
$cloudId = $body['message']['data']['federationId'];
try {
- $verified = $this->verifyRequest($cloudId, $body['message'], $body['signature']);
+ $verified = $this->signatureHandler->verify($cloudId, $body['message'], $body['signature']);
} catch(\Exception $e) {
$response->withStatus(400);
return $response;
@@ -312,20 +331,21 @@ LIMIT 50');
public function verify(Request $request, Response $response) {
$verificationRequests = $this->getOpenVerificationRequests();
- foreach ($verificationRequests as $verify) {
+ foreach ($verificationRequests as $verificationData) {
$success = false;
- switch ($verify['property']) {
+ switch ($verificationData['property']) {
case 'twitter':
//ToDo try to Verify Twitter account
$success = $this->verifyTwitter();
break;
case 'website':
- $success = $this->verifyWebpage($verify);
+ $userData = $this->getForUserId($verificationData['userId']);
+ $success = $this->websiteValidator->verify($verificationData, $userData);
break;
}
if ($success) {
- $this->updateVerificationStatus($verify['storeId']);
- $this->removeOpenVerificationRequest($verify['id']);
+ $this->updateVerificationStatus($verificationData['storeId']);
+ $this->removeOpenVerificationRequest($verificationData['id']);
}
}
}
@@ -377,94 +397,13 @@ LIMIT 50');
// ToDo get proof from twitter user $location
// ToDo split $message & $signature
// ToDo "verifyRequest" needs to be able to handle the shortened md5 signature from twitter
- $result = $this->verifyRequest($cloudId, $message, $signature);
+ $result = $this->signatureHandler->verify($cloudId, $message, $signature);
return result;
}
/**
- * @param array $data
- * @return bool
- */
- private function verifyWebpage($data) {
- $url = $this->getValidUrl($data['location']);
- $proof = @file_get_contents($url);
- $result = false;
- if ($proof) {
- $userData = $this->getForUserId($data['userId']);
- $cloudId = $userData['federationId'];
- $proofSanitized = trim(preg_replace('/\s\s+/', ' ', $proof));
- list($message, $signature) = $this->splitMessageSignature($proofSanitized);
- $result = $this->verifyRequest($cloudId, $message, $signature);
- }
-
- return $result;
- }
-
- private function getValidUrl($url) {
- $url = trim($url);
- $url = rtrim($url, '/');
- if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
- $url = 'http://' . $url;
- }
-
- return $url . '/.well-known/CloudIdVerificationCode.txt';
- }
-
- private function splitMessageSignature($proof) {
- $signature = substr($proof, -344);
- $message = substr($proof, 0, -344);
-
- return [trim($message), trim($signature)];
- }
-
- /**
- * check signature of incoming request
- *
- * @param string $cloudId
- * @param string $message
- * @param string $signature
- * @return bool
- * @throws \Exception
- */
- protected function verifyRequest($cloudId, $message, $signature) {
- // Get fed id
- list($user, $host) = $this->splitCloudId($cloudId);
-
- // Retrieve public key && store
- $ocsreq = new \GuzzleHttp\Psr7\Request(
- 'GET',
- 'http://'.$host . '/ocs/v2.php/identityproof/key/' . $user,
- [
- 'OCS-APIREQUEST' => 'true',
- 'Accept' => 'application/json',
- ]);
-
- $client = new Client();
- $ocsresponse = $client->send($ocsreq, ['timeout' => 10]);
-
- $ocsresponse = json_decode($ocsresponse->getBody(), true);
-
- if ($ocsresponse === null || !isset($ocsresponse['ocs']) ||
- !isset($ocsresponse['ocs']['data']) || !isset($ocsresponse['ocs']['data']['public'])) {
- throw new \BadMethodCallException();
- }
-
- $key = $ocsresponse['ocs']['data']['public'];
-
- // verify message
- $message = json_encode($message);
- $signature= base64_decode($signature);
-
- $res = openssl_verify($message, $signature, $key, OPENSSL_ALGO_SHA512);
-
- return $res === 1;
-
- }
-
-
- /**
* @param string $cloudId
* @param string[] $data
* @param int $timestamp
diff --git a/server/lib/Validator/Website.php b/server/lib/Validator/Website.php
new file mode 100644
index 0000000..e43bfb0
--- /dev/null
+++ b/server/lib/Validator/Website.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace LookupServer\Validator;
+
+
+use LookupServer\SignatureHandler;
+
+class Website {
+
+ /** @var SignatureHandler */
+ private $signatureHandler;
+
+ public function __construct(SignatureHandler $signatureHandler) {
+ $this->signatureHandler = $signatureHandler;
+ }
+
+ /**
+ * verify website proof
+ *
+ * @param array $verificationData from toVerify table
+ * @param array $userData stored user data
+ * @return bool
+ */
+ public function verify($verificationData, $userData) {
+ $url = $this->getValidUrl($verificationData['location']);
+ $proof = @file_get_contents($url);
+ $result = false;
+ try {
+ if ($proof) {
+ $cloudId = $userData['federationId'];
+ $proofSanitized = trim(preg_replace('/\s\s+/', ' ', $proof));
+ list($message, $signature) = $this->splitMessageSignature($proofSanitized);
+ $result = $this->signatureHandler->verify($cloudId, $message, $signature);
+ }
+ } catch (\Exception $e) {
+ // do nothing, just return false
+ }
+
+ return $result;
+ }
+
+ /**
+ * construct valid URL to proof
+ *
+ * @param string $url
+ * @return string
+ */
+ private function getValidUrl($url) {
+ $url = trim($url);
+ $url = rtrim($url, '/');
+ if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) {
+ $url = 'http://' . $url;
+ }
+
+ return $url . '/.well-known/CloudIdVerificationCode.txt';
+ }
+
+ /**
+ * split message and signature
+ *
+ * @param string $proof
+ * @return array
+ */
+ private function splitMessageSignature($proof) {
+ $signature = substr($proof, -344);
+ $message = substr($proof, 0, -344);
+
+ return [trim($message), trim($signature)];
+ }
+
+}
diff --git a/server/src/dependencies.php b/server/src/dependencies.php
index 0e95274..38e7fc4 100644
--- a/server/src/dependencies.php
+++ b/server/src/dependencies.php
@@ -9,7 +9,10 @@ $container['db'] = function($c) {
return $pdo;
};
$container['UserManager'] = function($c) {
- return new \LookupServer\UserManager($c->db, $c->EmailValidator);
+ return new \LookupServer\UserManager($c->db, $c->EmailValidator, $c->WebsiteValidator, $c->SignatureHandler);
+};
+$container['SignatureHandler'] = function($c) {
+ return new \LookupServer\SignatureHandler();
};
$container['EmailValidator'] = function($c) {
return new \LookupServer\Validator\Email(
@@ -19,6 +22,10 @@ $container['EmailValidator'] = function($c) {
$c->settings['emailfrom']
);
};
+$container['WebsiteValidator'] = function($c) {
+ return new \LookupServer\Validator\Website($c->SignatureHandler);
+};
+
$container['Status'] = function($c) {
return new \LookupServer\Status();
};
diff --git a/server/vendor/composer/autoload_classmap.php b/server/vendor/composer/autoload_classmap.php
index 071a334..0c0d91d 100644
--- a/server/vendor/composer/autoload_classmap.php
+++ b/server/vendor/composer/autoload_classmap.php
@@ -107,9 +107,11 @@ return array(
'Interop\\Container\\Exception\\NotFoundException' => $vendorDir . '/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php',
'LookupServer\\BruteForceMiddleware' => $baseDir . '/lib/BruteForceMiddleware.php',
'LookupServer\\Replication' => $baseDir . '/lib/Replication.php',
+ 'LookupServer\\SignatureHandler' => $baseDir . '/lib/SignatureHandler.php',
'LookupServer\\Status' => $baseDir . '/lib/Status.php',
'LookupServer\\UserManager' => $baseDir . '/lib/UserManager.php',
'LookupServer\\Validator\\Email' => $baseDir . '/lib/Validator/Email.php',
+ 'LookupServer\\Validator\\Website' => $baseDir . '/lib/Validator/Website.php',
'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
diff --git a/server/vendor/composer/autoload_static.php b/server/vendor/composer/autoload_static.php
index 9e6a83d..9726f0f 100644
--- a/server/vendor/composer/autoload_static.php
+++ b/server/vendor/composer/autoload_static.php
@@ -202,9 +202,11 @@ class ComposerStaticInit509ee4e79733fbe3199b97373b795eca
'Interop\\Container\\Exception\\NotFoundException' => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php',
'LookupServer\\BruteForceMiddleware' => __DIR__ . '/../..' . '/lib/BruteForceMiddleware.php',
'LookupServer\\Replication' => __DIR__ . '/../..' . '/lib/Replication.php',
+ 'LookupServer\\SignatureHandler' => __DIR__ . '/../..' . '/lib/SignatureHandler.php',
'LookupServer\\Status' => __DIR__ . '/../..' . '/lib/Status.php',
'LookupServer\\UserManager' => __DIR__ . '/../..' . '/lib/UserManager.php',
'LookupServer\\Validator\\Email' => __DIR__ . '/../..' . '/lib/Validator/Email.php',
+ 'LookupServer\\Validator\\Website' => __DIR__ . '/../..' . '/lib/Validator/Website.php',
'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
'Pimple\\Tests\\Fixtures\\Invokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',