diff options
Diffstat (limited to 'lib/private/security')
-rw-r--r-- | lib/private/security/certificate.php | 122 | ||||
-rw-r--r-- | lib/private/security/certificatemanager.php | 250 | ||||
-rw-r--r-- | lib/private/security/credentialsmanager.php | 125 | ||||
-rw-r--r-- | lib/private/security/crypto.php | 134 | ||||
-rw-r--r-- | lib/private/security/csp/contentsecuritypolicy.php | 199 | ||||
-rw-r--r-- | lib/private/security/csp/contentsecuritypolicymanager.php | 73 | ||||
-rw-r--r-- | lib/private/security/csrf/csrftoken.php | 69 | ||||
-rw-r--r-- | lib/private/security/csrf/csrftokengenerator.php | 52 | ||||
-rw-r--r-- | lib/private/security/csrf/csrftokenmanager.php | 97 | ||||
-rw-r--r-- | lib/private/security/csrf/tokenstorage/sessionstorage.php | 80 | ||||
-rw-r--r-- | lib/private/security/hasher.php | 160 | ||||
-rw-r--r-- | lib/private/security/securerandom.php | 86 | ||||
-rw-r--r-- | lib/private/security/trusteddomainhelper.php | 90 |
13 files changed, 0 insertions, 1537 deletions
diff --git a/lib/private/security/certificate.php b/lib/private/security/certificate.php deleted file mode 100644 index 54486ff51fe..00000000000 --- a/lib/private/security/certificate.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security; - -use OCP\ICertificate; - -class Certificate implements ICertificate { - protected $name; - - protected $commonName; - - protected $organization; - - protected $serial; - - protected $issueDate; - - protected $expireDate; - - protected $issuerName; - - protected $issuerOrganization; - - /** - * @param string $data base64 encoded certificate - * @param string $name - * @throws \Exception If the certificate could not get parsed - */ - public function __construct($data, $name) { - $this->name = $name; - $gmt = new \DateTimeZone('GMT'); - $info = openssl_x509_parse($data); - if(!is_array($info)) { - throw new \Exception('Certificate could not get parsed.'); - } - - $this->commonName = isset($info['subject']['CN']) ? $info['subject']['CN'] : null; - $this->organization = isset($info['subject']['O']) ? $info['subject']['O'] : null; - $this->issueDate = new \DateTime('@' . $info['validFrom_time_t'], $gmt); - $this->expireDate = new \DateTime('@' . $info['validTo_time_t'], $gmt); - $this->issuerName = isset($info['issuer']['CN']) ? $info['issuer']['CN'] : null; - $this->issuerOrganization = isset($info['issuer']['O']) ? $info['issuer']['O'] : null; - } - - /** - * @return string - */ - public function getName() { - return $this->name; - } - - /** - * @return string|null - */ - public function getCommonName() { - return $this->commonName; - } - - /** - * @return string - */ - public function getOrganization() { - return $this->organization; - } - - /** - * @return \DateTime - */ - public function getIssueDate() { - return $this->issueDate; - } - - /** - * @return \DateTime - */ - public function getExpireDate() { - return $this->expireDate; - } - - /** - * @return bool - */ - public function isExpired() { - $now = new \DateTime(); - return $this->issueDate > $now or $now > $this->expireDate; - } - - /** - * @return string|null - */ - public function getIssuerName() { - return $this->issuerName; - } - - /** - * @return string|null - */ - public function getIssuerOrganization() { - return $this->issuerOrganization; - } -} diff --git a/lib/private/security/certificatemanager.php b/lib/private/security/certificatemanager.php deleted file mode 100644 index f4932ca568e..00000000000 --- a/lib/private/security/certificatemanager.php +++ /dev/null @@ -1,250 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security; - -use OC\Files\Filesystem; -use OCP\ICertificateManager; -use OCP\IConfig; - -/** - * Manage trusted certificates for users - */ -class CertificateManager implements ICertificateManager { - /** - * @var string - */ - protected $uid; - - /** - * @var \OC\Files\View - */ - protected $view; - - /** - * @var IConfig - */ - protected $config; - - /** - * @param string $uid - * @param \OC\Files\View $view relative to data/ - * @param IConfig $config - */ - public function __construct($uid, \OC\Files\View $view, IConfig $config) { - $this->uid = $uid; - $this->view = $view; - $this->config = $config; - } - - /** - * Returns all certificates trusted by the user - * - * @return \OCP\ICertificate[] - */ - public function listCertificates() { - - if (!$this->config->getSystemValue('installed', false)) { - return array(); - } - - $path = $this->getPathToCertificates() . 'uploads/'; - if (!$this->view->is_dir($path)) { - return array(); - } - $result = array(); - $handle = $this->view->opendir($path); - if (!is_resource($handle)) { - return array(); - } - while (false !== ($file = readdir($handle))) { - if ($file != '.' && $file != '..') { - try { - $result[] = new Certificate($this->view->file_get_contents($path . $file), $file); - } catch (\Exception $e) { - } - } - } - closedir($handle); - return $result; - } - - /** - * create the certificate bundle of all trusted certificated - */ - public function createCertificateBundle() { - $path = $this->getPathToCertificates(); - $certs = $this->listCertificates(); - - if (!$this->view->file_exists($path)) { - $this->view->mkdir($path); - } - - $fhCerts = $this->view->fopen($path . '/rootcerts.crt', 'w'); - - // Write user certificates - foreach ($certs as $cert) { - $file = $path . '/uploads/' . $cert->getName(); - $data = $this->view->file_get_contents($file); - if (strpos($data, 'BEGIN CERTIFICATE')) { - fwrite($fhCerts, $data); - fwrite($fhCerts, "\r\n"); - } - } - - // Append the default certificates - $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt'); - fwrite($fhCerts, $defaultCertificates); - - // Append the system certificate bundle - $systemBundle = $this->getCertificateBundle(null); - if ($this->view->file_exists($systemBundle)) { - $systemCertificates = $this->view->file_get_contents($systemBundle); - fwrite($fhCerts, $systemCertificates); - } - - fclose($fhCerts); - } - - /** - * Save the certificate and re-generate the certificate bundle - * - * @param string $certificate the certificate data - * @param string $name the filename for the certificate - * @return \OCP\ICertificate - * @throws \Exception If the certificate could not get added - */ - public function addCertificate($certificate, $name) { - if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) { - throw new \Exception('Filename is not valid'); - } - - $dir = $this->getPathToCertificates() . 'uploads/'; - if (!$this->view->file_exists($dir)) { - $this->view->mkdir($dir); - } - - try { - $file = $dir . $name; - $certificateObject = new Certificate($certificate, $name); - $this->view->file_put_contents($file, $certificate); - $this->createCertificateBundle(); - return $certificateObject; - } catch (\Exception $e) { - throw $e; - } - - } - - /** - * Remove the certificate and re-generate the certificate bundle - * - * @param string $name - * @return bool - */ - public function removeCertificate($name) { - if (!Filesystem::isValidPath($name)) { - return false; - } - $path = $this->getPathToCertificates() . 'uploads/'; - if ($this->view->file_exists($path . $name)) { - $this->view->unlink($path . $name); - $this->createCertificateBundle(); - } - return true; - } - - /** - * Get the path to the certificate bundle for this user - * - * @param string $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle - * @return string - */ - public function getCertificateBundle($uid = '') { - if ($uid === '') { - $uid = $this->uid; - } - return $this->getPathToCertificates($uid) . 'rootcerts.crt'; - } - - /** - * Get the full local path to the certificate bundle for this user - * - * @param string $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle - * @return string - */ - public function getAbsoluteBundlePath($uid = '') { - if ($uid === '') { - $uid = $this->uid; - } - if ($this->needsRebundling($uid)) { - if (is_null($uid)) { - $manager = new CertificateManager(null, $this->view, $this->config); - $manager->createCertificateBundle(); - } else { - $this->createCertificateBundle(); - } - } - return $this->view->getLocalFile($this->getCertificateBundle($uid)); - } - - /** - * @param string $uid (optional) user to get the certificate path for, use `null` to get the system path - * @return string - */ - private function getPathToCertificates($uid = '') { - if ($uid === '') { - $uid = $this->uid; - } - $path = is_null($uid) ? '/files_external/' : '/' . $uid . '/files_external/'; - - return $path; - } - - /** - * Check if we need to re-bundle the certificates because one of the sources has updated - * - * @param string $uid (optional) user to get the certificate path for, use `null` to get the system path - * @return bool - */ - private function needsRebundling($uid = '') { - if ($uid === '') { - $uid = $this->uid; - } - $sourceMTimes = [filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt')]; - $targetBundle = $this->getCertificateBundle($uid); - if (!$this->view->file_exists($targetBundle)) { - return true; - } - if (!is_null($uid)) { // also depend on the system bundle - $sourceBundles[] = $this->view->filemtime($this->getCertificateBundle(null)); - } - - $sourceMTime = array_reduce($sourceMTimes, function ($max, $mtime) { - return max($max, $mtime); - }, 0); - return $sourceMTime > $this->view->filemtime($targetBundle); - } -} diff --git a/lib/private/security/credentialsmanager.php b/lib/private/security/credentialsmanager.php deleted file mode 100644 index d4104dbe712..00000000000 --- a/lib/private/security/credentialsmanager.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * @author Robin McCorkell <robin@mccorkell.me.uk> - * - * @copyright Copyright (c) 2016, 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\Security; - -use OCP\Security\ICrypto; -use OCP\IDBConnection; -use OCP\Security\ICredentialsManager; -use OCP\IConfig; - -/** - * Store and retrieve credentials for external services - * - * @package OC\Security - */ -class CredentialsManager implements ICredentialsManager { - - const DB_TABLE = 'credentials'; - - /** @var ICrypto */ - protected $crypto; - - /** @var IDBConnection */ - protected $dbConnection; - - /** - * @param ICrypto $crypto - * @param IDBConnection $dbConnection - */ - public function __construct(ICrypto $crypto, IDBConnection $dbConnection) { - $this->crypto = $crypto; - $this->dbConnection = $dbConnection; - } - - /** - * Store a set of credentials - * - * @param string|null $userId Null for system-wide credentials - * @param string $identifier - * @param mixed $credentials - */ - public function store($userId, $identifier, $credentials) { - $value = $this->crypto->encrypt(json_encode($credentials)); - - $this->dbConnection->setValues(self::DB_TABLE, [ - 'user' => $userId, - 'identifier' => $identifier, - ], [ - 'credentials' => $value, - ]); - } - - /** - * Retrieve a set of credentials - * - * @param string|null $userId Null for system-wide credentials - * @param string $identifier - * @return mixed - */ - public function retrieve($userId, $identifier) { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->select('credentials') - ->from(self::DB_TABLE) - ->where($qb->expr()->eq('user', $qb->createNamedParameter($userId))) - ->andWhere($qb->expr()->eq('identifier', $qb->createNamedParameter($identifier))) - ; - $result = $qb->execute()->fetch(); - - if (!$result) { - return null; - } - $value = $result['credentials']; - - return json_decode($this->crypto->decrypt($value), true); - } - - /** - * Delete a set of credentials - * - * @param string|null $userId Null for system-wide credentials - * @param string $identifier - * @return int rows removed - */ - public function delete($userId, $identifier) { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->delete(self::DB_TABLE) - ->where($qb->expr()->eq('user', $qb->createNamedParameter($userId))) - ->andWhere($qb->expr()->eq('identifier', $qb->createNamedParameter($identifier))) - ; - return $qb->execute(); - } - - /** - * Erase all credentials stored for a user - * - * @param string $userId - * @return int rows removed - */ - public function erase($userId) { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->delete(self::DB_TABLE) - ->where($qb->expr()->eq('user', $qb->createNamedParameter($userId))) - ; - return $qb->execute(); - } - -} diff --git a/lib/private/security/crypto.php b/lib/private/security/crypto.php deleted file mode 100644 index 3c3ffb47398..00000000000 --- a/lib/private/security/crypto.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/** - * @author Andreas Fischer <bantu@owncloud.com> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <rullzer@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security; - -use phpseclib\Crypt\AES; -use phpseclib\Crypt\Hash; -use OCP\Security\ICrypto; -use OCP\Security\ISecureRandom; -use OCP\IConfig; - -/** - * Class Crypto provides a high-level encryption layer using AES-CBC. If no key has been provided - * it will use the secret defined in config.php as key. Additionally the message will be HMAC'd. - * - * Usage: - * $encryptWithDefaultPassword = \OC::$server->getCrypto()->encrypt('EncryptedText'); - * $encryptWithCustompassword = \OC::$server->getCrypto()->encrypt('EncryptedText', 'password'); - * - * @package OC\Security - */ -class Crypto implements ICrypto { - /** @var AES $cipher */ - private $cipher; - /** @var int */ - private $ivLength = 16; - /** @var IConfig */ - private $config; - /** @var ISecureRandom */ - private $random; - - /** - * @param IConfig $config - * @param ISecureRandom $random - */ - function __construct(IConfig $config, ISecureRandom $random) { - $this->cipher = new AES(); - $this->config = $config; - $this->random = $random; - } - - /** - * @param string $message The message to authenticate - * @param string $password Password to use (defaults to `secret` in config.php) - * @return string Calculated HMAC - */ - public function calculateHMAC($message, $password = '') { - if($password === '') { - $password = $this->config->getSystemValue('secret'); - } - - // Append an "a" behind the password and hash it to prevent reusing the same password as for encryption - $password = hash('sha512', $password . 'a'); - - $hash = new Hash('sha512'); - $hash->setKey($password); - return $hash->hash($message); - } - - /** - * Encrypts a value and adds an HMAC (Encrypt-Then-MAC) - * @param string $plaintext - * @param string $password Password to encrypt, if not specified the secret from config.php will be taken - * @return string Authenticated ciphertext - */ - public function encrypt($plaintext, $password = '') { - if($password === '') { - $password = $this->config->getSystemValue('secret'); - } - $this->cipher->setPassword($password); - - $iv = $this->random->generate($this->ivLength); - $this->cipher->setIV($iv); - - $ciphertext = bin2hex($this->cipher->encrypt($plaintext)); - $hmac = bin2hex($this->calculateHMAC($ciphertext.$iv, $password)); - - return $ciphertext.'|'.$iv.'|'.$hmac; - } - - /** - * Decrypts a value and verifies the HMAC (Encrypt-Then-Mac) - * @param string $authenticatedCiphertext - * @param string $password Password to encrypt, if not specified the secret from config.php will be taken - * @return string plaintext - * @throws \Exception If the HMAC does not match - */ - public function decrypt($authenticatedCiphertext, $password = '') { - if($password === '') { - $password = $this->config->getSystemValue('secret'); - } - $this->cipher->setPassword($password); - - $parts = explode('|', $authenticatedCiphertext); - if(sizeof($parts) !== 3) { - throw new \Exception('Authenticated ciphertext could not be decoded.'); - } - - $ciphertext = hex2bin($parts[0]); - $iv = $parts[1]; - $hmac = hex2bin($parts[2]); - - $this->cipher->setIV($iv); - - if(!hash_equals($this->calculateHMAC($parts[0].$parts[1], $password), $hmac)) { - throw new \Exception('HMAC does not match.'); - } - - return $this->cipher->decrypt($ciphertext); - } - -} diff --git a/lib/private/security/csp/contentsecuritypolicy.php b/lib/private/security/csp/contentsecuritypolicy.php deleted file mode 100644 index 25eacfab1d6..00000000000 --- a/lib/private/security/csp/contentsecuritypolicy.php +++ /dev/null @@ -1,199 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSP; - -/** - * Class ContentSecurityPolicy extends the public class and adds getter and setters. - * This is necessary since we don't want to expose the setters and getters to the - * public API. - * - * @package OC\Security\CSP - */ -class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy { - /** - * @return boolean - */ - public function isInlineScriptAllowed() { - return $this->inlineScriptAllowed; - } - - /** - * @param boolean $inlineScriptAllowed - */ - public function setInlineScriptAllowed($inlineScriptAllowed) { - $this->inlineScriptAllowed = $inlineScriptAllowed; - } - - /** - * @return boolean - */ - public function isEvalScriptAllowed() { - return $this->evalScriptAllowed; - } - - /** - * @param boolean $evalScriptAllowed - */ - public function setEvalScriptAllowed($evalScriptAllowed) { - $this->evalScriptAllowed = $evalScriptAllowed; - } - - /** - * @return array - */ - public function getAllowedScriptDomains() { - return $this->allowedScriptDomains; - } - - /** - * @param array $allowedScriptDomains - */ - public function setAllowedScriptDomains($allowedScriptDomains) { - $this->allowedScriptDomains = $allowedScriptDomains; - } - - /** - * @return boolean - */ - public function isInlineStyleAllowed() { - return $this->inlineStyleAllowed; - } - - /** - * @param boolean $inlineStyleAllowed - */ - public function setInlineStyleAllowed($inlineStyleAllowed) { - $this->inlineStyleAllowed = $inlineStyleAllowed; - } - - /** - * @return array - */ - public function getAllowedStyleDomains() { - return $this->allowedStyleDomains; - } - - /** - * @param array $allowedStyleDomains - */ - public function setAllowedStyleDomains($allowedStyleDomains) { - $this->allowedStyleDomains = $allowedStyleDomains; - } - - /** - * @return array - */ - public function getAllowedImageDomains() { - return $this->allowedImageDomains; - } - - /** - * @param array $allowedImageDomains - */ - public function setAllowedImageDomains($allowedImageDomains) { - $this->allowedImageDomains = $allowedImageDomains; - } - - /** - * @return array - */ - public function getAllowedConnectDomains() { - return $this->allowedConnectDomains; - } - - /** - * @param array $allowedConnectDomains - */ - public function setAllowedConnectDomains($allowedConnectDomains) { - $this->allowedConnectDomains = $allowedConnectDomains; - } - - /** - * @return array - */ - public function getAllowedMediaDomains() { - return $this->allowedMediaDomains; - } - - /** - * @param array $allowedMediaDomains - */ - public function setAllowedMediaDomains($allowedMediaDomains) { - $this->allowedMediaDomains = $allowedMediaDomains; - } - - /** - * @return array - */ - public function getAllowedObjectDomains() { - return $this->allowedObjectDomains; - } - - /** - * @param array $allowedObjectDomains - */ - public function setAllowedObjectDomains($allowedObjectDomains) { - $this->allowedObjectDomains = $allowedObjectDomains; - } - - /** - * @return array - */ - public function getAllowedFrameDomains() { - return $this->allowedFrameDomains; - } - - /** - * @param array $allowedFrameDomains - */ - public function setAllowedFrameDomains($allowedFrameDomains) { - $this->allowedFrameDomains = $allowedFrameDomains; - } - - /** - * @return array - */ - public function getAllowedFontDomains() { - return $this->allowedFontDomains; - } - - /** - * @param array $allowedFontDomains - */ - public function setAllowedFontDomains($allowedFontDomains) { - $this->allowedFontDomains = $allowedFontDomains; - } - - /** - * @return array - */ - public function getAllowedChildSrcDomains() { - return $this->allowedChildSrcDomains; - } - - /** - * @param array $allowedChildSrcDomains - */ - public function setAllowedChildSrcDomains($allowedChildSrcDomains) { - $this->allowedChildSrcDomains = $allowedChildSrcDomains; - } - -} diff --git a/lib/private/security/csp/contentsecuritypolicymanager.php b/lib/private/security/csp/contentsecuritypolicymanager.php deleted file mode 100644 index 760cd36e56b..00000000000 --- a/lib/private/security/csp/contentsecuritypolicymanager.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSP; - -use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\AppFramework\Http\EmptyContentSecurityPolicy; -use OCP\Security\IContentSecurityPolicyManager; - -class ContentSecurityPolicyManager implements IContentSecurityPolicyManager { - /** @var ContentSecurityPolicy[] */ - private $policies = []; - - /** {@inheritdoc} */ - public function addDefaultPolicy(EmptyContentSecurityPolicy $policy) { - $this->policies[] = $policy; - } - - /** - * Get the configured default policy. This is not in the public namespace - * as it is only supposed to be used by core itself. - * - * @return ContentSecurityPolicy - */ - public function getDefaultPolicy() { - $defaultPolicy = new \OC\Security\CSP\ContentSecurityPolicy(); - foreach($this->policies as $policy) { - $defaultPolicy = $this->mergePolicies($defaultPolicy, $policy); - } - return $defaultPolicy; - } - - /** - * Merges the first given policy with the second one - * - * @param ContentSecurityPolicy $defaultPolicy - * @param EmptyContentSecurityPolicy $originalPolicy - * @return ContentSecurityPolicy - */ - public function mergePolicies(ContentSecurityPolicy $defaultPolicy, - EmptyContentSecurityPolicy $originalPolicy) { - foreach((object)(array)$originalPolicy as $name => $value) { - $setter = 'set'.ucfirst($name); - if(is_array($value)) { - $getter = 'get'.ucfirst($name); - $currentValues = is_array($defaultPolicy->$getter()) ? $defaultPolicy->$getter() : []; - $defaultPolicy->$setter(array_values(array_unique(array_merge($currentValues, $value)))); - } elseif (is_bool($value)) { - $defaultPolicy->$setter($value); - } - } - - return $defaultPolicy; - } -} diff --git a/lib/private/security/csrf/csrftoken.php b/lib/private/security/csrf/csrftoken.php deleted file mode 100644 index 4524d0db6e6..00000000000 --- a/lib/private/security/csrf/csrftoken.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSRF; - -/** - * Class CsrfToken represents the stored or provided CSRF token. To mitigate - * BREACH alike vulnerabilities the token is returned in an encrypted value as - * well in an unencrypted value. For display measures to the user always the - * unencrypted one should be chosen. - * - * @package OC\Security\CSRF - */ -class CsrfToken { - /** @var string */ - private $value; - - /** - * @param string $value Value of the token. Can be encrypted or not encrypted. - */ - public function __construct($value) { - $this->value = $value; - } - - /** - * Encrypted value of the token. This is used to mitigate BREACH alike - * vulnerabilities. For display measures do use this functionality. - * - * @return string - */ - public function getEncryptedValue() { - $sharedSecret = base64_encode(random_bytes(strlen($this->value))); - return base64_encode($this->value ^ $sharedSecret) .':'.$sharedSecret; - } - - /** - * The unencrypted value of the token. Used for decrypting an already - * encrypted token. - * - * @return int - */ - public function getDecryptedValue() { - $token = explode(':', $this->value); - if (count($token) !== 2) { - return ''; - } - $obfuscatedToken = $token[0]; - $secret = $token[1]; - return base64_decode($obfuscatedToken) ^ $secret; - } -} diff --git a/lib/private/security/csrf/csrftokengenerator.php b/lib/private/security/csrf/csrftokengenerator.php deleted file mode 100644 index 6ea71636d22..00000000000 --- a/lib/private/security/csrf/csrftokengenerator.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSRF; - -use OCP\Security\ISecureRandom; - -/** - * Class CsrfTokenGenerator is used to generate a cryptographically secure - * pseudo-random number for the token. - * - * @package OC\Security\CSRF - */ -class CsrfTokenGenerator { - /** @var ISecureRandom */ - private $random; - - /** - * @param ISecureRandom $random - */ - public function __construct(ISecureRandom $random) { - $this->random = $random; - } - - /** - * Generate a new CSRF token. - * - * @param int $length Length of the token in characters. - * @return string - */ - public function generateToken($length = 32) { - return $this->random->generate($length); - } -} diff --git a/lib/private/security/csrf/csrftokenmanager.php b/lib/private/security/csrf/csrftokenmanager.php deleted file mode 100644 index 8d1bf5c0819..00000000000 --- a/lib/private/security/csrf/csrftokenmanager.php +++ /dev/null @@ -1,97 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSRF; - -use OC\Security\CSRF\TokenStorage\SessionStorage; - -/** - * Class CsrfTokenManager is the manager for all CSRF token related activities. - * - * @package OC\Security\CSRF - */ -class CsrfTokenManager { - /** @var CsrfTokenGenerator */ - private $tokenGenerator; - /** @var SessionStorage */ - private $sessionStorage; - - /** - * @param CsrfTokenGenerator $tokenGenerator - * @param SessionStorage $storageInterface - */ - public function __construct(CsrfTokenGenerator $tokenGenerator, - SessionStorage $storageInterface) { - $this->tokenGenerator = $tokenGenerator; - $this->sessionStorage = $storageInterface; - } - - /** - * Returns the current CSRF token, if none set it will create a new one. - * - * @return CsrfToken - */ - public function getToken() { - if($this->sessionStorage->hasToken()) { - $value = $this->sessionStorage->getToken(); - } else { - $value = $this->tokenGenerator->generateToken(); - $this->sessionStorage->setToken($value); - } - - return new CsrfToken($value); - } - - /** - * Invalidates any current token and sets a new one. - * - * @return CsrfToken - */ - public function refreshToken() { - $value = $this->tokenGenerator->generateToken(); - $this->sessionStorage->setToken($value); - return new CsrfToken($value); - } - - /** - * Remove the current token from the storage. - */ - public function removeToken() { - $this->sessionStorage->removeToken(); - } - - /** - * Verifies whether the provided token is valid. - * - * @param CsrfToken $token - * @return bool - */ - public function isTokenValid(CsrfToken $token) { - if(!$this->sessionStorage->hasToken()) { - return false; - } - - return hash_equals( - $this->sessionStorage->getToken(), - $token->getDecryptedValue() - ); - } -} diff --git a/lib/private/security/csrf/tokenstorage/sessionstorage.php b/lib/private/security/csrf/tokenstorage/sessionstorage.php deleted file mode 100644 index e1c8c96e920..00000000000 --- a/lib/private/security/csrf/tokenstorage/sessionstorage.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2016, 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\Security\CSRF\TokenStorage; - -use OCP\ISession; - -/** - * Class SessionStorage provides the session storage - * - * @package OC\Security\CSRF\TokenStorage - */ -class SessionStorage { - /** @var ISession */ - private $session; - - /** - * @param ISession $session - */ - public function __construct(ISession $session) { - $this->session = $session; - } - - /** - * Returns the current token or throws an exception if none is found. - * - * @return string - * @throws \Exception - */ - public function getToken() { - $token = $this->session->get('requesttoken'); - if(empty($token)) { - throw new \Exception('Session does not contain a requesttoken'); - } - - return $token; - } - - /** - * Set the valid current token to $value. - * - * @param string $value - */ - public function setToken($value) { - $this->session->set('requesttoken', $value); - } - - /** - * Removes the current token. - */ - public function removeToken() { - $this->session->remove('requesttoken'); - } - /** - * Whether the storage has a storage. - * - * @return bool - */ - public function hasToken() { - return $this->session->exists('requesttoken'); - } -} diff --git a/lib/private/security/hasher.php b/lib/private/security/hasher.php deleted file mode 100644 index a8b81aa60eb..00000000000 --- a/lib/private/security/hasher.php +++ /dev/null @@ -1,160 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @copyright Copyright (c) 2016, 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\Security; - -use OCP\IConfig; -use OCP\Security\IHasher; - -/** - * Class Hasher provides some basic hashing functions. Furthermore, it supports legacy hashes - * used by previous versions of ownCloud and helps migrating those hashes to newer ones. - * - * The hashes generated by this class are prefixed (version|hash) with a version parameter to allow possible - * updates in the future. - * Possible versions: - * - 1 (Initial version) - * - * Usage: - * // Hashing a message - * $hash = \OC::$server->getHasher()->hash('MessageToHash'); - * // Verifying a message - $newHash will contain the newly calculated hash - * $newHash = null; - * var_dump(\OC::$server->getHasher()->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash)); - * var_dump($newHash); - * - * @package OC\Security - */ -class Hasher implements IHasher { - /** @var IConfig */ - private $config; - /** @var array Options passed to password_hash and password_needs_rehash */ - private $options = array(); - /** @var string Salt used for legacy passwords */ - private $legacySalt = null; - /** @var int Current version of the generated hash */ - private $currentVersion = 1; - - /** - * @param IConfig $config - */ - function __construct(IConfig $config) { - $this->config = $config; - - $hashingCost = $this->config->getSystemValue('hashingCost', null); - if(!is_null($hashingCost)) { - $this->options['cost'] = $hashingCost; - } - } - - /** - * Hashes a message using PHP's `password_hash` functionality. - * Please note that the size of the returned string is not guaranteed - * and can be up to 255 characters. - * - * @param string $message Message to generate hash from - * @return string Hash of the message with appended version parameter - */ - public function hash($message) { - return $this->currentVersion . '|' . password_hash($message, PASSWORD_DEFAULT, $this->options); - } - - /** - * Get the version and hash from a prefixedHash - * @param string $prefixedHash - * @return null|array Null if the hash is not prefixed, otherwise array('version' => 1, 'hash' => 'foo') - */ - protected function splitHash($prefixedHash) { - $explodedString = explode('|', $prefixedHash, 2); - if(sizeof($explodedString) === 2) { - if((int)$explodedString[0] > 0) { - return array('version' => (int)$explodedString[0], 'hash' => $explodedString[1]); - } - } - - return null; - } - - /** - * Verify legacy hashes - * @param string $message Message to verify - * @param string $hash Assumed hash of the message - * @param null|string &$newHash Reference will contain the updated hash - * @return bool Whether $hash is a valid hash of $message - */ - protected function legacyHashVerify($message, $hash, &$newHash = null) { - if(empty($this->legacySalt)) { - $this->legacySalt = $this->config->getSystemValue('passwordsalt', ''); - } - - // Verify whether it matches a legacy PHPass or SHA1 string - $hashLength = strlen($hash); - if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) || - $hashLength === 40 && hash_equals($hash, sha1($message))) { - $newHash = $this->hash($message); - return true; - } - - return false; - } - - /** - * Verify V1 hashes - * @param string $message Message to verify - * @param string $hash Assumed hash of the message - * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one. - * @return bool Whether $hash is a valid hash of $message - */ - protected function verifyHashV1($message, $hash, &$newHash = null) { - if(password_verify($message, $hash)) { - if(password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) { - $newHash = $this->hash($message); - } - return true; - } - - return false; - } - - /** - * @param string $message Message to verify - * @param string $hash Assumed hash of the message - * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one. - * @return bool Whether $hash is a valid hash of $message - */ - public function verify($message, $hash, &$newHash = null) { - $splittedHash = $this->splitHash($hash); - - if(isset($splittedHash['version'])) { - switch ($splittedHash['version']) { - case 1: - return $this->verifyHashV1($message, $splittedHash['hash'], $newHash); - } - } else { - return $this->legacyHashVerify($message, $hash, $newHash); - } - - - return false; - } - -} diff --git a/lib/private/security/securerandom.php b/lib/private/security/securerandom.php deleted file mode 100644 index 45cb3f17ee4..00000000000 --- a/lib/private/security/securerandom.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @copyright Copyright (c) 2016, 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\Security; - -use RandomLib; -use Sabre\DAV\Exception; -use OCP\Security\ISecureRandom; - -/** - * Class SecureRandom provides a wrapper around the random_int function to generate - * secure random strings. For PHP 7 the native CSPRNG is used, older versions do - * use a fallback. - * - * Usage: - * \OC::$server->getSecureRandom()->generate(10); - * @package OC\Security - */ -class SecureRandom implements ISecureRandom { - /** - * Convenience method to get a low strength random number generator. - * - * Low Strength should be used anywhere that random strings are needed - * in a non-cryptographical setting. They are not strong enough to be - * used as keys or salts. They are however useful for one-time use tokens. - * - * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() - * @return $this - */ - public function getLowStrengthGenerator() { - return $this; - } - - /** - * Convenience method to get a medium strength random number generator. - * - * Medium Strength should be used for most needs of a cryptographic nature. - * They are strong enough to be used as keys and salts. However, they do - * take some time and resources to generate, so they should not be over-used - * - * @deprecated 9.0.0 Use \OC\Security\SecureRandom::generate directly or random_bytes() / random_int() - * @return $this - */ - public function getMediumStrengthGenerator() { - return $this; - } - - /** - * Generate a random string of specified length. - * @param int $length The length of the generated string - * @param string $characters An optional list of characters to use if no character list is - * specified all valid base64 characters are used. - * @return string - */ - public function generate($length, - $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/') { - $maxCharIndex = strlen($characters) - 1; - $randomString = ''; - - while($length > 0) { - $randomNumber = \random_int(0, $maxCharIndex); - $randomString .= $characters[$randomNumber]; - $length--; - } - return $randomString; - } -} diff --git a/lib/private/security/trusteddomainhelper.php b/lib/private/security/trusteddomainhelper.php deleted file mode 100644 index 409628677a7..00000000000 --- a/lib/private/security/trusteddomainhelper.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @copyright Copyright (c) 2016, 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\Security; -use OC\AppFramework\Http\Request; -use OCP\IConfig; - -/** - * Class TrustedDomain - * - * @package OC\Security - */ -class TrustedDomainHelper { - /** @var IConfig */ - private $config; - - /** - * @param IConfig $config - */ - function __construct(IConfig $config) { - $this->config = $config; - } - - /** - * Strips a potential port from a domain (in format domain:port) - * @param string $host - * @return string $host without appended port - */ - private function getDomainWithoutPort($host) { - $pos = strrpos($host, ':'); - if ($pos !== false) { - $port = substr($host, $pos + 1); - if (is_numeric($port)) { - $host = substr($host, 0, $pos); - } - } - return $host; - } - - /** - * Checks whether a domain is considered as trusted from the list - * of trusted domains. If no trusted domains have been configured, returns - * true. - * This is used to prevent Host Header Poisoning. - * @param string $domainWithPort - * @return bool true if the given domain is trusted or if no trusted domains - * have been configured - */ - public function isTrustedDomain($domainWithPort) { - $domain = $this->getDomainWithoutPort($domainWithPort); - - // Read trusted domains from config - $trustedList = $this->config->getSystemValue('trusted_domains', []); - if(!is_array($trustedList)) { - return false; - } - - // Always allow access from localhost - if (preg_match(Request::REGEX_LOCALHOST, $domain) === 1) { - return true; - } - - // Compare with port appended - if(in_array($domainWithPort, $trustedList, true)) { - return true; - } - - return in_array($domain, $trustedList, true); - } - -} |