schleuder 2.2.3 → 2.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/bin/schleuder-migrate-v2.1-to-v2.2 +27 -7
- data/bin/schleuder-newlist +27 -11
- data/contrib/check-expired-keys.rb +2 -2
- data/ext/default-list.conf +4 -1
- data/ext/schleuder.conf +11 -5
- data/lib/schleuder/crypt.rb +1 -1
- data/lib/schleuder/list.rb +20 -3
- data/lib/schleuder/log/listlogger.rb +3 -2
- data/lib/schleuder/log/outputter/emailoutputter.rb +2 -0
- data/lib/schleuder/log/schleuderlogger.rb +18 -7
- data/lib/schleuder/mail.rb +71 -66
- data/lib/schleuder/processor.rb +4 -4
- data/lib/schleuder/schleuder_config.rb +5 -2
- data/lib/schleuder/version.rb +1 -1
- data/man/schleuder-newlist.8 +7 -0
- data/plugins/manage_members_plugin.rb +18 -14
- data/plugins/sign_this_plugin.rb +14 -0
- metadata +51 -64
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c37622657ee9683d0d006af23a4fb74d53c1c697
|
4
|
+
data.tar.gz: 992426df30d2c0de1e97a9d9b611fc5dbc2d1557
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a4fa65cbe451d2880ef8f38201565c5672c8f41ebff22f8579f1e2ce3aef44f6aeb043e3d93610a55450e7296341ed8689bcf8bfc96dd40847b5d7ce1e987f5
|
7
|
+
data.tar.gz: 5238664faab3274a9803bc11a9ef0a91f0c46392a825c7cfe2e040efd0cfc1b3ea2d09fa2982ac8ef9419e3ba13a0ec2a6d81bed2f484fa5846a6a5cec7c666d
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
CHANGED
Binary file
|
@@ -50,7 +50,7 @@ def member_key(member)
|
|
50
50
|
member
|
51
51
|
end
|
52
52
|
|
53
|
-
def fix_list_conf(old_config,new_dir)
|
53
|
+
def fix_list_conf(old_config,new_dir,new_conf_path)
|
54
54
|
if old_config.delete('logging').to_s == 'true' && !old_config['lists_logfile'].nil?
|
55
55
|
old_config['log_file'] = old_config.delete('lists_logfile')
|
56
56
|
end
|
@@ -69,7 +69,7 @@ def fix_list_conf(old_config,new_dir)
|
|
69
69
|
end
|
70
70
|
old_config['key_fingerprint'] = Schleuder.list.key_fingerprint
|
71
71
|
|
72
|
-
File.open(
|
72
|
+
File.open(new_conf_path,'w') { |f| f << YAML::dump(old_config.to_hash) }
|
73
73
|
# reload list config
|
74
74
|
Schleuder.list = Schleuder::List.new(old_config['myaddr'])
|
75
75
|
end
|
@@ -161,11 +161,20 @@ end
|
|
161
161
|
|
162
162
|
## run
|
163
163
|
|
164
|
-
|
165
164
|
old_config = YAML.load_file(list_config)
|
166
|
-
|
167
|
-
|
168
|
-
|
165
|
+
|
166
|
+
if Schleuder.config.lists_configfile.end_with?('/')
|
167
|
+
# Common configuration for all lists
|
168
|
+
old_name = File.basename(list_config).gsub(/\.conf\Z/, '')
|
169
|
+
common_list_config_dir = true
|
170
|
+
else
|
171
|
+
# Configuration in list directory
|
172
|
+
old_name = File.basename(File.dirname(list_config))
|
173
|
+
end
|
174
|
+
|
175
|
+
old_config['myname'] ||= old_name
|
176
|
+
Schleuder.list = Schleuder::List.new(old_name)
|
177
|
+
old_dir = File.join(Schleuder.config.lists_dir, old_name)
|
169
178
|
|
170
179
|
files = Dir["#{old_dir}/*"].inject({}) do |files, file|
|
171
180
|
files[File.basename(file)] = [:uid, :gid, :mode].inject({}) do |hash, sym|
|
@@ -178,8 +187,19 @@ end
|
|
178
187
|
ENV['GNUPGHOME'] = new_dir = move_listdir(old_dir,old_config)
|
179
188
|
ENV.delete('GPG_AGENT_INFO') # might interfer with changing uids
|
180
189
|
|
190
|
+
if common_list_config_dir
|
191
|
+
# Move list configuration file to its new location
|
192
|
+
local_part, domain = old_config['myaddr'].split('@')
|
193
|
+
domain_dir = File.join(Schleuder.config.lists_configfile, domain)
|
194
|
+
FileUtils.mkdir_p domain_dir
|
195
|
+
new_conf_path = "#{domain_dir}/#{local_part}.conf"
|
196
|
+
FileUtils.mv list_config, new_conf_path
|
197
|
+
else
|
198
|
+
new_conf_path = File.join(new_dir, Schleuder.config.lists_configfile)
|
199
|
+
end
|
200
|
+
|
181
201
|
change_pubkey(old_config)
|
182
|
-
fix_list_conf(old_config, new_dir)
|
202
|
+
fix_list_conf(old_config, new_dir, new_conf_path)
|
183
203
|
harden_members
|
184
204
|
|
185
205
|
# Fix owner/modes if changed
|
data/bin/schleuder-newlist
CHANGED
@@ -18,6 +18,7 @@ class ListCreator
|
|
18
18
|
-initmember member1@foobar.com -initmemberkey /path/to/initmember_publickey
|
19
19
|
Optional options (flags on the same line have to be used together):
|
20
20
|
-mailuser mail (The user, which will invoke schleuder from your MTA, if non is supplied, the current user is taken)
|
21
|
+
-mailgroup mail (The group, with which schleuder will be invoked from your MTA, if non is supplied, the current group is taken)
|
21
22
|
-privatekeyfile /path/to/privatekey -publickeyfile /path/to/publickey -passphrase key_passphrase
|
22
23
|
-nointeractive
|
23
24
|
|
@@ -53,6 +54,8 @@ class ListCreator
|
|
53
54
|
args[:list_passphrase] = ARGV.shift
|
54
55
|
elsif nextarg == '-mailuser'
|
55
56
|
args[:mailuser] = ARGV.shift
|
57
|
+
elsif nextarg == '-mailgroup'
|
58
|
+
args[:mailgroup] = ARGV.shift
|
56
59
|
elsif nextarg == '-nointeractive'
|
57
60
|
interactive = false
|
58
61
|
else
|
@@ -109,6 +112,11 @@ class ListCreator
|
|
109
112
|
else
|
110
113
|
mailuser = Process::Sys.getuid
|
111
114
|
end
|
115
|
+
unless args[:mailgroup].nil?
|
116
|
+
mailgroup = Etc.getgrnam(args[:mailgroup]).gid
|
117
|
+
else
|
118
|
+
mailgroup = Process::Sys.getuid
|
119
|
+
end
|
112
120
|
unless (list_privatekeyfile == 'none') and
|
113
121
|
(list_publickeyfile == 'none') and
|
114
122
|
(list_passphrase == 'none') then
|
@@ -184,10 +192,11 @@ class ListCreator
|
|
184
192
|
end
|
185
193
|
|
186
194
|
# store the config
|
195
|
+
FileUtils.mkdir_p File.dirname(list.configfile)
|
187
196
|
Schleuder.log.debug "Store list config..."
|
188
197
|
list.config = list.config
|
189
198
|
Schleuder.log.debug "Changing ownership..."
|
190
|
-
ListCreator::filepermissions(list, mailuser)
|
199
|
+
ListCreator::filepermissions(list, mailuser, mailgroup)
|
191
200
|
Schleuder.log.debug "List successfully created..."
|
192
201
|
ListCreator::print_list_infos(list) if interactive
|
193
202
|
end
|
@@ -221,7 +230,7 @@ class ListCreator
|
|
221
230
|
end
|
222
231
|
yield(var) if block_given?
|
223
232
|
raise NewListError,"Missing mandatory variable: "+question if (var.nil? or var.empty?)
|
224
|
-
var
|
233
|
+
var.to_s
|
225
234
|
end
|
226
235
|
|
227
236
|
def self.verify_emailvar(var,interactive,question)
|
@@ -239,7 +248,7 @@ class ListCreator
|
|
239
248
|
var = ask("Filepath for "+question+": ")
|
240
249
|
end
|
241
250
|
raise NewListError,"Missing mandatory file: "+question if (not var.nil? and not File.exist?(var))
|
242
|
-
var
|
251
|
+
var.to_s
|
243
252
|
end
|
244
253
|
|
245
254
|
def self.progfunc(hook, what, type, current, total)
|
@@ -358,22 +367,29 @@ Passphrase: #{pass}
|
|
358
367
|
</GnupgKeyParms>"
|
359
368
|
end
|
360
369
|
|
361
|
-
def self.filepermissions(list, mailuser)
|
370
|
+
def self.filepermissions(list, mailuser, mailgroup)
|
362
371
|
listdir = list.listdir
|
363
|
-
|
364
|
-
FileUtils.
|
365
|
-
FileUtils.chmod 0700, dirs
|
372
|
+
FileUtils.chown(mailuser, mailgroup, listdir)
|
373
|
+
FileUtils.chmod(0700, listdir)
|
366
374
|
Dir.new(listdir).each{ |f|
|
367
375
|
unless f =~ /^\./
|
368
|
-
File.
|
369
|
-
File.
|
376
|
+
file = File.join(listdir,f)
|
377
|
+
File.chown(mailuser,mailgroup,file)
|
378
|
+
File.chmod(0600,file)
|
370
379
|
end
|
371
380
|
}
|
381
|
+
FileUtils.chown mailuser, mailgroup, list.configfile
|
382
|
+
FileUtils.chmod 0600, list.configfile
|
383
|
+
# do we have a shared directory?
|
384
|
+
# otherwise it's the listdir itself
|
385
|
+
if Schleuder.config.lists_configfile.end_with?('/')
|
386
|
+
FileUtils.chmod 0750, File.dirname(list.configfile)
|
387
|
+
end
|
372
388
|
if list.config.log_file
|
373
389
|
log_file = list.config.log_file
|
374
390
|
log_file = File.join(listdir, log_file) unless log_file.start_with?('/')
|
375
|
-
FileUtils.chown
|
376
|
-
FileUtils.chmod
|
391
|
+
FileUtils.chown(mailuser, mailgroup, log_file)
|
392
|
+
FileUtils.chmod(0600, log_file)
|
377
393
|
end
|
378
394
|
end
|
379
395
|
|
@@ -24,7 +24,7 @@ listname = ARGV.first
|
|
24
24
|
Schleuder.list = List.new(listname)
|
25
25
|
|
26
26
|
now = Time.now
|
27
|
-
checkdate = now +
|
27
|
+
checkdate = now + (60 * 60 * 24 * 14) # two weeks
|
28
28
|
crypt = Crypt.new('')
|
29
29
|
msg = ''
|
30
30
|
unusable = []
|
@@ -54,7 +54,7 @@ unusable.each do |key,trust|
|
|
54
54
|
end
|
55
55
|
|
56
56
|
unless msg.empty?
|
57
|
-
prefix = "Checking the public keys present in the keyring of list #{listname} for usability gave the following result:".fmt
|
57
|
+
prefix = "Checking the public keys present in the keyring of list #{listname} for usability gave the following result:".fmt(72)
|
58
58
|
Schleuder.log.notify_admin('keys', prefix + "\n\n" + msg)
|
59
59
|
end
|
60
60
|
|
data/ext/default-list.conf
CHANGED
@@ -88,7 +88,10 @@
|
|
88
88
|
#log_io: false
|
89
89
|
#
|
90
90
|
# Log to a file? To enable specify a filename, optionally with full path.
|
91
|
-
#
|
91
|
+
# If you specify a directory (ending with '/'), the file will be named
|
92
|
+
# "$LISTNAME.log" in that directory.
|
93
|
+
# To disable logging to a file set to false.
|
94
|
+
#log_file: 'list.log'
|
92
95
|
#
|
93
96
|
# speaks for itself, no?
|
94
97
|
#public_footer:
|
data/ext/schleuder.conf
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
#gpg_key_type: RSA
|
14
14
|
#
|
15
15
|
# Set the length of a key we might create for new lists.
|
16
|
-
#gpg_key_length:
|
16
|
+
#gpg_key_length: 4096
|
17
17
|
#
|
18
18
|
# Set the type of the subkey of a key we might create
|
19
19
|
# for new lists.
|
@@ -21,9 +21,12 @@
|
|
21
21
|
#
|
22
22
|
# Set the length of the subkey of a key we might create
|
23
23
|
# for new lists.
|
24
|
-
#gpg_subkey_length:
|
24
|
+
#gpg_subkey_length: 4096
|
25
25
|
#
|
26
|
-
# Name of the per list config file.
|
26
|
+
# Name of the per list config file. Either:
|
27
|
+
# - a file name that resides in the list data directory,
|
28
|
+
# - a directory, ending with '/' holding list configs as
|
29
|
+
# "$DOMAIN/$LISTNAME.conf".
|
27
30
|
#lists_configfile: list.conf
|
28
31
|
#
|
29
32
|
# Name of the per list file containing all members and their
|
@@ -38,7 +41,8 @@
|
|
38
41
|
# Location of the various schleuderlists' directory.
|
39
42
|
#lists_dir: /var/schleuderlists
|
40
43
|
#
|
41
|
-
# Location of the global logfile.
|
44
|
+
# Location of the global logfile. Specify "syslog" to log through
|
45
|
+
# the syslog(3) facility.
|
42
46
|
#log_file: /var/log/schleuder/schleuder.log
|
43
47
|
#
|
44
48
|
# Global schleuder log level, might change after the list config
|
@@ -48,7 +52,9 @@
|
|
48
52
|
#
|
49
53
|
# Location of schleuder plugins. Note: the following notion
|
50
54
|
# isn't valid. You have to provide a fully qualified path.
|
51
|
-
#
|
55
|
+
# Multiple plugins directory are supported.
|
56
|
+
#plugins_dir:
|
57
|
+
#-schleuder_base + '/plugins'
|
52
58
|
#
|
53
59
|
# The super administrator of this schleuder installation. This
|
54
60
|
# address will receive all notices which can'tbe delivered to a certain list
|
data/lib/schleuder/crypt.rb
CHANGED
@@ -91,7 +91,7 @@ module Schleuder
|
|
91
91
|
# TODO: return mailadresses or keys instead of signature-objects?
|
92
92
|
[output, in_encrypted, in_signed]
|
93
93
|
rescue GPGME::Error::General => exc
|
94
|
-
Schleuder.log.warn
|
94
|
+
Schleuder.log.warn "gpgme returned a general error. Most likely this is due to unexpected input, but as you never know here's the input and the exception:\ninput:\n#{str.inspect}\n#{exc.to_s}\n#{exc.backtrace[0..9].join("\n")}"
|
95
95
|
[str, nil, nil]
|
96
96
|
end
|
97
97
|
|
data/lib/schleuder/list.rb
CHANGED
@@ -88,10 +88,27 @@ module Schleuder
|
|
88
88
|
else
|
89
89
|
@config = ListConfig.new(data)
|
90
90
|
end
|
91
|
-
_write(YAML::dump(@config.to_hash),
|
91
|
+
_write(YAML::dump(@config.to_hash), configfile)
|
92
92
|
@config
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
|
+
# Returns path to the list configuration file
|
96
|
+
def configfile
|
97
|
+
# If `lists_configfile` ends with a '/', assume its pointing to a
|
98
|
+
# directory where configuration files are named "$DOMAIN/$LISTNAME.conf".
|
99
|
+
if Schleuder.config.lists_configfile.end_with?('/')
|
100
|
+
local_part, domain = listname.split('@')
|
101
|
+
if domain.nil?
|
102
|
+
# pre 2.2 style
|
103
|
+
File.join(Schleuder.config.lists_configfile, "#{local_part}.conf")
|
104
|
+
else
|
105
|
+
File.join(Schleuder.config.lists_configfile, domain, "#{local_part}.conf")
|
106
|
+
end
|
107
|
+
else
|
108
|
+
File.join(@listdir, Schleuder.config.lists_configfile)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
95
112
|
# Builds the bounce-address for the list
|
96
113
|
def bounce_addr
|
97
114
|
@bounce_addr ||= self.config.myaddr.gsub(/^(.*)@(.*)$/, '\1-bounce@\2')
|
@@ -146,7 +163,7 @@ module Schleuder
|
|
146
163
|
# Loads the configuration
|
147
164
|
def _load_config
|
148
165
|
Schleuder.log.debug("reading list-config for: #{@listname}") unless Schleuder.log.nil?
|
149
|
-
@config = ListConfig.new(
|
166
|
+
@config = ListConfig.new(configfile)
|
150
167
|
end
|
151
168
|
|
152
169
|
def find_by_key(ary, key)
|
@@ -18,6 +18,7 @@ module Schleuder
|
|
18
18
|
require 'log4r/outputter/fileoutputter'
|
19
19
|
filename = config.log_file
|
20
20
|
filename = File.join(listdir, filename) unless filename[0..0].eql?('/')
|
21
|
+
filename = File.join(filename, "#{listname}.log") if filename.end_with?('/')
|
21
22
|
add Log4r::FileOutputter.new("file",
|
22
23
|
{ :level => @level,
|
23
24
|
:filename => filename,
|
@@ -27,10 +28,10 @@ module Schleuder
|
|
27
28
|
|
28
29
|
if config.log_syslog
|
29
30
|
require 'log4r/outputter/syslogoutputter'
|
30
|
-
syslogfmtr = Log4r::PatternFormatter.new(:pattern => "#{listname}
|
31
|
+
syslogfmtr = Log4r::PatternFormatter.new(:pattern => "#{listname}: %M")
|
31
32
|
add Log4r::SyslogOutputter.new("syslog",
|
32
33
|
{ :level => @level,
|
33
|
-
:ident => '
|
34
|
+
:ident => 'schleuder',
|
34
35
|
:facility => "LOG_MAIL",
|
35
36
|
:formatter => syslogfmtr }
|
36
37
|
)
|
@@ -6,6 +6,8 @@ module Schleuder
|
|
6
6
|
:from => Schleuder.config.myaddr,
|
7
7
|
:'error-to' => Schleuder.config.superadminaddr,
|
8
8
|
:subject => 'Error',
|
9
|
+
:server => Schleuder.config.smtp_host,
|
10
|
+
:port => Schleuder.config.smtp_port,
|
9
11
|
:immediate_at => 'ERROR, FATAL',
|
10
12
|
:formatter => formatter,
|
11
13
|
:domain => 'schleuder', # necessary for log4r from debian "stable"
|
@@ -8,13 +8,24 @@ module Schleuder
|
|
8
8
|
super 'log4r'
|
9
9
|
# The initial log_level is inherited by all outputters.
|
10
10
|
@level = eval("Log4r::#{Schleuder.config.log_level.upcase}")
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
if Schleuder.config.log_file == 'syslog'
|
12
|
+
formatter = Log4r::PatternFormatter.new(:pattern => "%M")
|
13
|
+
require 'log4r/outputter/syslogoutputter'
|
14
|
+
add Log4r::SyslogOutputter.new('syslog',
|
15
|
+
{ :level => @level,
|
16
|
+
:ident => 'schleuder',
|
17
|
+
:facility => "LOG_MAIL",
|
18
|
+
:formatter => formatter }
|
19
|
+
)
|
20
|
+
else
|
21
|
+
pattern = "%d Schleuder %l\t%M"
|
22
|
+
formatter = Log4r::PatternFormatter.new(:pattern => pattern)
|
23
|
+
add Log4r::FileOutputter.new('file',
|
24
|
+
{ :level => @level,
|
25
|
+
:filename => Schleuder.config.log_file,
|
26
|
+
:formatter => formatter }
|
27
|
+
)
|
28
|
+
end
|
18
29
|
add MetaEmailOutputter.new('email',
|
19
30
|
{:to => Schleuder.config.superadminaddr,
|
20
31
|
:immediate_at => 'ERROR, FATAL'})
|
data/lib/schleuder/mail.rb
CHANGED
@@ -326,7 +326,7 @@ module Schleuder
|
|
326
326
|
new = Mail.new
|
327
327
|
new.crypt = crypt
|
328
328
|
# add some headers we want to keep
|
329
|
-
new.content_type = self['content-type'].to_s if self['content-type']
|
329
|
+
new.content_type = self['content-type'].to_s if self['content-type'] && !self['content-type'].illegal?
|
330
330
|
new.disposition = self._disposition
|
331
331
|
new.encoding = self.encoding.to_s
|
332
332
|
new.subject = _quote_if_necessary(self.subject.to_s,'UTF-8')
|
@@ -349,8 +349,9 @@ module Schleuder
|
|
349
349
|
|
350
350
|
def individualize_member(recv)
|
351
351
|
new = self.individualize(recv)
|
352
|
-
_message_ids(new) if Schleuder.list.config.keep_msgid
|
353
|
-
_list_headers(new) if Schleuder.list.config.include_list_headers
|
352
|
+
new = _message_ids(new) if Schleuder.list.config.keep_msgid
|
353
|
+
new = _list_headers(new) if Schleuder.list.config.include_list_headers
|
354
|
+
new
|
354
355
|
end
|
355
356
|
|
356
357
|
# Strips keywords from self and stores them in @+keywords+
|
@@ -366,7 +367,7 @@ module Schleuder
|
|
366
367
|
a = b.body.split("\n")
|
367
368
|
|
368
369
|
a.map! do |line|
|
369
|
-
if line.match(/^X-.*/)
|
370
|
+
if line.match(/^X-.*/i)
|
370
371
|
Schleuder.log.debug "found keyword-line: #{line.chomp}"
|
371
372
|
key, val = $&.split(/:|: | /, 2)
|
372
373
|
keyword = key.slice(2..-1).strip
|
@@ -377,7 +378,7 @@ module Schleuder
|
|
377
378
|
line
|
378
379
|
else
|
379
380
|
# Split values to catch multiple values separated by comma or the like (deprecated).
|
380
|
-
values = val.to_s.strip.split(/[
|
381
|
+
values = val.to_s.strip.split(/[,;]+/)
|
381
382
|
values << ' ' if values.empty?
|
382
383
|
values.each do |v|
|
383
384
|
Schleuder.log.info "Storing keyword #{keyword} with value #{v.inspect}"
|
@@ -426,73 +427,77 @@ module Schleuder
|
|
426
427
|
def process_plugins!
|
427
428
|
if self.keywords.empty?
|
428
429
|
Schleuder.log.info 'No keywords present, skipping plugins'
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
430
|
+
else
|
431
|
+
Schleuder.config.plugins_dir.each do |plugins_dir|
|
432
|
+
if File.directory?(plugins_dir)
|
433
|
+
replymsg = ""
|
434
|
+
# We might want to replace the object later, which we can't do with self.
|
435
|
+
mail = self
|
436
|
+
plugins = {:request => [], :list => []}
|
437
|
+
ptype = (self.request? ? :request : :list)
|
438
|
+
used_keywords = []
|
439
|
+
Plugin.signing_key(self)
|
440
|
+
Dir[plugins_dir + '/*_plugin.rb'].each do |plugfile|
|
441
|
+
Schleuder.log.debug "Instanciating #{plugfile} as plugin"
|
442
|
+
require plugfile
|
443
|
+
# interpreting class name from file name
|
444
|
+
classname = File.basename(plugfile, '.rb').split('_').collect { |p| p.capitalize }.join
|
445
|
+
plugin = instance_eval(classname).new
|
446
|
+
Schleuder.log.debug "Storing plugin in plugin-list '#{plugin.plugin_type}'"
|
447
|
+
plugins[plugin.plugin_type] << plugin
|
448
|
+
end
|
449
|
+
# This is neither elegant nor fast, but it's got to live only until the rewrite.
|
450
|
+
Schleuder.log.debug "Processing #{ptype}-plugins"
|
451
|
+
self.keywords.each do |kwhash|
|
452
|
+
keyword = kwhash.keys.first
|
453
|
+
value = kwhash.values.first
|
454
|
+
Schleuder.log.debug "Looping for keyword #{keyword}"
|
455
|
+
plugins[ptype].each do |plugin|
|
456
|
+
command = keyword.downcase.gsub(/-/, '_')
|
457
|
+
Schleuder.log.debug "Does #{plugin.class}.respond_to? '#{command}'"
|
458
|
+
if plugin.respond_to?(command)
|
459
|
+
Schleuder.log.debug "Yes it does, executing #{plugin.class}.#{command}"
|
460
|
+
used_keywords << keyword
|
461
|
+
foo = plugin.send(command, mail, value)
|
462
|
+
case foo
|
463
|
+
when String
|
464
|
+
Schleuder.log.debug "Method returned a string, saving it for reply to sender."
|
465
|
+
replymsg << foo << "\n\n\n"
|
466
|
+
when Mail
|
467
|
+
Schleuder.log.debug "Method returned a Mail-object, replacing myself by it."
|
468
|
+
mail = foo
|
469
|
+
else
|
470
|
+
Schleuder.log.debug "Method returned '#{foo.inspect}', don't know how to handle, skipping."
|
471
|
+
end
|
472
|
+
next
|
473
|
+
else
|
474
|
+
Schleuder.log.debug "No it doesn't."
|
475
|
+
end
|
476
|
+
end
|
477
|
+
# Generate error-message if no plugin was executed
|
478
|
+
unless used_keywords.include?(keyword)
|
479
|
+
msg = "No #{ptype}-plugin responded to keyword #{keyword}"
|
480
|
+
Schleuder.log.debug msg
|
481
|
+
if mail.request?
|
482
|
+
replymsg << "Error: #{msg}.\n\n"
|
483
|
+
else
|
484
|
+
mail.metadata[:error] << msg
|
485
|
+
end
|
468
486
|
end
|
469
|
-
next
|
470
|
-
else
|
471
|
-
Schleuder.log.debug "No it doesn't."
|
472
487
|
end
|
473
|
-
|
474
|
-
# Generate error-message if no plugin was executed
|
475
|
-
unless used_keywords.include?(keyword)
|
476
|
-
msg = "No #{ptype}-plugin responded to keyword #{keyword}"
|
477
|
-
Schleuder.log.debug msg
|
488
|
+
# Decide how to go on: reply or list?
|
478
489
|
if mail.request?
|
479
|
-
|
480
|
-
|
481
|
-
|
490
|
+
Schleuder.log.debug "Message is a request, sending plugins-output back to sender."
|
491
|
+
if replymsg.empty?
|
492
|
+
replymsg = 'The keywords you sent did not produce any output. If you feel this is an error please contact the adminisrators of this list.'.fmt
|
493
|
+
end
|
494
|
+
# This exits.
|
495
|
+
Plugin.reply(mail, replymsg, used_keywords)
|
482
496
|
end
|
497
|
+
else
|
498
|
+
Schleuder.log.error "#{plugins_dir} does not exist or is not readable!"
|
483
499
|
end
|
484
500
|
end
|
485
|
-
# Decide how to go on: reply or list?
|
486
|
-
if mail.request?
|
487
|
-
Schleuder.log.debug "Message is a request, sending plugins-output back to sender."
|
488
|
-
if replymsg.empty?
|
489
|
-
replymsg = 'The keywords you sent did not produce any output. If you feel this is an error please contact the adminisrators of this list.'.fmt
|
490
|
-
end
|
491
|
-
# This exits.
|
492
|
-
Plugin.reply(mail, replymsg, used_keywords)
|
493
|
-
end
|
494
|
-
else
|
495
|
-
Schleuder.log.error "#{Schleuder.config.plugins_dir} does not exist or is not readable!"
|
496
501
|
end
|
497
502
|
end
|
498
503
|
|
data/lib/schleuder/processor.rb
CHANGED
@@ -39,7 +39,7 @@ module Schleuder
|
|
39
39
|
|
40
40
|
class Processor
|
41
41
|
def self.run(listname, message)
|
42
|
-
Schleuder.listname
|
42
|
+
Schleuder.listname(listname)
|
43
43
|
Schleuder.origmsg = message
|
44
44
|
Schleuder.log.debug "Testing if list-dir exists"
|
45
45
|
unless File.directory?(List.listdir(listname))
|
@@ -127,7 +127,7 @@ module Schleuder
|
|
127
127
|
end
|
128
128
|
|
129
129
|
if Schleuder.list.config.receive_authenticated_only && !(mail.from_member || mail.from_admin)
|
130
|
-
self.bounce_or_drop "not authenticated", "This address
|
130
|
+
self.bounce_or_drop "not authenticated", "This address requires properly signed emails by its list-members. Either the signature can't be verified or is missing.", mail
|
131
131
|
end
|
132
132
|
|
133
133
|
if Schleuder.list.config.receive_from_member_emailaddresses_only && !(mail.from_member_address?||mail.from_admin_address?)
|
@@ -135,7 +135,7 @@ module Schleuder
|
|
135
135
|
end
|
136
136
|
|
137
137
|
if Schleuder.list.config.receive_admin_only && !mail.from_admin
|
138
|
-
self.bounce_or_drop "not authenticated as admin", "This address
|
138
|
+
self.bounce_or_drop "not authenticated as admin", "This address requires properly signed emails by its list-admins. Either the signature can't be verified or is missing.", mail
|
139
139
|
end
|
140
140
|
|
141
141
|
if mail.to.to_a.include?(Schleuder.list.request_addr)
|
@@ -337,7 +337,7 @@ module Schleuder
|
|
337
337
|
|
338
338
|
# if we're still alive: bounce message
|
339
339
|
Schleuder.log.info "bouncing mail to sender"
|
340
|
-
self.bounce_notify_admin
|
340
|
+
self.bounce_notify_admin("#{status}. - #{bounce_msg}")
|
341
341
|
$stdout.puts bounce_msg
|
342
342
|
exit 100
|
343
343
|
end
|
@@ -47,13 +47,13 @@ module Schleuder
|
|
47
47
|
schleuder_attr :gpg_key_type, 'RSA'
|
48
48
|
|
49
49
|
# GPG-Key length.
|
50
|
-
schleuder_attr :gpg_key_length,
|
50
|
+
schleuder_attr :gpg_key_length, 4096
|
51
51
|
|
52
52
|
# GPG-Sub-Key type.
|
53
53
|
schleuder_attr :gpg_subkey_type, 'RSA'
|
54
54
|
|
55
55
|
# GPG-Sub-Key length.
|
56
|
-
schleuder_attr :gpg_subkey_length,
|
56
|
+
schleuder_attr :gpg_subkey_length, 4096
|
57
57
|
|
58
58
|
### END OF CONFIG OPTIONS
|
59
59
|
|
@@ -67,6 +67,9 @@ module Schleuder
|
|
67
67
|
|
68
68
|
# overload with config
|
69
69
|
super(config)
|
70
|
+
|
71
|
+
# turn @plugins_dir into an array if needed
|
72
|
+
@plugins_dir = [@plugins_dir] unless @plugins_dir.class == Array
|
70
73
|
end
|
71
74
|
end
|
72
75
|
end
|
data/lib/schleuder/version.rb
CHANGED
data/man/schleuder-newlist.8
CHANGED
@@ -34,6 +34,9 @@
|
|
34
34
|
\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~[\-mailuser \fIschleuder\fR]
|
35
35
|
.
|
36
36
|
.br
|
37
|
+
\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~[\-mailgroup \fIschleuder\fR]
|
38
|
+
.
|
39
|
+
.br
|
37
40
|
\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~\~[\-nointeractive]
|
38
41
|
.
|
39
42
|
.SH "DESCRIPTION"
|
@@ -89,6 +92,10 @@ Specify the passphrase needed to access the private key specified in \fB\-privat
|
|
89
92
|
Specify the system user account under which \fBschleuder\fR(8) will be executed (when run as root, this defaults to \fBschleuder\fR)\.
|
90
93
|
.
|
91
94
|
.TP
|
95
|
+
\fB\-mailgroup\fR \fIschleuder\fR
|
96
|
+
Specify the system group under which \fBschleuder\fR(8) will be executed (when run as root, this defaults to \fBschleuder\fR)\.
|
97
|
+
.
|
98
|
+
.TP
|
92
99
|
\fB\-nointeractive\fR
|
93
100
|
When specified, no questions will be asked to complete missing information\.
|
94
101
|
.
|
@@ -79,22 +79,26 @@ module Schleuder
|
|
79
79
|
email, mime = string.split(' ')
|
80
80
|
mem = Member.new({:email => email})
|
81
81
|
mem.mime = mime if mime
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
82
|
+
if Schleuder.list.members.any?{|m| m.email == mem.email }
|
83
|
+
msg = "--> Member is already part of the list. Nothing changed!"
|
84
|
+
msg << "\nExisting members-list:"
|
85
|
+
else
|
86
|
+
Schleuder.list.members = Schleuder.list.members << mem
|
87
|
+
msg = "#{mem}\n--> Member saved.\n\n"
|
88
|
+
if key
|
89
|
+
mail.crypt.add_key(key).imports.each do |i|
|
90
|
+
msg << "#{mail.crypt.key_descr(mail.crypt.get_key(i.fpr))}\n"
|
91
|
+
if i.status.eql? 1
|
92
|
+
msg << "--> Key imported.\n\n"
|
93
|
+
else
|
94
|
+
msg << "--> Key *not* imported (no error, maybe already present?).\n\n"
|
95
|
+
end
|
92
96
|
end
|
97
|
+
msg << "\n"
|
93
98
|
end
|
94
|
-
msg << "
|
99
|
+
msg << "Updated members-list:"
|
95
100
|
end
|
96
|
-
msg << "
|
97
|
-
msg
|
101
|
+
msg << "\n\n#{_list_members(Schleuder.list.members)}"
|
98
102
|
end
|
99
103
|
|
100
104
|
def deletemember(mail, string)
|
@@ -110,7 +114,7 @@ module Schleuder
|
|
110
114
|
msg = "Something failed. Please ask the maintainer of this list to figure out what\nhappened (e.g. by mailing to #{Schleuder.list.owner_addr}).\n"
|
111
115
|
end
|
112
116
|
end
|
113
|
-
msg << "\nUpdated members-list:\n\n#{_list_members(
|
117
|
+
msg << "\nUpdated members-list:\n\n#{_list_members(Schleuder.list.members)}\n"
|
114
118
|
msg
|
115
119
|
end
|
116
120
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Clearsigns the incoming body and sends the signed text back.
|
2
|
+
# Useful if the public key of a list is widely known: Let schleuder sign e.g.
|
3
|
+
# the fingerprints of your email servers certificates, and publish them online.
|
4
|
+
module Schleuder
|
5
|
+
class SignThisPlugin < Plugin
|
6
|
+
def initialize
|
7
|
+
@plugin_type = :request
|
8
|
+
end
|
9
|
+
|
10
|
+
def sign_this(mail)
|
11
|
+
mail.crypt.clearsign(mail.body)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,49 +1,42 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schleuder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
5
|
-
prerelease:
|
4
|
+
version: 2.2.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
7
|
+
- lunar
|
8
8
|
- paz
|
9
9
|
- ng
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain:
|
13
|
-
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
MjM4U3k3Y1l3emQ3CnZhZEhrZHMzNTRsbU4vajNhYW1kTXJyeHUyOTlvdTh1
|
37
|
-
am9IbGcxK3IxNjlsa2J1VHdXbEI2RlVXT1J3emhvMWIKOFlJWWRpT29jUHdm
|
38
|
-
Zi9BZ3l3UVdGZDRGV2VNV0xQeXRkK1VndzZCSmZSSXY2VC9OTVJKWWRIUDJW
|
39
|
-
M1RTUVJyTApSYXNUTTVlUzIrK3EwQT09Ci0tLS0tRU5EIENFUlRJRklDQVRF
|
40
|
-
LS0tLS0K
|
41
|
-
date: 2012-07-04 00:00:00.000000000 Z
|
13
|
+
- |
|
14
|
+
-----BEGIN CERTIFICATE-----
|
15
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDApzY2hs
|
16
|
+
ZXVkZXIyMRUwEwYKCZImiZPyLGQBGRYFbmFkaXIxEzARBgoJkiaJk/IsZAEZFgNv
|
17
|
+
cmcwHhcNMTMwOTI5MjAwNzQxWhcNMTQwOTI5MjAwNzQxWjBBMRMwEQYDVQQDDApz
|
18
|
+
Y2hsZXVkZXIyMRUwEwYKCZImiZPyLGQBGRYFbmFkaXIxEzARBgoJkiaJk/IsZAEZ
|
19
|
+
FgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChGruoNnq3Ir7d
|
20
|
+
Fd+ktG0tMZlm2ZSOkuHO5QRrgYLgbBhpTEf8i6AjzoVL0AIC+uMMVY9iE6fzaKUD
|
21
|
+
B7SvNtccHskX6zHUVVtSqF9VpbQomWpck0iBqwQIw4vELe2iZ+/ZULKIJI/BY43y
|
22
|
+
tX7Ora8izSyPGcu6E1fr5PJI6igFnlEgs/jCjP/JYHf/f49fnIzAJgO0Q7YNNJVr
|
23
|
+
R0Zqm1HbYE2t+RtomT2jgCjBtF42hX8+gB4yV5nedfHKyZfD6zd7doPE/pdtpn80
|
24
|
+
BrRQbHXlEPDCadHH013j7oL7B5fJlHejX6PFfPtepq3adDQ/O3lFvzfHuJUGjEO5
|
25
|
+
QXp7l5+fAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
26
|
+
BBSBtRuT8QNZTfwVGJKJr5bbDlgk3jAfBgNVHREEGDAWgRRzY2hsZXVkZXIyQG5h
|
27
|
+
ZGlyLm9yZzAfBgNVHRIEGDAWgRRzY2hsZXVkZXIyQG5hZGlyLm9yZzANBgkqhkiG
|
28
|
+
9w0BAQUFAAOCAQEAOW1oNWquxZegMjQDZF3yTDsXbDAs4JYsLEbjnD2z32nMGvat
|
29
|
+
wDxKD0g3XIPHEoEi28/3n6C4Py2J+P7gUObr+wWF8G67nwg2tDjarOia93RcpxqW
|
30
|
+
n4NKeyRmvEzQ+yU+X9xiwJ005mc2ME2j3QF+sjDxgd+uCN0ZT77qz2Kk4iuCGOrM
|
31
|
+
cuTmrcZdTiHkGhK7UtDn7nk3ShgwrtyC0SqPna+PUMYkPr5FQLVwsOHGExOtVHZX
|
32
|
+
+VhPezxtXTAQ0pIYXF5NssxnhcngHV8fPs0g4gbU0RRKar9egfgZ8cVITgVauVPt
|
33
|
+
HdW17U59V5gWNuJBqqwiV2PJubSZekUq/YMdtg==
|
34
|
+
-----END CERTIFICATE-----
|
35
|
+
date: 2013-09-30 00:00:00.000000000 Z
|
42
36
|
dependencies:
|
43
37
|
- !ruby/object:Gem::Dependency
|
44
38
|
name: gpgme
|
45
39
|
requirement: !ruby/object:Gem::Requirement
|
46
|
-
none: false
|
47
40
|
requirements:
|
48
41
|
- - '='
|
49
42
|
- !ruby/object:Gem::Version
|
@@ -51,7 +44,6 @@ dependencies:
|
|
51
44
|
type: :runtime
|
52
45
|
prerelease: false
|
53
46
|
version_requirements: !ruby/object:Gem::Requirement
|
54
|
-
none: false
|
55
47
|
requirements:
|
56
48
|
- - '='
|
57
49
|
- !ruby/object:Gem::Version
|
@@ -59,59 +51,49 @@ dependencies:
|
|
59
51
|
- !ruby/object:Gem::Dependency
|
60
52
|
name: highline
|
61
53
|
requirement: !ruby/object:Gem::Requirement
|
62
|
-
none: false
|
63
54
|
requirements:
|
64
|
-
- -
|
55
|
+
- - '>='
|
65
56
|
- !ruby/object:Gem::Version
|
66
57
|
version: 1.6.1
|
67
58
|
type: :runtime
|
68
59
|
prerelease: false
|
69
60
|
version_requirements: !ruby/object:Gem::Requirement
|
70
|
-
none: false
|
71
61
|
requirements:
|
72
|
-
- -
|
62
|
+
- - '>='
|
73
63
|
- !ruby/object:Gem::Version
|
74
64
|
version: 1.6.1
|
75
65
|
- !ruby/object:Gem::Dependency
|
76
66
|
name: log4r
|
77
67
|
requirement: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
68
|
requirements:
|
80
|
-
- -
|
69
|
+
- - '>='
|
81
70
|
- !ruby/object:Gem::Version
|
82
71
|
version: 1.1.9
|
83
72
|
type: :runtime
|
84
73
|
prerelease: false
|
85
74
|
version_requirements: !ruby/object:Gem::Requirement
|
86
|
-
none: false
|
87
75
|
requirements:
|
88
|
-
- -
|
76
|
+
- - '>='
|
89
77
|
- !ruby/object:Gem::Version
|
90
78
|
version: 1.1.9
|
91
79
|
- !ruby/object:Gem::Dependency
|
92
80
|
name: ruby-filemagic
|
93
81
|
requirement: !ruby/object:Gem::Requirement
|
94
|
-
none: false
|
95
82
|
requirements:
|
96
|
-
- -
|
83
|
+
- - '>='
|
97
84
|
- !ruby/object:Gem::Version
|
98
85
|
version: 0.4.2
|
99
86
|
type: :runtime
|
100
87
|
prerelease: false
|
101
88
|
version_requirements: !ruby/object:Gem::Requirement
|
102
|
-
none: false
|
103
89
|
requirements:
|
104
|
-
- -
|
90
|
+
- - '>='
|
105
91
|
- !ruby/object:Gem::Version
|
106
92
|
version: 0.4.2
|
107
|
-
description:
|
108
|
-
(and pseudonymously) among themselves, receive emails from non-subscribers and send
|
109
|
-
emails to non-subscribers via the list.
|
93
|
+
description: |-
|
94
|
+
Schleuder is a group's gateway: subscribers can communicate encrypted (and pseudonymously) among themselves, receive emails from non-subscribers and send emails to non-subscribers via the list.
|
110
95
|
|
111
|
-
|
112
|
-
Schleuder takes care of all decryption and encryption, stripping of headers, formatting
|
113
|
-
conversions, etc. Schleuder can also send out its own public key upon request and
|
114
|
-
process administrative commands by email.'
|
96
|
+
Schleuder takes care of all decryption and encryption, stripping of headers, formatting conversions, etc. Schleuder can also send out its own public key upon request and process administrative commands by email.
|
115
97
|
email: schleuder2@nadir.org
|
116
98
|
executables:
|
117
99
|
- schleuder
|
@@ -154,6 +136,7 @@ files:
|
|
154
136
|
- plugins/manage_members_plugin.rb
|
155
137
|
- plugins/manage_self_plugin.rb
|
156
138
|
- plugins/resend_plugin.rb
|
139
|
+
- plugins/sign_this_plugin.rb
|
157
140
|
- plugins/version_plugin.rb
|
158
141
|
- README
|
159
142
|
- LICENSE
|
@@ -165,29 +148,33 @@ files:
|
|
165
148
|
- bin/schleuder-init-setup
|
166
149
|
- bin/schleuder-migrate-v2.1-to-v2.2
|
167
150
|
homepage: http://schleuder2.nadir.org
|
168
|
-
licenses:
|
169
|
-
|
170
|
-
|
171
|
-
|
151
|
+
licenses:
|
152
|
+
- GPL-2
|
153
|
+
metadata: {}
|
154
|
+
post_install_message: |2+
|
155
|
+
|
156
|
+
|
157
|
+
Note: There's still one dependency missing, which we can't install in
|
158
|
+
this run of rubygems. Please execute schleuder-fix-gem-dependencies to
|
159
|
+
complete the installation!
|
160
|
+
|
172
161
|
rdoc_options: []
|
173
162
|
require_paths:
|
174
163
|
- lib
|
175
164
|
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
-
none: false
|
177
165
|
requirements:
|
178
|
-
- -
|
166
|
+
- - '>='
|
179
167
|
- !ruby/object:Gem::Version
|
180
168
|
version: '0'
|
181
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
|
-
none: false
|
183
170
|
requirements:
|
184
|
-
- -
|
171
|
+
- - '>='
|
185
172
|
- !ruby/object:Gem::Version
|
186
173
|
version: '0'
|
187
174
|
requirements: []
|
188
|
-
rubyforge_project:
|
189
|
-
rubygems_version:
|
175
|
+
rubyforge_project: '[none]'
|
176
|
+
rubygems_version: 2.0.3
|
190
177
|
signing_key:
|
191
|
-
specification_version:
|
192
|
-
summary:
|
178
|
+
specification_version: 4
|
179
|
+
summary: 'Schleuder is a group''s gateway: a gpg-enabled mailinglist with remailing-capabilities.'
|
193
180
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|