#
# old_revision [39c9f012ce8b82b4f02cb9b3e8a1cc5775b00f4f]
#
# patch "pf/lib/pf/pfcmd/checkup.pm"
#  from [17846a6364dab125fd4dd0f36fff8acfd361fe6c]
#    to [4481fe6ebf7b2ccfef6fe2938acce528804a3e6f]
# 
# patch "pf/lib/pf/services.pm"
#  from [e8a77ad99f7a837dcca42d961fa84bb6492acf15]
#    to [04ea0912fd432bada1212f5807afc9c4a40ddb0a]
#
============================================================
--- pf/lib/pf/pfcmd/checkup.pm	17846a6364dab125fd4dd0f36fff8acfd361fe6c
+++ pf/lib/pf/pfcmd/checkup.pm	4481fe6ebf7b2ccfef6fe2938acce528804a3e6f
@@ -96,6 +96,7 @@ sub sanity_check {
     is_config_documented();
     extensions();
     permissions();
+    violations();
 
     return @problems;
 }
@@ -549,6 +550,56 @@ sub permissions {
 
 }
 
+=item violations
+
+Checking for violations configurations
+
+=cut
+sub violations {
+    require pf::services;
+    my %violations_conf;
+    tie %violations_conf, 'Config::IniFiles',
+        ( -file => "$conf_dir/violations.conf" );
+    my @errors = @Config::IniFiles::errors;
+    if ( scalar(@errors) ) {
+        add_problem( $FATAL, "Error reading violations.conf");
+    }
+    my %violations = pf::services::class_set_defaults(%violations_conf);    
+
+    foreach my $violation ( keys %violations ) {
+
+        # parse triggers if they exist
+        my @triggers;
+        if ( defined $violations{$violation}{'trigger'} ) {
+            foreach my $trigger (
+                split( /\s*,\s*/, $violations{$violation}{'trigger'} ) )
+            {
+                my ( $type, $tid ) = split( /::/, $trigger );
+                $type = lc($type);
+                if ( !grep( { lc($_) eq lc($type) } @valid_trigger_types ) ) {
+                    add_problem( $WARN, "invalid trigger '$type' found at $violation");
+                }
+                if ( $tid =~ /(\d+)-(\d+)/ ) {
+                    if ( $1 > $2 ) {
+                         add_problem( $FATAL, "Invalid usage of trigger range, start ID $1 is greater than end ID $2 for violation $violation");
+                    }
+                }
+            }
+	}
+         # parse grace, try to understand trailing signs, and convert back to seconds 
+        if ( defined $violations{$violation}{'grace'} ) {
+            # If we can detect s,m or y at the end of the string, we recalculate the number of seconds
+            # if we have nothing, we consider it is seconds (s=seconds, m=minutes, h=hours, d=days, M=months, Y=years)
+            my $time = pf::config::normalize_time($violations{$violation}{'grace'});
+            
+            if (!$time) {
+                add_problem( $FATAL, "Invalid grace format found ($violations{$violation}{'grace'}) for $violation, supported format are s (seconds),m (minutes),h (hours),d (days),w (weeks),y (years)");
+            }
+        }
+
+     }
+}
+
 =back
 
 =head1 AUTHOR
============================================================
--- pf/lib/pf/services.pm	e8a77ad99f7a837dcca42d961fa84bb6492acf15
+++ pf/lib/pf/services.pm	04ea0912fd432bada1212f5807afc9c4a40ddb0a
@@ -1082,6 +1082,13 @@ sub read_violations_conf {
             }
         }
 
+        # parse grace, try to understand trailing signs, and convert back to seconds 
+        if ( defined $violations{$violation}{'grace'} ) {
+            # If we can detect s,m or y at the end of the string, we recalculate the number of seconds
+            # if we have nothing, we consider it is seconds (s=seconds, m=minutes, h=hours, d=days, w=weeks, y=years)
+            $violations{$violation}{'grace'} = pf::config::normalize_time($violations{$violation}{'grace'});
+        }
+
         #print Dumper(@triggers);
         # be careful of the way parameters are passed, whitelists, actions and triggers are expected at the end
         class_merge(
