mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2012-04-29 07:11 am

[dw-free] Tools to manage %LJ::SECRETS

[commit: http://hg.dwscoalition.org/dw-free/rev/dd765fec7dac]

http://bugs.dwscoalition.org/show_bug.cgi?id=4084

Add secret generating/documentation framework

Patch by [personal profile] exor674.

Files modified:
  • bin/checkconfig.pl
  • bin/upgrading/gen-secrets.pl
  • cgi-bin/LJ/Global/Defaults.pm
  • cgi-bin/LJ/Global/Secrets.pm
  • cgi-bin/ljlib.pl
--------------------------------------------------------------------------------
diff -r acb4c85567e3 -r dd765fec7dac bin/checkconfig.pl
--- a/bin/checkconfig.pl	Sun Apr 29 00:18:57 2012 +0000
+++ b/bin/checkconfig.pl	Sun Apr 29 07:12:05 2012 +0000
@@ -27,6 +27,7 @@
     "modules",
     "env",
     "database",
+    "secrets",
 );
 foreach my $check (@checks) { $dochecks{$check} = 1; }
 
@@ -51,6 +52,7 @@
 if ($debs_only) {
     $dochecks{database} = 0;
     $dochecks{timezone} = 0;
+    $dochecks{secrets} = 0;
 }
 
 usage() if $only_check && $no_check;
@@ -379,3 +381,40 @@
     $err->( "Timezone must be UTC." ) unless $timezone->is_utc;
 }
 
+sub check_secrets {
+    print "[Checking Secrets...]\n";
+
+    foreach my $secret ( keys %LJ::Secrets::secret ) {
+        my $def = $LJ::Secrets::secret{$secret};
+        my $req_len = exists $def->{len} || exists $def->{min_len} || exists $def->{max_len};
+        my $rec_len = exists $def->{rec_len} || exists $def->{rec_min_len} || exists $def->{rec_max_len};
+
+        my $req_min = $def->{len} || $def->{min_len} || 0;
+        my $req_max = $def->{len} || $def->{max_len} || 0;
+
+        my $rec_min = $def->{rec_len} || $def->{rec_min_len} || 0;
+        my $rec_max = $def->{rec_len} || $def->{rec_max_len} || 0;
+        my $val = $LJ::SECRETS{$secret} || '';
+        my $len = length( $val );
+
+        if ( ! defined( $LJ::SECRETS{$secret} ) || ! $LJ::SECRETS{$secret} ) {
+            if ( $def->{required} ) {
+                $err->( "Missing requred secret '$secret': $def->{desc}" );
+            } else {
+                print STDERR "Missing optional secret '$secret': $def->{desc}\n";
+            }
+        } elsif ( $req_len && ( $len < $req_min || $len > $req_max ) ) {
+            if ( $req_min == $req_max ) {
+                $err->( "Secret '$secret' not of required length: is $len, must be $req_min" );
+            } else {
+                $err->( "Secret '$secret' not of required length: is $len, must be between $req_min and $req_max" );
+            }
+        } elsif ( $rec_len && ( $len < $rec_min || $len > $rec_max ) ) {
+            if ( $rec_min == $rec_max ) {
+                print STDERR "Secret '$secret' not of recommended length: is $len, should be $rec_min\n";
+            } else {
+                print STDERR "Secret '$secret' not of recommended length: is $len, should be between $rec_min and $rec_max\n";
+            }
+        }
+    }
+}
diff -r acb4c85567e3 -r dd765fec7dac bin/upgrading/gen-secrets.pl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/upgrading/gen-secrets.pl	Sun Apr 29 07:12:05 2012 +0000
@@ -0,0 +1,107 @@
+#!/usr/bin/perl
+#
+# bin/upgrading/gen-secrets.pl
+#
+# This script can generate items for %LJ::SECRETS
+#
+# Authors:
+#      Andrea Nall <anall@andreanall.com>
+#
+# Copyright (c) 2011 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself.  For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+use strict;
+use lib "$ENV{LJHOME}/cgi-bin";
+use Getopt::Long;
+use POSIX;
+use Data::Dumper;
+
+BEGIN { require "ljlib.pl"; }
+
+my $tv = system('openssl version >/dev/null 2>/dev/null');
+die "OpenSSL command line not found" if $tv;
+
+sub usage {
+    die "Usage: gen-secrets.pl BLAH";
+}
+
+my $regen = 0;
+my $no_rec= 0;
+
+usage() unless GetOptions(
+                          'regen'       => \$regen,
+                          'required'    => \$no_rec,
+                          );
+
+my %sec_use;
+%sec_use = %LJ::SECRETS unless $regen;
+
+my %sec_out;
+
+foreach my $secret ( sort keys %LJ::Secrets::secret ) {
+    my $def = $LJ::Secrets::secret{$secret};
+
+    next if defined $sec_use{$secret} && $sec_use{$secret};
+    next if $no_rec && ! $def->{required};
+
+    if ( $def->{max_len} && $def->{min_len} && $def->{max_len} < $def->{min_len} ) {
+        warn "Invalid required length specifications ( max < min ) for '$secret'.\n";
+        next;
+    }
+
+    if ( $def->{rec_max_len} && $def->{rec_min_len} && $def->{rec_max_len} < $def->{rec_min_len} ) {
+        warn "Invalid recommended length specifications ( max < min ) for '$secret'.\n";
+        next;
+    }
+
+    my $req_len = $def->{len} || $def->{max_len} || $def->{min_len};
+    my $len = $req_len || $def->{rec_len} || $def->{rec_max_len} || $def->{rec_min_len};
+
+    if ( $len < 0 ) {
+        warn "Length for '$secret' is less then 0";
+        next;
+    }
+
+    my $gen_len = ceil( $len / 2 );
+    my $data = substr( `openssl rand -hex $gen_len`, 0, $len );
+    chomp $data;
+    die "Unable to get $len bytes of data from OpenSSL\n"
+        if length($data) < $len;
+
+    $sec_out{$secret} = $data;
+}
+
+unless ( %sec_out ) {
+    print "Your secrets are up to date.\n";
+    exit;
+}
+
+if ( ! %LJ::SECRETS ) {
+    print "\nPlease add the following section to your etc/config-private.pl file,\n";
+    print "inside the LJ package:\n\n";
+    print "%LJ::SECRETS = (\n";
+} else {
+    print "\nPlease add or replace the following sections in LJ::SECRETS in your config\n";
+    print "file (probably etc/config-private.pl):\n\n";
+}
+
+foreach my $secret ( sort keys %sec_out ) {
+    my $value = $sec_out{$secret};
+    # FIXME: There has to be a better way to do this.
+    $value =~ s/\\/\\\\/g;
+    $value =~ s/'/\\'/g;
+
+    if ( $secret =~ m/^[a-zA-Z0-9_]+$/ ) {
+        print "    $secret => '$value',\n";
+    } else {
+        $secret =~ s/\\/\\\\/g;
+        $secret =~ s/'/\\'/g;
+        print "    '$secret' => '$value',\n";
+    }
+}
+
+print ");\n" unless %LJ::SECRETS;
+print "\n";
diff -r acb4c85567e3 -r dd765fec7dac cgi-bin/LJ/Global/Defaults.pm
--- a/cgi-bin/LJ/Global/Defaults.pm	Sun Apr 29 00:18:57 2012 +0000
+++ b/cgi-bin/LJ/Global/Defaults.pm	Sun Apr 29 07:12:05 2012 +0000
@@ -369,6 +369,8 @@
     # default location of community posting guidelines
     $DEFAULT_POSTING_GUIDELINES_LOC ||= "N";
 
+    # Secrets
+    %SECRETS = () unless defined %SECRETS;
 }
 
 
diff -r acb4c85567e3 -r dd765fec7dac cgi-bin/LJ/Global/Secrets.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/LJ/Global/Secrets.pm	Sun Apr 29 07:12:05 2012 +0000
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+#
+# LJ::Global::Secrets
+#
+# This module provides a list of definitions for
+# items in %LJ::SECRETS
+#
+# Authors:
+#      Andrea Nall <anall@andreanall.com>
+#
+# Copyright (c) 2011 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself.  For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+use strict;
+package LJ::Secrets;
+our %secret;
+
+# Potential flags
+#   desc -- english description, only showed in internal tools
+#   required -- requred for basic site operation, v.s. additional features
+#
+#   rec_len -- recommended length, implies rec_min_len/rec_max_len
+#   rec_min_len -- recommended minumum length
+#   rec_max_len -- recommended maximum length
+#
+#   len -- required len, implies min_len/max_len
+#   min_len -- required minimim length
+#   max_len -- required maximum length
+
+$secret{invite_img_auth} = {
+    desc => "Auth code for invite code status images",
+    rec_len => 64,
+};
diff -r acb4c85567e3 -r dd765fec7dac cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Sun Apr 29 00:18:57 2012 +0000
+++ b/cgi-bin/ljlib.pl	Sun Apr 29 07:12:05 2012 +0000
@@ -108,6 +108,7 @@
 use LJ::Capabilities;
 use DW::Mood;
 use LJ::Global::Img;  # defines LJ::Img
+use LJ::Global::Secrets;  # defines LJ::Secrets
 
 require "$LJ::HOME/cgi-bin/ljlib-local.pl"
     if -e "$LJ::HOME/cgi-bin/ljlib-local.pl";
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org