From: Mark Wells Date: Thu, 19 Nov 2015 22:52:42 +0000 (-0800) Subject: password policy enforcement for contacts, #32456 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=25d96215a7bfd0c4af5323ee658eed7675cf2ee0 password policy enforcement for contacts, #32456 --- diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 9bbde882b..8ab14fce9 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -2964,6 +2964,8 @@ sub myaccount_passwd { my $contact = FS::contact->by_selfservice_email($svc_acct->email); if ( $contact && $contact->custnum == $custnum ) { #svc_acct was successful but this one returns an error? "shouldn't happen" + #don't recheck is_password_allowed here; if the svc_acct password was + #legal, that's good enough $error ||= $contact->change_password($p->{'new_password'}); } @@ -3235,7 +3237,8 @@ sub process_reset_passwd { if ( $contact ) { - my $error = $contact->change_password($p->{'new_password'}); + my $error = $contact->is_password_allowed($p->{'new_password'}) + || $contact->change_password($p->{'new_password'}); return { %$info, 'error' => $error }; # if $error; diff --git a/FS/FS/ClientAPI/MyAccount/contact.pm b/FS/FS/ClientAPI/MyAccount/contact.pm index 009658d07..d78c234fe 100644 --- a/FS/FS/ClientAPI/MyAccount/contact.pm +++ b/FS/FS/ClientAPI/MyAccount/contact.pm @@ -32,6 +32,8 @@ sub contact_passwd { $error = 'Password too long.' if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8); + $error ||= $contact->is_password_allowed($p->{'new_password'}); + $error ||= $contact->change_password($p->{'new_password'}); return { 'error' => $error }; diff --git a/FS/FS/Password_Mixin.pm b/FS/FS/Password_Mixin.pm index c4549c727..9d5421bfa 100644 --- a/FS/FS/Password_Mixin.pm +++ b/FS/FS/Password_Mixin.pm @@ -105,7 +105,16 @@ sub insert_password_history { my $password = $self->_password; my $auth; - if ( $encoding eq 'bcrypt' or $encoding eq 'crypt' ) { + if ( $encoding eq 'bcrypt' ) { + # our format, used for contact and access_user passwords + my ($cost, $salt, $hash) = split(',', $password); + $auth = Authen::Passphrase::BlowfishCrypt->new( + cost => $cost, + salt_base64 => $salt, + hash_base64 => $hash, + ); + + } elsif ( $encoding eq 'crypt' ) { # it's smart enough to figure this out $auth = Authen::Passphrase->from_crypt($password); diff --git a/FS/FS/contact.pm b/FS/FS/contact.pm index 96632ff49..d906dc9a2 100644 --- a/FS/FS/contact.pm +++ b/FS/FS/contact.pm @@ -1,5 +1,6 @@ package FS::contact; -use base qw( FS::Record ); +use base qw( FS::Password_Mixin + FS::Record ); use strict; use vars qw( $skip_fuzzyfiles ); @@ -129,6 +130,8 @@ sub insert { my $dbh = dbh; my $error = $self->SUPER::insert; + $error ||= $self->insert_password_history; + if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -268,6 +271,9 @@ sub replace { my $dbh = dbh; my $error = $self->SUPER::replace($old); + if ( $old->_password ne $self->_password ) { + $error ||= $self->insert_password_history; + } if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -607,9 +613,22 @@ sub authenticate_password { } +=item change_password NEW_PASSWORD + +Changes the contact's selfservice access password to NEW_PASSWORD. This does +not check password policy rules (see C) and will return +an error only if editing the record fails for some reason. + +If NEW_PASSWORD is the same as the existing password, this does nothing. + +=cut + sub change_password { my($self, $new_password) = @_; + # do nothing if the password is unchanged + return if $self->authenticate_password($new_password); + $self->change_password_fields( $new_password ); $self->replace;