Skip to content

Instantly share code, notes, and snippets.

@bigntallmike
Created March 16, 2020 15:03
Show Gist options
  • Save bigntallmike/439f86bb55807c67903578ec20a8c273 to your computer and use it in GitHub Desktop.
Save bigntallmike/439f86bb55807c67903578ec20a8c273 to your computer and use it in GitHub Desktop.
--- qmail-scanner-queue.pl 2019-05-16 13:27:59.244644818 -0400
+++ qmail-scanner-queue-limit.pl 2019-05-16 13:40:30.543728379 -0400
@@ -101,6 +101,17 @@
+use POSIX qw(strftime);
+my $THISHOUR = strftime "%H", localtime;
+
+# How many messages can a user send per hour
+my $MAXMSGPERHR=5;
+if ($THISHOUR > 4 and $THISHOUR < 18) {
+ $MAXMSGPERHR=50;
+}
+
#Array of local domains that are checked against for
#deciding whether or not to send recipient alerts to
@@ -439,6 +448,14 @@
&working_copy;
+use DBI;
+
+my $sqluser = 'thisisyourusername';
+my $sqlpass = 'thisisyourpassword';
+my $dsn = "DBI:mysql:database=vpopmail;host=localhost";
+
+&debug("sql: connecting to $dsn");
+my $dbh = DBI->connect($dsn, $sqluser, $sqlpass);
#We will set our own value here as it allows us to unset
#it later without changing how Qmail actually interprets
@@ -500,6 +517,33 @@
$headers{'RCPTTO'}=$recips;
$headers{'REMOTEIPADDR'}=$remote_smtp_ip;
+ if ($returnpath =~ /^\s*$/) {
+ &debug("sql: returnpath blank");
+ } elsif ($returnpath =~ /someoneimportanthere/) {
+ &debug("sql: bypassing rules for someoneimportant");
+ } else {
+ # Check how many log entries are in the last hour
+ my $hourlycount = 0;
+ my $sqlstmt = $dbh->prepare("SELECT COUNT(userlogid) as hourly FROM userlog WHERE sender = ? AND ctime > SUBTIME(NOW(), '1:00:00.0')");
+ $sqlstmt->execute($returnpath);
+ if ($sqlstmt->rows) {
+ my $result = $sqlstmt->fetchrow_hashref();
+ $hourlycount = $result->{hourly};
+ &debug("sql: has sent $hourlycount messages this last hour");
+ if ($hourlycount > $MAXMSGPERHR) {
+ &error_condition("too many messages sent this hour $smtp_sender, please slow down", 452);
+ } else {
+ $dbh->do("INSERT INTO userlog(sender, senderip) VALUES (?, ?)", undef, $returnpath, $remote_smtp_host);
+ }
+ } else {
+ &debug("sql: failed to fetch message count");
+ }
+ }
+
if ( ($BAD_MIME_CHECKS > 1 && $headers{'mime-version'} eq "") || ($headers{'mime-version'} ne "" && $headers{'content-type'} =~ /^text\/plain/i)) {
#Hmm, doesn't look nice, but it feels better to make this a separate check for some reason
if ($skip_text_msgs && ($indicates_attachments < 2) && !@uufile_list && !@attachment_list) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment