Ignore:
Timestamp:
04/24/16 13:59:54 (8 years ago)
Author:
nanardon
Message:

bannedPassword feature (denied password for a user)

Location:
trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/User.pm

    r1751 r1752  
    12201220                label => l('Password set'), 
    12211221            }, 
     1222            oldPassword => { 
     1223                multiple => 1, 
     1224            }, 
     1225            bannedPassword => { 
     1226                multiple => 1, 
     1227            }, 
    12221228            currentEmployment => { 
    12231229                managed => 1, 
     
    15991605} 
    16001606 
     1607=head2 storeBannedPassword($epassword) 
     1608 
     1609Add an encrypted password to untrust list 
     1610 
     1611=cut 
     1612 
     1613sub storeBannedPassword { 
     1614    my ($self, $EncPass) = @_; 
     1615 
     1616    my @banned = sort { $b cmp $a } $self->_get_attributes('bannedPassword'); 
     1617    my $now = DateTime->now;  
     1618    unshift(@banned, $now->iso8601 . ';' . $EncPass); 
     1619    $self->set_fields('bannedPassword', [ grep { $_ } @banned ]); 
     1620 
     1621} 
     1622 
     1623=head2 banCurrentPassword 
     1624 
     1625Store the current password as banned 
     1626 
     1627=cut 
     1628 
     1629sub banCurrentPassword { 
     1630    my ($self) = @_; 
     1631     
     1632    my $old = $self->get_field('userPassword') or return; 
     1633    $self->storeBannedPassword($old); 
     1634} 
     1635 
     1636sub check_password { 
     1637    my ( $self, $password ) = @_; 
     1638 
     1639    if (my $res = $self->SUPER::check_password($password)) { 
     1640        return $res; 
     1641    } 
     1642 
     1643    foreach my $banned ($self->_get_attributes('bannedPassword')) { 
     1644        my ($date, $oldPassword) = $banned =~ /^([^;]*);(.*)/; 
     1645        warn $password; 
     1646        if (crypt($oldPassword, $password) eq $password) { 
     1647            return "Banned password, cannot be used anymore"; 
     1648        } 
     1649    } 
     1650 
     1651    return; 
     1652} 
     1653 
     1654sub _set_password { 
     1655    my ($self, $clear_pass) = @_; 
     1656    if (my $attr = $self->base->attribute($self->type, 'userPassword')) { 
     1657        my $field = $attr->iname; 
     1658 
     1659        # Storing as old password 
     1660        my @olds = sort { $b cmp $a } $self->_get_attributes('oldPassword'); 
     1661        my $old = $self->get_field('userPassword'); 
     1662        my $now = DateTime->now;  
     1663        unshift(@olds, $now->iso8601 . ';' . $old); 
     1664        $self->set_fields('oldPassword', [ grep { $_ } @olds[0 .. 14] ]); 
     1665 
     1666        my @salt_char = (('a' .. 'z'), ('A' .. 'Z'), (0 .. 9), '/', '.'); 
     1667        my $salt = join('', map { $salt_char[rand(scalar(@salt_char))] } (1 .. 8)); 
     1668        my $res = $self->set_fields($field, crypt($clear_pass, '$1$' . $salt)); 
     1669        if ($res) { 
     1670            if ($self->base->get_global_value('rsa_public_key')) { 
     1671                $self->setCryptPassword($clear_pass) or return; 
     1672            } 
     1673        } 
     1674 
     1675        $self->set_fields('passwordLastSet', DateTime->now->datetime); 
     1676        $self->base->log(LA_NOTICE, 
     1677            'Mot de passe changé pour %s', 
     1678            $self->id 
     1679        ); 
     1680 
     1681 
     1682        return $res; 
     1683    } else { 
     1684        $self->log(LA_WARN, 
     1685            "Cannot set password: userPassword attributes is unsupported"); 
     1686    } 
     1687} 
     1688 
     1689=head2 setCryptPassword($clear_pass) 
     1690 
     1691Store password encrypted using RSA encryption. 
     1692 
     1693=cut 
     1694 
     1695sub setCryptPassword { 
     1696    my ($self, $clear_pass) = @_; 
     1697    if (my $serialize = $self->base->get_global_value('rsa_public_key')) { 
     1698        my $public = Crypt::RSA::Key::Public->new; 
     1699        $public = $public->deserialize(String => [ $serialize ]); 
     1700        my $rsa = new Crypt::RSA ES => 'PKCS1v15'; 
     1701        my $rsa_password = $rsa->encrypt ( 
     1702            Message    => $clear_pass, 
     1703            Key        => $public, 
     1704            Armour     => 1, 
     1705        ) || die $rsa->errstr(); 
     1706        if (!$self->_set_c_fields('encryptedPassword', $rsa_password)) { 
     1707            $self->log(LA_ERR, 
     1708                "Cannot set 'encryptedPassword' attribute for object %s/%s", 
     1709                $self->type, $self->id, 
     1710            ); 
     1711            return; 
     1712        } 
     1713    } 
     1714    $self->ReportChange('Password', 'Password stored using internal key'); 
     1715    return 1; 
     1716} 
     1717 
     1718 
    16011719=head2 GenPasswordResetId 
    16021720 
  • trunk/LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm

    r1733 r1752  
    733733} 
    734734 
    735 sub _set_password { 
    736     my ($self, $clear_pass) = @_; 
    737     if (my $attr = $self->base->attribute($self->type, 'userPassword')) { 
    738         my $field = $attr->iname; 
    739         my @salt_char = (('a' .. 'z'), ('A' .. 'Z'), (0 .. 9), '/', '.'); 
    740         my $salt = join('', map { $salt_char[rand(scalar(@salt_char))] } (1 .. 8)); 
    741         my $res = $self->set_fields($field, crypt($clear_pass, '$1$' . $salt)); 
    742         if ($res) { 
    743             if ($self->base->get_global_value('rsa_public_key')) { 
    744                 $self->setCryptPassword($clear_pass) or return; 
    745             } 
    746         } 
    747  
    748         $self->set_fields('passwordLastSet', DateTime->now->datetime); 
    749         $self->base->log(LA_NOTICE, 
    750             'Mot de passe changé pour %s', 
    751             $self->id 
    752         ); 
    753         return $res; 
    754     } else { 
    755         $self->log(LA_WARN, 
    756             "Cannot set password: userPassword attributes is unsupported"); 
    757     } 
    758 } 
    759  
    760 =head2 setCryptPassword($clear_pass) 
    761  
    762 Store password encrypted using RSA encryption. 
    763  
    764 =cut 
    765  
    766 sub setCryptPassword { 
    767     my ($self, $clear_pass) = @_; 
    768     if (my $serialize = $self->base->get_global_value('rsa_public_key')) { 
    769         my $public = Crypt::RSA::Key::Public->new; 
    770         $public = $public->deserialize(String => [ $serialize ]); 
    771         my $rsa = new Crypt::RSA ES => 'PKCS1v15'; 
    772         my $rsa_password = $rsa->encrypt ( 
    773             Message    => $clear_pass, 
    774             Key        => $public, 
    775             Armour     => 1, 
    776         ) || die $rsa->errstr(); 
    777         if (!$self->_set_c_fields('encryptedPassword', $rsa_password)) { 
    778             $self->log(LA_ERR, 
    779                 "Cannot set 'encryptedPassword' attribute for object %s/%s", 
    780                 $self->type, $self->id, 
    781             ); 
    782             return; 
    783         } 
    784     } 
    785     $self->ReportChange('Password', 'Password stored using internal key'); 
    786     return 1; 
    787 } 
    788  
    789  
    790735sub search { 
    791736    my ($class, $base, @filter) = @_; 
Note: See TracChangeset for help on using the changeset viewer.