remailer 0.4.6 → 0.4.8
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/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
|