2013-12-11 17:10:39 +00:00
|
|
|
#!/usr/bin/env perl
|
|
|
|
|
|
|
|
use v5.10.1;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use DBI;
|
2013-12-13 17:45:25 +00:00
|
|
|
use File::Basename;
|
2014-01-21 02:08:08 +00:00
|
|
|
use Digest;
|
|
|
|
use Digest::MD5 qw(md5);
|
|
|
|
use Digest::SHA qw(sha1 sha224 sha256 sha384 sha512);
|
|
|
|
use Mcrypt qw(:ALGORITHMS :MODES :FUNCS);
|
|
|
|
|
|
|
|
sub encrypt
|
|
|
|
{
|
|
|
|
my ($algo, $key, $data, $mode) = @_;
|
|
|
|
|
|
|
|
my $td = mcrypt_load( $algo, "", $mode, '' );
|
|
|
|
mcrypt_init($td, $key, "");
|
|
|
|
|
|
|
|
my $encrypted = mcrypt_encrypt($td, $data);
|
|
|
|
|
|
|
|
mcrypt_end($td);
|
|
|
|
|
|
|
|
return $encrypted;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub my_crypt
|
|
|
|
{
|
|
|
|
my ($key, $content) = @_;
|
|
|
|
|
|
|
|
my $kfirst = pack('H*', substr($key, 0, 64));
|
|
|
|
$content = encrypt(SERPENT, $kfirst, $content, ECB);
|
|
|
|
|
|
|
|
if (length $key > 64)
|
|
|
|
{
|
|
|
|
my $ksec = pack('H*', substr($key, 64, 64));
|
|
|
|
$content = encrypt(SERPENT, $ksec, $content, ECB);
|
|
|
|
}
|
|
|
|
|
|
|
|
return unpack('H*', $content);
|
|
|
|
}
|
2013-12-11 17:10:39 +00:00
|
|
|
|
2013-12-13 17:45:25 +00:00
|
|
|
#Return number of good solutions
|
|
|
|
my $exit = 0;
|
|
|
|
|
|
|
|
my $root = dirname(__FILE__);
|
|
|
|
|
|
|
|
chdir($root);
|
2013-12-11 17:10:39 +00:00
|
|
|
|
|
|
|
# First, read PHP configuration to extract some settings
|
|
|
|
my $profile;
|
|
|
|
my $submission_dir;
|
|
|
|
|
2013-12-13 17:45:25 +00:00
|
|
|
open my $conf, "<", "$root/onyx/config/root.xml";
|
2013-12-11 17:10:39 +00:00
|
|
|
for my $p (<$conf>)
|
|
|
|
{
|
|
|
|
if ($p =~ /<(?:option|var) name="(.*)">(.*)<\/(?:option|var)>/)
|
|
|
|
{
|
|
|
|
$profile = $2 if ($1 eq "profile");
|
|
|
|
$submission_dir = $2 if ($1 eq "submission_dir");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close $conf;
|
|
|
|
|
2014-01-20 09:43:16 +00:00
|
|
|
my $end_time = 1999999999;
|
2015-01-13 16:58:33 +00:00
|
|
|
if (-f "$root/shared/challenge_started")
|
2014-01-20 09:43:16 +00:00
|
|
|
{
|
2015-01-13 16:58:33 +00:00
|
|
|
open my $conf, "<", "$root/shared/challenge_started";
|
2014-01-20 09:43:16 +00:00
|
|
|
$end_time = <$conf>;
|
|
|
|
close $conf;
|
|
|
|
chomp($end_time);
|
|
|
|
$end_time += 14400;
|
|
|
|
}
|
|
|
|
|
|
|
|
die("TIME expired!") if time() > $end_time;
|
2013-12-11 17:10:39 +00:00
|
|
|
die("No DB profile found") if ! $profile;
|
|
|
|
die("submission_dir is not a directory") if ! $submission_dir || ! -d $submission_dir;
|
|
|
|
|
|
|
|
# Read db settings
|
|
|
|
my %db_settings;
|
2013-12-13 17:45:25 +00:00
|
|
|
open my $dbprof, "<", "$root/onyx/db/$profile.profile.php";
|
2013-12-11 17:10:39 +00:00
|
|
|
while (<$dbprof>)
|
|
|
|
{
|
|
|
|
if (/\$___profile\[['"](.+)['"]\] = ['"](.+)['"]/)
|
|
|
|
{
|
|
|
|
$db_settings{$1} = $2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close $dbprof;
|
|
|
|
|
|
|
|
my $dbh;
|
|
|
|
# List all files to treat
|
|
|
|
opendir(my $dh, $submission_dir) || die "Can't opendir submission_dir: $!";
|
|
|
|
for my $f (readdir $dh)
|
|
|
|
{
|
2013-12-13 17:45:25 +00:00
|
|
|
if ($f =~ /^([0-9]+)-([0-9]+)-([a-zA-Z0-9_]+)$/)
|
2013-12-11 17:10:39 +00:00
|
|
|
{
|
2013-12-13 17:45:25 +00:00
|
|
|
my $good = -1;
|
|
|
|
|
2013-12-11 17:10:39 +00:00
|
|
|
my $team = $1;
|
|
|
|
my $theme = $2;
|
|
|
|
my $exercice = $3;
|
|
|
|
|
|
|
|
open my $fh, "<", "$submission_dir/$f";
|
2014-01-21 02:08:08 +00:00
|
|
|
my %solution;
|
|
|
|
$solution{md5} = <$fh>; chomp( $solution{md5} );
|
|
|
|
$solution{sha1} = <$fh>; chomp( $solution{sha1} );
|
|
|
|
$solution{sha256} = <$fh>; chomp( $solution{sha256} );
|
|
|
|
$solution{sha384} = <$fh>; chomp( $solution{sha384} );
|
|
|
|
$solution{sha512} = <$fh>; chomp( $solution{sha512} );
|
|
|
|
$solution{whirlpool} = <$fh>; chomp( $solution{whirlpool} );
|
2013-12-11 17:10:39 +00:00
|
|
|
close $fh;
|
|
|
|
|
2014-01-21 02:08:08 +00:00
|
|
|
use Data::Dumper;
|
|
|
|
print STDERR Dumper(\%solution);
|
|
|
|
|
2013-12-11 17:10:39 +00:00
|
|
|
$dbh = DBI->connect("DBI:mysql:database=$db_settings{db};host=$db_settings{host};port=3306",
|
|
|
|
$db_settings{user}, $db_settings{pass},
|
|
|
|
{'RaiseError' => 1, 'PrintError' => 1})
|
|
|
|
or die $DBI::errstr if !$dbh;
|
|
|
|
|
2014-01-14 16:09:29 +00:00
|
|
|
query($dbh, "INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES ('$exercice', $team, CURRENT_TIMESTAMP);");
|
|
|
|
|
2013-12-13 19:11:26 +00:00
|
|
|
my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".$dbh->quote($exercice));
|
2013-12-11 17:10:39 +00:00
|
|
|
|
2013-12-13 17:45:25 +00:00
|
|
|
# Check solutions
|
2013-12-11 17:10:39 +00:00
|
|
|
while (my $row = get_row($sth))
|
|
|
|
{
|
2013-12-13 17:45:25 +00:00
|
|
|
$good = 1 if ($good == -1);
|
|
|
|
|
|
|
|
my $type = @$row[0];
|
|
|
|
my $sol = @$row[1];
|
2014-01-21 02:08:08 +00:00
|
|
|
my $filh; my $tmp_solution;
|
2014-01-14 15:13:58 +00:00
|
|
|
|
|
|
|
if ($type eq "md5") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = md5($f);
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
elsif ($type eq "sha1") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = sha1($f);
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
elsif ($type eq "sha224") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = sha224($f);
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
elsif ($type eq "sha256") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = sha256($f);
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
elsif ($type eq "sha384") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = sha384($f);
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
elsif ($type eq "sha512") {
|
2014-01-21 02:08:08 +00:00
|
|
|
$filh = sha512($f);
|
2013-12-13 17:45:25 +00:00
|
|
|
}
|
2014-01-21 02:07:52 +00:00
|
|
|
elsif ($type eq "whirlpool") {
|
|
|
|
my $hash = Digest->new( 'Whirlpool' );
|
2014-01-21 02:08:08 +00:00
|
|
|
$hash->add( $f );
|
|
|
|
$filh = $hash->digest;
|
2014-01-21 02:07:52 +00:00
|
|
|
}
|
2014-01-21 02:08:08 +00:00
|
|
|
else {
|
2013-12-13 17:45:25 +00:00
|
|
|
warn "$type not implemented";
|
2014-01-14 15:13:58 +00:00
|
|
|
}
|
|
|
|
|
2014-01-21 02:08:08 +00:00
|
|
|
$tmp_solution = my_crypt($sol, $filh) if ($filh);
|
|
|
|
|
|
|
|
say STDERR "check $type: $solution{$type} vs $tmp_solution";
|
2014-01-14 15:13:58 +00:00
|
|
|
|
2014-01-21 02:08:08 +00:00
|
|
|
if ($solution{$type} ne $tmp_solution)
|
2014-01-14 15:13:58 +00:00
|
|
|
{
|
|
|
|
$good = 0;
|
2013-12-13 17:45:25 +00:00
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Register solve
|
|
|
|
if ($good == -1) {
|
2013-12-14 05:11:14 +00:00
|
|
|
say STDERR localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme.";
|
2013-12-11 17:10:39 +00:00
|
|
|
}
|
2013-12-13 17:45:25 +00:00
|
|
|
elsif ($good == 1)
|
|
|
|
{
|
2013-12-13 19:11:26 +00:00
|
|
|
# Check if the exercice exists
|
|
|
|
$sth = query($dbh, "SELECT `require` FROM exercices E WHERE E.id_theme = $theme AND E.id = ".$dbh->quote($exercice));
|
2013-12-14 05:11:14 +00:00
|
|
|
if ($sth->rows)
|
2013-12-13 19:11:26 +00:00
|
|
|
{
|
2013-12-14 05:11:14 +00:00
|
|
|
my $row = get_row($sth);
|
|
|
|
|
2013-12-13 19:11:26 +00:00
|
|
|
# Check if the team has solved dependancies
|
2013-12-14 05:11:14 +00:00
|
|
|
$sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0];
|
|
|
|
if (! @$row[0] || $sth->rows)
|
2013-12-13 19:11:26 +00:00
|
|
|
{
|
|
|
|
# Check if the team has not already solved this exercice
|
2014-11-20 20:02:29 +00:00
|
|
|
$sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_team = $team AND S.id_exercice = ".$dbh->quote($exercice));
|
2013-12-13 19:11:26 +00:00
|
|
|
if (! $sth->rows)
|
|
|
|
{
|
2015-01-20 10:22:32 +00:00
|
|
|
say "resetresetreset:TEAM$team,$theme:SYNCSYN:TEAM$team:SYNC:HOME:SYNC:all:SY";
|
2014-01-19 16:49:07 +00:00
|
|
|
|
2013-12-14 05:11:14 +00:00
|
|
|
say STDERR localtime().": Team $team solve exercice $exercice in $theme";
|
2013-12-13 19:11:26 +00:00
|
|
|
query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);");
|
|
|
|
$exit++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
warn localtime().": Team $team try to solve exercice $exercice in $theme but ALREADY solved it";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
warn localtime().": Team $team try to solve exercice $exercice in $theme but has NOT SOLVED required exercice ".@$row[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
warn localtime().": Team $team try to solve exercice $exercice in $theme but does not exist";
|
|
|
|
}
|
2013-12-13 17:45:25 +00:00
|
|
|
}
|
|
|
|
else {
|
2014-01-20 04:52:25 +00:00
|
|
|
say "resetresetreset:TEAM$team,$theme:SYNCSYN";
|
2014-01-19 16:49:07 +00:00
|
|
|
|
2013-12-14 05:11:14 +00:00
|
|
|
say STDERR localtime().": Team $team didn't give the correct answer for exercice $exercice.";
|
2013-12-13 17:45:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Remove the file
|
|
|
|
unlink("$submission_dir/$f");
|
2013-12-11 17:10:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir $dh;
|
|
|
|
|
|
|
|
$dbh->disconnect() if $dbh;
|
|
|
|
|
2013-12-13 17:45:25 +00:00
|
|
|
exit( $exit > 126 ? 126 : $exit );
|
|
|
|
|
2013-12-11 17:10:39 +00:00
|
|
|
sub query
|
|
|
|
{
|
|
|
|
my $sth = $_[0]->prepare($_[1]);
|
|
|
|
$sth->execute();
|
|
|
|
|
|
|
|
die($_[0]->errstr) if (!$sth);
|
|
|
|
|
|
|
|
return $sth;
|
|
|
|
}
|
2013-12-13 17:45:25 +00:00
|
|
|
|
|
|
|
sub get_row
|
|
|
|
{
|
|
|
|
return $_[0]->fetchrow_arrayref();
|
|
|
|
}
|