
oracle.kv.impl.util.PwdfileCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oracle-nosql-server Show documentation
Show all versions of oracle-nosql-server Show documentation
NoSQL Database Server - supplies build and runtime support for the server (store) side of the Oracle NoSQL Database.
The newest version!
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.impl.util;
import static oracle.kv.impl.security.PasswordManager.FILE_STORE_MANAGER_CLASS;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import oracle.kv.impl.security.PasswordManager;
import oracle.kv.impl.security.PasswordStore;
import oracle.kv.impl.security.PasswordStore.LoginId;
import oracle.kv.impl.security.PasswordStoreException;
import oracle.kv.impl.security.util.PasswordReader;
import oracle.kv.impl.security.util.SecurityUtils;
import oracle.kv.util.shell.CommandWithSubs;
import oracle.kv.util.shell.Shell;
import oracle.kv.util.shell.ShellException;
/**
* Security shell implementation of the pwdfile main command.
*/
class PwdfileCommand extends CommandWithSubs {
private enum Action {
SET, DELETE, LIST;
}
PwdfileCommand() {
super(Arrays.asList(new PwdfileCreate(),
new PwdfileSecret(),
new PwdfileLogin()), /* currently hidden */
"pwdfile", 4, 1);
}
@Override
public String getCommandOverview() {
return "The pwdfile command allows creation and modification of " +
"an Oracle NoSQL pwdfile.";
}
/**
* PwdfileCreate - implements the "pwdfile create" subcommand.
*/
private static final class PwdfileCreate extends SubCommand {
private static final String CREATE_COMMAND_NAME = "create";
private static final String CREATE_COMMAND_DESC =
"Creates a new password file.";
private static final String CREATE_COMMAND_ARGS =
"-file ";
private PwdfileCreate() {
super(CREATE_COMMAND_NAME, 3);
}
@Override
public String execute(String[] args, Shell shell)
throws ShellException {
Shell.checkHelp(args, this);
String file = null;
for (int i = 1; i < args.length; i++) {
final String arg = args[i];
if ("-file".equals(arg)) {
file = Shell.nextArg(args, i++, this);
} else {
shell.unknownArgument(arg, this);
}
}
if (file == null) {
shell.requiredArg("-file", this);
}
return doCreate(file, shell);
}
/**
* Performs the actual work for the pwdfile create command.
* @param file the name of the file that will hold the password store
* @param shell the Shell instance in which we are running
*/
private String doCreate(String file, Shell shell)
throws ShellException {
try {
final PasswordManager pwdMgr =
PasswordManager.load(FILE_STORE_MANAGER_CLASS);
final File pwdfileLoc = new File(file);
final PasswordStore pwdfile = pwdMgr.getStoreHandle(pwdfileLoc);
if (pwdfile.exists()) {
return "A pwdfile already exists at that location";
}
/* We currently do not support password-protected files */
final char[] pwd = null;
pwdfile.create(pwd);
return "Created";
} catch (PasswordStoreException pwse) {
throw new ShellException(
"PasswordStore error: " + pwse.getMessage(), pwse);
} catch (Exception e) {
throw new ShellException(
"Unexpected error: " + e.getMessage(), e);
}
}
@Override
public String getCommandSyntax() {
return "pwdfile create " + CREATE_COMMAND_ARGS;
}
@Override
public String getCommandDescription() {
return CREATE_COMMAND_DESC;
}
}
/**
* Implements the "pwdfile secret" subcommand.
*/
private static final class PwdfileSecret extends SubCommand {
private static final String SECRET_COMMAND_NAME = "secret";
private static final String SECRET_COMMAND_DESC =
"Manipulate secrets in a password file.";
private static final String SECRET_COMMAND_ARGS =
"-file " +
"{-set -alias [ -secret ]} | " +
"{-delete -alias } | " +
"{-list}";
private PwdfileSecret() {
super(SECRET_COMMAND_NAME, 3);
}
@Override
public String execute(String[] args, Shell shell)
throws ShellException {
String file = null;
String alias = null;
String secret = null;
final EnumSet actions = EnumSet.noneOf(Action.class);
for (int i = 1; i < args.length; i++) {
final String arg = args[i];
if ("-file".equals(arg)) {
file = Shell.nextArg(args, i++, this);
} else if ("-alias".equals(arg)) {
alias = Shell.nextArg(args, i++, this);
} else if ("-set".equals(arg)) {
actions.add(Action.SET);
} else if ("-list".equals(arg)) {
actions.add(Action.LIST);
} else if ("-delete".equals(arg)) {
actions.add(Action.DELETE);
} else if ("-secret".equals(arg)) {
secret = Shell.nextArg(args, i++, this);
} else {
shell.unknownArgument(arg, this);
}
}
if (file == null || actions.size() != 1) {
shell.badArgCount(this);
}
final Action action = actions.iterator().next();
if ((action == Action.SET || action == Action.DELETE) &&
alias == null) {
shell.badArgCount(this);
}
if (action == Action.LIST && alias != null) {
shell.badArgCount(this);
}
return doSecret(file, action, alias, secret, shell);
}
@Override
public String getCommandSyntax() {
return "pwdfile secret " + SECRET_COMMAND_ARGS;
}
@Override
public String getCommandDescription() {
return SECRET_COMMAND_DESC;
}
/**
* Performs the work for the command.
*/
private String doSecret(String file,
Action action,
String alias,
String secretArg,
Shell shell)
throws ShellException {
try {
final PasswordStore pwdfile = openStore(new File(file), shell);
final PasswordReader pwdReader =
((SecurityShell) shell).getPasswordReader();
final String retString;
if (action == Action.SET) {
char[] secret;
char[] verifySecret;
if (secretArg != null) {
secret = secretArg.toCharArray();
verifySecret = secret;
} else {
secret = pwdReader.readPassword(
"Enter the secret value to store: ");
verifySecret = pwdReader.readPassword(
"Re-enter the secret value for verification: ");
}
if (SecurityUtils.passwordsMatch(secret, verifySecret)) {
if (pwdfile.setSecret(alias, secret)) {
retString = "Secret updated";
} else {
retString = "Secret created";
}
pwdfile.save();
} else {
retString = "The passwords do not match";
}
} else if (action == Action.DELETE) {
if (pwdfile.deleteSecret(alias)) {
pwdfile.save();
retString = "Secret deleted";
} else {
retString = "Secret did not exist";
}
} else if (action == Action.LIST) {
final Collection secretAliases =
pwdfile.getSecretAliases();
if (secretAliases.size() == 0) {
retString = "The pwdfile contains no secrets";
} else {
final StringBuilder sb = new StringBuilder();
sb.append("The pwdfile contains the following secrets:");
for (String s : secretAliases) {
sb.append(eol);
sb.append(" ");
sb.append(s);
}
retString = sb.toString();
}
}
else {
throw new AssertionError("Unhandled action " + action);
}
return retString;
} catch (ShellException se) {
throw se;
} catch (PasswordStoreException pwse) {
throw new ShellException(
"PasswordStore error: " + pwse.getMessage(), pwse);
} catch (Exception e) {
throw new ShellException(
"Unknown error: " + e.getMessage(), e);
}
}
}
/**
* Implements the "pwdfile login" subcommand.
*/
private static final class PwdfileLogin extends SubCommand {
private static final String LOGIN_COMMAND_NAME = "login";
private static final String LOGIN_COMMAND_DESC =
"Manipulate logins in an Oracle Pwdfile.";
private static final String LOGIN_COMMAND_ARGS =
"-file -set [-secret ] |-delete " +
"-database -user ";
private PwdfileLogin() {
super(LOGIN_COMMAND_NAME, 3);
}
@Override
public String execute(String[] args, Shell shell)
throws ShellException {
String file = null;
String user = null;
String db = null;
String secret = null;
final EnumSet actions = EnumSet.noneOf(Action.class);
for (int i = 1; i < args.length; i++) {
final String arg = args[i];
if ("-file".equals(arg)) {
file = Shell.nextArg(args, i++, this);
} else if ("-database".equals(arg) || "-db".equals(arg)) {
db = Shell.nextArg(args, i++, this);
} else if ("-user".equals(arg)) {
user = Shell.nextArg(args, i++, this);
} else if ("-set".equals(arg)) {
actions.add(Action.SET);
} else if ("-list".equals(arg)) {
actions.add(Action.LIST);
} else if ("-delete".equals(arg)) {
actions.add(Action.DELETE);
} else if ("-secret".equals(arg)) {
secret = Shell.nextArg(args, i++, this);
} else {
shell.unknownArgument(arg, this);
}
}
if (file == null || actions.size() != 1) {
shell.badArgCount(this);
}
final Action action = actions.iterator().next();
if ((action == Action.SET || action == Action.DELETE) &&
(db == null)) {
shell.badArgCount(this);
}
if ((action == Action.SET) &&
(user == null)) {
shell.badArgCount(this);
}
if (action == Action.LIST && (db != null || user != null)) {
shell.badArgCount(this);
}
return doLogin(file, action, user, db, secret, shell);
}
@Override
public String getCommandSyntax() {
return "pwdfile login " + LOGIN_COMMAND_ARGS;
}
@Override
public String getCommandDescription() {
return LOGIN_COMMAND_DESC;
}
/* Not visible currently */
@Override
protected boolean isHidden() {
return true;
}
private String doLogin(String file,
Action action,
String user,
String db,
String secretArg,
Shell shell)
throws ShellException {
try {
final PasswordStore pwdfile = openStore(new File(file), shell);
final PasswordReader pwdReader =
((SecurityShell) shell).getPasswordReader();
final LoginId loginId = new LoginId(db, user);
final String retString;
if (action == Action.SET) {
char[] secret;
char[] verifySecret;
if (secretArg != null) {
secret = secretArg.toCharArray();
verifySecret = secret;
} else {
secret = pwdReader.readPassword(
"Enter the secret value to store: ");
verifySecret = pwdReader.readPassword(
"Re-enter the secret value for verification: ");
}
if (SecurityUtils.passwordsMatch(secret, verifySecret)) {
if (pwdfile.setLogin(loginId, secret)) {
retString = "Login updated";
} else {
retString = "Login created";
}
pwdfile.save();
} else {
retString = "The passwords do not match";
}
} else if (action == Action.DELETE) {
/*
* If the user specified a user (not required), check
* that that the user in the entry matches the specified
* user before deleting.
*/
final LoginId pwdfileLoginId =
pwdfile.getLoginId(loginId.getDatabase());
if (pwdfileLoginId != null) {
if (loginId.getUser() == null ||
loginId.getUser().equals(
pwdfileLoginId.getUser())) {
pwdfile.deleteLogin(loginId.getDatabase());
pwdfile.save();
retString = "Login deleted";
} else {
retString = "The specified user does not match " +
"the pwdfile entry";
}
} else {
retString = "Login did not exist";
}
} else if (action == Action.LIST) {
final Collection logins = pwdfile.getLogins();
if (logins.size() == 0) {
retString = "The pwdfile contains no logins";
} else {
final StringBuilder sb = new StringBuilder();
sb.append("The pwdfile contains the following logins:");
for (LoginId lid : logins) {
sb.append(eol);
sb.append(" ");
sb.append(lid.getDatabase());
sb.append(" as ");
sb.append(lid.getUser());
}
retString = sb.toString();
}
}
else {
throw new AssertionError("Unhandled action " + action);
}
return retString;
} catch (ShellException se) {
throw se;
} catch (PasswordStoreException pwse) {
throw new ShellException(
"PasswordStore error: " + pwse.getMessage(), pwse);
} catch (Exception e) {
throw new ShellException(
"Unknown error: " + e.getMessage(), e);
}
}
}
private static PasswordStore openStore(
File pwdfileLoc,
@SuppressWarnings("unused") Shell shell)
throws Exception {
final PasswordManager pwdMgr =
PasswordManager.load(FILE_STORE_MANAGER_CLASS);
final PasswordStore pwdfile = pwdMgr.getStoreHandle(pwdfileLoc);
if (!pwdfile.exists()) {
throw new ShellException("The store does not yet exist");
}
pwdfile.open(null);
return pwdfile;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy