schleuder 2.2.4 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +138 -0
  3. data/Rakefile +136 -0
  4. data/bin/pinentry-clearpassphrase +72 -0
  5. data/bin/schleuder +9 -89
  6. data/bin/schleuder-api-daemon +4 -0
  7. data/db/migrate/20140501103532_create_lists.rb +39 -0
  8. data/db/migrate/20140501112859_create_subscriptions.rb +21 -0
  9. data/db/migrate/201508092100_add_language_to_lists.rb +11 -0
  10. data/db/migrate/20150812165700_change_keywords_admin_only_defaults.rb +8 -0
  11. data/db/migrate/20150813235800_add_forward_all_incoming_to_admins.rb +11 -0
  12. data/db/migrate/201508141727_change_send_encrypted_only_default.rb +8 -0
  13. data/db/migrate/201508222143_add_logfiles_to_keep_to_lists.rb +11 -0
  14. data/db/migrate/201508261723_rename_delivery_disabled_to_delivery_enabled_and_change_default.rb +14 -0
  15. data/db/migrate/201508261815_strip_gpg_passphrase.rb +11 -0
  16. data/db/migrate/201508261827_remove_default_mime.rb +9 -0
  17. data/db/migrate/20160501172700_fix_headers_to_meta_defaults.rb +8 -0
  18. data/db/migrate/20170713215059_add_internal_footer_to_list.rb +11 -0
  19. data/db/schema.rb +62 -0
  20. data/etc/init.d/schleuder-api-daemon +87 -0
  21. data/etc/list-defaults.yml +123 -0
  22. data/etc/postfix/schleuder_sqlite.cf +28 -0
  23. data/etc/schleuder-api-daemon.service +10 -0
  24. data/etc/schleuder.cron.weekly +6 -0
  25. data/etc/schleuder.yml +61 -0
  26. data/lib/schleuder-api-daemon.rb +420 -0
  27. data/lib/schleuder.rb +81 -47
  28. data/lib/schleuder/cli.rb +334 -0
  29. data/lib/schleuder/cli/cert.rb +24 -0
  30. data/lib/schleuder/cli/schleuder_cert_manager.rb +84 -0
  31. data/lib/schleuder/cli/subcommand_fix.rb +11 -0
  32. data/lib/schleuder/conf.rb +131 -0
  33. data/lib/schleuder/errors/active_model_error.rb +15 -0
  34. data/lib/schleuder/errors/base.rb +17 -0
  35. data/lib/schleuder/errors/decryption_failed.rb +16 -0
  36. data/lib/schleuder/errors/fatal_error.rb +13 -0
  37. data/lib/schleuder/errors/file_not_found.rb +14 -0
  38. data/lib/schleuder/errors/invalid_listname.rb +13 -0
  39. data/lib/schleuder/errors/key_adduid_failed.rb +13 -0
  40. data/lib/schleuder/errors/key_generation_failed.rb +16 -0
  41. data/lib/schleuder/errors/keyword_admin_only.rb +13 -0
  42. data/lib/schleuder/errors/list_exists.rb +13 -0
  43. data/lib/schleuder/errors/list_not_found.rb +14 -0
  44. data/lib/schleuder/errors/list_property_missing.rb +14 -0
  45. data/lib/schleuder/errors/listdir_problem.rb +16 -0
  46. data/lib/schleuder/errors/loading_list_settings_failed.rb +14 -0
  47. data/lib/schleuder/errors/message_empty.rb +14 -0
  48. data/lib/schleuder/errors/message_not_from_admin.rb +13 -0
  49. data/lib/schleuder/errors/message_sender_not_subscribed.rb +13 -0
  50. data/lib/schleuder/errors/message_too_big.rb +14 -0
  51. data/lib/schleuder/errors/message_unauthenticated.rb +13 -0
  52. data/lib/schleuder/errors/message_unencrypted.rb +13 -0
  53. data/lib/schleuder/errors/message_unsigned.rb +13 -0
  54. data/lib/schleuder/errors/standard_error.rb +5 -0
  55. data/lib/schleuder/errors/too_many_keys.rb +17 -0
  56. data/lib/schleuder/errors/unknown_list_option.rb +14 -0
  57. data/lib/schleuder/filters/auth_filter.rb +39 -0
  58. data/lib/schleuder/filters/bounces_filter.rb +12 -0
  59. data/lib/schleuder/filters/forward_filter.rb +17 -0
  60. data/lib/schleuder/filters/forward_incoming.rb +13 -0
  61. data/lib/schleuder/filters/hotmail_message_filter.rb +25 -0
  62. data/lib/schleuder/filters/max_message_size.rb +14 -0
  63. data/lib/schleuder/filters/request_filter.rb +26 -0
  64. data/lib/schleuder/filters/send_key_filter.rb +20 -0
  65. data/lib/schleuder/filters/strip_alternative_filter.rb +21 -0
  66. data/lib/schleuder/filters_runner.rb +83 -0
  67. data/lib/schleuder/gpgme/ctx.rb +274 -0
  68. data/lib/schleuder/gpgme/import_status.rb +27 -0
  69. data/lib/schleuder/gpgme/key.rb +212 -0
  70. data/lib/schleuder/gpgme/sub_key.rb +13 -0
  71. data/lib/schleuder/gpgme/user_id.rb +22 -0
  72. data/lib/schleuder/list.rb +318 -127
  73. data/lib/schleuder/list_builder.rb +139 -0
  74. data/lib/schleuder/listlogger.rb +31 -0
  75. data/lib/schleuder/logger.rb +23 -0
  76. data/lib/schleuder/logger_notifications.rb +69 -0
  77. data/lib/schleuder/mail/message.rb +482 -0
  78. data/lib/schleuder/mail/parts_list.rb +9 -0
  79. data/lib/schleuder/plugin_runners/base.rb +91 -0
  80. data/lib/schleuder/plugin_runners/list_plugins_runner.rb +24 -0
  81. data/lib/schleuder/plugin_runners/request_plugins_runner.rb +27 -0
  82. data/lib/schleuder/plugins/attach_listkey.rb +17 -0
  83. data/lib/schleuder/plugins/get_version.rb +7 -0
  84. data/lib/schleuder/plugins/key_management.rb +113 -0
  85. data/lib/schleuder/plugins/list_management.rb +15 -0
  86. data/lib/schleuder/plugins/resend.rb +196 -0
  87. data/lib/schleuder/plugins/sign_this.rb +46 -0
  88. data/lib/schleuder/plugins/subscription_management.rb +140 -0
  89. data/lib/schleuder/runner.rb +130 -0
  90. data/lib/schleuder/subscription.rb +98 -0
  91. data/lib/schleuder/validators/boolean_validator.rb +7 -0
  92. data/lib/schleuder/validators/email_validator.rb +7 -0
  93. data/lib/schleuder/validators/fingerprint_validator.rb +7 -0
  94. data/lib/schleuder/validators/greater_than_zero_validator.rb +7 -0
  95. data/lib/schleuder/validators/no_line_breaks_validator.rb +7 -0
  96. data/lib/schleuder/version.rb +1 -1
  97. data/locales/de.yml +179 -0
  98. data/locales/en.yml +179 -0
  99. metadata +305 -108
  100. checksums.yaml.gz.sig +0 -3
  101. data.tar.gz.sig +0 -2
  102. data/LICENSE +0 -339
  103. data/README +0 -32
  104. data/bin/schleuder-fix-gem-dependencies +0 -37
  105. data/bin/schleuder-init-setup +0 -37
  106. data/bin/schleuder-migrate-v2.1-to-v2.2 +0 -225
  107. data/bin/schleuder-newlist +0 -413
  108. data/contrib/check-expired-keys.rb +0 -60
  109. data/contrib/mutt-schleuder-colors.rc +0 -10
  110. data/contrib/mutt-schleuder-resend.vim +0 -24
  111. data/contrib/smtpserver.rb +0 -76
  112. data/ext/default-list.conf +0 -149
  113. data/ext/default-members.conf +0 -7
  114. data/ext/list.conf.example +0 -14
  115. data/ext/schleuder.conf +0 -64
  116. data/lib/schleuder/archiver.rb +0 -46
  117. data/lib/schleuder/crypt.rb +0 -210
  118. data/lib/schleuder/errors.rb +0 -5
  119. data/lib/schleuder/list_config.rb +0 -146
  120. data/lib/schleuder/log/listlogger.rb +0 -57
  121. data/lib/schleuder/log/outputter/emailoutputter.rb +0 -120
  122. data/lib/schleuder/log/outputter/metaemailoutputter.rb +0 -50
  123. data/lib/schleuder/log/schleuderlogger.rb +0 -34
  124. data/lib/schleuder/mail.rb +0 -873
  125. data/lib/schleuder/mailer.rb +0 -26
  126. data/lib/schleuder/member.rb +0 -69
  127. data/lib/schleuder/plugin.rb +0 -54
  128. data/lib/schleuder/processor.rb +0 -363
  129. data/lib/schleuder/schleuder_config.rb +0 -75
  130. data/lib/schleuder/storage.rb +0 -84
  131. data/lib/schleuder/utils.rb +0 -80
  132. data/man/schleuder-newlist.8 +0 -174
  133. data/man/schleuder.8 +0 -416
  134. data/plugins/README +0 -20
  135. data/plugins/manage_keys_plugin.rb +0 -113
  136. data/plugins/manage_members_plugin.rb +0 -156
  137. data/plugins/manage_self_plugin.rb +0 -26
  138. data/plugins/resend_plugin.rb +0 -35
  139. data/plugins/sign_this_plugin.rb +0 -14
  140. data/plugins/version_plugin.rb +0 -12
  141. metadata.gz.sig +0 -0
@@ -1,26 +0,0 @@
1
- module Schleuder
2
- class Mailer
3
- def self.send(msg, to=nil, sender=Schleuder.list.bounce_addr, nolog=false)
4
- to = msg.to if to.nil?
5
-
6
- # TODO: TLS
7
- host = Schleuder.config.smtp_host
8
- port = Schleuder.config.smtp_port
9
- unless nolog
10
- Schleuder.log.info { "Delivering mail to #{host}:#{port}" }
11
- Schleuder.log.debug { "Mail has Sender: #{sender} - To: #{to.inspect}" }
12
- end
13
- Net::SMTP.start(host, port) do |smtpcon|
14
- smtpcon.send_message msg.to_s, sender, to
15
- end
16
- true
17
- rescue => e
18
- if e.message.frozen?
19
- Schleuder.log.warn "Something went wrong, while sending a message. I'll better preserve the message that should have been sent:\n#{msg.to_s}"
20
- else
21
- e.message << "\nOriginal message:\n#{msg.to_s}"
22
- end
23
- raise
24
- end
25
- end
26
- end
@@ -1,69 +0,0 @@
1
- module Schleuder
2
- class Member < Storage
3
- schleuder_attr :email, nil
4
- schleuder_attr :mime, 'MIME'
5
- # only send encrypted mail to this member
6
- schleuder_attr :encrypted_only, false
7
- schleuder_attr :key_fingerprint, nil
8
-
9
- def initialize(config=nil)
10
- super(config)
11
-
12
- # compress fingerprint
13
- self.key_fingerprint = self.key_fingerprint
14
- end
15
-
16
- def to_hash
17
- Hash[*self.class.default_schleuder_attributes.keys.collect { |key|
18
- unless (val = send(key)).to_s.empty?
19
- [ key, val ]
20
- else
21
- nil
22
- end
23
- }.flatten.compact]
24
- end
25
-
26
- def key_fingerprint=(fpr)
27
- schleuder_attributes['key_fingerprint'] = Schleuder::Utils.compress_fingerprint(fpr)
28
- end
29
-
30
- def to_s
31
- email
32
- end
33
-
34
- def key(only_valid_keys=true)
35
- if @key.nil? || !only_valid_keys # by default we want only valid keys. If
36
- # we ask also for invalid keys we want
37
- # to redo the keylookup
38
- lookup_str = self.key_fingerprint.nil? ? self.email : self.key_fingerprint
39
- key_result = crypt.get_key(lookup_str,only_valid_keys)
40
- if k = key_result.first
41
- @key = k
42
- self.key_fingerprint = @key.subkeys.first.fingerprint
43
- else
44
- @key = nil
45
- self.key_fingerprint = nil
46
- return key_result
47
- end
48
- end
49
- @key
50
- end
51
-
52
- def uses_key?(other_key)
53
- key # initialize @key
54
- !@key.nil? && @key.subkeys.first.fingerprint == other_key.subkeys.first.fingerprint
55
- end
56
-
57
- def key_descr
58
- k, msg = key
59
- k ? crypt.key_descr(k) : "*Warning:* #{msg}"
60
- end
61
-
62
- private
63
- def crypt
64
- # No simple way to get hands on mail.crypt, so we create another here.
65
- # But on class side as it does not need to be per member
66
- @@crypt ||= Crypt.new(nil)
67
- end
68
- end
69
- end
@@ -1,54 +0,0 @@
1
- module Schleuder
2
- # Parent-class for plugins. Sets up stub and helper methods.
3
- class Plugin
4
- # Define whether this plugin should be used for emails sent to the
5
- # list-address or the request-address.
6
- attr_reader :plugin_type
7
-
8
- def Plugin.signing_key(mail)
9
- @@key ||= mail.crypt.get_key(mail.in_signed.fpr).first
10
- end
11
-
12
- # Helper: creates a reply to the sender of the incoming message. The
13
- # destination address is detemined by finding the list-member connected to
14
- # the key that signed the incoming message. +msg+ is used as body for the
15
- # outgoing mail.
16
- def Plugin.reply(mail, msg, keywords)
17
- Schleuder.log.info "Building reply mail"
18
- out = Mail.new
19
-
20
- out.subject = "Re: #{mail.subject}"
21
- key = Plugin.signing_key(mail)
22
- Schleuder.log.debug "Looking up member by key: #{key.inspect}"
23
- member = Schleuder.list.find_member_by_key(key) || Schleuder.list.find_admin_by_key(key)
24
- Schleuder.log.debug { "Result: #{member.inspect}" }
25
- if member
26
- Schleuder.log.info { "Found member for key: %s" % member.inspect }
27
- else
28
- Schleuder.log.error "No member or admin found for signing key, aborting reply."
29
- return false
30
- end
31
-
32
- imail = out.individualize(member)
33
- imail.in_reply_to = mail.message_id
34
- imail.body = msg
35
-
36
- unless imail.encrypt!(member)
37
- Schleuder.log.debug 'encrypting failed, replacing body with please-fix-message'
38
- imail.body = "Encrypting to #{imail.to} failed. Please fix."
39
- end
40
-
41
- Schleuder.log.info "Sending to #{imail.to}"
42
- Mailer.send(imail)
43
-
44
- unless (Schleuder.list.config.keywords_admin_notify & keywords).empty?
45
- Schleuder.log.info "Sending notification to admins"
46
- msg = "Hello list-admin,\n\nmember #{member.email} sent the keyword(s) '#{keywords.join("','")}' and received the following reply-message:\n\n\n".fmt << msg
47
- Schleuder.log.notify_admin 'Notice', msg
48
- end
49
-
50
- Schleuder.log.info "Exiting"
51
- exit 0
52
- end
53
- end
54
- end
@@ -1,363 +0,0 @@
1
- module Schleuder
2
- def log
3
- SchleuderLogger.new unless Log4r::Logger['log4r']
4
- # If there's a ListLogger we use that, else the global SchleuderLogger.
5
- # The ListLogger is being set up in List::initialize().
6
- Log4r::Logger['list'] || Log4r::Logger['log4r']
7
- end
8
- module_function :log
9
-
10
- def config(config_file=nil)
11
- # read the base config (class overloads itself with conf/schleuder.conf)
12
- @config ||= SchleuderConfig.new(config_file)
13
- end
14
- module_function :config
15
-
16
- def list
17
- @list || nil
18
- end
19
- module_function :list
20
-
21
- def list=(list)
22
- @list = list
23
- end
24
- module_function :list=
25
-
26
- def origmsg=(msg)
27
- @origmsg = msg
28
- end
29
- module_function :origmsg=
30
-
31
- def origmsg
32
- @origmsg || nil
33
- end
34
- module_function :origmsg
35
-
36
- def self.listname(listname=nil)
37
- @listname ||= listname
38
- end
39
-
40
- class Processor
41
- def self.run(listname, message)
42
- Schleuder.listname(listname)
43
- Schleuder.origmsg = message
44
- Schleuder.log.debug "Testing if list-dir exists"
45
- unless File.directory?(List.listdir(listname))
46
- msg = "No such list: #{listname}"
47
- $stderr.puts msg
48
- Schleuder.log.warn msg
49
- exit 1
50
- end
51
-
52
- Schleuder.log.debug "Creating list"
53
- Schleuder.list = List.new(listname)
54
-
55
- Schleuder.log.debug "Parsing incoming message"
56
- mail = Mail.parse(message)
57
- Schleuder.log.info "New mail incoming from #{mail.from}"
58
-
59
- msize = message.size / 1024
60
- lsize = Schleuder.list.config.max_message_size
61
- if msize > lsize
62
- self.bounce_or_drop "too big (#{msize}kB > #{lsize}kB)", "This address accepts only messages up to #{Schleuder.list.config.max_message_size} kilobyte.", mail
63
- end
64
-
65
- # if mail is a bounce we forward it directly to the admins, as
66
- # dealing with those probably fails (encrypted attachments etc.)
67
- if mail.bounce?
68
- Schleuder.log.info "This is a bounce, forwarding to admins and exiting"
69
- Schleuder.log.notify_admin "Problem", [ "Hello,\n\nI caught a bounce. Please take care of it.", message ]
70
- Schleuder.log.info "Exiting cleanly"
71
- exit(0)
72
- end
73
-
74
- if Schleuder.list.config.dump_incoming_mail
75
- dump_dir = File.join(Schleuder.list.listdir,'dumps')
76
- Dir.mkdir dump_dir unless File.directory? dump_dir
77
- require 'digest/sha1'
78
- msg_file = File.join(dump_dir,"#{Digest::SHA1.hexdigest(message[0..10000])}.msg")
79
- Schleuder.log.info "Dumping message to #{msg_file}"
80
- File.open(msg_file,"w") { |f| f << message }
81
- Schleuder.log.notify_admin "Dump notification", "Hello,\n\nI dumped the current incoming message to #{msg_file} \n\nYou should erase that file after inspection!"
82
- end
83
-
84
- # if mail is a send-key-request we answer directly
85
- if mail.to.to_a.include?(Schleuder.list.sendkey_addr) || (mail.subject.strip.downcase == 'send key!' && mail.body.strip.empty?)
86
- Schleuder.log.info "Found send-key-request"
87
- # TODO: refactor with Plugin::reply
88
- out = Mail.new
89
- out.subject = "Re: #{mail.subject}"
90
- Schleuder.log.info "Building reply"
91
- iout = out.individualize(Member.new({'email' => mail.from.first}))
92
- iout.in_reply_to = mail.message_id
93
- Schleuder.log.debug "Filling body with key-id and key"
94
- iout.body = "#{Schleuder.list.key.to_s}\n#{mail.crypt.export(Schleuder.list.key_fingerprint).to_s}"
95
- Schleuder.log.debug "Signing outgoing email"
96
- rawmail = iout.sign
97
- Schleuder.log.info "Handing over to Mailer"
98
- Mailer.send(rawmail, iout.to)
99
- Schleuder.log.info "Exiting"
100
- exit 0
101
- end
102
-
103
- # Analyse data (hopefully an incoming mail).
104
- # Is it multi-part? encrypted? pgp/mime? signed?
105
- Schleuder.log.debug "Analysing incoming mail"
106
- begin
107
- mail.decrypt!
108
- rescue GPGME::Error::DecryptFailed => e
109
- Schleuder.log.error "#{e}\n\nOriginal message:\n#{message}"
110
- $stdout.puts "Schleuder speaking. Cannot decrypt. Please check your setup.\nMessages to this list need to be encrypted with this key:\n#{Schleuder.list.key}"
111
- exit 100
112
- end
113
-
114
- if !mail.to.nil? && mail.to.include?(Schleuder.list.owner_addr)
115
- Schleuder.log.info "This is a message to the owner(s), forwarding to admins and exiting"
116
- Schleuder.log.notify_admin "Message", [ "Hello,\n\nthe attached message is directed to you as list-owner(s). Please take care of it!\n\n", mail ]
117
- Schleuder.log.info "Exiting cleanly"
118
- exit(0)
119
- end
120
-
121
- if Schleuder.list.config.receive_signed_only && !mail.in_signed
122
- self.bounce_or_drop "not validly signed", "This address accepts only messages validly signed in an OpenPGP-compatible way", mail
123
- end
124
-
125
- if Schleuder.list.config.receive_encrypted_only && !mail.in_encrypted
126
- self.bounce_or_drop 'not encrypted', "This address accepts only messages encrypted with this key:\n#{Schleuder.list.key}", mail
127
- end
128
-
129
- if Schleuder.list.config.receive_authenticated_only && !(mail.from_member || mail.from_admin)
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
- end
132
-
133
- if Schleuder.list.config.receive_from_member_emailaddresses_only && !(mail.from_member_address?||mail.from_admin_address?)
134
- self.bounce_or_drop "not from a member e-mail address", "This address accepts only messages from member addresses.", mail
135
- end
136
-
137
- if Schleuder.list.config.receive_admin_only && !mail.from_admin
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
- end
140
-
141
- if mail.to.to_a.include?(Schleuder.list.request_addr)
142
- if (mail.from_member || mail.from_admin) && mail.in_encrypted
143
- process_plugins(mail)
144
- # If we reach this point no plugin took over
145
- self.bounce_or_drop "not a valid request", "No valid command found in message. This address (-request) accepts only messages containing valid schleuder-keyword-commands.".fmt, mail
146
- end
147
- self.bounce_or_drop "not authenticated", "This address (-request) accepts only encrypted messages by list-members.".fmt, mail
148
- end
149
-
150
- unless mail.from_member || mail.from_admin
151
- Schleuder.log.debug "Mail is not from a list-member, adding prefix_in"
152
- mail.add_prefix_in!
153
- end
154
-
155
- # Checking for keywords in mail-body (e.g. X-RESEND)
156
- if mail.from_member || mail.from_admin
157
- if mail.in_encrypted
158
- Schleuder.log.info "Incoming mail is encrypted and authorized, processing plugins"
159
- process_plugins(mail)
160
- else
161
- Schleuder.log.info "Incoming mail is not encrypted or authorized, skipping plugins"
162
- end
163
- end
164
-
165
- # first encrypt and send message to external recipients and collect
166
- # information about the process
167
- mail.resend_to.each do |receiver|
168
- if receiver.email.to_s.empty?
169
- errmsg = "Invalid value for receiver.email: %s. Skipping."
170
- Schleuder.log.warn { errmsg % receiver.email.inspect }
171
- next
172
- end
173
-
174
- imail = mail.individualize(receiver)
175
- imail.add_public_footer!
176
-
177
- if Schleuder.list.config.send_encrypted_only
178
- enc_only = true
179
- else
180
- enc_only = receiver.encrypted_only
181
- end
182
-
183
- begin
184
- ret = self.send(imail, receiver, enc_only)
185
- if ret.first
186
- # store meta-data about the sent message
187
- crypt = " (#{ret[1]})"
188
- mail.metadata[:resent_to] << receiver.email + crypt
189
- else
190
- mail.metadata[:error] << "Not resent to #{receiver.email}: #{ret[1]}"
191
- end
192
- rescue => e
193
- Schleuder.log.error e
194
- end
195
- end
196
-
197
- mail.add_prefix_out! unless mail.metadata[:resent_to].empty?
198
- mail.add_prefix!
199
- mail.add_metadata!
200
-
201
- # archive message if necessary
202
- Schleuder.list.archive(mail) if Schleuder.list.config.archive
203
-
204
- # encrypt message and send mail for each list-member
205
- Schleuder.log.info { 'Looping over all list-members to send out' }
206
- Schleuder.list.members.each do |receiver|
207
- Schleuder.log.debug { "Looping for #{receiver.inspect}" }
208
-
209
- if receiver.email.to_s.empty?
210
- errmsg = "Invalid value for receiver.email: %s. Skipping."
211
- Schleuder.log.warn { errmsg % receiver.email.inspect }
212
- next
213
- end
214
-
215
- imail = mail.individualize_member(receiver)
216
-
217
- if Schleuder.list.config.send_encrypted_only
218
- enc_only = true
219
- else
220
- enc_only = receiver.encrypted_only
221
- end
222
-
223
- # encrypt for each receiver
224
- begin
225
- sent = self.send(imail, receiver, enc_only)
226
- unless sent.first
227
- Schleuder.log.error sent[1]
228
- end
229
- rescue => e
230
- Schleuder.log.error e
231
- end
232
- end
233
- Schleuder.log.info { 'Processing done, this is the end.' }
234
- end
235
-
236
- def self.send(mail, receiver, encrypted_only=true, sender=Schleuder.list.bounce_addr)
237
- begin
238
- encrypted, errmsg = mail.encrypt!(receiver)
239
- rescue GPGME::Error::UnusablePublicKey => e
240
- # This exception is thrown, if the public key of a certain list
241
- # member is not usable (because it is revoked, expired, disabled or
242
- # invalid).
243
- k = e.keys.first
244
- key = mail.crypt.get_key(k.fpr).first
245
- errmsg = "#{e.message}: (#{k.class})\n#{key.to_s}"
246
- Schleuder.log.error "Encryption failed (#{errmsg})"
247
- encrypted = false
248
- rescue GPGME::Error::General => e
249
- errmsg = e.message
250
- Schleuder.log.error "Encryption failed (#{errmsg})"
251
- encrypted = false
252
- end
253
- if encrypted
254
- Mailer.send(mail, nil, sender)
255
- return [true, 'encrypted']
256
- else
257
- if encrypted_only
258
- Schleuder.log.debug "Sending plaintext not allowed, message not sent to #{receiver.inspect}!"
259
- return [false, "Encrypting to #{receiver.email.inspect} failed: #{errmsg} (sending plaintext disallowed)"]
260
- else
261
- Schleuder.log.info "Sending plaintext allowed, doing so"
262
- # sign msg
263
- if rawmail = mail.sign
264
- Mailer.send(rawmail, mail.to, sender)
265
- return [true, "unencrypted (#{errmsg})"]
266
- else
267
- return [false, "signing failed"]
268
- end
269
- end
270
- end
271
- end
272
-
273
- def self.test(listname=nil)
274
- # Doing things that trigger exceptions if they fail, which we rescue and
275
- # put to stderr
276
- # TODO: test #{smtp_host}:25
277
- begin
278
- # test listdir
279
- Dir.entries Schleuder.config.lists_dir
280
-
281
- # test superadminaddr
282
- Utils::verify_addr('superadminaddr', Schleuder.config.superadminaddr)
283
-
284
- if listname
285
- # testwise create a list-object (reads list-config etc.)
286
- list = List.new listname
287
- # test for listdir
288
- Dir.entries list.listdir
289
- # test admins
290
- list.config.admins.each do |a|
291
- Utils::verify_addr('adminaddr', a.email)
292
- key, msg = a.key
293
- if !key
294
- raise "Admin: #{a}'s key lookup fails! Problem: #{msg}"
295
- end
296
- end
297
-
298
- crypt = Crypt.new(list.config.gpg_password)
299
-
300
- list.members.each do |m|
301
- Utils::verify_addr('member address', m.email)
302
- key, msg = m.key
303
- if !key
304
- raise "#{m}'s key lookup fails! Problem: #{msg}"
305
- end
306
- end
307
- end
308
- rescue => e
309
- $stderr.puts e.message
310
- $stderr.puts e.backtrace
311
- exit 1
312
- end
313
- end
314
-
315
- def self.newlist(listname, interactive='true', args=nil)
316
- created_list = Schleuder::ListCreator.create(listname,interactive,args)
317
- end
318
-
319
- def self.bounce_or_drop(status, bounce_msg, mail)
320
- Schleuder.log.warn "Mail is #{status}, not passing it along"
321
-
322
- if Schleuder.list.config.bounces_drop_all
323
- Schleuder.log.warn "Found bounces_drop_all being true: dropping!"
324
- self.bounce_notify_admin status, "bounces_drop_all is true"
325
- exit 0
326
- end
327
-
328
- Schleuder.log.debug "Testing bounces_drop_on_headers"
329
- Schleuder.list.config.bounces_drop_on_headers.each do |header,value|
330
- Schleuder.log.debug "Testing #{header} => #{value}"
331
- if mail.header[header].to_s.downcase == value.to_s.downcase
332
- Schleuder.log.warn "Found matching drop-header: #{header} => #{value} -- dropping!"
333
- self.bounce_notify_admin status, "Forbidden header found: '#{header.capitalize}: #{value.capitalize}'"
334
- exit 0
335
- end
336
- end
337
-
338
- # if we're still alive: bounce message
339
- Schleuder.log.info "bouncing mail to sender"
340
- self.bounce_notify_admin("#{status}. - #{bounce_msg}")
341
- $stdout.puts bounce_msg
342
- exit 100
343
- end
344
-
345
- def self.bounce_notify_admin(reason, drop_reason='')
346
- msg = "The attached incoming email has not been passed to the list.\nReason: #{reason}.\n"
347
- if drop_reason.empty?
348
- msg += "\nIt has been bounced to the sender.\n"
349
- else
350
- msg += "\nIt has *not* been bounced but dropped.\nReason: #{drop_reason}.\n"
351
- end
352
-
353
- Schleuder.log.notify_admin("Notice", [ msg, Mail.parse(Schleuder.origmsg) ]) if Schleuder.list.config.bounces_notify_admin
354
- end
355
-
356
- def self.process_plugins(mail)
357
- Schleuder.log.info 'Email is encrypted and authorized, processing plugins'
358
- # process plugins
359
- Schleuder.log.debug 'Processing plugins'
360
- mail.process_plugins!
361
- end
362
- end
363
- end