diff options
-rw-r--r-- | perl/lib/Mail/Rspamd/Config.pm | 93 | ||||
-rwxr-xr-x | rspamc.pl.in | 52 |
2 files changed, 82 insertions, 63 deletions
diff --git a/perl/lib/Mail/Rspamd/Config.pm b/perl/lib/Mail/Rspamd/Config.pm index c468a3170..7f3d8fefd 100644 --- a/perl/lib/Mail/Rspamd/Config.pm +++ b/perl/lib/Mail/Rspamd/Config.pm @@ -26,7 +26,6 @@ use constant PARSER_STATE_MODULE => 3; use constant PARSER_STATE_CLASSIFIER => 4; use constant PARSER_STATE_STATFILE => 5; use constant PARSER_STATE_LOGGING => 6; -use constant PARSER_STATE_FACTORS => 7; use constant PARSER_STATE_METRIC => 8; use constant PARSER_STATE_VIEW => 9; use constant PARSER_STATE_MODULES => 10; @@ -53,13 +52,14 @@ sub new { workers => [], modules => {}, classifiers => {}, - factors => {}, + metrics => {}, options => {}, variables => {}, logging => {}, lua => [], composites => {}, paths => [], + views => [], parser_state => { state => PARSER_STATE_START, valid => 1, @@ -163,10 +163,13 @@ sub _handle_start_element { $self->{parser_state}->{state} = PARSER_STATE_WORKER; $self->{parser_state}->{worker} = { options => {} }; } + elsif ($lce eq 'view') { + $self->{parser_state}->{state} = PARSER_STATE_VIEW; + $self->{parser_state}->{view} = {}; + } elsif ($lce eq 'metric') { - $self->parser_state->state = PARSER_STATE_METRIC; - $self->_get_attr('name', 'name', 1, @attrs); - $self->{parser_state}->{metric} = {}; + $self->{parser_state}->{state} = PARSER_STATE_METRIC; + $self->{parser_state}->{metric} = { symbols => {} }; } elsif ($lce eq 'module') { $self->{parser_state}->{state} = PARSER_STATE_MODULE; @@ -178,9 +181,6 @@ sub _handle_start_element { $self->_get_attr('type', 'type', 1, @attrs); $self->{parser_state}->{classifier} = { statfiles => []}; } - elsif ($lce eq 'factors') { - $self->{parser_state}->{state} = PARSER_STATE_FACTORS; - } elsif ($lce eq 'variable') { $self->_get_attr('name', 'name', 1, @attrs); } @@ -208,10 +208,10 @@ sub _handle_start_element { $self->{error} = 'Invalid tag <' . $lce . '> in module section'; } } - elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) { + elsif ($self->{parser_state}->{state} == PARSER_STATE_METRIC) { my $lce = lc $element; - if ($lce eq 'factor') { - $self->_get_attr('name', 'name', 1, @attrs); + if ($lce eq 'symbol') { + $self->_get_attr('weight', 'weight', 1, @attrs); } } elsif ($self->{parser_state}->{state} == PARSER_STATE_CLASSIFIER) { @@ -272,9 +272,15 @@ sub _handle_end_element { } elsif ($self->{parser_state}->{state} == PARSER_STATE_METRIC) { if ($lce eq 'metric') { - $self->{metrics}->{ $self->{parser_state}->{name} } = $self->{parser_state}->{metric}; - $self->{parser_state}->{state} = PARSER_STATE_MAIN; - $self->{parser_state}->{metric} = undef; + if (exists ($self->{parser_state}->{metric}->{name})) { + $self->{metrics}->{ $self->{parser_state}->{metric}->{name} } = $self->{parser_state}->{metric}; + $self->{parser_state}->{state} = PARSER_STATE_MAIN; + $self->{parser_state}->{metric} = undef; + } + else { + $self->{parser_state}->{valid} = 0; + $self->{error} = 'Metric must have <name> tag'; + } } } elsif ($self->{parser_state}->{state} == PARSER_STATE_STATFILE) { @@ -296,12 +302,14 @@ sub _handle_end_element { $self->{parser_state}->{state} = PARSER_STATE_MAIN; } } - elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) { - if ($lce eq 'factors') { + elsif ($self->{parser_state}->{state} == PARSER_STATE_VIEW) { + if ($lce eq 'view') { + push(@{$self->{views}}, $self->{parser_state}->{view}); $self->{parser_state}->{state} = PARSER_STATE_MAIN; + $self->{parser_state}->{view} = undef; } } - elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) { + elsif ($self->{parser_state}->{state} == PARSER_STATE_MODULES) { if ($lce eq 'modules') { $self->{parser_state}->{state} = PARSER_STATE_MAIN; } @@ -351,7 +359,7 @@ sub _handle_text { $self->{logging}->{ $self->{parser_state}->{element} } = $data; } elsif ($self->{parser_state}->{state} == PARSER_STATE_WORKER) { - if ($self->{parser_state}->{element} eq 'param') { + if ($self->{parser_state}->{element} eq 'param' || $self->{parser_state}->{element} eq 'option') { $self->{parser_state}->{worker}->{options}->{$self->{parser_state}->{name}} = $data; } else { @@ -367,14 +375,19 @@ sub _handle_text { elsif ($self->{parser_state}->{state} == PARSER_STATE_MODULE) { $self->{parser_state}->{module}->{ $self->{parser_state}->{option} } = $data; } - elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) { - $self->{factors}->{ $self->{parser_state}->{name} } = $data; + elsif ($self->{parser_state}->{state} == PARSER_STATE_VIEW) { + $self->{parser_state}->{view}->{ $self->{parser_state}->{option} } = $data; } elsif ($self->{parser_state}->{state} == PARSER_STATE_MODULES) { push(@{$self->{paths}}, $data); } elsif ($self->{parser_state}->{state} == PARSER_STATE_METRIC) { - $self->{parser_state}->{metric}->{ $self->{parser_state}->{element} } = $data; + if ($self->{parser_state}->{element} eq 'symbol') { + $self->{parser_state}->{metric}->{symbols}->{ $data } = $self->{parser_state}->{weight}; + } + else { + $self->{parser_state}->{metric}->{ $self->{parser_state}->{element} } = $data; + } } } } @@ -473,11 +486,23 @@ sub _dump { } print XML "<!-- End of workers section -->\n\n"; - print XML "<!-- Factors section -->\n<factors>\n"; - while (my ($k, $v) = each (%{$self->{factors}})) { - print XML " <factor name=\"". $self->_xml_escape($k) ."\">" . $self->_xml_escape($v) . "</factor>\n"; + print XML "<!-- Metrics section -->\n"; + while (my ($k, $v) = each (%{$self->{metrics}})) { + print XML "<metric name=\"". $self->_xml_escape($k) ."\">\n"; + while (my ($kk, $vv) = each (%{ $v })) { + my $ek = $self->_xml_escape($kk); + if ($ek eq 'symbols') { + while (my ($sym, $weight) = each (%{ $vv })) { + print XML " <symbol weight=\"". $self->_xml_escape($weight) ."\">" . $self->_xml_escape($sym) . "</symbol>\n"; + } + } + else { + print XML " <$ek>" . $self->_xml_escape($vv) . "</$ek>\n"; + } + } + print XML "</metric>\n"; } - print XML "</factors>\n<!-- End of factors section -->\n\n"; + print XML "<!-- End of metrics section -->\n\n"; print XML "<!-- Logging section -->\n<logging>\n"; while (my ($k, $v) = each (%{$self->{logging}})) { @@ -548,3 +573,21 @@ sub _xml_escape { return $data; } +=head2 _xml_unescape + +private _xml_unescape() + +Description: +Unescapes characters in xml string + +=cut +sub _xml_unescape { + my $data = $_[1]; + if ($data =~ /\&|\<|\>|\"/) { + $data =~ s/\&/\&/g; + $data =~ s/\<\;/\</g; + $data =~ s/\>\;/\>/g; + $data =~ s/\"\;/\"/g; + } + return $data; +} diff --git a/rspamc.pl.in b/rspamc.pl.in index f994eced7..a261f66c9 100755 --- a/rspamc.pl.in +++ b/rspamc.pl.in @@ -10,6 +10,7 @@ use Socket qw(:DEFAULT :crlf); use Term::Cap; use Mail::Rspamd::Client; +use Mail::Rspamd::Config; use Data::Dumper; my %cfg = ( @@ -101,47 +102,22 @@ sub load_hosts_file { # Load rspamd config params sub parse_config { my ($is_ctrl) = @_; - - if (! open CONF, "< $cfg{'conf_file'}") { - print STDERR "Config file $cfg{'conf_file'} cannot be opened\n"; - return; - } - my $ctrl = 0, $skip = 0; - while (<CONF>) { - if ($_ =~ /^.*type.*=.*controller.*$/i) { - $ctrl = 1; - } - if ($ctrl && $_ =~ /}/) { - $ctrl = 0; - } - if ($_ =~ /^.*type.*=.*(?:lmtp|delivery|fuzzy).*$/i) { - $skip = 1; - } - if ($skip && $_ =~ /}/) { - $skip = 0; - } - if (!$skip && ((!$is_ctrl && !$ctrl) || ($ctrl && $is_ctrl)) - && $_ =~ /^\s*bind_socket\s*=\s*((([^:]+):(\d+))|(\/\S*))/i) { - if ($3 && $4) { - if ($3 eq '*') { - $cfg{'hosts'} = [ "127.0.0.1:$4" ]; - } - else { - $cfg{'hosts'} = [ "$3:$4" ]; - } - } - else { - $cfg{'hosts'} = [ "$5" ]; - } - } - if ($ctrl && $is_ctrl && $_ =~ /^\s*password\s*=\s*"(\S+)"/) { - $cfg{'password'} = $1; - } - } + my $parser = Mail::Rspamd::Config->new(); - close CONF; + $parser->load($cfg{'conf_file'}); + if (defined ($parser->{workers})) { + foreach my $worker (@{ $parser->{workers} }) { + if ($is_ctrl && $worker->{'type'} eq 'controller') { + $cfg{'hosts'} = [ $worker->{'bind_socket'} ]; + $cfg{'password'} = $worker->{options}->{password}; + } + elsif (!$is_ctrl && $worker->{'type'} eq 'normal') { + $cfg{'hosts'} = [ $worker->{'bind_socket'} ]; + } + } + } } sub print_control_result { |