schleuder 2.2.0

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.
Files changed (45) hide show
  1. data.tar.gz.sig +0 -0
  2. data/LICENSE +339 -0
  3. data/README +32 -0
  4. data/bin/schleuder +96 -0
  5. data/bin/schleuder-fix-gem-dependencies +30 -0
  6. data/bin/schleuder-init-setup +37 -0
  7. data/bin/schleuder-migrate-v2.1-to-v2.2 +205 -0
  8. data/bin/schleuder-newlist +384 -0
  9. data/contrib/check-expired-keys.rb +59 -0
  10. data/contrib/mutt-schleuder-colors.rc +10 -0
  11. data/contrib/mutt-schleuder-resend.vim +24 -0
  12. data/contrib/smtpserver.rb +76 -0
  13. data/ext/default-list.conf +146 -0
  14. data/ext/default-members.conf +7 -0
  15. data/ext/list.conf.example +14 -0
  16. data/ext/schleuder.conf +62 -0
  17. data/lib/schleuder.rb +49 -0
  18. data/lib/schleuder/archiver.rb +46 -0
  19. data/lib/schleuder/crypt.rb +188 -0
  20. data/lib/schleuder/errors.rb +5 -0
  21. data/lib/schleuder/list.rb +177 -0
  22. data/lib/schleuder/list_config.rb +146 -0
  23. data/lib/schleuder/log/listlogger.rb +56 -0
  24. data/lib/schleuder/log/outputter/emailoutputter.rb +118 -0
  25. data/lib/schleuder/log/outputter/metaemailoutputter.rb +50 -0
  26. data/lib/schleuder/log/schleuderlogger.rb +23 -0
  27. data/lib/schleuder/mail.rb +861 -0
  28. data/lib/schleuder/mailer.rb +26 -0
  29. data/lib/schleuder/member.rb +69 -0
  30. data/lib/schleuder/plugin.rb +54 -0
  31. data/lib/schleuder/processor.rb +363 -0
  32. data/lib/schleuder/schleuder_config.rb +72 -0
  33. data/lib/schleuder/storage.rb +84 -0
  34. data/lib/schleuder/utils.rb +80 -0
  35. data/lib/schleuder/version.rb +3 -0
  36. data/man/schleuder-newlist.8 +191 -0
  37. data/man/schleuder.8 +400 -0
  38. data/plugins/README +20 -0
  39. data/plugins/manage_keys_plugin.rb +113 -0
  40. data/plugins/manage_members_plugin.rb +152 -0
  41. data/plugins/manage_self_plugin.rb +26 -0
  42. data/plugins/resend_plugin.rb +35 -0
  43. data/plugins/version_plugin.rb +12 -0
  44. metadata +178 -0
  45. metadata.gz.sig +2 -0
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script checks all public keys in the keyring of the given schleuder-list
4
+ # for being expired (or otherwise unusable) and reports the output (if there
5
+ # was something found) to the list-admins.
6
+ # Key are being reported if they expire within the next 14 days.
7
+ # We suggest to run this script from cron once a week.
8
+
9
+ $VERBOSE = nil
10
+
11
+ require 'schleuder'
12
+ include Schleuder
13
+
14
+ if ARGV.size != 1
15
+ puts "Usage: #{File.basename(__FILE__)} listname"
16
+ exit 1
17
+ elsif ! File.directory?(List.listdir(ARGV.first))
18
+ puts "No such list: '#{ARGV.first}'."
19
+ exit 1
20
+ end
21
+
22
+ listname = ARGV.first
23
+ Schleuder.list = List.new(listname)
24
+
25
+ now = Time.now
26
+ checkdate = now + 120960000 # two weeks
27
+ crypt = Crypt.new('')
28
+ msg = ''
29
+ unusable = []
30
+ expiring = []
31
+
32
+ crypt.list_keys.each do |key|
33
+ if (exp = key.subkeys.first.expires) > Time.utc(1971, 1, 1, 1)
34
+ # key has expiry date
35
+ if now < exp && exp < checkdate
36
+ # key expires in the near future
37
+ expdays = ((exp - now)/86400).to_i
38
+ expiring << [key, expdays]
39
+ end
40
+ end
41
+
42
+ if not (trust = [:revoked, :expired, :disabled, :invalid].grep(key.trust)).empty?
43
+ unusable << [key, trust]
44
+ end
45
+ end
46
+
47
+ expiring.each do |key,days|
48
+ msg << "-> Key expires in #{days} days:\n#{key.to_s}\n\n"
49
+ end
50
+
51
+ unusable.each do |key,trust|
52
+ msg << "-> Key is #{trust.join(' and ')}:\n#{key.to_s}\n"
53
+ end
54
+
55
+ unless msg.empty?
56
+ prefix = "Checking the public keys present in the keyring of list #{listname} for usability gave the following result:".fmt
57
+ Schleuder.log.notify_admin('keys', prefix + "\n\n" + msg)
58
+ end
59
+
@@ -0,0 +1,10 @@
1
+ # insert "source /path/to/mutt-schleuder-colors.rc" into your muttrc
2
+ # metadata schleuder v2
3
+ color body red default "^From: .*"
4
+ color body red default "^To: .*"
5
+ color body red default "^Cc: .*"
6
+ color body red default "^Date: .*"
7
+ color body brightred default "^Enc: unenc.*"
8
+ color body red default "^Enc: enc.*"
9
+ color body brightred default "^Sig: [^G]?.*"
10
+ color body red default "^Sig: Good signature.*"
@@ -0,0 +1,24 @@
1
+ " Reply-helper for mutt with schleuder (>= v2.0.0).
2
+ " Will insert a resend-line filled with the address from the quoted Text
3
+ " you're replying to.
4
+ function! SchleuderInsert(string)
5
+ let fromline = search('> From:', 'n')
6
+ let addr = matchstr(getline(fromline), '[^ <]*@[^ >]*')
7
+ let insline = search('^$', 'n')
8
+ " append after the first blank line
9
+ let foo = append(insline, a:string . addr)
10
+ " can't figure out how to append() a newline, so we simply add another
11
+ " empty line
12
+ return append(insline+1, '')
13
+ endfunction
14
+
15
+ function! SchleuderInsertResendEncrypted()
16
+ return SchleuderInsert('X-RESEND-ENCRYPTED-ONLY: ')
17
+ endfunction
18
+
19
+ function! SchleuderInsertResend()
20
+ return SchleuderInsert('X-RESEND: ')
21
+ endfunction
22
+
23
+ nmap ;sr :call SchleuderInsertResend()<CR>
24
+ nmap ;sc :call SchleuderInsertResendEncrypted()<CR>
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # defaults
4
+ port = 25
5
+ output = "/tmp"
6
+
7
+ def usage
8
+ file = File.basename(__FILE__)
9
+ puts "Usage: #{file} [-p portnum] { .../output_base_dir/ | .../bin/schleuder listname }"
10
+ exit 1
11
+ end
12
+
13
+ # get args
14
+ if (not ARGV.empty?) and (ARGV.first[0..0] == '-')
15
+ arg = ARGV.shift
16
+ if arg == '-p'
17
+ port = ARGV.shift.to_i
18
+ usage if port == 0 # nil or not convertable strings convert to 0
19
+ else
20
+ usage
21
+ end
22
+ end
23
+
24
+ output = ARGV.join(" ") || output
25
+
26
+
27
+ # run the server
28
+ require 'socket'
29
+ server = TCPServer.new("localhost", port)
30
+
31
+ def p(msg)
32
+ #puts "o:" + msg
33
+ @s.print msg + "\r\n"
34
+ end
35
+
36
+ # receive input
37
+ while (@s = server.accept)
38
+ input = ''
39
+ #p "200 OK"
40
+ p "220 localhost SMTP"
41
+ #p "Wazzup?"
42
+ begin
43
+ while i = @s.gets.chomp
44
+ #puts "i:" + i
45
+ case i[0..3].downcase
46
+ when 'ehlo', 'helo'
47
+ p "250 localhost"
48
+ when 'mail', 'rcpt', 'rset', '.'
49
+ p "250 ok"
50
+ when 'data'
51
+ p "354 go ahead"
52
+ when 'quit'
53
+ p "221 localhost"
54
+ @s.close
55
+ else
56
+ input << i + "\n"
57
+ end
58
+ end
59
+ rescue IOError
60
+ end
61
+ # write input to #{output}
62
+ if File.directory? output
63
+ file = output + "/schleuder-#{$$}-#{Time.now.to_f}"
64
+ File.open(file, 'w') do |f|
65
+ f.puts input
66
+ end
67
+ File.chown 1000, 10, file
68
+ puts file
69
+ else
70
+ IO.popen(output, 'w') do |p|
71
+ p.puts input
72
+ end
73
+ end
74
+ end
75
+
76
+
@@ -0,0 +1,146 @@
1
+ # Setting default values for lists. Each setting can be overridden by the
2
+ # list-specific config-file.
3
+ # Options are listed alphabetically and provided with the default behaviour.
4
+ # Some options that need to be set for each list individually are listed in
5
+ # list.conf.example.
6
+ #
7
+ # The configuration format is yaml (http://www.yaml.org).
8
+ #
9
+ # Be careful with changes here once lists are running! You might change
10
+ # their behaviour!
11
+ ---
12
+ # Emailaddresses and key_fingerprints of the admin(s) (aka maintainer) of the
13
+ # list, which will receive errormsgs etc. Must be a non-empty array of hashes
14
+ # (:email, :key_fingerprint).
15
+ #admins:
16
+ #- email: anna@example.org
17
+ # key_fingerprint: 01234567DEADBEE01234567DEADBEEF
18
+ #- email: arthur@example.org
19
+ # key_fingerprint: DEADBEE01234567DEADBEEF01234567
20
+ #
21
+ # Only send out enrypted emails?
22
+ #send_encrypted_only: false
23
+ #
24
+ # Allow receiving unenrypted mails? If false, any other email will be bounced.
25
+ #receive_encrypted_only: false
26
+ #
27
+ # Allow receiving mails not validly signed? If false, any other email will be
28
+ # bounced.
29
+ #receive_signed_only: false
30
+ #
31
+ # Allow receiving mails that are not validly signed by a list members key? If
32
+ # true, any other email will be bounced.
33
+ #receive_authenticated_only: false
34
+ #
35
+ # Only allow mails being sent from a members address? If true, any other sending
36
+ # address will be dropped.
37
+ # NOTE: This is a very weak restriction mechanism on which you should not rely,
38
+ # as sending addresses can easily be faked! We recommend you to rather
39
+ # rely on the `receive_authenticated_only` option. Setting the
40
+ # `receive_authenticated_only` option to true, will authenticated senders
41
+ # based on the signature on the mail, which is the strongest
42
+ # authentication mechanism you can get.
43
+ # This option could be useful, if you would like to have a closed
44
+ # mailinglist, but could not yet get all members to properly use GPG.
45
+ #receive_from_member_emailaddresses_only: false
46
+ #
47
+ # Whether to accept only emails that are validly signed by a list-admin's key
48
+ # This is useful for newsletters, announce or notification lists
49
+ #receive_admin_only: false
50
+ #
51
+ # Which pgp encoding? Chose out of PLAIN (text/plain), APPL (application/pgp)
52
+ # and MIME (pgp/mime)
53
+ #default_mime: MIME
54
+ #
55
+ # Schleuder can include various metadata from the original mail. You can tweak
56
+ # Schleuder which header fields should be included.
57
+ #headers_to_meta:
58
+ #- :from
59
+ #- :to
60
+ #- :cc
61
+ #- :date
62
+ #
63
+ # Whether to keep the msgids (In-Reply-To:, References:) or not
64
+ # Schleuder will only pass valid schleuder Message-Ids, all the others
65
+ # are filtered out.
66
+ # This setting can lead to information leakage, as replies are connectable
67
+ # and a thread of (encrypted) messages can be built by an eavesdropper.
68
+ #keep_msgid: true
69
+ #
70
+ # Schleuder can be commanded to process various plugins via keywords in signed
71
+ # emails. To restrict the usage of specific keywords to the admin (some can
72
+ # cause fatal damage) list them here.
73
+ #keywords_admin_only: ['ADD-MEMBER', 'DELETE-MEMBER', 'DELETE-KEY', 'SAVE-MEMBERS', 'DEL-KEY']
74
+ #
75
+ # For keywords listed here the list-admin(s) will receive a notice whenever a
76
+ # member triggers a command with it.
77
+ #keywords_admin_notify: ['ADD-KEY']
78
+ #
79
+ # list-specific log-level: ERROR || WARN || INFO || DEBUG
80
+ #log_level: ERROR
81
+ #
82
+ # Log to SYSLOG? To enable set to true.
83
+ #log_syslog: false
84
+ #
85
+ # Log to IO (write into STDIN of another process/executable)? To enable specify
86
+ # executable with full path and optional arguments here.
87
+ # Example: /path/to/multilog tt /var/schleuderlists/listname/log/
88
+ #log_io: false
89
+ #
90
+ # Log to a file? To enable specify a filename, optionally with full path.
91
+ #log_file: false
92
+ #
93
+ # speaks for itself, no?
94
+ #public_footer:
95
+ #
96
+ # A string that the subject of every email that *is* validly signed by a
97
+ # list-member will be prefixed with (unless the string is already present in
98
+ # the subject)
99
+ #prefix: ''
100
+ #
101
+ # A string that the subject of every email that is *not* validly signed by a
102
+ # list-member will be prefixed with.
103
+ #prefix_in: ''
104
+ #
105
+ # A string that the subject of every internal email, that has been resent to
106
+ # the outside, will be prefixed with.
107
+ #prefix_out: ''
108
+ #
109
+ # Drop any bounces (incoming email not passing the receive_*_only-rules)
110
+ #bounces_drop_all: false
111
+ #
112
+ # Drop bounces if they match one of these headers. Must be a hash, keys and
113
+ # values are case insensitive.
114
+ #bounces_drop_on_headers: {'x-spam-flag' => 'yes'}
115
+ #
116
+ # Send a notice to admin(s) on bouncing or dropping
117
+ #bounces_notify_admins: true
118
+ #
119
+ # Include RFC-compliant List-* Headers into member mails
120
+ #include_list_headers: true
121
+ #
122
+ # Include OpenPGP-Header
123
+ #include_openpgp_header: true
124
+ #
125
+ # Prefered way to receive emails to note in OpenPGP-Header ('sign'|'encrypt'|'signencrypt'|'unprotected'|'none')
126
+ # 'none' to not include a preference
127
+ # default: 'signencrypt'
128
+ #openpgp_header_preference: 'signencrypt'
129
+ #
130
+ # If we want to dump the original incoming mail.
131
+ # ATTENTION: this stores the incoming e-mail on disk!
132
+ #dump_incoming_mail: false
133
+ #
134
+ # Maximum size of message allowed on the list in kilobyte. All others will be bounced.
135
+ # Default is 10MB
136
+ #max_message_size: 10240
137
+ #
138
+ # Whether to archive messages sent to list members or not.
139
+ # Setting this option to true will archive every message sent to list members
140
+ # into <listdir>/archive/$YEAR/$MONTH/$DAY/$MESSAGEID.msg
141
+ # The messages are encrypted with the lists' public key and dumped as it would
142
+ # have been handed over to the MTA.
143
+ # Beware that this will archive every communication over that list on a remote
144
+ # box amongst the matching private key and its password!
145
+ # Default: false
146
+ #archive: false
@@ -0,0 +1,7 @@
1
+ # Example members-file to give an idea of the syntax.
2
+ ---
3
+ - email: root@localhost
4
+ key_fingerprint: DEADBEEFDEADBEEFDEADBEEFDEADBEEF
5
+ - email: postmaster@localhost
6
+ key_fingerprint: BEEFDEADBEEFDEADBEEFDEADBEEFDEAD
7
+ mime: plain
@@ -0,0 +1,14 @@
1
+ # Configuration options for individal lists.
2
+ # Options are listed alphabetically and provided with the default behaviour.
3
+ # Beyond those options listed here all options listed in default-list.conf can be specified.
4
+ #
5
+ # The configuration format is yaml (http://www.yaml.org).
6
+ ---
7
+ # The emailaddress of the list. Needed to identify headers, loops and also the GnuPG key.
8
+ # Must be a valid email address.
9
+ #myaddr: list@example.org
10
+ # Realname of this list address (mainly used for GnuPG key)
11
+ #myname: The Listname
12
+ # Password for the GnuPG private key. (You're working on an encrypted filesystem, aren't you?)
13
+ # Make it long and complicated, you won't ever need to type it.
14
+ #gpg_password: "iuttIs6flewd)#misIg5drash/#tesJor:5Quej"
@@ -0,0 +1,62 @@
1
+ # Configuration options for schleuder.
2
+ # The options are sorted alphabetically and the defaults
3
+ # are provided as commented option.
4
+ # The configuration format is yaml.
5
+ ---
6
+ # Outgoing SMTP host
7
+ #smtp_host: localhost
8
+ #
9
+ # Outgoing SMTP port
10
+ #smtp_port: 25
11
+ #
12
+ # Set the type of a key we might create for new lists.
13
+ #gpg_key_type: RSA
14
+ #
15
+ # Set the length of a key we might create for new lists.
16
+ #gpg_key_length: 2048
17
+ #
18
+ # Set the type of the subkey of a key we might create
19
+ # for new lists.
20
+ #gpg_subkey_type: RSA
21
+ #
22
+ # Set the length of the subkey of a key we might create
23
+ # for new lists.
24
+ #gpg_subkey_length: 2048
25
+ #
26
+ # Name of the per list config file.
27
+ #lists_configfile: list.conf
28
+ #
29
+ # Per list logfile name. Will be written into the directory
30
+ # of the list.
31
+ #lists_logfile: list.log
32
+ #
33
+ # Name of the per list file containing all members and their
34
+ # options.
35
+ #lists_memberfile: members.conf
36
+ #
37
+ # Where we find the global options for all lists.
38
+ # Note: the following notion isn't valid. You have
39
+ # to provide a fully qualified path.
40
+ #lists_default_conf: conf_dir + '/default-list.conf'
41
+ #
42
+ # Location of the various schleuderlists' directory.
43
+ #lists_dir: /var/schleuderlists
44
+ #
45
+ # Location of the global logfile.
46
+ #log_file: /var/log/schleuder/schleuder.log
47
+ #
48
+ # Global schleuder log level, might change after the list config
49
+ # have been read.
50
+ # Possible values: ERROR || WARN || INFO || DEBUG
51
+ #log_level: ERROR
52
+ #
53
+ # Location of schleuder plugins. Note: the following notion
54
+ # isn't valid. You have to provide a fully qualified path.
55
+ #plugins_dir = schleuder_base + '/plugins'
56
+ #
57
+ # The super administrator of this schleuder installation. This
58
+ # address will receive all notices which can'tbe delivered to a certain list
59
+ # admin. It will also be used as sender for emails to list-admins and thus
60
+ # receive their bounces and be seen in public.
61
+ #superadminaddr: root@localhost
62
+
data/lib/schleuder.rb ADDED
@@ -0,0 +1,49 @@
1
+ # third party
2
+
3
+ errmsg = "For use with ruby v%s %s is required!\nPlease run schleuder-fix-gem-dependencies to fix this!"
4
+ if RUBY_VERSION =~ /1.8/
5
+ require 'rubygems'
6
+ begin
7
+ require 'tmail'
8
+ rescue LoadError
9
+ $stderr.puts errmsg % %w(1.8, tmail \(preferably v1.2.3.1\))
10
+ exit 1
11
+ end
12
+ else
13
+ begin
14
+ gem 'actionmailer', '=2.3.14'
15
+ require 'action_mailer'
16
+ rescue LoadError
17
+ $stderr.puts errmsg % %w(1.9, actionmailer-2.3.14)
18
+ exit 1
19
+ end
20
+ end
21
+
22
+ gem 'gpgme', '=1.0.8'
23
+ require 'gpgme'
24
+
25
+ require 'net/smtp'
26
+ require 'log4r'
27
+ require 'log4r/outputter/emailoutputter'
28
+ require 'log4r/outputter/fileoutputter'
29
+ require 'filemagic/ext'
30
+
31
+ # internal requires
32
+ $:.unshift File.dirname(__FILE__)
33
+ require 'schleuder/errors'
34
+ require 'schleuder/utils'
35
+ require 'schleuder/crypt'
36
+ require 'schleuder/storage'
37
+ require 'schleuder/list_config'
38
+ require 'schleuder/list'
39
+ require 'schleuder/mailer'
40
+ require 'schleuder/mail'
41
+ require 'schleuder/member'
42
+ require 'schleuder/plugin'
43
+ require 'schleuder/schleuder_config'
44
+ require 'schleuder/log/outputter/emailoutputter'
45
+ require 'schleuder/log/outputter/metaemailoutputter'
46
+ require 'schleuder/log/schleuderlogger'
47
+ require 'schleuder/log/listlogger'
48
+ require 'schleuder/archiver'
49
+ require 'schleuder/processor'