[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
exor674.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=4084
Add secret generating/documentation framework
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
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"; --------------------------------------------------------------------------------