eventmachine-email_server 0.0.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45064a738c416e1fce2c8726b3bab01c10f55860
4
- data.tar.gz: 25c163465275237d7caf9f48d257d20348a812c9
3
+ metadata.gz: 7f8d810ad36c8d3b8515f5f209afaadbb9038391
4
+ data.tar.gz: d6f036b47bd9fedf1e566ad576ed02e6f8a02b71
5
5
  SHA512:
6
- metadata.gz: cecf95b16f4d4e38cf83a65c2f4f9a69c5d4807b71a31a37fbc1cf4f723eb7476c95b7450adef582e8939019c5b4d6b96e8449a4070cb2ff0b78fa5b5bab4aa0
7
- data.tar.gz: 3cb06186363faef276e41cd92ea2127938d1d1bd3109a2bcf50f343a3d844b021e8969bd4213d3e01976547b8e8b8292482d8157bbf440cc27e45380b38a2e93
6
+ metadata.gz: bc9f85702c714eca052dd7b5ee52c66f84d35866df288494917e4039c29c5b533e1edd118a65f2815b4208962ef3331796808fb3da16e8ec50d45c1f311b7abf
7
+ data.tar.gz: dcc7d410bdd476b78db32533a507f8812d10b97c57bb2c7b177f752c95770a972ccbd111af44b416e2e06521b3be342719e0b425e6af58df9a7a3ee9c9677698
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency "sqlite3", ">= 1.3.6"
23
23
  spec.add_runtime_dependency "ratelimit-bucketbased", ">= 0.0.1"
24
24
  spec.add_runtime_dependency "eventmachine-dnsbl", ">= 0.0.2"
25
+ spec.add_runtime_dependency "spf", ">= 0.0.44"
25
26
  spec.add_development_dependency "minitest", "~> 5.5"
26
27
  spec.add_development_dependency "bundler", "~> 1.6"
27
28
  spec.add_development_dependency "rake", "~> 10.0"
@@ -1,5 +1,6 @@
1
1
  require 'eventmachine'
2
2
  require 'eventmachine/dnsbl'
3
+ require 'spf'
3
4
 
4
5
  module EventMachine
5
6
  module EmailServer
@@ -11,6 +12,15 @@ module EventMachine
11
12
  @@spf_check = false
12
13
  @@reject_filters = Array.new
13
14
 
15
+ def self.reset
16
+ @@graylist = nil
17
+ @@dnsbl_check = nil
18
+ @@ratelimiter = nil
19
+ @@reverse_ptr_check = false
20
+ @@spf_check = false
21
+ @@reject_filters = Array.new
22
+ end
23
+
14
24
  def self.reverse_ptr_check(ptr=nil)
15
25
  if not ptr.nil?
16
26
  @@reverse_ptr_check = ptr
@@ -135,36 +145,53 @@ module EventMachine
135
145
  end
136
146
  end
137
147
 
138
- def check_spf(from_domain)
148
+ def check_spf(helo, client_ip, identity)
139
149
  if @@spf_check
140
150
  @spf_ok = false
141
151
  @pending_checks << :spf
142
- d = EM::DNS::Resolver.resolve(from_domain, Resolv::DNS::Resource::IN::TXT)
143
- d.errback { |r|
144
- # fail open?
145
- @spf_ok = true
146
- @pending_checks -= [:spf]
147
- if @pending_checks.length == 0
148
- send_answer
152
+
153
+ spf_dispatcher = EventMachine::ThreadedResource.new do
154
+ spf_server = SPF::Server.new
155
+ end
156
+
157
+ pool = EM::Pool.new
158
+
159
+ pool.add spf_dispatcher
160
+
161
+ pool.perform do |dispatcher|
162
+ completion = dispatcher.dispatch do |spf_server|
163
+
164
+ request = SPF::Request.new(
165
+ versions: [1, 2], # optional
166
+ scope: 'mfrom', # or 'helo', 'pra'
167
+ identity: identity,
168
+ ip_address: client_ip,
169
+ helo_identity: helo # optional
170
+ )
171
+
172
+ result = spf_server.process(request)
149
173
  end
150
- }
151
- d.callback { |r|
152
- r.each do |rec|
153
- #pp rec
154
- if rec.start_with?('v=spf1')
155
- if rec == "v=spf1 -all"
156
- @spf_ok = false
157
- else
158
- # I need to create an SPF checker now :(
159
- @spf_ok = true
160
- end
174
+
175
+ completion.callback do |result|
176
+ if result.code == :pass
177
+ @spf_ok = true
178
+ elsif result.code == :fail
179
+ @spf_ok = false
180
+ elsif result.code == :softfail
181
+ @spf_ok = true
182
+ elsif result.code == :neutral
183
+ @spf_ok = true
184
+ else
185
+ @spf_ok = false
186
+ end
187
+ @pending_checks -= [:spf]
188
+ if @pending_checks.length == 0
189
+ send_answer
161
190
  end
162
191
  end
163
- @pending_checks -= [:spf]
164
- if @pending_checks.length == 0
165
- send_answer
166
- end
167
- }
192
+
193
+ completion
194
+ end
168
195
  end
169
196
  end
170
197
 
@@ -202,7 +229,8 @@ module EventMachine
202
229
  elsif (line =~ /^MAIL FROM\:/)
203
230
  @mail_from = (/^MAIL FROM\:<(.+)>.*$/).match(line)[1]
204
231
  if @@spf_check
205
- check_spf(@mail_from.split(/@/,2)[1])
232
+ port, ip = Socket.unpack_sockaddr_in(get_peername)
233
+ check_spf(helo, ip, @mail_from)
206
234
  end
207
235
  return true, "250 OK"
208
236
  elsif (line =~ /^RCPT TO\:/)
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module EmailServer
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -133,6 +133,7 @@ Looks like we had fun!
133
133
 
134
134
  def test_graylisting
135
135
  return unless @test_vector.call(__method__)
136
+ SMTPServer.reset
136
137
  SMTPServer.graylist(Hash.new)
137
138
  userstore = MemoryUserStore.new
138
139
  emailstore = MemoryEmailStore.new
@@ -161,6 +162,7 @@ Looks like we had fun!
161
162
  }
162
163
  storage = RateLimit::Memory.new
163
164
  rl = RateLimit::BucketBased.new(storage, config, 'default')
165
+ SMTPServer.reset
164
166
  SMTPServer.ratelimiter(rl)
165
167
  userstore = MemoryUserStore.new
166
168
  emailstore = MemoryEmailStore.new
@@ -220,6 +222,7 @@ Looks like we had fun!
220
222
  "127.0.0.2" => "Blacklisted as an example"
221
223
  }
222
224
  })
225
+ SMTPServer.reset
223
226
  SMTPServer.dnsbl_check(true)
224
227
 
225
228
  userstore = MemoryUserStore.new
@@ -255,32 +258,13 @@ Looks like we had fun!
255
258
  }
256
259
  end
257
260
 
258
- def test_spf_resolution
259
- return unless @test_vector.call(__method__)
260
- EM.run {
261
- d = EventMachine::DNS::Resolver.resolve("example.com", Resolv::DNS::Resource::IN::TXT)
262
- d.errback do |r|
263
- fail "dns resolution failed"
264
- EM.stop
265
- end
266
- d.callback do |r|
267
- refute_nil(r)
268
- assert_equal(2, r.length)
269
- refute_nil(r.index("v=spf1 -all"))
270
- EM.stop
271
- end
272
- timer = EventMachine::Timer.new(10) do
273
- EM.stop
274
- end
275
- }
276
- end
277
-
278
261
  def test_spf
279
262
  return unless @test_vector.call(__method__)
280
263
  userstore = MemoryUserStore.new
281
264
  emailstore = MemoryEmailStore.new
282
265
  setup_user(userstore)
283
266
 
267
+ SMTPServer.reset
284
268
  SMTPServer.spf_check(true)
285
269
  EM.run {
286
270
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
@@ -314,6 +298,7 @@ Looks like we had fun!
314
298
  rl = RateLimit::BucketBased.new(storage, config, 'default')
315
299
 
316
300
 
301
+ SMTPServer.reset
317
302
  SMTPServer.reverse_ptr_check(true)
318
303
  SMTPServer.graylist(Hash.new)
319
304
  SMTPServer.ratelimiter(rl)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventmachine-email_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-03 00:00:00.000000000 Z
11
+ date: 2015-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.0.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: spf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 0.0.44
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 0.0.44
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: minitest
71
85
  requirement: !ruby/object:Gem::Requirement