schleuder 2.2.4 → 3.2.2
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 +5 -5
- data/README.md +138 -0
- data/Rakefile +136 -0
- data/bin/pinentry-clearpassphrase +72 -0
- data/bin/schleuder +9 -89
- data/bin/schleuder-api-daemon +4 -0
- data/db/migrate/20140501103532_create_lists.rb +39 -0
- data/db/migrate/20140501112859_create_subscriptions.rb +21 -0
- data/db/migrate/201508092100_add_language_to_lists.rb +11 -0
- data/db/migrate/20150812165700_change_keywords_admin_only_defaults.rb +8 -0
- data/db/migrate/20150813235800_add_forward_all_incoming_to_admins.rb +11 -0
- data/db/migrate/201508141727_change_send_encrypted_only_default.rb +8 -0
- data/db/migrate/201508222143_add_logfiles_to_keep_to_lists.rb +11 -0
- data/db/migrate/201508261723_rename_delivery_disabled_to_delivery_enabled_and_change_default.rb +14 -0
- data/db/migrate/201508261815_strip_gpg_passphrase.rb +11 -0
- data/db/migrate/201508261827_remove_default_mime.rb +9 -0
- data/db/migrate/20160501172700_fix_headers_to_meta_defaults.rb +8 -0
- data/db/migrate/20170713215059_add_internal_footer_to_list.rb +11 -0
- data/db/schema.rb +62 -0
- data/etc/init.d/schleuder-api-daemon +87 -0
- data/etc/list-defaults.yml +123 -0
- data/etc/postfix/schleuder_sqlite.cf +28 -0
- data/etc/schleuder-api-daemon.service +10 -0
- data/etc/schleuder.cron.weekly +6 -0
- data/etc/schleuder.yml +61 -0
- data/lib/schleuder-api-daemon.rb +420 -0
- data/lib/schleuder.rb +81 -47
- data/lib/schleuder/cli.rb +334 -0
- data/lib/schleuder/cli/cert.rb +24 -0
- data/lib/schleuder/cli/schleuder_cert_manager.rb +84 -0
- data/lib/schleuder/cli/subcommand_fix.rb +11 -0
- data/lib/schleuder/conf.rb +131 -0
- data/lib/schleuder/errors/active_model_error.rb +15 -0
- data/lib/schleuder/errors/base.rb +17 -0
- data/lib/schleuder/errors/decryption_failed.rb +16 -0
- data/lib/schleuder/errors/fatal_error.rb +13 -0
- data/lib/schleuder/errors/file_not_found.rb +14 -0
- data/lib/schleuder/errors/invalid_listname.rb +13 -0
- data/lib/schleuder/errors/key_adduid_failed.rb +13 -0
- data/lib/schleuder/errors/key_generation_failed.rb +16 -0
- data/lib/schleuder/errors/keyword_admin_only.rb +13 -0
- data/lib/schleuder/errors/list_exists.rb +13 -0
- data/lib/schleuder/errors/list_not_found.rb +14 -0
- data/lib/schleuder/errors/list_property_missing.rb +14 -0
- data/lib/schleuder/errors/listdir_problem.rb +16 -0
- data/lib/schleuder/errors/loading_list_settings_failed.rb +14 -0
- data/lib/schleuder/errors/message_empty.rb +14 -0
- data/lib/schleuder/errors/message_not_from_admin.rb +13 -0
- data/lib/schleuder/errors/message_sender_not_subscribed.rb +13 -0
- data/lib/schleuder/errors/message_too_big.rb +14 -0
- data/lib/schleuder/errors/message_unauthenticated.rb +13 -0
- data/lib/schleuder/errors/message_unencrypted.rb +13 -0
- data/lib/schleuder/errors/message_unsigned.rb +13 -0
- data/lib/schleuder/errors/standard_error.rb +5 -0
- data/lib/schleuder/errors/too_many_keys.rb +17 -0
- data/lib/schleuder/errors/unknown_list_option.rb +14 -0
- data/lib/schleuder/filters/auth_filter.rb +39 -0
- data/lib/schleuder/filters/bounces_filter.rb +12 -0
- data/lib/schleuder/filters/forward_filter.rb +17 -0
- data/lib/schleuder/filters/forward_incoming.rb +13 -0
- data/lib/schleuder/filters/hotmail_message_filter.rb +25 -0
- data/lib/schleuder/filters/max_message_size.rb +14 -0
- data/lib/schleuder/filters/request_filter.rb +26 -0
- data/lib/schleuder/filters/send_key_filter.rb +20 -0
- data/lib/schleuder/filters/strip_alternative_filter.rb +21 -0
- data/lib/schleuder/filters_runner.rb +83 -0
- data/lib/schleuder/gpgme/ctx.rb +274 -0
- data/lib/schleuder/gpgme/import_status.rb +27 -0
- data/lib/schleuder/gpgme/key.rb +212 -0
- data/lib/schleuder/gpgme/sub_key.rb +13 -0
- data/lib/schleuder/gpgme/user_id.rb +22 -0
- data/lib/schleuder/list.rb +318 -127
- data/lib/schleuder/list_builder.rb +139 -0
- data/lib/schleuder/listlogger.rb +31 -0
- data/lib/schleuder/logger.rb +23 -0
- data/lib/schleuder/logger_notifications.rb +69 -0
- data/lib/schleuder/mail/message.rb +482 -0
- data/lib/schleuder/mail/parts_list.rb +9 -0
- data/lib/schleuder/plugin_runners/base.rb +91 -0
- data/lib/schleuder/plugin_runners/list_plugins_runner.rb +24 -0
- data/lib/schleuder/plugin_runners/request_plugins_runner.rb +27 -0
- data/lib/schleuder/plugins/attach_listkey.rb +17 -0
- data/lib/schleuder/plugins/get_version.rb +7 -0
- data/lib/schleuder/plugins/key_management.rb +113 -0
- data/lib/schleuder/plugins/list_management.rb +15 -0
- data/lib/schleuder/plugins/resend.rb +196 -0
- data/lib/schleuder/plugins/sign_this.rb +46 -0
- data/lib/schleuder/plugins/subscription_management.rb +140 -0
- data/lib/schleuder/runner.rb +130 -0
- data/lib/schleuder/subscription.rb +98 -0
- data/lib/schleuder/validators/boolean_validator.rb +7 -0
- data/lib/schleuder/validators/email_validator.rb +7 -0
- data/lib/schleuder/validators/fingerprint_validator.rb +7 -0
- data/lib/schleuder/validators/greater_than_zero_validator.rb +7 -0
- data/lib/schleuder/validators/no_line_breaks_validator.rb +7 -0
- data/lib/schleuder/version.rb +1 -1
- data/locales/de.yml +179 -0
- data/locales/en.yml +179 -0
- metadata +305 -108
- checksums.yaml.gz.sig +0 -3
- data.tar.gz.sig +0 -2
- data/LICENSE +0 -339
- data/README +0 -32
- data/bin/schleuder-fix-gem-dependencies +0 -37
- data/bin/schleuder-init-setup +0 -37
- data/bin/schleuder-migrate-v2.1-to-v2.2 +0 -225
- data/bin/schleuder-newlist +0 -413
- data/contrib/check-expired-keys.rb +0 -60
- data/contrib/mutt-schleuder-colors.rc +0 -10
- data/contrib/mutt-schleuder-resend.vim +0 -24
- data/contrib/smtpserver.rb +0 -76
- data/ext/default-list.conf +0 -149
- data/ext/default-members.conf +0 -7
- data/ext/list.conf.example +0 -14
- data/ext/schleuder.conf +0 -64
- data/lib/schleuder/archiver.rb +0 -46
- data/lib/schleuder/crypt.rb +0 -210
- data/lib/schleuder/errors.rb +0 -5
- data/lib/schleuder/list_config.rb +0 -146
- data/lib/schleuder/log/listlogger.rb +0 -57
- data/lib/schleuder/log/outputter/emailoutputter.rb +0 -120
- data/lib/schleuder/log/outputter/metaemailoutputter.rb +0 -50
- data/lib/schleuder/log/schleuderlogger.rb +0 -34
- data/lib/schleuder/mail.rb +0 -873
- data/lib/schleuder/mailer.rb +0 -26
- data/lib/schleuder/member.rb +0 -69
- data/lib/schleuder/plugin.rb +0 -54
- data/lib/schleuder/processor.rb +0 -363
- data/lib/schleuder/schleuder_config.rb +0 -75
- data/lib/schleuder/storage.rb +0 -84
- data/lib/schleuder/utils.rb +0 -80
- data/man/schleuder-newlist.8 +0 -174
- data/man/schleuder.8 +0 -416
- data/plugins/README +0 -20
- data/plugins/manage_keys_plugin.rb +0 -113
- data/plugins/manage_members_plugin.rb +0 -156
- data/plugins/manage_self_plugin.rb +0 -26
- data/plugins/resend_plugin.rb +0 -35
- data/plugins/sign_this_plugin.rb +0 -14
- data/plugins/version_plugin.rb +0 -12
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
class Cert < Thor
|
|
3
|
+
extend SubcommandFix
|
|
4
|
+
|
|
5
|
+
desc 'generate', 'Generate a new TLS-certificate.'
|
|
6
|
+
def generate
|
|
7
|
+
key = Conf.api['tls_key_file']
|
|
8
|
+
cert = Conf.api['tls_cert_file']
|
|
9
|
+
fingerprint = SchleuderCertManager.generate('schleuder', key, cert)
|
|
10
|
+
puts "Fingerprint of generated certificate: #{fingerprint}"
|
|
11
|
+
puts "Have this fingerprint included into the configuration-file of all clients that want to connect to your Schleuder API."
|
|
12
|
+
if Process.euid == 0
|
|
13
|
+
puts "! Warning: this process was run as root — please make sure the above files are accessible by the user that is running `schleuder-api-daemon`."
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'fingerprint', 'Show fingerprint of configured certificate.'
|
|
18
|
+
def fingerprint
|
|
19
|
+
cert = Conf.api['tls_cert_file']
|
|
20
|
+
fingerprint = SchleuderCertManager.fingerprint(cert)
|
|
21
|
+
say "Fingerprint of #{Conf.api['tls_cert_file']}: #{fingerprint}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
class SchleuderCertManager
|
|
5
|
+
def self.generate(project_name, filename_key, filename_cert)
|
|
6
|
+
keysize = 2048
|
|
7
|
+
subject = "/C=MW/O=Schleuder/OU=#{project_name}"
|
|
8
|
+
filename_key = Pathname.new(filename_key).expand_path
|
|
9
|
+
filename_cert = Pathname.new(filename_cert).expand_path
|
|
10
|
+
|
|
11
|
+
key = OpenSSL::PKey::RSA.new(keysize)
|
|
12
|
+
cert = OpenSSL::X509::Certificate.new
|
|
13
|
+
cert.subject = OpenSSL::X509::Name.parse(subject)
|
|
14
|
+
cert.issuer = cert.subject
|
|
15
|
+
cert.not_before = Time.now
|
|
16
|
+
cert.not_after = Time.now + 10 * 365 * 24 * 60 * 60
|
|
17
|
+
cert.public_key = key.public_key
|
|
18
|
+
cert.serial = 0x0
|
|
19
|
+
cert.version = 2
|
|
20
|
+
|
|
21
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
|
22
|
+
ef.subject_certificate = cert
|
|
23
|
+
ef.issuer_certificate = cert
|
|
24
|
+
cert.extensions = [
|
|
25
|
+
ef.create_extension("basicConstraints","CA:TRUE", true),
|
|
26
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
|
27
|
+
]
|
|
28
|
+
cert.add_extension ef.create_extension("authorityKeyIdentifier",
|
|
29
|
+
"keyid:always,issuer:always")
|
|
30
|
+
|
|
31
|
+
cert.sign key, OpenSSL::Digest::SHA256.new
|
|
32
|
+
|
|
33
|
+
filename_key = prepare_writing(filename_key)
|
|
34
|
+
filename_cert = prepare_writing(filename_cert)
|
|
35
|
+
|
|
36
|
+
filename_key.open('w', 400) do |fd|
|
|
37
|
+
fd.puts key
|
|
38
|
+
end
|
|
39
|
+
puts "Private key written to: #{filename_key}"
|
|
40
|
+
|
|
41
|
+
filename_cert.open('w') do |fd|
|
|
42
|
+
fd.puts cert.to_pem
|
|
43
|
+
end
|
|
44
|
+
puts "Certificate written to: #{filename_cert}"
|
|
45
|
+
|
|
46
|
+
fingerprint(cert)
|
|
47
|
+
rescue => exc
|
|
48
|
+
error exc.message
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.fingerprint(cert)
|
|
52
|
+
if ! cert.is_a?(OpenSSL::X509::Certificate)
|
|
53
|
+
path = Pathname.new(cert).expand_path
|
|
54
|
+
if ! path.readable?
|
|
55
|
+
error "Error: Not a readable file: #{path}"
|
|
56
|
+
end
|
|
57
|
+
cert = OpenSSL::X509::Certificate.new(path.read)
|
|
58
|
+
end
|
|
59
|
+
OpenSSL::Digest::SHA256.new(cert.to_der).to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.error(msg)
|
|
63
|
+
$stderr.puts "Error: #{msg}"
|
|
64
|
+
exit 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.note(msg)
|
|
68
|
+
$stdout.puts "Note: #{msg}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.prepare_writing(filename)
|
|
72
|
+
if filename.exist?
|
|
73
|
+
note "File exists: #{filename} — writing to current directory, you should move the file manually or change the configuration file."
|
|
74
|
+
if filename.basename.exist?
|
|
75
|
+
error "File exists: #{filename.basename} — (re)move it or fix previous error and try again."
|
|
76
|
+
end
|
|
77
|
+
filename = filename.basename
|
|
78
|
+
end
|
|
79
|
+
if ! filename.dirname.exist?
|
|
80
|
+
filename.dirname.mkpath
|
|
81
|
+
end
|
|
82
|
+
filename
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
module SubcommandFix
|
|
3
|
+
|
|
4
|
+
# Fixing a bug in Thor where the actual subcommand wouldn't show up
|
|
5
|
+
# with some invokations of the help-output.
|
|
6
|
+
def banner(task, namespace = true, subcommand = true)
|
|
7
|
+
"#{basename} #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module Schleuder
|
|
4
|
+
class Conf
|
|
5
|
+
include Singleton
|
|
6
|
+
|
|
7
|
+
EMAIL_REGEXP = /\A.+@[[:alnum:]_.-]+\z/i
|
|
8
|
+
FINGERPRINT_REGEXP = /\A(0x)?[a-f0-9]{32,}\z/i
|
|
9
|
+
|
|
10
|
+
DEFAULTS = {
|
|
11
|
+
'lists_dir' => '/var/lib/schleuder/lists',
|
|
12
|
+
'listlogs_dir' => '/var/lib/schleuder/lists',
|
|
13
|
+
'plugins_dir' => '/etc/schleuder/plugins',
|
|
14
|
+
'log_level' => 'warn',
|
|
15
|
+
'superadmin' => 'root@localhost',
|
|
16
|
+
'keyserver' => 'hkp://pool.sks-keyservers.net',
|
|
17
|
+
'smtp_settings' => {
|
|
18
|
+
'address' => 'localhost',
|
|
19
|
+
'port' => 25,
|
|
20
|
+
'domain' => 'localhost',
|
|
21
|
+
'enable_starttls_auto' => true,
|
|
22
|
+
# Don't verify by default because most smtp servers don't include
|
|
23
|
+
# 'localhost' into their TLS-certificates.
|
|
24
|
+
'openssl_verify_mode' => 'none',
|
|
25
|
+
'authentication' => nil,
|
|
26
|
+
'user_name' => nil,
|
|
27
|
+
'password' => nil,
|
|
28
|
+
},
|
|
29
|
+
'database' => {
|
|
30
|
+
'production' => {
|
|
31
|
+
'adapter' => 'sqlite3',
|
|
32
|
+
'database' => '/var/lib/schleuder/db.sqlite',
|
|
33
|
+
'timeout' => 5000
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
'api' => {
|
|
37
|
+
'host' => 'localhost',
|
|
38
|
+
'port' => 4443,
|
|
39
|
+
'tls_cert_file' => '/etc/schleuder/schleuder-certificate.pem',
|
|
40
|
+
'tls_key_file' => '/etc/schleuder/schleuder-private-key.pem',
|
|
41
|
+
'valid_api_keys' => []
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
def config
|
|
46
|
+
@config ||= load_config(ENV['SCHLEUDER_CONFIG'])
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.lists_dir
|
|
50
|
+
instance.config['lists_dir']
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.listlogs_dir
|
|
54
|
+
instance.config['listlogs_dir']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.plugins_dir
|
|
58
|
+
instance.config['plugins_dir']
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.database
|
|
62
|
+
instance.config['database'][ENV['SCHLEUDER_ENV']]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.databases
|
|
66
|
+
instance.config['database']
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.superadmin
|
|
70
|
+
instance.config['superadmin']
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def self.log_level
|
|
74
|
+
instance.config['log_level'] || 'WARN'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.api
|
|
78
|
+
instance.config['api'] || {}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.api_valid_api_keys
|
|
82
|
+
Array(api['valid_api_keys'])
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Three legacy options
|
|
86
|
+
def self.smtp_host
|
|
87
|
+
instance.config['smtp_host']
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.smtp_port
|
|
91
|
+
instance.config['smtp_port']
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def self.smtp_helo_domain
|
|
95
|
+
instance.config['smtp_helo_domain']
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.smtp_settings
|
|
99
|
+
settings = instance.config['smtp_settings'] || {}
|
|
100
|
+
# Support previously used config-options.
|
|
101
|
+
# Remove this in future versions.
|
|
102
|
+
{smtp_host: :address, smtp_port: :port, smtp_helo_domain: :domain}.each do |old, new|
|
|
103
|
+
value = self.send(old)
|
|
104
|
+
if value.present?
|
|
105
|
+
Schleuder.logger.warn "Deprecation warning: In schleuder.yml #{old} should be changed to smtp_settings[#{new}]."
|
|
106
|
+
settings[new] = value
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
settings
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.keyserver
|
|
113
|
+
instance.config['keyserver']
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
def load_config(filename)
|
|
119
|
+
DEFAULTS.deep_merge(load_config_file(filename))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def load_config_file(filename)
|
|
123
|
+
file = Pathname.new(filename)
|
|
124
|
+
if file.readable?
|
|
125
|
+
YAML.load(ERB.new(file.read).result)
|
|
126
|
+
else
|
|
127
|
+
{}
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
module Errors
|
|
3
|
+
class DecryptionFailed < Base
|
|
4
|
+
def initialize(list)
|
|
5
|
+
set_default_locale
|
|
6
|
+
@list = list
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def message
|
|
10
|
+
t('errors.decryption_failed',
|
|
11
|
+
{ key: @list.key.to_s,
|
|
12
|
+
email: @list.sendkey_address })
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
module Errors
|
|
3
|
+
class KeyGenerationFailed < Base
|
|
4
|
+
def initialize(listdir, listname)
|
|
5
|
+
@listdir = listdir
|
|
6
|
+
@listname = listname
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def message
|
|
10
|
+
t('errors.key_generation_failed',
|
|
11
|
+
{ listdir: @listdir,
|
|
12
|
+
listname: @listname })
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
module Errors
|
|
3
|
+
class ListPropertyMissing < Base
|
|
4
|
+
def initialize(listdir, property)
|
|
5
|
+
@listdir = listdir
|
|
6
|
+
@property = property
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
t("errors.list_#{@property}_missing", listdir: @listdir)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Schleuder
|
|
2
|
+
module Errors
|
|
3
|
+
class ListdirProblem < Base
|
|
4
|
+
def initialize(dir, problem)
|
|
5
|
+
@dir = dir
|
|
6
|
+
@problem = problem
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def message
|
|
10
|
+
problem = t("errors.listdir_problem.#{@problem}")
|
|
11
|
+
t('errors.listdir_problem.message', dir: @dir, problem: problem)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|