aboutsummaryrefslogtreecommitdiff
path: root/perl/t
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2007-09-25 20:57:06 +0000
committerRuss Allbery <rra@stanford.edu>2007-09-25 20:57:06 +0000
commit766ba9295705be7c91593b6e7ce5db66bf88d453 (patch)
treee568ee88b65b3d1b592a74d32e34fd4f2f063847 /perl/t
parent3242b66fbf8274991d3fbb0d02ca85e1e2ca60b6 (diff)
Add support for synchronizing a key with an AFS kaserver in the keytab
object implementation, extracting the DES key with Authen::Krb5 (since ktutil doesn't work). Rename the KEYTAB_CACHE variable to KEYTAB_REMCTL_CACHE to match the rest of the keytab retrieval configuration and reorganize the Wallet::Config documentation to group related configuration options for the keytab backend. Fix a column name in the keytab_enctypes table to be more consistent with the rest of the schema.
Diffstat (limited to 'perl/t')
-rw-r--r--perl/t/data/README17
-rwxr-xr-xperl/t/keytab.t121
-rwxr-xr-xperl/t/schema.t2
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';