Blame tools/rules-updater.pl.in

Packit Service 384592
#!@PERL@
Packit Service 384592
#
Packit Service 384592
# Fetches the latest ModSecurity Ruleset
Packit Service 384592
#
Packit Service 384592
Packit Service 384592
use strict;
Packit Service 384592
use Sys::Hostname;
Packit Service 384592
use LWP::UserAgent ();
Packit Service 384592
use LWP::Debug qw(-);
Packit Service 384592
use URI ();
Packit Service 384592
use HTTP::Date ();
Packit Service 384592
use Cwd qw(getcwd);
Packit Service 384592
use Getopt::Std;
Packit Service 384592
Packit Service 384592
my $VERSION = "0.0.1";
Packit Service 384592
my($SCRIPT) = ($0 =~ m/([^\/\\]+)$/);
Packit Service 384592
my $CRLFRE = qr/\015?\012/;
Packit Service 384592
my $HOST = Sys::Hostname::hostname();
Packit Service 384592
my $UNZIP = [qw(unzip -a)];
Packit Service 384592
my $SENDMAIL = [qw(/usr/lib/sendmail -oi -t)];
Packit Service 384592
my $HAVE_GNUPG = 0;
Packit Service 384592
my %PREFIX_MAP = (
Packit Service 384592
	-dev => 0,
Packit Service 384592
	-rc => 1,
Packit Service 384592
	"" => 9,
Packit Service 384592
);
Packit Service 384592
my %GPG_TRUST = ();
Packit Service 384592
my $REQUIRED_SIG_TRUST;
Packit Service 384592
Packit Service 384592
eval "use GnuPG qw(:trust)";
Packit Service 384592
if ($@) {
Packit Service 384592
	warn "Could not load GnuPG module - cannot verify ruleset signatures\n";
Packit Service 384592
}
Packit Service 384592
else {
Packit Service 384592
	$HAVE_GNUPG = 1;
Packit Service 384592
	%GPG_TRUST = (
Packit Service 384592
		&TRUST_UNDEFINED    => "not",
Packit Service 384592
		&TRUST_NEVER        => "not",
Packit Service 384592
		&TRUST_MARGINAL     => "marginally",
Packit Service 384592
		&TRUST_FULLY        => "fully",
Packit Service 384592
		&TRUST_ULTIMATE     => "ultimatly",
Packit Service 384592
	);
Packit Service 384592
	$REQUIRED_SIG_TRUST = &TRUST_FULLY;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
################################################################################
Packit Service 384592
################################################################################
Packit Service 384592
Packit Service 384592
my @fetched = ();
Packit Service 384592
my %opt = ();
Packit Service 384592
getopts('c:r:p:s:v:t:e:f:EuS:D:R:U:F:L:ldh', \%opt);
Packit Service 384592
Packit Service 384592
usage(1) if(defined $opt{h});
Packit Service 384592
usage(1) if(@ARGV > 1);
Packit Service 384592
Packit Service 384592
# Make sure we have an action
Packit Service 384592
if (! grep { defined } @opt{qw(S D R U F L l)}) {
Packit Service 384592
	usage(1, "Action required.");
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
# Merge config with commandline opts
Packit Service 384592
if ($opt{c}) {
Packit Service 384592
	%opt = parse_config($opt{c}, \%opt);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
LWP::Debug::level("+") if ($opt{d});
Packit Service 384592
Packit Service 384592
# Make the version into a regex
Packit Service 384592
if (defined $opt{v}) {
Packit Service 384592
	my($a,$b,$c,$d) = ($opt{v} =~ m/^(\d+)\.?(\d+)?\.?(\d+)?(?:-(\D+\d+$)|($))/);
Packit Service 384592
	if (defined $d) {
Packit Service 384592
		(my $key = $d) =~ s/^(\D+)\d+$/-$1/;
Packit Service 384592
		unless (exists $PREFIX_MAP{$key}) {
Packit Service 384592
			usage(1, "Invalid version (bad suffix \"$d\"): $opt{v}");
Packit Service 384592
		}
Packit Service 384592
		$opt{v} = qr/^$a\.$b\.$c-$d$/;
Packit Service 384592
	}
Packit Service 384592
	elsif (defined $c) {
Packit Service 384592
		$opt{v} = qr/^$a\.$b\.$c(?:-|$)/;
Packit Service 384592
	}
Packit Service 384592
	elsif (defined $b) {
Packit Service 384592
		$opt{v} = qr/^$a\.$b\./;
Packit Service 384592
	}
Packit Service 384592
	elsif (defined $a) {
Packit Service 384592
		$opt{v} = qr/^$a\./;
Packit Service 384592
	}
Packit Service 384592
	else {
Packit Service 384592
		usage(1, "Invalid version: $opt{v}");
Packit Service 384592
	}
Packit Service 384592
	if ($opt{d}) {
Packit Service 384592
		print STDERR "Using version regex: $opt{v}\n";
Packit Service 384592
	}
Packit Service 384592
}
Packit Service 384592
else {
Packit Service 384592
	$opt{v} = qr/^/;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
# Remove trailing slashes from uri and path
Packit Service 384592
$opt{r} =~ s/\/+$//;
Packit Service 384592
$opt{p} =~ s/\/+$//;
Packit Service 384592
Packit Service 384592
# Required opts
Packit Service 384592
usage(1, "Repository (-r) required.") unless(defined $opt{r});
Packit Service 384592
usage(1, "Local path (-p) required.") unless(defined $opt{p} or defined $opt{l});
Packit Service 384592
Packit Service 384592
my $ua = LWP::UserAgent->new(
Packit Service 384592
	agent => "ModSecurity Updator/$VERSION",
Packit Service 384592
	keep_alive => 1,
Packit Service 384592
	env_proxy => 1,
Packit Service 384592
	max_redirect => 5,
Packit Service 384592
	requests_redirectable => [qw(GET HEAD)],
Packit Service 384592
	timeout => ($opt{t} || 600),
Packit Service 384592
);
Packit Service 384592
Packit Service 384592
sub usage {
Packit Service 384592
	my $rc = defined($$_[0]) ? $_[0] : 0;
Packit Service 384592
	my $msg = defined($_[1]) ? "\n$_[1]\n\n" : "";
Packit Service 384592
Packit Service 384592
	print STDERR << "EOT";
Packit Service 384592
${msg}Usage: $SCRIPT [-c config_file] [[options] [action]
Packit Service 384592
Packit Service 384592
 Options (commandline will override config file):
Packit Service 384592
  -r uri   RepositoryURI   Repository URI.
Packit Service 384592
  -p path  LocalRepository Local repository path to use as base for downloads.
Packit Service 384592
  -s path  LocalRules      Local rules base path to use for unpacking.
Packit Service 384592
  -v text  Version         Full/partial version (EX: 1, 1.5, 1.5.2, 1.5.2-dev3)
Packit Service 384592
  -t secs  Timeout         Timeout for fetching data in seconds (default 600).
Packit Service 384592
  -e addr  NotifyEmail     Notify via email on update (comma separated list).
Packit Service 384592
  -f addr  NotifyEmailFrom From address for notification email.
Packit Service 384592
  -u       Unpack          Unpack into LocalRules/version path.
Packit Service 384592
  -d       Debug           Print out lots of debugging.
Packit Service 384592
Packit Service 384592
 Actions:
Packit Service 384592
  -S name    Fetch the latest stable ruleset, "name"
Packit Service 384592
  -D name    Fetch the latest development ruleset, "name"
Packit Service 384592
  -R name    Fetch the latest release candidate ruleset, "name"
Packit Service 384592
  -U name    Fetch the latest unstable (non-stable) ruleset, "name"
Packit Service 384592
  -F name    Fetch the latest ruleset, "name"
Packit Service 384592
  -l         Print listing of what is available
Packit Service 384592
Packit Service 384592
 Misc:
Packit Service 384592
  -c         Specify a config file for options.
Packit Service 384592
  -h         This help
Packit Service 384592
Packit Service 384592
Examples:
Packit Service 384592
Packit Service 384592
# Get a list of what the repository contains:
Packit Service 384592
$SCRIPT -rhttp://host/repo/ -l
Packit Service 384592
Packit Service 384592
# Get a partial list of versions 1.5.x:
Packit Service 384592
$SCRIPT -rhttp://host/repo/ -v1.5 -l
Packit Service 384592
Packit Service 384592
# Get the latest stable version of "breach_ModSecurityCoreRules":
Packit Service 384592
$SCRIPT -rhttp://host/repo/ -p/my/repo -Sbreach_ModSecurityCoreRules
Packit Service 384592
Packit Service 384592
# Get the latest stable 1.5 release of "breach_ModSecurityCoreRules":
Packit Service 384592
$SCRIPT -rhttp://host/repo/ -p/my/repo -v1.5 -Sbreach_ModSecurityCoreRules
Packit Service 384592
EOT
Packit Service 384592
	exit $rc;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub sort_versions {
Packit Service 384592
	(my $A = $a) =~ s/^(\d+)\.(\d+)\.(\d+)(-[^-\d]+|)(\d*)$/sprintf("%03d%03d%03d%03d%03d", $1, $2, $3, $PREFIX_MAP{$4}, $5)/e;
Packit Service 384592
	(my $B = $b) =~ s/^(\d+)\.(\d+)\.(\d+)(-[^-\d]+|)(\d*)$/sprintf("%03d%03d%03d%03d%03d", $1, $2, $3, $PREFIX_MAP{$4}, $5)/e;
Packit Service 384592
	return $A cmp $B;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub parse_config {
Packit Service 384592
	my($file,$clo) = @_;
Packit Service 384592
	my %cfg = ();
Packit Service 384592
Packit Service 384592
	print STDERR "Parsing config: $file\n" if ($opt{d});
Packit Service 384592
	open(CFG, "<$file") or die "Failed to open config \"$file\": $!\n";
Packit Service 384592
	while(<CFG>) {
Packit Service 384592
		# Skip comments and empty lines
Packit Service 384592
		next if (/^\s*(?:#|$)/);
Packit Service 384592
Packit Service 384592
		# Parse
Packit Service 384592
		chomp;
Packit Service 384592
		my($var,$q1,$val,$q2) = (m/^\s*(\S+)\s+(['"]?)(.*)(\2)\s*$/);
Packit Service 384592
Packit Service 384592
		# Fixup values
Packit Service 384592
		$var = lc($var);
Packit Service 384592
		if ($val =~ m/^(?:true|on)$/i) { $val = 1 };
Packit Service 384592
		if ($val =~ m/^(?:false|off)$/i) { $val = 0 };
Packit Service 384592
Packit Service 384592
		# Set opts
Packit Service 384592
		if    ($var eq "repositoryuri")       { $cfg{r} = $val }
Packit Service 384592
		elsif ($var eq "localrepository")        { $cfg{p} = $val }
Packit Service 384592
		elsif ($var eq "localrules")       { $cfg{s} = $val }
Packit Service 384592
		elsif ($var eq "version")          { $cfg{v} = $val }
Packit Service 384592
		elsif ($var eq "timeout")          { $cfg{t} = $val }
Packit Service 384592
		elsif ($var eq "notifyemail")      { $cfg{e} = $val }
Packit Service 384592
		elsif ($var eq "notifyemailfrom")  { $cfg{f} = $val }
Packit Service 384592
		elsif ($var eq "notifyemaildiff")  { $cfg{E} = $val }
Packit Service 384592
		elsif ($var eq "unpack")           { $cfg{u} = $val }
Packit Service 384592
		elsif ($var eq "debug")            { $cfg{d} = $val }
Packit Service 384592
		else { die "Invalid config directive: $var\n" }
Packit Service 384592
	}
Packit Service 384592
	close CFG;
Packit Service 384592
Packit Service 384592
	my($k, $v);
Packit Service 384592
	while (($k, $v) = each %{$clo || {}}) {
Packit Service 384592
		$cfg{$k} = $v if (defined $v);
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	return %cfg;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub repository_dump {
Packit Service 384592
	my @replist = repository_listing();
Packit Service 384592
Packit Service 384592
	print STDERR "\nRepository: $opt{r}\n\n";
Packit Service 384592
	unless (@replist) {
Packit Service 384592
		print STDERR "No matching entries.\n";
Packit Service 384592
		return;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	for my $repo (@replist) {
Packit Service 384592
		print "$repo {\n";
Packit Service 384592
		my @versions = ruleset_available_versions($repo);
Packit Service 384592
		for my $version (@versions) {
Packit Service 384592
			if ($version =~ m/$opt{v}/) {
Packit Service 384592
				printf "%15s: %s_%s.zip\n", $version, $repo, $version;
Packit Service 384592
			}
Packit Service 384592
			elsif ($opt{d}) {
Packit Service 384592
				print STDERR "Skipping version: $version\n";
Packit Service 384592
			}
Packit Service 384592
		}
Packit Service 384592
		print "}\n";
Packit Service 384592
	}
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub repository_listing {
Packit Service 384592
	my $res = $ua->get("$opt{r}/.listing");
Packit Service 384592
	unless ($res->is_success()) {
Packit Service 384592
		die "Failed to get repository listing \"$opt{r}/.listing\": ".$res->status_line()."\n";
Packit Service 384592
	}
Packit Service 384592
	return grep(/\S/, split(/$CRLFRE/, $res->content)) ;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_listing {
Packit Service 384592
	my $res = $ua->get("$opt{r}/$_[0]/.listing");
Packit Service 384592
	unless ($res->is_success()) {
Packit Service 384592
		die "Failed to get ruleset listing \"$opt{r}/$_[0]/.listing\": ".$res->status_line()."\n";
Packit Service 384592
	}
Packit Service 384592
	return grep(/\S/, split(/$CRLFRE/, $res->content)) ;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_available_versions {
Packit Service 384592
	return sort sort_versions map { m/_([^_]+)\.zip.*$/; $1 } ruleset_listing($_[0]);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_fetch {
Packit Service 384592
	my($repo, $version) = @_;
Packit Service 384592
Packit Service 384592
	# Create paths
Packit Service 384592
	if (! -e "$opt{p}" ) {
Packit Service 384592
		mkdir "$opt{p}" or die "Failed to create \"$opt{p}\": $!\n";
Packit Service 384592
	}
Packit Service 384592
	if (! -e "$opt{p}/$repo" ) {
Packit Service 384592
		mkdir "$opt{p}/$repo" or die "Failed to create \"$opt{p}/$repo\": $!\n";
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	my $fn = "${repo}_$version.zip";
Packit Service 384592
	my $ruleset = "$repo/$fn";
Packit Service 384592
	my $ruleset_sig = "$repo/$fn.sig";
Packit Service 384592
Packit Service 384592
	if (-e "$opt{p}/$ruleset") {
Packit Service 384592
		die "Refused to overwrite ruleset \"$opt{p}/$ruleset\".\n";
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	# Fetch the ruleset
Packit Service 384592
	print STDERR "Fetching: $ruleset ...\n";
Packit Service 384592
	my $res = $ua->get(
Packit Service 384592
		"$opt{r}/$ruleset",
Packit Service 384592
		":content_file" => "$opt{p}/$ruleset",
Packit Service 384592
	);
Packit Service 384592
	die "Failed to retrieve ruleset $ruleset: ".$res->status_line()."\n" unless ($res->is_success());
Packit Service 384592
Packit Service 384592
	# Fetch the ruleset signature
Packit Service 384592
	if (-e "$opt{p}/$ruleset_sig") {
Packit Service 384592
		die "Refused to overwrite ruleset signature \"$opt{p}/$ruleset_sig\".\n";
Packit Service 384592
	}
Packit Service 384592
	$res = $ua->get(
Packit Service 384592
		"$opt{r}/$ruleset_sig",
Packit Service 384592
		":content_file" => "$opt{p}/$ruleset_sig",
Packit Service 384592
	);
Packit Service 384592
Packit Service 384592
	# Verify the signature if we can
Packit Service 384592
	if ($HAVE_GNUPG) {
Packit Service 384592
		die "Failed to retrieve ruleset signature $ruleset_sig: ".$res->status_line()."\n" unless ($res->is_success());
Packit Service 384592
Packit Service 384592
		ruleset_verifysig("$opt{p}/$ruleset", "$opt{p}/$ruleset_sig");
Packit Service 384592
	}
Packit Service 384592
	push @fetched, [$repo, $version, $ruleset, undef];
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_unpack {
Packit Service 384592
	my($repo, $version, $ruleset) = @{ $_[0] || [] };
Packit Service 384592
	my $fn = "$opt{p}/$ruleset";
Packit Service 384592
Packit Service 384592
	if (! -e "$fn" ) {
Packit Service 384592
		die "Internal Error: No ruleset to unpack - \"$fn\"\n";
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	# Create paths
Packit Service 384592
	if (! -e "$opt{s}" ) {
Packit Service 384592
		mkdir "$opt{s}" or die "Failed to create \"$opt{p}\": $!\n";
Packit Service 384592
	}
Packit Service 384592
	if (! -e "$opt{s}/$repo" ) {
Packit Service 384592
		mkdir "$opt{s}/$repo" or die "Failed to create \"$opt{p}/$repo\": $!\n";
Packit Service 384592
	}
Packit Service 384592
	if (! -e "$opt{s}/$repo/$version" ) {
Packit Service 384592
		mkdir "$opt{s}/$repo/$version" or die "Failed to create \"$opt{p}/$repo/$version\": $!\n";
Packit Service 384592
	}
Packit Service 384592
	else {
Packit Service 384592
		die "Refused to overwrite previously unpacked \"$opt{s}/$repo/$version\".\n";
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	# TODO: Verify sig
Packit Service 384592
Packit Service 384592
	my $pwd = getcwd();
Packit Service 384592
	my $unpackdir = "$opt{s}/$repo/$version";
Packit Service 384592
	chdir "$unpackdir";
Packit Service 384592
	if ($@) {
Packit Service 384592
		my $err = $!;
Packit Service 384592
		chdir $pwd;
Packit Service 384592
		die "Failed to chdir to \"$unpackdir\": $err\n";
Packit Service 384592
	}
Packit Service 384592
	undef $!;
Packit Service 384592
	system(@$UNZIP, $fn);
Packit Service 384592
	if ($? != 0) {
Packit Service 384592
		my $err = $!;
Packit Service 384592
		chdir $pwd;
Packit Service 384592
		die "Failed to unpack \"$unpackdir\"".($err?": $err":".")."\n";
Packit Service 384592
	}
Packit Service 384592
	chdir $pwd;
Packit Service 384592
Packit Service 384592
	# Add where we unpacked it
Packit Service 384592
	$_->[3] = $unpackdir;
Packit Service 384592
Packit Service 384592
	return 0;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_fetch_latest {
Packit Service 384592
	my($repo, @type) = @_;
Packit Service 384592
	my @versions = ruleset_available_versions($repo);
Packit Service 384592
	my $verre = defined($opt{v}) ? qr/^$opt{v}/ : qr/^/;
Packit Service 384592
	my $typere = undef;
Packit Service 384592
	
Packit Service 384592
	# Figure out what to look for
Packit Service 384592
	if (@type == 1 and $type[0] ne "") {
Packit Service 384592
        my $type = $type[0];
Packit Service 384592
		if ($type eq "UNSTABLE") {
Packit Service 384592
			$typere = qr/\d-\D+\d+$/;
Packit Service 384592
		}
Packit Service 384592
		else {
Packit Service 384592
			$typere = qr/\d-$type\d+$/;
Packit Service 384592
		}
Packit Service 384592
	}
Packit Service 384592
	elsif (@type > 1) {
Packit Service 384592
        my $type;
Packit Service 384592
        for (@type) {
Packit Service 384592
            if ($_ eq "") {
Packit Service 384592
                $type .= ($type?"|":"").qr/\.\d+$/;
Packit Service 384592
            }
Packit Service 384592
            elsif ($_ eq "UNSTABLE") {
Packit Service 384592
                $type .= ($type?"|":"").qr/\d-\D+\d+$/;
Packit Service 384592
            }
Packit Service 384592
            else {
Packit Service 384592
                $type .= ($type?"|":"").qr/\d-$_\d+$/;
Packit Service 384592
            }
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
        $typere = qr/$type/;
Packit Service 384592
    }
Packit Service 384592
    else {
Packit Service 384592
		$typere = qr/\.\d+$/;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    if ($opt{d}) {
Packit Service 384592
        print STDERR "REPO: $repo\n";
Packit Service 384592
        print STDERR "TYPES: ".join(", ", @type)."\n";
Packit Service 384592
        print STDERR "VERSIONS: ".join(", ", @versions)."\n";
Packit Service 384592
        print STDERR "REGEX: version=$opt{v} type=$typere\n";
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	while (@versions) {
Packit Service 384592
		my $last = pop(@versions);
Packit Service 384592
		# Check REs on version
Packit Service 384592
		if ($last =~ m/$opt{v}/ and (!defined($typere) || $last =~ m/$typere/)) {
Packit Service 384592
			return ruleset_fetch($repo, $last);
Packit Service 384592
		}
Packit Service 384592
		if ($opt{d}) {
Packit Service 384592
			print STDERR "Skipping version: $last\n";
Packit Service 384592
		}
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	die "No '".join("' or '", @type)."' ruleset found.\n";
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub notify_email {
Packit Service 384592
	my $version_text = join("\n", map { "$_->[0] v$_->[1]".(defined($_->[3])?": $_->[3]":"") } @_);
Packit Service 384592
	my $from = $opt{f} ? "From: $opt{f}\n" : "";
Packit Service 384592
	my $body = << "EOT";
Packit Service 384592
ModSecurity rulesets updated and ready to install on host $HOST:
Packit Service 384592
Packit Service 384592
$version_text
Packit Service 384592
Packit Service 384592
ModSecurity - http://www.modsecurity.org/
Packit Service 384592
EOT
Packit Service 384592
Packit Service 384592
	# TODO: Diffs
Packit Service 384592
Packit Service 384592
	open(SM, "|-", @$SENDMAIL) or die "Failed to send mail: $!\n";
Packit Service 384592
	print STDERR "Sending notification email to: $opt{e}\n";
Packit Service 384592
	print SM << "EOT";
Packit Service 384592
${from}To: $opt{e}
Packit Service 384592
Subject: [$HOST] ModSecurity Ruleset Update Notification
Packit Service 384592
Packit Service 384592
$body
Packit Service 384592
EOT
Packit Service 384592
	close SM;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub ruleset_verifysig {
Packit Service 384592
	my($fn, $sigfn) = @_;
Packit Service 384592
Packit Service 384592
	print STDERR "Verifying \"$fn\" with signature \"$sigfn\"\n";
Packit Service 384592
	my $gpg = new GnuPG();
Packit Service 384592
	my $sig = eval { $gpg->verify( signature => $sigfn, file => $fn ) };
Packit Service 384592
	if (defined $sig) {
Packit Service 384592
		print STDERR sig2str($sig)."\n"; 
Packit Service 384592
	}
Packit Service 384592
	if (!defined($sig)) {
Packit Service 384592
		die "Signature validation failed.\n";
Packit Service 384592
	}
Packit Service 384592
	if ( $sig->{trust} < $REQUIRED_SIG_TRUST ) {
Packit Service 384592
		die "Signature is not trusted ".$GPG_TRUST{$REQUIRED_SIG_TRUST}.".\n";
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	return;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
sub sig2str {
Packit Service 384592
	my %sig = %{ $_[0] || {} };
Packit Service 384592
	"Signature made ".localtime($sig{timestamp})." by $sig{user} (ID: $sig{keyid}) and is $GPG_TRUST{$sig{trust}} trusted.";
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
################################################################################
Packit Service 384592
################################################################################
Packit Service 384592
Packit Service 384592
# List what is there
Packit Service 384592
if ($opt{l}) { repository_dump(); exit 0 }
Packit Service 384592
# Latest stable
Packit Service 384592
elsif (defined($opt{S})) { ruleset_fetch_latest($opt{S}, "") }
Packit Service 384592
# Latest development
Packit Service 384592
elsif (defined($opt{D})) { ruleset_fetch_latest($opt{D}, "dev") }
Packit Service 384592
# Latest release candidate
Packit Service 384592
elsif (defined($opt{R})) { ruleset_fetch_latest($opt{R}, "rc") }
Packit Service 384592
# Latest unstable
Packit Service 384592
elsif (defined($opt{U})) { ruleset_fetch_latest($opt{U}, "UNSTABLE") }
Packit Service 384592
# Latest release candidate or stable
Packit Service 384592
elsif (defined($opt{L})) { ruleset_fetch_latest($opt{R}, "rc", "") }
Packit Service 384592
# Latest (any type)
Packit Service 384592
elsif (defined($opt{F})) { ruleset_fetch_latest($opt{F}, undef) }
Packit Service 384592
Packit Service 384592
# Unpack
Packit Service 384592
if ($opt{u}) {
Packit Service 384592
	if (! defined $opt{s} ) { usage(1, "LocalRules is required for unpacking.") }
Packit Service 384592
	for (@fetched) {
Packit Service 384592
		ruleset_unpack($_);
Packit Service 384592
	}
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
# Unpack
Packit Service 384592
if ($opt{e}) {
Packit Service 384592
	notify_email(@fetched);
Packit Service 384592
}