Skip to content

Commit

Permalink
delete expired nonces
Browse files Browse the repository at this point in the history
  • Loading branch information
djoos committed Oct 3, 2013
1 parent 408ae53 commit 6809dea
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 17 deletions.
122 changes: 122 additions & 0 deletions Command/DeleteNoncesCommand.php
@@ -0,0 +1,122 @@
<?php

namespace Escape\WSSEAuthenticationBundle\Command;

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

class DeleteNoncesCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('escape:wsseauthentication:nonces:delete')
->setDescription('Delete nonces')
->setDefinition(
array(
new InputArgument('nonceDir', InputArgument::REQUIRED, 'nonce directory'),
new InputArgument('lifetime', InputArgument::REQUIRED, 'lifetime')
)
)
->setHelp(<<<EOT
The <info>escape:wsseauthentication:nonces:delete</info> command deletes all expired nonces:
<info>php app/console escape:wsseauthentication:nonces:delete</info>
This interactive shell will ask you for a nonceDir and a lifetime.
You can alternatively specify the nonceDir and lifetime arguments:
<info>php app/console escape:wsseauthentication:nonces:delete /path/to/security/nonces 300</info>
EOT
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$nonceDir = $input->getArgument('nonceDir');
$lifetime = $input->getArgument('lifetime');

$fs = new Filesystem();

$finder = new Finder();

$finder->files()->in($nonceDir);

$i = 0;

foreach($finder as $file)
{
if(file_get_contents($file->getRealPath()) + $lifetime < time())
{
$file = $file->getRealPath();

$fs->remove($file);
$i++;

$output->writeln(sprintf('Deleted expired nonce <comment>%s</comment>.', $file));
}
}

$output->writeln(
sprintf(
'Deleted <comment>%s</comment> expired nonces in <comment>%s</comment>.',
$i,
$nonceDir
)
);
}

protected function interact(InputInterface $input, OutputInterface $output)
{
if(!$input->getArgument('nonceDir'))
{
$arg = $this->getHelper('dialog')->askAndValidate(
$output,
'Please specify the nonceDir:',
function($arg)
{
if(empty($arg))
{
$error = 'nonceDir can not be empty';
$output->writeln(sprintf('<error>%s</error>',$error));

throw new Exception($error);
}

return $arg;
}
);

$input->setArgument('nonceDir', $arg);
}

if(!$input->getArgument('lifetime'))
{
$arg = $this->getHelper('dialog')->askAndValidate(
$output,
'Please specify the lifetime:',
function($arg)
{
if(empty($arg))
{
$error = 'lifetime can not be empty';
$output->writeln(sprintf('<error>%s</error>',$error));

throw new Exception($error);
}

return $arg;
}
);

$input->setArgument('lifetime', $arg);
}
}
}
15 changes: 13 additions & 2 deletions Security/Core/Authentication/Provider/Provider.php
Expand Up @@ -4,6 +4,7 @@

use Escape\WSSEAuthenticationBundle\Security\Core\Authentication\Token\Token;

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
Expand Down Expand Up @@ -50,8 +51,18 @@ protected function validateDigest($digest, $nonce, $created, $secret)

if($this->nonceDir)
{
//validate nonce is unique within specified lifetime
if(file_exists($this->nonceDir.'/'.$nonce) && file_get_contents($this->nonceDir.'/'.$nonce) + $this->lifetime > time())
$fs = new Filesystem();

if(!$fs->exists($this->nonceDir))
{
$fs->mkdir($this->nonceDir);
}

//validate whether nonce is unique within specified lifetime
if(
file_exists($this->nonceDir.DIRECTORY_SEPARATOR.$nonce) &&
file_get_contents($this->nonceDir.DIRECTORY_SEPARATOR.$nonce) + $this->lifetime > time()
)
{
throw new NonceExpiredException('Previously used nonce detected.');
}
Expand Down
33 changes: 19 additions & 14 deletions Tests/Security/Core/Authentication/Provider/ProviderTest.php
Expand Up @@ -4,6 +4,9 @@

use Escape\WSSEAuthenticationBundle\Security\Core\Authentication\Provider\Provider;
use Escape\WSSEAuthenticationBundle\Security\Core\Authentication\Token\Token;

use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;

class ProviderTestSimple extends Provider
Expand All @@ -26,11 +29,11 @@ public static function setUpBeforeClass()

self::$nonceDir = __DIR__.'/../../../../nonceDir/';

//setup
if(!is_dir(self::$nonceDir))
$fs = new Filesystem();

if(!$fs->exists(self::$nonceDir))
{
//create temp nonceDir
mkdir(self::$nonceDir);
$fs->mkdir(self::$nonceDir);
}
}

Expand All @@ -39,24 +42,26 @@ public static function tearDownAfterClass()
{
parent::tearDownAfterClass();

$fs = new Filesystem();

//cleanup
if(is_dir(self::$nonceDir))
if($fs->exists(self::$nonceDir))
{
//remove temp nonceDir
rmdir(self::$nonceDir);
$fs->remove(self::$nonceDir);
}
}

private function clearDir()
{
$handle = opendir(self::$nonceDir);

while($tmp = readdir($handle))
$fs = new Filesystem();

$finder = new Finder();

$finder->files()->in(self::$nonceDir);

foreach($finder as $file)
{
if($tmp != '..' && $tmp != '.' && $tmp != '')
{
unlink(self::$nonceDir.$tmp);
}
$fs->remove($file->getRealPath());
}
}

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -26,7 +26,8 @@
},
"require-dev": {
"symfony/framework-bundle": "2.3.*",
"symfony/security-bundle": "2.3.*"
"symfony/security-bundle": "2.3.*",
"symfony/finder": "2.3.*@dev"
},
"autoload": {
"psr-0": { "Escape\\WSSEAuthenticationBundle": "" }
Expand Down

0 comments on commit 6809dea

Please sign in to comment.