drillmail 0.0.0 → 0.0.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 +4 -4
- data/.gitignore +35 -0
- data/bin/drillmail +5 -0
- data/drillmail.gemspec +17 -0
- data/lib/drillmail/commands/data.rb +25 -0
- data/lib/drillmail/commands/definitions.rb +55 -0
- data/lib/drillmail/commands/extended_hello.rb +6 -0
- data/lib/drillmail/commands/hello.rb +6 -0
- data/lib/drillmail/commands/mail.rb +15 -0
- data/lib/drillmail/commands/quit.rb +6 -0
- data/lib/drillmail/commands/recipient.rb +14 -0
- data/lib/drillmail/commands/reset.rb +6 -0
- data/lib/drillmail/smtp_test.rb +19 -0
- data/readme.md +31 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9673acdf08216e5b74722a4005401a1a0d592831
|
4
|
+
data.tar.gz: 564beb157e8894a5828342b6ead713fff2eaf634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79497d75d9f764bf9e2a4015b512aad7bb66cc8f5722394531a962ec4af6cfb2daaae8048f39d7010e3c02843527d7251a3b0f9265b29ccdb64f5ce39f070ef6
|
7
|
+
data.tar.gz: 8c6ea44529e5d02d800d42c0f887da86ddc757a37a62585d63b8bca9ee2d0fd66f566dbcf0cf01b35ed834fac898b45b3f2bfbe94c941b62d27b66dde5d2c5b0
|
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
*.rbc
|
2
|
+
capybara-*.html
|
3
|
+
.rspec
|
4
|
+
/log
|
5
|
+
/tmp
|
6
|
+
/db/*.sqlite3
|
7
|
+
/db/*.sqlite3-journal
|
8
|
+
/public/system
|
9
|
+
/coverage/
|
10
|
+
/spec/tmp
|
11
|
+
**.orig
|
12
|
+
rerun.txt
|
13
|
+
pickle-email-*.html
|
14
|
+
|
15
|
+
# TODO Comment out these rules if you are OK with secrets being uploaded to the repo
|
16
|
+
config/initializers/secret_token.rb
|
17
|
+
config/secrets.yml
|
18
|
+
|
19
|
+
## Environment normalization:
|
20
|
+
/.bundle
|
21
|
+
/vendor/bundle
|
22
|
+
|
23
|
+
# these should all be checked in to normalize the environment:
|
24
|
+
# Gemfile.lock, .ruby-version, .ruby-gemset
|
25
|
+
|
26
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
27
|
+
.rvmrc
|
28
|
+
|
29
|
+
# if using bower-rails ignore default bower_components path bower.json files
|
30
|
+
/vendor/assets/bower_components
|
31
|
+
*.bowerrc
|
32
|
+
bower.json
|
33
|
+
|
34
|
+
# Ignore pow environment settings
|
35
|
+
.powenv
|
data/bin/drillmail
ADDED
data/drillmail.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'drillmail'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = '2016-11-30'
|
5
|
+
s.summary = "A Ruby mail server and library"
|
6
|
+
s.description = "A Ruby implementation of the SMTP protocol that can be run as a deamon"
|
7
|
+
s.authors = ["Jasper Lyons"]
|
8
|
+
s.email = 'jasper.lyons@gmail.com'
|
9
|
+
|
10
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
11
|
+
s.bindir = "bin"
|
12
|
+
s.executables << 'drillmail'
|
13
|
+
s.require_paths = ["lib"]
|
14
|
+
|
15
|
+
s.homepage = 'https://github.com/releaseplatform/drillmail'
|
16
|
+
s.license = 'MIT'
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
DataCommand = Struct.new(:session, :body) do
|
5
|
+
def call
|
6
|
+
if session.reverse_path and session.forward_path
|
7
|
+
session.connection.puts session.reply(354)
|
8
|
+
|
9
|
+
while line = session.connection.gets and not line =~ /^(\r\n)?\.\r\n$/
|
10
|
+
puts "Recieved #{line}"
|
11
|
+
session.message.push(line)
|
12
|
+
end
|
13
|
+
|
14
|
+
mail = Mail.new(session.message.join)
|
15
|
+
puts "writing to #{mail.to.last}/#{mail.subject}.eml"
|
16
|
+
File.open("./#{mail.to.last}/#{mail.subject}.eml", 'w') do |f|
|
17
|
+
f.write(mail)
|
18
|
+
end
|
19
|
+
|
20
|
+
session.reply(250)
|
21
|
+
else
|
22
|
+
session.reply(451)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Commands
|
2
|
+
module Definitions
|
3
|
+
|
4
|
+
def commands
|
5
|
+
{
|
6
|
+
HELO: self.respond_to?(:hello) ? self.method(:hello) : proc { reply(502) },
|
7
|
+
EHLO: self.respond_to?(:extended_hello) ? self.method(:extended_hello) : proc { reply (502) },
|
8
|
+
MAIL: self.respond_to?(:mail) ? self.method(:mail) : proc { reply(502) },
|
9
|
+
RCPT: self.respond_to?(:recipient) ? self.method(:recipient) : proc { reply(502) },
|
10
|
+
DATA: self.respond_to?(:data) ? self.method(:data) : proc { reply(502) },
|
11
|
+
SEND: self.respond_to?(:send) ? self.method(:send) : proc { reply(502) },
|
12
|
+
SOML: self.respond_to?(:send_or_mail) ? self.method(:send_or_mail) : proc { reply(502) },
|
13
|
+
SAML: self.respond_to?(:send_and_mail) ? self.method(:send_and_mail) : proc { reply(502) },
|
14
|
+
RSET: self.respond_to?(:reset) ? self.method(:reset) : proc { reply(502) },
|
15
|
+
VRFY: self.respond_to?(:verify) ? self.method(:verify) : proc { reply(502) },
|
16
|
+
EXPN: self.respond_to?(:expand) ? self.method(:expand) : proc { reply(502) },
|
17
|
+
HELP: self.respond_to?(:help) ? self.method(:help) : proc { reply(502) },
|
18
|
+
NOOP: self.respond_to?(:no_operation) ? self.method(:no_operation) : proc { reply(502) },
|
19
|
+
QUIT: self.respond_to?(:quit) ? self.method(:quit) : proc { reply(502) },
|
20
|
+
TURN: self.respond_to?(:turn) ? self.method(:turn) : proc { reply(502) }
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def reply(number, message='')
|
25
|
+
"#{number} #{replies[number] % { message: message }}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def replies
|
29
|
+
{
|
30
|
+
211 => "System status",
|
31
|
+
214 => "Help message",
|
32
|
+
# weird issue where only 220 needs a \r\n
|
33
|
+
220 => "%{message} service ready\r\n",
|
34
|
+
221 => "%{message} service closing transmission tunnel",
|
35
|
+
250 => "%{message} OK",
|
36
|
+
251 => "User not local; will forward to %{message}",
|
37
|
+
354 => "Start mail input; end with <CLRF>.<CLRF>",
|
38
|
+
421 => "%{message} service not available, closing transmission tunnel",
|
39
|
+
450 => "Requested mail action not taken: mailbox unavailable",
|
40
|
+
451 => "Requested action aborted: local error in processing",
|
41
|
+
452 => "Requested action not taken: insufficient system storage",
|
42
|
+
500 => "Syntax error, command not recognized",
|
43
|
+
501 => "Syntax error in paramters or arguments",
|
44
|
+
502 => "Command not implemented",
|
45
|
+
503 => "Bad sequence of commands",
|
46
|
+
504 => "Command parameter not implemented",
|
47
|
+
550 => "Requested action not taken: mailbox unavailable %{message}",
|
48
|
+
551 => "User not local; please try %{message}",
|
49
|
+
552 => "Requested mail action aborted: exceeded storage allocation",
|
50
|
+
553 => "Requested action not taken: mailbox name not allowed",
|
51
|
+
554 => "Transaction Failed"
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
MailCommand = Struct.new(:session, :body) do
|
2
|
+
def call
|
3
|
+
# MAIL <SP> FROM:<reverse-path> <CLRF>
|
4
|
+
if session.domain
|
5
|
+
if reverse_path_match = /FROM:<(.+)>/.match(body)
|
6
|
+
session.reverse_path = reverse_path_match[1]
|
7
|
+
session.reply(250)
|
8
|
+
else
|
9
|
+
session.reply(501)
|
10
|
+
end
|
11
|
+
else
|
12
|
+
session.reply(451)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
RecipientCommand = Struct.new(:session, :body) do
|
2
|
+
def call
|
3
|
+
# RCPT <SP> TO:<forward-path> <CRLF>
|
4
|
+
return session.reply(451) unless session.reverse_path
|
5
|
+
|
6
|
+
forward_path = /TO:<(.+)>/.match(body)[1]
|
7
|
+
return session.reply(501) unless forward_path
|
8
|
+
return session.reply(551, forward_path) unless Dir.
|
9
|
+
exists?("./#{forward_path}")
|
10
|
+
|
11
|
+
session.forward_path = forward_path
|
12
|
+
session.reply(250, 'added recipient')
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'net/smtp'
|
2
|
+
|
3
|
+
msgstr = <<END_OF_MESSAGE
|
4
|
+
From: Your Name <your@mail.address>
|
5
|
+
To: Destination Address <bob@thecat.com>
|
6
|
+
Subject: test message
|
7
|
+
Date: Sat, 23 Jun 2001 16:26:43 +0900
|
8
|
+
Message-Id: <unique.message.id.string@example.com>
|
9
|
+
|
10
|
+
This is a test message.
|
11
|
+
END_OF_MESSAGE
|
12
|
+
|
13
|
+
begin
|
14
|
+
Net::SMTP.start('localhost', 5000) do |smtp|
|
15
|
+
smtp.send_message(msgstr, 'jasper.lyons@gmail.com', 'bob@thecat.com')
|
16
|
+
end
|
17
|
+
rescue => e
|
18
|
+
puts e.inspect
|
19
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Drillmail
|
2
|
+
|
3
|
+
To install:
|
4
|
+
`gem install drillmail`
|
5
|
+
|
6
|
+
To run for testing locally:
|
7
|
+
`drillmail <port>`
|
8
|
+
|
9
|
+
To run in production:
|
10
|
+
`sudo drillmail`
|
11
|
+
|
12
|
+
> The default port is 587, you can change this by passing the port number as the
|
13
|
+
> first argument to drillmail e.g. `sudo drillmail 25`
|
14
|
+
|
15
|
+
## Accepting email
|
16
|
+
|
17
|
+
Drillmail will only accept emails for users who have directories present in
|
18
|
+
the directory drillmail is run in e.g:
|
19
|
+
|
20
|
+
`tree .`
|
21
|
+
`bob@cat.com/`
|
22
|
+
|
23
|
+
will allow emails to bob@cat.com but not to john@cat.com.
|
24
|
+
|
25
|
+
## Emails
|
26
|
+
|
27
|
+
Emails are stored inside of users directories in a `.eml` file names after the
|
28
|
+
subject of the email.
|
29
|
+
|
30
|
+
> Yes this breaks lots of things, like emails with the same subject line from
|
31
|
+
> different people but this early days.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drillmail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jasper Lyons
|
@@ -12,12 +12,26 @@ date: 2016-11-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
13
13
|
description: A Ruby implementation of the SMTP protocol that can be run as a deamon
|
14
14
|
email: jasper.lyons@gmail.com
|
15
|
-
executables:
|
15
|
+
executables:
|
16
|
+
- drillmail
|
16
17
|
extensions: []
|
17
18
|
extra_rdoc_files: []
|
18
19
|
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- bin/drillmail
|
22
|
+
- drillmail.gemspec
|
19
23
|
- lib/drillmail.rb
|
24
|
+
- lib/drillmail/commands/data.rb
|
25
|
+
- lib/drillmail/commands/definitions.rb
|
26
|
+
- lib/drillmail/commands/extended_hello.rb
|
27
|
+
- lib/drillmail/commands/hello.rb
|
28
|
+
- lib/drillmail/commands/mail.rb
|
29
|
+
- lib/drillmail/commands/quit.rb
|
30
|
+
- lib/drillmail/commands/recipient.rb
|
31
|
+
- lib/drillmail/commands/reset.rb
|
20
32
|
- lib/drillmail/smtp.rb
|
33
|
+
- lib/drillmail/smtp_test.rb
|
34
|
+
- readme.md
|
21
35
|
homepage: https://github.com/releaseplatform/drillmail
|
22
36
|
licenses:
|
23
37
|
- MIT
|