"Fossies" - the Fresh Open Source Software Archive

Member "encfs-1.9.5/integration/reverse.t.pl" (27 Apr 2018, 8444 Bytes) of package /linux/misc/encfs-1.9.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "reverse.t.pl": 1.9.4_vs_1.9.5.

    1 #!/usr/bin/perl -w
    2 
    3 # Test EncFS --reverse mode
    4 
    5 use warnings;
    6 use Test::More tests => 46;
    7 use File::Path;
    8 use File::Temp;
    9 use IO::Handle;
   10 use Errno qw(EROFS);
   11 
   12 require("integration/common.pl");
   13 
   14 my $tempDir = $ENV{'TMPDIR'} || "/tmp";
   15 
   16 if($^O eq "linux" and $tempDir eq "/tmp") {
   17    # On Linux, /tmp is often a tmpfs mount that does not support
   18    # extended attributes. Use /var/tmp instead.
   19    $tempDir = "/var/tmp";
   20 }
   21 
   22 # Find attr binary
   23 # Linux
   24 my @binattr = ("attr", "-l");
   25 if(system("which xattr > /dev/null 2>&1") == 0)
   26 {
   27     # Mac OS X
   28     @binattr = ("xattr", "-s");
   29 }
   30 if(system("which lsextattr > /dev/null 2>&1") == 0)
   31 {
   32     # FreeBSD
   33     @binattr = ("lsextattr", "-h", "user");
   34 }
   35 # Do we support xattr ?
   36 my $have_xattr = 1;
   37 if(system("./build/encfs --verbose --version 2>&1 | grep -q HAVE_XATTR") != 0)
   38 {
   39     $have_xattr = 0;
   40 }
   41 
   42 # Helper function
   43 # Create a new empty working directory
   44 sub newWorkingDir
   45 {
   46     our $workingDir = mkdtemp("$tempDir/encfs-reverse-tests-XXXX")
   47         || BAIL_OUT("Could not create temporary directory");
   48 
   49     our $plain = "$workingDir/plain";
   50     mkdir($plain);
   51     our $ciphertext = "$workingDir/ciphertext";
   52     if ($^O ne "cygwin")
   53     {
   54         mkdir($ciphertext);
   55     }
   56     else
   57     {
   58         $ciphertext = "/cygdrive/x";
   59     }
   60     our $decrypted = "$workingDir/decrypted";
   61     if ($^O ne "cygwin")
   62     {
   63         mkdir($decrypted);
   64     }
   65     else
   66     {
   67         $decrypted = "/cygdrive/y";
   68     }
   69 }
   70 
   71 # Helper function
   72 # Unmount and delete mountpoint
   73 sub cleanup
   74 {
   75     portable_unmount($decrypted);
   76     portable_unmount($ciphertext);
   77     our $workingDir;
   78     rmtree($workingDir);
   79     ok( ! -d $workingDir, "working dir removed");
   80 }
   81 
   82 # Helper function
   83 # Mount encryption-decryption chain
   84 #
   85 # Directory structure: plain -[encrypt]-> ciphertext -[decrypt]-> decrypted
   86 sub mount
   87 {
   88     delete $ENV{"ENCFS6_CONFIG"};
   89     system("./build/encfs --extpass=\"echo test\" --standard $plain $ciphertext --reverse --nocache");
   90     ok(waitForFile("$plain/.encfs6.xml"), "plain .encfs6.xml exists") or BAIL_OUT("'$plain/.encfs6.xml'");
   91     my $e = encName(".encfs6.xml");
   92     ok(waitForFile("$ciphertext/$e"), "encrypted .encfs6.xml exists") or BAIL_OUT("'$ciphertext/$e'");
   93     system("ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfs --noattrcache --nodatacache --extpass=\"echo test\" $ciphertext $decrypted");
   94     ok(waitForFile("$decrypted/.encfs6.xml"), "decrypted .encfs6.xml exists") or BAIL_OUT("'$decrypted/.encfs6.xml'");
   95 }
   96 
   97 # Helper function
   98 #
   99 # Get encrypted name for file
  100 sub encName
  101 {
  102     my $name = shift;
  103     my $enc = qx(ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfsctl encode --extpass="echo test" $ciphertext $name);
  104     chomp($enc);
  105     return $enc;
  106 }
  107 
  108 # Copy a directory tree and verify that the decrypted data is identical, we also create a foo/.encfs6.xml file, to be sure it correctly shows-up
  109 sub copy_test
  110 {
  111     # first be sure .encfs6.xml does not show up
  112     # We does not use -f for this test, as it would succeed, .encfs6.xml is only hidden from readdir.
  113     my $f = encName(".encfs6.xml");
  114     cmp_ok( length($f), '>', 8, "encrypted name ok" );
  115     ok(system("ls -1 $ciphertext | grep -qwF -- $f") != 0, "configuration file .encfs6.xml not visible in $ciphertext");
  116     # copy test
  117     ok(system("cp -a encfs $plain && mkdir $plain/foo && touch $plain/foo/.encfs6.xml")==0, "copying files to plain");
  118     ok(system("diff -r -q --exclude='.encfs6.xml' $plain $decrypted")==0, "decrypted files are identical");
  119     ok(-f "$plain/encfs/encfs.cpp", "file exists");
  120     unlink("$plain/encfs/encfs.cpp");
  121     ok(! -f "$decrypted/encfs.cpp", "file deleted");
  122 }
  123 
  124 # Encfsctl cat test
  125 sub encfsctl_cat_test
  126 {
  127     my $contents = "hello world\n";
  128     ok(open(OUT, "> $plain/hello.txt"), "create file for encfsctl cat test");
  129     print OUT $contents;
  130     close OUT;
  131     qx(ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfsctl cat --extpass="echo test" $ciphertext hello.txt > $plain/hellodec.txt);
  132     qx(ENCFS6_CONFIG=$plain/.encfs6.xml ./build/encfsctl cat --extpass="echo test" --reverse $plain hello.txt > $plain/helloenc.txt);
  133     my $cname = encName("hello.txt");
  134     ok(system("diff -q $plain/helloenc.txt $ciphertext/$cname")==0, "encfsctl correctly encrypts");
  135     ok(system("diff -q $plain/hello.txt $plain/hellodec.txt")==0, "encfsctl correctly decrypts");
  136 }
  137 
  138 # Create symlinks and verify they are correctly decrypted
  139 # Parameter: symlink target
  140 sub symlink_test
  141 {
  142     my $target = shift;
  143     ok(symlink($target, "$plain/symlink"), "Symlink create, $plain/symlink -> $target");
  144     ok(my $dec = readlink("$decrypted/symlink"), "Symlink read, $decrypted/symlink -> $target");
  145     $dec.="";
  146     ok($dec eq $target, "Symlink compare, '$target' != '$dec'");
  147     my $return_code = ($have_xattr) ? system(@binattr, "$decrypted/symlink") : 0;
  148     is($return_code, 0, "Symlink xattr, $plain/symlink -> $target, extended attributes can be read (return code was $return_code)");
  149     unlink("$plain/symlink");
  150 }
  151 
  152 # Grow a file from 0 to x kB and
  153 # * check the ciphertext length is correct (stat + read)
  154 # * check that the decrypted length is correct (stat + read)
  155 # * check that plaintext and decrypted are identical
  156 sub grow {
  157     # pfh ... plaintext file handle
  158     open(my $pfh, ">", "$plain/grow");
  159     # vfh ... verification file handle
  160     open(my $vfh, "<", "$plain/grow");
  161     $pfh->autoflush;
  162     # ciphertext file name
  163     my $cname = encName("grow");
  164     # cfh ... ciphertext file handle
  165     ok(open(my $cfh, "<", "$ciphertext/$cname"), "open ciphertext grow file");
  166     # dfh ... decrypted file handle
  167     ok(open(my $dfh, "<", "$decrypted/grow"), "open decrypted grow file");
  168 
  169     # csz ... ciphertext size
  170     ok(sizeVerify($cfh, 0), "ciphertext of empty file is empty");
  171     ok(sizeVerify($dfh, 0), "decrypted empty file is empty");
  172 
  173     my $ok = 1;
  174     my $max = 9000;
  175     for($i=5; $i < $max; $i += 5)
  176     {
  177         print($pfh "abcde") or die("write failed");
  178         # autoflush should make sure the write goes to the kernel
  179         # immediately. Just to be sure, check it here.
  180         sizeVerify($vfh, $i) or die("unexpected plain file size");
  181         sizeVerify($cfh, $i) or $ok = 0;
  182         sizeVerify($dfh, $i) or $ok = 0;
  183         
  184         if(md5fh($vfh) ne md5fh($dfh))
  185         {
  186             $ok = 0;
  187             print("# content is different, unified diff:\n");
  188             system("diff -u $plain/grow $decrypted/grow");
  189         }
  190 
  191         last unless $ok;
  192     }
  193     ok($ok, "ciphertext and decrypted size of file grown to $i bytes");
  194     close($pfh);
  195     close($vfh);
  196     close($cfh);
  197     close($dfh);
  198     unlink("$plain/grow"); 
  199 }
  200 
  201 sub largeRead {
  202     writeZeroes("$plain/largeRead", 1024*1024);
  203     # ciphertext file name
  204     my $cname = encName("largeRead");
  205     # cfh ... ciphertext file handle
  206     ok(open(my $cfh, "<", "$ciphertext/$cname"), "open ciphertext largeRead file");
  207     ok(sizeVerify($cfh, 1024*1024), "1M file size");
  208 }
  209 
  210 # Check that the reverse mount is read-only
  211 # (writing is not supported in reverse mode because of the added
  212 #  complexity and the marginal use case)
  213 sub writesDenied {
  214     $fn = "$plain/writesDenied";
  215     writeZeroes($fn, 1024);
  216     my $efn = $ciphertext . "/" . encName("writesDenied");
  217     open(my $fh, ">", $efn);
  218     if( ok( $! == EROFS, "open for write denied, EROFS")) {
  219         ok( 1, "writing denied, filehandle not open");
  220     }
  221     else {
  222         print($fh "foo");
  223         ok( $! == EROFS, "writing denied, EROFS");
  224     }
  225     $target = $ciphertext . "/" . encName("writesDenied2");
  226     rename($efn, $target);
  227     ok( $! == EROFS, "rename denied, EROFS") or die();
  228     unlink($efn);
  229     ok( $! == EROFS, "unlink denied, EROFS");
  230     utime(undef, undef, $efn) ;
  231     ok( $! == EROFS, "touch denied, EROFS");
  232     truncate($efn, 10);
  233     ok( $! == EROFS, "truncate denied, EROFS");
  234 }
  235 
  236 # Setup mounts
  237 newWorkingDir();
  238 mount();
  239 
  240 # Actual tests
  241 grow();
  242 largeRead();
  243 copy_test();
  244 encfsctl_cat_test();
  245 symlink_test("/"); # absolute
  246 symlink_test("foo"); # relative
  247 symlink_test("/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/15/17/18"); # long
  248 if ($^O ne "cygwin")
  249 {
  250     symlink_test("!§\$%&/()\\<>#+="); # special characters
  251 }
  252 else
  253 {
  254     symlink_test("!§\$%&/()//<>#+="); # special characters but without \ which is not Windows compliant
  255 }                                     # Absolute symlinks may failed on Windows : https://github.com/billziss-gh/winfsp/issues/153
  256 symlink_test("$plain/foo");
  257 writesDenied();
  258 
  259 # Umount and delete files
  260 cleanup();