(RANGER-247)Development of Ranger Key Storage Provider

Signed-off-by: Velmurugan Periasamy <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/bb0bdced
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/bb0bdced
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/bb0bdced

Branch: refs/heads/master
Commit: bb0bdcedeb134f5aadeef17be11f4df7e8150b71
Parents: ce139e0
Author: Gautam Borad <[email protected]>
Authored: Tue Mar 24 12:12:19 2015 +0530
Committer: Velmurugan Periasamy <[email protected]>
Committed: Tue Mar 24 13:26:30 2015 -0400

----------------------------------------------------------------------
 kms/config/kms-webapp/dbks-site.xml             | 120 ++++
 kms/config/kms-webapp/kms-site.xml              |   9 +-
 kms/config/webserver/kms_webserver.properties   |  20 +-
 kms/dev-support/findbugsExcludeFile.xml         |  41 ++
 kms/pom.xml                                     | 413 +++++++++++++-
 kms/scripts/db/mysql/kms_core_db.sql            |  30 +
 kms/scripts/db_setup.py                         | 252 +++++++++
 kms/scripts/ranger-kms                          |   2 +-
 kms/scripts/ranger-kms-services.sh              |   2 +-
 kms/scripts/setup.sh                            | 172 ++++++
 .../crypto/key/EncryptedPrivateKeyInfo.java     | 111 ++++
 .../apache/hadoop/crypto/key/KeyProtector.java  | 541 +++++++++++++++++++
 .../apache/hadoop/crypto/key/RangerKMSDB.java   |  85 +++
 .../hadoop/crypto/key/RangerKeyStore.java       | 537 ++++++++++++++++++
 .../crypto/key/RangerKeyStoreProvider.java      | 341 ++++++++++++
 .../hadoop/crypto/key/RangerMasterKey.java      | 210 +++++++
 ...rKeyGeneratorKeyProviderCryptoExtension.java | 171 ++++++
 .../hadoop/crypto/key/kms/server/KMS.java       | 482 +++++++++++++++++
 .../hadoop/crypto/key/kms/server/KMSACLs.java   | 253 +++++++++
 .../crypto/key/kms/server/KMSACLsType.java      |  17 +
 .../hadoop/crypto/key/kms/server/KMSAudit.java  | 230 ++++++++
 .../key/kms/server/KMSAuthenticationFilter.java | 154 ++++++
 .../crypto/key/kms/server/KMSConfiguration.java | 126 +++++
 .../key/kms/server/KMSExceptionsProvider.java   | 113 ++++
 .../crypto/key/kms/server/KMSJMXServlet.java    |  36 ++
 .../crypto/key/kms/server/KMSJSONReader.java    |  54 ++
 .../crypto/key/kms/server/KMSJSONWriter.java    |  70 +++
 .../crypto/key/kms/server/KMSMDCFilter.java     |  93 ++++
 .../key/kms/server/KMSServerJSONUtils.java      | 102 ++++
 .../hadoop/crypto/key/kms/server/KMSWebApp.java | 307 +++++++++++
 .../kms/server/KeyAuthorizationKeyProvider.java | 299 ++++++++++
 .../java/org/apache/ranger/entity/XXDBBase.java | 216 ++++++++
 .../apache/ranger/entity/XXRangerKeyStore.java  | 121 +++++
 .../apache/ranger/entity/XXRangerMasterKey.java |  67 +++
 .../apache/ranger/kms/biz/RangerKMSStartUp.java |  35 ++
 .../java/org/apache/ranger/kms/dao/BaseDao.java | 261 +++++++++
 .../org/apache/ranger/kms/dao/DaoManager.java   |  35 ++
 .../apache/ranger/kms/dao/DaoManagerBase.java   |  31 ++
 .../org/apache/ranger/kms/dao/RangerKMSDao.java |  18 +
 .../ranger/kms/dao/RangerMasterKeyDao.java      |  10 +
 .../META-INF/kms_jpa_named_queries.xml          |  32 ++
 kms/src/main/resources/META-INF/persistence.xml |  28 +
 ....apache.hadoop.crypto.key.KeyProviderFactory |  18 +
 kms/src/main/resources/WEB-INF/web.xml          |  62 +++
 .../main/resources/log4j-kmsaudit.properties    |  25 +
 kms/src/main/resources/log4j.properties         |  31 ++
 .../main/resources/mini-kms-acls-default.xml    | 135 +++++
 kms/src/main/webapp/WEB-INF/web.xml             |  62 +++
 .../hadoop/crypto/key/kms/server/MiniKMS.java   | 238 ++++++++
 .../crypto/key/kms/server/TestKMSACLs.java      |  52 ++
 .../crypto/key/kms/server/TestKMSAudit.java     | 135 +++++
 .../server/TestKeyAuthorizationKeyProvider.java | 271 ++++++++++
 pom.xml                                         |  22 +
 src/main/assembly/kms.xml                       | 167 ++++--
 54 files changed, 7418 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/config/kms-webapp/dbks-site.xml
----------------------------------------------------------------------
diff --git a/kms/config/kms-webapp/dbks-site.xml 
b/kms/config/kms-webapp/dbks-site.xml
new file mode 100644
index 0000000..a428c6f
--- /dev/null
+++ b/kms/config/kms-webapp/dbks-site.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+  <!-- Encryption key Password -->
+  
+  <property>
+       <name>ranger.db.encrypt.key.password</name>
+    <value>Str0ngPassw0rd</value>
+    <description>
+       Password used for encrypting Master Key
+    </description>
+  </property>
+  
+   <!-- db Details -->
+  
+  <property>
+    <name>ranger.db.ks.database.flavor</name>
+    <value>MYSQL</value>
+    <description>
+      ULR for Database
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.core.file</name>
+    <value>db/mysql/kms_core_db.sql</value>
+    <description>
+      ULR for Database
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.db.ks.javax.persistence.jdbc.url</name>
+    <value>jdbc:log4jdbc:mysql://localhost:3306/rangerkms</value>
+    <description>
+      ULR for Database
+    </description>
+  </property>
+    
+  <property>
+    <name>ranger.db.root.user</name>
+    <value>root</value>
+    <description>
+      Database root user name used for operation
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.root.password</name>
+    <value>root</value>
+    <description>
+      Database root user name used for operation
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.host</name>
+    <value>localhost</value>
+    <description>
+      Database root user name used for operation
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.name</name>
+    <value>rangerkms</value>
+    <description>
+      Driver used for database
+    </description>    
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.javax.persistence.jdbc.user</name>
+    <value>kmsadmin</value>
+    <description>
+      Database user name used for operation
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.javax.persistence.jdbc.password</name>
+    <value>kmsadmin</value>
+    <description>
+      Database user's password 
+    </description>
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.javax.persistence.jdbc.dialect</name>
+    <value>org.eclipse.persistence.platform.database.MySQLPlatform</value>
+    <description>
+      Dialect used for database
+    </description>    
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.javax.persistence.jdbc.driver</name>
+    <value>net.sf.log4jdbc.DriverSpy</value>
+    <description>
+      Driver used for database
+    </description>    
+  </property>
+  
+  <property>
+    <name>ranger.db.ks.sql.connector.jar</name>
+    <value>/usr/share/java/mysql-connector-java.jar</value>
+    <description>
+      Driver used for database
+    </description>    
+  </property>  
+  
+  <property>
+    <name>ranger.db.ks.java.bin</name>
+    <value>java</value>
+    <description>
+      ULR for Database
+    </description>
+  </property>
+    
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/config/kms-webapp/kms-site.xml
----------------------------------------------------------------------
diff --git a/kms/config/kms-webapp/kms-site.xml 
b/kms/config/kms-webapp/kms-site.xml
index a810ca4..06e7ec4 100644
--- a/kms/config/kms-webapp/kms-site.xml
+++ b/kms/config/kms-webapp/kms-site.xml
@@ -18,7 +18,7 @@
 
   <property>
     <name>hadoop.kms.key.provider.uri</name>
-    <value>jceks://file@/${user.home}/kms.keystore</value>
+    <value>dbks://http@localhost:9292/kms</value>
     <description>
       URI of the backing KeyProvider for the KMS.
     </description>
@@ -31,7 +31,7 @@
       If using the JavaKeyStoreProvider, the password for the keystore file.
     </description>
   </property>
-
+  
   <!-- KMS Cache -->
 
   <property>
@@ -169,5 +169,10 @@
       The Kerberos service principal used to connect to Zookeeper.
     </description>
   </property>
+  
+  <property>
+       <name>hadoop.kms.security.authorization.manager</name>
+       <value></value>
+  </property>
 
 </configuration>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/config/webserver/kms_webserver.properties
----------------------------------------------------------------------
diff --git a/kms/config/webserver/kms_webserver.properties 
b/kms/config/webserver/kms_webserver.properties
index e96b9fc..1d227cf 100644
--- a/kms/config/webserver/kms_webserver.properties
+++ b/kms/config/webserver/kms_webserver.properties
@@ -44,4 +44,22 @@ accesslog.pattern=%h %l %u %t "%r" %s %b "%{Referer}i" 
"%{User-Agent}i"
 # Web Application root folder
 #
 xa.webapp.contextName=/kms
-xa.webapp.dir=./webapp/root/hadoop-kms-2.6.0.war
+xa.webapp.dir=./webapp
+
+#
+# Values required for setup script
+#
+realScriptPath=`readlink -f $0`
+realScriptDir=`dirname $realScriptPath`
+RANGER_KMS_DIR=`(cd $realScriptDir/..; pwd)`
+RANGER_KMS_EWS_DIR=${RANGER_KMS_DIR}/ews
+
+app_home=${RANGER_KMS_EWS_DIR}/webapp
+SQL_CONNECTOR_JAR=/usr/share/java/mysql-connector-java.jar
+PYTHON_COMMAND_INVOKER="python"
+JAVA_VERSION_REQUIRED="1.7"
+#
+# Log file path
+#
+LOGFILE=${RANGER_KMS_DIR}/logfile
+LOGFILES="$LOGFILE"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/dev-support/findbugsExcludeFile.xml
----------------------------------------------------------------------
diff --git a/kms/dev-support/findbugsExcludeFile.xml 
b/kms/dev-support/findbugsExcludeFile.xml
new file mode 100644
index 0000000..bc92ed7
--- /dev/null
+++ b/kms/dev-support/findbugsExcludeFile.xml
@@ -0,0 +1,41 @@
+<!--
+   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.
+-->
+<FindBugsFilter>
+  <!--
+    Findbug is complaining about System.out being NULL
+  -->
+  <Match>
+    <Class name="org.apache.hadoop.crypto.key.kms.server.KMSWebApp"/>
+    <Bug pattern="NP_ALWAYS_NULL"/>
+  </Match>
+  <!--
+    KMSWebApp is a webapp singleton managed by the servlet container via
+    ServletContextListener.
+  -->
+  <Match>
+    <Class name="org.apache.hadoop.crypto.key.kms.server.KMSWebApp"/>
+    <Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD"/>
+  </Match>
+  <!--
+    KMSWebApp does an exit to kill the servlet container if the initialization
+    fails.
+  -->
+  <Match>
+    <Class name="org.apache.hadoop.crypto.key.kms.server.KMSWebApp"/>
+    <Bug pattern="DM_EXIT"/>
+  </Match>
+</FindBugsFilter>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/pom.xml
----------------------------------------------------------------------
diff --git a/kms/pom.xml b/kms/pom.xml
index 4c0f73b..5ce8b11 100644
--- a/kms/pom.xml
+++ b/kms/pom.xml
@@ -26,14 +26,6 @@
        <artifactId>ranger</artifactId>
        <version>0.5.0</version>
   </parent>
-  <build>
-       <resources>
-               <resource>
-                       <directory>src/main/resources</directory>
-                       <filtering>true</filtering>
-               </resource>
-       </resources>
-  </build>
   <dependencies>
        <dependency>
                <groupId>org.apache.hadoop</groupId>
@@ -46,5 +38,410 @@
         <artifactId>hadoop-common</artifactId>
         <version>${hadoop-common.version}</version>
     </dependency>
+    <dependency>
+               <groupId>org.eclipse.persistence</groupId>
+               <artifactId>eclipselink</artifactId>
+               <version>${eclipse.jpa.version}</version>
+     </dependency>
+       <dependency>
+               <groupId>org.eclipse.persistence</groupId>
+               <artifactId>javax.persistence</artifactId>
+               <version>${javax.persistence.version}</version>
+    </dependency>
+    <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-aop</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-asm</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-beans</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-context</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-context-support</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-core</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-expression</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-jdbc</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-orm</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-tx</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>org.springframework</groupId>
+                   <artifactId>spring-web</artifactId>
+                   <version>${springframework.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.security</groupId>
+                       <artifactId>xml-security-impl</artifactId>
+                       <version>1.0</version>
+               </dependency>
+               <dependency>
+                   <groupId>com.googlecode.log4jdbc</groupId>
+                   <artifactId>log4jdbc</artifactId>
+                   <version>${googlecode.log4jdbc.version}</version>
+               </dependency>
+               <dependency>
+                   <groupId>mysql</groupId>
+                   <artifactId>mysql-connector-java</artifactId>
+                   <version>${mysql-connector-java.version}</version>
+               </dependency>
+               
+               <!-- Hadoop KMS dependency -->
+       <!-- <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minikdc</artifactId>
+      <version>${hadoop.minikdc.version}</version>
+      <scope>test</scope>
+    </dependency> -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>${mockito.version}</version>      
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-auth</artifactId>
+      <version>${hadoop-auth.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>      
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+      <version>${jersey-server.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-server</artifactId>
+      <version>${jersey-server.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>${servlet.api.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mortbay.jetty</groupId>
+      <artifactId>jetty</artifactId>
+      <version>${mortbay.jetty.version}</version>      
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${log4j.version}</version>      
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j-api.version}</version>      
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <version>${slf4j-api.version}</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jul-to-slf4j</artifactId>
+      <version>${slf4j-api.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mortbay.jetty</groupId>
+      <artifactId>jetty-util</artifactId>
+      <version>${mortbay.jetty.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.codahale.metrics</groupId>
+      <artifactId>metrics-core</artifactId>
+      <version>${metrics.core.version}</version>      
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.curator</groupId>
+      <artifactId>curator-test</artifactId>
+      <version>${curator.test.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>       
+               <groupId>com.sun.jersey</groupId>
+               <artifactId>jersey-bundle</artifactId>
+               <version>${sun-jersey-bundle.version}</version>
+    </dependency>
+    <dependency>
+               <groupId>asm</groupId>
+               <artifactId>asm-all</artifactId>
+               <version>${asm.all.version}</version>
+       </dependency>   
+       <dependency>
+               <groupId>org.apache.httpcomponents</groupId>
+               <artifactId>httpclient</artifactId>
+               <version>${httpcomponents.httpclient.version}</version>
+       </dependency>   
+       
+       <!-- change for version variable -->
+       <dependency>
+               <groupId>javax.activation</groupId>
+               <artifactId>activation</artifactId>
+               <version>1.1</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.directory.server</groupId>
+               <artifactId>apacheds-i18n</artifactId>
+               <version>2.0.0-M15</version>
+       </dependency>   
+       <dependency>
+               <groupId>org.apache.directory.server</groupId>
+               <artifactId>apacheds-kerberos-codec</artifactId>
+               <version>2.0.0-M15</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.directory.api</groupId>
+               <artifactId>api-asn1-api</artifactId>
+               <version>1.0.0-M20</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.directory.api</groupId>
+               <artifactId>api-i18n</artifactId>
+               <version>1.0.0-M20</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.directory.api</groupId>
+               <artifactId>api-util</artifactId>
+               <version>1.0.0-M20</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.avro</groupId>
+               <artifactId>avro</artifactId>
+               <version>1.7.4</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-beanutils</groupId>
+               <artifactId>commons-beanutils</artifactId>
+               <version>1.7.0</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-beanutils</groupId>
+               <artifactId>commons-beanutils-core</artifactId>
+               <version>1.8.0</version>
+       </dependency>   
+       <dependency>
+               <groupId>commons-cli</groupId>
+               <artifactId>commons-cli</artifactId>
+               <version>1.2</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-codec</groupId>
+               <artifactId>commons-codec</artifactId>
+               <version>1.4</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.commons</groupId>
+               <artifactId>commons-compress</artifactId>
+               <version>1.4.1</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-configuration</groupId>
+               <artifactId>commons-configuration</artifactId>
+               <version>1.6</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-digester</groupId>
+               <artifactId>commons-digester</artifactId>
+               <version>1.8</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-io</groupId>
+               <artifactId>commons-io</artifactId>
+               <version>2.4</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.commons</groupId>
+               <artifactId>commons-math3</artifactId>
+               <version>3.1.1</version>
+       </dependency>
+       <dependency>
+               <groupId>commons-net</groupId>
+               <artifactId>commons-net</artifactId>
+               <version>3.1</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.curator</groupId>
+               <artifactId>curator-recipes</artifactId>
+               <version>2.6.0</version>
+       </dependency>
+       <dependency>
+               <groupId>com.google.code.gson</groupId>
+               <artifactId>gson</artifactId>
+               <version>2.2.4</version>
+       </dependency>   
+       <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-annotations</artifactId>
+      <version>${hadoop-auth.version}</version>
+    </dependency>
+    <dependency>
+               <groupId>org.htrace</groupId>
+               <artifactId>htrace-core</artifactId>
+               <version>3.0.4</version>
+       </dependency>
+       <dependency>
+               <groupId>org.apache.httpcomponents</groupId>
+               <artifactId>httpcore</artifactId>
+               <version>4.2.5</version>
+       </dependency>
+       <dependency>
+               <groupId>org.codehaus.jackson</groupId>
+               <artifactId>jackson-core-asl</artifactId>
+               <version>${jackson.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.codehaus.jackson</groupId>
+               <artifactId>jackson-jaxrs</artifactId>
+               <version>${jackson.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.codehaus.jackson</groupId>
+               <artifactId>jackson-mapper-asl</artifactId>
+               <version>${jackson.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.codehaus.jackson</groupId>
+               <artifactId>jackson-xc</artifactId>
+               <version>${jackson.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>javax.xml.bind</groupId>
+               <artifactId>jaxb-api</artifactId>
+               <version>${jaxb-api.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>com.sun.xml.bind</groupId>
+               <artifactId>jaxb-impl</artifactId>
+               <version>${jaxb-impl.version}</version>
+       </dependency>   
+       <dependency>
+               <groupId>com.sun.jersey</groupId>
+               <artifactId>jersey-json</artifactId>
+               <version>${jersey-server.version}</version>
+       </dependency>     
+       <dependency>
+               <groupId>org.codehaus.jettison</groupId>
+               <artifactId>jettison</artifactId>
+               <version>${jettison.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>jline</groupId>
+               <artifactId>jline</artifactId>
+               <version>${jline.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>com.jcraft</groupId>
+               <artifactId>jsch</artifactId>
+               <version>${jsch.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>com.google.code.findbugs</groupId>
+               <artifactId>jsr305</artifactId>
+               <version>${jsr305.version}</version>
+       </dependency>   
+       <dependency>
+               <groupId>io.netty</groupId>
+               <artifactId>netty</artifactId>
+               <version>${netty.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>com.thoughtworks.paranamer</groupId>
+               <artifactId>paranamer</artifactId>
+               <version>${paranamer.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>com.google.protobuf</groupId>
+               <artifactId>protobuf-java</artifactId>
+               <version>${protobuf-java.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>org.xerial.snappy</groupId>
+               <artifactId>snappy-java</artifactId>
+               <version>${snappy-java.version}</version>
+       </dependency>
+       <dependency>
+               <groupId>xmlenc</groupId>
+               <artifactId>xmlenc</artifactId>
+               <version>${xmlenc.version}</version>
+       </dependency>   
+       <dependency>
+               <groupId>org.tukaani</groupId>
+               <artifactId>xz</artifactId>
+               <version>${xz.version}</version>
+       </dependency>             
   </dependencies>
+  <build>
+  <pluginManagement>
+       <plugins>
+               <plugin>
+                       <groupId>org.apache.maven.plugins</groupId>
+                       <artifactId>maven-war-plugin</artifactId>
+                       <version>2.4</version>
+               </plugin>
+       </plugins>
+       </pluginManagement>
+       <resources>
+               <resource>
+                       <directory>src/main/resources</directory>
+                       <filtering>true</filtering>
+               </resource>
+       </resources>
+  </build>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/scripts/db/mysql/kms_core_db.sql
----------------------------------------------------------------------
diff --git a/kms/scripts/db/mysql/kms_core_db.sql 
b/kms/scripts/db/mysql/kms_core_db.sql
new file mode 100644
index 0000000..b95a75b
--- /dev/null
+++ b/kms/scripts/db/mysql/kms_core_db.sql
@@ -0,0 +1,30 @@
+DROP TABLE IF EXISTS `ranger_masterkey`;
+CREATE TABLE `ranger_masterkey` (
+`id` bigint( 20 ) NOT NULL AUTO_INCREMENT ,
+`create_time` datetime DEFAULT NULL ,
+`update_time` datetime DEFAULT NULL ,
+`added_by_id` bigint( 20 ) DEFAULT NULL ,
+`upd_by_id` bigint( 20 ) DEFAULT NULL ,
+`cipher` varchar( 255 ) DEFAULT NULL ,
+`bitlength` int DEFAULT NULL ,
+`masterkey` varchar(2048),
+PRIMARY KEY ( `id` )
+)ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+DROP TABLE IF EXISTS `ranger_keystore`;
+CREATE TABLE `ranger_keystore` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `create_time` datetime DEFAULT NULL,
+  `update_time` datetime DEFAULT NULL,
+  `added_by_id` bigint(20) DEFAULT NULL,
+  `upd_by_id` bigint(20) DEFAULT NULL,
+  `kms_alias` varchar(255) NOT NULL,
+  `kms_createdDate` bigint(20) DEFAULT NULL,
+  `kms_cipher` varchar(255) DEFAULT NULL,
+   `kms_bitLength` bigint(20) DEFAULT NULL,
+  `kms_description` varchar(512) DEFAULT NULL,
+  `kms_version` bigint(20) DEFAULT NULL,
+  `kms_attributes` varchar(1024) DEFAULT NULL,
+  `kms_encoded`varchar(2048),
+  PRIMARY KEY (`id`)
+)ENGINE=InnoDB DEFAULT CHARSET=latin1;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/scripts/db_setup.py
----------------------------------------------------------------------
diff --git a/kms/scripts/db_setup.py b/kms/scripts/db_setup.py
new file mode 100644
index 0000000..301bdcc
--- /dev/null
+++ b/kms/scripts/db_setup.py
@@ -0,0 +1,252 @@
+#
+# 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. See accompanying LICENSE file.
+#
+
+import os
+import re
+import sys
+import errno
+import shlex
+import logging
+import subprocess
+import fileinput
+from os.path import basename
+from datetime import date
+from xml.etree import ElementTree as ET
+globalDict = {}
+
+def check_output(query):
+       p = subprocess.Popen(query, stdout=subprocess.PIPE)
+       output = p.communicate ()[0]
+       return output
+       
+def log(msg,type):
+       if type == 'info':
+               logging.info(" %s",msg)
+       if type == 'debug':
+               logging.debug(" %s",msg)
+       if type == 'warning':
+               logging.warning(" %s",msg)
+       if type == 'exception':
+               logging.exception(" %s",msg)
+
+def populate_global_dict():
+    global globalDict
+    os.chdir("..")
+    read_config_file = 
open(os.path.join(os.getcwd(),'ews/webapp/config/dbks-site.xml'))
+    dbks_site_properties = import_properties_from_xml(read_config_file, 
globalDict)
+
+class BaseDB(object):
+
+       def init_logfiles(self):
+               FORMAT = '%(asctime)-15s %(message)s'
+               logging.basicConfig(format=FORMAT, level=logging.DEBUG) 
+
+       def create_rangerdb_user(self, root_user, db_user, db_password, 
db_root_password):      
+               log("---------- Creating User ----------", "info")
+
+       def check_table(self, db_name, root_user, db_root_password, TABLE_NAME):
+               log("---------- Verifying table ----------", "info")
+       def import_file_to_db(self, root_user, db_name, db_user, db_password, 
db_root_password, file_name):     
+               log("---------- Importing db schema ----------", "info")
+       
+class MysqlConf(BaseDB):
+       # Constructor
+       def __init__(self, host,SQL_CONNECTOR_JAR,JAVA_BIN):
+               self.host = host
+               self.SQL_CONNECTOR_JAR = SQL_CONNECTOR_JAR
+               self.JAVA_BIN = JAVA_BIN
+               BaseDB.init_logfiles(self)
+
+       def get_jisql_cmd(self, user, password ,db_name):
+               #TODO: User array for forming command
+               jisql_cmd = "%s -cp %s:jisql/lib/* org.apache.util.sql.Jisql 
-driver mysqlconj -cstring jdbc:mysql://%s/%s -u %s -p %s -noheader -trim -c 
\;" %(self.JAVA_BIN,self.SQL_CONNECTOR_JAR,self.host,db_name,user,password)
+               return jisql_cmd
+
+               
+       def create_rangerdb_user(self, root_user, db_user, db_password, 
db_root_password):
+               hosts_arr =["%", "localhost"]
+               for host in hosts_arr:
+                       get_cmd = self.get_jisql_cmd(root_user, 
db_root_password ,'mysql')
+                       query = get_cmd + " -query \"select user from 
mysql.user where user='%s' and host='%s';\"" %(db_user,host)
+                       output = check_output(shlex.split(query))
+                       if output.strip(db_user + " |"):
+                               log( "\nMYSQL User: " + db_user + " already 
exists!", "debug")
+                       else:
+                               log("User does not exists", "info")
+                               if db_password == "":
+                                       log ("Creating MySQL user: "+ db_user 
+" with DB password blank\n", "info")
+                                       query = get_cmd + " -query \"create 
user '%s'@'%s';\"" %(db_user, host)
+                                       ret = 
subprocess.check_call(shlex.split(query))
+                                       if ret == 0:
+                                               query = get_cmd + " -query 
\"select user from mysql.user where user='%s' and host='%s';\"" %(db_user,host)
+                                               output = 
check_output(shlex.split(query))
+                                               if output.strip(db_user + " |"):
+                                                       log("Mysql user " + 
db_user +" created","info") 
+                                               else:
+                                                       log("Creating Mysql 
user " + db_user +" Failed","info") 
+                                                       sys.exit(1)
+                               else:
+                                       log ("Creating MySQL user: "+ db_user 
+" with DB password\n", "info")
+                                       query = get_cmd + " -query \"create 
user '%s'@'%s' identified by '%s';\"" %(db_user, host, db_password)
+                                       ret = 
subprocess.check_call(shlex.split(query))
+                                       if ret == 0:
+                                               log("Mysql user " + db_user +" 
created","info") 
+                                       else:
+                                               log("Creating Mysql user " + 
db_user +" Failed","info") 
+                                               sys.exit(1)
+
+        def verify_db(self, root_user, db_root_password, db_name):
+                log("\nVerifying Database: " + db_name + "\n", "debug")
+                get_cmd = self.get_jisql_cmd(root_user, db_root_password, 
'mysql')
+                query = get_cmd + " -query \"show databases like '%s';\"" 
%(db_name)
+                output = check_output(shlex.split(query))
+                if output.strip(db_name + " |"):
+                        return True
+                else:
+                        return False
+
+
+        def import_file_to_db(self, root_user, db_name, db_user, db_password, 
db_root_password, file_name):
+                log ("\nImporting db schema to Database: " + db_name,"debug");
+                if self.verify_db(root_user, db_root_password, db_name):
+                        log("\nDatabase: "+db_name + " already exists. 
Ignoring import_db\n","info")
+                else:
+                        log("\nDatabase does not exist. Creating database : " 
+ db_name,"info")
+                       get_cmd = self.get_jisql_cmd(root_user, 
db_root_password, 'mysql')
+                        query = get_cmd + " -query \"create database %s;\"" 
%(db_name)
+                       ret = subprocess.check_call(shlex.split(query))
+                       if ret != 0:
+                               log("\nDatabase creation failed!!\n","info")
+                               sys.exit(1)
+                       else:
+                               if self.verify_db(root_user, db_root_password, 
db_name):
+                                       log("Creating database: " + db_name + " 
succeeded", "info")
+                                       self.import_db_file(db_name, root_user 
, db_user, db_password, db_root_password, file_name)
+                               else:
+                                       log("\nDatabase creation 
failed!!\n","info")
+                                       sys.exit(1)
+
+
+       def grant_xa_db_user(self, root_user, db_name, db_user, db_password, 
db_root_password , is_revoke):
+               hosts_arr =["%", "localhost"]
+               if is_revoke:
+                       for host in hosts_arr:
+                               get_cmd = self.get_jisql_cmd(root_user, 
db_root_password, 'mysql')
+                               query = get_cmd + " -query \"REVOKE ALL 
PRIVILEGES,GRANT OPTION FROM '%s'@'%s';\"" %(db_user, host)
+                               ret = subprocess.check_call(shlex.split(query))
+                               if ret == 0:
+                                       query = get_cmd + " -query \"FLUSH 
PRIVILEGES;\""
+                                       ret = 
subprocess.check_call(shlex.split(query))
+                                       if ret != 0:
+                                               sys.exit(1)
+                               else:
+                                       sys.exit(1)
+       
+               for host in hosts_arr:
+                       log ("---------------GRANTING PRIVILEGES TO user 
'"+db_user+"'@'"+host+"' on db '"+db_name+"'-------------" , "info")
+                       get_cmd = self.get_jisql_cmd(root_user, 
db_root_password, 'mysql')
+                       query = get_cmd + " -query \"grant all privileges on 
%s.* to '%s'@'%s' with grant option;\"" %(db_name,db_user, host)
+                       ret = subprocess.check_call(shlex.split(query))
+                       if ret == 0:
+                               log ("---------------FLUSH PRIVILEGES 
-------------" , "info")
+                               query = get_cmd + " -query \"FLUSH 
PRIVILEGES;\""
+                               ret = subprocess.check_call(shlex.split(query))
+                               if ret == 0:
+                                       log("Privileges granted to '" + db_user 
+ "' on '"+db_name+"'\n", "info")
+                               else:
+                                       log("Granting privileges to '" 
+db_user+"' FAILED on '"+db_name+"'\n", "info")
+                                       sys.exit(1)
+                       else:
+                               log("\nGranting privileges to '" +db_user+"' 
FAILED on '"+db_name+"'\n", "info")
+                               sys.exit(1)
+
+       def import_db_file(self, db_name, root_user, db_user, db_password, 
db_root_password, file_name):
+               name = basename(file_name)
+               if os.path.isfile(file_name):
+                       log("Importing db schema to database : " + db_name + " 
from file: " + name,"info")
+                       get_cmd = self.get_jisql_cmd(root_user, 
db_root_password, db_name)
+                       query = get_cmd + " -input %s" %file_name
+                       ret = subprocess.check_call(shlex.split(query))
+                       if ret == 0:
+                               log(name + " DB schema imported 
successfully\n","info")
+                       else:
+                               log(name + " DB Schema import failed!\n","info")
+                               sys.exit(1)
+               else:
+                   log("\nDB Schema file " + name+ " not found\n","exception")
+                   sys.exit(1)
+
+       def check_table(self, db_name, root_user, db_root_password, TABLE_NAME):
+                if self.verify_db(root_user, db_root_password, db_name):
+                       log("Verifying table " + TABLE_NAME +" in database " + 
db_name, "debug")
+
+                       get_cmd = self.get_jisql_cmd(root_user, 
db_root_password, db_name)
+                       query = get_cmd + " -query \"show tables like '%s';\"" 
%(TABLE_NAME)
+                       output = check_output(shlex.split(query))       
+                       if output.strip(TABLE_NAME + " |"):
+                               log("Table " + TABLE_NAME +" already exists in  
database " + db_name + "\n","info")
+                               return True 
+                       else:
+                               log("Table " + TABLE_NAME +" does not exist in 
database " + db_name + "\n","info")
+                               return False
+               else:
+                       log("Database " + db_name +" does not exist\n","info")
+                       return False
+
+def import_properties_from_xml(xml_path, properties_from_xml=None):
+       xml = ET.parse(xml_path)
+       root = xml.getroot()
+       if properties_from_xml is None:
+               properties_from_xml = dict()
+       for child in root.findall('property'):
+               name = child.find("name").text.strip()
+               value = child.find("value").text.strip() if 
child.find("value").text is not None else ""
+               properties_from_xml[name] = value
+       return properties_from_xml
+
+
+def main():
+       populate_global_dict()
+       JAVA_BIN=globalDict['ranger.db.ks.java.bin']
+       XA_DB_FLAVOR=globalDict['ranger.db.ks.database.flavor']
+       XA_DB_FLAVOR.upper()
+       
+       xa_db_host = globalDict['ranger.db.host']
+
+       mysql_core_file = globalDict['ranger.db.ks.core.file']
+
+       db_name = globalDict['ranger.db.ks.name']
+       db_user = globalDict['ranger.db.ks.javax.persistence.jdbc.user']
+       db_password = globalDict['ranger.db.ks.javax.persistence.jdbc.password']
+       xa_db_root_user = globalDict['ranger.db.root.user']
+       xa_db_root_password = globalDict['ranger.db.root.password']
+
+       if XA_DB_FLAVOR == "MYSQL":
+               
MYSQL_CONNECTOR_JAR=globalDict['ranger.db.ks.sql.connector.jar']                
+               xa_sqlObj = MysqlConf(xa_db_host,MYSQL_CONNECTOR_JAR,JAVA_BIN)
+               xa_db_core_file_script = os.path.join(os.getcwd(),'scripts')
+                xa_db_core_file = 
os.path.join(xa_db_core_file_script,mysql_core_file)
+       else:
+               log ("--------- NO SUCH FLAVOUR ---------", "info")
+               sys.exit(1)
+
+       # Methods Begin
+       log("\n--------- Creating kms user --------- \n","info")
+       xa_sqlObj.create_rangerdb_user(xa_db_root_user, db_user, db_password, 
xa_db_root_password)
+       log("\n--------- Importing DB Core Database ---------\n","info")        
+       xa_sqlObj.import_file_to_db(xa_db_root_user, db_name, db_user, 
db_password, xa_db_root_password, xa_db_core_file)
+       xa_sqlObj.grant_xa_db_user(xa_db_root_user, db_name, db_user, 
db_password, xa_db_root_password, True)
+
+main()
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/scripts/ranger-kms
----------------------------------------------------------------------
diff --git a/kms/scripts/ranger-kms b/kms/scripts/ranger-kms
index a7cc20e..f049dd2 100755
--- a/kms/scripts/ranger-kms
+++ b/kms/scripts/ranger-kms
@@ -39,7 +39,7 @@ stop)
 restart)
        echo "Stopping Apache Ranger Kms."
        ${BIN_PATH}/${MOD_NAME} stop
-       echo "Stopping Apache Ranger Kms."
+       echo "Starting Apache Ranger Kms."
        ${BIN_PATH}/${MOD_NAME} start
        ;;
 *)

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/scripts/ranger-kms-services.sh
----------------------------------------------------------------------
diff --git a/kms/scripts/ranger-kms-services.sh 
b/kms/scripts/ranger-kms-services.sh
index 7c80cc8..8677c64 100755
--- a/kms/scripts/ranger-kms-services.sh
+++ b/kms/scripts/ranger-kms-services.sh
@@ -71,7 +71,7 @@ fi
 
 KMS_CONF_DIR=${RANGER_KMS_EWS_DIR}/webapp/config/
 
-JAVA_OPTS="${JAVA_OPTS} -Dcatalina.base=${RANGER_KMS_EWS_DIR} 
-Dkms.config.dir=${KMS_CONF_DIR} -Dkms.log.dir=${TOMCAT_LOG_DIR} -cp 
${RANGER_KMS_EWS_CONF_DIR}:${RANGER_KMS_EWS_LIB_DIR}/*:${JAVA_HOME}/lib/* "
+JAVA_OPTS="${JAVA_OPTS} -Dcatalina.base=${RANGER_KMS_EWS_DIR} 
-Dkms.config.dir=${KMS_CONF_DIR} -Dkms.log.dir=${TOMCAT_LOG_DIR} -cp 
${RANGER_KMS_EWS_CONF_DIR}:${RANGER_KMS_EWS_LIB_DIR}/*:${RANGER_KMS_EWS_DIR}/webapp/lib/*:${JAVA_HOME}/lib/*
 "
 
 if [ "${action^^}" == "START" ]; then
        echo "+ java -D${PROC_NAME} ${JAVA_OPTS} ${START_CLASS_NAME} 
${KMS_CONFIG_FILENAME} "

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/scripts/setup.sh
----------------------------------------------------------------------
diff --git a/kms/scripts/setup.sh b/kms/scripts/setup.sh
new file mode 100644
index 0000000..fa88bba
--- /dev/null
+++ b/kms/scripts/setup.sh
@@ -0,0 +1,172 @@
+#!/bin/bash
+# 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.
+# 
-------------------------------------------------------------------------------------
+#
+# Ranger KMS Setup Script
+#
+# This script will install ranger kms webapplication under tomcat and also, 
initialize the database with ranger kms users/tables.
+
+realScriptPath=`readlink -f $0`
+realScriptDir=`dirname $realScriptPath`
+RANGER_KMS_DIR=`(cd $realScriptDir/..; pwd)`
+RANGER_KMS_EWS_DIR=${RANGER_KMS_DIR}/ews
+RANGER_KMS_EWS_CONF_DIR="${RANGER_KMS_EWS_DIR}/conf"
+RANGER_KMS_EWS_LIB_DIR="${RANGER_KMS_EWS_DIR}/lib"
+
+PROPFILE=${RANGER_KMS_EWS_CONF_DIR}/kms_webserver.properties
+propertyValue=''
+
+. $PROPFILE 1>/dev/null 2>&1
+if [ ! $? = "0" ];then
+       log "$PROPFILE file not found....!!";
+       exit 1;
+fi
+
+usage() {
+  [ "$*" ] && echo "$0: $*"
+  sed -n '/^##/,/^$/s/^## \{0,1\}//p' "$0"
+  exit 2
+} 2>/dev/null
+
+log() {
+   local prefix="[$(date +%Y/%m/%d\ %H:%M:%S)]: "
+   echo "${prefix} $@" >> $LOGFILE
+   echo "${prefix} $@"
+}
+
+check_ret_status(){
+       if [ $1 -ne 0 ]; then
+               log "[E] $2";
+               exit 1;
+       fi
+}
+
+is_command () {
+    log "[I] check if command $1 exists"
+    type "$1" >/dev/null
+}
+
+get_distro(){
+       log "[I] Checking distribution name.."
+       ver=$(cat /etc/*{issues,release,version} 2> /dev/null)
+       if [[ $(echo $ver | grep DISTRIB_ID) ]]; then
+           DIST_NAME=$(lsb_release -si)
+       else
+           DIST_NAME=$(echo $ver | cut -d ' ' -f 1 | sort -u | head -1)
+       fi
+       export $DIST_NAME
+       log "[I] Found distribution : $DIST_NAME"
+
+}
+
+init_logfiles () {
+    for f in $LOGFILES; do
+        touch $f
+    done
+}
+
+init_variables(){
+       curDt=`date '+%Y%m%d%H%M%S'`
+
+       INSTALL_DIR=${RANGER_KMS_DIR}
+
+       DB_FLAVOR=`echo $DB_FLAVOR | tr '[:lower:]' '[:upper:]'`
+       if [ "${DB_FLAVOR}" == "" ]
+       then
+               DB_FLAVOR="MYSQL"
+       fi
+       log "[I] DB_FLAVOR=${DB_FLAVOR}"
+}
+
+check_python_command() {
+               if is_command ${PYTHON_COMMAND_INVOKER} ; then
+                       log "[I] '${PYTHON_COMMAND_INVOKER}' command found"
+               else
+                       log "[E] '${PYTHON_COMMAND_INVOKER}' command not found"
+               exit 1;
+               fi
+}
+
+check_java_version() {
+       #Check for JAVA_HOME
+       if [ "${JAVA_HOME}" == "" ]
+       then
+               log "[E] JAVA_HOME environment property not defined, aborting 
installation."
+               exit 1
+       fi
+
+        export JAVA_BIN=${JAVA_HOME}/bin/java
+
+       if is_command ${JAVA_BIN} ; then
+               log "[I] '${JAVA_BIN}' command found"
+       else
+               log "[E] '${JAVA_BIN}' command not found"
+               exit 1;
+       fi
+
+       $JAVA_BIN -version 2>&1 | grep -q $JAVA_VERSION_REQUIRED
+       if [ $? != 0 ] ; then
+               log "[E] Java 1.7 is required"
+               exit 1;
+       fi
+}
+
+sanity_check_files() {
+
+       if test -d $app_home; then
+               log "[I] $app_home folder found"
+       else
+               log "[E] $app_home does not exists" ; exit 1;
+    fi
+       if [ "${DB_FLAVOR}" == "MYSQL" ]
+    then
+               if test -f $mysql_core_file; then
+                       log "[I] $mysql_core_file file found"
+               else
+                       log "[E] $mysql_core_file does not exists" ; exit 1;
+               fi
+       fi      
+}
+
+copy_db_connector(){
+       log "[I] Copying ${DB_FLAVOR} Connector to $app_home/lib ";
+    cp -f $SQL_CONNECTOR_JAR $app_home/lib
+       check_ret_status $? "Copying ${DB_FLAVOR} Connector to $app_home/lib 
failed"
+       log "[I] Copying ${DB_FLAVOR} Connector to $app_home/lib DONE";
+}
+
+setup_kms(){
+        #copying ranger kms provider 
+        cd ${RANGER_KMS_EWS_DIR}/webapp
+        log "[I] Adding ranger kms provider as services in hadoop-common jar"
+        jar -uf lib/hadoop-common*.jar 
META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
+}
+
+
+init_logfiles
+log " --------- Running ranger kms Web Application Install Script --------- "
+log "[I] uname=`uname`"
+log "[I] hostname=`hostname`"
+init_variables
+get_distro
+check_java_version
+sanity_check_files
+copy_db_connector
+check_python_command
+$PYTHON_COMMAND_INVOKER db_setup.py    
+setup_kms
+
+echo "Installation of ranger kms is completed."

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/EncryptedPrivateKeyInfo.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/EncryptedPrivateKeyInfo.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/EncryptedPrivateKeyInfo.java
new file mode 100644
index 0000000..ec8f67d
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/EncryptedPrivateKeyInfo.java
@@ -0,0 +1,111 @@
+package org.apache.hadoop.crypto.key;
+
+import java.io.*;
+
+import sun.security.x509.AlgorithmId;
+import sun.security.util.*;
+
+/**
+ * This class implements the <code>EncryptedPrivateKeyInfo</code> type,
+ * which is defined in PKCS #8 as follows:
+ *
+ * <pre>
+ * EncryptedPrivateKeyInfo ::=  SEQUENCE {
+ *     encryptionAlgorithm   AlgorithmIdentifier,
+ *     encryptedData   OCTET STRING }
+ * </pre>
+ *
+ * @author Jan Luehe
+ */
+final class EncryptedPrivateKeyInfo {
+
+    // the "encryptionAlgorithm" field
+    private AlgorithmId algid;
+
+    // the "encryptedData" field
+    private byte[] encryptedData;
+
+    // the ASN.1 encoded contents of this class
+    private byte[] encoded;
+
+    /**
+     * Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from
+     * its encoding.
+     */
+    @SuppressWarnings("restriction")
+       EncryptedPrivateKeyInfo(byte[] encoded) throws IOException {
+        DerValue val = new DerValue(encoded);
+
+        DerValue[] seq = new DerValue[2];
+
+        seq[0] = val.data.getDerValue();
+        seq[1] = val.data.getDerValue();
+
+        if (val.data.available() != 0) {
+            throw new IOException("overrun, bytes = " + val.data.available());
+        }
+
+        this.algid = AlgorithmId.parse(seq[0]);
+        if (seq[0].data.available() != 0) {
+            throw new IOException("encryptionAlgorithm field overrun");
+        }
+
+        this.encryptedData = seq[1].getOctetString();
+        if (seq[1].data.available() != 0)
+            throw new IOException("encryptedData field overrun");
+
+        this.encoded = (byte[])encoded.clone();
+    }
+
+    /**
+     * Constructs an <code>EncryptedPrivateKeyInfo</code> from the
+     * encryption algorithm and the encrypted data.
+     */
+    @SuppressWarnings("restriction")
+       EncryptedPrivateKeyInfo(AlgorithmId algid, byte[] encryptedData) {
+        this.algid = algid;
+        this.encryptedData = (byte[])encryptedData.clone();
+        this.encoded = null; // lazy generation of encoding
+    }
+
+    /**
+     * Returns the encryption algorithm.
+     */
+    @SuppressWarnings("restriction")
+       AlgorithmId getAlgorithm() {
+        return this.algid;
+    }
+
+    /**
+     * Returns the encrypted data.
+     */
+    byte[] getEncryptedData() {
+        return (byte[])this.encryptedData.clone();
+    }
+
+    /**
+     * Returns the ASN.1 encoding of this class.
+     */
+    @SuppressWarnings("restriction")
+    byte[] getEncoded()
+        throws IOException
+    {
+        if (this.encoded != null) return (byte[])this.encoded.clone();
+
+        
+               DerOutputStream out = new DerOutputStream();
+        DerOutputStream tmp = new DerOutputStream();
+
+        // encode encryption algorithm
+        algid.encode(tmp);
+
+        // encode encrypted data
+        tmp.putOctetString(encryptedData);
+
+        // wrap everything into a SEQUENCE
+        out.write(DerValue.tag_Sequence, tmp);
+        this.encoded = out.toByteArray();
+
+        return (byte[])this.encoded.clone();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/KeyProtector.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/KeyProtector.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/KeyProtector.java
new file mode 100644
index 0000000..5c43301
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/KeyProtector.java
@@ -0,0 +1,541 @@
+package org.apache.hadoop.crypto.key;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.security.KeyRep;
+import java.security.Security;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.AlgorithmParameters;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.SealedObject;
+import javax.crypto.spec.*;
+
+import com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher;
+
+import sun.security.x509.AlgorithmId;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+
+/**
+ * This class implements a protection mechanism for private keys. In JCE, we
+ * use a stronger protection mechanism than in the JDK, because we can use
+ * the <code>Cipher</code> class.
+ * Private keys are protected using the JCE mechanism, and are recovered using
+ * either the JDK or JCE mechanism, depending on how the key has been
+ * protected. This allows us to parse Sun's keystore implementation that ships
+ * with JDK 1.2.
+ *
+ * @author Jan Luehe
+ *
+ *
+ * @see JceKeyStore
+ */
+
+final class KeyProtector {
+
+    // defined by SunSoft (SKI project)
+    private static final String PBE_WITH_MD5_AND_DES3_CBC_OID
+            = "1.3.6.1.4.1.42.2.19.1";
+
+    // JavaSoft proprietary key-protection algorithm (used to protect private
+    // keys in the keystore implementation that comes with JDK 1.2)
+    private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
+
+    private static final int SALT_LEN = 20; // the salt length
+    private static final int DIGEST_LEN = 20;
+
+    // the password used for protecting/recovering keys passed through this
+    // key protector
+    private char[] password;
+
+    private static final Provider PROV = Security.getProvider("SunJCE");
+    
+    KeyProtector(char[] password) {
+        if (password == null) {
+           throw new IllegalArgumentException("password can't be null");
+        }
+        this.password = password;
+    }
+
+    /**
+     * Protects the given cleartext private key, using the password provided at
+     * construction time.
+     */
+    byte[] protect(PrivateKey key)
+        throws Exception
+    {
+        // create a random salt (8 bytes)
+        byte[] salt = new byte[8];
+        new SecureRandom().nextBytes(salt);
+
+        // create PBE parameters from salt and iteration count
+        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+
+        // create PBE key from password
+        PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
+        SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
+        pbeKeySpec.clearPassword();
+
+        // encrypt private key
+        Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+        cipher.init(Cipher.ENCRYPT_MODE, sKey, pbeSpec, null);
+        byte[] plain = (byte[])key.getEncoded();
+        byte[] encrKey = cipher.doFinal(plain, 0, plain.length);
+        
+        // wrap encrypted private key in EncryptedPrivateKeyInfo
+        // (as defined in PKCS#8)
+        AlgorithmParameters pbeParams = AlgorithmParameters.getInstance("PBE", 
PROV);
+        pbeParams.init(pbeSpec);
+
+        AlgorithmId encrAlg = new AlgorithmId(new 
ObjectIdentifier(PBE_WITH_MD5_AND_DES3_CBC_OID), pbeParams);
+        return new EncryptedPrivateKeyInfo(encrAlg,encrKey).getEncoded();
+    }
+
+    /*
+     * Recovers the cleartext version of the given key (in protected format),
+     * using the password provided at construction time.
+     */
+    Key recover(EncryptedPrivateKeyInfo encrInfo)
+        throws UnrecoverableKeyException, NoSuchAlgorithmException
+    {
+        byte[] plain;
+
+        try {
+            String encrAlg = encrInfo.getAlgorithm().getOID().toString();
+            if (!encrAlg.equals(PBE_WITH_MD5_AND_DES3_CBC_OID)
+                && !encrAlg.equals(KEY_PROTECTOR_OID)) {
+                throw new UnrecoverableKeyException("Unsupported encryption "
+                                                    + "algorithm");
+            }
+
+            if (encrAlg.equals(KEY_PROTECTOR_OID)) {
+                // JDK 1.2 style recovery
+                plain = recover(encrInfo.getEncryptedData());
+            } else {
+                byte[] encodedParams =
+                    encrInfo.getAlgorithm().getEncodedParams();
+
+                // parse the PBE parameters into the corresponding spec
+                AlgorithmParameters pbeParams =
+                    AlgorithmParameters.getInstance("PBE");
+                pbeParams.init(encodedParams);
+                PBEParameterSpec pbeSpec = (PBEParameterSpec)
+                    pbeParams.getParameterSpec(PBEParameterSpec.class);
+
+                // create PBE key from password
+                PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
+                SecretKey sKey =
+                    new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
+                pbeKeySpec.clearPassword();
+
+                // decrypt private key
+                Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+                cipher.init(Cipher.DECRYPT_MODE, sKey, pbeSpec, null);
+                plain= cipher.doFinal(encrInfo.getEncryptedData(), 0, 
encrInfo.getEncryptedData().length);
+            }
+
+            // determine the private-key algorithm, and parse private key
+            // using the appropriate key factory
+            String oidName = new AlgorithmId(new 
PrivateKeyInfo(plain).getAlgorithm().getOID()).getName();
+            KeyFactory kFac = KeyFactory.getInstance(oidName);
+            return kFac.generatePrivate(new PKCS8EncodedKeySpec(plain));
+
+        } catch (NoSuchAlgorithmException ex) {
+            // Note: this catch needed to be here because of the
+            // later catch of GeneralSecurityException
+            throw ex;
+        } catch (IOException ioe) {
+            throw new UnrecoverableKeyException(ioe.getMessage());
+        } catch (GeneralSecurityException gse) {
+            throw new UnrecoverableKeyException(gse.getMessage());
+        }
+    }
+
+    /*
+     * Recovers the cleartext version of the given key (in protected format),
+     * using the password provided at construction time. This method implements
+     * the recovery algorithm used by Sun's keystore implementation in
+     * JDK 1.2.
+     */
+    private byte[] recover(byte[] protectedKey)
+        throws UnrecoverableKeyException, NoSuchAlgorithmException
+    {
+        int i, j;
+        byte[] digest;
+        int numRounds;
+        int xorOffset; // offset in xorKey where next digest will be stored
+        int encrKeyLen; // the length of the encrpyted key
+
+        MessageDigest md = MessageDigest.getInstance("SHA");
+
+        // Get the salt associated with this key (the first SALT_LEN bytes of
+        // <code>protectedKey</code>)
+        byte[] salt = new byte[SALT_LEN];
+        System.arraycopy(protectedKey, 0, salt, 0, SALT_LEN);
+
+        // Determine the number of digest rounds
+        encrKeyLen = protectedKey.length - SALT_LEN - DIGEST_LEN;
+        numRounds = encrKeyLen / DIGEST_LEN;
+        if ((encrKeyLen % DIGEST_LEN) != 0)
+            numRounds++;
+
+        // Get the encrypted key portion and store it in "encrKey"
+        byte[] encrKey = new byte[encrKeyLen];
+        System.arraycopy(protectedKey, SALT_LEN, encrKey, 0, encrKeyLen);
+
+        // Set up the byte array which will be XORed with "encrKey"
+        byte[] xorKey = new byte[encrKey.length];
+
+        // Convert password to byte array, so that it can be digested
+        byte[] passwdBytes = new byte[password.length * 2];
+        for (i=0, j=0; i<password.length; i++) {
+            passwdBytes[j++] = (byte)(password[i] >> 8);
+            passwdBytes[j++] = (byte)password[i];
+        }
+
+        // Compute the digests, and store them in "xorKey"
+        for (i = 0, xorOffset = 0, digest = salt;
+             i < numRounds;
+             i++, xorOffset += DIGEST_LEN) {
+            md.update(passwdBytes);
+            md.update(digest);
+            digest = md.digest();
+            md.reset();
+            // Copy the digest into "xorKey"
+            if (i < numRounds - 1) {
+                System.arraycopy(digest, 0, xorKey, xorOffset,
+                                 digest.length);
+            } else {
+                System.arraycopy(digest, 0, xorKey, xorOffset,
+                                 xorKey.length - xorOffset);
+            }
+        }
+
+        // XOR "encrKey" with "xorKey", and store the result in "plainKey"
+        byte[] plainKey = new byte[encrKey.length];
+        for (i = 0; i < plainKey.length; i++) {
+            plainKey[i] = (byte)(encrKey[i] ^ xorKey[i]);
+        }
+
+        // Check the integrity of the recovered key by concatenating it with
+        // the password, digesting the concatenation, and comparing the
+        // result of the digest operation with the digest provided at the end
+        // of <code>protectedKey</code>. If the two digest values are
+        // different, throw an exception.
+        md.update(passwdBytes);
+        java.util.Arrays.fill(passwdBytes, (byte)0x00);
+        passwdBytes = null;
+        md.update(plainKey);
+        digest = md.digest();
+        md.reset();
+        for (i = 0; i < digest.length; i++) {
+            if (digest[i] != protectedKey[SALT_LEN + encrKeyLen + i]) {
+                throw new UnrecoverableKeyException("Cannot recover key");
+            }
+        }
+        return plainKey;
+    }
+
+    /**
+     * Seals the given cleartext key, using the password provided at
+     * construction time
+     */
+    SealedObject seal(Key key)
+        throws Exception
+    {
+        // create a random salt (8 bytes)
+        byte[] salt = new byte[8];
+        new SecureRandom().nextBytes(salt);
+
+        // create PBE parameters from salt and iteration count
+        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+
+        // create PBE key from password
+        PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
+        SecretKey sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
+        pbeKeySpec.clearPassword();
+
+        // seal key
+        Cipher cipher;
+
+        PBEWithMD5AndTripleDESCipher cipherSpi;
+        cipherSpi = new PBEWithMD5AndTripleDESCipher();
+        cipher = new CipherForKeyProtector(cipherSpi, PROV,
+                                           "PBEWithMD5AndTripleDES");
+        cipher.init(Cipher.ENCRYPT_MODE, sKey, pbeSpec);
+        return new SealedObjectForKeyProtector(key, cipher);
+    }
+
+    /**
+     * Unseals the sealed key.
+     */
+    Key unseal(SealedObject so)
+        throws NoSuchAlgorithmException, UnrecoverableKeyException
+    {
+        try {
+            // create PBE key from password
+            PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
+            SecretKey skey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES");
+            pbeKeySpec.clearPassword();
+
+            SealedObjectForKeyProtector soForKeyProtector = null;
+            if (!(so instanceof SealedObjectForKeyProtector)) {
+                soForKeyProtector = new SealedObjectForKeyProtector(so);
+            } else {
+                soForKeyProtector = (SealedObjectForKeyProtector)so;
+            }
+            AlgorithmParameters params = soForKeyProtector.getParameters();
+            if (params == null) {
+                throw new UnrecoverableKeyException("Cannot get " +
+                                                    "algorithm parameters");
+            }
+            PBEWithMD5AndTripleDESCipher cipherSpi;
+            cipherSpi = new PBEWithMD5AndTripleDESCipher();
+            Cipher cipher = new CipherForKeyProtector(cipherSpi, PROV,
+                                                   "PBEWithMD5AndTripleDES");
+            cipher.init(Cipher.DECRYPT_MODE, skey, params);
+            return (Key)soForKeyProtector.getObject(cipher);
+        } catch (NoSuchAlgorithmException ex) {
+            // Note: this catch needed to be here because of the
+            // later catch of GeneralSecurityException
+            throw ex;
+        } catch (IOException ioe) {
+            throw new UnrecoverableKeyException(ioe.getMessage());
+        } catch (ClassNotFoundException cnfe) {
+            throw new UnrecoverableKeyException(cnfe.getMessage());
+        } catch (GeneralSecurityException gse) {
+            throw new UnrecoverableKeyException(gse.getMessage());
+        }
+    }
+}
+
+
+final class CipherForKeyProtector extends javax.crypto.Cipher {
+    /**
+     * Creates a Cipher object.
+     *
+     * @param cipherSpi the delegate
+     * @param provider the provider
+     * @param transformation the transformation
+     */
+    protected CipherForKeyProtector(CipherSpi cipherSpi,
+                                    Provider provider,
+                                    String transformation) {
+        super(cipherSpi, provider, transformation);
+    }
+}
+
+final class SealedObjectForKeyProtector extends javax.crypto.SealedObject {
+
+    static final long serialVersionUID = -3650226485480866989L;
+
+    SealedObjectForKeyProtector(Serializable object, Cipher c)
+        throws IOException, IllegalBlockSizeException {
+        super(object, c);
+    }
+
+    SealedObjectForKeyProtector(SealedObject so) {
+        super(so);
+    }
+
+    AlgorithmParameters getParameters() {
+        AlgorithmParameters params = null;
+        if (super.encodedParams != null) {
+            try {
+                params = AlgorithmParameters.getInstance("PBE", "SunJCE");
+                params.init(super.encodedParams);
+            } catch (NoSuchProviderException nspe) {
+                // eat.
+            } catch (NoSuchAlgorithmException nsae) {
+                //eat.
+            } catch (IOException ioe) {
+                //eat.
+            }
+        }
+        return params;
+    }
+}
+
+final class PrivateKeyInfo {
+
+    // the version number defined by the PKCS #8 standard
+    private static final BigInteger VERSION = BigInteger.ZERO;
+
+    // the private-key algorithm
+    private AlgorithmId algid;
+
+    // the private-key value
+    private byte[] privkey;
+
+    /**
+     * Constructs a PKCS#8 PrivateKeyInfo from its ASN.1 encoding.
+     */
+    PrivateKeyInfo(byte[] encoded) throws IOException {
+        DerValue val = new DerValue(encoded);
+
+        if (val.tag != DerValue.tag_Sequence)
+            throw new IOException("private key parse error: not a sequence");
+
+        // version
+        BigInteger parsedVersion = val.data.getBigInteger();
+        if (!parsedVersion.equals(VERSION)) {
+            throw new IOException("version mismatch: (supported: " +
+                                  VERSION + ", parsed: " + parsedVersion);
+        }
+
+        // privateKeyAlgorithm
+        this.algid = AlgorithmId.parse(val.data.getDerValue());
+
+        // privateKey
+        this.privkey = val.data.getOctetString();
+
+        // OPTIONAL attributes not supported yet
+    }
+
+    /**
+     * Returns the private-key algorithm.
+     */
+    AlgorithmId getAlgorithm() {
+        return this.algid;
+    }
+}
+
+/**
+ * This class represents a PBE key.
+ *
+ * @author Jan Luehe
+ *
+ */
+final class PBEKey implements SecretKey {
+
+    static final long serialVersionUID = -2234768909660948176L;
+
+    private byte[] key;
+
+    private String type;
+
+    /**
+     * Creates a PBE key from a given PBE key specification.
+     *
+     * @param key the given PBE key specification
+     */
+    PBEKey(PBEKeySpec keySpec, String keytype) throws InvalidKeySpecException {
+        char[] passwd = keySpec.getPassword();
+        if (passwd == null) {
+            // Should allow an empty password.
+            passwd = new char[0];
+        }
+        for (int i=0; i<passwd.length; i++) {
+            if ((passwd[i] < '\u0020') || (passwd[i] > '\u007E')) {
+                throw new InvalidKeySpecException("Password is not ASCII");
+            }
+        }
+        this.key = new byte[passwd.length];
+        for (int i=0; i<passwd.length; i++)
+            this.key[i] = (byte) (passwd[i] & 0x7f);
+        java.util.Arrays.fill(passwd, ' ');
+        type = keytype;
+    }
+
+    public byte[] getEncoded() {
+        return (byte[])this.key.clone();
+    }
+
+    public String getAlgorithm() {
+        return type;
+    }
+
+    public String getFormat() {
+        return "RAW";
+    }
+
+    /**
+     * Calculates a hash code value for the object.
+     * Objects that are equal will also have the same hashcode.
+     */
+    public int hashCode() {
+        int retval = 0;
+        for (int i = 1; i < this.key.length; i++) {
+            retval += this.key[i] * i;
+        }
+        return(retval ^= getAlgorithm().toLowerCase().hashCode());
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+
+        if (!(obj instanceof SecretKey))
+            return false;
+
+        SecretKey that = (SecretKey)obj;
+
+        if (!(that.getAlgorithm().equalsIgnoreCase(type)))
+            return false;
+
+        byte[] thatEncoded = that.getEncoded();
+        boolean ret = java.util.Arrays.equals(this.key, thatEncoded);
+        java.util.Arrays.fill(thatEncoded, (byte)0x00);
+        return ret;
+    }
+
+    /**
+     * readObject is called to restore the state of this key from
+     * a stream.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+         throws java.io.IOException, ClassNotFoundException
+    {
+        s.defaultReadObject();
+        key = (byte[])key.clone();
+    }
+
+
+    /**
+     * Replace the PBE key to be serialized.
+     *
+     * @return the standard KeyRep object to be serialized
+     *
+     * @throws java.io.ObjectStreamException if a new object representing
+     * this PBE key could not be created
+     */
+    private Object writeReplace() throws java.io.ObjectStreamException {
+        return new KeyRep(KeyRep.Type.SECRET,
+                        getAlgorithm(),
+                        getFormat(),
+                        getEncoded());
+    }
+
+    /**
+     * Ensures that the password bytes of this key are
+     * set to zero when there are no more references to it.
+     */
+    protected void finalize() throws Throwable {
+        try {
+            if (this.key != null) {
+                java.util.Arrays.fill(this.key, (byte)0x00);
+                this.key = null;
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKMSDB.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKMSDB.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKMSDB.java
new file mode 100644
index 0000000..649a321
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKMSDB.java
@@ -0,0 +1,85 @@
+package org.apache.hadoop.crypto.key;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.ranger.kms.dao.DaoManager;
+
+public class RangerKMSDB {
+       
+       static final Logger logger = Logger.getLogger(RangerKMSDB.class);
+       
+       private EntityManagerFactory entityManagerFactory;
+       private DaoManager daoManager;
+       
+       private static Map<String, String> DB_PROPERTIES = null;
+       
+       private static final String PROPERTY_PREFIX = "ranger.db.ks.";
+       private static final String DB_DIALECT = 
"javax.persistence.jdbc.dialect";
+       private static final String DB_DRIVER = "javax.persistence.jdbc.driver";
+       private static final String DB_URL = "javax.persistence.jdbc.url";
+       private static final String DB_USER = "javax.persistence.jdbc.user";
+       private static final String DB_PASSWORD = 
"javax.persistence.jdbc.password";
+       
+       private final Configuration conf;
+       
+       public RangerKMSDB(){
+               conf = new Configuration();
+       }
+       
+       public RangerKMSDB(Configuration conf){         
+               this.conf = conf;               
+               initDBConnectivity();
+       }
+       
+       public DaoManager getDaoManager(){
+               return daoManager;
+       }
+
+       private void initDBConnectivity(){
+               try {
+                       DB_PROPERTIES = new HashMap<String, String>();
+                       DB_PROPERTIES.put(DB_DIALECT, 
conf.get(PROPERTY_PREFIX+DB_DIALECT));
+                       DB_PROPERTIES.put(DB_DRIVER, 
conf.get(PROPERTY_PREFIX+DB_DRIVER));
+                       DB_PROPERTIES.put(DB_URL, 
conf.get(PROPERTY_PREFIX+DB_URL));
+                       DB_PROPERTIES.put(DB_USER, 
conf.get(PROPERTY_PREFIX+DB_USER));
+                       DB_PROPERTIES.put(DB_PASSWORD, 
conf.get(PROPERTY_PREFIX+DB_PASSWORD));
+                               
+                       entityManagerFactory = 
Persistence.createEntityManagerFactory("persistence_ranger_server", 
DB_PROPERTIES);
+
+                   daoManager = new DaoManager();
+                   daoManager.setEntityManagerFactory(entityManagerFactory);
+
+                   daoManager.getEntityManager(); // this forces the 
connection to be made to DB
+                   logger.info("Connected to DB : "+isDbConnected());          
    
+               } catch(Exception excp) {
+                       excp.printStackTrace();
+               }
+       }
+       
+       private boolean isDbConnected() {
+               EntityManager em = getEntityManager();
+               
+               return em != null && em.isOpen();
+       }
+       
+       private EntityManager getEntityManager() {
+               DaoManager daoMgr = daoManager;
+
+               if(daoMgr != null) {
+                       try {
+                               return daoMgr.getEntityManager();
+                       } catch(Exception excp) {
+                               excp.printStackTrace();
+                       }
+               }
+
+               return null;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
new file mode 100644
index 0000000..9b1ff67
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
@@ -0,0 +1,537 @@
+package org.apache.hadoop.crypto.key;
+
+import java.io.*;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.*;
+
+import javax.crypto.SealedObject;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.log4j.Logger;
+import org.apache.ranger.entity.XXRangerKeyStore;
+import org.apache.ranger.kms.dao.DaoManager;
+import org.apache.ranger.kms.dao.RangerKMSDao;
+
+/**
+ * This class provides the Database store implementation.
+ *
+ *
+ * @see KeyProtector
+ *
+ */
+
+public class RangerKeyStore extends KeyStoreSpi {
+       
+       static final Logger logger = Logger.getLogger(RangerKeyStore.class);
+               
+       private DaoManager daoManager;
+       
+    // keys
+    private static class KeyEntry {
+        Date date; // the creation date of this entry
+    };
+
+    // Secret key
+    private static final class SecretKeyEntry {
+        Date date; // the creation date of this entry
+        SealedObject sealedKey;
+        String cipher_field;
+        int bit_length;
+        String description;
+        String attributes;
+        int version;
+    }
+
+    /**
+     * keys are stored in a hashtable.
+     * Hash entries are keyed by alias names.
+     */
+    private final Hashtable<String, Object> entries;
+    
+    RangerKeyStore() {
+        entries = new Hashtable<String, Object>();
+    }
+
+    RangerKeyStore(DaoManager daoManager) {
+       entries = new Hashtable<String, Object>();
+       this.daoManager = daoManager;
+       }
+
+       // convert an alias to internal form, overridden in subclasses:
+    String convertAlias(String alias){
+       return alias.toLowerCase();
+    }
+
+    /**
+     * Returns the key associated with the given alias, using the given
+     * password to recover it.
+     *
+     * @param alias the alias name
+     * @param password the password for recovering the key
+     *
+     * @return the requested key, or null if the given alias does not exist
+     * or does not identify a <i>key entry</i>.
+     *
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     * key cannot be found
+     * @exception UnrecoverableKeyException if the key cannot be recovered
+     * (e.g., the given password is wrong).
+     */
+    public Key engineGetKey(String alias, char[] password)
+        throws NoSuchAlgorithmException, UnrecoverableKeyException
+    {
+       Key key = null;
+
+        Object entry = entries.get(alias.toLowerCase());
+
+        if (!(entry instanceof SecretKeyEntry)) {
+            return null;
+        }
+
+        KeyProtector keyProtector = new KeyProtector(password);
+        key = keyProtector.unseal(((SecretKeyEntry)entry).sealedKey);
+        return key;        
+    }
+
+    /**
+     * Returns the creation date of the entry identified by the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the creation date of this entry, or null if the given alias does
+     * not exist
+     */
+    public Date engineGetCreationDate(String alias) {
+        Object entry = entries.get(convertAlias(alias));
+        if (entry != null) {
+               return new Date(((KeyEntry)entry).date.getTime());
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Assigns the given key to the given alias, protecting
+     * it with the given password as defined in PKCS8.
+     *
+     * <p>The given java.security.PrivateKey <code>key</code> must
+     * be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key and certificate
+     * chain.
+     *
+     * @param alias the alias name
+     * @param key the key to be associated with the alias
+     * @param password the password to protect the key
+     * @param cipher the cipher used for the key
+     * @param bitLength bit length for the key
+     * @param description Description for the key
+     * @param version Key version
+     * @param attributes key attributes 
+     *
+     * @exception KeyStoreException if the given key is not a private key,
+     * cannot be protected, or this operation fails for some other reason
+     */
+    public void engineSetKeyEntry(String alias, Key key, char[] password, 
String cipher, int bitLength, String description, int version, String 
attributes)
+        throws KeyStoreException
+    {
+        synchronized(entries) {
+            try {
+                KeyProtector keyProtector = new KeyProtector(password);
+
+                SecretKeyEntry entry = new SecretKeyEntry();
+                entry.date = new Date();
+                // seal and store the key
+                entry.sealedKey = keyProtector.seal(key);
+                entry.cipher_field = cipher;
+                entry.bit_length = bitLength;
+                entry.description = description;
+                entry.version = version;
+                entry.attributes = attributes;
+                entries.put(alias.toLowerCase(), entry);                
+            } catch (Exception e) {
+                throw new KeyStoreException(e.getMessage());
+            }      
+        }
+    }
+
+    /**
+     * Deletes the entry identified by the given alias from this database.
+     *
+     * @param alias the alias name
+     *
+     * @exception KeyStoreException if the entry cannot be removed.
+     */
+    public void engineDeleteEntry(String alias)
+        throws KeyStoreException
+    {
+        synchronized(entries) {
+                       dbOperationDelete(convertAlias(alias));
+                       entries.remove(convertAlias(alias));    
+        }
+    }
+
+    private void dbOperationDelete(String alias) {
+       try{
+                         if(daoManager != null){
+                                 RangerKMSDao rangerKMSDao = new 
RangerKMSDao(daoManager);                       
+                                 rangerKMSDao.deleteByAlias(alias);
+                         }                       
+               }catch(Exception e){
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+     * Lists all the alias names of this database.
+     *
+     * @return enumeration of the alias names
+     */
+    public Enumeration<String> engineAliases() {
+        return entries.keys();
+    }
+
+    /**
+     * Checks if the given alias exists in this database.
+     *
+     * @param alias the alias name
+     *
+     * @return true if the alias exists, false otherwise
+     */
+    public boolean engineContainsAlias(String alias) {
+        return entries.containsKey(convertAlias(alias));
+    }
+
+    /**
+     * Retrieves the number of entries in this database.
+     *
+     * @return the number of entries in this database
+     */
+    public int engineSize() {
+        return entries.size();
+    }
+
+    /**
+     * Stores this keystore to the provided ranger database, and protects its
+     * integrity with the given password.
+     *
+     * @param stream null.
+     * @param password the password to generate the keystore integrity check
+     *
+     * @exception IOException if there was an I/O problem with data
+     * @exception NoSuchAlgorithmException if the appropriate data integrity
+     * algorithm could not be found
+     * @exception CertificateException if any of the certificates included in
+     * the keystore data could not be stored
+     */
+    public void engineStore(OutputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException
+    {
+        synchronized(entries) {
+            // password is mandatory when storing
+            if (password == null) {
+                throw new IllegalArgumentException("Ranger Master Key can't be 
null");
+            }
+
+            MessageDigest md = getPreKeyedHash(password);            
+            
+               byte digest[] = md.digest();    
+               for (Enumeration<String> e = entries.keys(); 
e.hasMoreElements();) {
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                DataOutputStream dos = new DataOutputStream(new 
DigestOutputStream(baos, md));
+                
+                ObjectOutputStream oos = null;
+               try{
+               
+                       String alias = e.nextElement();
+                       Object entry = entries.get(alias);
+
+                    // write the sealed key
+                    oos = new ObjectOutputStream(dos);
+                    oos.writeObject(((SecretKeyEntry)entry).sealedKey);
+                    /*
+                     * Write the keyed hash which is used to detect tampering 
with
+                     * the keystore (such as deleting or modifying key or
+                     * certificate entries).
+                     */
+                    dos.write(digest);
+                    dos.flush();
+                    Long creationDate = ((SecretKeyEntry)entry).date.getTime();
+                    SecretKeyEntry secretKey = (SecretKeyEntry)entry;
+                    XXRangerKeyStore xxRangerKeyStore = 
mapObjectToEntity(alias,creationDate,baos.toByteArray(), 
secretKey.cipher_field, secretKey.bit_length, secretKey.description, 
secretKey.version, secretKey.attributes);
+                    dbOperationStore(xxRangerKeyStore);
+               }finally {
+                    if (oos != null) {
+                        oos.close();
+                    } else {
+                        dos.close();
+                    }
+                }                
+            }
+        }
+    }
+
+    private XXRangerKeyStore mapObjectToEntity(String alias, Long creationDate,
+               byte[] byteArray, String cipher_field, int bit_length,
+               String description, int version, String attributes) {
+       XXRangerKeyStore xxRangerKeyStore = new XXRangerKeyStore();
+       xxRangerKeyStore.setAlias(alias);
+       xxRangerKeyStore.setCreatedDate(creationDate);
+       
xxRangerKeyStore.setEncoded(DatatypeConverter.printBase64Binary(byteArray));
+       xxRangerKeyStore.setCipher(cipher_field);
+       xxRangerKeyStore.setBitLength(bit_length);
+       xxRangerKeyStore.setDescription(description);
+       xxRangerKeyStore.setVersion(version);
+       xxRangerKeyStore.setAttributes(attributes);
+               return xxRangerKeyStore;
+       }
+
+       private void dbOperationStore(XXRangerKeyStore rangerKeyStore) {
+               try{
+                         if(daoManager != null){
+                                 RangerKMSDao rangerKMSDao = new 
RangerKMSDao(daoManager);
+                                 XXRangerKeyStore xxRangerKeyStore = 
rangerKMSDao.findByAlias(rangerKeyStore.getAlias());
+                                 boolean keyStoreExists = true;
+                                 if (xxRangerKeyStore == null) {
+                                         xxRangerKeyStore = new 
XXRangerKeyStore();
+                                         keyStoreExists = false;
+                                 }
+
+                                 xxRangerKeyStore = 
mapToEntityBean(rangerKeyStore, xxRangerKeyStore, 0);              
+                                 if (keyStoreExists) {
+                                         xxRangerKeyStore = 
rangerKMSDao.update(xxRangerKeyStore);
+                                 } else {
+                                         xxRangerKeyStore = 
rangerKMSDao.create(xxRangerKeyStore);
+                                 }
+                         }
+               }catch(Exception e){
+                       e.printStackTrace();
+               }
+       }
+
+       private XXRangerKeyStore mapToEntityBean(XXRangerKeyStore 
rangerKMSKeyStore, XXRangerKeyStore xxRangerKeyStore,int i) {
+               xxRangerKeyStore.setAlias(rangerKMSKeyStore.getAlias());
+               
xxRangerKeyStore.setCreatedDate(rangerKMSKeyStore.getCreatedDate());
+               xxRangerKeyStore.setEncoded(rangerKMSKeyStore.getEncoded());
+               xxRangerKeyStore.setCipher(rangerKMSKeyStore.getCipher());
+               xxRangerKeyStore.setBitLength(rangerKMSKeyStore.getBitLength());
+               
xxRangerKeyStore.setDescription(rangerKMSKeyStore.getDescription());
+               xxRangerKeyStore.setVersion(rangerKMSKeyStore.getVersion());
+               
xxRangerKeyStore.setAttributes(rangerKMSKeyStore.getAttributes());
+               return xxRangerKeyStore;
+       }
+
+       /**
+     * Loads the keystore from the given ranger database.
+     *
+     * <p>If a password is given, it is used to check the integrity of the
+     * keystore data. Otherwise, the integrity of the keystore is not checked.
+     *
+     * @param stream the input stream from which the keystore is loaded
+     * @param password the (optional) password used to check the integrity of
+     * the keystore.
+     *
+     * @exception IOException if there is an I/O or format problem with the
+     * keystore data
+     * @exception NoSuchAlgorithmException if the algorithm used to check
+     * the integrity of the keystore cannot be found
+     * @exception CertificateException if any of the certificates in the
+     * keystore could not be loaded
+     */
+    public void engineLoad(InputStream stream, char[] password)
+        throws IOException     , NoSuchAlgorithmException, CertificateException
+    {
+        synchronized(entries) {
+               List<XXRangerKeyStore> rangerKeyDetails = dbOperationLoad();
+            DataInputStream dis;
+            MessageDigest md = null;
+           
+                       if(rangerKeyDetails == null || rangerKeyDetails.size() 
< 1){
+                       return;
+               }
+                       
+                       entries.clear();     
+                       if (password != null) {
+                               md = getPreKeyedHash(password);
+                       }                       
+                       byte computed[];
+            computed = md.digest();
+            for(XXRangerKeyStore rangerKey : rangerKeyDetails){
+               String encoded = rangerKey.getEncoded();
+               byte[] data = DatatypeConverter.parseBase64Binary(encoded);
+               
+               if(data  != null && data.length > 0){
+                       stream = new ByteArrayInputStream(data);
+               }else{
+                       logger.error("No Key found for alias 
"+rangerKey.getAlias());
+               }
+               
+               /*
+                    * If a password has been provided, we check the keyed 
digest
+                    * at the end. If this check fails, the store has been 
tampered
+                    * with
+                    */
+                    if (password != null) {                    
+                       int counter = 0; 
+                       for (int i = computed.length-1; i >= 0; i--) {
+                           if (computed[i] != data[data.length-(1+counter)]) {
+                               Throwable t = new UnrecoverableKeyException
+                                   ("Password verification failed");
+                               throw (IOException)new IOException
+                                   ("Keystore was tampered with, or "
+                                   + "password was incorrect").initCause(t);
+                           }else{
+                               counter++;
+                           }
+                       }
+                    }
+               
+                               if (password != null) {
+                                       dis = new DataInputStream(new 
DigestInputStream(stream, md));
+                               } else {
+                                       dis = new DataInputStream(stream);
+                               }
+                               
+                               ObjectInputStream ois = null;
+                               try{
+                                       String alias;
+
+                                       SecretKeyEntry entry = new 
SecretKeyEntry();
+
+                                       //read the alias
+                                       alias = rangerKey.getAlias();
+
+                                       //read the (entry creation) date
+                                       entry.date = new 
Date(rangerKey.getCreatedDate());
+                                       entry.cipher_field = 
rangerKey.getCipher();
+                                       entry.bit_length = 
rangerKey.getBitLength();
+                                       entry.description = 
rangerKey.getDescription();
+                                       entry.version = rangerKey.getVersion();
+                                       entry.attributes = 
rangerKey.getAttributes();
+
+                                       //read the sealed key
+                                       try {
+                                               ois = new 
ObjectInputStream(dis);
+                                               entry.sealedKey = 
(SealedObject)ois.readObject();
+                                       } catch (ClassNotFoundException cnfe) {
+                                               throw new 
IOException(cnfe.getMessage());
+                                       }
+
+                                       //Add the entry to the list
+                                       entries.put(alias, entry);              
            
+                                }finally {
+                       if (ois != null) {
+                           ois.close();
+                       } else {
+                           dis.close();
+                       }
+                   }
+            }
+        }
+    }
+
+    private List<XXRangerKeyStore> dbOperationLoad() throws IOException {
+               try{
+                         if(daoManager != null){
+                                 RangerKMSDao rangerKMSDao = new 
RangerKMSDao(daoManager);
+                                 return rangerKMSDao.getAll();
+                         }                       
+               }catch(Exception e){
+                       e.printStackTrace();
+               }
+                       return null;
+       }
+
+       /**
+     * To guard against tampering with the keystore, we append a keyed
+     * hash with a bit of whitener.
+     */
+    private MessageDigest getPreKeyedHash(char[] password)
+        throws NoSuchAlgorithmException, UnsupportedEncodingException
+    {
+        int i, j;
+
+        MessageDigest md = MessageDigest.getInstance("SHA");
+        byte[] passwdBytes = new byte[password.length * 2];
+        for (i=0, j=0; i<password.length; i++) {
+            passwdBytes[j++] = (byte)(password[i] >> 8);
+            passwdBytes[j++] = (byte)password[i];
+        }
+        md.update(passwdBytes);
+        for (i=0; i<passwdBytes.length; i++)
+            passwdBytes[i] = 0;
+        md.update("Mighty Aphrodite".getBytes("UTF8"));
+        return md;
+    }
+
+       @Override
+       public void engineSetKeyEntry(String arg0, byte[] arg1, Certificate[] 
arg2)
+                       throws KeyStoreException {      
+               
+       }
+
+       @Override
+       public Certificate engineGetCertificate(String alias) {
+               return null;
+       }
+
+       @Override
+       public String engineGetCertificateAlias(Certificate cert) {
+               return null;
+       }
+
+       @Override
+       public Certificate[] engineGetCertificateChain(String alias) {
+               return null;
+       }
+
+       @Override
+       public boolean engineIsCertificateEntry(String alias) {
+               return false;
+       }
+
+       @Override
+       public boolean engineIsKeyEntry(String alias) {
+               return false;
+       }
+
+       @Override
+       public void engineSetCertificateEntry(String alias, Certificate cert)
+                       throws KeyStoreException {
+       }
+
+       @Override
+       public void engineSetKeyEntry(String alias, Key key, char[] password,
+                       Certificate[] chain) throws KeyStoreException {
+       }
+       
+       public Map<String, String> getPropertiesWithPrefix(Properties props, 
String prefix) {
+               Map<String, String> prefixedProperties = new HashMap<String, 
String>();
+
+               if(props != null && prefix != null) {
+                       for(String key : props.stringPropertyNames()) {
+                               if(key == null) {
+                                       continue;
+                               }
+
+                               String val = props.getProperty(key);
+
+                               if(key.startsWith(prefix)) {
+                                       key = key.substring(prefix.length());
+
+                                       if(key == null) {
+                                               continue;
+                                       }
+
+                                       prefixedProperties.put(key, val);
+                               }
+                       }
+               }
+
+               return prefixedProperties;
+       }       
+}
\ No newline at end of file

Reply via email to