Hi Gregor

I debugged this a bit further and the problem seems to me more that as
you said spamassassin 'is wrong', as IO::Socket::SSL is checking
correctly his alternatives ...

The messages:

Sep  6 21:25:12.103 [9244] error: Socket version 1.95 required--this is only 
version 1.94 at /usr/share/perl5/IO/Socket/SSL.pm line 71.
Sep  6 21:25:12.103 [9244] error: Can't locate IO/Socket/IP.pm in @INC (@INC 
contains: /usr/share/perl5 /etc/perl /usr/local/lib/perl/5.14.2 
/usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/lib/perl/5.14 
/usr/share/perl/5.14 /usr/local/lib/site_perl) at 
/usr/share/perl5/IO/Socket/SSL.pm line 85.

are outputed in:

113 BEGIN {
114   # redirect __WARN__ and __DIE__
115   # do not trap warnings here based on eval scope; evals are very
116   # common throughout.  die()s can be trapped though.
117   $SIG{__WARN__} = sub {
118     log_message("warn", $_[0]);
119   };
120   $SIG{__DIE__} = sub {
121     # see http://use.perl.org/comments.pl?mode=flat&sid=33872 for $^S
122     log_message("error", $_[0]) unless $^S;
123   };
124 }

And log_message is loaded by:

89 use Mail::SpamAssassin::Logger qw(:DEFAULT log_message);

Here is an output traced running spamd with --ssl, to see first what
happens:

----cut---------cut---------cut---------cut---------cut---------cut-----
>> /usr/share/perl5/IO/Socket/SSL.pm:74:        } || eval {
>> /usr/share/perl5/IO/Socket/SSL.pm:70:            require Socket;
>> /usr/share/perl5/IO/Socket/SSL.pm:71:            Socket->VERSION(1.95);
>> ./spamd:120:     log_message("error", $_[0]) unless $^S;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:145:   my ($level, @message) = 
>> @_;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:155:   if ($level eq "error") {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:157:     return if ($message[0] 
>> =~ /__ignore__/);
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:161:     my @caller = caller 2;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:162:     return if (defined 
>> $caller[3] && defined $caller[0] &&
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:167:   return if $LOG_ENTERED;  
>> # avoid recursion on die or warn from within logging
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:168:   $LOG_ENTERED = 1;  # no 
>> 'returns' from this point on, must clear the flag
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:170:   my $message = join(" ", 
>> @message);
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:171:   $message =~ 
>> s/[\r\n]+$//;                # remove any trailing newlines
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:175:   my $first = 1;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:176:   foreach my $line 
>> (split(/\n/, $message)) {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:179:     $line =~ 
>> tr/\x09\x20\x00-\x1f/  _/s;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:180:     if ($first) {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:181:       $first = 0;
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:186:     while (my ($name, 
>> $object) = each %{ $LOG_SA{method} }) {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:186:     while (my ($name, 
>> $object) = each %{ $LOG_SA{method} }) {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:187:       
>> $object->log_message($level, $line);
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:57:   my ($self, $level, 
>> $msg) = @_;
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:59:   my $timestamp;
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:60:   my $fmt = 
>> $self->{timestamp_fmt};
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:61:   if (!defined $fmt) 
>> {
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:63:     my $now = 
>> Time::HiRes::time;
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:64:     $timestamp = 
>> sprintf("%s:%06.3f",
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:67:     local $1; 
>> $timestamp =~ s/^(\S+\s+)0/$1 /;
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:67:     local $1; 
>> $timestamp =~ s/^(\S+\s+)0/$1 /;
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:73:   $timestamp .= ' '  
>> if $timestamp ne '';
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:75:   my($nwrite) = 
>> syswrite(STDERR, sprintf("%s[%d] %s: %s\n",
Sep  6 21:12:28.658 [9216] error: Socket version 1.95 required--this is only 
version 1.94 at /usr/share/perl5/IO/Socket/SSL.pm line 71.
>> /usr/share/perl5/Mail/SpamAssassin/Logger/Stderr.pm:77:   defined $nwrite  
>> or warn "error writing to log file: $!";
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:186:     while (my ($name, 
>> $object) = each %{ $LOG_SA{method} }) {
>> /usr/share/perl5/Mail/SpamAssassin/Logger.pm:190:   $LOG_ENTERED = 0;
>> /usr/share/perl5/IO/Socket/SSL.pm:75:            require Socket6;
>> /usr/share/perl5/IO/Socket/SSL.pm:76:            Socket6->import( 
>> 'inet_pton' );
>> /usr/share/perl/5.14/Exporter.pm:29:   my $pkg = shift;
>> /usr/share/perl/5.14/Exporter.pm:30:   my $callpkg = caller($ExportLevel);
>> /usr/share/perl/5.14/Exporter.pm:32:   if ($pkg eq "Exporter" and @_ and 
>> $_[0] eq "import") {
>> /usr/share/perl/5.14/Exporter.pm:38:   my $exports = \@{"$pkg\::EXPORT"};
>> /usr/share/perl/5.14/Exporter.pm:38:   my $exports = \@{"$pkg\::EXPORT"};
>> /usr/share/perl/5.14/Exporter.pm:41:   my $fail = ${$pkg . 
>> '::'}{EXPORT_FAIL} && \@{"$pkg\::EXPORT_FAIL"};
>> /usr/share/perl/5.14/Exporter.pm:41:   my $fail = ${$pkg . 
>> '::'}{EXPORT_FAIL} && \@{"$pkg\::EXPORT_FAIL"};
>> /usr/share/perl/5.14/Exporter.pm:42:   return export $pkg, $callpkg, @_
>> /usr/share/perl/5.14/Exporter.pm:44:   my $export_cache = ($Cache{$pkg} ||= 
>> {});
>> /usr/share/perl/5.14/Exporter.pm:45:   my $args = @_ or @_ = @$exports;
>> /usr/share/perl/5.14/Exporter.pm:47:   local $_;
>> /usr/share/perl/5.14/Exporter.pm:48:   if ($args and not %$export_cache) {
>> /usr/share/perl/5.14/Exporter.pm:52:   my $heavy;
>> /usr/share/perl/5.14/Exporter.pm:55:   if ($args or $fail) {
>> /usr/share/perl/5.14/Exporter.pm:58:                  foreach (@_);
>> /usr/share/perl/5.14/Exporter.pm:63:   return export $pkg, $callpkg, ($args 
>> ? @_ : ()) if $heavy;
>> /usr/share/perl/5.14/Exporter.pm:65:         sub {require Carp; &Carp::carp} 
>> if not $SIG{__WARN__};
>> /usr/share/perl/5.14/Exporter.pm:67:   *{"$callpkg\::$_"} = \&{"$pkg\::$_"} 
>> foreach @_;
>> /usr/share/perl/5.14/Exporter.pm:67:   *{"$callpkg\::$_"} = \&{"$pkg\::$_"} 
>> foreach @_;
>> /usr/share/perl/5.14/Exporter.pm:67:   *{"$callpkg\::$_"} = \&{"$pkg\::$_"} 
>> foreach @_;
>> /usr/share/perl5/IO/Socket/SSL.pm:77:            1;
>> /usr/share/perl5/IO/Socket/SSL.pm:81:        if ( $ip6 ) {
>> /usr/share/perl5/IO/Socket/SSL.pm:85:            if ( eval { require 
>> IO::Socket::IP; IO::Socket::IP->VERSION(0.11); } ) {
>> /usr/share/perl5/IO/Socket/SSL.pm:85:            if ( eval { require 
>> IO::Socket::IP; IO::Socket::IP->VERSION(0.11); } ) {
>> ./spamd:120:     log_message("error", $_[0]) unless $^S;
[...]

# and here comes the second error log_message
----cut---------cut---------cut---------cut---------cut---------cut-----

The error messages thus are comming when we have the eval in

409 if ( $listen_ssl ) {
410   eval { require IO::Socket::SSL };
411   die "spamd: SSL encryption requested, but IO::Socket::SSL is unavailable 
($@)\n"
412     if ($@);
413 
414   if ( !-e $opt{'server-key'} ) {
415     die "spamd: server key file $opt{'server-key'} does not exist\n";
416   }
417   if ( !-e $opt{'server-cert'} ) {
418     die "spamd: server certificate file $opt{'server-cert'} does not 
exist\n";
419   }
420 }

at line 410. But I added here a Dump of $^S before the eval and after
the eval resulting in the following:

$^S is '0'
Sep  6 21:51:21.233 [9298] error: Socket version 1.95 required--this is only 
version 1.94 at /usr/share/perl5/IO/Socket/SSL.pm line 71.
Sep  6 21:51:21.233 [9298] error: Can't locate IO/Socket/IP.pm in @INC (@INC 
contains: /usr/share/perl5 /etc/perl /usr/local/lib/perl/5.14.2 
/usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/lib/perl/5.14 
/usr/share/perl/5.14 /usr/local/lib/site_perl .) at 
/usr/share/perl5/IO/Socket/SSL.pm line 85.
$^S is '0'

It does not seem to be an error of IO::Socket::SSL to me (but I'm not
expert on this), but rather that Spamassassin is handling $^S here in
'strange' way? I suspect this because overall

        # try to load inet_pton from Socket or Socket6
        my $ip6 = eval {
            require Socket;
            Socket->VERSION(1.95);
            Socket->import( 'inet_pton' );
            1;
        } || eval {
            require Socket6;
            Socket6->import( 'inet_pton' );
            1;
        };

in IO::Socket::SSL is satisfied correctly by Socket6.

Opinions? I would go for reassigning the bug to spamassassin and in
particular lowering the serverity (spamd is started and error messages
are missleading).

Regards,
Salvatore

Attachment: signature.asc
Description: Digital signature

Reply via email to