ids-functions.pl: Use libarchive to extract archives
This gives us a lot of benefits: * Speed up the extraction process * More supported archive types due the power of libarchive * Support of passphrase protected archives It also fixes a problem with non extracted files next to a zero sized file inside an archive. Fixes #13632. Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org> Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
This commit is contained in:
parent
2ef62acc01
commit
ee16b227a5
|
@ -30,7 +30,7 @@ require "${General::swroot}/network-functions.pl";
|
|||
require "${General::swroot}/suricata/ruleset-sources";
|
||||
|
||||
# Load perl module to deal with Archives.
|
||||
use Archive::Tar;
|
||||
use Archive::Peek::Libarchive;
|
||||
|
||||
# Load perl module to deal with files and path.
|
||||
use File::Basename;
|
||||
|
@ -515,9 +515,6 @@ sub downloadruleset ($) {
|
|||
sub extractruleset ($) {
|
||||
my ($provider) = @_;
|
||||
|
||||
# Disable chown functionality when uncompressing files.
|
||||
$Archive::Tar::CHOWN = "0";
|
||||
|
||||
# Get full path and downloaded rulesfile for the given provider.
|
||||
my $tarball = &_get_dl_rulesfile($provider);
|
||||
|
||||
|
@ -547,13 +544,11 @@ sub extractruleset ($) {
|
|||
|
||||
} elsif ( $type eq "archive") {
|
||||
# Initialize the tar module.
|
||||
my $tar = Archive::Tar->new($tarball);
|
||||
my $tar = Archive::Peek::Libarchive->new(filename => $tarball);
|
||||
|
||||
# Get the filelist inside the tarball.
|
||||
my @packed_files = $tar->list_files;
|
||||
|
||||
# Loop through the filelist.
|
||||
foreach my $packed_file (@packed_files) {
|
||||
# Loop through the archive
|
||||
$tar->iterate( sub {
|
||||
my ($packed_file, $content) = @_;
|
||||
my $destination;
|
||||
|
||||
# Splitt the packed file into chunks.
|
||||
|
@ -572,13 +567,13 @@ sub extractruleset ($) {
|
|||
# Handle rules files.
|
||||
} elsif ($file =~ m/\.rules$/) {
|
||||
# Skip rule files which are not located in the rules directory or archive root.
|
||||
next unless(($packed_file =~ /^rules\//) || ($packed_file =~ /^$provider-rules\//) || ($packed_file !~ /\//));
|
||||
return unless(($packed_file =~ /^rules\//) || ($packed_file =~ /^$provider-rules\//) || ($packed_file !~ /\//));
|
||||
|
||||
# Skip deleted.rules.
|
||||
#
|
||||
# Mostly they have been taken out for correctness or performance reasons and therfore
|
||||
# it is not a great idea to enable any of them.
|
||||
next if($file =~ m/deleted.rules$/);
|
||||
return if($file =~ m/deleted.rules$/);
|
||||
|
||||
my $rulesfilename;
|
||||
|
||||
|
@ -615,39 +610,24 @@ sub extractruleset ($) {
|
|||
$destination = "$tmp_rules_directory/$rulesfilename";
|
||||
} else {
|
||||
# Skip all other files.
|
||||
next;
|
||||
return;
|
||||
}
|
||||
|
||||
# Check if the destination file exists.
|
||||
unless(-e "$destination") {
|
||||
# Extract the file to the temporary directory.
|
||||
$tar->extract_file("$packed_file", "$destination");
|
||||
# Open filehandle to write the content to a new file.
|
||||
open(FILE, ">", "$destination") or die "Could not open $destination. $!\n";
|
||||
} else {
|
||||
# Generate temporary file name, located in the temporary rules directory and a suffix of ".tmp".
|
||||
my $tmp = File::Temp->new( SUFFIX => ".tmp", DIR => "$tmp_rules_directory", UNLINK => 0 );
|
||||
my $tmpfile = $tmp->filename();
|
||||
|
||||
# Extract the file to the new temporary file name.
|
||||
$tar->extract_file("$packed_file", "$tmpfile");
|
||||
|
||||
# Open the the existing file.
|
||||
open(DESTFILE, ">>", "$destination") or die "Could not open $destination. $!\n";
|
||||
open(TMPFILE, "<", "$tmpfile") or die "Could not open $tmpfile. $!\n";
|
||||
|
||||
# Loop through the content of the temporary file.
|
||||
while (<TMPFILE>) {
|
||||
# Append the content line by line to the destination file.
|
||||
print DESTFILE "$_";
|
||||
}
|
||||
|
||||
# Close the file handles.
|
||||
close(TMPFILE);
|
||||
close(DESTFILE);
|
||||
|
||||
# Remove the temporary file.
|
||||
unlink("$tmpfile");
|
||||
# Open filehandle to append the content to the existing file.
|
||||
open(FILE, ">>", "$destination") or die "Could not open $destination. $!\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Write the extracted file content to the filehandle.
|
||||
print FILE "$content" if ($content);
|
||||
|
||||
# Close the file handle.
|
||||
close(FILE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue