mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-10 14:11:59 +00:00
GP-3295: Add askPassword to GhidraScript API.
This commit is contained in:
parent
92e77ff5cb
commit
899772973a
@ -23,6 +23,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainFolder;
|
||||
import ghidra.program.model.address.Address;
|
||||
@ -117,6 +118,10 @@ public class AskScript extends GhidraScript {
|
||||
boolean yesOrNo = askYesNo("yes or no", "is this a yes/no question?");
|
||||
println("Yes or No? " + yesOrNo);
|
||||
|
||||
try (Password password = askPassword("Password", null)) {
|
||||
println("Password has %d characters".formatted(password.getPasswordChars().length));
|
||||
// try-with-resources ensures buffer is zeroed out before garbage collected
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
Msg.warn(this, "Error during headless processing: " + iae.toString());
|
||||
|
@ -22,6 +22,7 @@ import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.PasswordDialog;
|
||||
import docking.widgets.dialogs.MultiLineMessageDialog;
|
||||
import docking.widgets.filechooser.GhidraFileChooser;
|
||||
import docking.widgets.filechooser.GhidraFileChooserMode;
|
||||
@ -47,6 +48,7 @@ import ghidra.framework.Application;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.cmd.BackgroundCommand;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import ghidra.framework.main.DataTreeDialog;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.OptionType;
|
||||
@ -2977,6 +2979,61 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Password}, using the String input parameters for guidance. This method can
|
||||
* only be used in headed mode.
|
||||
* <p>
|
||||
* In the GUI environment, this method displays a password popup dialog that prompts the user
|
||||
* for a secret, usually a password or other credential. There is no pre-population of the
|
||||
* input. If the user cancels the dialog, it is immediately disposed, and any input to that
|
||||
* dialog is cleared from memory. If the user completes the dialog, then the secret is returned
|
||||
* in a wrapped buffer. The buffer can be cleared by calling {@link Secret#close()}; however, it
|
||||
* is meant to be used in a {@code try-with-resources} block. The pattern does not guarantee
|
||||
* protection of the secret, but it will help you avoid some typical pitfalls:
|
||||
*
|
||||
* <pre>
|
||||
* String user = askString("Login", "Username:");
|
||||
* Project project;
|
||||
* try (Secret secret = askSecret("Login", "Password:")) {
|
||||
* if (secret == null) {
|
||||
* return; // User cancelled
|
||||
* }
|
||||
* project = doLoginAndOpenProject(user, secret.buffer());
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* The buffer will be zero-filled upon leaving the {@code try-with-resources} block. If, in the
|
||||
* sample, the {@code doLoginAndOpenProject} method or any part of its implementation needs to
|
||||
* retain the secret, it must make a copy. It is then the implementation's responsibility to
|
||||
* protect its copy.
|
||||
*
|
||||
* @param title the title of the dialog
|
||||
* @param serverType the server type, i.e., its protocol or URL schema
|
||||
* @param serverName the host name of the server
|
||||
* @param prompt the prompt to the left of the input field, or null to display "Password:"
|
||||
* @return the password
|
||||
* @throws CancelledException if the user cancels
|
||||
* @throws ImproperUseException if in headless mode
|
||||
*/
|
||||
public Password askPassword(String title, String prompt) throws CancelledException {
|
||||
if (isRunningHeadless()) {
|
||||
throw new ImproperUseException(
|
||||
"The askPassword() method can only be used when running headed Ghidra.");
|
||||
}
|
||||
PasswordDialog dialog =
|
||||
new PasswordDialog(title, null, null, prompt, null, null);
|
||||
try {
|
||||
state.getTool().showDialog(dialog);
|
||||
if (!dialog.okWasPressed()) {
|
||||
throw new CancelledException("User cancelled password prompt.");
|
||||
}
|
||||
return Password.wrap(dialog.getPassword());
|
||||
}
|
||||
finally {
|
||||
dialog.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a choice from a string.
|
||||
*
|
||||
|
@ -18,6 +18,7 @@ package ghidra.formats.gfilesystem.crypto;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* Caches passwords used to unlock a file.
|
||||
@ -34,10 +35,10 @@ public class CachedPasswordProvider implements PasswordProvider {
|
||||
* Adds a password / file combo to the cache.
|
||||
*
|
||||
* @param fsrl {@link FSRL} file
|
||||
* @param password password to unlock the file. Specified PasswordValue is
|
||||
* @param password password to unlock the file. Specified {@link Password} is
|
||||
* only copied, clearing is still callers responsibility
|
||||
*/
|
||||
public synchronized void addPassword(FSRL fsrl, PasswordValue password) {
|
||||
public synchronized void addPassword(FSRL fsrl, Password password) {
|
||||
CryptoRec rec = new CryptoRec();
|
||||
rec.fsrl = fsrl;
|
||||
rec.value = password.clone();
|
||||
@ -95,7 +96,7 @@ public class CachedPasswordProvider implements PasswordProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt,
|
||||
public synchronized Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt,
|
||||
Session session) {
|
||||
Set<CryptoRec> uniqueFoundRecs = new LinkedHashSet<>();
|
||||
uniqueFoundRecs.addAll(values.getOrDefault(fsrl.toString(), Collections.emptyList()));
|
||||
@ -105,7 +106,7 @@ public class CachedPasswordProvider implements PasswordProvider {
|
||||
uniqueFoundRecs.addAll(values.getOrDefault(fsrl.getMD5(), Collections.emptyList()));
|
||||
}
|
||||
|
||||
List<PasswordValue> results = new ArrayList<>();
|
||||
List<Password> results = new ArrayList<>();
|
||||
for (CryptoRec rec : uniqueFoundRecs) {
|
||||
results.add(rec.value);
|
||||
}
|
||||
@ -117,13 +118,13 @@ public class CachedPasswordProvider implements PasswordProvider {
|
||||
|
||||
private static class CryptoRec {
|
||||
FSRL fsrl;
|
||||
PasswordValue value;
|
||||
Password value;
|
||||
}
|
||||
|
||||
private class CloningPasswordIterator implements Iterator<PasswordValue> {
|
||||
Iterator<PasswordValue> delegate;
|
||||
private class CloningPasswordIterator implements Iterator<Password> {
|
||||
Iterator<Password> delegate;
|
||||
|
||||
CloningPasswordIterator(Iterator<PasswordValue> it) {
|
||||
CloningPasswordIterator(Iterator<Password> it) {
|
||||
this.delegate = it;
|
||||
}
|
||||
|
||||
@ -133,8 +134,8 @@ public class CachedPasswordProvider implements PasswordProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordValue next() {
|
||||
PasswordValue result = delegate.next();
|
||||
public Password next() {
|
||||
Password result = delegate.next();
|
||||
return result.clone();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import java.util.*;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import ghidra.util.Msg;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
@ -51,7 +52,7 @@ public class CmdLinePasswordProvider implements PasswordProvider {
|
||||
public static final String CMDLINE_PASSWORD_PROVIDER_PROPERTY_NAME = "filesystem.passwords";
|
||||
|
||||
@Override
|
||||
public Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt, Session session) {
|
||||
public Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt, Session session) {
|
||||
String propertyValue = System.getProperty(CMDLINE_PASSWORD_PROVIDER_PROPERTY_NAME);
|
||||
if (propertyValue == null) {
|
||||
return Collections.emptyIterator();
|
||||
@ -60,8 +61,8 @@ public class CmdLinePasswordProvider implements PasswordProvider {
|
||||
return load(passwordFile, fsrl).iterator();
|
||||
}
|
||||
|
||||
private List<PasswordValue> load(File f, FSRL fsrl) {
|
||||
List<PasswordValue> result = new ArrayList<>();
|
||||
private List<Password> load(File f, FSRL fsrl) {
|
||||
List<Password> result = new ArrayList<>();
|
||||
try {
|
||||
for (String s : FileUtilities.getLines(f)) {
|
||||
String[] fields = s.split("\t");
|
||||
@ -73,7 +74,7 @@ public class CmdLinePasswordProvider implements PasswordProvider {
|
||||
|
||||
if (fileIdStr == null) {
|
||||
// no file identifier string, always matches
|
||||
result.add(PasswordValue.wrap(password.toCharArray()));
|
||||
result.add(Password.wrap(password.toCharArray()));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ public class CmdLinePasswordProvider implements PasswordProvider {
|
||||
FSRL currentFSRL = FSRL.fromString(fileIdStr);
|
||||
// was a fsrl string, only test as fsrl
|
||||
if (currentFSRL.isEquivalent(fsrl)) {
|
||||
result.add(PasswordValue.wrap(password.toCharArray()));
|
||||
result.add(Password.wrap(password.toCharArray()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -93,14 +94,14 @@ public class CmdLinePasswordProvider implements PasswordProvider {
|
||||
if (!nameOnly.equals(fileIdStr)) {
|
||||
// was a path str, only test against path component
|
||||
if (fileIdStr.equals(fsrl.getPath())) {
|
||||
result.add(PasswordValue.wrap(password.toCharArray()));
|
||||
result.add(Password.wrap(password.toCharArray()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// was a plain name, only test against name component
|
||||
if (nameOnly.equals(fsrl.getName())) {
|
||||
result.add(PasswordValue.wrap(password.toCharArray()));
|
||||
result.add(Password.wrap(password.toCharArray()));
|
||||
continue;
|
||||
}
|
||||
// no matches, try next line
|
||||
|
@ -18,6 +18,7 @@ package ghidra.formats.gfilesystem.crypto;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* A stub implementation of CryptoSession that relies on a parent instance.
|
||||
@ -41,12 +42,12 @@ public class CryptoProviderSessionChildImpl implements CryptoSession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt) {
|
||||
public Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt) {
|
||||
return parentSession.getPasswordsFor(fsrl, prompt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSuccessfulPassword(FSRL fsrl, PasswordValue password) {
|
||||
public void addSuccessfulPassword(FSRL fsrl, Password password) {
|
||||
parentSession.addSuccessfulPassword(fsrl, password);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* Registry of {@link CryptoProvider crypto providers} and {@link #newSession() session creator}.
|
||||
@ -122,7 +123,7 @@ public class CryptoProviders {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSuccessfulPassword(FSRL fsrl, PasswordValue password) {
|
||||
public void addSuccessfulPassword(FSRL fsrl, Password password) {
|
||||
cachedCryptoProvider.addPassword(fsrl, password);
|
||||
}
|
||||
|
||||
@ -159,16 +160,16 @@ public class CryptoProviders {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt) {
|
||||
public Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt) {
|
||||
return new PasswordIterator(providers, fsrl, prompt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Union iterator of all password providers
|
||||
*/
|
||||
class PasswordIterator implements Iterator<PasswordValue> {
|
||||
class PasswordIterator implements Iterator<Password> {
|
||||
private List<PasswordProvider> providers;
|
||||
private Iterator<PasswordValue> currentIt;
|
||||
private Iterator<Password> currentIt;
|
||||
private String prompt;
|
||||
private FSRL fsrl;
|
||||
|
||||
@ -194,7 +195,7 @@ public class CryptoProviders {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordValue next() {
|
||||
public Password next() {
|
||||
return currentIt.next();
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import java.io.Closeable;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* Provides the caller with the ability to perform crypto querying operations
|
||||
@ -42,7 +43,7 @@ public interface CryptoSession extends Closeable {
|
||||
* @param prompt optional prompt that may be displayed to a user
|
||||
* @return {@link Iterator} of possible passwords
|
||||
*/
|
||||
Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt);
|
||||
Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt);
|
||||
|
||||
/**
|
||||
* Pushes a known good password into a cache for later re-retrieval.
|
||||
@ -50,7 +51,7 @@ public interface CryptoSession extends Closeable {
|
||||
* @param fsrl {@link FSRL} path to the file that was unlocked by the password
|
||||
* @param password the good password
|
||||
*/
|
||||
void addSuccessfulPassword(FSRL fsrl, PasswordValue password);
|
||||
void addSuccessfulPassword(FSRL fsrl, Password password);
|
||||
|
||||
/**
|
||||
* Returns true if this session has been closed.
|
||||
|
@ -18,6 +18,7 @@ package ghidra.formats.gfilesystem.crypto;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* Instances of this interface provide passwords to decrypt files.
|
||||
@ -47,5 +48,5 @@ public interface PasswordProvider extends CryptoProvider {
|
||||
* related queries
|
||||
* @return {@link Iterator} of possible passwords
|
||||
*/
|
||||
Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt, Session session);
|
||||
Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt, Session session);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.awt.Component;
|
||||
import docking.DockingWindowManager;
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.formats.gfilesystem.crypto.PasswordDialog.RESULT_STATE;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
|
||||
/**
|
||||
* Pops up up a GUI dialog prompting the user to enter a password for the specified file.
|
||||
@ -36,7 +37,7 @@ import ghidra.formats.gfilesystem.crypto.PasswordDialog.RESULT_STATE;
|
||||
public class PopupGUIPasswordProvider implements PasswordProvider {
|
||||
|
||||
@Override
|
||||
public Iterator<PasswordValue> getPasswordsFor(FSRL fsrl, String prompt, Session session) {
|
||||
public Iterator<Password> getPasswordsFor(FSRL fsrl, String prompt, Session session) {
|
||||
return new PasswordIterator(session, fsrl, prompt);
|
||||
}
|
||||
|
||||
@ -44,11 +45,11 @@ public class PopupGUIPasswordProvider implements PasswordProvider {
|
||||
boolean cancelAll;
|
||||
}
|
||||
|
||||
class PasswordIterator implements Iterator<PasswordValue> {
|
||||
class PasswordIterator implements Iterator<Password> {
|
||||
private SessionState sessionState;
|
||||
private FSRL fsrl;
|
||||
private boolean cancelled;
|
||||
private PasswordValue password;
|
||||
private Password password;
|
||||
private String prompt;
|
||||
private int tryCount;
|
||||
|
||||
@ -73,7 +74,7 @@ public class PopupGUIPasswordProvider implements PasswordProvider {
|
||||
DockingWindowManager.showDialog(rootFrame, pwdDialog);
|
||||
|
||||
cancelled = pwdDialog.resultState == RESULT_STATE.CANCELED;
|
||||
password = cancelled ? null : PasswordValue.wrap(pwdDialog.passwordField.getPassword());
|
||||
password = cancelled ? null : Password.wrap(pwdDialog.passwordField.getPassword());
|
||||
sessionState.cancelAll |= cancelled && pwdDialog.cancelledAll;
|
||||
pwdDialog.dispose();
|
||||
}
|
||||
@ -90,8 +91,8 @@ public class PopupGUIPasswordProvider implements PasswordProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordValue next() {
|
||||
PasswordValue result = password;
|
||||
public Password next() {
|
||||
Password result = password;
|
||||
password = null;
|
||||
return result;
|
||||
}
|
||||
|
@ -25,12 +25,13 @@ import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import util.CollectionUtils;
|
||||
|
||||
public class CachedPasswordProviderTest extends AbstractGenericTest {
|
||||
private CryptoProviders cryptoProviders = CryptoProviders.getInstance();
|
||||
|
||||
private List<PasswordValue> getPasswords(CryptoSession cryptoSession, String fsrlStr)
|
||||
private List<Password> getPasswords(CryptoSession cryptoSession, String fsrlStr)
|
||||
throws MalformedURLException {
|
||||
return CollectionUtils
|
||||
.asList(cryptoSession.getPasswordsFor(FSRL.fromString(fsrlStr), "badbeef"));
|
||||
@ -60,7 +61,7 @@ public class CachedPasswordProviderTest extends AbstractGenericTest {
|
||||
|
||||
// shouldn't match passwords: file1.txt to file2.txt
|
||||
cryptoSession.addSuccessfulPassword(FSRL.fromString("file:///fake/path/file1.txt"),
|
||||
PasswordValue.wrap("password_for_file2.txt".toCharArray()));
|
||||
Password.wrap("password_for_file2.txt".toCharArray()));
|
||||
assertEquals(1, getPasswords(cryptoSession, "file:///fake/path/file1.txt").size());
|
||||
assertEquals(0, getPasswords(cryptoSession, "file:///fake/path/file2.txt").size());
|
||||
|
||||
|
@ -26,6 +26,7 @@ import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.formats.gfilesystem.FSRL;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import util.CollectionUtils;
|
||||
import utilities.util.FileUtilities;
|
||||
|
||||
@ -33,7 +34,7 @@ public class CmdLinePasswordProviderTest extends AbstractGenericTest {
|
||||
|
||||
private CryptoProviders cryptoProviders = CryptoProviders.getInstance();
|
||||
|
||||
private List<PasswordValue> getPasswords(CryptoSession cryptoSession, String fsrlStr)
|
||||
private List<Password> getPasswords(CryptoSession cryptoSession, String fsrlStr)
|
||||
throws MalformedURLException {
|
||||
return CollectionUtils
|
||||
.asList(cryptoSession.getPasswordsFor(FSRL.fromString(fsrlStr), "badbeef"));
|
||||
@ -76,7 +77,7 @@ public class CmdLinePasswordProviderTest extends AbstractGenericTest {
|
||||
System.setProperty(CmdLinePasswordProvider.CMDLINE_PASSWORD_PROVIDER_PROPERTY_NAME,
|
||||
pwdFile.getPath());
|
||||
try (CryptoSession cryptoSession = cryptoProviders.newSession()) {
|
||||
List<PasswordValue> pwdList =
|
||||
List<Password> pwdList =
|
||||
getPasswords(cryptoSession, "file:///fake/path/file1.txt");
|
||||
|
||||
assertEquals(2, pwdList.size());
|
||||
@ -93,12 +94,12 @@ public class CmdLinePasswordProviderTest extends AbstractGenericTest {
|
||||
System.setProperty(CmdLinePasswordProvider.CMDLINE_PASSWORD_PROVIDER_PROPERTY_NAME,
|
||||
pwdFile.getPath());
|
||||
try (CryptoSession cryptoSession = cryptoProviders.newSession()) {
|
||||
List<PasswordValue> pwdList =
|
||||
List<Password> pwdList =
|
||||
getPasswords(cryptoSession, "file:///not_matching/path/file1.txt");
|
||||
|
||||
assertEquals(0, pwdList.size());
|
||||
|
||||
List<PasswordValue> list2 = getPasswords(cryptoSession, "file:///path/to/a/file1.txt");
|
||||
List<Password> list2 = getPasswords(cryptoSession, "file:///path/to/a/file1.txt");
|
||||
assertEquals(1, list2.size());
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,9 @@ package ghidra.file.formats.sevenzip;
|
||||
|
||||
import static ghidra.formats.gfilesystem.fileinfo.FileAttributeType.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
@ -31,9 +30,9 @@ import ghidra.formats.gfilesystem.FileCache.FileCacheEntry;
|
||||
import ghidra.formats.gfilesystem.FileCache.FileCacheEntryBuilder;
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.formats.gfilesystem.crypto.CryptoSession;
|
||||
import ghidra.formats.gfilesystem.crypto.PasswordValue;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileAttributes;
|
||||
import ghidra.formats.gfilesystem.fileinfo.FileType;
|
||||
import ghidra.framework.generic.auth.Password;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.CryptoException;
|
||||
@ -141,9 +140,9 @@ public class SevenZipFileSystem implements GFileSystem {
|
||||
String prompt = passwords.isEmpty()
|
||||
? fsrl.getContainer().getName()
|
||||
: String.format("%s in %s", file.getName(), fsrl.getContainer().getName());
|
||||
for (Iterator<PasswordValue> pwIt =
|
||||
for (Iterator<Password> pwIt =
|
||||
cryptoSession.getPasswordsFor(fsrl.getContainer(), prompt); pwIt.hasNext();) {
|
||||
try (PasswordValue passwordValue = pwIt.next()) {
|
||||
try (Password passwordValue = pwIt.next()) {
|
||||
monitor.setMessage("Testing password for " + file.getName());
|
||||
|
||||
String password = String.valueOf(passwordValue.getPasswordChars()); // we are forced to use strings by 7zip's api
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.formats.gfilesystem.crypto;
|
||||
package ghidra.framework.generic.auth;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Arrays;
|
||||
@ -23,44 +23,44 @@ import java.util.Arrays;
|
||||
* <p>
|
||||
* {@link #close() Closing} an instance will clear the characters of the char array.
|
||||
*/
|
||||
public class PasswordValue implements Closeable {
|
||||
public class Password implements Closeable {
|
||||
|
||||
/**
|
||||
* Creates a new PasswordValue using a copy the specified characters.
|
||||
* Creates a new {@code Password} using a copy the specified characters.
|
||||
*
|
||||
* @param password password characters
|
||||
* @return new PasswordValue instance
|
||||
* @return new {@code Password} instance
|
||||
*/
|
||||
public static PasswordValue copyOf(char[] password) {
|
||||
PasswordValue result = new PasswordValue();
|
||||
public static Password copyOf(char[] password) {
|
||||
Password result = new Password();
|
||||
result.password = new char[password.length];
|
||||
System.arraycopy(password, 0, result.password, 0, password.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PasswordValue by wrapping the specified character array.
|
||||
* Creates a new {@code Password} by wrapping the specified character array.
|
||||
* <p>
|
||||
* The new instance will take ownership of the char array, and
|
||||
* clear it when the instance is {@link #close() closed}.
|
||||
*
|
||||
* @param password password characters
|
||||
* @return new PasswordValue instance
|
||||
* @return new {@code Password} instance
|
||||
*/
|
||||
public static PasswordValue wrap(char[] password) {
|
||||
PasswordValue result = new PasswordValue();
|
||||
public static Password wrap(char[] password) {
|
||||
Password result = new Password();
|
||||
result.password = password;
|
||||
return result;
|
||||
}
|
||||
|
||||
private char[] password;
|
||||
|
||||
private PasswordValue() {
|
||||
private Password() {
|
||||
// empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordValue clone() {
|
||||
public Password clone() {
|
||||
return copyOf(password);
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ public class PasswordValue implements Closeable {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
PasswordValue other = (PasswordValue) obj;
|
||||
Password other = (Password) obj;
|
||||
return Arrays.equals(password, other.password);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user