ARCv2

 view release on metacpan or  search on metacpan

lib/Arc/Connection/Server.pm  view on Meta::CPAN

	@{$this->{_expectedcmds}} = qw(QUIT AUTHENTICATE);
	return $this->_SendCommand("AUTH",join (",",@{$this->{sasl_mechanisms}}));
}

## send an error msg to client (Server error).
## Protocol command: ERR <msg>\r\n
##out> true when succesful, otherwise false
##eg> $this->_Error("failure.");
sub _Error
{
	my $this = shift;
	return $this->_SendCommand("ERR",join("",@_));
}

## send a command error msg to client.
## Protocol command: CMDERR <msg>\r\n
##out> true when succesful, otherwise false
##eg> $this->_CmdError("failure.");
sub _CmdError
{
	my $this = shift;
	return $this->_SendCommand("CMDERR",join("",@_));
}

## command is ready.
## When the ARCv2 command is ready with its work, the server
## sends the DONE command on the control connection.
## Protocol command: DONE\r\n
##out> true when succesful, otherwise false
##eg> $this->_Done();
sub _Done
{
	my $this = shift;
	return $this->_SendCommand("DONE");
}

## tell the client, which SASL mechanism is used.
## Protocol command: AUTHTYPE <SASL mechansism>\r\n
##out> true when succesful, otherwise false
##eg> $this->_Authtype();
sub _Authtype
{
	my $this = shift;
	@{$this->{_expectedcmds}} = qw(QUIT SASL);
	return $this->_SendCommand("AUTHTYPE",$this->{_saslmech});
}

## Creates the sasl object (server_new)
## and sends the first sasl challenge/response.
## 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;

	# Setting the Callback for getting the username
	# This has to happen just before the object-creation of cyrus sasl
	# because there is no way to set a callback after sasl_*_new
	$this->{__sasl}->callback(
		canonuser => [ \&_CBCanonUser, $this ],
		checkpass => $this->{sasl_cb_checkpass},
		getsecret => $this->{sasl_cb_getsecret},
	);

	my $sasl = $this->{_sasl} =
		$this->{__sasl}->server_new(
			$this->{service},
			"",
			inet_ntoa($this->{_connection}->sockaddr).";".$this->{_connection}->sockport,
			inet_ntoa($this->{_connection}->peeraddr).";".$this->{_connection}->peerport,
	);

	if ((!defined $sasl) or ($sasl->code != 0)) {
		return $this->_SetError("SASL: ",$sasl->error());
	}

	$this->_Debug("Available mechanisms. ",$sasl->listmech("","|",""));

	return $this->_StepAuthentication(1);
}

## Another SASL step
## Response of a SASL command from the client
## Protocol command: SASL <base64 encoded SASL outout>\r\n
##in> bool $first_step
##out> true when succesful, otherwise false
##eg> $this->_StepAuthentication(1);
sub _StepAuthentication
{
	my $this = shift;
	my $first = shift;
	my $sasl = $this->{_sasl};
	my $ret = 0;
	my $str;

	if ($first) {
		if ($this->{_cmdparameter} =~ /^\s+$/) {
			$this->_Debug("No cmdparameter, plain server start.");
			$str = $sasl->server_start();
		} else {
			$this->_Debug("SASL parameter is present.");
			$str = $sasl->server_start(decode_base64($this->{_cmdparameter}));
		}
	} else {
		$str = $sasl->server_step(decode_base64($this->{_cmdparameter}));
	}

	$str = "" unless defined $str;

	if ($sasl->need_step || $sasl->code == 0) {
		if ($sasl->code == 0) {
			$this->_Sasl($str) if $str ne "";

			$this->{_authenticated} = 1;
			@{$this->{_expectedcmds}} = qw(QUIT CMD);
			$this->{_username} = $sasl->property("user");
			$this->{_realm} = $sasl->property("realm");



( run in 0.868 second using v1.01-cache-2.11-cpan-39bf76dae61 )