From 30bfc9cbd02d69d03456683f2d40e0ea1b555b76 Mon Sep 17 00:00:00 2001 From: Anu Engineer Date: Thu, 3 Jan 2019 20:34:25 -0800 Subject: [PATCH] HDDS-955. SCM CA: Add CA to SCM. Contributed by Anu Engineer. --- .../certificate/authority/BaseApprover.java | 6 +- .../authority/CertificateApprover.java | 10 +-- .../authority/DefaultApprover.java | 8 +- .../authority/DefaultCAServer.java | 8 +- .../utils/CertificateSignRequest.java | 3 +- .../x509/certificates/utils/package-info.java | 4 +- .../certificate/authority/MockApprover.java | 9 +- .../authority/TestDefaultCAServer.java | 2 +- .../authority/TestDefaultProfile.java | 33 ++++---- .../x509/certificate/utils/package-info.java | 23 +++++ .../TestCertificateSignRequest.java | 5 +- .../certificates/TestRootCertificate.java | 4 +- .../scm/server/StorageContainerManager.java | 84 +++++++++++++------ .../hadoop/ozone/client/package-info.java | 20 +++++ 14 files changed, 152 insertions(+), 67 deletions(-) create mode 100644 hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/package-info.java create mode 100644 hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/package-info.java diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java index 7a8e6edf54..12ececd8d4 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/BaseApprover.java @@ -173,9 +173,9 @@ boolean verifyPkcs10Request(PKCS10CertificationRequest pkcs10Request) * {@inheritDoc} */ @Override - public CompletableFuture approve(String csr) + public CompletableFuture inspectCSR(String csr) throws IOException { - return approve(CertificateSignRequest.getCertificationRequest(csr)); + return inspectCSR(CertificateSignRequest.getCertificationRequest(csr)); } /** @@ -183,7 +183,7 @@ public CompletableFuture approve(String csr) */ @Override public CompletableFuture - approve(PKCS10CertificationRequest csr) { + inspectCSR(PKCS10CertificationRequest csr) { /** * The base approver executes the following algorithm to verify that a * CSR meets the PKI Profile criteria. diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java index 13b88f2170..fc62f69de1 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/CertificateApprover.java @@ -30,7 +30,7 @@ import java.util.concurrent.CompletableFuture; /** - * Certificate Approver interface is used to approve a certificate. + * Certificate Approver interface is used to inspectCSR a certificate. */ interface CertificateApprover { /** @@ -40,7 +40,7 @@ interface CertificateApprover { * @return - Future that will be contain the certificate or exception. */ CompletableFuture - approve(PKCS10CertificationRequest csr); + inspectCSR(PKCS10CertificationRequest csr); /** * Approves a Certificate Request based on the policies of this approver. @@ -50,14 +50,14 @@ interface CertificateApprover { * @throws IOException - On Error. */ CompletableFuture - approve(String csr) throws IOException; + inspectCSR(String csr) throws IOException; /** * Sign function signs a Certificate. * @param config - Security Config. * @param caPrivate - CAs private Key. * @param caCertificate - CA Certificate. - * @param validFrom - Begin Da te + * @param validFrom - Begin Date * @param validTill - End Date * @param certificationRequest - Certification Request. * @return Signed Certificate. @@ -79,7 +79,7 @@ X509CertificateHolder sign( */ enum ApprovalType { KERBEROS_TRUSTED, /* The Request came from a DN using Kerberos Identity*/ - MANUAL, /* Wait for a Human being to approve this certificate */ + MANUAL, /* Wait for a Human being to inspect CSR of this certificate */ TESTING_AUTOMATIC /* For testing purpose, Automatic Approval. */ } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java index 84ef7bd1bd..9e08321735 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultApprover.java @@ -115,14 +115,14 @@ public X509CertificateHolder sign( } @Override - public CompletableFuture approve(String csr) + public CompletableFuture inspectCSR(String csr) throws IOException { - return super.approve(csr); + return super.inspectCSR(csr); } @Override public CompletableFuture - approve(PKCS10CertificationRequest csr) { - return super.approve(csr); + inspectCSR(PKCS10CertificationRequest csr) { + return super.inspectCSR(csr); } } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java index 7149253a48..40e2c703f6 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/DefaultCAServer.java @@ -179,14 +179,15 @@ private KeyPair getCAKeys() throws IOException { @Override public Future requestCertificate( - PKCS10CertificationRequest csr, CertificateApprover.ApprovalType approverType) { + PKCS10CertificationRequest csr, + CertificateApprover.ApprovalType approverType) { LocalDate beginDate = LocalDate.now().atStartOfDay().toLocalDate(); LocalDateTime temp = LocalDateTime.of(beginDate, LocalTime.MIDNIGHT); LocalDate endDate = temp.plus(config.getDefaultCertDuration()).toLocalDate(); CompletableFuture xcertHolder = - approver.approve(csr); + approver.inspectCSR(csr); if(xcertHolder.isCompletedExceptionally()) { // This means that approver told us there are things which it disagrees @@ -227,7 +228,8 @@ public Future requestCertificate(String csr, @Override public Future revokeCertificate(X509Certificate certificate, - CertificateApprover.ApprovalType approverType) throws SCMSecurityException { + CertificateApprover.ApprovalType approverType) + throws SCMSecurityException { return null; } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/CertificateSignRequest.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/CertificateSignRequest.java index 7e9cf4dd02..a45e433516 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/CertificateSignRequest.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/CertificateSignRequest.java @@ -75,7 +75,8 @@ public final class CertificateSignRequest { * @param extensions - CSR extensions */ private CertificateSignRequest(String subject, String scmID, String clusterID, - KeyPair keyPair, SecurityConfig config, Extensions extensions) { + KeyPair keyPair, SecurityConfig config, + Extensions extensions) { this.subject = subject; this.clusterID = clusterID; this.scmID = scmID; diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/package-info.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/package-info.java index 945adc934b..e7110e3125 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/package-info.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/security/x509/certificates/utils/package-info.java @@ -17,6 +17,6 @@ * */ /** - * Utils for Certificates. + Helpers for Certificates. */ -package org.apache.hadoop.hdds.security.x509.certificates.utils; \ No newline at end of file +package org.apache.hadoop.hdds.security.x509.certificates.utils; diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java index 972ef4417a..d1777e18a2 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/MockApprover.java @@ -41,14 +41,15 @@ public MockApprover(PKIProfile pkiProfile, SecurityConfig config) { @Override public CompletableFuture - approve(PKCS10CertificationRequest csr) { - return super.approve(csr); + inspectCSR(PKCS10CertificationRequest csr) { + return super.inspectCSR(csr); } @Override public X509CertificateHolder sign(SecurityConfig config, PrivateKey caPrivate, - X509CertificateHolder caCertificate, Date validFrom, - Date validTill, PKCS10CertificationRequest certificationRequest) + X509CertificateHolder caCertificate, + Date validFrom, Date validTill, + PKCS10CertificationRequest request) throws IOException, OperatorCreationException { return null; } diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java index 6b913717af..ba02ba7ab9 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultCAServer.java @@ -166,4 +166,4 @@ public void testRequestCertificate() throws IOException, assertNotNull(holder.get()); } -} \ No newline at end of file +} diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java index b5a6b35dc6..f892b8d05d 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/authority/TestDefaultProfile.java @@ -92,7 +92,8 @@ public void testisSupportedGeneralName() { assertTrue(defaultProfile.isSupportedGeneralName(GeneralName.iPAddress)); assertTrue(defaultProfile.isSupportedGeneralName(GeneralName.dNSName)); // Negative Tests - assertFalse(defaultProfile.isSupportedGeneralName(GeneralName.directoryName)); + assertFalse(defaultProfile.isSupportedGeneralName( + GeneralName.directoryName)); assertFalse(defaultProfile.isSupportedGeneralName(GeneralName.rfc822Name)); assertFalse(defaultProfile.isSupportedGeneralName(GeneralName.otherName)); } @@ -207,16 +208,16 @@ public void testInvalidExtensionsWithCA() throws SCMSecurityException { */ @Test - public void testInvalidExtensionsWithEmail() throws IOException, - OperatorCreationException { - Extensions emailExtension = getSANExtension(GeneralName.rfc822Name,"bilbo" + - "@apache.org", false); + public void testInvalidExtensionsWithEmail() + throws IOException, OperatorCreationException { + Extensions emailExtension = getSANExtension(GeneralName.rfc822Name, + "bilbo@apache.org", false); PKCS10CertificationRequest csr = getInvalidCSR(keyPair, emailExtension); assertFalse(testApprover.verfiyExtensions(csr)); - emailExtension = getSANExtension(GeneralName.rfc822Name,"bilbo" + + emailExtension = getSANExtension(GeneralName.rfc822Name, "bilbo" + "@apache.org", true); - csr = getInvalidCSR(keyPair, emailExtension); + csr = getInvalidCSR(keyPair, emailExtension); assertFalse(testApprover.verfiyExtensions(csr)); } @@ -230,7 +231,7 @@ public void testInvalidExtensionsWithEmail() throws IOException, public void testInvalidExtensionsWithURI() throws IOException, OperatorCreationException { Extensions oExtension = getSANExtension( - GeneralName.uniformResourceIdentifier,"s3g.ozone.org", false); + GeneralName.uniformResourceIdentifier, "s3g.ozone.org", false); PKCS10CertificationRequest csr = getInvalidCSR(keyPair, oExtension); assertFalse(testApprover.verfiyExtensions(csr)); oExtension = getSANExtension(GeneralName.uniformResourceIdentifier, @@ -274,7 +275,8 @@ public void testValidExtendedKeyUsage() throws IOException, PKCS10CertificationRequest csr = getInvalidCSR(keyPair, extendedExtension); assertTrue(testApprover.verfiyExtensions(csr)); - extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_serverAuth, false); + extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_serverAuth, + false); csr = getInvalidCSR(keyPair, extendedExtension); assertTrue(testApprover.verfiyExtensions(csr)); } @@ -293,7 +295,8 @@ public void testInValidExtendedKeyUsage() throws IOException, PKCS10CertificationRequest csr = getInvalidCSR(keyPair, extendedExtension); assertFalse(testApprover.verfiyExtensions(csr)); - extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_OCSPSigning, false); + extendedExtension = getKeyUsageExtension(KeyPurposeId.id_kp_OCSPSigning, + false); csr = getInvalidCSR(keyPair, extendedExtension); assertFalse(testApprover.verfiyExtensions(csr)); } @@ -306,11 +309,11 @@ public void testInValidExtendedKeyUsage() throws IOException, * rejects these invalid extensions, Hence the function name, by itself it * is a well formed CSR, but our PKI profile will treat it as invalid CSR. * - * @param keyPair - Key Pair. + * @param kPair - Key Pair. * @return CSR - PKCS10CertificationRequest * @throws OperatorCreationException - on Error. */ - private PKCS10CertificationRequest getInvalidCSR(KeyPair keyPair, + private PKCS10CertificationRequest getInvalidCSR(KeyPair kPair, Extensions extensions) throws OperatorCreationException { X500NameBuilder namebuilder = new X500NameBuilder(X500Name.getDefaultStyle()); @@ -355,7 +358,7 @@ private Extensions getKeyUsageExtension(KeyPurposeId purposeId, ExtendedKeyUsage extendedKeyUsage = new ExtendedKeyUsage(purposeId); ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator(); extensionsGenerator.addExtension( - Extension.extendedKeyUsage,critical, extendedKeyUsage); - return extensionsGenerator.generate(); + Extension.extendedKeyUsage, critical, extendedKeyUsage); + return extensionsGenerator.generate(); } -} \ No newline at end of file +} diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/package-info.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/package-info.java new file mode 100644 index 0000000000..4551f29ee2 --- /dev/null +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/utils/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + * + */ +/** + Tests for Certificate helpers. + */ +package org.apache.hadoop.hdds.security.x509.certificate.utils; + diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestCertificateSignRequest.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestCertificateSignRequest.java index a6c826bf1c..16b32147e6 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestCertificateSignRequest.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestCertificateSignRequest.java @@ -16,7 +16,7 @@ * limitations under the License. * */ -package org.apache.hadoop.hdds.security.x509.certificate.utils; +package org.apache.hadoop.hdds.security.x509.certificates; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.security.exception.SCMSecurityException; @@ -274,6 +274,7 @@ public void testCsrSerialization() throws NoSuchProviderException, .setClusterID(clusterID) .setKey(keyPair) .setConfiguration(conf); + PKCS10CertificationRequest csr = builder.build(); byte[] csrBytes = csr.getEncoded(); @@ -281,4 +282,4 @@ public void testCsrSerialization() throws NoSuchProviderException, PKCS10CertificationRequest dsCsr = new PKCS10CertificationRequest(csrBytes); Assert.assertEquals(csr, dsCsr); } -} \ No newline at end of file +} diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestRootCertificate.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestRootCertificate.java index 416cc61093..02d0078644 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestRootCertificate.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/security/x509/certificates/TestRootCertificate.java @@ -17,7 +17,7 @@ * */ -package org.apache.hadoop.hdds.security.x509.certificate.utils; +package org.apache.hadoop.hdds.security.x509.certificates; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.security.exception.SCMSecurityException; @@ -255,4 +255,4 @@ public void testInvalidParamFails() // Assert that we can create a certificate with all sane params. Assert.assertNotNull(builder.build()); } -} \ No newline at end of file +} diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java index 98491e121d..e7941fba2f 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java @@ -33,8 +33,8 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState; -import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.HddsServerUtil; +import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.block.BlockManager; import org.apache.hadoop.hdds.scm.block.BlockManagerImpl; import org.apache.hadoop.hdds.scm.block.DeletedBlockLogImpl; @@ -68,46 +68,49 @@ import org.apache.hadoop.hdds.scm.node.SCMNodeManager; import org.apache.hadoop.hdds.scm.node.StaleNodeHandler; import org.apache.hadoop.hdds.scm.pipeline.PipelineActionHandler; -import org.apache.hadoop.hdds.scm.pipeline.SCMPipelineManager; import org.apache.hadoop.hdds.scm.pipeline.PipelineManager; import org.apache.hadoop.hdds.scm.pipeline.PipelineReportHandler; +import org.apache.hadoop.hdds.scm.pipeline.SCMPipelineManager; +import org.apache.hadoop.hdds.security.x509.SecurityConfig; +import org.apache.hadoop.hdds.security.x509.certificate.authority.CertificateServer; +import org.apache.hadoop.hdds.security.x509.certificate.authority.DefaultCAServer; import org.apache.hadoop.hdds.server.ServiceRuntimeInfoImpl; import org.apache.hadoop.hdds.server.events.EventPublisher; import org.apache.hadoop.hdds.server.events.EventQueue; -import org.apache.hadoop.ozone.OzoneSecurityUtil; -import org.apache.hadoop.ozone.protocol.commands.RetriableDatanodeEventWatcher; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.metrics2.util.MBeans; import org.apache.hadoop.ozone.OzoneConfigKeys; +import org.apache.hadoop.ozone.OzoneSecurityUtil; import org.apache.hadoop.ozone.common.Storage.StorageState; import org.apache.hadoop.ozone.common.StorageInfo; import org.apache.hadoop.ozone.lease.LeaseManager; +import org.apache.hadoop.ozone.protocol.commands.RetriableDatanodeEventWatcher; +import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod; -import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.util.GenericOptionsParser; import org.apache.hadoop.util.JvmPauseMonitor; import org.apache.hadoop.util.StringUtils; -import static org.apache.hadoop.hdds.scm.ScmConfigKeys - .HDDS_SCM_WATCHER_TIMEOUT_DEFAULT; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.ObjectName; import java.io.IOException; import java.io.PrintStream; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; - +import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_SCM_WATCHER_TIMEOUT_DEFAULT; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ENABLED; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_SCM_KERBEROS_PRINCIPAL_KEY; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_SCM_KERBEROS_KEYTAB_FILE_KEY; @@ -192,14 +195,15 @@ public final class StorageContainerManager extends ServiceRuntimeInfoImpl private final ReplicationActivityStatus replicationStatus; private final SCMChillModeManager scmChillModeManager; + private final CertificateServer certificateServer; private JvmPauseMonitor jvmPauseMonitor; private final OzoneConfiguration configuration; /** - * Creates a new StorageContainerManager. Configuration will be updated - * with information on the - * actual listening addresses used for RPC servers. + * Creates a new StorageContainerManager. Configuration will be + * updated with information on the actual listening addresses used + * for RPC servers. * * @param conf configuration */ @@ -209,17 +213,29 @@ private StorageContainerManager(OzoneConfiguration conf) configuration = conf; StorageContainerManager.initMetrics(); initContainerReportCache(conf); - // Authenticate SCM if security is enabled - if (OzoneSecurityUtil.isSecurityEnabled(conf)) { - loginAsSCMUser(conf); - } - scmStorage = new SCMStorage(conf); if (scmStorage.getState() != StorageState.INITIALIZED) { throw new SCMException("SCM not initialized.", ResultCodes .SCM_NOT_INITIALIZED); } + // Authenticate SCM if security is enabled + if (OzoneSecurityUtil.isSecurityEnabled(conf)) { + loginAsSCMUser(conf); + certificateServer = initializeCertificateServer( + getScmStorage().getClusterID(), getScmStorage().getScmId()); + // TODO: Support Intermediary CAs in future. + certificateServer.init(new SecurityConfig(conf), + CertificateServer.CAType.SELF_SIGNED_CA); + } else { + // if no Security, we do not create a Certificate Server at all. + // This allows user to boot SCM without security temporarily + // and then come back and enable it without any impact. + certificateServer = null; + } + + + eventQueue = new EventQueue(); scmNodeManager = new SCMNodeManager( @@ -362,15 +378,33 @@ private void loginAsSCMUser(Configuration conf) LOG.info("SCM login successful."); } + + /** + * This function creates/initializes a certificate server as needed. + * This function is idempotent, so calling this again and again after the + * server is initialized is not a problem. + * + * @param clusterID - Cluster ID + * @param scmID - SCM ID + */ + private CertificateServer initializeCertificateServer(String clusterID, + String scmID) throws IOException { + // TODO: Support Certificate Server loading via Class Name loader. + // So it is easy to use different Certificate Servers if needed. + String subject = "scm@" + InetAddress.getLocalHost().getHostName(); + return new DefaultCAServer(subject, clusterID, scmID); + + } + /** * Builds a message for logging startup information about an RPC server. * * @param description RPC server description - * @param addr RPC server listening address + * @param addr RPC server listening address * @return server startup message */ public static String buildRpcServerStartMessage(String description, - InetSocketAddress addr) { + InetSocketAddress addr) { return addr != null ? String.format("%s is listening at %s", description, addr.toString()) : String.format("%s not started", description); @@ -445,7 +479,7 @@ private static void printUsage(PrintStream out) { /** * Create an SCM instance based on the supplied command-line arguments. - * + *

* This method is intended for unit tests only. It suppresses the * startup/shutdown message and skips registering Unix signal * handlers. @@ -465,8 +499,8 @@ public static StorageContainerManager createSCM( /** * Create an SCM instance based on the supplied command-line arguments. * - * @param args command-line arguments. - * @param conf HDDS configuration + * @param args command-line arguments. + * @param conf HDDS configuration * @param printBanner if true, then log a verbose startup message. * @return SCM instance * @throws IOException, AuthenticationException @@ -736,7 +770,7 @@ public void start() throws IOException { LOG.info(buildRpcServerStartMessage("ScmDatanodeProtocl RPC " + "server", getDatanodeProtocolServer().getDatanodeRpcAddress())); getDatanodeProtocolServer().start(); - if(getSecurityProtocolServer() != null) { + if (getSecurityProtocolServer() != null) { getSecurityProtocolServer().start(); } @@ -853,7 +887,7 @@ public void join() { getBlockProtocolServer().join(); getClientProtocolServer().join(); getDatanodeProtocolServer().join(); - if(getSecurityProtocolServer() != null) { + if (getSecurityProtocolServer() != null) { getSecurityProtocolServer().join(); } } catch (InterruptedException e) { @@ -987,7 +1021,7 @@ public boolean isInChillMode() { /** * Returns EventPublisher. */ - public EventPublisher getEventQueue(){ + public EventPublisher getEventQueue() { return eventQueue; } @@ -1007,7 +1041,7 @@ public double getCurrentContainerThreshold() { @Override public Map getContainerStateCount() { Map nodeStateCount = new HashMap<>(); - for (HddsProtos.LifeCycleState state: HddsProtos.LifeCycleState.values()) { + for (HddsProtos.LifeCycleState state : HddsProtos.LifeCycleState.values()) { nodeStateCount.put(state.toString(), containerManager.getContainers( state).size()); } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/package-info.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/package-info.java new file mode 100644 index 0000000000..b1023e824c --- /dev/null +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/package-info.java @@ -0,0 +1,20 @@ +/** + * 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. + */ +/** + * Ozone Client tests. + */ +package org.apache.hadoop.ozone.client;