diff options
Diffstat (limited to 'perl/t')
-rw-r--r-- | perl/t/data/README | 17 | ||||
-rwxr-xr-x | perl/t/keytab.t | 121 | ||||
-rwxr-xr-x | perl/t/schema.t | 2 |
3 files changed, 136 insertions, 4 deletions
diff --git a/perl/t/data/README b/perl/t/data/README index 33ec32f..968ec6c 100644 --- a/perl/t/data/README +++ b/perl/t/data/README @@ -27,3 +27,20 @@ and <realm> is the Kerberos realm. Again, I do not recommend using a production realm; the test doesn't need a production realm and it's more secure to stick to a test realm. + +In order to test the AFS kaserver synchronization, you will need to grant +the test processes access to a principal with ADMIN rights in a test AFS +kaserver. This should not be pointed at a production cell! Create the +following files: + + test.admin Fully-qualified principal of ADMIN user + test.cell AFS kaserver test cell + +The ADMIN user will be parsed to determine the default realm for +principals created in the kaserver. You cannot use cross-realm +authentication for this test. This AFS kaserver Kerberos v4 realm will +also need to be configured in your local krb.conf (but not krb.realms). + +The test process will create the principals wallet.one and wallet.two and +on success will clean up after itself. If the test fails, they may be +left behind in the AFS kaserver. diff --git a/perl/t/keytab.t b/perl/t/keytab.t index 7b9a067..d90699c 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -3,7 +3,7 @@ # # t/keytab.t -- Tests for the keytab object implementation. -use Test::More tests => 66; +use Test::More tests => 96; use Wallet::Config; use Wallet::Object::Keytab; @@ -12,7 +12,7 @@ use Wallet::Server; # Use a local SQLite database for testing. $Wallet::Config::DB_DRIVER = 'SQLite'; $Wallet::Config::DB_INFO = 'wallet-db'; -unlink 'wallet-db'; +unlink ('wallet-db', 'krb5cc_temp', 'krb5cc_test', 'test-acl', 'test-pid'); # Some global defaults to use. my $user = 'admin@EXAMPLE.COM'; @@ -96,6 +96,21 @@ sub created { return (system_quiet ('kvno', $principal) == 0); } +# Check whether a principal exists in the kaserver. Requires that the admin +# and srvtab variables be set up already. +sub created_kaserver { + my ($principal) = @_; + my $admin = $Wallet::Config::KEYTAB_AFS_ADMIN; + my $srvtab = $Wallet::Config::KEYTAB_AFS_SRVTAB; + my $realm = $Wallet::Config::KEYTAB_AFS_REALM; + my ($name, $instance) = split (/\./, $principal); + $ENV{KRBTKFILE} = 'krb4cc_temp'; + system ("k4start -f $srvtab -r $realm -S $name -I $instance $admin" + . " 2>&1 >/dev/null </dev/null"); + unlink 'krb4cc_temp'; + return ($? == 0) ? 1 : 0; +} + # Given keytab data and the principal, write it to a file and try # authenticating using kinit. sub valid { @@ -111,6 +126,24 @@ sub valid { return $result; } +# Given a Wallet::Object::Keytab object, the keytab data, the Kerberos v5 +# principal, and the Kerberos v4 principal, write the keytab to a file, +# generate a srvtab, and try authenticating using k4start. +sub valid_srvtab { + my ($object, $keytab, $k5, $k4) = @_; + open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n"; + print KEYTAB $keytab; + close KEYTAB; + unless ($object->kaserver_srvtab ('keytab', $k5, 'srvtab', $k4)) { + warn "cannot write srvtab: ", $object->error, "\n"; + return 0; + } + $ENV{KRBTKFILE} = 'krb4cc_temp'; + system ("k4start -f srvtab $k4 2>&1 >/dev/null </dev/null"); + unlink 'keytab', 'srvtab', 'krb4cc_temp'; + return ($? == 0) ? 1 : 0; +} + # Start remctld with the appropriate options to run our fake keytab backend. sub spawn_remctld { my ($path, $principal, $keytab) = @_; @@ -351,7 +384,7 @@ SKIP: { is ($one->get (@trace), undef, 'Get without configuration fails'); is ($one->error, 'keytab unchanging support not configured', ' with the right error'); - $Wallet::Config::KEYTAB_CACHE = 'krb5cc_test'; + $Wallet::Config::KEYTAB_REMCTL_CACHE = 'krb5cc_test'; is ($one->get (@trace), undef, ' and still fails without host'); is ($one->error, 'keytab unchanging support not configured', ' with the right error'); @@ -377,5 +410,87 @@ SKIP: { stop_remctld; } +# Tests for kaserver synchronization support. +SKIP: { + skip 'no keytab configuration', 30 unless -f 't/data/test.keytab'; + skip 'no AFS kaserver configuration', 30 unless -f 't/data/test.srvtab'; + + # Set up our configuration. + $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; + $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal'); + $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm'); + $Wallet::Config::KEYTAB_TMP = '.'; + $Wallet::Config::KEYTAB_AFS_KASETKEY = '../kasetkey/kasetkey'; + my $realm = $Wallet::Config::KEYTAB_REALM; + my $k5 = "wallet/one\@$realm"; + + # Create an object for testing and set the sync attribute. + my $one = eval { + Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace) + }; + ok (defined ($one), 'Creating wallet/one succeeds'); + is ($one->attr ('foo', [ 'bar' ], @trace), undef, + 'Setting unknown attribute fails'); + is ($one->error, 'unknown attribute foo', ' with the right error'); + my @targets = $one->attr ('foo'); + is (scalar (@targets), 0, ' and getting an unknown attribute fails'); + is ($one->error, 'unknown attribute foo', ' with the right error'); + is ($one->attr ('sync', [ 'foo' ], @trace), undef, + ' and setting an unknown sync target fails'); + is ($one->error, 'unsupported synchronization target foo', + ' with the right error'); + is ($one->attr ('sync', [ 'kaserver', 'bar' ], @trace), undef, + ' and setting two targets fails'); + is ($one->error, 'only one synchronization target supported', + ' with the right error'); + is ($one->attr ('sync', [ 'kaserver' ], @trace), 1, + ' but setting only kaserver works'); + @targets = $one->attr ('sync'); + is (scalar (@targets), 1, ' and now one target is set'); + is ($targets[0], 'kaserver', ' and it is correct'); + is ($one->error, undef, ' and there is no error'); + + # Finally, we can test. + is ($one->get (@trace), undef, 'Get without configuration fails'); + is ($one->error, 'kaserver synchronization not configured', + ' with the right error'); + $Wallet::Config::KEYTAB_AFS_ADMIN = contents ('t/data/test.admin'); + my $k4_realm = $Wallet::Config::KEYTAB_AFS_ADMIN; + $k4_realm =~ s/^[^\@]+\@//; + $Wallet::Config::KEYTAB_AFS_REALM = $k4_realm; + my $k4 = "wallet.one\@$k4_realm"; + is ($one->get (@trace), undef, ' and still fails with just admin'); + is ($one->error, 'kaserver synchronization not configured', + ' with the right error'); + $Wallet::Config::KEYTAB_AFS_SRVTAB = 't/data/test.srvtab'; + my $keytab = $one->get (@trace); + if (defined ($keytab)) { + ok (1, ' and now get works'); + } else { + is ($one->error, '', ' and now get works'); + } + ok (valid_srvtab ($one, $keytab, $k5, $k4), ' and the srvtab is valid'); + ok (! -f "./srvtab.$$", ' and the temporary file was cleaned up'); + + # Now remove the sync attribute and make sure things aren't synced. + is ($one->attr ('sync', [], @trace), 1, 'Clearing sync works'); + @targets = $one->attr ('sync'); + is (scalar (@targets), 0, ' and now there is no attribute'); + is ($one->error, undef, ' and no error'); + $keytab = $one->get (@trace); + ok (defined ($keytab), ' and get still works'); + ok (! valid_srvtab ($one, $keytab, $k5, $k4), ' but the srvtab does not'); + ok (created_kaserver ('wallet.one'), ' and the principal is still there'); + + # Put it back and make sure it works again. + is ($one->attr ('sync', [ 'kaserver' ], @trace), 1, 'Setting sync works'); + $keytab = $one->get (@trace); + ok (defined ($keytab), ' and get works'); + ok (valid_srvtab ($one, $keytab, $k5, $k4), ' and the srvtab is valid'); + + # Destroy the principal. + is ($one->destroy (@trace), 1, 'Destroying wallet/one works'); +} + # Clean up. unlink ('wallet-db', 'krb5cc_temp', 'krb5cc_test', 'test-acl', 'test-pid'); diff --git a/perl/t/schema.t b/perl/t/schema.t index 6829700..02993ae 100755 --- a/perl/t/schema.t +++ b/perl/t/schema.t @@ -13,7 +13,7 @@ ok (defined $schema, 'Wallet::Schema creation'); ok ($schema->isa ('Wallet::Schema'), ' and class verification'); my @sql = $schema->sql; ok (@sql > 0, 'sql() returns something'); -is (scalar (@sql), 22, ' and returns the right number of statements'); +is (scalar (@sql), 26, ' and returns the right number of statements'); # Create a SQLite database to use for create. unlink 'wallet-db'; |