Break <command> into <command>[<optionlist>]

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2013-07-14 08:44:01 -07:00
parent 5ba8df81fb
commit 8c27b027fc
2 changed files with 77 additions and 45 deletions

View File

@ -54,20 +54,56 @@ if ( supplied $duration ) {
fatal_error "Invalid hit count ($hitcount)" unless $hitcount =~ /^\d+$/;
fatal_error "Invalid Src or Dest ($destination)" unless $destination =~ /^(?:src|dst)$/;
fatal_error "Invalid reset flag ($command)" unless $command =~ /^(?:reset|update|updatereap|check|checkreap)$/;
my $srcdst = $destination eq 'src'? '--rsource' : '--rdest';
our $commands_defined;
#
# Can't 'use constant' here
#
my ( $UPDATE_CMD, $CHECK_CMD, $RESET_CMD, $REAP_OPT, $TTL_OPT ) = ( 1, 2, 4, 8, 16 );
my %command = ( check => $CHECK_CMD,
update => $UPDATE_CMD,
reset => $RESET_CMD
);
my %commandopts = (
reap => $REAP_OPT,
ttl => $TTL_OPT
);
my @command = split(':', $command);
$command = $command{shift @command} || 0;
fatal_error "Command must be 'check', 'update' or 'reset" unless $command & ( $CHECK_CMD | $UPDATE_CMD | $RESET_CMD);
for ( @command ) {
fatal_error "Invalid command option ($_)" unless $commandopts{$_};
if ( $command & $commandopts{$_} ) {
warning_message "Duplicate command ($_)";
} else {
$command |= $commandopts{$_};
}
}
my $duplicate;
set_action_disposition( $disposition) if supplied $disposition;
set_action_name_to_caller;
require_capability 'RECENT_MATCH', 'Use of events', 's';
my $reap;
if ( $command & $REAP_OPT ) {
fatal_error "${command}reap requires a time limit" if ! $duration;
$duration .= '--reap ';
}
fatal_error "${command}reap requires a time limit" if ( $reap = $command =~ s/reap$// ? '--reap ' : '' ) && ! $duration;
$duration .= '--rttl ' if $command & $TTL_OPT;
$duration .= $reap;
if ( $command eq 'reset' ) {
if ( $command & $RESET_CMD ) {
require_capability 'MARK_ANYWHERE', '"reset"', 's';
print "Resetting....\n";
@ -86,19 +122,15 @@ if ( $command eq 'reset' ) {
#
# Mark the packet if event is armed
#
if ( $destination eq 'dst' ) {
perl_action_helper( 'INLINE', "-m recent --rcheck ${duration}--hitcount $hitcount --name $event --rdest -j MARK --or-mark $mark" );
} else {
perl_action_helper( 'INLINE', "-m recent --rcheck ${duration}--hitcount $hitcount --name $event --rsource -j MARK --or-mark $mark" );
}
perl_action_helper( 'INLINE', "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst -j MARK --or-mark $mark" );
#
# if the event is armed, remove it and perform the action
#
perl_action_helper( $action , "-m mark --mark $mark/$mark -m recent --remove --name $event" );
} elsif ( $command eq 'update' ) {
perl_action_helper( $action, "-m recent --update ${duration}--hitcount $hitcount --name $event" );
} elsif ( $command & $UPDATE_CMD ) {
perl_action_helper( $action, "-m recent --update ${duration}--hitcount $hitcount --name $event $srcdst" );
} else {
perl_action_helper( $action, "-m recent --rcheck ${duration}--hitcount $hitcount --name $event" );
perl_action_helper( $action, "-m recent --rcheck ${duration}--hitcount $hitcount --name $event $srcdst" );
}
1;

View File

@ -272,8 +272,8 @@
[ <replaceable>duration</replaceable> ], [
<replaceable>hitcount</replaceable> ], [
<replaceable>src-dst</replaceable>], [
<replaceable>command</replaceable> ], [
<replaceable>disposition</replaceable> ] )</para>
<replaceable>command</replaceable>[:<replaceable>option</replaceable>]...,
[ <replaceable>disposition</replaceable> ] )</para>
<variablelist>
<varlistentry>
@ -348,8 +348,9 @@
<listitem>
<para>Like <emphasis role="bold">check</emphasis>. If the
test succeeds, the <replaceable>event</replaceable> will be
reset before the <replaceable>action</replaceable> is
taken.</para>
reset before the <replaceable>action</replaceable> is taken.
Requires the <firstterm>Mark in filter table</firstterm>
capability in your kernel and iptables.</para>
</listitem>
</varlistentry>
@ -364,36 +365,35 @@
<replaceable>event</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>checkreap</term>
<listitem>
<para>Requires a <replaceable>duration</replaceable>. Like
<emphasis role="bold">check</emphasis> but regardless of
whether the test succeeds, entries for the
<replaceable>src-dst</replaceable> IP address that are older
than <replaceable>duration</replaceable> seconds will be
deleted from the <replaceable>event</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>updatereap</term>
<listitem>
<para>Requires a <replaceable>duration</replaceable>. Like
<emphasis role="bold">update</emphasis> but regardless of
whether the test succeeds, entries for the
<replaceable>src-dst</replaceable> IP address that are older
than <replaceable>duration</replaceable> seconds will be
deleted from the <replaceable>event</replaceable>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>The default is <emphasis
role="bold">check</emphasis>.</para>
<para><replaceable>option</replaceable> may be one of:</para>
<variablelist>
<varlistentry>
<term>reap</term>
<listitem>
<para>Regardless of whether the test succeeds, entries for
the <replaceable>src-dst</replaceable> IP address that are
older than <replaceable>duration</replaceable> seconds will
be deleted from the <replaceable>event</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ttl</term>
<listitem>
<para>Constrains the test to require that the packet TTL
match the ttl in the original packet that created the
entry.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
@ -521,7 +521,7 @@ IfEvent(SSH_COUNTER,REJECT,300,1)
#
# Blacklist if 5 attempts in the last minute
#
IfEvent(SSH,SSH_BLACKLIST,60,5,src,checkreap)
IfEvent(SSH,SSH_BLACKLIST,60,5,src,check:reap)
#
# Log and reject if the client has tried to connect
# in the last two seconds