about summary refs log tree commit
path: root/lib/Net/NNTP.pm
diff options
context:
space:
mode:
authorSteffen Ullrich <Steffen_Ullrich@genua.de>2014-11-28 11:47:16 +0100
committerSteffen Ullrich <Steffen_Ullrich@genua.de>2014-11-28 16:03:40 +0100
commit50c6fd25f2958e6300ec8377ab40c3f1a23bd9fd (patch)
treea93cee6837a770a5a3ce09de337554db35f32b72 /lib/Net/NNTP.pm
parent4dadbf4eb332a886023b2451ab3ef08d9af31423 (diff)
downloadperl-libnet-50c6fd25f2958e6300ec8377ab40c3f1a23bd9fd.tar.gz
- model SSL support for Net::NNTP after Net::SMTP, i.e. upgrade to SSL class instead of using IO::Socket::SSL in plain and SSL mode
- use SNI for SSL support in SMTP, NNTP, POP3, FTP by default
Diffstat (limited to 'lib/Net/NNTP.pm')
-rw-r--r--lib/Net/NNTP.pm57
1 files changed, 38 insertions, 19 deletions
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;