eliminate some false laziness in FS::Misc::send_email vs. msg_template/email.pm send_...
[freeside.git] / FS / FS / Password_Mixin.pm
index 633265b..b29cf57 100644 (file)
@@ -14,8 +14,6 @@ FS::UID->install_callback( sub {
   $conf = FS::Conf->new;
 });
 
-our @pw_set;
-
 our $me = '[' . __PACKAGE__ . ']';
 
 our $BLOWFISH_COST = 10;
@@ -47,8 +45,8 @@ sub is_password_allowed {
 
   # basic checks using Data::Password;
   # options for Data::Password
-  $DICTIONARY = 4;   # minimum length of disallowed words
-  $MINLEN = $conf->config('passwordmin') || 6;
+  $DICTIONARY = 0;   # minimum length of disallowed words, false value disables dictionary checking
+  $MINLEN = $conf->config('passwordmin') || 8;
   $MAXLEN = $conf->config('passwordmax') || 12;
   $GROUPS = 4;       # must have all 4 'character groups': numbers, symbols, uppercase, lowercase
   # other options use the defaults listed below:
@@ -57,9 +55,23 @@ sub is_password_allowed {
   # # lists of disallowed words
   # @DICTIONARIES = qw( /usr/share/dict/web2 /usr/share/dict/words /usr/share/dict/linux.words );
 
+  # first, no dictionary checking but require 4 char groups
   my $error = IsBadPassword($password);
-  $error = 'must contain at least one each of numbers, symbols, and lowercase and uppercase letters'
-    if $error eq 'contains less than 4 character groups'; # avoid confusion
+
+  # but they can get away with 3 char groups, so long as they're not using a word
+  if ($error eq 'contains less than 4 character groups') {
+    $DICTIONARY = 4; # default from Data::Password is 5
+    $GROUPS = 3;
+    $error = IsBadPassword($password);
+    # take note--we never actually report dictionary word errors;
+    # 4 char groups is the rule, 3 char groups and no dictionary words is an acceptable exception
+    $error = 'should contain at least one each of numbers, symbols, lowercase and uppercase letters'
+      if $error;
+  }
+
+  # maybe also at some point add an exception for any passwords of sufficient length,
+  # see https://xkcd.com/936/
+
   $error = 'Invalid password - ' . $error if $error;
   return $error if $error;
 
@@ -70,7 +82,9 @@ sub is_password_allowed {
   return '' unless $self->get($self->primary_key); # for validating new passwords pre-insert
 
   #check against customer fields
-  my $cust_main = $self->cust_main;
+  my $cust_main = $self->table eq 'access_user'
+                    ? $self->user_cust_main
+                    : $self->cust_main;
   if ($cust_main) {
     my @words;
     # words from cust_main
@@ -262,26 +276,19 @@ sub _blowfishcrypt {
 
 =item pw_set
 
-Returns the list of characters allowed in random passwords (from the
-C<password-generated-characters> config).
+Returns the list of characters allowed in random passwords. This is now
+hardcoded.
 
 =cut
 
 sub pw_set {
-  my $class = shift;
-  if (!@pw_set) {
-    my $pw_set = $conf->config('password-generated-characters');
-    $pw_set =~ s/\s//g; # don't ever allow whitespace
-    if ( $pw_set =~ /[[:lower:]]/
-      && $pw_set =~ /[[:upper:]]/
-      && $pw_set =~ /[[:digit:]]/
-      && $pw_set =~ /[[:punct:]]/ ) {
-      @pw_set = split('', $pw_set);
-    }
-    warn "password-generated-characters set is insufficient; using default.";
-    @pw_set = split('', 'abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789()#.,');
-  }
-  return @pw_set;
+
+  # ASCII alphabet, minus easily confused stuff (l, o, O, 0, 1)
+  # and plus some "safe" punctuation
+  split('',
+    'abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789#.,[]-_=+'
+  );
+
 }
 
 =back