ranger-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From v..@apache.org
Subject [2/4] incubator-ranger git commit: (RANGER-247)Development of Ranger Key Storage Provider
Date Tue, 24 Mar 2015 17:27:41 GMT
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
new file mode 100644
index 0000000..3674e7a
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Jersey provider that converts <code>Map</code>s and <code>List</code>s
+ * to their JSON representation.
+ */
+@Provider
+@Produces(MediaType.APPLICATION_JSON)
+@InterfaceAudience.Private
+public class KMSJSONWriter implements MessageBodyWriter<Object> {
+
+  @Override
+  public boolean isWriteable(Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType) {
+    return Map.class.isAssignableFrom(aClass) ||
+        List.class.isAssignableFrom(aClass);
+  }
+
+  @Override
+  public long getSize(Object obj, Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType) {
+    return -1;
+  }
+
+  @Override
+  public void writeTo(Object obj, Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, Object> stringObjectMultivaluedMap,
+      OutputStream outputStream) throws IOException, WebApplicationException {
+    Writer writer = new OutputStreamWriter(outputStream);
+    ObjectMapper jsonMapper = new ObjectMapper();
+    jsonMapper.writerWithDefaultPrettyPrinter().writeValue(writer, obj);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
new file mode 100644
index 0000000..2a3c149
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * Servlet filter that captures context of the HTTP request to be use in the
+ * scope of KMS calls on the server side.
+ */
+@InterfaceAudience.Private
+public class KMSMDCFilter implements Filter {
+
+  private static class Data {
+    private UserGroupInformation ugi;
+    private String method;
+    private StringBuffer url;
+
+    private Data(UserGroupInformation ugi, String method, StringBuffer url) {
+      this.ugi = ugi;
+      this.method = method;
+      this.url = url;
+    }
+  }
+
+  private static ThreadLocal<Data> DATA_TL = new ThreadLocal<Data>();
+
+  public static UserGroupInformation getUgi() {
+    return DATA_TL.get().ugi;
+  }
+
+  public static String getMethod() {
+    return DATA_TL.get().method;
+  }
+
+  public static String getURL() {
+    return DATA_TL.get().url.toString();
+  }
+
+  @Override
+  public void init(FilterConfig config) throws ServletException {
+  }
+
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain)
+      throws IOException, ServletException {
+    try {
+      DATA_TL.remove();
+      UserGroupInformation ugi = HttpUserGroupInformation.get();
+      String method = ((HttpServletRequest) request).getMethod();
+      StringBuffer requestURL = ((HttpServletRequest) request).getRequestURL();
+      String queryString = ((HttpServletRequest) request).getQueryString();
+      if (queryString != null) {
+        requestURL.append("?").append(queryString);
+      }
+      DATA_TL.set(new Data(ugi, method, requestURL));
+      chain.doFilter(request, response);
+    } finally {
+      DATA_TL.remove();
+    }
+  }
+
+  @Override
+  public void destroy() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
new file mode 100644
index 0000000..24af81b
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.crypto.key.KeyProvider;
+import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
+import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JSON utility methods for the KMS.
+ */
+@InterfaceAudience.Private
+public class KMSServerJSONUtils {
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(KeyProvider.KeyVersion keyVersion) {
+    Map json = new LinkedHashMap();
+    if (keyVersion != null) {
+      json.put(KMSRESTConstants.NAME_FIELD,
+          keyVersion.getName());
+      json.put(KMSRESTConstants.VERSION_NAME_FIELD,
+          keyVersion.getVersionName());
+      json.put(KMSRESTConstants.MATERIAL_FIELD,
+          Base64.encodeBase64URLSafeString(
+              keyVersion.getMaterial()));
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static List toJSON(List<KeyProvider.KeyVersion> keyVersions) {
+    List json = new ArrayList();
+    if (keyVersions != null) {
+      for (KeyProvider.KeyVersion version : keyVersions) {
+        json.add(toJSON(version));
+      }
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(EncryptedKeyVersion encryptedKeyVersion) {
+    Map json = new LinkedHashMap();
+    if (encryptedKeyVersion != null) {
+      json.put(KMSRESTConstants.VERSION_NAME_FIELD,
+          encryptedKeyVersion.getEncryptionKeyVersionName());
+      json.put(KMSRESTConstants.IV_FIELD,
+          Base64.encodeBase64URLSafeString(
+              encryptedKeyVersion.getEncryptedKeyIv()));
+      json.put(KMSRESTConstants.ENCRYPTED_KEY_VERSION_FIELD,
+          toJSON(encryptedKeyVersion.getEncryptedKeyVersion()));
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(String keyName, KeyProvider.Metadata meta) {
+    Map json = new LinkedHashMap();
+    if (meta != null) {
+      json.put(KMSRESTConstants.NAME_FIELD, keyName);
+      json.put(KMSRESTConstants.CIPHER_FIELD, meta.getCipher());
+      json.put(KMSRESTConstants.LENGTH_FIELD, meta.getBitLength());
+      json.put(KMSRESTConstants.DESCRIPTION_FIELD, meta.getDescription());
+      json.put(KMSRESTConstants.ATTRIBUTES_FIELD, meta.getAttributes());
+      json.put(KMSRESTConstants.CREATED_FIELD,
+          meta.getCreated().getTime());
+      json.put(KMSRESTConstants.VERSIONS_FIELD,
+          (long) meta.getVersions());
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static List toJSON(String[] keyNames, KeyProvider.Metadata[] metas) {
+    List json = new ArrayList();
+    for (int i = 0; i < keyNames.length; i++) {
+      json.add(toJSON(keyNames[i], metas[i]));
+    }
+    return json;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
new file mode 100644
index 0000000..67b9f88
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
@@ -0,0 +1,307 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.CachingKeyProvider;
+import org.apache.hadoop.crypto.key.KeyProvider;
+import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
+import org.apache.hadoop.crypto.key.KeyProviderFactory;
+import org.apache.hadoop.crypto.key.kms.server.KeyAuthorizationKeyProvider.KeyACLs;
+import org.apache.hadoop.http.HttpServer2;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.util.ReflectionUtils;
+import org.apache.hadoop.util.VersionInfo;
+import org.apache.log4j.PropertyConfigurator;
+import org.mortbay.log.Log;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.bridge.SLF4JBridgeHandler;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+@InterfaceAudience.Private
+public class KMSWebApp implements ServletContextListener {
+
+  private static final String LOG4J_PROPERTIES = "kms-log4j.properties";
+
+  private static final String METRICS_PREFIX = "hadoop.kms.";
+  private static final String ADMIN_CALLS_METER = METRICS_PREFIX +
+      "admin.calls.meter";
+  private static final String KEY_CALLS_METER = METRICS_PREFIX +
+      "key.calls.meter";
+  private static final String INVALID_CALLS_METER = METRICS_PREFIX +
+      "invalid.calls.meter";
+  private static final String UNAUTHORIZED_CALLS_METER = METRICS_PREFIX +
+      "unauthorized.calls.meter";
+  private static final String UNAUTHENTICATED_CALLS_METER = METRICS_PREFIX +
+      "unauthenticated.calls.meter";
+  private static final String GENERATE_EEK_METER = METRICS_PREFIX +
+      "generate_eek.calls.meter";
+  private static final String DECRYPT_EEK_METER = METRICS_PREFIX +
+      "decrypt_eek.calls.meter";
+
+  private static Logger LOG;
+  private static MetricRegistry metricRegistry;
+
+  private JmxReporter jmxReporter;
+  private static Configuration kmsConf;
+  private static KeyACLs kmsAcls;
+  private static Meter adminCallsMeter;
+  private static Meter keyCallsMeter;
+  private static Meter unauthorizedCallsMeter;
+  private static Meter unauthenticatedCallsMeter;
+  private static Meter decryptEEKCallsMeter;
+  private static Meter generateEEKCallsMeter;
+  private static Meter invalidCallsMeter;
+  private static KMSAudit kmsAudit;
+  private static KeyProviderCryptoExtension keyProviderCryptoExtension;
+
+  static {
+    SLF4JBridgeHandler.removeHandlersForRootLogger();
+    SLF4JBridgeHandler.install();
+  }
+
+  private void initLogging(String confDir) {
+    if (System.getProperty("log4j.configuration") == null) {
+      System.setProperty("log4j.defaultInitOverride", "true");
+      boolean fromClasspath = true;
+      File log4jConf = new File(confDir, LOG4J_PROPERTIES).getAbsoluteFile();
+      if (log4jConf.exists()) {
+        PropertyConfigurator.configureAndWatch(log4jConf.getPath(), 1000);
+        fromClasspath = false;
+      } else {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        URL log4jUrl = cl.getResource(LOG4J_PROPERTIES);
+        if (log4jUrl != null) {
+          PropertyConfigurator.configure(log4jUrl);
+        }
+      }
+      LOG = LoggerFactory.getLogger(KMSWebApp.class);
+      LOG.debug("KMS log starting");
+      if (fromClasspath) {
+        LOG.warn("Log4j configuration file '{}' not found", LOG4J_PROPERTIES);
+        LOG.warn("Logging with INFO level to standard output");
+      }
+    } else {
+      LOG = LoggerFactory.getLogger(KMSWebApp.class);
+    }
+  }
+
+  @Override
+  public void contextInitialized(ServletContextEvent sce) {
+    try {
+      String confDir = System.getProperty(KMSConfiguration.KMS_CONFIG_DIR);
+      if (confDir == null) {
+        throw new RuntimeException("System property '" +
+            KMSConfiguration.KMS_CONFIG_DIR + "' not defined");
+      }
+      kmsConf = KMSConfiguration.getKMSConf();
+      initLogging(confDir);
+      LOG.info("-------------------------------------------------------------");
+      LOG.info("  Java runtime version : {}", System.getProperty(
+          "java.runtime.version"));
+      LOG.info("  KMS Hadoop Version: " + VersionInfo.getVersion());
+      LOG.info("-------------------------------------------------------------");
+
+      
+      kmsAcls = getAcls(kmsConf.get(KMSConfiguration.KMS_SECURITY_AUTHORIZER));
+    		  
+      //kmsAcls = new KMSACLs();
+      kmsAcls.startACLReloader();
+
+      metricRegistry = new MetricRegistry();
+      jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+      jmxReporter.start();
+      generateEEKCallsMeter = metricRegistry.register(GENERATE_EEK_METER,
+          new Meter());
+      decryptEEKCallsMeter = metricRegistry.register(DECRYPT_EEK_METER,
+          new Meter());
+      adminCallsMeter = metricRegistry.register(ADMIN_CALLS_METER, new Meter());
+      keyCallsMeter = metricRegistry.register(KEY_CALLS_METER, new Meter());
+      invalidCallsMeter = metricRegistry.register(INVALID_CALLS_METER,
+          new Meter());
+      unauthorizedCallsMeter = metricRegistry.register(UNAUTHORIZED_CALLS_METER,
+          new Meter());
+      unauthenticatedCallsMeter = metricRegistry.register(
+          UNAUTHENTICATED_CALLS_METER, new Meter());
+
+      kmsAudit =
+          new KMSAudit(kmsConf.getLong(
+              KMSConfiguration.KMS_AUDIT_AGGREGATION_WINDOW,
+              KMSConfiguration.KMS_AUDIT_AGGREGATION_WINDOW_DEFAULT));
+
+      // this is required for the the JMXJsonServlet to work properly.
+      // the JMXJsonServlet is behind the authentication filter,
+      // thus the '*' ACL.
+      sce.getServletContext().setAttribute(HttpServer2.CONF_CONTEXT_ATTRIBUTE,
+          kmsConf);
+      sce.getServletContext().setAttribute(HttpServer2.ADMINS_ACL,
+          new AccessControlList(AccessControlList.WILDCARD_ACL_VALUE));
+
+      // intializing the KeyProvider
+      String providerString = kmsConf.get(KMSConfiguration.KEY_PROVIDER_URI);
+      if (providerString == null) {
+        throw new IllegalStateException("No KeyProvider has been defined");
+      }
+      Log.info("------------------ Ranger KMSWEbApp---------------------");
+      Log.info("provider string = "+providerString);
+      Log.info("URI = "+new URI(providerString).toString()+" scheme = "+new URI(providerString).getScheme());
+      Log.info("kmsconf size= "+kmsConf.size() + " kms classname="+kmsConf.getClass().getName());
+      Log.info("----------------INstantiating key provider ---------------");
+      KeyProvider keyProvider =
+          KeyProviderFactory.get(new URI(providerString), kmsConf);
+      Log.info("keyProvider = "+keyProvider.toString());
+      if (kmsConf.getBoolean(KMSConfiguration.KEY_CACHE_ENABLE,
+          KMSConfiguration.KEY_CACHE_ENABLE_DEFAULT)) {
+        long keyTimeOutMillis =
+            kmsConf.getLong(KMSConfiguration.KEY_CACHE_TIMEOUT_KEY,
+                KMSConfiguration.KEY_CACHE_TIMEOUT_DEFAULT);
+        long currKeyTimeOutMillis =
+            kmsConf.getLong(KMSConfiguration.CURR_KEY_CACHE_TIMEOUT_KEY,
+                KMSConfiguration.CURR_KEY_CACHE_TIMEOUT_DEFAULT);
+        keyProvider = new CachingKeyProvider(keyProvider, keyTimeOutMillis,
+            currKeyTimeOutMillis);
+      }
+      LOG.info("Initialized KeyProvider " + keyProvider);
+
+      keyProviderCryptoExtension = KeyProviderCryptoExtension.
+          createKeyProviderCryptoExtension(keyProvider);
+      keyProviderCryptoExtension =
+          new EagerKeyGeneratorKeyProviderCryptoExtension(kmsConf,
+              keyProviderCryptoExtension);
+      if (kmsConf.getBoolean(KMSConfiguration.KEY_AUTHORIZATION_ENABLE,
+          KMSConfiguration.KEY_AUTHORIZATION_ENABLE_DEFAULT)) {
+        keyProviderCryptoExtension =
+            new KeyAuthorizationKeyProvider(
+                keyProviderCryptoExtension, kmsAcls);
+      }
+        
+      LOG.info("Initialized KeyProviderCryptoExtension "
+          + keyProviderCryptoExtension);
+      final int defaultBitlength = kmsConf
+          .getInt(KeyProvider.DEFAULT_BITLENGTH_NAME,
+              KeyProvider.DEFAULT_BITLENGTH);
+      LOG.info("Default key bitlength is {}", defaultBitlength);
+      LOG.info("Ranger KMS Started");
+    } catch (Throwable ex) {
+      System.out.println();
+      System.out.println("ERROR: Hadoop KMS could not be started");
+      System.out.println();
+      System.out.println("REASON: " + ex.toString());
+      System.out.println();
+      System.out.println("Stacktrace:");
+      System.out.println("---------------------------------------------------");
+      ex.printStackTrace(System.out);
+      System.out.println("---------------------------------------------------");
+      System.out.println();
+      System.exit(1);
+    }
+  }
+
+  private KeyACLs getAcls(String clsStr) throws IOException {
+	  KeyACLs keyAcl = null;
+	  try {
+        Class<? extends KeyACLs> cls = null;
+        if (clsStr == null || clsStr.trim().equals("")) {
+        	cls = KMSACLs.class;
+        } else {
+            //Class<?> configClass = Class.forName(clsStr, true, JavaUtils.getClassLoader());
+        	Class<?> configClass = Class.forName(clsStr);
+            //Class<?> configClass = Class.forName(clsStr, true, JavaUtils.getClassLoader());
+            if(!KeyACLs.class.isAssignableFrom(configClass) ){
+            	//if it's not of type KeyACLs
+            	//we can have default also "cls = KMSACLs.class;"
+	            return null;
+            }
+            cls = (Class<? extends KeyACLs>)configClass;
+        }
+        if (cls != null) {
+            keyAcl = ReflectionUtils.newInstance(cls, kmsConf);
+        }
+      } catch (Exception e) {
+	        throw new IOException(e.getMessage());
+      }
+	  return keyAcl;
+  }
+
+@Override
+  public void contextDestroyed(ServletContextEvent sce) {
+    kmsAudit.shutdown();
+    kmsAcls.stopACLReloader();
+    jmxReporter.stop();
+    jmxReporter.close();
+    metricRegistry = null;
+    LOG.info("KMS Stopped");
+  }
+
+  public static Configuration getConfiguration() {
+    return new Configuration(kmsConf);
+  }
+
+  public static KeyACLs getACLs() {
+    return kmsAcls;
+  }
+
+  public static Meter getAdminCallsMeter() {
+    return adminCallsMeter;
+  }
+
+  public static Meter getKeyCallsMeter() {
+    return keyCallsMeter;
+  }
+
+  public static Meter getInvalidCallsMeter() {
+    return invalidCallsMeter;
+  }
+
+  public static Meter getGenerateEEKCallsMeter() {
+    return generateEEKCallsMeter;
+  }
+
+  public static Meter getDecryptEEKCallsMeter() {
+    return decryptEEKCallsMeter;
+  }
+
+  public static Meter getUnauthorizedCallsMeter() {
+    return unauthorizedCallsMeter;
+  }
+
+  public static Meter getUnauthenticatedCallsMeter() {
+    return unauthenticatedCallsMeter;
+  }
+
+  public static KeyProviderCryptoExtension getKeyProvider() {
+    return keyProviderCryptoExtension;
+  }
+
+  public static KMSAudit getKMSAudit() {
+    return kmsAudit;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
new file mode 100644
index 0000000..5099daf
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
@@ -0,0 +1,299 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.crypto.key.kms.server;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.crypto.key.KeyProvider;
+import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
+import org.apache.hadoop.crypto.key.kms.server.KMS.KMSOp;
+import org.apache.hadoop.security.AccessControlException;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authorize.AuthorizationException;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * A {@link KeyProvider} proxy that checks whether the current user derived via
+ * {@link UserGroupInformation}, is authorized to perform the following
+ * type of operations on a Key :
+ * <ol>
+ * <li>MANAGEMENT operations : createKey, rollNewVersion, deleteKey</li>
+ * <li>GENERATE_EEK operations : generateEncryptedKey, warmUpEncryptedKeys</li>
+ * <li>DECRYPT_EEK operation : decryptEncryptedKey</li>
+ * <li>READ operations : getKeyVersion, getKeyVersions, getMetadata,
+ * getKeysMetadata, getCurrentKey</li>
+ * </ol>
+ * The read operations (getCurrentKeyVersion / getMetadata) etc are not checked.
+ */
+public class KeyAuthorizationKeyProvider extends KeyProviderCryptoExtension {
+
+  public static final String KEY_ACL = "key.acl.";
+  private static final String KEY_ACL_NAME = KEY_ACL + "name";
+
+  public enum KeyOpType {
+    ALL, READ, MANAGEMENT, GENERATE_EEK, DECRYPT_EEK;
+  }
+
+  /**
+   * Interface that needs to be implemented by a client of the
+   * <code>KeyAuthorizationKeyProvider</code>.
+   */
+  public static interface KeyACLs {
+    
+    /**
+     * This is called by the KeyProvider to check if the given user is
+     * authorized to perform the specified operation on the given acl name.
+     * @param aclName name of the key ACL
+     * @param ugi User's UserGroupInformation
+     * @param opType Operation Type 
+     * @return true if user has access to the aclName and opType else false
+     */
+    public boolean hasAccessToKey(String aclName, UserGroupInformation ugi,
+        KeyOpType opType);
+
+    /**
+     * 
+     * @param aclName ACL name
+     * @param opType Operation Type
+     * @return true if AclName exists else false 
+     */
+    public boolean isACLPresent(String aclName, KeyOpType opType);
+
+	public void startACLReloader();
+	
+	public void stopACLReloader();
+
+	public boolean hasAccess(KMSACLsType.Type aclType, UserGroupInformation ugi);
+
+	public void assertAccess(KMSACLsType.Type aclType, UserGroupInformation ugi,
+			KMSOp operation, String key) throws AccessControlException;
+  }
+
+  private final KeyProviderCryptoExtension provider;
+  private final KeyACLs acls;
+
+  /**
+   * The constructor takes a {@link KeyProviderCryptoExtension} and an
+   * implementation of <code>KeyACLs</code>. All calls are delegated to the
+   * provider keyProvider after authorization check (if required)
+   * @param keyProvider 
+   * @param acls
+   */
+  public KeyAuthorizationKeyProvider(KeyProviderCryptoExtension keyProvider,
+      KeyACLs acls) {
+    super(keyProvider, null);
+    this.provider = keyProvider;
+    this.acls = acls;
+  }
+
+  // This method first checks if "key.acl.name" attribute is present as an
+  // attribute in the provider Options. If yes, use the aclName for any
+  // subsequent access checks, else use the keyName as the aclName and set it
+  // as the value of the "key.acl.name" in the key's metadata.
+  private void authorizeCreateKey(String keyName, Options options,
+      UserGroupInformation ugi) throws IOException{
+    Preconditions.checkNotNull(ugi, "UserGroupInformation cannot be null");
+    Map<String, String> attributes = options.getAttributes();
+    String aclName = attributes.get(KEY_ACL_NAME);
+    boolean success = false;
+    if (Strings.isNullOrEmpty(aclName)) {
+      if (acls.isACLPresent(keyName, KeyOpType.MANAGEMENT)) {
+        options.setAttributes(ImmutableMap.<String, String> builder()
+            .putAll(attributes).put(KEY_ACL_NAME, keyName).build());
+        success =
+            acls.hasAccessToKey(keyName, ugi, KeyOpType.MANAGEMENT)
+                || acls.hasAccessToKey(keyName, ugi, KeyOpType.ALL);
+      } else {
+        success = false;
+      }
+    } else {
+      success = acls.isACLPresent(aclName, KeyOpType.MANAGEMENT) &&
+          (acls.hasAccessToKey(aclName, ugi, KeyOpType.MANAGEMENT)
+          || acls.hasAccessToKey(aclName, ugi, KeyOpType.ALL));
+    }
+    if (!success)
+      throw new AuthorizationException(String.format("User [%s] is not"
+          + " authorized to create key !!", ugi.getShortUserName()));
+  }
+
+  private void checkAccess(String aclName, UserGroupInformation ugi,
+      KeyOpType opType) throws AuthorizationException {
+    Preconditions.checkNotNull(aclName, "Key ACL name cannot be null");
+    Preconditions.checkNotNull(ugi, "UserGroupInformation cannot be null");
+    if (acls.isACLPresent(aclName, KeyOpType.MANAGEMENT) &&
+        (acls.hasAccessToKey(aclName, ugi, opType)
+            || acls.hasAccessToKey(aclName, ugi, KeyOpType.ALL))) {
+      return;
+    } else {
+      throw new AuthorizationException(String.format("User [%s] is not"
+          + " authorized to perform [%s] on key with ACL name [%s]!!",
+          ugi.getShortUserName(), opType, aclName));
+    }
+  }
+
+  @Override
+  public KeyVersion createKey(String name, Options options)
+      throws NoSuchAlgorithmException, IOException {
+    authorizeCreateKey(name, options, getUser());
+    return provider.createKey(name, options);
+  }
+
+  @Override
+  public KeyVersion createKey(String name, byte[] material, Options options)
+      throws IOException {
+    authorizeCreateKey(name, options, getUser());
+    return provider.createKey(name, material, options);
+  }
+
+  @Override
+  public KeyVersion rollNewVersion(String name)
+      throws NoSuchAlgorithmException, IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    return provider.rollNewVersion(name);
+  }
+
+  @Override
+  public void deleteKey(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    provider.deleteKey(name);
+  }
+
+  @Override
+  public KeyVersion rollNewVersion(String name, byte[] material)
+      throws IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    return provider.rollNewVersion(name, material);
+  }
+
+  @Override
+  public void warmUpEncryptedKeys(String... names) throws IOException {
+    for (String name : names) {
+      doAccessCheck(name, KeyOpType.GENERATE_EEK);
+    }
+    provider.warmUpEncryptedKeys(names);
+  }
+
+  @Override
+  public EncryptedKeyVersion generateEncryptedKey(String encryptionKeyName)
+      throws IOException, GeneralSecurityException {
+    doAccessCheck(encryptionKeyName, KeyOpType.GENERATE_EEK);
+    return provider.generateEncryptedKey(encryptionKeyName);
+  }
+
+  private void verifyKeyVersionBelongsToKey(EncryptedKeyVersion ekv)
+      throws IOException {
+    String kn = ekv.getEncryptionKeyName();
+    String kvn = ekv.getEncryptionKeyVersionName();
+    KeyVersion kv = provider.getKeyVersion(kvn);
+    if (!kv.getName().equals(kn)) {
+      throw new IllegalArgumentException(String.format(
+          "KeyVersion '%s' does not belong to the key '%s'", kvn, kn));
+    }
+  }
+
+  @Override
+  public KeyVersion decryptEncryptedKey(EncryptedKeyVersion encryptedKeyVersion)
+          throws IOException, GeneralSecurityException {
+    verifyKeyVersionBelongsToKey(encryptedKeyVersion);
+    doAccessCheck(
+        encryptedKeyVersion.getEncryptionKeyName(), KeyOpType.DECRYPT_EEK);
+    return provider.decryptEncryptedKey(encryptedKeyVersion);
+  }
+
+  @Override
+  public KeyVersion getKeyVersion(String versionName) throws IOException {
+    KeyVersion keyVersion = provider.getKeyVersion(versionName);
+    if (keyVersion != null) {
+      doAccessCheck(keyVersion.getName(), KeyOpType.READ);
+    }
+    return keyVersion;
+  }
+
+  @Override
+  public List<String> getKeys() throws IOException {
+    return provider.getKeys();
+  }
+
+  @Override
+  public List<KeyVersion> getKeyVersions(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getKeyVersions(name);
+  }
+
+  @Override
+  public Metadata getMetadata(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getMetadata(name);
+  }
+
+  @Override
+  public Metadata[] getKeysMetadata(String... names) throws IOException {
+    for (String name : names) {
+      doAccessCheck(name, KeyOpType.READ);
+    }
+    return provider.getKeysMetadata(names);
+  }
+
+  @Override
+  public KeyVersion getCurrentKey(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getCurrentKey(name);
+  }
+
+  @Override
+  public void flush() throws IOException {
+    provider.flush();
+  }
+
+  @Override
+  public boolean isTransient() {
+    return provider.isTransient();
+  }
+
+  private void doAccessCheck(String keyName, KeyOpType opType) throws
+      IOException {
+    Metadata metadata = provider.getMetadata(keyName);
+    if (metadata != null) {
+      String aclName = metadata.getAttributes().get(KEY_ACL_NAME);
+      checkAccess((aclName == null) ? keyName : aclName, getUser(), opType);
+    }
+  }
+
+  private UserGroupInformation getUser() throws IOException {
+    return UserGroupInformation.getCurrentUser();
+  }
+
+  @Override
+  protected KeyProvider getKeyProvider() {
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return provider.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java b/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
new file mode 100644
index 0000000..08ab1f7
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
@@ -0,0 +1,216 @@
+package org.apache.ranger.entity;
+
+/**
+ * Base JPA class with id, versionNumber and other common attributes
+ * 
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import javax.persistence.Column;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@MappedSuperclass
+@XmlRootElement
+public abstract class XXDBBase extends Object implements java.io.Serializable {
+	private static final long serialVersionUID = 1L;
+	public static final int CLASS_TYPE_NONE = 0;
+	private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT+0");
+	
+	/**
+	 * Date/Time creation of this user.
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="CREATE_TIME"   )
+	protected Date createTime = getUTCDate();
+
+	/**
+	 * Date value.
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="UPDATE_TIME"   )
+	protected Date updateTime = getUTCDate();
+
+	/**
+	 * Added by
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name="ADDED_BY_ID"   )
+	protected Long addedByUserId;
+
+
+	/**
+	 * Last updated by
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name="UPD_BY_ID"   )
+	protected Long updatedByUserId;
+
+
+	/**
+	 * Default constructor. This will set all the attributes to default value.
+	 */
+	public XXDBBase ( ) {
+	}
+
+	public int getMyClassType( ) {
+	    return CLASS_TYPE_NONE;
+	}
+
+	public String getMyDisplayValue() {
+		return null;
+	}
+
+	/**
+	 * This method sets the value to the member attribute <b>id</b>.
+	 * You cannot set null to the attribute.
+	 * @param id Value to set member attribute <b>id</b>
+	 */
+	public abstract void setId( Long id ) ;
+
+	/**
+	 * Returns the value for the member attribute <b>id</b>
+	 * @return Long - value of member attribute <b>id</b>.
+	 */
+	public abstract Long getId( );
+
+	/**
+	 * This method sets the value to the member attribute <b>createTime</b>.
+	 * You cannot set null to the attribute.
+	 * @param createTime Value to set member attribute <b>createTime</b>
+	 */
+	public void setCreateTime( Date createTime ) {
+		this.createTime = createTime;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>createTime</b>
+	 * @return Date - value of member attribute <b>createTime</b>.
+	 */
+	public Date getCreateTime( ) {
+		return this.createTime;
+	}
+
+	/**
+	 * This method sets the value to the member attribute <b>updateTime</b>.
+	 * You cannot set null to the attribute.
+	 * @param updateTime Value to set member attribute <b>updateTime</b>
+	 */
+	public void setUpdateTime( Date updateTime ) {
+		this.updateTime = updateTime;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>updateTime</b>
+	 * @return Date - value of member attribute <b>updateTime</b>.
+	 */
+	public Date getUpdateTime( ) {
+		return this.updateTime;
+	}
+
+	/**
+	 * This method sets the value to the member attribute <b>addedByUserId</b>.
+	 * You cannot set null to the attribute.
+	 * @param addedByUserId Value to set member attribute <b>addedByUserId</b>
+	 */
+	public void setAddedByUserId( Long addedByUserId ) {
+		this.addedByUserId = addedByUserId;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>addedByUserId</b>
+	 * @return Long - value of member attribute <b>addedByUserId</b>.
+	 */
+	public Long getAddedByUserId( ) {
+		return this.addedByUserId;
+	}
+
+
+	/**
+	 * This method sets the value to the member attribute <b>updatedByUserId</b>.
+	 * You cannot set null to the attribute.
+	 * @param updatedByUserId Value to set member attribute <b>updatedByUserId</b>
+	 */
+	public void setUpdatedByUserId( Long updatedByUserId ) {
+		this.updatedByUserId = updatedByUserId;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>updatedByUserId</b>
+	 * @return Long - value of member attribute <b>updatedByUserId</b>.
+	 */
+	public Long getUpdatedByUserId( ) {
+		return this.updatedByUserId;
+	}
+
+
+	/**
+	 * This return the bean content in string format
+	 * @return formatedStr
+	*/
+	@Override
+	public String toString( ) {
+		String str = "XXDBBase={";
+		//`str += "id={" + id + "} ";
+		str += "createTime={" + createTime + "} ";
+		str += "updateTime={" + updateTime + "} ";
+		str += "addedByUserId={" + addedByUserId + "} ";
+		str += "updatedByUserId={" + updatedByUserId + "} ";
+		str += "}";
+		return str;
+	}
+
+	/**
+	 * Checks for all attributes except referenced db objects
+	 * @return true if all attributes match
+	*/
+	@Override
+	public boolean equals( Object obj) {
+		XXDBBase other = (XXDBBase) obj;
+        	if ((this.createTime == null && other.createTime != null) || (this.createTime != null && !this.createTime.equals(other.createTime))) {
+            		return false;
+        	}
+        	if ((this.updateTime == null && other.updateTime != null) || (this.updateTime != null && !this.updateTime.equals(other.updateTime))) {
+            		return false;
+        	}
+        	if ((this.addedByUserId == null && other.addedByUserId != null) || (this.addedByUserId != null && !this.addedByUserId.equals(other.addedByUserId))) {
+            		return false;
+        	}
+        	if ((this.updatedByUserId == null && other.updatedByUserId != null) || (this.updatedByUserId != null && !this.updatedByUserId.equals(other.updatedByUserId))) {
+            		return false;
+        	}
+		return true;
+	}
+	public static String getEnumName(String fieldName ) {
+		return null;
+	}
+
+	private static Date getUTCDate(){
+		try{
+			Calendar local=Calendar.getInstance();
+		    int offset = local.getTimeZone().getOffset(local.getTimeInMillis());
+		    GregorianCalendar utc = new GregorianCalendar(gmtTimeZone);
+		    utc.setTimeInMillis(local.getTimeInMillis());
+		    utc.add(Calendar.MILLISECOND, -offset);
+		    return utc.getTime();
+		}catch(Exception ex){
+			return null;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java b/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
new file mode 100644
index 0000000..c9eb77e
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
@@ -0,0 +1,121 @@
+package org.apache.ranger.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@Table(name="ranger_keystore")
+@XmlRootElement
+public class XXRangerKeyStore extends XXDBBase implements java.io.Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	@Id
+	@SequenceGenerator(name="kmskeys",sequenceName="kmskeys",allocationSize=1)
+	@GeneratedValue(strategy=GenerationType.AUTO,generator="kmskeys")
+	@Column(name="ID")
+	protected Long id;
+	@Override
+	public void setId(Long id) {
+		this.id=id;
+	}
+
+	@Override
+	public Long getId() {
+		return id;
+	}
+	
+	@Column(name="kms_alias"  , length=255 )
+	protected String alias;
+	
+	public String getAlias() {
+		return alias;
+	}
+
+	public void setAlias(String alias) {
+		this.alias = alias;
+	}
+	
+	@Column(name="kms_createdDate"  , length=255 )
+	protected Long createdDate;
+	
+	public Long getCreatedDate() {
+		return createdDate;
+	}
+
+	public void setCreatedDate(Long createdDate) {
+		this.createdDate = createdDate;
+	}
+
+	@Lob
+	@Column(name="kms_encoded")
+	protected String encoded;
+
+	public String getEncoded() {
+		return encoded;
+	}
+
+	public void setEncoded(String encoded) {
+		this.encoded = encoded;
+	}
+	
+	@Column(name="kms_cipher" , length=255)
+	protected String cipher;
+	
+	public String getCipher() {
+		return cipher;
+	}
+
+	public void setCipher(String cipher) {
+		this.cipher = cipher;
+	}
+
+	@Column(name="kms_bitLength")
+	protected int bitLength;
+	
+	public int getBitLength() {
+		return bitLength;
+	}
+
+	public void setBitLength(int bitLength) {
+		this.bitLength = bitLength;
+	}
+	
+	@Column(name="kms_description")
+	protected String description;
+	
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	
+	@Column(name="kms_version")
+	protected int version;
+	
+	public int getVersion() {
+		return version;
+	}
+
+	public void setVersion(int version) {
+		this.version = version;
+	}
+	
+	@Column(name="kms_attributes")
+	protected String attributes;
+	public String getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(String attributes) {
+		this.attributes = attributes;
+	}	
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java b/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
new file mode 100644
index 0000000..6175286
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
@@ -0,0 +1,67 @@
+package org.apache.ranger.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@Table(name="ranger_masterkey")
+@XmlRootElement
+public class XXRangerMasterKey extends XXDBBase implements java.io.Serializable {
+	private static final long serialVersionUID = 1L;
+	
+	@Id
+	@SequenceGenerator(name="rangermasterkey",sequenceName="rangermasterkey",allocationSize=1)
+	@GeneratedValue(strategy=GenerationType.AUTO,generator="rangermasterkey")
+	@Column(name="ID")
+	protected Long id;
+	@Override
+	public void setId(Long id) {
+		this.id=id;
+	}
+
+	@Override
+	public Long getId() {
+		return id;
+	}
+	
+	@Column(name="cipher")
+	protected String cipher;
+
+	public String getCipher() {
+		return cipher;
+	}
+
+	public void setCipher(String cipher) {
+		this.cipher = cipher;
+	}
+	
+	@Column(name="bitlength")
+	protected int bitLength;
+
+	public int getBitLength() {
+		return bitLength;
+	}
+
+	public void setBitLength(int bitLength) {
+		this.bitLength = bitLength;
+	}
+		
+	@Lob
+	@Column(name="masterkey")
+	protected String masterKey;
+
+	public String getMasterKey() {
+		return masterKey;
+	}
+
+	public void setMasterKey(String masterKey) {
+		this.masterKey = masterKey;
+	}		
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java b/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
new file mode 100644
index 0000000..af9bfa1
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
@@ -0,0 +1,35 @@
+package org.apache.ranger.kms.biz;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.RangerKeyStoreProvider;
+import org.apache.hadoop.crypto.key.RangerMasterKey;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("serial")
+@Component
+public class RangerKMSStartUp extends HttpServlet
+{	
+	public static final String ENCRYPTION_KEY = "ranger.db.encrypt.key.password";
+	private static Logger LOG = LoggerFactory.getLogger(RangerKMSStartUp.class);
+	
+	@PostConstruct
+	public void initRangerMasterKey() {
+		LOG.info("Ranger KMSStartUp");
+		RangerMasterKey rangerMasterKey = new RangerMasterKey();
+		try {
+				Configuration conf = RangerKeyStoreProvider.getDBKSConf();
+				String password = conf.get(ENCRYPTION_KEY);
+				boolean check = rangerMasterKey.generateMasterKey(password);
+				if(check){
+					LOG.info("MasterKey Generated..");
+				}
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}				
+	}	
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java b/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
new file mode 100644
index 0000000..f835bcc
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.ranger.kms.dao;
+
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+
+import org.apache.log4j.Logger;
+
+public abstract class BaseDao<T> {
+	static final Logger logger = Logger.getLogger(BaseDao.class);
+
+	protected DaoManager daoManager;
+
+	protected Class<T> tClass;
+
+	public BaseDao(DaoManagerBase daoManager) {
+		this.init(daoManager);
+	}
+
+	@SuppressWarnings("unchecked")
+	private void init(DaoManagerBase daoManager) {
+		this.daoManager = (DaoManager) daoManager;
+
+		ParameterizedType genericSuperclass = (ParameterizedType) getClass()
+				.getGenericSuperclass();
+
+		Type type = genericSuperclass.getActualTypeArguments()[0];
+
+		if (type instanceof ParameterizedType) {
+			this.tClass = (Class<T>) ((ParameterizedType) type).getRawType();
+		} else {
+			this.tClass = (Class<T>) type;
+		}
+	}
+
+	public EntityManager getEntityManager() {
+		return daoManager.getEntityManager();
+	}
+
+	public boolean beginTransaction() {
+		boolean ret = false;
+
+		EntityManager em = getEntityManager();
+
+		if(em != null) {
+			EntityTransaction et = em.getTransaction();
+			
+			// check the transaction is not already active
+			if(et != null && !et.isActive()) {
+				et.begin();
+				ret = true;
+			}
+		}
+		
+		return ret;
+	}
+
+	public void commitTransaction() {
+		EntityManager em = getEntityManager();
+
+		if(em != null) {
+			em.flush();
+
+			EntityTransaction et = em.getTransaction();
+
+			if(et != null) {
+				et.commit();
+			}
+		}
+	}
+
+	public void rollbackTransaction() {
+		EntityManager em = getEntityManager();
+
+		if(em != null) {
+			EntityTransaction et = em.getTransaction();
+
+			if(et != null) {
+				et.rollback();
+			}
+		}
+	}
+
+	public T create(T obj) {
+		T ret = null;
+
+		boolean trxBegan = beginTransaction();
+
+		getEntityManager().persist(obj);
+
+		if(trxBegan) {
+			commitTransaction();
+		}
+
+		ret = obj;
+
+		return ret;
+	}
+
+	public T update(T obj) {
+		boolean trxBegan = beginTransaction();
+
+		getEntityManager().merge(obj);
+
+		if(trxBegan) {
+			commitTransaction();
+		}
+
+		return obj;
+	}
+
+	public boolean remove(Long id) {
+		return remove(getById(id));
+	}
+
+	public boolean remove(T obj) {
+		if (obj == null) {
+			return true;
+		}
+
+		boolean ret = false;
+
+		boolean trxBegan = beginTransaction();
+
+		getEntityManager().remove(obj);
+
+		if(trxBegan) {
+			commitTransaction();
+		}
+
+		ret = true;
+
+		return ret;
+	}
+
+	public T getById(Long id) {
+		if (id == null) {
+			return null;
+		}
+		T ret = null;
+		try {
+			ret = getEntityManager().find(tClass, id);
+		} catch (NoResultException e) {
+			return null;
+		}
+		return ret;
+	}
+
+	public List<T> getAll() {
+		List<T> ret = null;
+		
+		TypedQuery<T> qry = getEntityManager().createQuery(
+				"SELECT t FROM " + tClass.getSimpleName() + " t", tClass);
+
+		ret = qry.getResultList();
+
+		return ret;
+	}
+
+	public Long getAllCount() {
+		Long ret = null;
+
+		TypedQuery<Long> qry = getEntityManager().createQuery(
+				"SELECT count(t) FROM " + tClass.getSimpleName() + " t",
+				Long.class);
+
+		ret = qry.getSingleResult();
+
+		return ret;
+	}
+
+	public T getUniqueResult(TypedQuery<T> qry) {
+		T ret = null;
+
+		try {
+			ret = qry.getSingleResult();
+		} catch (NoResultException e) {
+			// ignore
+		}
+		return ret;
+	}
+
+	public List<T> executeQuery(TypedQuery<T> qry) {
+		List<T> ret = null;
+
+		ret = qry.getResultList();
+
+		return ret;
+	}
+
+	public List<T> findByNamedQuery(String namedQuery, String paramName,
+			Object refId) {
+		List<T> ret = new ArrayList<T>();
+
+		if (namedQuery == null) {
+			return ret;
+		}
+		try {
+			TypedQuery<T> qry = getEntityManager().createNamedQuery(namedQuery, tClass);
+			qry.setParameter(paramName, refId);
+			ret = qry.getResultList();
+		} catch (NoResultException e) {
+			// ignore
+		}
+		return ret;
+	}	
+	
+	public T findByAlias(String namedQuery, String alias) {
+		try {
+			return getEntityManager()
+					.createNamedQuery(namedQuery, tClass)
+					.setParameter("alias", alias)
+					.getSingleResult();
+		} catch (NoResultException e) {
+		}
+		return null;
+	}
+	
+	public int deleteByAlias(String namedQuery, String alias) {
+		boolean trxBegan = beginTransaction();
+		try {
+			int i = getEntityManager()
+					.createNamedQuery(namedQuery, tClass)
+					.setParameter("alias", alias).executeUpdate();
+			if(trxBegan) {
+				commitTransaction();
+			}
+			return i;
+		} catch (NoResultException e) {
+			e.printStackTrace();
+			rollbackTransaction();
+		}		
+		return 0;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
new file mode 100644
index 0000000..be67204
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
@@ -0,0 +1,35 @@
+package org.apache.ranger.kms.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+
+public class DaoManager extends DaoManagerBase {
+
+	@PersistenceContext
+	private EntityManagerFactory emf;
+
+	static ThreadLocal<EntityManager> sEntityManager;
+
+	public void setEntityManagerFactory(EntityManagerFactory emf) {
+		this.emf = emf;
+		sEntityManager = new ThreadLocal<EntityManager>();
+	}
+
+	@Override
+	public EntityManager getEntityManager() {
+		EntityManager em = null;
+
+		if(sEntityManager != null) {
+			em = sEntityManager.get();
+
+			if(em == null && this.emf != null) {
+				em = this.emf.createEntityManager();
+
+				sEntityManager.set(em);
+			}
+		}
+
+		return em;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
new file mode 100644
index 0000000..5cd84b0
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
@@ -0,0 +1,31 @@
+package org.apache.ranger.kms.dao;
+
+import javax.persistence.EntityManager;
+import org.apache.log4j.Logger;
+
+public abstract class DaoManagerBase {
+	final static Logger logger = Logger.getLogger(DaoManagerBase.class);
+
+	abstract public EntityManager getEntityManager();
+
+	private RangerMasterKeyDao rangerMasterKeyDao = null;
+	private RangerKMSDao rangerKmsDao = null;
+
+    public DaoManagerBase() {
+	}
+
+	public RangerMasterKeyDao getRangerMasterKeyDao() {
+		if(rangerMasterKeyDao == null) {
+			rangerMasterKeyDao = new RangerMasterKeyDao(this);
+		}
+
+		return rangerMasterKeyDao;
+	}
+	
+	public RangerKMSDao getRangerKMSDao(){
+		if(rangerKmsDao == null){
+			rangerKmsDao = new RangerKMSDao(this);
+		}
+		return rangerKmsDao;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java b/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
new file mode 100644
index 0000000..d5c94fe
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
@@ -0,0 +1,18 @@
+package org.apache.ranger.kms.dao;
+
+import org.apache.ranger.entity.XXRangerKeyStore;
+
+public class RangerKMSDao extends BaseDao<XXRangerKeyStore> {
+
+	public RangerKMSDao(DaoManagerBase daoManager) {
+		super(daoManager);
+	}
+	
+	public XXRangerKeyStore findByAlias(String alias){
+		return super.findByAlias("XXRangerKeyStore.findByAlias", alias);
+	}
+	
+	public int deleteByAlias(String alias){
+		return super.deleteByAlias("XXRangerKeyStore.deleteByAlias", alias);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java b/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
new file mode 100644
index 0000000..4170433
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
@@ -0,0 +1,10 @@
+package org.apache.ranger.kms.dao;
+
+import org.apache.ranger.entity.XXRangerMasterKey;
+
+public class RangerMasterKeyDao extends BaseDao<XXRangerMasterKey> {
+
+	public RangerMasterKeyDao(DaoManagerBase daoManager) {
+		super(daoManager);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml b/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
new file mode 100644
index 0000000..8fd3128
--- /dev/null
+++ b/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<entity-mappings version="1.0"
+	xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd ">
+	<named-query name="XXRangerKeyStore.findByAlias">
+		<query>SELECT Obj FROM XXRangerKeyStore obj
+			   WHERE obj.alias=:alias
+		</query>
+	</named-query>
+
+	<named-query name="XXRangerKeyStore.deleteByAlias">
+		<query>DELETE FROM XXRangerKeyStore obj
+			   WHERE obj.alias=:alias
+		</query>
+	</named-query>
+</entity-mappings>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/META-INF/persistence.xml b/kms/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..31c0bc4
--- /dev/null
+++ b/kms/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+	<persistence-unit name="persistence_ranger_server">
+		<mapping-file>META-INF/kms_jpa_named_queries.xml</mapping-file>
+		<class>org.apache.ranger.entity.XXRangerMasterKey</class>
+		<class>org.apache.ranger.entity.XXRangerKeyStore</class>
+
+		<properties>
+			<property name="eclipselink.logging.level" value="SEVERE"/>
+		</properties>
+	</persistence-unit>
+</persistence>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory b/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
new file mode 100644
index 0000000..bb9f0bb
--- /dev/null
+++ b/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+org.apache.hadoop.crypto.key.RangerKeyStoreProvider$Factory
+org.apache.hadoop.crypto.key.JavaKeyStoreProvider$Factory
+org.apache.hadoop.crypto.key.UserProvider$Factory
+org.apache.hadoop.crypto.key.kms.KMSClientProvider$Factory

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/WEB-INF/web.xml b/kms/src/main/resources/WEB-INF/web.xml
new file mode 100644
index 0000000..71c580c
--- /dev/null
+++ b/kms/src/main/resources/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
+
+  <display-name>ranger-kms</display-name>
+
+  <listener>
+    <listener-class>org.apache.hadoop.crypto.key.kms.server.KMSWebApp</listener-class>
+  </listener>
+
+  <servlet>
+    <servlet-name>webservices-driver</servlet-name>
+    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>com.sun.jersey.config.property.packages</param-name>
+      <param-value>org.apache.hadoop.crypto.key.kms.server</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  
+<!--   <servlet>
+    <servlet-name>RangerKMSStartUp</servlet-name>
+    <servlet-class>org.apache.ranger.kms.biz.RangerKMSStartUp</servlet-class>    
+    <load-on-startup>2</load-on-startup>
+  </servlet> -->
+
+  <servlet>
+    <servlet-name>jmx-servlet</servlet-name>
+    <servlet-class>org.apache.hadoop.crypto.key.kms.server.KMSJMXServlet</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>webservices-driver</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>jmx-servlet</servlet-name>
+    <url-pattern>/jmx</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>authFilter</filter-name>
+    <filter-class>org.apache.hadoop.crypto.key.kms.server.KMSAuthenticationFilter</filter-class>
+  </filter>
+
+  <filter>
+    <filter-name>MDCFilter</filter-name>
+    <filter-class>org.apache.hadoop.crypto.key.kms.server.KMSMDCFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>authFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>MDCFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/log4j-kmsaudit.properties
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/log4j-kmsaudit.properties b/kms/src/main/resources/log4j-kmsaudit.properties
new file mode 100644
index 0000000..cca6941
--- /dev/null
+++ b/kms/src/main/resources/log4j-kmsaudit.properties
@@ -0,0 +1,25 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# LOG Appender
+log4j.appender.kms-audit=org.apache.log4j.ConsoleAppender
+log4j.appender.kms-audit.Target=System.err
+log4j.appender.kms-audit.layout=org.apache.log4j.PatternLayout
+log4j.appender.kms-audit.layout.ConversionPattern=%m
+
+log4j.rootLogger=INFO, kms-audit
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/log4j.properties b/kms/src/main/resources/log4j.properties
new file mode 100644
index 0000000..5cd037a
--- /dev/null
+++ b/kms/src/main/resources/log4j.properties
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# STDOUT Appender
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{1} - %m%n
+
+log4j.rootLogger=WARN, stdout
+log4j.logger.org.apache.hadoop.conf=ERROR
+log4j.logger.org.apache.hadoop.crytpo.key.kms.server=ALL
+log4j.logger.com.sun.jersey.server.wadl.generators.WadlGeneratorJAXBGrammarGenerator=OFF
+log4j.logger.org.apache.hadoop.security=OFF
+log4j.logger.org.apache.directory.server.core=OFF
+log4j.logger.org.apache.hadoop.util.NativeCodeLoader=OFF
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/mini-kms-acls-default.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/mini-kms-acls-default.xml b/kms/src/main/resources/mini-kms-acls-default.xml
new file mode 100644
index 0000000..24a46b8
--- /dev/null
+++ b/kms/src/main/resources/mini-kms-acls-default.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<configuration>
+
+  <!-- This file is hot-reloaded when it changes -->
+
+  <!-- KMS ACLs -->
+
+  <property>
+    <name>hadoop.kms.acl.CREATE</name>
+    <value>*</value>
+    <description>
+      ACL for create-key operations.
+      If the user does is not in the GET ACL, the key material is not returned
+      as part of the response.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.DELETE</name>
+    <value>*</value>
+    <description>
+      ACL for delete-key operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.ROLLOVER</name>
+    <value>*</value>
+    <description>
+      ACL for rollover-key operations.
+      If the user does is not in the GET ACL, the key material is not returned
+      as part of the response.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET</name>
+    <value>*</value>
+    <description>
+      ACL for get-key-version and get-current-key operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET_KEYS</name>
+    <value>*</value>
+    <description>
+      ACL for get-keys operation.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET_METADATA</name>
+    <value>*</value>
+    <description>
+      ACL for get-key-metadata an get-keys-metadata operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.SET_KEY_MATERIAL</name>
+    <value>*</value>
+    <description>
+      Complimentary ACL for CREATE and ROLLOVER operation to allow the client
+      to provide the key material when creating or rolling a key.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GENERATE_EEK</name>
+    <value>*</value>
+    <description>
+      ACL for generateEncryptedKey CryptoExtension operations
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.DECRYPT_EEK</name>
+    <value>*</value>
+    <description>
+      ACL for decrypt EncryptedKey CryptoExtension operations
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.MANAGEMENT</name>
+    <value>*</value>
+    <description>
+      default ACL for MANAGEMENT operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.GENERATE_EEK</name>
+    <value>*</value>
+    <description>
+      default ACL for GENERATE_EEK operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.DECRYPT_EEK</name>
+    <value>*</value>
+    <description>
+      default ACL for DECRYPT_EEK operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.READ</name>
+    <value>*</value>
+    <description>
+      default ACL for READ operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/webapp/WEB-INF/web.xml b/kms/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..7d87e90
--- /dev/null
+++ b/kms/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
+
+  <display-name>ranger-kms</display-name>
+
+  <listener>
+    <listener-class>org.apache.hadoop.crypto.key.kms.server.KMSWebApp</listener-class>
+  </listener>
+
+  <servlet>
+    <servlet-name>webservices-driver</servlet-name>
+    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>com.sun.jersey.config.property.packages</param-name>
+      <param-value>org.apache.hadoop.crypto.key.kms.server</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  
+  <!-- <servlet>
+    <servlet-name>RangerKMSStartUp</servlet-name>
+    <servlet-class>org.apache.ranger.kms.biz.RangerKMSStartUp</servlet-class>    
+    <load-on-startup>2</load-on-startup>
+  </servlet> -->
+
+  <servlet>
+    <servlet-name>jmx-servlet</servlet-name>
+    <servlet-class>org.apache.hadoop.crypto.key.kms.server.KMSJMXServlet</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>webservices-driver</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>jmx-servlet</servlet-name>
+    <url-pattern>/jmx</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>authFilter</filter-name>
+    <filter-class>org.apache.hadoop.crypto.key.kms.server.KMSAuthenticationFilter</filter-class>
+  </filter>
+
+  <filter>
+    <filter-name>MDCFilter</filter-name>
+    <filter-class>org.apache.hadoop.crypto.key.kms.server.KMSMDCFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>authFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>MDCFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
----------------------------------------------------------------------
diff --git a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
new file mode 100644
index 0000000..4f802cc
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
@@ -0,0 +1,238 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.io.IOUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.ssl.SslSocketConnectorSecure;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.ServerSocket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.UUID;
+
+public class MiniKMS {
+
+  private static Server createJettyServer(String keyStore, String password, int inPort) {
+    try {
+      boolean ssl = keyStore != null;
+      InetAddress localhost = InetAddress.getByName("localhost");
+      String host = "localhost";
+      ServerSocket ss = new ServerSocket((inPort < 0) ? 0 : inPort, 50, localhost);
+      int port = ss.getLocalPort();
+      ss.close();
+      Server server = new Server(0);
+      if (!ssl) {
+        server.getConnectors()[0].setHost(host);
+        server.getConnectors()[0].setPort(port);
+      } else {
+        SslSocketConnector c = new SslSocketConnectorSecure();
+        c.setHost(host);
+        c.setPort(port);
+        c.setNeedClientAuth(false);
+        c.setKeystore(keyStore);
+        c.setKeystoreType("jks");
+        c.setKeyPassword(password);
+        server.setConnectors(new Connector[]{c});
+      }
+      return server;
+    } catch (Exception ex) {
+      throw new RuntimeException("Could not start embedded servlet container, "
+          + ex.getMessage(), ex);
+    }
+  }
+
+  private static URL getJettyURL(Server server) {
+    boolean ssl = server.getConnectors()[0].getClass()
+        == SslSocketConnectorSecure.class;
+    try {
+      String scheme = (ssl) ? "https" : "http";
+      return new URL(scheme + "://" +
+          server.getConnectors()[0].getHost() + ":" +
+          server.getConnectors()[0].getPort());
+    } catch (MalformedURLException ex) {
+      throw new RuntimeException("It should never happen, " + ex.getMessage(),
+          ex);
+    }
+  }
+
+  public static class Builder {
+    private File kmsConfDir;
+    private String log4jConfFile;
+    private File keyStoreFile;
+    private String keyStorePassword;
+    private int inPort = -1;
+
+    public Builder() {
+      kmsConfDir = new File("target/test-classes").getAbsoluteFile();
+      log4jConfFile = "kms-log4j.properties";
+    }
+
+    public Builder setKmsConfDir(File confDir) {
+      Preconditions.checkNotNull(confDir, "KMS conf dir is NULL");
+      Preconditions.checkArgument(confDir.exists(),
+          "KMS conf dir does not exist");
+      kmsConfDir = confDir;
+      return this;
+    }
+
+    public Builder setLog4jConfFile(String log4jConfFile) {
+      Preconditions.checkNotNull(log4jConfFile, "log4jconf file is NULL");
+      this.log4jConfFile = log4jConfFile;
+      return this;
+    }
+
+    public Builder setPort(int port) {
+      Preconditions.checkArgument(port > 0, "input port must be greater than 0");
+      this.inPort = port;
+      return this;
+    }
+
+    public Builder setSslConf(File keyStoreFile, String keyStorePassword) {
+      Preconditions.checkNotNull(keyStoreFile, "keystore file is NULL");
+      Preconditions.checkNotNull(keyStorePassword, "keystore password is NULL");
+      Preconditions.checkArgument(keyStoreFile.exists(),
+          "keystore file does not exist");
+      this.keyStoreFile = keyStoreFile;
+      this.keyStorePassword = keyStorePassword;
+      return this;
+    }
+
+    public MiniKMS build() {
+      Preconditions.checkArgument(kmsConfDir.exists(),
+          "KMS conf dir does not exist");
+      return new MiniKMS(kmsConfDir.getAbsolutePath(), log4jConfFile,
+          (keyStoreFile != null) ? keyStoreFile.getAbsolutePath() : null,
+          keyStorePassword, inPort);
+    }
+  }
+
+  private String kmsConfDir;
+  private String log4jConfFile;
+  private String keyStore;
+  private String keyStorePassword;
+  private Server jetty;
+  private int inPort;
+  private URL kmsURL;
+
+  public MiniKMS(String kmsConfDir, String log4ConfFile, String keyStore,
+      String password, int inPort) {
+    this.kmsConfDir = kmsConfDir;
+    this.log4jConfFile = log4ConfFile;
+    this.keyStore = keyStore;
+    this.keyStorePassword = password;
+    this.inPort = inPort;
+  }
+
+  public void start() throws Exception {
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    System.setProperty(KMSConfiguration.KMS_CONFIG_DIR, kmsConfDir);
+    File aclsFile = new File(kmsConfDir, "kms-acls.xml");
+    if (!aclsFile.exists()) {
+      InputStream is = cl.getResourceAsStream("mini-kms-acls-default.xml");
+      OutputStream os = new FileOutputStream(aclsFile);
+      IOUtils.copy(is, os);
+      is.close();
+      os.close();
+    }
+    File coreFile = new File(kmsConfDir, "core-site.xml");
+    if (!coreFile.exists()) {
+      Configuration core = new Configuration();
+      Writer writer = new FileWriter(coreFile);
+      core.writeXml(writer);
+      writer.close();
+    }
+    File kmsFile = new File(kmsConfDir, "kms-site.xml");
+    if (!kmsFile.exists()) {
+      Configuration kms = new Configuration(false);
+      kms.set(KMSConfiguration.KEY_PROVIDER_URI,
+          "jceks://file@" + new Path(kmsConfDir, "kms.keystore").toUri());
+      kms.set("hadoop.kms.authentication.type", "simple");
+      Writer writer = new FileWriter(kmsFile);
+      kms.writeXml(writer);
+      writer.close();
+    }
+    System.setProperty("log4j.configuration", log4jConfFile);
+    jetty = createJettyServer(keyStore, keyStorePassword, inPort);
+
+    // we need to do a special handling for MiniKMS to work when in a dir and
+    // when in a JAR in the classpath thanks to Jetty way of handling of webapps
+    // when they are in the a DIR, WAR or JAR.
+    URL webXmlUrl = cl.getResource("kms-webapp/WEB-INF/web.xml");
+    if (webXmlUrl == null) {
+      throw new RuntimeException(
+          "Could not find kms-webapp/ dir in test classpath");
+    }
+    boolean webXmlInJar = webXmlUrl.getPath().contains(".jar!/");
+    String webappPath;
+    if (webXmlInJar) {
+      File webInf = new File("target/" + UUID.randomUUID().toString() +
+          "/kms-webapp/WEB-INF");
+      webInf.mkdirs();
+      new File(webInf, "web.xml").delete();
+      InputStream is = cl.getResourceAsStream("kms-webapp/WEB-INF/web.xml");
+      OutputStream os = new FileOutputStream(new File(webInf, "web.xml"));
+      IOUtils.copy(is, os);
+      is.close();
+      os.close();
+      webappPath = webInf.getParentFile().getAbsolutePath();
+    } else {
+      webappPath = cl.getResource("kms-webapp").getPath();
+    }
+    WebAppContext context = new WebAppContext(webappPath, "/kms");
+    if (webXmlInJar) {
+      context.setClassLoader(cl);
+    }
+    jetty.addHandler(context);
+    jetty.start();
+    kmsURL = new URL(getJettyURL(jetty), "kms");
+  }
+
+  public URL getKMSUrl() {
+    return kmsURL;
+  }
+
+  public void stop() {
+    if (jetty != null && jetty.isRunning()) {
+      try {
+        jetty.stop();
+        jetty = null;
+      } catch (Exception ex) {
+        throw new RuntimeException("Could not stop MiniKMS embedded Jetty, " +
+            ex.getMessage(), ex);
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
----------------------------------------------------------------------
diff --git a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
new file mode 100644
index 0000000..12945d7
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.kms.server.KMSACLsType.Type;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestKMSACLs {
+
+  @Test
+  public void testDefaults() {
+    KMSACLs acls = new KMSACLs(new Configuration(false));
+    for (Type type : Type.values()) {
+      Assert.assertTrue(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser("foo")));
+    }
+  }
+
+  @Test
+  public void testCustom() {
+    Configuration conf = new Configuration(false);
+    for (Type type : Type.values()) {
+      conf.set(type.getAclConfigKey(), type.toString() + " ");
+    }
+    KMSACLs acls = new KMSACLs(conf);
+    for (Type type : Type.values()) {
+      Assert.assertTrue(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser(type.toString())));
+      Assert.assertFalse(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser("foo")));
+    }
+  }
+
+}


Mime
View raw message