Java tutorial
/* * 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.slider.server.services.security; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.RandomStringUtils; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.RawLocalFileSystem; import org.apache.hadoop.fs.permission.FsAction; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.slider.common.SliderKeys; import org.apache.slider.common.SliderXmlConfKeys; import org.apache.slider.core.conf.MapOperations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; //import java.nio.file.Files; //import java.nio.file.Path; //import java.nio.file.Paths; //import java.nio.file.attribute.PosixFilePermission; //import java.nio.file.attribute.PosixFilePermissions; /** * */ public class SecurityUtils { private static final Logger LOG = LoggerFactory.getLogger(SecurityUtils.class); private static String CA_CONFIG_CONTENTS = "[ ca ]\n" + "default_ca = CA_CLIENT\n" + "[ CA_CLIENT ]\n" + "dir\t\t = ${SEC_DIR}/db\n" + "certs = $dir/certs\n" + "new_certs_dir = $dir/newcerts\n" + "\n" + "database = $dir/index.txt\n" + "serial = $dir/serial\n" + "default_days = 365 \n" + "\n" + "default_crl_days = 7 \n" + "default_md = md5 \n" + "\n" + "policy = policy_anything \n" + "\n" + "[ policy_anything ]\n" + "countryName = optional\n" + "stateOrProvinceName = optional \n" + "localityName = optional\n" + "organizationName = optional\n" + "organizationalUnitName = optional\n" + "commonName = optional \n" + "emailAddress = optional \n" + "\n" + "[ jdk7_ca ]\n" + "subjectKeyIdentifier = hash\n" + "authorityKeyIdentifier = keyid:always,issuer:always\n" + "basicConstraints = CA:true"; private static final String PASS_TOKEN = "pass:"; private static String keystorePass; private static String securityDir; public static void logOpenSslExitCode(String command, int exitCode) { if (exitCode == 0) { LOG.info(getOpenSslCommandResult(command, exitCode)); } else { LOG.warn(getOpenSslCommandResult(command, exitCode)); } } public static String hideOpenSslPassword(String command) { int start = command.indexOf(PASS_TOKEN) + PASS_TOKEN.length(); CharSequence cs = command.subSequence(start, command.indexOf(" ", start)); return command.replace(cs, "****"); } public static String getOpenSslCommandResult(String command, int exitCode) { return new StringBuilder().append("Command ").append(hideOpenSslPassword(command)) .append(" was finished with exit code: ").append(exitCode).append(" - ") .append(getOpenSslExitCodeDescription(exitCode)).toString(); } private static String getOpenSslExitCodeDescription(int exitCode) { switch (exitCode) { case 0: { return "the operation was completed successfully."; } case 1: { return "an error occurred parsing the command options."; } case 2: { return "one of the input files could not be read."; } case 3: { return "an error occurred creating the PKCS#7 file or when reading the MIME message."; } case 4: { return "an error occurred decrypting or verifying the message."; } case 5: { return "the message was verified correctly but an error occurred writing out the signers certificates."; } default: return "unsupported code"; } } public static void writeCaConfigFile(String path) throws IOException { String contents = CA_CONFIG_CONTENTS.replace("${SEC_DIR}", path); FileUtils.writeStringToFile(new File(path, "ca.config"), contents); } public static String getKeystorePass() { return keystorePass; } public static String getSecurityDir() { return securityDir; } public static void initializeSecurityParameters(MapOperations configMap) { initializeSecurityParameters(configMap, false); } public static void initializeSecurityParameters(MapOperations configMap, boolean persistPassword) { String keyStoreLocation = configMap.getOption(SliderXmlConfKeys.KEY_KEYSTORE_LOCATION, getDefaultKeystoreLocation()); File secDirFile = new File(keyStoreLocation).getParentFile(); if (!secDirFile.exists()) { // create entire required directory structure File dbDir = new File(secDirFile, "db"); File newCertsDir = new File(dbDir, "newcerts"); newCertsDir.mkdirs(); try { RawLocalFileSystem fileSystem = new RawLocalFileSystem(); FsPermission permissions = new FsPermission(FsAction.ALL, FsAction.NONE, FsAction.NONE); fileSystem.setPermission(new Path(dbDir.getAbsolutePath()), permissions); fileSystem.setPermission(new Path(dbDir.getAbsolutePath()), permissions); fileSystem.setPermission(new Path(newCertsDir.getAbsolutePath()), permissions); File indexFile = new File(dbDir, "index.txt"); indexFile.createNewFile(); SecurityUtils.writeCaConfigFile(secDirFile.getAbsolutePath().replace('\\', '/')); } catch (IOException e) { LOG.error("Unable to create SSL configuration directories/files", e); } // need to create the password } keystorePass = getKeystorePassword(secDirFile, persistPassword); securityDir = secDirFile.getAbsolutePath(); } private static String getKeystorePassword(File secDirFile, boolean persistPassword) { File passFile = new File(secDirFile, SliderKeys.CRT_PASS_FILE_NAME); String password = null; if (!passFile.exists()) { LOG.info("Generating keystore password"); password = RandomStringUtils.randomAlphanumeric(Integer.valueOf(SliderKeys.PASS_LEN)); if (persistPassword) { try { FileUtils.writeStringToFile(passFile, password); passFile.setWritable(true); passFile.setReadable(true); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("Error creating certificate password file"); } } } else { LOG.info("Reading password from existing file"); try { password = FileUtils.readFileToString(passFile); password = password.replaceAll("\\p{Cntrl}", ""); } catch (IOException e) { e.printStackTrace(); } } return password; } private static String getDefaultKeystoreLocation() { File workDir = null; try { workDir = new File( FileUtils.getTempDirectory().getAbsolutePath() + "/sec" + System.currentTimeMillis()); if (!workDir.mkdirs()) { throw new IOException("Unable to create temporary security directory"); } } catch (IOException e) { LOG.warn("Unable to create security directory"); return null; } return new StringBuilder().append(workDir.getAbsolutePath()).append(File.separator) .append(SliderKeys.SECURITY_DIR).append(File.separator).append(SliderKeys.KEYSTORE_FILE_NAME) .toString(); } }