maildiode 0.0.5 → 0.1.0
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.
- data/bin/maildiode +25 -3
- data/lib/maildiode-plugins/alias.rb +5 -3
- data/lib/maildiode-plugins/blacklist.rb +3 -1
- data/lib/maildiode-plugins/delay.rb +1 -0
- data/lib/maildir.rb +5 -2
- data/lib/server.rb +6 -2
- data/lib/settings.rb +41 -3
- data/maildiode.conf.sample +6 -6
- metadata +2 -2
data/bin/maildiode
CHANGED
@@ -72,7 +72,7 @@ module MailDiode
|
|
72
72
|
def self.load_plugins(settings)
|
73
73
|
plugins = []
|
74
74
|
settings.get_settings('plugin').each do | setting |
|
75
|
-
plugins << create_plugin(setting
|
75
|
+
plugins << create_plugin(setting.key, settings)
|
76
76
|
end
|
77
77
|
return plugins
|
78
78
|
end
|
@@ -119,6 +119,23 @@ def uid(user_name)
|
|
119
119
|
return Etc::getpwnam.uid
|
120
120
|
end
|
121
121
|
|
122
|
+
def apply_debug_settings(settings)
|
123
|
+
available_levels = {
|
124
|
+
'error' => Logger::ERROR,
|
125
|
+
'warn' => Logger::WARN,
|
126
|
+
'info' => Logger::INFO,
|
127
|
+
'debug' => Logger::DEBUG,
|
128
|
+
}
|
129
|
+
|
130
|
+
log_level_string = settings.get_setting('debug', 'level')
|
131
|
+
if(log_level_string)
|
132
|
+
level = available_levels[log_level_string]
|
133
|
+
if(level)
|
134
|
+
MailDiode::set_log_level(level)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
122
139
|
def drop_privileges(new_user_name)
|
123
140
|
gid = Etc::getpwnam(new_user_name).gid
|
124
141
|
Process::Sys::setresgid(gid, gid, gid)
|
@@ -132,17 +149,22 @@ def start
|
|
132
149
|
|
133
150
|
MailDiode::log_to_file($log_filename)
|
134
151
|
MailDiode::set_log_level(Logger::INFO)
|
152
|
+
MailDiode::log_info "----Starting MailDiode"
|
135
153
|
|
136
154
|
config_file = MailDiode::Settings.default_file
|
137
155
|
settings = MailDiode::Settings.new(config_file)
|
156
|
+
|
157
|
+
apply_debug_settings(settings)
|
158
|
+
MailDiode::log_debug "Debug logging enabled"
|
159
|
+
|
138
160
|
user = settings.get_setting('server', 'user')
|
139
161
|
user.untaint
|
140
162
|
|
163
|
+
|
141
164
|
plugins = MailDiode::load_plugins(settings)
|
142
165
|
factory = MailDiode::EngineFactory.new(plugins, settings)
|
143
|
-
MailDiode::log_info "Starting server..."
|
144
|
-
MailDiode::log_debug "Debug logging enabled"
|
145
166
|
server = MailDiode::Server.new(factory, settings)
|
167
|
+
MailDiode::log_info "Starting server #{server.ip}:#{server.port}..."
|
146
168
|
server.start
|
147
169
|
if(user)
|
148
170
|
drop_privileges(user)
|
@@ -28,19 +28,21 @@ module MailDiode
|
|
28
28
|
MailDiode::log_debug "alias checking: #{pattern}"
|
29
29
|
re = Regexp.new(pattern, Regexp::IGNORECASE)
|
30
30
|
if(recipient.match(re))
|
31
|
-
MailDiode::
|
31
|
+
MailDiode::log_debug "Alias #{recipient} --> #{target}"
|
32
32
|
filterable_data.recipient = target
|
33
33
|
return
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
MailDiode::
|
37
|
+
MailDiode::log_debug "No alias for #{recipient}"
|
38
38
|
end
|
39
39
|
|
40
40
|
def load_settings(settings)
|
41
41
|
settings.get_settings('alias').each do | setting |
|
42
|
-
|
42
|
+
pattern = setting.key
|
43
|
+
target = setting.value
|
43
44
|
@aliases << [pattern, target]
|
45
|
+
MailDiode::log_debug " #{pattern} -> #{target}"
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
@@ -37,10 +37,12 @@ module MailDiode
|
|
37
37
|
|
38
38
|
def load_settings(settings)
|
39
39
|
settings.get_settings('blacklist').each do | setting |
|
40
|
-
key
|
40
|
+
key = setting.key
|
41
|
+
value = setting.value
|
41
42
|
case key
|
42
43
|
when 'to'
|
43
44
|
@blacklisted_recipients << value
|
45
|
+
MailDiode::log_debug " #{key} X #{value}"
|
44
46
|
else
|
45
47
|
MailDiode::log_warning "Blacklist ignoring unknown: #{key}"
|
46
48
|
end
|
@@ -43,6 +43,7 @@ module MailDiode
|
|
43
43
|
@delay_helo = settings.get_setting('delay', 'helo').to_i
|
44
44
|
@delay_mail = settings.get_setting('delay', 'mail').to_i
|
45
45
|
@delay_rcpt = settings.get_setting('delay', 'rcpt').to_i
|
46
|
+
MailDiode::log_debug " HELO #{@delay_helo} MAIL #{@delay_mail} RCPT #{@delay_rcpt} seconds"
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
data/lib/maildir.rb
CHANGED
@@ -55,7 +55,7 @@ module MailDiode
|
|
55
55
|
raw_dir = get_maildir(recipient)
|
56
56
|
folder = ''
|
57
57
|
dir = "#{raw_dir.chomp('/')}#{folder}/"
|
58
|
-
MailDiode::log_info "Delivering to #{dir}"
|
58
|
+
MailDiode::log_info "Delivering to #{dir} for #{recipient}"
|
59
59
|
if !File.exist?(dir)
|
60
60
|
MailDiode::log_error "ERROR: Missing maildir folder: #{dir}"
|
61
61
|
raise FolderMissingError.new(File.basename(dir))
|
@@ -100,12 +100,15 @@ module MailDiode
|
|
100
100
|
|
101
101
|
def load_settings(settings)
|
102
102
|
settings.get_settings('maildir').each do | setting |
|
103
|
-
name
|
103
|
+
name = setting.key
|
104
|
+
maildir = setting.value
|
104
105
|
if(maildir.index('/') != 0)
|
105
106
|
raise "Maildir must start with slash (/): #{maildir}"
|
106
107
|
end
|
107
108
|
maildir.untaint
|
108
109
|
@maildirs[name] = maildir
|
110
|
+
#Disabled because this is called per-connection
|
111
|
+
#MailDiode::log_debug " #{name} -> #{maildir}"
|
109
112
|
end
|
110
113
|
end
|
111
114
|
end
|
data/lib/server.rb
CHANGED
@@ -19,6 +19,10 @@ require 'io/wait'
|
|
19
19
|
|
20
20
|
module MailDiode
|
21
21
|
class Server < GServer
|
22
|
+
|
23
|
+
attr_reader :ip
|
24
|
+
attr_reader :port
|
25
|
+
|
22
26
|
def initialize(engine_factory, settings)
|
23
27
|
load_settings(settings)
|
24
28
|
|
@@ -41,7 +45,7 @@ module MailDiode
|
|
41
45
|
while !engine.terminate?
|
42
46
|
line = get_line(client, TIMEOUT_SECONDS)
|
43
47
|
if(!line)
|
44
|
-
MailDiode::log_info("
|
48
|
+
MailDiode::log_info("Client disconnected")
|
45
49
|
return
|
46
50
|
end
|
47
51
|
line.chomp!(NEWLINE)
|
@@ -52,7 +56,7 @@ module MailDiode
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
rescue Errno::ECONNRESET
|
55
|
-
MailDiode::log_info "
|
59
|
+
MailDiode::log_info "Client dropped connection"
|
56
60
|
rescue Exception => e
|
57
61
|
MailDiode::log_error("Exception #{e.class}: #{e}")
|
58
62
|
e.backtrace.each do | line |
|
data/lib/settings.rb
CHANGED
@@ -15,7 +15,41 @@
|
|
15
15
|
|
16
16
|
|
17
17
|
module MailDiode
|
18
|
+
class SingleSetting
|
19
|
+
attr_reader :key
|
20
|
+
attr_reader :value
|
21
|
+
|
22
|
+
def initialize(key, value)
|
23
|
+
@key = key
|
24
|
+
@value = value
|
25
|
+
end
|
26
|
+
end
|
18
27
|
|
28
|
+
class ComponentSettings
|
29
|
+
def initialize
|
30
|
+
@settings = []
|
31
|
+
end
|
32
|
+
|
33
|
+
def add(new_setting)
|
34
|
+
@settings << new_setting
|
35
|
+
end
|
36
|
+
|
37
|
+
def each
|
38
|
+
@settings.each do | setting |
|
39
|
+
yield setting
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_setting(key)
|
44
|
+
each do | setting |
|
45
|
+
if(setting.key == key)
|
46
|
+
return setting
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
19
53
|
class Settings
|
20
54
|
def initialize(config_file)
|
21
55
|
@settings = {}
|
@@ -30,13 +64,13 @@ module MailDiode
|
|
30
64
|
|
31
65
|
def load_setting(component, keyword, args)
|
32
66
|
component_settings = get_settings(component)
|
33
|
-
component_settings
|
67
|
+
component_settings.add(SingleSetting.new(keyword, args))
|
34
68
|
end
|
35
69
|
|
36
70
|
def get_settings(component)
|
37
71
|
component_settings = @settings[component]
|
38
72
|
if(!component_settings)
|
39
|
-
component_settings =
|
73
|
+
component_settings = ComponentSettings.new
|
40
74
|
@settings[component] = component_settings
|
41
75
|
end
|
42
76
|
return component_settings
|
@@ -47,7 +81,11 @@ module MailDiode
|
|
47
81
|
if(!component_settings)
|
48
82
|
return nil
|
49
83
|
end
|
50
|
-
|
84
|
+
setting = component_settings.get_setting(keyword)
|
85
|
+
if(!setting)
|
86
|
+
return nil
|
87
|
+
end
|
88
|
+
return setting.value
|
51
89
|
end
|
52
90
|
|
53
91
|
def get_int(component, keyword, default_value)
|
data/maildiode.conf.sample
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#debug warn # error warn info debug
|
1
|
+
#debug level warn # error warn info debug
|
2
2
|
|
3
3
|
# Basic server info
|
4
4
|
server hostname localhost
|
@@ -12,13 +12,13 @@ maildir bob@example.com /home/bob/mail
|
|
12
12
|
maildir kevin /home/kevins/TestMail/main/
|
13
13
|
maildir catchall /home/kevins/TestMail/other/
|
14
14
|
|
15
|
-
# Aliases
|
15
|
+
# Aliases define a regexp and its corresponding maildir name
|
16
16
|
# (Stops as soon as the first match is hit, so put catchall last)
|
17
17
|
plugin alias
|
18
|
-
alias
|
19
|
-
alias
|
20
|
-
alias
|
21
|
-
alias
|
18
|
+
alias ^kevin@qualitycode.com$ kevin
|
19
|
+
alias ^kevins@qualitycode.com$ kevin
|
20
|
+
alias @qualitycode.com$ catchall
|
21
|
+
alias @example.com$ catchall
|
22
22
|
|
23
23
|
# Blacklist only supports filtering on "to" for now
|
24
24
|
# (handy to limit catchall spam)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maildiode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Smith
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-12-
|
12
|
+
date: 2008-12-13 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|