Changeset 1264

Show
Ignore:
Timestamp:
09/29/08 19:46:59 (2 months ago)
Author:
mbr
Message:

- Updated fwknopd to enforce the DIGEST_TYPE variable more strictly by not
accepting SPA packets that do not include digest of the specified type.
The DIGEST_TYPE default is 'ALL', so normally fwknopd accepts any
supported digest.
- (Test suite) Added test for mis-matched DIGEST_TYPE vs. digest algorithm
used in SPA packets.

Files:

Legend:

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

    r1260 r1264  
    2727      sure randomness is high or to test encryption properties over large 
    2828      sets of SPA packets). 
     29    - Updated fwknopd to enforce the DIGEST_TYPE variable more strictly by not 
     30      accepting SPA packets that do not include digest of the specified type. 
     31      The DIGEST_TYPE default is 'ALL', so normally fwknopd accepts any 
     32      supported digest. 
    2933    - Bugfix to make sure to apply BLACKLIST checks to IP addresses specified 
    3034      with -a (or derived via -R) in addition to the source IP in the IP 
  • fwknop/trunk/fwknopd

    r1262 r1264  
    15861586        my $sum = $2; 
    15871587        if (length($sum) == $SHA256_DIGEST_LEN) { 
    1588             if ($sum eq sha256_base64($msg)) { 
    1589                 $hr->{'digest_str'} = 'SHA256'; 
    1590                 $hr->{'digest'} = $sum; 
    1591                 $rv = 1; 
     1588            if ($config{'DIGEST_TYPE'} eq 'ALL' 
     1589                    or $config{'DIGEST_TYPE'} =~ /SHA256/) { 
     1590                if ($sum eq sha256_base64($msg)) { 
     1591                    $hr->{'digest_str'} = 'SHA256'; 
     1592                    $hr->{'digest'} = $sum; 
     1593                    $rv = 1; 
     1594                } 
     1595            } else { 
     1596                print STDERR localtime() . " [-] Digest alg mis-match.\n"; 
    15921597            } 
    15931598        } elsif (length($sum) == $SHA1_DIGEST_LEN) { 
    1594             if ($sum eq sha1_base64($msg)) { 
    1595                 $hr->{'digest_str'} = 'SHA1'; 
    1596                 $hr->{'digest'} = $sum; 
    1597                 $rv = 1; 
     1599            if ($config{'DIGEST_TYPE'} eq 'ALL' 
     1600                    or $config{'DIGEST_TYPE'} =~ /SHA1/) { 
     1601                if ($sum eq sha1_base64($msg)) { 
     1602                    $hr->{'digest_str'} = 'SHA1'; 
     1603                    $hr->{'digest'} = $sum; 
     1604                    $rv = 1; 
     1605                } 
     1606            } else { 
     1607                print STDERR localtime() . " [-] Digest alg mis-match.\n"; 
    15981608            } 
    15991609        } elsif (length($sum) == $MD5_DIGEST_LEN) { 
    1600             if ($sum eq md5_base64($msg)) { 
    1601                 $hr->{'digest_str'} = 'MD5'; 
    1602                 $hr->{'digest'} = $sum; 
    1603                 $rv = 1; 
     1610            if ($config{'DIGEST_TYPE'} eq 'ALL' 
     1611                    or $config{'DIGEST_TYPE'} =~ /MD5/) { 
     1612                if ($sum eq md5_base64($msg)) { 
     1613                    $hr->{'digest_str'} = 'MD5'; 
     1614                    $hr->{'digest'} = $sum; 
     1615                    $rv = 1; 
     1616                } 
     1617            } else { 
     1618                print STDERR localtime() . " [-] Digest alg mis-match.\n"; 
    16041619            } 
    16051620        } 
     
    23422357    } 
    23432358 
    2344     my $input  = IO::Handle->new() or die $!; 
    2345     my $output = IO::Handle->new() or die $!; 
    2346     my $error  = IO::Handle->new() or die $!; 
    2347     my $pw     = IO::Handle->new() or die $!; 
    2348     my $status = IO::Handle->new() or die $!; 
     2359    my $input_fh  = IO::Handle->new() or die $!; 
     2360    my $output_fh = IO::Handle->new() or die $!; 
     2361    my $error_fh  = IO::Handle->new() or die $!; 
     2362    my $pw_fh     = IO::Handle->new() or die $!; 
     2363    my $status_fh = IO::Handle->new() or die $!; 
    23492364 
    23502365    my $handles = GnuPG::Handles->new( 
    2351         stdin      => $input
    2352         stdout     => $output
    2353         stderr     => $error
    2354         passphrase => $pw
    2355         status     => $status
     2366        stdin      => $input_fh
     2367        stdout     => $output_fh
     2368        stderr     => $error_fh
     2369        passphrase => $pw_fh
     2370        status     => $status_fh
    23562371    ); 
    23572372 
     
    23792394    } 
    23802395 
    2381     print $pw $access_hr->{'GPG_DECRYPT_PW'}; 
    2382  
    2383     close $pw; 
    2384  
    2385     print $input $base64_decoded_msg; 
    2386     close $input; 
    2387  
    2388     @plaintext = <$output>; 
    2389     close $output; 
    2390  
    2391     my @errors = <$error>; 
    2392     close $error; 
     2396    print $pw_fh $access_hr->{'GPG_DECRYPT_PW'}; 
     2397 
     2398    close $pw_fh; 
     2399 
     2400    print $input_fh $base64_decoded_msg; 
     2401    close $input_fh; 
     2402 
     2403    @plaintext = <$output_fh>; 
     2404    close $output_fh; 
     2405 
     2406    my @errors = <$error_fh>; 
     2407    close $error_fh; 
     2408 
     2409    my @status = <$status_fh>; 
     2410    close $status_fh; 
    23932411 
    23942412    waitpid $pid, 0; 
     2413 
     2414    if ($debug) { 
     2415        print STDERR localtime() . " [+] GnuPG status messages:\n"; 
     2416        print STDERR for @status; 
     2417    } 
    23952418 
    23962419    ### we require the message to be signed; make sure 
     
    23992422        $key_id = $1 if $key_id =~ /^0x(\w+)/; 
    24002423        my $found_candidate_sig = 0; 
     2424        if ($debug) { 
     2425            print STDERR localtime() . " [+] gpg key ID: $key_id\n" 
     2426                    localtime() . "     GnuPG error messages:\n"; 
     2427        } 
    24012428        LINE: for my $err (@errors) { 
    2402             print STDERR localtime() . "     $err" if $debug and $verbose
     2429            print STDERR localtime() . "     $err" if $debug
    24032430            if ($key_id eq 'ANY') { 
    24042431                if ($err =~ /Good\s+signature/i) { 
     
    28122839                        $grant_dst, $auto_rule_position, $table, $to_chain, 
    28132840                        $target, \%extended_info); 
     2841 
     2842                    if ($debug) { 
     2843                        print STDERR localtime() . " [+] Dumping $to_chain to ", 
     2844                            "see newly added rule:\n"; 
     2845                        $ipt->run_ipt_cmd("$cmds{'iptables'} -t " . 
     2846                            "$table -v -n -L $to_chain"); 
     2847                    } 
    28142848 
    28152849                    if ($rv) { 
     
    44854519        &build_ipt_config(); 
    44864520 
    4487         my $ipt = &get_iptables_chainmgr_obj(); 
    4488         print "[+] Listing rules in fwknop chains...\n"; 
    4489         for my $hr (@ipt_config) { 
    4490             my $table    = $hr->{'table'}; 
    4491             my $to_chain = $hr->{'to_chain'}; 
    4492  
    4493             if ($ipt->chain_exists($table, $to_chain)) { 
    4494                 my ($rv, $out_aref, $err_aref) = 
    4495                     $ipt->run_ipt_cmd("$cmds{'iptables'} -t " . 
    4496                         "$table -v -n -L $to_chain"); 
    4497  
    4498                 if ($rv and $out_aref) { 
    4499                     print for @$out_aref; 
    4500                     print "\n"; 
    4501                 } 
    4502             } else { 
    4503                 print "[-] Table: $table, chain: $to_chain, does not exist\n"; 
    4504             } 
     4521        &dump_ipt_policy(); 
     4522    } 
     4523    return 0; 
     4524
     4525 
     4526sub dump_ipt_policy() { 
     4527 
     4528    print STDERR localtime() . " [+] dump_ipt_policy()\n" if $debug; 
     4529 
     4530    my $ipt = &get_iptables_chainmgr_obj(); 
     4531    print "[+] Listing rules in fwknop chains...\n"; 
     4532    for my $hr (@ipt_config) { 
     4533        my $table    = $hr->{'table'}; 
     4534        my $to_chain = $hr->{'to_chain'}; 
     4535 
     4536        if ($ipt->chain_exists($table, $to_chain)) { 
     4537            my ($rv, $out_aref, $err_aref) = 
     4538                $ipt->run_ipt_cmd("$cmds{'iptables'} -t " . 
     4539                    "$table -v -n -L $to_chain"); 
     4540 
     4541            if ($rv and $out_aref) { 
     4542                print for @$out_aref; 
     4543                print "\n"; 
     4544            } 
     4545        } else { 
     4546            print "[-] Table: $table, chain: $to_chain, does not exist\n"; 
    45054547        } 
    45064548    } 
     
    51265168 
    51275169    my $found_digest = 0; 
     5170    my $use_md5    = 0; 
     5171    my $use_sha1   = 0; 
     5172    my $use_sha256 = 0; 
    51285173    if ($config{'DIGEST_TYPE'} eq 'ALL') { 
    51295174        $found_digest = 1; 
     5175        $use_md5      = 1; 
     5176        $use_sha1     = 1; 
     5177        $use_sha256   = 1; 
    51305178    } else { 
    51315179        if ($config{'DIGEST_TYPE'} =~ /SHA256/) { 
    51325180            $found_digest = 1; 
     5181            $use_sha256 = 1; 
    51335182        } 
    51345183        if ($config{'DIGEST_TYPE'} =~ /SHA1/) { 
    51355184            $found_digest = 1; 
     5185            $use_sha1 = 1; 
    51365186        } 
    51375187        if ($config{'DIGEST_TYPE'} =~ /MD5/) { 
    51385188            $found_digest = 1; 
     5189            $use_md5 = 1; 
    51395190        } 
    51405191    } 
     
    51455196    ### an old fwknop client can send an SPA packet with an 
    51465197    ### MD5 sum 
    5147     require Digest::MD5; 
    5148     Digest::MD5->import(qw(md5_base64)); 
    5149  
    5150     require Digest::SHA; 
    5151     Digest::SHA->import(qw(sha1_base64 sha256_base64)); 
     5198    if ($use_md5) { 
     5199        require Digest::MD5; 
     5200        Digest::MD5->import(qw(md5_base64)); 
     5201    } 
     5202 
     5203    if ($use_sha1 or $use_sha256) { 
     5204        require Digest::SHA; 
     5205        if ($use_sha1 and $use_sha256) { 
     5206            Digest::SHA->import(qw(sha1_base64 sha256_base64)); 
     5207        } elsif ($use_sha1) { 
     5208            Digest::SHA->import(qw(sha1_base64)); 
     5209        } elsif ($use_sha256) { 
     5210            Digest::SHA->import(qw(sha256_base64)); 
     5211        } 
     5212    } 
    51525213 
    51535214    if ($debug) { 
  • fwknop/trunk/test/fwknop_test.pl

    r1262 r1264  
    277277    \&SPA_access_packet_md5); 
    278278&test_driver('(Internal digest alg mis-match) Sniffing SPA packet', 
    279     \&SPA_sniff_decrypt); 
    280 &test_driver('(Internal digest alg mis-match) Verifying SPA packet format', 
    281     \&spa_access_format); 
    282 &test_driver('(Internal digest alg mis-match) Firewall access rules exist', 
    283     \&fw_rules_exist); 
    284 &fw_sleep('(Internal digest alg mis-match)'); 
    285 &test_driver('(Internal digest alg mis-match) Firewall access rules removed', 
     279    \&SPA_sniff_decrypt_sha256); 
     280&test_driver('(Internal digest alg mis-match) Firewall rules do not exist', 
    286281    \&fw_rules_removed); 
    287 &test_driver('(Internal digest alg mis-match) Stopping all fwknopd processes', 
    288     \&stop_fwknopd); 
     282&stop_fwknopd_quiet('(Internal digest alg mis-match)'); 
    289283 
    290284&test_driver('(pcap filter) SPA packet with --Server-port 62203', 
     
    542536&test_driver('(Command execution) Making sure firewall rules do not exist', 
    543537    \&fw_rules_removed); 
     538&stop_fwknopd_quiet('(Command execution)'); 
    544539 
    545540if ($config{'FIREWALL_TYPE'} eq 'iptables') { 
     
    15711566} 
    15721567 
     1568sub SPA_sniff_decrypt_sha256() { 
     1569 
     1570    if (&run_fwknopd($cache_encrypted_spa_packet, 
     1571            $sha256_fwknop_conf, $default_access_conf)) { 
     1572 
     1573        ### now that fwknopd has exited, see if the SPA packet was valid 
     1574        my $found_err = 0; 
     1575        open SE, "< $current_test_file" 
     1576            or die "[*] Could not open $current_test_file: $!"; 
     1577        while (<SE>) { 
     1578            if (/Digest\s+alg\s+mis\-match/) { 
     1579                $found_err = 1; 
     1580                last; 
     1581            } 
     1582        } 
     1583        close SE; 
     1584        if ($found_err) { 
     1585            return 1; 
     1586        } else { 
     1587            return &print_errors("[*] fwknopd accepted excluded digest algorithm type"); 
     1588        } 
     1589    } 
     1590    return &print_errors("[-] Sniff alarm ($sniff_alarm seconds) expired"); 
     1591} 
     1592 
    15731593sub sniff_decrypt() { 
    15741594    my $fwknop_conf = shift;