Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
atlas
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
dataplatform
atlas
Commits
9648a823
Commit
9648a823
authored
Mar 17, 2015
by
Jon Maron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BUG-32837 enhance DGI ssl
parent
77b11f26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
608 additions
and
43 deletions
+608
-43
pom.xml
pom.xml
+1
-1
cputil.sh
src/bin/cputil.sh
+111
-0
pom.xml
webapp/pom.xml
+36
-23
CredentialProviderUtility.java
...org/apache/hadoop/metadata/CredentialProviderUtility.java
+144
-0
EmbeddedServer.java
...rg/apache/hadoop/metadata/web/service/EmbeddedServer.java
+5
-3
SecureEmbeddedServer.java
...che/hadoop/metadata/web/service/SecureEmbeddedServer.java
+68
-14
CredentialProviderUtilityIT.java
...g/apache/hadoop/metadata/CredentialProviderUtilityIT.java
+0
-0
BaseResourceIT.java
.../apache/hadoop/metadata/web/resources/BaseResourceIT.java
+1
-2
SecureEmbeddedServerIT.java
...e/hadoop/metadata/web/service/SecureEmbeddedServerIT.java
+242
-0
No files found.
pom.xml
View file @
9648a823
...
...
@@ -79,7 +79,7 @@
<jersey.version>
1.9
</jersey.version>
<tinkerpop.version>
2.5.0
</tinkerpop.version>
<titan.version>
0.5.3
</titan.version>
<hadoop.version>
2.
5
.0
</hadoop.version>
<hadoop.version>
2.
6
.0
</hadoop.version>
<hive.version>
0.14.0
</hive.version>
<falcon.version>
0.6.0.2.2.0.0-2041
</falcon.version>
...
...
src/bin/cputil.sh
0 → 100644
View file @
9648a823
#!/bin/bash
#
# 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.
#
# resolve links - $0 may be a softlink
PRG
=
"
${
0
}
"
while
[
-h
"
${
PRG
}
"
]
;
do
ls
=
`
ls
-ld
"
${
PRG
}
"
`
link
=
`
expr
"
$ls
"
:
'.*-> \(.*\)$'
`
if
expr
"
$link
"
:
'/.*'
>
/dev/null
;
then
PRG
=
"
$link
"
else
PRG
=
`
dirname
"
${
PRG
}
"
`
/
"
$link
"
fi
done
BASEDIR
=
`
dirname
${
PRG
}
`
BASEDIR
=
`
cd
${
BASEDIR
}
/..
;
pwd
`
if
[
-z
"
$METADATA_CONF
"
]
;
then
METADATA_CONF
=
${
BASEDIR
}
/conf
fi
export
METADATA_CONF
if
[
-f
"
${
METADATA_CONF
}
/metadata-env.sh"
]
;
then
.
"
${
METADATA_CONF
}
/metadata-env.sh"
fi
if
test
-z
${
JAVA_HOME
}
then
JAVA_BIN
=
`
which java
`
JAR_BIN
=
`
which jar
`
else
JAVA_BIN
=
${
JAVA_HOME
}
/bin/java
JAR_BIN
=
${
JAVA_HOME
}
/bin/jar
fi
export
JAVA_BIN
if
[
!
-e
$JAVA_BIN
]
||
[
!
-e
$JAR_BIN
]
;
then
echo
"
$JAVA_BIN
and/or
$JAR_BIN
not found on the system. Please make sure java and jar commands are available."
exit
1
fi
# default the heap size to 1GB
DEFAULT_JAVA_HEAP_MAX
=
-Xmx1024m
METADATA_OPTS
=
"
$DEFAULT_JAVA_HEAP_MAX
$METADATA_OPTS
"
METADATACPPATH
=
"
$METADATA_CONF
"
METADATA_EXPANDED_WEBAPP_DIR
=
${
METADATA_EXPANDED_WEBAPP_DIR
:-${
BASEDIR
}
/server/webapp
}
export
METADATA_EXPANDED_WEBAPP_DIR
# set the server classpath
if
[
!
-d
${
METADATA_EXPANDED_WEBAPP_DIR
}
/metadata/WEB-INF
]
;
then
mkdir
-p
${
METADATA_EXPANDED_WEBAPP_DIR
}
/metadata
cd
${
METADATA_EXPANDED_WEBAPP_DIR
}
/metadata
$JAR_BIN
-xf
${
BASEDIR
}
/server/webapp/metadata.war
cd
-
fi
METADATACPPATH
=
"
${
METADATACPPATH
}
:
${
METADATA_EXPANDED_WEBAPP_DIR
}
/metadata/WEB-INF/classes"
METADATACPPATH
=
"
${
METADATACPPATH
}
:
${
METADATA_EXPANDED_WEBAPP_DIR
}
/metadata/WEB-INF/lib/*:
${
BASEDIR
}
/libext/*"
# log and pid dirs for applications
METADATA_LOG_DIR
=
"
${
METADATA_LOG_DIR
:-
$BASEDIR
/logs
}
"
export
METADATA_LOG_DIR
METADATA_PID_DIR
=
"
${
METADATA_PID_DIR
:-
$BASEDIR
/logs
}
"
# create the pid dir if its not there
[
-w
"
$METADATA_PID_DIR
"
]
||
mkdir
-p
"
$METADATA_PID_DIR
"
export
METADATA_PID_DIR
METADATA_PID_FILE
=
${
METADATA_PID_DIR
}
/metadata.pid
export
METADATA_PID_FILE
METADATA_DATA_DIR
=
${
METADATA_DATA_DIR
:-${
BASEDIR
}
/data
}
METADATA_HOME_DIR
=
"
${
METADATA_HOME_DIR
:-
$BASEDIR
}
"
export
METADATA_HOME_DIR
# make sure the process is not running
if
[
-f
$METADATA_PID_FILE
]
;
then
if
kill
-0
`
cat
$METADATA_PID_FILE
`
>
/dev/null 2>&1
;
then
echo
metadata running as process
`
cat
$METADATA_PID_FILE
`
.
Stop it first.
exit
1
fi
fi
mkdir
-p
$METADATA_LOG_DIR
pushd
${
BASEDIR
}
>
/dev/null
JAVA_PROPERTIES
=
"
$METADATA_OPTS
$METADATA_PROPERTIES
-Dmetadata.log.dir=
$METADATA_LOG_DIR
-Dmetadata.home=
${
METADATA_HOME_DIR
}
"
shift
while
[[
${
1
}
=
~ ^
\-
D
]]
;
do
JAVA_PROPERTIES
=
"
${
JAVA_PROPERTIES
}
${
1
}
"
shift
done
TIME
=
`
date
+%Y%m%d%H%M%s
`
${
JAVA_BIN
}
${
JAVA_PROPERTIES
}
-cp
${
METADATACPPATH
}
org.apache.hadoop.metadata.CredentialProviderUtility
webapp/pom.xml
View file @
9648a823
...
...
@@ -45,6 +45,11 @@
<artifactId>
hadoop-client
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.apache.hadoop
</groupId>
<artifactId>
hadoop-common
</artifactId>
<version>
${hadoop.version}
</version>
</dependency>
</dependencies>
</profile>
</profiles>
...
...
@@ -96,6 +101,12 @@
</dependency>
<dependency>
<groupId>
javax.servlet
</groupId>
<artifactId>
javax.servlet-api
</artifactId>
<version>
3.1.0
</version>
</dependency>
<dependency>
<groupId>
org.mortbay.jetty
</groupId>
<artifactId>
jetty
</artifactId>
</dependency>
...
...
@@ -106,6 +117,12 @@
</dependency>
<dependency>
<groupId>
org.mortbay.jetty
</groupId>
<artifactId>
jetty-util
</artifactId>
<version>
6.1.26
</version>
</dependency>
<dependency>
<groupId>
com.sun.jersey
</groupId>
<artifactId>
jersey-core
</artifactId>
</dependency>
...
...
@@ -211,11 +228,12 @@
<goal>
copy-resources
</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/webapps
</outputDirectory>
<outputDirectory>
${basedir}/conf
</outputDirectory>
<resources>
<resource>
<directory>
src
/conf
</directory>
<filtering>
tru
e
</filtering>
<directory>
${project.build.directory}
/conf
</directory>
<filtering>
fals
e
</filtering>
</resource>
</resources>
</configuration>
...
...
@@ -252,7 +270,7 @@
</goals>
</execution>
<execution>
<id>
gen
key
</id>
<id>
gen
erateKeyPair
</id>
<phase>
generate-resources
</phase>
<goals>
<goal>
generateKeyPair
</goal>
...
...
@@ -261,9 +279,9 @@
</executions>
<configuration>
<dname>
cn=metadata.incubator.apache.org
</dname>
<keystore>
${project.build.directory}/metadata.keystore
</keystore>
<keypass>
metadata-passwd
</keypass>
<storepass>
metadata-passwd
</storepass>
<keystore>
${project.build.directory}/
conf/
metadata.keystore
</keystore>
<keypass>
keypass
</keypass>
<storepass>
keypass
</storepass>
<alias>
metadata
</alias>
<keyalg>
RSA
</keyalg>
<validity>
100000
</validity>
...
...
@@ -279,22 +297,20 @@
<!--only skip int tests -->
<connectors>
<!--
<connector implementation="org.mortbay.jetty.security.SslSocketConnector">
<port>21443</port>
<maxIdleTime>60000</maxIdleTime>
<keystore>${project.build.directory}/../../webapp/target/metadata.keystore</keystore>
<keyPassword>metadata-passwd</keyPassword>
<password>metadata-passwd</password>
</connector>
<connector implementation="org.mortbay.jetty.security.SslSocketConnector">
<port>21443</port>
<maxIdleTime>60000</maxIdleTime>
<keystore>${project.build.directory}/../../webapp/target/metadata.keystore</keystore>
<keyPassword>metadata-passwd</keyPassword>
<password>metadata-passwd</password>
</connector>
-->
<connector
implementation=
"org.mortbay.jetty.nio.SelectChannelConnector"
>
<connector
implementation=
"org.mortbay.jetty.nio.SelectChannelConnector"
>
<port>
21000
</port>
<maxIdleTime>
60000
</maxIdleTime>
</connector>
</connectors>
<webApp>
${project.build.directory}/metadata-webapp-${project.version}
</webApp>
<webApp>
${project.build.directory}/metadata-webapp-${project.version}
</webApp>
<contextPath>
/
</contextPath>
<useTestClasspath>
true
</useTestClasspath>
<systemProperties>
...
...
@@ -316,15 +332,12 @@
</systemProperty>
<systemProperty>
<name>
keystore.file
</name>
<value>
${project.build.directory}/../../webapp/target/metadata.keystore
<value>
${project.build.directory}/../../webapp/target/metadata.keystore
</value>
</systemProperty>
<systemProperty>
<name>
truststore.file
</name>
<value>
${project.build.directory}/../../webapp/target/metadata.keystore
</value>
<value>
${project.build.directory}/../../webapp/target/metadata.keystore
</value>
</systemProperty>
</systemProperties>
<stopKey>
metadata-stop
</stopKey>
...
...
webapp/src/main/java/org/apache/hadoop/metadata/CredentialProviderUtility.java
0 → 100644
View file @
9648a823
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
apache
.
hadoop
.
metadata
;
import
org.apache.commons.lang.StringUtils
;
import
org.apache.hadoop.conf.Configuration
;
import
org.apache.hadoop.metadata.web.service.SecureEmbeddedServer
;
import
org.apache.hadoop.security.alias.CredentialProvider
;
import
org.apache.hadoop.security.alias.CredentialProviderFactory
;
import
org.apache.hadoop.security.alias.JavaKeyStoreProvider
;
import
java.io.*
;
import
java.util.Arrays
;
/**
* A utility class for generating a credential provider containing the entries required for supporting the SSL implementation
* of the DGC server.
*/
public
class
CredentialProviderUtility
{
private
static
final
String
[]
KEYS
=
new
String
[]
{
SecureEmbeddedServer
.
KEYSTORE_PASSWORD_KEY
,
SecureEmbeddedServer
.
TRUSTSTORE_PASSWORD_KEY
,
SecureEmbeddedServer
.
SERVER_CERT_PASSWORD_KEY
};
public
static
abstract
class
TextDevice
{
public
abstract
void
printf
(
String
fmt
,
Object
...
params
);
public
abstract
String
readLine
(
String
fmt
,
Object
...
args
);
public
abstract
char
[]
readPassword
(
String
fmt
,
Object
...
args
);
}
private
static
TextDevice
DEFAULT_TEXT_DEVICE
=
new
TextDevice
()
{
Console
console
=
System
.
console
();
@Override
public
void
printf
(
String
fmt
,
Object
...
params
)
{
console
.
printf
(
fmt
,
params
);
}
@Override
public
String
readLine
(
String
fmt
,
Object
...
args
)
{
return
console
.
readLine
(
fmt
,
args
);
}
@Override
public
char
[]
readPassword
(
String
fmt
,
Object
...
args
)
{
return
console
.
readPassword
(
fmt
,
args
);
}
};
public
static
TextDevice
textDevice
=
DEFAULT_TEXT_DEVICE
;
public
static
void
main
(
String
[]
args
)
throws
IOException
{
// prompt for the provider name
CredentialProvider
provider
=
getCredentialProvider
(
textDevice
);
char
[]
cred
;
for
(
String
key
:
KEYS
)
{
cred
=
getPassword
(
textDevice
,
key
);
// create a credential entry and store it
boolean
overwrite
=
true
;
if
(
provider
.
getCredentialEntry
(
key
)
!=
null
)
{
String
choice
=
textDevice
.
readLine
(
"Entry for %s already exists. Overwrite? (y/n) [y]:"
,
key
);
overwrite
=
StringUtils
.
isEmpty
(
choice
)
||
choice
.
equalsIgnoreCase
(
"y"
);
if
(
overwrite
)
{
provider
.
deleteCredentialEntry
(
key
);
provider
.
flush
();
provider
.
createCredentialEntry
(
key
,
cred
);
provider
.
flush
();
textDevice
.
printf
(
"Entry for %s was overwritten with the new value.\n"
,
key
);
}
else
{
textDevice
.
printf
(
"Entry for %s was not overwritten.\n"
,
key
);
}
}
else
{
provider
.
createCredentialEntry
(
key
,
cred
);
provider
.
flush
();
}
}
}
/**
* Retrieves a password from the command line.
* @param textDevice the system console.
* @param key the password key/alias.
* @return the password.
*/
private
static
char
[]
getPassword
(
TextDevice
textDevice
,
String
key
)
{
boolean
noMatch
;
char
[]
cred
=
new
char
[
0
];
char
[]
passwd1
;
char
[]
passwd2
;
do
{
passwd1
=
textDevice
.
readPassword
(
"Please enter the password value for %s:"
,
key
);
passwd2
=
textDevice
.
readPassword
(
"Please enter the password value for %s again:"
,
key
);
noMatch
=
!
Arrays
.
equals
(
passwd1
,
passwd2
);
if
(
noMatch
)
{
if
(
passwd1
!=
null
)
Arrays
.
fill
(
passwd1
,
' '
);
textDevice
.
printf
(
"Password entries don't match. Please try again.\n"
);
}
else
{
if
(
passwd1
.
length
==
0
)
{
textDevice
.
printf
(
"An empty password is not valid. Please try again.\n"
);
noMatch
=
true
;
}
else
{
cred
=
passwd1
;
}
}
if
(
passwd2
!=
null
)
Arrays
.
fill
(
passwd2
,
' '
);
}
while
(
noMatch
);
return
cred
;
}
/**\
* Returns a credential provider for the entered JKS path.
* @param textDevice the system console.
* @return the Credential provider
* @throws IOException
*/
private
static
CredentialProvider
getCredentialProvider
(
TextDevice
textDevice
)
throws
IOException
{
String
providerPath
=
textDevice
.
readLine
(
"Please enter the full path to the credential provider:"
);
File
file
=
new
File
(
providerPath
);
if
(
file
.
exists
())
{
textDevice
.
printf
(
"%s already exists. You will need to specify whether existing entries should be overwritten "
+
"(default is 'yes')\n"
,
providerPath
);
}
String
providerURI
=
JavaKeyStoreProvider
.
SCHEME_NAME
+
"://file"
+
providerPath
;
Configuration
conf
=
new
Configuration
(
false
);
conf
.
set
(
CredentialProviderFactory
.
CREDENTIAL_PROVIDER_PATH
,
providerURI
);
return
CredentialProviderFactory
.
getProviders
(
conf
).
get
(
0
);
}
}
webapp/src/main/java/org/apache/hadoop/metadata/web/service/EmbeddedServer.java
View file @
9648a823
...
...
@@ -25,6 +25,8 @@ import org.mortbay.jetty.Server;
import
org.mortbay.jetty.bio.SocketConnector
;
import
org.mortbay.jetty.webapp.WebAppContext
;
import
java.io.IOException
;
/**
* This class embeds a Jetty server and a connector.
*/
...
...
@@ -33,7 +35,7 @@ public class EmbeddedServer {
protected
final
Server
server
=
new
Server
();
public
EmbeddedServer
(
int
port
,
String
path
)
{
public
EmbeddedServer
(
int
port
,
String
path
)
throws
IOException
{
Connector
connector
=
getConnector
(
port
);
server
.
addConnector
(
connector
);
...
...
@@ -41,7 +43,7 @@ public class EmbeddedServer {
server
.
setHandler
(
application
);
}
public
static
EmbeddedServer
newServer
(
int
port
,
String
path
,
boolean
secure
)
{
public
static
EmbeddedServer
newServer
(
int
port
,
String
path
,
boolean
secure
)
throws
IOException
{
if
(
secure
)
{
return
new
SecureEmbeddedServer
(
port
,
path
);
}
else
{
...
...
@@ -49,7 +51,7 @@ public class EmbeddedServer {
}
}
protected
Connector
getConnector
(
int
port
)
{
protected
Connector
getConnector
(
int
port
)
throws
IOException
{
Connector
connector
=
new
SocketConnector
();
connector
.
setPort
(
port
);
connector
.
setHost
(
"0.0.0.0"
);
...
...
webapp/src/main/java/org/apache/hadoop/metadata/web/service/SecureEmbeddedServer.java
View file @
9648a823
...
...
@@ -20,39 +20,93 @@ package org.apache.hadoop.metadata.web.service;
import
org.apache.commons.configuration.ConfigurationException
;
import
org.apache.commons.configuration.PropertiesConfiguration
;
import
org.apache.hadoop.conf.Configuration
;
import
org.apache.hadoop.security.alias.CredentialProvider
;
import
org.apache.hadoop.security.alias.CredentialProviderFactory
;
import
org.mortbay.jetty.Connector
;
import
org.mortbay.jetty.security.SslSocketConnector
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.IOException
;
/**
* This is a jetty server which requires client auth via certificates.
*/
public
class
SecureEmbeddedServer
extends
EmbeddedServer
{
public
SecureEmbeddedServer
(
int
port
,
String
path
)
{
public
static
final
String
KEYSTORE_FILE_KEY
=
"keystore.file"
;
public
static
final
String
DEFAULT_KEYSTORE_FILE_LOCATION
=
"conf/metadata.keystore"
;
public
static
final
String
KEYSTORE_PASSWORD_KEY
=
"keystore.password"
;
public
static
final
String
TRUSTSTORE_FILE_KEY
=
"truststore.file"
;
public
static
final
String
DEFATULT_TRUSTORE_FILE_LOCATION
=
"conf/metadata.keystore"
;
public
static
final
String
TRUSTSTORE_PASSWORD_KEY
=
"truststore.password"
;
public
static
final
String
SERVER_CERT_PASSWORD_KEY
=
"password"
;
public
static
final
String
CLIENT_AUTH_KEY
=
"client.auth.enabled"
;
public
static
final
String
CERT_STORES_CREDENTIAL_PROVIDER_PATH
=
"cert.stores.credential.provider.path"
;
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SecureEmbeddedServer
.
class
);
public
SecureEmbeddedServer
(
int
port
,
String
path
)
throws
IOException
{
super
(
port
,
path
);
}
protected
Connector
getConnector
(
int
port
)
{
protected
Connector
getConnector
(
int
port
)
throws
IOException
{
PropertiesConfiguration
config
=
getConfiguration
();
SslSocketConnector
connector
=
new
SslSocketConnector
();
connector
.
setPort
(
port
);
connector
.
setHost
(
"0.0.0.0"
);
connector
.
setKeystore
(
config
.
getString
(
"keystore.file"
,
System
.
getProperty
(
"keystore.file"
,
"conf/metadata.keystore"
)));
connector
.
setKeyPassword
(
config
.
getString
(
"keystore.password"
,
System
.
getProperty
(
"keystore.password"
,
"metadata-passwd"
)));
connector
.
setTruststore
(
config
.
getString
(
"truststore.file"
,
System
.
getProperty
(
"truststore.file"
,
"conf/metadata.keystore"
)));
connector
.
setTrustPassword
(
config
.
getString
(
"truststore.password"
,
System
.
getProperty
(
"truststore.password"
,
"metadata-passwd"
)));
connector
.
setPassword
(
config
.
getString
(
"password"
,
System
.
getProperty
(
"password"
,
"metadata-passwd"
)));
connector
.
setWantClientAuth
(
true
);
connector
.
setKeystore
(
config
.
getString
(
KEYSTORE_FILE_KEY
,
System
.
getProperty
(
KEYSTORE_FILE_KEY
,
DEFAULT_KEYSTORE_FILE_LOCATION
)));
connector
.
setKeyPassword
(
getPassword
(
config
,
KEYSTORE_PASSWORD_KEY
));
connector
.
setTruststore
(
config
.
getString
(
TRUSTSTORE_FILE_KEY
,
System
.
getProperty
(
TRUSTSTORE_FILE_KEY
,
DEFATULT_TRUSTORE_FILE_LOCATION
)));
connector
.
setTrustPassword
(
getPassword
(
config
,
TRUSTSTORE_PASSWORD_KEY
));
connector
.
setPassword
(
getPassword
(
config
,
SERVER_CERT_PASSWORD_KEY
));
connector
.
setWantClientAuth
(
config
.
getBoolean
(
CLIENT_AUTH_KEY
,
Boolean
.
getBoolean
(
CLIENT_AUTH_KEY
)));
return
connector
;
}
private
PropertiesConfiguration
getConfiguration
()
{
/**
* Retrieves a password from a configured credential provider or prompts for the password and stores it in the
* configured credential provider.
* @param config application configuration
* @param key the key/alias for the password.
* @return the password.
* @throws IOException
*/
private
String
getPassword
(
PropertiesConfiguration
config
,
String
key
)
throws
IOException
{
String
password
=
null
;
String
provider
=
config
.
getString
(
CERT_STORES_CREDENTIAL_PROVIDER_PATH
);
if
(
provider
!=
null
)
{
LOG
.
info
(
"Attempting to retrieve password from configured credential provider path"
);
Configuration
c
=
new
Configuration
();
c
.
set
(
CredentialProviderFactory
.
CREDENTIAL_PROVIDER_PATH
,
provider
);
CredentialProvider
credentialProvider
=
CredentialProviderFactory
.
getProviders
(
c
).
get
(
0
);
CredentialProvider
.
CredentialEntry
entry
=
credentialProvider
.
getCredentialEntry
(
key
);
if
(
entry
==
null
)
{
throw
new
IOException
(
String
.
format
(
"No credential entry found for %s. "
+
"Please create an entry in the configured credential provider"
,
key
));
}
else
{
password
=
String
.
valueOf
(
entry
.
getCredential
());
}
}
else
{
throw
new
IOException
(
"No credential provider path configured for storage of certificate store passwords"
);
}
return
password
;
}
/**
* Returns the application configuration.
* @return
*/
protected
PropertiesConfiguration
getConfiguration
()
{
try
{
return
new
PropertiesConfiguration
(
"application.properties"
);
}
catch
(
ConfigurationException
e
)
{
...
...
webapp/src/test/java/org/apache/hadoop/metadata/CredentialProviderUtilityIT.java
0 → 100644
View file @
9648a823
This diff is collapsed.
Click to expand it.
webapp/src/test/java/org/apache/hadoop/metadata/web/resources/BaseResourceIT.java
View file @
9648a823
...
...
@@ -37,14 +37,13 @@ public abstract class BaseResourceIT {
protected
TypeSystem
typeSystem
;
protected
WebResource
service
;
public
static
String
baseUrl
=
"http://localhost:21000/"
;;
@BeforeClass
public
void
setUp
()
throws
Exception
{
typeSystem
=
TypeSystem
.
getInstance
();
typeSystem
.
reset
();
String
baseUrl
=
"http://localhost:21000/"
;
DefaultClientConfig
config
=
new
DefaultClientConfig
();
Client
client
=
Client
.
create
(
config
);
client
.
resource
(
UriBuilder
.
fromUri
(
baseUrl
).
build
());
...
...
webapp/src/test/java/org/apache/hadoop/metadata/web/service/SecureEmbeddedServerIT.java
0 → 100644
View file @
9648a823
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
apache
.
hadoop
.
metadata
.
web
.
service
;
import
com.sun.jersey.api.client.Client
;
import
com.sun.jersey.api.client.WebResource
;
import
com.sun.jersey.api.client.config.DefaultClientConfig
;
import
org.apache.commons.configuration.PropertiesConfiguration
;
import
org.apache.hadoop.conf.Configuration
;
import
org.apache.hadoop.fs.Path
;
import
org.apache.hadoop.metadata.web.resources.*
;
import
org.apache.hadoop.security.alias.CredentialProvider
;
import
org.apache.hadoop.security.alias.CredentialProviderFactory
;
import
org.apache.hadoop.security.alias.JavaKeyStoreProvider
;
import
org.mortbay.jetty.webapp.WebAppContext
;
import
org.testng.Assert
;
import
org.testng.TestListenerAdapter
;
import
org.testng.TestNG
;
import
org.testng.annotations.AfterClass
;
import
org.testng.annotations.BeforeClass
;
import
org.testng.annotations.BeforeMethod
;
import
org.testng.annotations.Test
;
import
javax.ws.rs.core.UriBuilder
;
import
java.io.ByteArrayInputStream
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.nio.file.Files
;
import
java.util.List
;
/**
*
*/
public
class
SecureEmbeddedServerIT
{
private
SecureEmbeddedServer
secureEmbeddedServer
;
private
String
providerUrl
;
private
Path
jksPath
;
protected
WebResource
service
;
static
{
//for localhost testing only
javax
.
net
.
ssl
.
HttpsURLConnection
.
setDefaultHostnameVerifier
(
new
javax
.
net
.
ssl
.
HostnameVerifier
(){
public
boolean
verify
(
String
hostname
,
javax
.
net
.
ssl
.
SSLSession
sslSession
)
{
if
(
hostname
.
equals
(
"localhost"
))
{
return
true
;
}
return
false
;
}
});
System
.
setProperty
(
"javax.net.ssl.trustStore"
,
SecureEmbeddedServer
.
DEFAULT_KEYSTORE_FILE_LOCATION
);
System
.
setProperty
(
"javax.net.ssl.trustStorePassword"
,
"keypass"
);
System
.
setProperty
(
"javax.net.ssl.trustStoreType"
,
"JKS"
);
}
@BeforeClass
public
void
setupServerURI
()
throws
Exception
{
BaseResourceIT
.
baseUrl
=
"https://localhost:21443"
;
}
@AfterClass
public
void
resetServerURI
()
throws
Exception
{
BaseResourceIT
.
baseUrl
=
"http://localhost:21000"
;
}
@BeforeMethod
public
void
setup
()
throws
Exception
{
jksPath
=
new
Path
(
Files
.
createTempDirectory
(
"tempproviders"
).
toString
(),
"test.jks"
);
providerUrl
=
JavaKeyStoreProvider
.
SCHEME_NAME
+
"://file"
+
jksPath
.
toUri
();
String
baseUrl
=
"https://localhost:21443/"
;
DefaultClientConfig
config
=
new
DefaultClientConfig
();
Client
client
=
Client
.
create
(
config
);
client
.
resource
(
UriBuilder
.
fromUri
(
baseUrl
).
build
());
service
=
client
.
resource
(
UriBuilder
.
fromUri
(
baseUrl
).
build
());
}
@Test
public
void
testNoConfiguredCredentialProvider
()
throws
Exception
{
try
{
secureEmbeddedServer
=
new
SecureEmbeddedServer
(
21443
,
"webapp/target/metadata-governance"
);
WebAppContext
webapp
=
new
WebAppContext
();
webapp
.
setContextPath
(
"/"
);
webapp
.
setWar
(
System
.
getProperty
(
"user.dir"
)
+
"/target/metadata-governance.war"
);
secureEmbeddedServer
.
server
.
setHandler
(
webapp
);
secureEmbeddedServer
.
server
.
start
();
Assert
.
fail
(
"Should have thrown an exception"
);
}
catch
(
IOException
e
)
{
assert
e
.
getMessage
().
equals
(
"No credential provider path configured for storage of certificate store passwords"
);
}
}
@Test
public
void
testServerConfiguredUsingCredentialProvider
()
throws
Exception
{
// setup the configuration
final
PropertiesConfiguration
configuration
=
new
PropertiesConfiguration
();
configuration
.
setProperty
(
SecureEmbeddedServer
.
CERT_STORES_CREDENTIAL_PROVIDER_PATH
,
providerUrl
);
// setup the credential provider
setupCredentials
();
secureEmbeddedServer
=
new
SecureEmbeddedServer
(
21443
,
"webapp/target/metadata-governance"
)
{
@Override
protected
PropertiesConfiguration
getConfiguration
()
{
return
configuration
;
}
};
WebAppContext
webapp
=
new
WebAppContext
();
webapp
.
setContextPath
(
"/"
);
webapp
.
setWar
(
System
.
getProperty
(
"user.dir"
)
+
"/target/metadata-governance.war"
);
secureEmbeddedServer
.
server
.
setHandler
(
webapp
);
secureEmbeddedServer
.
server
.
start
();
URL
url
=
new
URL
(
"https://localhost:21443/"
);
HttpURLConnection
connection
=
(
HttpURLConnection
)
url
.
openConnection
();
connection
.
setRequestMethod
(
"GET"
);
connection
.
connect
();
// test to see whether server is up and root page can be served
assert
connection
.
getResponseCode
()
==
200
;
secureEmbeddedServer
.
server
.
stop
();
}
@Test
public
void
testMissingEntriesInCredentialProvider
()
throws
Exception
{
// setup the configuration
final
PropertiesConfiguration
configuration
=
new
PropertiesConfiguration
();
configuration
.
setProperty
(
SecureEmbeddedServer
.
CERT_STORES_CREDENTIAL_PROVIDER_PATH
,
providerUrl
);
try
{
secureEmbeddedServer
=
new
SecureEmbeddedServer
(
21443
,
"webapp/target/metadata-governance"
)
{
@Override
protected
PropertiesConfiguration
getConfiguration
()
{
return
configuration
;
}
};
Assert
.
fail
(
"No entries should generate an exception"
);
}
catch
(
IOException
e
)
{
assert
e
.
getMessage
().
startsWith
(
"No credential entry found for"
);
}
}
/**
* Runs the existing webapp test cases, this time against the initiated secure server instance.
* @throws Exception
*/
@Test
public
void
runOtherSuitesAgainstSecureServer
()
throws
Exception
{
final
PropertiesConfiguration
configuration
=
new
PropertiesConfiguration
();
configuration
.
setProperty
(
SecureEmbeddedServer
.
CERT_STORES_CREDENTIAL_PROVIDER_PATH
,
providerUrl
);
// setup the credential provider
setupCredentials
();
secureEmbeddedServer
=
new
SecureEmbeddedServer
(
21443
,
"webapp/target/metadata-governance"
)
{
@Override
protected
PropertiesConfiguration
getConfiguration
()
{
return
configuration
;
}
};
WebAppContext
webapp
=
new
WebAppContext
();
webapp
.
setContextPath
(
"/"
);
webapp
.
setWar
(
System
.
getProperty
(
"user.dir"
)
+
"/target/metadata-governance.war"
);
secureEmbeddedServer
.
server
.
setHandler
(
webapp
);
secureEmbeddedServer
.
server
.
start
();
TestListenerAdapter
tla
=
new
TestListenerAdapter
();
TestNG
testng
=
new
TestNG
();
testng
.
setTestClasses
(
new
Class
[]
{
EntityJerseyResourceIT
.
class
,
MetadataDiscoveryResourceIT
.
class
,
RexsterGraphJerseyResourceIT
.
class
,
TypesJerseyResourceIT
.
class
});
testng
.
addListener
(
tla
);
testng
.
run
();
secureEmbeddedServer
.
server
.
stop
();
}
private
void
setupCredentials
()
throws
Exception
{
Configuration
conf
=
new
Configuration
(
false
);
File
file
=
new
File
(
jksPath
.
toUri
().
getPath
());
file
.
delete
();
conf
.
set
(
CredentialProviderFactory
.
CREDENTIAL_PROVIDER_PATH
,
providerUrl
);
CredentialProvider
provider
=
CredentialProviderFactory
.
getProviders
(
conf
).
get
(
0
);
// create new aliases
try
{
char
[]
storepass
=
{
'k'
,
'e'
,
'y'
,
'p'
,
'a'
,
's'
,
's'
};
provider
.
createCredentialEntry
(
SecureEmbeddedServer
.
KEYSTORE_PASSWORD_KEY
,
storepass
);
char
[]
trustpass
=
{
'k'
,
'e'
,
'y'
,
'p'
,
'a'
,
's'
,
's'
};
provider
.
createCredentialEntry
(
SecureEmbeddedServer
.
TRUSTSTORE_PASSWORD_KEY
,
trustpass
);
char
[]
certpass
=
{
'k'
,
'e'
,
'y'
,
'p'
,
'a'
,
's'
,
's'
};
provider
.
createCredentialEntry
(
SecureEmbeddedServer
.
SERVER_CERT_PASSWORD_KEY
,
certpass
);
// write out so that it can be found in checks
provider
.
flush
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
e
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment