schleuder 3.5.3 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -21
- data/Rakefile +15 -12
- data/bin/schleuder +1 -1
- data/db/migrate/20140501103532_create_lists.rb +1 -1
- data/db/migrate/20140501112859_create_subscriptions.rb +1 -1
- data/db/migrate/{201508092100_add_language_to_lists.rb → 20150809210000_add_language_to_lists.rb} +1 -1
- data/db/migrate/20150812165700_change_keywords_admin_only_defaults.rb +1 -1
- data/db/migrate/20150813235800_add_forward_all_incoming_to_admins.rb +1 -1
- data/db/migrate/{201508141727_change_send_encrypted_only_default.rb → 20150814172700_change_send_encrypted_only_default.rb} +1 -1
- data/db/migrate/{201508222143_add_logfiles_to_keep_to_lists.rb → 20150822214300_add_logfiles_to_keep_to_lists.rb} +1 -1
- data/db/migrate/{201508261723_rename_delivery_disabled_to_delivery_enabled_and_change_default.rb → 20150826172300_rename_delivery_disabled_to_delivery_enabled_and_change_default.rb} +1 -1
- data/db/migrate/{201508261815_strip_gpg_passphrase.rb → 20150826181500_strip_gpg_passphrase.rb} +1 -1
- data/db/migrate/{201508261827_remove_default_mime.rb → 20150826182700_remove_default_mime.rb} +1 -1
- data/db/migrate/20160501172700_fix_headers_to_meta_defaults.rb +1 -1
- data/db/migrate/20170713215059_add_internal_footer_to_list.rb +1 -1
- data/db/migrate/20180110203100_add_sig_enc_to_headers_to_meta_defaults.rb +1 -1
- data/db/migrate/20180723173900_add_deliver_selfsent_to_list.rb +1 -1
- data/db/migrate/20190906194820_add_autocrypt_header_to_list.rb +1 -1
- data/db/migrate/20200118170110_add_set_reply_to_to_sender_and_munge_from.rb +15 -0
- data/db/schema.rb +45 -45
- data/etc/list-defaults.yml +18 -0
- data/etc/postfix/schleuder_sqlite.cf +1 -1
- data/etc/schleuder-weekly-key-maintenance.service +9 -0
- data/etc/schleuder-weekly-key-maintenance.timer +9 -0
- data/etc/schleuder.yml +3 -3
- data/lib/schleuder-api-daemon/helpers/schleuder-api-daemon-helper.rb +3 -3
- data/lib/schleuder-api-daemon/routes/subscription.rb +4 -4
- data/lib/schleuder.rb +13 -12
- data/lib/schleuder/cli.rb +9 -189
- data/lib/schleuder/cli/cert.rb +2 -2
- data/lib/schleuder/cli/cli_helper.rb +14 -0
- data/lib/schleuder/cli/schleuder_cert_manager.rb +4 -4
- data/lib/schleuder/conf.rb +4 -4
- data/lib/schleuder/errors/base.rb +2 -2
- data/lib/schleuder/errors/decryption_failed.rb +1 -1
- data/lib/schleuder/errors/fatal_error.rb +1 -1
- data/lib/schleuder/errors/key_adduid_failed.rb +1 -1
- data/lib/schleuder/errors/key_generation_failed.rb +1 -1
- data/lib/schleuder/errors/message_empty.rb +1 -1
- data/lib/schleuder/errors/message_too_big.rb +1 -1
- data/lib/schleuder/errors/too_many_keys.rb +1 -1
- data/lib/schleuder/filters/post_decryption/10_request.rb +3 -3
- data/lib/schleuder/filters/post_decryption/20_max_message_size.rb +1 -1
- data/lib/schleuder/filters/post_decryption/30_forward_to_owner.rb +1 -1
- data/lib/schleuder/filters/post_decryption/40_receive_admin_only.rb +1 -1
- data/lib/schleuder/filters/post_decryption/50_receive_authenticated_only.rb +1 -1
- data/lib/schleuder/filters/post_decryption/60_receive_signed_only.rb +1 -1
- data/lib/schleuder/filters/post_decryption/70_receive_encrypted_only.rb +1 -1
- data/lib/schleuder/filters/post_decryption/80_receive_from_subscribed_emailaddresses_only.rb +1 -1
- data/lib/schleuder/filters/pre_decryption/10_forward_bounce_to_admins.rb +1 -1
- data/lib/schleuder/filters/pre_decryption/30_send_key.rb +1 -1
- data/lib/schleuder/filters/pre_decryption/40_fix_exchange_messages.rb +1 -1
- data/lib/schleuder/filters/pre_decryption/50_strip_html_from_alternative.rb +2 -2
- data/lib/schleuder/filters_runner.rb +9 -9
- data/lib/schleuder/gpgme/ctx.rb +15 -67
- data/lib/schleuder/gpgme/key.rb +4 -136
- data/lib/schleuder/gpgme/user_id.rb +2 -0
- data/lib/schleuder/keyword_handlers/attach_list_key.rb +17 -0
- data/lib/schleuder/keyword_handlers/base.rb +36 -0
- data/lib/schleuder/keyword_handlers/get_version.rb +11 -0
- data/lib/schleuder/keyword_handlers/key_management.rb +141 -0
- data/lib/schleuder/keyword_handlers/list_management.rb +19 -0
- data/lib/schleuder/keyword_handlers/resend.rb +208 -0
- data/lib/schleuder/keyword_handlers/sign_this.rb +54 -0
- data/lib/schleuder/keyword_handlers/subscription_management.rb +213 -0
- data/lib/schleuder/keyword_handlers_runner.rb +146 -0
- data/lib/schleuder/list.rb +28 -40
- data/lib/schleuder/list_builder.rb +16 -5
- data/lib/schleuder/listlogger.rb +1 -1
- data/lib/schleuder/logger.rb +2 -6
- data/lib/schleuder/mail/{encrypted_part.rb → gpg/encrypted_part.rb} +0 -0
- data/lib/schleuder/mail/gpg/sign_part.rb +33 -0
- data/lib/schleuder/mail/message.rb +135 -40
- data/lib/schleuder/runner.rb +18 -16
- data/lib/schleuder/subscription.rb +35 -13
- data/lib/schleuder/validators/boolean_validator.rb +1 -1
- data/lib/schleuder/validators/email_validator.rb +1 -1
- data/lib/schleuder/validators/fingerprint_validator.rb +1 -1
- data/lib/schleuder/validators/greater_than_zero_validator.rb +1 -1
- data/lib/schleuder/validators/no_line_breaks_validator.rb +1 -1
- data/lib/schleuder/version.rb +1 -1
- data/locales/de.yml +49 -36
- data/locales/en.yml +34 -21
- metadata +131 -79
- data/bin/pinentry-clearpassphrase +0 -72
- data/lib/schleuder/plugin_runners/base.rb +0 -91
- data/lib/schleuder/plugin_runners/list_plugins_runner.rb +0 -24
- data/lib/schleuder/plugin_runners/request_plugins_runner.rb +0 -27
- data/lib/schleuder/plugins/attach_listkey.rb +0 -13
- data/lib/schleuder/plugins/get_version.rb +0 -7
- data/lib/schleuder/plugins/key_management.rb +0 -121
- data/lib/schleuder/plugins/list_management.rb +0 -15
- data/lib/schleuder/plugins/resend.rb +0 -199
- data/lib/schleuder/plugins/sign_this.rb +0 -46
- data/lib/schleuder/plugins/subscription_management.rb +0 -207
@@ -1,46 +0,0 @@
|
|
1
|
-
module Schleuder
|
2
|
-
module RequestPlugins
|
3
|
-
def self.sign_this(arguments, list, mail)
|
4
|
-
if mail.has_attachments?
|
5
|
-
list.logger.debug "Signing each attachment's body"
|
6
|
-
intro = I18n.t('plugins.signatures_attached')
|
7
|
-
parts = mail.attachments.map do |attachment|
|
8
|
-
make_signature_part(attachment, list)
|
9
|
-
end
|
10
|
-
[intro, parts].flatten
|
11
|
-
else
|
12
|
-
list.logger.debug "Clear-signing first available text/plain part"
|
13
|
-
clearsign(mail.first_plaintext_part)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
# helper methods
|
18
|
-
private
|
19
|
-
|
20
|
-
def self.make_signature_part(attachment, list)
|
21
|
-
material = attachment.body.to_s
|
22
|
-
return nil if material.strip.blank?
|
23
|
-
file_basename = attachment.filename.presence || Digest::SHA256.hexdigest(material)
|
24
|
-
list.logger.debug "Signing #{file_basename}"
|
25
|
-
filename = "#{file_basename}.sig"
|
26
|
-
part = Mail::Part.new
|
27
|
-
part.body = detachsign(material)
|
28
|
-
part.content_type = 'application/pgp-signature'
|
29
|
-
part.content_disposition = "attachment; filename=#{filename}"
|
30
|
-
part.content_description = "OpenPGP signature for '#{file_basename}'"
|
31
|
-
part
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.detachsign(thing)
|
35
|
-
crypto.sign(thing, mode: GPGME::SIG_MODE_DETACH).to_s
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.clearsign(mail)
|
39
|
-
crypto.clearsign(mail.body.to_s).to_s
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.crypto
|
43
|
-
@crypto ||= GPGME::Crypto.new(armor: true)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,207 +0,0 @@
|
|
1
|
-
module Schleuder
|
2
|
-
module RequestPlugins
|
3
|
-
def self.subscribe(arguments, list, mail)
|
4
|
-
if arguments.blank?
|
5
|
-
return I18n.t(
|
6
|
-
"plugins.subscription_management.subscribe_requires_arguments"
|
7
|
-
)
|
8
|
-
end
|
9
|
-
|
10
|
-
email = arguments.shift
|
11
|
-
|
12
|
-
if arguments.present?
|
13
|
-
# Collect all arguments that look like fingerprint-material
|
14
|
-
fingerprint = ''
|
15
|
-
while arguments.first.present? && arguments.first.match(/^(0x)?[a-f0-9]+$/i)
|
16
|
-
fingerprint << arguments.shift
|
17
|
-
end
|
18
|
-
# Use possibly remaining args as flags.
|
19
|
-
adminflag = arguments.shift
|
20
|
-
deliveryflag = arguments.shift
|
21
|
-
end
|
22
|
-
|
23
|
-
sub, _ = list.subscribe(email, fingerprint, adminflag, deliveryflag)
|
24
|
-
|
25
|
-
if sub.persisted?
|
26
|
-
I18n.t(
|
27
|
-
"plugins.subscription_management.subscribed",
|
28
|
-
email: sub.email,
|
29
|
-
fingerprint: sub.fingerprint,
|
30
|
-
admin: sub.admin,
|
31
|
-
delivery_enabled: sub.delivery_enabled
|
32
|
-
)
|
33
|
-
else
|
34
|
-
I18n.t(
|
35
|
-
"plugins.subscription_management.subscribing_failed",
|
36
|
-
email: sub.email,
|
37
|
-
errors: sub.errors.full_messages.join(".\n")
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.unsubscribe(arguments, list, mail)
|
43
|
-
# If no address was given we unsubscribe the sender.
|
44
|
-
email = arguments.first.presence || mail.signer.email
|
45
|
-
|
46
|
-
# Refuse to unsubscribe the last admin.
|
47
|
-
if list.admins.size == 1 && list.admins.first.email == email
|
48
|
-
return I18n.t(
|
49
|
-
"plugins.subscription_management.cannot_unsubscribe_last_admin", email: email
|
50
|
-
)
|
51
|
-
end
|
52
|
-
|
53
|
-
# TODO: May signers have multiple UIDs? We don't match those currently.
|
54
|
-
if ! list.from_admin?(mail) && email != mail.signer.email
|
55
|
-
# Only admins may unsubscribe others.
|
56
|
-
return I18n.t(
|
57
|
-
"plugins.subscription_management.forbidden", email: email
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
sub = list.subscriptions.where(email: email).first
|
62
|
-
|
63
|
-
if sub.blank?
|
64
|
-
return I18n.t(
|
65
|
-
"plugins.subscription_management.is_not_subscribed", email: email
|
66
|
-
)
|
67
|
-
end
|
68
|
-
|
69
|
-
if res = sub.delete
|
70
|
-
I18n.t(
|
71
|
-
"plugins.subscription_management.unsubscribed", email: email
|
72
|
-
)
|
73
|
-
else
|
74
|
-
I18n.t(
|
75
|
-
"plugins.subscription_management.unsubscribing_failed",
|
76
|
-
email: email,
|
77
|
-
error: res.errors.to_a
|
78
|
-
)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.list_subscriptions(arguments, list, mail)
|
83
|
-
subs = if arguments.blank?
|
84
|
-
list.subscriptions.all.to_a
|
85
|
-
else
|
86
|
-
arguments.map do |argument|
|
87
|
-
list.subscriptions.where("email like ?", "%#{argument}%").to_a
|
88
|
-
end.flatten
|
89
|
-
end
|
90
|
-
|
91
|
-
if subs.blank?
|
92
|
-
return nil
|
93
|
-
end
|
94
|
-
|
95
|
-
out = [ I18n.t("plugins.subscription_management.list_of_subscriptions") ]
|
96
|
-
|
97
|
-
out << subs.map do |subscription|
|
98
|
-
# Fingerprints are at most 40 characters long, and lines shouldn't
|
99
|
-
# exceed 80 characters if possible.
|
100
|
-
s = subscription.email
|
101
|
-
if subscription.fingerprint.present?
|
102
|
-
s << "\t0x#{subscription.fingerprint}"
|
103
|
-
end
|
104
|
-
if ! subscription.delivery_enabled?
|
105
|
-
s << "\tDelivery disabled!"
|
106
|
-
end
|
107
|
-
s
|
108
|
-
end
|
109
|
-
|
110
|
-
out.join("\n")
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.set_fingerprint(arguments, list, mail)
|
114
|
-
if arguments.blank?
|
115
|
-
return I18n.t(
|
116
|
-
"plugins.subscription_management.set_fingerprint_requires_arguments"
|
117
|
-
)
|
118
|
-
end
|
119
|
-
|
120
|
-
if arguments.first.match(/@/)
|
121
|
-
if arguments.first == mail.signer.email || list.from_admin?(mail)
|
122
|
-
email = arguments.shift
|
123
|
-
else
|
124
|
-
return I18n.t(
|
125
|
-
"plugins.subscription_management.set_fingerprint_only_self"
|
126
|
-
)
|
127
|
-
end
|
128
|
-
else
|
129
|
-
email = mail.signer.email
|
130
|
-
end
|
131
|
-
|
132
|
-
sub = list.subscriptions.where(email: email).first
|
133
|
-
|
134
|
-
if sub.blank?
|
135
|
-
return I18n.t(
|
136
|
-
"plugins.subscription_management.is_not_subscribed", email: email
|
137
|
-
)
|
138
|
-
end
|
139
|
-
|
140
|
-
fingerprint = arguments.join
|
141
|
-
unless GPGME::Key.valid_fingerprint?(fingerprint)
|
142
|
-
return I18n.t(
|
143
|
-
"plugins.subscription_management.set_fingerprint_requires_valid_fingerprint",
|
144
|
-
fingerprint: fingerprint
|
145
|
-
)
|
146
|
-
end
|
147
|
-
|
148
|
-
sub.fingerprint = fingerprint
|
149
|
-
if sub.save
|
150
|
-
I18n.t(
|
151
|
-
"plugins.subscription_management.fingerprint_set",
|
152
|
-
email: email,
|
153
|
-
fingerprint: sub.fingerprint
|
154
|
-
)
|
155
|
-
else
|
156
|
-
I18n.t(
|
157
|
-
"plugins.subscription_management.setting_fingerprint_failed",
|
158
|
-
email: email,
|
159
|
-
fingerprint: sub.fingerprint,
|
160
|
-
errors: sub.errors.to_a.join("\n")
|
161
|
-
)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def self.unset_fingerprint(arguments, list, mail)
|
166
|
-
if arguments.blank?
|
167
|
-
return I18n.t(
|
168
|
-
"plugins.subscription_management.unset_fingerprint_requires_arguments"
|
169
|
-
)
|
170
|
-
end
|
171
|
-
|
172
|
-
email = arguments.first
|
173
|
-
unless email == mail.signer.email || list.from_admin?(mail)
|
174
|
-
return I18n.t(
|
175
|
-
"plugins.subscription_management.unset_fingerprint_only_self"
|
176
|
-
)
|
177
|
-
end
|
178
|
-
if email == mail.signer.email && list.from_admin?(mail) && arguments.last != 'force'
|
179
|
-
return I18n.t(
|
180
|
-
"plugins.subscription_management.unset_fingerprint_requires_arguments"
|
181
|
-
)
|
182
|
-
end
|
183
|
-
|
184
|
-
sub = list.subscriptions.where(email: email).first
|
185
|
-
if sub.blank?
|
186
|
-
return I18n.t(
|
187
|
-
"plugins.subscription_management.is_not_subscribed", email: email
|
188
|
-
)
|
189
|
-
end
|
190
|
-
|
191
|
-
sub.fingerprint = ''
|
192
|
-
if sub.save
|
193
|
-
I18n.t(
|
194
|
-
"plugins.subscription_management.fingerprint_unset",
|
195
|
-
email: email
|
196
|
-
)
|
197
|
-
else
|
198
|
-
I18n.t(
|
199
|
-
"plugins.subscription_management.unsetting_fingerprint_failed",
|
200
|
-
email: email,
|
201
|
-
errors: sub.errors.to_a.join("\n")
|
202
|
-
)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|