ARCv2
view release on metacpan or search on metacpan
lib/Arc/Connection/Client.pm view on Meta::CPAN
use IO::Socket::INET;
use IO::Select;
use Arc qw(LOG_AUTH LOG_USER LOG_ERR LOG_CMD LOG_SIDE LOG_DEBUG);
use Arc::Connection;
use MIME::Base64;
@Arc::Connection::Client::ISA = qw(Arc::Connection);
sub members
{
my $this = shift;
return { %{$this->SUPER::members},
logfileprefix => "client",
logdestination => "stderr",
sasl_cb_user => $ENV{'USER'}, # SASL Callback for username (PLAIN and some other mechs only)
sasl_cb_auth => $ENV{'USER'}, # SASL Callback for authname (PLAIN and some other mechs only)
sasl_cb_pass => "", # SASL Callback for password (PLAIN and some other mechs only)
server => undef, # Server to connect to
port => undef, # Port to connect to
sasl_mechanism => undef, # use this mechanism for authentication
server_sasl_mechanisms => [], # filled by the sasl mechanisms
protocol => 1, # Which protocol type the shall use.
};
}
sub _Init
{
my $this = shift;
return 0 unless $this->SUPER::_Init(@_);
# server
return $this->_SetError("No ARCv2 server given.") unless defined $this->{server};
# port
unless (defined $this->{port}) {
$this->Log(LOG_SIDE,"No port specified. Using $Arc::DefaultPort.");
$this->{port} = $Arc::DefaultPort;
}
# sasl mech
$this->Log(LOG_SIDE,"No sasl mechanism specified. Using the one supplied by the server.")
unless defined $this->{sasl_mechanism};
}
## connects to the server
##out> true when succesful, otherwise false
##eg> $this->_Connect();
sub _Connect
{
my $this = shift;
$this->{_connection} = new IO::Socket::INET(
PeerAddr => $this->{server},
PeerPort => $this->{port},
Type => SOCK_STREAM,
) || return $this->_SetError("Could not create Client socket: $! $@.");
# Fill the connected Socket into the select object
$this->{_select} = new IO::Select($this->{_connection})
|| return $this->_SetError("Select creation failed.");
$this->{_connection}->autoflush(0);
$this->{_connected} = 1;
return 1;
}
## initialize the protocol.
## Sends the initial protocol message ARC/2.0
##out> true when succesful, otherwise false
##eg> $this->_InitARC2();
sub _InitARC2
{
my $this = shift;
@{$this->{_expectedcmds}} = qw(ERR AUTH);
$this->{_authenticated} = 0;
return $this->_SendCommand ("ARC/2.".$this->{protocol});
}
## initiate the authentication.
## Tells the server which authtype we want to use.
## Protocol command: AUTHENTICATE [<authtype>]\r\n
##out> true when succesful, otherwise false
##eg> $this->_Authenticate();
sub _Authenticate
{
my $this = shift;
@{$this->{_expectedcmds}} = qw(ERR AUTHTYPE);
return $this->_SendCommand ("AUTHENTICATE",$this->{sasl_mechanism});
}
## initiate the authentication (sasl)
## Creates the sasl object (client_new).
## Client begins always and sends the first SASL challenge
## Protocol command: SASL <base64 encoded SASL output>\r\n
##out> true when succesful, otherwise false
##eg> $this->_StartAuthentication();
sub _StartAuthentication
{
my $this = shift;
$this->_PrepareAuthentication() || return;
$this->{__sasl}->callback(
user => $this->{sasl_cb_user},
auth => $this->{sasl_cb_auth},
pass => $this->{sasl_cb_pass},
);
my $sasl = $this->{_sasl} = $this->{__sasl}->client_new(
$this->{service},
$this->{server},
$this->{_connection}->sockhost.";".$this->{_connection}->sockport,
$this->{_connection}->peerhost.";".$this->{_connection}->peerport,
);
# sasl Context created
if (!defined $sasl || $sasl->code != 0) {
return $this->_SetError("creating SASL object failed: ",$sasl->error());
( run in 1.116 second using v1.01-cache-2.11-cpan-39bf76dae61 )