Courier-Filter

 view release on metacpan or  search on metacpan

lib/Courier/Filter/Module/Parts.pm  view on Meta::CPAN

        views           => ['raw', 'zip'],
        signatures      => [
            {
                # One or more of the following options:
                mime_type       => 'text/html' || qr/html/i,
                file_name       => 'file_name.ext' || qr/\.(com|exe)$/i,
                size            => 106496,
                digest_md5      => 'b09e26c292759d654633d3c8ed00d18d',
                encrypted       => 0,
                
                # Optionally any of the following:
                views           => ['raw', 'zip'],
                response        => $response_text
            },
            ...
        ],
        
        logger          => $logger,
        inverse         => 0,
        trusting        => 0,
        testing         => 0,
        debugging       => 0
    );
    
    my $filter = Courier::Filter->new(
        ...
        modules         => [ $module ],
        ...
    );

=head1 DESCRIPTION

This class is a filter module class for use with Courier::Filter.  It matches a
message if one of the message's parts (MIME parts, or files in a ZIP archive)
matches one of the configured signatures.

=cut

# Implementation:
###############################################################################

=head2 Constructor

The following constructor is provided:

=over

=item B<new(%options)>: returns I<Courier::Filter::Module::Parts>

Creates a new B<Parts> filter module.

%options is a list of key/value pairs representing any of the following
options:

=over

=item B<views>

An arrayref containing the global default set of I<views> the filter module
should apply to message parts when matching the configured signatures against
them.  A view is the way how a MIME part's (MIME-decoded) data is interpreted.
Defaults to B<['raw']>.

The following views are supported:

=over

=item B<raw>

The MIME part is MIME-decoded but not otherwise transformed.  The raw MIME part
is then matched against the configured signatures.

=item B<zip>

If the MIME part has a file name ending in C<.zip>, it is considered a ZIP
archive, and all unencrypted files in the archive are matched as individual
message parts against the configured signatures.  The zip view requires the
B<Archive::Zip> Perl module to be installed.

=back

=item B<max_message_size>

=item B<max_size> (DEPRECATED)

An integer value controlling the maximum size (in bytes) of the overall message
text for a message to be processed by this filter module.  Messages larger than
this value will never be processed, and thus will never match.  If B<undef>,
there is no size limit.  Defaults to B<1024**2> (1MB).

As MIME multipart and ZIP archive processing can be quite CPU- and
memory-intensive (although the B<Parts> filter module makes use of temporary
files since version 0.13), you should definitely restrict the message size to
some sensible value that easily fits in your server's memory.  1024**2 (1MB)
should be appropriate for most uses of this filter module.

The C<max_message_size> option was previously called C<max_size>, but the
latter is now deprecated and may not be supported in future versions of the
B<Parts> filter module.

=item B<max_part_size>

An integer value controlling the maximum size (in bytes) of any single message
part (i.e. MIME part in a message, or file in an archive) for that part to be
processed by this filter module.  Parts larger than this value will never be
processed, and thus will never match.  If B<undef>, there is no size limit.

Defaults to the value of the C<max_message_size> option, so you don't really
need to specify a part size limit if you are comfortable with using the same
value for both.  See the C<max_message_size> option for its default.

If you make use of the B<'zip'> view, be aware of the risk posed by so-called
I<decompression bombs>, which allow messages to easily fall below the overall
message size limit, while a file in a small attached ZIP archive can decompress
to a huge size.  The part size limit prevents huge files from being
decompressed.

=item B<signatures>

I<Required>.  A reference to an array containing the list of I<signatures>
against which message parts are to be matched.  A signature in turn is a
reference to a hash containing one or more so-called signature I<aspects> (as
key/value pairs) and any signature I<options> (also as key/value pairs).

I<Signature aspects>

Aspects may either be scalar values (for exact, case-sensitive matches), or
regular expression objects created with the C<qr//> operator (for inexact,
partial matches).  For a signature to match a message part, I<all> of the
signature's specified aspects must match those of the message part.  For the
filter module to match a message, I<any> of the signatures must match I<any> of
the message's parts.

A signature aspect can be any of the following:

=over

=item B<mime_type>

The MIME type of the message part ('type/sub-type').

=item B<file_name>

The file name of the message part.

=item B<size>

The exact size (in bytes) of the decoded message part.

=item B<digest_md5>

The MD5 digest of the decoded message part (32 hex digits, as printed by
`md5sum`).

=item B<encrypted>

A boolean value denoting whether the message part is encrypted and its contents
are inaccessible to the B<Parts> filter module.

=back

I<Signature options>

A signature option can be any of the following:

=over

=item B<views>

An arrayref containing the set of I<views> the filter module should apply to
message parts when matching I<this> signature against them.  For a list of
supported views, see the description of the constructor's C<views> option.
Defaults to the global set of views specified to the constructor.

=item B<response>

A string that is to be returned as the match result in case of a match.
Defaults to B<"Prohibited message part detected.">.

=back

I<Example>

So for instance, a signature list could look like this:

    signatures  => [
        {
            mime_type   => qr/html/i,
            response    => 'No HTML mail, please.'
        },
        {
            file_name   => qr/\.(com|exe|lnk|pif|scr|vbs)$/i,
            response    => 'Executable content detected'
        },
        {
            size        => 106496,
            digest_md5  => 'b09e26c292759d654633d3c8ed00d18d',
            views       => ['raw', 'zip'],  # Look into ZIP archives, too!
            response    => 'Worm detected: W32.Swen'
        },
        {
            size        => 22528,
            # Cannot set a specific digest_md5 since W32.Mydoom
            # is polymorphic.
            response    => 'Worm suspected: W32.Mydoom'
        },
        {
            encrypted   => 1,
            views       => ['zip'],
            response    => 'Worm suspected ' .
                           '(only worms and fools use ZIP encryption)'
        }



( run in 1.148 second using v1.01-cache-2.11-cpan-59e3e3084b8 )