remailer 0.7.1.2 → 0.9.1
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 +5 -5
- data/Gemfile +1 -1
- data/LICENSE.txt +19 -0
- data/README.md +1 -1
- data/Rakefile +13 -8
- data/VERSION +1 -1
- data/lib/remailer/abstract_connection.rb +19 -11
- data/lib/remailer/interpreter.rb +7 -5
- data/lib/remailer/smtp/client.rb +2 -0
- data/lib/remailer/smtp/client/interpreter.rb +85 -12
- data/lib/remailer/smtp/server.rb +9 -4
- data/lib/remailer/smtp/server/interpreter.rb +14 -13
- data/lib/remailer/smtp/server/transaction.rb +9 -2
- data/lib/remailer/socks5/client/interpreter.rb +2 -2
- data/remailer.gemspec +26 -31
- data/test/helper.rb +2 -5
- data/test/unit/remailer_imap_client_test.rb +3 -3
- data/test/unit/remailer_interpreter_test.rb +5 -5
- data/test/unit/remailer_smtp_client_interpreter_test.rb +65 -18
- data/test/unit/remailer_smtp_client_test.rb +4 -9
- data/test/unit/remailer_smtp_server_test.rb +6 -6
- data/test/unit/remailer_socks5_client_interpreter_test.rb +1 -0
- metadata +12 -13
- data/.travis.yml +0 -10
- data/test/config.yml.enc +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c66f7fc5cd78fcb8115342274f77169e4658cfb575d6b2609d2ae07bbd7278a0
|
4
|
+
data.tar.gz: 277347ffde8646bb32f6dc01cddca71be940c21fc46f5cfe32ecb4d02c849065
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6352a8dddf0f8cf1cd16cb810af0993a7bbd3386fe0ccc28c20fc9d891a9a9d4ae69e98b106f6d3a31933620364bb88f77217c2db1103400607333e9f5bcec71
|
7
|
+
data.tar.gz: 3b935c992a65b812b268cd616353886b104ba7c3cb97009c6234bae1e57d685d381c466219dd357542d6a424ddfe643f9648a8a644797f35806170e166cdfdd8
|
data/Gemfile
CHANGED
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2010-2019 Scott Tadman, PostageApp Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -6,21 +6,26 @@ require 'bundler/setup'
|
|
6
6
|
Bundler.require
|
7
7
|
|
8
8
|
begin
|
9
|
-
require '
|
9
|
+
require 'juwelier'
|
10
10
|
|
11
|
-
|
11
|
+
Juwelier::Tasks.new do |gem|
|
12
12
|
gem.name = "remailer"
|
13
13
|
gem.summary = %Q{Reactor-Ready SMTP Mailer}
|
14
|
-
gem.description = %Q{EventMachine SMTP
|
15
|
-
gem.email = "
|
16
|
-
gem.homepage = "http://github.com/
|
14
|
+
gem.description = %Q{EventMachine Mail Agent for SMTP and IMAP}
|
15
|
+
gem.email = "tadman@postageapp.com"
|
16
|
+
gem.homepage = "http://github.com/postageapp/remailer"
|
17
17
|
gem.authors = [ "Scott Tadman" ]
|
18
|
+
|
19
|
+
gem.files.exclude(
|
20
|
+
'.travis.yml',
|
21
|
+
'test/config.yml.enc'
|
22
|
+
)
|
18
23
|
end
|
19
24
|
|
20
|
-
|
25
|
+
Juwelier::GemcutterTasks.new
|
21
26
|
|
22
27
|
rescue LoadError
|
23
|
-
puts "
|
28
|
+
puts "Juwelier (or a dependency) not available. Install it with: gem install Juwelier"
|
24
29
|
end
|
25
30
|
|
26
31
|
require 'rake/testtask'
|
@@ -31,4 +36,4 @@ Rake::TestTask.new(:test) do |test|
|
|
31
36
|
test.verbose = true
|
32
37
|
end
|
33
38
|
|
34
|
-
task :
|
39
|
+
task default: :test
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.1
|
@@ -133,6 +133,14 @@ class Remailer::AbstractConnection < EventMachine::Connection
|
|
133
133
|
@options = options
|
134
134
|
@hostname = @options[:hostname] || Socket.gethostname
|
135
135
|
@timeout = @options[:timeout] || self.class.default_timeout
|
136
|
+
@timed_out = false
|
137
|
+
|
138
|
+
@active_message = nil
|
139
|
+
@established = false
|
140
|
+
@connected = false
|
141
|
+
@closed = false
|
142
|
+
@unbound = false
|
143
|
+
@connecting_to_proxy = false
|
136
144
|
|
137
145
|
@messages = [ ]
|
138
146
|
|
@@ -156,9 +164,9 @@ class Remailer::AbstractConnection < EventMachine::Connection
|
|
156
164
|
STDERR.puts "#{e.class}: #{e}" rescue nil
|
157
165
|
end
|
158
166
|
|
159
|
-
def after_complete
|
167
|
+
def after_complete(&block)
|
160
168
|
if (block_given?)
|
161
|
-
@options[:after_complete] =
|
169
|
+
@options[:after_complete] = block
|
162
170
|
elsif (@options[:after_complete])
|
163
171
|
@options[:after_complete].call
|
164
172
|
end
|
@@ -176,9 +184,15 @@ class Remailer::AbstractConnection < EventMachine::Connection
|
|
176
184
|
end
|
177
185
|
|
178
186
|
# Returns true if the connection has advertised authentication support, or
|
179
|
-
# false if not availble or could not be detected.
|
180
|
-
|
181
|
-
|
187
|
+
# false if not availble or could not be detected. If type is specified,
|
188
|
+
# returns true only if that type is supported, false otherwise.
|
189
|
+
def auth_support?(type = nil)
|
190
|
+
case (type)
|
191
|
+
when nil
|
192
|
+
!!@auth_support
|
193
|
+
else
|
194
|
+
!!(@auth_support&.include?(type))
|
195
|
+
end
|
182
196
|
end
|
183
197
|
|
184
198
|
# Returns true if the connection will be using a proxy to connect, false
|
@@ -381,12 +395,6 @@ class Remailer::AbstractConnection < EventMachine::Connection
|
|
381
395
|
def error?
|
382
396
|
!!@error
|
383
397
|
end
|
384
|
-
|
385
|
-
# EventMachine: Enables TLS support on the connection.
|
386
|
-
def start_tls
|
387
|
-
debug_notification(:tls, "Started")
|
388
|
-
super
|
389
|
-
end
|
390
398
|
|
391
399
|
# EventMachine: Closes down the connection.
|
392
400
|
def close_connection
|
data/lib/remailer/interpreter.rb
CHANGED
@@ -19,7 +19,7 @@ class Remailer::Interpreter
|
|
19
19
|
|
20
20
|
# Defines the initial state for objects of this class.
|
21
21
|
def self.initial_state
|
22
|
-
@initial_state
|
22
|
+
@initial_state ||= :initialized
|
23
23
|
end
|
24
24
|
|
25
25
|
# Can be used to reassign the initial state for this class. May be easier
|
@@ -82,15 +82,15 @@ class Remailer::Interpreter
|
|
82
82
|
end
|
83
83
|
|
84
84
|
# This is a method to convert a spec and a block into a proper parser
|
85
|
-
# method. If spec is specified, it should be a
|
86
|
-
#
|
85
|
+
# method. If spec is specified, it should be a Integer, or a Regexp. A
|
86
|
+
# Integer defines a minimum size to process, useful for packed binary
|
87
87
|
# streams, while a Regexp defines a pattern that must match before the
|
88
88
|
# parser is engaged.
|
89
89
|
def self.create_parser_for_spec(spec, &block)
|
90
90
|
case (spec)
|
91
91
|
when nil
|
92
92
|
block
|
93
|
-
when
|
93
|
+
when Integer
|
94
94
|
lambda do |s|
|
95
95
|
if (s.length >= spec)
|
96
96
|
part = s.slice!(0, spec)
|
@@ -168,6 +168,8 @@ class Remailer::Interpreter
|
|
168
168
|
# before the first state is entered.
|
169
169
|
def initialize(options = nil)
|
170
170
|
@delegate = (options and options[:delegate])
|
171
|
+
@state = nil
|
172
|
+
@error = nil
|
171
173
|
|
172
174
|
yield(self) if (block_given?)
|
173
175
|
|
@@ -258,7 +260,7 @@ class Remailer::Interpreter
|
|
258
260
|
match_result = match_result.to_a
|
259
261
|
|
260
262
|
if (match_result.length > 1)
|
261
|
-
|
263
|
+
match_result.shift
|
262
264
|
args[0, 1] = match_result
|
263
265
|
else
|
264
266
|
args[0].sub!(match_result[0], '')
|
data/lib/remailer/smtp/client.rb
CHANGED
@@ -60,6 +60,8 @@ class Remailer::SMTP::Client < Remailer::AbstractConnection
|
|
60
60
|
# Called by AbstractConnection at the end of the initialize procedure
|
61
61
|
def after_initialize
|
62
62
|
@protocol = :smtp
|
63
|
+
@error = nil
|
64
|
+
@tls_support = nil
|
63
65
|
|
64
66
|
if (using_proxy?)
|
65
67
|
proxy_connection_initiated!
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'set'
|
3
|
+
|
1
4
|
class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
2
5
|
# == Constants ============================================================
|
3
6
|
|
@@ -22,7 +25,7 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
22
25
|
# Encodes the given data for an RFC5321-compliant stream where lines with
|
23
26
|
# leading period chracters are escaped.
|
24
27
|
def self.encode_data(data)
|
25
|
-
data.gsub(
|
28
|
+
data.gsub(/\r?\n/, "\r\n").gsub(/\r\n\./, "\r\n..")
|
26
29
|
end
|
27
30
|
|
28
31
|
# Encodes a string in Base64 as a single line
|
@@ -37,6 +40,10 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
37
40
|
end
|
38
41
|
|
39
42
|
state :initialized do
|
43
|
+
enter do
|
44
|
+
@tls = false
|
45
|
+
end
|
46
|
+
|
40
47
|
interpret(220) do |message, continues|
|
41
48
|
message_parts = message.split(/\s+/)
|
42
49
|
delegate.remote = message_parts.first
|
@@ -68,6 +75,8 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
68
75
|
state :helo do
|
69
76
|
enter do
|
70
77
|
delegate.send_line("HELO #{delegate.hostname}")
|
78
|
+
|
79
|
+
delegate.auth_support = Set.new(%i[ plain ])
|
71
80
|
end
|
72
81
|
|
73
82
|
interpret(250) do
|
@@ -85,20 +94,17 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
85
94
|
end
|
86
95
|
|
87
96
|
interpret(250) do |message, continues|
|
88
|
-
message_parts = message.split(/\s+/)
|
97
|
+
directive, *message_parts = message.split(/\s+/)
|
89
98
|
|
90
|
-
case (
|
99
|
+
case (directive.to_s.upcase)
|
91
100
|
when 'SIZE'
|
92
|
-
delegate.max_size = message_parts[
|
101
|
+
delegate.max_size = message_parts[0].to_i
|
93
102
|
when 'PIPELINING'
|
94
103
|
delegate.pipelining = true
|
95
104
|
when 'STARTTLS'
|
96
105
|
delegate.tls_support = true
|
97
106
|
when 'AUTH'
|
98
|
-
delegate.auth_support = message_parts
|
99
|
-
h[v] = true
|
100
|
-
h
|
101
|
-
end
|
107
|
+
delegate.auth_support = Set.new(message_parts.map(&:downcase).map(&:to_sym))
|
102
108
|
end
|
103
109
|
|
104
110
|
unless (continues)
|
@@ -140,7 +146,19 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
140
146
|
|
141
147
|
state :auth do
|
142
148
|
enter do
|
143
|
-
|
149
|
+
if (delegate.auth_support?(:plain))
|
150
|
+
delegate.send_line(
|
151
|
+
'AUTH PLAIN %s' % [
|
152
|
+
self.class.encode_authentication(
|
153
|
+
delegate.options[:username],
|
154
|
+
delegate.options[:password]
|
155
|
+
)
|
156
|
+
]
|
157
|
+
)
|
158
|
+
elsif (delegate.auth_support&.include?(:login))
|
159
|
+
delegate.send_line('AUTH LOGIN')
|
160
|
+
enter_state(:auth_username)
|
161
|
+
end
|
144
162
|
end
|
145
163
|
|
146
164
|
interpret(235) do
|
@@ -158,7 +176,62 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
158
176
|
end
|
159
177
|
end
|
160
178
|
end
|
161
|
-
|
179
|
+
|
180
|
+
state :auth_username do
|
181
|
+
interpret(334) do
|
182
|
+
delegate.send_line(Base64.strict_encode64(delegate.options[:username]))
|
183
|
+
|
184
|
+
enter_state(:auth_password)
|
185
|
+
end
|
186
|
+
|
187
|
+
interpret(535) do |reply_message, continues|
|
188
|
+
handle_reply_continuation(535, reply_message, continues) do |reply_code, reply_message|
|
189
|
+
@error = reply_message
|
190
|
+
|
191
|
+
delegate.debug_notification(:error, "[#{@state}] #{reply_code} #{reply_message}")
|
192
|
+
delegate.error_notification(reply_code, reply_message)
|
193
|
+
|
194
|
+
enter_state(:quit)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
state :auth_password do
|
200
|
+
interpret(334) do
|
201
|
+
delegate.send_line(Base64.strict_encode64(delegate.options[:password]))
|
202
|
+
|
203
|
+
enter_state(:auth_acknowledge)
|
204
|
+
end
|
205
|
+
|
206
|
+
interpret(535) do |reply_message, continues|
|
207
|
+
handle_reply_continuation(535, reply_message, continues) do |reply_code, reply_message|
|
208
|
+
@error = reply_message
|
209
|
+
|
210
|
+
delegate.debug_notification(:error, "[#{@state}] #{reply_code} #{reply_message}")
|
211
|
+
delegate.error_notification(reply_code, reply_message)
|
212
|
+
|
213
|
+
enter_state(:quit)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
state :auth_acknowledge do
|
219
|
+
interpret(235) do
|
220
|
+
enter_state(:established)
|
221
|
+
end
|
222
|
+
|
223
|
+
interpret(535) do |reply_message, continues|
|
224
|
+
handle_reply_continuation(535, reply_message, continues) do |reply_code, reply_message|
|
225
|
+
@error = reply_message
|
226
|
+
|
227
|
+
delegate.debug_notification(:error, "[#{@state}] #{reply_code} #{reply_message}")
|
228
|
+
delegate.error_notification(reply_code, reply_message)
|
229
|
+
|
230
|
+
enter_state(:quit)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
162
235
|
state :established do
|
163
236
|
enter do
|
164
237
|
delegate.connect_notification(true)
|
@@ -251,7 +324,7 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
251
324
|
end
|
252
325
|
end
|
253
326
|
|
254
|
-
interpret(
|
327
|
+
interpret(400..599) do |reply_code, reply_message, continues|
|
255
328
|
handle_reply_continuation(reply_code, reply_message, continues) do |reply_code, reply_message|
|
256
329
|
delegate_call(:after_message_sent, reply_code, reply_message)
|
257
330
|
|
@@ -281,7 +354,7 @@ class Remailer::SMTP::Client::Interpreter < Remailer::Interpreter
|
|
281
354
|
# Ensure that a blank line is sent after the last bit of email content
|
282
355
|
# to ensure that the dot is on its own line.
|
283
356
|
delegate.send_line
|
284
|
-
delegate.send_line(
|
357
|
+
delegate.send_line('.')
|
285
358
|
end
|
286
359
|
|
287
360
|
default do |reply_code, reply_message, continues|
|
data/lib/remailer/smtp/server.rb
CHANGED
@@ -19,7 +19,7 @@ class Remailer::SMTP::Server < EventMachine::Protocols::LineAndTextProtocol
|
|
19
19
|
|
20
20
|
attr_accessor :logger
|
21
21
|
attr_reader :server_name, :quirks
|
22
|
-
attr_reader :remote_ip, :remote_port
|
22
|
+
attr_reader :remote_ip, :remote_port, :remote_name
|
23
23
|
attr_reader :local_ip, :local_port
|
24
24
|
attr_reader :local_config
|
25
25
|
|
@@ -60,6 +60,11 @@ class Remailer::SMTP::Server < EventMachine::Protocols::LineAndTextProtocol
|
|
60
60
|
|
61
61
|
@server_name = @options[:server_name] || self.class.hostname(@local_ip) || @local_ip
|
62
62
|
|
63
|
+
@logger = nil
|
64
|
+
@remote_host = nil
|
65
|
+
@tls_support = false
|
66
|
+
@interpreter_class = options && options[:interpreter] || Interpreter
|
67
|
+
|
63
68
|
log(:debug, "Connection from #{@remote_ip}:#{@remote_port} to #{@local_ip}:#{@local_port}")
|
64
69
|
|
65
70
|
@on_transaction = @options[:on_transaction]
|
@@ -69,15 +74,15 @@ class Remailer::SMTP::Server < EventMachine::Protocols::LineAndTextProtocol
|
|
69
74
|
def post_init
|
70
75
|
super
|
71
76
|
|
72
|
-
@interpreter =
|
77
|
+
@interpreter = @interpreter_class.new(delegate: self)
|
73
78
|
|
74
79
|
if (@on_connect)
|
75
80
|
@on_connect.call(@remote_ip)
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
79
|
-
def on_transaction
|
80
|
-
@on_transaction =
|
84
|
+
def on_transaction(&block)
|
85
|
+
@on_transaction = block
|
81
86
|
end
|
82
87
|
|
83
88
|
def receive_line(line)
|
@@ -40,7 +40,7 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
interpret(/^\s*HELO\s+(\S+)\s*$/) do |remote_host|
|
43
|
+
interpret(/^\s*HELO\s+(\S+)\s*$/i) do |remote_host|
|
44
44
|
delegate.validate_hostname(remote_host) do |valid|
|
45
45
|
if (valid)
|
46
46
|
delegate.log(:debug, "#{delegate.remote_ip}:#{delegate.remote_port} to #{delegate.local_ip}:#{delegate.local_port} Accepting connection from #{remote_host}")
|
@@ -54,7 +54,7 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
interpret(/^\s*MAIL\s+FROM:\s*<([^>]+)>\s*/) do |address|
|
57
|
+
interpret(/^\s*MAIL\s+FROM:\s*<([^>]+)>\s*/i) do |address|
|
58
58
|
if (Remailer::EmailAddress.valid?(address))
|
59
59
|
accept, message = will_accept_sender(address)
|
60
60
|
|
@@ -68,7 +68,7 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
interpret(/^\s*RCPT\s+TO:\s*<([^>]+)>\s*/) do |address|
|
71
|
+
interpret(/^\s*RCPT\s+TO:\s*<([^>]+)>\s*/i) do |address|
|
72
72
|
if (@transaction.sender)
|
73
73
|
if (Remailer::EmailAddress.valid?(address))
|
74
74
|
accept, message = will_accept_recipient(address)
|
@@ -87,17 +87,17 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
interpret(/^\s*AUTH\s+PLAIN\s+(.*)\s*$/) do |auth|
|
90
|
+
interpret(/^\s*AUTH\s+PLAIN\s+(.*)\s*$/i) do |auth|
|
91
91
|
# 235 2.7.0 Authentication successful
|
92
|
-
delegate.send("235
|
92
|
+
delegate.send("235 If you insist")
|
93
93
|
end
|
94
94
|
|
95
|
-
interpret(/^\s*AUTH\s+PLAIN\s*$/) do
|
95
|
+
interpret(/^\s*AUTH\s+PLAIN\s*$/i) do
|
96
96
|
# Multi-line authentication method
|
97
97
|
enter_state(:auth_plain)
|
98
98
|
end
|
99
99
|
|
100
|
-
interpret(/^\s*STARTTLS\s*$/) do
|
100
|
+
interpret(/^\s*STARTTLS\s*$/i) do
|
101
101
|
if (@tls_started)
|
102
102
|
delegate.send_line("454 TLS already started")
|
103
103
|
elsif (delegate.tls?)
|
@@ -113,27 +113,27 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
interpret(/^\s*DATA\s*$/) do
|
116
|
+
interpret(/^\s*DATA\s*$/i) do
|
117
117
|
if (@transaction.sender)
|
118
118
|
else
|
119
|
-
delegate.send_line("503
|
119
|
+
delegate.send_line("503 Valid RCPT command must precede DATA")
|
120
120
|
end
|
121
121
|
|
122
122
|
enter_state(:data)
|
123
123
|
delegate.send_line("354 Supply message data")
|
124
124
|
end
|
125
125
|
|
126
|
-
interpret(/^\s*NOOP\s*$/) do |remote_host|
|
126
|
+
interpret(/^\s*NOOP\s*$/i) do |remote_host|
|
127
127
|
delegate.send_line("250 OK")
|
128
128
|
end
|
129
129
|
|
130
|
-
interpret(/^\s*RSET\s*$/) do |remote_host|
|
130
|
+
interpret(/^\s*RSET\s*$/i) do |remote_host|
|
131
131
|
delegate.send_line("250 Reset OK")
|
132
132
|
|
133
133
|
enter_state(:reset)
|
134
134
|
end
|
135
135
|
|
136
|
-
interpret(/^\s*QUIT\s*$/) do
|
136
|
+
interpret(/^\s*QUIT\s*$/i) do
|
137
137
|
delegate.send_line("221 #{delegate.server_name} closing connection")
|
138
138
|
|
139
139
|
delegate.close_connection(true)
|
@@ -142,6 +142,8 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
142
142
|
|
143
143
|
state :data do
|
144
144
|
interpret(/^\.$/) do
|
145
|
+
@transaction.remote_ip = delegate.remote_ip
|
146
|
+
|
145
147
|
accept, message = will_accept_transaction(@transaction)
|
146
148
|
|
147
149
|
if (accept)
|
@@ -159,7 +161,6 @@ class Remailer::SMTP::Server::Interpreter < Remailer::Interpreter
|
|
159
161
|
|
160
162
|
default do |line|
|
161
163
|
# RFC5321 4.5.2 - Leading dot is removed if line has content
|
162
|
-
|
163
164
|
@transaction.data << (line.sub(/^\./, '') << Remailer::Constants::CRLF)
|
164
165
|
end
|
165
166
|
end
|
@@ -1,11 +1,18 @@
|
|
1
1
|
class Remailer::SMTP::Server::Transaction
|
2
2
|
# == Constants ============================================================
|
3
3
|
|
4
|
-
ATTRIBUTES = [
|
4
|
+
ATTRIBUTES = [
|
5
|
+
:sender,
|
6
|
+
:remote_ip,
|
7
|
+
:remote_name,
|
8
|
+
:auth,
|
9
|
+
:recipients,
|
10
|
+
:data
|
11
|
+
].freeze
|
5
12
|
|
6
13
|
# == Properties ===========================================================
|
7
14
|
|
8
|
-
attr_accessor
|
15
|
+
attr_accessor(*ATTRIBUTES)
|
9
16
|
|
10
17
|
# == Class Methods ========================================================
|
11
18
|
|
@@ -60,7 +60,7 @@ class Remailer::SOCKS5::Client::Interpreter < Remailer::Interpreter
|
|
60
60
|
|
61
61
|
parse do |s|
|
62
62
|
if (s.length >= 2)
|
63
|
-
|
63
|
+
_version, method = s.slice!(0,2).unpack('CC')
|
64
64
|
|
65
65
|
method
|
66
66
|
end
|
@@ -109,7 +109,7 @@ class Remailer::SOCKS5::Client::Interpreter < Remailer::Interpreter
|
|
109
109
|
|
110
110
|
parse do |s|
|
111
111
|
if (s.length >= 10)
|
112
|
-
|
112
|
+
_version, reply, _reserved, address_type, address, port = s.slice!(0,10).unpack('CCCCNn')
|
113
113
|
|
114
114
|
[
|
115
115
|
reply,
|
data/remailer.gemspec
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
# Generated by
|
1
|
+
# Generated by juwelier
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit
|
3
|
+
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: remailer 0.
|
5
|
+
# stub: remailer 0.9.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
|
-
s.name = "remailer"
|
9
|
-
s.version = "0.
|
8
|
+
s.name = "remailer".freeze
|
9
|
+
s.version = "0.9.1"
|
10
10
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.require_paths = ["lib"]
|
13
|
-
s.authors = ["Scott Tadman"]
|
14
|
-
s.date = "
|
15
|
-
s.description = "EventMachine SMTP
|
16
|
-
s.email = "
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Scott Tadman".freeze]
|
14
|
+
s.date = "2020-09-22"
|
15
|
+
s.description = "EventMachine Mail Agent for SMTP and IMAP".freeze
|
16
|
+
s.email = "tadman@postageapp.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
18
19
|
"README.md"
|
19
20
|
]
|
20
21
|
s.files = [
|
21
22
|
".document",
|
22
|
-
".travis.yml",
|
23
23
|
"Gemfile",
|
24
|
+
"LICENSE.txt",
|
24
25
|
"README.md",
|
25
26
|
"Rakefile",
|
26
27
|
"VERSION",
|
@@ -49,7 +50,6 @@ Gem::Specification.new do |s|
|
|
49
50
|
"test/bin/exercise",
|
50
51
|
"test/config.example.yml",
|
51
52
|
"test/config.rb",
|
52
|
-
"test/config.yml.enc",
|
53
53
|
"test/helper.rb",
|
54
54
|
"test/unit/remailer_imap_client_interpreter_test.rb",
|
55
55
|
"test/unit/remailer_imap_client_test.rb",
|
@@ -61,29 +61,24 @@ Gem::Specification.new do |s|
|
|
61
61
|
"test/unit/remailer_socks5_client_interpreter_test.rb",
|
62
62
|
"test/unit/remailer_test.rb"
|
63
63
|
]
|
64
|
-
s.homepage = "http://github.com/
|
65
|
-
s.rubygems_version = "
|
66
|
-
s.summary = "Reactor-Ready SMTP Mailer"
|
64
|
+
s.homepage = "http://github.com/postageapp/remailer".freeze
|
65
|
+
s.rubygems_version = "3.1.4".freeze
|
66
|
+
s.summary = "Reactor-Ready SMTP Mailer".freeze
|
67
67
|
|
68
68
|
if s.respond_to? :specification_version then
|
69
69
|
s.specification_version = 4
|
70
|
+
end
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
else
|
77
|
-
s.add_dependency(%q<eventmachine>, [">= 0"])
|
78
|
-
s.add_dependency(%q<minitest>, [">= 0"])
|
79
|
-
s.add_dependency(%q<minitest-reporters>, [">= 0"])
|
80
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
81
|
-
end
|
72
|
+
if s.respond_to? :add_runtime_dependency then
|
73
|
+
s.add_runtime_dependency(%q<eventmachine>.freeze, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<minitest>.freeze, [">= 0"])
|
75
|
+
s.add_development_dependency(%q<minitest-reporters>.freeze, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
|
82
77
|
else
|
83
|
-
s.add_dependency(%q<eventmachine
|
84
|
-
s.add_dependency(%q<minitest
|
85
|
-
s.add_dependency(%q<minitest-reporters
|
86
|
-
s.add_dependency(%q<
|
78
|
+
s.add_dependency(%q<eventmachine>.freeze, [">= 0"])
|
79
|
+
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
80
|
+
s.add_dependency(%q<minitest-reporters>.freeze, [">= 0"])
|
81
|
+
s.add_dependency(%q<juwelier>.freeze, [">= 0"])
|
87
82
|
end
|
88
83
|
end
|
89
84
|
|
data/test/helper.rb
CHANGED
@@ -10,7 +10,6 @@ $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
|
10
10
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
11
11
|
|
12
12
|
require 'timeout'
|
13
|
-
require 'thwait'
|
14
13
|
require 'rubygems'
|
15
14
|
|
16
15
|
begin
|
@@ -41,8 +40,6 @@ end
|
|
41
40
|
module TestTriggerHelper
|
42
41
|
def self.included(base)
|
43
42
|
base.class_eval do
|
44
|
-
attr_reader :triggered
|
45
|
-
|
46
43
|
def triggered
|
47
44
|
@triggered ||= Hash.new(false)
|
48
45
|
end
|
@@ -138,12 +135,12 @@ class MiniTest::Test
|
|
138
135
|
end
|
139
136
|
|
140
137
|
def assert_mapping(map, &block)
|
141
|
-
result_map = map.inject({ }) do |h, (k,
|
138
|
+
result_map = map.inject({ }) do |h, (k, _v)|
|
142
139
|
h[k] = yield(k)
|
143
140
|
h
|
144
141
|
end
|
145
142
|
|
146
|
-
differences = result_map.inject([ ]) do |a, (k,v)|
|
143
|
+
differences = result_map.inject([ ]) do |a, (k, v)|
|
147
144
|
if (v != map[k])
|
148
145
|
a << k
|
149
146
|
end
|
@@ -3,14 +3,14 @@ require_relative '../helper'
|
|
3
3
|
class RemailerIMAPClientTest < MiniTest::Test
|
4
4
|
def test_connect
|
5
5
|
skip
|
6
|
+
|
7
|
+
debug = { }
|
6
8
|
|
7
9
|
engine do
|
8
|
-
debug = { }
|
9
|
-
|
10
10
|
client = Remailer::IMAP::Client.open(
|
11
11
|
TestConfig.options[:imap_server][:host],
|
12
12
|
debug: self.debug_channel,
|
13
|
-
connect: lambda { |
|
13
|
+
connect: lambda { |_success, host| debug[:connected_host] = host }
|
14
14
|
)
|
15
15
|
|
16
16
|
assert client
|
@@ -138,7 +138,7 @@ class RemailerInterpreterTest < MiniTest::Test
|
|
138
138
|
|
139
139
|
interpreter = test_interpreter_class.new(delegate: delegate)
|
140
140
|
|
141
|
-
|
141
|
+
assert_nil delegate.attribute
|
142
142
|
assert_equal false, delegate.triggered[:method_no_args]
|
143
143
|
assert_equal false, delegate.triggered[:method_with_args]
|
144
144
|
|
@@ -236,7 +236,7 @@ class RemailerInterpreterTest < MiniTest::Test
|
|
236
236
|
|
237
237
|
interpreter.process(line)
|
238
238
|
|
239
|
-
|
239
|
+
assert_nil interpreter.lines[-1]
|
240
240
|
assert_equal "TEST", line
|
241
241
|
|
242
242
|
line << "\0"
|
@@ -250,7 +250,7 @@ class RemailerInterpreterTest < MiniTest::Test
|
|
250
250
|
def test_regexp_interpreter
|
251
251
|
interpreter = RegexpInterpreter.new
|
252
252
|
|
253
|
-
|
253
|
+
assert_nil interpreter.received
|
254
254
|
|
255
255
|
line = "HELO example.com"
|
256
256
|
|
@@ -277,7 +277,7 @@ class RemailerInterpreterTest < MiniTest::Test
|
|
277
277
|
assert_equal true, interpreter.interpret(:random)
|
278
278
|
|
279
279
|
assert_equal :branch, interpreter.state
|
280
|
-
|
280
|
+
assert_nil interpreter.error
|
281
281
|
|
282
282
|
assert_equal :random, interpreter.reply
|
283
283
|
end
|
@@ -299,7 +299,7 @@ class RemailerInterpreterTest < MiniTest::Test
|
|
299
299
|
def test_new_with_block
|
300
300
|
interpreter = InterpreterWithAccessor.new
|
301
301
|
|
302
|
-
|
302
|
+
assert_nil interpreter.example
|
303
303
|
|
304
304
|
interpreter = InterpreterWithAccessor.new do |interpreter|
|
305
305
|
interpreter.example = 'example'
|
@@ -1,13 +1,16 @@
|
|
1
1
|
require_relative '../helper'
|
2
2
|
|
3
|
-
class
|
4
|
-
attr_accessor :options, :protocol, :active_message
|
3
|
+
class TestSMTPDelegate
|
4
|
+
attr_accessor :options, :protocol, :active_message, :auth_support
|
5
5
|
attr_accessor :tls_support
|
6
6
|
|
7
7
|
def initialize(options = { })
|
8
8
|
@sent = [ ]
|
9
9
|
@options = options
|
10
10
|
@protocol = :smtp
|
11
|
+
@started_tls = false
|
12
|
+
@tls_support = nil
|
13
|
+
@closed = false
|
11
14
|
end
|
12
15
|
|
13
16
|
def hostname
|
@@ -57,6 +60,15 @@ class SMTPDelegate
|
|
57
60
|
def read
|
58
61
|
@sent.shift
|
59
62
|
end
|
63
|
+
|
64
|
+
def auth_support?(type = nil)
|
65
|
+
case (type)
|
66
|
+
when nil
|
67
|
+
!!@auth_support
|
68
|
+
else
|
69
|
+
!!(@auth_support&.include?(type))
|
70
|
+
end
|
71
|
+
end
|
60
72
|
|
61
73
|
def method_missing(*args)
|
62
74
|
end
|
@@ -119,27 +131,27 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
119
131
|
end
|
120
132
|
|
121
133
|
def test_delegate_default_state
|
122
|
-
delegate =
|
134
|
+
delegate = TestSMTPDelegate.new
|
123
135
|
|
124
136
|
assert_equal false, delegate.closed?
|
125
|
-
|
137
|
+
assert_nil delegate.read
|
126
138
|
assert_equal 0, delegate.size
|
127
139
|
end
|
128
140
|
|
129
141
|
def test_delegate_options
|
130
|
-
delegate =
|
142
|
+
delegate = TestSMTPDelegate.new(use_tls: true)
|
131
143
|
|
132
144
|
assert_equal true, delegate.use_tls?
|
133
145
|
assert_equal false, delegate.requires_authentication?
|
134
146
|
|
135
|
-
delegate =
|
147
|
+
delegate = TestSMTPDelegate.new(username: 'test@example.com', password: 'tester')
|
136
148
|
|
137
149
|
assert_equal false, delegate.use_tls?
|
138
150
|
assert_equal true, delegate.requires_authentication?
|
139
151
|
end
|
140
152
|
|
141
153
|
def test_standard_smtp_connection
|
142
|
-
delegate =
|
154
|
+
delegate = TestSMTPDelegate.new
|
143
155
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
144
156
|
|
145
157
|
assert_equal :initialized, interpreter.state
|
@@ -162,7 +174,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
162
174
|
end
|
163
175
|
|
164
176
|
def test_standard_smtp_connection_send_email
|
165
|
-
delegate =
|
177
|
+
delegate = TestSMTPDelegate.new
|
166
178
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
167
179
|
|
168
180
|
assert_equal :initialized, interpreter.state
|
@@ -217,7 +229,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
217
229
|
end
|
218
230
|
|
219
231
|
def test_standard_esmtp_connection
|
220
|
-
delegate =
|
232
|
+
delegate = TestSMTPDelegate.new
|
221
233
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
222
234
|
|
223
235
|
assert_equal :initialized, interpreter.state
|
@@ -254,7 +266,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
254
266
|
end
|
255
267
|
|
256
268
|
def test_multi_line_hello_response
|
257
|
-
delegate =
|
269
|
+
delegate = TestSMTPDelegate.new(use_tls: true)
|
258
270
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
259
271
|
|
260
272
|
assert_equal :initialized, interpreter.state
|
@@ -276,7 +288,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
276
288
|
end
|
277
289
|
|
278
290
|
def test_tls_connection_with_support
|
279
|
-
delegate =
|
291
|
+
delegate = TestSMTPDelegate.new(use_tls: true)
|
280
292
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
281
293
|
|
282
294
|
assert_equal true, delegate.use_tls?
|
@@ -307,7 +319,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
307
319
|
end
|
308
320
|
|
309
321
|
def test_tls_connection_without_support
|
310
|
-
delegate =
|
322
|
+
delegate = TestSMTPDelegate.new(use_tls: true)
|
311
323
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
312
324
|
|
313
325
|
interpreter.process("220 mail.example.com ESMTP Exim 4.63\r\n")
|
@@ -322,7 +334,7 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
322
334
|
end
|
323
335
|
|
324
336
|
def test_basic_smtp_plaintext_auth_accepted
|
325
|
-
delegate =
|
337
|
+
delegate = TestSMTPDelegate.new(username: 'tester@example.com', password: 'tester')
|
326
338
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
327
339
|
|
328
340
|
assert delegate.requires_authentication?
|
@@ -347,14 +359,15 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
347
359
|
assert_equal :ready, interpreter.state
|
348
360
|
end
|
349
361
|
|
350
|
-
def
|
351
|
-
delegate =
|
362
|
+
def test_basic_esmtp_auth_plain_accepted
|
363
|
+
delegate = TestSMTPDelegate.new(username: 'tester@example.com', password: 'tester')
|
352
364
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
353
365
|
|
354
366
|
interpreter.process("220 mail.example.com ESMTP Exim 4.63\r\n")
|
355
367
|
assert_equal 'EHLO localhost.local', delegate.read
|
356
368
|
|
357
369
|
interpreter.process("250-mail.example.com Hello\r\n")
|
370
|
+
interpreter.process("250-AUTH PLAIN\r\n")
|
358
371
|
interpreter.process("250 HELP\r\n")
|
359
372
|
|
360
373
|
assert_equal false, delegate.started_tls?
|
@@ -367,17 +380,19 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
367
380
|
assert_equal :ready, interpreter.state
|
368
381
|
end
|
369
382
|
|
370
|
-
def
|
371
|
-
delegate =
|
383
|
+
def test_basic_esmtp_auth_plain_rejected
|
384
|
+
delegate = TestSMTPDelegate.new(username: 'tester@example.com', password: 'tester')
|
372
385
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
373
386
|
|
374
387
|
interpreter.process("220 mx.google.com ESMTP\r\n")
|
375
388
|
assert_equal 'EHLO localhost.local', delegate.read
|
376
389
|
|
377
390
|
interpreter.process("250-mx.google.com at your service\r\n")
|
391
|
+
interpreter.process("250-AUTH PLAIN LOGIN\r\n")
|
378
392
|
interpreter.process("250 HELP\r\n")
|
379
393
|
|
380
394
|
assert_equal false, delegate.started_tls?
|
395
|
+
assert_equal %i[ plain login ], delegate.auth_support.to_a
|
381
396
|
|
382
397
|
assert_equal :auth, interpreter.state
|
383
398
|
assert_equal "AUTH PLAIN AHRlc3RlckBleGFtcGxlLmNvbQB0ZXN0ZXI=", delegate.read
|
@@ -395,8 +410,40 @@ class RemailerSMTPClientInterpreterTest < MiniTest::Test
|
|
395
410
|
assert_equal true, delegate.closed?
|
396
411
|
end
|
397
412
|
|
413
|
+
def test_basic_esmtp_auth_login_accepted
|
414
|
+
delegate = TestSMTPDelegate.new(username: 'tester@example.com', password: 'tester')
|
415
|
+
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
416
|
+
|
417
|
+
interpreter.process("220 mail.example.com ESMTP Exim 4.63\r\n")
|
418
|
+
assert_equal 'EHLO localhost.local', delegate.read
|
419
|
+
|
420
|
+
interpreter.process("250-mail.example.com Hello\r\n")
|
421
|
+
interpreter.process("250-AUTH NTLM CRAM-MD5 GSSAPI LOGIN\r\n")
|
422
|
+
interpreter.process("250 HELP\r\n")
|
423
|
+
|
424
|
+
assert_equal false, delegate.started_tls?
|
425
|
+
assert_equal %i[ ntlm cram-md5 gssapi login ], delegate.auth_support.to_a
|
426
|
+
|
427
|
+
assert_equal "AUTH LOGIN", delegate.read
|
428
|
+
|
429
|
+
assert_equal :auth_username, interpreter.state
|
430
|
+
interpreter.process("334 VXNlcm5hbWU6\r\n")
|
431
|
+
assert_equal Base64.strict_encode64('tester@example.com'), delegate.read
|
432
|
+
|
433
|
+
assert_equal :auth_password, interpreter.state
|
434
|
+
|
435
|
+
interpreter.process("334 UGFzc3dvcmQ6\r\n")
|
436
|
+
assert_equal Base64.strict_encode64('tester'), delegate.read
|
437
|
+
|
438
|
+
assert_equal :auth_acknowledge, interpreter.state
|
439
|
+
interpreter.process("235 Sounds good\r\n")
|
440
|
+
|
441
|
+
assert_equal :ready, interpreter.state
|
442
|
+
end
|
443
|
+
|
444
|
+
|
398
445
|
def test_unexpected_response
|
399
|
-
delegate =
|
446
|
+
delegate = TestSMTPDelegate.new(username: 'tester@example.com', password: 'tester')
|
400
447
|
interpreter = Remailer::SMTP::Client::Interpreter.new(delegate: delegate)
|
401
448
|
|
402
449
|
interpreter.process("530 Go away\r\n")
|
@@ -3,7 +3,6 @@ require_relative '../helper'
|
|
3
3
|
class RemailerSMTPClientTest < MiniTest::Test
|
4
4
|
def test_connect
|
5
5
|
engine do
|
6
|
-
debug = { }
|
7
6
|
connected_host = nil
|
8
7
|
|
9
8
|
connection = Remailer::SMTP::Client.open(
|
@@ -31,7 +30,7 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
31
30
|
|
32
31
|
assert_equal true, after_complete_trigger
|
33
32
|
|
34
|
-
assert_equal
|
33
|
+
assert_equal 157286400, connection.max_size
|
35
34
|
assert_equal :esmtp, connection.protocol
|
36
35
|
assert_equal true, connection.tls_support?
|
37
36
|
end
|
@@ -70,7 +69,7 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
70
69
|
engine do
|
71
70
|
error_received = nil
|
72
71
|
|
73
|
-
|
72
|
+
Remailer::SMTP::Client.open(
|
74
73
|
'invalid-example-domain--x.com',
|
75
74
|
debug: self.debug_channel,
|
76
75
|
error: lambda { |code, message|
|
@@ -89,8 +88,6 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
89
88
|
|
90
89
|
def test_connect_with_auth
|
91
90
|
engine do
|
92
|
-
debug = { }
|
93
|
-
|
94
91
|
connection = Remailer::SMTP::Client.open(
|
95
92
|
TestConfig.options[:smtp_server][:host],
|
96
93
|
port: TestConfig.options[:smtp_server][:port] || Remailer::SMTP::Client::SMTP_PORT,
|
@@ -113,7 +110,7 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
113
110
|
connection.closed?
|
114
111
|
end
|
115
112
|
|
116
|
-
assert_equal TestConfig.options[:
|
113
|
+
assert_equal TestConfig.options[:smtp_server][:identifier], connection.remote
|
117
114
|
|
118
115
|
assert_equal true, after_complete_trigger
|
119
116
|
|
@@ -125,8 +122,6 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
125
122
|
|
126
123
|
def test_connect_via_proxy
|
127
124
|
engine do
|
128
|
-
debug = { }
|
129
|
-
|
130
125
|
connection = Remailer::SMTP::Client.open(
|
131
126
|
TestConfig.options[:public_smtp_server][:host],
|
132
127
|
debug: self.debug_channel,
|
@@ -154,7 +149,7 @@ class RemailerSMTPClientTest < MiniTest::Test
|
|
154
149
|
|
155
150
|
assert_equal true, after_complete_trigger
|
156
151
|
|
157
|
-
assert_equal
|
152
|
+
assert_equal 157286400, connection.max_size
|
158
153
|
assert_equal :esmtp, connection.protocol
|
159
154
|
assert_equal true, connection.tls_support?
|
160
155
|
end
|
@@ -24,7 +24,7 @@ class RemailerSMTPServerTest < MiniTest::Test
|
|
24
24
|
remote_ip = nil
|
25
25
|
|
26
26
|
server = Remailer::SMTP::Server.bind(
|
27
|
-
|
27
|
+
'127.0.0.1',
|
28
28
|
server_port,
|
29
29
|
on_connect: lambda { |_remote_ip| remote_ip = _remote_ip }
|
30
30
|
)
|
@@ -34,11 +34,13 @@ class RemailerSMTPServerTest < MiniTest::Test
|
|
34
34
|
connected_host = nil
|
35
35
|
|
36
36
|
client = Remailer::SMTP::Client.open(
|
37
|
-
'
|
37
|
+
'127.0.0.1',
|
38
38
|
port: server_port,
|
39
39
|
debug: self.debug_channel,
|
40
40
|
connect: lambda { |success, host| connected_host = host }
|
41
41
|
)
|
42
|
+
|
43
|
+
assert client
|
42
44
|
|
43
45
|
assert_eventually(30) do
|
44
46
|
connected_host
|
@@ -56,17 +58,15 @@ class RemailerSMTPServerTest < MiniTest::Test
|
|
56
58
|
transaction = nil
|
57
59
|
|
58
60
|
server = Remailer::SMTP::Server.bind(
|
59
|
-
|
61
|
+
'127.0.0.1',
|
60
62
|
server_port,
|
61
63
|
on_transaction: lambda { |_transaction| transaction = _transaction }
|
62
64
|
)
|
63
65
|
|
64
66
|
assert server
|
65
67
|
|
66
|
-
connected_host = nil
|
67
|
-
|
68
68
|
client = Remailer::SMTP::Client.open(
|
69
|
-
'
|
69
|
+
'127.0.0.1',
|
70
70
|
port: server_port,
|
71
71
|
debug: self.debug_channel
|
72
72
|
)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Tadman
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: juwelier
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -66,16 +66,17 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: EventMachine SMTP
|
70
|
-
email:
|
69
|
+
description: EventMachine Mail Agent for SMTP and IMAP
|
70
|
+
email: tadman@postageapp.com
|
71
71
|
executables: []
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files:
|
74
|
+
- LICENSE.txt
|
74
75
|
- README.md
|
75
76
|
files:
|
76
77
|
- ".document"
|
77
|
-
- ".travis.yml"
|
78
78
|
- Gemfile
|
79
|
+
- LICENSE.txt
|
79
80
|
- README.md
|
80
81
|
- Rakefile
|
81
82
|
- VERSION
|
@@ -104,7 +105,6 @@ files:
|
|
104
105
|
- test/bin/exercise
|
105
106
|
- test/config.example.yml
|
106
107
|
- test/config.rb
|
107
|
-
- test/config.yml.enc
|
108
108
|
- test/helper.rb
|
109
109
|
- test/unit/remailer_imap_client_interpreter_test.rb
|
110
110
|
- test/unit/remailer_imap_client_test.rb
|
@@ -115,10 +115,10 @@ files:
|
|
115
115
|
- test/unit/remailer_smtp_server_test.rb
|
116
116
|
- test/unit/remailer_socks5_client_interpreter_test.rb
|
117
117
|
- test/unit/remailer_test.rb
|
118
|
-
homepage: http://github.com/
|
118
|
+
homepage: http://github.com/postageapp/remailer
|
119
119
|
licenses: []
|
120
120
|
metadata: {}
|
121
|
-
post_install_message:
|
121
|
+
post_install_message:
|
122
122
|
rdoc_options: []
|
123
123
|
require_paths:
|
124
124
|
- lib
|
@@ -133,9 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
133
|
- !ruby/object:Gem::Version
|
134
134
|
version: '0'
|
135
135
|
requirements: []
|
136
|
-
|
137
|
-
|
138
|
-
signing_key:
|
136
|
+
rubygems_version: 3.1.4
|
137
|
+
signing_key:
|
139
138
|
specification_version: 4
|
140
139
|
summary: Reactor-Ready SMTP Mailer
|
141
140
|
test_files: []
|
data/.travis.yml
DELETED
data/test/config.yml.enc
DELETED
Binary file
|