diff options
author | Russ Allbery <rra@stanford.edu> | 2007-11-15 05:42:29 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2007-11-15 05:42:29 +0000 |
commit | 2393ffbc3c52c6552e00212d5209d6b870a55d4e (patch) | |
tree | 2eaca996ede5d9b835db69f6ac143e8cba051d36 /perl/t | |
parent | b6bb3f3a72ec1dc32991cffeeab4f8b1cc27cc46 (diff) |
Add an ACL verifier that checks access against NetDB roles using the
NetDB remctl interface.
Diffstat (limited to 'perl/t')
-rw-r--r-- | perl/t/data/keytab.conf | 10 | ||||
-rwxr-xr-x | perl/t/data/netdb-fake | 58 | ||||
-rw-r--r-- | perl/t/data/netdb.conf | 10 | ||||
-rwxr-xr-x | perl/t/verifier.t | 134 |
4 files changed, 204 insertions, 8 deletions
diff --git a/perl/t/data/keytab.conf b/perl/t/data/keytab.conf index eb105e2..e7908ed 100644 --- a/perl/t/data/keytab.conf +++ b/perl/t/data/keytab.conf @@ -1,10 +1,6 @@ # $Id$ # -# This is the remctl configuration used for testing the keytab backend's -# ability to retrieve existing keytabs through remctl. Currently the only -# supported and used command is keytab retrieve. The ACL is written on -# the fly by the test program. -# -# Compare to config/keytab. +# This is the remctl configuration used for testing the NetDB ACL verifier. +# The ACL is written on the fly by the test program. -keytab retrieve t/data/keytab-fake test-acl +netdb node-roles t/data/netdb-fake test-acl diff --git a/perl/t/data/netdb-fake b/perl/t/data/netdb-fake new file mode 100755 index 0000000..56744a7 --- /dev/null +++ b/perl/t/data/netdb-fake @@ -0,0 +1,58 @@ +#!/bin/sh +# $Id$ +# +# netdb-fake -- Fake NetDB remctl interface. +# +# This netdb-fake script is meant to be run by remctld during testing of +# the NetDB ACL verifier. It returns known roles or errors for different +# nodes. + +set -e + +if [ "$1" != "node-roles" ] ; then + echo "Invalid command $1" >&2 + exit 1 +fi + +case "$2" in +test-user) + case "$3" in + all) + echo 'admin' + echo 'team' + echo 'user' + ;; + admin) + echo 'admin' + ;; + team) + echo 'team' + ;; + user) + echo 'This is just ignored' >&2 + echo 'user' + ;; + unknown) + echo 'admin' >&2 + echo 'unknown' + ;; + none) + ;; + esac + ;; +error) + case "$3" in + normal) + echo 'some error' >&2 + exit 1 + ;; + status) + exit 1 + ;; + esac + ;; +*) + echo "Unknown principal $2" >&2 + exit 1 + ;; +esac diff --git a/perl/t/data/netdb.conf b/perl/t/data/netdb.conf new file mode 100644 index 0000000..eb105e2 --- /dev/null +++ b/perl/t/data/netdb.conf @@ -0,0 +1,10 @@ +# $Id$ +# +# This is the remctl configuration used for testing the keytab backend's +# ability to retrieve existing keytabs through remctl. Currently the only +# supported and used command is keytab retrieve. The ACL is written on +# the fly by the test program. +# +# Compare to config/keytab. + +keytab retrieve t/data/keytab-fake test-acl diff --git a/perl/t/verifier.t b/perl/t/verifier.t index 713c495..467115f 100755 --- a/perl/t/verifier.t +++ b/perl/t/verifier.t @@ -8,10 +8,67 @@ # # See LICENSE for licensing terms. -use Test::More tests => 13; +use Test::More tests => 37; use Wallet::ACL::Base; use Wallet::ACL::Krb5; +use Wallet::ACL::NetDB; +use Wallet::Config; + +# Returns the one-line contents of a file as a string, removing the newline. +sub contents { + my ($file) = @_; + open (FILE, '<', $file) or die "cannot open $file: $!\n"; + my $data = <FILE>; + close FILE; + chomp $data; + return $data; +} + +# Given a keytab file, try authenticating with kinit. +sub getcreds { + my ($file, $principal) = @_; + my @commands = ( + "kinit -k -t $file $principal >/dev/null </dev/null", + "kinit -t $file $principal >/dev/null </dev/null", + "kinit -k -K $file $principal >/dev/null </dev/null", + ); + for my $command (@commands) { + if (system ($command) == 0) { + return 1; + } + } + return 0; +} + +# Start remctld with the appropriate options to run our fake keytab backend. +sub spawn_remctld { + my ($path, $principal, $keytab) = @_; + unlink 'test-pid'; + my $pid = fork; + if (not defined $pid) { + die "cannot fork: $!\n"; + } elsif ($pid == 0) { + open (STDERR, '>&STDOUT') or die "cannot redirect stderr: $!\n"; + exec ($path, '-m', '-p', 14373, '-s', $principal, '-P', 'test-pid', + '-f', 't/data/keytab.conf', '-S', '-F', '-k', $keytab) == 0 + or die "cannot exec $path: $!\n"; + } else { + my $tries = 0; + while ($tries < 10 && ! -f 'test-pid') { + select (undef, undef, undef, 0.25); + } + } +} + +# Stop the running remctld process. +sub stop_remctld { + open (PID, '<', 'test-pid') or return; + my $pid = <PID>; + close PID; + chomp $pid; + kill 15, $pid; +} my $verifier = Wallet::ACL::Base->new; ok (defined $verifier, 'Wallet::ACL::Base creation'); @@ -33,3 +90,78 @@ is ($verifier->check (undef, 'rra@stanford.edu'), undef, is ($verifier->error, 'no principal specified', ' and right error'); is ($verifier->check ('rra@stanford.edu', ''), undef, 'Empty ACL'); is ($verifier->error, 'malformed krb5 ACL', ' and right error'); + +# Tests for unchanging support. Skip these if we don't have a keytab or if we +# can't find remctld. +SKIP: { + skip 'no keytab configuration', 24 unless -f 't/data/test.keytab'; + my @path = (split (':', $ENV{PATH}), '/usr/local/sbin', '/usr/sbin'); + my ($remctld) = grep { -x $_ } map { "$_/remctld" } @path; + skip 'remctld not found', 24 unless $remctld; + eval { require Net::Remctl }; + skip 'Net::Remctl not available', 24 if $@; + + # Set up our configuration. + $Wallet::Config::NETDB_REALM = 'EXAMPLE.COM'; + my $principal = contents ('t/data/test.principal'); + + # Now spawn our remctld server and get a ticket cache. + unlink ('krb5cc_test', 'test-acl', 'test-pid'); + spawn_remctld ($remctld, $principal, 't/data/test.keytab'); + $ENV{KRB5CCNAME} = 'krb5cc_test'; + getcreds ('t/data/test.keytab', $principal); + + # Finally, we can test. + my $verifier = eval { Wallet::ACL::NetDB->new }; + is ($verifier, undef, 'Constructor fails without configuration'); + is ($@, "NetDB ACL support not configured\n", ' with the right exception'); + $Wallet::Config::NETDB_REMCTL_CACHE = 'krb5cc_test'; + $verifier = eval { Wallet::ACL::NetDB->new }; + is ($verifier, undef, ' and still fails without host'); + is ($@, "NetDB ACL support not configured\n", ' with the right exception'); + $Wallet::Config::NETDB_REMCTL_HOST = 'localhost'; + $Wallet::Config::NETDB_REMCTL_PRINCIPAL = $principal; + $Wallet::Config::NETDB_REMCTL_PORT = 14373; + $verifier = eval { Wallet::ACL::NetDB->new }; + ok (defined $verifier, ' and now creation succeeds'); + ok ($verifier->isa ('Wallet::ACL::NetDB'), ' and returns the right class'); + is ($verifier->check ('test-user', 'all'), undef, + ' but verification fails without an ACL'); + is ($verifier->error, 'cannot check NetDB ACL: Access denied', + ' with the right error'); + + # Create an ACL so that tests will start working. + open (ACL, '>', 'test-acl') or die "cannot create test-acl: $!\n"; + print ACL "$principal\n"; + close ACL; + is ($verifier->check ('test-user', 'all'), 1, + ' and now verification works'); + + # Test the successful verifications. + for my $node (qw/admin team user/) { + is ($verifier->check ('test-user', $node), 1, + "Verification succeeds for $node"); + } + + # Test various failures. + is ($verifier->check ('test-user', 'unknown'), 0, + 'Verification fails for unknown'); + is ($verifier->check ('test-user', 'none'), 0, ' and for none'); + is ($verifier->check (undef, 'all'), undef, + 'Undefined principal'); + is ($verifier->error, 'no principal specified', ' and right error'); + is ($verifier->check ('test-user', ''), undef, 'Empty ACL'); + is ($verifier->error, 'malformed netdb ACL', ' and right error'); + is ($verifier->check ('error', 'normal'), undef, 'Regular error'); + is ($verifier->error, 'error checking NetDB ACL: some error', + ' and correct error return'); + is ($verifier->check ('error', 'status'), undef, 'Status-only error'); + is ($verifier->error, 'error checking NetDB ACL', ' and correct error'); + is ($verifier->check ('unknown', 'unknown'), undef, 'Unknown node'); + is ($verifier->error, + 'error checking NetDB ACL: Unknown principal unknown', + ' and correct error'); + stop_remctld; + + unlink ('krb5cc_test', 'test-acl', 'test-pid'); +} |