# HG changeset patch # User Heiko Schlittermann (JUMPER) # Date 1312121424 -7200 # Node ID b8f8ec90c296ea3146703ed4e9cfc8fe6f6d7f14 # Parent f361d688365c82a848486406c94f6a5ee42cd2da# Parent 31906810aafb8f492db522b13ca87f25d3a508af [merged] diff -r f361d688365c -r b8f8ec90c296 bin/imager.check --- a/bin/imager.check Fri Jul 29 16:06:55 2011 +0200 +++ b/bin/imager.check Sun Jul 31 16:10:24 2011 +0200 @@ -133,11 +133,16 @@ # we don't need uncompressed files if an compressed version # exists unlink $_ and return if -f "$_.gz"; + unlink "$_.x" and return if -f "$_.x.gz"; + + # the next step we can't do, because it can happen that + # the restorer does not know about a password + #unlink "$_.gz.x" and return if -f "$_.gz"; # cut away the first part of the filename and # some optional extension (my $rn = $File::Find::name) =~ s/^$dir\/data\/(.*?)(?:\..+)?$/$1/; - exists $block{$rn} and return; + return if exists $block{$rn}; push @unused, abs_path $File::Find::name; return; @@ -201,7 +206,10 @@ next if -f "$dir/data/$k" - or -f "$dir/data/$k.gz"; + or -f "$dir/data/$k.gz" + or -f "$dir/data/$k.x" + or -f "$dir/data/$k.x.gz" + or -f "$dir/data/$k.gz.x"; say "missing $k @$i"; @invalid{@$i} = (); } diff -r f361d688365c -r b8f8ec90c296 bin/imager.restore --- a/bin/imager.restore Fri Jul 29 16:06:55 2011 +0200 +++ b/bin/imager.restore Sun Jul 31 16:10:24 2011 +0200 @@ -1,11 +1,12 @@ #! /usr/bin/perl # Eigentlich geht das selbe mit: # grep '^[[:space:]]*[[:digit:]]' IDX-file | tr -d | cut -f4 -d' ' | while read f; do -# cat DATA/$f || zcat DATA/$f.gz -# done -# ODER -# perl -ne '/^\s*\d/ and print "DATA/" . (split)[2] . "\n"' IDX-File | while read f; do -# cat DATA/$f || zcat DATA/$f.gz +# if test -f DATA/$f then cat $f +# elif test -f DATA/$f.gz then zcat DATA/$f.gz +# elif test -f DATA/$f.x then openssl aes-128-cbc -d -in DATA/$f.x +# elif test -f DATA/$f.gz.x then openssl aes-128-cbc -d -in DATA/$f.gz.x | zcat +# elif test -f DATA/$f.x.gz then zcat DATA/$f.x.gz | openssl aes-128-cbs -d +# fi # done use 5.010; @@ -16,12 +17,17 @@ use autodie qw(:all); use Pod::Usage; use Getopt::Long; +use Hash::Util qw(lock_keys); use IO::Uncompress::Gunzip qw(gunzip $GunzipError); use constant KiB => 1024; use constant MiB => 1024 * KiB; use constant GiB => 1024 * MiB; use constant ME => basename $0; +use constant CIPHER => "aes-128-cbc"; + +my %o = (pass => "stdin"); +lock_keys(%o); sub find_data_dir; @@ -29,8 +35,9 @@ Getopt::Long::Configure(qw(Bundling)); GetOptions( - "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) }, - "m|man" => sub { + "p|pass=s" => \$o{pass}, + "h|help" => sub { pod2usage(-verbose => 1, -exit => 0) }, + "m|man" => sub { pod2usage( -verbose => 2, -exit => 0, @@ -66,7 +73,7 @@ if (-f "$data/$path") { open($in => "$data/$path"); binmode($in); - local $/ = \$blocksize; + local $/ = undef; $buffer = <$in>; } elsif (-f "$data/$path.gz") { @@ -75,6 +82,26 @@ gunzip($in => \$buffer) or die $GunzipError; } + elsif (-f "$data/$path.x") { + open($in, "openssl @{[CIPHER]} -d -pass $o{pass} -in '$data/$path.x'|"); + binmode($in); + local $/ = undef; + $buffer = <$in>; + } + elsif (-f "$data/$path.gz.x") { + open($in, "openssl @{[CIPHER]} -d -pass $o{pass} -in $data/$path.gz.x|"); + binmode($in); + gunzip($in => \$buffer) + or die $GunzipError; + } + elsif (-f "$data/$path.x.gz") { + warn "$data/$path.x.gz: depreciated!\n"; + open($in, + "gzip -d -c $data/$path.x.gz | openssl @{[CIPHER]} -d -pass $o{pass}|"); + binmode($in); + local $/ = undef; + $buffer = <$in>; + } else { die ME . ": Can't open $data/$path: $!\n"; } @@ -100,7 +127,7 @@ =head1 SYNOPSIS - imager.restore {idx} {destination} + imager.restore [options] {idx} {destination} =head1 DESCRIPTION @@ -108,5 +135,22 @@ cats them as one data stream. The destination can be any block device, a file name or even B<-> (STDOUT). +=head1 OPTIONS + +=over + +=item B<-p> I | B<--pass=>I + +In case you expect encrypted data, this option takes the argument for +B's C<-pass> option. See L for mor information. +(default: stdin) + +=item B<-h>|B<--help> + +=item B<-m>|B<--man> + +The standard help options. + +=back =cut diff -r f361d688365c -r b8f8ec90c296 bin/imager.save --- a/bin/imager.save Fri Jul 29 16:06:55 2011 +0200 +++ b/bin/imager.save Sun Jul 31 16:10:24 2011 +0200 @@ -20,6 +20,7 @@ use constant GiB => 1024 * MiB; use constant NOW => time(); use constant DATETIME => strftime("%Y-%m-%dT%H:%M:%SZ" => gmtime(NOW)); +use constant CIPHER => "aes-128-cbc"; sub get_devsize; sub get_devname; @@ -31,6 +32,7 @@ compress => undef, verbose => undef, blocksize => 4 * MiB, + pass => undef, ); lock_keys(%o); @@ -47,6 +49,7 @@ ); }, "z|compress:i" => sub { $o{compress} = $_[1] ? $_[1] : Z_BEST_SPEED }, + "p|pass=s" => \$o{pass}, "b|blocksize=s" => sub { given ($_[1]) { when (/(\d+)G/i) { $o{blocksize} = $1 * GiB }; @@ -137,17 +140,27 @@ my ($file, $ext, $cs); $file = $cs = md5_hex($buffer); $file =~ s/(?(?...).*)/$+{prefix}\/$+{fn}/g; - $ext = $o{compress} ? ".gz" : ""; + $ext = ""; + $ext .= $o{compress} ? ".gz" : ""; + $ext .= $o{pass} ? ".x" : ""; # the extension we do not put into the index my $log = sprintf "%12d %s %s" => ($. - 1), $cs, $file; - if (not(-e "$data/$file" or -e "$data/$file.gz")) { - mkpath dirname("$data/$file.gz"); - my $out = File::Temp->new( + if (not(-e "$data/$file" + or -e "$data/$file.gz" + or -e "$data/$file.x" + or -e "$data/$file.gz.x" + or -e "$data/$file.x.gz")) { + mkpath dirname("$data/$file"); + my $out = File::Temp->new( TEMPLATE => ".XXXXXXX", DIR => dirname("$data/$file") ); + + if ($o{pass}) { + open($out, "|openssl @{[CIPHER]} -pass $o{pass} -out $out"); + } binmode($out); if ($o{compress}) { gzip( @@ -227,14 +240,19 @@ =over +=item B<-b> I | B<--blocksize>=I + +The blocksize used. (may be suffixed with K, M, G). (default: 4 MiB) + +=item B<-p> I | B<--pass>=I + +Use symmetric encryption for writing the data blocks. This option +is passed to L. + =item B<-z> [I]|B<--compress>[=I] Use compression when writing the blocks to disk. (default: off) -=item B<-b> I|B<--blocksize>=I - -The blocksize used. (may be suffixed with K, M, G). (default: 4 MiB) - =item B<-h>|B<--help> =item B<-m>|B<--man> @@ -243,4 +261,12 @@ =back +=head1 PERFORMANCE + +Some experiments have shown that if compression and encryption is used, +about 1/3 of the time is consumed by the encryption, and 2/3 are used +for compression. The compression is done before(!) encrypting the file, +since otherwise there is almost no benefit in compressing an encrypted +file! + =cut diff -r f361d688365c -r b8f8ec90c296 scratch/x.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scratch/x.pl Sun Jul 31 16:10:24 2011 +0200 @@ -0,0 +1,61 @@ +#!/usr/bin/perl +use 5.010; +use strict; +use warnings; +use Crypt::CBC; +use autodie qw(:all); +use Benchmark qw(:all); +use IO::Compress::Gzip qw(gzip $GzipError); +use File::Temp; + +my $tmp = File::Temp->new(); +warn "<< $tmp >>\n"; + +my $cipher0 = Crypt::CBC->new( + -key => "x", + -keysize => 16, + -cipher => 'Blowfish', +) or die; +$ENV{X} = "x"; + +@ARGV = qw(/boot/vmlinuz-2.6.32-5-amd64); +my $text = join "" => <>; + +say length $text; + +cmpthese(30 => { + 'openssl' => sub { openssl($text) }, + 'perlssl' => sub { perlssl($text) }, + } +); + +cmpthese(30 => { + 'gzip' => sub { bingzip($text) }, + 'perlzip' => sub { perlzip($text) }, + } +); + +sub openssl { + open(my $out, "|openssl bf -pass env:X -out $tmp") or die; + print $out $_[0]; + close $out; + die $? if $?; +} + +sub perlssl { + open(my $out, ">$tmp"); + print $out $cipher0->encrypt($_[0]); + close $out; +} + +sub perlzip { + open(my $out, ">$tmp"); + gzip($_[0] => $out); +} + +sub bingzip { + open(my $out, "|gzip -1 >$tmp"); + print $out $_[0]; + close $out; + die $? if $? +}