remailer 0.4.6 → 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/remailer/connection.rb +1 -0
- data/lib/remailer/connection/smtp_interpreter.rb +9 -3
- data/lib/remailer/connection/socks5_interpreter.rb +2 -2
- data/lib/remailer/interpreter.rb +15 -5
- data/lib/remailer/interpreter/state_proxy.rb +5 -22
- data/remailer.gemspec +5 -5
- data/test/helper.rb +3 -4
- data/test/unit/remailer_connection_smtp_interpreter_test.rb +52 -3
- metadata +3 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.8
|
data/lib/remailer/connection.rb
CHANGED
@@ -41,10 +41,8 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
|
|
41
41
|
message_parts = message.split(/\s+/)
|
42
42
|
delegate.remote = message_parts.first
|
43
43
|
|
44
|
-
if (
|
44
|
+
if (message.match(/\bESMTP\b/))
|
45
45
|
delegate.protocol = :esmtp
|
46
|
-
else
|
47
|
-
delegate.protocol = :smtp
|
48
46
|
end
|
49
47
|
|
50
48
|
unless (continues)
|
@@ -317,4 +315,12 @@ class Remailer::Connection::SmtpInterpreter < Remailer::Interpreter
|
|
317
315
|
def label
|
318
316
|
'SMTP'
|
319
317
|
end
|
318
|
+
|
319
|
+
def will_interpret?(proc, args)
|
320
|
+
# Can only interpret blocks if the last part of the message has been
|
321
|
+
# received. The continue flag is argument index 1. This will only apply
|
322
|
+
# to interpret blocks that do not receive arguments.
|
323
|
+
|
324
|
+
(proc.arity == 0) ? !args[1] : true
|
325
|
+
end
|
320
326
|
end
|
@@ -90,9 +90,9 @@ class Remailer::Connection::Socks5Interpreter < Remailer::Interpreter
|
|
90
90
|
|
91
91
|
state :connect_through_proxy do
|
92
92
|
enter do
|
93
|
-
delegate.debug_notification(:proxy, "Sending proxy connection request to #{@destination_address.unpack('CCCC').join('.')}:#{delegate.options[:port]}")
|
94
|
-
|
95
93
|
if (@destination_address)
|
94
|
+
delegate.debug_notification(:proxy, "Sending proxy connection request to #{@destination_address.unpack('CCCC').join('.')}:#{delegate.options[:port]}")
|
95
|
+
|
96
96
|
delegate.send_data(
|
97
97
|
[
|
98
98
|
SOCKS5_VERSION,
|
data/lib/remailer/interpreter.rb
CHANGED
@@ -223,7 +223,7 @@ class Remailer::Interpreter
|
|
223
223
|
object = args[0]
|
224
224
|
config = self.class.states[@state]
|
225
225
|
interpreters = (config and config[:interpret])
|
226
|
-
|
226
|
+
|
227
227
|
if (interpreters)
|
228
228
|
match_result = nil
|
229
229
|
|
@@ -235,12 +235,12 @@ class Remailer::Interpreter
|
|
235
235
|
response === object
|
236
236
|
end
|
237
237
|
end
|
238
|
-
|
238
|
+
|
239
239
|
if (matched)
|
240
240
|
case (matched)
|
241
241
|
when Regexp
|
242
242
|
match_result = match_result.to_a
|
243
|
-
|
243
|
+
|
244
244
|
if (match_result.length > 1)
|
245
245
|
match_string = match_result.shift
|
246
246
|
args[0, 1] = match_result
|
@@ -252,8 +252,11 @@ class Remailer::Interpreter
|
|
252
252
|
else
|
253
253
|
args.shift
|
254
254
|
end
|
255
|
-
|
256
|
-
|
255
|
+
|
256
|
+
# Specifying a block with no arguments will mean that it waits until
|
257
|
+
# all pieces are collected before transitioning to a new state,
|
258
|
+
# waiting until the continue flag is false.
|
259
|
+
will_interpret?(proc, args) and instance_exec(*args, &proc)
|
257
260
|
|
258
261
|
return true
|
259
262
|
end
|
@@ -276,6 +279,13 @@ class Remailer::Interpreter
|
|
276
279
|
end
|
277
280
|
end
|
278
281
|
|
282
|
+
# This method is used by interpret to determine if the supplied block should
|
283
|
+
# be executed or not. The default behavior is to always execute but this
|
284
|
+
# can be modified in sub-classes.
|
285
|
+
def will_interpret?(proc, args)
|
286
|
+
true
|
287
|
+
end
|
288
|
+
|
279
289
|
# Returns true if an error has been generated, false otherwise. The error
|
280
290
|
# content can be retrived by calling error.
|
281
291
|
def error?
|
@@ -12,40 +12,23 @@ class Remailer::Interpreter::StateProxy
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def enter(&block)
|
15
|
-
@options[:enter] ||= [ ]
|
16
|
-
@options[:enter] << block
|
15
|
+
(@options[:enter] ||= [ ]) << block
|
17
16
|
end
|
18
17
|
|
19
18
|
def interpret(response, &block)
|
20
|
-
@options[:interpret] ||= [ ]
|
21
|
-
|
22
|
-
handler =
|
23
|
-
case (block.arity)
|
24
|
-
when 0
|
25
|
-
# Specifying a block with no arguments will mean that it waits until
|
26
|
-
# all pieces are collected before transitioning to a new state,
|
27
|
-
# waiting until the continue flag is false.
|
28
|
-
Proc.new { |m,c| instance_exec(&block) unless (c) }
|
29
|
-
else
|
30
|
-
block
|
31
|
-
end
|
32
|
-
|
33
|
-
@options[:interpret] << [ response, handler ]
|
19
|
+
(@options[:interpret] ||= [ ]) << [ response, block ]
|
34
20
|
end
|
35
21
|
|
36
22
|
def default(&block)
|
37
|
-
@options[:default] ||= [ ]
|
38
|
-
@options[:default] << block
|
23
|
+
(@options[:default] ||= [ ]) << block
|
39
24
|
end
|
40
25
|
|
41
26
|
def leave(&block)
|
42
|
-
@options[:leave] ||= [ ]
|
43
|
-
@options[:leave] << block
|
27
|
+
(@options[:leave] ||= [ ]) << block
|
44
28
|
end
|
45
29
|
|
46
30
|
def terminate(&block)
|
47
|
-
@options[:terminate] ||= [ ]
|
48
|
-
@options[:terminate] << block
|
31
|
+
(@options[:terminate] ||= [ ]) << block
|
49
32
|
end
|
50
33
|
|
51
34
|
protected
|
data/remailer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{remailer}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-05-
|
11
|
+
s.authors = [%q{Scott Tadman}]
|
12
|
+
s.date = %q{2011-05-15}
|
13
13
|
s.description = %q{EventMachine SMTP Mail User Agent}
|
14
14
|
s.email = %q{scott@twg.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -37,8 +37,8 @@ Gem::Specification.new do |s|
|
|
37
37
|
"test/unit/remailer_test.rb"
|
38
38
|
]
|
39
39
|
s.homepage = %q{http://github.com/twg/remailer}
|
40
|
-
s.require_paths = [
|
41
|
-
s.rubygems_version = %q{1.
|
40
|
+
s.require_paths = [%q{lib}]
|
41
|
+
s.rubygems_version = %q{1.8.2}
|
42
42
|
s.summary = %q{Reactor-Ready SMTP Mailer}
|
43
43
|
s.test_files = [
|
44
44
|
"test/config.example.rb",
|
data/test/helper.rb
CHANGED
@@ -8,11 +8,10 @@ require 'timeout'
|
|
8
8
|
require 'thwait'
|
9
9
|
require 'rubygems'
|
10
10
|
|
11
|
-
|
12
|
-
gem 'eventmachine'
|
11
|
+
begin
|
13
12
|
require 'eventmachine'
|
14
|
-
|
15
|
-
raise "EventMachine gem
|
13
|
+
rescue => e
|
14
|
+
raise "EventMachine gem could not be loaded: #{e.class}: #{e}"
|
16
15
|
end
|
17
16
|
|
18
17
|
require 'remailer'
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
|
2
2
|
|
3
3
|
class SmtpDelegate
|
4
|
-
attr_accessor :options, :active_message
|
4
|
+
attr_accessor :options, :protocol, :active_message
|
5
5
|
attr_accessor :tls_support
|
6
6
|
|
7
7
|
def initialize(options = { })
|
8
8
|
@sent = [ ]
|
9
9
|
@options = options
|
10
|
+
@protocol = :smtp
|
10
11
|
end
|
11
12
|
|
12
13
|
def hostname
|
@@ -251,6 +252,28 @@ class RemailerConnectionSmtpInterpreterTest < Test::Unit::TestCase
|
|
251
252
|
assert_equal :terminated, interpreter.state
|
252
253
|
assert_equal true, delegate.closed?
|
253
254
|
end
|
255
|
+
|
256
|
+
def test_multi_line_hello_response
|
257
|
+
delegate = SmtpDelegate.new(:use_tls => true)
|
258
|
+
interpreter = Remailer::Connection::SmtpInterpreter.new(:delegate => delegate)
|
259
|
+
|
260
|
+
assert_equal :initialized, interpreter.state
|
261
|
+
assert_equal :smtp, delegate.protocol
|
262
|
+
|
263
|
+
interpreter.process("220-mail.example.com Hello ESMTP Example Server\r\n")
|
264
|
+
assert_equal :initialized, interpreter.state
|
265
|
+
assert_equal :esmtp, delegate.protocol
|
266
|
+
|
267
|
+
interpreter.process("220-This is a long notice that is posted here\r\n")
|
268
|
+
assert_equal :initialized, interpreter.state
|
269
|
+
|
270
|
+
interpreter.process("220-as some servers like to have a little chat\r\n")
|
271
|
+
assert_equal :initialized, interpreter.state
|
272
|
+
|
273
|
+
interpreter.process("220 with you before getting down to business.\r\n")
|
274
|
+
|
275
|
+
assert_equal :ehlo, interpreter.state
|
276
|
+
end
|
254
277
|
|
255
278
|
def test_tls_connection_with_support
|
256
279
|
delegate = SmtpDelegate.new(:use_tls => true)
|
@@ -298,7 +321,33 @@ class RemailerConnectionSmtpInterpreterTest < Test::Unit::TestCase
|
|
298
321
|
assert_equal :ready, interpreter.state
|
299
322
|
end
|
300
323
|
|
301
|
-
def
|
324
|
+
def test_basic_smtp_plaintext_auth_accepted
|
325
|
+
delegate = SmtpDelegate.new(:username => 'tester@example.com', :password => 'tester')
|
326
|
+
interpreter = Remailer::Connection::SmtpInterpreter.new(:delegate => delegate)
|
327
|
+
|
328
|
+
assert delegate.requires_authentication?
|
329
|
+
|
330
|
+
assert_equal :initialized, interpreter.state
|
331
|
+
|
332
|
+
interpreter.process("220 mail.example.com SMTP Server 1.0\r\n")
|
333
|
+
assert_equal 'HELO localhost.local', delegate.read
|
334
|
+
|
335
|
+
assert_equal :helo, interpreter.state, interpreter.error
|
336
|
+
|
337
|
+
interpreter.process("250-mail.example.com Hello\r\n")
|
338
|
+
interpreter.process("250 HELP\r\n")
|
339
|
+
|
340
|
+
assert_equal false, delegate.started_tls?
|
341
|
+
|
342
|
+
assert_equal :auth, interpreter.state
|
343
|
+
assert_equal "AUTH PLAIN AHRlc3RlckBleGFtcGxlLmNvbQB0ZXN0ZXI=", delegate.read
|
344
|
+
|
345
|
+
interpreter.process("235 Accepted\r\n")
|
346
|
+
|
347
|
+
assert_equal :ready, interpreter.state
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_basic_esmtp_plaintext_auth_accepted
|
302
351
|
delegate = SmtpDelegate.new(:username => 'tester@example.com', :password => 'tester')
|
303
352
|
interpreter = Remailer::Connection::SmtpInterpreter.new(:delegate => delegate)
|
304
353
|
|
@@ -318,7 +367,7 @@ class RemailerConnectionSmtpInterpreterTest < Test::Unit::TestCase
|
|
318
367
|
assert_equal :ready, interpreter.state
|
319
368
|
end
|
320
369
|
|
321
|
-
def
|
370
|
+
def test_basic_esmtp_plaintext_auth_rejected
|
322
371
|
delegate = SmtpDelegate.new(:username => 'tester@example.com', :password => 'tester')
|
323
372
|
interpreter = Remailer::Connection::SmtpInterpreter.new(:delegate => delegate)
|
324
373
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: remailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.8
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Scott Tadman
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-05-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-05-15 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: eventmachine
|
@@ -52,7 +51,6 @@ files:
|
|
52
51
|
- test/unit/remailer_interpreter_state_proxy_test.rb
|
53
52
|
- test/unit/remailer_interpreter_test.rb
|
54
53
|
- test/unit/remailer_test.rb
|
55
|
-
has_rdoc: true
|
56
54
|
homepage: http://github.com/twg/remailer
|
57
55
|
licenses: []
|
58
56
|
|
@@ -76,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
74
|
requirements: []
|
77
75
|
|
78
76
|
rubyforge_project:
|
79
|
-
rubygems_version: 1.
|
77
|
+
rubygems_version: 1.8.2
|
80
78
|
signing_key:
|
81
79
|
specification_version: 3
|
82
80
|
summary: Reactor-Ready SMTP Mailer
|