@Test public void testDelegationTokenAccess() throws Exception { Configuration conf = new Configuration(); conf.set("hadoop.security.authentication", "kerberos"); UserGroupInformation.setConfiguration(conf); final File testDir = getTestDir(); conf = createBaseKMSConf(testDir); conf.set("hadoop.kms.authentication.type", "kerberos"); conf.set("hadoop.kms.authentication.kerberos.keytab", keytab.getAbsolutePath()); conf.set("hadoop.kms.authentication.kerberos.principal", "HTTP/localhost"); conf.set("hadoop.kms.authentication.kerberos.name.rules", "DEFAULT"); conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "kA.ALL", "*"); conf.set(KeyAuthorizationKeyProvider.KEY_ACL + "kD.ALL", "*"); writeConf(testDir, conf); runServer(null, null, testDir, new KMSCallable<Void>() { @Override public Void call() throws Exception { final Configuration conf = new Configuration(); conf.setInt(KeyProvider.DEFAULT_BITLENGTH_NAME, 64); final URI uri = createKMSUri(getKMSUrl()); final Credentials credentials = new Credentials(); final UserGroupInformation nonKerberosUgi = UserGroupInformation.getCurrentUser(); try { KeyProvider kp = new KMSClientProvider(uri, conf); kp.createKey("kA", new KeyProvider.Options(conf)); } catch (IOException ex) { System.out.println(ex.getMessage()); } doAs("client", new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { KeyProvider kp = new KMSClientProvider(uri, conf); KeyProviderDelegationTokenExtension kpdte = KeyProviderDelegationTokenExtension. createKeyProviderDelegationTokenExtension(kp); kpdte.addDelegationTokens("foo", credentials); return null; } }); nonKerberosUgi.addCredentials(credentials); try { KeyProvider kp = new KMSClientProvider(uri, conf); kp.createKey("kA", new KeyProvider.Options(conf)); } catch (IOException ex) { System.out.println(ex.getMessage()); } nonKerberosUgi.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { KeyProvider kp = new KMSClientProvider(uri, conf); kp.createKey("kD", new KeyProvider.Options(conf)); return null; } }); return null; } }); }
@POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") public Response createKey(Map jsonKey) throws Exception { KMSWebApp.getAdminCallsMeter().mark(); UserGroupInformation user = HttpUserGroupInformation.get(); final String name = (String) jsonKey.get(KMSRESTConstants.NAME_FIELD); KMSClientProvider.checkNotEmpty(name, KMSRESTConstants.NAME_FIELD); assertAccess(KMSACLs.Type.CREATE, user, KMSOp.CREATE_KEY, name); String cipher = (String) jsonKey.get(KMSRESTConstants.CIPHER_FIELD); final String material = (String) jsonKey.get(KMSRESTConstants.MATERIAL_FIELD); int length = (jsonKey.containsKey(KMSRESTConstants.LENGTH_FIELD)) ? (Integer) jsonKey.get(KMSRESTConstants.LENGTH_FIELD) : 0; String description = (String) jsonKey.get(KMSRESTConstants.DESCRIPTION_FIELD); Map<String, String> attributes = (Map<String, String>) jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD); if (material != null) { assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, name); } final KeyProvider.Options options = new KeyProvider.Options( KMSWebApp.getConfiguration()); if (cipher != null) { options.setCipher(cipher); } if (length != 0) { options.setBitLength(length); } options.setDescription(description); options.setAttributes(attributes); KeyProvider.KeyVersion keyVersion = user.doAs( new PrivilegedExceptionAction<KeyVersion>() { @Override public KeyVersion run() throws Exception { KeyProvider.KeyVersion keyVersion = (material != null) ? provider.createKey(name, Base64.decodeBase64(material), options) : provider.createKey(name, options); provider.flush(); return keyVersion; } } ); kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" + (material != null) + " Description:" + description); if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) { keyVersion = removeKeyMaterial(keyVersion); } Map json = KMSServerJSONUtils.toJSON(keyVersion); String requestURL = KMSMDCFilter.getURL(); int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE); requestURL = requestURL.substring(0, idx); String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name; return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON). header("Location", keyURL).entity(json).build(); }
KMS { @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") public Response createKey(Map jsonKey) throws Exception { KMSWebApp.getAdminCallsMeter().mark(); UserGroupInformation user = HttpUserGroupInformation.get(); final String name = (String) jsonKey.get(KMSRESTConstants.NAME_FIELD); KMSClientProvider.checkNotEmpty(name, KMSRESTConstants.NAME_FIELD); assertAccess(KMSACLs.Type.CREATE, user, KMSOp.CREATE_KEY, name); String cipher = (String) jsonKey.get(KMSRESTConstants.CIPHER_FIELD); final String material = (String) jsonKey.get(KMSRESTConstants.MATERIAL_FIELD); int length = (jsonKey.containsKey(KMSRESTConstants.LENGTH_FIELD)) ? (Integer) jsonKey.get(KMSRESTConstants.LENGTH_FIELD) : 0; String description = (String) jsonKey.get(KMSRESTConstants.DESCRIPTION_FIELD); Map<String, String> attributes = (Map<String, String>) jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD); if (material != null) { assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, name); } final KeyProvider.Options options = new KeyProvider.Options( KMSWebApp.getConfiguration()); if (cipher != null) { options.setCipher(cipher); } if (length != 0) { options.setBitLength(length); } options.setDescription(description); options.setAttributes(attributes); KeyProvider.KeyVersion keyVersion = user.doAs( new PrivilegedExceptionAction<KeyVersion>() { @Override public KeyVersion run() throws Exception { KeyProvider.KeyVersion keyVersion = (material != null) ? provider.createKey(name, Base64.decodeBase64(material), options) : provider.createKey(name, options); provider.flush(); return keyVersion; } } ); kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" + (material != null) + " Description:" + description); if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) { keyVersion = removeKeyMaterial(keyVersion); } Map json = KMSServerJSONUtils.toJSON(keyVersion); String requestURL = KMSMDCFilter.getURL(); int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE); requestURL = requestURL.substring(0, idx); String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name; return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON). header("Location", keyURL).entity(json).build(); } }
KMS { @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") public Response createKey(Map jsonKey) throws Exception { KMSWebApp.getAdminCallsMeter().mark(); UserGroupInformation user = HttpUserGroupInformation.get(); final String name = (String) jsonKey.get(KMSRESTConstants.NAME_FIELD); KMSClientProvider.checkNotEmpty(name, KMSRESTConstants.NAME_FIELD); assertAccess(KMSACLs.Type.CREATE, user, KMSOp.CREATE_KEY, name); String cipher = (String) jsonKey.get(KMSRESTConstants.CIPHER_FIELD); final String material = (String) jsonKey.get(KMSRESTConstants.MATERIAL_FIELD); int length = (jsonKey.containsKey(KMSRESTConstants.LENGTH_FIELD)) ? (Integer) jsonKey.get(KMSRESTConstants.LENGTH_FIELD) : 0; String description = (String) jsonKey.get(KMSRESTConstants.DESCRIPTION_FIELD); Map<String, String> attributes = (Map<String, String>) jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD); if (material != null) { assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, name); } final KeyProvider.Options options = new KeyProvider.Options( KMSWebApp.getConfiguration()); if (cipher != null) { options.setCipher(cipher); } if (length != 0) { options.setBitLength(length); } options.setDescription(description); options.setAttributes(attributes); KeyProvider.KeyVersion keyVersion = user.doAs( new PrivilegedExceptionAction<KeyVersion>() { @Override public KeyVersion run() throws Exception { KeyProvider.KeyVersion keyVersion = (material != null) ? provider.createKey(name, Base64.decodeBase64(material), options) : provider.createKey(name, options); provider.flush(); return keyVersion; } } ); kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" + (material != null) + " Description:" + description); if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) { keyVersion = removeKeyMaterial(keyVersion); } Map json = KMSServerJSONUtils.toJSON(keyVersion); String requestURL = KMSMDCFilter.getURL(); int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE); requestURL = requestURL.substring(0, idx); String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name; return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON). header("Location", keyURL).entity(json).build(); } KMS(); }
KMS { @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") public Response createKey(Map jsonKey) throws Exception { KMSWebApp.getAdminCallsMeter().mark(); UserGroupInformation user = HttpUserGroupInformation.get(); final String name = (String) jsonKey.get(KMSRESTConstants.NAME_FIELD); KMSClientProvider.checkNotEmpty(name, KMSRESTConstants.NAME_FIELD); assertAccess(KMSACLs.Type.CREATE, user, KMSOp.CREATE_KEY, name); String cipher = (String) jsonKey.get(KMSRESTConstants.CIPHER_FIELD); final String material = (String) jsonKey.get(KMSRESTConstants.MATERIAL_FIELD); int length = (jsonKey.containsKey(KMSRESTConstants.LENGTH_FIELD)) ? (Integer) jsonKey.get(KMSRESTConstants.LENGTH_FIELD) : 0; String description = (String) jsonKey.get(KMSRESTConstants.DESCRIPTION_FIELD); Map<String, String> attributes = (Map<String, String>) jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD); if (material != null) { assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, name); } final KeyProvider.Options options = new KeyProvider.Options( KMSWebApp.getConfiguration()); if (cipher != null) { options.setCipher(cipher); } if (length != 0) { options.setBitLength(length); } options.setDescription(description); options.setAttributes(attributes); KeyProvider.KeyVersion keyVersion = user.doAs( new PrivilegedExceptionAction<KeyVersion>() { @Override public KeyVersion run() throws Exception { KeyProvider.KeyVersion keyVersion = (material != null) ? provider.createKey(name, Base64.decodeBase64(material), options) : provider.createKey(name, options); provider.flush(); return keyVersion; } } ); kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" + (material != null) + " Description:" + description); if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) { keyVersion = removeKeyMaterial(keyVersion); } Map json = KMSServerJSONUtils.toJSON(keyVersion); String requestURL = KMSMDCFilter.getURL(); int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE); requestURL = requestURL.substring(0, idx); String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name; return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON). header("Location", keyURL).entity(json).build(); } KMS(); @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") Response createKey(Map jsonKey); @DELETE @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") Response deleteKey(@PathParam("name") final String name); @POST @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response rolloverKey(@PathParam("name") final String name,
      Map jsonMaterial); @GET @Path(KMSRESTConstants.KEYS_METADATA_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeysMetadata(@QueryParam(KMSRESTConstants.KEY)
      List<String> keyNamesList); @GET @Path(KMSRESTConstants.KEYS_NAMES_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeyNames(); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") Response getKey(@PathParam("name") String name); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.METADATA_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getMetadata(@PathParam("name") final String name); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.CURRENT_VERSION_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getCurrentVersion(@PathParam("name") final String name); @GET @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}") @Produces(MediaType.APPLICATION_JSON) Response getKeyVersion(
      @PathParam("versionName") final String versionName); @SuppressWarnings({ "rawtypes", "unchecked" }) @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response generateEncryptedKeys(
          @PathParam("name") final String name,
          @QueryParam(KMSRESTConstants.EEK_OP) String edekOp,
          @DefaultValue("1")
          @QueryParam(KMSRESTConstants.EEK_NUM_KEYS) final int numKeys); @SuppressWarnings("rawtypes") @POST @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response decryptEncryptedKey(
      @PathParam("versionName") final String versionName,
      @QueryParam(KMSRESTConstants.EEK_OP) String eekOp,
      Map jsonPayload); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.VERSIONS_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeyVersions(@PathParam("name") final String name); }
KMS { @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") public Response createKey(Map jsonKey) throws Exception { KMSWebApp.getAdminCallsMeter().mark(); UserGroupInformation user = HttpUserGroupInformation.get(); final String name = (String) jsonKey.get(KMSRESTConstants.NAME_FIELD); KMSClientProvider.checkNotEmpty(name, KMSRESTConstants.NAME_FIELD); assertAccess(KMSACLs.Type.CREATE, user, KMSOp.CREATE_KEY, name); String cipher = (String) jsonKey.get(KMSRESTConstants.CIPHER_FIELD); final String material = (String) jsonKey.get(KMSRESTConstants.MATERIAL_FIELD); int length = (jsonKey.containsKey(KMSRESTConstants.LENGTH_FIELD)) ? (Integer) jsonKey.get(KMSRESTConstants.LENGTH_FIELD) : 0; String description = (String) jsonKey.get(KMSRESTConstants.DESCRIPTION_FIELD); Map<String, String> attributes = (Map<String, String>) jsonKey.get(KMSRESTConstants.ATTRIBUTES_FIELD); if (material != null) { assertAccess(KMSACLs.Type.SET_KEY_MATERIAL, user, KMSOp.CREATE_KEY, name); } final KeyProvider.Options options = new KeyProvider.Options( KMSWebApp.getConfiguration()); if (cipher != null) { options.setCipher(cipher); } if (length != 0) { options.setBitLength(length); } options.setDescription(description); options.setAttributes(attributes); KeyProvider.KeyVersion keyVersion = user.doAs( new PrivilegedExceptionAction<KeyVersion>() { @Override public KeyVersion run() throws Exception { KeyProvider.KeyVersion keyVersion = (material != null) ? provider.createKey(name, Base64.decodeBase64(material), options) : provider.createKey(name, options); provider.flush(); return keyVersion; } } ); kmsAudit.ok(user, KMSOp.CREATE_KEY, name, "UserProvidedMaterial:" + (material != null) + " Description:" + description); if (!KMSWebApp.getACLs().hasAccess(KMSACLs.Type.GET, user)) { keyVersion = removeKeyMaterial(keyVersion); } Map json = KMSServerJSONUtils.toJSON(keyVersion); String requestURL = KMSMDCFilter.getURL(); int idx = requestURL.lastIndexOf(KMSRESTConstants.KEYS_RESOURCE); requestURL = requestURL.substring(0, idx); String keyURL = requestURL + KMSRESTConstants.KEY_RESOURCE + "/" + name; return Response.created(getKeyURI(name)).type(MediaType.APPLICATION_JSON). header("Location", keyURL).entity(json).build(); } KMS(); @POST @Path(KMSRESTConstants.KEYS_RESOURCE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") Response createKey(Map jsonKey); @DELETE @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") Response deleteKey(@PathParam("name") final String name); @POST @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Response rolloverKey(@PathParam("name") final String name,
      Map jsonMaterial); @GET @Path(KMSRESTConstants.KEYS_METADATA_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeysMetadata(@QueryParam(KMSRESTConstants.KEY)
      List<String> keyNamesList); @GET @Path(KMSRESTConstants.KEYS_NAMES_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeyNames(); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}") Response getKey(@PathParam("name") String name); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.METADATA_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getMetadata(@PathParam("name") final String name); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.CURRENT_VERSION_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getCurrentVersion(@PathParam("name") final String name); @GET @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}") @Produces(MediaType.APPLICATION_JSON) Response getKeyVersion(
      @PathParam("versionName") final String versionName); @SuppressWarnings({ "rawtypes", "unchecked" }) @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response generateEncryptedKeys(
          @PathParam("name") final String name,
          @QueryParam(KMSRESTConstants.EEK_OP) String edekOp,
          @DefaultValue("1")
          @QueryParam(KMSRESTConstants.EEK_NUM_KEYS) final int numKeys); @SuppressWarnings("rawtypes") @POST @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}/" + KMSRESTConstants.EEK_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response decryptEncryptedKey(
      @PathParam("versionName") final String versionName,
      @QueryParam(KMSRESTConstants.EEK_OP) String eekOp,
      Map jsonPayload); @GET @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" + KMSRESTConstants.VERSIONS_SUB_RESOURCE) @Produces(MediaType.APPLICATION_JSON) Response getKeyVersions(@PathParam("name") final String name);  }