[rt-users] RT::Authen::ExternalAuth with PHPass (phpbb3);

Adrian Stel adisan82 at gmail.com
Thu Nov 17 04:49:01 EST 2011


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
Adrian


2011/11/16 Ruslan Zakirov <ruz at 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] https://github.com/bestpractical/rt-authen-externalauth/commit/22ba2bfa8d59a00354712e63daaa5d622e39cf4d
> [2] http://search.cpan.org/~zefram/Authen-Passphrase-0.007/lib/Authen/Passphrase.pm#CONSTRUCTORS
>
> On Wed, Nov 16, 2011 at 4:27 PM, Adrian Stel <adisan82 at 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 at 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 at 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 at 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



More information about the rt-users mailing list