ARCv2
view release on metacpan or search on metacpan
lib/Arc/Connection.pm view on Meta::CPAN
package Arc::Connection;
use strict;
use warnings;
use Carp;
use MIME::Base64;
use Arc qw(LOG_AUTH LOG_USER LOG_ERR LOG_CMD LOG_SIDE LOG_DEBUG);
use Authen::SASL;
@Arc::Connection::ISA = qw(Arc);
sub members
{
my $this = shift;
return { %{$this->SUPER::members},
# private:
__sasl => undef, # Authen::SASL Handle
__linequeue => [], # internal line buffer (idea From Net::Cmd)
__partial => "", # a partial line (idea From Net::Cmd)
# protected:
_connection => undef, # IO::Socket for the ARCv2 Connection
_cmdclientsock => undef, # IO::Socket for the command connection (encrypted)
_select => undef, # IO::Select for the ARCv2 Connection
_authenticated => 0, # Are we authenticated
#_sasl => undef, # Authen::SASL::Cyrus Handle
#_saslmech => "", # SASL mechnanism used at authentication
_cmdparameter => undef, # parameter after the command
_expectedcmds => undef, # array, which ARCv2 protocol commands are allowed to come next
_connected => 0, # are we connected
_username => "anonymous", # username extracted from SASL
# public:
protocol => undef, # Which protocol is used (0 = ARC/2.0, 1 = ARC/2.1)
timeout => undef, # timeout for all connections (ARCv2 and command) in seconds
service => undef, # name of the server (for SASL)
};
}
sub _Init
{
my $this = shift;
return $this->_SetError("Initialization failed.") unless $this->SUPER::_Init(@_);
# timeout
# unless (defined $this->{timeout}) {
# $this->Log(LOG_SIDE,"Setting timeout to 30 secs since no time specified.");
# $this->{timeout} = 30;
# }
return $this->_SetError("No service name for SASL authentication specified.")
unless defined $this->{service};
return 1;
}
## initializes command connection. (protocol)
## Starts listen on the Command socket and sends the B<CMDPASV> command.
##out> true if everything went like expected, otherwise false.
##eg> $this->_CommandConnection();
sub _CommandConnection
{
my $this = shift;
my $consock = IO::Socket::INET->new(
Listen => 1,
Proto => 'tcp',
LocalAddr => $this->{_connection}->sockhost,
ReuseAddr => 1,
) || return $this->_SetError("Socket creation for CommandConnection failed.");
unless ($this->_SendCommand("CMDPASV",$consock->sockhost.':'.$consock->sockport)) {
return;
}
my $sel = new IO::Select($consock);
if (my @socks = $sel->can_read(10)) {
foreach my $sock (@socks) {
if ($sock == $consock) {
$this->{_cmdclientsock} = $consock->accept() || last;
return 1;
}
}
} else {
return $this->_SetError("No CommandConnection received (Client died?).");
}
}
## function for reading and writing on the command connection.
## This function is always used by the C<Arc::Connection::Server> to handle
lib/Arc/Connection.pm view on Meta::CPAN
## send the ARCv2 SASL command. (protocol)
## This function encodes the output from sasl_*_start and sasl_*_step with Base-64 and sends
## it to the other side
##in> $saslstr
##out> true if successful, otherwise false
##eg> $this->_Sasl($sasl->client_start());
sub _Sasl
{
my ($this,$str) = @_;
return $this->_SendCommand("SASL",encode_base64($str,""));
}
## initialize sasl.
## This function initializes the C<__sasl> member with an object
## of C<Authen::SASL>.
##out> true if successful, otherwise false
##eg> $this->_PrepareAuthentication() || return;
sub _PrepareAuthentication
{
my $this = shift;
# Authen::SASL Instance creation
$this->{__sasl} = Authen::SASL->new(
mechanism => "".$this->{_saslmech},
);
if (!defined $this->{__sasl}) {
return $this->_SetError("SASL error. No SASL object created.");
}
return 1;
}
## are we connected?
##out> true, if the ARCv2 control connection is connected, otherwise false
##eg> last unless $arc->IsConnected;
sub IsConnected
{
my $this = shift;
return $this->{_connected};
}
sub clean
{
my $this = shift;
delete $this->{__sasl};
$this->{__linequeue} = [];
$this->{__partial} = "";
$this->{_authenticated} = 0;
$this->{_sasl} = undef;
$this->{_saslmech} = "";
$this->{_cmdparameter} = undef;
$this->{_expectedcmds} = undef;
$this->{_connected} = 0;
$this->{_username} = "anonymous";
$this->{_error} = undef;
# public:
$this->{protocol} = undef;
}
1;
( run in 1.079 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )