schleuder 3.6.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -6
  3. data/Rakefile +12 -14
  4. data/bin/schleuder +1 -1
  5. data/db/migrate/20140501103532_create_lists.rb +1 -1
  6. data/db/migrate/20140501112859_create_subscriptions.rb +1 -1
  7. data/db/migrate/{201508092100_add_language_to_lists.rb → 20150809210000_add_language_to_lists.rb} +1 -1
  8. data/db/migrate/20150812165700_change_keywords_admin_only_defaults.rb +1 -1
  9. data/db/migrate/20150813235800_add_forward_all_incoming_to_admins.rb +1 -1
  10. data/db/migrate/{201508141727_change_send_encrypted_only_default.rb → 20150814172700_change_send_encrypted_only_default.rb} +1 -1
  11. data/db/migrate/{201508222143_add_logfiles_to_keep_to_lists.rb → 20150822214300_add_logfiles_to_keep_to_lists.rb} +1 -1
  12. 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
  13. data/db/migrate/{201508261815_strip_gpg_passphrase.rb → 20150826181500_strip_gpg_passphrase.rb} +1 -1
  14. data/db/migrate/{201508261827_remove_default_mime.rb → 20150826182700_remove_default_mime.rb} +1 -1
  15. data/db/migrate/20160501172700_fix_headers_to_meta_defaults.rb +1 -1
  16. data/db/migrate/20170713215059_add_internal_footer_to_list.rb +1 -1
  17. data/db/migrate/20180110203100_add_sig_enc_to_headers_to_meta_defaults.rb +1 -1
  18. data/db/migrate/20180723173900_add_deliver_selfsent_to_list.rb +1 -1
  19. data/db/migrate/20190906194820_add_autocrypt_header_to_list.rb +1 -1
  20. data/db/migrate/20200118170110_add_set_reply_to_to_sender_and_munge_from.rb +1 -1
  21. data/db/schema.rb +45 -47
  22. data/etc/postfix/schleuder_sqlite.cf +1 -1
  23. data/etc/schleuder-weekly-key-maintenance.service +9 -0
  24. data/etc/schleuder-weekly-key-maintenance.timer +9 -0
  25. data/etc/schleuder.yml +3 -3
  26. data/lib/schleuder-api-daemon/helpers/schleuder-api-daemon-helper.rb +3 -3
  27. data/lib/schleuder-api-daemon/routes/subscription.rb +4 -4
  28. data/lib/schleuder.rb +9 -11
  29. data/lib/schleuder/cli.rb +9 -188
  30. data/lib/schleuder/cli/cert.rb +2 -2
  31. data/lib/schleuder/cli/cli_helper.rb +14 -0
  32. data/lib/schleuder/cli/schleuder_cert_manager.rb +4 -4
  33. data/lib/schleuder/conf.rb +3 -3
  34. data/lib/schleuder/errors/base.rb +2 -2
  35. data/lib/schleuder/errors/decryption_failed.rb +1 -1
  36. data/lib/schleuder/errors/fatal_error.rb +1 -1
  37. data/lib/schleuder/errors/key_adduid_failed.rb +1 -1
  38. data/lib/schleuder/errors/key_generation_failed.rb +1 -1
  39. data/lib/schleuder/errors/message_empty.rb +1 -1
  40. data/lib/schleuder/errors/message_too_big.rb +1 -1
  41. data/lib/schleuder/errors/too_many_keys.rb +1 -1
  42. data/lib/schleuder/filters/post_decryption/10_request.rb +3 -3
  43. data/lib/schleuder/filters/post_decryption/20_max_message_size.rb +1 -1
  44. data/lib/schleuder/filters/post_decryption/30_forward_to_owner.rb +1 -1
  45. data/lib/schleuder/filters/post_decryption/40_receive_admin_only.rb +1 -1
  46. data/lib/schleuder/filters/post_decryption/50_receive_authenticated_only.rb +1 -1
  47. data/lib/schleuder/filters/post_decryption/60_receive_signed_only.rb +1 -1
  48. data/lib/schleuder/filters/post_decryption/70_receive_encrypted_only.rb +1 -1
  49. data/lib/schleuder/filters/post_decryption/80_receive_from_subscribed_emailaddresses_only.rb +1 -1
  50. data/lib/schleuder/filters/pre_decryption/10_forward_bounce_to_admins.rb +1 -1
  51. data/lib/schleuder/filters/pre_decryption/30_send_key.rb +1 -1
  52. data/lib/schleuder/filters/pre_decryption/40_fix_exchange_messages.rb +1 -1
  53. data/lib/schleuder/filters/pre_decryption/50_strip_html_from_alternative.rb +2 -2
  54. data/lib/schleuder/filters_runner.rb +9 -9
  55. data/lib/schleuder/gpgme/ctx.rb +15 -35
  56. data/lib/schleuder/gpgme/key.rb +4 -136
  57. data/lib/schleuder/gpgme/user_id.rb +2 -0
  58. data/lib/schleuder/keyword_handlers/attach_list_key.rb +17 -0
  59. data/lib/schleuder/keyword_handlers/base.rb +36 -0
  60. data/lib/schleuder/keyword_handlers/get_version.rb +11 -0
  61. data/lib/schleuder/keyword_handlers/key_management.rb +141 -0
  62. data/lib/schleuder/keyword_handlers/list_management.rb +19 -0
  63. data/lib/schleuder/keyword_handlers/resend.rb +208 -0
  64. data/lib/schleuder/keyword_handlers/sign_this.rb +54 -0
  65. data/lib/schleuder/keyword_handlers/subscription_management.rb +213 -0
  66. data/lib/schleuder/keyword_handlers_runner.rb +146 -0
  67. data/lib/schleuder/list.rb +11 -39
  68. data/lib/schleuder/list_builder.rb +16 -5
  69. data/lib/schleuder/listlogger.rb +1 -1
  70. data/lib/schleuder/mail/message.rb +82 -61
  71. data/lib/schleuder/runner.rb +18 -16
  72. data/lib/schleuder/subscription.rb +9 -10
  73. data/lib/schleuder/validators/boolean_validator.rb +1 -1
  74. data/lib/schleuder/validators/email_validator.rb +1 -1
  75. data/lib/schleuder/validators/fingerprint_validator.rb +1 -1
  76. data/lib/schleuder/validators/greater_than_zero_validator.rb +1 -1
  77. data/lib/schleuder/validators/no_line_breaks_validator.rb +1 -1
  78. data/lib/schleuder/version.rb +1 -1
  79. data/locales/de.yml +48 -36
  80. data/locales/en.yml +33 -21
  81. metadata +117 -53
  82. data/bin/pinentry-clearpassphrase +0 -72
  83. data/lib/schleuder/plugin_runners/base.rb +0 -91
  84. data/lib/schleuder/plugin_runners/list_plugins_runner.rb +0 -24
  85. data/lib/schleuder/plugin_runners/request_plugins_runner.rb +0 -27
  86. data/lib/schleuder/plugins/attach_listkey.rb +0 -13
  87. data/lib/schleuder/plugins/get_version.rb +0 -7
  88. data/lib/schleuder/plugins/key_management.rb +0 -121
  89. data/lib/schleuder/plugins/list_management.rb +0 -15
  90. data/lib/schleuder/plugins/resend.rb +0 -199
  91. data/lib/schleuder/plugins/sign_this.rb +0 -46
  92. 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
-