rubymta 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d94b02b7553df5c9c37317c7081949df6e2a1df6
4
- data.tar.gz: c8963029d4eda72e12dda04fc7c7dfceebbbf266
3
+ metadata.gz: db5391a0c0a63fc549ebe8c21db735b96dd901f5
4
+ data.tar.gz: 48fbfaa4c0678490799c9d5b96dd54cfc40b7cad
5
5
  SHA512:
6
- metadata.gz: 50b91a554c32a383688f18492125cd08186aba6ded6f0eda35459bb1ed321338f6fc32bccd2795668515678ce999910bbf517393d04186f0bf4bc512ab58fc43
7
- data.tar.gz: 308793abfd6ed53b9a7b795ad2b4bb4558e24022c88b0f931c94bf2f3da300da3cf8d47abb9e99a49cda750bc42d5cfbc7bff9eee0740849f0fcd1184ce377e3
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.
@@ -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
- parcel[:delivery] = if rcptto[:accepted] then rcptto[:delivery].to_s else "none" end
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
@@ -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
- raise "Fix this in transporter.rb::recv_text rescue"
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
@@ -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
- if (text.nil?) # the client closed the channel abruptly
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!=false
261
+ f.flock(File::LOCK_UN) if ok
253
262
  end
254
- if ok!=false
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
@@ -1,5 +1,5 @@
1
1
  module Version
2
- VERSION = "0.0.1"
3
- MODIFIED = "2017-07-29"
2
+ VERSION = "0.0.2"
3
+ MODIFIED = "2017-08-14"
4
4
  end
5
5
 
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.1
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-07-29 00:00:00.000000000 Z
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.5.1
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.