blob: ff99e080c49ebf04cad35ed27000e26931b7f161 [file] [log] [blame]
/*
* 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.hdds.security.x509.certificate.client;
import com.google.common.base.Preconditions;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.validator.routines.DomainValidator;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.utils.CertificateCodec;
import org.apache.hadoop.hdds.security.x509.certificates.utils.CertificateSignRequest;
import org.apache.hadoop.hdds.security.x509.exceptions.CertificateException;
import org.apache.hadoop.hdds.security.x509.keys.HDDSKeyGenerator;
import org.apache.hadoop.hdds.security.x509.keys.KeyCodec;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.protocol.SCMSecurityProtocol;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolClientSideTranslatorPB;
import org.apache.hadoop.hdds.protocolPB.SCMSecurityProtocolPB;
import org.apache.hadoop.hdds.scm.protocolPB.ScmBlockLocationProtocolPB;
import org.apache.hadoop.ipc.Client;
import org.apache.hadoop.ipc.ProtobufRpcEngine;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.ozone.OzoneSecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.bouncycastle.cert.X509CertificateHolder;
import org.slf4j.Logger;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertStore;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import static org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient.InitResponse.FAILURE;
import static org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient.InitResponse.GETCERT;
import static org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient.InitResponse.SUCCESS;
import static org.apache.hadoop.hdds.security.x509.exceptions.CertificateException.ErrorCode.*;
/**
* Default Certificate client implementation. It provides certificate
* operations that needs to be performed by certificate clients in the Ozone
* eco-system.
*/
public abstract class DefaultCertificateClient implements CertificateClient {
private static final String CERT_FILE_NAME_FORMAT = "%s.crt";
private static final String CA_CERT_PREFIX = "CA-";
private static final int CA_CERT_PREFIX_LEN = 3;
private final Logger logger;
private final SecurityConfig securityConfig;
private final KeyCodec keyCodec;
private PrivateKey privateKey;
private PublicKey publicKey;
private X509Certificate x509Certificate;
private Map<String, X509Certificate> certificateMap;
private String certSerialId;
private String caCertId;
private String component;
DefaultCertificateClient(SecurityConfig securityConfig, Logger log,
String certSerialId, String component) {
Objects.requireNonNull(securityConfig);
this.securityConfig = securityConfig;
keyCodec = new KeyCodec(securityConfig, component);
this.logger = log;
this.certificateMap = new ConcurrentHashMap<>();
this.certSerialId = certSerialId;
this.component = component;
loadAllCertificates();
}
/**
* Load all certificates from configured location.
* */
private void loadAllCertificates() {
// See if certs directory exists in file system.
Path certPath = securityConfig.getCertificateLocation(component);
if (Files.exists(certPath) && Files.isDirectory(certPath)) {
getLogger().info("Loading certificate from location:{}.",
certPath);
File[] certFiles = certPath.toFile().listFiles();
if (certFiles != null) {
CertificateCodec certificateCodec =
new CertificateCodec(securityConfig, component);
long latestCaCertSerailId = -1L;
for (File file : certFiles) {
if (file.isFile()) {
try {
X509CertificateHolder x509CertificateHolder = certificateCodec
.readCertificate(certPath, file.getName());
X509Certificate cert =
CertificateCodec.getX509Certificate(x509CertificateHolder);
if (cert != null && cert.getSerialNumber() != null) {
if (cert.getSerialNumber().toString().equals(certSerialId)) {
x509Certificate = cert;
}
certificateMap.putIfAbsent(cert.getSerialNumber().toString(),
cert);
if (file.getName().startsWith(CA_CERT_PREFIX)) {
String certFileName = FilenameUtils.getBaseName(
file.getName());
long tmpCaCertSerailId = NumberUtils.toLong(
certFileName.substring(CA_CERT_PREFIX_LEN));
if (tmpCaCertSerailId > latestCaCertSerailId) {
latestCaCertSerailId = tmpCaCertSerailId;
}
}
getLogger().info("Added certificate from file:{}.",
file.getAbsolutePath());
} else {
getLogger().error("Error reading certificate from file:{}",
file);
}
} catch (java.security.cert.CertificateException | IOException e) {
getLogger().error("Error reading certificate from file:{}.",
file.getAbsolutePath(), e);
}
}
}
if (latestCaCertSerailId != -1) {
caCertId = Long.toString(latestCaCertSerailId);
}
}
}
}
/**
* Returns the private key of the specified if it exists on the local
* system.
*
* @return private key or Null if there is no data.
*/
@Override
public PrivateKey getPrivateKey() {
if (privateKey != null) {
return privateKey;
}
Path keyPath = securityConfig.getKeyLocation(component);
if (OzoneSecurityUtil.checkIfFileExist(keyPath,
securityConfig.getPrivateKeyFileName())) {
try {
privateKey = keyCodec.readPrivateKey();
} catch (InvalidKeySpecException | NoSuchAlgorithmException
| IOException e) {
getLogger().error("Error while getting private key.", e);
}
}
return privateKey;
}
/**
* Returns the public key of the specified if it exists on the local system.
*
* @return public key or Null if there is no data.
*/
@Override
public PublicKey getPublicKey() {
if (publicKey != null) {
return publicKey;
}
Path keyPath = securityConfig.getKeyLocation(component);
if (OzoneSecurityUtil.checkIfFileExist(keyPath,
securityConfig.getPublicKeyFileName())) {
try {
publicKey = keyCodec.readPublicKey();
} catch (InvalidKeySpecException | NoSuchAlgorithmException
| IOException e) {
getLogger().error("Error while getting public key.", e);
}
}
return publicKey;
}
/**
* Returns the default certificate of given client if it exists.
*
* @return certificate or Null if there is no data.
*/
@Override
public X509Certificate getCertificate() {
if (x509Certificate != null) {
return x509Certificate;
}
if (certSerialId == null) {
getLogger().error("Default certificate serial id is not set. Can't " +
"locate the default certificate for this client.");
return null;
}
// Refresh the cache from file system.
loadAllCertificates();
if (certificateMap.containsKey(certSerialId)) {
x509Certificate = certificateMap.get(certSerialId);
}
return x509Certificate;
}
/**
* Return the latest CA certificate known to the client.
* @return latest ca certificate known to the client.
*/
@Override
public X509Certificate getCACertificate() {
if (caCertId != null) {
return certificateMap.get(caCertId);
}
return null;
}
/**
* Returns the certificate with the specified certificate serial id if it
* exists else try to get it from SCM.
* @param certId
*
* @return certificate or Null if there is no data.
*/
@Override
public X509Certificate getCertificate(String certId)
throws CertificateException {
// Check if it is in cache.
if (certificateMap.containsKey(certId)) {
return certificateMap.get(certId);
}
// Try to get it from SCM.
return this.getCertificateFromScm(certId);
}
/**
* Get certificate from SCM and store it in local file system.
* @param certId
* @return certificate
*/
private X509Certificate getCertificateFromScm(String certId)
throws CertificateException {
getLogger().info("Getting certificate with certSerialId:{}.",
certId);
try {
SCMSecurityProtocol scmSecurityProtocolClient = getScmSecurityClient(
(OzoneConfiguration) securityConfig.getConfiguration());
String pemEncodedCert =
scmSecurityProtocolClient.getCertificate(certId);
this.storeCertificate(pemEncodedCert, true);
return CertificateCodec.getX509Certificate(pemEncodedCert);
} catch (Exception e) {
getLogger().error("Error while getting Certificate with " +
"certSerialId:{} from scm.", certId, e);
throw new CertificateException("Error while getting certificate for " +
"certSerialId:" + certId, e, CERTIFICATE_ERROR);
}
}
/**
* Verifies if this certificate is part of a trusted chain.
*
* @param certificate - certificate.
* @return true if it trusted, false otherwise.
*/
@Override
public boolean verifyCertificate(X509Certificate certificate) {
throw new UnsupportedOperationException("Operation not supported.");
}
/**
* Creates digital signature over the data stream using the s private key.
*
* @param stream - Data stream to sign.
* @throws CertificateException - on Error.
*/
@Override
public byte[] signDataStream(InputStream stream)
throws CertificateException {
try {
Signature sign = Signature.getInstance(securityConfig.getSignatureAlgo(),
securityConfig.getProvider());
sign.initSign(getPrivateKey());
byte[] buffer = new byte[1024 * 4];
int len;
while (-1 != (len = stream.read(buffer))) {
sign.update(buffer, 0, len);
}
return sign.sign();
} catch (NoSuchAlgorithmException | NoSuchProviderException
| InvalidKeyException | SignatureException | IOException e) {
getLogger().error("Error while signing the stream", e);
throw new CertificateException("Error while signing the stream", e,
CRYPTO_SIGN_ERROR);
}
}
/**
* Creates digital signature over the data stream using the s private key.
*
* @param data - Data to sign.
* @throws CertificateException - on Error.
*/
@Override
public byte[] signData(byte[] data) throws CertificateException {
try {
Signature sign = Signature.getInstance(securityConfig.getSignatureAlgo(),
securityConfig.getProvider());
sign.initSign(getPrivateKey());
sign.update(data);
return sign.sign();
} catch (NoSuchAlgorithmException | NoSuchProviderException
| InvalidKeyException | SignatureException e) {
getLogger().error("Error while signing the stream", e);
throw new CertificateException("Error while signing the stream", e,
CRYPTO_SIGN_ERROR);
}
}
/**
* Verifies a digital Signature, given the signature and the certificate of
* the signer.
*
* @param stream - Data Stream.
* @param signature - Byte Array containing the signature.
* @param cert - Certificate of the Signer.
* @return true if verified, false if not.
*/
@Override
public boolean verifySignature(InputStream stream, byte[] signature,
X509Certificate cert) throws CertificateException {
try {
Signature sign = Signature.getInstance(securityConfig.getSignatureAlgo(),
securityConfig.getProvider());
sign.initVerify(cert);
byte[] buffer = new byte[1024 * 4];
int len;
while (-1 != (len = stream.read(buffer))) {
sign.update(buffer, 0, len);
}
return sign.verify(signature);
} catch (NoSuchAlgorithmException | NoSuchProviderException
| InvalidKeyException | SignatureException | IOException e) {
getLogger().error("Error while signing the stream", e);
throw new CertificateException("Error while signing the stream", e,
CRYPTO_SIGNATURE_VERIFICATION_ERROR);
}
}
/**
* Verifies a digital Signature, given the signature and the certificate of
* the signer.
*
* @param data - Data in byte array.
* @param signature - Byte Array containing the signature.
* @param cert - Certificate of the Signer.
* @return true if verified, false if not.
*/
@Override
public boolean verifySignature(byte[] data, byte[] signature,
X509Certificate cert) throws CertificateException {
try {
Signature sign = Signature.getInstance(securityConfig.getSignatureAlgo(),
securityConfig.getProvider());
sign.initVerify(cert);
sign.update(data);
return sign.verify(signature);
} catch (NoSuchAlgorithmException | NoSuchProviderException
| InvalidKeyException | SignatureException e) {
getLogger().error("Error while signing the stream", e);
throw new CertificateException("Error while signing the stream", e,
CRYPTO_SIGNATURE_VERIFICATION_ERROR);
}
}
/**
* Verifies a digital Signature, given the signature and the certificate of
* the signer.
*
* @param data - Data in byte array.
* @param signature - Byte Array containing the signature.
* @param pubKey - Certificate of the Signer.
* @return true if verified, false if not.
*/
private boolean verifySignature(byte[] data, byte[] signature,
PublicKey pubKey) throws CertificateException {
try {
Signature sign = Signature.getInstance(securityConfig.getSignatureAlgo(),
securityConfig.getProvider());
sign.initVerify(pubKey);
sign.update(data);
return sign.verify(signature);
} catch (NoSuchAlgorithmException | NoSuchProviderException
| InvalidKeyException | SignatureException e) {
getLogger().error("Error while signing the stream", e);
throw new CertificateException("Error while signing the stream", e,
CRYPTO_SIGNATURE_VERIFICATION_ERROR);
}
}
/**
* Returns a CSR builder that can be used to creates a Certificate signing
* request.
*
* @return CertificateSignRequest.Builder
*/
@Override
public CertificateSignRequest.Builder getCSRBuilder()
throws CertificateException {
CertificateSignRequest.Builder builder =
new CertificateSignRequest.Builder()
.setConfiguration(securityConfig.getConfiguration());
try {
DomainValidator validator = DomainValidator.getInstance();
// Add all valid ips.
OzoneSecurityUtil.getValidInetsForCurrentHost().forEach(
ip -> {
builder.addIpAddress(ip.getHostAddress());
if(validator.isValid(ip.getCanonicalHostName())) {
builder.addDnsName(ip.getCanonicalHostName());
}
});
} catch (IOException e) {
throw new CertificateException("Error while adding ip to CSR builder",
e, CSR_ERROR);
}
return builder;
}
/**
* Get the certificate of well-known entity from SCM.
*
* @param query - String Query, please see the implementation for the
* discussion on the query formats.
* @return X509Certificate or null if not found.
*/
@Override
public X509Certificate queryCertificate(String query) {
// TODO:
throw new UnsupportedOperationException("Operation not supported");
}
/**
* Stores the Certificate for this client. Don't use this api to add trusted
* certificates of others.
*
* @param pemEncodedCert - pem encoded X509 Certificate
* @param force - override any existing file
* @throws CertificateException - on Error.
*
*/
@Override
public void storeCertificate(String pemEncodedCert, boolean force)
throws CertificateException {
this.storeCertificate(pemEncodedCert, force, false);
}
/**
* Stores the Certificate for this client. Don't use this api to add trusted
* certificates of others.
*
* @param pemEncodedCert - pem encoded X509 Certificate
* @param force - override any existing file
* @param caCert - Is CA certificate.
* @throws CertificateException - on Error.
*
*/
@Override
public void storeCertificate(String pemEncodedCert, boolean force,
boolean caCert) throws CertificateException {
CertificateCodec certificateCodec = new CertificateCodec(securityConfig,
component);
try {
Path basePath = securityConfig.getCertificateLocation(component);
X509Certificate cert =
CertificateCodec.getX509Certificate(pemEncodedCert);
String certName = String.format(CERT_FILE_NAME_FORMAT,
cert.getSerialNumber().toString());
if(caCert) {
certName = CA_CERT_PREFIX + certName;
caCertId = cert.getSerialNumber().toString();
}
certificateCodec.writeCertificate(basePath, certName,
pemEncodedCert, force);
certificateMap.putIfAbsent(cert.getSerialNumber().toString(), cert);
} catch (IOException | java.security.cert.CertificateException e) {
throw new CertificateException("Error while storing certificate.", e,
CERTIFICATE_ERROR);
}
}
/**
* Stores the trusted chain of certificates for a specific .
*
* @param ks - Key Store.
* @throws CertificateException - on Error.
*/
@Override
public synchronized void storeTrustChain(CertStore ks)
throws CertificateException {
throw new UnsupportedOperationException("Operation not supported.");
}
/**
* Stores the trusted chain of certificates for a specific .
*
* @param certificates - List of Certificates.
* @throws CertificateException - on Error.
*/
@Override
public synchronized void storeTrustChain(List<X509Certificate> certificates)
throws CertificateException {
throw new UnsupportedOperationException("Operation not supported.");
}
/**
* Defines 8 cases of initialization.
* Each case specifies objects found.
* 0. NONE Keypair as well as certificate not found.
* 1. CERT Certificate found but keypair missing.
* 2. PUBLIC_KEY Public key found but private key and
* certificate is missing.
* 3. PUBLICKEY_CERT Only public key and certificate is present.
* 4. PRIVATE_KEY Only private key is present.
* 5. PRIVATEKEY_CERT Only private key and certificate is present.
* 6. PUBLICKEY_PRIVATEKEY indicates private and public key were read
* successfully from configured location but
* Certificate.
* 7. All Keypair as well as certificate is present.
*
* */
protected enum InitCase {
NONE,
CERT,
PUBLIC_KEY,
PUBLICKEY_CERT,
PRIVATE_KEY,
PRIVATEKEY_CERT,
PUBLICKEY_PRIVATEKEY,
ALL
}
/**
*
* Initializes client by performing following actions.
* 1. Create key dir if not created already.
* 2. Generates and stores a keypair.
* 3. Try to recover public key if private key and certificate is present
* but public key is missing.
*
* Truth table:
* +--------------+-----------------+--------------+----------------+
* | Private Key | Public Keys | Certificate | Result |
* +--------------+-----------------+--------------+----------------+
* | False (0) | False (0) | False (0) | GETCERT 000 |
* | False (0) | False (0) | True (1) | FAILURE 001 |
* | False (0) | True (1) | False (0) | FAILURE 010 |
* | False (0) | True (1) | True (1) | FAILURE 011 |
* | True (1) | False (0) | False (0) | FAILURE 100 |
* | True (1) | False (0) | True (1) | SUCCESS 101 |
* | True (1) | True (1) | False (0) | GETCERT 110 |
* | True (1) | True (1) | True (1) | SUCCESS 111 |
* +--------------+-----------------+--------------+----------------+
*
* @return InitResponse
* Returns FAILURE in following cases:
* 1. If private key is missing but public key or certificate is available.
* 2. If public key and certificate is missing.
*
* Returns SUCCESS in following cases:
* 1. If keypair as well certificate is available.
* 2. If private key and certificate is available and public key is
* recovered successfully.
*
* Returns GETCERT in following cases:
* 1. First time when keypair and certificate is not available, keypair
* will be generated and stored at configured location.
* 2. When keypair (public/private key) is available but certificate is
* missing.
*
*/
@Override
public synchronized InitResponse init() throws CertificateException {
int initCase = 0;
PrivateKey pvtKey= getPrivateKey();
PublicKey pubKey = getPublicKey();
X509Certificate certificate = getCertificate();
if(pvtKey != null){
initCase = initCase | 1<<2;
}
if(pubKey != null){
initCase = initCase | 1<<1;
}
if(certificate != null){
initCase = initCase | 1;
}
getLogger().info("Certificate client init case: {}", initCase);
Preconditions.checkArgument(initCase < 8, "Not a " +
"valid case.");
InitCase init = InitCase.values()[initCase];
return handleCase(init);
}
/**
* Default handling of each {@link InitCase}.
* */
protected InitResponse handleCase(InitCase init)
throws CertificateException {
switch (init) {
case NONE:
getLogger().info("Creating keypair for client as keypair and " +
"certificate not found.");
bootstrapClientKeys();
return GETCERT;
case CERT:
getLogger().error("Private key not found, while certificate is still" +
" present. Delete keypair and try again.");
return FAILURE;
case PUBLIC_KEY:
getLogger().error("Found public key but private key and certificate " +
"missing.");
return FAILURE;
case PRIVATE_KEY:
getLogger().info("Found private key but public key and certificate " +
"is missing.");
// TODO: Recovering public key from private might be possible in some
// cases.
return FAILURE;
case PUBLICKEY_CERT:
getLogger().error("Found public key and certificate but private " +
"key is missing.");
return FAILURE;
case PRIVATEKEY_CERT:
getLogger().info("Found private key and certificate but public key" +
" missing.");
if (recoverPublicKey()) {
return SUCCESS;
} else {
getLogger().error("Public key recovery failed.");
return FAILURE;
}
case PUBLICKEY_PRIVATEKEY:
getLogger().info("Found private and public key but certificate is" +
" missing.");
if (validateKeyPair(getPublicKey())) {
return GETCERT;
} else {
getLogger().info("Keypair validation failed.");
return FAILURE;
}
case ALL:
getLogger().info("Found certificate file along with KeyPair.");
if (validateKeyPairAndCertificate()) {
return SUCCESS;
} else {
return FAILURE;
}
default:
getLogger().error("Unexpected case: {} (private/public/cert)",
Integer.toBinaryString(init.ordinal()));
return FAILURE;
}
}
/**
* Validate keypair and certificate.
* */
protected boolean validateKeyPairAndCertificate() throws
CertificateException {
if (validateKeyPair(getPublicKey())) {
getLogger().info("Keypair validated.");
// TODO: Certificates cryptographic validity can be checked as well.
if (validateKeyPair(getCertificate().getPublicKey())) {
getLogger().info("Keypair validated with certificate.");
} else {
getLogger().error("Stored certificate is generated with different " +
"private key.");
return false;
}
} else {
getLogger().error("Keypair validation failed.");
return false;
}
return true;
}
/**
* Tries to recover public key from certificate. Also validates recovered
* public key.
* */
protected boolean recoverPublicKey() throws CertificateException {
PublicKey pubKey = getCertificate().getPublicKey();
try {
if(validateKeyPair(pubKey)){
keyCodec.writePublicKey(pubKey);
publicKey = pubKey;
} else {
getLogger().error("Can't recover public key " +
"corresponding to private key.", BOOTSTRAP_ERROR);
return false;
}
} catch (IOException e) {
throw new CertificateException("Error while trying to recover " +
"public key.", e, BOOTSTRAP_ERROR);
}
return true;
}
/**
* Validates public and private key of certificate client.
*
* @param pubKey
* */
protected boolean validateKeyPair(PublicKey pubKey)
throws CertificateException {
byte[] challenge = RandomStringUtils.random(1000).getBytes(
StandardCharsets.UTF_8);
byte[] sign = signDataStream(new ByteArrayInputStream(challenge));
return verifySignature(challenge, sign, pubKey);
}
/**
* Bootstrap the client by creating keypair and storing it in configured
* location.
* */
protected void bootstrapClientKeys() throws CertificateException {
Path keyPath = securityConfig.getKeyLocation(component);
if (Files.notExists(keyPath)) {
try {
Files.createDirectories(keyPath);
} catch (IOException e) {
throw new CertificateException("Error while creating directories " +
"for certificate storage.", BOOTSTRAP_ERROR);
}
}
KeyPair keyPair = createKeyPair();
privateKey = keyPair.getPrivate();
publicKey = keyPair.getPublic();
}
protected KeyPair createKeyPair() throws CertificateException {
HDDSKeyGenerator keyGenerator = new HDDSKeyGenerator(securityConfig);
KeyPair keyPair = null;
try {
keyPair = keyGenerator.generateKey();
keyCodec.writePublicKey(keyPair.getPublic());
keyCodec.writePrivateKey(keyPair.getPrivate());
} catch (NoSuchProviderException | NoSuchAlgorithmException
| IOException e) {
getLogger().error("Error while bootstrapping certificate client.", e);
throw new CertificateException("Error while bootstrapping certificate.",
BOOTSTRAP_ERROR);
}
return keyPair;
}
public Logger getLogger() {
return logger;
}
/**
* Create a scm security client, used to get SCM signed certificate.
*
* @return {@link SCMSecurityProtocol}
*/
private static SCMSecurityProtocol getScmSecurityClient(
OzoneConfiguration conf) throws IOException {
RPC.setProtocolEngine(conf, SCMSecurityProtocolPB.class,
ProtobufRpcEngine.class);
long scmVersion =
RPC.getProtocolVersion(ScmBlockLocationProtocolPB.class);
InetSocketAddress scmSecurityProtoAdd =
HddsUtils.getScmAddressForSecurityProtocol(conf);
SCMSecurityProtocolClientSideTranslatorPB scmSecurityClient =
new SCMSecurityProtocolClientSideTranslatorPB(
RPC.getProxy(SCMSecurityProtocolPB.class, scmVersion,
scmSecurityProtoAdd, UserGroupInformation.getCurrentUser(),
conf, NetUtils.getDefaultSocketFactory(conf),
Client.getRpcTimeout(conf)));
return scmSecurityClient;
}
}