rubymta 0.0.1 → 0.0.2
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/rubymta/item_of_mail.rb +6 -1
- data/lib/rubymta/queue_runner.rb +62 -1
- data/lib/rubymta/receiver.rb +14 -4
- data/lib/rubymta/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db5391a0c0a63fc549ebe8c21db735b96dd901f5
|
4
|
+
data.tar.gz: 48fbfaa4c0678490799c9d5b96dd54cfc40b7cad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 583963c19dd3465c318c62d0bd5b3576eb5cfb3413582806144d4845aece9b591b2f953b499146bb60ee14aa5dde9f1e00305914d719cffe9a6faac73a2f1760
|
7
|
+
data.tar.gz: c9b5f25a6497ab2be2260588d647f8daca356a8097d5f87d7d26cf43d6252f7909571185b432e5710931dc12fc7d7512d81b1ac72b11c3e1e729f52234019898
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
# v0.0.2
|
2
|
+
|
3
|
+
* Added code to make sure RubyMTA quits on the next command after a violations warning is given.
|
4
|
+
* Added code to detect the GET command from an attempt to connect with a web browser.
|
5
|
+
* Made corrections to the README.md file.
|
6
|
+
* removed the gmta-dev.db test file. A new one will be created when RubyMTA starts running.
|
7
|
+
* Added the method `send_local_alert` method which simply places the message into the local delivery system (Dovecot, in my case). This method provides a way to send an alert when there is a failure that requires someone's attention right away.
|
8
|
+
* Fixed a bug in queue_runner where it coded a partial item of mail as 'local'. Now, if the @mail[:accepted] flag is not true, the mail destination in the packet is set to 'none' as it should be.
|
9
|
+
* Made a change such that all packets coded as :delivery=>'none' also have the :delivery_at=>Time.now.
|
10
|
+
|
11
|
+
# v0.0.1
|
12
|
+
|
13
|
+
* Initial load. See the README.md for details.
|
data/lib/rubymta/item_of_mail.rb
CHANGED
@@ -64,7 +64,12 @@ class ItemOfMail < Hash
|
|
64
64
|
parcel[:to_url] = rcptto[:url]
|
65
65
|
parcel[:delivery_msg] = rcptto[:message]
|
66
66
|
parcel[:retry_at] = nil
|
67
|
-
|
67
|
+
if self[:accepted] && rcptto[:accepted]
|
68
|
+
parcel[:delivery] = rcptto[:delivery].to_s
|
69
|
+
else
|
70
|
+
parcel[:delivery] = 'none'
|
71
|
+
parcel[:delivery_at] = Time.now
|
72
|
+
end
|
68
73
|
parcel[:created_at] = parcel[:updated_at] = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
69
74
|
rcptto[:parcel_id] = S3DB[:parcels].insert(parcel)
|
70
75
|
end
|
data/lib/rubymta/queue_runner.rb
CHANGED
@@ -4,6 +4,8 @@ require 'openssl'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'pdkim'
|
6
6
|
|
7
|
+
LocalLMTPPort = 24
|
8
|
+
|
7
9
|
def manually_run_queue_runner
|
8
10
|
exit unless File::open(LockFilePath,"w").flock(File::LOCK_NB | File::LOCK_EX)
|
9
11
|
QueueRunner.new.run_queue
|
@@ -51,7 +53,7 @@ class QueueRunner
|
|
51
53
|
return ok, lines
|
52
54
|
end
|
53
55
|
rescue Timeout::Error => e
|
54
|
-
|
56
|
+
return '5', "500 5.0.0 No data received after #{QueueRunnerTimeout} seconds (Time Out)"
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
@@ -373,4 +375,63 @@ class QueueRunner
|
|
373
375
|
end
|
374
376
|
end
|
375
377
|
|
378
|
+
# to send an alert email to a registered user --
|
379
|
+
# this just delivers the message to dovecot with no processing --
|
380
|
+
# the caller is responsible to provide valid arguments
|
381
|
+
def send_local_email(from, to, subject, text)
|
382
|
+
@connection = nil
|
383
|
+
|
384
|
+
# open connection
|
385
|
+
ssl_socket = TCPSocket.open('localhost',LocalLMTPPort)
|
386
|
+
@connection = OpenSSL::SSL::SSLSocket.new(ssl_socket);
|
387
|
+
|
388
|
+
# receive the server's welcome message
|
389
|
+
ok, lines = recv_text
|
390
|
+
return ok, lines if ok!='2'
|
391
|
+
|
392
|
+
# send the LHLO
|
393
|
+
send_text("LHLO admin")
|
394
|
+
ok, lines = recv_text
|
395
|
+
return ok, lines if ok!='2'
|
396
|
+
|
397
|
+
# MAIL FROM
|
398
|
+
send_text("MAIL FROM:<#{from}>")
|
399
|
+
ok, lines = recv_text
|
400
|
+
return ok, lines if ok!='2'
|
401
|
+
|
402
|
+
# RCPT TO
|
403
|
+
send_text("RCPT TO:<#{to}>")
|
404
|
+
ok, lines = recv_text
|
405
|
+
return ok, lines if ok!='2'
|
406
|
+
|
407
|
+
# DATA -- send the email
|
408
|
+
send_text("DATA")
|
409
|
+
ok, lines = recv_text
|
410
|
+
return ok, lines if ok!='3'
|
411
|
+
lines = <<ALERT
|
412
|
+
To: <#{to}>
|
413
|
+
From: <#{from}>
|
414
|
+
Subject: #{subject}
|
415
|
+
Date: #{Time.now.strftime("%a, %d %b %Y %H:%M:%S %z")}
|
416
|
+
|
417
|
+
#{text}
|
418
|
+
ALERT
|
419
|
+
lines.split("\n").each do |line|
|
420
|
+
send_text(line, :data)
|
421
|
+
end
|
422
|
+
|
423
|
+
# send the end of the message prompt
|
424
|
+
send_text(".", :data)
|
425
|
+
|
426
|
+
# get the response from DoveCot
|
427
|
+
return recv_text
|
428
|
+
|
429
|
+
ensure
|
430
|
+
@connection.close if @connection
|
431
|
+
end
|
432
|
+
|
433
|
+
end
|
434
|
+
|
435
|
+
def send_local_alert(from, to, subject, text)
|
436
|
+
QueueRunner::new.send_local_email(from, to, subject, text)
|
376
437
|
end
|
data/lib/rubymta/receiver.rb
CHANGED
@@ -181,6 +181,7 @@ class Receiver
|
|
181
181
|
@done = false
|
182
182
|
@encrypted = false
|
183
183
|
@authenticated = false
|
184
|
+
@warning_given = false
|
184
185
|
@mail[:encrypted] = false
|
185
186
|
@mail[:authenticated] = nil
|
186
187
|
send_text(connect_base)
|
@@ -190,10 +191,18 @@ class Receiver
|
|
190
191
|
begin
|
191
192
|
break if @done
|
192
193
|
text = recv_text
|
193
|
-
|
194
|
+
# the client closed the channel abruptly or we're forcing QUIT
|
195
|
+
if (text.nil?) || @warning_given
|
194
196
|
text = "QUIT"
|
195
197
|
@contact.violation
|
196
198
|
end
|
199
|
+
# this handles an attempt to connect with HTTP
|
200
|
+
if text.start_with?("GET")
|
201
|
+
LOG.error(@mail[:mail_id]) {"An attempt was made to connect with a web browser"}
|
202
|
+
@mail[:saved] = true # prevent saving
|
203
|
+
raise Quit
|
204
|
+
end
|
205
|
+
# main command detect loop
|
197
206
|
unrecognized = true
|
198
207
|
Patterns.each do |pattern|
|
199
208
|
break if pattern[0]>@level
|
@@ -249,9 +258,9 @@ class Receiver
|
|
249
258
|
ok = nil
|
250
259
|
File.open(LockFilePath,"w") do |f|
|
251
260
|
ok = f.flock( File::LOCK_NB | File::LOCK_EX )
|
252
|
-
f.flock(File::LOCK_UN) if ok
|
261
|
+
f.flock(File::LOCK_UN) if ok
|
253
262
|
end
|
254
|
-
if ok
|
263
|
+
if ok
|
255
264
|
pid = Process::spawn("#{$app[:path]}/run_queue.rb")
|
256
265
|
Process::detach(pid)
|
257
266
|
end
|
@@ -275,6 +284,7 @@ class Receiver
|
|
275
284
|
|
276
285
|
if @contact.warning?
|
277
286
|
# this is the first denied message
|
287
|
+
@warning_given = true
|
278
288
|
expires_at = @contact.violation.strftime('%Y-%m-%d %H:%M:%S %Z') # to kick it up to prohibited
|
279
289
|
LOG.warn(@mail[:mail_id]) {"Access TEMPORARILY denied to #{@mail[:remote_ip]} (#{@mail[:remote_hostname]}) until #{expires_at}"}
|
280
290
|
return "454 4.7.1 Access TEMPORARILY denied to #{@mail[:remote_ip]}: you may try again after #{expires_at}"
|
@@ -576,7 +586,7 @@ class Receiver
|
|
576
586
|
|
577
587
|
def quit(value)
|
578
588
|
@done = true
|
579
|
-
if @mail[:saved].nil?
|
589
|
+
if (@mail[:saved].nil?) && (@contact.violations? == 0)
|
580
590
|
LOG.warn(@mail[:mail_id]) {"Quitting before a message is finished is considered a violation"}
|
581
591
|
@contact.violation
|
582
592
|
end
|
data/lib/rubymta/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubymta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael J. Welch, Ph.D.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: RubyMta is an experimental mail transport agent written in Ruby. See
|
14
14
|
the README.
|
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
53
|
version: '0'
|
54
54
|
requirements: []
|
55
55
|
rubyforge_project:
|
56
|
-
rubygems_version: 2.
|
56
|
+
rubygems_version: 2.4.6
|
57
57
|
signing_key:
|
58
58
|
specification_version: 4
|
59
59
|
summary: A Ruby Gem providing a complete Mail Transport Agent package.
|