blob: 6a413fca87ca013e36f4bdf8bf9e2b502f08cf9f [file]
/*
* 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.ranger.credentialapi;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.alias.CredentialShell;
import org.apache.hadoop.util.GenericOptionsParser;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.security.KeyStore;
import java.util.Arrays;
public class buildks {
public static void main(String[] args) {
buildks buildksOBJ = new buildks();
String command = null;
try {
if (args != null && args.length >= 3) {
command = args[0];
if (command != null && !command.trim().isEmpty()) {
if (command.equalsIgnoreCase("create")) {
buildksOBJ.createCredential(args);
} else if (command.equalsIgnoreCase("list")) {
buildksOBJ.listCredential(args);
} else {
System.out.println(command + " is not supported in current version of CredentialBuilder API.");
System.exit(1);
}
}
} else {
System.out.println("Invalid Command line argument.");
System.exit(1);
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
public static boolean isValidCreateCommand(String command, String alias, String valueOption, String credential, String providerOption, String providerPath, String storeTypeOption, String storeType) {
boolean isValid = true;
try {
if (command == null || !"create".equalsIgnoreCase(command.trim())) {
System.out.println("Invalid create phrase in credential creation command!!");
System.out.println("Expected:'create' Found:'" + command + "'");
displaySyntax("create", storeType);
return false;
}
if (alias == null || "".equalsIgnoreCase(alias.trim())) {
System.out.println("Invalid alias name phrase in credential creation command!!");
System.out.println("Found:'" + alias + "'");
displaySyntax("create", storeType);
return false;
}
if (valueOption == null || !"-value".equalsIgnoreCase(valueOption.trim())) {
System.out.println("Invalid value option in credential creation command!!");
System.out.println("Expected:'-value' Found:'" + valueOption + "'");
displaySyntax("create", storeType);
return false;
}
if (credential == null) {
System.out.println("Invalid credential value in credential creation command!!");
System.out.println("Found:" + credential);
displaySyntax("create", storeType);
return false;
}
if (providerOption == null || !"-provider".equalsIgnoreCase(providerOption.trim())) {
System.out.println("Invalid provider option in credential creation command!!");
System.out.println("Expected:'-provider' Found:'" + providerOption + "'");
displaySyntax("create", storeType);
return false;
}
if (providerPath == null || "".equalsIgnoreCase(providerPath.trim()) || ((!providerPath.startsWith("localjceks://") && !providerPath.startsWith("jceks://")) && (!providerPath.startsWith("localbcfks://") && !providerPath.startsWith("bcfks://")))) {
System.out.println("Invalid provider option in credential creation command!!");
System.out.println("Found:'" + providerPath + "'");
displaySyntax("create", storeType);
return false;
}
} catch (Exception ex) {
System.out.println("Invalid input or runtime error! Please try again.");
System.out.println("Input:" + command + " " + alias + " " + valueOption + " " + credential + " " + providerOption + " " + providerPath);
displaySyntax("create", storeType);
ex.printStackTrace();
return false;
}
return isValid;
}
public static boolean isValidListCommand(String command, String providerOption, String providerPath, String storeTpe) {
boolean isValid = true;
try {
if (command == null || !"list".equalsIgnoreCase(command.trim())) {
System.out.println("Invalid list phrase in credential get command!!");
System.out.println("Expected:'list' Found:'" + command + "'");
displaySyntax("list", storeTpe);
return false;
}
if (providerOption == null || !"-provider".equalsIgnoreCase(providerOption.trim())) {
System.out.println("Invalid provider option in credential get command!!");
System.out.println("Expected:'-provider' Found:'" + providerOption + "'");
displaySyntax("list", storeTpe);
return false;
}
if (providerPath == null || "".equalsIgnoreCase(providerPath.trim()) || ((!providerPath.startsWith("localjceks://") && !providerPath.startsWith("jceks://")) && (!providerPath.startsWith("localbcfks://") && !providerPath.startsWith("bcfks://")))) {
System.out.println("Invalid provider option in credential get command!!");
System.out.println("Found:'" + providerPath + "'");
displaySyntax("list", storeTpe);
return false;
}
} catch (Exception ex) {
System.out.println("Invalid input or runtime error! Please try again.");
System.out.println("Input:" + command + " " + providerOption + " " + providerPath);
displaySyntax("list", storeTpe);
ex.printStackTrace();
return false;
}
return isValid;
}
public static void displayCommand(String[] args) {
String debugOption = System.getProperty("debug");
if (debugOption != null && "TRUE".equalsIgnoreCase(debugOption)) {
StringBuilder tempBuffer = new StringBuilder("");
if (args != null && args.length > 0) {
for (String arg : args) {
tempBuffer.append(arg).append(" ");
}
System.out.println("Command to execute:[" + tempBuffer + "]");
}
}
}
public static void displaySyntax(String command, String storeType) {
if ("bcfks".equalsIgnoreCase(storeType)) {
if (command != null && command.trim().equalsIgnoreCase("create")) {
System.out.println("Correct syntax is:create <aliasname> -value <password> -provider <bcfks://file/filepath>");
System.out.println("sample command is:create myalias -value password123 -provider bcfks://file/tmp/ks/myks.bcfks");
}
if (command != null && command.trim().equalsIgnoreCase("list")) {
System.out.println("Correct syntax is:list -provider <bcfks://file/filepath>");
System.out.println("sample command is:list -provider bcfks://file/tmp/ks/myks.bcfks");
}
if (command != null && command.trim().equalsIgnoreCase("get")) {
System.out.println("Correct syntax is:get <aliasname> -provider <bcfks://file/filepath>");
System.out.println("sample command is:get myalias -provider bcfks://file/tmp/ks/myks.bcfks");
}
} else {
if (command != null && command.trim().equalsIgnoreCase("create")) {
System.out.println("Correct syntax is:create <aliasname> -value <password> -provider <jceks://file/filepath>");
System.out.println("sample command is:create myalias -value password123 -provider jceks://file/tmp/ks/myks.jceks");
}
if (command != null && command.trim().equalsIgnoreCase("list")) {
System.out.println("Correct syntax is:list -provider <jceks://file/filepath>");
System.out.println("sample command is:list -provider jceks://file/tmp/ks/myks.jceks");
}
if (command != null && command.trim().equalsIgnoreCase("get")) {
System.out.println("Correct syntax is:get <aliasname> -provider <jceks://file/filepath>");
System.out.println("sample command is:get myalias -provider jceks://file/tmp/ks/myks.jceks");
}
}
}
public static boolean isValidGetCommand(String command, String alias, String providerOption, String providerPath, String storeType) {
boolean isValid = true;
try {
if (command == null || !"get".equalsIgnoreCase(command.trim())) {
System.out.println("Invalid get phrase in credential get command!!");
System.out.println("Expected:'get' Found:'" + command + "'");
displaySyntax("get", storeType);
return false;
}
if (alias == null || "".equalsIgnoreCase(alias.trim())) {
System.out.println("Invalid alias name phrase in credential get command!!");
System.out.println("Found:'" + alias + "'");
displaySyntax("get", storeType);
return false;
}
if (providerOption == null || !"-provider".equalsIgnoreCase(providerOption.trim())) {
System.out.println("Invalid provider option in credential get command!!");
System.out.println("Expected:'-provider' Found:'" + providerOption + "'");
displaySyntax("get", storeType);
return false;
}
if (providerPath == null || "".equalsIgnoreCase(providerPath.trim()) || (!providerPath.startsWith("localjceks://") && !providerPath.startsWith("jceks://")) && (!providerPath.startsWith("localbcfks://") && !providerPath.startsWith("bcfks://"))) {
System.out.println("Invalid provider option in credential get command!!");
System.out.println("Found:'" + providerPath + "'");
displaySyntax("get", storeType);
return false;
}
} catch (Exception ex) {
System.out.println("Invalid input or runtime error! Please try again.");
System.out.println("Input:" + command + " " + alias + " " + providerOption + " " + providerPath);
displaySyntax("get", storeType);
ex.printStackTrace();
return false;
}
return isValid;
}
public int createCredential(String[] args) {
int returnCode = -1;
String command = null;
String alias = null;
String valueOption = null;
String credential = null;
String providerOption = null;
String providerPath = null;
String tempCredential = null;
String storeTypeOption = "storeType";
String storeType = KeyStore.getDefaultType();
try {
if (args != null && (args.length == 6 || args.length == 8)) {
command = args[0];
alias = args[1];
valueOption = args[2];
credential = args[3];
providerOption = args[4];
providerPath = args[5];
if (args.length == 8) {
storeTypeOption = args[6];
storeType = args[7];
}
if (!isValidCreateCommand(command, alias, valueOption, credential, providerOption, providerPath, storeTypeOption, storeType)) {
return returnCode;
}
deleteInvalidKeystore(providerPath);
tempCredential = CredentialReader.getDecryptedString(providerPath, alias, storeType);
} else {
return returnCode;
}
if (tempCredential == null) {
returnCode = createKeyStore(args);
} else {
try {
System.out.println("The alias " + alias + " already exists!! Will try to delete first.");
boolean isSilentMode = true;
String[] argsDelete = new String[4];
argsDelete[0] = "delete";
argsDelete[1] = alias;
argsDelete[2] = providerOption;
argsDelete[3] = providerPath;
returnCode = deleteCredential(argsDelete, isSilentMode);
if (returnCode == 0) {
returnCode = createKeyStore(args);
}
} catch (Exception ex) {
returnCode = -1;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return returnCode;
}
public int createKeyStore(String[] args) {
int returnCode = -1;
try {
String command = null;
String alias = null;
String valueOption = null;
String credential = null;
String providerOption = null;
String providerPath = null;
String storeTypeOption = "storeType";
String storeType = KeyStore.getDefaultType();
if (args != null && (args.length == 6 || args.length == 8)) {
command = args[0];
alias = args[1];
valueOption = args[2];
credential = args[3];
providerOption = args[4];
providerPath = args[5];
if (args.length == 8) {
storeTypeOption = args[6];
storeType = args[7];
}
if (!isValidCreateCommand(command, alias, valueOption, credential, providerOption, providerPath, storeTypeOption, storeType)) {
return returnCode;
}
displayCommand(args);
} else {
return returnCode;
}
CredentialShell cs = new CredentialShell();
Configuration conf = new Configuration();
//parse argument
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
cs.setConf(conf);
//get valid and remaining argument
String[] toolArgs = parser.getRemainingArgs();
//execute command in CredentialShell
// int i = 0;
//for(String s : toolArgs) {
//System.out.println("TooArgs [" + i + "] = [" + s + "]");
//i++;
// }
String[] finalArgs = Arrays.copyOfRange(toolArgs, 0, 6);
returnCode = cs.run(finalArgs);
//if response code is zero then success else failure
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return returnCode;
}
public int createCredentialFromUserInput() {
int returnCode = -1;
try {
String[] args = null;
String command = null;
String alias = null;
String valueOption = null;
String credential = null;
String providerOption = null;
String providerPath = null;
String storeTypeOption = null;
String storeType = null;
//below code can ask user to input if command line input fails
System.out.println("Enter Alias Name:");
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
alias = bufferRead.readLine();
System.out.println("Enter password:");
credential = bufferRead.readLine();
System.out.println("Enter .jceks output file name with path:");
providerPath = bufferRead.readLine();
if (providerPath != null && !providerPath.trim().isEmpty() && (!providerPath.startsWith("localjceks://file") && !providerPath.startsWith("jceks://file") && !providerPath.startsWith("localbcfks://file") && !providerPath.startsWith("bcfks://file"))) {
if (providerPath.startsWith("/")) {
providerPath = "jceks://file" + providerPath;
} else {
providerPath = "jceks://file/" + providerPath;
}
}
command = "create";
valueOption = "-value";
providerOption = "-provider";
if (!isValidCreateCommand(command, alias, valueOption, credential, providerOption, providerPath, storeTypeOption, storeType)) {
return returnCode;
}
args = new String[6];
args[0] = command;
args[1] = alias;
args[2] = valueOption;
args[3] = credential;
args[4] = providerOption;
args[5] = providerPath;
CredentialShell cs = new CredentialShell();
Configuration conf = new Configuration();
//parse argument
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
cs.setConf(conf);
//get valid and remaining argument
String[] toolArgs = parser.getRemainingArgs();
//execute command in CredentialShell
returnCode = cs.run(toolArgs);
//if response code is zero then success else failure
//System.out.println("Response Code:"+returnCode);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return returnCode;
}
public int listCredential(String[] args) {
int returnCode = -1;
String command = null;
String providerOption = null;
String providerPath = null;
String storeType = KeyStore.getDefaultType();
try {
if (args != null && args.length == 3) {
command = args[0];
providerOption = args[1];
providerPath = args[2];
if (!isValidListCommand(command, providerOption, providerPath, storeType)) {
return returnCode;
}
//display command which need to be executed or entered
displayCommand(args);
} else {
return returnCode;
}
CredentialShell cs = new CredentialShell();
Configuration conf = new Configuration();
//parse argument
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
cs.setConf(conf);
//get valid and remaining argument
String[] toolArgs = parser.getRemainingArgs();
//execute command in CredentialShell
returnCode = cs.run(toolArgs);
//if response code is zero then success else failure
//System.out.println("Response Code:"+returnCode);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return returnCode;
}
public int deleteCredential(String[] args, boolean isSilentMode) {
int returnCode = -1;
try {
if (args != null && args.length == 4) {
// for non-interactive, insert argument "-f" if needed
if (isSilentMode && isCredentialShellInteractiveEnabled()) {
String[] updatedArgs = new String[5];
updatedArgs[0] = args[0];
updatedArgs[1] = args[1];
updatedArgs[2] = "-f";
updatedArgs[3] = args[2];
updatedArgs[4] = args[3];
args = updatedArgs;
}
//display command which need to be executed or entered
displayCommand(args);
} else {
return returnCode;
}
CredentialShell cs = new CredentialShell();
Configuration conf = new Configuration();
//parse argument
GenericOptionsParser parser = new GenericOptionsParser(conf, args);
//set the configuration back, so that Tool can configure itself
cs.setConf(conf);
//get valid and remaining argument
String[] toolArgs = parser.getRemainingArgs();
//execute command in CredentialShell
// String[] finalArgs = Arrays.copyOfRange(toolArgs, 0, 6);
returnCode = cs.run(toolArgs);
//if response code is zero then success else failure
//System.out.println("Response Code:"+returnCode);
} catch (IOException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return returnCode;
}
public String getCredential(String[] args) {
String command = null;
String alias = null;
String providerOption = null;
String providerPath = null;
String tempCredential = null;
String storeType = KeyStore.getDefaultType();
try {
if (args != null && args.length == 4) {
command = args[0];
alias = args[1];
providerOption = args[2];
providerPath = args[3];
if (!isValidGetCommand(command, alias, providerOption, providerPath, storeType)) {
displaySyntax("get", storeType);
} else {
tempCredential = CredentialReader.getDecryptedString(providerPath, alias, storeType);
}
} else {
displaySyntax("get", storeType);
}
if (tempCredential == null) {
System.out.println("Alias " + alias + " does not exist!!");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return tempCredential;
}
public void deleteInvalidKeystore(String providerPath) {
if (providerPath != null) {
String keystore = null;
if (providerPath.startsWith("jceks://file")) {
keystore = providerPath.replace("jceks://file", "");
} else if (providerPath.startsWith("localjceks://file")) {
keystore = providerPath.replace("jceks://file", "");
} else if (providerPath.startsWith("bcfks://file")) {
keystore = providerPath.replace("bcfks://file", "");
} else if (providerPath.startsWith("localbcfks://file")) {
keystore = providerPath.replace("bcfks://file", "");
} else {
keystore = providerPath;
}
if (keystore != null && !keystore.isEmpty()) {
File file = new File(keystore);
if (file != null && file.exists() && file.length() == 0) {
System.out.println("Provider file '" + keystore + "' is in invalid state or corrupt!! will try to delete first.");
file.delete();
file = null;
}
}
}
}
private static boolean isCredentialShellInteractiveEnabled() {
boolean ret = false;
String fieldName = "interactive";
CredentialShell cs = new CredentialShell();
try {
Field interactiveField = cs.getClass().getDeclaredField(fieldName);
if (interactiveField != null) {
interactiveField.setAccessible(true);
ret = interactiveField.getBoolean(cs);
System.out.println("FOUND value of [" + fieldName + "] field in the Class [" + cs.getClass().getName() + "] = [" + ret + "]");
}
} catch (Throwable e) {
System.out.println("Unable to find the value of [" + fieldName + "] field in the Class [" + cs.getClass().getName() + "]. Skiping -f option");
e.printStackTrace();
ret = false;
}
return ret;
}
}