option to limit the set of characters in random passwords, #40792
authorMark Wells <mark@freeside.biz>
Tue, 8 Mar 2016 21:23:35 +0000 (13:23 -0800)
committerMark Wells <mark@freeside.biz>
Tue, 8 Mar 2016 21:23:52 +0000 (13:23 -0800)
FS/FS/Conf.pm
FS/FS/Password_Mixin.pm
FS/FS/Upgrade.pm
FS/FS/part_export/broadband_sqlradius.pm
FS/FS/svc_acct.pm
FS/FS/svc_phone.pm
conf/password-generated-characters [new file with mode: 0644]
httemplate/elements/random_pass.html

index d5e0fa6..72b449c 100644 (file)
@@ -4043,10 +4043,10 @@ and customer address. Include units.',
   },
 
   {
-    'key'         => 'password-generated-allcaps',
+    'key'         => 'password-generated-characters',
     'section'     => 'password',
-    'description' => 'Causes passwords automatically generated to consist entirely of capital letters',
-    'type'        => 'checkbox',
+    'description' => 'Set of characters to use when generating random passwords. This must contain at least one lowercase letter, uppercase letter, digit, and punctuation mark.',
+    'type'        => 'textarea',
   },
 
 #  {
index ac7ba50..633265b 100644 (file)
@@ -14,6 +14,8 @@ FS::UID->install_callback( sub {
   $conf = FS::Conf->new;
 });
 
+our @pw_set;
+
 our $me = '[' . __PACKAGE__ . ']';
 
 our $BLOWFISH_COST = 10;
@@ -254,6 +256,36 @@ sub _blowfishcrypt {
 
 =back
 
+=head1 CLASS METHODS
+
+=over 4
+
+=item pw_set
+
+Returns the list of characters allowed in random passwords (from the
+C<password-generated-characters> config).
+
+=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;
+}
+
+=back
+
 =head1 SEE ALSO
 
 L<FS::password_history>
index 0ac7a4e..1f38310 100644 (file)
@@ -165,6 +165,12 @@ If you need to continue using the old Form 477 report, turn on the
     $conf->delete('voip-cust_email_csv_cdr') ;
   }
 
+  if ( !$conf->config('password-generated-characters') ) {
+    my $pw_set = 
+      'abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789()#.,' ;
+    $conf->set('password-generated-characters', $pw_set);
+  }
+
   enable_banned_pay_pad() unless length($conf->config('banned_pay-pad'));
 
 }
index 522c637..e58c641 100644 (file)
@@ -6,16 +6,20 @@ use Tie::IxHash;
 use FS::Conf;
 use FS::Record qw( dbh str2time_sql ); #qsearch qsearchs );
 use FS::part_export::sqlradius qw(sqlradius_connect);
+use FS::Password_Mixin;
 use NEXT;
 
-FS::UID->install_callback(sub { $conf = new FS::Conf });
+FS::UID->install_callback(
+  sub {
+    $conf = new FS::Conf;
+    @pw_set = FS::Password_Mixin->pw_set;
+  }
+);
 
 @ISA = qw(FS::part_export::sqlradius);
 
 $DEBUG = 0;
 
-@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '.', ',' );
-
 tie %options, 'Tie::IxHash',
   'datasrc'  => { label=>'DBI data source ' },
   'username' => { label=>'Database username' },
index 8283e6f..b4db082 100644 (file)
@@ -93,12 +93,11 @@ FS::UID->install_callback( sub {
   $smtpmachine = $conf->config('smtpmachine');
   $radius_password = $conf->config('radius-password') || 'Password';
   $radius_ip = $conf->config('radius-ip') || 'Framed-IP-Address';
-  @pw_set = ( 'A'..'Z' ) if $conf->exists('password-generated-allcaps');
+  @pw_set = FS::svc_acct->pw_set;
 }
 );
 
 @saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
-@pw_set = ( 'a'..'z', 'A'..'Z', '0'..'9', '(', ')', '#', '.', ',' );
 
 sub _cache {
   my $self = shift;
index f2be7d3..2b2db8c 100644 (file)
@@ -16,6 +16,7 @@ use FS::Conf;
 use FS::Record qw( qsearch qsearchs dbh );
 use FS::PagedSearch qw( psearch );
 use FS::Msgcat qw(gettext);
+use FS::Password_Mixin; # for pw_set
 use FS::part_svc;
 use FS::svc_pbx;
 use FS::svc_domain;
@@ -25,15 +26,13 @@ use FS::phone_avail;
 $me = '[' . __PACKAGE__ . ']';
 $DEBUG = 0;
 
-#avoid l 1 and o O 0
-@pw_set = ( 'a'..'k', 'm','n', 'p-z', 'A'..'N', 'P'..'Z' , '2'..'9' );
-
 #ask FS::UID to run this stuff for us later
 FS::UID->install_callback( sub { 
   $conf = new FS::Conf;
   $phone_name_max = $conf->config('svc_phone-phone_name-max_length');
   $passwordmin = $conf->config('sip_passwordmin') || 0;
   $passwordmax = $conf->config('sip_passwordmax') || 80;
+  @pw_set = FS::Password_Mixin->pw_set;
 }
 );
 
diff --git a/conf/password-generated-characters b/conf/password-generated-characters
new file mode 100644 (file)
index 0000000..57aa935
--- /dev/null
@@ -0,0 +1 @@
+abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789()#.,
index 14bbb58..1517a55 100644 (file)
@@ -1,16 +1,16 @@
 <INPUT TYPE="button" VALUE="<% emt($label) %>" onclick="randomPass()">
 <SCRIPT TYPE="text/javascript">
 function randomPass() {
-  var lower='<% join('', 'a'..'z') %>';
-  var upper='<% join('', 'A'..'Z') %>';
-  var number='<% join('', '0'..'9') %>';
-  var symbol='`~!@#$%^&*-_=+:;<>,.?';
-  var pw_set=lower+upper+number+symbol;
+  var pw_set = <% $pw_set |js_string %>;
+  var lower = <% $lower |js_string %>;
+  var upper = <% $upper |js_string %>;
+  var digit = <% $digit |js_string %>;
+  var punct = <% $punct |js_string %>;
   var pass=[];
   pass.push(lower.charAt(Math.floor(Math.random() * lower.length)));
-  pass.push(upper.charAt(Math.floor(Math.random() * lower.length)));
-  pass.push(number.charAt(Math.floor(Math.random() * number.length)));
-  pass.push(symbol.charAt(Math.floor(Math.random() * symbol.length)));
+  pass.push(upper.charAt(Math.floor(Math.random() * upper.length)));
+  pass.push(digit.charAt(Math.floor(Math.random() * digit.length)));
+  pass.push(punct.charAt(Math.floor(Math.random() * punct.length)));
   var i=0;
   while(i < 4) {
     i++;
@@ -24,4 +24,10 @@ function randomPass() {
 <%init>
 my $id = shift;
 my $label = shift || 'Generate';
+my $pw_set = join('', FS::Password_Mixin->pw_set);
+my $lower = join('', $pw_set =~ /[[:lower:]]/g);
+my $upper = join('', $pw_set =~ /[[:upper:]]/g);
+my $digit = join('', $pw_set =~ /[[:digit:]]/g);
+my $punct = join('', $pw_set =~ /[[:punct:]]/g);
+
 </%init>