mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
2936493408
11 changed files with 83 additions and 78 deletions
|
@ -658,8 +658,8 @@ public class Repository implements FileSystemListener, RepositoryLogger {
|
|||
synchronized (fileSystem) {
|
||||
User user = getUser(currentUser);
|
||||
if (user == null) {
|
||||
throw new UserAccessException(
|
||||
"User " + currentUser + " was not found in the user access list.");
|
||||
throw new UserAccessException("User " + currentUser + " was not found in the '" +
|
||||
name + "' repository access list.");
|
||||
}
|
||||
if (!user.isAdmin()) {
|
||||
throw new UserAccessException(
|
||||
|
@ -679,8 +679,8 @@ public class Repository implements FileSystemListener, RepositoryLogger {
|
|||
synchronized (fileSystem) {
|
||||
User user = getUser(currentUser);
|
||||
if (user == null) {
|
||||
throw new UserAccessException(
|
||||
"User " + currentUser + " was not found in the user access list.");
|
||||
throw new UserAccessException("User " + currentUser + " was not found in the '" +
|
||||
name + "' repository access list.");
|
||||
}
|
||||
if (user.isReadOnly()) {
|
||||
throw new UserAccessException(
|
||||
|
@ -700,8 +700,8 @@ public class Repository implements FileSystemListener, RepositoryLogger {
|
|||
synchronized (fileSystem) {
|
||||
User user = getUser(currentUser);
|
||||
if (user == null) {
|
||||
throw new UserAccessException(
|
||||
"User " + currentUser + " was not found in the user access list.");
|
||||
throw new UserAccessException("User " + currentUser + " was not found in the '" +
|
||||
name + "' repository access list.");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
|
|
@ -52,11 +52,16 @@ public class RepositoryManager {
|
|||
* @param rootDir directory where repositories will be created; this
|
||||
* path contains a list of users that can access the repositories
|
||||
* being managed.
|
||||
* @throws IOException
|
||||
* @param enableLocalPasswords if true user passwords will be maintained
|
||||
* within local 'users' file
|
||||
* @param defaultPasswordExpirationDays password expiration in days when
|
||||
* local passwords are enabled
|
||||
* @param anonymousAccessAllowed if true server permits anonymous access
|
||||
* to repositories.
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public RepositoryManager(File rootDir, boolean supportLocalPasswords,
|
||||
boolean requireExplicitPasswordReset, int defaultPasswordExpirationDays,
|
||||
boolean anonymousAccessAllowed) throws IOException {
|
||||
public RepositoryManager(File rootDir, boolean enableLocalPasswords,
|
||||
int defaultPasswordExpirationDays, boolean anonymousAccessAllowed) throws IOException {
|
||||
rootDirFile = rootDir;
|
||||
log.info("Instantiating Repository Manager for " + rootDirFile.getAbsolutePath());
|
||||
if (!rootDirFile.isDirectory()) {
|
||||
|
@ -66,8 +71,7 @@ public class RepositoryManager {
|
|||
throw new IOException(rootDirFile + " can not be written to");
|
||||
}
|
||||
this.anonymousAccessAllowed = anonymousAccessAllowed;
|
||||
this.userMgr = new UserManager(this, supportLocalPasswords, requireExplicitPasswordReset,
|
||||
defaultPasswordExpirationDays);
|
||||
this.userMgr = new UserManager(this, enableLocalPasswords, defaultPasswordExpirationDays);
|
||||
repositoryMap = new HashMap<>();
|
||||
initialize();
|
||||
}
|
||||
|
|
|
@ -59,9 +59,8 @@ public class UserManager {
|
|||
private final File userFile;
|
||||
private final File sshDir;
|
||||
|
||||
private boolean enableLocalPasswords = false;
|
||||
private boolean enableLocalPasswords;
|
||||
private long defaultPasswordExpirationMS;
|
||||
private boolean requireExplicitPasswordReset = true;
|
||||
|
||||
private PrintWriter dnLogOut;
|
||||
|
||||
|
@ -71,14 +70,17 @@ public class UserManager {
|
|||
private boolean userListUpdateInProgress = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param repositoryRoot root server directory
|
||||
* Construct server user manager
|
||||
* @param repositoryMgr repository manager (used for queued command processing)
|
||||
* @param enableLocalPasswords if true user passwords will be maintained
|
||||
* within local 'users' file
|
||||
* @param defaultPasswordExpirationDays password expiration in days when
|
||||
* local passwords are enabled
|
||||
*/
|
||||
UserManager(RepositoryManager repositoryMgr, boolean enableLocalPasswords,
|
||||
boolean requireExplicitPasswordReset, int defaultPasswordExpirationDays) {
|
||||
int defaultPasswordExpirationDays) {
|
||||
this.repositoryMgr = repositoryMgr;
|
||||
this.enableLocalPasswords = enableLocalPasswords;
|
||||
this.requireExplicitPasswordReset = requireExplicitPasswordReset;
|
||||
if (defaultPasswordExpirationDays < 0) {
|
||||
defaultPasswordExpirationDays = DEFAULT_PASSWORD_TIMEOUT_DAYS;
|
||||
}
|
||||
|
@ -163,7 +165,7 @@ public class UserManager {
|
|||
* @param passwordHash MD5 hash of initial password or null if explicit password reset required
|
||||
* @param dn X500 distinguished name for user (may be null)
|
||||
* @throws DuplicateNameException if username already exists
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
private synchronized void addUser(String username, char[] passwordHash, X500Principal x500User)
|
||||
throws DuplicateNameException, IOException {
|
||||
|
@ -190,11 +192,10 @@ public class UserManager {
|
|||
* Add a user.
|
||||
* @param username user name/SID
|
||||
* @throws DuplicateNameException if username already exists
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public void addUser(String username) throws DuplicateNameException, IOException {
|
||||
char[] passwordHash = requireExplicitPasswordReset ? null : getDefaultPasswordHash();
|
||||
addUser(username, passwordHash, null);
|
||||
addUser(username, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,11 +203,11 @@ public class UserManager {
|
|||
* @param username user name/SID
|
||||
* @param x500User X500 distinguished name for user (may be null)
|
||||
* @throws DuplicateNameException if username already exists
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public void addUser(String username, X500Principal x500User)
|
||||
throws DuplicateNameException, IOException {
|
||||
char[] passwordHash = requireExplicitPasswordReset ? null : getDefaultPasswordHash();
|
||||
char[] passwordHash = enableLocalPasswords ? getDefaultPasswordHash() : null;
|
||||
addUser(username, passwordHash, x500User);
|
||||
}
|
||||
|
||||
|
|
|
@ -158,11 +158,9 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
}
|
||||
|
||||
boolean supportLocalPasswords = false;
|
||||
boolean requireExplicitPasswordReset = true;
|
||||
switch (authMode) {
|
||||
case PASSWORD_FILE_LOGIN:
|
||||
supportLocalPasswords = true;
|
||||
requireExplicitPasswordReset = false;
|
||||
authModule = new PasswordFileAuthenticationModule(allowUserToSpecifyName);
|
||||
break;
|
||||
case PKI_LOGIN:
|
||||
|
@ -199,8 +197,8 @@ public class GhidraServer extends UnicastRemoteObject implements GhidraServerHan
|
|||
sshAuthModule = new SSHAuthenticationModule(allowUserToSpecifyName);
|
||||
}
|
||||
|
||||
mgr = new RepositoryManager(rootDir, supportLocalPasswords, requireExplicitPasswordReset,
|
||||
defaultPasswordExpirationDays, allowAnonymousAccess);
|
||||
mgr = new RepositoryManager(rootDir, supportLocalPasswords, defaultPasswordExpirationDays,
|
||||
allowAnonymousAccess);
|
||||
|
||||
GhidraServer.server = this;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import ghidra.framework.remote.security.SSHKeyManager;
|
|||
import ghidra.net.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.UserAccessException;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
|
||||
/**
|
||||
|
@ -205,6 +206,10 @@ public class ClientUtil {
|
|||
Msg.debug(ClientUtil.class, "Server not connected (" + operation + ")");
|
||||
promptForReconnect(repository, operation, mustRetry, parent);
|
||||
}
|
||||
else if (exc instanceof UserAccessException) {
|
||||
Msg.showError(ClientUtil.class, parent, title,
|
||||
"Access denied: " + repository + "\n" + exc.getMessage());
|
||||
}
|
||||
else if ((exc instanceof ServerException) || (exc instanceof ServerError)) {
|
||||
Msg.showError(ClientUtil.class, parent, title,
|
||||
"Exception occurred on the Ghidra Server.", exc.getCause());
|
||||
|
|
|
@ -375,43 +375,42 @@ class ProjectActionManager {
|
|||
buildCloseViewsActions();
|
||||
|
||||
boolean hasActiveProject = activeProject != null;
|
||||
enableActions(hasActiveProject);
|
||||
|
||||
if (hasActiveProject) {
|
||||
RepositoryAdapter repository = activeProject.getRepository();
|
||||
if (repository != null) {
|
||||
if (isUserAdmin(repository)) {
|
||||
tool.addAction(editAccessAction);
|
||||
editAccessAction.setEnabled(true);
|
||||
}
|
||||
else if (!isAnonymousUserOrNotConnected(repository)) {
|
||||
tool.addAction(viewAccessAction);
|
||||
viewAccessAction.setEnabled(true);
|
||||
}
|
||||
|
||||
if (repository.isConnected() && repository.getServer().canSetPassword()) {
|
||||
tool.addAction(setPasswordAction);
|
||||
setPasswordAction.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
enableActions(activeProject != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the connection state has changed;
|
||||
* enable or disable the edit Project access action.
|
||||
* @param repository shared project repository adapter
|
||||
*/
|
||||
void connectionStateChanged(RepositoryAdapter repository) {
|
||||
|
||||
// Action removal is done each time to avoid possibility
|
||||
// of adding actions twice. Action manipulated here are
|
||||
// not intended to appear in menu when not available.
|
||||
|
||||
setPasswordAction.setEnabled(false);
|
||||
editAccessAction.setEnabled(false);
|
||||
viewAccessAction.setEnabled(false);
|
||||
|
||||
tool.removeAction(setPasswordAction);
|
||||
tool.removeAction(editAccessAction);
|
||||
tool.removeAction(viewAccessAction);
|
||||
|
||||
if (repository.isConnected()) {
|
||||
editAccessAction.setEnabled(isUserAdmin(repository));
|
||||
if (repository.getServer().canSetPassword()) {
|
||||
tool.addAction(setPasswordAction);
|
||||
setPasswordAction.setEnabled(true);
|
||||
}
|
||||
if (isUserAdmin(repository)) {
|
||||
tool.addAction(editAccessAction);
|
||||
editAccessAction.setEnabled(true);
|
||||
}
|
||||
else if (!isAnonymousUserOrNotConnected(repository)) {
|
||||
tool.addAction(viewAccessAction);
|
||||
viewAccessAction.setEnabled(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
editAccessAction.setEnabled(false);
|
||||
tool.removeAction(setPasswordAction);
|
||||
}
|
||||
|
||||
if (infoDialog != null && infoDialog.isVisible()) {
|
||||
infoDialog.updateConnectionStatus();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -16,12 +15,12 @@
|
|||
*/
|
||||
package ghidra.framework.main.datatable;
|
||||
|
||||
import ghidra.framework.model.DomainFile;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import ghidra.framework.model.DomainFile;
|
||||
|
||||
public class DomainFileInfo {
|
||||
|
||||
// TODO: should not hang onto DomainFile since it may not track changes anymore
|
||||
|
@ -56,7 +55,7 @@ public class DomainFileInfo {
|
|||
if (domainFile.isCheckedOut()) {
|
||||
int latestVersionNumber = domainFile.getLatestVersion();
|
||||
String latestVersionStr = "" + latestVersionNumber;
|
||||
if (latestVersionNumber < 0) {
|
||||
if (latestVersionNumber <= 0) {
|
||||
latestVersionStr = "?";
|
||||
}
|
||||
displayName += " (" + versionStr + " of " + latestVersionStr + ")";
|
||||
|
|
|
@ -55,7 +55,8 @@ public class StructureFactory {
|
|||
* <li>if there are no data components to add to the structure
|
||||
* </ul>
|
||||
*/
|
||||
public static Structure createStructureDataType(Program program, Address address, int dataLength) {
|
||||
public static Structure createStructureDataType(Program program, Address address,
|
||||
int dataLength) {
|
||||
return createStructureDataType(program, address, dataLength, DEFAULT_STRUCTURE_NAME, true);
|
||||
}
|
||||
|
||||
|
@ -89,8 +90,8 @@ public class StructureFactory {
|
|||
}
|
||||
|
||||
if (dataLength <= 0) {
|
||||
throw new IllegalArgumentException("Structure length must be positive, not " +
|
||||
dataLength);
|
||||
throw new IllegalArgumentException(
|
||||
"Structure length must be positive, not " + dataLength);
|
||||
}
|
||||
|
||||
Address endAddress;
|
||||
|
@ -116,7 +117,7 @@ public class StructureFactory {
|
|||
name = providerContext.getUniqueName(name);
|
||||
}
|
||||
|
||||
Structure newStructure = new StructureDataType(name, 0);
|
||||
Structure newStructure = new StructureDataType(name, 0, program.getDataTypeManager());
|
||||
|
||||
initializeStructureFromContext(newStructure, providerContext, dataLength);
|
||||
|
||||
|
@ -211,16 +212,15 @@ public class StructureFactory {
|
|||
}
|
||||
|
||||
// create the context
|
||||
DataTypeProviderContext providerContext =
|
||||
new ProgramStructureProviderContext(program, data.getMinAddress(),
|
||||
(Structure) parentDataType, comp1.getParentOffset());
|
||||
DataTypeProviderContext providerContext = new ProgramStructureProviderContext(program,
|
||||
data.getMinAddress(), (Structure) parentDataType, comp1.getParentOffset());
|
||||
|
||||
String name = structureName;
|
||||
if (makeUniqueName) {
|
||||
name = providerContext.getUniqueName(name);
|
||||
}
|
||||
|
||||
Structure newStructure = new StructureDataType(name, 0);
|
||||
Structure newStructure = new StructureDataType(name, 0, program.getDataTypeManager());
|
||||
|
||||
initializeStructureFromContext(newStructure, providerContext, dataLength);
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class RepositoryFileSystemTest extends AbstractGhidraHeadedIntegrationTes
|
|||
FileUtilities.deleteDir(serverRoot);
|
||||
serverRoot.mkdir();
|
||||
|
||||
mgr = new RepositoryManager(serverRoot, false, false, 0, false);
|
||||
mgr = new RepositoryManager(serverRoot, false, 0, false);
|
||||
mgr.getUserManager().addUser(USER);
|
||||
|
||||
repository = mgr.createRepository(USER, "My_Repository");
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -61,7 +60,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testCreateRepositoryManager() throws Exception {
|
||||
|
||||
mgr = new RepositoryManager(root, false, false, 0, false);
|
||||
mgr = new RepositoryManager(root, false, 0, false);
|
||||
assertNotNull(mgr);
|
||||
|
||||
String[] userNames = mgr.getAllUsers("User_0");
|
||||
|
@ -71,7 +70,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
@Test
|
||||
public void testCreateRepositoryManagerWithAnonymous() throws Exception {
|
||||
|
||||
mgr = new RepositoryManager(root, false, false, 0, true);
|
||||
mgr = new RepositoryManager(root, false, 0, true);
|
||||
assertNotNull(mgr);
|
||||
|
||||
String[] userNames = mgr.getAllUsers("User_0");
|
||||
|
@ -83,7 +82,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testCreateRepository() throws Exception {
|
||||
mgr = new RepositoryManager(root, false, false, 0, false);
|
||||
mgr = new RepositoryManager(root, false, 0, false);
|
||||
|
||||
Repository rep = mgr.createRepository("User_0", "REPOSITORY_A");
|
||||
assertNotNull(rep);
|
||||
|
@ -91,7 +90,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testCreateRepositoryAnonymous() throws Exception {
|
||||
mgr = new RepositoryManager(root, false, false, 0, true);
|
||||
mgr = new RepositoryManager(root, false, 0, true);
|
||||
|
||||
Repository rep = mgr.createRepository("User_0", "REPOSITORY_A");
|
||||
assertNotNull(rep);
|
||||
|
@ -107,7 +106,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testCreateDuplicateRepository() throws Exception {
|
||||
mgr = new RepositoryManager(root, false, false, 0, false);
|
||||
mgr = new RepositoryManager(root, false, 0, false);
|
||||
mgr.createRepository("User_0", "REPOSITORY_A");
|
||||
try {
|
||||
mgr.createRepository("User_5", "REPOSITORY_A");
|
||||
|
@ -119,7 +118,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testGetRepository() throws Exception {
|
||||
mgr = new RepositoryManager(root, false, false, 0, true);
|
||||
mgr = new RepositoryManager(root, false, 0, true);
|
||||
Repository rep1 = mgr.createRepository("User_0", "REPOSITORY_A");
|
||||
addUsers("User_0", true, rep1);
|
||||
|
||||
|
@ -148,7 +147,7 @@ public class RepositoryManagerTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void testGetRepositoryBadUser() throws Exception {
|
||||
mgr = new RepositoryManager(root, false, false, 0, false);
|
||||
mgr = new RepositoryManager(root, false, 0, false);
|
||||
mgr.createRepository("User_0", "REPOSITORY_A");
|
||||
|
||||
try {
|
||||
|
|
|
@ -49,7 +49,7 @@ public class RepositoryTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
FileUtilities.deleteDir(serverRoot);
|
||||
serverRoot.mkdir();
|
||||
|
||||
mgr = new RepositoryManager(serverRoot, false, false, 0, false);
|
||||
mgr = new RepositoryManager(serverRoot, false, 0, false);
|
||||
mgr.getUserManager().addUser(userName);
|
||||
|
||||
repository = mgr.createRepository(userName, REPOSITORY_NAME);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue