RT::Authen::ExternalAuth with PHPass (phpbb3);

Hi,

I’m trying to configure ExternalAuth on my RT4.0.2

External database use Portable PHP password hashing framework. (phpbb3)
http://www.openwall.com/phpass/

There is perl module for this Authen::Passphrase::PHPass (Perl module
reimplements the support for portable hashes introduced in phpass, but
in Perl).

My question is haw I should configure RT_siteConfig.pm:

‘p_enc_pkg’ => ‘?’
‘p_enc_sub’ => ‘?’

When I use:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘’,

I get:

My_MySQL AUTH FAILED The encryption package you gave me (
Authen::Passphrase::PHPass ) does not support the encryption method
you specified ( )
(/opt/rt4/local/plugins/RT-Authen-ExternalAuth/lib/RT/Authen/ExternalAuth/DBI.pm:99)

Any idea why ?

Best
Adrian Stelmaszyk

Hi,

thanks :slight_smile:

phpass has many method I use hash_base64, RTSiteConfig.pm:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘hash_base64’,

and when i put user/pass I get:

RT Site:
http://150.254.148.60/NoAuth/Login.html

Can’t use string (“*****”) as a HASH ref while “strict refs” in use at
/usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm line 278.

But when I reload page I will be login to RT.

Any idea why we get this error.

I test 2 more method hash and cost i both case we get the same error.

I’m not sure if I chose rigt method.

Or there is issues in RTSiteConfig.pm

Best
Adrian2011/11/14 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,
When I use:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘’,

I get:

My_MySQL AUTH FAILED The encryption package you gave me (
Authen::Passphrase::PHPass ) does not support the encryption method
you specified ( )
(/opt/rt4/local/plugins/RT-Authen-ExternalAuth/lib/RT/Authen/ExternalAuth/DBI.pm:99)

Any idea why ?

Very simple, you haven’t specified a method (subroutine) for the
encryption; only the package.

Take MySQL’s password function as an example. To use it you would
specific the p_enc_pkg as Crypt::MySQL which will “include” that perl
module, but that module provides many different methods. Normally you’d
expect to use “password41” as the p_enc_sub.

If it were MD5:

p_eng_pkg: Digest::MD5
p_enc_sub: md5_hex

Zordrak
zordrak@tpa.me.uk

Pozdrawiam
Adrian Stelmaszyk

Hi,

thanks :slight_smile:

phpass has many method I use hash_base64, RTSiteConfig.pm:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘hash_base64’,

and when i put user/pass I get:

RT Site:
http://150.254.148.60/NoAuth/Login.html

Can’t use string (“*****”) as a HASH ref while “strict refs” in use at
/usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm line 278.

Sounds like the Authen::Passphrase::PHPass module doesn’t like the way
that RT-Authen-ExternalAuth is invoking it.

Unfortunately, you’ll need to add some debugging to figure out where
it goes wrong unless someone on the list has experience with the
configuration you want to use.

-kevin

Hi,

any idea where I should look, file name ? function ?

Best
Adrian2011/11/14 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

thanks :slight_smile:

phpass has many method I use hash_base64, RTSiteConfig.pm:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘hash_base64’,

and when i put user/pass I get:

RT Site:
http://150.254.148.60/NoAuth/Login.html

Can’t use string (“*****”) as a HASH ref while “strict refs” in use at
/usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm line 278.

But when I reload page I will be login to RT.

Any idea why we get this error.

My guess would be that PHPass.pm expects the password to be sent to it
as a hashref instead of a string. IF this is the case then you will need
to modify the code in ExternalAuth so that when the subroutine is
called, the string is first converted into a hashref and then sent as a
parameter.

Zordrak
zordrak@tpa.me.uk

Hi,

Can’t use string (“user password”) as a HASH ref while “strict refs”
in use at /usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm
line 278.

Problem is with type of user password.

Still need to know where I should search.

Best
Adrian2011/11/15 Adrian Stel adisan82@gmail.com:

Hi,

any idea where I should look, file name ? function ?

Best
Adrian

2011/11/14 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

thanks :slight_smile:

phpass has many method I use hash_base64, RTSiteConfig.pm:

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘hash_base64’,

and when i put user/pass I get:

RT Site:
http://150.254.148.60/NoAuth/Login.html

Can’t use string (“*****”) as a HASH ref while “strict refs” in use at
/usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm line 278.

But when I reload page I will be login to RT.

Any idea why we get this error.

My guess would be that PHPass.pm expects the password to be sent to it
as a hashref instead of a string. IF this is the case then you will need
to modify the code in ExternalAuth so that when the subroutine is
called, the string is first converted into a hashref and then sent as a
parameter.

Zordrak
zordrak@tpa.me.uk

Pozdrawiam
Adrian Stelmaszyk

Hi,

DBI.pm
this is the place with p_enc_sub:

sub GetAuth {

my ($service, $username, $password) = @_;

my $config = $RT::ExternalSettings->{$service};
$RT::Logger->debug( "Trying external auth service:",$service);

my $db_table        = $config->{'table'};
my $db_u_field      = $config->{'u_field'};
my $db_p_field          = $config->{'p_field'};
my $db_p_enc_pkg    = $config->{'p_enc_pkg'};
my $db_p_enc_sub    = $config->{'p_enc_sub'};
my $db_p_salt       = $config->{'p_salt'};

Place where the password is submitted to that method as a string parameter.

In my opinion could be here:

Get the user’s password from the database query result

my $pass_from_db = $results_hashref->{$username}->{$db_p_field};

# This is the encryption package & subroutine passed in by the config file
$RT::Logger->debug( "Encryption Package:",
                    $db_p_enc_pkg);
$RT::Logger->debug( "Encryption Subroutine:",
                    $db_p_enc_sub);

# Use config info to auto-load the perl package needed for

password encryption
# I know it uses a string eval - but I don’t think there’s a
better way to do this
# Jump to next external authentication service on failure
eval “require $db_p_enc_pkg” or
$RT::Logger->error(“AUTH FAILED, Couldn’t Load Password
Encryption Package. Error: $@”) && return 0;

my $encrypt = $db_p_enc_pkg->can($db_p_enc_sub);
if (defined($encrypt)) {
    # If the package given can perform the subroutine given, then

use it to compare the
# password given with the password pulled from the database.
# Jump to the next external authentication service if they don’t match
if(defined($db_p_salt)) {
$RT::Logger->debug(“Using salt:”,$db_p_salt);
if(${encrypt}->($password,$db_p_salt) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
} else {
if(${encrypt}->($password) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
}
} else {
# If the encryption package can’t perform the request subroutine,
# dump an error and jump to the next external authentication service.
$RT::Logger->error($service,
“AUTH FAILED”,
“The encryption package you gave me (”,
$db_p_enc_pkg,
“) does not support the encryption method
you specified (”,
$db_p_enc_sub,
“)”);
return 0;
}

But i’m not shure where exactly. And how I can convert string to hash.

I’m not familiar with perl ;/

Best
Adrian2011/11/15 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

Can’t use string (“user password”) as a HASH ref while “strict refs”
in use at /usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm
line 278.

Problem is with type of user password.

Still need to know where I should search.

Search for the text “p_enc_sub”. There’s only one place it should be
defined and it will be very close to where the password is submitted to
that method as a string parameter.

Zordrak
zordrak@tpa.me.uk

Pozdrawiam
Adrian Stelmaszyk

Hi,

I get some info from PHPass but I don’t know how use it ;/ any
sugestion from your site ?

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘cost’,

The comment above, the example below, and a bit of googling all show that
p_enc_pkg and p_enc_sub are together meant to name a hash function.
Your password string will be passed through the function, and the
resulting hash value is then managed by RT. The clearest example:

#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

Crypt::MySQL::password41() is a function to which you pass a password
string and it returns a hash. For example, password41(“hunter2”) returns
“*58815970BE77B3720276F63DB198B1FA42E5CC02”.

Authen::Passphrase::PHPass::cost is not a hashing function. It’s
not meant to be called as a standalone function at all. It’s the
implementation of the ->cost method on the Authen::Passphrase::PHPass
class, and so expects to be passed an A:P:PHPass object, not a string.
A:P:PHPass doesn’t actually expose the hash function on its own, so you
can’t use it this way.

In fact, the PHPass hash algorithm can’t be properly used by RT,
because it takes a salt input, and apparently RT can’t perform salting.
(There’s a p_salt parameter, which appears to be a fixed salt, defeating
the purpose.)

You could write a wrapper function around A:P:PHPass that creates a
recogniser for a supplied password and then just extracts the hash.
The wrapper would have to fix the cost parameter and the salt. It looks
like this:

   use Authen::Passphrase::PHPass ();
   sub phpass_10_aaaaaaaa($) {
           return Authen::Passphrase::PHPass->new(
                   cost=>10,
                   passphrase=>$_[0],
                   salt=>"aaaaaaaa",
           )->hash_base64;
   }

phpass_10_aaaaaaaa(“hunter2”) returns “LvYU3dRamxKB1.lRa4ow1/”. This
is a hash function and could be used by RT via p_enc_pkg and p_enc_sub.

It’s a bit of an abstraction inversion to use A:P:PHPass just for
its hash function. If A:P:PHPass were wrapping some other module
that just provides the hash then I’d point you at the other module.
Most A:P modules do this, such as A:P:MySQL323 wrapping Crypt::MySQL.
But A:P:PHPass implements the hash itself. Also, if there were a module
exposing the PHPass algorithm on its own, you’d still have to write a
wrapper, because of the cost parameter that RT has no idea how to handle.2011/11/16 Adrian Stel adisan82@gmail.com:

Hi,

DBI.pm
this is the place with p_enc_sub:

sub GetAuth {

my ($service, $username, $password) = @_;

my $config = $RT::ExternalSettings->{$service};
$RT::Logger->debug( “Trying external auth service:”,$service);

my $db_table = $config->{‘table’};
my $db_u_field = $config->{‘u_field’};
my $db_p_field = $config->{‘p_field’};
my $db_p_enc_pkg = $config->{‘p_enc_pkg’};
my $db_p_enc_sub = $config->{‘p_enc_sub’};
my $db_p_salt = $config->{‘p_salt’};

Place where the password is submitted to that method as a string parameter.

In my opinion could be here:

Get the user’s password from the database query result

my $pass_from_db = $results_hashref->{$username}->{$db_p_field};

This is the encryption package & subroutine passed in by the config file

$RT::Logger->debug( “Encryption Package:”,
$db_p_enc_pkg);
$RT::Logger->debug( “Encryption Subroutine:”,
$db_p_enc_sub);

Use config info to auto-load the perl package needed for

password encryption

I know it uses a string eval - but I don’t think there’s a

better way to do this

Jump to next external authentication service on failure

eval “require $db_p_enc_pkg” or
$RT::Logger->error(“AUTH FAILED, Couldn’t Load Password
Encryption Package. Error: $@”) && return 0;

my $encrypt = $db_p_enc_pkg->can($db_p_enc_sub);
if (defined($encrypt)) {
# If the package given can perform the subroutine given, then
use it to compare the
# password given with the password pulled from the database.
# Jump to the next external authentication service if they don’t match
if(defined($db_p_salt)) {
$RT::Logger->debug(“Using salt:”,$db_p_salt);
if(${encrypt}->($password,$db_p_salt) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
} else {
if(${encrypt}->($password) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
}
} else {
# If the encryption package can’t perform the request subroutine,
# dump an error and jump to the next external authentication service.
$RT::Logger->error($service,
“AUTH FAILED”,
“The encryption package you gave me (”,
$db_p_enc_pkg,
“) does not support the encryption method
you specified (”,
$db_p_enc_sub,
“)”);
return 0;
}

But i’m not shure where exactly. And how I can convert string to hash.

I’m not familiar with perl ;/

Best
Adrian

2011/11/15 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

Can’t use string (“user password”) as a HASH ref while “strict refs”
in use at /usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm
line 278.

Problem is with type of user password.

Still need to know where I should search.

Search for the text “p_enc_sub”. There’s only one place it should be
defined and it will be very close to where the password is submitted to
that method as a string parameter.

Zordrak
zordrak@tpa.me.uk


Pozdrawiam
Adrian Stelmaszyk

Pozdrawiam
Adrian Stelmaszyk

Hello,

I didn’t read full thread, but long time ago I talked with zordrak
about how password checking is wrong and not flexible. The current set
of options is not suitable for many cases. I’ve cooked a patch [1].
The following config with patched extension can check any format
supported by Authen::Passphrase framework:


p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

Above covers HASH schemes described in [2]. If stored hash doesn’t
have $schema$ prefix then code needs a little bit of change.

However, I didn’t test the patch.

[1] add new option p_check to DBI auth module · bestpractical/rt-authen-externalauth@22ba2bf · GitHub
[2] Authen::Passphrase - hashed passwords/passphrases as objects - metacpan.org Wed, Nov 16, 2011 at 4:27 PM, Adrian Stel adisan82@gmail.com wrote:

Hi,

I get some info from PHPass but I don’t know how use it ;/ any
sugestion from your site ?

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘cost’,

The comment above, the example below, and a bit of googling all show that
p_enc_pkg and p_enc_sub are together meant to name a hash function.
Your password string will be passed through the function, and the
resulting hash value is then managed by RT. The clearest example:

#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

Crypt::MySQL::password41() is a function to which you pass a password
string and it returns a hash. For example, password41(“hunter2”) returns
“*58815970BE77B3720276F63DB198B1FA42E5CC02”.

Authen::Passphrase::PHPass::cost is not a hashing function. It’s
not meant to be called as a standalone function at all. It’s the
implementation of the ->cost method on the Authen::Passphrase::PHPass
class, and so expects to be passed an A:P:PHPass object, not a string.
A:P:PHPass doesn’t actually expose the hash function on its own, so you
can’t use it this way.

In fact, the PHPass hash algorithm can’t be properly used by RT,
because it takes a salt input, and apparently RT can’t perform salting.
(There’s a p_salt parameter, which appears to be a fixed salt, defeating
the purpose.)

You could write a wrapper function around A:P:PHPass that creates a
recogniser for a supplied password and then just extracts the hash.
The wrapper would have to fix the cost parameter and the salt. It looks
like this:

  use Authen::Passphrase::PHPass ();
  sub phpass_10_aaaaaaaa($) {
          return Authen::Passphrase::PHPass->new(
                  cost=>10,
                  passphrase=>$_[0],
                  salt=>"aaaaaaaa",
          )->hash_base64;
  }

phpass_10_aaaaaaaa(“hunter2”) returns “LvYU3dRamxKB1.lRa4ow1/”. This
is a hash function and could be used by RT via p_enc_pkg and p_enc_sub.

It’s a bit of an abstraction inversion to use A:P:PHPass just for
its hash function. If A:P:PHPass were wrapping some other module
that just provides the hash then I’d point you at the other module.
Most A:P modules do this, such as A:P:MySQL323 wrapping Crypt::MySQL.
But A:P:PHPass implements the hash itself. Also, if there were a module
exposing the PHPass algorithm on its own, you’d still have to write a
wrapper, because of the cost parameter that RT has no idea how to handle.

2011/11/16 Adrian Stel adisan82@gmail.com:

Hi,

DBI.pm
this is the place with p_enc_sub:

sub GetAuth {

my ($service, $username, $password) = @_;

my $config = $RT::ExternalSettings->{$service};
$RT::Logger->debug( “Trying external auth service:”,$service);

my $db_table = $config->{‘table’};
my $db_u_field = $config->{‘u_field’};
my $db_p_field = $config->{‘p_field’};
my $db_p_enc_pkg = $config->{‘p_enc_pkg’};
my $db_p_enc_sub = $config->{‘p_enc_sub’};
my $db_p_salt = $config->{‘p_salt’};

Place where the password is submitted to that method as a string parameter.

In my opinion could be here:

Get the user’s password from the database query result

my $pass_from_db = $results_hashref->{$username}->{$db_p_field};

This is the encryption package & subroutine passed in by the config file

$RT::Logger->debug( “Encryption Package:”,
$db_p_enc_pkg);
$RT::Logger->debug( “Encryption Subroutine:”,
$db_p_enc_sub);

Use config info to auto-load the perl package needed for

password encryption

I know it uses a string eval - but I don’t think there’s a

better way to do this

Jump to next external authentication service on failure

eval “require $db_p_enc_pkg” or
$RT::Logger->error(“AUTH FAILED, Couldn’t Load Password
Encryption Package. Error: $@”) && return 0;

my $encrypt = $db_p_enc_pkg->can($db_p_enc_sub);
if (defined($encrypt)) {
# If the package given can perform the subroutine given, then
use it to compare the
# password given with the password pulled from the database.
# Jump to the next external authentication service if they don’t match
if(defined($db_p_salt)) {
$RT::Logger->debug(“Using salt:”,$db_p_salt);
if(${encrypt}->($password,$db_p_salt) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
} else {
if(${encrypt}->($password) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
}
} else {
# If the encryption package can’t perform the request subroutine,
# dump an error and jump to the next external authentication service.
$RT::Logger->error($service,
“AUTH FAILED”,
“The encryption package you gave me (”,
$db_p_enc_pkg,
“) does not support the encryption method
you specified (”,
$db_p_enc_sub,
“)”);
return 0;
}

But i’m not shure where exactly. And how I can convert string to hash.

I’m not familiar with perl ;/

Best
Adrian

2011/11/15 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

Can’t use string (“user password”) as a HASH ref while “strict refs”
in use at /usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm
line 278.

Problem is with type of user password.

Still need to know where I should search.

Search for the text “p_enc_sub”. There’s only one place it should be
defined and it will be very close to where the password is submitted to
that method as a string parameter.

Zordrak
zordrak@tpa.me.uk


Pozdrawiam
Adrian Stelmaszyk


Pozdrawiam
Adrian Stelmaszyk

RT Training Sessions (http://bestpractical.com/services/training.html)

  • Barcelona, Spain November 28 & 29, 2011

Best regards, Ruslan.

Hi Ruslan,

If I understand well:

  1. apply patch - easy to do (just add line to
    /opt/rt4/local/plugins/RT-Authen-ExternalAuth/lib/RT/Authen/ExternalAuth/DBI.pm)

  2. Here I have some question because I’m not sure how set ‘p_enc_pkg’
    and ‘p_enc_sub’

I need add this check to RT_SiteConfig.pm: ??

p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

then RT_SiteConfig.pm looks like:

The Perl package & subroutine used to encrypt passwords

e.g. if the passwords are stored using the MySQL v3.23 “PASSWORD”

function, then you will need Crypt::MySQL::password, but for the

MySQL4+ password function you will need Crypt::MySQL::password41

Alternatively, you could use Digest::MD5::md5_hex or any other

encryption subroutine you can load in your perl installation

‘p_enc_pkg’ => ‘Authen::Passphrase’, (???)
‘p_enc_sub’ => ‘$P$’, (???)
p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},
#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

If your p_enc_sub takes a salt as a second parameter,

uncomment this line to add your salt

#‘p_salt’ => ‘SALT’,

If i mix/miss something please correct me.

Best Regards
Adrian2011/11/16 Ruslan Zakirov ruz@bestpractical.com:

Hello,

I didn’t read full thread, but long time ago I talked with zordrak
about how password checking is wrong and not flexible. The current set
of options is not suitable for many cases. I’ve cooked a patch [1].
The following config with patched extension can check any format
supported by Authen::Passphrase framework:


p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

Above covers HASH schemes described in [2]. If stored hash doesn’t
have $schema$ prefix then code needs a little bit of change.

However, I didn’t test the patch.

[1] add new option p_check to DBI auth module · bestpractical/rt-authen-externalauth@22ba2bf · GitHub
[2] Authen::Passphrase - hashed passwords/passphrases as objects - metacpan.org

On Wed, Nov 16, 2011 at 4:27 PM, Adrian Stel adisan82@gmail.com wrote:

Hi,

I get some info from PHPass but I don’t know how use it ;/ any
sugestion from your site ?

‘p_enc_pkg’ => ‘Authen::Passphrase::PHPass’,
‘p_enc_sub’ => ‘cost’,

The comment above, the example below, and a bit of googling all show that
p_enc_pkg and p_enc_sub are together meant to name a hash function.
Your password string will be passed through the function, and the
resulting hash value is then managed by RT. The clearest example:

#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

Crypt::MySQL::password41() is a function to which you pass a password
string and it returns a hash. For example, password41(“hunter2”) returns
“*58815970BE77B3720276F63DB198B1FA42E5CC02”.

Authen::Passphrase::PHPass::cost is not a hashing function. It’s
not meant to be called as a standalone function at all. It’s the
implementation of the ->cost method on the Authen::Passphrase::PHPass
class, and so expects to be passed an A:P:PHPass object, not a string.
A:P:PHPass doesn’t actually expose the hash function on its own, so you
can’t use it this way.

In fact, the PHPass hash algorithm can’t be properly used by RT,
because it takes a salt input, and apparently RT can’t perform salting.
(There’s a p_salt parameter, which appears to be a fixed salt, defeating
the purpose.)

You could write a wrapper function around A:P:PHPass that creates a
recogniser for a supplied password and then just extracts the hash.
The wrapper would have to fix the cost parameter and the salt. It looks
like this:

  use Authen::Passphrase::PHPass ();
  sub phpass_10_aaaaaaaa($) {
          return Authen::Passphrase::PHPass->new(
                  cost=>10,
                  passphrase=>$_[0],
                  salt=>"aaaaaaaa",
          )->hash_base64;
  }

phpass_10_aaaaaaaa(“hunter2”) returns “LvYU3dRamxKB1.lRa4ow1/”. This
is a hash function and could be used by RT via p_enc_pkg and p_enc_sub.

It’s a bit of an abstraction inversion to use A:P:PHPass just for
its hash function. If A:P:PHPass were wrapping some other module
that just provides the hash then I’d point you at the other module.
Most A:P modules do this, such as A:P:MySQL323 wrapping Crypt::MySQL.
But A:P:PHPass implements the hash itself. Also, if there were a module
exposing the PHPass algorithm on its own, you’d still have to write a
wrapper, because of the cost parameter that RT has no idea how to handle.

2011/11/16 Adrian Stel adisan82@gmail.com:

Hi,

DBI.pm
this is the place with p_enc_sub:

sub GetAuth {

my ($service, $username, $password) = @_;

my $config = $RT::ExternalSettings->{$service};
$RT::Logger->debug( “Trying external auth service:”,$service);

my $db_table = $config->{‘table’};
my $db_u_field = $config->{‘u_field’};
my $db_p_field = $config->{‘p_field’};
my $db_p_enc_pkg = $config->{‘p_enc_pkg’};
my $db_p_enc_sub = $config->{‘p_enc_sub’};
my $db_p_salt = $config->{‘p_salt’};

Place where the password is submitted to that method as a string parameter.

In my opinion could be here:

Get the user’s password from the database query result

my $pass_from_db = $results_hashref->{$username}->{$db_p_field};

This is the encryption package & subroutine passed in by the config file

$RT::Logger->debug( “Encryption Package:”,
$db_p_enc_pkg);
$RT::Logger->debug( “Encryption Subroutine:”,
$db_p_enc_sub);

Use config info to auto-load the perl package needed for

password encryption

I know it uses a string eval - but I don’t think there’s a

better way to do this

Jump to next external authentication service on failure

eval “require $db_p_enc_pkg” or
$RT::Logger->error(“AUTH FAILED, Couldn’t Load Password
Encryption Package. Error: $@”) && return 0;

my $encrypt = $db_p_enc_pkg->can($db_p_enc_sub);
if (defined($encrypt)) {
# If the package given can perform the subroutine given, then
use it to compare the
# password given with the password pulled from the database.
# Jump to the next external authentication service if they don’t match
if(defined($db_p_salt)) {
$RT::Logger->debug(“Using salt:”,$db_p_salt);
if(${encrypt}->($password,$db_p_salt) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
} else {
if(${encrypt}->($password) ne $pass_from_db){
$RT::Logger->info( $service,
“AUTH FAILED”,
$username,
“Password Incorrect”);
return 0;
}
}
} else {
# If the encryption package can’t perform the request subroutine,
# dump an error and jump to the next external authentication service.
$RT::Logger->error($service,
“AUTH FAILED”,
“The encryption package you gave me (”,
$db_p_enc_pkg,
“) does not support the encryption method
you specified (”,
$db_p_enc_sub,
“)”);
return 0;
}

But i’m not shure where exactly. And how I can convert string to hash.

I’m not familiar with perl ;/

Best
Adrian

2011/11/15 Zordrak zordrak@tpa.me.uk:

Adrian Stel wrote:

Hi,

Can’t use string (“user password”) as a HASH ref while “strict refs”
in use at /usr/local/share/perl/5.10.1/Authen/Passphrase/PHPass.pm
line 278.

Problem is with type of user password.

Still need to know where I should search.

Search for the text “p_enc_sub”. There’s only one place it should be
defined and it will be very close to where the password is submitted to
that method as a string parameter.

Zordrak
zordrak@tpa.me.uk


Pozdrawiam
Adrian Stelmaszyk


Pozdrawiam
Adrian Stelmaszyk

RT Training Sessions (http://bestpractical.com/services/training.html)

  • Barcelona, Spain November 28 & 29, 2011


Best regards, Ruslan.

Pozdrawiam
Adrian Stelmaszyk

Hi Ruslan,

If I understand well:

  1. apply patch - easy to do (just add line to
    /opt/rt4/local/plugins/RT-Authen-ExternalAuth/lib/RT/Authen/ExternalAuth/DBI.pm)

  2. Here I have some question because I’m not sure how set 'p_enc_pkg’
    and ‘p_enc_sub’

These are not required when p_check is set. p_check is a code inlined
right into config that does whole job of checking password user
entered against the hash.

I need add this check to RT_SiteConfig.pm: ??

Yes.

p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

then RT_SiteConfig.pm looks like:

The Perl package & subroutine used to encrypt passwords

e.g. if the passwords are stored using the MySQL v3.23 “PASSWORD”

function, then you will need Crypt::MySQL::password, but for the

MySQL4+ password function you will need Crypt::MySQL::password41

Alternatively, you could use Digest::MD5::md5_hex or any other

encryption subroutine you can load in your perl installation

‘p_enc_pkg’ => ‘Authen::Passphrase’, (???)
‘p_enc_sub’ => ‘$P$’, (???)
p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},
#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

If your p_enc_sub takes a salt as a second parameter,

uncomment this line to add your salt

#‘p_salt’ => ‘SALT’,

If i mix/miss something please correct me.

Leave p_check and options that control how to find user in the DB,
drop p_salt and p_enc_* options.

Best Regards
Adrian

Best regards, Ruslan.

Hi Ruslan,

I comment in RT_SiteConfig.pm:

#p_enc_pkg =>
#p_enc_sub =>

and put:

p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

In log I can see:

p_check for My_MySQL failed: unrecognised crypt scheme $H$ at
/opt/rt4/etc/RT_SiteConfig.pm line 154

This is the line:

154 return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);

I’m not sure if I put this p_check i right place, or I miss some ‘’ ?

Normal we have:
‘‘p_enc_pkg’ => ‘Authen::Passphrase’,’

Should I live this p_check like this:

151 p_check => sub {
152 my
($hash, $pass) = @_;
153 use
Authen::Passphrase;
154
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
155 },
156

I can send you whole Set($ExternalSettings,) if it will help find issues.

Best
Adrian2011/11/17 Ruslan Zakirov ruz@bestpractical.com:

On Thu, Nov 17, 2011 at 1:49 PM, Adrian Stel adisan82@gmail.com wrote:

Hi Ruslan,

If I understand well:

  1. apply patch - easy to do (just add line to
    /opt/rt4/local/plugins/RT-Authen-ExternalAuth/lib/RT/Authen/ExternalAuth/DBI.pm)

  2. Here I have some question because I’m not sure how set ‘p_enc_pkg’
    and ‘p_enc_sub’

These are not required when p_check is set. p_check is a code inlined
right into config that does whole job of checking password user
entered against the hash.

I need add this check to RT_SiteConfig.pm: ??

Yes.

p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},

then RT_SiteConfig.pm looks like:

The Perl package & subroutine used to encrypt passwords

e.g. if the passwords are stored using the MySQL v3.23 “PASSWORD”

function, then you will need Crypt::MySQL::password, but for the

MySQL4+ password function you will need Crypt::MySQL::password41

Alternatively, you could use Digest::MD5::md5_hex or any other

encryption subroutine you can load in your perl installation

‘p_enc_pkg’ => ‘Authen::Passphrase’, (???)
‘p_enc_sub’ => ‘$P$’, (???)
p_check => sub {
my ($hash, $pass) = @_;
use Authen::Passphrase;
return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);
},
#‘p_enc_pkg’ => ‘Crypt::MySQL’,
#‘p_enc_sub’ => ‘password41’,

If your p_enc_sub takes a salt as a second parameter,

uncomment this line to add your salt

#‘p_salt’ => ‘SALT’,

If i mix/miss something please correct me.

Leave p_check and options that control how to find user in the DB,
drop p_salt and p_enc_* options.

Best Regards
Adrian


Best regards, Ruslan.

Pozdrawiam
Adrian Stelmaszyk

Hi Ruslan,

[snip]

In log I can see:

p_check for My_MySQL failed: unrecognised crypt scheme $H$ at
/opt/rt4/etc/RT_SiteConfig.pm line 154

Looks like it works.

This is the line:

154 return Authen::Passphrase->from_crypt($hash || ‘*’)->match($pass);

I’m not sure if I put this p_check i right place, or I miss some ‘’ ?

Everything in its right place. However, according to
Portable PHP password hashing ("password encryption") framework smart people in phpBB3 team changed
$P$ to $H$ without changing meaning, so you need to oversmart them.
Put the following line right before line 154 (return Authen…):

$hash =~ s/^$H$/$P$/;

That will replace $H$ in the beginning with $P$ and Authen::Passphrase
should find proper module.

Best regards, Ruslan.