Return-Path: X-Original-To: apmail-hadoop-common-commits-archive@www.apache.org Delivered-To: apmail-hadoop-common-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9ABAD18277 for ; Mon, 2 Nov 2015 21:51:59 +0000 (UTC) Received: (qmail 45695 invoked by uid 500); 2 Nov 2015 21:51:59 -0000 Delivered-To: apmail-hadoop-common-commits-archive@hadoop.apache.org Received: (qmail 45598 invoked by uid 500); 2 Nov 2015 21:51:59 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: common-dev@hadoop.apache.org Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 45589 invoked by uid 99); 2 Nov 2015 21:51:59 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Nov 2015 21:51:59 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 04E82E0942; Mon, 2 Nov 2015 21:51:59 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: zhz@apache.org To: common-commits@hadoop.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: hadoop git commit: HDFS-9339. Extend full test of KMS ACLs. Contributed by Daniel Templeton. Date: Mon, 2 Nov 2015 21:51:59 +0000 (UTC) Repository: hadoop Updated Branches: refs/heads/trunk 9e7dcab18 -> 78d689086 HDFS-9339. Extend full test of KMS ACLs. Contributed by Daniel Templeton. Change-Id: I61eeee8fa5e85250eabc1eef3d8c11f32700d6fb Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/78d68908 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/78d68908 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/78d68908 Branch: refs/heads/trunk Commit: 78d6890865424db850faecfc5c76f14c64925063 Parents: 9e7dcab Author: Zhe Zhang Authored: Mon Nov 2 13:51:45 2015 -0800 Committer: Zhe Zhang Committed: Mon Nov 2 13:51:45 2015 -0800 ---------------------------------------------------------------------- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 2 + .../apache/hadoop/hdfs/TestAclsEndToEnd.java | 1042 +++++++++++++++++- 2 files changed, 1041 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/78d68908/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index a2e4824..fea4106 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -1613,6 +1613,8 @@ Release 2.8.0 - UNRELEASED HDFS-9229. Expose size of NameNode directory as a metric. (Surendra Singh Lilhore via zhz) + HDFS-9339. Extend full test of KMS ACLs. (Daniel Templeton via zhz) + OPTIMIZATIONS HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than http://git-wip-us.apache.org/repos/asf/hadoop/blob/78d68908/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestAclsEndToEnd.java ---------------------------------------------------------------------- diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestAclsEndToEnd.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestAclsEndToEnd.java index de0646a..2b515d0 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestAclsEndToEnd.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestAclsEndToEnd.java @@ -233,15 +233,15 @@ public class TestAclsEndToEnd { keyadminUgi.getUserName()); conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.ROLLOVER", keyadminUgi.getUserName()); - conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET", ""); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET", " "); conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_KEYS", keyadminUgi.getUserName()); conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", hdfsUgi.getUserName()); - conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.SET_KEY_MATERIAL", ""); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.SET_KEY_MATERIAL", " "); conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", hdfsUgi.getUserName()); - conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", ""); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", "*"); return conf; } @@ -478,6 +478,1042 @@ public class TestAclsEndToEnd { } /** + * Test that key creation is correctly governed by ACLs. + * @throws Exception thrown if setup fails + */ + @Test + public void testCreateKey() throws Exception { + Configuration conf = new Configuration(); + + // Correct config with whitelist ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertTrue("Exception during key creation with correct config" + + " using whitelist key ACLs", createKey(realUgi, KEY1, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Correct config with default ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertTrue("Exception during key creation with correct config" + + " using default key ACLs", createKey(realUgi, KEY2, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertFalse("Allowed key creation with blacklist for CREATE", + createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Missing KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", " "); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertFalse("Allowed key creation without CREATE KMS ACL", + createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Missing key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + + try { + setup(conf); + + assertFalse("Allowed key creation without MANAGMENT key ACL", + createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because the key ACL set ignores the default ACL set for key3 + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + conf.set(KeyAuthorizationKeyProvider.KEY_ACL + KEY3 + ".DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf); + + assertFalse("Allowed key creation when default key ACL should have been" + + " overridden by key ACL", createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Allowed because the default setting for KMS ACLs is fully permissive + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertTrue("Exception during key creation with default KMS ACLs", + createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + } + + /** + * Test that zone creation is correctly governed by ACLs. + * @throws Exception thrown if setup fails + */ + @Test + public void testCreateEncryptionZone() throws Exception { + Configuration conf = new Configuration(); + + // Create a test key + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertTrue("Exception during key creation", + createKey(realUgi, KEY1, conf)); + } finally { + teardown(); + } + + // We tear everything down and then restart it with the ACLs we want to + // test so that there's no contamination from the ACLs needed for setup. + // To make that work, we have to tell the setup() method not to create a + // new KMS directory. + conf = new Configuration(); + + // Correct config with whitelist ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE1); + + assertTrue("Exception during zone creation with correct config using" + + " whitelist key ACLs", createEncryptionZone(realUgi, KEY1, ZONE1)); + } finally { + fs.delete(ZONE1, true); + teardown(); + } + + conf = new Configuration(); + + // Correct config with default ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE2); + + assertTrue("Exception during zone creation with correct config using" + + " default key ACLs", createEncryptionZone(realUgi, KEY1, ZONE2)); + } finally { + fs.delete(ZONE2, true); + teardown(); + } + + conf = new Configuration(); + + // Denied because the key ACL set ignores the default ACL set for key1 + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KeyAuthorizationKeyProvider.KEY_ACL + KEY1 + ".DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE3); + + assertFalse("Allowed creation of zone when default key ACLs should have" + + " been overridden by key ACL", + createEncryptionZone(realUgi, KEY1, ZONE3)); + } finally { + fs.delete(ZONE3, true); + teardown(); + } + + conf = new Configuration(); + + // Correct config with blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE3); + + assertFalse("Allowed zone creation of zone with blacklisted GET_METADATA", + createEncryptionZone(realUgi, KEY1, ZONE3)); + } finally { + fs.delete(ZONE3, true); + teardown(); + } + + conf = new Configuration(); + + // Correct config with blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE3); + + assertFalse("Allowed zone creation of zone with blacklisted GENERATE_EEK", + createEncryptionZone(realUgi, KEY1, ZONE3)); + } finally { + fs.delete(ZONE3, true); + teardown(); + } + + conf = new Configuration(); + + // Missing KMS ACL but works because defaults for KMS ACLs are fully + // permissive + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE3); + + assertTrue("Exception during zone creation with default KMS ACLs", + createEncryptionZone(realUgi, KEY1, ZONE3)); + } finally { + fs.delete(ZONE3, true); + teardown(); + } + + conf = new Configuration(); + + // Missing GET_METADATA KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", " "); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE4); + + assertFalse("Allowed zone creation without GET_METADATA KMS ACL", + createEncryptionZone(realUgi, KEY1, ZONE4)); + } finally { + fs.delete(ZONE4, true); + teardown(); + } + + conf = new Configuration(); + + // Missing GET_METADATA KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", " "); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE4); + + assertFalse("Allowed zone creation without GENERATE_EEK KMS ACL", + createEncryptionZone(realUgi, KEY1, ZONE4)); + } finally { + fs.delete(ZONE4, true); + teardown(); + } + + conf = new Configuration(); + + // Missing READ key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE4); + + assertFalse("Allowed zone creation without READ ACL", + createEncryptionZone(realUgi, KEY1, ZONE4)); + } finally { + fs.delete(ZONE4, true); + teardown(); + } + + conf = new Configuration(); + + // Missing GENERATE_EEK key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + + try { + setup(conf, false); + + fs.mkdirs(ZONE4); + + assertFalse("Allowed zone creation without GENERATE_EEK ACL", + createEncryptionZone(realUgi, KEY1, ZONE4)); + } finally { + fs.delete(ZONE4, true); + teardown(); + } + } + + /** + * Test that in-zone file creation is correctly governed by ACLs. + * @throws Exception thrown if setup fails + */ + @Test + public void testCreateFileInEncryptionZone() throws Exception { + Configuration conf = new Configuration(); + + // Create a test key + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + assertTrue(new File(kmsDir, "kms.keystore").length() == 0); + + try { + setup(conf); + + assertTrue("Exception during key creation", + createKey(realUgi, KEY1, conf)); + fs.mkdirs(ZONE1); + assertTrue("Exception during zone creation", + createEncryptionZone(realUgi, KEY1, ZONE1)); + fs.mkdirs(ZONE2); + assertTrue("Exception during zone creation", + createEncryptionZone(realUgi, KEY1, ZONE2)); + fs.mkdirs(ZONE3); + assertTrue("Exception during zone creation", + createEncryptionZone(realUgi, KEY1, ZONE3)); + fs.mkdirs(ZONE4); + assertTrue("Exception during zone creation", + createEncryptionZone(realUgi, KEY1, ZONE4)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + fs.delete(ZONE2, true); + fs.delete(ZONE3, true); + fs.delete(ZONE4, true); + + throw ex; + } finally { + teardown(); + } + + // We tear everything down and then restart it with the ACLs we want to + // test so that there's no contamination from the ACLs needed for setup. + // To make that work, we have to tell the setup() method not to create a + // new KMS directory or DFS dierctory. + + conf = new Configuration(); + + // Correct config with whitelist ACLs + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception during file creation with correct config" + + " using whitelist ACL", createFile(realUgi, FILE1, TEXT)); + } finally { + fs.delete(ZONE1, true); + teardown(); + } + + conf = new Configuration(); + + // Correct config with default ACLs + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception during file creation with correct config" + + " using whitelist ACL", createFile(realUgi, FILE2, TEXT)); + } finally { + fs.delete(ZONE2, true); + teardown(); + } + + conf = new Configuration(); + + // Denied because the key ACL set ignores the default ACL set for key1 + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KeyAuthorizationKeyProvider.KEY_ACL + KEY1 + ".READ", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation when default key ACLs should have been" + + " overridden by key ACL", createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied by blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation with blacklist for GENERATE_EEK", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied by blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation with blacklist for DECRYPT_EEK", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Allowed because default KMS ACLs are fully permissive + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception during file creation with default KMS ACLs", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of missing GENERATE_EEK KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", " "); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation without GENERATE_EEK KMS ACL", + createFile(realUgi, FILE4, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of missing DECRYPT_EEK KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", " "); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation without DECRYPT_EEK KMS ACL", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of missing GENERATE_EEK key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation without GENERATE_EEK key ACL", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of missing DECRYPT_EEK key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file creation without DECRYPT_EEK key ACL", + createFile(realUgi, FILE3, TEXT)); + } catch (Exception ex) { + fs.delete(ZONE3, true); + + throw ex; + } finally { + teardown(); + } + } + + /** + * Test that in-zone file read is correctly governed by ACLs. + * @throws Exception thrown if setup fails + */ + @Test + public void testReadFileInEncryptionZone() throws Exception { + Configuration conf = new Configuration(); + + // Create a test key + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GET_METADATA", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "READ", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "GENERATE_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + assertTrue(new File(kmsDir, "kms.keystore").length() == 0); + + try { + setup(conf); + + assertTrue("Exception during key creation", + createKey(realUgi, KEY1, conf)); + fs.mkdirs(ZONE1); + assertTrue("Exception during zone creation", + createEncryptionZone(realUgi, KEY1, ZONE1)); + assertTrue("Exception during file creation", + createFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + // We tear everything down and then restart it with the ACLs we want to + // test so that there's no contamination from the ACLs needed for setup. + // To make that work, we have to tell the setup() method not to create a + // new KMS directory or DFS dierctory. + + conf = new Configuration(); + + // Correct config with whitelist ACLs + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception while reading file with correct config with" + + " whitelist ACLs", compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Correct config with default ACLs + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception while reading file with correct config" + + " with default ACLs", compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because the key ACL set ignores the default ACL set for key1 + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KeyAuthorizationKeyProvider.KEY_ACL + KEY1 + ".READ", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file read when default key ACLs should have been" + + " overridden by key ACL", compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied by blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.DECRYPT_EEK", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file read with blacklist for DECRYPT_EEK", + compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Allowed because default KMS ACLs are fully permissive + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertTrue("Exception while reading file with default KMS ACLs", + compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of missing DECRYPT_EEK KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DECRYPT_EEK", " "); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false, false); + + assertFalse("Allowed file read without DECRYPT_EEK KMS ACL", + compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + + // Denied because of missing DECRYPT_EEK key ACL + conf = new Configuration(); + + try { + setup(conf, false, false); + + assertFalse("Allowed file read without DECRYPT_EEK key ACL", + compareFile(realUgi, FILE1, TEXT)); + } catch (Throwable ex) { + fs.delete(ZONE1, true); + + throw ex; + } finally { + teardown(); + } + } + + /** + * Test that key deletion is correctly governed by ACLs. + * @throws Exception thrown if setup fails + */ + @Test + public void testDeleteKey() throws Exception { + Configuration conf = new Configuration(); + + // Create a test key + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.CREATE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf); + + assertTrue("Exception during key creation", + createKey(realUgi, KEY1, conf)); + assertTrue("Exception during key creation", + createKey(realUgi, KEY2, conf)); + assertTrue("Exception during key creation", + createKey(realUgi, KEY3, conf)); + } finally { + teardown(); + } + + // We tear everything down and then restart it with the ACLs we want to + // test so that there's no contamination from the ACLs needed for setup. + // To make that work, we have to tell the setup() method not to create a + // new KMS directory. + + conf = new Configuration(); + + // Correct config with whitelist ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertTrue("Exception during key deletion with correct config" + + " using whitelist key ACLs", deleteKey(realUgi, KEY1)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Correct config with default ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertTrue("Exception during key deletion with correct config" + + " using default key ACLs", deleteKey(realUgi, KEY2)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because of blacklist + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", + realUgi.getUserName()); + conf.set(KMSConfiguration.CONFIG_PREFIX + "blacklist.DELETE", + realUgi.getUserName()); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertFalse("Allowed key deletion with blacklist for DELETE", + deleteKey(realUgi, KEY3)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Missing KMS ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", " "); + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertFalse("Allowed key deletion without DELETE KMS ACL", + deleteKey(realUgi, KEY3)); + } finally { + teardown(); + } + + conf = new Configuration(); + + + // Missing key ACL + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertFalse("Allowed key deletion without MANAGMENT key ACL", + deleteKey(realUgi, KEY3)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Denied because the key ACL set ignores the default ACL set for key3 + conf.set(KMSConfiguration.CONFIG_PREFIX + "acl.DELETE", + realUgi.getUserName()); + conf.set(KMSConfiguration.DEFAULT_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + conf.set(KeyAuthorizationKeyProvider.KEY_ACL + KEY3 + ".DECRYPT_EEK", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertFalse("Allowed key deletion when default key ACL should have been" + + " overridden by key ACL", deleteKey(realUgi, KEY3)); + } finally { + teardown(); + } + + conf = new Configuration(); + + // Allowed because the default setting for KMS ACLs is fully permissive + conf.set(KMSConfiguration.WHITELIST_KEY_ACL_PREFIX + "MANAGEMENT", + realUgi.getUserName()); + + try { + setup(conf, false); + + assertTrue("Exception during key deletion with default KMS ACLs", + deleteKey(realUgi, KEY3)); + } finally { + teardown(); + } + } + + /** * Create a key as the specified user. * * @param ugi the target user