smailr 0.3.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/smailr +165 -0
- data/contrib/dovecot-sql.conf +135 -0
- data/contrib/dovecot.conf +1281 -0
- data/contrib/exim4.conf +308 -0
- data/lib/smailr/alias.rb +36 -0
- data/lib/smailr/dkim.rb +35 -0
- data/lib/smailr/domain.rb +18 -0
- data/lib/smailr/mailbox.rb +22 -0
- data/lib/smailr/model.rb +68 -0
- data/lib/smailr.rb +22 -0
- data/migrations/001_domains.rb +8 -0
- data/migrations/002_mailboxes.rb +12 -0
- data/migrations/003_aliases.rb +12 -0
- data/migrations/004_dkims.rb +12 -0
- metadata +133 -0
data/contrib/exim4.conf
ADDED
@@ -0,0 +1,308 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Smailr Exim Configuration
|
3
|
+
|
4
|
+
|
5
|
+
# DATABASE QUERIES
|
6
|
+
|
7
|
+
ACL_DONT_SCAN_TWIZE_SECRET = Quai2tohr7TeeGh
|
8
|
+
|
9
|
+
SQLITE_DATABASE_FILE = /etc/exim4/smailr.sqlite
|
10
|
+
|
11
|
+
VIRTUAL_DOMAINS_SQL = SELECT DISTINCT fqdn FROM domains WHERE fqdn = '${quote_sqlite:$domain}'
|
12
|
+
VIRTUAL_DOMAINS = ${lookup sqlite{SQLITE_DATABASE_FILE VIRTUAL_DOMAINS_SQL}}
|
13
|
+
|
14
|
+
R_VIRTUAL_MAILBOX_CONDITION_SQL = \
|
15
|
+
SELECT '/srv/mail/users/' || domains.fqdn || '/' || mailboxes.localpart \
|
16
|
+
FROM mailboxes, domains \
|
17
|
+
WHERE mailboxes.localpart = '${quote_sqlite:$local_part}' \
|
18
|
+
AND domains.fqdn = '${quote_sqlite:$domain}' \
|
19
|
+
AND mailboxes.domain_id = domains.id
|
20
|
+
|
21
|
+
R_VIRTUAL_MAILBOX_CONDITION = ${lookup sqlite{SQLITE_DATABASE_FILE R_VIRTUAL_MAILBOX_CONDITION_SQL}}
|
22
|
+
|
23
|
+
domainlist local_domains = @ : VIRTUAL_DOMAINS
|
24
|
+
|
25
|
+
#############################################################################
|
26
|
+
# Main Settings
|
27
|
+
|
28
|
+
smtp_banner = $primary_hostname NO UCE/NO UBE ESMTP MTA
|
29
|
+
|
30
|
+
exim_user = Debian-exim
|
31
|
+
exim_group = Debian-exim
|
32
|
+
never_users = root
|
33
|
+
|
34
|
+
daemon_smtp_ports = 25 : 465 : 587
|
35
|
+
|
36
|
+
tls_certificate = /etc/exim4/exim.crt
|
37
|
+
tls_privatekey = /etc/exim4/exim.key
|
38
|
+
tls_advertise_hosts = *
|
39
|
+
|
40
|
+
split_spool_directory = true
|
41
|
+
|
42
|
+
smtp_return_error_details = true
|
43
|
+
|
44
|
+
log_selector = +subject \
|
45
|
+
+address_rewrite \
|
46
|
+
+connection_reject \
|
47
|
+
+delay_delivery \
|
48
|
+
+delivery_size \
|
49
|
+
+dnslist_defer \
|
50
|
+
+lost_incoming_connection \
|
51
|
+
+queue_run \
|
52
|
+
+received_recipients \
|
53
|
+
+sender_on_delivery \
|
54
|
+
+size_reject \
|
55
|
+
+smtp_confirmation \
|
56
|
+
+smtp_protocol_error \
|
57
|
+
+smtp_syntax_error \
|
58
|
+
+tls_cipher \
|
59
|
+
+tls_peerdn
|
60
|
+
|
61
|
+
# Maximum message size
|
62
|
+
message_size_limit = 20M
|
63
|
+
|
64
|
+
# Number of unknown SMTP commands we accept before dropping the connection
|
65
|
+
smtp_max_unknown_commands = 10
|
66
|
+
|
67
|
+
bounce_return_size_limit = 10K
|
68
|
+
|
69
|
+
# These protections need to take into account MailScanners need to do
|
70
|
+
# MIME explosion.
|
71
|
+
check_spool_inodes = 1000
|
72
|
+
check_spool_space = 100M
|
73
|
+
|
74
|
+
# do a reverse DNS lookup on every connection
|
75
|
+
host_lookup = *
|
76
|
+
|
77
|
+
# No RFC 1413 (ident)-lookups
|
78
|
+
rfc1413_hosts = !*
|
79
|
+
|
80
|
+
# Make ESMTP PIPELINING available in all cases
|
81
|
+
pipelining_advertise_hosts = *
|
82
|
+
|
83
|
+
# A bit of good cop / bad cop with helo
|
84
|
+
helo_allow_chars = "_"
|
85
|
+
helo_verify_hosts = !*
|
86
|
+
helo_try_verify_hosts = !*
|
87
|
+
|
88
|
+
# Reverse DNS information is useful
|
89
|
+
helo_lookup_domains = *
|
90
|
+
|
91
|
+
# Send a notification about forzen messages at these intervals
|
92
|
+
delay_warning = 1h:2h:8h:24h:48h:72h
|
93
|
+
|
94
|
+
# Don't send a notification for messages with Precedence:bulk|list|junk
|
95
|
+
delay_warning_condition = "${if match{$h_precedence:}{(?i)bulk|list|junk}{no}{yes}}"
|
96
|
+
|
97
|
+
# Accept 8-bit MIME in Helo and Body.
|
98
|
+
accept_8bitmime
|
99
|
+
|
100
|
+
# Allow to manually specify a envelope-from when submitting local mail
|
101
|
+
local_from_check = false
|
102
|
+
local_sender_retain = true
|
103
|
+
untrusted_set_sender = *
|
104
|
+
|
105
|
+
# Clamav socket
|
106
|
+
av_scanner = clamd:/var/run/clamav/clamd.ctl
|
107
|
+
|
108
|
+
|
109
|
+
#############################################################################
|
110
|
+
# ACL Configuration
|
111
|
+
|
112
|
+
# We use the following ACLs:
|
113
|
+
acl_smtp_connect = accept
|
114
|
+
acl_smtp_helo = accept
|
115
|
+
acl_smtp_starttls = accept
|
116
|
+
acl_smtp_mail = accept
|
117
|
+
acl_smtp_rcpt = acl_check_rcpt
|
118
|
+
acl_smtp_data = acl_check_data
|
119
|
+
|
120
|
+
# We dont allow VRFY/EXPN
|
121
|
+
acl_smtp_vrfy = deny
|
122
|
+
acl_smtp_expn = deny
|
123
|
+
|
124
|
+
begin acl
|
125
|
+
|
126
|
+
acl_check_rcpt:
|
127
|
+
# TODO: Put up propper spam detection
|
128
|
+
|
129
|
+
# Accept if source is local SMTP (not over TCP). We do this by testing
|
130
|
+
# for an empty sending host field.
|
131
|
+
accept hosts = :
|
132
|
+
|
133
|
+
# Accept everything from localhost
|
134
|
+
accept hosts = 127.0.0.1/8 : ::::1
|
135
|
+
|
136
|
+
# Deny if the local part contains @ or % or / or | or !. These are rarely
|
137
|
+
# found in genuine local parts, but are often tried by people looking to
|
138
|
+
# circumvent relaying restrictions.
|
139
|
+
deny local_parts = ^.*[@%!/|] : ^\\.
|
140
|
+
|
141
|
+
# Don't scan messages with our cryptographic header.
|
142
|
+
# This is needed for messages, which run the ACL twize, (eg. redirects)
|
143
|
+
# to save processing time.
|
144
|
+
warn message = X-SA-Do-Not-Run: Yes
|
145
|
+
condition = ${if eq{\
|
146
|
+
${hmac{md5}{ACL_DONT_SCAN_TWIZE_SECRET}{$body_linecount}}}\
|
147
|
+
{$h_X-Scan-Signature:}\
|
148
|
+
{1}{0}}
|
149
|
+
|
150
|
+
# Accept authenticated messages.
|
151
|
+
accept authenticated = *
|
152
|
+
|
153
|
+
# Deny relaying on port 587 if not authenticated.
|
154
|
+
deny !authenticated = *
|
155
|
+
condition = ${if eq {$interface_port}{587} {yes}{no}}
|
156
|
+
message = Relaying denied. Proper authentication required on port 587.
|
157
|
+
|
158
|
+
# Teergrube any borken reverse DNS entries.
|
159
|
+
warn message = X-Broken-Reverse-DNS: no host name for IP address $sender_host_address
|
160
|
+
!verify = reverse_host_lookup
|
161
|
+
delay = TEERGRUBE
|
162
|
+
|
163
|
+
# Accept if the address is in a local domain, but only if the recipient can
|
164
|
+
# be verified. Otherwise deny. The "endpass" line is the border between
|
165
|
+
# passing on to the next ACL statement (if tests above it fail) or denying
|
166
|
+
# access (if tests below it fail).
|
167
|
+
accept domains = +local_domains
|
168
|
+
endpass
|
169
|
+
verify = recipient
|
170
|
+
|
171
|
+
# Accept if the address is in a domain for which we are relaying, but again,
|
172
|
+
# only if the recipient can be verified (this saves your secondary
|
173
|
+
# MXes from accepting mail that they then can't send to your primary
|
174
|
+
# MX)
|
175
|
+
accept domains = +relay_to_domains
|
176
|
+
endpass
|
177
|
+
message = unrouteable address
|
178
|
+
verify = recipient/callout=30s/callout_defer_ok
|
179
|
+
|
180
|
+
accept hosts = +relay_from_hosts
|
181
|
+
|
182
|
+
# Reaching the end of the ACL causes a "deny".
|
183
|
+
deny message = <$local_part@$domain>: Relaying denied. Proper authentication required.
|
184
|
+
delay = TEERGRUBE
|
185
|
+
|
186
|
+
|
187
|
+
acl_check_data:
|
188
|
+
|
189
|
+
# Accept if source is local SMTP (i.e. not over TCP/IP). We do this by
|
190
|
+
# testing for an empty sending host field.
|
191
|
+
accept hosts = :
|
192
|
+
|
193
|
+
# Run clamav against the message and reject if it contains malware. This
|
194
|
+
# acl condition will not deny if there is a problem with clamav.
|
195
|
+
deny message = This message contains malware ($malware_name)
|
196
|
+
malware = */defer_ok
|
197
|
+
|
198
|
+
accept
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
#############################################################################
|
203
|
+
# Router Configuration
|
204
|
+
|
205
|
+
begin routers
|
206
|
+
|
207
|
+
# Aliases for local mailboxes
|
208
|
+
virtual_alias:
|
209
|
+
debug_print = "R: virtual_alias for $local_part@$domain"
|
210
|
+
driver = redirect
|
211
|
+
domains = +local_domains
|
212
|
+
allow_fail
|
213
|
+
allow_defer
|
214
|
+
# Lookup the mailbox which we route to
|
215
|
+
data = ${lookup sqlite {SQLITE_DATABASE_FILE \
|
216
|
+
SELECT mailboxes.localpart || '@' || domains.fqdn \
|
217
|
+
FROM mailboxes, domains, aliases \
|
218
|
+
WHERE aliases.address = '${quote_sqlite:$local_part}@${quote_sqlite:$domain}' \
|
219
|
+
AND domains.fqdn = '${quote_sqlite:$domain}' \
|
220
|
+
AND mailboxes.domain_id = domains.id \
|
221
|
+
AND aliases.mailbox_id = mailboxes.id }{$value}fail}
|
222
|
+
|
223
|
+
virtual_mailbox:
|
224
|
+
debug_print = "R: virtual_mailbox for $local_part@$domain"
|
225
|
+
driver = accept
|
226
|
+
domains = +local_domains
|
227
|
+
transport = dovecot_virtual_delivery
|
228
|
+
condition = R_VIRTUAL_MAILBOX_CONDITION
|
229
|
+
|
230
|
+
# This router routes to remote hosts over SMTP using a DNS lookup with
|
231
|
+
# default options.
|
232
|
+
dnslookup:
|
233
|
+
debug_print = "R: dnslookup for $local_part@$domain"
|
234
|
+
driver = dnslookup
|
235
|
+
domains = ! +local_domains
|
236
|
+
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
|
237
|
+
cannot_route_message = Unkown user $local_part in domain $domain
|
238
|
+
# Optimization since the dnslookup router is independent of the local part
|
239
|
+
same_domain_copy_routing = yes
|
240
|
+
transport = remote_smtp
|
241
|
+
no_more
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
#############################################################################
|
246
|
+
# Transport Configuration
|
247
|
+
|
248
|
+
begin transports
|
249
|
+
|
250
|
+
remote_smtp:
|
251
|
+
debug_print = "T: remote_smtp for $local_part@$domain"
|
252
|
+
driver = smtp
|
253
|
+
hosts_nopass_tls = *
|
254
|
+
hosts_avoid_tls = +hosts_avoid_tls
|
255
|
+
hosts_try_auth = +hosts_try_auth
|
256
|
+
headers_remove = "X-SA-Do-Not-Run:X-SA-Exim-Scanned:X-SA-Exim-Rcpt-From:X-SA-Exim-Rcpt-To:X-SA-Exim-Version"
|
257
|
+
|
258
|
+
|
259
|
+
dovecot_virtual_delivery:
|
260
|
+
debug_print = "T: dovecot_virtual_delivery for $local_part@$domain"
|
261
|
+
driver = pipe
|
262
|
+
command = /usr/lib/dovecot/deliver -d $local_part@$domain -f $sender_address -a $original_local_part@$original_domain
|
263
|
+
message_prefix =
|
264
|
+
message_suffix =
|
265
|
+
delivery_date_add
|
266
|
+
envelope_to_add
|
267
|
+
return_path_add
|
268
|
+
log_output
|
269
|
+
user = vmail
|
270
|
+
temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78
|
271
|
+
# Remove the X-SA_Exim-Rcpt-To header again, otherwise we would expose BCCs
|
272
|
+
headers_remove = "X-SA-Exim-Rcpt-To"
|
273
|
+
|
274
|
+
|
275
|
+
#############################################################################
|
276
|
+
# Rewrites/Retries/Authenticatos
|
277
|
+
|
278
|
+
begin rewrite
|
279
|
+
|
280
|
+
|
281
|
+
begin retry
|
282
|
+
|
283
|
+
# Retry.. every 10 mins for 2 hours
|
284
|
+
# Then.. every hour for 24 hours
|
285
|
+
# Finaly.. every 6 hours for 4 days
|
286
|
+
|
287
|
+
# Domain Error Retry.. Then.. Finaly..
|
288
|
+
* * F,2h,10m; F,24h,1h; F,4d,6h
|
289
|
+
|
290
|
+
begin authenticators
|
291
|
+
|
292
|
+
plain:
|
293
|
+
driver = plaintext
|
294
|
+
public_name = PLAIN
|
295
|
+
server_set_id = $2
|
296
|
+
server_debug_print = yes
|
297
|
+
server_prompts = :
|
298
|
+
server_condition = \
|
299
|
+
"${if and { \
|
300
|
+
{!eq{$2}{}} \
|
301
|
+
{!eq{$3}{}} \
|
302
|
+
{crypteq{$3}{\\{sha1\\}${lookup sqlite{SQLITE_DATABASE_FILE \
|
303
|
+
SELECT mailboxes.password \
|
304
|
+
FROM mailboxes, domains \
|
305
|
+
WHERE mailboxes.localpart = '${quote_sqlite:${local_part:$auth2}}' \
|
306
|
+
AND domains.fqdn = '${quote_sqlite:${domain:$auth2}}' \
|
307
|
+
AND domains.id = mailboxes.domain_id} \
|
308
|
+
{$value}fail}} }} {yes}{no}}"
|
data/lib/smailr/alias.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Smailr
|
2
|
+
module Alias
|
3
|
+
def self.add(source, destinations)
|
4
|
+
srclocalpart, srcdomain = source.split('@')
|
5
|
+
|
6
|
+
# We don't want aliases for non-local domains, since the
|
7
|
+
# exim router won't accept it.
|
8
|
+
if not Model::Domain[:fqdn => srcdomain].exists?
|
9
|
+
say_error "You are trying to add an alias for a non-local domain: #{source}"
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
|
13
|
+
destinations.each do |dst|
|
14
|
+
dstlocalpart, dstdomain = dst.split('@')
|
15
|
+
|
16
|
+
Model::Alias.find_or_create(:domain => Model::Domain[:fqdn => srcdomain],
|
17
|
+
:localpart => srclocalpart,
|
18
|
+
:dstdomain => dstdomain,
|
19
|
+
:dstlocalpart => dstlocalpart)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.rm(source, destinations)
|
24
|
+
srclocalpart, srcdomain = source.split('@')
|
25
|
+
|
26
|
+
destinations.each do |dst|
|
27
|
+
dstlocalpart, dstdomain = dst.split('@')
|
28
|
+
|
29
|
+
Model::Alias.filter(:domain => Model::Domain[:fqdn => srcdomain],
|
30
|
+
:localpart => srclocalpart,
|
31
|
+
:dstdomain => dstdomain,
|
32
|
+
:dstlocalpart => dstlocalpart).delete
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/smailr/dkim.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module Smailr
|
5
|
+
module Dkim
|
6
|
+
def self.add(fqdn, options)
|
7
|
+
options.testing ||= true
|
8
|
+
|
9
|
+
if not Model::Domain[:fqdn => fqdn]
|
10
|
+
say_error "You trying to add a DKIM key for a non existing domain: #{fqdn}"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
private_key, public_key = generate_rsa_key
|
15
|
+
dkim = Model::Dkim.for_domain!(fqdn)
|
16
|
+
dkim.set(:private_key => private_key,
|
17
|
+
:public_key => public_key,
|
18
|
+
:testing => options.testing)
|
19
|
+
dkim.save
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.rm(fqdn, options)
|
23
|
+
dkim = Model::Dkim.for_domain(fqdn)
|
24
|
+
dkim.destroy
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.generate_rsa_key(length = 1024)
|
30
|
+
rsa_key = OpenSSL::PKey::RSA.new(length)
|
31
|
+
[ rsa_key.to_pem,
|
32
|
+
rsa_key.public_key.to_pem ]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Smailr
|
2
|
+
module Domain
|
3
|
+
def self.add(fqdn)
|
4
|
+
puts "Adding domain: #{fqdn}"
|
5
|
+
Model::Domain.create(:fqdn => fqdn)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.rm(fqdn, force = false)
|
9
|
+
if force or
|
10
|
+
agree("Do you want to remove the domain #{fqdn} and all related items? (yes/no) ")
|
11
|
+
|
12
|
+
domain = Model::Domain[:fqdn => fqdn]
|
13
|
+
domain.rm_related
|
14
|
+
domain.destroy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Smailr
|
2
|
+
module Mailbox
|
3
|
+
def self.add(address, password)
|
4
|
+
fqdn = address.split('@')[1]
|
5
|
+
|
6
|
+
if not Model::Domain[:fqdn => fqdn]
|
7
|
+
say_error "Trying to add a mailbox for a non existing domain: #{fqdn}"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
mbox = Model::Mailbox.for_address!(address)
|
12
|
+
mbox.password = password
|
13
|
+
mbox.save
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.rm(address, options)
|
17
|
+
mbox = Model::Mailbox.for_address(address)
|
18
|
+
mbox.rm_related
|
19
|
+
mbox.destroy
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/smailr/model.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Smailr
|
4
|
+
module Model
|
5
|
+
class Domain < Sequel::Model
|
6
|
+
one_to_many :mailboxes
|
7
|
+
one_to_many :aliases
|
8
|
+
one_to_many :dkims
|
9
|
+
|
10
|
+
def rm_related
|
11
|
+
self.remove_all_mailboxes
|
12
|
+
self.remove_all_aliases
|
13
|
+
self.remove_all_dkims
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Dkim < Sequel::Model
|
18
|
+
many_to_one :domain
|
19
|
+
|
20
|
+
def self.for_domain(fqdn)
|
21
|
+
self[:domain => Domain[:fqdn => fqdn]]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.for_domain!(fqdn)
|
25
|
+
find_or_create(:domain => Domain[:fqdn => fqdn])
|
26
|
+
end
|
27
|
+
one_to_many :aliases
|
28
|
+
end
|
29
|
+
|
30
|
+
class Mailbox < Sequel::Model
|
31
|
+
many_to_one :domain
|
32
|
+
|
33
|
+
def password=(clear)
|
34
|
+
self[:password] = Digest::SHA1.hexdigest(clear)
|
35
|
+
end
|
36
|
+
|
37
|
+
def rm_related
|
38
|
+
self.aliases.destroy
|
39
|
+
end
|
40
|
+
|
41
|
+
def aliases
|
42
|
+
Model::Alias.where(
|
43
|
+
:dstlocalpart => self.localpart,
|
44
|
+
:dstdomain => self.domain.fqdn
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.domain(fqdn)
|
49
|
+
Domain[:fqdn => fqdn]
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.for_address(address)
|
53
|
+
localpart, fqdn = address.split('@')
|
54
|
+
self[:localpart => localpart, :domain => domain(fqdn)]
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.for_address!(address)
|
58
|
+
localpart, fqdn = address.split('@')
|
59
|
+
find_or_create(:localpart => localpart, :domain => domain(fqdn))
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
class Alias < Sequel::Model
|
65
|
+
many_to_one :domain
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/smailr.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sqlite3'
|
3
|
+
require 'sequel'
|
4
|
+
require 'commander/import'
|
5
|
+
|
6
|
+
module Smailr
|
7
|
+
autoload :Model, 'smailr/model'
|
8
|
+
autoload :Domain, 'smailr/domain'
|
9
|
+
autoload :Mailbox, 'smailr/mailbox'
|
10
|
+
autoload :Alias, 'smailr/alias'
|
11
|
+
autoload :Dkim, 'smailr/dkim'
|
12
|
+
|
13
|
+
class << self;
|
14
|
+
attr_accessor :contrib_directory
|
15
|
+
attr_accessor :migrations_directory
|
16
|
+
end
|
17
|
+
|
18
|
+
VERSION = '0.3.0'
|
19
|
+
end
|
20
|
+
|
21
|
+
Smailr.contrib_directory ||= File.expand_path('../../contrib', __FILE__)
|
22
|
+
Smailr.migrations_directory ||= File.expand_path('../../migrations', __FILE__)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
change do
|
3
|
+
create_table :aliases do
|
4
|
+
primary_key :id
|
5
|
+
foreign_key :domain_id
|
6
|
+
String :localpart
|
7
|
+
String :dstlocalpart
|
8
|
+
String :dstdomain
|
9
|
+
index [:domain_id, :localpart, :dstlocalpart, :dstdomain], :unique => true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
change do
|
3
|
+
create_table :dkims do
|
4
|
+
primary_key :id
|
5
|
+
foreign_key :domain_id
|
6
|
+
String :private_key, :required => true
|
7
|
+
String :public_key, :required => true
|
8
|
+
String :mode, :required => true
|
9
|
+
Boolean :testing, :required => true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smailr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Stefan Schlesinger
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-04-26 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: commander
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: sqlite3
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: sequel
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
description: |-
|
63
|
+
Smailr is a CLI tool which lets you manage your Exim/Dovecot setup
|
64
|
+
from the shell. It currently uses SQLite as a backend.
|
65
|
+
email: sts@ono.at
|
66
|
+
executables:
|
67
|
+
- smailr
|
68
|
+
extensions: []
|
69
|
+
|
70
|
+
extra_rdoc_files: []
|
71
|
+
|
72
|
+
files:
|
73
|
+
- bin/smailr
|
74
|
+
- lib/smailr/alias.rb
|
75
|
+
- lib/smailr/dkim.rb
|
76
|
+
- lib/smailr/domain.rb
|
77
|
+
- lib/smailr/mailbox.rb
|
78
|
+
- lib/smailr/model.rb
|
79
|
+
- lib/smailr.rb
|
80
|
+
- contrib/dovecot-sql.conf
|
81
|
+
- contrib/dovecot.conf
|
82
|
+
- contrib/exim4.conf
|
83
|
+
- migrations/001_domains.rb
|
84
|
+
- migrations/002_mailboxes.rb
|
85
|
+
- migrations/003_aliases.rb
|
86
|
+
- migrations/004_dkims.rb
|
87
|
+
homepage: http://github.com/sts/smailr
|
88
|
+
licenses: []
|
89
|
+
|
90
|
+
post_install_message: |+
|
91
|
+
|
92
|
+
|
93
|
+
SMAILR /////////////////////////////////////////////////////////////////
|
94
|
+
|
95
|
+
To finish the installation copy the example Exim and Dovecot
|
96
|
+
configuration files from the contrib directory and run
|
97
|
+
'smailr migrate' to initialize the database.
|
98
|
+
|
99
|
+
//////////////////////////////////////////////////////////////// ///////
|
100
|
+
|
101
|
+
rdoc_options: []
|
102
|
+
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 3
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
hash: 3
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
version: "0"
|
123
|
+
requirements:
|
124
|
+
- Exim
|
125
|
+
- Dovecot
|
126
|
+
- Debian
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.8.21
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Simple MAIL manageR - Virtual mail hosting management from the CLI
|
132
|
+
test_files: []
|
133
|
+
|