Changeset 310

Show
Ignore:
Timestamp:
08/31/08 19:09:16 (3 months ago)
Author:
mbr
Message:

- Added new modes '--sign <dir>' and '--verify <dir>' to allow all files
in the specified directory to be signed or verified instead of encrypted
or decrypted. All GnuPG signatures are created as "<file>.asc", and the
original file is not removed in --sign mode. In --verify mode, if any
file does not match the expected .asc signature, then a warning like the
following will be generated:

[+] Verifying: /home/mbr/src/gpgdir/test/data-dir/multi-line-ascii.asc
[GNUPG:] BADSIG 9EDEEEEBA742EEEF Some User <someuser@domain.org>

- Bugfix to not die() when files that are encrypted with a different GnuPG
key are encountered in a directory that is being decrypted. A warning
message (see below) is now generated and the file is skipped:

[+] Decrypting: /home/mbr/tmp/gpgdir/a.gpg
[GNUPG:] BAD_PASSPHRASE CF16F0FCFFF3FF4F
[-] Skipping file encrypted with different GnuPG key: a.gpg

- Updated to use the status output from GnuPG::Interface to detect a bad
passphrase and whether a file is encrypted with the expected GnuPG key.

- Updated the test suite to generate files in the output/ directory
according to test number and append the result of each test within each
file. This makes it easy to tell which tests have failed with a simple
'grep fail output/*test'.

- Updated to use the 'auto' heuristic (first implemented in the fwknop
project) to detect perl module directories that should be used in the
--Lib-dir directory to import perl modules from.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gpgdir/trunk/ChangeLog

    r303 r310  
    11gpgdir-1.9.2 (08//2008): 
     2    - Added new modes '--sign <dir>' and '--verify <dir>' to allow all files 
     3      in the specified directory to be signed or verified instead of encrypted 
     4      or decrypted.  All GnuPG signatures are created as "<file>.asc", and the 
     5      original file is not removed in --sign mode.  In --verify mode, if any 
     6      file does not match the expected .asc signature, then a warning like the 
     7      following will be generated: 
     8 
     9        [+] Verifying:  /home/mbr/src/gpgdir/test/data-dir/multi-line-ascii.asc 
     10        [GNUPG:] BADSIG 9EDEEEEBA742EEEF Some User <someuser@domain.org> 
     11 
     12    - Bugfix to not die() when files that are encrypted with a different GnuPG 
     13      key are encountered in a directory that is being decrypted. A warning 
     14      message (see below) is now generated and the file is skipped: 
     15 
     16      [+] Decrypting:  /home/mbr/tmp/gpgdir/a.gpg 
     17      [GNUPG:] BAD_PASSPHRASE CF16F0FCFFF3FF4F 
     18      [-] Skipping file encrypted with different GnuPG key: a.gpg 
     19 
     20    - Updated to use the status output from GnuPG::Interface to detect a bad 
     21      passphrase and whether a file is encrypted with the expected GnuPG key. 
    222    - Moved the GnuPG::Interface, Class::MethodMaker, and Term::ReadKey 
    323      modules to the deps/ directory, and updated the installer and RPM spec 
    424      file to account for the path change.  This change was suggested by 
    525      Franck Joncourt for the other cipherdyne.org projects. 
     26    - Updated the test suite to generate files in the output/ directory 
     27      according to test number and append the result of each test within each 
     28      file.  This makes it easy to tell which tests have failed with a simple 
     29      'grep fail output/*test'. 
    630    - Added the gpgdir-nodeps.spec file to allow an RPM to be built that does 
    731      not contain any perl modules dependencies. 
    832    - Updated gpgdir to import perl modules via 'require' statements instead 
    933      of 'use' statements so that the path to the modules directory can be 
    10       changed via the --Lib-dir command line argument. 
     34      changed via the --Lib-dir command line argument.  Also updated to use 
     35      the 'auto' heuristic (first implemented in the fwknop project) to detect 
     36      perl module directories that should be used in the --Lib-dir directory 
     37      to import perl modules from. 
    1138 
    1239gpgdir-1.9.1 (06/07/2008): 
  • gpgdir/trunk/gpgdir

    r304 r310  
    1515# Copyright (C) 2002-2008 Michael Rash (mbr@cipherdyne.org) 
    1616# 
    17 # License (GNU General Public License): 
     17# License: GNU General Public License version 2 (GPLv2) 
    1818# 
    1919#    This program is distributed in the hope that it will be useful, 
     
    5353my $encrypt_dir     = ''; 
    5454my $decrypt_dir     = ''; 
     55my $sign_dir        = ''; 
     56my $verify_dir      = ''; 
    5557my $homedir         = ''; 
    5658my $exclude_pat     = ''; 
     
    7779my $wipe_mode       = 0; 
    7880my $encrypt_mode    = 0; 
     81my $signing_mode    = 0; 
     82my $verify_mode     = 0; 
    7983my $use_default_key = 0; 
    8084my $pw_file         = ''; 
     
    97101my $overwrite_encrypted = 0; 
    98102my $overwrite_decrypted = 0; 
    99 my $symmetric_mode  = 0; 
    100 my $DEL_SOURCE_FILE = 1; 
     103my $symmetric_mode  = 0; 
     104my $DEL_SOURCE_FILE = 1; 
    101105my $NO_DEL_SOURCE_FILE = 0; 
    102106 
     
    107111my $ACCEPT_YES_DEFAULT = 1; 
    108112my $ACCEPT_NO_DEFAULT  = 2; 
     113 
     114### turn off buffering 
     115$| = 1; 
    109116 
    110117unless ($< == $>) { 
     
    120127 
    121128die "[*] Use --help for usage information.\n" unless(GetOptions ( 
    122     'encrypt=s'      => \$encrypt_dir,     # Encrypt files in this directory. 
    123     'decrypt=s'      => \$decrypt_dir,     # Decrypt files in this directory. 
     129    'encrypt-dir=s'  => \$encrypt_dir,     # Encrypt files in this directory. 
     130    'decrypt-dir=s'  => \$decrypt_dir,     # Decrypt files in this directory. 
     131    'sign-dir=s'     => \$sign_dir,        # Sign files in this directory. 
     132    'verify-dir=s'   => \$verify_dir,      # Verify files in this directory. 
    124133    'gnupg-dir=s'    => \$gpg_homedir,     # Path to /path/to/.gnupg directory. 
    125134    'pw-file=s'      => \$pw_file,         # Read password out of this file. 
     
    159168    'Default-key'    => \$use_default_key, # Assume that default-key is set within 
    160169                                           # ~/.gnupg/options. 
    161     'Symmetric'      => \$symmetric_mode, # encrypt using symmetric cipher. 
    162                                                   # (this option is not required to 
    163                                                   # also decrypt, GnuPG handles 
    164                                                   # that automatically). 
     170    'Symmetric'      => \$symmetric_mode, # encrypt using symmetric cipher. 
     171                                            (this option is not required to 
     172                                            also decrypt, GnuPG handles 
     173                                            that automatically). 
    165174    'Plain-ascii'    => \$ascii_armor_mode, # Ascii armor mode (creates non-binary 
    166175                                            # encrypted files). 
     
    197206} 
    198207 
     208die "[*] Cannot --sign-dir and --verify-dir" 
     209    if $sign_dir and $verify_dir; 
     210 
     211if ($sign_dir) { 
     212    $encrypt_dir  = $sign_dir; 
     213    $signing_mode = 1; 
     214} elsif ($verify_dir) { 
     215    $decrypt_dir = $verify_dir; 
     216    $verify_mode = 1; 
     217} 
     218 
    199219if ($encrypt_dir and $overwrite_decrypted) { 
    200220    die "[*] The -e and --overwrite-decrypted options are incompatible."; 
     
    236256} 
    237257 
    238 $options{'armor'} = 1 if $ascii_armor_mode
     258$options{'armor'} = 1 if $ascii_armor_mode or $signing_mode
    239259 
    240260### get the path to the user's home directory 
     
    256276 
    257277if ($decrypt_dir and $encrypt_dir) { 
    258     die "[*] You cannot encrypt and decrypt the same directory, see --help\n"; 
     278    die "[*] Cannot encrypt and decrypt the same directory, see --help\n"; 
    259279} 
    260280 
    261281unless ($decrypt_dir or $encrypt_dir or $test_and_exit) { 
    262     print "[*] Please specify -e <dir>, -d <dir>, or --test-mode, see --help\n"; 
     282    die "[*] Please specify -e <dir>, -d <dir>, or --test-mode, see --help\n"; 
     283
     284 
     285if ($obfuscate_mode) { 
     286    if ($sign_dir) { 
     287        die "[*] -O mode incompatible with --sign-dir"; 
     288    } elsif ($verify_dir) { 
     289        die "[*] -O mode incompatible with --verify-dir"; 
     290    } 
    263291} 
    264292 
     
    306334### don't need to test encrypt/decrypt ability if we are running 
    307335### in --Trial-run mode. 
    308 $skip_test_mode = 1 if $trial_run
     336$skip_test_mode = 1 if $trial_run or $signing_mode or $verify_mode
    309337 
    310338if ($dir eq '.') { 
     
    321349&write_pid(); 
    322350 
    323 if ($symmetric_mode) { 
     351if ($symmetric_mode or $signing_mode) { 
    324352    &get_password(); 
    325353} else { 
    326     &get_password() unless $encrypt_mode and $skip_test_mode; 
     354    &get_password() unless (($encrypt_mode and $skip_test_mode) 
     355            or $verify_mode); 
    327356} 
    328357 
     
    333362} 
    334363 
    335 if ($encrypt_mode) { 
    336     print "[+] Encrypting directory: $dir\n" unless $quiet; 
     364if ($signing_mode) { 
     365    print "[+] Signing files in directory: $dir\n" unless $quiet; 
     366} elsif ($encrypt_mode) { 
     367    print "[+] Encrypting files in directory: $dir\n" unless $quiet; 
     368} elsif ($verify_mode) { 
     369    print "[+] Verifying signatures in directory: $dir\n" unless $quiet; 
    337370} else { 
    338     print "[+] Decrypting directory: $dir\n" unless $quiet; 
     371    print "[+] Decrypting files in directory: $dir\n" unless $quiet; 
    339372} 
    340373 
     
    369402#==================== end main ===================== 
    370403 
    371 sub encrypt_file() { 
     404sub encrypt_or_sign_file() { 
    372405    my ($in_file, $out_file, $del_flag) = @_; 
    373406 
     
    415448        if ($symmetric_mode) { 
    416449            $pid = $gpg->encrypt_symmetrically('handles' => $handles); 
     450        } elsif ($signing_mode) { 
     451            $pid = $gpg->detach_sign('handles' => $handles); 
    417452        } else { 
    418453            $pid = $gpg->encrypt('handles' => $handles); 
     
    446481            die "[*] Created zero-size file: $out_file\n", 
    447482"    Maybe gpg-agent does not yet have the password for that key?\n", 
    448 "    Try re-running with -v."; 
     483"    Try with --verbose"; 
    449484        } else { 
    450485            die "[*] Created zero-size file: $out_file\n", 
    451                 "    Bad password? Try re-running with -v."; 
     486                "    Bad password? Try with --verbose"; 
    452487        } 
    453488    } 
     
    456491} 
    457492 
    458 sub decrypt_file() { 
     493sub decrypt_or_verify_file() { 
    459494    my ($in_file, $out_file, $del_flag) = @_; 
     495 
     496    my $pid; 
     497    my $bad_passphrase = 0; 
     498    my $bad_signature  = 0; 
     499    my $file_encrypted_with_expected_key = 0; 
     500    my $input_fh  = ''; 
     501    my $output_fh = ''; 
     502    my $error_fh  = ''; 
     503    my $pw_fh     = ''; 
     504    my $status_fh = ''; 
     505    my $handles   = ''; 
    460506 
    461507    my $gpg = GnuPG::Interface->new(); 
     
    465511        "homedir: $gpg_homedir" unless $gpg; 
    466512 
    467     unless ($symmetric_mode or $use_default_key) { 
     513    unless ($verify_mode or $symmetric_mode or $use_default_key) { 
    468514        $gpg->options->default_key($encrypt_user); 
    469515        $gpg->options->push_recipients($encrypt_user); 
    470516    } 
    471517 
    472     my ($input_fh, $output_fh, $error_fh, $pw_fh, $status_fh) = 
    473         (IO::File->new($in_file), 
    474         IO::File->new("> $out_file"), 
    475         IO::Handle->new(), 
    476         IO::Handle->new(), 
    477         IO::Handle->new()); 
    478  
    479     my $handles = GnuPG::Handles->new( 
    480         stdin  => $input_fh, 
    481         stdout => $output_fh, 
    482         stderr => $error_fh, 
    483         passphrase => $pw_fh, 
    484         status => $status_fh 
    485     ); 
    486     $handles->options('stdin')->{'direct'}  = 1; 
    487     $handles->options('stdout')->{'direct'} = 1; 
    488  
    489     my $pid; 
     518    if ($verify_mode) { 
     519        ($input_fh, $output_fh, $error_fh, $status_fh) = 
     520            (IO::Handle->new(), 
     521            IO::Handle->new(), 
     522            IO::Handle->new(), 
     523            IO::Handle->new()); 
     524        $handles = GnuPG::Handles->new( 
     525            stdin  => $input_fh, 
     526            stdout => $output_fh, 
     527            stderr => $error_fh, 
     528            status => $status_fh 
     529        ); 
     530    } else { 
     531        ($input_fh, $output_fh, $error_fh, $pw_fh, $status_fh) = 
     532            (IO::File->new($in_file), 
     533            IO::File->new("> $out_file"), 
     534            IO::Handle->new(), 
     535            IO::Handle->new(), 
     536            IO::Handle->new()); 
     537        $handles = GnuPG::Handles->new( 
     538            stdin  => $input_fh, 
     539            stdout => $output_fh, 
     540            stderr => $error_fh, 
     541            passphrase => $pw_fh, 
     542            status => $status_fh 
     543        ); 
     544        $handles->options('stdin')->{'direct'}  = 1; 
     545        $handles->options('stdout')->{'direct'} = 1; 
     546    } 
    490547 
    491548    if ($use_gpg_agent) { 
     
    493550            'command_args' => [ qw( --use-agent ) ]); 
    494551    } else { 
    495         $pid = $gpg->decrypt('handles' => $handles); 
    496     } 
    497  
    498     print $pw_fh $pw; 
    499     close $pw_fh; 
     552        if ($verify_mode) { 
     553            $pid = $gpg->wrap_call( 
     554                'commands'     => [ qw( --verify ) ], 
     555                'command_args' => [ ( $in_file ) ], 
     556                'handles'      => $handles 
     557            ); 
     558        } else { 
     559            $pid = $gpg->decrypt('handles' => $handles); 
     560        } 
     561    } 
     562 
     563    unless ($verify_mode) { 
     564        print $pw_fh $pw; 
     565        close $pw_fh; 
     566    } 
    500567 
    501568    my @errors = <$error_fh>; 
    502  
    503     if ($verbose) { 
    504         print for @errors; 
    505     } else { 
    506         for (@errors) { 
    507             print if /bad\s+pass/; 
    508         } 
    509     } 
     569    my @status = <$status_fh>; 
    510570 
    511571    close $input_fh; 
     
    516576    waitpid $pid, 0; 
    517577 
    518     if (-s $out_file == 0) { 
     578    for (@status) { 
     579        if ($verify_mode) { 
     580            ### [GNUPG:] BADSIG 9EEEEE6BEE428EEE Some User <someone@domain.com> 
     581            $bad_signature = 1 if /BADSIG/; 
     582        } else { 
     583            ### [GNUPG:] BAD_PASSPHRASE C326F95CE133EA4E 
     584            $bad_passphrase = 1 if /BAD_?PASS/; 
     585            if (/NEED_PASSPHRASE\s\S+\s+\S+$encrypt_user\s/) { 
     586                ### [GNUPG:] NEED_PASSPHRASE CDE4D7DDFD66DCB9 95D85DDDDD42D39D 16 0 
     587                $file_encrypted_with_expected_key = 1; 
     588            } elsif ((length($encrypt_user) == 8) 
     589                    and /USERID_HINT\s+.*$encrypt_user/) { 
     590                $file_encrypted_with_expected_key = 1; 
     591            } 
     592        } 
     593    } 
     594 
     595    if ($verbose) { 
     596        print "    GnuPG errors:\n"; 
     597        print for @errors; 
     598        print "    GnuPG status:\n"; 
     599        print for @status; 
     600    } else { 
     601        for (@status) { 
     602            if (/BAD_?PASS/) { 
     603                print unless $quiet; 
     604            } elsif (/BADSIG/) { 
     605                print unless $quiet; 
     606            } 
     607        } 
     608    } 
     609 
     610    if ($bad_passphrase) { 
     611        if (-s $out_file == 0) { 
     612            &delete_file($out_file); 
     613            &delete_file($in_file) if $del_flag == $DEL_SOURCE_FILE; 
     614            if ($file_encrypted_with_expected_key) { 
     615                die "[*] Bad passphrase, try gpgdir with -v"; 
     616            } else { 
     617                print "[-] Skipping file encrypted with different ", 
     618                    "GnuPG key: $in_file\n" unless $quiet; 
     619            } 
     620        } else { 
     621            die 
     622"[*] Bad passphrase, but created non-zero sized output file, should not\n", 
     623"    happen. Try with --verbose"; 
     624        } 
     625    } elsif (-s $out_file == 0) { 
    519626        &delete_file($out_file); 
    520627        &delete_file($in_file) if $del_flag == $DEL_SOURCE_FILE; 
     
    522629            die "[*] Created zero-size file: $out_file\n", 
    523630"    Maybe gpg-agent does not yet have the password for that key?\n", 
    524 "    Try re-running with -v."; 
     631"    Try with --verbose"; 
    525632        } else { 
    526633            die "[*] Created zero-size file: $out_file\n", 
    527                 "    Bad password? Try re-running with -v."; 
     634                "    Bad password? Try with --verbose"; 
    528635        } 
    529636    } 
     
    625732            } 
    626733 
    627             if ($ascii_armor_mode) { 
     734            if ($ascii_armor_mode or $signing_mode) { 
    628735                $encrypt_filename = "$filename.asc"; 
    629736            } 
    630737 
    631738            if (-e $encrypt_filename and not $overwrite_encrypted) { 
    632                 print "[-] Encrypted file $dir/$encrypt_filename already ", 
     739                my $str = 'Encrypted'; 
     740                $str = 'Signed' if $signing_mode; 
     741                print "[-] $str file $dir/$encrypt_filename already ", 
    633742                    "exists, skipping.\n" unless $quiet; 
    634743                next FILE; 
     
    636745 
    637746            if ($interactive_mode) { 
     747                my $str = 'Encrypt'; 
     748                $str = 'Sign' if $signing_mode; 
    638749                next FILE unless (&query_yes_no( 
    639                     "    Encrypt: $file ([y]/n)?  ", $ACCEPT_YES_DEFAULT)); 
    640             } 
    641  
    642             print "[+] Encrypting:  $file\n" unless $quiet; 
     750                    "    $str: $file ([y]/n)?  ", $ACCEPT_YES_DEFAULT)); 
     751            } 
     752 
     753            my $str = 'Encrypting'; 
     754            $str = 'Signing' if $signing_mode; 
     755            print "[+] $str:  $file\n" unless $quiet; 
    643756 
    644757            unless ($trial_run) { 
    645758 
    646                 &encrypt_file($filename, $encrypt_filename, 
     759                &encrypt_or_sign_file($filename, $encrypt_filename, 
    647760                        $NO_DEL_SOURCE_FILE); 
    648761 
    649                 if (-e $encrypt_filename && -s $encrypt_filename != 0) { 
     762                if (-e $encrypt_filename and -s $encrypt_filename != 0) { 
    650763                    ### set the atime and mtime to be the same as the 
    651764                    ### original file. 
     
    656769                        } 
    657770                    } 
    658                     ### only delete the original file if 
    659                     ### the encrypted one exists 
    660                     if ($wipe_mode and not $quiet) { 
    661                         print "    Securely deleting file: $file\n"; 
     771 
     772                    unless ($signing_mode) { 
     773                        ### only delete the original file if 
     774                        ### the encrypted one exists 
     775                        if ($wipe_mode and not $quiet) { 
     776                            print "    Securely deleting file: $file\n"; 
     777                        } 
     778                        &delete_file($filename); 
     779 
     780                        if ($obfuscate_mode) { 
     781 
     782                            ### record the original file name mapping 
     783                            &append_obfuscated_mapping($filename, 
     784                                $encrypt_filename); 
     785 
     786                            $obfuscate_ctrs{$dir}++; 
     787                        } 
    662788                    } 
    663                     &delete_file($filename); 
    664  
    665                     if ($obfuscate_mode) { 
    666  
    667                         ### record the original file name mapping 
    668                         &append_obfuscated_mapping($filename, 
    669                             $encrypt_filename); 
    670  
    671                         $obfuscate_ctrs{$dir}++; 
    672                     } 
    673789 
    674790                    $total_encrypted++; 
    675791 
    676792                } else { 
    677                     print "[-] Could not encrypt file: $file\n" unless $quiet; 
     793                    my $str = 'encrypt'; 
     794                    $str = 'sign' if $signing_mode; 
     795                    print "[-] Could not $str file: $file\n" unless $quiet; 
    678796                    next FILE; 
    679797                } 
     
    720838            next FILE unless length($decrypt_filename) > 0; 
    721839 
    722             ### don't decrypt a file on top of a normal file of 
    723             ### the same name 
    724             if (-e $decrypt_filename and not $overwrite_decrypted) { 
    725                 print "[-] Decrypted file $dir/$decrypt_filename ", 
    726                     "already exists. Skipping.\n" unless $quiet; 
    727                 next FILE; 
     840            if ($verify_mode) { 
     841                unless (-e $decrypt_filename) { 
     842                    print "[-] Original file $decrypt_filename ", 
     843                        "does not exist, skipping.\n"; 
     844                    next FILE; 
     845                } 
     846            } else { 
     847                ### don't decrypt a file on top of a normal file of 
     848                ### the same name 
     849                if (-e $decrypt_filename and not $overwrite_decrypted) { 
     850                    print "[-] Decrypted file $dir/$decrypt_filename ", 
     851                        "already exists. Skipping.\n" unless $quiet; 
     852                    next FILE; 
     853                } 
    728854            } 
    729855 
    730856            if ($interactive_mode) { 
     857                my $str = 'Decrypt'; 
     858                $str = 'Verify' if $verify_mode; 
    731859                next FILE unless (&query_yes_no( 
    732                     "    Decrypt: $file ([y]/n)?  ", $ACCEPT_YES_DEFAULT)); 
     860                    "    $str: $file ([y]/n)?  ", $ACCEPT_YES_DEFAULT)); 
    733861            } 
    734862 
    735863            unless ($trial_run) { 
    736  
    737                 print "[+] Decrypting:  $dir/$filename\n" unless $quiet; 
    738                 &decrypt_file($filename, $decrypt_filename, 
     864                my $str = 'Decrypting'; 
     865                $str = 'Verifying' if $verify_mode; 
     866                print "[+] $str:  $dir/$filename\n" unless $quiet; 
     867                &decrypt_or_verify_file($filename, $decrypt_filename, 
    739868                        $NO_DEL_SOURCE_FILE); 
    740869 
    741                 if (-e $decrypt_filename && -s $decrypt_filename != 0) { 
    742                     ### set the atime and mtime to be the same as the 
    743                     ### original file. 
    744                     unless ($no_fs_times) { 
    745                         if (defined $mtime and $mtime and 
    746                                 defined $atime and $atime) { 
    747                             utime $atime, $mtime, $decrypt_filename; 
     870                unless ($verify_mode) { 
     871                    if (-e $decrypt_filename and -s $decrypt_filename != 0) { 
     872                        ### set the atime and mtime to be the same as the 
     873                        ### original file. 
     874                        unless ($no_fs_times) { 
     875                            if (defined $mtime and $mtime and 
     876                                    defined $atime and $atime) { 
     877                                utime $atime, $mtime, $decrypt_filename; 
     878                            } 
    748879                        } 
     880                        if ($wipe_mode and not $quiet) { 
     881                            print "    Securely deleting file: $file\n"; 
     882                        } 
     883                        ### only delete the original encrypted 
     884                        ### file if the decrypted one exists 
     885                        &delete_file($filename); 
     886 
     887                        $total_decrypted++; 
     888 
     889                    } else { 
     890                        print "[-] Could not decrypt file: $file\n" 
     891                            unless $quiet; 
     892                        next FILE; 
    749893                    } 
    750                     if ($wipe_mode and not $quiet) { 
    751                         print "    Securely deleting file: $file\n"; 
    752                     } 
    753                     ### only delete the original encrypted 
    754                     ### file if the decrypted one exists 
    755                     &delete_file($filename); 
    756  
    757                     $total_decrypted++; 
    758  
    759                 } else { 
    760                     print "[-] Could not decrypt file: $file\n" unless $quiet; 
    761                     next FILE; 
    762894                } 
    763895            } 
     
    837969                "$dir/$obfuscate_map_filename\n" unless $quiet; 
    838970            unless ($trial_run) { 
    839                 &encrypt_file($obfuscate_map_filename, 
     971                &encrypt_or_sign_file($obfuscate_map_filename, 
    840972                    "$obfuscate_map_filename.gpg", $NO_DEL_SOURCE_FILE); 
    841973 
     
    849981                "$dir/$obfuscate_map_filename.gpg\n" unless $quiet; 
    850982            unless ($trial_run) { 
    851                 &decrypt_file("$obfuscate_map_filename.gpg", 
     983                &decrypt_or_verify_file("$obfuscate_map_filename.gpg", 
    852984                    $obfuscate_map_filename, $NO_DEL_SOURCE_FILE); 
    853985 
     
    867999    return unless -e "$obfuscate_map_filename.gpg"; 
    8681000 
    869     &decrypt_file("$obfuscate_map_filename.gpg", 
     1001    &decrypt_or_verify_file("$obfuscate_map_filename.gpg", 
    8701002            $obfuscate_map_filename, $NO_DEL_SOURCE_FILE); 
    8711003 
     
    9171049    return unless -e "$obfuscate_map_filename.gpg"; 
    9181050 
    919     &decrypt_file("$obfuscate_map_filename.gpg", 
     1051    &decrypt_or_verify_file("$obfuscate_map_filename.gpg", 
    9201052            $obfuscate_map_filename, $NO_DEL_SOURCE_FILE); 
    9211053 
     
    10071139 
    10081140    close F; 
    1009     print 
     1141    die 
    10101142"[*] Please edit $homedir/.gpgdirrc to include your gpg key identifier,\n", 
    10111143"    or use the default GnuPG key defined in ~/.gnupg/options.  Exiting.\n"; 
    1012     exit 0; 
    10131144} 
    10141145 
     
    10261157    if (-e $file and not -l $file and -s $file != 0 
    10271158            and $file !~ m|/\.|) { 
    1028         if ($encrypt_mode) { 
     1159        if ($encrypt_mode or $signing_mode) { 
    10291160            if ($file =~ m|\.gpg| or $file =~ m|\.asc|) { 
    1030                 print "[-] Skipping encrypted file: $file\n" unless $quiet; 
     1161                print "[-] Skipping encrypted/signed file: $file\n" unless $quiet; 
     1162                return; 
     1163            } 
     1164        } elsif ($verify_mode) { 
     1165            unless ($file =~ m|\.asc|) { 
     1166                ### only pick up the signature files 
    10311167                return; 
    10321168            } 
     
    10761212            print "    *** test_mode() ***\n" unless $quiet; 
    10771213        } 
    1078         if ($encrypt_mode) { 
     1214        if ($signing_mode) { 
     1215            print "    Enter signing password.\n" unless $quiet; 
     1216        } elsif ($encrypt_mode) { 
    10791217            print '    Enter password (for initial ' . 
    10801218                "encrypt/decrypt test)\n" unless $quiet; 
     
    10831221        ### get the password without echoing the chars back to the screen 
    10841222        ReadMode('noecho'); 
    1085         while (! $pw) { 
     1223        while (not $pw) { 
    10861224            print $msg; 
    10871225            $pw = ReadLine(0); 
     
    11261264    } 
    11271265 
    1128     &encrypt_file($test_file, "${test_file}.gpg", $DEL_SOURCE_FILE); 
     1266    &encrypt_or_sign_file($test_file, "${test_file}.gpg", $DEL_SOURCE_FILE); 
    11291267 
    11301268    if (-e "$test_file.gpg" and (-s $test_file != 0)) { 
     
    11361274    } 
    11371275 
    1138     &decrypt_file("${test_file}.gpg", $test_file, $DEL_SOURCE_FILE); 
     1276    &decrypt_or_verify_file("${test_file}.gpg", $test_file, $DEL_SOURCE_FILE); 
    11391277 
    11401278    if (-e $test_file and (-s $test_file != 0)) { 
     
    12541392        next unless -d "$lib_dir/$dir"; 
    12551393        push @paths, "$lib_dir/$dir" 
    1256             if $dir =~ m|linux| or $dir =~ m|thread|; 
     1394            if $dir =~ m|linux| or $dir =~ m|thread| 
     1395                or (-d "$lib_dir/$dir/auto"); 
    12571396    } 
    12581397    return \@paths; 
     
    12711410 
    12721411Options: 
    1273     -e, --encrypt <directory>   - Encrypt <directory> and all of its 
    1274                                   subdirectories. 
    1275     -d, --decrypt <directory>   - Decrypt <directory> and all of its 
    1276                                   subdirectories. 
     1412    -e, --encrypt <directory>   - Recursively encrypt all files in 
     1413                                  <directory> and all subdirectories. 
     1414    -d, --decrypt <directory>   - Recursively decrypt all files in 
     1415                                  <directory> and all subdirectories. 
     1416    --sign <directory>          - Recursively sign all files in <directory> 
     1417                                  and all subdirectories. 
     1418    --verify <directory>        - Recursively verify all GnuPG signatures 
     1419                                  in <directory>. 
     1420    -K, --Key-id <id>           - Specify GnuPG key ID, or key-matching 
     1421                                  string. This overrides the use_key value 
     1422                                  in ~/.gpgdirrc 
     1423    -D, --Default-key           - Use the key that GnuPG defines as the 
     1424                                  default (i.e. the key that is specified 
     1425                                  by the default-key option in 
     1426                                  ~/.gnupg/options). 
    12771427    -a, --agent                 - Acquire password information from a 
    12781428                                  running instance of gpg-agent. 
     
    12831433                                  gpg keys (the default is ~/.gnupg if this 
    12841434                                  option is not used). 
     1435    -S, --Symmetric             - Use symmetric encryption instead of the 
     1436                                  default asymmetric encryption. 
    12851437    -p, --pw-file <file>        - Read password in from <file>. 
    1286     -s, --skip-test             - Skip encrypt -> decrypt test. 
     1438    --skip-test                 - Skip encrypt -> decrypt test. 
    12871439    -t, --test-mode             - Run encrypt -> decrypt test and exit. 
    12881440    -T, --Trial-run             - Show what filesystem actions would take 
     
    12991451    --Include-from <file>       - Include only those filenames that match a 
    13001452                                  pattern contained within <file>. 
    1301     -K, --Key-id <id>           - Specify GnuPG key ID, or key-matching 
    1302                                   string. This overrides the use_key value 
    1303                                   in ~/.gpgdirrc 
    1304     -D, --Default-key           - Use the key that GnuPG defines as the 
    1305                                   default (i.e. the key that is specified 
    1306                                   by the default-key option in 
    1307                                   ~/.gnupg/options). 
    13081453    -O, --Obfuscate-filenames   - Substitute all real filenames in a 
    13091454                                  directory with manufactured ones (the 
     
    13421487    --no-locale                 - Don't set the locale to anything (the 
    13431488                                  default is the "C" locale). 
    1344     -v, --verbose               - Run in verbose mode. 
     1489    --verbose               - Run in verbose mode. 
    13451490    -V, --Version               - print version. 
    13461491    -h, --help                  - print help. 
  • gpgdir/trunk/test/gpgdir_test.pl

    r308 r310  
    3333use Digest::MD5 'md5_base64'; 
    3434use File::Find; 
     35use File::Copy; 
    3536use Getopt::Long; 
    3637use strict; 
     
    4748my $gpg_dir = "$conf_dir/test-gpg"; 
    4849my $pw_file = "$conf_dir/test.pw"; 
     50my $broken_pw_file = "$conf_dir/broken.pw"; 
    4951my $key_id  = '375D7DB9'; 
    50  
    51 my $cmd_stdout = "$output_dir/cmd.stdout"; 
    52 my $cmd_stderr = "$output_dir/cmd.stderr"; 
    5352#==================== end config ================== 
    5453 
     
    5655my $test_num  = 0; 
    5756my $PRINT_LEN = 68; 
     57my $APPEND    = 1; 
     58my $NO_APPEND = 0; 
    5859my $failed_tests = 0; 
    5960my $prepare_results = 0; 
    6061my $successful_tests = 0; 
     62my $current_test_file = "$output_dir/$test_num.test"; 
     63my $previous_test_file = ''; 
    6164my @data_dir_files = (); 
    6265my %md5sums = (); 
     
    125128&test_driver('(Sign/verify dir) Excluded hidden files/dirs', 
    126129    \&skipped_hidden_files_dirs); 
     130&test_driver('(Sign/verify dir) Broken signature detection', 
     131    \&broken_sig_detection); 
    127132&test_driver('(Sign/verify dir) gpgdir directory verification', \&verify); 
    128133&test_driver('(Sign/verify dir) Files recursively verified', 
    129134    \&recursively_verified); 
    130 ### remove all .asc files now 
     135 
     136### bad password detection 
     137&test_driver('(Bad passphrase) detected broken passphrase', 
     138    \&broken_passphrase); 
    131139 
    132140&logr("\n"); 
     
    147155    my ($msg, $func_ref) = @_; 
    148156 
     157    my $test_status = 'pass'; 
    149158    &dots_print($msg); 
    150159    if (&{$func_ref}) { 
    151160        &pass(); 
    152161    } else { 
     162        $test_status = 'fail'; 
    153163        $failed_tests++; 
    154164    } 
     165 
     166    open C, ">> $current_test_file" 
     167        or die "[*] Could not open $current_test_file: $!"; 
     168    print C "\nTEST: $msg, STATUS: $test_status\n"; 
     169    close C; 
     170 
     171    $previous_test_file = $current_test_file; 
    155172    $test_num++; 
     173    $current_test_file = "$output_dir/$test_num.test"; 
    156174    return; 
     175} 
     176 
     177sub broken_passphrase() { 
     178    if (not &run_cmd("$gpgdirCmd --gnupg-dir $gpg_dir " . 
     179            " --pw-file $broken_pw_file --Key-id $key_id -e $data_dir", 
     180            $NO_APPEND)) { 
     181        my $found_bad_pass = 0; 
     182        open F, "< $current_test_file" or die $!; 
     183        while (<F>) { 
     184            if (/BAD_?PASS/) { 
     185                $found_bad_pass = 1; 
     186            } 
     187        } 
     188        close F; 
     189        if ($found_bad_pass) { 
     190            return 1; 
     191        } 
     192    } 
     193    return &print_errors("[-] Accepted broken passphrase"); 
    157194} 
    158195 
    159196sub encrypt() { 
    160197    if (&run_cmd("$gpgdirCmd --gnupg-dir $gpg_dir " . 
    161             " --pw-file $pw_file --Key-id $key_id -e $data_dir")) { 
    162         return 1; 
    163     } 
    164     return &print_errors("fail ($test_num)\n[*] " . 
    165         "Directory encryption"); 
     198            " --pw-file $pw_file --Key-id $key_id -e $data_dir", 
     199            $NO_APPEND)) { 
     200        return 1; 
     201    } 
     202    return &print_errors("[-] Directory encryption"); 
    166203} 
    167204 
    168205sub ascii_encrypt() { 
    169206    if (&run_cmd("$gpgdirCmd --Plain-ascii --gnupg-dir $gpg_dir " . 
    170             " --pw-file $pw_file --Key-id $key_id -e $data_dir")) { 
    171         return 1; 
    172     } 
    173     return &print_errors("fail ($test_num)\n[*] " . 
    174         "Directory encryption"); 
     207            " --pw-file $pw_file --Key-id $key_id -e $data_dir", 
     208            $NO_APPEND)) { 
     209        return 1; 
     210    } 
     211    return &print_errors("[-] Directory encryption"); 
    175212} 
    176213 
    177214sub obf_encrypt() { 
    178215    if (&run_cmd("$gpgdirCmd -O --gnupg-dir $gpg_dir " . 
    179             " --pw-file $pw_file --Key-id $key_id -e $data_dir")) { 
    180         return 1; 
    181     } 
    182     return &print_errors("fail ($test_num)\n[*] " . 
    183         "Directory encryption"); 
     216            " --pw-file $pw_file --Key-id $key_id -e $data_dir", 
     217            $NO_APPEND)) { 
     218        return 1; 
     219    } 
     220    return &print_errors("[-] Directory encryption"); 
    184221} 
    185222 
    186223sub sign() { 
    187224    if (&run_cmd("$gpgdirCmd --gnupg-dir $gpg_dir " . 
    188             " --pw-file $pw_file --Key-id $key_id --sign $data_dir")) { 
    189         return 1; 
    190     } 
    191     return &print_errors("fail ($test_num)\n[*] " . 
    192         "Directory signing"); 
     225            " --pw-file $pw_file --Key-id $key_id --sign $data_dir", 
     226            $NO_APPEND)) { 
     227        return 1; 
     228    } 
     229    return &print_errors("[-] Directory signing"); 
    193230} 
    194231 
    195232sub decrypt() { 
    196233    if (&run_cmd("$gpgdirCmd --gnupg-dir $gpg_dir " . 
    197             " --pw-file $pw_file --Key-id $key_id -d $data_dir")) { 
    198         return 1; 
    199     } 
    200     return &print_errors("fail ($test_num)\n[*] " . 
    201         "Directory decryption"); 
     234            " --pw-file $pw_file --Key-id $key_id -d $data_dir", 
     235            $NO_APPEND)) { 
     236        return 1; 
     237    } 
     238    return &print_errors("[-] Directory decryption"); 
    202239} 
    203240 
    204241sub obf_decrypt() { 
    205242    if (&run_cmd("$gpgdirCmd -O --gnupg-dir $gpg_dir " . 
    206             " --pw-file $pw_file --Key-id $key_id -d $data_dir")) { 
    207         return 1; 
    208     } 
    209     return &print_errors("fail ($test_num)\n[*] " . 
    210         "Directory decryption"); 
     243            " --pw-file $pw_file --Key-id $key_id -d $data_dir", 
     244            $NO_APPEND)) { 
     245        return 1; 
     246    } 
     247    return &print_errors("[-] Directory decryption"); 
    211248} 
    212249 
    213250sub verify() { 
    214251    if (&run_cmd("$gpgdirCmd --gnupg-dir $gpg_dir " . 
    215             " --pw-file $pw_file --Key-id $key_id --verify $data_dir")) { 
    216         return 1; 
    217     } 
    218     return &print_errors("fail ($test_num)\n[*] " . 
    219         "Directory verification"); 
     252            " --pw-file $pw_file --Key-id $key_id --verify $data_dir", 
     253            $NO_APPEND)) { 
     254        return 1; 
     255    } 
     256    return &print_errors("[-] Directory verification"); 
    220257} 
    221258 
     
    226263        if (-f $file and not ($file =~ m|^\.| or $file =~ m|/\.|)) { 
    227264            unless ($file =~ m|\.gpg$|) { 
    228                 return &print_errors("fail ($test_num)\n[*] " . 
    229                     "File $file not encrypted"); 
     265                return &print_errors("[-] File $file not encrypted"); 
    230266            } 
    231267        } 
     
    241277            if ($file !~ m|\.asc$|) { 
    242278                unless (-e "$file.asc") { 
    243           &nb