| /* |
| * 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; |
| } |
| } |