maildiode-greylist 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/plugins/greylist.rb +137 -0
- metadata +71 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
# Copyright 2007-2008 Kevin B. Smith
|
2
|
+
# This file is part of MailDiode.
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License version 3, as
|
6
|
+
# published by the Free Software Foundation.
|
7
|
+
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require 'kirbybase'
|
17
|
+
|
18
|
+
ONE_HOUR_IN_SECONDS = 60*60
|
19
|
+
|
20
|
+
module MailDiode
|
21
|
+
class GreylistFilter < Filter
|
22
|
+
# Traditional (client IP, sender address, recipient address)
|
23
|
+
# or selective (client IP, HELO name, sender domain)?
|
24
|
+
GREYLIST_ADDED = "450 You are being put on a waiting list--please try again later"
|
25
|
+
GREYLIST_WAITING = "450 You are still on the waiting list--please try later"
|
26
|
+
GREYLIST_DELAY_IN_SECONDS = 60
|
27
|
+
|
28
|
+
def initialize(settings)
|
29
|
+
@delay_minutes = 60
|
30
|
+
load_settings(settings)
|
31
|
+
@kirby = KirbyBase.new(:local, nil, nil, '/var/local/maildiode/')
|
32
|
+
ensure_database_table_exists
|
33
|
+
end
|
34
|
+
|
35
|
+
def delay_seconds
|
36
|
+
@settings.delay_minutes * 60
|
37
|
+
end
|
38
|
+
|
39
|
+
def process(filterable_data)
|
40
|
+
ip = filterable_data.sender_ip
|
41
|
+
helo = filterable_data.helo
|
42
|
+
from = filterable_data.sender
|
43
|
+
to = filterable_data.recipient
|
44
|
+
|
45
|
+
if is_bounce_message(from)
|
46
|
+
MailDiode::log_info "Greylist allowing bounce message"
|
47
|
+
return true
|
48
|
+
end
|
49
|
+
from_user, from_domain = from.split('@')
|
50
|
+
table = get_database_table
|
51
|
+
found = table.select { | r | (r.ip == ip && r.helo == helo && r.from_domain = from_domain) }
|
52
|
+
case found.size
|
53
|
+
when 0
|
54
|
+
record = create_record(ip, helo, from_user, from_domain, to)
|
55
|
+
MailDiode::log_info "Greylist added #{key(record)}"
|
56
|
+
raise SMTPError.new(GREYLIST_ADDED)
|
57
|
+
when 1
|
58
|
+
if !check_existing_record(found[0])
|
59
|
+
raise SMTPError.new(GREYLIST_WAITING)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
MailDiode::log_warning "Greylist found multiple entries for #{ip};#{helo};#{from};#{to}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_bounce_message(from)
|
67
|
+
return from.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def key(record)
|
71
|
+
return "#{record.ip};#{record.helo};#{record.from_domain}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_record(ip, helo, from_user, from_domain, to)
|
75
|
+
recno = get_database_table.insert do |r|
|
76
|
+
r.ip = ip
|
77
|
+
r.helo = helo
|
78
|
+
r.from_user = from_user
|
79
|
+
r.from_domain = from_domain
|
80
|
+
r.to = to
|
81
|
+
r.first_seen = now
|
82
|
+
r.last_seen = now
|
83
|
+
r.approved = false
|
84
|
+
record = r
|
85
|
+
end
|
86
|
+
return get_database_table.select { | r | r.recno == recno }
|
87
|
+
end
|
88
|
+
|
89
|
+
def check_existing_record(record)
|
90
|
+
if(record.approved)
|
91
|
+
MailDiode::log_info "Greylist approved"
|
92
|
+
return true
|
93
|
+
end
|
94
|
+
|
95
|
+
table = get_database_table
|
96
|
+
delay_until = record.first_seen + delay_seconds
|
97
|
+
if now > delay_until
|
98
|
+
table.update(:approved => true) { | r | r.recno == record.recno }
|
99
|
+
MailDiode::log_info "Greylist approved #{key(record)}"
|
100
|
+
return true
|
101
|
+
end
|
102
|
+
|
103
|
+
table.update(:last_seen => now) { | r | r.recno == record.recno }
|
104
|
+
MailDiode::log_info "Greylist delaying #{key(record)} until #{Time.at(delay_until)}"
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
|
108
|
+
def now
|
109
|
+
return Time.now.to_i
|
110
|
+
end
|
111
|
+
|
112
|
+
def get_database_table
|
113
|
+
return @kirby.get_table(:greylist)
|
114
|
+
end
|
115
|
+
|
116
|
+
def ensure_database_table_exists
|
117
|
+
if @kirby.table_exists?(:greylist)
|
118
|
+
return
|
119
|
+
end
|
120
|
+
MailDiode::log_info "Creating greylist database"
|
121
|
+
@kirby.create_table(:greylist,
|
122
|
+
:ip, :String,
|
123
|
+
:helo, :String,
|
124
|
+
:from_user, :String,
|
125
|
+
:from_domain, :String,
|
126
|
+
:to, :String,
|
127
|
+
:first_seen, :Integer,
|
128
|
+
:last_seen, :Integer,
|
129
|
+
:approved, :Boolean
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def load_settings(settings)
|
134
|
+
@delay_minutes = settings.get_setting('greylist', 'delayminutes').to_i
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maildiode-greylist
|
3
|
+
version: &id001 !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-03 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: maildiode
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- *id001
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: KirbyBase
|
26
|
+
type: :runtime
|
27
|
+
version_requirement:
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.6.0
|
33
|
+
version:
|
34
|
+
description:
|
35
|
+
email: kevins@qualitycode.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- lib/plugins/greylist.rb
|
44
|
+
has_rdoc: false
|
45
|
+
homepage: http://maildiode.rubyforge.org/
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.8.1
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: maildiode
|
66
|
+
rubygems_version: 1.2.0
|
67
|
+
signing_key:
|
68
|
+
specification_version: 2
|
69
|
+
summary: Greylist anti-spam plugin for MailDiode
|
70
|
+
test_files: []
|
71
|
+
|