diff options
author | Steffen Ullrich <Steffen_Ullrich@genua.de> | 2014-11-28 11:47:16 +0100 |
---|---|---|
committer | Steffen Ullrich <Steffen_Ullrich@genua.de> | 2014-11-28 16:03:40 +0100 |
commit | 50c6fd25f2958e6300ec8377ab40c3f1a23bd9fd (patch) | |
tree | a93cee6837a770a5a3ce09de337554db35f32b72 /lib/Net/NNTP.pm | |
parent | 4dadbf4eb332a886023b2451ab3ef08d9af31423 (diff) | |
download | perl-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.pm | 57 |
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; |