schleuder 2.2.1 → 2.2.2
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.
- data.tar.gz.sig +0 -0
 - data/bin/schleuder-fix-gem-dependencies +9 -2
 - data/bin/schleuder-newlist +23 -10
 - data/contrib/check-expired-keys.rb +1 -0
 - data/ext/schleuder.conf +0 -4
 - data/lib/schleuder/crypt.rb +58 -36
 - data/lib/schleuder/list.rb +5 -6
 - data/lib/schleuder/list_config.rb +4 -4
 - data/lib/schleuder/mail.rb +36 -33
 - data/lib/schleuder/member.rb +2 -2
 - data/lib/schleuder/processor.rb +1 -1
 - data/lib/schleuder/schleuder_config.rb +7 -7
 - data/lib/schleuder/storage.rb +19 -19
 - data/lib/schleuder/version.rb +1 -1
 - data/man/schleuder-newlist.8 +66 -90
 - data/man/schleuder.8 +195 -179
 - metadata +7 -12
 - metadata.gz.sig +0 -0
 
    
        data.tar.gz.sig
    CHANGED
    
    | 
         Binary file 
     | 
| 
         @@ -8,7 +8,14 @@ require 'rubygems' 
     | 
|
| 
       8 
8 
     | 
    
         
             
            require 'rubygems/dependency_installer.rb'
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            inst = Gem::DependencyInstaller.new
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            if Gem::Specification.respond_to? :find_by_name
         
     | 
| 
      
 13 
     | 
    
         
            +
              spec = Gem::Specification.find_by_name 'schleuder'
         
     | 
| 
      
 14 
     | 
    
         
            +
              spec_file = spec.spec_file
         
     | 
| 
      
 15 
     | 
    
         
            +
            else
         
     | 
| 
      
 16 
     | 
    
         
            +
              spec = Gem.source_index.find_name('schleuder').first
         
     | 
| 
      
 17 
     | 
    
         
            +
              spec_file = spec.loaded_from
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
       12 
19 
     | 
    
         | 
| 
       13 
20 
     | 
    
         
             
            begin
         
     | 
| 
       14 
21 
     | 
    
         
             
              if RUBY_VERSION < "1.9"
         
     | 
| 
         @@ -21,7 +28,7 @@ begin 
     | 
|
| 
       21 
28 
     | 
    
         
             
              inst.install name, ver
         
     | 
| 
       22 
29 
     | 
    
         
             
              spec.add_dependency name, ver
         
     | 
| 
       23 
30 
     | 
    
         
             
              # Write spec back to file, from rubygems/installer.rb
         
     | 
| 
       24 
     | 
    
         
            -
              File.open( 
     | 
| 
      
 31 
     | 
    
         
            +
              File.open(spec_file.untaint, "w") do |f|
         
     | 
| 
       25 
32 
     | 
    
         
             
                f << spec.to_ruby_for_cache
         
     | 
| 
       26 
33 
     | 
    
         
             
              end
         
     | 
| 
       27 
34 
     | 
    
         
             
            rescue Gem::FilePermissionError => e
         
     | 
    
        data/bin/schleuder-newlist
    CHANGED
    
    | 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            #!/usr/bin/env ruby
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            trap ("INT") { exit 1 }
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            $:.unshift File.dirname(__FILE__) + '/../lib'
         
     | 
| 
       4 
6 
     | 
    
         
             
            require 'schleuder'
         
     | 
| 
       5 
7 
     | 
    
         
             
            require 'etc'
         
     | 
| 
         @@ -90,7 +92,9 @@ class ListCreator 
     | 
|
| 
       90 
92 
     | 
    
         
             
                listdir = File.join([Schleuder.config.lists_dir, listname.split('@').reverse].flatten)
         
     | 
| 
       91 
93 
     | 
    
         
             
                raise NewListError, "List or parts of a list named: #{listname} already exists!" if File.directory?(listdir)
         
     | 
| 
       92 
94 
     | 
    
         
             
                list_email = ListCreator::verify_emailvar(listname,interactive,"The lists's email address")
         
     | 
| 
       93 
     | 
    
         
            -
                list_realname = ListCreator::verify_strvar(args[:list_realname],interactive,"'Realname' (for GPG-key and email-headers)")
         
     | 
| 
      
 95 
     | 
    
         
            +
                list_realname = ListCreator::verify_strvar(args[:list_realname],interactive,"'Realname' (for GPG-key and email-headers)") do |var|
         
     | 
| 
      
 96 
     | 
    
         
            +
                  raise NewListError, "Realname must be at least 5 characters long (requirement of GnuPG)" if var.size < 5
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
       94 
98 
     | 
    
         
             
                list_adminaddress = ListCreator::verify_emailvar(args[:list_adminaddress],interactive,"Admin email address")
         
     | 
| 
       95 
99 
     | 
    
         | 
| 
       96 
100 
     | 
    
         
             
                raise NewListError,"Lists' email address and the admin address can't be the same" if list_email == list_adminaddress
         
     | 
| 
         @@ -183,7 +187,7 @@ class ListCreator 
     | 
|
| 
       183 
187 
     | 
    
         
             
                Schleuder.log.debug "Store list config..."
         
     | 
| 
       184 
188 
     | 
    
         
             
                list.config = list.config
         
     | 
| 
       185 
189 
     | 
    
         
             
                Schleuder.log.debug "Changing ownership..."
         
     | 
| 
       186 
     | 
    
         
            -
                ListCreator::filepermissions( 
     | 
| 
      
 190 
     | 
    
         
            +
                ListCreator::filepermissions(list, mailuser)
         
     | 
| 
       187 
191 
     | 
    
         
             
                Schleuder.log.debug "List successfully created..."
         
     | 
| 
       188 
192 
     | 
    
         
             
                ListCreator::print_list_infos(list) if interactive
         
     | 
| 
       189 
193 
     | 
    
         
             
              end
         
     | 
| 
         @@ -206,7 +210,7 @@ class ListCreator 
     | 
|
| 
       206 
210 
     | 
    
         
             
                end
         
     | 
| 
       207 
211 
     | 
    
         
             
              end
         
     | 
| 
       208 
212 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
              def self.verify_strvar(var,interactive,question, echo=true)
         
     | 
| 
      
 213 
     | 
    
         
            +
              def self.verify_strvar(var,interactive,question, echo=true, &block)
         
     | 
| 
       210 
214 
     | 
    
         
             
                if (var.nil? or var.empty?) and interactive then
         
     | 
| 
       211 
215 
     | 
    
         
             
                  str = question+": "
         
     | 
| 
       212 
216 
     | 
    
         
             
                  if echo
         
     | 
| 
         @@ -215,6 +219,7 @@ class ListCreator 
     | 
|
| 
       215 
219 
     | 
    
         
             
                    var = ask(str) { |question| question.echo = '*' }
         
     | 
| 
       216 
220 
     | 
    
         
             
                  end
         
     | 
| 
       217 
221 
     | 
    
         
             
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
                yield(var) if block_given?
         
     | 
| 
       218 
223 
     | 
    
         
             
                raise NewListError,"Missing mandatory variable: "+question if (var.nil? or var.empty?)
         
     | 
| 
       219 
224 
     | 
    
         
             
                var
         
     | 
| 
       220 
225 
     | 
    
         
             
              end
         
     | 
| 
         @@ -290,9 +295,9 @@ class ListCreator 
     | 
|
| 
       290 
295 
     | 
    
         
             
                    else
         
     | 
| 
       291 
296 
     | 
    
         
             
                      reply = nil
         
     | 
| 
       292 
297 
     | 
    
         
             
                    end
         
     | 
| 
       293 
     | 
    
         
            -
                     
     | 
| 
      
 298 
     | 
    
         
            +
                    $stderr.puts line if $DEBUG
         
     | 
| 
       294 
299 
     | 
    
         
             
                    if reply
         
     | 
| 
       295 
     | 
    
         
            -
                       
     | 
| 
      
 300 
     | 
    
         
            +
                      $stderr.puts reply if $DEBUG
         
     | 
| 
       296 
301 
     | 
    
         
             
                      stdin.puts reply
         
     | 
| 
       297 
302 
     | 
    
         
             
                    end
         
     | 
| 
       298 
303 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -332,7 +337,7 @@ class ListCreator 
     | 
|
| 
       332 
337 
     | 
    
         
             
              end
         
     | 
| 
       333 
338 
     | 
    
         | 
| 
       334 
339 
     | 
    
         
             
              def self.import_keypair(list,list_privatekeyfile,list_publickeyfile)
         
     | 
| 
       335 
     | 
    
         
            -
                crypt = Schleuder::Crypt.new(list.config.gpg_password)
         
     | 
| 
      
 340 
     | 
    
         
            +
                crypt = Schleuder::Crypt.new(list.config.gpg_password, :new_keyring => true)
         
     | 
| 
       336 
341 
     | 
    
         
             
                Schleuder.log.debug "Importing private key from #{list_privatekeyfile}"
         
     | 
| 
       337 
342 
     | 
    
         
             
                crypt.add_key_from_file(list_privatekeyfile)
         
     | 
| 
       338 
343 
     | 
    
         
             
                Schleuder.log.debug "Importing public key from #{list_publickeyfile}"
         
     | 
| 
         @@ -353,15 +358,23 @@ Passphrase: #{pass} 
     | 
|
| 
       353 
358 
     | 
    
         
             
            </GnupgKeyParms>"
         
     | 
| 
       354 
359 
     | 
    
         
             
              end
         
     | 
| 
       355 
360 
     | 
    
         | 
| 
       356 
     | 
    
         
            -
              def self.filepermissions( 
     | 
| 
       357 
     | 
    
         
            -
                 
     | 
| 
       358 
     | 
    
         
            -
                File. 
     | 
| 
      
 361 
     | 
    
         
            +
              def self.filepermissions(list, mailuser)
         
     | 
| 
      
 362 
     | 
    
         
            +
                listdir = list.listdir
         
     | 
| 
      
 363 
     | 
    
         
            +
                dirs = [File.dirname(listdir), listdir]
         
     | 
| 
      
 364 
     | 
    
         
            +
                FileUtils.chown mailuser, nil, dirs
         
     | 
| 
      
 365 
     | 
    
         
            +
                FileUtils.chmod 0700, dirs
         
     | 
| 
       359 
366 
     | 
    
         
             
                Dir.new(listdir).each{ |f|
         
     | 
| 
       360 
367 
     | 
    
         
             
                  unless f =~ /^\./
         
     | 
| 
       361 
368 
     | 
    
         
             
                    File.chown(mailuser,nil,listdir+"/"+f)
         
     | 
| 
       362 
     | 
    
         
            -
                    File.chmod(0600)
         
     | 
| 
      
 369 
     | 
    
         
            +
                    File.chmod(0600,listdir+"/"+f)
         
     | 
| 
       363 
370 
     | 
    
         
             
                  end
         
     | 
| 
       364 
371 
     | 
    
         
             
                }
         
     | 
| 
      
 372 
     | 
    
         
            +
                if list.config.log_file
         
     | 
| 
      
 373 
     | 
    
         
            +
                  log_file = list.config.log_file
         
     | 
| 
      
 374 
     | 
    
         
            +
                  log_file = File.join(listdir, log_file) unless log_file.start_with?('/')
         
     | 
| 
      
 375 
     | 
    
         
            +
                  FileUtils.chown mailuser, nil, log_file
         
     | 
| 
      
 376 
     | 
    
         
            +
                  FileUtils.chmod 0600, log_file
         
     | 
| 
      
 377 
     | 
    
         
            +
                end
         
     | 
| 
       365 
378 
     | 
    
         
             
              end
         
     | 
| 
       366 
379 
     | 
    
         | 
| 
       367 
380 
     | 
    
         
             
              def self.print_list_infos(list)
         
     | 
    
        data/ext/schleuder.conf
    CHANGED
    
    | 
         @@ -26,10 +26,6 @@ 
     | 
|
| 
       26 
26 
     | 
    
         
             
            # Name of the per list config file.
         
     | 
| 
       27 
27 
     | 
    
         
             
            #lists_configfile: list.conf
         
     | 
| 
       28 
28 
     | 
    
         
             
            #
         
     | 
| 
       29 
     | 
    
         
            -
            # Per list logfile name. Will be written into the directory
         
     | 
| 
       30 
     | 
    
         
            -
            # of the list.
         
     | 
| 
       31 
     | 
    
         
            -
            #lists_logfile: list.log
         
     | 
| 
       32 
     | 
    
         
            -
            #
         
     | 
| 
       33 
29 
     | 
    
         
             
            # Name of the per list file containing all members and their
         
     | 
| 
       34 
30 
     | 
    
         
             
            # options.
         
     | 
| 
       35 
31 
     | 
    
         
             
            #lists_memberfile: members.conf
         
     | 
    
        data/lib/schleuder/crypt.rb
    CHANGED
    
    | 
         @@ -3,15 +3,17 @@ module Schleuder 
     | 
|
| 
       3 
3 
     | 
    
         
             
                # change but aliases will be set up then.
         
     | 
| 
       4 
4 
     | 
    
         
             
                class Crypt
         
     | 
| 
       5 
5 
     | 
    
         
             
                  # Instantiates and stores password
         
     | 
| 
       6 
     | 
    
         
            -
                  def initialize(password)
         
     | 
| 
       7 
     | 
    
         
            -
                     
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                       
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(password, options={})
         
     | 
| 
      
 7 
     | 
    
         
            +
                    unless options[:new_keyring]
         
     | 
| 
      
 8 
     | 
    
         
            +
                      # Check file permissions. ruby-gpgme unfortunately returns unspecific
         
     | 
| 
      
 9 
     | 
    
         
            +
                      # errors if it can't read files.
         
     | 
| 
      
 10 
     | 
    
         
            +
                      %w(pubring.gpg secring.gpg trustdb.gpg).each do |fn|
         
     | 
| 
      
 11 
     | 
    
         
            +
                        f = File.join(ENV['GNUPGHOME'], fn)
         
     | 
| 
      
 12 
     | 
    
         
            +
                        if ! File.readable?(f)
         
     | 
| 
      
 13 
     | 
    
         
            +
                          raise Errno::EACCES.new('%s is not readable' % f)
         
     | 
| 
      
 14 
     | 
    
         
            +
                        elsif ! File.writable?(f)
         
     | 
| 
      
 15 
     | 
    
         
            +
                          raise Errno::EACCES.new('%s is not writable' % f)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        end
         
     | 
| 
       15 
17 
     | 
    
         
             
                      end
         
     | 
| 
       16 
18 
     | 
    
         
             
                    end
         
     | 
| 
       17 
19 
     | 
    
         | 
| 
         @@ -21,7 +23,7 @@ module Schleuder 
     | 
|
| 
       21 
23 
     | 
    
         
             
                    end
         
     | 
| 
       22 
24 
     | 
    
         
             
                    @ctx = GPGME::Ctx.new
         
     | 
| 
       23 
25 
     | 
    
         
             
                    # feed the passphrase into the Context
         
     | 
| 
       24 
     | 
    
         
            -
                    @ctx.set_passphrase_cb(method(:passfunc)) 
     | 
| 
      
 26 
     | 
    
         
            +
                    @ctx.set_passphrase_cb(method(:passfunc))
         
     | 
| 
       25 
27 
     | 
    
         
             
                  end
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
       27 
29 
     | 
    
         
             
                  # Verify a gpg-signature. Use +signed_string+ if the signature is
         
     | 
| 
         @@ -56,35 +58,41 @@ module Schleuder 
     | 
|
| 
       56 
58 
     | 
    
         
             
                    in_encrypted = nil
         
     | 
| 
       57 
59 
     | 
    
         
             
                    in_signed = nil
         
     | 
| 
       58 
60 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                    # TODO: return ciphertext if missing key 
     | 
| 
       60 
     | 
    
         
            -
                    #  
     | 
| 
       61 
     | 
    
         
            -
                    #  
     | 
| 
       62 
     | 
    
         
            -
                    # the processor.
         
     | 
| 
      
 61 
     | 
    
         
            +
                    # TODO: return ciphertext if missing key when decrypting inline
         
     | 
| 
      
 62 
     | 
    
         
            +
                    # attachments or recursing into mime-messages.  Breaking if even the
         
     | 
| 
      
 63 
     | 
    
         
            +
                    # whole message is not decryptable is a job for the processor.
         
     | 
| 
       63 
64 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                    #  
     | 
| 
       65 
     | 
    
         
            -
                     
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                      # match pgp-mime- and inline-pgp-signatures
         
     | 
| 
       69 
     | 
    
         
            -
                      if str =~ /^-----BEGIN PGP SIG/
         
     | 
| 
       70 
     | 
    
         
            -
                        Schleuder.log.debug 'found signed, not encrypted message, verifying'
         
     | 
| 
       71 
     | 
    
         
            -
                        output, in_signed = verify(str)
         
     | 
| 
       72 
     | 
    
         
            -
                      else
         
     | 
| 
       73 
     | 
    
         
            -
                        Schleuder.log.debug 'found not signed, not encrypted message, returning input'
         
     | 
| 
       74 
     | 
    
         
            -
                        output = str
         
     | 
| 
       75 
     | 
    
         
            -
                      end
         
     | 
| 
      
 65 
     | 
    
         
            +
                    # match pgp-mime- and inline-pgp-signatures
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if str =~ /^-----BEGIN PGP SIG/
         
     | 
| 
      
 67 
     | 
    
         
            +
                      Schleuder.log.debug 'found ascii-armored, signed, not encrypted message, verifying'
         
     | 
| 
      
 68 
     | 
    
         
            +
                      output, in_signed = verify(str)
         
     | 
| 
       76 
69 
     | 
    
         
             
                    else
         
     | 
| 
       77 
     | 
    
         
            -
                       
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 71 
     | 
    
         
            +
                        Schleuder.log.debug 'Trying to decrypt'
         
     | 
| 
      
 72 
     | 
    
         
            +
                        output = GPGME.decrypt(str, :passphrase_callback => method(:passfunc)) do |sig|
         
     | 
| 
      
 73 
     | 
    
         
            +
                          in_signed = sig
         
     | 
| 
      
 74 
     | 
    
         
            +
                        end
         
     | 
| 
      
 75 
     | 
    
         
            +
                        in_encrypted = true
         
     | 
| 
      
 76 
     | 
    
         
            +
                      rescue GPGME::Error::NoData => exc
         
     | 
| 
      
 77 
     | 
    
         
            +
                        Schleuder.log.debug "Caught NoData-exception from gpgme. This probably means we're dealing with a binary signature, trying to verify."
         
     | 
| 
      
 78 
     | 
    
         
            +
                        output, in_signed = verify(str)
         
     | 
| 
      
 79 
     | 
    
         
            +
                        if output.empty?
         
     | 
| 
      
 80 
     | 
    
         
            +
                          Schleuder.log.debug "Empty output from verification. No more options, returning."
         
     | 
| 
      
 81 
     | 
    
         
            +
                        end
         
     | 
| 
       84 
82 
     | 
    
         
             
                      end
         
     | 
| 
       85 
     | 
    
         
            -
                      # TODO: return mailadresses or keys instead of signature-objects?
         
     | 
| 
       86 
83 
     | 
    
         
             
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    Schleuder.log.debug "mime_type of decrypted content: #{output.mime.inspect}"
         
     | 
| 
      
 85 
     | 
    
         
            +
                    Schleuder.log.debug "in_signed: #{in_signed.inspect}"
         
     | 
| 
      
 86 
     | 
    
         
            +
                    Schleuder.log.debug "in_encrypted: #{in_encrypted.inspect}"
         
     | 
| 
      
 87 
     | 
    
         
            +
            	if output.empty?
         
     | 
| 
      
 88 
     | 
    
         
            +
                      Schleuder.log.debug "Empty output, returning input"
         
     | 
| 
      
 89 
     | 
    
         
            +
                      output = str
         
     | 
| 
      
 90 
     | 
    
         
            +
            	end
         
     | 
| 
      
 91 
     | 
    
         
            +
                    # TODO: return mailadresses or keys instead of signature-objects?
         
     | 
| 
       87 
92 
     | 
    
         
             
                    [output, in_encrypted, in_signed]
         
     | 
| 
      
 93 
     | 
    
         
            +
                  rescue GPGME::Error::General => exc
         
     | 
| 
      
 94 
     | 
    
         
            +
                    Schleuder.log.warn = "gpgme returned a general error. Most likely this is due to unexpected input, but as you never know here's the input and the exception:\ninput:\n#{str.inspect}\n#{exc.to_s}\n#{exc.backtrace[0..9].join("\n")}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                    [str, nil, nil]
         
     | 
| 
       88 
96 
     | 
    
         
             
                  end
         
     | 
| 
       89 
97 
     | 
    
         | 
| 
       90 
98 
     | 
    
         
             
                  # Encrypt a string to a single receiver and sign it. +receiver+ must be a
         
     | 
| 
         @@ -114,7 +122,7 @@ module Schleuder 
     | 
|
| 
       114 
122 
     | 
    
         
             
                    pattern = "<#{pattern}>" if pattern =~ /.*@.*/ && !(pattern =~ /^<.*>$/)
         
     | 
| 
       115 
123 
     | 
    
         
             
                    keys = list_keys(pattern)
         
     | 
| 
       116 
124 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
                    keys.reject! { |key|  
     | 
| 
      
 125 
     | 
    
         
            +
                    keys.reject! { |key| unusable_key?(key) } if only_valid_keys
         
     | 
| 
       118 
126 
     | 
    
         | 
| 
       119 
127 
     | 
    
         
             
                    if keys.empty?
         
     | 
| 
       120 
128 
     | 
    
         
             
                      [false, "no key found for #{pattern}."]
         
     | 
| 
         @@ -175,7 +183,21 @@ module Schleuder 
     | 
|
| 
       175 
183 
     | 
    
         
             
                  private
         
     | 
| 
       176 
184 
     | 
    
         | 
| 
       177 
185 
     | 
    
         
             
                  def key_infos(keys, only_valid_keys=false)
         
     | 
| 
       178 
     | 
    
         
            -
                    keys.collect  
     | 
| 
      
 186 
     | 
    
         
            +
                    keys.collect do |key|
         
     | 
| 
      
 187 
     | 
    
         
            +
                      info = key_descr(key)
         
     | 
| 
      
 188 
     | 
    
         
            +
                      unless only_valid_keys
         
     | 
| 
      
 189 
     | 
    
         
            +
                        info << trust_info(key)
         
     | 
| 
      
 190 
     | 
    
         
            +
                      end
         
     | 
| 
      
 191 
     | 
    
         
            +
                      info
         
     | 
| 
      
 192 
     | 
    
         
            +
                    end
         
     | 
| 
      
 193 
     | 
    
         
            +
                  end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                  def trust_info(key)
         
     | 
| 
      
 196 
     | 
    
         
            +
                    unusable_key?(key) ? " *#{key.trust}*" : ''
         
     | 
| 
      
 197 
     | 
    
         
            +
                  end
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                  def unusable_key?(key)
         
     | 
| 
      
 200 
     | 
    
         
            +
                    [:revoked, :expired].include?(key.trust)
         
     | 
| 
       179 
201 
     | 
    
         
             
                  end
         
     | 
| 
       180 
202 
     | 
    
         | 
| 
       181 
203 
     | 
    
         
             
                  def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
         
     | 
    
        data/lib/schleuder/list.rb
    CHANGED
    
    | 
         @@ -8,7 +8,7 @@ module Schleuder 
     | 
|
| 
       8 
8 
     | 
    
         
             
                # Prepare some variables, set up the SchleuderLogger and set GNUPGHOME
         
     | 
| 
       9 
9 
     | 
    
         
             
                def initialize(listname,newlist=false)
         
     | 
| 
       10 
10 
     | 
    
         
             
                  @listname = listname
         
     | 
| 
       11 
     | 
    
         
            -
                  @config =  
     | 
| 
      
 11 
     | 
    
         
            +
                  @config = ListConfig.new if newlist
         
     | 
| 
       12 
12 
     | 
    
         
             
                  @log = ListLogger.new listname, listdir, config
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  # setting GNUPGHOME to list's home, to make use of the keys there
         
     | 
| 
         @@ -22,7 +22,7 @@ module Schleuder 
     | 
|
| 
       22 
22 
     | 
    
         
             
                  unless @members
         
     | 
| 
       23 
23 
     | 
    
         
             
                    Schleuder.log.debug("reading #{members_file}")
         
     | 
| 
       24 
24 
     | 
    
         
             
                    @members = YAML::load_file(members_file).collect do |h|
         
     | 
| 
       25 
     | 
    
         
            -
                      h.kind_of?(Schleuder::Member) ? h : Schleuder::Member.new(h 
     | 
| 
      
 25 
     | 
    
         
            +
                      h.kind_of?(Schleuder::Member) ? h : Schleuder::Member.new(h)
         
     | 
| 
       26 
26 
     | 
    
         
             
                    end
         
     | 
| 
       27 
27 
     | 
    
         
             
                  end
         
     | 
| 
       28 
28 
     | 
    
         
             
                  @members
         
     | 
| 
         @@ -36,7 +36,7 @@ module Schleuder 
     | 
|
| 
       36 
36 
     | 
    
         
             
                def members=(arr)
         
     | 
| 
       37 
37 
     | 
    
         
             
                  Schleuder.log.debug 'writing members'
         
     | 
| 
       38 
38 
     | 
    
         
             
                  Schleuder.log.info("writing #{members_file}")
         
     | 
| 
       39 
     | 
    
         
            -
                  @members = arr.collect { |m| m.kind_of?(Hash) ? Member.new(m 
     | 
| 
      
 39 
     | 
    
         
            +
                  @members = arr.collect { |m| m.kind_of?(Hash) ? Member.new(m) : m }
         
     | 
| 
       40 
40 
     | 
    
         
             
                  _write(YAML.dump(@members.collect { |m| m.to_hash }), members_file)
         
     | 
| 
       41 
41 
     | 
    
         
             
                  @members
         
     | 
| 
       42 
42 
     | 
    
         
             
                end
         
     | 
| 
         @@ -144,10 +144,9 @@ module Schleuder 
     | 
|
| 
       144 
144 
     | 
    
         
             
                private
         
     | 
| 
       145 
145 
     | 
    
         | 
| 
       146 
146 
     | 
    
         
             
                # Loads the configuration
         
     | 
| 
       147 
     | 
    
         
            -
                 
     | 
| 
       148 
     | 
    
         
            -
                def _load_config(fromfile=true)
         
     | 
| 
      
 147 
     | 
    
         
            +
                def _load_config
         
     | 
| 
       149 
148 
     | 
    
         
             
                    Schleuder.log.debug("reading list-config for: #{@listname}") unless Schleuder.log.nil?
         
     | 
| 
       150 
     | 
    
         
            -
                    @config = ListConfig.new(File.join(listdir, Schleuder.config.lists_configfile) 
     | 
| 
      
 149 
     | 
    
         
            +
                    @config = ListConfig.new(File.join(listdir, Schleuder.config.lists_configfile))
         
     | 
| 
       151 
150 
     | 
    
         
             
                end
         
     | 
| 
       152 
151 
     | 
    
         | 
| 
       153 
152 
     | 
    
         
             
                def find_by_key(ary, key)
         
     | 
| 
         @@ -75,10 +75,10 @@ module Schleuder 
     | 
|
| 
       75 
75 
     | 
    
         
             
                schleuder_attr :headers_to_meta, [:from, :to, :cc, :date]
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
                # Restrict specific plugins to admin
         
     | 
| 
       78 
     | 
    
         
            -
                schleuder_attr :keywords_admin_only, 
     | 
| 
      
 78 
     | 
    
         
            +
                schleuder_attr :keywords_admin_only, ['ADD-MEMBER', 'DELETE-MEMBER', 'DELETE-KEY', 'SAVE-MEMBERS', 'DEL-KEY' ]
         
     | 
| 
       79 
79 
     | 
    
         | 
| 
       80 
80 
     | 
    
         
             
                # Notify admin if these keywords triggered commands.
         
     | 
| 
       81 
     | 
    
         
            -
                schleuder_attr :keywords_admin_notify, [ ' 
     | 
| 
      
 81 
     | 
    
         
            +
                schleuder_attr :keywords_admin_notify, [ 'ADD-KEY' ]
         
     | 
| 
       82 
82 
     | 
    
         | 
| 
       83 
83 
     | 
    
         
             
                # Drop any bounces (incoming email not passing the receive_*_only-rules)
         
     | 
| 
       84 
84 
     | 
    
         
             
                schleuder_attr :bounces_drop_all, false
         
     | 
| 
         @@ -112,11 +112,11 @@ module Schleuder 
     | 
|
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
                ### END OF CONFIG OPTIONS
         
     | 
| 
       114 
114 
     | 
    
         | 
| 
       115 
     | 
    
         
            -
                def initialize( 
     | 
| 
      
 115 
     | 
    
         
            +
                def initialize(config=nil)
         
     | 
| 
       116 
116 
     | 
    
         
             
                  # First Overload with default-list.conf then load our config
         
     | 
| 
       117 
117 
     | 
    
         
             
                  overload_from_file!(Schleuder.config.lists_default_conf)
         
     | 
| 
       118 
118 
     | 
    
         
             
                  # overload with config_file
         
     | 
| 
       119 
     | 
    
         
            -
                  super( 
     | 
| 
      
 119 
     | 
    
         
            +
                  super(config)
         
     | 
| 
       120 
120 
     | 
    
         | 
| 
       121 
121 
     | 
    
         
             
                  # load admins as members
         
     | 
| 
       122 
122 
     | 
    
         
             
                  self.admins = self.admins
         
     | 
    
        data/lib/schleuder/mail.rb
    CHANGED
    
    | 
         @@ -111,6 +111,11 @@ module Schleuder 
     | 
|
| 
       111 
111 
     | 
    
         
             
                      self.parts.each do |part|
         
     | 
| 
       112 
112 
     | 
    
         
             
                        _decrypt_pgp_inline(part)
         
     | 
| 
       113 
113 
     | 
    
         
             
                      end
         
     | 
| 
      
 114 
     | 
    
         
            +
                      # If all parts are equally encrypted and signed mark the whole message as such
         
     | 
| 
      
 115 
     | 
    
         
            +
                      self.in_encrypted = self.parts.map{ |p| p.in_encrypted }.uniq == [true]
         
     | 
| 
      
 116 
     | 
    
         
            +
                      if self.parts.map { |p| p.in_signed.fpr }.uniq.size == 1
         
     | 
| 
      
 117 
     | 
    
         
            +
                        self.in_signed = self.parts.first.in_signed
         
     | 
| 
      
 118 
     | 
    
         
            +
                      end
         
     | 
| 
       114 
119 
     | 
    
         
             
                    else
         
     | 
| 
       115 
120 
     | 
    
         
             
                      Schleuder.log.debug 'single inline content found, looking for pgp content'
         
     | 
| 
       116 
121 
     | 
    
         
             
                      _decrypt_pgp_inline(self)
         
     | 
| 
         @@ -627,14 +632,14 @@ module Schleuder 
     | 
|
| 
       627 
632 
     | 
    
         
             
                def _decrypt_pgp_inline(msg)
         
     | 
| 
       628 
633 
     | 
    
         
             
                  if msg._content_type_stripped == 'text/html'
         
     | 
| 
       629 
634 
     | 
    
         
             
                    Schleuder.log.debug "Content-type is text/html, can't handle that, skipping"
         
     | 
| 
       630 
     | 
    
         
            -
                  elsif msg.body =~ /^-----BEGIN PGP.*/ || msg. 
     | 
| 
      
 635 
     | 
    
         
            +
                  elsif msg.body =~ /^-----BEGIN PGP.*/ || ['pgp', 'gpg'].include?(msg.disposition_param('filename').to_s.split('.').last.to_s.downcase)
         
     | 
| 
       631 
636 
     | 
    
         
             
                    Schleuder.log.debug 'found pgp-inline in input'
         
     | 
| 
       632 
     | 
    
         
            -
                    #  
     | 
| 
       633 
     | 
    
         
            -
                     
     | 
| 
       634 
     | 
    
         
            -
             
     | 
| 
       635 
     | 
    
         
            -
             
     | 
| 
       636 
     | 
    
         
            -
             
     | 
| 
       637 
     | 
    
         
            -
                     
     | 
| 
      
 637 
     | 
    
         
            +
                    # We need to do this in three steps:
         
     | 
| 
      
 638 
     | 
    
         
            +
                    # 1. get the decoded body from TMail
         
     | 
| 
      
 639 
     | 
    
         
            +
                    # 2. delete the encoding-header
         
     | 
| 
      
 640 
     | 
    
         
            +
                    # 3. put the plaintext back into TMail
         
     | 
| 
      
 641 
     | 
    
         
            +
                    # Else TMail either can't decode the body correctly or 'over-decodes' it
         
     | 
| 
      
 642 
     | 
    
         
            +
                    # on next output
         
     | 
| 
       638 
643 
     | 
    
         
             
                    # TMail decodes QP if body() is called, Umlauts if to_s() is called.
         
     | 
| 
       639 
644 
     | 
    
         
             
                    # Life with TMail is hard...
         
     | 
| 
       640 
645 
     | 
    
         
             
                    if msg.encoding.to_s.downcase.eql?('quoted-printable') || !msg.main_type.eql?('text')
         
     | 
| 
         @@ -642,32 +647,29 @@ module Schleuder 
     | 
|
| 
       642 
647 
     | 
    
         
             
                    else
         
     | 
| 
       643 
648 
     | 
    
         
             
                      str = msg.to_s
         
     | 
| 
       644 
649 
     | 
    
         
             
                    end
         
     | 
| 
       645 
     | 
    
         
            -
                    # We need to do this in three steps:
         
     | 
| 
       646 
     | 
    
         
            -
                    # 1. get the decoded body from TMail
         
     | 
| 
       647 
     | 
    
         
            -
                    # 2. delete the encoding-header
         
     | 
| 
       648 
     | 
    
         
            -
                    # 3. put the plaintext back into TMail
         
     | 
| 
       649 
     | 
    
         
            -
                    # Else TMail either can't decode the body correctly or 'over-decodes' it
         
     | 
| 
       650 
     | 
    
         
            -
                    # on next output
         
     | 
| 
       651 
650 
     | 
    
         
             
                    ptxt, enc, sig = crypt.decrypt(str)
         
     | 
| 
       652 
     | 
    
         
            -
                    if  
     | 
| 
       653 
     | 
    
         
            -
                       
     | 
| 
       654 
     | 
    
         
            -
                      msg.charset = @charset || 'UTF-8'
         
     | 
| 
       655 
     | 
    
         
            -
                      msg.encoding = nil
         
     | 
| 
      
 651 
     | 
    
         
            +
                    if ptxt == str
         
     | 
| 
      
 652 
     | 
    
         
            +
                      Schleuder.log.debug "Output equals input, content was obviously not suitable for gpg. Passing it untouched."
         
     | 
| 
       656 
653 
     | 
    
         
             
                    else
         
     | 
| 
       657 
     | 
    
         
            -
                      #  
     | 
| 
       658 
     | 
    
         
            -
                       
     | 
| 
       659 
     | 
    
         
            -
                      msg. 
     | 
| 
       660 
     | 
    
         
            -
                      msg. 
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
             
     | 
| 
       663 
     | 
    
         
            -
             
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
       665 
     | 
    
         
            -
             
     | 
| 
       666 
     | 
    
         
            -
             
     | 
| 
       667 
     | 
    
         
            -
             
     | 
| 
       668 
     | 
    
         
            -
             
     | 
| 
       669 
     | 
    
         
            -
             
     | 
| 
      
 654 
     | 
    
         
            +
                      #Schleuder.log.debug "ptxt.mime_encoding: #{FileMagic.fm(:mime_encoding).buffer(ptxt).inspect}"
         
     | 
| 
      
 655 
     | 
    
         
            +
                      Schleuder.log.debug "Processing plaincontent: #{ptxt.mime}"
         
     | 
| 
      
 656 
     | 
    
         
            +
                      msg.in_encrypted = enc
         
     | 
| 
      
 657 
     | 
    
         
            +
                      msg.in_signed = sig
         
     | 
| 
      
 658 
     | 
    
         
            +
                      if ! msg.disposition_param('filename').nil?
         
     | 
| 
      
 659 
     | 
    
         
            +
                        msg['content-disposition'].params['filename'] = msg.disposition_param('filename').gsub(/\.(gpg|pgp|asc)$/, '')
         
     | 
| 
      
 660 
     | 
    
         
            +
                      end
         
     | 
| 
      
 661 
     | 
    
         
            +
                      if ptxt.content_type.split('/').first == 'text'
         
     | 
| 
      
 662 
     | 
    
         
            +
                        msg['content-type'] = ptxt.mime
         
     | 
| 
      
 663 
     | 
    
         
            +
                        msg.encoding = nil
         
     | 
| 
      
 664 
     | 
    
         
            +
                        msg.body = ptxt
         
     | 
| 
      
 665 
     | 
    
         
            +
                      else
         
     | 
| 
      
 666 
     | 
    
         
            +
                        # TMail handles binary data in an "interesting" way, so we manuall encode before handing Tmail the data.
         
     | 
| 
      
 667 
     | 
    
         
            +
                        msg['content-type'] = ptxt.content_type
         
     | 
| 
      
 668 
     | 
    
         
            +
                        msg.encoding = 'Base64'
         
     | 
| 
      
 669 
     | 
    
         
            +
                        msg.body = [ptxt].pack('m')
         
     | 
| 
      
 670 
     | 
    
         
            +
                      end
         
     | 
| 
       670 
671 
     | 
    
         
             
                    end
         
     | 
| 
      
 672 
     | 
    
         
            +
                    msg
         
     | 
| 
       671 
673 
     | 
    
         
             
                  else
         
     | 
| 
       672 
674 
     | 
    
         
             
                    Schleuder.log.debug 'no pgp-inline-data found, doing nothing'
         
     | 
| 
       673 
675 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -696,15 +698,16 @@ module Schleuder 
     | 
|
| 
       696 
698 
     | 
    
         
             
                end
         
     | 
| 
       697 
699 
     | 
    
         | 
| 
       698 
700 
     | 
    
         
             
                def _sig_str(arg)
         
     | 
| 
       699 
     | 
    
         
            -
                  if arg
         
     | 
| 
      
 701 
     | 
    
         
            +
                  # gpgme breaks if we use arg.to_s.empty? here.
         
     | 
| 
      
 702 
     | 
    
         
            +
                  if arg.nil? || (arg.is_a?(String) && arg.empty?)
         
     | 
| 
      
 703 
     | 
    
         
            +
                    'No signature'
         
     | 
| 
      
 704 
     | 
    
         
            +
                  else
         
     | 
| 
       700 
705 
     | 
    
         
             
                    if crypt.get_key(arg.fpr).first
         
     | 
| 
       701 
706 
     | 
    
         
             
                      arg.to_s
         
     | 
| 
       702 
707 
     | 
    
         
             
                    else
         
     | 
| 
       703 
708 
     | 
    
         
             
                      #Schleuder.log.debug arg.inspect
         
     | 
| 
       704 
709 
     | 
    
         
             
                      "Unknown signature from #{arg.fpr} (public key not present)"
         
     | 
| 
       705 
710 
     | 
    
         
             
                    end
         
     | 
| 
       706 
     | 
    
         
            -
                  else
         
     | 
| 
       707 
     | 
    
         
            -
                    'No signature'
         
     | 
| 
       708 
711 
     | 
    
         
             
                  end
         
     | 
| 
       709 
712 
     | 
    
         
             
                end
         
     | 
| 
       710 
713 
     | 
    
         | 
    
        data/lib/schleuder/member.rb
    CHANGED
    
    | 
         @@ -6,8 +6,8 @@ module Schleuder 
     | 
|
| 
       6 
6 
     | 
    
         
             
                schleuder_attr :encrypted_only, false
         
     | 
| 
       7 
7 
     | 
    
         
             
                schleuder_attr :key_fingerprint, nil
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                def initialize( 
     | 
| 
       10 
     | 
    
         
            -
                  super( 
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(config=nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  super(config)
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                  # compress fingerprint
         
     | 
| 
       13 
13 
     | 
    
         
             
                  self.key_fingerprint = self.key_fingerprint
         
     |