about summary refs log tree commit
diff options
context:
space:
mode:
authorSteve Hay <steve.m.hay@googlemail.com>2014-11-28 21:03:55 +0000
committerSteve Hay <steve.m.hay@googlemail.com>2014-11-28 21:03:55 +0000
commitd814f792aa4ffe7afb6fc3111d48e8848fb5c782 (patch)
treea93cee6837a770a5a3ce09de337554db35f32b72
parent4dadbf4eb332a886023b2451ab3ef08d9af31423 (diff)
parent50c6fd25f2958e6300ec8377ab40c3f1a23bd9fd (diff)
downloadperl-libnet-d814f792aa4ffe7afb6fc3111d48e8848fb5c782.tar.gz
Merge pull request #9 from noxxi/ssl
Remodel SSL support for Net::NNTP after Net::SMTP
-rw-r--r--lib/Net/FTP.pm2
-rw-r--r--lib/Net/NNTP.pm57
-rw-r--r--lib/Net/POP3.pm9
-rw-r--r--lib/Net/SMTP.pm7
4 files changed, 49 insertions, 26 deletions
diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm
index 7141734..e95da87 100644
--- a/lib/Net/FTP.pm
+++ b/lib/Net/FTP.pm
@@ -103,6 +103,7 @@ sub new {
     %tlsargs = (
       SSL_verifycn_scheme => 'ftp',
       SSL_verifycn_name => $hostname,
+      SSL_hostname => $hostname,
       # reuse SSL session of control connection in data connections
       SSL_session_cache => Net::FTP::_SSL_SingleSessionCache->new,
     );
@@ -1038,6 +1039,7 @@ sub _dataconn {
         $ftp->is_SSL ? (
           SSL_reuse_ctx => $ftp,
           SSL_verifycn_name => ${*$ftp}{net_ftp_tlsargs}{SSL_verifycn_name},
+          SSL_hostname => ${*$ftp}{net_ftp_tlsargs}{SSL_hostname},
         ) :( %{${*$ftp}{net_ftp_tlsargs}} ),
       ):(),
     ) or return;
diff --git a/lib/Net/NNTP.pm b/lib/Net/NNTP.pm
index b63d421..09cebe1 100644
--- a/lib/Net/NNTP.pm
+++ b/lib/Net/NNTP.pm
@@ -47,7 +47,7 @@ my $inet6_class = eval {
 sub can_ssl   { $ssl_class };
 sub can_inet6 { $inet6_class };
 
-our @ISA = ('Net::Cmd', $ssl_class || $inet6_class || 'IO::Socket::INET');
+our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
 
 
 sub new {
@@ -73,18 +73,11 @@ sub new {
 
   my %connect = ( Proto => 'tcp');
 
-  if ($ssl_class) {
-    $connect{SSL_verifycn_scheme} = 'nntp';
+  if ($arg{SSL}) {
+    # SSL from start
+    die $nossl_warn if ! $ssl_class;
+    $arg{Port} ||= 563;
     $connect{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
-    if ($arg{SSL}) {
-      # SSL from start
-      $arg{Port} ||= 563;
-    } else {
-      # upgrade later with STARTTLS
-      $connect{SSL_startHandshake} = 0;
-    }
-  } elsif ($arg{SSL}) {
-    die $nossl_warn;
   }
 
   foreach my $o (qw(LocalAddr Timeout)) {
@@ -94,16 +87,18 @@ sub new {
   $connect{PeerPort} = $arg{Port} || 'nntp(119)';
   foreach my $h (@{$hosts}) {
     $connect{PeerAddr} = $h;
-    $connect{SSL_verifycn_name} = $arg{SSL_verifycn_name} || $h if $ssl_class;
-    $obj = $type->SUPER::new(%connect)
-      and last;
+    $obj = $type->SUPER::new(%connect) or next;
+    ${*$obj}{'net_nntp_host'} = $h;
+    ${*$obj}{'net_nntp_arg'} = \%arg;
+    if ($arg{SSL}) {
+      Net::NNTP::_SSL->start_SSL($obj,%arg) or next;
+    }
+    last:
   }
 
   return
     unless defined $obj;
 
-  ${*$obj}{'net_nntp_host'} = $connect{PeerAddr};
-
   $obj->autoflush(1);
   $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
 
@@ -168,9 +163,11 @@ sub postok {
 sub starttls {
   my $self = shift;
   $ssl_class or die $nossl_warn;
-  $self->is_SSL and croak("NNTP connection is already in SSL mode");
   $self->_STARTTLS or return;
-  $self->connect_SSL;
+  Net::NNTP::_SSL->start_SSL($self,
+    %{ ${*$self}{'net_nntp_arg'} }, # (ssl) args given in new
+    @_   # more (ssl) args
+  );
 }
 
 
@@ -750,6 +747,28 @@ sub DESTROY {
   defined(fileno($nntp)) && $nntp->quit;
 }
 
+{
+  package Net::NNTP::_SSL;
+  our @ISA = ( $ssl_class ? ($ssl_class):(), 'Net::NNTP' );
+  sub starttls { die "NNTP connection is already in SSL mode" }
+  sub start_SSL {
+    my ($class,$nntp,%arg) = @_;
+    delete @arg{ grep { !m{^SSL_} } keys %arg };
+    ( $arg{SSL_verifycn_name} ||= $nntp->host )
+        =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname};
+    my $ok = $class->SUPER::start_SSL($nntp,
+      SSL_verifycn_scheme => 'nntp',
+      %arg
+    );
+    $@ = $ssl_class->errstr if !$ok;
+    return $ok;
+  }
+}
+
+
+
 
 1;
 
diff --git a/lib/Net/POP3.pm b/lib/Net/POP3.pm
index ae102a3..5bebe9b 100644
--- a/lib/Net/POP3.pm
+++ b/lib/Net/POP3.pm
@@ -87,14 +87,11 @@ sub new {
     unless defined $obj;
 
   ${*$obj}{'net_pop3_arg'} = \%arg;
+  ${*$obj}{'net_pop3_host'} = $host;
   if ($arg{SSL}) {
-    Net::POP3::_SSL->start_SSL($obj,
-      SSL_verifycn_name => $host,%arg
-    ) or return;
+    Net::POP3::_SSL->start_SSL($obj,%arg) or return;
   }
 
-  ${*$obj}{'net_pop3_host'} = $host;
-
   $obj->autoflush(1);
   $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
 
@@ -581,6 +578,8 @@ sub banner {
     delete @arg{ grep { !m{^SSL_} } keys %arg };
     ( $arg{SSL_verifycn_name} ||= $pop3->host )
         =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname};
     $arg{SSL_verifycn_scheme} ||= 'pop3';
     my $ok = $class->SUPER::start_SSL($pop3,%arg);
     $@ = $ssl_class->errstr if !$ok;
diff --git a/lib/Net/SMTP.pm b/lib/Net/SMTP.pm
index 5cc3922..23a0cca 100644
--- a/lib/Net/SMTP.pm
+++ b/lib/Net/SMTP.pm
@@ -89,8 +89,10 @@ sub new {
     unless defined $obj;
 
   ${*$obj}{'net_smtp_arg'} = \%arg;
+  ${*$obj}{'net_smtp_host'} = $host;
+
   if ($arg{SSL}) {
-    Net::SMTP::_SSL->start_SSL($obj,SSL_verifycn_name => $host,%arg)
+    Net::SMTP::_SSL->start_SSL($obj,%arg)
       or return;
   }
 
@@ -106,7 +108,6 @@ sub new {
   }
 
   ${*$obj}{'net_smtp_exact_addr'} = $arg{ExactAddresses};
-  ${*$obj}{'net_smtp_host'}       = $host;
 
   (${*$obj}{'net_smtp_banner'}) = $obj->message;
   (${*$obj}{'net_smtp_domain'}) = $obj->message =~ /\A\s*(\S+)/;
@@ -614,6 +615,8 @@ sub _STARTTLS { shift->command("STARTTLS")->response() == CMD_OK }
     delete @arg{ grep { !m{^SSL_} } keys %arg };
     ( $arg{SSL_verifycn_name} ||= $smtp->host )
         =~s{(?<!:):[\w()]+$}{}; # strip port
+    $arg{SSL_hostname} = $arg{SSL_verifycn_name}
+        if ! defined $arg{SSL_hostname};
     $arg{SSL_verifycn_scheme} ||= 'smtp';
     my $ok = $class->SUPER::start_SSL($smtp,%arg);
     $@ = $ssl_class->errstr if !$ok;