mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge remote-tracking branch 'origin/GP-7281_ghidra1_CorrectGhidraURLErrorHandling' into Ghidra_12.2
This commit is contained in:
@@ -31,12 +31,14 @@ import org.jgrapht.traverse.TopologicalOrderIterator;
|
||||
import org.osgi.framework.*;
|
||||
import org.osgi.framework.launch.Framework;
|
||||
import org.osgi.framework.wiring.*;
|
||||
import org.osgi.service.url.URLStreamHandlerService;
|
||||
|
||||
import generic.io.NullPrintWriter;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.protocol.ghidra.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -417,10 +419,6 @@ public class BundleHost {
|
||||
// setup the cache path
|
||||
config.setProperty(Constants.FRAMEWORK_STORAGE, makeCacheDir());
|
||||
|
||||
// prevent the use of Felix URL handlers which can interfere with URL.openConnection
|
||||
// exception handling
|
||||
config.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false");
|
||||
|
||||
config.put(FelixConstants.LOG_LEVEL_PROP, "1");
|
||||
if (STDERR_DEBUGGING) {
|
||||
config.put(FelixConstants.LOG_LEVEL_PROP, "999");
|
||||
@@ -481,6 +479,8 @@ public class BundleHost {
|
||||
throw new OSGiException("Felix OSGi framework has no bundle context");
|
||||
}
|
||||
|
||||
registerGhidraProtocolHandler(frameworkBundleContext);
|
||||
|
||||
addDebuggingListeners();
|
||||
|
||||
Bundle bundle = frameworkBundleContext.getBundle();
|
||||
@@ -521,6 +521,23 @@ public class BundleHost {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install Ghidra URL stream handler service to force standard use of {@code ghidra} protocol
|
||||
* {@link Handler}. This bypasses the improper IOException propagation caused by
|
||||
* {@code URLHandlersStreamHandlerProxy.openConnection(URL)} which forces itself to
|
||||
* act as a proxy for all normal protocol handlers.
|
||||
*
|
||||
* @param context OSGI Bundle context
|
||||
*/
|
||||
private void registerGhidraProtocolHandler(BundleContext context) {
|
||||
Hashtable<String, Object> properties = new Hashtable<>();
|
||||
properties.put("url.handler.protocol", new String[] { GhidraURL.PROTOCOL });
|
||||
context.registerService(
|
||||
URLStreamHandlerService.class.getName(),
|
||||
new GhidraOSGIStreamHandler(),
|
||||
properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the host framework.
|
||||
* @return the OSGi framework
|
||||
|
||||
@@ -111,41 +111,55 @@ public class URLAnnotatedStringHandler implements AnnotatedStringHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUnsupportedGhidraURL(URL url) {
|
||||
try {
|
||||
return GhidraURL.isGhidraURL(url) && GhidraURL.getProjectPathname(url) == null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMouseClick(String[] annotationParts, Navigatable navigatable,
|
||||
ServiceProvider serviceProvider) {
|
||||
|
||||
String urlString = annotationParts[1];
|
||||
URL url = getURLForString(urlString);
|
||||
if (url != null) {
|
||||
|
||||
String protocol = url.getProtocol();
|
||||
if (!allowedProtocols.contains(protocol)) {
|
||||
Msg.showError(this, null, "URL Access Not Allowed",
|
||||
"Unsupported URL annotation protocol - " + allowedProtocolsStr +
|
||||
" required:\n\n" +
|
||||
urlString);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ClientUtil.getAllowListProvider().isAllowed(url)) {
|
||||
Msg.showError(this, null, "URL Access Not Allowed",
|
||||
"Access denied by Server Allow List");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GhidraURL.PROTOCOL.equals(url.getProtocol())) {
|
||||
ProgramManager programManager = serviceProvider.getService(ProgramManager.class);
|
||||
return programManager.openProgram(url, ProgramManager.OPEN_CURRENT) != null;
|
||||
}
|
||||
|
||||
BrowserLoader.display(url, null, serviceProvider);
|
||||
return true;
|
||||
if (url == null) {
|
||||
Msg.showError(this, null, "Invalid URL",
|
||||
"Invalid URL annotation: " + urlString);
|
||||
return false;
|
||||
}
|
||||
|
||||
Msg.showError(this, null, "Invalid URL",
|
||||
"Invalid URL annotation - not a valid URL: " + urlString);
|
||||
String protocol = url.getProtocol();
|
||||
if (!allowedProtocols.contains(protocol)) {
|
||||
Msg.showError(this, null, "URL Access Not Allowed",
|
||||
"Unsupported URL annotation protocol - " + allowedProtocolsStr +
|
||||
" required:\n" + urlString);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (isUnsupportedGhidraURL(url)) {
|
||||
Msg.showError(this, null, "Invalid Ghidra URL",
|
||||
"Unsupported Ghidra URL annotation:\n" + urlString);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GhidraURL.isLocalURL(url) && !ClientUtil.getAllowListProvider().isAllowed(url)) {
|
||||
Msg.showError(this, null, "URL Access Not Allowed",
|
||||
"Access denied by Server Allow List");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GhidraURL.isGhidraURL(url)) {
|
||||
|
||||
ProgramManager programManager = serviceProvider.getService(ProgramManager.class);
|
||||
return programManager.openProgram(url, ProgramManager.OPEN_CURRENT) != null;
|
||||
}
|
||||
|
||||
BrowserLoader.display(url, null, serviceProvider);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.protocol.ghidra;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
import org.osgi.service.url.AbstractURLStreamHandlerService;
|
||||
|
||||
/**
|
||||
* {@link GhidraOSGIStreamHandler} provides a Ghidra URL stream handler service for
|
||||
* Felix OSGI. This allows direct use of the standard {@code ghidra} protocol
|
||||
* {@link Handler} and bypasses the improper IOException propagation caused by
|
||||
* {@code URLHandlersStreamHandlerProxy.openConnection(URL)}.
|
||||
*/
|
||||
public class GhidraOSGIStreamHandler extends AbstractURLStreamHandlerService {
|
||||
|
||||
private static final Handler ghidraProtocolHandler = new Handler();
|
||||
|
||||
@Override
|
||||
public URLConnection openConnection(URL url) throws IOException {
|
||||
return ghidraProtocolHandler.openConnection(url);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user