|
@@ -17,7 +17,6 @@
|
|
|
*/
|
|
|
package org.apache.hadoop.hdfs;
|
|
|
|
|
|
-import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_KEY_PREFIX;
|
|
|
import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_CLIENT_CACHE_DROP_BEHIND_READS;
|
|
|
import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_CLIENT_CACHE_DROP_BEHIND_WRITES;
|
|
|
import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_CLIENT_CACHE_READAHEAD;
|
|
@@ -58,18 +57,15 @@ import javax.net.SocketFactory;
|
|
|
import org.apache.hadoop.HadoopIllegalArgumentException;
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
-import org.apache.hadoop.crypto.CipherSuite;
|
|
|
import org.apache.hadoop.crypto.CryptoCodec;
|
|
|
import org.apache.hadoop.crypto.CryptoInputStream;
|
|
|
import org.apache.hadoop.crypto.CryptoOutputStream;
|
|
|
-import org.apache.hadoop.crypto.CryptoProtocolVersion;
|
|
|
import org.apache.hadoop.crypto.key.KeyProvider;
|
|
|
import org.apache.hadoop.crypto.key.KeyProvider.KeyVersion;
|
|
|
import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
|
|
|
import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
|
|
|
import org.apache.hadoop.fs.BlockLocation;
|
|
|
import org.apache.hadoop.fs.CacheFlag;
|
|
|
-import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
|
|
import org.apache.hadoop.fs.ContentSummary;
|
|
|
import org.apache.hadoop.fs.CreateFlag;
|
|
|
import org.apache.hadoop.fs.FileAlreadyExistsException;
|
|
@@ -171,7 +167,6 @@ import org.apache.hadoop.ipc.RpcNoSuchMethodException;
|
|
|
import org.apache.hadoop.net.DNS;
|
|
|
import org.apache.hadoop.net.NetUtils;
|
|
|
import org.apache.hadoop.security.AccessControlException;
|
|
|
-import org.apache.hadoop.security.Credentials;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.security.token.SecretManager.InvalidToken;
|
|
|
import org.apache.hadoop.security.token.Token;
|
|
@@ -207,7 +202,6 @@ import com.google.common.net.InetAddresses;
|
|
|
public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
|
|
DataEncryptionKeyFactory {
|
|
|
public static final Logger LOG = LoggerFactory.getLogger(DFSClient.class);
|
|
|
- private static final String DFS_KMS_PREFIX = "dfs-kms-";
|
|
|
|
|
|
private final Configuration conf;
|
|
|
private final Tracer tracer;
|
|
@@ -936,55 +930,6 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Obtain the crypto protocol version from the provided FileEncryptionInfo,
|
|
|
- * checking to see if this version is supported by.
|
|
|
- *
|
|
|
- * @param feInfo FileEncryptionInfo
|
|
|
- * @return CryptoProtocolVersion from the feInfo
|
|
|
- * @throws IOException if the protocol version is unsupported.
|
|
|
- */
|
|
|
- private static CryptoProtocolVersion getCryptoProtocolVersion(
|
|
|
- FileEncryptionInfo feInfo) throws IOException {
|
|
|
- final CryptoProtocolVersion version = feInfo.getCryptoProtocolVersion();
|
|
|
- if (!CryptoProtocolVersion.supports(version)) {
|
|
|
- throw new IOException("Client does not support specified " +
|
|
|
- "CryptoProtocolVersion " + version.getDescription() + " version " +
|
|
|
- "number" + version.getVersion());
|
|
|
- }
|
|
|
- return version;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Obtain a CryptoCodec based on the CipherSuite set in a FileEncryptionInfo
|
|
|
- * and the available CryptoCodecs configured in the Configuration.
|
|
|
- *
|
|
|
- * @param conf Configuration
|
|
|
- * @param feInfo FileEncryptionInfo
|
|
|
- * @return CryptoCodec
|
|
|
- * @throws IOException if no suitable CryptoCodec for the CipherSuite is
|
|
|
- * available.
|
|
|
- */
|
|
|
- private static CryptoCodec getCryptoCodec(Configuration conf,
|
|
|
- FileEncryptionInfo feInfo) throws IOException {
|
|
|
- final CipherSuite suite = feInfo.getCipherSuite();
|
|
|
- if (suite.equals(CipherSuite.UNKNOWN)) {
|
|
|
- throw new IOException("NameNode specified unknown CipherSuite with ID "
|
|
|
- + suite.getUnknownValue() + ", cannot instantiate CryptoCodec.");
|
|
|
- }
|
|
|
- final CryptoCodec codec = CryptoCodec.getInstance(conf, suite);
|
|
|
- if (codec == null) {
|
|
|
- throw new UnknownCipherSuiteException(
|
|
|
- "No configuration found for the cipher suite "
|
|
|
- + suite.getConfigSuffix() + " prefixed with "
|
|
|
- + HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_KEY_PREFIX
|
|
|
- + ". Please see the example configuration "
|
|
|
- + "hadoop.security.crypto.codec.classes.EXAMPLECIPHERSUITE "
|
|
|
- + "at core-default.xml for details.");
|
|
|
- }
|
|
|
- return codec;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Wraps the stream in a CryptoInputStream if the underlying file is
|
|
|
* encrypted.
|
|
@@ -995,8 +940,8 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
|
|
if (feInfo != null) {
|
|
|
// File is encrypted, wrap the stream in a crypto stream.
|
|
|
// Currently only one version, so no special logic based on the version #
|
|
|
- getCryptoProtocolVersion(feInfo);
|
|
|
- final CryptoCodec codec = getCryptoCodec(conf, feInfo);
|
|
|
+ HdfsKMSUtil.getCryptoProtocolVersion(feInfo);
|
|
|
+ final CryptoCodec codec = HdfsKMSUtil.getCryptoCodec(conf, feInfo);
|
|
|
final KeyVersion decrypted = decryptEncryptedDataEncryptionKey(feInfo);
|
|
|
final CryptoInputStream cryptoIn =
|
|
|
new CryptoInputStream(dfsis, codec, decrypted.getMaterial(),
|
|
@@ -1027,8 +972,8 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
|
|
if (feInfo != null) {
|
|
|
// File is encrypted, wrap the stream in a crypto stream.
|
|
|
// Currently only one version, so no special logic based on the version #
|
|
|
- getCryptoProtocolVersion(feInfo);
|
|
|
- final CryptoCodec codec = getCryptoCodec(conf, feInfo);
|
|
|
+ HdfsKMSUtil.getCryptoProtocolVersion(feInfo);
|
|
|
+ final CryptoCodec codec = HdfsKMSUtil.getCryptoCodec(conf, feInfo);
|
|
|
KeyVersion decrypted = decryptEncryptedDataEncryptionKey(feInfo);
|
|
|
final CryptoOutputStream cryptoOut =
|
|
|
new CryptoOutputStream(dfsos, codec,
|
|
@@ -2983,51 +2928,9 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
|
|
return HEDGED_READ_METRIC;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Returns a key to map namenode uri to key provider uri.
|
|
|
- * Tasks will lookup this key to find key Provider.
|
|
|
- */
|
|
|
- public Text getKeyProviderMapKey() {
|
|
|
- return new Text(DFS_KMS_PREFIX + namenodeUri.getScheme()
|
|
|
- +"://" + namenodeUri.getAuthority());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * The key provider uri is searched in the following order.
|
|
|
- * 1. If there is a mapping in Credential's secrets map for namenode uri.
|
|
|
- * 2. From namenode getServerDefaults rpc.
|
|
|
- * 3. Finally fallback to local conf.
|
|
|
- * @return keyProviderUri if found from either of above 3 cases,
|
|
|
- * null otherwise
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
URI getKeyProviderUri() throws IOException {
|
|
|
- URI keyProviderUri = null;
|
|
|
- // Lookup the secret in credentials object for namenodeuri.
|
|
|
- Credentials credentials = ugi.getCredentials();
|
|
|
- byte[] keyProviderUriBytes = credentials.getSecretKey(getKeyProviderMapKey());
|
|
|
- if(keyProviderUriBytes != null) {
|
|
|
- keyProviderUri =
|
|
|
- URI.create(DFSUtilClient.bytes2String(keyProviderUriBytes));
|
|
|
- return keyProviderUri;
|
|
|
- }
|
|
|
-
|
|
|
- // Query the namenode for the key provider uri.
|
|
|
- FsServerDefaults serverDefaults = getServerDefaults();
|
|
|
- if (serverDefaults.getKeyProviderUri() != null) {
|
|
|
- if (!serverDefaults.getKeyProviderUri().isEmpty()) {
|
|
|
- keyProviderUri = URI.create(serverDefaults.getKeyProviderUri());
|
|
|
- }
|
|
|
- return keyProviderUri;
|
|
|
- }
|
|
|
-
|
|
|
- // Last thing is to trust its own conf to be backwards compatible.
|
|
|
- String keyProviderUriStr = conf.getTrimmed(
|
|
|
- CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH);
|
|
|
- if (keyProviderUriStr != null && !keyProviderUriStr.isEmpty()) {
|
|
|
- keyProviderUri = URI.create(keyProviderUriStr);
|
|
|
- }
|
|
|
- return keyProviderUri;
|
|
|
+ return HdfsKMSUtil.getKeyProviderUri(ugi, namenodeUri,
|
|
|
+ getServerDefaults().getKeyProviderUri(), conf);
|
|
|
}
|
|
|
|
|
|
public KeyProvider getKeyProvider() throws IOException {
|