Merge pull request #20005 from joeried/occ-remove-bruteforce-attempts-by-ip
Implement occ command to reset bruteforce attemps from a given IP address
This commit is contained in:
commit
e57bca31ad
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020, Johannes Riedel (johannes@johannes-riedel.de)
|
||||||
|
*
|
||||||
|
* @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 OC\Core\Command\Security;
|
||||||
|
|
||||||
|
use OC\Core\Command\Base;
|
||||||
|
use OC\Security\Bruteforce\Throttler;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class ResetBruteforceAttempts extends Base {
|
||||||
|
|
||||||
|
/** @var Throttler */
|
||||||
|
protected $throttler;
|
||||||
|
|
||||||
|
public function __construct(Throttler $throttler) {
|
||||||
|
$this->throttler = $throttler;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configure() {
|
||||||
|
$this
|
||||||
|
->setName('security:bruteforce:reset')
|
||||||
|
->setDescription('resets bruteforce attemps for given IP address')
|
||||||
|
->addArgument(
|
||||||
|
'ipaddress',
|
||||||
|
InputArgument::REQUIRED,
|
||||||
|
'IP address for which the attempts are to be reset'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||||
|
$ip = $input->getArgument('ipaddress');
|
||||||
|
|
||||||
|
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||||
|
$output->writeln('<error>"' . $ip . '" is not a valid IP address</error>');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->throttler->resetDelayForIP($ip);
|
||||||
|
}
|
||||||
|
}
|
|
@ -175,6 +175,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
|
||||||
$application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
|
$application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
|
||||||
$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
|
$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
|
||||||
$application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
|
$application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
|
||||||
|
$application->add(new OC\Core\Command\Security\ResetBruteforceAttempts(\OC::$server->getBruteForceThrottler()));
|
||||||
} else {
|
} else {
|
||||||
$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
|
$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getSystemConfig()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -789,6 +789,7 @@ return array(
|
||||||
'OC\\Core\\Command\\Security\\ImportCertificate' => $baseDir . '/core/Command/Security/ImportCertificate.php',
|
'OC\\Core\\Command\\Security\\ImportCertificate' => $baseDir . '/core/Command/Security/ImportCertificate.php',
|
||||||
'OC\\Core\\Command\\Security\\ListCertificates' => $baseDir . '/core/Command/Security/ListCertificates.php',
|
'OC\\Core\\Command\\Security\\ListCertificates' => $baseDir . '/core/Command/Security/ListCertificates.php',
|
||||||
'OC\\Core\\Command\\Security\\RemoveCertificate' => $baseDir . '/core/Command/Security/RemoveCertificate.php',
|
'OC\\Core\\Command\\Security\\RemoveCertificate' => $baseDir . '/core/Command/Security/RemoveCertificate.php',
|
||||||
|
'OC\\Core\\Command\\Security\\ResetBruteforceAttempts' => $baseDir . '/core/Command/Security/ResetBruteforceAttempts.php',
|
||||||
'OC\\Core\\Command\\Status' => $baseDir . '/core/Command/Status.php',
|
'OC\\Core\\Command\\Status' => $baseDir . '/core/Command/Status.php',
|
||||||
'OC\\Core\\Command\\TwoFactorAuth\\Base' => $baseDir . '/core/Command/TwoFactorAuth/Base.php',
|
'OC\\Core\\Command\\TwoFactorAuth\\Base' => $baseDir . '/core/Command/TwoFactorAuth/Base.php',
|
||||||
'OC\\Core\\Command\\TwoFactorAuth\\Cleanup' => $baseDir . '/core/Command/TwoFactorAuth/Cleanup.php',
|
'OC\\Core\\Command\\TwoFactorAuth\\Cleanup' => $baseDir . '/core/Command/TwoFactorAuth/Cleanup.php',
|
||||||
|
|
|
@ -818,6 +818,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||||
'OC\\Core\\Command\\Security\\ImportCertificate' => __DIR__ . '/../../..' . '/core/Command/Security/ImportCertificate.php',
|
'OC\\Core\\Command\\Security\\ImportCertificate' => __DIR__ . '/../../..' . '/core/Command/Security/ImportCertificate.php',
|
||||||
'OC\\Core\\Command\\Security\\ListCertificates' => __DIR__ . '/../../..' . '/core/Command/Security/ListCertificates.php',
|
'OC\\Core\\Command\\Security\\ListCertificates' => __DIR__ . '/../../..' . '/core/Command/Security/ListCertificates.php',
|
||||||
'OC\\Core\\Command\\Security\\RemoveCertificate' => __DIR__ . '/../../..' . '/core/Command/Security/RemoveCertificate.php',
|
'OC\\Core\\Command\\Security\\RemoveCertificate' => __DIR__ . '/../../..' . '/core/Command/Security/RemoveCertificate.php',
|
||||||
|
'OC\\Core\\Command\\Security\\ResetBruteforceAttempts' => __DIR__ . '/../../..' . '/core/Command/Security/ResetBruteforceAttempts.php',
|
||||||
'OC\\Core\\Command\\Status' => __DIR__ . '/../../..' . '/core/Command/Status.php',
|
'OC\\Core\\Command\\Status' => __DIR__ . '/../../..' . '/core/Command/Status.php',
|
||||||
'OC\\Core\\Command\\TwoFactorAuth\\Base' => __DIR__ . '/../../..' . '/core/Command/TwoFactorAuth/Base.php',
|
'OC\\Core\\Command\\TwoFactorAuth\\Base' => __DIR__ . '/../../..' . '/core/Command/TwoFactorAuth/Base.php',
|
||||||
'OC\\Core\\Command\\TwoFactorAuth\\Cleanup' => __DIR__ . '/../../..' . '/core/Command/TwoFactorAuth/Cleanup.php',
|
'OC\\Core\\Command\\TwoFactorAuth\\Cleanup' => __DIR__ . '/../../..' . '/core/Command/TwoFactorAuth/Cleanup.php',
|
||||||
|
|
|
@ -89,6 +89,17 @@ class Throttler {
|
||||||
return $d2->diff($d1);
|
return $d2->diff($d1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the cut off timestamp
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function getCutoffTimestamp(): int {
|
||||||
|
return (new \DateTime())
|
||||||
|
->sub($this->getCutoff(43200))
|
||||||
|
->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a failed attempt to bruteforce a security control
|
* Register a failed attempt to bruteforce a security control
|
||||||
*
|
*
|
||||||
|
@ -212,9 +223,7 @@ class Throttler {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cutoffTime = (new \DateTime())
|
$cutoffTime = $this->getCutoffTimestamp();
|
||||||
->sub($this->getCutoff(43200))
|
|
||||||
->getTimestamp();
|
|
||||||
|
|
||||||
$qb = $this->db->getQueryBuilder();
|
$qb = $this->db->getQueryBuilder();
|
||||||
$qb->select('*')
|
$qb->select('*')
|
||||||
|
@ -259,9 +268,7 @@ class Throttler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cutoffTime = (new \DateTime())
|
$cutoffTime = $this->getCutoffTimestamp();
|
||||||
->sub($this->getCutoff(43200))
|
|
||||||
->getTimestamp();
|
|
||||||
|
|
||||||
$qb = $this->db->getQueryBuilder();
|
$qb = $this->db->getQueryBuilder();
|
||||||
$qb->delete('bruteforce_attempts')
|
$qb->delete('bruteforce_attempts')
|
||||||
|
@ -273,6 +280,22 @@ class Throttler {
|
||||||
$qb->execute();
|
$qb->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the throttling delay for an IP address
|
||||||
|
*
|
||||||
|
* @param string $ip
|
||||||
|
*/
|
||||||
|
public function resetDelayForIP($ip) {
|
||||||
|
$cutoffTime = $this->getCutoffTimestamp();
|
||||||
|
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$qb->delete('bruteforce_attempts')
|
||||||
|
->where($qb->expr()->gt('occurred', $qb->createNamedParameter($cutoffTime)))
|
||||||
|
->andWhere($qb->expr()->eq('ip', $qb->createNamedParameter($ip)));
|
||||||
|
|
||||||
|
$qb->execute();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will sleep for the defined amount of time
|
* Will sleep for the defined amount of time
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue