| /* |
| * 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.atlas.util; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.security.alias.CredentialProvider; |
| import org.apache.hadoop.security.alias.CredentialProviderFactory; |
| import org.apache.hadoop.security.alias.JavaKeyStoreProvider; |
| |
| import java.io.Console; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Arrays; |
| |
| import static org.apache.atlas.security.SecurityProperties.KEYSTORE_PASSWORD_KEY; |
| import static org.apache.atlas.security.SecurityProperties.SERVER_CERT_PASSWORD_KEY; |
| import static org.apache.atlas.security.SecurityProperties.TRUSTSTORE_PASSWORD_KEY; |
| |
| /** |
| * 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[]{KEYSTORE_PASSWORD_KEY, TRUSTSTORE_PASSWORD_KEY, 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); |
| |
| if(provider != null) { |
| 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:"); |
| |
| if (providerPath != null) { |
| Configuration conf = new Configuration(false); |
| conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, providerPath); |
| return CredentialProviderFactory.getProviders(conf).get(0); |
| } |
| |
| return null; |
| } |
| } |