111 lines
3.7 KiB
Perl
Executable File
111 lines
3.7 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
#
|
|
# Copyright (c) 2022 Mischa Peters <mischa @ high5.nl>
|
|
#
|
|
# Permission to use, copy, modify, and distribute this software for any
|
|
# purpose with or without fee is hereby granted, provided that the above
|
|
# copyright notice and this permission notice appear in all copies.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
#
|
|
use 5.024;
|
|
use strict;
|
|
use warnings;
|
|
use autodie;
|
|
use Getopt::Std;
|
|
use DBI;
|
|
|
|
my $db_type = 'MariaDB';
|
|
my $db_host = '';
|
|
my $db_user = '';
|
|
my $db_pass = '';
|
|
my $db_name = '';
|
|
|
|
getopts('dv');
|
|
our($opt_d, $opt_v);
|
|
|
|
my $email = "";
|
|
my $from = "";
|
|
my %ooo;
|
|
my $dbh = DBI->connect("DBI:$db_type:$db_name:$db_host", "$db_user", "$db_pass", {RaiseError => 1});
|
|
sub do_query {
|
|
my ($query) = @_;
|
|
my $sth = $dbh->prepare($query);
|
|
$sth->execute;
|
|
return $sth;
|
|
}
|
|
|
|
open (my $fh, '>', "/tmp/virtualvacation.log") if ($opt_d);
|
|
select(STDOUT);
|
|
$|++;
|
|
select($fh);
|
|
$|++;
|
|
print STDOUT "register|filter|smtp-in|rcpt-to\n";
|
|
print STDOUT "register|filter|smtp-in|mail-from\n";
|
|
print STDOUT "register|filter|smtp-in|data-line\n";
|
|
print STDOUT "register|ready\n";
|
|
|
|
while (my $line = <>) {
|
|
next if ($line =~ m/^config/);
|
|
chomp $line;
|
|
print $fh "$line\n" if ($opt_v);
|
|
if ($line =~ m/filter/) {
|
|
my ($stream, $version, $timestamp, $subsystem, $event, $sid, $token, $data) = split /\|/, $line;
|
|
if ($line =~ m/mail-from/) {
|
|
$from = $data;
|
|
print STDOUT "filter-result|$sid|$token|proceed\n";
|
|
}
|
|
if ($line =~ m/rcpt-to/) {
|
|
$email = $data;
|
|
$ooo{$sid} = 1;
|
|
print $fh "Virtual Vacation: created session $sid\n";
|
|
print STDOUT "filter-result|$sid|$token|proceed\n";
|
|
}
|
|
if ($line =~ m/data-line/) {
|
|
if (!$data) { $data = ""; }
|
|
if ($data =~ m/^precedence:\s+(bulk|list|junk)/i) { $ooo{$sid} = 0; }
|
|
if ($data =~ m/^x-loop:\s+opensmtpd\ admin\ virtual\ vacation/i) { $ooo{$sid} = 0; }
|
|
print STDOUT "filter-dataline|$sid|$token|$data\n";
|
|
}
|
|
if ($line =~ m/data-line/ && $data eq '.' && $ooo{$sid} == 1) {
|
|
print $fh "Virtual Vacation: To: $email, From: $from\n" if ($opt_d);
|
|
my $query = qq{SELECT subject,body FROM vacation WHERE email='$email' and active=1};
|
|
my $sth = do_query($query);
|
|
my $rv = $sth->rows;
|
|
if ($rv == 1) {
|
|
my @row = $sth->fetchrow_array;
|
|
print $fh "Virtual Vacation: Found OOO for $email\n" if ($opt_d);
|
|
$query = qq{SELECT cache FROM vacation WHERE email='$email' AND FIND_IN_SET('$from',cache)};
|
|
$sth = do_query ($query);
|
|
$rv = $sth->rows;
|
|
if ($rv == 0) {
|
|
$query = qq{UPDATE vacation SET cache=CONCAT(cache,',','$from') WHERE email='$email'};
|
|
$sth = do_query($query);
|
|
print $fh "Virtual Vacation: Sending OOO to $from\n" if ($opt_d);
|
|
open my $fh_email, "|-", "/usr/sbin/sendmail -t";
|
|
print $fh_email "From: $email\n";
|
|
print $fh_email "To: $from\n";;
|
|
print $fh_email "Subject: $row[0]\n";
|
|
print $fh_email "X-Loop: OpenSMTPD Admin Virtual Vacation\n";
|
|
print $fh_email "Content-Type: text/plain; charset=utf-8\n\n";
|
|
print $fh_email "$row[1]\n";
|
|
close $fh_email;
|
|
}
|
|
delete $ooo{$sid};
|
|
print $fh "Virtual Vacation: removed session $sid\n" if ($opt_d);
|
|
}
|
|
} elsif ($line =~ m/data-line/ && $data eq '.' && $ooo{$sid} == 0) {
|
|
delete $ooo{$sid};
|
|
print $fh "Virtual Vacation: removed session $sid\n" if ($opt_d);
|
|
}
|
|
}
|
|
}
|
|
close $fh;
|
|
0;
|