schleuder 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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'