mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-5362 Correct password entry bug and refactor PasswordDialog/ClientAuthenticator
This commit is contained in:
parent
99ed1003b5
commit
d0badde92b
12 changed files with 194 additions and 116 deletions
|
@ -418,10 +418,6 @@ public class CreateBsimServerInfoDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
String user = userField.getText().trim();
|
||||
if (ClientUtil.getUserName().equals(user)) {
|
||||
user = null;
|
||||
}
|
||||
|
||||
String name = nameField.getText().trim();
|
||||
String host = hostField.getText().trim();
|
||||
|
||||
|
|
|
@ -334,14 +334,16 @@ public class BSimPostgresDBConnectionManager {
|
|||
throw new SQLException("No registered authenticator");
|
||||
}
|
||||
NameCallback nameCb = new NameCallback("User ID:", bds.getUsername());
|
||||
boolean allowUserIDEntry = true;
|
||||
if (!serverInfo.hasDefaultLogin()) {
|
||||
nameCb.setName(bds.getUsername());
|
||||
allowUserIDEntry = false;
|
||||
}
|
||||
PasswordCallback passCb = new PasswordCallback(" ", false); // force use of default prompting
|
||||
try {
|
||||
if (!clientAuthenticator.processPasswordCallbacks(
|
||||
"BSim Database Authentication", "BSim Database Server",
|
||||
serverInfo.toString(), nameCb, passCb, null, null, loginError)) {
|
||||
"BSim Database Authentication", "BSim DB Server", serverInfo.toString(),
|
||||
allowUserIDEntry, nameCb, passCb, null, null, loginError)) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
bds.setPassword(new String(passCb.getPassword()));
|
||||
|
|
|
@ -376,7 +376,7 @@ public class BSimServerInfo implements Comparable<BSimServerInfo> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine of user info was stipulated during construction
|
||||
* Determine if user info was stipulated during construction
|
||||
* @return true if user info was stipulated during construction
|
||||
*/
|
||||
public boolean hasDefaultLogin() {
|
||||
|
|
|
@ -590,8 +590,8 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
if (isRunningHeadless()) {
|
||||
// only change client authenticator in headless mode
|
||||
try {
|
||||
HeadlessClientAuthenticator.installHeadlessClientAuthenticator(
|
||||
ClientUtil.getUserName(), null, false);
|
||||
HeadlessClientAuthenticator
|
||||
.installHeadlessClientAuthenticator(ClientUtil.getUserName(), null, false);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected Exception", e);
|
||||
|
@ -2629,8 +2629,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
|
||||
Address choice = doAsk(Integer.class, title, message, existingValue, lastValue -> {
|
||||
|
||||
AskAddrDialog dialog =
|
||||
new AskAddrDialog(title, message, currentProgram, lastValue);
|
||||
AskAddrDialog dialog = new AskAddrDialog(title, message, currentProgram, lastValue);
|
||||
if (dialog.isCanceled()) {
|
||||
throw new CancelledException();
|
||||
}
|
||||
|
@ -3158,7 +3157,7 @@ public abstract class GhidraScript extends FlatProgramAPI {
|
|||
throw new ImproperUseException(
|
||||
"The askPassword() method can only be used when running headed Ghidra.");
|
||||
}
|
||||
PasswordDialog dialog = new PasswordDialog(title, null, null, prompt, null, null);
|
||||
PasswordDialog dialog = new PasswordDialog(title, null, null, prompt);
|
||||
try {
|
||||
state.getTool().showDialog(dialog);
|
||||
if (!dialog.okWasPressed()) {
|
||||
|
|
|
@ -20,6 +20,8 @@ import java.awt.event.*;
|
|||
|
||||
import javax.swing.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import docking.DialogComponentProvider;
|
||||
import docking.widgets.checkbox.GCheckBox;
|
||||
import docking.widgets.combobox.GComboBox;
|
||||
|
@ -39,26 +41,34 @@ public class PasswordDialog extends DialogComponentProvider {
|
|||
private JComboBox<String> choiceCB;
|
||||
private JCheckBox anonymousAccess;
|
||||
private boolean okPressed = false;
|
||||
private String defaultUserID;
|
||||
private String defaultUserId;
|
||||
|
||||
/**
|
||||
* Construct a new PasswordDialog.
|
||||
* Construct a new PasswordDialog which may include user ID specification/prompt, if either
|
||||
* {@code allowUserIdEntry} is true or a non-null {@code defaultUserId} has been specified, and
|
||||
* other optional elements. The dialog includes a message text area which supports the use
|
||||
* of {@link #setErrorText(String)}.
|
||||
*
|
||||
* @param title title of the dialog
|
||||
* @param serverType 'Server' or 'Key-store' designation
|
||||
* @param serverName name of server or keystore pathname
|
||||
* @param passPrompt password prompt to show in the dialog; may be null, in which case
|
||||
* @param passPrompt password prompt to show in the dialog; may be null/empty, in which case
|
||||
* "Password:" is displayed next to the password field
|
||||
* @param userIdPrompt User ID / Name prompt to show in the dialog, if null a name will not be prompted for.
|
||||
* @param defaultUserID default name when prompting for a name
|
||||
* @param allowUserIdEntry if true user ID entry will be supported
|
||||
* @param userIdPrompt User ID / Name prompt to show in the dialog, if null "User ID:" is prompt
|
||||
* if either {@code allowUserIdEntry} is true or a non-null {@code defaultUserId} has been specified.
|
||||
* @param defaultUserId default name when prompting for a name
|
||||
* @param choicePrompt namePrompt name prompt to show in the dialog, if null a name will not be prompted for.
|
||||
* @param choices array of choices to present if choicePrompt is not null
|
||||
* @param defaultChoice default choice index
|
||||
* @param includeAnonymousOption true signals to add a checkbox to request anonymous login
|
||||
*/
|
||||
public PasswordDialog(String title, String serverType, String serverName, String passPrompt,
|
||||
String userIdPrompt, String defaultUserID, String choicePrompt, String[] choices,
|
||||
int defaultChoice, boolean includeAnonymousOption) {
|
||||
this(title, serverType, serverName, passPrompt, userIdPrompt, defaultUserID);
|
||||
boolean allowUserIdEntry, String userIdPrompt, String defaultUserId,
|
||||
String choicePrompt, String[] choices, int defaultChoice,
|
||||
boolean includeAnonymousOption) {
|
||||
this(title, serverType, serverName, passPrompt, allowUserIdEntry, userIdPrompt,
|
||||
defaultUserId, true);
|
||||
if (choicePrompt != null) {
|
||||
workPanel.add(new GLabel(choicePrompt));
|
||||
choiceCB = new GComboBox<>(choices);
|
||||
|
@ -89,43 +99,70 @@ public class PasswordDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a new PasswordDialog.
|
||||
* Construct a new PasswordDialog which only prompts for a password for a specified server
|
||||
* type and name. The dialog will not include a User ID display, although server fields
|
||||
* may be used for a similar display purpose. The dialog includes a message text area
|
||||
* which supports the use of {@link #setErrorText(String)}.
|
||||
*
|
||||
* @param title title of the dialog
|
||||
* @param serverType 'Server' or 'Key-store' designation
|
||||
* @param serverName name of server or keystore pathname
|
||||
* @param passPrompt password prompt to show in the dialog; may be null, in which case
|
||||
* "Password:" is displayed next to the password field
|
||||
* @param userIdPrompt User ID / Name prompt to show in the dialog, if null a name will not be prompted for.
|
||||
* @param defaultUserID default name when prompting for a name
|
||||
* "Password:" is prompt.
|
||||
*/
|
||||
public PasswordDialog(String title, String serverType, String serverName, String passPrompt,
|
||||
String userIdPrompt, String defaultUserID) {
|
||||
this(title, serverType, serverName, passPrompt, userIdPrompt, defaultUserID, true);
|
||||
public PasswordDialog(String title, String serverType, String serverName, String passPrompt) {
|
||||
this(title, serverType, serverName, passPrompt, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new PasswordDialog.
|
||||
* Construct a new PasswordDialog which only prompts for a password for a specified server
|
||||
* type and name. The dialog will not include a User ID display, although server fields
|
||||
* may be used for a similar display purpose. The dialog optionally includes a message
|
||||
* text area which supports the use of {@link #setErrorText(String)}.
|
||||
*
|
||||
* @param title title of the dialog
|
||||
* @param serverType 'Server' or 'Key-store' designation
|
||||
* @param serverName name of server or keystore pathname
|
||||
* @param passPrompt password prompt to show in the dialog; may be null, in which case
|
||||
* "Password:" is displayed next to the password field
|
||||
* @param userIdPrompt User ID / Name prompt to show in the dialog, if null a name will not be prompted for.
|
||||
* @param defaultUserID default name when prompting for a name
|
||||
* @param hasMessages true if the client will set messages on this dialog. If true, the
|
||||
* dialog's minimum size will be increased
|
||||
* @param hasMessages true if a message text area should be included allowing for use of
|
||||
* {@link #setErrorText(String)}
|
||||
*/
|
||||
public PasswordDialog(String title, String serverType, String serverName, String passPrompt,
|
||||
String userIdPrompt, String defaultUserID, boolean hasMessages) {
|
||||
boolean hasMessages) {
|
||||
this(title, serverType, serverName, passPrompt, false, null, null, hasMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new PasswordDialog which may include user ID specification/prompt if either
|
||||
* {@code allowUserIdEntry} is true or a non-null {@code defaultUserId} has been specified.
|
||||
* The dialog optionally includes a message text area area which supports the use of
|
||||
* {@link #setErrorText(String)}.
|
||||
*
|
||||
* @param title title of the dialog
|
||||
* @param serverType 'Server' or 'Key-store' designation
|
||||
* @param serverName name of server or keystore pathname
|
||||
* @param passPrompt password prompt to show in the dialog; may be null/empty, in which case
|
||||
* "Password:" is displayed next to the password field
|
||||
* @param allowUserIdEntry if true user ID entry will be supported
|
||||
* @param userIdPrompt User ID / Name prompt to show in the dialog, if null "User ID:" is prompt
|
||||
* if either {@code allowUserIdEntry} is true or a non-null {@code defaultUserId} has been specified.
|
||||
* @param defaultUserId default name when prompting for a name
|
||||
* @param hasMessages true if a message text area should be included allowing for use of
|
||||
* {@link #setErrorText(String)}
|
||||
*/
|
||||
public PasswordDialog(String title, String serverType, String serverName, String passPrompt,
|
||||
boolean allowUserIdEntry, String userIdPrompt, String defaultUserId,
|
||||
boolean hasMessages) {
|
||||
super(title, true);
|
||||
|
||||
this.defaultUserID = defaultUserID;
|
||||
this.defaultUserId = defaultUserId;
|
||||
|
||||
setRememberSize(false);
|
||||
setTransient(true);
|
||||
|
||||
if (hasMessages) {
|
||||
setMinimumSize(300, 150);
|
||||
setMinimumSize(350, 150);
|
||||
}
|
||||
|
||||
workPanel = new JPanel(new PairLayout(5, 5));
|
||||
|
@ -136,20 +173,27 @@ public class PasswordDialog extends DialogComponentProvider {
|
|||
workPanel.add(new GLabel(serverName));
|
||||
}
|
||||
|
||||
if (userIdPrompt != null) {
|
||||
if (StringUtils.isBlank(userIdPrompt)) {
|
||||
userIdPrompt = "User ID:";
|
||||
}
|
||||
if (StringUtils.isBlank(passPrompt)) {
|
||||
passPrompt = "Password:";
|
||||
}
|
||||
|
||||
if (allowUserIdEntry) {
|
||||
workPanel.add(new GLabel(userIdPrompt));
|
||||
nameField = new JTextField(defaultUserID, 16);
|
||||
nameField = new JTextField(defaultUserId, 16);
|
||||
nameField.setName("NAME-ENTRY-COMPONENT");
|
||||
workPanel.add(nameField);
|
||||
}
|
||||
else if (defaultUserID != null) {
|
||||
workPanel.add(new GLabel("User ID:"));
|
||||
JLabel nameLabel = new GLabel(defaultUserID);
|
||||
else if (defaultUserId != null) {
|
||||
workPanel.add(new GLabel(userIdPrompt));
|
||||
JLabel nameLabel = new GLabel(defaultUserId);
|
||||
nameLabel.setName("NAME-COMPONENT");
|
||||
workPanel.add(nameLabel);
|
||||
}
|
||||
|
||||
workPanel.add(new GLabel(passPrompt != null ? passPrompt : "Password:"));
|
||||
workPanel.add(new GLabel(passPrompt));
|
||||
passwordField = new JPasswordField(16);
|
||||
passwordField.setName("PASSWORD-ENTRY-COMPONENT");
|
||||
workPanel.add(passwordField);
|
||||
|
@ -245,7 +289,7 @@ public class PasswordDialog extends DialogComponentProvider {
|
|||
* @return the user ID / Name entered in the password field
|
||||
*/
|
||||
public String getUserID() {
|
||||
return nameField != null ? nameField.getText().trim() : defaultUserID;
|
||||
return nameField != null ? nameField.getText().trim() : defaultUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -63,7 +62,7 @@ public class PopupKeyStorePasswordProvider implements KeyStorePasswordProvider {
|
|||
@Override
|
||||
public void run() {
|
||||
PasswordDialog pwdDialog =
|
||||
new PasswordDialog("Protected PKI Certificate", "Cert File", file, null, null, null);
|
||||
new PasswordDialog("Protected PKI Certificate", "Cert File", file, null);
|
||||
if (passwordError) {
|
||||
pwdDialog.setErrorText("Incorrect password");
|
||||
}
|
||||
|
|
|
@ -139,8 +139,8 @@ public class SplashScreenTest extends AbstractDockingTest {
|
|||
private DockingDialog showModalPasswordDialog(Frame parentFrame) throws Exception {
|
||||
|
||||
String dialogTitle = "InfoWindowTest.testSplashScreenPasswordModality() Dialog";
|
||||
DialogComponentProvider passwordDialog = runSwing(() -> new PasswordDialog(dialogTitle,
|
||||
"Server Type", "Server Name", "Prompt", null, null));
|
||||
DialogComponentProvider passwordDialog =
|
||||
runSwing(() -> new PasswordDialog(dialogTitle, "Server Type", "Server Name", "Prompt"));
|
||||
|
||||
if (parentFrame == null) {
|
||||
// null means to share the parent
|
||||
|
|
|
@ -33,10 +33,11 @@ public interface ClientAuthenticator extends KeyStorePasswordProvider {
|
|||
public Authenticator getAuthenticator();
|
||||
|
||||
/**
|
||||
* Process Ghidra Server password authentication callbacks.
|
||||
* Process password authentication callbacks.
|
||||
* @param title password prompt title if GUI is used
|
||||
* @param serverType type of server (label associated with serverName)
|
||||
* @param serverName name of server
|
||||
* @param allowUserNameEntry if true user ID entry will be supported if nameCb is not null.
|
||||
* @param nameCb provides storage for user login name. A null indicates
|
||||
* that the default user name will be used, @see ClientUtil#getUserName()
|
||||
* @param passCb provides storage for user password, @see PasswordCallback#setPassword(char[])
|
||||
|
@ -51,8 +52,8 @@ public interface ClientAuthenticator extends KeyStorePasswordProvider {
|
|||
* @return true if password provided, false if entry cancelled
|
||||
*/
|
||||
public boolean processPasswordCallbacks(String title, String serverType, String serverName,
|
||||
NameCallback nameCb, PasswordCallback passCb, ChoiceCallback choiceCb,
|
||||
AnonymousCallback anonymousCb, String loginError);
|
||||
boolean allowUserNameEntry, NameCallback nameCb, PasswordCallback passCb,
|
||||
ChoiceCallback choiceCb, AnonymousCallback anonymousCb, String loginError);
|
||||
|
||||
/**
|
||||
* Prompt user for reconnect
|
||||
|
|
|
@ -425,7 +425,8 @@ public class ClientUtil {
|
|||
"Unsupported authentication callback: " + callbacks[0].getClass().getName());
|
||||
}
|
||||
if (!clientAuthenticator.processPasswordCallbacks("Repository Server Authentication",
|
||||
"Repository Server", serverName, nameCb, passCb, choiceCb, anonymousCb, loginError)) {
|
||||
"Repository Server", serverName, nameCb != null, nameCb, passCb, choiceCb, anonymousCb,
|
||||
loginError)) {
|
||||
return false;
|
||||
}
|
||||
String name = defaultUserID;
|
||||
|
|
|
@ -76,9 +76,10 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
}
|
||||
|
||||
NameCallback nameCb = new NameCallback("Name: ", userName);
|
||||
boolean allowUserIDEntry = true;
|
||||
if (!useDefaultUser) {
|
||||
// Prevent modification of user name by password prompting
|
||||
nameCb.setName(userName);
|
||||
allowUserIDEntry = false;
|
||||
}
|
||||
|
||||
// Prompt for password
|
||||
|
@ -89,7 +90,7 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
PasswordCallback passCb = new PasswordCallback(prompt, false);
|
||||
try {
|
||||
ServerPasswordPrompt pp = new ServerPasswordPrompt("Connection Authentication",
|
||||
"Server", serverName, nameCb, passCb, null, null, null);
|
||||
"Server", serverName, allowUserIDEntry, nameCb, passCb, null, null, null);
|
||||
SystemUtilities.runSwingNow(pp);
|
||||
if (pp.okWasPressed()) {
|
||||
return new PasswordAuthentication(nameCb.getName(), passCb.getPassword());
|
||||
|
@ -135,10 +136,10 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
|
||||
@Override
|
||||
public boolean processPasswordCallbacks(String title, String serverType, String serverName,
|
||||
NameCallback nameCb, PasswordCallback passCb, ChoiceCallback choiceCb,
|
||||
AnonymousCallback anonymousCb, String loginError) {
|
||||
ServerPasswordPrompt pp = new ServerPasswordPrompt(title, serverType, serverName, nameCb,
|
||||
passCb, choiceCb, anonymousCb, loginError);
|
||||
boolean allowUserNameEntry, NameCallback nameCb, PasswordCallback passCb,
|
||||
ChoiceCallback choiceCb, AnonymousCallback anonymousCb, String loginError) {
|
||||
ServerPasswordPrompt pp = new ServerPasswordPrompt(title, serverType, serverName,
|
||||
allowUserNameEntry, nameCb, passCb, choiceCb, anonymousCb, loginError);
|
||||
SystemUtilities.runSwingNow(pp);
|
||||
return pp.okWasPressed();
|
||||
}
|
||||
|
@ -172,6 +173,7 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
private String title;
|
||||
private String serverType; // label for serverName field
|
||||
private String serverName;
|
||||
private boolean allowUserIDEntry;
|
||||
private NameCallback nameCb;
|
||||
private PasswordCallback passCb;
|
||||
private ChoiceCallback choiceCb;
|
||||
|
@ -180,11 +182,12 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
private boolean okPressed = false;
|
||||
|
||||
ServerPasswordPrompt(String title, String serverType, String serverName,
|
||||
NameCallback nameCb, PasswordCallback passCb, ChoiceCallback choiceCb,
|
||||
AnonymousCallback anonymousCb, String errorMsg) {
|
||||
boolean allowUserIDEntry, NameCallback nameCb, PasswordCallback passCb,
|
||||
ChoiceCallback choiceCb, AnonymousCallback anonymousCb, String errorMsg) {
|
||||
this.title = title;
|
||||
this.serverType = serverType;
|
||||
this.serverName = serverName;
|
||||
this.allowUserIDEntry = allowUserIDEntry && (nameCb != null);
|
||||
this.nameCb = nameCb;
|
||||
this.passCb = passCb;
|
||||
this.choiceCb = choiceCb;
|
||||
|
@ -225,20 +228,20 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
String defaultUserName = null;
|
||||
String namePrompt = null;
|
||||
if (nameCb != null) {
|
||||
defaultUserName = nameCb.getName();
|
||||
if (defaultUserName == null) {
|
||||
// Name entry only permitted with name callback where name has not be pre-set
|
||||
defaultUserName = nameCb.getDefaultName();
|
||||
namePrompt = nameCb.getPrompt();
|
||||
defaultUserName = nameCb.getName();
|
||||
if (StringUtils.isBlank(defaultUserName)) {
|
||||
defaultUserName = nameCb.getDefaultName();
|
||||
}
|
||||
}
|
||||
if (defaultUserName == null) {
|
||||
|
||||
if (StringUtils.isBlank(defaultUserName)) {
|
||||
defaultUserName = getDefaultUserName();
|
||||
}
|
||||
|
||||
PasswordDialog pwdDialog = new PasswordDialog(title, serverType, serverName,
|
||||
passCb.getPrompt(), namePrompt, defaultUserName, choicePrompt, choices,
|
||||
getDefaultChoice(), anonymousCb != null);
|
||||
passCb.getPrompt(), allowUserIDEntry, namePrompt, defaultUserName, choicePrompt,
|
||||
choices, getDefaultChoice(), anonymousCb != null);
|
||||
|
||||
if (errorMsg != null) {
|
||||
pwdDialog.setErrorText(errorMsg);
|
||||
|
@ -252,7 +255,7 @@ public class DefaultClientAuthenticator extends PopupKeyStorePasswordProvider
|
|||
}
|
||||
else {
|
||||
passCb.setPassword(pwdDialog.getPassword());
|
||||
if (nameCb != null) {
|
||||
if (nameCb != null && allowUserIDEntry) {
|
||||
String username = pwdDialog.getUserID();
|
||||
nameCb.setName(username);
|
||||
Preferences.setProperty(NAME_PREFERENCE, username);
|
||||
|
|
|
@ -39,22 +39,25 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
private final static char[] BADPASSWORD = "".toCharArray();
|
||||
|
||||
private static Object sshPrivateKey;
|
||||
private static String defaultUserName = ClientUtil.getUserName();
|
||||
private static String preferredName = null;
|
||||
private static boolean passwordPromptAllowed;
|
||||
|
||||
/**
|
||||
* Simple authentication handler using a default authenticator which may be passed to
|
||||
* {@link Authenticator#setDefault(Authenticator)}. The preferred username must be set by
|
||||
* invoking {@link #installHeadlessClientAuthenticator(String, String, boolean)} or
|
||||
* stipulated by the requesting URL. The {@link ClientUtil#getUserName()} identity is never
|
||||
* used.
|
||||
*/
|
||||
private Authenticator authenticator = new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
|
||||
if (defaultUserName == null) {
|
||||
throw new IllegalStateException("Default user name is unknown");
|
||||
}
|
||||
|
||||
String serverName = getRequestingHost();
|
||||
URL requestingURL = getRequestingURL(); // may be null
|
||||
|
||||
String pwd = null;
|
||||
String userName = defaultUserName;
|
||||
String name = preferredName;
|
||||
|
||||
if (requestingURL != null) {
|
||||
String userInfo = requestingURL.getUserInfo();
|
||||
|
@ -62,12 +65,12 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
// Use user info from URL
|
||||
int pwdSep = userInfo.indexOf(':');
|
||||
if (pwdSep < 0) {
|
||||
userName = userInfo;
|
||||
name = userInfo;
|
||||
}
|
||||
else {
|
||||
pwd = userInfo.substring(pwdSep + 1);
|
||||
if (pwdSep != 0) {
|
||||
userName = userInfo.substring(0, pwdSep);
|
||||
name = userInfo.substring(0, pwdSep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,17 +83,21 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
|
||||
Msg.debug(this, "PasswordAuthentication requested for " + serverName);
|
||||
|
||||
if (StringUtils.isBlank(name)) {
|
||||
throw new IllegalStateException("Connection user name is unknown");
|
||||
}
|
||||
|
||||
if (pwd != null) {
|
||||
// Requesting URL specified password
|
||||
return new PasswordAuthentication(userName, pwd.toCharArray());
|
||||
return new PasswordAuthentication(name, pwd.toCharArray());
|
||||
}
|
||||
|
||||
String usage = "Access password requested for " + serverName;
|
||||
String prompt = getRequestingPrompt();
|
||||
if (StringUtils.isBlank(prompt) || "security".equals(prompt)) {
|
||||
prompt = "Password for " + userName +":";
|
||||
prompt = "Password for " + name + ":";
|
||||
}
|
||||
return new PasswordAuthentication(userName, getPassword(usage, prompt));
|
||||
return new PasswordAuthentication(name, getPassword(usage, prompt));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -103,7 +110,9 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Install headless client authenticator for Ghidra Server
|
||||
* Install headless client authenticator for Ghidra Server and when http/https
|
||||
* connections require authentication and have not specified user information.
|
||||
*
|
||||
* @param username optional username to be used with a Ghidra Server which
|
||||
* allows username to be specified. If null, {@link ClientUtil#getUserName()}
|
||||
* will be used.
|
||||
|
@ -118,7 +127,7 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
boolean allowPasswordPrompt) throws IOException {
|
||||
passwordPromptAllowed = allowPasswordPrompt;
|
||||
if (username != null) {
|
||||
defaultUserName = username;
|
||||
preferredName = username;
|
||||
}
|
||||
|
||||
// clear existing key store settings
|
||||
|
@ -247,35 +256,38 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
|
||||
@Override
|
||||
public boolean processPasswordCallbacks(String title, String serverType, String serverName,
|
||||
NameCallback nameCb, PasswordCallback passCb, ChoiceCallback choiceCb,
|
||||
AnonymousCallback anonymousCb, String loginError) {
|
||||
boolean allowUserNameEntry, NameCallback nameCb, PasswordCallback passCb,
|
||||
ChoiceCallback choiceCb, AnonymousCallback anonymousCb, String loginError) {
|
||||
if (anonymousCb != null && !passwordPromptAllowed) {
|
||||
// Assume that login error will not occur with anonymous login
|
||||
anonymousCb.setAnonymousAccessRequested(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (defaultUserName == null) {
|
||||
throw new IllegalStateException("Default user name is unknown");
|
||||
}
|
||||
|
||||
if (choiceCb != null) {
|
||||
choiceCb.setSelectedIndex(1);
|
||||
}
|
||||
|
||||
String userName = null;
|
||||
if (nameCb != null) {
|
||||
if (allowUserNameEntry) {
|
||||
// use preferred login name
|
||||
userName = preferredName;
|
||||
}
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
// check for default login name in order of precedence
|
||||
userName = nameCb.getName();
|
||||
if (userName == null) {
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
userName = nameCb.getDefaultName();
|
||||
}
|
||||
}
|
||||
if (userName == null) {
|
||||
userName = defaultUserName;
|
||||
if (allowUserNameEntry) {
|
||||
nameCb.setName(userName);
|
||||
}
|
||||
}
|
||||
|
||||
if (nameCb != null) {
|
||||
nameCb.setName(defaultUserName);
|
||||
if (!StringUtils.isBlank(userName)) {
|
||||
userName = ClientUtil.getUserName();
|
||||
}
|
||||
|
||||
String usage = null;
|
||||
|
@ -284,7 +296,7 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
}
|
||||
|
||||
// Ignore prompt specified by passCb
|
||||
String prompt = "Password for " + userName +":";
|
||||
String prompt = "Password for " + userName + ":";
|
||||
|
||||
char[] password = getPassword(usage, prompt);
|
||||
passCb.setPassword(password);
|
||||
|
@ -321,7 +333,18 @@ public class HeadlessClientAuthenticator implements ClientAuthenticator {
|
|||
return false;
|
||||
}
|
||||
if (nameCb != null) {
|
||||
nameCb.setName(defaultUserName);
|
||||
// presence of NameCallback implies user is allowed to specify name
|
||||
String userName = preferredName;
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
userName = nameCb.getName();
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
userName = nameCb.getDefaultName();
|
||||
}
|
||||
if (!StringUtils.isBlank(userName)) {
|
||||
userName = ClientUtil.getUserName();
|
||||
}
|
||||
}
|
||||
nameCb.setName(userName);
|
||||
}
|
||||
try {
|
||||
sshCb.sign(sshPrivateKey);
|
||||
|
|
|
@ -83,14 +83,24 @@ public class PasswordClientAuthenticator implements ClientAuthenticator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean processPasswordCallbacks(String title, String serverType,
|
||||
String serverName, NameCallback nameCb, PasswordCallback passCb,
|
||||
public boolean processPasswordCallbacks(String title, String serverType, String serverName,
|
||||
boolean allowUserNameEntry, NameCallback nameCb, PasswordCallback passCb,
|
||||
ChoiceCallback choiceCb, AnonymousCallback anonymousCb, String loginError) {
|
||||
if (choiceCb != null) {
|
||||
choiceCb.setSelectedIndex(1);
|
||||
}
|
||||
if (nameCb != null && username != null) {
|
||||
nameCb.setName(username);
|
||||
if (nameCb != null && allowUserNameEntry) {
|
||||
String name = username;
|
||||
if (name == null) {
|
||||
name = nameCb.getName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = nameCb.getDefaultName();
|
||||
}
|
||||
if (name == null) {
|
||||
name = ClientUtil.getUserName();
|
||||
}
|
||||
nameCb.setName(name);
|
||||
}
|
||||
passCb.setPassword(password.clone());
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue