mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-08-28 05:20:21 +00:00
GP-4472 Improved handling of read-only case for headless analyzer and GhidraURL connections.
This commit is contained in:
parent
74e402ef15
commit
66c7e4ad19
|
@ -603,9 +603,6 @@ public class HeadlessAnalyzer {
|
||||||
*/
|
*/
|
||||||
private boolean checkUpdateOptions() {
|
private boolean checkUpdateOptions() {
|
||||||
|
|
||||||
boolean isImport = !options.runScriptsNoImport;
|
|
||||||
boolean commitAllowed = isCommitAllowed();
|
|
||||||
|
|
||||||
if (options.readOnly) {
|
if (options.readOnly) {
|
||||||
String readOnlyError =
|
String readOnlyError =
|
||||||
"Abort due to Headless analyzer error: The requested -readOnly option " +
|
"Abort due to Headless analyzer error: The requested -readOnly option " +
|
||||||
|
@ -621,7 +618,13 @@ public class HeadlessAnalyzer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!isInWritableProject()) {
|
||||||
|
Msg.error(this, "Processing files within read-only project/repository " +
|
||||||
|
"- the -readOnly option is required.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean commitAllowed = isCommitAllowed();
|
||||||
if (options.commit && !commitAllowed) {
|
if (options.commit && !commitAllowed) {
|
||||||
Msg.error(this,
|
Msg.error(this,
|
||||||
"Commit to repository not possible (due to permission or connection issue)");
|
"Commit to repository not possible (due to permission or connection issue)");
|
||||||
|
@ -640,6 +643,7 @@ public class HeadlessAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.overwrite) {
|
if (options.overwrite) {
|
||||||
|
boolean isImport = !options.runScriptsNoImport;
|
||||||
if (!isImport) {
|
if (!isImport) {
|
||||||
Msg.info(this,
|
Msg.info(this,
|
||||||
"Ignoring -overwrite because it is not applicable to -process mode.");
|
"Ignoring -overwrite because it is not applicable to -process mode.");
|
||||||
|
@ -654,6 +658,10 @@ public class HeadlessAnalyzer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInWritableProject() {
|
||||||
|
return project.getProjectData().getRootFolder().isInWritableProject();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isCommitAllowed() {
|
private boolean isCommitAllowed() {
|
||||||
RepositoryAdapter repository = project.getRepository();
|
RepositoryAdapter repository = project.getRepository();
|
||||||
if (repository == null) {
|
if (repository == null) {
|
||||||
|
@ -666,7 +674,7 @@ public class HeadlessAnalyzer {
|
||||||
}
|
}
|
||||||
User user = repository.getUser();
|
User user = repository.getUser();
|
||||||
if (!user.hasWritePermission()) {
|
if (!user.hasWritePermission()) {
|
||||||
Msg.warn(this, "User '" + user.getName() +
|
Msg.error(this, "User '" + user.getName() +
|
||||||
"' does not have write permission to repository - commit not allowed");
|
"' does not have write permission to repository - commit not allowed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1126,31 +1134,38 @@ public class HeadlessAnalyzer {
|
||||||
boolean keepFile = true; // if false file should be deleted after release
|
boolean keepFile = true; // if false file should be deleted after release
|
||||||
boolean terminateCheckoutWhenDone = false;
|
boolean terminateCheckoutWhenDone = false;
|
||||||
|
|
||||||
boolean readOnlyFile = options.readOnly || domFile.isReadOnly();
|
boolean readOnlyFile =
|
||||||
|
options.readOnly || domFile.isReadOnly() || !domFile.isInWritableProject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Exclusive checkout required when commit option specified
|
// Exclusive checkout required when commit option specified
|
||||||
if (!readOnlyFile) {
|
if (!readOnlyFile && domFile.isVersioned()) {
|
||||||
if (domFile.isVersioned()) {
|
if (!domFile.isCheckedOut()) {
|
||||||
if (!domFile.isCheckedOut()) {
|
if (!domFile.canCheckout()) {
|
||||||
if (!domFile.checkout(options.commit, TaskMonitor.DUMMY)) {
|
Msg.warn(this, "Skipped processing for " + domFile.getPathname() +
|
||||||
Msg.warn(this, "Skipped processing for " + domFile.getPathname() +
|
" within read-only repository");
|
||||||
" -- failed to get exclusive file checkout required for commit");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (options.commit && !domFile.isCheckedOutExclusive()) {
|
|
||||||
Msg.error(this, "Skipped processing for " + domFile.getPathname() +
|
|
||||||
" -- file is checked-out non-exclusive (commit requires exclusive checkout)");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!domFile.checkout(options.commit, TaskMonitor.DUMMY)) {
|
||||||
|
Msg.warn(this, "Skipped processing for " + domFile.getPathname() +
|
||||||
|
" -- failed to get exclusive file checkout required for commit");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Only terminate checkout when done if we did the checkout
|
||||||
|
terminateCheckoutWhenDone = true;
|
||||||
|
}
|
||||||
|
else if (options.commit && !domFile.isCheckedOutExclusive()) {
|
||||||
|
Msg.error(this, "Skipped processing for " + domFile.getPathname() +
|
||||||
|
" -- file is checked-out non-exclusive (commit requires exclusive checkout)");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
terminateCheckoutWhenDone = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
program = (Program) domFile.getDomainObject(this, true, false, TaskMonitor.DUMMY);
|
program = (Program) domFile.getDomainObject(this, true, false, TaskMonitor.DUMMY);
|
||||||
|
|
||||||
Msg.info(this, "REPORT: Processing project file: " + domFile.getPathname());
|
String readOnlyText = readOnlyFile ? "read-only " : "";
|
||||||
|
Msg.info(this,
|
||||||
|
"REPORT: Processing " + readOnlyText + "project file: " + domFile.getPathname());
|
||||||
|
|
||||||
// This method already takes into account whether the user has set the "noanalysis"
|
// This method already takes into account whether the user has set the "noanalysis"
|
||||||
// flag or not
|
// flag or not
|
||||||
|
|
|
@ -65,28 +65,32 @@ public class DefaultGhidraProtocolConnector extends GhidraProtocolConnector {
|
||||||
|
|
||||||
repositoryServerAdapter =
|
repositoryServerAdapter =
|
||||||
ClientUtil.getRepositoryServer(url.getHost(), url.getPort(), true);
|
ClientUtil.getRepositoryServer(url.getHost(), url.getPort(), true);
|
||||||
|
if (!repositoryServerAdapter.isConnected()) {
|
||||||
|
if (repositoryServerAdapter.isCancelled()) {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
Throwable t = repositoryServerAdapter.getLastConnectError();
|
||||||
|
if (t instanceof LoginException) {
|
||||||
|
statusCode = StatusCode.UNAUTHORIZED;
|
||||||
|
}
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
if (repositoryName == null) {
|
if (repositoryName == null) {
|
||||||
|
if (repositoryServerAdapter.isReadOnly()) {
|
||||||
|
this.readOnly = true; // write access not permitted
|
||||||
|
Msg.warn(this, "User does not have write permission for server");
|
||||||
|
}
|
||||||
statusCode = StatusCode.OK;
|
statusCode = StatusCode.OK;
|
||||||
return statusCode;
|
return statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
repositoryAdapter = repositoryServerAdapter.getRepository(repositoryName);
|
repositoryAdapter = repositoryServerAdapter.getRepository(repositoryName);
|
||||||
if (repositoryServerAdapter.isConnected()) {
|
try {
|
||||||
try {
|
repositoryAdapter.connect();
|
||||||
repositoryAdapter.connect();
|
|
||||||
}
|
|
||||||
catch (RepositoryNotFoundException e) {
|
|
||||||
statusCode = StatusCode.NOT_FOUND;
|
|
||||||
return statusCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!repositoryServerAdapter.isCancelled()) {
|
catch (RepositoryNotFoundException e) {
|
||||||
Throwable t = repositoryServerAdapter.getLastConnectError();
|
statusCode = StatusCode.NOT_FOUND;
|
||||||
if (t instanceof LoginException) {
|
|
||||||
statusCode = StatusCode.UNAUTHORIZED;
|
|
||||||
}
|
|
||||||
//throw new NotConnectedException("Not connected to repository server", t);
|
|
||||||
return statusCode;
|
return statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,8 +415,10 @@ The Headless Analyzer uses the command-line parameters discussed below. See <a h
|
||||||
<a name="readOnly"><typewriter>-readOnly</typewriter></a><br>
|
<a name="readOnly"><typewriter>-readOnly</typewriter></a><br>
|
||||||
If present in <typewriter>-import</typewriter> mode, imported files will NOT be saved to the
|
If present in <typewriter>-import</typewriter> mode, imported files will NOT be saved to the
|
||||||
project. If present in <typewriter>-process</typewriter> mode, any changes made to existing
|
project. If present in <typewriter>-process</typewriter> mode, any changes made to existing
|
||||||
files by scripts or analysis are discarded. The <typewriter>-overwrite</typewriter> option
|
files by scripts or analysis are discarded. When processing a shared project or URL associated
|
||||||
will be ignored if this option is specified during import operations.
|
with a read-only repository, such files will be skipped unless this option is specified.
|
||||||
|
The <typewriter>-overwrite</typewriter> option will be ignored if this option is specified
|
||||||
|
during import operations.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
Loading…
Reference in a new issue