remailer 0.7.1.2 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|