is it possible to block calls to System.exit through ConditionalPermissionAdmin? - java

The documentation is not helping at all, OSGi in Action does not have an example head to toes on how to do things. For example, I want bundle A to deny a package import from Bundle B, etc. Simple examples, from start to end - I can't find them.
But back to my question, I want to block calls to System.exit for obvious reasons, besides "do not implement your own Security Manager", I did not get much from the Virgo forum, thus my question here.
EDIT
Since I want this to happen in Virgo, here is what I have tried:
public void start(BundleContext context) throws Exception {
System.out.println("===== Starting Bundle PermissionsTest =====");
SecurityManager securityManager = System.getSecurityManager();
if(securityManager == null) throw new IllegalArgumentException("Security Manager is not defined!");
ServiceReference serviceReference =
(ServiceReference) context.getServiceReference(ConditionalPermissionAdmin.class.getName());
if(serviceReference == null) throw new IllegalArgumentException(ConditionalPermissionAdmin.class.getName() + " IS NULL");
else System.out.println("===== Good so far 1 =====");
ConditionalPermissionAdmin conditionalPermissionAdmin =
(ConditionalPermissionAdmin)context.getService(serviceReference);
if(conditionalPermissionAdmin == null) throw new IllegalArgumentException("ConditionalPermissionAdmin can not be found");
else System.out.println("===== Good so far 2 =====");
What I did first in Virgo ie enable the Equinox Security Manager (because this is the one Virgo uses). The specification of the OSGi says that each container has to implement it's own Security Manager extended with a bunch of OSGi specific actions.
In case of Virgo this is Equinox Security Manager. Enabling it is pretty easy - just add two lines in bin/dmk.sh and thus you have it.
Ok, so I do have the ConditionalPermissionAdmin - good! Now, I can for example, add a Security Check, like, BundlePermission say for a Bundle. Sure, but that happens for bundle specific actions, like start/stop/export, etc etc. I can't seem to figure out how to do it for a LifeCycle action - System.exit in my case.
btw, I use version 4.2.0 of the osgi-core, and nope I can't upgrade to 4.3.0, at least not now.

System.exit is governed by RuntimePermission( "exitVm", "<>"), so the example syntax in the spec gives
DENY {
( java.lang.RuntimePermission "exitVm" "*" )
}
In Java code (haven't tested it, so beware):
ConditionalPermissionInfo info = admin.newConditionalPermissionInfo(
"name",
null,
new PermissionInfo[] { new PermissionInfo(
"java.lang.RuntimePermission", "exitVm", "*") },
ConditionalPermissionInfo.DENY
);
ConditionalPermissionUpdate update = admin
.newConditionalPermissionUpdate();
update.getConditionalPermissionInfos().add(0, info);
update.commit();
The subject is rather well treated in the book "OSGi in Action". Please remember that the primary audience of the specification was the implementer of the specification, not the end user. The members were supposed to provide the educational material to bridge that gap. Later specs tried to become more educational for end-users.

Related

How to get the current substate and the parent state out of the Spring Statemachine?

I am running a hierachical Spring Statemachine and - after walking through the inital transitions into state UP with the default substate STOPPED - want to use statemachine.getState(). Trouble is, it gives me only the parent state UP, and I cannot find an obvious way to retrieve both the parent state and the sub state.
The machine has states constructed like so:
StateMachineBuilder.Builder<ToolStates, ToolEvents> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(ToolStates.UP)
.state(ToolStates.UP, new ToolUpEventAction(), null)
.state(ToolStates.DOWN
.and()
.withStates()
.parent(ToolStates.UP)
.initial(ToolStates.STOPPED)
.state(ToolStates.STOPPED,new ToolStoppedEventAction(), null )
.state(ToolStates.IDLE)
.state(ToolStates.PROCESSING,
new ToolBeginProcessingPartAction(),
new ToolDoneProcessingPartAction());
...
builder.build();
ToolStates and ToolEvents are just enums. In the client class, after running the builder code above, the statemachine is started with statemachine.start(); When I subsequently call statemachine.getState().getId(); it gives me UP. No events sent to statemachine before that call.
I have been up and down the Spring statemachine docs and examples. I know from debugging that the entry actions of both states UP and STOPPED have been invoked, so I am assuming they are both "active" and would want to have both states presented when querying the statemachine. Is there a clean way to achieve this ? I want to avoid storing the substate somewhere from inside the Action classes, since I believe I have delegated all state management issues to the freakin Statemachine in the first place and I would rather like to learn how to use its API for this purpose.
Hopefully this is something embarrasingly obvious...
Any advice most welcome!
The documentation describes getStates():
https://docs.spring.io/spring-statemachine/docs/current/api/org/springframework/statemachine/state/State.html
java.util.Collection<State<S,E>> getStates()
Gets all possible states this state knows about including itself and substates.
stateMachine.getState().getStates();
to wrap it up after SMA's most helpful advice: turns out the stateMachine.getState().getStates(); does in my case return a list of four elements:
a StateMachineState instance containing UP and STOPPED
three ObjectState instances containing IDLE, STOPPED and PROCESSING,
respectively.
this leads me to go forward for the time being with the following solution:
public List<ToolStates> getStates() {
List<ToolStates> result = new ArrayList<>();
Collection<State<ToolStates, ToolEvents>> states = this.stateMachine.getState().getStates();
Iterator<State<ToolStates, ToolEvents>> iter = states.iterator();
while (iter.hasNext()) {
State<ToolStates, ToolEvents> candidate = iter.next();
if (!candidate.isSimple()) {
Collection<ToolStates> ids = candidate.getIds();
Iterator<ToolStates> i = ids.iterator();
while (i.hasNext()) {
result.add(i.next());
}
}
}
return result;
}
This maybe would be more elegant with some streaming and filtering, but does the trick for now. I don't like it much, though. It's a lot of error-prone logic and I'll have to see if it holds in the future - I wonder why there isn't a function in the Spring Statemachine that gives me a list of the enum values of all the currently active states, rather than giving me everything possible and forcing me to poke around in it with external logic...

embedded Nashorn - sandboxing execution

I would like to get a clear answer on how to Sandbox execution Nashorn within a Java Application.
I have seen 'similar questions' (which I will refer to) but ultimately none of the answer seem to address my concerns.
Let me start with definitions.
Assume we start with this:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.put("map",new HashMap());
engine.eval(jsCode); // jsCode can access 'map' only.
By "Sandboxing" I mean ensure that the JavaScript must not access any java object except the one added in the scope.
so the following evals should be fine.
engine.eval("map.toString()");
engine.eval("map.size()");
engine.eval("map.put('name','jeff'); ");
engine.eval("map.getClass()");
But the following evals will not:
engine.eval("var m = new java.util.HashMap();"); // <-- stop accessing Java
engine.eval("map.getClass().forName('java.io.File'); "); // stop. it's trying to be sneaky
Finally, I am not concerned about this:
engine.eval("while(1) {;}"); // this is impossible to detect. Maybe it's possible for this simple case... but sneaky users could make it impossible to detect... anyway this is not what I am asking. I am only concerned on accessing java objects.
So by sandboxing I intend to prevent jsCode to access java objects that I don't define.
I saw that this might be a potential solution:
jdk.nashorn.api.scripting.NashornScriptEngineFactory factory = new jdk.nashorn.api.scripting.NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new jdk.nashorn.api.scripting.ClassFilter() {
public boolean exposeToScripts(String s) {
return false;
}
});
but is it 'safe' to access a package beginning with jdk.* directly ?
Another approach I saw is even more mysterious:
final ScriptEngine engine =
new NashornScriptEngineFactory().getScriptEngine(new String[] { "--no-java" });
I saw that one here:
Safely re-using sandboxed Nashorn containers
Can somebody let me know ?
You can use jdk.nashorn.api.scripting.* API if that would help in your application. javadoc for the same is here -> https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/
And yes, --no-java is the option for preventing java package access from script code.

Implementing a URL redirect in Java webapp

I'm having trouble figuring out how to create issue a redirect to the browser after a certain condition in a Java webapp running on Tomcat. I'm sure there must be a simple solution, but my Java skills are extremely limited.
Here's the specific code I'm working with (copied from guacamole-auth-passthrough):
if (req.getParameter("username") == null {
LOG.error("username is required");
throw new GuacamoleServerException("username is required");
}
I'd like to replace that exception with a redirect back to the index page. In PHP I could simply do this:
header("Location: https://site.domain.com/",TRUE,302);
Java's not letting me off so easily, though. The best direct analog I could find is this:
response.sendRedirect("https://site.domain.com/");
However, that fails compilation with:
[ERROR] /home/dev/guacamole-client-0.9.9/extensions/guacamole-auth-passthrough/src/main/java/com/github/edouardswiac/guacamole/ext/PassthroughAuthProvider.java:[31,6] error: cannot find symbol
I've found many other examples of Java redirects (including this other stackoverflow thread), but almost all of them seem to implement separate methods to implement the redirect. As I said, my java skills are very basic, and I have no idea how to actually implement something like that to be used/called from within an if condition.
Can anyone provide some pointers on how I can correctly implement this within the condition above? I'm pretty much completely out of ideas at this point, and would very much appreciate any guidance. Thanks.
I would suggest to write response.sendRedirect() in the catch block of the exception. For example:
HttpServletResponse response = credentials.getResponse();
try{
if (req.getParameter("username") == null {
LOG.error("username is required");
throw new GuacamoleServerException("username is required");
}
catch(GuacamoleServerException e){
response.sendRedirect("https://site.domain.com/");
}
P.S. This is provided you are using Java Servlets for your purpose.

Access FacesContext in xAgent (in new Thread)

I am planning to use single entry point for all 5 minutes xAgents, meaning one XPage launchs all 5 minutes "java agents" (classes that should be launched every 5 minutes). I would like to lauch that java code in new different Threads to have true parallel lauch of such agents.
The mentioned "java agents" have strong interdependency with other NSF app classes. Many of them rely on FacesContext and / or other XSP / JSF global variables.
"Java agent" code example:
import javax.faces.context.FacesContext;
import com.ibm.domino.xsp.module.nsf.NSFComponentModule;
import com.ibm.domino.xsp.module.nsf.NotesContext;
import com.ibm.xsp.extlib.util.ExtLibUtil;
public class Agent1 implements Runnable {
private NSFComponentModule module;
public Agent1() {
this.module = NotesContext.getCurrent().getModule();
System.out.println("Agent1: test 1.1: " + (ExtLibUtil.getCurrentSessionAsSigner() == null)); // FALSE here
System.out.println("Agent1: test 1.2: " + (FacesContext.getCurrentInstance() == null)); // FALSE here
}
public void run() {
NotesContext context = new NotesContext(this.module);
NotesContext.initThread(context);
System.out.println("Agent1: test 2.2: " + (ExtLibUtil.getCurrentSessionAsSigner() == null)); // TRUE here
System.out.println("Agent1: test 2.2: " + (FacesContext.getCurrentInstance() == null)); // TRUE here
// Threaded xAgent job here...
NotesContext.termThread();
}
}
The issue: Such methods like: FacesContext.getCurrentInstance(), ExtLibUtil.getCurrentSessionAsSigner() return NULL in new Thread.
The question: Is it possible to init XSP / JSF engine inside new Thread to get access to FacesContext, etc (to get not null in lines "Agent1: test 2.1" and "Agent1: test 2.2")?
Thanks in advance!
I encountered a similar problem when developing with XOTS in OpenNTF Domino API. The best option is to pass whatever objects are needed in the constructor. Here's the relevant blog post on XOTS http://www.intec.co.uk/xots-background-and-multithreaded-tasks-the-openntf-domino-api-way-part-two/ (replace "two" with "one" and "three" for the other parts of the series).
XOTS works very well for parallel processing and allows configuration of the number of threads, by default 10.
When I looked at documentation for threading in XPages, the blog posts I found suggested potential issues not covered in that post, but didn't elaborate. I've not investigated further.

Java Jinput: rescan / reload controllers

I am using java jinput library to read data from joypad, and I have trouble reloading Controllers, I use this to load them:
public Controller[] findStickControllers() {
ControllerEnvironment ce =
ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
System.out.println(cs.length); //test
ArrayList<Controller> sel = new ArrayList<>();
for (Controller c: cs) {
if(c.getType() == Type.STICK) {
sel.add(c);
}
}
return sel.toArray(new Controller[]{});
}
This works fine, but if I disconnect my controller, calling this will find it again, and vice versa (connecting it after the first check will not find it at all).
I have tried to put sleep before the fist lookup, with these results:
Controllers are acctually scanned when this method is called first time (not at start of the program)
When called again, this always returns same controllers as it returned for the first time.
First call will also write warning bellow
Even when controller is connected (and works), then disconnected (it will still find it though) and reconnected, it will not work
Warning from point 3: (didn't format well in the list)
WARNING: Found unknown Windows version: Windows 8
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
I am using Win 8, and had same problem on Win 7. I had also tried this with mouse, same results.
How can I acctually reload controllers for the 2nd, 3rd, and so on time?
I encountered the same problem. The reason is that the actual hardware scan happens only once for each DefaultControllerEnvironment object. Since the only accessible instantiation is a singleton, it never does another scan.
A simple way to force a hardware scan is to create a new object, but neither the class nor the constructor are public. You can however work around this limitation by calling the constructor via reflection.
Rescan
private static ControllerEnvironment createDefaultEnvironment() throws ReflectiveOperationException {
// Find constructor (class is package private, so we can't access it directly)
Constructor<ControllerEnvironment> constructor = (Constructor<ControllerEnvironment>)
Class.forName("net.java.games.input.DefaultControllerEnvironment").getDeclaredConstructors()[0];
// Constructor is package private, so we have to deactivate access control checks
constructor.setAccessible(true);
// Create object with default constructor
return constructor.newInstance();
}
Usage
// Be aware that creating a new environment is fairly expensive
Controller[] controllers = createDefaultEnvironment().getControllers();
Remove Windows 8 Warnings
/**
* Fix windows 8 warnings by defining a working plugin
*/
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
String os = System.getProperty("os.name", "").trim();
if (os.startsWith("Windows 8")) { // 8, 8.1 etc.
// disable default plugin lookup
System.setProperty("jinput.useDefaultPlugin", "false");
// set to same as windows 7 (tested for windows 8 and 8.1)
System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin");
}
return null;
}
});
}
If you use the accepted answer, you might want to consider killing the thread that was spawned by the previous environment before setting a new one because it won't be cleaned up otherwise. You can do so by calling something like:
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (final Thread thread : threadSet) {
final String name = thread.getClass().getName();
if (name.equals("net.java.games.input.RawInputEventQueue$QueueThread")) {
thread.interrupt();
try {
thread.join();
} catch (final InterruptedException e) {
thread.interrupt();
}
}
}
The warning is because the last time I updated that code windows 7 wasn't even out IIRC, I'll update it.
The controller reload is a feature that has been requested a number of times, but no-one deems it important enough to spend any time implementing it. If you submit a patch I'll take a look and see about committing it. Until someone finds it important enough to spend the time to write it, it's just a missing feature.
I had the same problem before.
I add the rescanning feature (for Windows back-end only) and post the patch on Java gaming forum but no ones seem interested in to integrate it.
So if you need it, apply my patch from here: http://www.java-gaming.org/topics/rescan-controllers/24782/msg/224604/view.html#msg224604

Categories